mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-28 09:03:53 +00:00
style: dataset detail page style refactor (#2501)
* style: dataset detail page style refactor * remove px * remove py px px * change shadow * style: 2期联调结束 * 优化部分代码
This commit is contained in:
@@ -85,7 +85,7 @@ const EditResourceModal = ({
|
||||
w={'2rem'}
|
||||
h={'2rem'}
|
||||
cursor={'pointer'}
|
||||
borderRadius={'md'}
|
||||
borderRadius={'sm'}
|
||||
onClick={onOpenSelectFile}
|
||||
/>
|
||||
</MyTooltip>
|
||||
|
@@ -15,9 +15,10 @@ const DatasetTypeTag = ({ type, ...props }: { type: `${DatasetTypeEnum}` } & Fle
|
||||
bg={'myGray.100'}
|
||||
borderWidth={'1px'}
|
||||
borderColor={'myGray.200'}
|
||||
px={4}
|
||||
py={'6px'}
|
||||
borderRadius={'md'}
|
||||
px={3}
|
||||
py={1.5}
|
||||
h={'1.75rem'}
|
||||
borderRadius={'sm'}
|
||||
fontSize={'xs'}
|
||||
alignItems={'center'}
|
||||
{...props}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Box, BoxProps } from '@chakra-ui/react';
|
||||
import { Box, BoxProps, ButtonProps } from '@chakra-ui/react';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
import React from 'react';
|
||||
import type { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||
@@ -20,6 +20,7 @@ type Props = Omit<BoxProps, 'onChange'> & {
|
||||
writePer?: PermissionValueType;
|
||||
onChange: (v: PermissionValueType) => Promise<any> | any;
|
||||
isInheritPermission?: boolean;
|
||||
isDisabled?: boolean;
|
||||
hasParent?: boolean;
|
||||
};
|
||||
|
||||
@@ -31,6 +32,7 @@ const DefaultPermissionList = ({
|
||||
onChange,
|
||||
isInheritPermission = false,
|
||||
hasParent,
|
||||
isDisabled = false,
|
||||
...styles
|
||||
}: Props) => {
|
||||
const { ConfirmModal, openConfirm } = useConfirm({});
|
||||
@@ -63,6 +65,8 @@ const DefaultPermissionList = ({
|
||||
return onRequestChange(per);
|
||||
}
|
||||
}}
|
||||
isDisabled={isDisabled}
|
||||
fontSize={styles?.fontSize}
|
||||
/>
|
||||
</Box>
|
||||
<ConfirmModal />
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Box, Button, Flex } from '@chakra-ui/react';
|
||||
import { Box, Button, Flex, FormLabel } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
import CollaboratorContextProvider, {
|
||||
MemberManagerInputPropsType
|
||||
@@ -9,29 +9,38 @@ import { useTranslation } from 'next-i18next';
|
||||
function MemberManager({ managePer }: { managePer: MemberManagerInputPropsType }) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Box mt={4}>
|
||||
<Box>
|
||||
<CollaboratorContextProvider {...managePer}>
|
||||
{({ MemberListCard, onOpenManageModal, onOpenAddMember }) => {
|
||||
return (
|
||||
<>
|
||||
<Flex alignItems="center" flexDirection="row" justifyContent="space-between" w="full">
|
||||
<Flex flexDirection="row" gap="2">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="whitePrimary"
|
||||
leftIcon={<MyIcon w="4" name="common/settingLight" />}
|
||||
onClick={onOpenManageModal}
|
||||
>
|
||||
{t('common:permission.Manage')}
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="whitePrimary"
|
||||
leftIcon={<MyIcon w="4" name="support/permission/collaborator" />}
|
||||
onClick={onOpenAddMember}
|
||||
>
|
||||
{t('common:common.Add')}
|
||||
</Button>
|
||||
<Box>
|
||||
<FormLabel fontSize={'mini'}>{t('common:permission.Collaborator')}</FormLabel>
|
||||
</Box>
|
||||
<Flex gap={0.5}>
|
||||
<Box p={1}>
|
||||
<MyIcon
|
||||
onClick={onOpenManageModal}
|
||||
name="common/setting"
|
||||
w={'1rem'}
|
||||
h={'1rem'}
|
||||
color={'myGray.600'}
|
||||
cursor={'pointer'}
|
||||
_hover={{ color: 'primary.500' }}
|
||||
/>
|
||||
</Box>
|
||||
<Box p={1}>
|
||||
<MyIcon
|
||||
cursor={'pointer'}
|
||||
onClick={onOpenAddMember}
|
||||
name="common/addUser"
|
||||
_hover={{ color: 'primary.500' }}
|
||||
w={'1rem'}
|
||||
h={'1rem'}
|
||||
color={'myGray.600'}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<MemberListCard mt={2} p={1.5} bg="myGray.100" borderRadius="md" />
|
||||
|
@@ -39,6 +39,7 @@ const FileSourceSelector = dynamic(() => import('../Import/components/FileSource
|
||||
const Header = ({}: {}) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
|
||||
const { setLoading, feConfigs } = useSystemStore();
|
||||
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
|
||||
|
||||
@@ -110,35 +111,43 @@ const Header = ({}: {}) => {
|
||||
successToast: t('common:common.Create Success'),
|
||||
errorToast: t('common:common.Create Failed')
|
||||
});
|
||||
const isWebSite = datasetDetail?.type === DatasetTypeEnum.websiteDataset;
|
||||
|
||||
return (
|
||||
<Flex px={[2, 6]} alignItems={'flex-start'} h={'35px'}>
|
||||
<Box flex={1}>
|
||||
<Box flex={1} fontWeight={'500'} color={'myGray.900'} h={'100%'}>
|
||||
<ParentPath
|
||||
paths={paths.map((path, i) => ({
|
||||
parentId: path.parentId,
|
||||
parentName: i === paths.length - 1 ? `${path.parentName}` : path.parentName
|
||||
}))}
|
||||
FirstPathDom={
|
||||
<>
|
||||
<Box fontWeight={'bold'} fontSize={['sm', 'md']}>
|
||||
<Flex
|
||||
flexDir={'column'}
|
||||
justify={'center'}
|
||||
h={'100%'}
|
||||
fontSize={isWebSite ? 'sm' : 'md'}
|
||||
fontWeight={'500'}
|
||||
color={'myGray.600'}
|
||||
>
|
||||
<Flex align={'center'}>
|
||||
{!isWebSite && <MyIcon name="common/list" mr={2} w={'20px'} color={'black'} />}
|
||||
{t(DatasetTypeMap[datasetDetail?.type]?.collectionLabel as any)}({total})
|
||||
</Box>
|
||||
</Flex>
|
||||
{datasetDetail?.websiteConfig?.url && (
|
||||
<Flex fontSize={'sm'}>
|
||||
<Flex fontSize={'mini'}>
|
||||
{t('common:core.dataset.website.Base Url')}:
|
||||
<Link
|
||||
href={datasetDetail.websiteConfig.url}
|
||||
target="_blank"
|
||||
mr={2}
|
||||
textDecoration={'underline'}
|
||||
color={'primary.600'}
|
||||
color={'blue.700'}
|
||||
>
|
||||
{datasetDetail.websiteConfig.url}
|
||||
</Link>
|
||||
</Flex>
|
||||
)}
|
||||
</>
|
||||
</Flex>
|
||||
}
|
||||
onClick={(e) => {
|
||||
router.replace({
|
||||
@@ -202,18 +211,26 @@ const Header = ({}: {}) => {
|
||||
fontSize={['sm', 'md']}
|
||||
>
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
px={5}
|
||||
px={3.5}
|
||||
py={2}
|
||||
borderRadius={'md'}
|
||||
borderRadius={'sm'}
|
||||
cursor={'pointer'}
|
||||
bg={'primary.500'}
|
||||
overflow={'hidden'}
|
||||
color={'white'}
|
||||
h={['28px', '35px']}
|
||||
>
|
||||
<MyIcon name={'common/importLight'} mr={2} w={'14px'} />
|
||||
<Box>{t('common:dataset.collections.Create And Import')}</Box>
|
||||
<Flex h={'20px'} alignItems={'center'}>
|
||||
<MyIcon
|
||||
name={'common/folderImport'}
|
||||
mr={2}
|
||||
w={'18px'}
|
||||
h={'18px'}
|
||||
color={'white'}
|
||||
/>
|
||||
</Flex>
|
||||
<Box h={'20px'} fontSize={'sm'} fontWeight={'500'}>
|
||||
{t('common:dataset.collections.Create And Import')}
|
||||
</Box>
|
||||
</Flex>
|
||||
</MenuButton>
|
||||
}
|
||||
@@ -323,18 +340,26 @@ const Header = ({}: {}) => {
|
||||
fontSize={['sm', 'md']}
|
||||
>
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
px={5}
|
||||
px={3.5}
|
||||
py={2}
|
||||
borderRadius={'md'}
|
||||
borderRadius={'sm'}
|
||||
cursor={'pointer'}
|
||||
bg={'primary.500'}
|
||||
overflow={'hidden'}
|
||||
color={'white'}
|
||||
h={['28px', '35px']}
|
||||
>
|
||||
<MyIcon name={'common/importLight'} mr={2} w={'14px'} />
|
||||
<Box>{t('common:dataset.collections.Create And Import')}</Box>
|
||||
<Flex h={'20px'} alignItems={'center'}>
|
||||
<MyIcon
|
||||
name={'common/folderImport'}
|
||||
mr={2}
|
||||
w={'18px'}
|
||||
h={'18px'}
|
||||
color={'white'}
|
||||
/>
|
||||
</Flex>
|
||||
<Box h={'20px'} fontSize={'sm'} fontWeight={'500'}>
|
||||
{t('common:dataset.collections.Create And Import')}
|
||||
</Box>
|
||||
</Flex>
|
||||
</MenuButton>
|
||||
}
|
||||
|
@@ -121,7 +121,7 @@ const HeaderTagPopOver = () => {
|
||||
<Input
|
||||
pl={2}
|
||||
h={8}
|
||||
borderRadius={'4px'}
|
||||
borderRadius={'xs'}
|
||||
value={searchTag}
|
||||
placeholder={t('dataset:tag.searchOrAddTag')}
|
||||
onChange={(e) => setSearchTag(e.target.value)}
|
||||
|
@@ -246,7 +246,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
|
||||
flex={'1'}
|
||||
_hover={{ bg: 'myGray.100' }}
|
||||
alignItems={'center'}
|
||||
borderRadius={'4px'}
|
||||
borderRadius={'xs'}
|
||||
>
|
||||
<Flex
|
||||
flex={'1 0 0'}
|
||||
@@ -263,7 +263,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
|
||||
bg={'#DBF3FF'}
|
||||
color={'#0884DD'}
|
||||
fontSize={'xs'}
|
||||
borderRadius={'6px'}
|
||||
borderRadius={'sm'}
|
||||
>
|
||||
{item.tag}
|
||||
</Box>
|
||||
@@ -299,7 +299,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
|
||||
_hover={{ bg: '#1118240D' }}
|
||||
mr={2}
|
||||
p={1}
|
||||
borderRadius={'6px'}
|
||||
borderRadius={'sm'}
|
||||
onClick={() => {
|
||||
setCurrentAddTag({ ...item, collections });
|
||||
}}
|
||||
@@ -313,7 +313,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
|
||||
_hover={{ bg: '#1118240D' }}
|
||||
mr={2}
|
||||
p={1}
|
||||
borderRadius={'6px'}
|
||||
borderRadius={'sm'}
|
||||
cursor={'pointer'}
|
||||
onClick={(e) => {
|
||||
setCurrentEditTag(item);
|
||||
@@ -332,7 +332,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
|
||||
display="none"
|
||||
_hover={{ bg: '#1118240D' }}
|
||||
p={1}
|
||||
borderRadius={'6px'}
|
||||
borderRadius={'sm'}
|
||||
cursor={'pointer'}
|
||||
>
|
||||
<MyIcon name="delete" w={4} />
|
||||
@@ -441,7 +441,7 @@ const AddTagToCollections = ({
|
||||
bg={'#DBF3FF'}
|
||||
color={'#0884DD'}
|
||||
fontSize={'sm'}
|
||||
borderRadius={'6px'}
|
||||
borderRadius={'sm'}
|
||||
>
|
||||
{currentAddTag.tag}
|
||||
</Box>
|
||||
@@ -496,7 +496,7 @@ const AddTagToCollections = ({
|
||||
: {})
|
||||
}}
|
||||
alignItems={'center'}
|
||||
borderRadius={'4px'}
|
||||
borderRadius={'xs'}
|
||||
key={collection.id}
|
||||
cursor={'pointer'}
|
||||
onClick={() => {
|
||||
@@ -525,7 +525,7 @@ const AddTagToCollections = ({
|
||||
isChecked={selectedCollections.includes(collection.id)}
|
||||
/>
|
||||
<MyIcon name={collection.icon as any} w={'20px'} mr={2} />
|
||||
<Box fontSize={'14px'} borderRadius={'6px'} color={'myGray.900'}>
|
||||
<Box fontSize={'sm'} borderRadius={'sm'} color={'myGray.900'}>
|
||||
{collection.name}
|
||||
</Box>
|
||||
</Flex>
|
||||
|
@@ -161,7 +161,7 @@ const TagsPopOver = ({
|
||||
fontWeight={'500'}
|
||||
bg={'#F0FBFF'}
|
||||
color={'#0884DD'}
|
||||
borderRadius={'4px'}
|
||||
borderRadius={'xs'}
|
||||
>
|
||||
{item.tag}
|
||||
</Box>
|
||||
@@ -197,7 +197,7 @@ const TagsPopOver = ({
|
||||
onBlur={() => setIsFocusInput(false)}
|
||||
pl={2}
|
||||
h={7}
|
||||
borderRadius={'4px'}
|
||||
borderRadius={'xs'}
|
||||
value={searchTag}
|
||||
placeholder={t('dataset:tag.searchOrAddTag')}
|
||||
onChange={(e) => setSearchTag(e.target.value)}
|
||||
@@ -217,7 +217,7 @@ const TagsPopOver = ({
|
||||
// setCheckedTags([...checkedTags, item]);
|
||||
}}
|
||||
>
|
||||
<MyIcon name={'common/addLight'} w={'14px'} />
|
||||
<MyIcon name={'common/addLight'} w={'sm'} />
|
||||
<Box ml={1} py={1}>
|
||||
{t('dataset:tag.add') + ` "${searchTag}"`}
|
||||
</Box>
|
||||
@@ -277,7 +277,7 @@ const TagsPopOver = ({
|
||||
fontSize={'11px'}
|
||||
bg={'#F0FBFF'}
|
||||
color={'#0884DD'}
|
||||
borderRadius={'4px'}
|
||||
borderRadius={'xs'}
|
||||
>
|
||||
{tag.tag}
|
||||
</Box>
|
||||
|
@@ -186,12 +186,12 @@ const CollectionCard = () => {
|
||||
|
||||
return (
|
||||
<MyBox isLoading={isLoading} h={'100%'} py={[2, 4]}>
|
||||
<Flex ref={BoxRef} flexDirection={'column'} py={[1, 3]} h={'100%'}>
|
||||
<Flex ref={BoxRef} flexDirection={'column'} py={[1, 0]} h={'100%'}>
|
||||
{/* header */}
|
||||
<Header />
|
||||
|
||||
{/* collection table */}
|
||||
<TableContainer px={[2, 6]} mt={[0, 3]} flex={'1 0 0'} overflowY={'auto'} fontSize={'sm'}>
|
||||
<TableContainer px={[2, 6]} mt={[0, 3]} overflowY={'auto'} fontSize={'sm'}>
|
||||
<Table variant={'simple'} draggable={false}>
|
||||
<Thead draggable={false}>
|
||||
<Tr>
|
||||
|
@@ -7,12 +7,6 @@ import {
|
||||
Grid,
|
||||
Button,
|
||||
useTheme,
|
||||
Drawer,
|
||||
DrawerBody,
|
||||
DrawerFooter,
|
||||
DrawerHeader,
|
||||
DrawerOverlay,
|
||||
DrawerContent,
|
||||
useDisclosure,
|
||||
HStack
|
||||
} from '@chakra-ui/react';
|
||||
@@ -52,6 +46,8 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import TagsPopOver from './CollectionCard/TagsPopOver';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyDivider from '@fastgpt/web/components/common/MyDivider';
|
||||
import index from '../../../index';
|
||||
|
||||
const DataCard = () => {
|
||||
const BoxRef = useRef<HTMLDivElement>(null);
|
||||
@@ -67,7 +63,6 @@ const DataCard = () => {
|
||||
const { feConfigs } = useSystemStore();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { datasetT } = useI18n();
|
||||
const [searchText, setSearchText] = useState('');
|
||||
const { toast } = useToast();
|
||||
const { openConfirm, ConfirmModal } = useConfirm({
|
||||
@@ -132,66 +127,6 @@ const DataCard = () => {
|
||||
|
||||
const canWrite = useMemo(() => datasetDetail.permission.hasWritePer, [datasetDetail]);
|
||||
|
||||
const metadataList = useMemo(() => {
|
||||
if (!collection) return [];
|
||||
|
||||
const webSelector =
|
||||
collection?.datasetId?.websiteConfig?.selector || collection?.metadata?.webPageSelector;
|
||||
|
||||
return [
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.source'),
|
||||
value: t(DatasetCollectionTypeMap[collection.type]?.name as any)
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.source name'),
|
||||
value: collection.file?.filename || collection?.rawLink || collection?.name
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.source size'),
|
||||
value: collection.file ? formatFileSize(collection.file.length) : '-'
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Createtime'),
|
||||
value: formatTime2YMDHM(collection.createTime)
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Updatetime'),
|
||||
value: formatTime2YMDHM(collection.updateTime)
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Raw text length'),
|
||||
value: collection.rawTextLength ?? '-'
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Training Type'),
|
||||
value: t(TrainingTypeMap[collection.trainingType]?.label as any)
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Chunk Size'),
|
||||
value: collection.chunkSize || '-'
|
||||
},
|
||||
...(webSelector
|
||||
? [
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Web page selector'),
|
||||
value: webSelector
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
...(collection.tags
|
||||
? [
|
||||
{
|
||||
label: datasetT('collection_tags'),
|
||||
value: collection.tags?.join(', ') || '-'
|
||||
}
|
||||
]
|
||||
: [])
|
||||
}
|
||||
];
|
||||
}, [collection, datasetT, t]);
|
||||
|
||||
const { run: onUpdate, loading } = useRequest2(putDatasetDataById, {
|
||||
onSuccess() {
|
||||
getData(pageNum);
|
||||
@@ -205,23 +140,6 @@ const DataCard = () => {
|
||||
<Flex ref={BoxRef} flexDirection={'column'} h={'100%'}>
|
||||
{/* Header */}
|
||||
<Flex alignItems={'center'} px={5}>
|
||||
<IconButton
|
||||
mr={3}
|
||||
icon={<MyIcon name={'common/backFill'} w={['14px', '18px']} color={'primary.500'} />}
|
||||
variant={'whitePrimary'}
|
||||
size={'smSquare'}
|
||||
borderRadius={'50%'}
|
||||
aria-label={''}
|
||||
onClick={() =>
|
||||
router.replace({
|
||||
query: {
|
||||
datasetId: router.query.datasetId,
|
||||
parentId: router.query.parentId,
|
||||
currentTab: TabEnum.collectionCard
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Flex className="textEllipsis" flex={'1 0 0'} mr={[3, 5]} alignItems={'center'}>
|
||||
<Box>
|
||||
<Box alignItems={'center'} gap={2} display={isPc ? 'flex' : ''}>
|
||||
@@ -234,12 +152,6 @@ const DataCard = () => {
|
||||
textDecoration={'none'}
|
||||
/>
|
||||
)}
|
||||
<Box fontSize={'sm'} color={'myGray.500'}>
|
||||
{t('common:core.dataset.collection.id')}:{' '}
|
||||
<Box as={'span'} userSelect={'all'}>
|
||||
{collection?._id}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
{feConfigs?.isPlus && !!collection?.tags?.length && (
|
||||
<TagsPopOver currentCollection={collection} />
|
||||
@@ -250,7 +162,6 @@ const DataCard = () => {
|
||||
<Box>
|
||||
<Button
|
||||
ml={2}
|
||||
mr={isPc ? 2 : 0}
|
||||
variant={'whitePrimary'}
|
||||
size={['sm', 'md']}
|
||||
onClick={() => {
|
||||
@@ -262,24 +173,17 @@ const DataCard = () => {
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
{isPc && (
|
||||
<MyTooltip label={t('common:core.dataset.collection.metadata.Read Metadata')}>
|
||||
<IconButton
|
||||
variant={'whiteBase'}
|
||||
size={['sm', 'md']}
|
||||
icon={<MyIcon name={'menu'} w={'18px'} />}
|
||||
aria-label={''}
|
||||
onClick={onOpen}
|
||||
/>
|
||||
</MyTooltip>
|
||||
)}
|
||||
</Flex>
|
||||
<Flex my={3} alignItems={'center'} px={5}>
|
||||
<Box>
|
||||
<Box as={'span'} fontSize={['sm', 'md']}>
|
||||
<Box justifyContent={'center'} px={5} pos={'relative'} w={'100%'}>
|
||||
<MyDivider my={'17px'} w={'100%'} />
|
||||
</Box>
|
||||
<Flex alignItems={'center'} px={5} pb={4}>
|
||||
<Flex align={'center'} color={'myGray.500'}>
|
||||
<MyIcon name="common/list" mr={2} w={'18px'} />
|
||||
<Box as={'span'} fontSize={['sm', '14px']} fontWeight={'500'}>
|
||||
{t('core.dataset.data.Total Amount', { total })}
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box flex={1} mr={1} />
|
||||
<MyInput
|
||||
leftIcon={
|
||||
@@ -287,9 +191,12 @@ const DataCard = () => {
|
||||
name="common/searchLight"
|
||||
position={'absolute'}
|
||||
w={'14px'}
|
||||
color={'myGray.500'}
|
||||
color={'myGray.600'}
|
||||
/>
|
||||
}
|
||||
bg={'myGray.25'}
|
||||
borderColor={'myGray.200'}
|
||||
color={'myGray.500'}
|
||||
w={['200px', '300px']}
|
||||
placeholder={t('common:core.dataset.data.Search data placeholder')}
|
||||
value={searchText}
|
||||
@@ -300,45 +207,59 @@ const DataCard = () => {
|
||||
</Flex>
|
||||
{/* data */}
|
||||
<Box flex={'1 0 0'} overflow={'auto'} px={5}>
|
||||
<Grid
|
||||
gridTemplateColumns={['1fr', 'repeat(2,1fr)', 'repeat(3,1fr)', 'repeat(4,1fr)']}
|
||||
gridGap={4}
|
||||
>
|
||||
{datasetDataList.map((item) => (
|
||||
<Flex flexDir={'column'} gap={2}>
|
||||
{datasetDataList.map((item, index) => (
|
||||
<Card
|
||||
key={item._id}
|
||||
cursor={'pointer'}
|
||||
p={3}
|
||||
userSelect={'none'}
|
||||
boxShadow={'none'}
|
||||
bg={'myWhite.500'}
|
||||
bg={index % 2 === 1 ? 'myGray.50' : 'blue.50'}
|
||||
border={theme.borders.sm}
|
||||
position={'relative'}
|
||||
overflow={'hidden'}
|
||||
_hover={{
|
||||
borderColor: 'myGray.200',
|
||||
borderColor: 'blue.600',
|
||||
boxShadow: 'lg',
|
||||
bg: 'white',
|
||||
'& .footer': { h: 'auto', p: 3 },
|
||||
'& .forbid-switch': { display: 'flex' }
|
||||
'& .header': { visibility: 'visible' },
|
||||
'& .footer': { visibility: 'visible' },
|
||||
'& .forbid-switch': { display: 'flex' },
|
||||
bg: index % 2 === 1 ? 'myGray.200' : 'blue.100'
|
||||
}}
|
||||
onClick={() => {
|
||||
if (!collection) return;
|
||||
setEditDataId(item._id);
|
||||
}}
|
||||
>
|
||||
<Flex zIndex={1} alignItems={'center'}>
|
||||
<MyTag type="borderFill"># {item.chunkIndex ?? '-'}</MyTag>
|
||||
|
||||
<Box
|
||||
className={'textEllipsis'}
|
||||
flex={'1 0 0'}
|
||||
w="0"
|
||||
fontSize={'mini'}
|
||||
textAlign={'right'}
|
||||
<Flex
|
||||
position={'absolute'}
|
||||
zIndex={1}
|
||||
alignItems={'center'}
|
||||
visibility={'hidden'}
|
||||
className="header"
|
||||
>
|
||||
<MyTag
|
||||
px={2}
|
||||
type="borderFill"
|
||||
borderRadius={'sm'}
|
||||
border={'1px'}
|
||||
color={'myGray.200'}
|
||||
bg={'white'}
|
||||
fontWeight={'500'}
|
||||
>
|
||||
ID:{item._id}
|
||||
</Box>
|
||||
<Box color={'blue.600'}>#{item.chunkIndex ?? '-'} </Box>
|
||||
<Box
|
||||
ml={1.5}
|
||||
className={'textEllipsis'}
|
||||
fontSize={'mini'}
|
||||
textAlign={'right'}
|
||||
color={'myGray.500'}
|
||||
>
|
||||
ID:{item._id}
|
||||
</Box>
|
||||
</MyTag>
|
||||
|
||||
{/* {item.forbid ? (
|
||||
<MyTag colorSchema="gray" bg={'transparent'} px={1} showDot>
|
||||
{datasetT('Disabled')}
|
||||
@@ -390,54 +311,69 @@ const DataCard = () => {
|
||||
<Flex
|
||||
className="footer"
|
||||
position={'absolute'}
|
||||
top={0}
|
||||
bottom={0}
|
||||
left={0}
|
||||
right={0}
|
||||
h={'0'}
|
||||
bottom={2}
|
||||
right={2}
|
||||
overflow={'hidden'}
|
||||
bg={'linear-gradient(to top, white,white 20%, rgba(255,255,255,0) 60%)'}
|
||||
alignItems={'flex-end'}
|
||||
visibility={'hidden'}
|
||||
fontSize={'mini'}
|
||||
>
|
||||
<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
|
||||
alignItems={'center'}
|
||||
bg={'white'}
|
||||
color={'myGray.600'}
|
||||
borderRadius={'sm'}
|
||||
border={'1px'}
|
||||
borderColor={'myGray.200'}
|
||||
h={'24px'}
|
||||
px={2}
|
||||
fontSize={'mini'}
|
||||
boxShadow={'1'}
|
||||
py={1}
|
||||
mr={2}
|
||||
>
|
||||
<MyIcon
|
||||
bg={'white'}
|
||||
color={'myGray.600'}
|
||||
borderRadius={'sm'}
|
||||
border={'1px'}
|
||||
borderColor={'myGray.200'}
|
||||
name="common/text/t"
|
||||
w={'14px'}
|
||||
mr={1}
|
||||
/>
|
||||
{item.q.length + (item.a?.length || 0)}
|
||||
</Flex>
|
||||
{canWrite && (
|
||||
<IconButton
|
||||
display={'flex'}
|
||||
p={1}
|
||||
boxShadow={'1'}
|
||||
icon={<MyIcon name={'common/trash'} w={'14px'} color={'myGray.600'} />}
|
||||
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'
|
||||
});
|
||||
}
|
||||
})();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
</Box>
|
||||
</Card>
|
||||
))}
|
||||
</Grid>
|
||||
</Flex>
|
||||
{total > pageSize && (
|
||||
<Flex mt={2} justifyContent={'center'}>
|
||||
<Pagination />
|
||||
@@ -447,38 +383,6 @@ const DataCard = () => {
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
{/* metadata drawer */}
|
||||
<Drawer isOpen={isOpen} placement="right" size={'md'} onClose={onClose}>
|
||||
<DrawerOverlay />
|
||||
<DrawerContent>
|
||||
<DrawerHeader fontSize={'lg'}>
|
||||
{t('common:core.dataset.collection.metadata.metadata')}
|
||||
</DrawerHeader>
|
||||
|
||||
<DrawerBody>
|
||||
{metadataList.map((item, i) => (
|
||||
<Flex key={i} alignItems={'center'} mb={5} wordBreak={'break-all'} fontSize={'sm'}>
|
||||
<Box color={'myGray.500'} flex={'0 0 100px'}>
|
||||
{item.label}
|
||||
</Box>
|
||||
<Box>{item.value}</Box>
|
||||
</Flex>
|
||||
))}
|
||||
{collection?.sourceId && (
|
||||
<Button variant={'whitePrimary'} onClick={readSource}>
|
||||
{t('common:core.dataset.collection.metadata.read source')}
|
||||
</Button>
|
||||
)}
|
||||
</DrawerBody>
|
||||
|
||||
<DrawerFooter>
|
||||
<Button variant={'whitePrimary'} onClick={onClose}>
|
||||
{t('common:common.Close')}
|
||||
</Button>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
{editDataId !== undefined && collection && (
|
||||
<InputDataModal
|
||||
collectionId={collection._id}
|
||||
|
@@ -6,7 +6,7 @@ import { ImportDataSourceEnum, TrainingModeEnum } from '@fastgpt/global/core/dat
|
||||
import { useMyStep } from '@fastgpt/web/hooks/useStep';
|
||||
import { Box, Button, Flex, IconButton } from '@chakra-ui/react';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { TabEnum } from '../Slider';
|
||||
import { TabEnum } from '../NavBar';
|
||||
import { ImportProcessWayEnum } from '@/web/core/dataset/constants';
|
||||
import { UseFormReturn, useForm } from 'react-hook-form';
|
||||
import { ImportSourceItemType } from '@/web/core/dataset/type';
|
||||
|
@@ -272,7 +272,7 @@ function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean
|
||||
<Box mt={5} pl={[0, '100px']} gap={3}>
|
||||
{feConfigs?.show_pay && (
|
||||
<MyTooltip label={priceTip}>
|
||||
<MyTag colorSchema={'gray'} py={'6px'} borderRadius={'md'} px={3} whiteSpace={'wrap'}>
|
||||
<MyTag colorSchema={'gray'} py={1.5} borderRadius={'md'} px={3} whiteSpace={'wrap'}>
|
||||
{priceTip}
|
||||
</MyTag>
|
||||
</MyTooltip>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Box, Flex, Button, IconButton, Input, Textarea, HStack } from '@chakra-ui/react';
|
||||
import { DeleteIcon } from '@chakra-ui/icons';
|
||||
@@ -16,15 +16,15 @@ import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
|
||||
import AIModelSelector from '@/components/Select/AIModelSelector';
|
||||
import { postRebuildEmbedding } from '@/web/core/dataset/api';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import type { VectorModelItemType } from '@fastgpt/global/core/ai/model.d';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
|
||||
import MyDivider from '@fastgpt/web/components/common/MyDivider/index';
|
||||
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
import { DatasetTypeEnum, DatasetTypeMap } from '@fastgpt/global/core/dataset/constants';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
||||
import DefaultPermissionList from '@/components/support/permission/DefaultPerList';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import {
|
||||
DatasetDefaultPermissionVal,
|
||||
DatasetPermissionList
|
||||
@@ -35,18 +35,23 @@ import {
|
||||
postUpdateDatasetCollaborators,
|
||||
deleteDatasetCollaborators
|
||||
} from '@/web/core/dataset/api/collaborator';
|
||||
import DatasetTypeTag from '@/components/core/dataset/DatasetTypeTag';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { EditResourceInfoFormType } from '@/components/common/Modal/EditResourceModal';
|
||||
const EditResourceModal = dynamic(() => import('@/components/common/Modal/EditResourceModal'));
|
||||
|
||||
const Info = ({ datasetId }: { datasetId: string }) => {
|
||||
const router = useRouter();
|
||||
const [openBaseConfig, setOpenBaseConfig] = useState(true);
|
||||
const [openPermissionConfig, setOpenPermissionConfig] = useState(true);
|
||||
const { t } = useTranslation();
|
||||
const { datasetT, commonT } = useI18n();
|
||||
const { datasetDetail, loadDatasetDetail, updateDataset, rebuildingCount, trainingCount } =
|
||||
useContextSelector(DatasetPageContext, (v) => v);
|
||||
|
||||
const [editedDataset, setEditedDataset] = useState<EditResourceInfoFormType>();
|
||||
const refetchDatasetTraining = useContextSelector(
|
||||
DatasetPageContext,
|
||||
(v) => v.refetchDatasetTraining
|
||||
);
|
||||
|
||||
const { setValue, register, handleSubmit, watch } = useForm<DatasetItemType>({
|
||||
defaultValues: datasetDetail
|
||||
});
|
||||
@@ -57,16 +62,13 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
||||
const defaultPermission = watch('defaultPermission');
|
||||
|
||||
const { datasetModelList, vectorModelList } = useSystemStore();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const { openConfirm: onOpenConfirmDel, ConfirmModal: ConfirmDelModal } = useConfirm({
|
||||
content: t('common:core.dataset.Delete Confirm'),
|
||||
type: 'delete'
|
||||
});
|
||||
const { openConfirm: onOpenConfirmRebuild, ConfirmModal: ConfirmRebuildModal } = useConfirm({
|
||||
title: t('common:common.confirm.Common Tip'),
|
||||
content: datasetT('confirm_to_rebuild_embedding_tip'),
|
||||
content: t('dataset:confirm_to_rebuild_embedding_tip'),
|
||||
type: 'delete'
|
||||
});
|
||||
|
||||
@@ -87,13 +89,10 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
||||
errorToast: t('common:common.Delete Failed')
|
||||
});
|
||||
|
||||
const { mutate: onclickSave, isLoading: isSaving } = useRequest({
|
||||
const { mutate: onSave, isLoading: isSaving } = useRequest({
|
||||
mutationFn: (data: DatasetItemType) => {
|
||||
return updateDataset({
|
||||
id: datasetId,
|
||||
name: data.name,
|
||||
avatar: data.avatar,
|
||||
intro: data.intro,
|
||||
agentModel: data.agentModel,
|
||||
externalReadUrl: data.externalReadUrl,
|
||||
defaultPermission: data.defaultPermission
|
||||
@@ -133,156 +132,191 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
||||
refetchDatasetTraining();
|
||||
loadDatasetDetail(datasetId);
|
||||
},
|
||||
successToast: datasetT('rebuild_embedding_start_tip'),
|
||||
successToast: t('dataset:rebuild_embedding_start_tip'),
|
||||
errorToast: t('common:common.Update Failed')
|
||||
});
|
||||
|
||||
const btnLoading = isSelecting || isDeleting || isSaving || isRebuilding;
|
||||
const totalLoading = isSelecting || isDeleting || isSaving || isRebuilding;
|
||||
|
||||
return (
|
||||
<Box py={5} px={[5, 10]}>
|
||||
<Flex mt={5} w={'100%'} alignItems={'center'}>
|
||||
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
|
||||
{t('common:core.dataset.Dataset ID')}
|
||||
</FormLabel>
|
||||
<Box flex={1}>{datasetDetail._id}</Box>
|
||||
</Flex>
|
||||
<Flex mt={8} w={'100%'} alignItems={'center'} flexWrap={'wrap'}>
|
||||
<HStack flex={['0 0 90px', '0 0 160px']} w={0} spacing={1}>
|
||||
<FormLabel>{t('common:core.ai.model.Vector Model')}</FormLabel>
|
||||
<QuestionTip label={t('common:core.dataset.embedding model tip')} />
|
||||
</HStack>
|
||||
<Box flex={[1, '0 0 320px']}>
|
||||
<AIModelSelector
|
||||
w={'100%'}
|
||||
value={vectorModel.model}
|
||||
disableTip={
|
||||
rebuildingCount > 0 || trainingCount > 0
|
||||
? datasetT('the_knowledge_base_has_indexes_that_are_being_trained_or_being_rebuilt')
|
||||
: undefined
|
||||
<Box w={'100%'} h={'100%'} p={6}>
|
||||
<Box>
|
||||
<Flex mb={2} alignItems={'center'}>
|
||||
<Avatar src={datasetDetail.avatar} w={'20px'} h={'20px'} borderRadius={'xs'} />
|
||||
<Box ml={1.5}>
|
||||
<Box fontWeight={'bold'} color={'myGray.900'}>
|
||||
{datasetDetail.name}
|
||||
</Box>
|
||||
</Box>
|
||||
<MyIcon
|
||||
pl={1.5}
|
||||
name={'edit'}
|
||||
_hover={{ color: 'primary.600' }}
|
||||
w={'0.875rem'}
|
||||
cursor={'pointer'}
|
||||
onClick={() =>
|
||||
setEditedDataset({
|
||||
id: datasetDetail._id,
|
||||
name: datasetDetail.name,
|
||||
avatar: datasetDetail.avatar,
|
||||
intro: datasetDetail.intro
|
||||
})
|
||||
}
|
||||
list={vectorModelList.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.model
|
||||
}))}
|
||||
onchange={(e) => {
|
||||
const vectorModel = vectorModelList.find((item) => item.model === e);
|
||||
if (!vectorModel) return;
|
||||
onOpenConfirmRebuild(() => {
|
||||
setValue('vectorModel', vectorModel);
|
||||
onRebuilding(vectorModel);
|
||||
})();
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex mt={8} w={'100%'} alignItems={'center'}>
|
||||
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
|
||||
{t('common:core.Max Token')}
|
||||
</FormLabel>
|
||||
<Box flex={[1, '0 0 320px']}>{vectorModel.maxToken}</Box>
|
||||
</Flex>
|
||||
<Flex mt={6} alignItems={'center'} flexWrap={'wrap'}>
|
||||
<HStack flex={['0 0 90px', '0 0 160px']} w={0} spacing={1}>
|
||||
<FormLabel>{t('common:core.ai.model.Dataset Agent Model')}</FormLabel>
|
||||
<QuestionTip label={t('dataset:file_model_function_tip')} />
|
||||
</HStack>
|
||||
<Box flex={[1, '0 0 320px']}>
|
||||
<AIModelSelector
|
||||
w={'100%'}
|
||||
value={agentModel.model}
|
||||
list={datasetModelList.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.model
|
||||
}))}
|
||||
onchange={(e) => {
|
||||
const agentModel = datasetModelList.find((item) => item.model === e);
|
||||
if (!agentModel) return;
|
||||
setValue('agentModel', agentModel);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
<MyDivider my={6} h={'2px'} maxW={'500px'} />
|
||||
|
||||
{datasetDetail.type === DatasetTypeEnum.externalFile && (
|
||||
<>
|
||||
<Flex w={'100%'} alignItems={'center'}>
|
||||
<FormLabel
|
||||
display={'flex'}
|
||||
flex={['0 0 90px', '0 0 160px']}
|
||||
w={0}
|
||||
gap={1}
|
||||
alignItems={'center'}
|
||||
>
|
||||
<Box>{datasetT('external_read_url')}</Box>
|
||||
<QuestionTip label={datasetT('external_read_url_tip')} />
|
||||
</FormLabel>
|
||||
<Input
|
||||
flex={[1, '0 0 320px']}
|
||||
placeholder="https://test.com/read?fileId={{fileId}}"
|
||||
{...register('externalReadUrl')}
|
||||
/>
|
||||
</Flex>
|
||||
{DatasetTypeMap[datasetDetail.type] && (
|
||||
<Flex alignItems={'center'} justifyContent={'space-between'}>
|
||||
<DatasetTypeTag type={datasetDetail.type} />
|
||||
</Flex>
|
||||
<MyDivider my={6} h={'2px'} maxW={'500px'} />
|
||||
</>
|
||||
)}
|
||||
|
||||
<Flex mt={5} w={'100%'} alignItems={'center'}>
|
||||
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
|
||||
{t('common:core.dataset.Avatar')}
|
||||
</FormLabel>
|
||||
<Box flex={[1, '0 0 320px']}>
|
||||
<MyTooltip label={t('common:common.avatar.Select Avatar')}>
|
||||
<Avatar
|
||||
m={'auto'}
|
||||
src={avatar}
|
||||
w={['32px', '40px']}
|
||||
h={['32px', '40px']}
|
||||
cursor={'pointer'}
|
||||
borderRadius={'md'}
|
||||
onClick={onOpenSelectFile}
|
||||
/>
|
||||
</MyTooltip>
|
||||
)}
|
||||
<Box
|
||||
flex={1}
|
||||
className={'textEllipsis3'}
|
||||
pt={3}
|
||||
wordBreak={'break-all'}
|
||||
fontSize={'xs'}
|
||||
color={'myGray.500'}
|
||||
>
|
||||
{datasetDetail.intro || t('common:core.dataset.Intro Placeholder')}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex mt={8} w={'100%'} alignItems={'center'}>
|
||||
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
|
||||
{t('common:core.dataset.Name')}
|
||||
</FormLabel>
|
||||
<Input flex={[1, '0 0 320px']} maxLength={30} {...register('name')} />
|
||||
</Flex>
|
||||
<Flex mt={8} alignItems={'center'} w={'100%'}>
|
||||
<FormLabel flex={['0 0 90px', '0 0 160px']}>{t('common:common.Intro')}</FormLabel>
|
||||
<Textarea
|
||||
flex={[1, '0 0 320px']}
|
||||
{...register('intro')}
|
||||
placeholder={t('common:common.Intro')}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
|
||||
<MyDivider my={4} h={'2px'} maxW={'500px'} />
|
||||
|
||||
<Box overflow={'hidden'} h={openBaseConfig ? 'auto' : '24px'}>
|
||||
<Flex justify={'space-between'} alignItems={'center'} fontSize={'mini'} h={'24px'}>
|
||||
<Box fontWeight={'500'} color={'myGray.900'}>
|
||||
{t('common:common.base_config')}
|
||||
</Box>
|
||||
<MyIcon
|
||||
w={'16px'}
|
||||
_hover={{ color: 'primary.500', cursor: 'pointer' }}
|
||||
color={'myGray.500'}
|
||||
name={openBaseConfig ? 'core/chat/chevronUp' : 'core/chat/chevronDown'}
|
||||
onClick={() => setOpenBaseConfig(!openBaseConfig)}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex mt={3} w={'100%'} flexDir={'column'}>
|
||||
<FormLabel fontSize={'mini'}>{t('common:core.dataset.Dataset ID')}</FormLabel>
|
||||
<Box fontSize={'mini'}>{datasetDetail._id}</Box>
|
||||
</Flex>
|
||||
|
||||
<Box mt={5} w={'100%'}>
|
||||
<FormLabel fontSize={'mini'}>{t('common:core.ai.model.Vector Model')}</FormLabel>
|
||||
<Box pt={2} flex={[1, '0 0 320px']}>
|
||||
<AIModelSelector
|
||||
w={'100%'}
|
||||
value={vectorModel.model}
|
||||
fontSize={'mini'}
|
||||
disableTip={
|
||||
rebuildingCount > 0 || trainingCount > 0
|
||||
? t(
|
||||
'dataset:the_knowledge_base_has_indexes_that_are_being_trained_or_being_rebuilt'
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
list={vectorModelList.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.model
|
||||
}))}
|
||||
onchange={(e) => {
|
||||
const vectorModel = vectorModelList.find((item) => item.model === e);
|
||||
if (!vectorModel) return;
|
||||
onOpenConfirmRebuild(() => {
|
||||
setValue('vectorModel', vectorModel);
|
||||
onRebuilding(vectorModel);
|
||||
})();
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Flex mt={2} w={'100%'} alignItems={'center'}>
|
||||
<FormLabel flex={['0 0 90px', '0 0 160px']} fontSize={'mini'} w={0}>
|
||||
{t('common:core.Max Token')}
|
||||
</FormLabel>
|
||||
<Box flex={[1, '0 0 320px']} fontSize={'mini'}>
|
||||
{vectorModel.maxToken}
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
<Box pt={5}>
|
||||
<FormLabel fontSize={'mini'}>{t('common:core.ai.model.Dataset Agent Model')}</FormLabel>
|
||||
<Box pt={2}>
|
||||
<AIModelSelector
|
||||
w={'100%'}
|
||||
value={agentModel.model}
|
||||
list={datasetModelList.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.model
|
||||
}))}
|
||||
fontSize={'mini'}
|
||||
onchange={(e) => {
|
||||
const agentModel = datasetModelList.find((item) => item.model === e);
|
||||
if (!agentModel) return;
|
||||
setValue('agentModel', agentModel);
|
||||
handleSubmit((data) => onSave({ ...data, agentModel: agentModel }))();
|
||||
}}
|
||||
isDisabled={totalLoading}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* <MyDivider my={4} h={'2px'} maxW={'500px'} /> */}
|
||||
|
||||
{datasetDetail.type === DatasetTypeEnum.externalFile && (
|
||||
<>
|
||||
<Box w={'100%'} alignItems={'center'} pt={4}>
|
||||
<FormLabel display={'flex'} pb={2} fontSize={'mini'}>
|
||||
<Box>{t('dataset:external_read_url')}</Box>
|
||||
<QuestionTip label={t('dataset:external_read_url_tip')} />
|
||||
</FormLabel>
|
||||
<Input
|
||||
fontSize={'mini'}
|
||||
flex={[1, '0 0 320px']}
|
||||
placeholder="https://test.com/read?fileId={{fileId}}"
|
||||
{...register('externalReadUrl')}
|
||||
onBlur={handleSubmit((data) => onSave(data))}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{datasetDetail.permission.hasManagePer && (
|
||||
<>
|
||||
<MyDivider my={6} h={'2px'} maxW={'500px'} />
|
||||
<MyDivider my={4} h={'2px'} maxW={'500px'} />
|
||||
<Box overflow={'hidden'} h={openPermissionConfig ? 'auto' : '24px'}>
|
||||
<Flex justify={'space-between'} alignItems={'center'} fontSize={'mini'} h={'24px'}>
|
||||
<Box fontWeight={'500'} color={'myGray.900'}>
|
||||
{t('common:permission.Permission config')}
|
||||
</Box>
|
||||
<MyIcon
|
||||
w={'16px'}
|
||||
_hover={{ color: 'primary.500', cursor: 'pointer' }}
|
||||
color={'myGray.500'}
|
||||
name={openPermissionConfig ? 'core/chat/chevronUp' : 'core/chat/chevronDown'}
|
||||
onClick={() => setOpenPermissionConfig(!openPermissionConfig)}
|
||||
/>
|
||||
</Flex>
|
||||
|
||||
<Flex mt={5} alignItems={'center'} w={'100%'} flexWrap={'wrap'} maxW="500px">
|
||||
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
|
||||
{commonT('permission.Default permission')}
|
||||
</FormLabel>
|
||||
<DefaultPermissionList
|
||||
w="320px"
|
||||
per={defaultPermission}
|
||||
defaultPer={DatasetDefaultPermissionVal}
|
||||
onChange={(v) => setValue('defaultPermission', v)}
|
||||
/>
|
||||
</Flex>
|
||||
<Box mt={3}>
|
||||
<FormLabel fontSize={'mini'} pb={3}>
|
||||
{t('common:permission.Default permission')}
|
||||
</FormLabel>
|
||||
<DefaultPermissionList
|
||||
fontSize={'mini'}
|
||||
per={defaultPermission}
|
||||
defaultPer={DatasetDefaultPermissionVal}
|
||||
isDisabled={totalLoading}
|
||||
onChange={(v) => {
|
||||
setValue('defaultPermission', v);
|
||||
handleSubmit((data) => onSave({ ...data, defaultPermission: v }))();
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Flex mt={5} alignItems={'center'} w={'100%'} flexWrap={'wrap'} maxW="500px">
|
||||
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
|
||||
{commonT('permission.Collaborator')}
|
||||
</FormLabel>
|
||||
<Box flex={1}>
|
||||
<Box mt={4}>
|
||||
<MemberManager
|
||||
managePer={{
|
||||
permission: datasetDetail.permission,
|
||||
@@ -301,35 +335,31 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Flex mt={5} w={'100%'} alignItems={'flex-end'}>
|
||||
<Box flex={['0 0 90px', '0 0 160px']} w={0}></Box>
|
||||
<Button
|
||||
isLoading={btnLoading}
|
||||
mr={4}
|
||||
w={'100px'}
|
||||
onClick={handleSubmit((data) => onclickSave(data))}
|
||||
>
|
||||
{t('common:common.Save')}
|
||||
</Button>
|
||||
{datasetDetail.permission.isOwner && (
|
||||
<IconButton
|
||||
isLoading={btnLoading}
|
||||
icon={<DeleteIcon />}
|
||||
aria-label={''}
|
||||
variant={'whiteDanger'}
|
||||
size={'smSquare'}
|
||||
onClick={onOpenConfirmDel(onclickDelete)}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
<File onSelect={onSelectFile} />
|
||||
<ConfirmDelModal />
|
||||
<ConfirmRebuildModal countDown={10} />
|
||||
{editedDataset && (
|
||||
<EditResourceModal
|
||||
{...editedDataset}
|
||||
title={t('common:dataset.Edit Info')}
|
||||
onClose={() => {
|
||||
setEditedDataset(undefined);
|
||||
}}
|
||||
onEdit={async (data) => {
|
||||
await updateDataset({
|
||||
id: editedDataset.id,
|
||||
name: data.name,
|
||||
intro: data.intro,
|
||||
avatar: data.avatar
|
||||
});
|
||||
setEditedDataset(undefined);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@@ -0,0 +1,123 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Box, Flex, Button, IconButton, Input, Textarea, HStack } from '@chakra-ui/react';
|
||||
import { DeleteIcon } from '@chakra-ui/icons';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { getDatasetCollectionById } from '@/web/core/dataset/api';
|
||||
import { useRouter } from 'next/router';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import { formatFileSize } from '@fastgpt/global/common/file/tools';
|
||||
import { formatTime2YMDHM } from '@fastgpt/global/common/string/time';
|
||||
import { DatasetCollectionTypeMap, TrainingTypeMap } from '@fastgpt/global/core/dataset/constants';
|
||||
import { getCollectionSourceAndOpen } from '@/web/core/dataset/hooks/readCollectionSource';
|
||||
|
||||
const MetaDataCard = ({ datasetId }: { datasetId: string }) => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const { collectionId = '' } = router.query as {
|
||||
collectionId: string;
|
||||
datasetId: string;
|
||||
};
|
||||
const readSource = getCollectionSourceAndOpen(collectionId);
|
||||
const { data: collection, loading: isLoading } = useRequest2(
|
||||
() => getDatasetCollectionById(collectionId),
|
||||
{
|
||||
onError: () => {
|
||||
router.replace({
|
||||
query: {
|
||||
datasetId
|
||||
}
|
||||
});
|
||||
},
|
||||
manual: false
|
||||
}
|
||||
);
|
||||
const metadataList = useMemo(() => {
|
||||
if (!collection) return [];
|
||||
|
||||
const webSelector =
|
||||
collection?.datasetId?.websiteConfig?.selector || collection?.metadata?.webPageSelector;
|
||||
|
||||
return [
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.source'),
|
||||
value: t(DatasetCollectionTypeMap[collection.type]?.name as any)
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.source name'),
|
||||
value: collection.file?.filename || collection?.rawLink || collection?.name
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.source size'),
|
||||
value: collection.file ? formatFileSize(collection.file.length) : '-'
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Createtime'),
|
||||
value: formatTime2YMDHM(collection.createTime)
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Updatetime'),
|
||||
value: formatTime2YMDHM(collection.updateTime)
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Raw text length'),
|
||||
value: collection.rawTextLength ?? '-'
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Training Type'),
|
||||
value: t(TrainingTypeMap[collection.trainingType]?.label as any)
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Chunk Size'),
|
||||
value: collection.chunkSize || '-'
|
||||
},
|
||||
...(webSelector
|
||||
? [
|
||||
{
|
||||
label: t('common:core.dataset.collection.metadata.Web page selector'),
|
||||
value: webSelector
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
...(collection.tags
|
||||
? [
|
||||
{
|
||||
label: t('dataset:collection_tags'),
|
||||
value: collection.tags?.join(', ') || '-'
|
||||
}
|
||||
]
|
||||
: [])
|
||||
}
|
||||
];
|
||||
}, [collection, t]);
|
||||
|
||||
return (
|
||||
<MyBox isLoading={isLoading} w={'100%'} h={'100%'} p={6}>
|
||||
<Box fontSize={'lg'} pb={4}>
|
||||
{t('common:core.dataset.collection.metadata.metadata')}
|
||||
</Box>
|
||||
<Box fontSize={'sm'} color={'myGray.500'} mb={5}>
|
||||
{t('common:core.dataset.collection.id')}:{' '}
|
||||
<Box as={'span'} userSelect={'all'}>
|
||||
{collection?._id}
|
||||
</Box>
|
||||
</Box>
|
||||
{metadataList.map((item, i) => (
|
||||
<Flex key={i} alignItems={'center'} mb={5} wordBreak={'break-all'} fontSize={'sm'}>
|
||||
<Box color={'myGray.500'} flex={'0 0 100px'}>
|
||||
{item.label}
|
||||
</Box>
|
||||
<Box>{item.value}</Box>
|
||||
</Flex>
|
||||
))}
|
||||
{collection?.sourceId && (
|
||||
<Button variant={'whitePrimary'} onClick={readSource}>
|
||||
{t('common:core.dataset.collection.metadata.read source')}
|
||||
</Button>
|
||||
)}
|
||||
</MyBox>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(MetaDataCard);
|
212
projects/app/src/pages/dataset/detail/components/NavBar.tsx
Normal file
212
projects/app/src/pages/dataset/detail/components/NavBar.tsx
Normal file
@@ -0,0 +1,212 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { Box, Flex, IconButton, useTheme, Progress } from '@chakra-ui/react';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
|
||||
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
||||
|
||||
export enum TabEnum {
|
||||
dataCard = 'dataCard',
|
||||
collectionCard = 'collectionCard',
|
||||
test = 'test',
|
||||
info = 'info',
|
||||
import = 'import'
|
||||
}
|
||||
|
||||
const NavBar = ({ currentTab }: { currentTab: TabEnum }) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const { datasetT } = useI18n();
|
||||
const router = useRouter();
|
||||
const query = router.query;
|
||||
const { isPc } = useSystem();
|
||||
const { datasetDetail, vectorTrainingMap, agentTrainingMap, rebuildingCount } =
|
||||
useContextSelector(DatasetPageContext, (v) => v);
|
||||
|
||||
const tabList = [
|
||||
{
|
||||
label: t('common:core.dataset.Collection'),
|
||||
value: TabEnum.collectionCard
|
||||
},
|
||||
{ label: t('common:core.dataset.test.Search Test'), value: TabEnum.test },
|
||||
...(datasetDetail.permission.hasManagePer && !isPc
|
||||
? [{ label: t('common:common.Config'), value: TabEnum.info }]
|
||||
: [])
|
||||
];
|
||||
|
||||
const setCurrentTab = useCallback(
|
||||
(tab: TabEnum) => {
|
||||
router.replace({
|
||||
query: {
|
||||
datasetId: query.datasetId,
|
||||
currentTab: tab
|
||||
}
|
||||
});
|
||||
},
|
||||
[query, router]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isPc ? (
|
||||
<Flex
|
||||
py={2}
|
||||
px={4}
|
||||
justify={'space-between'}
|
||||
borderBottom={theme.borders.base}
|
||||
borderColor={'myGray.200'}
|
||||
position={'relative'}
|
||||
>
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
cursor={'pointer'}
|
||||
py={'0.38rem'}
|
||||
px={2}
|
||||
h={10}
|
||||
borderRadius={'md'}
|
||||
_hover={{ bg: 'myGray.05' }}
|
||||
fontSize={'sm'}
|
||||
fontWeight={500}
|
||||
onClick={() => {
|
||||
if (currentTab !== TabEnum.dataCard) router.replace('/dataset/list');
|
||||
else
|
||||
router.replace({
|
||||
query: {
|
||||
datasetId: router.query.datasetId,
|
||||
parentId: router.query.parentId,
|
||||
currentTab: TabEnum.collectionCard
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<IconButton
|
||||
p={2}
|
||||
mr={2}
|
||||
w={'1.5rem'}
|
||||
h={'24px'}
|
||||
border={'1px solid'}
|
||||
borderColor={'myGray.200'}
|
||||
boxShadow={'1'}
|
||||
icon={<MyIcon name={'common/arrowLeft'} w={'16px'} color={'myGray.500'} />}
|
||||
bg={'white'}
|
||||
size={'smSquare'}
|
||||
borderRadius={'50%'}
|
||||
aria-label={''}
|
||||
_hover={'none'}
|
||||
/>
|
||||
<Box fontWeight={500} color={'myGray.600'} fontSize={'sm'}>
|
||||
{currentTab !== TabEnum.dataCard
|
||||
? t('common:core.dataset.All Dataset')
|
||||
: datasetDetail.name}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box position={'absolute'} left={'50%'} transform={'translateX(-50%)'}>
|
||||
<LightRowTabs<TabEnum>
|
||||
px={4}
|
||||
py={1}
|
||||
visibility={currentTab === TabEnum.dataCard ? 'hidden' : 'visible'}
|
||||
flex={1}
|
||||
mx={'auto'}
|
||||
w={'100%'}
|
||||
list={tabList}
|
||||
value={currentTab}
|
||||
activatedColor="blue.700"
|
||||
onChange={setCurrentTab}
|
||||
inlineStyles={{
|
||||
fontSize: '1rem',
|
||||
lineHeight: '1.5rem',
|
||||
fontWeight: 500,
|
||||
border: 'none',
|
||||
_hover: {
|
||||
bg: 'myGray.05',
|
||||
color: 'blue.700'
|
||||
},
|
||||
borderRadius: '6px'
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* 训练情况hover弹窗 */}
|
||||
<MyPopover
|
||||
placement="bottom-end"
|
||||
visibility={currentTab === TabEnum.collectionCard ? 'visible' : 'hidden'}
|
||||
trigger="hover"
|
||||
Trigger={
|
||||
<Flex
|
||||
visibility={currentTab === TabEnum.collectionCard ? 'visible' : 'hidden'}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
p={2}
|
||||
borderRadius={'md'}
|
||||
_hover={{
|
||||
bg: 'myGray.05'
|
||||
}}
|
||||
>
|
||||
<MyIcon name={'common/monitor'} w={'18px'} h={'18px'} color={'myGray.500'} />
|
||||
<Box color={'myGray.600'} ml={1.5} fontWeight={500}>
|
||||
{t('common:core.dataset.training.tag')}
|
||||
</Box>
|
||||
</Flex>
|
||||
}
|
||||
>
|
||||
{({ onClose }) => (
|
||||
<Box p={6}>
|
||||
{rebuildingCount > 0 && (
|
||||
<Box mb={3}>
|
||||
<Box fontSize={'sm'}>
|
||||
{datasetT('rebuilding_index_count', { count: rebuildingCount })}
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
<Box mb={3}>
|
||||
<Box fontSize={'sm'} pb={1}>
|
||||
{t('common:core.dataset.training.Agent queue')}({agentTrainingMap.tip})
|
||||
</Box>
|
||||
<Progress
|
||||
value={100}
|
||||
size={'xs'}
|
||||
colorScheme={agentTrainingMap.colorSchema}
|
||||
borderRadius={'md'}
|
||||
isAnimated
|
||||
hasStripe
|
||||
/>
|
||||
</Box>
|
||||
<Box>
|
||||
<Box fontSize={'sm'} pb={1}>
|
||||
{t('common:core.dataset.training.Vector queue')}({vectorTrainingMap.tip})
|
||||
</Box>
|
||||
<Progress
|
||||
value={100}
|
||||
size={'xs'}
|
||||
colorScheme={vectorTrainingMap.colorSchema}
|
||||
borderRadius={'md'}
|
||||
isAnimated
|
||||
hasStripe
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
</MyPopover>
|
||||
</Flex>
|
||||
) : (
|
||||
<Box mb={3}>
|
||||
<LightRowTabs<TabEnum>
|
||||
m={'auto'}
|
||||
w={'full'}
|
||||
size={'sm'}
|
||||
list={tabList}
|
||||
value={currentTab}
|
||||
onChange={setCurrentTab}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavBar;
|
@@ -1,165 +0,0 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { Box, Flex, IconButton, useTheme, Progress } from '@chakra-ui/react';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import { DatasetTypeMap } from '@fastgpt/global/core/dataset/constants';
|
||||
import DatasetTypeTag from '@/components/core/dataset/DatasetTypeTag';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import SideTabs from '@/components/SideTabs';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
|
||||
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
|
||||
export enum TabEnum {
|
||||
dataCard = 'dataCard',
|
||||
collectionCard = 'collectionCard',
|
||||
test = 'test',
|
||||
info = 'info',
|
||||
import = 'import'
|
||||
}
|
||||
|
||||
const Slider = ({ currentTab }: { currentTab: TabEnum }) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const { datasetT } = useI18n();
|
||||
const router = useRouter();
|
||||
const query = router.query;
|
||||
const { isPc } = useSystem();
|
||||
const { datasetDetail, vectorTrainingMap, agentTrainingMap, rebuildingCount } =
|
||||
useContextSelector(DatasetPageContext, (v) => v);
|
||||
|
||||
const tabList = [
|
||||
{
|
||||
label: t('common:core.dataset.Collection'),
|
||||
value: TabEnum.collectionCard,
|
||||
icon: 'common/overviewLight'
|
||||
},
|
||||
{ label: t('common:core.dataset.test.Search Test'), value: TabEnum.test, icon: 'kbTest' },
|
||||
...(datasetDetail.permission.hasManagePer
|
||||
? [{ label: t('common:common.Config'), value: TabEnum.info, icon: 'common/settingLight' }]
|
||||
: [])
|
||||
];
|
||||
|
||||
const setCurrentTab = useCallback(
|
||||
(tab: TabEnum) => {
|
||||
router.replace({
|
||||
query: {
|
||||
datasetId: query.datasetId,
|
||||
currentTab: tab
|
||||
}
|
||||
});
|
||||
},
|
||||
[query, router]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isPc ? (
|
||||
<Flex
|
||||
flexDirection={'column'}
|
||||
py={4}
|
||||
h={'100%'}
|
||||
flex={'0 0 200px'}
|
||||
borderRight={theme.borders.base}
|
||||
>
|
||||
<Box px={4} borderBottom={'1px'} borderColor={'myGray.200'} pb={4} mb={4}>
|
||||
<Flex mb={4} alignItems={'center'}>
|
||||
<Avatar src={datasetDetail.avatar} w={'34px'} borderRadius={'md'} />
|
||||
<Box ml={2}>
|
||||
<Box fontWeight={'bold'}>{datasetDetail.name}</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
{DatasetTypeMap[datasetDetail.type] && (
|
||||
<Flex alignItems={'center'} pl={2} justifyContent={'space-between'}>
|
||||
<DatasetTypeTag type={datasetDetail.type} />
|
||||
</Flex>
|
||||
)}
|
||||
</Box>
|
||||
<SideTabs<TabEnum>
|
||||
px={4}
|
||||
flex={1}
|
||||
mx={'auto'}
|
||||
w={'100%'}
|
||||
list={tabList}
|
||||
value={currentTab}
|
||||
onChange={setCurrentTab}
|
||||
/>
|
||||
<Box px={4}>
|
||||
{rebuildingCount > 0 && (
|
||||
<Box mb={3}>
|
||||
<Box fontSize={'sm'}>
|
||||
{datasetT('rebuilding_index_count', { count: rebuildingCount })}
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
<Box mb={3}>
|
||||
<Box fontSize={'sm'}>
|
||||
{t('common:core.dataset.training.Agent queue')}({agentTrainingMap.tip})
|
||||
</Box>
|
||||
<Progress
|
||||
value={100}
|
||||
size={'xs'}
|
||||
colorScheme={agentTrainingMap.colorSchema}
|
||||
borderRadius={'10px'}
|
||||
isAnimated
|
||||
hasStripe
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={3}>
|
||||
<Box fontSize={'sm'}>
|
||||
{t('common:core.dataset.training.Vector queue')}({vectorTrainingMap.tip})
|
||||
</Box>
|
||||
<Progress
|
||||
value={100}
|
||||
size={'xs'}
|
||||
colorScheme={vectorTrainingMap.colorSchema}
|
||||
borderRadius={'10px'}
|
||||
isAnimated
|
||||
hasStripe
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
cursor={'pointer'}
|
||||
py={2}
|
||||
px={3}
|
||||
borderRadius={'md'}
|
||||
_hover={{ bg: 'myGray.100' }}
|
||||
fontSize={'sm'}
|
||||
onClick={() => router.replace('/dataset/list')}
|
||||
>
|
||||
<IconButton
|
||||
mr={3}
|
||||
icon={<MyIcon name={'common/backFill'} w={'1rem'} color={'primary.500'} />}
|
||||
bg={'white'}
|
||||
boxShadow={'1px 1px 9px rgba(0,0,0,0.15)'}
|
||||
size={'smSquare'}
|
||||
borderRadius={'50%'}
|
||||
aria-label={''}
|
||||
/>
|
||||
{t('common:core.dataset.All Dataset')}
|
||||
</Flex>
|
||||
</Flex>
|
||||
) : (
|
||||
<Box mb={3}>
|
||||
<LightRowTabs<TabEnum>
|
||||
m={'auto'}
|
||||
w={'full'}
|
||||
size={isPc ? 'md' : 'sm'}
|
||||
list={tabList}
|
||||
value={currentTab}
|
||||
onChange={setCurrentTab}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Slider;
|
@@ -141,7 +141,6 @@ const Test = ({ datasetId }: { datasetId: string }) => {
|
||||
flex={1}
|
||||
maxW={'500px'}
|
||||
py={4}
|
||||
borderRight={['none', theme.borders.base]}
|
||||
>
|
||||
<Box
|
||||
border={'2px solid'}
|
||||
@@ -280,7 +279,7 @@ const Test = ({ datasetId }: { datasetId: string }) => {
|
||||
</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
<Box mt={5} flex={'1 0 0'} px={4} overflow={'overlay'} display={['none', 'block']}>
|
||||
<Box mt={5} px={4} overflow={'overlay'} display={['none', 'block']}>
|
||||
<TestHistories
|
||||
datasetId={datasetId}
|
||||
datasetTestItem={datasetTestItem}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
@@ -8,8 +8,8 @@ import dynamic from 'next/dynamic';
|
||||
import PageContainer from '@/components/PageContainer';
|
||||
import { serviceSideProps } from '@/web/common/utils/i18n';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
import Slider from './components/Slider';
|
||||
import MetaDataCard from './components/MetaDataCard';
|
||||
import NavBar from './components/NavBar';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import {
|
||||
DatasetPageContext,
|
||||
@@ -19,6 +19,7 @@ import CollectionPageContextProvider from './components/CollectionCard/Context';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import NextHead from '@/components/common/NextHead';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
|
||||
const CollectionCard = dynamic(() => import('./components/CollectionCard/index'));
|
||||
const DataCard = dynamic(() => import('./components/DataCard'));
|
||||
@@ -39,6 +40,7 @@ const Detail = ({ datasetId, currentTab }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const router = useRouter();
|
||||
const { isPc } = useSystem();
|
||||
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
|
||||
const loadDatasetDetail = useContextSelector(DatasetPageContext, (v) => v.loadDatasetDetail);
|
||||
const loadAllDatasetTags = useContextSelector(DatasetPageContext, (v) => v.loadAllDatasetTags);
|
||||
@@ -60,25 +62,71 @@ const Detail = ({ datasetId, currentTab }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<NextHead title={datasetDetail?.name} icon={datasetDetail?.avatar} />
|
||||
<PageContainer insertProps={{ bg: 'white' }}>
|
||||
<MyBox display={'flex'} flexDirection={['column', 'row']} h={'100%'} pt={[4, 0]}>
|
||||
<Slider currentTab={currentTab} />
|
||||
|
||||
{!!datasetDetail._id && (
|
||||
<Box flex={'1 0 0'} pb={0} overflow={'auto'}>
|
||||
{isPc ? (
|
||||
<Flex h={'100%'} w={'100%'}>
|
||||
<Flex
|
||||
flexGrow={1}
|
||||
flex={81}
|
||||
bg={'white'}
|
||||
w={'100%'}
|
||||
flexDir={'column'}
|
||||
my={3}
|
||||
mr={2}
|
||||
boxShadow={'2'}
|
||||
borderRadius={'md'}
|
||||
>
|
||||
{currentTab !== TabEnum.import && <NavBar currentTab={currentTab} />}
|
||||
<Box flex={'1 0 0'} w={'100%'} overflow={'auto'}>
|
||||
{currentTab === TabEnum.collectionCard && (
|
||||
<CollectionPageContextProvider>
|
||||
<CollectionCard />
|
||||
</CollectionPageContextProvider>
|
||||
)}
|
||||
{currentTab === TabEnum.dataCard && <DataCard />}
|
||||
{currentTab === TabEnum.test && <Test datasetId={datasetId} />}
|
||||
{currentTab === TabEnum.info && <Info datasetId={datasetId} />}
|
||||
{currentTab === TabEnum.dataCard && <DataCard />}
|
||||
{currentTab === TabEnum.import && <Import />}
|
||||
</Box>
|
||||
</Flex>
|
||||
{currentTab !== TabEnum.import && (
|
||||
<Flex
|
||||
bg={'white'}
|
||||
borderRadius={'md'}
|
||||
overflowY={'scroll'}
|
||||
boxShadow={'2'}
|
||||
my={3}
|
||||
mr={3}
|
||||
flex={19}
|
||||
>
|
||||
{currentTab === TabEnum.dataCard ? (
|
||||
<MetaDataCard datasetId={datasetId} />
|
||||
) : (
|
||||
<Info datasetId={datasetId} />
|
||||
)}
|
||||
</Flex>
|
||||
)}
|
||||
</MyBox>
|
||||
</PageContainer>
|
||||
</Flex>
|
||||
) : (
|
||||
<PageContainer insertProps={{ bg: 'white' }}>
|
||||
<MyBox display={'flex'} flexDirection={['column', 'row']} h={'100%'} pt={[4, 0]}>
|
||||
<NavBar currentTab={currentTab} />
|
||||
|
||||
{!!datasetDetail._id && (
|
||||
<Box flex={'1 0 0'} pb={0} overflow={'auto'}>
|
||||
{currentTab === TabEnum.collectionCard && (
|
||||
<CollectionPageContextProvider>
|
||||
<CollectionCard />
|
||||
</CollectionPageContextProvider>
|
||||
)}
|
||||
{currentTab === TabEnum.dataCard && <DataCard />}
|
||||
{currentTab === TabEnum.test && <Test datasetId={datasetId} />}
|
||||
{currentTab === TabEnum.info && <Info datasetId={datasetId} />}
|
||||
{currentTab === TabEnum.import && <Import />}
|
||||
</Box>
|
||||
)}
|
||||
</MyBox>
|
||||
</PageContainer>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@@ -118,7 +118,7 @@ const CreateModal = ({
|
||||
<MyModal
|
||||
title={
|
||||
<Flex alignItems={'center'} ml={-3}>
|
||||
<Avatar w={'20px'} h={'20px'} borderRadius={'4px'} src={iconMap[type]} pr={'10px'} />
|
||||
<Avatar w={'20px'} h={'20px'} borderRadius={'xs'} src={iconMap[type]} pr={'10px'} />
|
||||
{t('common:core.dataset.Create dataset', { name: databaseNameMap[type] })}
|
||||
</Flex>
|
||||
}
|
||||
@@ -127,9 +127,9 @@ const CreateModal = ({
|
||||
isCentered={!isPc}
|
||||
w={'490px'}
|
||||
>
|
||||
<ModalBody py={'24px'} px={'36px'}>
|
||||
<ModalBody py={6} px={9}>
|
||||
<Box>
|
||||
<Box color={'myGray.900'} fontWeight={500} fontSize={'14px'}>
|
||||
<Box color={'myGray.900'} fontWeight={500} fontSize={'sm'}>
|
||||
{t('common:common.Set Name')}
|
||||
</Box>
|
||||
<Flex mt={'12px'} alignItems={'center'}>
|
||||
@@ -226,7 +226,7 @@ const CreateModal = ({
|
||||
)}
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter px={'36px'}>
|
||||
<ModalFooter px={9}>
|
||||
<Button variant={'whiteBase'} mr={3} onClick={onClose}>
|
||||
{t('common:common.Close')}
|
||||
</Button>
|
||||
|
@@ -229,7 +229,7 @@ function List() {
|
||||
>
|
||||
<HStack>
|
||||
<Avatar src={dataset.avatar} borderRadius={6} w={'28px'} />
|
||||
<Box flex={'1 0 0'} className="textEllipsis3">
|
||||
<Box flex={'1 0 0'} className="textEllipsis3" color={'myGray.900'}>
|
||||
{dataset.name}
|
||||
</Box>
|
||||
|
||||
@@ -264,7 +264,7 @@ function List() {
|
||||
h={'24px'}
|
||||
alignItems={'center'}
|
||||
justifyContent={'space-between'}
|
||||
fontSize={'12px'}
|
||||
fontSize={'sm'}
|
||||
fontWeight={500}
|
||||
color={'myGray.500'}
|
||||
>
|
||||
|
@@ -28,7 +28,7 @@ const SideTag = ({ type, ...props }: { type: `${DatasetTypeEnum}` } & FlexProps)
|
||||
return (
|
||||
<Flex
|
||||
bg={'myGray.100'}
|
||||
py={'3px'}
|
||||
py={0.75}
|
||||
pl={'8px'}
|
||||
pr={'12px'}
|
||||
borderRadius={'md'}
|
||||
|
@@ -155,7 +155,7 @@ const Dataset = () => {
|
||||
placement="bottom-end"
|
||||
Button={
|
||||
<Button variant={'primary'} px="0">
|
||||
<Flex alignItems={'center'} px={'20px'}>
|
||||
<Flex alignItems={'center'} px={5}>
|
||||
<AddIcon mr={2} />
|
||||
<Box>{t('common:common.Create New')}</Box>
|
||||
</Flex>
|
||||
|
Reference in New Issue
Block a user