feat(delegations): UI fuer Berechtigungs-Delegationen — Modul 2/16 des UI-Backlogs

Backend existierte vollstaendig (5 Endpoints: list/create/update/delete/
active-check, delegations:read/write seit Audit-Fix im Katalog), Frontend
hatte 0% Abdeckung. Modul folgt dem Approvals-Muster (Modul 1):

- api/delegations.ts: TanStack-Hooks (useDelegations mit direction-Filter,
useActiveDelegations, create/update/delete-Mutations mit Cache-Invalidierung)
- pages/Delegations.tsx: Richtungstabs (alle/von mir/an mich), Karten mit
  Phasen-Badges (aktiv/geplant/abgelaufen/inaktiv), Erstellen-Dialog mit
  Empfaenger-Picker (useUsers, sich selbst ausschliessend), Start/Ende-
  Datetime, Scope-Toggle (alle Berechtigungen), Aktivieren/Deaktivieren,
  Loeschen mit Confirm — Aktionen hinter delegations:write gegated
- Route /delegations (PermissionRoute delegations:read) — als Core-Route
  bewusst statisch registriert (Phase-Q-Regel: nur Plugin-Routen laufen
  ueber Manifeste) Sidebar-Entry order 92 (ArrowRightLeft-Icon)
- i18n delegations.* + nav.delegations de/en

Verifikation: Vitest 9/9 (Rendering, Tabs, Phasen, Permission-Gating,
Create-Flow, Toggle, Delete) · tsc exit 0 · production build exit 0.
This commit is contained in:
Agent Zero
2026-09-13 09:17:17 +02:00
parent b58c96ff71
commit 36771d471d
7 changed files with 752 additions and 3 deletions
+2
View File
@@ -44,6 +44,7 @@ const AutomationSettingsPage = React.lazy(() => import('@/pages/AutomationSettin
const CustomFieldsPage = React.lazy(() => import('@/pages/CustomFields').then(m => ({ default: m.CustomFieldsPage })));
const ActivityTimelinePage = React.lazy(() => import('@/pages/ActivityTimeline').then(m => ({ default: m.ActivityTimelinePage })));
const ApprovalsPage = React.lazy(() => import('@/pages/Approvals').then(m => ({ default: m.ApprovalsPage })));
const DelegationsPage = React.lazy(() => import('@/pages/Delegations').then(m => ({ default: m.DelegationsPage })));
const SettingsWebhooksPage = React.lazy(() => import('@/pages/SettingsWebhooks').then(m => ({ default: m.SettingsWebhooksPage })));
const SettingsBackupPage = React.lazy(() => import('@/pages/SettingsBackup').then(m => ({ default: m.SettingsBackupPage })));
const WorkspaceManagerPage = React.lazy(() => import('@/pages/SettingsWorkspaces').then(m => ({ default: m.WorkspaceManagerPage })));
@@ -226,6 +227,7 @@ const router = createBrowserRouter([
// via PluginRouteRenderer below - single source of truth.
{ path: '/trash', element: <PermissionRoute permission="contacts:read">{withSuspense(<TrashPage />)}</PermissionRoute> },
{ path: '/approvals', element: <PermissionRoute permission="approvals:read">{withSuspense(<ApprovalsPage />)}</PermissionRoute> },
{ path: '/delegations', element: <PermissionRoute permission="delegations:read">{withSuspense(<DelegationsPage />)}</PermissionRoute> },
{ path: '/api-docs', element: <PermissionRoute permission="settings:read">{withSuspense(<ApiDocsPage />)}</PermissionRoute> },
{ path: '/activity', element: <PermissionRoute permission="audit:read">{withSuspense(<ActivityTimelinePage />)}</PermissionRoute> },
{ path: '/system-dashboard', element: withSuspense(<SystemDashboardPage />) },