mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-27 00:17:31 +00:00
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:
@@ -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');
|
||||
|
@@ -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)}
|
||||
/>
|
||||
|
@@ -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 (
|
||||
|
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user