Release v0.1.3

This commit is contained in:
2026-06-26 01:39:19 +02:00
parent 02564047e9
commit df701fddd2
29 changed files with 600 additions and 154 deletions

View File

@@ -8,6 +8,7 @@ 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";
@@ -18,7 +19,6 @@ import ApiKeysPanel from "./ApiKeysPanel";
import AdminAuditPanel from "./AdminAuditPanel";
import MailProfilesPanel from "./MailProfilesPanel";
import RetentionPoliciesPanel from "./RetentionPoliciesPanel";
import PageTitle from "../../components/PageTitle";
import { usePlatformUiCapability } from "../../platform/ModuleContext";
type AdminSection =
@@ -120,42 +120,42 @@ export default function AdminPage({
{
title: "SYSTEM",
items: [
...(available.has("system-settings") ? [{ id: "system-settings" as const, label: "Settings" }] : []),
...(available.has("system-retention") ? [{ id: "system-retention" as const, label: "Retention" }] : []),
...(available.has("system-mail-servers") ? [{ id: "system-mail-servers" as const, label: "Mail servers" }] : []),
...(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-users") ? [{ id: "system-users" as const, label: "Users" }] : []),
...(available.has("system-groups") ? [{ id: "system-groups" as const, label: "Groups" }] : []),
...(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: "Settings" }] : []),
...(available.has("tenant-users") ? [{ id: "tenant-users" as const, label: "Users" }] : []),
...(available.has("tenant-groups") ? [{ id: "tenant-groups" as const, label: "Groups" }] : []),
...(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-api-keys") ? [{ id: "tenant-api-keys" as const, label: "API keys" }] : []),
...(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: "USER",
items: [
...(available.has("tenant-user-mail-servers") ? [{ id: "tenant-user-mail-servers" as const, label: "User mail" }] : []),
...(available.has("tenant-user-retention") ? [{ id: "tenant-user-retention" as const, label: "User retention" }] : []),
]
},
{
title: "GROUP",
items: [
...(available.has("tenant-group-mail-servers") ? [{ id: "tenant-group-mail-servers" as const, label: "Group mail" }] : []),
...(available.has("tenant-group-retention") ? [{ id: "tenant-group-retention" as const, label: "Group retention" }] : []),
...(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);
@@ -197,14 +197,10 @@ export default function AdminPage({
{active === "tenant-retention" && <RetentionPoliciesPanel settings={settings} scopeType="tenant" canWrite={hasScope(auth, "admin:policies:write")} />}
{active === "tenant-user-retention" && <RetentionPoliciesPanel settings={settings} scopeType="user" canWrite={hasScope(auth, "admin:policies:write")} />}
{active === "tenant-group-retention" && <RetentionPoliciesPanel settings={settings} scopeType="group" canWrite={hasScope(auth, "admin:policies:write")} />}
{active === "tenant-settings" && <PreparationPage title="Tenant settings" text="Tenant-specific policy values are now represented by typed governance overrides on the system Tenants page; further campaign-policy inheritance will build on that foundation." />}
{active === "tenant-settings" && <TenantSettingsPanel settings={settings} canWrite={hasScope(auth, "admin:settings:write")} onAuthRefresh={refreshAuth} />}
{active === "tenant-audit" && <AdminAuditPanel settings={settings} auth={auth} />}
</div>
</section>
</div>
);
}
function PreparationPage({ title, text }: { title: string; text: string }) {
return <div className="admin-section-page"><div className="page-heading workspace-heading"><div><PageTitle>{title}</PageTitle><p>{text}</p></div></div><Card><p className="muted">This boundary is intentionally visible but not presented as an implemented editor.</p></Card></div>;
}