mirror of
https://github.com/labring/FastGPT.git
synced 2025-08-02 12:48:30 +00:00
4.8.6 merge (#1943)
* Dataset collection forbid (#1885) * perf: tool call support same id * feat: collection forbid * feat: collection forbid * Inheritance Permission for apps (#1897) * feat: app schema define chore: references of authapp * feat: authApp method inheritance * feat: create and update api * feat: update * feat: inheritance Permission controller for app. * feat: abstract version of inheritPermission * feat: ancestorId for apps * chore: update app * fix: inheritPermission abstract version * feat: update folder defaultPermission * feat: app update api * chore: inheritance frontend * chore: app list api * feat: update defaultPermission in app deatil * feat: backend api finished * feat: app inheritance permission fe * fix: app update defaultpermission causes collaborator miss * fix: ts error * chore: adjust the codes * chore: i18n chore: i18n * chore: fe adjust and i18n * chore: adjust the code * feat: resume api; chore: rewrite update api and inheritPermission methods * chore: something * chore: fe code adjusting * feat: frontend adjusting * chore: fe code adjusting * chore: adjusting the code * perf: fe loading * format * Inheritance fix (#1908) * fix: SlideCard * fix: authapp did not return parent app for inheritance app * fix: fe adjusting * feat: fe adjusing * perf: inherit per ux * doc * fix: ts errors (#1916) * perf: inherit permission * fix: permission inherit * Workflow type (#1938) * perf: workflow type tmp workflow perf: workflow type feat: custom field config * perf: dynamic input * perf: node classify * perf: node classify * perf: node classify * perf: node classify * fix: workflow custom input * feat: text editor and customFeedback move to basic nodes * feat: community system plugin * fix: ts * feat: exprEval plugin * perf: workflow type * perf: plugin important * fix: default templates * perf: markdown hr css * lock * perf: fetch url * perf: new plugin version * fix: chat histories update * fix: collection paths invalid * perf: app card ui --------- Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
This commit is contained in:
@@ -41,7 +41,7 @@ const Header = ({}: {}) => {
|
||||
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
|
||||
|
||||
const router = useRouter();
|
||||
const { parentId = '' } = router.query as { parentId: string; datasetId: string };
|
||||
const { parentId = '' } = router.query as { parentId: string };
|
||||
const { isPc } = useSystemStore();
|
||||
|
||||
const lastSearch = useRef('');
|
||||
|
@@ -9,7 +9,8 @@ import {
|
||||
Th,
|
||||
Td,
|
||||
Tbody,
|
||||
MenuButton
|
||||
MenuButton,
|
||||
Switch
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
delDatasetCollectionById,
|
||||
@@ -20,8 +21,7 @@ import { useQuery } from '@tanstack/react-query';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import dayjs from 'dayjs';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { useRouter } from 'next/router';
|
||||
import MyMenu from '@fastgpt/web/components/common/MyMenu';
|
||||
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
|
||||
@@ -33,7 +33,6 @@ import {
|
||||
import { getCollectionIcon } from '@fastgpt/global/core/dataset/utils';
|
||||
import { TabEnum } from '../../index';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useDrag } from '@/web/common/hooks/useDrag';
|
||||
import SelectCollections from '@/web/core/dataset/components/SelectCollections';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
@@ -42,6 +41,14 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { CollectionPageContext } from './Context';
|
||||
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { formatTime2YMDHM } from '@fastgpt/global/common/string/time';
|
||||
import MyTag from '@fastgpt/web/components/common/Tag/index';
|
||||
import {
|
||||
checkCollectionIsFolder,
|
||||
getTrainingTypeLabel
|
||||
} from '@fastgpt/global/core/dataset/collection/utils';
|
||||
import { useFolderDrag } from '@/components/common/folder/useFolderDrag';
|
||||
|
||||
const Header = dynamic(() => import('./Header'));
|
||||
const EmptyCollectionTip = dynamic(() => import('./EmptyCollectionTip'));
|
||||
@@ -51,6 +58,7 @@ const CollectionCard = () => {
|
||||
const router = useRouter();
|
||||
const { toast } = useToast();
|
||||
const { t } = useTranslation();
|
||||
const { datasetT } = useI18n();
|
||||
const { datasetDetail, loadDatasetDetail } = useContextSelector(DatasetPageContext, (v) => v);
|
||||
|
||||
const { openConfirm: openDeleteConfirm, ConfirmModal: ConfirmDeleteModal } = useConfirm({
|
||||
@@ -70,8 +78,6 @@ const CollectionCard = () => {
|
||||
const { collections, Pagination, total, getData, isGetting, pageNum, pageSize } =
|
||||
useContextSelector(CollectionPageContext, (v) => v);
|
||||
|
||||
const { dragStartId, setDragStartId, dragTargetId, setDragTargetId } = useDrag();
|
||||
|
||||
// Ad file status icon
|
||||
const formatCollections = useMemo(
|
||||
() =>
|
||||
@@ -83,16 +89,12 @@ const CollectionCard = () => {
|
||||
statusText: t('dataset.collections.Collection Embedding', {
|
||||
total: collection.trainingAmount
|
||||
}),
|
||||
color: 'myGray.600',
|
||||
bg: 'myGray.50',
|
||||
borderColor: 'borderColor.low'
|
||||
colorSchema: 'gray'
|
||||
};
|
||||
}
|
||||
return {
|
||||
statusText: t('core.dataset.collection.status.active'),
|
||||
color: 'green.600',
|
||||
bg: 'green.50',
|
||||
borderColor: 'green.300'
|
||||
colorSchema: 'green'
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -105,20 +107,15 @@ const CollectionCard = () => {
|
||||
[collections, t]
|
||||
);
|
||||
|
||||
const { mutate: onUpdateCollectionName } = useRequest({
|
||||
mutationFn: ({ collectionId, name }: { collectionId: string; name: string }) => {
|
||||
return putDatasetCollectionById({
|
||||
id: collectionId,
|
||||
name
|
||||
});
|
||||
},
|
||||
onSuccess() {
|
||||
getData(pageNum);
|
||||
},
|
||||
|
||||
successToast: t('common.Rename Success'),
|
||||
errorToast: t('common.Rename Failed')
|
||||
});
|
||||
const { runAsync: onUpdateCollection, loading: isUpdating } = useRequest2(
|
||||
putDatasetCollectionById,
|
||||
{
|
||||
onSuccess() {
|
||||
getData(pageNum);
|
||||
},
|
||||
successToast: t('common.Update Success')
|
||||
}
|
||||
);
|
||||
const { mutate: onDelCollection, isLoading: isDeleting } = useRequest({
|
||||
mutationFn: (collectionId: string) => {
|
||||
return delDatasetCollectionById({
|
||||
@@ -150,10 +147,6 @@ const CollectionCard = () => {
|
||||
() => !!formatCollections.find((item) => item.trainingAmount > 0),
|
||||
[formatCollections]
|
||||
);
|
||||
const isLoading = useMemo(
|
||||
() => isDeleting || isSyncing || (isGetting && collections.length === 0),
|
||||
[collections.length, isDeleting, isGetting, isSyncing]
|
||||
);
|
||||
|
||||
useQuery(
|
||||
['refreshCollection'],
|
||||
@@ -170,6 +163,24 @@ const CollectionCard = () => {
|
||||
}
|
||||
);
|
||||
|
||||
const { getBoxProps, isDropping } = useFolderDrag({
|
||||
activeStyles: {
|
||||
bg: 'primary.100'
|
||||
},
|
||||
onDrop: async (dragId: string, targetId: string) => {
|
||||
try {
|
||||
await putDatasetCollectionById({
|
||||
id: dragId,
|
||||
parentId: targetId
|
||||
});
|
||||
getData(pageNum);
|
||||
} catch (error) {}
|
||||
}
|
||||
});
|
||||
|
||||
const isLoading =
|
||||
isUpdating || isDeleting || isSyncing || (isGetting && collections.length === 0) || isDropping;
|
||||
|
||||
return (
|
||||
<MyBox isLoading={isLoading} h={'100%'} py={[2, 4]}>
|
||||
<Flex ref={BoxRef} flexDirection={'column'} py={[1, 3]} h={'100%'}>
|
||||
@@ -177,75 +188,41 @@ const CollectionCard = () => {
|
||||
<Header />
|
||||
|
||||
{/* collection table */}
|
||||
<TableContainer
|
||||
px={[2, 6]}
|
||||
mt={[0, 3]}
|
||||
position={'relative'}
|
||||
flex={'1 0 0'}
|
||||
overflowY={'auto'}
|
||||
fontSize={'sm'}
|
||||
>
|
||||
<TableContainer px={[2, 6]} mt={[0, 3]} flex={'1 0 0'} overflowY={'auto'} fontSize={'sm'}>
|
||||
<Table variant={'simple'} draggable={false}>
|
||||
<Thead draggable={false}>
|
||||
<Tr>
|
||||
<Th py={4}>#</Th>
|
||||
<Th py={4}>{t('common.Name')}</Th>
|
||||
<Th py={4}>{datasetT('collection.Training type')}</Th>
|
||||
<Th py={4}>{t('dataset.collections.Data Amount')}</Th>
|
||||
<Th py={4}>{t('core.dataset.Sync Time')}</Th>
|
||||
<Th py={4}>{datasetT('collection.Create update time')}</Th>
|
||||
<Th py={4}>{t('common.Status')}</Th>
|
||||
<Th py={4}>{datasetT('Enable')}</Th>
|
||||
<Th py={4} />
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
<Tr h={'10px'} />
|
||||
{formatCollections.map((collection, index) => (
|
||||
<Tr h={'5px'} />
|
||||
{formatCollections.map((collection) => (
|
||||
<Tr
|
||||
key={collection._id}
|
||||
_hover={{ bg: 'myGray.50' }}
|
||||
cursor={'pointer'}
|
||||
data-drag-id={
|
||||
collection.type === DatasetCollectionTypeEnum.folder
|
||||
? collection._id
|
||||
: undefined
|
||||
}
|
||||
bg={dragTargetId === collection._id ? 'primary.100' : ''}
|
||||
userSelect={'none'}
|
||||
onDragStart={() => {
|
||||
setDragStartId(collection._id);
|
||||
}}
|
||||
onDragOver={(e) => {
|
||||
e.preventDefault();
|
||||
const targetId = e.currentTarget.getAttribute('data-drag-id');
|
||||
if (!targetId) return;
|
||||
DatasetCollectionTypeEnum.folder && setDragTargetId(targetId);
|
||||
}}
|
||||
onDragLeave={(e) => {
|
||||
e.preventDefault();
|
||||
setDragTargetId(undefined);
|
||||
}}
|
||||
onDrop={async (e) => {
|
||||
e.preventDefault();
|
||||
if (!dragTargetId || !dragStartId || dragTargetId === dragStartId) return;
|
||||
// update parentId
|
||||
try {
|
||||
await putDatasetCollectionById({
|
||||
id: dragStartId,
|
||||
parentId: dragTargetId
|
||||
});
|
||||
getData(pageNum);
|
||||
} catch (error) {}
|
||||
setDragTargetId(undefined);
|
||||
}}
|
||||
{...getBoxProps({
|
||||
dataId: collection._id,
|
||||
isFolder: collection.type === DatasetCollectionTypeEnum.folder
|
||||
})}
|
||||
draggable={false}
|
||||
onClick={() => {
|
||||
if (collection.type === DatasetCollectionTypeEnum.folder) {
|
||||
router.replace({
|
||||
router.push({
|
||||
query: {
|
||||
...router.query,
|
||||
parentId: collection._id
|
||||
}
|
||||
});
|
||||
} else {
|
||||
router.replace({
|
||||
router.push({
|
||||
query: {
|
||||
...router.query,
|
||||
collectionId: collection._id,
|
||||
@@ -255,8 +232,7 @@ const CollectionCard = () => {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Td w={'50px'}>{index + 1}</Td>
|
||||
<Td minW={'150px'} maxW={['200px', '300px']} draggable>
|
||||
<Td minW={'150px'} maxW={['200px', '300px']} draggable py={2}>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={collection.icon as any} w={'16px'} mr={2} />
|
||||
<MyTooltip label={t('common.folder.Drag Tip')} shouldWrapChildren={false}>
|
||||
@@ -266,33 +242,36 @@ const CollectionCard = () => {
|
||||
</MyTooltip>
|
||||
</Flex>
|
||||
</Td>
|
||||
<Td>{collection.dataAmount || '-'}</Td>
|
||||
<Td>{dayjs(collection.updateTime).format('YYYY/MM/DD HH:mm')}</Td>
|
||||
<Td>
|
||||
<Box
|
||||
display={'inline-flex'}
|
||||
alignItems={'center'}
|
||||
w={'auto'}
|
||||
color={collection.color}
|
||||
bg={collection.bg}
|
||||
borderWidth={'1px'}
|
||||
borderColor={collection.borderColor}
|
||||
px={3}
|
||||
py={1}
|
||||
borderRadius={'md'}
|
||||
_before={{
|
||||
content: '""',
|
||||
w: '6px',
|
||||
h: '6px',
|
||||
mr: 2,
|
||||
borderRadius: 'lg',
|
||||
bg: collection.color
|
||||
}}
|
||||
>
|
||||
{t(collection.statusText)}
|
||||
</Box>
|
||||
<Td py={2}>
|
||||
{!checkCollectionIsFolder(collection.type) ? (
|
||||
<>{t(getTrainingTypeLabel(collection.trainingType) || '-')}</>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</Td>
|
||||
<Td onClick={(e) => e.stopPropagation()}>
|
||||
<Td py={2}>{collection.dataAmount || '-'}</Td>
|
||||
<Td fontSize={'xs'} py={2} color={'myGray.500'}>
|
||||
<Box>{formatTime2YMDHM(collection.createTime)}</Box>
|
||||
<Box>{formatTime2YMDHM(collection.updateTime)}</Box>
|
||||
</Td>
|
||||
<Td py={2}>
|
||||
<MyTag showDot colorSchema={collection.colorSchema as any} type={'borderFill'}>
|
||||
{t(collection.statusText)}
|
||||
</MyTag>
|
||||
</Td>
|
||||
<Td py={2} onClick={(e) => e.stopPropagation()}>
|
||||
<Switch
|
||||
isChecked={!collection.forbid}
|
||||
size={'sm'}
|
||||
onChange={(e) =>
|
||||
onUpdateCollection({
|
||||
id: collection._id,
|
||||
forbid: !e.target.checked
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Td>
|
||||
<Td py={2} onClick={(e) => e.stopPropagation()}>
|
||||
{collection.permission.hasWritePer && (
|
||||
<MyMenu
|
||||
width={100}
|
||||
@@ -360,12 +339,11 @@ const CollectionCard = () => {
|
||||
onClick: () =>
|
||||
onOpenEditTitleModal({
|
||||
defaultVal: collection.name,
|
||||
onSuccess: (newName) => {
|
||||
onUpdateCollectionName({
|
||||
collectionId: collection._id,
|
||||
onSuccess: (newName) =>
|
||||
onUpdateCollection({
|
||||
id: collection._id,
|
||||
name: newName
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
]
|
||||
|
@@ -13,12 +13,15 @@ import {
|
||||
DrawerHeader,
|
||||
DrawerOverlay,
|
||||
DrawerContent,
|
||||
useDisclosure
|
||||
useDisclosure,
|
||||
HStack,
|
||||
Switch
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
getDatasetDataList,
|
||||
delOneDatasetDataById,
|
||||
getDatasetCollectionById
|
||||
getDatasetCollectionById,
|
||||
putDatasetDataById
|
||||
} from '@/web/core/dataset/api';
|
||||
import { DeleteIcon } from '@chakra-ui/icons';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
@@ -47,6 +50,9 @@ import { useI18n } from '@/web/context/I18n';
|
||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import MyTag from '@fastgpt/web/components/common/Tag/index';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
|
||||
const DataCard = () => {
|
||||
const BoxRef = useRef<HTMLDivElement>(null);
|
||||
@@ -60,7 +66,6 @@ const DataCard = () => {
|
||||
};
|
||||
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
|
||||
|
||||
const { Loading, setIsLoading } = useLoading({ defaultLoading: true });
|
||||
const { t } = useTranslation();
|
||||
const { datasetT } = useI18n();
|
||||
const [searchText, setSearchText] = useState('');
|
||||
@@ -78,16 +83,17 @@ const DataCard = () => {
|
||||
total,
|
||||
getData,
|
||||
pageNum,
|
||||
pageSize
|
||||
pageSize,
|
||||
isLoading: isRequesting
|
||||
} = usePagination<DatasetDataListItemType>({
|
||||
api: getDatasetDataList,
|
||||
pageSize: 24,
|
||||
defaultRequest: false,
|
||||
params: {
|
||||
collectionId,
|
||||
searchText
|
||||
},
|
||||
onChange() {
|
||||
setIsLoading(false);
|
||||
if (BoxRef.current) {
|
||||
BoxRef.current.scrollTop = 0;
|
||||
}
|
||||
@@ -97,12 +103,16 @@ const DataCard = () => {
|
||||
const [editDataId, setEditDataId] = useState<string>();
|
||||
|
||||
// get first page data
|
||||
const getFirstData = useCallback(
|
||||
debounce(() => {
|
||||
useRequest2(
|
||||
async () => {
|
||||
getData(1);
|
||||
lastSearch.current = searchText;
|
||||
}, 300),
|
||||
[searchText]
|
||||
},
|
||||
{
|
||||
manual: false,
|
||||
debounceWait: 300,
|
||||
refreshDeps: [searchText]
|
||||
}
|
||||
);
|
||||
|
||||
// get file info
|
||||
@@ -182,9 +192,18 @@ const DataCard = () => {
|
||||
];
|
||||
}, [collection, datasetT, t]);
|
||||
|
||||
const { run: onUpdate, loading } = useRequest2(putDatasetDataById, {
|
||||
onSuccess() {
|
||||
getData(pageNum);
|
||||
}
|
||||
});
|
||||
|
||||
const isLoading = isRequesting || loading;
|
||||
|
||||
return (
|
||||
<Box position={'relative'} py={[1, 5]} h={'100%'}>
|
||||
<MyBox isLoading={isLoading} position={'relative'} py={[1, 5]} h={'100%'}>
|
||||
<Flex ref={BoxRef} flexDirection={'column'} h={'100%'}>
|
||||
{/* Header */}
|
||||
<Flex alignItems={'center'} px={5}>
|
||||
<IconButton
|
||||
mr={3}
|
||||
@@ -270,20 +289,10 @@ const DataCard = () => {
|
||||
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();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
{/* data */}
|
||||
<Box flex={'1 0 0'} overflow={'auto'} px={5}>
|
||||
<Grid
|
||||
gridTemplateColumns={['1fr', 'repeat(2,1fr)', 'repeat(3,1fr)', 'repeat(4,1fr)']}
|
||||
@@ -304,29 +313,58 @@ const DataCard = () => {
|
||||
borderColor: 'myGray.200',
|
||||
boxShadow: 'lg',
|
||||
bg: 'white',
|
||||
'& .footer': { h: 'auto', p: 3 }
|
||||
'& .footer': { h: 'auto', p: 3 },
|
||||
'& .forbid-switch': { display: 'flex' }
|
||||
}}
|
||||
onClick={() => {
|
||||
if (!collection) return;
|
||||
setEditDataId(item._id);
|
||||
}}
|
||||
>
|
||||
<Flex zIndex={1} alignItems={'center'} justifyContent={'space-between'}>
|
||||
<Flex zIndex={1} alignItems={'center'}>
|
||||
<MyTag type="borderFill"># {item.chunkIndex ?? '-'}</MyTag>
|
||||
|
||||
<Box
|
||||
borderWidth={'1px'}
|
||||
borderColor={'primary.200'}
|
||||
bg={'primary.50'}
|
||||
color={'primary.600'}
|
||||
px={2}
|
||||
fontSize={'sm'}
|
||||
mr={1}
|
||||
borderRadius={'md'}
|
||||
className={'textEllipsis'}
|
||||
flex={'1 0 0'}
|
||||
w="0"
|
||||
fontSize={'mini'}
|
||||
textAlign={'right'}
|
||||
>
|
||||
# {item.chunkIndex ?? '-'}
|
||||
</Box>
|
||||
<Box className={'textEllipsis'} fontSize={'xs'}>
|
||||
ID:{item._id}
|
||||
</Box>
|
||||
{/* {item.forbid ? (
|
||||
<MyTag colorSchema="gray" bg={'transparent'} px={1} showDot>
|
||||
{datasetT('Disabled')}
|
||||
</MyTag>
|
||||
) : (
|
||||
<MyTag colorSchema="green" bg={'transparent'} px={1} showDot>
|
||||
{datasetT('Enabled')}
|
||||
</MyTag>
|
||||
)}
|
||||
<HStack
|
||||
borderLeftWidth={'1.5px'}
|
||||
className="forbid-switch"
|
||||
display={['flex', 'none']}
|
||||
borderLeftColor={'myGray.200'}
|
||||
pl={1}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
h={'12px'}
|
||||
>
|
||||
<Switch
|
||||
size={'sm'}
|
||||
isChecked={!item.forbid}
|
||||
onChange={(e) => {
|
||||
e.stopPropagation();
|
||||
onUpdate({
|
||||
dataId: item._id,
|
||||
forbid: !e.target.checked
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</HStack> */}
|
||||
</Flex>
|
||||
<Box
|
||||
maxH={'135px'}
|
||||
@@ -335,13 +373,14 @@ const DataCard = () => {
|
||||
wordBreak={'break-all'}
|
||||
pt={1}
|
||||
pb={3}
|
||||
fontSize={'13px'}
|
||||
fontSize={'sm'}
|
||||
>
|
||||
<Box color={'black'} mb={1}>
|
||||
{item.q}
|
||||
</Box>
|
||||
<Box color={'myGray.700'}>{item.a}</Box>
|
||||
|
||||
{/* Mask */}
|
||||
<Flex
|
||||
className="footer"
|
||||
position={'absolute'}
|
||||
@@ -351,39 +390,43 @@ const DataCard = () => {
|
||||
right={0}
|
||||
h={'0'}
|
||||
overflow={'hidden'}
|
||||
p={0}
|
||||
bg={'linear-gradient(to top, white,white 20%, rgba(255,255,255,0) 60%)'}
|
||||
alignItems={'flex-end'}
|
||||
fontSize={'sm'}
|
||||
fontSize={'mini'}
|
||||
>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name="common/text/t" w={'14px'} mr={1} color={'myGray.500'} />
|
||||
{item.q.length + (item.a?.length || 0)}
|
||||
</Flex>
|
||||
<Box flex={1} />
|
||||
{canWrite && (
|
||||
<IconButton
|
||||
display={'flex'}
|
||||
icon={<DeleteIcon />}
|
||||
variant={'whiteDanger'}
|
||||
size={'xsSquare'}
|
||||
aria-label={'delete'}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
openConfirm(async () => {
|
||||
try {
|
||||
await delOneDatasetDataById(item._id);
|
||||
getData(pageNum);
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: getErrText(error),
|
||||
status: 'error'
|
||||
});
|
||||
}
|
||||
})();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<HStack p={0} flex={1}>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name="common/text/t" w={'0.8rem'} mr={1} color={'myGray.500'} />
|
||||
<Box>{item.q.length + (item.a?.length || 0)}</Box>
|
||||
</Flex>
|
||||
<Box flex={1}></Box>
|
||||
{/* <Box className={'textEllipsis'} flex={'1 0 0'} w="0">
|
||||
ID:{item._id}
|
||||
</Box> */}
|
||||
{canWrite && (
|
||||
<IconButton
|
||||
display={'flex'}
|
||||
icon={<DeleteIcon />}
|
||||
variant={'whiteDanger'}
|
||||
size={'xsSquare'}
|
||||
aria-label={'delete'}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
openConfirm(async () => {
|
||||
try {
|
||||
await delOneDatasetDataById(item._id);
|
||||
getData(pageNum);
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: getErrText(error),
|
||||
status: 'error'
|
||||
});
|
||||
}
|
||||
})();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</HStack>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Card>
|
||||
@@ -440,8 +483,7 @@ const DataCard = () => {
|
||||
/>
|
||||
)}
|
||||
<ConfirmModal />
|
||||
<Loading fixed={false} />
|
||||
</Box>
|
||||
</MyBox>
|
||||
);
|
||||
};
|
||||
|
||||
|
@@ -14,7 +14,7 @@ import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { getDefaultIndex } from '@fastgpt/global/core/dataset/utils';
|
||||
import { DatasetDataIndexItemType } from '@fastgpt/global/core/dataset/type';
|
||||
@@ -183,13 +183,14 @@ const InputDataModal = ({
|
||||
errorToast: t('common.error.unKnow')
|
||||
});
|
||||
// update
|
||||
const { mutate: onUpdateData, isLoading: isUpdating } = useRequest({
|
||||
mutationFn: async (e: InputDataType) => {
|
||||
if (!dataId) return e;
|
||||
|
||||
const { runAsync: onUpdateData, loading: isUpdating } = useRequest2(
|
||||
async (e: InputDataType) => {
|
||||
if (!dataId) return Promise.reject(t('common.error.unKnow'));
|
||||
|
||||
// not exactly same
|
||||
await putDatasetDataById({
|
||||
id: dataId,
|
||||
dataId,
|
||||
...e,
|
||||
indexes:
|
||||
e.indexes?.map((index) =>
|
||||
@@ -202,13 +203,14 @@ const InputDataModal = ({
|
||||
...e
|
||||
};
|
||||
},
|
||||
successToast: t('dataset.data.Update Success Tip'),
|
||||
errorToast: t('common.error.unKnow'),
|
||||
onSuccess(data) {
|
||||
onSuccess(data);
|
||||
onClose();
|
||||
{
|
||||
successToast: t('dataset.data.Update Success Tip'),
|
||||
onSuccess(data) {
|
||||
onSuccess(data);
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
// delete
|
||||
const { mutate: onDeleteData, isLoading: isDeleting } = useRequest({
|
||||
mutationFn: () => {
|
||||
@@ -224,10 +226,7 @@ const InputDataModal = ({
|
||||
errorToast: t('common.error.unKnow')
|
||||
});
|
||||
|
||||
const isLoading = useMemo(
|
||||
() => isImporting || isUpdating || isFetchingData || isDeleting,
|
||||
[isImporting, isUpdating, isFetchingData, isDeleting]
|
||||
);
|
||||
const isLoading = isFetchingData || isDeleting;
|
||||
|
||||
return (
|
||||
<MyModal isOpen={true} isCentered w={'90vw'} maxW={'1440px'} h={'90vh'}>
|
||||
@@ -370,6 +369,7 @@ const InputDataModal = ({
|
||||
>
|
||||
<Button
|
||||
isDisabled={!collection.permission.hasWritePer}
|
||||
isLoading={isImporting || isUpdating}
|
||||
// @ts-ignore
|
||||
onClick={handleSubmit(dataId ? onUpdateData : sureImportData)}
|
||||
>
|
||||
|
@@ -47,7 +47,7 @@ const Slider = ({ currentTab }: { currentTab: TabEnum }) => {
|
||||
(tab: TabEnum) => {
|
||||
router.replace({
|
||||
query: {
|
||||
...query,
|
||||
datasetId: query.datasetId,
|
||||
currentTab: tab
|
||||
}
|
||||
});
|
||||
|
@@ -159,7 +159,7 @@ const Test = ({ datasetId }: { datasetId: string }) => {
|
||||
>
|
||||
{/* header */}
|
||||
<Flex alignItems={'center'} justifyContent={'space-between'}>
|
||||
<MySelect
|
||||
<MySelect<'text' | 'file'>
|
||||
size={'sm'}
|
||||
w={'150px'}
|
||||
list={[
|
||||
|
Reference in New Issue
Block a user