diff --git a/src/govoplan_approvals/backend/manifest.py b/src/govoplan_approvals/backend/manifest.py index 838e832..1014c94 100644 --- a/src/govoplan_approvals/backend/manifest.py +++ b/src/govoplan_approvals/backend/manifest.py @@ -354,6 +354,8 @@ manifest = ModuleManifest( title="Governed approval chains", summary="Create exact-subject approval chains with delegation, separation of duties, escalation, and signature evidence.", body=( + "Documentation books are beside the Approval requests and template headings and beside " + "request or decision dialog titles; field help stays with its label. " "An Approval request freezes its subject revision, ordered steps, eligible selectors, quorum, rejection policy, signature requirement, and governance references. " "Decisions are append-only, tenant-bound, optimistic-concurrency protected, and replay safe. Consuming modules verify the exact subject through the capability rather than reading Approval tables. " "When Tasks is enabled, a pending step appears in the common work inbox only for a principal who currently passes the exact decision eligibility checks. " @@ -394,6 +396,9 @@ manifest = ModuleManifest( "Genehmigungsketten für exakt bezeichnete Gegenstände mit Delegation, Funktionstrennung, Eskalation und Signaturnachweisen erstellen." ), "body": ( + "Dokumentationsbücher stehen neben den Überschriften der Genehmigungsanfragen und Vorlagen " + "sowie neben den Titeln der Anfrage- und Entscheidungsdialoge; Feldhilfe bleibt bei der " + "Feldbezeichnung. " "Ein Genehmigungsantrag fixiert Gegenstandsrevision, geordnete Schritte, zulässige Selektoren, Quorum, " "Ablehnungsregel, Signaturanforderung und Governance-Verweise. Entscheidungen werden nur angefügt, sind " "mandantengebunden, durch optimistische Nebenläufigkeit geschützt und wiederholungssicher. Verbrauchende " diff --git a/webui/src/features/approvals/ApprovalRequestDialog.tsx b/webui/src/features/approvals/ApprovalRequestDialog.tsx index 56b80b1..47d1025 100644 --- a/webui/src/features/approvals/ApprovalRequestDialog.tsx +++ b/webui/src/features/approvals/ApprovalRequestDialog.tsx @@ -41,9 +41,8 @@ export default function ApprovalRequestDialog({ settings, onClose, onSaved }: { else onClose(); } - return }> + return } onClose={requestClose} closeDisabled={busy} portal className="approval-request-dialog" footer={<>}>
-
{error && {error}} setDraft({ ...draft, title: event.target.value })} /> diff --git a/webui/src/features/approvals/ApprovalTemplatesPanel.tsx b/webui/src/features/approvals/ApprovalTemplatesPanel.tsx index 68ab448..bcb1085 100644 --- a/webui/src/features/approvals/ApprovalTemplatesPanel.tsx +++ b/webui/src/features/approvals/ApprovalTemplatesPanel.tsx @@ -190,7 +190,7 @@ export default function ApprovalTemplatesPanel({ ); return <> - } variant="primary" onClick={openCreate} disabled={!canAdmin} disabledReason={!canAdmin ? "Approval administration permission is required." : undefined} />}> + } description="Define reusable, immutable approval chains and compare every published or draft revision." loading={loading} error={error} success={success} actions={<>} variant="primary" onClick={openCreate} disabled={!canAdmin} disabledReason={!canAdmin ? "Approval administration permission is required." : undefined} />}>
row.id} emptyText="No approval templates found." />
diff --git a/webui/src/features/approvals/ApprovalsPage.tsx b/webui/src/features/approvals/ApprovalsPage.tsx index 55b9718..d73b295 100644 --- a/webui/src/features/approvals/ApprovalsPage.tsx +++ b/webui/src/features/approvals/ApprovalsPage.tsx @@ -69,7 +69,9 @@ export default function ApprovalsPage({ settings, auth }: PlatformRouteContext) helpContextId="approvals.workspace" helpModuleId="approvals" primary={<> - void load(), loading: loading || busy, label: "Refresh approvals" }} className="approvals-toolbar" createAction={} helpAction={} /> + } scope="collection-pane" variant="collection" refreshable reloadAction={{ onReload: () => void load(), loading: loading || busy, label: "Refresh approvals" }} className="approvals-toolbar" createAction={} /> {loading && }{items.map((item) => setSelectedId(item.id)}>)}{!loading && items.length === 0 && } } > @@ -98,7 +100,7 @@ function DecisionDialog({ outcome, busy, signatureRequired, onClose, onConfirm } const valid = Boolean(reason.trim() && (!signatureRequired || signatureId.trim())); useUnsavedDraftGuard({ dirty, onSave: async () => valid && onConfirm(reason.trim(), signatureId.trim()), onDiscard: () => { setReason(""); setSignatureId(""); }, title: "i18n:govoplan-approvals.unsaved_title", message: "i18n:govoplan-approvals.unsaved_message" }); const requestClose = () => { if (busy) return; if (dirty) requestDiscard(onClose); else onClose(); }; - return }>