dataset inheritance permission (#2151)

* refactor: dataset create and update api

* chore: defaultpermission & resume fe

* refactor: database auth

* fix(ts): add inheritPermission into default data types

* chore: adjust the code

* fix: list api type filter

* fix: query condition
This commit is contained in:
Finley Ge
2024-07-25 19:03:24 +08:00
committed by GitHub
parent 5906daff9f
commit 65515e7952
20 changed files with 481 additions and 199 deletions

View File

@@ -20,7 +20,6 @@ import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants'
import AIModelSelector from '@/components/Select/AIModelSelector';
import { useI18n } from '@/web/context/I18n';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import { DatasetDefaultPermissionVal } from '@fastgpt/global/support/permission/dataset/constant';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: string }) => {
@@ -41,8 +40,7 @@ const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: st
name: '',
intro: '',
vectorModel: filterNotHiddenVectorModelList[0].model,
agentModel: datasetModelList[0].model,
defaultPermission: DatasetDefaultPermissionVal
agentModel: datasetModelList[0].model
}
});
const avatar = watch('avatar');

View File

@@ -1,5 +1,5 @@
import React, { useMemo, useRef, useState } from 'react';
import { putDatasetById } from '@/web/core/dataset/api';
import { resumeInheritPer } from '@/web/core/dataset/api';
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
import { Box, Flex, Grid } from '@chakra-ui/react';
import { DatasetTypeEnum, DatasetTypeMap } from '@fastgpt/global/core/dataset/constants';
@@ -42,16 +42,16 @@ function List() {
const { t } = useTranslation();
const { commonT } = useI18n();
const {
refetchDatasets,
loadMyDatasets,
setMoveDatasetId,
refetchPaths,
refetchFolderDetail,
editedDataset,
setEditedDataset,
onDelDataset
onDelDataset,
onUpdateDataset,
myDatasets
} = useContextSelector(DatasetsContext, (v) => v);
const [editPerDatasetIndex, setEditPerDatasetIndex] = useState<number>();
const { myDatasets, loadMyDatasets } = useDatasetStore();
const [loadingDatasetId, setLoadingDatasetId] = useState<string>();
const { getBoxProps } = useFolderDrag({
@@ -61,11 +61,10 @@ function List() {
onDrop: async (dragId: string, targetId: string) => {
setLoadingDatasetId(dragId);
try {
await putDatasetById({
await onUpdateDataset({
id: dragId,
parentId: targetId
});
refetchDatasets();
} catch (error) {}
setLoadingDatasetId(undefined);
}
@@ -132,7 +131,7 @@ function List() {
() =>
onDelDataset(id).then(() => {
refetchPaths();
refetchDatasets();
loadMyDatasets();
}),
undefined,
DeleteTipsMap.current[DatasetTypeEnum.dataset]
@@ -350,15 +349,12 @@ function List() {
title={commonT('dataset.Edit Info')}
onClose={() => setEditedDataset(undefined)}
onEdit={async (data) => {
await putDatasetById({
await onUpdateDataset({
id: editedDataset.id,
name: data.name,
intro: data.intro,
avatar: data.avatar
});
loadMyDatasets(parentId ? parentId : undefined);
refetchFolderDetail();
refetchPaths();
setEditedDataset(undefined);
}}
/>
@@ -366,18 +362,22 @@ function List() {
{!!editPerDataset && (
<ConfigPerModal
hasParent={!!parentId}
refetchResource={loadMyDatasets}
isInheritPermission={editPerDataset.inheritPermission}
resumeInheritPermission={() =>
resumeInheritPer(editPerDataset._id).then(() => Promise.all([loadMyDatasets()]))
}
avatar={editPerDataset.avatar}
name={editPerDataset.name}
defaultPer={{
value: editPerDataset.defaultPermission,
defaultValue: DatasetDefaultPermissionVal,
onChange: async (e) => {
await putDatasetById({
onChange: (e) =>
onUpdateDataset({
id: editPerDataset._id,
defaultPermission: e
});
refetchDatasets();
}
})
}}
managePer={{
permission: editPerDataset.permission,
@@ -400,7 +400,8 @@ function List() {
deleteDatasetCollaborators({
datasetId: editPerDataset._id,
tmbId
})
}),
refreshDeps: [editPerDataset._id, editPerDataset.inheritPermission]
}}
onClose={() => setEditPerDatasetIndex(undefined)}
/>

View File

@@ -5,7 +5,6 @@ import {
getDatasetById,
delDatasetById
} from '@/web/core/dataset/api';
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
import {
GetResourceFolderListProps,
ParentIdType,
@@ -19,16 +18,17 @@ import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { DatasetUpdateBody } from '@fastgpt/global/core/dataset/api';
import dynamic from 'next/dynamic';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { DatasetItemType } from '@fastgpt/global/core/dataset/type';
import { DatasetItemType, DatasetListItemType } from '@fastgpt/global/core/dataset/type';
import { EditResourceInfoFormType } from '@/components/common/Modal/EditResourceModal';
import { useTranslation } from 'react-i18next';
const MoveModal = dynamic(() => import('@/components/common/folder/MoveModal'));
export type DatasetContextType = {
refetchDatasets: () => void;
myDatasets: DatasetListItemType[];
loadMyDatasets: () => Promise<DatasetListItemType[]>;
refetchPaths: () => void;
refetchFolderDetail: () => void;
refetchFolderDetail: () => Promise<DatasetItemType | undefined>;
isFetchingDatasets: boolean;
setMoveDatasetId: (id: string) => void;
paths: ParentTreePathItemType[];
@@ -36,28 +36,48 @@ export type DatasetContextType = {
editedDataset?: EditResourceInfoFormType;
setEditedDataset: (data?: EditResourceInfoFormType) => void;
onDelDataset: (id: string) => Promise<void>;
onUpdateDataset: (data: DatasetUpdateBody) => Promise<void>;
};
export const DatasetsContext = createContext<DatasetContextType>({
refetchDatasets: () => {},
isFetchingDatasets: false,
setMoveDatasetId: () => {},
refetchPaths: () => {},
paths: [],
refetchFolderDetail: () => {},
folderDetail: {} as any,
editedDataset: {} as any,
setEditedDataset: () => {},
onDelDataset: () => Promise.resolve()
onDelDataset: () => Promise.resolve(),
loadMyDatasets: function (): Promise<DatasetListItemType[]> {
throw new Error('Function not implemented.');
},
refetchFolderDetail: function (): Promise<DatasetItemType | undefined> {
throw new Error('Function not implemented.');
},
onUpdateDataset: function (_data: DatasetUpdateBody): Promise<void> {
throw new Error('Function not implemented.');
},
myDatasets: []
});
function DatasetContextProvider({ children }: { children: React.ReactNode }) {
const router = useRouter();
const { commonT } = useI18n();
const { t } = useTranslation();
const [moveDatasetId, setMoveDatasetId] = useState<string>();
const { parentId = null } = router.query as { parentId?: string | null };
const { myDatasets, loadMyDatasets } = useDatasetStore();
const { data: myDatasets = [], runAsync: loadMyDatasets } = useRequest2(
() =>
getDatasets({
parentId
}),
{
manual: false,
refreshDeps: [parentId]
}
);
const { data: folderDetail, runAsync: refetchFolderDetail } = useRequest2(
() => (parentId ? getDatasetById(parentId) : Promise.resolve(undefined)),
@@ -66,17 +86,6 @@ function DatasetContextProvider({ children }: { children: React.ReactNode }) {
refreshDeps: [parentId, myDatasets]
}
);
const getDatasetFolderList = useCallback(({ parentId }: GetResourceFolderListProps) => {
return getDatasets({
parentId,
type: DatasetTypeEnum.folder
}).then((res) => {
return res.map((item) => ({
id: item._id,
name: item.name
}));
});
}, []);
const { data: paths = [], runAsync: refetchPaths } = useRequest2(
() => getDatasetPaths(parentId),
@@ -87,21 +96,16 @@ function DatasetContextProvider({ children }: { children: React.ReactNode }) {
);
const { runAsync: refetchDatasets, loading: isFetchingDatasets } = useRequest2(
() => loadMyDatasets(parentId ?? undefined),
() => loadMyDatasets(),
{
manual: false,
refreshDeps: [parentId]
}
);
const [moveDatasetId, setMoveDatasetId] = useState<string>();
const { runAsync: onUpdateDataset } = useRequest2((data: DatasetUpdateBody) =>
putDatasetById(data).then(async (res) => {
await Promise.all([refetchDatasets(), refetchPaths()]);
return res;
})
);
const { runAsync: onUpdateDataset } = useRequest2(putDatasetById, {
onSuccess: () => Promise.all([refetchDatasets(), refetchPaths(), loadMyDatasets()])
});
const onMoveDataset = useCallback(
async (parentId: ParentIdType) => {
@@ -114,6 +118,18 @@ function DatasetContextProvider({ children }: { children: React.ReactNode }) {
[moveDatasetId, onUpdateDataset]
);
const getDatasetFolderList = useCallback(async ({ parentId }: GetResourceFolderListProps) => {
return (
await getDatasets({
parentId,
type: DatasetTypeEnum.folder
})
).map((item) => ({
id: item._id,
name: item.name
}));
}, []);
const [editedDataset, setEditedDataset] = useState<EditResourceInfoFormType>();
const { runAsync: onDelDataset } = useRequest2(delDatasetById, {
@@ -131,7 +147,10 @@ function DatasetContextProvider({ children }: { children: React.ReactNode }) {
folderDetail,
editedDataset,
setEditedDataset,
onDelDataset
onDelDataset,
onUpdateDataset,
myDatasets,
loadMyDatasets
};
return (

View File

@@ -5,7 +5,6 @@ import PageContainer from '@/components/PageContainer';
import { useTranslation } from 'next-i18next';
import { serviceSideProps } from '@/web/common/utils/i18n';
import ParentPaths from '@/components/common/folder/Path';
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
import List from './component/List';
import { DatasetsContext } from './context';
import DatasetContextProvider from './context';
@@ -14,13 +13,11 @@ import MyMenu from '@fastgpt/web/components/common/MyMenu';
import { AddIcon } from '@chakra-ui/icons';
import { useUserStore } from '@/web/support/user/useUserStore';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { FolderIcon, FolderImgUrl } from '@fastgpt/global/common/file/image/constants';
import { FolderIcon } from '@fastgpt/global/common/file/image/constants';
import { EditFolderFormType } from '@fastgpt/web/components/common/MyModal/EditFolderModal';
import dynamic from 'next/dynamic';
import { postCreateDataset, putDatasetById } from '@/web/core/dataset/api';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { postCreateDatasetFolder, resumeInheritPer } from '@/web/core/dataset/api';
import FolderSlideCard from '@/components/common/folder/SlideCard';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import {
DatasetDefaultPermissionVal,
DatasetPermissionList
@@ -44,17 +41,18 @@ const Dataset = () => {
const router = useRouter();
const { parentId } = router.query as { parentId: string };
const { myDatasets } = useDatasetStore();
const {
myDatasets,
paths,
isFetchingDatasets,
refetchPaths,
refetchDatasets,
loadMyDatasets,
refetchFolderDetail,
folderDetail,
setEditedDataset,
setMoveDatasetId,
onDelDataset
onDelDataset,
onUpdateDataset
} = useContextSelector(DatasetsContext, (v) => v);
const { userInfo } = useUserStore();
@@ -139,7 +137,11 @@ const Dataset = () => {
{!!folderDetail && isPc && (
<Box ml="6">
<FolderSlideCard
refreshDeps={[folderDetail._id]}
resumeInheritPermission={() => resumeInheritPer(folderDetail._id)}
isInheritPermission={folderDetail.inheritPermission}
hasParent={!!folderDetail.parentId}
refetchResource={() => Promise.all([refetchFolderDetail(), loadMyDatasets()])}
refreshDeps={[folderDetail._id, folderDetail.inheritPermission]}
name={folderDetail.name}
intro={folderDetail.intro}
onEdit={() => {
@@ -165,7 +167,7 @@ const Dataset = () => {
value: folderDetail.defaultPermission,
defaultValue: DatasetDefaultPermissionVal,
onChange: (e) => {
return putDatasetById({
return onUpdateDataset({
id: folderDetail._id,
defaultPermission: e
});
@@ -192,7 +194,8 @@ const Dataset = () => {
deleteDatasetCollaborators({
datasetId: folderDetail._id,
tmbId
})
}),
refreshDeps: [folderDetail._id, folderDetail.inheritPermission]
}}
/>
</Box>
@@ -202,16 +205,14 @@ const Dataset = () => {
{!!editFolderData && (
<EditFolderModal
onClose={() => setEditFolderData(undefined)}
onCreate={async ({ name }) => {
onCreate={async ({ name, intro }) => {
try {
await postCreateDataset({
await postCreateDatasetFolder({
parentId: parentId || undefined,
name,
type: DatasetTypeEnum.folder,
avatar: FolderImgUrl,
intro: ''
intro: intro ?? ''
});
refetchDatasets();
loadMyDatasets();
refetchPaths();
} catch (error) {
return Promise.reject(error);
@@ -219,13 +220,11 @@ const Dataset = () => {
}}
onEdit={async ({ name, intro, id }) => {
try {
await putDatasetById({
await onUpdateDataset({
id,
name,
intro
});
refetchDatasets();
refetchPaths();
} catch (error) {
return Promise.reject(error);
}