improvement: pdf generation added to cases feature.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
description: Lab Cases tab — prosthesis filter, auto-select, list cards
|
||||
globs: frontend/src/components/ui/lab/CasesPage.tsx,frontend/src/components/ui/lab/CaseDetailPanel.tsx,frontend/src/components/ui/lab/LabCaseProsthesisGroupsList.tsx,frontend/src/components/ui/lab/LabCaseShareQr*.tsx,frontend/src/components/lab/caseDetailUtils.ts,backend/src/modules/cases/**
|
||||
description: Lab Cases tab — prosthesis filter, auto-select, list cards, Case Sheet PDF
|
||||
globs: frontend/src/components/ui/lab/CasesPage.tsx,frontend/src/components/ui/lab/CaseDetailPanel.tsx,frontend/src/components/ui/lab/LabCaseProsthesisGroupsList.tsx,frontend/src/components/ui/lab/LabCaseShareQr*.tsx,frontend/src/components/ui/lab/CaseSheet*.tsx,frontend/src/components/lab/caseSheetPdf.ts,frontend/src/components/lab/caseDetailUtils.ts,backend/src/modules/cases/**
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
@@ -11,5 +11,7 @@ alwaysApply: false
|
||||
- **List cards:** `LabCaseProsthesisGroupsList` (catalog color + teeth); same component as Treatment shipments rail; no patient mobile on card.
|
||||
- **Assignment** in detail only (`TAB_CASES_EDIT`); task status changes on Tasks tab.
|
||||
- **Share link:** QR + URL when case is sent; token API + focus page — see `.cursor/skills/lab-case-share-link/SKILL.md`.
|
||||
- **Case Sheet PDF:** client A4 via `jspdf` + `html2canvas`; print layout must stay **hex-only** (Tailwind `lab()`/`oklch` breaks capture). Optional `externalCode` replaces PDF order number when set.
|
||||
- **Detail chrome:** Important Case checkbox (`labelPosition="start"`) then external-code input (no field title; placeholder only).
|
||||
|
||||
Skill: `.cursor/skills/lab-cases/SKILL.md`
|
||||
|
||||
@@ -38,8 +38,39 @@ List item shape: `prosthesisGroups: { prosthesisTypeCode, teeth[] }[]` from task
|
||||
- Task assignment: `PATCH /cases/:caseId/tasks/:taskId/assign` (`TAB_CASES_EDIT`)
|
||||
- Comments: shared `LabCaseCommentsPanel` + `tasksApi` comment routes (`viewerSide="LAB"`). Newest-first; sent/received use logical start/end alignment (RTL-safe). Compact `h-9` composer with primary send + visibility controls.
|
||||
- Mark read: `POST /notifications/mark-case-read` on select (Cases tab badge)
|
||||
- FDI chart (`CaseToothChartPanel`): prosthesis colors + **connected bridge dots** from `selectionGroupId` (`buildCaseConnectedTeeth` / `buildCaseProsthesisRows` in `caseDetailUtils.ts`).
|
||||
- **Important + external code** (`TAB_CASES_EDIT`): row is **Important Case** label then checkbox (`Checkbox` `labelPosition="start"`), then optional external-code input (no title; placeholder only). Save code on blur → `PATCH /cases/:id/external-code`.
|
||||
- **Case Sheet PDF** — see below.
|
||||
- **Share link (sent cases):** `shareUrl` on detail; attachment preview left + QR thumb right; `LabCaseShareQrDialog` (`react-qr-code`). Full flow: `.cursor/skills/lab-case-share-link/SKILL.md`.
|
||||
|
||||
## Case Sheet PDF
|
||||
|
||||
**Entry:** Download PDF beside Comments on `CaseDetailPanel`.
|
||||
**Builder:** [`caseSheetPdf.ts`](frontend/src/components/lab/caseSheetPdf.ts) → off-screen [`CaseSheetPrintLayout.tsx`](frontend/src/components/ui/lab/CaseSheetPrintLayout.tsx) → `html2canvas` → `jspdf` A4 (ISO √2 — prints cleanly onto A3–A6).
|
||||
|
||||
### html2canvas + Tailwind v4 (required)
|
||||
|
||||
Stock `html2canvas` **cannot** parse `lab()` / `oklch()` from app CSS. Do **not** mount live `FdiToothChart` / Tailwind color classes into the capture tree.
|
||||
|
||||
| Do | Don't |
|
||||
|----|--------|
|
||||
| Hex/rgb **inline styles** only in print layout | Tailwind color utilities / CSS variables in capture |
|
||||
| [`CaseSheetFdiChart`](frontend/src/components/ui/lab/CaseSheetFdiChart.tsx) (SVG, catalog hex colors) | Reuse interactive `FdiToothChart` for PDF |
|
||||
| `onclone`: strip `style` + `link[rel=stylesheet]` | Rely on global stylesheets during capture |
|
||||
| Prosthesis labels from **catalog** (then task label) | Fallback `code.replace(/_/g,' ')` alone (breaks casing like `ti base…`) |
|
||||
|
||||
### Layout conventions
|
||||
|
||||
- Sections: meta → parties → **Prosthesis** rows → **Tooth Chart** heading *above* the horizontal rule → chart → Comments.
|
||||
- Connected badge: bold + underline (no border box — html2canvas centering is unreliable).
|
||||
- Order number: `externalCode.trim()` when set, else short case id (`id` without hyphens, first 8, uppercased).
|
||||
- Share QR when `shareUrl` present.
|
||||
|
||||
### API
|
||||
|
||||
- `LabCase.externalCode` (optional string, max 64)
|
||||
- `PATCH /cases/:id/external-code` `{ externalCode: string | null }` — same edit permission as important flag
|
||||
|
||||
## Live soft refresh
|
||||
|
||||
Inbox Socket.IO `notification.created` → `notifyTabBadgesChanged()` → silent `loadCases` + selected `loadDetail` (keeps filters/selection; no full remount). Same event refreshes sidebar Cases badge via `useTabBadgeCounts`. See `.cursor/skills/notifications-inbox/SKILL.md`.
|
||||
|
||||
Reference in New Issue
Block a user