fix: tags manage (#2556)

* fix: tags manage

* fix infinite invoke
This commit is contained in:
heheer
2024-08-29 12:04:45 +08:00
committed by GitHub
parent 6c16fa9166
commit 0632dfed80
3 changed files with 74 additions and 45 deletions

View File

@@ -14,6 +14,17 @@ import {
import MyBox from '../components/common/MyBox'; import MyBox from '../components/common/MyBox';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
export type ScrollListType = ({
children,
EmptyChildren,
isLoading,
...props
}: {
children: React.ReactNode;
EmptyChildren?: React.ReactNode;
isLoading?: boolean;
} & BoxProps) => React.JSX.Element;
export function useScrollPagination< export function useScrollPagination<
TParams extends PaginationProps, TParams extends PaginationProps,
TData extends PaginationResponse TData extends PaginationResponse

View File

@@ -1,5 +1,5 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Input, Button, Flex, Box, Checkbox } from '@chakra-ui/react'; import { Input, Button, Flex, Box, Checkbox, BoxProps } from '@chakra-ui/react';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
@@ -19,10 +19,10 @@ import {
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
import MyInput from '@/components/MyInput'; import MyInput from '@/components/MyInput';
import { DatasetTagType } from '@fastgpt/global/core/dataset/type'; import { DatasetTagType } from '@fastgpt/global/core/dataset/type';
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination'; import { ScrollListType, useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
import EmptyTip from '@fastgpt/web/components/common/EmptyTip'; import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm'; import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
import MyBox from '@fastgpt/web/components/common/MyBox'; import { DatasetCollectionsListItemType } from '@/global/core/dataset/type';
const TagManageModal = ({ onClose }: { onClose: () => void }) => { const TagManageModal = ({ onClose }: { onClose: () => void }) => {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -39,6 +39,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
>(undefined); >(undefined);
const [newTag, setNewTag] = useState<string | undefined>(undefined); const [newTag, setNewTag] = useState<string | undefined>(undefined);
const [searchText, setSearchText] = useState('');
const [currentEditTagContent, setCurrentEditTagContent] = useState<string | undefined>(undefined); const [currentEditTagContent, setCurrentEditTagContent] = useState<string | undefined>(undefined);
const [currentEditTag, setCurrentEditTag] = useState<DatasetTagType | undefined>(undefined); const [currentEditTag, setCurrentEditTag] = useState<DatasetTagType | undefined>(undefined);
@@ -134,6 +135,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
} }
); );
// Tags list
const { const {
list, list,
ScrollList, ScrollList,
@@ -154,11 +156,38 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
} }
}); });
// Collections list
const {
list: collectionsList,
ScrollList: ScrollListCollections,
isLoading: collectionsListLoading
} = useScrollPagination(getScrollCollectionList, {
refreshDeps: [searchText],
debounceWait: 300,
itemHeight: 37,
overscan: 10,
pageSize: 30,
defaultParams: {
datasetId: datasetDetail._id,
searchText
}
});
const { data: tagUsages } = useRequest2(() => getTagUsage(datasetDetail._id), { const { data: tagUsages } = useRequest2(() => getTagUsage(datasetDetail._id), {
manual: false, manual: false,
refreshDeps: [collections] refreshDeps: [collections]
}); });
const isLoading =
isRequesting ||
isCreateCollectionTagLoading ||
isDeleteCollectionTagLoading ||
isUpdateCollectionTagLoading ||
isSaveCollectionTagLoading ||
collectionsListLoading;
return ( return (
<MyModal <MyModal
isOpen isOpen
@@ -167,14 +196,8 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
title={t('dataset:tag.manage')} title={t('dataset:tag.manage')}
w={'580px'} w={'580px'}
h={'600px'} h={'600px'}
isLoading={
isRequesting ||
isCreateCollectionTagLoading ||
isDeleteCollectionTagLoading ||
isUpdateCollectionTagLoading ||
isSaveCollectionTagLoading
}
closeOnOverlayClick={false} closeOnOverlayClick={false}
isLoading={isLoading}
> >
{currentAddTag === undefined ? ( {currentAddTag === undefined ? (
<> <>
@@ -200,14 +223,9 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
{t('dataset:tag.Add New')} {t('dataset:tag.Add New')}
</Button> </Button>
</Flex> </Flex>
<ScrollList <Flex px={8} w={'full'}>
px={8}
flex={'1 0 0'}
fontSize={'sm'}
EmptyChildren={<EmptyTip text={t('dataset:dataset.no_tags')} />}
>
{newTag !== undefined && ( {newTag !== undefined && (
<Flex p={2} borderBottom={'1px solid #E8EBF0'}> <Flex py={3} px={2} w={'full'} borderBottom={'1px solid #E8EBF0'}>
<Input <Input
placeholder={t('dataset:tag.Add_new_tag')} placeholder={t('dataset:tag.Add_new_tag')}
value={newTag} value={newTag}
@@ -223,6 +241,13 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
/> />
</Flex> </Flex>
)} )}
</Flex>
<ScrollList
px={8}
flex={'1 0 0'}
fontSize={'sm'}
EmptyChildren={<EmptyTip text={t('dataset:dataset.no_tags')} />}
>
{list.map((listItem) => { {list.map((listItem) => {
const item = listItem.data; const item = listItem.data;
const tagUsage = tagUsages?.find((tagUsage) => tagUsage.tagId === item._id); const tagUsage = tagUsages?.find((tagUsage) => tagUsage.tagId === item._id);
@@ -351,6 +376,9 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
currentAddTag={currentAddTag} currentAddTag={currentAddTag}
setCurrentAddTag={setCurrentAddTag} setCurrentAddTag={setCurrentAddTag}
onSaveCollectionTag={onSaveCollectionTag} onSaveCollectionTag={onSaveCollectionTag}
setSearchText={setSearchText}
collectionsList={collectionsList}
ScrollListCollections={ScrollListCollections}
/> />
)} )}
</MyModal> </MyModal>
@@ -362,7 +390,10 @@ export default TagManageModal;
const AddTagToCollections = ({ const AddTagToCollections = ({
currentAddTag, currentAddTag,
setCurrentAddTag, setCurrentAddTag,
onSaveCollectionTag onSaveCollectionTag,
setSearchText,
collectionsList,
ScrollListCollections
}: { }: {
currentAddTag: DatasetTagType & { collections: string[] }; currentAddTag: DatasetTagType & { collections: string[] };
setCurrentAddTag: (tag: (DatasetTagType & { collections: string[] }) | undefined) => void; setCurrentAddTag: (tag: (DatasetTagType & { collections: string[] }) | undefined) => void;
@@ -375,33 +406,19 @@ const AddTagToCollections = ({
originCollectionIds: string[]; originCollectionIds: string[];
collectionIds: string[]; collectionIds: string[];
}) => void; }) => void;
setSearchText: (text: string) => void;
collectionsList: {
index: number;
data: DatasetCollectionsListItemType;
}[];
ScrollListCollections: ScrollListType;
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
const [selectedCollections, setSelectedCollections] = useState<string[]>( const [selectedCollections, setSelectedCollections] = useState<string[]>(
currentAddTag.collections currentAddTag.collections
); );
const [originCollections, setOriginCollections] = useState<string[]>(currentAddTag.collections);
const [searchText, setSearchText] = useState('');
const {
list: collectionsList,
ScrollList: ScrollListCollections,
isLoading: isCollectionLoading
} = useScrollPagination(getScrollCollectionList, {
refreshDeps: [searchText],
debounceWait: 300,
itemHeight: 29,
overscan: 10,
pageSize: 30,
defaultParams: {
datasetId: datasetDetail._id,
searchText
}
});
const formatCollections = useMemo( const formatCollections = useMemo(
() => () =>
@@ -419,7 +436,7 @@ const AddTagToCollections = ({
); );
return ( return (
<MyBox flex={'1 0 0'} isLoading={isCollectionLoading}> <>
<Flex alignItems={'center'} pb={2} mx={8} pt={6} borderBottom={'1px solid #E8EBF0'}> <Flex alignItems={'center'} pb={2} mx={8} pt={6} borderBottom={'1px solid #E8EBF0'}>
<MyIcon <MyIcon
name="common/backFill" name="common/backFill"
@@ -465,9 +482,10 @@ const AddTagToCollections = ({
onClick={() => { onClick={() => {
onSaveCollectionTag({ onSaveCollectionTag({
tag: currentAddTag._id, tag: currentAddTag._id,
originCollectionIds: currentAddTag.collections, originCollectionIds: originCollections,
collectionIds: selectedCollections collectionIds: selectedCollections
}); });
setOriginCollections(selectedCollections);
}} }}
> >
{t('common:common.Save')} {t('common:common.Save')}
@@ -530,6 +548,6 @@ const AddTagToCollections = ({
); );
})} })}
</ScrollListCollections> </ScrollListCollections>
</MyBox> </>
); );
}; };

View File

@@ -55,7 +55,8 @@ const TagsPopOver = ({
useEffect(() => { useEffect(() => {
if (!isFocusInput) return; if (!isFocusInput) return;
loadDatasetTags({ id: datasetDetail._id, searchKey: searchTag }); loadDatasetTags({ id: datasetDetail._id, searchKey: searchTag });
}, [datasetDetail._id, isFocusInput, loadDatasetTags, searchTag]); // eslint-disable-next-line react-hooks/exhaustive-deps
}, [datasetDetail._id, isFocusInput, searchTag]);
const [visibleTags, setVisibleTags] = useState<DatasetTagType[]>(tagList); const [visibleTags, setVisibleTags] = useState<DatasetTagType[]>(tagList);
const [overflowTags, setOverflowTags] = useState<DatasetTagType[]>([]); const [overflowTags, setOverflowTags] = useState<DatasetTagType[]>([]);
@@ -214,10 +215,9 @@ const TagsPopOver = ({
borderRadius={'xs'} borderRadius={'xs'}
onClick={() => { onClick={() => {
onCreateCollectionTag(searchTag); onCreateCollectionTag(searchTag);
// setCheckedTags([...checkedTags, item]);
}} }}
> >
<MyIcon name={'common/addLight'} w={'sm'} /> <MyIcon name={'common/addLight'} w={'16px'} />
<Box ml={1} py={1}> <Box ml={1} py={1}>
{t('dataset:tag.add') + ` "${searchTag}"`} {t('dataset:tag.add') + ` "${searchTag}"`}
</Box> </Box>