Commit 4a33e04a by Finley Ge Committed by GitHub

Dataset frontend style adjusting (#1820)

* feat: dataset controllers

feat: dataset schema

fix: add missing type to dataset schema
Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: use new auth method

Signed-off-by: FinleyGe <m13203533462@163.com>

* feat: finish the dataset permission

fix: ts errors
Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: adjust the code

* chore: adjust the code

* chore: dataset fe adjusting

* fix: double delete confirm

---------

Signed-off-by: FinleyGe <m13203533462@163.com>
parent a9ab9ebe
......@@ -15,11 +15,11 @@
"@chakra-ui/cli": "^2.4.1",
"husky": "^8.0.3",
"i18next": "23.10.0",
"lint-staged": "^13.2.1",
"lint-staged": "^13.3.0",
"next-i18next": "15.2.0",
"prettier": "3.2.4",
"react-i18next": "13.5.0",
"zhlint": "^0.7.1"
"zhlint": "^0.7.4"
},
"lint-staged": {
"./**/**/*.{ts,tsx,scss}": "npm run format-code",
......
import { DatasetDataIndexItemType, DatasetSchemaType } from './type';
import { TrainingModeEnum, DatasetCollectionTypeEnum } from './constants';
import type { LLMModelItemType } from '../ai/model.d';
import { ParentIdType } from 'common/parentFolder/type';
/* ================= dataset ===================== */
export type DatasetUpdateBody = {
id: string;
parentId?: string;
parentId?: ParentIdType;
name?: string;
avatar?: string;
intro?: string;
......
......@@ -1128,6 +1128,7 @@
"Create Folder": "Create Folder",
"Create manual collection": "Create manual collection",
"Delete Dataset Error": "Delete Dataset Error",
"Edit Info": "Edit Information",
"Edit Folder": "Edit Folder",
"Export": "Export",
"Export Dataset Limit Error": "Export Dataset Error",
......
......@@ -1137,6 +1137,7 @@
"Create Folder": "创建文件夹",
"Create manual collection": "创建手动数据集",
"Delete Dataset Error": "删除知识库异常",
"Edit Info": "编辑信息",
"Edit Folder": "编辑文件夹",
"Export": "导出",
"Export Dataset Limit Error": "导出数据失败",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -12,6 +12,7 @@ import {
} from '@fastgpt/global/support/permission/constant';
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
import { parseParentIdInMongo } from '@fastgpt/global/common/parentFolder/utils';
import { DatasetDefaultPermission } from '@fastgpt/global/support/permission/dataset/constant';
async function handler(req: NextApiRequest) {
const { parentId, type } = req.query as { parentId?: string; type?: DatasetTypeEnum };
......@@ -71,7 +72,7 @@ async function handler(req: NextApiRequest) {
type: item.type,
permission: item.permission,
vectorModel: getVectorModel(item.vectorModel),
defaultPermission: item.defaultPermission
defaultPermission: item.defaultPermission ?? DatasetDefaultPermission
}))
);
......
......@@ -59,7 +59,7 @@ const Detail = ({ datasetId, currentTab }: Props) => {
<Slider currentTab={currentTab} />
{!!datasetDetail._id && (
<Box flex={'1 0 0'} pb={0}>
<Box flex={'1 0 0'} pb={0} overflow={'auto'}>
{currentTab === TabEnum.collectionCard && (
<CollectionPageContextProvider>
<CollectionCard />
......
import { getDatasetPaths } from '@/web/core/dataset/api';
import { getDatasetPaths, putDatasetById } from '@/web/core/dataset/api';
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
import { getErrText } from '@fastgpt/global/common/error/utils';
import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'next-i18next';
import {
GetResourceFolderListProps,
ParentIdType,
ParentTreePathItemType
} from '@fastgpt/global/common/parentFolder/type';
import { useRouter } from 'next/router';
import React from 'react';
import React, { useCallback, useState } from 'react';
import { createContext } from 'use-context-selector';
import { useI18n } from '@/web/context/I18n';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { DatasetUpdateBody } from '@fastgpt/global/core/dataset/api';
import dynamic from 'next/dynamic';
const MoveModal = dynamic(() => import('@/components/common/folder/MoveModal'));
export type DatasetContextType = {
refetch: () => void;
isFetching: boolean;
refetchDatasets: () => void;
refetchPaths: () => void;
isFetchingDatasets: boolean;
setMoveDatasetId: (id: string) => void;
paths: ParentTreePathItemType[];
};
export const DatasetContext = createContext<DatasetContextType>({
refetch: () => {},
isFetching: false,
refetchDatasets: () => {},
isFetchingDatasets: false,
setMoveDatasetId: () => {},
refetchPaths: () => {},
paths: []
});
function DatasetContextProvider({ children }: { children: React.ReactNode }) {
const router = useRouter();
const { toast } = useToast();
const { t } = useTranslation();
const { commonT } = useI18n();
const { parentId } = router.query as { parentId: string };
const { parentId = null } = router.query as { parentId?: string | null };
const { loadMyDatasets } = useDatasetStore();
const { data, refetch, isFetching } = useQuery(
['loadDataset', parentId],
() => {
return Promise.all([loadMyDatasets(parentId), getDatasetPaths(parentId)]);
},
const getDatasetFolderList = useCallback(async ({ parentId }: GetResourceFolderListProps) => {
const res = await getDatasetPaths(parentId);
return res.map((item) => ({
id: item.parentId,
name: item.parentName
}));
}, []);
const { data: paths = [], runAsync: refetchPaths } = useRequest2(
() => getDatasetPaths(parentId),
{
manual: false,
refreshDeps: [parentId]
}
);
const { runAsync: refetchDatasets, loading: isFetchingDatasets } = useRequest2(
() => loadMyDatasets(parentId ?? undefined),
{
onError(err) {
toast({
status: 'error',
title: t(getErrText(err))
});
}
manual: false,
refreshDeps: [parentId]
}
);
const paths = data?.[1] || [];
const [moveDatasetId, setMoveDatasetId] = useState<string>();
const { runAsync: onUpdateDataset } = useRequest2((data: DatasetUpdateBody) =>
putDatasetById(data).then(async (res) => {
await Promise.all([refetchDatasets(), refetchPaths()]);
return res;
})
);
const onMoveDataset = useCallback(
async (parentId: ParentIdType) => {
if (!moveDatasetId) return;
await onUpdateDataset({
id: moveDatasetId,
parentId
});
},
[moveDatasetId, onUpdateDataset]
);
const contextValue = {
refetch,
isFetching,
paths
refetchDatasets,
isFetchingDatasets,
setMoveDatasetId,
paths,
refetchPaths
};
return <DatasetContext.Provider value={contextValue}>{children}</DatasetContext.Provider>;
return (
<DatasetContext.Provider value={contextValue}>
{children}
{!!moveDatasetId && (
<MoveModal
moveResourceId={moveDatasetId}
server={getDatasetFolderList}
title={commonT('Move')}
onClose={() => setMoveDatasetId(undefined)}
onConfirm={onMoveDataset}
/>
)}
</DatasetContext.Provider>
);
}
export default DatasetContextProvider;
import React from 'react';
import { Box, Flex, useDisclosure, Image, Button } from '@chakra-ui/react';
import { Box, Flex, Image } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import PageContainer from '@/components/PageContainer';
import { AddIcon } from '@chakra-ui/icons';
import { postCreateDataset } from '@/web/core/dataset/api';
import { useTranslation } from 'next-i18next';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { serviceSideProps } from '@/web/common/utils/i18n';
import dynamic from 'next/dynamic';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { FolderImgUrl, FolderIcon } from '@fastgpt/global/common/file/image/constants';
import MyMenu from '@fastgpt/web/components/common/MyMenu';
import EditFolderModal, { useEditFolder } from '../component/EditFolderModal';
import { useUserStore } from '@/web/support/user/useUserStore';
import ParentPaths from '@/components/common/ParentPaths';
import ParentPaths from '@/components/common/folder/Path';
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
import List from './component/List';
import { DatasetContext } from './context';
import DatasetContextProvider from './context';
import { useContextSelector } from 'use-context-selector';
const CreateModal = dynamic(() => import('./component/CreateModal'), { ssr: false });
const Dataset = () => {
const { t } = useTranslation();
const router = useRouter();
const { userInfo } = useUserStore();
const { myDatasets } = useDatasetStore();
const { parentId } = router.query as { parentId: string };
const {
isOpen: isOpenCreateModal,
onOpen: onOpenCreateModal,
onClose: onCloseCreateModal
} = useDisclosure();
const { editFolderData, setEditFolderData } = useEditFolder();
const { paths, refetch, isFetching } = useContextSelector(DatasetContext, (v) => v);
const { paths, isFetchingDatasets } = useContextSelector(DatasetContext, (v) => v);
return (
<PageContainer
isLoading={myDatasets.length === 0 && isFetching}
isLoading={myDatasets.length === 0 && isFetchingDatasets}
insertProps={{ px: [5, '48px'] }}
>
<Flex pt={[4, '30px']} alignItems={'center'} justifyContent={'space-between'}>
{/* url path */}
<ParentPaths
paths={paths.map((path) => ({
parentId: path.parentId,
parentName: path.parentName
}))}
paths={paths}
FirstPathDom={
<Flex flex={1} alignItems={'center'}>
<Image src={'/imgs/workflow/db.png'} alt={''} mr={2} h={'24px'} />
......@@ -66,68 +43,8 @@ const Dataset = () => {
});
}}
/>
{/* create icon */}
{userInfo?.team?.permission.hasWritePer && (
<MyMenu
offset={[-30, 5]}
width={120}
Button={
<Button variant={'primaryOutline'} px={0}>
<Flex alignItems={'center'} px={'20px'}>
<AddIcon mr={2} />
<Box>{t('common.Create New')}</Box>
</Flex>
</Button>
}
menuList={[
{
children: [
{
label: (
<Flex>
<MyIcon name={FolderIcon} w={'20px'} mr={1} />
{t('Folder')}
</Flex>
),
onClick: () => setEditFolderData({})
},
{
label: (
<Flex>
<Image src={'/imgs/workflow/db.png'} alt={''} w={'20px'} mr={1} />
{t('core.dataset.Dataset')}
</Flex>
),
onClick: onOpenCreateModal
}
]
}
]}
/>
)}
</Flex>
<List />
{isOpenCreateModal && <CreateModal onClose={onCloseCreateModal} parentId={parentId} />}
{!!editFolderData && (
<EditFolderModal
onClose={() => setEditFolderData(undefined)}
editCallback={async (name) => {
try {
await postCreateDataset({
parentId,
name,
type: DatasetTypeEnum.folder,
avatar: FolderImgUrl,
intro: ''
});
refetch();
} catch (error) {
return Promise.reject(error);
}
}}
isEdit={false}
/>
)}
</PageContainer>
);
};
......
import { GET, POST, PUT, DELETE } from '@/web/common/api/request';
import type { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type.d';
import type {
ParentIdType,
ParentTreePathItemType
} from '@fastgpt/global/common/parentFolder/type.d';
import type {
DatasetItemType,
DatasetListItemType,
......@@ -56,7 +59,7 @@ export const getDatasets = (data: { parentId?: string; type?: DatasetTypeEnum })
*/
export const getAllDataset = () => GET<DatasetSimpleItemType[]>(`/core/dataset/allDataset`);
export const getDatasetPaths = (parentId?: string) =>
export const getDatasetPaths = (parentId: ParentIdType) =>
GET<ParentTreePathItemType[]>('/core/dataset/paths', { parentId });
export const getDatasetById = (id: string) => GET<DatasetItemType>(`/core/dataset/detail?id=${id}`);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment