diff --git a/plane-src/apps/web/core/components/settings/project/sidebar/item-categories.tsx b/plane-src/apps/web/core/components/settings/project/sidebar/item-categories.tsx index e877db8..76187b5 100644 --- a/plane-src/apps/web/core/components/settings/project/sidebar/item-categories.tsx +++ b/plane-src/apps/web/core/components/settings/project/sidebar/item-categories.tsx @@ -7,11 +7,13 @@ import { observer } from "mobx-react"; import { usePathname } from "next/navigation"; import { useParams } from "react-router"; +import useSWR from "swr"; // plane imports import { EUserPermissionsLevel, GROUPED_PROJECT_SETTINGS, PROJECT_SETTINGS_CATEGORIES } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; // components import { SettingsSidebarItem } from "@/components/settings/sidebar/item"; +import { WorkspaceService } from "@/services/workspace.service"; // hooks import { useUserPermissions } from "@/hooks/store/user"; // local imports @@ -24,6 +26,8 @@ const PROJECT_CATEGORY_I18N_KEYS = { execution: "project_settings_categories.execution", } as const; +const workspaceService = new WorkspaceService(); + type Props = { projectId: string; }; @@ -37,15 +41,22 @@ export const ProjectSettingsSidebarItemCategories = observer(function ProjectSet const pathname = usePathname(); // store hooks const { allowPermissions } = useUserPermissions(); + const { data: nodedcWorkspacePolicy } = useSWR( + workspaceSlug ? `NODEDC_WORKSPACE_POLICY_${workspaceSlug}` : null, + () => workspaceService.getNodeDCWorkspacePolicy(workspaceSlug?.toString()) + ); // translation const { t } = useTranslation(); + const shouldHideMemberSettings = !nodedcWorkspacePolicy || nodedcWorkspacePolicy.managed_by === "launcher"; return (
{PROJECT_SETTINGS_CATEGORIES.map((category) => { const categoryItems = GROUPED_PROJECT_SETTINGS[category]; - const accessibleItems = categoryItems.filter((item) => - allowPermissions(item.access, EUserPermissionsLevel.PROJECT, workspaceSlug, projectId) + const accessibleItems = categoryItems.filter( + (item) => + (!shouldHideMemberSettings || item.key !== "members") && + allowPermissions(item.access, EUserPermissionsLevel.PROJECT, workspaceSlug, projectId) ); if (accessibleItems.length === 0) return null; diff --git a/plane-src/apps/web/core/components/workspace/sidebar/dropdown-item.tsx b/plane-src/apps/web/core/components/workspace/sidebar/dropdown-item.tsx index f522bdb..a8eff6b 100644 --- a/plane-src/apps/web/core/components/workspace/sidebar/dropdown-item.tsx +++ b/plane-src/apps/web/core/components/workspace/sidebar/dropdown-item.tsx @@ -8,6 +8,7 @@ import { observer } from "mobx-react"; import Link from "next/link"; import { useParams, useRouter } from "next/navigation"; import type { MouseEvent } from "react"; +import useSWR from "swr"; import { Archive, BarChart3, Layers3, Settings, UserPlus } from "lucide-react"; import { Menu } from "@headlessui/react"; // plane imports @@ -18,9 +19,12 @@ import type { IWorkspace } from "@plane/types"; import { cn, getFileURL, getUserRole } from "@plane/utils"; // components import { openWorkspaceSettingsModal } from "@/components/workspace/settings/workspace-settings-modal.utils"; +import { WorkspaceService } from "@/services/workspace.service"; // plane web imports import { SubscriptionPill } from "@/plane-web/components/common/subscription/subscription-pill"; +const workspaceService = new WorkspaceService(); + type TProps = { workspace: IWorkspace; activeWorkspace: IWorkspace | null; @@ -35,8 +39,13 @@ const SidebarDropdownItem = observer(function SidebarDropdownItem(props: TProps) const router = useRouter(); // hooks const { t } = useTranslation(); + const { data: nodedcWorkspacePolicy } = useSWR( + workspace.id === activeWorkspace?.id ? `NODEDC_WORKSPACE_POLICY_${workspace.slug}` : null, + () => workspaceService.getNodeDCWorkspacePolicy(workspace.slug) + ); const canOpenWorkspaceSettings = [EUserPermissions.ADMIN, EUserPermissions.MEMBER].includes(workspace?.role); - const canInviteMembers = [EUserPermissions.ADMIN].includes(workspace?.role); + const canInviteMembers = + [EUserPermissions.ADMIN].includes(workspace?.role) && nodedcWorkspacePolicy?.managed_by === "tasker"; const handleWorkspaceAction = (e: MouseEvent, action: () => void) => { e.preventDefault(); diff --git a/plane-src/apps/web/core/components/workspace/sidebar/workspace-menu-root.tsx b/plane-src/apps/web/core/components/workspace/sidebar/workspace-menu-root.tsx index eb7fe45..1d22935 100644 --- a/plane-src/apps/web/core/components/workspace/sidebar/workspace-menu-root.tsx +++ b/plane-src/apps/web/core/components/workspace/sidebar/workspace-menu-root.tsx @@ -8,6 +8,7 @@ import { Fragment, useEffect, useCallback, useLayoutEffect, useRef, useState, ty import { observer } from "mobx-react"; import Link from "next/link"; import { createPortal } from "react-dom"; +import useSWR from "swr"; // icons import { CirclePlus, LogOut, Mails } from "lucide-react"; // ui @@ -21,6 +22,7 @@ import { Loader } from "@plane/ui"; import { orderWorkspacesList, cn } from "@plane/utils"; // helpers import { AppSidebarItem } from "@/components/sidebar/sidebar-item"; +import { WorkspaceService } from "@/services/workspace.service"; // hooks import { useAppTheme } from "@/hooks/store/use-app-theme"; import { useWorkspace } from "@/hooks/store/use-workspace"; @@ -30,6 +32,8 @@ import { useInstance } from "@/hooks/store/use-instance"; import { WorkspaceLogo } from "../logo"; import SidebarDropdownItem from "./dropdown-item"; +const workspaceService = new WorkspaceService(); + type WorkspaceMenuRootProps = { variant: "sidebar" | "top-navigation" | "sidebar-panel" | "toolbar" | "expanded-toolbar"; }; @@ -98,8 +102,12 @@ export const WorkspaceMenuRoot = observer(function WorkspaceMenuRoot(props: Work const { signOut } = useUser(); const { updateUserProfile } = useUserProfile(); const { currentWorkspace: activeWorkspace, workspaces } = useWorkspace(); + const { data: nodedcWorkspacePolicy } = useSWR(currentUser ? "NODEDC_WORKSPACE_POLICY" : null, () => + workspaceService.getNodeDCWorkspacePolicy() + ); // derived values const isWorkspaceCreationDisabled = config?.is_workspace_creation_disabled ?? false; + const canCreateWorkspace = !isWorkspaceCreationDisabled && nodedcWorkspacePolicy?.can_create_workspace === true; // translation const { t } = useTranslation(); // local state @@ -312,7 +320,7 @@ export const WorkspaceMenuRoot = observer(function WorkspaceMenuRoot(props: Work )}
- {!isWorkspaceCreationDisabled && ( + {canCreateWorkspace && (