feat(templates): UI fuer Berechtigungs-Vorlagen — Modul 6/16 des UI-Backlogs

Backend existierte vollstaendig (list mit entity_type-Filter, create, update,
delete, apply — templates:read/write, seit Audit-Fix im Katalog), Frontend
hatte 0% Abdeckung.

- api/permissionTemplates.ts: TanStack-Hooks (usePermissionTemplates,
  create/update/delete/apply mit Cache-Invalidierung, TemplateLevel-Typ)
- pages/PermissionTemplates.tsx: Template-Karten (Name, Level-Badge,
  Entity-Type, Auto-Share-Zusammenfassung), Create/Edit-Dialog mit
  Level-Select und JSON-Textarea inkl. Array-Validierung mit Fehlertext,
  Apply-Dialog (Entity-Type vorbelegt, Entity-ID), Ergebnis-Banner mit
  Anzahl erstellter Berechtigungen, Delete mit Confirm — alle Aktionen
  hinter templates:write gegated
- Platzierung: Settings-Subpage /settings/permission-templates (statisch,
  Core-Route) + Settings-Nav-Item
- i18n permissionTemplates.* de/en

Verifikation: Vitest 10/10 (Rendering, Level-Badges, Create mit validem +
invalidem JSON, Edit prefilled, Apply mit Ergebnis, Delete-Confirm,
Permission-Gating, Empty/Error) · tsc exit 0 · production build exit 0.
This commit is contained in:
Agent Zero
2026-09-13 10:27:10 +02:00
parent c99d2f19ef
commit 33b4b52206
7 changed files with 880 additions and 0 deletions
+35
View File
@@ -1723,5 +1723,40 @@
"empty": "Keine Plugins gefunden.",
"loadError": "Marketplace konnte nicht geladen werden.",
"noAccess": "Kein Zugriff auf den Marketplace (marketplace:read noetig)."
},
"permissionTemplates": {
"title": "Berechtigungs-Vorlagen",
"create": "Vorlage erstellen",
"createTitle": "Neue Berechtigungs-Vorlage",
"createSubmit": "Erstellen",
"editTitle": "Vorlage bearbeiten",
"save": "Speichern",
"name": "Name",
"namePlaceholder": "z.B. Standard-Freigabe Kontakte",
"entityType": "Entitaets-Typ",
"entityTypePlaceholder": "z.B. contact",
"entityId": "Entitaets-ID",
"level": "Standard-Level",
"levelRead": "Lesen",
"levelWrite": "Schreiben",
"levelAdmin": "Admin",
"levelDelete": "Loeschen",
"level_read": "Lesen",
"level_write": "Schreiben",
"level_admin": "Admin",
"level_delete": "Loeschen",
"autoShareWith": "Automatisch teilen mit",
"autoShareJson": "Freigaben (JSON)",
"autoShareHelper": "Liste von {principal_type, principal_id, level}. Leer = keine Auto-Freigaben.",
"jsonInvalid": "Ungueltiges JSON",
"jsonMustBeArray": "Das JSON muss eine Liste sein",
"apply": "Anwenden",
"applyTitle": "Vorlage '{{name}}' anwenden",
"applySubmit": "Anwenden",
"appliedCount": "{{count}} Berechtigung(en) erstellt",
"delete": "Loeschen",
"deleteConfirm": "Vorlage '{{name}}' wirklich loeschen?",
"empty": "Keine Berechtigungs-Vorlagen vorhanden.",
"loadError": "Vorlagen konnten nicht geladen werden."
}
}
+35
View File
@@ -1723,5 +1723,40 @@
"empty": "No plugins found.",
"loadError": "Failed to load the marketplace.",
"noAccess": "No marketplace access (marketplace:read required)."
},
"permissionTemplates": {
"title": "Permission Templates",
"create": "Create template",
"createTitle": "New permission template",
"createSubmit": "Create",
"editTitle": "Edit template",
"save": "Save",
"name": "Name",
"namePlaceholder": "e.g. Standard contact sharing",
"entityType": "Entity type",
"entityTypePlaceholder": "e.g. contact",
"entityId": "Entity ID",
"level": "Default level",
"levelRead": "Read",
"levelWrite": "Write",
"levelAdmin": "Admin",
"levelDelete": "Delete",
"level_read": "Read",
"level_write": "Write",
"level_admin": "Admin",
"level_delete": "Delete",
"autoShareWith": "Auto-share with",
"autoShareJson": "Share entries (JSON)",
"autoShareHelper": "List of {principal_type, principal_id, level}. Empty = no auto-shares.",
"jsonInvalid": "Invalid JSON",
"jsonMustBeArray": "The JSON must be an array",
"apply": "Apply",
"applyTitle": "Apply template '{{name}}'",
"applySubmit": "Apply",
"appliedCount": "{{count}} permission(s) created",
"delete": "Delete",
"deleteConfirm": "Really delete template '{{name}}'?",
"empty": "No permission templates yet.",
"loadError": "Failed to load templates."
}
}