import { useUserStore } from '@/web/support/user/useUserStore'; import { Box, Divider, Flex, HStack, Table, TableContainer, Tag, Tbody, Td, Th, Thead, Tr, VStack } from '@chakra-ui/react'; import type { OrgType } from '@fastgpt/global/support/user/team/org/type'; import Avatar from '@fastgpt/web/components/common/Avatar'; import MyIcon from '@fastgpt/web/components/common/Icon'; import type { IconNameType } from '@fastgpt/web/components/common/Icon/type'; import MyMenu from '@fastgpt/web/components/common/MyMenu'; import { useConfirm } from '@fastgpt/web/hooks/useConfirm'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useTranslation } from 'next-i18next'; import { useMemo, useState } from 'react'; import { useContextSelector } from 'use-context-selector'; import MemberTag from '@/components/support/user/team/Info/MemberTag'; import { TeamContext } from '../context'; import { deleteOrg, deleteOrgMember, getOrgList } from '@/web/support/user/team/org/api'; import IconButton from './IconButton'; import { defaultOrgForm, type OrgFormType } from './OrgInfoModal'; import dynamic from 'next/dynamic'; import MyBox from '@fastgpt/web/components/common/MyBox'; import Path from '@/components/common/folder/Path'; import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type'; import { getOrgChildrenPath } from '@fastgpt/global/support/user/team/org/constant'; import { useSystemStore } from '@/web/common/system/useSystemStore'; const OrgInfoModal = dynamic(() => import('./OrgInfoModal')); const OrgMemberManageModal = dynamic(() => import('./OrgMemberManageModal')); const OrgMoveModal = dynamic(() => import('./OrgMoveModal')); function ActionButton({ icon, text, onClick }: { icon: IconNameType; text: string; onClick: () => void; }) { return ( {text} ); } function OrgTable({ Tabs }: { Tabs: React.ReactNode }) { const { t } = useTranslation(); const { userInfo, isTeamAdmin } = useUserStore(); const { members, MemberScrollData } = useContextSelector(TeamContext, (v) => v); const { feConfigs } = useSystemStore(); const isSyncMember = feConfigs.register_method?.includes('sync'); const [parentPath, setParentPath] = useState(''); const { data: orgs = [], loading: isLoadingOrgs, refresh: refetchOrgs } = useRequest2(getOrgList, { manual: false, refreshDeps: [userInfo?.team?.teamId] }); const currentOrgs = useMemo(() => { if (orgs.length === 0) return []; // Auto select the first org(root org is team) if (parentPath === '') { setParentPath(getOrgChildrenPath(orgs[0])); return []; } return orgs .filter((org) => org.path === parentPath) .map((item) => { return { ...item, // Member + org count: item.members.length + orgs.filter((org) => org.path === getOrgChildrenPath(item)).length }; }); }, [orgs, parentPath]); const currentOrg = useMemo(() => { const splitPath = parentPath.split('/'); const currentOrgId = splitPath[splitPath.length - 1]; if (!currentOrgId) return; return orgs.find((org) => org.pathId === currentOrgId); }, [orgs, parentPath]); const paths = useMemo(() => { const splitPath = parentPath.split('/').filter(Boolean); return splitPath .map((id) => { const org = orgs.find((org) => org.pathId === id)!; if (org.path === '') return; return { parentId: getOrgChildrenPath(org), parentName: org.name }; }) .filter(Boolean) as ParentTreePathItemType[]; }, [parentPath, orgs]); const [editOrg, setEditOrg] = useState(); const [manageMemberOrg, setManageMemberOrg] = useState(); const [movingOrg, setMovingOrg] = useState(); // Delete org const { ConfirmModal: ConfirmDeleteOrgModal, openConfirm: openDeleteOrgModal } = useConfirm({ type: 'delete', content: t('account_team:confirm_delete_org') }); const deleteOrgHandler = (orgId: string) => openDeleteOrgModal(() => deleteOrgReq(orgId))(); const { runAsync: deleteOrgReq } = useRequest2(deleteOrg, { onSuccess: () => { refetchOrgs(); } }); // Delete member const { ConfirmModal: ConfirmDeleteMember, openConfirm: openDeleteMemberModal } = useConfirm({ type: 'delete', content: t('account_team:confirm_delete_member') }); const { runAsync: deleteMemberReq } = useRequest2(deleteOrgMember, { onSuccess: () => { refetchOrgs(); } }); return ( <> {Tabs} {/* Table */} {!isSyncMember && ( )} {currentOrgs.map((org) => ( {isTeamAdmin && !isSyncMember && ( )} ))} {currentOrg?.members.map((member) => { const memberInfo = members.find((m) => m.tmbId === member.tmbId); if (!memberInfo) return null; return ( ); })}
{t('common:Name')} {t('common:common.Action')}
setParentPath(getOrgChildrenPath(org))} > {org.count} } menuList={[ { children: [ { icon: 'edit', label: t('account_team:edit_info'), onClick: () => setEditOrg(org) }, { icon: 'common/file/move', label: t('common:Move'), onClick: () => setMovingOrg(org) }, { icon: 'delete', label: t('account_team:delete'), type: 'danger', onClick: () => deleteOrgHandler(org._id) } ] } ]} />
{isTeamAdmin && !isSyncMember && ( } menuList={[ { children: [ { icon: 'delete', label: t('account_team:delete'), type: 'danger', onClick: () => openDeleteMemberModal(() => deleteMemberReq(currentOrg._id, member.tmbId) )() } ] } ]} /> )}
{/* Slider */} {!isSyncMember && ( {currentOrg?.name} {currentOrg?.path !== '' && ( setEditOrg(currentOrg)} /> )} {currentOrg?.description || t('common:common.no_intro')} {t('common:common.Action')} {currentOrg && isTeamAdmin && ( { setEditOrg({ ...defaultOrgForm, parentId: currentOrg?._id }); }} /> setManageMemberOrg(currentOrg)} /> {currentOrg?.path !== '' && ( <> setMovingOrg(currentOrg)} /> deleteOrgHandler(currentOrg._id)} /> )} )} )}
{!!editOrg && ( setEditOrg(undefined)} onSuccess={refetchOrgs} /> )} {!!movingOrg && ( setMovingOrg(undefined)} onSuccess={refetchOrgs} /> )} {!!manageMemberOrg && ( setManageMemberOrg(undefined)} /> )} ); } export default OrgTable;