import React, { useMemo, useState } from 'react'; import { Box, BoxProps, Flex } from '@chakra-ui/react'; import { GetResourceFolderListProps, GetResourceListItemResponse, ParentIdType } from '@fastgpt/global/common/parentFolder/type'; import MyIcon from '@fastgpt/web/components/common/Icon'; import Loading from '@fastgpt/web/components/common/MyLoading'; import Avatar from '@/components/Avatar'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useMemoizedFn } from 'ahooks'; import { FolderImgUrl } from '@fastgpt/global/common/file/image/constants'; import { useTranslation } from 'next-i18next'; type ResourceItemType = GetResourceListItemResponse & { open: boolean; children?: ResourceItemType[]; }; const rootId = 'root'; const SelectOneResource = ({ server, value, onSelect, maxH = ['80vh', '600px'] }: { server: (e: GetResourceFolderListProps) => Promise; value?: ParentIdType; onSelect: (e?: string) => any; maxH?: BoxProps['maxH']; }) => { const { t } = useTranslation(); const [dataList, setDataList] = useState([]); const [requestingIdList, setRequestingIdList] = useState([]); const concatRoot = useMemo(() => { const root: ResourceItemType = { id: rootId, open: true, avatar: FolderImgUrl, name: t('common:common.folder.Root Path'), isFolder: true, children: dataList }; return [root]; }, [dataList, t]); const { runAsync: requestServer } = useRequest2((e: GetResourceFolderListProps) => { if (requestingIdList.includes(e.parentId)) return Promise.reject(null); setRequestingIdList((state) => [...state, e.parentId]); return server(e).finally(() => setRequestingIdList((state) => state.filter((id) => id !== e.parentId)) ); }, {}); const { loading } = useRequest2(() => requestServer({ parentId: null }), { manual: false, onSuccess: (data) => { setDataList( data.map((item) => ({ ...item, open: false })) ); } }); const Render = useMemoizedFn( ({ list, index = 0 }: { list: ResourceItemType[]; index?: number }) => { return ( <> {list.map((item) => ( onSelect(undefined) } : { onClick: async () => { if (item.id === rootId) return; // folder => open(request children) or close if (item.isFolder) { if (!item.children) { const data = await requestServer({ parentId: item.id }); item.children = data.map((item) => ({ ...item, open: false })); } item.open = !item.open; setDataList([...dataList]); } else { onSelect(item.id); } } })} > {index !== 0 && ( )} {item.name} {item.children && item.open && ( )} ))} ); } ); return loading ? ( ) : ( ); }; export default SelectOneResource;