import { useEffect, useMemo } from "react"; import { useSearchParams } from "react-router-dom"; import type { ApiSettings, AuthInfo, MailProfilesUiCapability } from "../../types"; import { fetchMe } from "../../api/auth"; import Card from "../../components/Card"; import ModuleSubnav, { type ModuleSubnavGroup } from "../../layout/ModuleSubnav"; import { adminReadScopes, hasAnyScope, hasScope } from "../../utils/permissions"; import AdminOverviewPanel from "./AdminOverviewPanel"; import SystemUsersPanel from "./SystemUsersPanel"; import SystemSettingsPanel from "./SystemSettingsPanel"; import TenantSettingsPanel from "./TenantSettingsPanel"; import GovernanceTemplatesPanel from "./GovernanceTemplatesPanel"; import SystemRolesPanel from "./SystemRolesPanel"; import TenantsPanel from "./TenantsPanel"; import UsersPanel from "./UsersPanel"; import GroupsPanel from "./GroupsPanel"; import RolesPanel from "./RolesPanel"; import ApiKeysPanel from "./ApiKeysPanel"; import AdminAuditPanel from "./AdminAuditPanel"; import MailProfilesPanel from "./MailProfilesPanel"; import RetentionPoliciesPanel from "./RetentionPoliciesPanel"; import { usePlatformUiCapability } from "../../platform/ModuleContext"; type AdminSection = | "overview" | "system-settings" | "system-retention" | "system-mail-servers" | "system-tenants" | "system-users" | "system-groups" | "system-roles" | "system-role-templates" | "system-audit" | "tenant-users" | "tenant-groups" | "tenant-roles" | "tenant-api-keys" | "tenant-mail-servers" | "tenant-user-mail-servers" | "tenant-group-mail-servers" | "tenant-retention" | "tenant-user-retention" | "tenant-group-retention" | "tenant-settings" | "tenant-audit"; export default function AdminPage({ settings, auth, onAuthChange }: { settings: ApiSettings; auth: AuthInfo; onAuthChange: (auth: AuthInfo | null, accessToken?: string) => void; }) { const mailProfilesUi = usePlatformUiCapability("mail.profiles"); const mailProfilesAvailable = Boolean(mailProfilesUi); const available = useMemo(() => { const sections = new Set(["overview"]); if (hasScope(auth, "system:settings:read")) { sections.add("system-settings"); sections.add("system-retention"); if (mailProfilesAvailable) sections.add("system-mail-servers"); } if (hasScope(auth, "system:tenants:read")) sections.add("system-tenants"); if (hasAnyScope(auth, ["system:accounts:read", "system:access:read"])) sections.add("system-users"); if (hasScope(auth, "system:governance:read")) sections.add("system-groups"); if (hasAnyScope(auth, ["system:roles:read", "system:access:read"])) sections.add("system-roles"); if (hasScope(auth, "system:governance:read")) sections.add("system-role-templates"); if (hasScope(auth, "system:audit:read")) sections.add("system-audit"); if (hasScope(auth, "admin:users:read")) sections.add("tenant-users"); if (hasScope(auth, "admin:groups:read")) sections.add("tenant-groups"); if (hasScope(auth, "admin:roles:read")) sections.add("tenant-roles"); if (hasScope(auth, "admin:api_keys:read")) sections.add("tenant-api-keys"); if (mailProfilesAvailable && hasAnyScope(auth, ["mail_servers:read", "admin:policies:read"])) { sections.add("tenant-mail-servers"); if (hasScope(auth, "admin:users:read")) sections.add("tenant-user-mail-servers"); if (hasScope(auth, "admin:groups:read")) sections.add("tenant-group-mail-servers"); } if (hasScope(auth, "admin:policies:read")) { sections.add("tenant-retention"); if (hasScope(auth, "admin:users:read")) sections.add("tenant-user-retention"); if (hasScope(auth, "admin:groups:read")) sections.add("tenant-group-retention"); } if (hasScope(auth, "admin:settings:read")) sections.add("tenant-settings"); if (hasScope(auth, "audit:read")) sections.add("tenant-audit"); return sections; }, [auth, mailProfilesAvailable]); const [searchParams, setSearchParams] = useSearchParams(); const requestedSection = searchParams.get("section") as AdminSection | null; const active: AdminSection = requestedSection && available.has(requestedSection) ? requestedSection : "overview"; function selectSection(section: AdminSection) { const next = new URLSearchParams(searchParams); if (section === "overview") next.delete("section"); else next.set("section", section); setSearchParams(next, { replace: true }); } useEffect(() => { if (requestedSection && !available.has(requestedSection)) selectSection("overview"); }, [requestedSection, available]); async function refreshAuth() { onAuthChange(await fetchMe(settings)); } useEffect(() => { void refreshAuth().catch(() => undefined); }, [settings.accessToken, settings.apiBaseUrl]); if (!hasAnyScope(auth, adminReadScopes)) { return

Your current roles do not grant administrative access.

; } const adminSubnav: ModuleSubnavGroup[] = [ { items: [{ id: "overview" as const, label: "Overview" }] }, { title: "SYSTEM", items: [ ...(available.has("system-settings") ? [{ id: "system-settings" as const, label: "General" }] : []), ...(available.has("system-tenants") ? [{ id: "system-tenants" as const, label: "Tenants" }] : []), ...(available.has("system-roles") ? [{ id: "system-roles" as const, label: "System roles" }] : []), ...(available.has("system-role-templates") ? [{ id: "system-role-templates" as const, label: "Tenant roles" }] : []), ...(available.has("system-groups") ? [{ id: "system-groups" as const, label: "Groups" }] : []), ...(available.has("system-users") ? [{ id: "system-users" as const, label: "Users" }] : []), ...(available.has("system-mail-servers") ? [{ id: "system-mail-servers" as const, label: "Mail servers" }] : []), ...(available.has("system-retention") ? [{ id: "system-retention" as const, label: "Retention" }] : []), ...(available.has("system-audit") ? [{ id: "system-audit" as const, label: "Audit" }] : []) ] }, { title: "TENANT", items: [ ...(available.has("tenant-settings") ? [{ id: "tenant-settings" as const, label: "General" }] : []), ...(available.has("tenant-roles") ? [{ id: "tenant-roles" as const, label: "Roles" }] : []), ...(available.has("tenant-groups") ? [{ id: "tenant-groups" as const, label: "Groups" }] : []), ...(available.has("tenant-users") ? [{ id: "tenant-users" as const, label: "Users" }] : []), ...(available.has("tenant-mail-servers") ? [{ id: "tenant-mail-servers" as const, label: "Mail servers" }] : []), ...(available.has("tenant-retention") ? [{ id: "tenant-retention" as const, label: "Retention" }] : []), ...(available.has("tenant-api-keys") ? [{ id: "tenant-api-keys" as const, label: "API keys" }] : []), ...(available.has("tenant-audit") ? [{ id: "tenant-audit" as const, label: "Audit" }] : []) ] }, { title: "GROUP", items: [ ...(available.has("tenant-group-mail-servers") ? [{ id: "tenant-group-mail-servers" as const, label: "Mail servers" }] : []), ...(available.has("tenant-group-retention") ? [{ id: "tenant-group-retention" as const, label: "Retention" }] : []), ] }, { title: "USER", items: [ ...(available.has("tenant-user-mail-servers") ? [{ id: "tenant-user-mail-servers" as const, label: "Mail servers" }] : []), ...(available.has("tenant-user-retention") ? [{ id: "tenant-user-retention" as const, label: "Retention" }] : []), ] } ].filter((group) => group.items.length > 0); return (
{active === "overview" && available.has(section as AdminSection) && selectSection(section as AdminSection)} />} {active === "system-settings" && } {active === "system-retention" && } {active === "system-mail-servers" && } {active === "system-tenants" && } {active === "system-users" && } {active === "system-groups" && } {active === "system-roles" && } {active === "system-role-templates" && } {active === "system-audit" && } {active === "tenant-users" && } {active === "tenant-groups" && } {active === "tenant-roles" && } {active === "tenant-api-keys" && } {active === "tenant-mail-servers" && } {active === "tenant-user-mail-servers" && } {active === "tenant-group-mail-servers" && } {active === "tenant-retention" && } {active === "tenant-user-retention" && } {active === "tenant-group-retention" && } {active === "tenant-settings" && } {active === "tenant-audit" && }
); }