style: 知识库新列表 (#2448)

* style: 知识库新列表

* i18n adjust

* fix:  i18n
This commit is contained in:
papapatrick
2024-08-20 17:29:41 +08:00
committed by GitHub
parent 2d0e6bd085
commit 40b1d22d9d
12 changed files with 215 additions and 111 deletions

View File

@@ -1,4 +1,4 @@
import React, { useCallback } from 'react';
import React, { useCallback, useMemo } from 'react';
import { Box, Flex, Button, ModalFooter, ModalBody, Input } from '@chakra-ui/react';
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
import { useForm } from 'react-hook-form';
@@ -14,29 +14,56 @@ import MyModal from '@fastgpt/web/components/common/MyModal';
import { postCreateDataset } from '@/web/core/dataset/api';
import type { CreateDatasetParams } from '@/global/core/dataset/api.d';
import { useTranslation } from 'next-i18next';
import MyRadio from '@/components/common/MyRadio';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
import AIModelSelector from '@/components/Select/AIModelSelector';
import { useI18n } from '@/web/context/I18n';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: string }) => {
export type CreateDatasetType =
| DatasetTypeEnum.dataset
| DatasetTypeEnum.externalFile
| DatasetTypeEnum.websiteDataset;
const CreateModal = ({
onClose,
parentId,
type
}: {
onClose: () => void;
parentId?: string;
type: CreateDatasetType;
}) => {
const { t } = useTranslation();
const { datasetT } = useI18n();
const { toast } = useToast();
const router = useRouter();
const { feConfigs, vectorModelList, datasetModelList } = useSystemStore();
const { vectorModelList, datasetModelList } = useSystemStore();
const { isPc } = useSystem();
const databaseNameMap = useMemo(() => {
return {
[DatasetTypeEnum.dataset]: t('dataset:common_dataset'),
[DatasetTypeEnum.externalFile]: t('dataset:external_file'),
[DatasetTypeEnum.websiteDataset]: t('dataset:website_dataset')
};
}, [t]);
const iconMap = useMemo(() => {
return {
[DatasetTypeEnum.dataset]: 'core/dataset/commonDatasetColor',
[DatasetTypeEnum.externalFile]: 'core/dataset/externalDatasetColor',
[DatasetTypeEnum.websiteDataset]: 'core/dataset/websiteDatasetColor'
};
}, []);
const filterNotHiddenVectorModelList = vectorModelList.filter((item) => !item.hidden);
const { register, setValue, handleSubmit, watch } = useForm<CreateDatasetParams>({
defaultValues: {
parentId,
type: DatasetTypeEnum.dataset,
avatar: '/icon/logo.svg',
type: type || DatasetTypeEnum.dataset,
avatar: iconMap[type] || 'core/dataset/commonDatasetColor',
name: '',
intro: '',
vectorModel: filterNotHiddenVectorModelList[0].model,
@@ -44,7 +71,6 @@ const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: st
}
});
const avatar = watch('avatar');
const datasetType = watch('type');
const vectorModel = watch('vectorModel');
const agentModel = watch('agentModel');
@@ -88,63 +114,16 @@ const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: st
}
});
const onSelectDatasetType = useCallback(
(e: DatasetTypeEnum) => {
if (
!feConfigs?.isPlus &&
(e === DatasetTypeEnum.websiteDataset || e === DatasetTypeEnum.externalFile)
) {
return toast({
status: 'warning',
title: t('common:common.system.Commercial version function')
});
}
setValue('type', e);
},
[feConfigs?.isPlus, setValue, t, toast]
);
return (
<MyModal
iconSrc="/imgs/workflow/db.png"
title={t('common:core.dataset.Create dataset')}
iconSrc={iconMap[type]}
title={t('common:core.dataset.Create dataset', { name: databaseNameMap[type] })}
isOpen
onClose={onClose}
isCentered={!isPc}
w={'450px'}
>
<ModalBody py={2}>
<>
<Box mb={1} color={'myGray.900'}>
{t('common:core.dataset.Dataset Type')}
</Box>
<MyRadio
gridGap={2}
gridTemplateColumns={'repeat(1,1fr)'}
list={[
{
title: datasetT('common_dataset'),
value: DatasetTypeEnum.dataset,
icon: 'core/dataset/commonDataset',
desc: datasetT('common_dataset_desc')
},
{
title: datasetT('website_dataset'),
value: DatasetTypeEnum.websiteDataset,
icon: 'core/dataset/websiteDataset',
desc: datasetT('website_dataset_desc')
},
{
title: datasetT('external_file'),
value: DatasetTypeEnum.externalFile,
icon: 'core/dataset/externalDataset',
desc: datasetT('external_file_dataset_desc')
}
]}
value={datasetType}
onChange={onSelectDatasetType}
/>
</>
<Box mt={5}>
<Box color={'myGray.900'}>{t('common:common.Set Name')}</Box>
<Flex mt={1} alignItems={'center'}>

View File

@@ -49,7 +49,8 @@ function List() {
setEditedDataset,
onDelDataset,
onUpdateDataset,
myDatasets
myDatasets,
folderDetail
} = useContextSelector(DatasetsContext, (v) => v);
const [editPerDatasetIndex, setEditPerDatasetIndex] = useState<number>();
const [loadingDatasetId, setLoadingDatasetId] = useState<string>();
@@ -142,11 +143,14 @@ function List() {
<>
{formatDatasets.length > 0 && (
<Grid
flexGrow={1}
py={5}
gridTemplateColumns={['1fr', 'repeat(2,1fr)', 'repeat(3,1fr)', 'repeat(4,1fr)']}
py={4}
gridTemplateColumns={
folderDetail
? ['1fr', 'repeat(2,1fr)', 'repeat(2,1fr)', 'repeat(3,1fr)']
: ['1fr', 'repeat(2,1fr)', 'repeat(3,1fr)', 'repeat(3,1fr)', 'repeat(4,1fr)']
}
gridGap={5}
userSelect={'none'}
alignItems={'stretch'}
>
{formatDatasets.map((dataset, index) => (
<MyTooltip
@@ -165,14 +169,18 @@ function List() {
isLoading={loadingDatasetId === dataset._id}
display={'flex'}
flexDirection={'column'}
lineHeight={1.5}
h="100%"
py={3}
px={5}
cursor={'pointer'}
borderWidth={1.5}
border={'base'}
boxShadow={'2'}
bg={'white'}
borderRadius={'md'}
minH={'130px'}
borderRadius={'lg'}
position={'relative'}
minH={'150px'}
{...getBoxProps({
dataId: dataset._id,
isFolder: dataset.type === DatasetTypeEnum.folder

View File

@@ -37,6 +37,8 @@ export type DatasetContextType = {
setEditedDataset: (data?: EditResourceInfoFormType) => void;
onDelDataset: (id: string) => Promise<void>;
onUpdateDataset: (data: DatasetUpdateBody) => Promise<void>;
searchKey: string;
setSearchKey: React.Dispatch<React.SetStateAction<string>>;
};
export const DatasetsContext = createContext<DatasetContextType>({
@@ -57,7 +59,11 @@ export const DatasetsContext = createContext<DatasetContextType>({
onUpdateDataset: function (_data: DatasetUpdateBody): Promise<void> {
throw new Error('Function not implemented.');
},
myDatasets: []
myDatasets: [],
searchKey: '',
setSearchKey: function (value: React.SetStateAction<string>): void {
throw new Error('Function not implemented.');
}
});
function DatasetContextProvider({ children }: { children: React.ReactNode }) {
@@ -65,7 +71,7 @@ function DatasetContextProvider({ children }: { children: React.ReactNode }) {
const { commonT } = useI18n();
const { t } = useTranslation();
const [moveDatasetId, setMoveDatasetId] = useState<string>();
const [searchKey, setSearchKey] = useState('');
const { parentId = null } = router.query as { parentId?: string | null };
const {
@@ -75,11 +81,12 @@ function DatasetContextProvider({ children }: { children: React.ReactNode }) {
} = useRequest2(
() =>
getDatasets({
searchKey,
parentId
}),
{
manual: false,
refreshDeps: [parentId]
refreshDeps: [parentId, searchKey]
}
);
@@ -145,7 +152,9 @@ function DatasetContextProvider({ children }: { children: React.ReactNode }) {
onDelDataset,
onUpdateDataset,
myDatasets,
loadMyDatasets
loadMyDatasets,
searchKey,
setSearchKey
};
return (

View File

@@ -1,5 +1,14 @@
import React, { useState } from 'react';
import { Box, Flex, Image, Button, useDisclosure } from '@chakra-ui/react';
import React, { useCallback, useMemo, useState } from 'react';
import {
Box,
Flex,
Image,
Button,
useDisclosure,
InputGroup,
InputLeftElement,
Input
} from '@chakra-ui/react';
import { useRouter } from 'next/router';
import PageContainer from '@/components/PageContainer';
import { useTranslation } from 'next-i18next';
@@ -28,6 +37,10 @@ import {
getCollaboratorList
} from '@/web/core/dataset/api/collaborator';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { CreateDatasetType } from './component/CreateModal';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { useToast } from '@fastgpt/web/hooks/useToast';
import MyBox from '@fastgpt/web/components/common/MyBox';
const EditFolderModal = dynamic(
() => import('@fastgpt/web/components/common/MyModal/EditFolderModal')
@@ -52,32 +65,62 @@ const Dataset = () => {
setEditedDataset,
setMoveDatasetId,
onDelDataset,
onUpdateDataset
onUpdateDataset,
searchKey,
setSearchKey
} = useContextSelector(DatasetsContext, (v) => v);
const { userInfo } = useUserStore();
const { toast } = useToast();
const [editFolderData, setEditFolderData] = useState<EditFolderFormType>();
const [createDatasetType, setCreateDatasetType] = useState<CreateDatasetType>();
const {
isOpen: isOpenCreateModal,
onOpen: onOpenCreateModal,
onClose: onCloseCreateModal
} = useDisclosure();
const onSelectDatasetType = useCallback(
(e: CreateDatasetType) => {
if (
!feConfigs?.isPlus &&
(e === DatasetTypeEnum.websiteDataset || e === DatasetTypeEnum.externalFile)
) {
return toast({
status: 'warning',
title: t('common:common.system.Commercial version function')
});
}
setCreateDatasetType(e);
},
[t, toast]
);
const RenderSearchInput = useMemo(
() => (
<InputGroup maxW={['auto', '250px']} pr={4}>
<InputLeftElement h={'full'} alignItems={'center'} display={'flex'}>
<MyIcon name={'common/searchLight'} w={'1rem'} />
</InputLeftElement>
<Input
value={searchKey}
onChange={(e) => setSearchKey(e.target.value)}
placeholder={t('common:dataset.dataset_name')}
maxLength={30}
bg={'white'}
/>
</InputGroup>
),
[searchKey, setSearchKey, t]
);
return (
<PageContainer
<MyBox
isLoading={myDatasets.length === 0 && isFetchingDatasets}
insertProps={{ px: folderDetail ? [4, 6] : [5, '10'] }}
flexDirection={'column'}
h={'100%'}
>
<Flex pt={[4, 6]}>
<Flex pt={[4, 6]} pl={3} pr={10}>
<Flex flexGrow={1} flexDirection="column">
<Flex alignItems={'flex-start'} justifyContent={'space-between'}>
<ParentPaths
paths={paths}
FirstPathDom={
<Flex flex={1} alignItems={'center'}>
<Image src={'/imgs/workflow/db.png'} alt={''} mr={2} h={'24px'} />
<Box className="textlg" letterSpacing={1} fontSize={'24px'} fontWeight={'bold'}>
<Box pl={2} letterSpacing={1} fontSize={'1.25rem'} fontWeight={'bold'}>
{t('common:core.dataset.My Dataset')}
</Box>
</Flex>
@@ -90,10 +133,14 @@ const Dataset = () => {
});
}}
/>
{isPc && RenderSearchInput}
{userInfo?.team?.permission.hasWritePer && (
<MyMenu
offset={[-30, 5]}
width={120}
iconSize="2rem"
Button={
<Button variant={'primary'} px="0">
<Flex alignItems={'center'} px={'20px'}>
@@ -106,22 +153,31 @@ const Dataset = () => {
{
children: [
{
label: (
<Flex>
<MyIcon name={FolderIcon} w={'20px'} mr={1} />
{t('common:Folder')}
</Flex>
),
onClick: () => setEditFolderData({})
icon: 'core/dataset/commonDatasetColor',
label: t('dataset:common_dataset'),
description: t('dataset:common_dataset_desc'),
onClick: () => setCreateDatasetType(DatasetTypeEnum.dataset)
},
{
label: (
<Flex>
<Image src={'/imgs/workflow/db.png'} alt={''} w={'20px'} mr={1} />
{t('common:core.dataset.Dataset')}
</Flex>
),
onClick: onOpenCreateModal
icon: 'core/dataset/websiteDatasetColor',
label: t('dataset:website_dataset'),
description: t('dataset:website_dataset_desc'),
onClick: () => setCreateDatasetType(DatasetTypeEnum.websiteDataset)
},
{
icon: 'core/dataset/externalDatasetColor',
label: t('dataset:external_file'),
description: t('dataset:external_file_dataset_desc'),
onClick: () => setCreateDatasetType(DatasetTypeEnum.externalFile)
}
]
},
{
children: [
{
icon: FolderIcon,
label: t('common:Folder'),
onClick: () => setEditFolderData({})
}
]
}
@@ -129,6 +185,9 @@ const Dataset = () => {
/>
)}
</Flex>
{!isPc && <Box mt={2}>{RenderSearchInput}</Box>}
<Box flexGrow={1}>
<List />
</Box>
@@ -231,13 +290,16 @@ const Dataset = () => {
}}
/>
)}
{isOpenCreateModal && (
<CreateModal onClose={onCloseCreateModal} parentId={parentId || undefined} />
{createDatasetType && (
<CreateModal
type={createDatasetType}
onClose={() => setCreateDatasetType(undefined)}
parentId={parentId || undefined}
/>
)}
</PageContainer>
</MyBox>
);
};
export async function getServerSideProps(content: any) {
return {
props: {