From 028423b32f47efedd4e4975f7f7e8fd3ae745948 Mon Sep 17 00:00:00 2001 From: m Date: Fri, 8 May 2026 02:27:54 +0200 Subject: [PATCH] feat(t-paliad-154) commit 4/5: admin /admin/approval-policies page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New TSX page shell + client orchestration + admin-index card + CSS for the matrix + i18n keys (DE+EN). Page structure: - Section 1 'Partner-Unit-Standards': accordion list, each
block expandable into the 8-cell matrix for that partner unit. - Section 2 'Projekt-spezifisch': search-driven project picker → matrix showing the EFFECTIVE policy per cell with attribution chips (Projekt / Geerbt / Standard) per source. - Bulk-apply modal: 'Auf Unterprojekte anwenden' button per project; lists affected descendants; POST to /api/admin/approval-policies/apply-to-descendants. Cell semantics: - Select per cell with options: '— keine Regel —' (= DELETE), partner / of_counsel / associate / senior_pa / pa / 'Keine Genehmigung' (= 'none' sentinel, project-row only). - Change → PUT for any value, DELETE for empty. Re-fetch the affected scope so attribution chips reflect the new state. CSS: matrix grid on desktop (≥700px); two stacked sections (Fristen / Termine) below 700px via media query — both rendered in DOM, CSS toggles. All tokens are existing --color-* / --status-* / --hlc-*-rgb (no bare --surface / --text-muted / --bg-subtle). i18n: 42 new keys × 2 languages = 84 entries. Total i18n keys: 1924. Build: bun run build clean (i18n codegen updated, IIFE wrapping enforced). --- frontend/build.ts | 3 + frontend/src/admin-approval-policies.tsx | 135 +++++ frontend/src/admin.tsx | 6 + .../src/client/admin-approval-policies.ts | 540 ++++++++++++++++++ frontend/src/client/i18n.ts | 84 +++ frontend/src/styles/global.css | 333 +++++++++++ 6 files changed, 1101 insertions(+) create mode 100644 frontend/src/admin-approval-policies.tsx create mode 100644 frontend/src/client/admin-approval-policies.ts diff --git a/frontend/build.ts b/frontend/build.ts index e770282..4e76433 100644 --- a/frontend/build.ts +++ b/frontend/build.ts @@ -38,6 +38,7 @@ import { renderAdminPartnerUnits } from "./src/admin-partner-units"; import { renderAdminEmailTemplates } from "./src/admin-email-templates"; import { renderAdminEmailTemplatesEdit } from "./src/admin-email-templates-edit"; import { renderAdminEventTypes } from "./src/admin-event-types"; +import { renderAdminApprovalPolicies } from "./src/admin-approval-policies"; import { renderAdminBroadcasts } from "./src/admin-broadcasts"; import { renderPaliadin } from "./src/paliadin"; import { renderAdminPaliadin } from "./src/admin-paliadin"; @@ -267,6 +268,7 @@ async function build() { join(import.meta.dir, "src/client/admin-email-templates.ts"), join(import.meta.dir, "src/client/admin-email-templates-edit.ts"), join(import.meta.dir, "src/client/admin-event-types.ts"), + join(import.meta.dir, "src/client/admin-approval-policies.ts"), join(import.meta.dir, "src/client/admin-broadcasts.ts"), join(import.meta.dir, "src/client/paliadin.ts"), join(import.meta.dir, "src/client/admin-paliadin.ts"), @@ -385,6 +387,7 @@ async function build() { await Bun.write(join(DIST, "admin-email-templates.html"), renderAdminEmailTemplates()); await Bun.write(join(DIST, "admin-email-templates-edit.html"), renderAdminEmailTemplatesEdit()); await Bun.write(join(DIST, "admin-event-types.html"), renderAdminEventTypes()); + await Bun.write(join(DIST, "admin-approval-policies.html"), renderAdminApprovalPolicies()); await Bun.write(join(DIST, "admin-broadcasts.html"), renderAdminBroadcasts()); await Bun.write(join(DIST, "paliadin.html"), renderPaliadin()); await Bun.write(join(DIST, "admin-paliadin.html"), renderAdminPaliadin()); diff --git a/frontend/src/admin-approval-policies.tsx b/frontend/src/admin-approval-policies.tsx new file mode 100644 index 0000000..9cefc92 --- /dev/null +++ b/frontend/src/admin-approval-policies.tsx @@ -0,0 +1,135 @@ +import { h } from "./jsx"; +import { Sidebar } from "./components/Sidebar"; +import { BottomNav } from "./components/BottomNav"; +import { Footer } from "./components/Footer"; +import { PWAHead } from "./components/PWAHead"; + +// t-paliad-154 — admin approval-policy authoring page. Single page with +// two sections: +// +// 1. Partner-Unit-Standards: list of partner_units, each expandable into +// its 8-cell matrix (deadline + appointment × create / update / +// complete / delete). Edits hit /api/admin/partner-units/{id}/... +// +// 2. Projekt-spezifisch: project-tree picker → 8-cell matrix for the +// selected project, showing the EFFECTIVE policy per cell with an +// attribution chip (Projekt / Geerbt / Standard). Edits hit +// /api/projects/{id}/approval-policies/{entity}/{lifecycle}. +// +// Mobile shape: the matrix grid collapses to two stacked sections (Fristen, +// Termine) below 700px — driven by CSS, not by JS. + +export function renderAdminApprovalPolicies(): string { + return "" + ( + + + + + + + Genehmigungspflichten — Paliad + + + + + + +
+
+
+
+

Genehmigungspflichten

+

+ 4-Augen-Prüfung pro Projekt und Partner Unit konfigurieren. +

+
+ +
+
+
+ + {/* Bulk-apply confirm modal — populated client-side. */} + + +