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 && (