mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-19 10:07:24 +00:00
@@ -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
|
||||||
|
@@ -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>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -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>
|
||||||
|
Reference in New Issue
Block a user