@@ -258,34 +258,36 @@ export default function ModelProviderKeysTableView({ provider, className, header
-
-
-
-
-
- {
- setShowAddNewKeyDialog({ show: true, keyId: key.id });
- }}
- disabled={!hasUpdateProviderAccess}
- >
-
- Edit
-
- {
- setShowDeleteKeyDialog({ show: true, keyId: key.id });
- }}
- disabled={!hasDeleteProviderAccess}
- >
-
- Delete
-
-
-
+ {hasUpdateProviderAccess || hasDeleteProviderAccess ?
+
+
+
+
+
+ {
+ setShowAddNewKeyDialog({ show: true, keyId: key.id });
+ }}
+ disabled={!hasUpdateProviderAccess}
+ >
+
+ Edit
+
+ {
+ setShowDeleteKeyDialog({ show: true, keyId: key.id });
+ }}
+ disabled={!hasDeleteProviderAccess}
+ >
+
+ Delete
+
+
+ : null
+ }
diff --git a/ui/components/sidebar.tsx b/ui/components/sidebar.tsx
index cf0bbad8f8..c6042e044f 100644
--- a/ui/components/sidebar.tsx
+++ b/ui/components/sidebar.tsx
@@ -19,10 +19,8 @@ import {
LogOut,
Logs,
Network,
- PanelLeft,
PanelLeftClose,
PanelLeftOpen,
- PanelRight,
Plug,
Puzzle,
ScrollText,
@@ -67,7 +65,6 @@ import {
useGetVersionQuery,
useLogoutMutation,
} from "@/lib/store";
-import { cn } from "@/lib/utils";
import { RbacOperation, RbacResource, useRbac } from "@enterprise/lib";
import type { UserInfo } from "@enterprise/lib/store/utils/tokenManager";
import { getUserInfo } from "@enterprise/lib/store/utils/tokenManager";
@@ -564,6 +561,8 @@ export default function AppSidebar() {
const hasObservabilityAccess = useRbac(RbacResource.Observability, RbacOperation.View);
const hasModelProvidersAccess = useRbac(RbacResource.ModelProvider, RbacOperation.View);
const hasMCPGatewayAccess = useRbac(RbacResource.MCPGateway, RbacOperation.View);
+ const hasMCPToolGroupsAccess = useRbac(RbacResource.MCPToolGroups, RbacOperation.View);
+ const hasMCPLogsAccess = useRbac(RbacResource.MCPLogs, RbacOperation.View);
const hasPluginsAccess = useRbac(RbacResource.Plugins, RbacOperation.View);
const hasUsersAccess = useRbac(RbacResource.Users, RbacOperation.View);
const hasUserProvisioningAccess = useRbac(RbacResource.UserProvisioning, RbacOperation.View);
@@ -583,6 +582,7 @@ export default function AppSidebar() {
const hasClusterConfigAccess = useRbac(RbacResource.Cluster, RbacOperation.View);
const isAdaptiveRoutingAllowed = useRbac(RbacResource.AdaptiveRouter, RbacOperation.View);
const hasSettingsAccess = useRbac(RbacResource.Settings, RbacOperation.View);
+ const hasAPIKeyAccess = useRbac(RbacResource.APIKeys, RbacOperation.View);
const hasPromptRepositoryAccess = useRbac(RbacResource.PromptRepository, RbacOperation.View);
const hasAccessProfilesAccess = useRbac(RbacResource.AccessProfiles, RbacOperation.View);
const hasAnyGovernanceAccess =
@@ -625,7 +625,7 @@ export default function AppSidebar() {
url: "/workspace/mcp-logs",
icon: MCPIcon,
description: "MCP tool execution logs",
- hasAccess: hasLogsAccess,
+ hasAccess: hasMCPLogsAccess,
},
{
title: "Connectors",
@@ -699,7 +699,7 @@ export default function AppSidebar() {
icon: MCPIcon,
description: "MCP configuration",
url: "/workspace/mcp-gateway",
- hasAccess: hasMCPGatewayAccess,
+ hasAccess: hasMCPGatewayAccess || hasMCPToolGroupsAccess,
subItems: [
{
title: "MCP Catalog",
@@ -713,7 +713,7 @@ export default function AppSidebar() {
url: "/workspace/mcp-tool-groups",
icon: ToolCase,
description: "Tool Groups",
- hasAccess: hasMCPGatewayAccess,
+ hasAccess: hasMCPToolGroupsAccess,
},
{
title: "MCP Settings",
@@ -910,7 +910,7 @@ export default function AppSidebar() {
url: "/workspace/config/api-keys",
icon: KeyRound,
description: "API keys management",
- hasAccess: hasSettingsAccess,
+ hasAccess: hasAPIKeyAccess,
},
{
title: "Performance Tuning",
@@ -923,11 +923,13 @@ export default function AppSidebar() {
},
],
[
- hasLogsAccess,
- hasObservabilityAccess,
- hasModelProvidersAccess,
- hasMCPGatewayAccess,
- hasPluginsAccess,
+ hasLogsAccess,
+ hasObservabilityAccess,
+ hasModelProvidersAccess,
+ hasMCPGatewayAccess,
+ hasMCPToolGroupsAccess,
+ hasMCPLogsAccess,
+ hasPluginsAccess,
hasUsersAccess,
hasUserProvisioningAccess,
hasAuditLogsAccess,
@@ -950,11 +952,26 @@ export default function AppSidebar() {
],
);
+ const accessibleItems: SidebarItem[] = useMemo(() => {
+ return items
+ .map((item) => {
+ const hadSubItems = !!item.subItems?.length;
+ if (hadSubItems) {
+ const visibleSubItems = item.subItems!.filter((sub) => sub.hasAccess !== false);
+ if (visibleSubItems.length === 0) return null;
+ return { ...item, subItems: visibleSubItems, hasAccess: true };
+ }
+ if (item.hasAccess === false) return null;
+ return item;
+ })
+ .filter(Boolean) as SidebarItem[];
+ }, [items]);
+
const filteredItems: SidebarItem[] = useMemo(() => {
const query = searchQuery.trim().toLowerCase();
- if (!query) return items;
+ if (!query) return accessibleItems;
- return items
+ return accessibleItems
.map((item) => {
const parentMatches = item.title.toLowerCase().includes(query);
if (parentMatches) return item;
@@ -970,7 +987,7 @@ export default function AppSidebar() {
return null;
})
.filter(Boolean) as SidebarItem[];
- }, [items, searchQuery]);
+ }, [accessibleItems, searchQuery]);
const { data: version } = useGetVersionQuery();
const { resolvedTheme } = useTheme();
@@ -1447,4 +1464,4 @@ export default function AppSidebar() {
);
-}
\ No newline at end of file
+}