From 83b6ff51b779933c55fd2a55ef8c5dce3088909d Mon Sep 17 00:00:00 2001 From: Chaim Date: Sun, 17 May 2026 10:55:45 +0000 Subject: [PATCH] feat: fix wizard step-skip bug + extend case edit with all fields + Paperclip title sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix keyboard navigation bug: React was reusing the submit button DOM element when transitioning "הבא" → "צור תיק", retaining focus and causing Enter to auto-submit step 3. Added key props to force element replacement. - CaseEditDialog now covers all wizard fields: appellants, respondents, property_address, permit_number (in addition to existing title, subject, hearing_date, expected_outcome, notes). - When case title changes, Paperclip project name is updated in background via new update_project_name() in paperclip_client.py. - Extended CaseUpdateRequest, case_update MCP tool, and caseUpdateSchema to carry the new fields end-to-end. Co-Authored-By: Claude Sonnet 4.6 --- mcp-server/src/legal_mcp/tools/cases.py | 16 + .../src/components/cases/case-edit-dialog.tsx | 70 ++- web-ui/src/components/wizard/case-wizard.tsx | 2 + web-ui/src/lib/api/cases.ts | 4 + web-ui/src/lib/api/types.ts | 438 +++++++++++++++++- web-ui/src/lib/schemas/case.ts | 8 + web/app.py | 17 + web/paperclip_client.py | 15 + 8 files changed, 562 insertions(+), 8 deletions(-) diff --git a/mcp-server/src/legal_mcp/tools/cases.py b/mcp-server/src/legal_mcp/tools/cases.py index 1ebd8de..874ee35 100644 --- a/mcp-server/src/legal_mcp/tools/cases.py +++ b/mcp-server/src/legal_mcp/tools/cases.py @@ -271,6 +271,10 @@ async def case_update( decision_date: str = "", tags: list[str] | None = None, expected_outcome: str = "", + appellants: list[str] | None = None, + respondents: list[str] | None = None, + property_address: str = "", + permit_number: str = "", ) -> str: """עדכון פרטי תיק. @@ -284,6 +288,10 @@ async def case_update( decision_date: תאריך החלטה (YYYY-MM-DD) tags: תגיות expected_outcome: תוצאה צפויה (rejection/partial_acceptance/full_acceptance/betterment_levy) + appellants: רשימת עוררים חדשה + respondents: רשימת משיבים חדשה + property_address: כתובת נכס חדשה + permit_number: מספר תכנית/בקשה חדש """ from datetime import date as date_type @@ -322,6 +330,14 @@ async def case_update( fields["tags"] = tags if expected_outcome: fields["expected_outcome"] = expected_outcome + if appellants is not None: + fields["appellants"] = appellants + if respondents is not None: + fields["respondents"] = respondents + if property_address: + fields["property_address"] = property_address + if permit_number: + fields["permit_number"] = permit_number updated = await db.update_case(UUID(case["id"]), **fields) diff --git a/web-ui/src/components/cases/case-edit-dialog.tsx b/web-ui/src/components/cases/case-edit-dialog.tsx index 07fc842..3ecc0c3 100644 --- a/web-ui/src/components/cases/case-edit-dialog.tsx +++ b/web-ui/src/components/cases/case-edit-dialog.tsx @@ -1,7 +1,7 @@ "use client"; import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; +import { useForm, Controller } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { toast } from "sonner"; import { @@ -15,14 +15,15 @@ import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { PartiesField } from "@/components/wizard/parties-field"; import { useUpdateCase } from "@/lib/api/cases"; import { caseUpdateSchema, expectedOutcomes, type CaseUpdateInput } from "@/lib/schemas/case"; import type { CaseDetail } from "@/lib/api/cases"; /* - * Inline edit dialog for core case fields. Uses react-hook-form + zod - * directly (shadcn's
registry entry wasn't available at init - * time, so the styling is reproduced by hand in a lean form layout). + * Inline edit dialog for all case fields set at creation time. + * Uses react-hook-form + zod directly (shadcn's registry entry + * wasn't available at init time, so the styling is reproduced by hand). */ function FieldError({ message }: { message?: string }) { @@ -42,6 +43,10 @@ export function CaseEditDialog({ data }: { data: CaseDetail }) { hearing_date: data.hearing_date ?? "", notes: "", expected_outcome: data.expected_outcome ?? "", + appellants: data.appellants ?? [], + respondents: data.respondents ?? [], + property_address: data.property_address ?? "", + permit_number: data.permit_number ?? "", }, }); @@ -54,6 +59,10 @@ export function CaseEditDialog({ data }: { data: CaseDetail }) { hearing_date: data.hearing_date ?? "", notes: "", expected_outcome: data.expected_outcome ?? "", + appellants: data.appellants ?? [], + respondents: data.respondents ?? [], + property_address: data.property_address ?? "", + permit_number: data.permit_number ?? "", }); }, [open, data, form]); @@ -74,11 +83,11 @@ export function CaseEditDialog({ data }: { data: CaseDetail }) { עריכת פרטי תיק - + עריכת פרטי תיק {data.case_number} - השינויים נשמרים ישירות ל-FastAPI. השדות הריקים נשארים ללא שינוי. + השינויים נשמרים ישירות ל-DB. שינוי כותרת יסנכרן גם ל-Paperclip. @@ -95,6 +104,55 @@ export function CaseEditDialog({ data }: { data: CaseDetail }) { +
+ + ( + + )} + /> + + ( + + )} + /> + +
+ +
+
+ + +
+
+ + +
+
+
diff --git a/web-ui/src/components/wizard/case-wizard.tsx b/web-ui/src/components/wizard/case-wizard.tsx index f4a4bd8..046b7d2 100644 --- a/web-ui/src/components/wizard/case-wizard.tsx +++ b/web-ui/src/components/wizard/case-wizard.tsx @@ -321,6 +321,7 @@ export function CaseWizard() { {isLast ? (