Release v0.1.8

This commit is contained in:
2026-07-11 16:49:00 +02:00
parent 24edb7eb8a
commit 11ecf362a3
7 changed files with 59 additions and 26 deletions

View File

@@ -1,5 +1,9 @@
# GovOPlaN Admin
<!-- govoplan-repository-type:start -->
**Repository type:** module (platform).
<!-- govoplan-repository-type:end -->
`govoplan-admin` owns generic system administration API and WebUI contributions
during the GovOPlaN module split.

View File

@@ -1,6 +1,6 @@
{
"name": "@govoplan/admin-webui",
"version": "0.1.7",
"version": "0.1.8",
"private": true,
"type": "module",
"main": "webui/src/index.ts",
@@ -18,7 +18,7 @@
"LICENSE"
],
"peerDependencies": {
"@govoplan/core-webui": "^0.1.7",
"@govoplan/core-webui": "^0.1.8",
"lucide-react": "^1.23.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",

View File

@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
[project]
name = "govoplan-admin"
version = "0.1.7"
version = "0.1.8"
description = "GovOPlaN generic administration module."
readme = "README.md"
requires-python = ">=3.12"
authors = [{ name = "GovOPlaN" }]
dependencies = [
"govoplan-core>=0.1.7",
"govoplan-access>=0.1.7",
"govoplan-core>=0.1.8",
"govoplan-access>=0.1.8",
]
[tool.setuptools.packages.find]

View File

@@ -17,7 +17,7 @@ def _route_factory(context: ModuleContext):
manifest = ModuleManifest(
id="admin",
name="Admin",
version="0.1.7",
version="0.1.8",
required_capabilities=(CAPABILITY_AUTH_PRINCIPAL_RESOLVER, CAPABILITY_AUTH_PERMISSION_EVALUATOR),
route_factory=_route_factory,
migration_spec=MigrationSpec(module_id="admin", metadata=Base.metadata),

View File

@@ -1,6 +1,6 @@
{
"name": "@govoplan/admin-webui",
"version": "0.1.7",
"version": "0.1.8",
"private": true,
"type": "module",
"main": "src/index.ts",
@@ -13,7 +13,7 @@
}
},
"peerDependencies": {
"@govoplan/core-webui": "^0.1.7",
"@govoplan/core-webui": "^0.1.8",
"lucide-react": "^1.23.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",

View File

@@ -19,7 +19,7 @@ import {
type PermissionItem,
type TenantAdminItem } from
"../../api/admin";
import { AdminIconButton, AdminPageLayout, AdminSelectionList, adminErrorMessage, joinLabels, i18nMessage, useUnsavedDraftGuard } from "@govoplan/core-webui";
import { AdminIconButton, AdminPageLayout, AdminSelectionList, adminErrorMessage, i18nMessage, useUnsavedDraftGuard } from "@govoplan/core-webui";
const emptyDraft = {
slug: "",
@@ -54,6 +54,7 @@ export default function GovernanceTemplatesPanel({
const [error, setError] = useState("");
const [success, setSuccess] = useState("");
const dirty = editing !== null && draftKey(draft) !== savedDraftKey;
const permissionsByScope = useMemo(() => new Map(permissions.map((permission) => [permission.scope, permission])), [permissions]);
useUnsavedDraftGuard({
dirty,
@@ -238,7 +239,7 @@ export default function GovernanceTemplatesPanel({
</Dialog>
<Dialog open={Boolean(viewing)} title={viewing?.name || "i18n:govoplan-admin.template_details.d5d75e4d"} onClose={() => setViewing(null)} className="admin-dialog admin-dialog-wide" footer={<Button onClick={() => setViewing(null)}>i18n:govoplan-admin.close.bbfa773e</Button>}>
{viewing && <dl className="admin-details-grid"><div><dt>i18n:govoplan-admin.kind.e00ac23f</dt><dd>{viewing.kind}</dd></div><div><dt>i18n:govoplan-admin.slug.094da9b9</dt><dd>{viewing.slug}</dd></div><div><dt>i18n:govoplan-admin.status.bae7d5be</dt><dd>{viewing.is_active ? "i18n:govoplan-admin.active.a733b809" : "i18n:govoplan-admin.inactive.09af574c"}</dd></div><div><dt>i18n:govoplan-admin.tenants.1f7ae776</dt><dd>{viewing.assignments.length || "i18n:govoplan-admin.none.6eef6648"}</dd></div><div><dt>i18n:govoplan-admin.description.55f8ebc8</dt><dd>{viewing.description || "—"}</dd></div><div><dt>i18n:govoplan-admin.permissions.d06d5557</dt><dd>{viewing.permissions.length ? joinLabels(viewing.permissions.map((name) => ({ name }))) : "—"}</dd></div></dl>}
{viewing && <dl className="admin-details-grid"><div><dt>i18n:govoplan-admin.kind.e00ac23f</dt><dd>{viewing.kind}</dd></div><div><dt>i18n:govoplan-admin.slug.094da9b9</dt><dd>{viewing.slug}</dd></div><div><dt>i18n:govoplan-admin.status.bae7d5be</dt><dd>{viewing.is_active ? "i18n:govoplan-admin.active.a733b809" : "i18n:govoplan-admin.inactive.09af574c"}</dd></div><div><dt>i18n:govoplan-admin.tenants.1f7ae776</dt><dd>{viewing.assignments.length || "i18n:govoplan-admin.none.6eef6648"}</dd></div><div><dt>i18n:govoplan-admin.description.55f8ebc8</dt><dd>{viewing.description || "—"}</dd></div><div><dt>i18n:govoplan-admin.permissions.d06d5557</dt><dd>{viewing.permissions.length ? <PermissionDetails scopes={viewing.permissions} permissionsByScope={permissionsByScope} /> : "—"}</dd></div></dl>}
</Dialog>
<ConfirmDialog open={Boolean(deleting)} title={kind === "group" ? "i18n:govoplan-admin.delete_group_template.8745d842" : "i18n:govoplan-admin.delete_tenant_role.4efa0813"} message={i18nMessage("i18n:govoplan-admin.delete_value_removal_is_blocked_while_a_material.d4eba73d", { value0: deleting?.name })} confirmLabel={kind === "group" ? "i18n:govoplan-admin.delete_template.399bf72a" : "i18n:govoplan-admin.delete_tenant_role.4efa0813"} tone="danger" busy={busy} onCancel={() => setDeleting(null)} onConfirm={() => void remove()} />
@@ -249,3 +250,31 @@ export default function GovernanceTemplatesPanel({
function draftKey(draft: typeof emptyDraft): string {
return JSON.stringify(draft);
}
function PermissionDetails({ scopes, permissionsByScope }: {scopes: string[];permissionsByScope: ReadonlyMap<string, PermissionItem>;}) {
const groups = groupPermissionScopes(scopes, permissionsByScope);
return (
<div className="admin-permission-details">
{groups.map((group) => <section key={group.module}>
<strong>{group.module}</strong>
<ul>
{group.permissions.map((permission) => <li key={permission.scope}>
<span>{permission.label}</span>
<code>{permission.scope}</code>
</li>)}
</ul>
</section>)}
</div>);
}
function groupPermissionScopes(scopes: string[], permissionsByScope: ReadonlyMap<string, PermissionItem>) {
const groups = new Map<string, {scope: string;label: string}[]>();
for (const scope of [...scopes].sort()) {
const moduleId = scope.split(":", 1)[0] || "other";
const permission = permissionsByScope.get(scope);
const group = groups.get(moduleId) ?? [];
group.push({ scope, label: permission?.label || scope });
groups.set(moduleId, group);
}
return [...groups.entries()].map(([module, permissions]) => ({ module, permissions }));
}

View File

@@ -14,7 +14,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.after.695c89be": "After:",
"i18n:govoplan-admin.add_group_template.b74d8f0f": "Add group template",
"i18n:govoplan-admin.add_plan_item.fa55f028": "Add plan item",
"i18n:govoplan-admin.add_tenant_role.fcd904ea": "Add tenant role",
"i18n:govoplan-admin.add_tenant_role.fcd904ea": "Add role template",
"i18n:govoplan-admin.admin.4e7afebc": "Admin",
"i18n:govoplan-admin.administration.b8be3d12": "Administration",
"i18n:govoplan-admin.platform_administration": "Platform administration",
@@ -75,7 +75,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.create_group_template.72407248": "Create group template",
"i18n:govoplan-admin.create_request_and_apply.da79e153": "Create request and apply",
"i18n:govoplan-admin.create_suspend_and_govern_tenant_spaces.77992a39": "Create, suspend and govern tenant spaces.",
"i18n:govoplan-admin.create_tenant_role.f58db104": "Create tenant role",
"i18n:govoplan-admin.create_tenant_role.f58db104": "Create role template",
"i18n:govoplan-admin.created.0c78dab1": "Created:",
"i18n:govoplan-admin.created.accf40c8": "Created",
"i18n:govoplan-admin.current_window.73e25c9f": "Current window:",
@@ -100,7 +100,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.defaults_for_newly_created_tenants.9d0f4ccd": "Defaults for newly created tenants",
"i18n:govoplan-admin.delete_group_template.8745d842": "Delete group template",
"i18n:govoplan-admin.delete_template.399bf72a": "Delete template",
"i18n:govoplan-admin.delete_tenant_role.4efa0813": "Delete tenant role",
"i18n:govoplan-admin.delete_tenant_role.4efa0813": "Delete role template",
"i18n:govoplan-admin.delete_value_removal_is_blocked_while_a_material.d4eba73d": "Delete {value0}? Removal is blocked while a materialized tenant definition still has members or assignments.",
"i18n:govoplan-admin.delete_value.4d18989e": "Delete {value0}",
"i18n:govoplan-admin.dependencies.9f4f78d1": "Dependencies:",
@@ -115,7 +115,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.dry_run_change_request_created_value_enable_main.49826d07": "Dry-run change request created: {value0}. Enable maintenance mode, then apply the request.",
"i18n:govoplan-admin.dry_run.3d14659c": "Dry-run",
"i18n:govoplan-admin.edit_group_template.9bc72d21": "Edit group template",
"i18n:govoplan-admin.edit_tenant_role.c15a260d": "Edit tenant role",
"i18n:govoplan-admin.edit_tenant_role.c15a260d": "Edit role template",
"i18n:govoplan-admin.edit_value.fad75899": "Edit {value0}",
"i18n:govoplan-admin.enable_maintenance_mode.75f98d57": "Enable maintenance mode",
"i18n:govoplan-admin.enabled_modules.3c38e9ff": "Enabled modules:",
@@ -302,7 +302,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.save_plan.842dc280": "Save plan",
"i18n:govoplan-admin.save_settings.913aba9f": "Save settings",
"i18n:govoplan-admin.save_template.0885fab2": "Save template",
"i18n:govoplan-admin.save_tenant_role.8fc0d37d": "Save tenant role",
"i18n:govoplan-admin.save_tenant_role.8fc0d37d": "Save role template",
"i18n:govoplan-admin.save_the_install_plan_before_queueing_a_daemon_r.3ba00691": "Save the install plan before queueing a daemon request.",
"i18n:govoplan-admin.saved.c0ae8f6e": "Saved",
"i18n:govoplan-admin.saving.56a2285c": "Saving…",
@@ -347,9 +347,9 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.tenant_locale_and_tenant_specific_settings.ac49c83b": "Tenant locale and tenant-specific settings.",
"i18n:govoplan-admin.tenant_memberships_and_inherited_roles.16eda9f6": "Tenant memberships and inherited roles.",
"i18n:govoplan-admin.tenant_permission_bundles_and_system_managed_rol.bb563bea": "Tenant permission bundles and system-managed role copies.",
"i18n:govoplan-admin.tenant_permissions.246294bc": "Tenant permissions",
"i18n:govoplan-admin.tenant_role.6b53115d": "Tenant role",
"i18n:govoplan-admin.tenant_roles.51aca82d": "Tenant roles",
"i18n:govoplan-admin.tenant_permissions.246294bc": "Permissions",
"i18n:govoplan-admin.tenant_role.6b53115d": "Role template",
"i18n:govoplan-admin.tenant_roles.51aca82d": "Role templates",
"i18n:govoplan-admin.tenant_users.cb800b38": "Tenant users",
"i18n:govoplan-admin.tenants.1f7ae776": "Tenants",
"i18n:govoplan-admin.these_settings_are_enforced_by_the_backend_centr.8112ed6f": "These settings are enforced by the backend. Central groups and tenant roles remain available even when local creation is disabled.",
@@ -403,7 +403,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.after.695c89be": "Nach:",
"i18n:govoplan-admin.add_group_template.b74d8f0f": "Add group template",
"i18n:govoplan-admin.add_plan_item.fa55f028": "Add plan item",
"i18n:govoplan-admin.add_tenant_role.fcd904ea": "Add tenant role",
"i18n:govoplan-admin.add_tenant_role.fcd904ea": "Rollenvorlage hinzufügen",
"i18n:govoplan-admin.admin.4e7afebc": "Administration",
"i18n:govoplan-admin.administration.b8be3d12": "Administration",
"i18n:govoplan-admin.platform_administration": "Plattformadministration",
@@ -464,7 +464,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.create_group_template.72407248": "Create group template",
"i18n:govoplan-admin.create_request_and_apply.da79e153": "Create request and apply",
"i18n:govoplan-admin.create_suspend_and_govern_tenant_spaces.77992a39": "Create, suspend and govern tenant spaces.",
"i18n:govoplan-admin.create_tenant_role.f58db104": "Create tenant role",
"i18n:govoplan-admin.create_tenant_role.f58db104": "Rollenvorlage erstellen",
"i18n:govoplan-admin.created.0c78dab1": "Created:",
"i18n:govoplan-admin.created.accf40c8": "Erstellt",
"i18n:govoplan-admin.current_window.73e25c9f": "Aktuelles Fenster:",
@@ -489,7 +489,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.defaults_for_newly_created_tenants.9d0f4ccd": "Standards für neu erstellte Mandanten",
"i18n:govoplan-admin.delete_group_template.8745d842": "Delete group template",
"i18n:govoplan-admin.delete_template.399bf72a": "Delete template",
"i18n:govoplan-admin.delete_tenant_role.4efa0813": "Delete tenant role",
"i18n:govoplan-admin.delete_tenant_role.4efa0813": "Rollenvorlage löschen",
"i18n:govoplan-admin.delete_value_removal_is_blocked_while_a_material.d4eba73d": "Delete {value0}? Removal is blocked while a materialized tenant definition still has members or assignments.",
"i18n:govoplan-admin.delete_value.4d18989e": "Delete {value0}",
"i18n:govoplan-admin.dependencies.9f4f78d1": "Abhaengigkeiten:",
@@ -504,7 +504,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.dry_run_change_request_created_value_enable_main.49826d07": "Dry-run change request created: {value0}. Enable maintenance mode, then apply the request.",
"i18n:govoplan-admin.dry_run.3d14659c": "Dry-run",
"i18n:govoplan-admin.edit_group_template.9bc72d21": "Edit group template",
"i18n:govoplan-admin.edit_tenant_role.c15a260d": "Edit tenant role",
"i18n:govoplan-admin.edit_tenant_role.c15a260d": "Rollenvorlage bearbeiten",
"i18n:govoplan-admin.edit_value.fad75899": "Edit {value0}",
"i18n:govoplan-admin.enable_maintenance_mode.75f98d57": "Enable maintenance mode",
"i18n:govoplan-admin.enabled_modules.3c38e9ff": "Aktive Module:",
@@ -691,7 +691,7 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.save_plan.842dc280": "Save plan",
"i18n:govoplan-admin.save_settings.913aba9f": "Einstellungen speichern",
"i18n:govoplan-admin.save_template.0885fab2": "Save template",
"i18n:govoplan-admin.save_tenant_role.8fc0d37d": "Save tenant role",
"i18n:govoplan-admin.save_tenant_role.8fc0d37d": "Rollenvorlage speichern",
"i18n:govoplan-admin.save_the_install_plan_before_queueing_a_daemon_r.3ba00691": "Speichern Sie den Installationsplan, bevor eine Daemon-Anfrage eingereiht wird.",
"i18n:govoplan-admin.saved.c0ae8f6e": "Gespeichert",
"i18n:govoplan-admin.saving.56a2285c": "Saving…",
@@ -736,9 +736,9 @@ export const generatedTranslations: PlatformTranslations = {
"i18n:govoplan-admin.tenant_locale_and_tenant_specific_settings.ac49c83b": "Tenant locale and tenant-specific settings.",
"i18n:govoplan-admin.tenant_memberships_and_inherited_roles.16eda9f6": "Tenant memberships and inherited roles.",
"i18n:govoplan-admin.tenant_permission_bundles_and_system_managed_rol.bb563bea": "Tenant permission bundles and system-managed role copies.",
"i18n:govoplan-admin.tenant_permissions.246294bc": "Tenant permissions",
"i18n:govoplan-admin.tenant_role.6b53115d": "Tenant role",
"i18n:govoplan-admin.tenant_roles.51aca82d": "Mandantenrollen",
"i18n:govoplan-admin.tenant_permissions.246294bc": "Berechtigungen",
"i18n:govoplan-admin.tenant_role.6b53115d": "Rollenvorlage",
"i18n:govoplan-admin.tenant_roles.51aca82d": "Rollenvorlagen",
"i18n:govoplan-admin.tenant_users.cb800b38": "Mandantenbenutzer",
"i18n:govoplan-admin.tenants.1f7ae776": "Mandanten",
"i18n:govoplan-admin.these_settings_are_enforced_by_the_backend_centr.8112ed6f": "Diese Einstellungen werden vom Backend erzwungen. Zentrale Gruppen und Mandantenrollen bleiben verfügbar, auch wenn lokale Erstellung deaktiviert ist.",