Adopt shared WebUI layout primitives

This commit is contained in:
2026-08-18 10:42:50 +02:00
parent 4cf870f322
commit 9731daae4a
4 changed files with 11 additions and 12 deletions
@@ -1,6 +1,6 @@
import { GitCompareArrows, History, Pencil, Plus, Send } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import {
import { FormGrid, ActionToolbar,
AdminIconButton,
AdminPageLayout,
Button,
@@ -196,13 +196,13 @@ export default function ApprovalTemplatesPanel({
<Dialog open={Boolean(editor)} title={editor?.mode === "create" ? "Create approval template" : "Revise approval template"} onClose={() => !busy && setEditor(null)} closeDisabled={busy} className="approval-template-dialog" footer={<><Button onClick={() => setEditor(null)} disabled={busy}>Cancel</Button><Button variant="primary" onClick={() => void save()} disabled={busy || !valid || !canAdmin} disabledReason={!canAdmin ? "Approval administration permission is required." : !valid ? APPROVALS_I18N.incomplete : busy ? APPROVALS_I18N.busy : undefined}>{busy ? "Saving..." : "Save draft revision"}</Button></>}>
<div className="approval-editor">
<div className="approval-editor-grid">
<FormGrid columns={2} gap="compact" collapseAt="workspace">
<FormField label="Stable key"><input value={draft.key} disabled={busy || editor?.mode === "edit"} onChange={(event) => setDraft({ ...draft, key: event.target.value })} /></FormField>
<FormField label="Title"><input value={draft.title} disabled={busy} onChange={(event) => setDraft({ ...draft, title: event.target.value })} /></FormField>
<FormField label="Description" className="approval-editor-wide"><textarea rows={3} value={draft.description ?? ""} disabled={busy} onChange={(event) => setDraft({ ...draft, description: event.target.value })} /></FormField>
<ToggleSwitch label="Separate requester and approver" checked={draft.separation_of_duties} disabled={busy} onChange={(value) => setDraft({ ...draft, separation_of_duties: value })} />
<ToggleSwitch label="Different actor for every step" checked={draft.unique_actors_across_steps} disabled={busy} onChange={(value) => setDraft({ ...draft, unique_actors_across_steps: value })} />
</div>
</FormGrid>
<ApprovalStepsEditor steps={draft.steps} disabled={busy} onChange={(steps) => setDraft({ ...draft, steps })} />
</div>
</Dialog>
@@ -210,11 +210,11 @@ export default function ApprovalTemplatesPanel({
<Dialog open={Boolean(historyTemplate)} title={`${historyTemplate?.title ?? "Template"} history`} onClose={() => !busy && setHistoryTemplate(null)} className="approval-template-history-dialog" footer={<Button onClick={() => setHistoryTemplate(null)} disabled={busy}>Close</Button>}>
<div className="approval-template-history-layout">
<div className="admin-table-surface"><DataGrid id="approval-template-history-v1" rows={history} columns={historyColumns} initialFit="container" getRowKey={(row) => `${row.id}:${row.revision}`} emptyText="No template revisions found." /></div>
<div className="approval-compare-toolbar">
<ActionToolbar className="approval-compare-toolbar">
<FormField label="From revision"><select value={fromRevision} onChange={(event) => setFromRevision(Number(event.target.value))}>{history.map((item) => <option key={item.revision} value={item.revision}>Revision {item.revision} ({item.state})</option>)}</select></FormField>
<FormField label="To revision"><select value={toRevision} onChange={(event) => setToRevision(Number(event.target.value))}>{history.map((item) => <option key={item.revision} value={item.revision}>Revision {item.revision} ({item.state})</option>)}</select></FormField>
<Button onClick={() => void compare()} disabled={busy || !history.length}><GitCompareArrows aria-hidden="true" />Compare</Button>
</div>
</ActionToolbar>
{comparison && <div className="admin-table-surface"><DataGrid id="approval-template-compare-v1" rows={comparison.changes} columns={changeColumns} initialFit="container" getRowKey={(row) => `${row.path}:${row.change}`} emptyText="These revisions have identical template content." /></div>}
</div>
</Dialog>