import { Scale } from "lucide-react"; import { useEffect, useMemo, useRef, useState } from "react"; import { FormGrid, Button, ConfirmDialog, Dialog, DismissibleAlert, DocumentationHelpLink, FormField, i18nMessage, type ApiSettings } from "@govoplan/core-webui"; import { recordCaseDecision, type CaseDecisionResult, type CaseRecord } from "../../api/cases"; import { CASES_FIELDS_DOCUMENTATION } from "./interfacePatterns"; export default function CaseDecisionDialog({ settings, record, purpose, open, onClose, onSaved }: { settings: ApiSettings; record: CaseRecord; purpose: string; open: boolean; onClose: () => void; onSaved: (result: CaseDecisionResult) => void; }) { const [decisionType, setDecisionType] = useState(""); const [effectiveAt, setEffectiveAt] = useState(""); const [operativeResult, setOperativeResult] = useState(""); const [reasoning, setReasoning] = useState(""); const [conditions, setConditions] = useState(""); const [changeReason, setChangeReason] = useState(""); const [busy, setBusy] = useState(false); const [error, setError] = useState(""); const [confirmOpen, setConfirmOpen] = useState(false); const idempotencyKey = useRef(crypto.randomUUID()); useEffect(() => { if (!open) return; setDecisionType(defaultDecisionType(record)); setEffectiveAt(dateTimeLocalValue(new Date())); setOperativeResult(""); setReasoning(""); setConditions(""); setChangeReason(""); setError(""); setConfirmOpen(false); idempotencyKey.current = crypto.randomUUID(); }, [open, record]); const disabledReason = useMemo(() => { if (busy) return "The formal Decision is being recorded."; if ( !decisionType.trim() || !effectiveAt || !operativeResult.trim() || !reasoning.trim() || !changeReason.trim() ) { return "Complete the Decision type, effective time, result, reasoning, and change reason."; } return undefined; }, [busy, changeReason, decisionType, effectiveAt, operativeResult, reasoning]); async function save() { if (disabledReason) return; setBusy(true); setError(""); try { const result = await recordCaseDecision(settings, record.reference.object_id, { expected_case_revision: record.revision, effective_at: new Date(effectiveAt).toISOString(), decision_type: decisionType.trim(), operative_result: operativeResult.trim(), reasoning: reasoning.trim(), conditions: conditions.split("\n").map((item) => item.trim()).filter(Boolean), change_reason: changeReason.trim(), idempotency_key: idempotencyKey.current, purpose }); setConfirmOpen(false); onSaved(result); onClose(); } catch (reason) { setConfirmOpen(false); setError(reason instanceof Error ? reason.message : "The formal Decision could not be recorded."); } finally { setBusy(false); } } return ( <> } onClose={onClose} closeDisabled={busy} portal className="case-decision-dialog" footer={ <> } >
{error ? {error} : null}

The server verifies your current acting assignment, the effective Mandate, the exact Case revision, evidence, and legal basis before recording the outcome.

setDecisionType(event.target.value)} /> setEffectiveAt(event.target.value)} />