mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-21 11:43:56 +00:00
Move app owner (#2280)
* feat: app owner change (#2271) * feat(app): changeOwner api * feat: changeOwner api * feat: ChangeOwnerModal * feat: update change owner api * chore: move change owner api into pro version feat(fe): change owner modal * feat: add change owner button and modal to InfoModal * change owner ux * feat: doc * perf: remove info change owner btn --------- Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
This commit is contained in:
@@ -36,13 +36,14 @@ curl --location --request POST 'https://{{host}}/api/admin/init/489' \
|
||||
4. 商业版新增 - 团队通知账号绑定,用于接收重要信息。
|
||||
5. 商业版新增 - 知识库集合标签功能,可以对知识库进行标签管理。
|
||||
6. 商业版新增 - 知识库搜索节点支持标签过滤和创建时间过滤。
|
||||
7. 新增 - 删除所有对话引导内容。
|
||||
8. 优化 - 对话框信息懒加载,减少网络传输。
|
||||
9. 优化 - 清除选文件缓存,支持重复选择同一个文件。
|
||||
10. 修复 - 知识库上传文件,网络不稳定或文件较多情况下,进度无法到 100%。
|
||||
11. 修复 - 删除应用后回到聊天选择最后一次对话的应用为删除的应用时提示无该应用问题。
|
||||
12. 修复 - 插件动态变量配置默认值时,无法正常显示默认值。
|
||||
13. 修复 - 工具调用温度和最大回复值未生效。
|
||||
14. 修复 - 函数调用模式,assistant role 中,GPT 模型必须传入 content 参数。(不影响大部分模型,目前基本都改用用 ToolChoice 模式,FC 模式已弃用)。
|
||||
15. 修复 - 知识库文件上传进度更新可能异常。
|
||||
16. 修复 - 知识库 rebuilding 时候,页面总是刷新到第一页。
|
||||
7. 商业版新增 - 转移 App owner 权限。
|
||||
8. 新增 - 删除所有对话引导内容。
|
||||
9. 优化 - 对话框信息懒加载,减少网络传输。
|
||||
10. 优化 - 清除选文件缓存,支持重复选择同一个文件。
|
||||
11. 修复 - 知识库上传文件,网络不稳定或文件较多情况下,进度无法到 100%。
|
||||
12. 修复 - 删除应用后回到聊天选择最后一次对话的应用为删除的应用时提示无该应用问题。
|
||||
13. 修复 - 插件动态变量配置默认值时,无法正常显示默认值。
|
||||
14. 修复 - 工具调用温度和最大回复值未生效。
|
||||
15. 修复 - 函数调用模式,assistant role 中,GPT 模型必须传入 content 参数。(不影响大部分模型,目前基本都改用用 ToolChoice 模式,FC 模式已弃用)。
|
||||
16. 修复 - 知识库文件上传进度更新可能异常。
|
||||
17. 修复 - 知识库 rebuilding 时候,页面总是刷新到第一页。
|
||||
|
@@ -3,7 +3,9 @@ import { i18nT } from '../../../../web/i18n/utils';
|
||||
/* dataset: 502000 */
|
||||
export enum AppErrEnum {
|
||||
unExist = 'appUnExist',
|
||||
unAuthApp = 'unAuthApp'
|
||||
unAuthApp = 'unAuthApp',
|
||||
invalidOwner = 'invalidOwner',
|
||||
invalidAppType = 'invalidAppType'
|
||||
}
|
||||
const appErrList = [
|
||||
{
|
||||
@@ -13,6 +15,14 @@ const appErrList = [
|
||||
{
|
||||
statusText: AppErrEnum.unAuthApp,
|
||||
message: i18nT('common:code_error.app_error.un_auth_app')
|
||||
},
|
||||
{
|
||||
statusText: AppErrEnum.invalidOwner,
|
||||
message: i18nT('common:code_error.app_error.invalid_owner')
|
||||
},
|
||||
{
|
||||
statusText: AppErrEnum.invalidAppType,
|
||||
message: i18nT('common:code_error.app_error.invalid_app_type')
|
||||
}
|
||||
];
|
||||
export default appErrList.reduce((acc, cur, index) => {
|
||||
|
@@ -34,6 +34,7 @@ export const iconPaths = {
|
||||
'common/language/en': () => import('./icons/common/language/en.svg'),
|
||||
'common/language/zh': () => import('./icons/common/language/zh.svg'),
|
||||
'common/leftArrowLight': () => import('./icons/common/leftArrowLight.svg'),
|
||||
'common/lineChange': () => import('./icons/common/lineChange.svg'),
|
||||
'common/linkBlue': () => import('./icons/common/linkBlue.svg'),
|
||||
'common/loading': () => import('./icons/common/loading.svg'),
|
||||
'common/logLight': () => import('./icons/common/logLight.svg'),
|
||||
@@ -241,6 +242,7 @@ export const iconPaths = {
|
||||
menu: () => import('./icons/menu.svg'),
|
||||
minus: () => import('./icons/minus.svg'),
|
||||
'modal/AddClb': () => import('./icons/modal/AddClb.svg'),
|
||||
'modal/changePer': () => import('./icons/modal/changePer.svg'),
|
||||
'modal/concat': () => import('./icons/modal/concat.svg'),
|
||||
'modal/confirmPay': () => import('./icons/modal/confirmPay.svg'),
|
||||
'modal/edit': () => import('./icons/modal/edit.svg'),
|
||||
|
@@ -0,0 +1,4 @@
|
||||
<svg viewBox="0 0 18 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.6688 0.977385C12.9942 0.651948 13.5219 0.651948 13.8473 0.977385L17.1446 4.27471C17.1531 4.28305 17.1613 4.29157 17.1693 4.30026C17.2353 4.37136 17.2865 4.45116 17.3231 4.53579C17.3669 4.63717 17.3912 4.74898 17.3912 4.86647C17.3912 4.98306 17.3673 5.09406 17.3241 5.19481C17.2868 5.28189 17.234 5.3639 17.1656 5.43664C17.1537 5.44941 17.1413 5.46179 17.1285 5.47378C17.0538 5.54406 16.9693 5.59796 16.8796 5.63546C16.7843 5.67534 16.6801 5.69805 16.5708 5.69971L16.5565 5.6998L4.39124 5.6998C3.931 5.6998 3.55791 5.32671 3.55791 4.86647C3.55791 4.40623 3.931 4.03314 4.39124 4.03314L14.5461 4.03314L12.6688 2.1559C12.3434 1.83046 12.3434 1.30282 12.6688 0.977385Z"/>
|
||||
<path d="M0.968656 8.54428C1.04865 8.46429 1.14086 8.40396 1.23928 8.36329C1.33521 8.32357 1.44016 8.30124 1.55022 8.30024L1.55791 8.30021H13.7246C14.1848 8.30021 14.5579 8.6733 14.5579 9.13354C14.5579 9.59378 14.1848 9.96687 13.7246 9.96687H3.56976L5.447 11.8441C5.77244 12.1696 5.77244 12.6972 5.447 13.0226C5.12156 13.3481 4.59392 13.3481 4.26849 13.0226L0.969527 9.72367L0.961458 9.71551C0.88513 9.63732 0.827247 9.54784 0.787811 9.45253C0.747067 9.35427 0.724579 9.24653 0.724579 9.13354C0.724579 9.02068 0.747013 8.91307 0.787665 8.81491C0.828333 8.71649 0.888664 8.62428 0.968656 8.54428Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="none">
|
||||
<path d="M13.6688 3.97738C13.9942 3.65195 14.5219 3.65195 14.8473 3.97738L18.1446 7.27471C18.1531 7.28305 18.1613 7.29157 18.1693 7.30026C18.2353 7.37136 18.2865 7.45116 18.3231 7.53579C18.3669 7.63717 18.3912 7.74898 18.3912 7.86647C18.3912 7.98306 18.3673 8.09406 18.3241 8.19481C18.2868 8.28189 18.234 8.3639 18.1656 8.43664C18.1537 8.44941 18.1413 8.46179 18.1285 8.47378C18.0538 8.54406 17.9693 8.59796 17.8796 8.63546C17.7843 8.67534 17.6801 8.69805 17.5708 8.69971L17.5565 8.6998L5.39124 8.6998C4.931 8.6998 4.55791 8.32671 4.55791 7.86647C4.55791 7.40623 4.931 7.03314 5.39124 7.03314L15.5461 7.03314L13.6688 5.1559C13.3434 4.83046 13.3434 4.30282 13.6688 3.97738Z" fill="#3370FF"/>
|
||||
<path d="M1.96866 11.5443C2.04865 11.4643 2.14086 11.404 2.23928 11.3633C2.33521 11.3236 2.44016 11.3012 2.55022 11.3002L2.55791 11.3002H14.7246C15.1848 11.3002 15.5579 11.6733 15.5579 12.1335C15.5579 12.5938 15.1848 12.9669 14.7246 12.9669H4.56976L6.447 14.8441C6.77244 15.1696 6.77244 15.6972 6.447 16.0226C6.12156 16.3481 5.59392 16.3481 5.26849 16.0226L1.96953 12.7237L1.96146 12.7155C1.88513 12.6373 1.82725 12.5478 1.78781 12.4525C1.74707 12.3543 1.72458 12.2465 1.72458 12.1335C1.72458 12.0207 1.74701 11.9131 1.78767 11.8149C1.82833 11.7165 1.88866 11.6243 1.96866 11.5443Z" fill="#3370FF"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@@ -60,7 +60,9 @@
|
||||
"code_error": {
|
||||
"app_error": {
|
||||
"not_exist": "应用不存在",
|
||||
"un_auth_app": "无权操作该应用"
|
||||
"un_auth_app": "无权操作该应用",
|
||||
"invalid_owner": "非法的应用所有者",
|
||||
"invalid_app_type": "错误的应用类型"
|
||||
},
|
||||
"chat_error": {
|
||||
"un_auth": "没有权限操作此对话记录"
|
||||
@@ -1095,7 +1097,13 @@
|
||||
"Remove InheritPermission Confirm": "此操作会导致权限继承失效,是否进行?",
|
||||
"Resume InheritPermission Confirm": "是否恢复为继承父级文件夹的权限?",
|
||||
"Resume InheritPermission Failed": "恢复失败",
|
||||
"Resume InheritPermission Success": "恢复成功"
|
||||
"Resume InheritPermission Success": "恢复成功",
|
||||
"change_owner": "转移所有权",
|
||||
"change_owner_to": "转移给",
|
||||
"change_owner_placeholder": "输入用户名查找账号",
|
||||
"change_owner_tip": "转移后将保留您的管理员权限",
|
||||
"change_owner_success": "成功转移所有权",
|
||||
"change_owner_failed": "转移所有权失败"
|
||||
},
|
||||
"plugin": {
|
||||
"App": "选择应用",
|
||||
|
@@ -0,0 +1,162 @@
|
||||
import { getTeamMembers } from '@/web/support/user/team/api';
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
HStack,
|
||||
Input,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
Button,
|
||||
useDisclosure
|
||||
} from '@chakra-ui/react';
|
||||
import { TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import Icon from '@fastgpt/web/components/common/Icon';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import MyTag from '@fastgpt/web/components/common/Tag';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export type ChangeOwnerModalProps = {
|
||||
avatar?: string;
|
||||
name: string;
|
||||
onChangeOwner: (tmbId: string) => Promise<unknown>;
|
||||
};
|
||||
|
||||
export function ChangeOwnerModal({
|
||||
onClose,
|
||||
avatar,
|
||||
name,
|
||||
onChangeOwner
|
||||
}: ChangeOwnerModalProps & { onClose: () => void }) {
|
||||
const { t } = useTranslation();
|
||||
const [inputValue, setInputValue] = React.useState('');
|
||||
const { data: teamMembers = [] } = useRequest2(getTeamMembers, {
|
||||
manual: false
|
||||
});
|
||||
|
||||
const memberList = teamMembers.filter((item) => {
|
||||
return item.memberName.includes(inputValue);
|
||||
});
|
||||
|
||||
const {
|
||||
isOpen: isOpenMemberListMenu,
|
||||
onClose: onCloseMemberListMenu,
|
||||
onOpen: onOpenMemberListMenu
|
||||
} = useDisclosure();
|
||||
const [selectedMember, setSelectedMember] = useState<TeamMemberItemType | null>(null);
|
||||
|
||||
const { runAsync, loading } = useRequest2(onChangeOwner, {
|
||||
onSuccess: onClose,
|
||||
successToast: t('common:permission.change_owner_success'),
|
||||
errorToast: t('common:permission.change_owner_failed')
|
||||
});
|
||||
|
||||
const onConfirm = async () => {
|
||||
if (!selectedMember) {
|
||||
return;
|
||||
}
|
||||
await runAsync(selectedMember.tmbId);
|
||||
};
|
||||
|
||||
return (
|
||||
<MyModal
|
||||
isOpen
|
||||
iconSrc="modal/changePer"
|
||||
onClose={onClose}
|
||||
title={t('common:permission.change_owner')}
|
||||
isLoading={loading}
|
||||
>
|
||||
<ModalBody>
|
||||
<HStack>
|
||||
<Avatar src={avatar} w={'1.75rem'} borderRadius={'md'} />
|
||||
<Box>{name}</Box>
|
||||
</HStack>
|
||||
<Flex mt={4} justify="start" flexDirection="column">
|
||||
<Box fontSize="14px" fontWeight="500" color="myGray.900">
|
||||
{t('common:permission.change_owner_to')}
|
||||
</Box>
|
||||
<Flex mt="4" alignItems="center" position={'relative'}>
|
||||
{selectedMember && (
|
||||
<Avatar
|
||||
src={selectedMember.avatar}
|
||||
w={'20px'}
|
||||
borderRadius={'md'}
|
||||
position="absolute"
|
||||
left={3}
|
||||
/>
|
||||
)}
|
||||
<Input
|
||||
placeholder={t('common:permission.change_owner_placeholder')}
|
||||
value={inputValue}
|
||||
onChange={(e) => {
|
||||
setInputValue(e.target.value);
|
||||
setSelectedMember(null);
|
||||
}}
|
||||
onFocus={() => {
|
||||
onOpenMemberListMenu();
|
||||
setSelectedMember(null);
|
||||
}}
|
||||
// onBlur={() => {
|
||||
// setTimeout(() => {
|
||||
// onCloseMemberListMenu();
|
||||
// }, 10);
|
||||
// }}
|
||||
{...(selectedMember && { pl: '10' })}
|
||||
/>
|
||||
</Flex>
|
||||
{isOpenMemberListMenu && memberList.length > 0 && (
|
||||
<Flex
|
||||
mt={2}
|
||||
w={'100%'}
|
||||
flexDirection={'column'}
|
||||
gap={2}
|
||||
p={1}
|
||||
boxShadow="lg"
|
||||
bg="white"
|
||||
borderRadius="md"
|
||||
zIndex={10}
|
||||
maxH={'300px'}
|
||||
overflow={'auto'}
|
||||
>
|
||||
{memberList.map((item) => (
|
||||
<Box
|
||||
key={item.tmbId}
|
||||
p="2"
|
||||
_hover={{ bg: 'myGray.100' }}
|
||||
mx="1"
|
||||
borderRadius="md"
|
||||
cursor={'pointer'}
|
||||
onClickCapture={() => {
|
||||
setInputValue(item.memberName);
|
||||
setSelectedMember(item);
|
||||
onCloseMemberListMenu();
|
||||
}}
|
||||
>
|
||||
<Flex align="center">
|
||||
<Avatar src={item.avatar} w="1.25rem" />
|
||||
<Box ml="2">{item.memberName}</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
<MyTag mt="4" colorSchema="blue">
|
||||
<Icon name="common/info" w="1rem" />
|
||||
<Box ml="2">{t('common:permission.change_owner_tip')}</Box>
|
||||
</MyTag>
|
||||
</Flex>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<HStack>
|
||||
<Button onClick={onClose} variant={'whiteBase'}>
|
||||
{t('common:common.Cancel')}
|
||||
</Button>
|
||||
<Button onClick={onConfirm}>{t('common:common.Confirm')}</Button>
|
||||
</HStack>
|
||||
</ModalFooter>
|
||||
</MyModal>
|
||||
);
|
||||
}
|
@@ -3,13 +3,12 @@ import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||
import CollaboratorContextProvider, { MemberManagerInputPropsType } from '../MemberManager/context';
|
||||
import { Box, Button, Flex, HStack, ModalBody } from '@chakra-ui/react';
|
||||
import { Box, Button, Flex, HStack, ModalBody, useDisclosure } from '@chakra-ui/react';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import DefaultPermissionList from '../DefaultPerList';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import ResumeInherit from '../ResumeInheritText';
|
||||
import { ChangeOwnerModal } from '../ChangeOwnerModal';
|
||||
|
||||
export type ConfigPerModalProps = {
|
||||
avatar?: string;
|
||||
@@ -25,6 +24,7 @@ export type ConfigPerModalProps = {
|
||||
resumeInheritPermission?: () => void;
|
||||
hasParent?: boolean;
|
||||
refetchResource?: () => void;
|
||||
onChangeOwner?: (tmbId: string) => Promise<unknown>;
|
||||
};
|
||||
|
||||
const ConfigPerModal = ({
|
||||
@@ -36,11 +36,17 @@ const ConfigPerModal = ({
|
||||
resumeInheritPermission,
|
||||
hasParent,
|
||||
onClose,
|
||||
refetchResource
|
||||
refetchResource,
|
||||
onChangeOwner
|
||||
}: ConfigPerModalProps & {
|
||||
onClose: () => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
isOpen: isChangeOwnerModalOpen,
|
||||
onOpen: onOpenChangeOwnerModal,
|
||||
onClose: onCloseChangeOwnerModal
|
||||
} = useDisclosure();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -113,8 +119,30 @@ const ConfigPerModal = ({
|
||||
}}
|
||||
</CollaboratorContextProvider>
|
||||
</Box>
|
||||
{onChangeOwner && (
|
||||
<Box mt={4}>
|
||||
<Button
|
||||
size="md"
|
||||
variant="whitePrimary"
|
||||
onClick={onOpenChangeOwnerModal}
|
||||
w="full"
|
||||
borderRadius="md"
|
||||
leftIcon={<MyIcon w="4" name="common/lineChange" />}
|
||||
>
|
||||
{t('common:permission.change_owner')}
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</ModalBody>
|
||||
</MyModal>
|
||||
{isChangeOwnerModalOpen && onChangeOwner && (
|
||||
<ChangeOwnerModal
|
||||
onClose={onCloseChangeOwnerModal}
|
||||
avatar={avatar}
|
||||
name={name}
|
||||
onChangeOwner={onChangeOwner}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
5
projects/app/src/global/core/app/api.d.ts
vendored
5
projects/app/src/global/core/app/api.d.ts
vendored
@@ -29,3 +29,8 @@ export type PostRevertAppProps = {
|
||||
editEdges: AppSchema['edges'];
|
||||
editChatConfig: AppSchema['chatConfig'];
|
||||
};
|
||||
|
||||
export type AppChangeOwnerBody = {
|
||||
appId: string;
|
||||
ownerId: string;
|
||||
};
|
||||
|
@@ -7,7 +7,8 @@ import {
|
||||
Input,
|
||||
Textarea,
|
||||
ModalFooter,
|
||||
ModalBody
|
||||
ModalBody,
|
||||
useDisclosure
|
||||
} from '@chakra-ui/react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { AppSchema } from '@fastgpt/global/core/app/type.d';
|
||||
@@ -15,7 +16,7 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
|
||||
import { compressImgFileAndUpload } from '@/web/common/file/controller';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@@ -35,7 +36,6 @@ import {
|
||||
import DefaultPermissionList from '@/components/support/permission/DefaultPerList';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { UpdateClbPermissionProps } from '@fastgpt/global/support/permission/collaborator';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { resumeInheritPer } from '@/web/core/app/api';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import ResumeInherit from '@/components/support/permission/ResumeInheritText';
|
||||
@@ -61,6 +61,7 @@ const InfoModal = ({ onClose }: { onClose: () => void }) => {
|
||||
defaultValues: appDetail
|
||||
});
|
||||
const avatar = getValues('avatar');
|
||||
const name = getValues('name');
|
||||
|
||||
// submit config
|
||||
const { runAsync: saveSubmitSuccess, loading: btnLoading } = useRequest2(
|
||||
@@ -135,6 +136,7 @@ const InfoModal = ({ onClose }: { onClose: () => void }) => {
|
||||
appId: appDetail._id
|
||||
});
|
||||
};
|
||||
|
||||
const onDelCollaborator = async (tmbId: string) => {
|
||||
await deleteAppCollaborators({
|
||||
appId: appDetail._id,
|
||||
|
@@ -53,7 +53,7 @@ const Provider = () => {
|
||||
export async function getServerSideProps(context: any) {
|
||||
return {
|
||||
props: {
|
||||
...(await serviceSideProps(context, ['app', 'chat', 'file', 'publish', 'workflow']))
|
||||
...(await serviceSideProps(context, ['app', 'chat', 'user', 'file', 'publish', 'workflow']))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Box, Grid, Flex, IconButton, HStack } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { delAppById, putAppById, resumeInheritPer } from '@/web/core/app/api';
|
||||
import { delAppById, putAppById, resumeInheritPer, changeOwner } from '@/web/core/app/api';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
@@ -399,6 +399,12 @@ const ListItem = () => {
|
||||
)}
|
||||
{!!editPerApp && (
|
||||
<ConfigPerModal
|
||||
onChangeOwner={(tmbId: string) =>
|
||||
changeOwner({
|
||||
appId: editPerApp._id,
|
||||
ownerId: tmbId
|
||||
}).then(() => loadMyApps())
|
||||
}
|
||||
refetchResource={loadMyApps}
|
||||
hasParent={Boolean(parentId)}
|
||||
resumeInheritPermission={onResumeInheritPermission}
|
||||
|
@@ -326,7 +326,7 @@ export default ContextRender;
|
||||
export async function getServerSideProps(content: any) {
|
||||
return {
|
||||
props: {
|
||||
...(await serviceSideProps(content, ['app']))
|
||||
...(await serviceSideProps(content, ['app', 'user']))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { GET, POST, DELETE, PUT } from '@/web/common/api/request';
|
||||
import type { AppDetailType, AppListItemType } from '@fastgpt/global/core/app/type.d';
|
||||
import type { GetAppChatLogsParams } from '@/global/core/api/appReq.d';
|
||||
import { AppUpdateParams } from '@/global/core/app/api';
|
||||
import { AppUpdateParams, AppChangeOwnerBody } from '@/global/core/app/api';
|
||||
import type { CreateAppBody } from '@/pages/api/core/app/create';
|
||||
import type { ListAppBody } from '@/pages/api/core/app/list';
|
||||
|
||||
@@ -40,3 +40,5 @@ export const getAppChatLogs = (data: GetAppChatLogsParams) => POST(`/core/app/ge
|
||||
|
||||
export const resumeInheritPer = (appId: string) =>
|
||||
GET(`/core/app/resumeInheritPermission`, { appId });
|
||||
|
||||
export const changeOwner = (data: AppChangeOwnerBody) => POST(`/proApi/core/app/changeOwner`, data);
|
||||
|
Reference in New Issue
Block a user