perf: Dataset new ui (#2555)

* perf: dataset detail ui

* fix: collection tag modal

* perf: data card support markdown

* fix :ts
This commit is contained in:
Archer
2024-08-28 12:48:55 +08:00
committed by GitHub
parent aba50e958e
commit b9a6b71fe9
16 changed files with 355 additions and 366 deletions

View File

@@ -5,9 +5,14 @@ import { Box, Image, ImageProps } from '@chakra-ui/react';
import { useSystem } from '../../../hooks/useSystem';
import Loading from '../MyLoading';
const MyPhotoView = (props: ImageProps) => {
const MyPhotoView = ({
forbidImgPreview,
...props
}: ImageProps & { forbidImgPreview?: boolean }) => {
const { isPc } = useSystem();
return (
return forbidImgPreview ? (
<Image {...props} />
) : (
<PhotoProvider
maskOpacity={0.6}
bannerVisible={!isPc}

View File

@@ -19,8 +19,8 @@ import {
} from '@chakra-ui/react';
import type { ButtonProps, MenuItemProps } from '@chakra-ui/react';
import { ChevronDownIcon } from '@chakra-ui/icons';
import { useLoading } from '../../../hooks/useLoading';
import MyIcon from '../Icon';
import { useRequest2 } from '../../../hooks/useRequest';
export type SelectProps<T = any> = ButtonProps & {
value?: T;
@@ -32,7 +32,7 @@ export type SelectProps<T = any> = ButtonProps & {
value: T;
}[];
isLoading?: boolean;
onchange?: (val: T) => void;
onchange?: (val: T) => any | Promise<any>;
};
const MySelect = <T = any,>(
@@ -82,6 +82,10 @@ const MySelect = <T = any,>(
}
}, [isOpen]);
const { runAsync: onChange, loading } = useRequest2((val: T) => onchange?.(val));
const isSelecting = loading || isLoading;
return (
<Box
css={css({
@@ -92,7 +96,7 @@ const MySelect = <T = any,>(
>
<Menu
autoSelect={false}
isOpen={isOpen}
isOpen={isOpen && !isSelecting}
onOpen={onOpen}
onClose={onClose}
strategy={'fixed'}
@@ -118,7 +122,7 @@ const MySelect = <T = any,>(
{...props}
>
<Flex alignItems={'center'}>
{isLoading && <MyIcon mr={2} name={'common/loading'} w={'16px'} />}
{isSelecting && <MyIcon mr={2} name={'common/loading'} w={'16px'} />}
{selectItem?.alias || selectItem?.label || placeholder}
</Flex>
</MenuButton>
@@ -160,8 +164,8 @@ const MySelect = <T = any,>(
color: 'myGray.900'
})}
onClick={() => {
if (onchange && value !== item.value) {
onchange(item.value);
if (onChange && value !== item.value) {
onChange(item.value);
}
}}
whiteSpace={'pre-wrap'}

View File

@@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import { Box, Flex, Grid, Image } from '@chakra-ui/react';
import { Box, Flex, Grid } from '@chakra-ui/react';
import type { FlexProps, GridProps } from '@chakra-ui/react';
import { useTranslation } from 'next-i18next';
import Avatar from '../Avatar';
@@ -9,7 +9,7 @@ type Props<ValueType = string> = Omit<GridProps, 'onChange'> & {
value: ValueType;
size?: 'sm' | 'md' | 'lg';
inlineStyles?: FlexProps;
activatedColor?: string;
activeColor?: string;
onChange: (value: ValueType) => void;
};
@@ -17,7 +17,7 @@ const LightRowTabs = <ValueType = string,>({
list,
size = 'md',
value,
activatedColor = 'primary.600',
activeColor = 'primary.600',
onChange,
inlineStyles,
...props
@@ -68,10 +68,10 @@ const LightRowTabs = <ValueType = string,>({
whiteSpace={'nowrap'}
{...(value === item.value
? {
color: activatedColor,
color: activeColor,
cursor: 'default',
fontWeight: 'bold',
borderBottomColor: activatedColor
borderBottomColor: activeColor
}
: {
cursor: 'pointer'

View File

@@ -3,7 +3,7 @@ import { Box, ImageProps, Skeleton } from '@chakra-ui/react';
import MyPhotoView from '@fastgpt/web/components/common/Image/PhotoView';
import { useBoolean } from 'ahooks';
const MdImage = ({ src, ...props }: { src?: string } & ImageProps) => {
const MdImage = ({ src, ...props }: { src?: string; forbidImgPreview?: boolean } & ImageProps) => {
const [isLoaded, { setTrue }] = useBoolean(false);
const [renderSrc, setRenderSrc] = useState(src);
@@ -11,7 +11,6 @@ const MdImage = ({ src, ...props }: { src?: string } & ImageProps) => {
if (src?.includes('base64') && !src.startsWith('data:image')) {
return <Box>Invalid base64 image</Box>;
}
return (
<Skeleton isLoaded={isLoaded}>
<MyPhotoView

View File

@@ -28,20 +28,22 @@ const QuestionGuide = dynamic(() => import('./chat/QuestionGuide'), { ssr: false
const Markdown = ({
source = '',
showAnimation = false
showAnimation = false,
forbidImgPreview = false
}: {
source?: string;
showAnimation?: boolean;
forbidImgPreview?: boolean;
}) => {
const components = useMemo<any>(
() => ({
img: Image,
img: (props: any) => <Image {...props} forbidImgPreview={forbidImgPreview} />,
pre: RewritePre,
p: (pProps: any) => <p {...pProps} dir="auto" />,
code: Code,
a: A
}),
[]
[forbidImgPreview]
);
const formatSource = useMemo(() => {
@@ -74,7 +76,7 @@ const Markdown = ({
export default React.memo(Markdown);
/* Custom dom */
const Code = React.memo(function Code(e: any) {
function Code(e: any) {
const { className, codeBlock, children } = e;
const match = /language-(\w+)/.exec(className || '');
const codeType = match?.[1];
@@ -103,11 +105,13 @@ const Code = React.memo(function Code(e: any) {
}, [codeType, className, codeBlock, match, children, strChildren]);
return Component;
});
const Image = React.memo(function Image({ src }: { src?: string }) {
return <MdImage src={src} />;
});
const A = React.memo(function A({ children, ...props }: any) {
}
function Image({ src, forbidImgPreview }: { forbidImgPreview: boolean; src?: string }) {
return <MdImage forbidImgPreview={forbidImgPreview} src={src} />;
}
function A({ children, ...props }: any) {
const { t } = useTranslation();
// empty href link
@@ -152,7 +156,7 @@ const A = React.memo(function A({ children, ...props }: any) {
}
return <Link {...props}>{children}</Link>;
});
}
function RewritePre({ children }: any) {
const modifiedChildren = React.Children.map(children, (child) => {

View File

@@ -61,7 +61,7 @@ const AIModelSelector = ({ list, onchange, disableTip, ...props }: Props) => {
router.push(AI_POINT_USAGE_CARD_ROUTE);
return;
}
onchange?.(e);
return onchange?.(e);
},
[onchange, router]
);

View File

@@ -1,4 +1,4 @@
import { Box, BoxProps, ButtonProps } from '@chakra-ui/react';
import { Box, BoxProps } 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,7 +20,6 @@ type Props = Omit<BoxProps, 'onChange'> & {
writePer?: PermissionValueType;
onChange: (v: PermissionValueType) => Promise<any> | any;
isInheritPermission?: boolean;
isDisabled?: boolean;
hasParent?: boolean;
};
@@ -42,15 +41,12 @@ const DefaultPermissionList = ({
{ label: t('user:permission.team_write'), value: writePer }
];
const { runAsync: onRequestChange, loading } = useRequest2((v: PermissionValueType) =>
onChange(v)
);
const { runAsync: onRequestChange } = useRequest2((v: PermissionValueType) => onChange(v));
return (
<>
<Box {...styles}>
<MySelect
isLoading={loading}
list={defaultPermissionSelectList}
value={per}
onchange={(per) => {

View File

@@ -1,5 +1,14 @@
import React, { useCallback, useRef } from 'react';
import { Box, Flex, MenuButton, Button, Link, useTheme, useDisclosure } from '@chakra-ui/react';
import {
Box,
Flex,
MenuButton,
Button,
Link,
useTheme,
useDisclosure,
HStack
} from '@chakra-ui/react';
import {
getDatasetCollectionPathById,
postDatasetCollection,
@@ -114,8 +123,9 @@ const Header = ({}: {}) => {
const isWebSite = datasetDetail?.type === DatasetTypeEnum.websiteDataset;
return (
<Flex px={[2, 6]} alignItems={'flex-start'} h={'35px'}>
<Box flex={1} fontWeight={'500'} color={'myGray.900'} h={'100%'}>
<Box display={['block', 'flex']} alignItems={'center'} gap={2}>
<HStack flex={1}>
<Box flex={1} fontWeight={'500'} color={'myGray.900'}>
<ParentPath
paths={paths.map((path, i) => ({
parentId: path.parentId,
@@ -162,7 +172,6 @@ const Header = ({}: {}) => {
{/* search input */}
{isPc && (
<Flex alignItems={'center'} mr={4}>
<MyInput
w={['100%', '250px']}
size={'sm'}
@@ -192,14 +201,15 @@ const Header = ({}: {}) => {
}
}}
/>
</Flex>
)}
{/* Tag */}
{datasetDetail.permission.hasWritePer && feConfigs?.isPlus && <HeaderTagPopOver />}
</HStack>
{/* diff collection button */}
{datasetDetail.permission.hasWritePer && (
<Flex gap={3}>
{feConfigs?.isPlus && <HeaderTagPopOver />}
<Box textAlign={'end'} mt={[3, 0]}>
{datasetDetail?.type === DatasetTypeEnum.dataset && (
<MyMenu
offset={[0, 5]}
@@ -396,7 +406,7 @@ const Header = ({}: {}) => {
]}
/>
)}
</Flex>
</Box>
)}
{/* modal */}
@@ -427,7 +437,7 @@ const Header = ({}: {}) => {
)}
<EditCreateVirtualFileModal iconSrc={'modal/manualDataset'} closeBtnText={''} />
{isOpenFileSourceSelector && <FileSourceSelector onClose={onCloseFileSourceSelector} />}
</Flex>
</Box>
);
};

View File

@@ -29,7 +29,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
const loadDatasetTags = useContextSelector(DatasetPageContext, (v) => v.loadDatasetTags);
const loadAllDatasetTags = useContextSelector(DatasetPageContext, (v) => v.loadAllDatasetTags);
const { getData, collections } = useContextSelector(CollectionPageContext, (v) => v);
const { getData, pageNum, collections } = useContextSelector(CollectionPageContext, (v) => v);
const tagInputRef = useRef<HTMLInputElement>(null);
const editInputRef = useRef<HTMLInputElement>(null);
@@ -73,15 +73,14 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
errorToast: t('common:common.Create Failed')
});
const { mutate: onDeleteCollectionTag, isLoading: isDeleteCollectionTagLoading } = useRequest({
mutationFn: async (tag: string) => {
const id = await delDatasetCollectionTag({
const { runAsync: onDeleteCollectionTag, loading: isDeleteCollectionTagLoading } = useRequest2(
(tag: string) => {
return delDatasetCollectionTag({
datasetId: datasetDetail._id,
id: tag
});
return id;
},
{
onSuccess() {
fetchData(1);
loadDatasetTags({ id: datasetDetail._id, searchKey: '' });
@@ -89,26 +88,28 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
},
successToast: t('common:common.Delete Success'),
errorToast: t('common:common.Delete Failed')
});
}
);
const { mutate: onUpdateCollectionTag, isLoading: isUpdateCollectionTagLoading } = useRequest({
mutationFn: async (tag: DatasetTagType) => {
const id = await updateDatasetCollectionTag({
const { runAsync: onUpdateCollectionTag, loading: isUpdateCollectionTagLoading } = useRequest2(
async (tag: DatasetTagType) => {
return updateDatasetCollectionTag({
datasetId: datasetDetail._id,
tagId: tag._id,
tag: tag.tag
});
return id;
},
{
onSuccess() {
fetchData(1);
loadDatasetTags({ id: datasetDetail._id, searchKey: '' });
loadAllDatasetTags({ id: datasetDetail._id });
}
});
}
);
const { mutate: onSaveCollectionTag, isLoading: isSaveCollectionTagLoading } = useRequest({
mutationFn: async ({
const { runAsync: onSaveCollectionTag, loading: isSaveCollectionTagLoading } = useRequest2(
async ({
tag,
originCollectionIds,
collectionIds
@@ -117,22 +118,21 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
originCollectionIds: string[];
collectionIds: string[];
}) => {
try {
await postAddTagsToCollections({
return postAddTagsToCollections({
tag,
originCollectionIds,
collectionIds,
datasetId: datasetDetail._id
});
} catch (error) {}
},
onSuccess() {
getData(1);
{
onFinally() {
getData(pageNum);
},
successToast: t('common:common.Save Success'),
errorToast: t('common:common.Save Failed')
});
}
);
const {
list,
@@ -379,11 +379,9 @@ const AddTagToCollections = ({
const { t } = useTranslation();
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
const [selectedCollections, setSelectedCollections] = useState<string[]>([]);
useEffect(() => {
setSelectedCollections(currentAddTag.collections);
}, []);
const [selectedCollections, setSelectedCollections] = useState<string[]>(
currentAddTag.collections
);
const [searchText, setSearchText] = useState('');

View File

@@ -21,7 +21,7 @@ import { useQuery } from '@tanstack/react-query';
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { useTranslation } from 'next-i18next';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useRouter } from 'next/router';
import MyMenu from '@fastgpt/web/components/common/MyMenu';
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
@@ -119,23 +119,22 @@ const CollectionCard = () => {
successToast: t('common:common.Update Success')
}
);
const { mutate: onDelCollection, isLoading: isDeleting } = useRequest({
mutationFn: (collectionId: string) => {
const { runAsync: onDelCollection, loading: isDeleting } = useRequest2(
(collectionId: string) => {
return delDatasetCollectionById({
id: collectionId
});
},
{
onSuccess() {
getData(pageNum);
},
successToast: t('common:common.Delete Success'),
errorToast: t('common:common.Delete Failed')
});
}
);
const { mutate: onclickStartSync, isLoading: isSyncing } = useRequest({
mutationFn: (collectionId: string) => {
return postLinkCollectionSync(collectionId);
},
const { runAsync: onclickStartSync, loading: isSyncing } = useRequest2(postLinkCollectionSync, {
onSuccess(res: DatasetCollectionSyncResultEnum) {
getData(pageNum);
toast({
@@ -186,12 +185,12 @@ const CollectionCard = () => {
return (
<MyBox isLoading={isLoading} h={'100%'} py={[2, 4]}>
<Flex ref={BoxRef} flexDirection={'column'} py={[1, 0]} h={'100%'}>
<Flex ref={BoxRef} flexDirection={'column'} py={[1, 0]} h={'100%'} px={[2, 6]}>
{/* header */}
<Header />
{/* collection table */}
<TableContainer px={[2, 6]} mt={[0, 3]} overflowY={'auto'} fontSize={'sm'}>
<TableContainer mt={3} overflowY={'auto'} fontSize={'sm'}>
<Table variant={'simple'} draggable={false}>
<Thead draggable={false}>
<Tr>
@@ -237,7 +236,7 @@ const CollectionCard = () => {
>
<Td minW={'150px'} maxW={['200px', '300px']} draggable py={2}>
<Flex alignItems={'center'}>
<MyIcon name={collection.icon as any} w={'18px'} mr={2} />
<MyIcon name={collection.icon as any} w={'1.25rem'} mr={2} />
<MyTooltip
label={t('common:common.folder.Drag Tip')}
shouldWrapChildren={false}
@@ -287,8 +286,8 @@ const CollectionCard = () => {
offset={[-70, 5]}
Button={
<MenuButton
w={'22px'}
h={'22px'}
w={'1.5rem'}
h={'1.5rem'}
borderRadius={'md'}
_hover={{
color: 'primary.500',
@@ -300,8 +299,8 @@ const CollectionCard = () => {
<MyIcon
className="icon"
name={'more'}
h={'16px'}
w={'16px'}
h={'1rem'}
w={'1rem'}
px={1}
py={1}
borderRadius={'md'}
@@ -317,7 +316,11 @@ const CollectionCard = () => {
{
label: (
<Flex alignItems={'center'}>
<MyIcon name={'common/refreshLight'} w={'14px'} mr={2} />
<MyIcon
name={'common/refreshLight'}
w={'0.9rem'}
mr={2}
/>
{t('common:core.dataset.collection.Sync')}
</Flex>
),
@@ -331,7 +334,7 @@ const CollectionCard = () => {
{
label: (
<Flex alignItems={'center'}>
<MyIcon name={'common/file/move'} w={'14px'} mr={2} />
<MyIcon name={'common/file/move'} w={'0.9rem'} mr={2} />
{t('common:Move')}
</Flex>
),
@@ -341,7 +344,7 @@ const CollectionCard = () => {
{
label: (
<Flex alignItems={'center'}>
<MyIcon name={'edit'} w={'14px'} mr={2} />
<MyIcon name={'edit'} w={'0.9rem'} mr={2} />
{t('common:Rename')}
</Flex>
),
@@ -365,7 +368,7 @@ const CollectionCard = () => {
<MyIcon
mr={1}
name={'delete'}
w={'14px'}
w={'0.9rem'}
_hover={{ color: 'red.600' }}
/>
<Box>{t('common:common.Delete')}</Box>

View File

@@ -47,7 +47,7 @@ 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';
import Markdown from '@/components/Markdown';
const DataCard = () => {
const BoxRef = useRef<HTMLDivElement>(null);
@@ -232,6 +232,7 @@ const DataCard = () => {
setEditDataId(item._id);
}}
>
{/* Data tag */}
<Flex
position={'absolute'}
zIndex={1}
@@ -259,53 +260,18 @@ const DataCard = () => {
ID:{item._id}
</Box>
</MyTag>
{/* {item.forbid ? (
<MyTag colorSchema="gray" bg={'transparent'} px={1} showDot>
{datasetT('Disabled')}
</MyTag>
) : (
<MyTag colorSchema="green" bg={'transparent'} px={1} showDot>
{datasetT('Enabled')}
</MyTag>
)}
<HStack
borderLeftWidth={'1.5px'}
className="forbid-switch"
display={['flex', 'none']}
borderLeftColor={'myGray.200'}
pl={1}
onClick={(e) => {
e.stopPropagation();
}}
h={'12px'}
>
<Switch
size={'sm'}
isChecked={!item.forbid}
onChange={(e) => {
e.stopPropagation();
onUpdate({
dataId: item._id,
forbid: !e.target.checked
});
}}
/>
</HStack> */}
</Flex>
<Box
maxH={'135px'}
minH={'90px'}
overflow={'hidden'}
wordBreak={'break-all'}
pt={1}
pb={3}
fontSize={'sm'}
>
<Box color={'black'} mb={1}>
{item.q}
{/* Data content */}
<Box wordBreak={'break-all'} fontSize={'sm'}>
<Markdown source={item.q} forbidImgPreview />
{!!item.a && (
<>
<MyDivider />
<Markdown source={item.a} forbidImgPreview />
</>
)}
</Box>
<Box color={'myGray.700'}>{item.a}</Box>
{/* Mask */}
<Flex
@@ -349,7 +315,7 @@ const DataCard = () => {
display={'flex'}
p={1}
boxShadow={'1'}
icon={<MyIcon name={'common/trash'} w={'14px'} color={'myGray.600'} />}
icon={<MyIcon name={'common/trash'} w={'14px'} />}
variant={'whiteDanger'}
size={'xsSquare'}
aria-label={'delete'}
@@ -370,7 +336,6 @@ const DataCard = () => {
/>
)}
</Flex>
</Box>
</Card>
))}
</Flex>

View File

@@ -1,7 +1,6 @@
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';
import { Box, Flex, Input } from '@chakra-ui/react';
import { delDatasetById } from '@/web/core/dataset/api';
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
@@ -9,7 +8,6 @@ import { useForm } from 'react-hook-form';
import { compressImgFileAndUpload } from '@/web/common/file/controller';
import type { DatasetItemType } from '@fastgpt/global/core/dataset/type.d';
import Avatar from '@fastgpt/web/components/common/Avatar';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useTranslation } from 'next-i18next';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
@@ -56,7 +54,6 @@ const Info = ({ datasetId }: { datasetId: string }) => {
defaultValues: datasetDetail
});
const avatar = watch('avatar');
const vectorModel = watch('vectorModel');
const agentModel = watch('agentModel');
const defaultPermission = watch('defaultPermission');
@@ -77,8 +74,20 @@ const Info = ({ datasetId }: { datasetId: string }) => {
multiple: false
});
const { mutate: onSave, isLoading: isSaving } = useRequest({
mutationFn: (data: DatasetItemType) => {
/* 点击删除 */
const { mutate: onclickDelete, isLoading: isDeleting } = useRequest({
mutationFn: () => {
return delDatasetById(datasetId);
},
onSuccess() {
router.replace(`/dataset/list`);
},
successToast: t('common:common.Delete Success'),
errorToast: t('common:common.Delete Failed')
});
const { runAsync: onSave, loading: isSaving } = useRequest2(
(data: DatasetItemType) => {
return updateDataset({
id: datasetId,
agentModel: data.agentModel,
@@ -86,12 +95,14 @@ const Info = ({ datasetId }: { datasetId: string }) => {
defaultPermission: data.defaultPermission
});
},
{
successToast: t('common:common.Update Success'),
errorToast: t('common:common.Update Failed')
});
}
);
const { mutate: onSelectFile, isLoading: isSelecting } = useRequest({
mutationFn: (e: File[]) => {
const { runAsync: onSelectFile, loading: isSelecting } = useRequest2(
(e: File[]) => {
const file = e[0];
if (!file) return Promise.resolve(null);
return compressImgFileAndUpload({
@@ -101,37 +112,41 @@ const Info = ({ datasetId }: { datasetId: string }) => {
maxH: 300
});
},
{
onSuccess(src: string | null) {
if (src) {
setValue('avatar', src);
}
},
errorToast: t('common:common.avatar.Select Failed')
});
}
);
const { mutate: onRebuilding, isLoading: isRebuilding } = useRequest({
mutationFn: (vectorModel: VectorModelItemType) => {
const { runAsync: onRebuilding, loading: isRebuilding } = useRequest2(
(vectorModel: VectorModelItemType) => {
return postRebuildEmbedding({
datasetId,
vectorModel: vectorModel.model
});
},
{
onSuccess() {
refetchDatasetTraining();
loadDatasetDetail(datasetId);
},
successToast: t('dataset:rebuild_embedding_start_tip'),
errorToast: t('common:common.Update Failed')
});
}
);
const { runAsync: onEditBaseInfo } = useRequest2((data) => updateDataset(data), {
manual: true,
const { runAsync: onEditBaseInfo } = useRequest2(updateDataset, {
onSuccess() {
setEditedDataset(undefined);
},
successToast: t('common:common.Update Success'),
errorToast: t('common:common.Update Failed')
});
const totalLoading = isSelecting || isSaving || isRebuilding;
return (
<Box w={'100%'} h={'100%'} p={6}>
<Box>
@@ -225,7 +240,7 @@ const Info = ({ datasetId }: { datasetId: string }) => {
if (!vectorModel) return;
return onOpenConfirmRebuild(() => {
setValue('vectorModel', vectorModel);
onRebuilding(vectorModel);
return onRebuilding(vectorModel);
})();
}}
/>
@@ -260,7 +275,6 @@ const Info = ({ datasetId }: { datasetId: string }) => {
setValue('agentModel', agentModel);
return handleSubmit((data) => onSave({ ...data, agentModel: agentModel }))();
}}
isDisabled={totalLoading}
/>
</Box>
</Box>
@@ -311,7 +325,6 @@ const Info = ({ datasetId }: { datasetId: string }) => {
fontSize={'mini'}
per={defaultPermission}
defaultPer={DatasetDefaultPermissionVal}
isDisabled={totalLoading}
onChange={(v) => {
setValue('defaultPermission', v);
return handleSubmit((data) => onSave({ ...data, defaultPermission: v }))();
@@ -349,18 +362,15 @@ const Info = ({ datasetId }: { datasetId: string }) => {
<EditResourceModal
{...editedDataset}
title={t('common:dataset.Edit Info')}
onClose={() => {
setEditedDataset(undefined);
}}
onEdit={async (data) => {
await onEditBaseInfo({
onClose={() => setEditedDataset(undefined)}
onEdit={(data) =>
onEditBaseInfo({
id: editedDataset.id,
name: data.name,
intro: data.intro,
avatar: data.avatar
});
setEditedDataset(undefined);
}}
})
}
/>
)}
</Box>

View File

@@ -115,7 +115,7 @@ const NavBar = ({ currentTab }: { currentTab: TabEnum }) => {
w={'100%'}
list={tabList}
value={currentTab}
activatedColor="blue.700"
activeColor="primary.700"
onChange={setCurrentTab}
inlineStyles={{
fontSize: '1rem',
@@ -193,7 +193,7 @@ const NavBar = ({ currentTab }: { currentTab: TabEnum }) => {
</MyPopover>
</Flex>
) : (
<Box mb={3}>
<Box mb={2}>
<LightRowTabs<TabEnum>
m={'auto'}
w={'full'}

View File

@@ -4,7 +4,7 @@ import { useDatasetStore } from '@/web/core/dataset/store/dataset';
import { useSearchTestStore, SearchTestStoreItemType } from '@/web/core/dataset/store/searchTest';
import { postSearchText } from '@/web/core/dataset/api';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { useRequest } from '@fastgpt/web/hooks/useRequest';
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
import { getErrText } from '@fastgpt/global/common/error/utils';
import { useToast } from '@fastgpt/web/hooks/useToast';
@@ -48,7 +48,6 @@ type FormType = {
const Test = ({ datasetId }: { datasetId: string }) => {
const { t } = useTranslation();
const theme = useTheme();
const { toast } = useToast();
const { llmModelList } = useSystemStore();
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
@@ -86,9 +85,10 @@ const Test = ({ datasetId }: { datasetId: string }) => {
onClose: onCloseSelectMode
} = useDisclosure();
const { mutate: onTextTest, isLoading: textTestIsLoading } = useRequest({
mutationFn: ({ inputText, searchParams }: FormType) =>
const { runAsync: onTextTest, loading: textTestIsLoading } = useRequest2(
({ inputText, searchParams }: FormType) =>
postSearchText({ datasetId, text: inputText.trim(), ...searchParams }),
{
onSuccess(res: SearchTestResponse) {
if (!res || res.list.length === 0) {
return toast({
@@ -119,7 +119,8 @@ const Test = ({ datasetId }: { datasetId: string }) => {
status: 'error'
});
}
});
}
);
const onSelectFile = async (files: File[]) => {
const file = files[0];
@@ -329,6 +330,7 @@ const TestHistories = React.memo(function TestHistories({
() => datasetTestList.filter((item) => item.datasetId === datasetId),
[datasetId, datasetTestList]
);
return (
<>
<Flex alignItems={'center'} color={'myGray.900'}>

View File

@@ -1,8 +1,7 @@
import React from 'react';
import { useRouter } from 'next/router';
import { Box, Flex } from '@chakra-ui/react';
import { Box, Flex, FlexProps } 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';
import dynamic from 'next/dynamic';
import PageContainer from '@/components/PageContainer';
@@ -36,6 +35,13 @@ export enum TabEnum {
}
type Props = { datasetId: string; currentTab: TabEnum };
const sliderStyles: FlexProps = {
bg: 'white',
borderRadius: 'md',
overflowY: 'scroll',
boxShadow: 2
};
const Detail = ({ datasetId, currentTab }: Props) => {
const { t } = useTranslation();
const { toast } = useToast();
@@ -64,20 +70,10 @@ const Detail = ({ datasetId, currentTab }: Props) => {
<NextHead title={datasetDetail?.name} icon={datasetDetail?.avatar} />
{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'}
>
<Flex h={'100%'} py={3} pl={1} pr={3} gap={2}>
<Flex flex={1} w={0} bg={'white'} flexDir={'column'} boxShadow={'2'} borderRadius={'md'}>
{currentTab !== TabEnum.import && <NavBar currentTab={currentTab} />}
<Box flex={'1 0 0'} w={'100%'} overflow={'auto'}>
<Box flex={'1'} overflow={'auto'}>
{currentTab === TabEnum.collectionCard && (
<CollectionPageContextProvider>
<CollectionCard />
@@ -88,27 +84,24 @@ const Detail = ({ datasetId, currentTab }: Props) => {
{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 ? (
{/* Slider */}
<>
{currentTab === TabEnum.dataCard && (
<Flex {...sliderStyles} flex={'0 0 20rem'}>
<MetaDataCard datasetId={datasetId} />
) : (
<Info datasetId={datasetId} />
)}
</Flex>
)}
{[TabEnum.collectionCard, TabEnum.test].includes(currentTab) && (
<Flex {...sliderStyles} flex={'0 0 17rem'}>
<Info datasetId={datasetId} />
</Flex>
)}
</>
</Flex>
) : (
<PageContainer insertProps={{ bg: 'white' }}>
<MyBox display={'flex'} flexDirection={['column', 'row']} h={'100%'} pt={[4, 0]}>
<MyBox display={'flex'} flexDirection={'column'} h={'100%'} pt={1}>
<NavBar currentTab={currentTab} />
{!!datasetDetail._id && (

View File

@@ -120,7 +120,7 @@ export const putDatasetCollectionById = (data: UpdateDatasetCollectionParams) =>
export const delDatasetCollectionById = (params: { id: string }) =>
DELETE(`/core/dataset/collection/delete`, params);
export const postLinkCollectionSync = (collectionId: string) =>
POST<`${DatasetCollectionSyncResultEnum}`>(`/core/dataset/collection/sync/link`, {
POST<DatasetCollectionSyncResultEnum>(`/core/dataset/collection/sync/link`, {
collectionId
});