From 898393a0f894ac478f3c8cd1f48e06f353508857 Mon Sep 17 00:00:00 2001 From: NFish Date: Mon, 12 Jan 2026 11:52:48 +0800 Subject: [PATCH] feat: add invite permission check for workspace invite members feature --- .../account-setting/members-page/index.tsx | 14 ++++---- .../members-page/invite-button.tsx | 32 +++++++++++++++++++ web/service/use-workspace.ts | 17 ++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 web/app/components/header/account-setting/members-page/invite-button.tsx create mode 100644 web/service/use-workspace.ts diff --git a/web/app/components/header/account-setting/members-page/index.tsx b/web/app/components/header/account-setting/members-page/index.tsx index d405e8e4c4..5a8f3aebdb 100644 --- a/web/app/components/header/account-setting/members-page/index.tsx +++ b/web/app/components/header/account-setting/members-page/index.tsx @@ -1,10 +1,9 @@ 'use client' import type { InvitationResult } from '@/models/common' -import { RiPencilLine, RiUserAddLine } from '@remixicon/react' +import { RiPencilLine } from '@remixicon/react' import { useState } from 'react' import { useTranslation } from 'react-i18next' import Avatar from '@/app/components/base/avatar' -import Button from '@/app/components/base/button' import Tooltip from '@/app/components/base/tooltip' import { NUM_INFINITE } from '@/app/components/billing/config' import { Plan } from '@/app/components/billing/type' @@ -16,8 +15,8 @@ import { useProviderContext } from '@/context/provider-context' import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now' import { LanguagesSupported } from '@/i18n-config/language' import { useMembers } from '@/service/use-common' -import { cn } from '@/utils/classnames' import EditWorkspaceModal from './edit-workspace-modal' +import InviteButton from './invite-button' import InviteModal from './invite-modal' import InvitedModal from './invited-modal' import Operation from './operation' @@ -37,7 +36,7 @@ const MembersPage = () => { const { userProfile, currentWorkspace, isCurrentWorkspaceOwner, isCurrentWorkspaceManager } = useAppContext() const { data, refetch } = useMembers() - const { systemFeatures } = useGlobalPublicStore() + const systemFeatures = useGlobalPublicStore(s => s.systemFeatures) const { formatTimeFromNow } = useFormatTimeFromNow() const [inviteModalVisible, setInviteModalVisible] = useState(false) const [invitationResults, setInvitationResults] = useState([]) @@ -104,10 +103,9 @@ const MembersPage = () => { {isMemberFull && ( )} - +
+ setInviteModalVisible(true)} /> +
diff --git a/web/app/components/header/account-setting/members-page/invite-button.tsx b/web/app/components/header/account-setting/members-page/invite-button.tsx new file mode 100644 index 0000000000..09002f2945 --- /dev/null +++ b/web/app/components/header/account-setting/members-page/invite-button.tsx @@ -0,0 +1,32 @@ +import { RiUserAddLine } from '@remixicon/react' +import { useTranslation } from 'react-i18next' +import Button from '@/app/components/base/button' +import Loading from '@/app/components/base/loading' +import { useGlobalPublicStore } from '@/context/global-public-context' +import { useWorkspacePermissions } from '@/service/use-workspace' + +type InviteButtonProps = { + disabled?: boolean + onClick?: () => void +} + +const InviteButton = (props: InviteButtonProps) => { + const { t } = useTranslation() + const systemFeatures = useGlobalPublicStore(s => s.systemFeatures) + const { data: workspacePermissions, isFetching: isFetchingWorkspacePermissions } = useWorkspacePermissions(systemFeatures.branding.enabled) + if (systemFeatures.branding.enabled) { + if (isFetchingWorkspacePermissions) { + return + } + if (!workspacePermissions || workspacePermissions.allow_member_invite !== true) { + return null + } + } + return ( + + ) +} +export default InviteButton diff --git a/web/service/use-workspace.ts b/web/service/use-workspace.ts new file mode 100644 index 0000000000..1b675c66ff --- /dev/null +++ b/web/service/use-workspace.ts @@ -0,0 +1,17 @@ +import type { ICurrentWorkspace } from '@/models/common' +import { useQuery } from '@tanstack/react-query' +import { get } from './base' + +type WorkspacePermissions = { + workspace_id: ICurrentWorkspace['id'] + allow_member_invite: boolean + allow_owner_transfer: boolean +} + +export function useWorkspacePermissions(enabled: boolean) { + return useQuery({ + queryKey: ['workspace-permissions'], + queryFn: () => get('/workspaces/current/permission'), + enabled, + }) +}