From baf478d9dc286a9e6d15da824b1b3a4d4f54da0b Mon Sep 17 00:00:00 2001 From: Chaim Date: Sun, 28 Jun 2026 17:54:33 +0000 Subject: [PATCH] fix(compose): wire staged-pipeline indicators to live learning-status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two stage indicators in the compose page's "השלמה והעברה" rail ("הרץ למידת-קול" / "הרץ אימות-הלכות") were static placeholder text translated from mockup 03 and never wired to data — they always read "ממתין להעלאת הסופי", even after the final was uploaded and both pipelines completed. (The real status was already shown correctly by LearningStatusBadges on the case page.) Wire them to useCaseLearningStatus (/api/cases/{n}/learning-status) — the same source the drafts-panel badges use (G2). The trailing text is now derived: "ממתין להעלאת הסופי" until the final is uploaded, then the live state ("✓ הושלם · 12 לקחים הופקו · 12 הוצעו לאישור" / "✓ הושלם · חולצו 48 · 33 אושרו · 15 נדחו", or running/queued/failed). Data-binding bugfix only — identical markup/classes (mockup-03 layout preserved), so no visual redesign; within the design-gate bugfix exception (chair-approved approach). tsc + eslint clean. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../app/cases/[caseNumber]/compose/page.tsx | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/web-ui/src/app/cases/[caseNumber]/compose/page.tsx b/web-ui/src/app/cases/[caseNumber]/compose/page.tsx index 5bfcf43..5884779 100644 --- a/web-ui/src/app/cases/[caseNumber]/compose/page.tsx +++ b/web-ui/src/app/cases/[caseNumber]/compose/page.tsx @@ -14,6 +14,10 @@ import { DecisionBlocksPanel } from "@/components/cases/decision-blocks-panel"; import { Markdown } from "@/components/ui/markdown"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { useCase, type CaseStatus } from "@/lib/api/cases"; +import { + useCaseLearningStatus, + type CaseLearningStatus, +} from "@/lib/api/learning"; import { useResearchAnalysis } from "@/lib/api/research"; import { useCasePrecedents } from "@/lib/api/precedents"; import { APPEAL_SUBTYPES } from "@/lib/practice-area"; @@ -52,6 +56,45 @@ function subtypeLabel(subtype?: string | null): string | null { return APPEAL_SUBTYPES.find((s) => s.value === subtype)?.label ?? null; } +// ── Staged-pipeline indicator text (mockup 03) — derived from the live +// learning-status, same source as the drafts-panel LearningStatusBadges. ────── +function voiceLearningText(s?: CaseLearningStatus): string { + if (!s?.final_uploaded) return "ממתין להעלאת הסופי"; + const v = s.voice_learning; + if (v.outcome === "succeeded") { + const bits = [`${v.lessons_count} לקחים הופקו`]; + if (v.lessons_proposed > 0) bits.push(`${v.lessons_proposed} הוצעו לאישור`); + return `✓ הושלם · ${bits.join(" · ")}`; + } + if (v.outcome === "failed") return v.error ? `✗ נכשל — ${v.error}` : "✗ נכשל"; + return "ממתין להרצה"; +} + +function halachaExtractionText(s?: CaseLearningStatus): string { + if (!s?.final_uploaded) return "ממתין להעלאת הסופי"; + const h = s.halacha_extraction; + if (!h.enrolled_in_corpus) + return h.not_enrolled_reason ?? "לא נכנס לקורפוס-הפסיקה"; + switch (h.status) { + case "completed": + return `✓ הושלם · חולצו ${h.halachot_count} · ${h.approved} אושרו · ${h.rejected} נדחו`; + case "processing": + return "רץ עכשיו…"; + case "pending": + case "busy": + return "בתור"; + case "partial": + return `חלקי · חולצו ${h.halachot_count}`; + case "failed": + case "extraction_failed": + return "✗ נכשל"; + case "no_chunks": + return "אין טקסט לחילוץ"; + default: + return "ממתין להרצה"; + } +} + function ProseSection({ title, content }: { title: string; content?: string }) { if (!content?.trim()) return null; return ( @@ -77,6 +120,7 @@ function FinishRail({ const fileRef = useRef(null); const [uploading, setUploading] = useState(false); const [uploadMsg, setUploadMsg] = useState<{ ok: boolean; text: string } | null>(null); + const learning = useCaseLearningStatus(caseNumber); async function handleUpload(file: File) { setUploading(true); @@ -168,10 +212,10 @@ function FinishRail({ {/* mockup 03: stage indicators — informational pointers, not actions */}
- הרץ למידת-קול — ממתין להעלאת הסופי + הרץ למידת-קול — {voiceLearningText(learning.data)}
- הרץ אימות-הלכות — ממתין להעלאת הסופי + הרץ אימות-הלכות — {halachaExtractionText(learning.data)}