import React, { useCallback, useState, useRef, useMemo } from 'react'; import { Box, Card, IconButton, Flex, Grid, Button, useTheme, Drawer, DrawerBody, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerContent, useDisclosure } from '@chakra-ui/react'; import { usePagination } from '@/web/common/hooks/usePagination'; import { getDatasetDataList, delOneDatasetDataById, getDatasetCollectionById } from '@/web/core/dataset/api'; import { DeleteIcon } from '@chakra-ui/icons'; import { useQuery } from '@tanstack/react-query'; import { useToast } from '@fastgpt/web/hooks/useToast'; import { debounce } from 'lodash'; import { getErrText } from '@fastgpt/global/common/error/utils'; import { useConfirm } from '@/web/common/hooks/useConfirm'; import { useTranslation } from 'next-i18next'; import { useRouter } from 'next/router'; import MyIcon from '@fastgpt/web/components/common/Icon'; import MyInput from '@/components/MyInput'; import { useLoading } from '@/web/common/hooks/useLoading'; import InputDataModal from '../components/InputDataModal'; import RawSourceBox from '@/components/core/dataset/RawSourceBox'; import type { DatasetDataListItemType } from '@/global/core/dataset/type.d'; import { TabEnum } from '..'; import { useUserStore } from '@/web/support/user/useUserStore'; import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import { DatasetCollectionTypeMap, TrainingModeEnum, TrainingTypeMap } from '@fastgpt/global/core/dataset/constants'; import { formatTime2YMDHM } from '@fastgpt/global/common/string/time'; import { formatFileSize } from '@fastgpt/global/common/file/tools'; import { getFileAndOpen } from '@/web/core/dataset/utils'; import MyTooltip from '@/components/MyTooltip'; const DataCard = () => { const BoxRef = useRef(null); const theme = useTheme(); const lastSearch = useRef(''); const router = useRouter(); const { userInfo } = useUserStore(); const { isPc } = useSystemStore(); const { collectionId = '', datasetId } = router.query as { collectionId: string; datasetId: string; }; const { Loading, setIsLoading } = useLoading({ defaultLoading: true }); const { t } = useTranslation(); const [searchText, setSearchText] = useState(''); const { toast } = useToast(); const { openConfirm, ConfirmModal } = useConfirm({ content: t('dataset.Confirm to delete the data'), type: 'delete' }); const { isOpen, onOpen, onClose } = useDisclosure(); const { data: datasetDataList, Pagination, total, getData, pageNum, pageSize } = usePagination({ api: getDatasetDataList, pageSize: 24, params: { collectionId, searchText }, onChange() { setIsLoading(false); if (BoxRef.current) { BoxRef.current.scrollTop = 0; } } }); const [editDataId, setEditDataId] = useState(); // get first page data const getFirstData = useCallback( debounce(() => { getData(1); lastSearch.current = searchText; }, 300), [] ); // get file info const { data: collection } = useQuery( ['getDatasetCollectionById', collectionId], () => getDatasetCollectionById(collectionId), { onError: () => { router.replace({ query: { datasetId } }); } } ); const canWrite = useMemo( () => userInfo?.team?.role !== TeamMemberRoleEnum.visitor && !!collection?.canWrite, [collection?.canWrite, userInfo?.team?.role] ); const metadataList = useMemo(() => { if (!collection) return []; const webSelector = collection?.datasetId?.websiteConfig?.selector || collection?.metadata?.webPageSelector; return [ { label: t('core.dataset.collection.metadata.source'), value: t(DatasetCollectionTypeMap[collection.type]?.name) }, { label: t('core.dataset.collection.metadata.source name'), value: collection.file?.filename || collection?.rawLink || collection?.name }, { label: t('core.dataset.collection.metadata.source size'), value: collection.file ? formatFileSize(collection.file.length) : '-' }, { label: t('core.dataset.collection.metadata.Createtime'), value: formatTime2YMDHM(collection.createTime) }, { label: t('core.dataset.collection.metadata.Updatetime'), value: formatTime2YMDHM(collection.updateTime) }, { label: t('core.dataset.collection.metadata.Raw text length'), value: collection.rawTextLength ?? '-' }, { label: t('core.dataset.collection.metadata.Training Type'), value: t(TrainingTypeMap[collection.trainingType]?.label) }, { label: t('core.dataset.collection.metadata.Chunk Size'), value: collection.chunkSize || '-' }, ...(webSelector ? [ { label: t('core.dataset.collection.metadata.Web page selector'), value: webSelector } ] : []) ]; }, [collection, t]); return ( } variant={'whitePrimary'} size={'smSquare'} borderRadius={'50%'} aria-label={''} onClick={() => router.replace({ query: { datasetId: router.query.datasetId, parentId: router.query.parentId, currentTab: TabEnum.collectionCard } }) } /> {t('core.dataset.collection.id')}:{' '} {collection?._id} {canWrite && ( )} {isPc && ( } aria-label={''} onClick={onOpen} /> )} {t('core.dataset.data.Total Amount', { total })} } w={['200px', '300px']} placeholder={t('core.dataset.data.Search data placeholder')} value={searchText} onChange={(e) => { setSearchText(e.target.value); getFirstData(); }} onBlur={() => { if (searchText === lastSearch.current) return; getFirstData(); }} onKeyDown={(e) => { if (searchText === lastSearch.current) return; if (e.key === 'Enter') { getFirstData(); } }} /> {datasetDataList.map((item, index) => ( { if (!collection) return; setEditDataId(item._id); }} > # {item.chunkIndex ?? '-'} ID:{item._id} {item.q} {item.a} {item.q.length + (item.a?.length || 0)} {canWrite && ( } variant={'whiteDanger'} size={'xsSquare'} aria-label={'delete'} onClick={(e) => { e.stopPropagation(); openConfirm(async () => { try { setIsLoading(true); await delOneDatasetDataById(item._id); getData(pageNum); } catch (error) { toast({ title: getErrText(error), status: 'error' }); } setIsLoading(false); })(); }} /> )} ))} {total > pageSize && ( )} {total === 0 && ( {t('core.dataset.data.Empty Tip')} )} {/* metadata drawer */} {t('core.dataset.collection.metadata.metadata')} {metadataList.map((item) => ( {item.label} {item.value} ))} {collection?.sourceId && ( )} {editDataId !== undefined && collection && ( setEditDataId(undefined)} onSuccess={() => getData(pageNum)} onDelete={() => getData(pageNum)} /> )} ); }; export default React.memo(DataCard);