tmp org api rewrite (#4304)
* sync collection * remove lock * tmp org api rewrite
This commit is contained in:
parent
db7510c5eb
commit
a956fbca73
@ -18,6 +18,7 @@ weight: 799
|
|||||||
2. 知识库分块增加自定义分隔符预设值,同时支持自定义换行符分割。
|
2. 知识库分块增加自定义分隔符预设值,同时支持自定义换行符分割。
|
||||||
3. 外部变量改名:自定义变量。 并且支持在测试时调试,在分享链接中,该变量直接隐藏。
|
3. 外部变量改名:自定义变量。 并且支持在测试时调试,在分享链接中,该变量直接隐藏。
|
||||||
4. 集合同步时,支持同步修改标题。
|
4. 集合同步时,支持同步修改标题。
|
||||||
|
5. 团队成员管理重构,抽离主流 IM SSO(企微、飞书、钉钉),并支持通过自定义 SSO 接入 FastGPT。同时完善与外部系统的成员同步。
|
||||||
|
|
||||||
## ⚙️ 优化
|
## ⚙️ 优化
|
||||||
|
|
||||||
|
|||||||
13
packages/global/support/user/team/org/type.d.ts
vendored
13
packages/global/support/user/team/org/type.d.ts
vendored
@ -1,6 +1,6 @@
|
|||||||
import type { TeamPermission } from 'support/permission/user/controller';
|
import type { TeamPermission } from '../../../permission/user/controller';
|
||||||
import { ResourcePermissionType } from '../type';
|
import { ResourcePermissionType } from '../type';
|
||||||
import { SourceMemberType } from 'support/user/type';
|
import { SourceMemberType } from '../../type';
|
||||||
|
|
||||||
type OrgSchemaType = {
|
type OrgSchemaType = {
|
||||||
_id: string;
|
_id: string;
|
||||||
@ -8,7 +8,7 @@ type OrgSchemaType = {
|
|||||||
pathId: string;
|
pathId: string;
|
||||||
path: string;
|
path: string;
|
||||||
name: string;
|
name: string;
|
||||||
avatar?: string;
|
avatar: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
updateTime: Date;
|
updateTime: Date;
|
||||||
};
|
};
|
||||||
@ -20,7 +20,12 @@ type OrgMemberSchemaType = {
|
|||||||
tmbId: string;
|
tmbId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type OrgType = Omit<OrgSchemaType, 'avatar'> & {
|
export type OrgListItemType = OrgSchemaType & {
|
||||||
|
permission: TeamPermission;
|
||||||
|
total: number; // members + children orgs
|
||||||
|
};
|
||||||
|
|
||||||
|
export type OrgType = Omit<OrgSchemaType, 'avatar'> & {
|
||||||
avatar: string;
|
avatar: string;
|
||||||
permission: TeamPermission;
|
permission: TeamPermission;
|
||||||
members: OrgMemberSchemaType[];
|
members: OrgMemberSchemaType[];
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant';
|
import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant';
|
||||||
import { connectionMongo, getMongoModel } from '../../../common/mongo';
|
import { connectionMongo, getMongoModel } from '../../../common/mongo';
|
||||||
import { MemberGroupSchemaType } from '@fastgpt/global/support/permission/memberGroup/type';
|
import { MemberGroupSchemaType } from '@fastgpt/global/support/permission/memberGroup/type';
|
||||||
import { GroupMemberCollectionName } from './groupMemberSchema';
|
|
||||||
const { Schema } = connectionMongo;
|
const { Schema } = connectionMongo;
|
||||||
|
|
||||||
export const MemberGroupCollectionName = 'team_member_groups';
|
export const MemberGroupCollectionName = 'team_member_groups';
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "app",
|
"name": "app",
|
||||||
"version": "4.9.1",
|
"version": "4.9.2",
|
||||||
"private": false,
|
"private": false,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|||||||
@ -24,6 +24,8 @@ import { useUserStore } from '@/web/support/user/useUserStore';
|
|||||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||||
import { DEFAULT_TEAM_AVATAR } from '@fastgpt/global/common/system/constants';
|
import { DEFAULT_TEAM_AVATAR } from '@fastgpt/global/common/system/constants';
|
||||||
import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
|
import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
|
||||||
|
import { GroupMemberItemType } from '@fastgpt/global/support/permission/memberGroup/type';
|
||||||
|
import { useMount } from 'ahooks';
|
||||||
|
|
||||||
export type GroupFormType = {
|
export type GroupFormType = {
|
||||||
members: {
|
members: {
|
||||||
@ -46,26 +48,20 @@ function GroupEditModal({ onClose, editGroupId }: { onClose: () => void; editGro
|
|||||||
return groups.find((item) => item._id === editGroupId);
|
return groups.find((item) => item._id === editGroupId);
|
||||||
}, [editGroupId, groups]);
|
}, [editGroupId, groups]);
|
||||||
|
|
||||||
const { data: groupMembers } = useRequest2(
|
|
||||||
() => {
|
|
||||||
if (editGroupId) return getGroupMembers(editGroupId);
|
|
||||||
return Promise.resolve(undefined);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
manual: false,
|
|
||||||
onSuccess: (data) => {
|
|
||||||
setMembers(data ?? []);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const allMembers = useContextSelector(TeamContext, (v) => v.members);
|
const allMembers = useContextSelector(TeamContext, (v) => v.members);
|
||||||
const refetchMembers = useContextSelector(TeamContext, (v) => v.refetchMembers);
|
const refetchMembers = useContextSelector(TeamContext, (v) => v.refetchMembers);
|
||||||
const MemberScrollData = useContextSelector(TeamContext, (v) => v.MemberScrollData);
|
const MemberScrollData = useContextSelector(TeamContext, (v) => v.MemberScrollData);
|
||||||
const [hoveredMemberId, setHoveredMemberId] = useState<string>();
|
const [hoveredMemberId, setHoveredMemberId] = useState<string>();
|
||||||
|
|
||||||
const selectedMembersRef = useRef<HTMLDivElement>(null);
|
const selectedMembersRef = useRef<HTMLDivElement>(null);
|
||||||
const [members, setMembers] = useState(groupMembers || []);
|
const [members, setMembers] = useState<GroupMemberItemType[]>([]);
|
||||||
|
|
||||||
|
useMount(async () => {
|
||||||
|
if (editGroupId) {
|
||||||
|
const data = await getGroupMembers(editGroupId);
|
||||||
|
setMembers(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const [searchKey, setSearchKey] = useState('');
|
const [searchKey, setSearchKey] = useState('');
|
||||||
const filtered = useMemo(() => {
|
const filtered = useMemo(() => {
|
||||||
@ -80,7 +76,7 @@ function GroupEditModal({ onClose, editGroupId }: { onClose: () => void; editGro
|
|||||||
const { runAsync: onUpdate, loading: isLoadingUpdate } = useRequest2(
|
const { runAsync: onUpdate, loading: isLoadingUpdate } = useRequest2(
|
||||||
async () => {
|
async () => {
|
||||||
if (!editGroupId || !members.length) return;
|
if (!editGroupId || !members.length) return;
|
||||||
console.log(members);
|
|
||||||
return putUpdateGroup({
|
return putUpdateGroup({
|
||||||
groupId: editGroupId,
|
groupId: editGroupId,
|
||||||
memberList: members
|
memberList: members
|
||||||
@ -209,7 +205,7 @@ function GroupEditModal({ onClose, editGroupId }: { onClose: () => void; editGro
|
|||||||
<Flex borderLeft="1px" borderColor="myGray.200" flexDirection="column" p="4" h={'100%'}>
|
<Flex borderLeft="1px" borderColor="myGray.200" flexDirection="column" p="4" h={'100%'}>
|
||||||
<Box mt={2}>{t('common:chosen') + ': ' + members.length}</Box>
|
<Box mt={2}>{t('common:chosen') + ': ' + members.length}</Box>
|
||||||
<MemberScrollData ScrollContainerRef={selectedMembersRef} mt={3} flex={'1 0 0'} h={0}>
|
<MemberScrollData ScrollContainerRef={selectedMembersRef} mt={3} flex={'1 0 0'} h={0}>
|
||||||
{members?.map((member) => {
|
{members.map((member) => {
|
||||||
return (
|
return (
|
||||||
<HStack
|
<HStack
|
||||||
onMouseEnter={() => setHoveredMemberId(member.tmbId)}
|
onMouseEnter={() => setHoveredMemberId(member.tmbId)}
|
||||||
|
|||||||
@ -236,7 +236,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
<Box className={'textEllipsis'}>
|
<Box className={'textEllipsis'}>
|
||||||
{member.memberName}
|
{member.memberName}
|
||||||
{member.status !== 'active' && (
|
{member.status !== 'active' && (
|
||||||
<Tag ml="2" colorSchema="gray">
|
<Tag ml="2" colorSchema="gray" bg={'myGray.100'} color={'myGray.700'}>
|
||||||
{t('account_team:leave')}
|
{t('account_team:leave')}
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
|||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
|
|
||||||
export type OrgFormType = {
|
export type OrgFormType = {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import type React from 'react';
|
|||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import { TeamContext } from '../context';
|
import { TeamContext } from '../context';
|
||||||
import { OrgType } from '@fastgpt/global/support/user/team/org/type';
|
import { OrgListItemType, OrgType } from '@fastgpt/global/support/user/team/org/type';
|
||||||
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
|
|
||||||
export type GroupFormType = {
|
export type GroupFormType = {
|
||||||
@ -46,7 +46,7 @@ function OrgMemberManageModal({
|
|||||||
refetchOrgs,
|
refetchOrgs,
|
||||||
onClose
|
onClose
|
||||||
}: {
|
}: {
|
||||||
currentOrg: OrgType;
|
currentOrg: OrgListItemType;
|
||||||
refetchOrgs: () => void;
|
refetchOrgs: () => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { putMoveOrg } from '@/web/support/user/team/org/api';
|
import { putMoveOrg } from '@/web/support/user/team/org/api';
|
||||||
import { Button, ModalBody, ModalFooter } from '@chakra-ui/react';
|
import { Button, ModalBody, ModalFooter } from '@chakra-ui/react';
|
||||||
import type { OrgType } from '@fastgpt/global/support/user/team/org/type';
|
import type { OrgListItemType, OrgType } from '@fastgpt/global/support/user/team/org/type';
|
||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
@ -15,13 +15,13 @@ function OrgMoveModal({
|
|||||||
onClose,
|
onClose,
|
||||||
onSuccess
|
onSuccess
|
||||||
}: {
|
}: {
|
||||||
movingOrg: OrgType;
|
movingOrg: OrgListItemType;
|
||||||
orgs: OrgType[];
|
orgs: OrgListItemType[];
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onSuccess: () => void;
|
onSuccess: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [selectedOrg, setSelectedOrg] = useState<OrgType>();
|
const [selectedOrg, setSelectedOrg] = useState<OrgListItemType>();
|
||||||
const { userInfo } = useUserStore();
|
const { userInfo } = useUserStore();
|
||||||
const team = userInfo?.team!;
|
const team = userInfo?.team!;
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
Tr,
|
Tr,
|
||||||
VStack
|
VStack
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import type { OrgType } from '@fastgpt/global/support/user/team/org/type';
|
import type { OrgListItemType, OrgType } from '@fastgpt/global/support/user/team/org/type';
|
||||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import type { IconNameType } from '@fastgpt/web/components/common/Icon/type';
|
import type { IconNameType } from '@fastgpt/web/components/common/Icon/type';
|
||||||
@ -23,9 +23,7 @@ import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
|||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useContextSelector } from 'use-context-selector';
|
|
||||||
import MemberTag from '@/components/support/user/team/Info/MemberTag';
|
import MemberTag from '@/components/support/user/team/Info/MemberTag';
|
||||||
import { TeamContext } from '../context';
|
|
||||||
import {
|
import {
|
||||||
deleteOrg,
|
deleteOrg,
|
||||||
deleteOrgMember,
|
deleteOrgMember,
|
||||||
@ -39,10 +37,10 @@ import { defaultOrgForm, type OrgFormType } from './OrgInfoModal';
|
|||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import Path from '@/components/common/folder/Path';
|
import Path from '@/components/common/folder/Path';
|
||||||
import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
|
import { ParentIdType, ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
|
||||||
import { getOrgChildrenPath } from '@fastgpt/global/support/user/team/org/constant';
|
import { getOrgChildrenPath } from '@fastgpt/global/support/user/team/org/constant';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
import { delRemoveMember, getTeamMembers } from '@/web/support/user/team/api';
|
import { delRemoveMember } from '@/web/support/user/team/api';
|
||||||
import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
|
import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
|
||||||
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
|
|
||||||
@ -82,24 +80,16 @@ function ActionButton({
|
|||||||
function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { userInfo, isTeamAdmin } = useUserStore();
|
const { userInfo, isTeamAdmin } = useUserStore();
|
||||||
const [searchOrg, setSearchOrg] = useState('');
|
|
||||||
const [orgStack, setOrgStack] = useState<OrgType[]>([]);
|
|
||||||
const currentOrg = useMemo(() => orgStack[orgStack.length - 1], [orgStack]);
|
|
||||||
|
|
||||||
const [rootOrg, setRootOrg] = useState<OrgType>();
|
|
||||||
|
|
||||||
const { data: members = [], ScrollData: MemberScrollData } = useScrollPagination(getOrgMembers, {
|
|
||||||
pageSize: 20,
|
|
||||||
params: {
|
|
||||||
orgId: currentOrg?._id ?? rootOrg?._id
|
|
||||||
},
|
|
||||||
refreshDeps: [currentOrg?._id, rootOrg?._id]
|
|
||||||
});
|
|
||||||
|
|
||||||
const { feConfigs } = useSystemStore();
|
const { feConfigs } = useSystemStore();
|
||||||
|
|
||||||
const isSyncMember = feConfigs.register_method?.includes('sync');
|
const isSyncMember = feConfigs.register_method?.includes('sync');
|
||||||
const [path, setPath] = useState('');
|
|
||||||
|
const [searchOrg, setSearchOrg] = useState('');
|
||||||
|
|
||||||
|
const [parentId, setParentId] = useState<ParentIdType>();
|
||||||
|
const [currentOrg, setCurrentOrg] = useState<OrgListItemType>();
|
||||||
|
|
||||||
|
// 用于 org 层级
|
||||||
|
const [orgStack, setOrgStack] = useState<OrgListItemType[]>([]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: orgs = [],
|
data: orgs = [],
|
||||||
@ -107,43 +97,35 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
refresh: refetchOrgs
|
refresh: refetchOrgs
|
||||||
} = useRequest2(
|
} = useRequest2(
|
||||||
() => {
|
() => {
|
||||||
// sync path to orgStack
|
return getOrgList(parentId);
|
||||||
const splitPath = path.split('/').filter(Boolean);
|
|
||||||
const orgs = orgStack.filter((o) => splitPath.includes(o.pathId));
|
|
||||||
setOrgStack(orgs);
|
|
||||||
return getOrgList(path);
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
manual: false,
|
manual: false,
|
||||||
refreshDeps: [userInfo?.team?.teamId, path],
|
refreshDeps: [userInfo?.team?.teamId, parentId]
|
||||||
onSuccess: (data) => {
|
|
||||||
if (!rootOrg) {
|
|
||||||
setRootOrg(data[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const paths = useMemo(() => {
|
const paths = useMemo(() => {
|
||||||
|
if (!currentOrg) return [];
|
||||||
return orgStack
|
return orgStack
|
||||||
.map((org) => {
|
.map((org) => {
|
||||||
if (org?.path === '') return;
|
|
||||||
return {
|
return {
|
||||||
parentId: getOrgChildrenPath(org),
|
parentId: getOrgChildrenPath(org),
|
||||||
parentName: org.name
|
parentName: org.name
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter(Boolean) as ParentTreePathItemType[];
|
.filter(Boolean) as ParentTreePathItemType[];
|
||||||
}, [orgStack]);
|
}, [currentOrg, orgStack]);
|
||||||
|
|
||||||
const onClickOrg = (org: OrgType) => {
|
const onClickOrg = (org: OrgListItemType) => {
|
||||||
|
setParentId(currentOrg?._id);
|
||||||
setOrgStack([...orgStack, org]);
|
setOrgStack([...orgStack, org]);
|
||||||
setPath(getOrgChildrenPath(org));
|
setCurrentOrg(org);
|
||||||
};
|
};
|
||||||
|
|
||||||
const [editOrg, setEditOrg] = useState<OrgFormType>();
|
const [editOrg, setEditOrg] = useState<OrgFormType>();
|
||||||
const [manageMemberOrg, setManageMemberOrg] = useState<OrgType>();
|
const [manageMemberOrg, setManageMemberOrg] = useState<OrgListItemType>();
|
||||||
const [movingOrg, setMovingOrg] = useState<OrgType>();
|
const [movingOrg, setMovingOrg] = useState<OrgListItemType>();
|
||||||
|
|
||||||
// Delete org
|
// Delete org
|
||||||
const { ConfirmModal: ConfirmDeleteOrgModal, openConfirm: openDeleteOrgModal } = useConfirm({
|
const { ConfirmModal: ConfirmDeleteOrgModal, openConfirm: openDeleteOrgModal } = useConfirm({
|
||||||
@ -157,6 +139,14 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { data: members = [], ScrollData: MemberScrollData } = useScrollPagination(getOrgMembers, {
|
||||||
|
pageSize: 20,
|
||||||
|
params: {
|
||||||
|
orgId: currentOrg?._id
|
||||||
|
},
|
||||||
|
refreshDeps: [currentOrg?._id]
|
||||||
|
});
|
||||||
|
|
||||||
// Delete member
|
// Delete member
|
||||||
const { ConfirmModal: ConfirmDeleteMemberFromOrg, openConfirm: openDeleteMemberFromOrgModal } =
|
const { ConfirmModal: ConfirmDeleteMemberFromOrg, openConfirm: openDeleteMemberFromOrgModal } =
|
||||||
useConfirm({
|
useConfirm({
|
||||||
@ -183,11 +173,7 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
const searchedOrgs = useMemo(() => {
|
const searchedOrgs = useMemo(() => {
|
||||||
if (!searchOrg) return [];
|
if (!searchOrg) return [];
|
||||||
|
|
||||||
return orgs
|
return orgs.filter((org) => org.name.includes(searchOrg));
|
||||||
.filter((org) => org.name.includes(searchOrg))
|
|
||||||
.map((org) => ({
|
|
||||||
...org
|
|
||||||
}));
|
|
||||||
}, [orgs, searchOrg]);
|
}, [orgs, searchOrg]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -231,7 +217,7 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
<Tr key={org._id} overflow={'unset'} onClick={() => onClickOrg(org)}>
|
<Tr key={org._id} overflow={'unset'} onClick={() => onClickOrg(org)}>
|
||||||
<Td>
|
<Td>
|
||||||
<HStack cursor={'pointer'} onClick={() => onClickOrg(org)}>
|
<HStack cursor={'pointer'} onClick={() => onClickOrg(org)}>
|
||||||
<MemberTag name={org.name} avatar={org.avatar} />
|
<MemberTag name={org.name} avatar={org.avatar!} />
|
||||||
<Tag size="sm">{org.total}</Tag>
|
<Tag size="sm">{org.total}</Tag>
|
||||||
<MyIcon
|
<MyIcon
|
||||||
name="core/chat/chevronRight"
|
name="core/chat/chevronRight"
|
||||||
@ -427,7 +413,7 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setEditOrg({
|
setEditOrg({
|
||||||
...defaultOrgForm,
|
...defaultOrgForm,
|
||||||
parentId: currentOrg?._id ?? rootOrg?._id
|
parentId: currentOrg?._id
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -16,7 +16,6 @@ import { useTranslation } from 'next-i18next';
|
|||||||
import { getGroupList } from '@/web/support/user/team/group/api';
|
import { getGroupList } from '@/web/support/user/team/group/api';
|
||||||
import { MemberGroupListType } from '@fastgpt/global/support/permission/memberGroup/type';
|
import { MemberGroupListType } from '@fastgpt/global/support/permission/memberGroup/type';
|
||||||
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
import { getOrgList } from '@/web/support/user/team/org/api';
|
|
||||||
import { OrgType } from '@fastgpt/global/support/user/team/org/type';
|
import { OrgType } from '@fastgpt/global/support/user/team/org/type';
|
||||||
|
|
||||||
const EditInfoModal = dynamic(() => import('./EditInfoModal'));
|
const EditInfoModal = dynamic(() => import('./EditInfoModal'));
|
||||||
@ -25,7 +24,6 @@ type TeamModalContextType = {
|
|||||||
myTeams: TeamTmbItemType[];
|
myTeams: TeamTmbItemType[];
|
||||||
members: TeamMemberItemType[];
|
members: TeamMemberItemType[];
|
||||||
groups: MemberGroupListType;
|
groups: MemberGroupListType;
|
||||||
orgs: OrgType[];
|
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
onSwitchTeam: (teamId: string) => void;
|
onSwitchTeam: (teamId: string) => void;
|
||||||
setEditTeamData: React.Dispatch<React.SetStateAction<EditTeamFormDataType | undefined>>;
|
setEditTeamData: React.Dispatch<React.SetStateAction<EditTeamFormDataType | undefined>>;
|
||||||
@ -33,7 +31,6 @@ type TeamModalContextType = {
|
|||||||
refetchMembers: () => void;
|
refetchMembers: () => void;
|
||||||
refetchTeams: () => void;
|
refetchTeams: () => void;
|
||||||
refetchGroups: () => void;
|
refetchGroups: () => void;
|
||||||
refetchOrgs: () => void;
|
|
||||||
teamSize: number;
|
teamSize: number;
|
||||||
MemberScrollData: ReturnType<typeof useScrollPagination>['ScrollData'];
|
MemberScrollData: ReturnType<typeof useScrollPagination>['ScrollData'];
|
||||||
};
|
};
|
||||||
@ -42,7 +39,6 @@ export const TeamContext = createContext<TeamModalContextType>({
|
|||||||
myTeams: [],
|
myTeams: [],
|
||||||
groups: [],
|
groups: [],
|
||||||
members: [],
|
members: [],
|
||||||
orgs: [],
|
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
onSwitchTeam: function (_teamId: string): void {
|
onSwitchTeam: function (_teamId: string): void {
|
||||||
throw new Error('Function not implemented.');
|
throw new Error('Function not implemented.');
|
||||||
@ -59,9 +55,6 @@ export const TeamContext = createContext<TeamModalContextType>({
|
|||||||
refetchGroups: function (): void {
|
refetchGroups: function (): void {
|
||||||
throw new Error('Function not implemented.');
|
throw new Error('Function not implemented.');
|
||||||
},
|
},
|
||||||
refetchOrgs: function (): void {
|
|
||||||
throw new Error('Function not implemented.');
|
|
||||||
},
|
|
||||||
teamSize: 0,
|
teamSize: 0,
|
||||||
MemberScrollData: () => <></>
|
MemberScrollData: () => <></>
|
||||||
});
|
});
|
||||||
@ -80,15 +73,6 @@ export const TeamModalContextProvider = ({ children }: { children: ReactNode })
|
|||||||
refreshDeps: [userInfo?._id]
|
refreshDeps: [userInfo?._id]
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
|
||||||
data: orgs = [],
|
|
||||||
loading: isLoadingOrgs,
|
|
||||||
refresh: refetchOrgs
|
|
||||||
} = useRequest2(getOrgList, {
|
|
||||||
manual: false,
|
|
||||||
refreshDeps: [userInfo?.team?.teamId]
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data: teamMemberCountData, refresh: refetchTeamMemberCount } = useRequest2(
|
const { data: teamMemberCountData, refresh: refetchTeamMemberCount } = useRequest2(
|
||||||
getTeamMemberCount,
|
getTeamMemberCount,
|
||||||
{
|
{
|
||||||
@ -135,16 +119,13 @@ export const TeamModalContextProvider = ({ children }: { children: ReactNode })
|
|||||||
refreshDeps: [userInfo?.team?.teamId]
|
refreshDeps: [userInfo?.team?.teamId]
|
||||||
});
|
});
|
||||||
|
|
||||||
const isLoading =
|
const isLoading = isLoadingTeams || isSwitchingTeam || loadingMembers || isLoadingGroups;
|
||||||
isLoadingTeams || isSwitchingTeam || loadingMembers || isLoadingGroups || isLoadingOrgs;
|
|
||||||
|
|
||||||
const contextValue = {
|
const contextValue = {
|
||||||
myTeams,
|
myTeams,
|
||||||
refetchTeams,
|
refetchTeams,
|
||||||
isLoading,
|
isLoading,
|
||||||
onSwitchTeam,
|
onSwitchTeam,
|
||||||
orgs,
|
|
||||||
refetchOrgs,
|
|
||||||
|
|
||||||
// create | update team
|
// create | update team
|
||||||
setEditTeamData,
|
setEditTeamData,
|
||||||
|
|||||||
@ -4,13 +4,14 @@ import type {
|
|||||||
putUpdateOrgData,
|
putUpdateOrgData,
|
||||||
putUpdateOrgMembersData
|
putUpdateOrgMembersData
|
||||||
} from '@fastgpt/global/support/user/team/org/api';
|
} from '@fastgpt/global/support/user/team/org/api';
|
||||||
import type { OrgType } from '@fastgpt/global/support/user/team/org/type';
|
import type { OrgListItemType } from '@fastgpt/global/support/user/team/org/type';
|
||||||
import type { putMoveOrgType } from '@fastgpt/global/support/user/team/org/api';
|
import type { putMoveOrgType } from '@fastgpt/global/support/user/team/org/api';
|
||||||
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
import { TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
|
import { TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
|
||||||
|
import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
|
||||||
|
|
||||||
export const getOrgList = (path: string) =>
|
export const getOrgList = (parentId: ParentIdType) =>
|
||||||
GET<OrgType[]>(`/proApi/support/user/team/org/list`, { orgPath: path });
|
GET<OrgListItemType[]>(`/proApi/support/user/team/org/list`, { parentId });
|
||||||
|
|
||||||
export const postCreateOrg = (data: postCreateOrgData) =>
|
export const postCreateOrg = (data: postCreateOrgData) =>
|
||||||
POST('/proApi/support/user/team/org/create', data);
|
POST('/proApi/support/user/team/org/create', data);
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import type { UserType } from '@fastgpt/global/support/user/type.d';
|
|||||||
import type { FeTeamPlanStatusType } from '@fastgpt/global/support/wallet/sub/type';
|
import type { FeTeamPlanStatusType } from '@fastgpt/global/support/wallet/sub/type';
|
||||||
import { getTeamPlanStatus } from './team/api';
|
import { getTeamPlanStatus } from './team/api';
|
||||||
import { getGroupList } from './team/group/api';
|
import { getGroupList } from './team/group/api';
|
||||||
import { getOrgList } from './team/org/api';
|
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
systemMsgReadId: string;
|
systemMsgReadId: string;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user