diff --git a/web-ui/src/components/cases/status-hero.tsx b/web-ui/src/components/cases/status-hero.tsx index 3cd734e..043d822 100644 --- a/web-ui/src/components/cases/status-hero.tsx +++ b/web-ui/src/components/cases/status-hero.tsx @@ -1,6 +1,6 @@ "use client"; -import { PHASES, type CaseStatus } from "@/lib/api/case-status"; +import { PHASES, phaseIndexOf, type CaseStatus } from "@/lib/api/case-status"; import { statusLabel } from "@/lib/api/case-status"; import { StatusChanger } from "@/components/cases/status-changer"; import { StatusGuide } from "@/components/cases/status-guide"; @@ -22,11 +22,6 @@ const EXPECTED_OUTCOME_LABELS: Record = Object.fromEntries( expectedOutcomes.map((o) => [o.value, o.label]), ); -function phaseIndexOf(status?: CaseStatus): number { - if (!status) return -1; - return PHASES.findIndex((p) => p.statuses.includes(status)); -} - /** Horizontal RTL stepper over the 5 lifecycle phases (mockup 18b .stepper). */ function HorizontalStepper({ status }: { status?: CaseStatus }) { const currentIdx = phaseIndexOf(status); diff --git a/web-ui/src/components/cases/workflow-timeline.tsx b/web-ui/src/components/cases/workflow-timeline.tsx index 4d887d4..0ec9e83 100644 --- a/web-ui/src/components/cases/workflow-timeline.tsx +++ b/web-ui/src/components/cases/workflow-timeline.tsx @@ -1,6 +1,6 @@ "use client"; -import { PHASES, type CaseStatus, type PhaseKey } from "@/lib/api/case-status"; +import { PHASES, phaseIndexOf, type CaseStatus, type PhaseKey } from "@/lib/api/case-status"; import { STATUS_LABELS, STATUS_ICONS, STATUS_DESCRIPTIONS } from "@/components/cases/status-badge"; import { FolderInput, ClipboardList, Brain, PenLine, CheckCircle2, @@ -21,11 +21,6 @@ const PHASE_ICONS: Record = { done: CheckCircle2, }; -function phaseIndexOf(status?: CaseStatus): number { - if (!status) return -1; - return PHASES.findIndex((p) => p.statuses.includes(status)); -} - export function WorkflowTimeline({ status }: { status?: CaseStatus }) { const currentIdx = phaseIndexOf(status); diff --git a/web-ui/src/lib/api/case-status.ts b/web-ui/src/lib/api/case-status.ts index 25aa3ca..d3fdc81 100644 --- a/web-ui/src/lib/api/case-status.ts +++ b/web-ui/src/lib/api/case-status.ts @@ -40,10 +40,40 @@ export const PHASES: { key: PhaseKey; label: string; statuses: CaseStatus[] }[] { key: "done", label: "סגירה", statuses: ["exported", "reviewed", "final"] }, ]; -/** Which phase a status belongs to (undefined for unknown/legacy values). */ +/** + * Legacy/intermediate statuses that the trimmed PHASES list dropped but the + * Paperclip agents still set (e.g. the analyst writes `analyst_verified`, the + * researcher writes `research_complete`). Without this map a case parked on one + * of them renders with NO active phase — the pipeline stepper goes blank and the + * chair can't see where the case stands. Map each to the phase it belongs to for + * display purposes only (these are NOT selectable statuses). + */ +const LEGACY_STATUS_PHASE: Record = { + analyst_verified: "thinking", + research_complete: "thinking", + analysis_enriched: "thinking", + ready_for_writing: "writing", + drafting: "writing", + in_progress: "thinking", +}; + +/** Which phase a status belongs to (undefined only for truly unknown values). */ export function phaseOf(status?: CaseStatus | string): PhaseKey | undefined { if (!status) return undefined; - return PHASES.find((p) => (p.statuses as string[]).includes(status))?.key; + return ( + PHASES.find((p) => (p.statuses as string[]).includes(status))?.key ?? + LEGACY_STATUS_PHASE[status] + ); +} + +/** + * Index of a status within the 5-phase pipeline (−1 only for unknown values). + * Single source of truth for the stepper — handles legacy statuses via phaseOf, + * so a case on `analyst_verified` lands on "ניתוח וכיוון" instead of blank. + */ +export function phaseIndexOf(status?: CaseStatus | string): number { + const key = phaseOf(status); + return key ? PHASES.findIndex((p) => p.key === key) : -1; } export const STATUS_LABELS: Record = {