fix(webui): bind approval decisions to help
Module Package Release / publish-packages (push) Successful in 12s
Module Package Release / publish-packages (push) Successful in 12s
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@govoplan/approvals-webui",
|
||||
"version": "0.1.19",
|
||||
"version": "0.1.20",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
|
||||
@@ -76,7 +76,7 @@ export default function ApprovalsPage({ settings, auth }: PlatformRouteContext)
|
||||
{error && <DismissibleAlert tone="danger" resetKey={error}>{error}</DismissibleAlert>}
|
||||
{!canWrite && <ActionBlockerHint tone="info" reason={{ summary: "No Approval creation permission", details: APPROVALS_I18N.writeReason, requiredAction: APPROVALS_I18N.permissionAction, actor: APPROVALS_I18N.permissionActor, target: APPROVALS_I18N.permissionDestination }} labels={{ requiredAction: APPROVALS_I18N.requiredAction, actor: APPROVALS_I18N.actor, target: APPROVALS_I18N.destination }} documentation={APPROVALS_DOCUMENTATION} />}
|
||||
{selected && <PageScrollViewport className="approvals-detail-viewport"><div className="approvals-detail">
|
||||
<header><div><h2>{selected.title}</h2><span>{selected.subject_module} / {selected.subject_type} / {selected.subject_id}{selected.subject_version ? ` @ ${selected.subject_version}` : ""}</span></div><div><StatusBadge status={tone(selected.state)} label={humanize(selected.state)} />{canAdmin && selected.state === "pending" && <Button disabled={busy || !escalationDue} disabledReason={busy ? APPROVALS_I18N.busy : !escalationDue ? "The current step is not due for escalation." : undefined} onClick={() => setEscalating(true)}><AlarmClock size={16} aria-hidden="true" />Escalate</Button>}<Button variant="primary" disabled={busy || !canDecide || !["pending", "escalated"].includes(selected.state)} disabledReason={busy ? APPROVALS_I18N.busy : !canDecide ? APPROVALS_I18N.decideReason : !["pending", "escalated"].includes(selected.state) ? APPROVALS_I18N.lifecycleReason : undefined} onClick={() => setDecision("approved")}><Check size={16} aria-hidden="true" />Approve</Button><Button variant="danger" disabled={busy || !canDecide || !["pending", "escalated"].includes(selected.state)} disabledReason={busy ? APPROVALS_I18N.busy : !canDecide ? APPROVALS_I18N.decideReason : !["pending", "escalated"].includes(selected.state) ? APPROVALS_I18N.lifecycleReason : undefined} onClick={() => setDecision("rejected")}><X size={16} aria-hidden="true" />Reject</Button></div></header>
|
||||
<header><div><h2>{selected.title}</h2><span>{selected.subject_module} / {selected.subject_type} / {selected.subject_id}{selected.subject_version ? ` @ ${selected.subject_version}` : ""}</span></div><div><StatusBadge status={tone(selected.state)} label={humanize(selected.state)} />{canAdmin && selected.state === "pending" && <Button disabled={busy || !escalationDue} disabledReason={busy ? APPROVALS_I18N.busy : !escalationDue ? "The current step is not due for escalation." : undefined} onClick={() => setEscalating(true)}><AlarmClock size={16} aria-hidden="true" />Escalate</Button>}<Button variant="primary" helpContextId="approvals.action.decide-request" helpModuleId="approvals" disabled={busy || !canDecide || !["pending", "escalated"].includes(selected.state)} disabledReason={busy ? APPROVALS_I18N.busy : !canDecide ? APPROVALS_I18N.decideReason : !["pending", "escalated"].includes(selected.state) ? APPROVALS_I18N.lifecycleReason : undefined} onClick={() => setDecision("approved")}><Check size={16} aria-hidden="true" />Approve</Button><Button variant="danger" helpContextId="approvals.action.decide-request" helpModuleId="approvals" disabled={busy || !canDecide || !["pending", "escalated"].includes(selected.state)} disabledReason={busy ? APPROVALS_I18N.busy : !canDecide ? APPROVALS_I18N.decideReason : !["pending", "escalated"].includes(selected.state) ? APPROVALS_I18N.lifecycleReason : undefined} onClick={() => setDecision("rejected")}><X size={16} aria-hidden="true" />Reject</Button></div></header>
|
||||
<MetricGrid columns={4} spacing="block"><MetricCard density="compact" label="Revision" value={selected.revision} /><MetricCard density="compact" label="Current step" value={selected.current_step_key ? humanize(selected.current_step_key) : "Complete"} /><MetricCard density="compact" label="Requested by" value={selected.requested_by || "-"} /><MetricCard density="compact" label="Steps" value={selected.steps.length} /></MetricGrid>
|
||||
{selected.description && <p>{selected.description}</p>}
|
||||
<section><h3>Approval chain</h3><div className="approval-chain">{selected.steps.map((step, index) => <div key={step.key} className={step.key === selected.current_step_key ? "is-current" : ""}><span>{index + 1}</span><strong>{step.label}</strong><small>{step.required_approvals} required / {step.selectors.map((item) => `${humanize(item.kind)}: ${item.label || item.value}`).join(", ")}</small>{step.signature_required && <em>Signature</em>}</div>)}</div></section>
|
||||
|
||||
Reference in New Issue
Block a user