4.6.3-website dataset (#532)

This commit is contained in:
Archer
2023-12-03 20:45:57 +08:00
committed by GitHub
parent b916183848
commit a9ae270335
122 changed files with 3793 additions and 1360 deletions

View File

@@ -1,14 +1,5 @@
import React, { useCallback, useState, useRef } from 'react';
import {
Box,
Flex,
Button,
ModalHeader,
ModalFooter,
ModalBody,
Input,
Image
} from '@chakra-ui/react';
import React, { useCallback, useState } 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';
import { compressImgFileAndUpload } from '@/web/common/file/controller';
@@ -23,10 +14,11 @@ import MyModal from '@/components/MyModal';
import { postCreateDataset } from '@/web/core/dataset/api';
import type { CreateDatasetParams } from '@/global/core/dataset/api.d';
import MySelect from '@/components/Select';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import { vectorModelList, qaModelList } from '@/web/common/system/staticData';
import Tag from '@/components/Tag';
import { useTranslation } from 'next-i18next';
import MyRadio from '@/components/common/MyRadio';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constant';
import { feConfigs } from '@/web/common/system/staticData';
const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: string }) => {
const { t } = useTranslation();
@@ -36,16 +28,15 @@ const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: st
const { isPc } = useSystemStore();
const { register, setValue, getValues, handleSubmit } = useForm<CreateDatasetParams>({
defaultValues: {
parentId,
type: DatasetTypeEnum.dataset,
avatar: '/icon/logo.svg',
name: '',
tags: '',
intro: '',
vectorModel: vectorModelList[0].model,
agentModel: qaModelList[0].model,
type: 'dataset',
parentId
agentModel: qaModelList[0].model
}
});
const InputRef = useRef<HTMLInputElement>(null);
const { File, onOpen: onOpenSelectFile } = useSelectFile({
fileType: '.jpg,.png',
@@ -59,8 +50,8 @@ const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: st
try {
const src = await compressImgFileAndUpload({
file,
maxW: 100,
maxH: 100
maxW: 300,
maxH: 300
});
setValue('avatar', src);
setRefresh((state) => !state);
@@ -97,32 +88,67 @@ const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: st
w={'450px'}
>
<ModalBody>
<Box color={'myGray.800'} fontWeight={'bold'}>
</Box>
<Flex mt={3} alignItems={'center'}>
<MyTooltip label={'点击设置头像'}>
<Avatar
flexShrink={0}
src={getValues('avatar')}
w={['28px', '32px']}
h={['28px', '32px']}
cursor={'pointer'}
borderRadius={'md'}
onClick={onOpenSelectFile}
/>
</MyTooltip>
<Input
ml={3}
flex={1}
autoFocus
bg={'myWhite.600'}
maxLength={30}
{...register('name', {
required: '知识库名称不能为空~'
})}
<>
<Box mb={1} color={'myGray.800'} fontWeight={'bold'}>
{t('core.dataset.Dataset Type')}
</Box>
<MyRadio
gridGap={2}
gridTemplateColumns={'repeat(1,1fr)'}
list={[
{
title: t('core.dataset.Common Dataset'),
value: DatasetTypeEnum.dataset,
icon: 'core/dataset/commonDataset',
desc: t('core.dataset.Common Dataset Desc')
},
...(feConfigs.isPlus
? [
{
title: t('core.dataset.Website Dataset'),
value: DatasetTypeEnum.websiteDataset,
icon: 'core/dataset/websiteDataset',
desc: t('core.dataset.Website Dataset Desc')
}
]
: [])
]}
value={getValues('type')}
onChange={(e) => {
setValue('type', e as `${DatasetTypeEnum}`);
setRefresh(!refresh);
}}
/>
</Flex>
</>
<Box mt={5}>
<Box color={'myGray.800'} fontWeight={'bold'}>
</Box>
<Flex mt={1} alignItems={'center'}>
<MyTooltip label={'点击设置头像'}>
<Avatar
flexShrink={0}
src={getValues('avatar')}
w={['28px', '32px']}
h={['28px', '32px']}
cursor={'pointer'}
borderRadius={'md'}
onClick={onOpenSelectFile}
/>
</MyTooltip>
<Input
ml={3}
flex={1}
autoFocus
bg={'myWhite.600'}
placeholder={t('common.Name')}
maxLength={30}
{...register('name', {
required: '知识库名称不能为空~'
})}
/>
</Flex>
</Box>
<Flex mt={6} alignItems={'center'}>
<Box flex={'0 0 100px'}></Box>
<Box flex={1}>
@@ -157,42 +183,14 @@ const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: st
/>
</Box>
</Flex>
<Flex mt={6} alignItems={'center'} w={'100%'}>
<Box flex={'0 0 100px'}>
<MyTooltip label={'用空格隔开多个标签,便于搜索'} forceShow>
<QuestionOutlineIcon ml={1} />
</MyTooltip>
</Box>
<Input
flex={1}
ref={InputRef}
placeholder={'标签,使用空格分割。'}
maxLength={30}
onChange={(e) => {
setValue('tags', e.target.value);
setRefresh(!refresh);
}}
/>
</Flex>
<Flex mt={2} flexWrap={'wrap'}>
{getValues('tags')
.split(' ')
.filter(Boolean)
.map((item, i) => (
<Tag mr={2} mb={2} key={i} whiteSpace={'nowrap'}>
{item}
</Tag>
))}
</Flex>
</ModalBody>
<ModalFooter>
<Button variant={'base'} mr={3} onClick={onClose}>
{t('common.Close')}
</Button>
<Button isLoading={creating} onClick={handleSubmit((data) => onclickCreate(data))}>
{t('common.Confirm Create')}
</Button>
</ModalFooter>

View File

@@ -7,8 +7,7 @@ import {
useDisclosure,
Card,
MenuButton,
Image,
Link
Image
} from '@chakra-ui/react';
import { useRouter } from 'next/router';
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
@@ -28,8 +27,11 @@ import Avatar from '@/components/Avatar';
import MyIcon from '@/components/Icon';
import { serviceSideProps } from '@/web/common/utils/i18n';
import dynamic from 'next/dynamic';
import { FolderAvatarSrc, DatasetTypeEnum } from '@fastgpt/global/core/dataset/constant';
import Tag from '@/components/Tag';
import {
FolderAvatarSrc,
DatasetTypeEnum,
DatasetTypeMap
} from '@fastgpt/global/core/dataset/constant';
import MyMenu from '@/components/MyMenu';
import { useRequest } from '@/web/common/hooks/useRequest';
import { useSystemStore } from '@/web/common/system/useSystemStore';
@@ -55,12 +57,12 @@ const Kb = () => {
const DeleteTipsMap = useRef({
[DatasetTypeEnum.folder]: t('dataset.deleteFolderTips'),
[DatasetTypeEnum.dataset]: t('dataset.deleteDatasetTips')
[DatasetTypeEnum.dataset]: t('dataset.deleteDatasetTips'),
[DatasetTypeEnum.websiteDataset]: t('core.dataset.Delete Website Tips')
});
const { openConfirm, ConfirmModal } = useConfirm({
title: t('common.Delete Warning'),
content: ''
type: 'delete'
});
const { myDatasets, loadDatasets, setDatasets, updateDataset } = useDatasetStore();
const { onOpenModal: onOpenTitleModal, EditModal: EditTitleModal } = useEditTitle({
@@ -110,14 +112,26 @@ const Kb = () => {
errorToast: t('dataset.Export Dataset Limit Error')
});
const { data, refetch } = useQuery(['loadDataset', parentId], () => {
const { data, refetch, isFetching } = useQuery(['loadDataset', parentId], () => {
return Promise.all([loadDatasets(parentId), getDatasetPaths(parentId)]);
});
const paths = data?.[1] || [];
const formatDatasets = useMemo(
() =>
myDatasets.map((item) => {
return {
...item,
label: DatasetTypeMap[item.type]?.label,
icon: DatasetTypeMap[item.type]?.icon
};
}),
[myDatasets]
);
return (
<PageContainer>
<PageContainer isLoading={isFetching}>
<Flex pt={3} px={5} alignItems={'center'}>
{/* url path */}
<ParentPaths
@@ -179,7 +193,7 @@ const Kb = () => {
child: (
<Flex>
<Image src={'/imgs/module/db.png'} alt={''} w={'20px'} mr={1} />
{t('Dataset')}
{t('core.dataset.Dataset')}
</Flex>
),
onClick: onOpenCreateModal
@@ -194,15 +208,15 @@ const Kb = () => {
gridGap={5}
userSelect={'none'}
>
{myDatasets.map((dataset) => (
{formatDatasets.map((dataset) => (
<Card
display={'flex'}
flexDirection={'column'}
key={dataset._id}
py={4}
py={3}
px={5}
cursor={'pointer'}
h={'130px'}
minH={'130px'}
border={theme.borders.md}
boxShadow={'none'}
position={'relative'}
@@ -250,7 +264,7 @@ const Kb = () => {
parentId: dataset._id
}
});
} else if (dataset.type === DatasetTypeEnum.dataset) {
} else {
router.push({
pathname: '/dataset/detail',
query: {
@@ -388,27 +402,22 @@ const Kb = () => {
{dataset.name}
</Box>
</Flex>
<Box flex={'1 0 0'} overflow={'hidden'} pt={2}>
<Flex>
{dataset.tags.filter(Boolean).map((tag, i) => (
<Tag key={i} mr={2} mb={2}>
{tag}
</Tag>
))}
</Flex>
<Box
flex={1}
className={'textEllipsis3'}
py={1}
wordBreak={'break-all'}
fontSize={'sm'}
color={'myGray.500'}
>
{dataset.intro || t('core.dataset.Intro Placeholder')}
</Box>
<Flex alignItems={'center'} fontSize={'sm'}>
<Box flex={1}>
<PermissionIconText permission={dataset.permission} color={'myGray.600'} />
</Box>
{dataset.type === DatasetTypeEnum.folder ? (
<Box color={'myGray.500'}>{t('Folder')}</Box>
) : (
<>
<MyIcon mr={1} name="kbTest" w={'12px'} />
<Box color={'myGray.500'}>{dataset.vectorModel.name}</Box>
</>
)}
<MyIcon mr={1} name={dataset.icon as any} w={'12px'} />
<Box color={'myGray.500'}>{t(dataset.label)}</Box>
</Flex>
</Card>
))}
@@ -417,7 +426,7 @@ const Kb = () => {
<Flex mt={'35vh'} flexDirection={'column'} alignItems={'center'}>
<MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
<Box mt={2} color={'myGray.500'}>
{t('core.dataset.Empty Dataset Tips')}
</Box>
</Flex>
)}
@@ -429,27 +438,19 @@ const Kb = () => {
onClose={() => setEditFolderData(undefined)}
editCallback={async (name) => {
try {
if (editFolderData.id) {
await putDatasetById({
id: editFolderData.id,
name
});
} else {
await postCreateDataset({
parentId,
name,
type: DatasetTypeEnum.folder,
avatar: FolderAvatarSrc,
tags: ''
});
}
await postCreateDataset({
parentId,
name,
type: DatasetTypeEnum.folder,
avatar: FolderAvatarSrc,
intro: ''
});
refetch();
} catch (error) {
return Promise.reject(error);
}
}}
isEdit={!!editFolderData.id}
name={editFolderData.name}
isEdit={false}
/>
)}
{!!moveDataId && (