--- name: dyolink-lab-tasks description: Lab Tasks tab — list, sort, filters, case grouping, prosthesis colors, step-completed filter. Use when changing TasksPage, tasks API, or lab task list UX. --- # Lab Tasks Main UI: [`frontend/src/components/ui/lab/TasksPage.tsx`](frontend/src/components/ui/lab/TasksPage.tsx) Backend: [`backend/src/modules/tasks/`](backend/src/modules/tasks/) ## Default sort (backend) `sortBy=date` + `sortDir=desc`: 1. `labCase.sentAt` desc (newest case first) 2. `labCaseId`, `treatmentDetailId`, `prosthesisTypeCode` asc (stable grouping) 3. `stepOrder` asc (steps 1→N within prosthesis group) 4. `id` asc Other sorts use flat list on the frontend; `stepOrder asc` is still a tiebreaker. ## Case grouping (frontend) - **`sortBy === 'date'`** → grouped view via [`taskListGrouping.ts`](frontend/src/components/lab/taskListGrouping.ts): case header → prosthesis sub-header → task rows. - **Other sorts** → flat list; show muted hint (`groupingOff*` i18n keys). Each row keeps clinic/patient/teeth context. Components: `TaskCaseGroupHeader`, `TaskProsthesisGroupHeader`, `TaskRow`. ## Prosthesis colors - Map: [`catalog-type-colors.ts`](frontend/src/components/shared/catalog-type-colors.ts) → `PROSTHESIS_TYPE_COLORS` (one hex per catalog code). - Resolve with [`prosthesisTypeDisplay.ts`](frontend/src/components/treatment/prosthesisTypeDisplay.ts) — use `prosthesisTypeBadgeStyleFromCatalog(code, catalog)`, **not** list row index. - Load catalog via `prosthesisCatalogApi.list()` on Tasks/Cases/Today dashboard. ## Filters | Param | API | UI | |-------|-----|-----| | `q`, `clinicOrganizationId`, `status` | `GET /tasks` | Search, clinic, status | | `stepCompleted` | `GET /tasks` | Workflow step dropdown | | `important` | `GET /tasks` | Important cases only | | Clinics + steps options | `GET /tasks/filter-options` | Populates dropdowns (not from current page) | **Step completed filter:** Restricts to prosthesis groups `(labCaseId, treatmentDetailId, prosthesisTypeCode)` where that `workflowStepCode` task is `COMPLETED`. Combined with `status=IN_PROGRESS`, returns only in-progress tasks in those groups (completed step row hidden). - **Important only:** server-side `important=true` on `GET /tasks` (full list pagination, not per-page client filter). - **Reset view:** `resetView` restores `DEFAULT_TASKS_VIEW` from `tasksViewDefaults.ts`. - **Show in case:** flat-sort rows only; resets filters/sort, calls `GET /tasks/locate-page` to find the correct page in the full default-sorted list, then highlights + scrolls to the task. - **Complete animation:** when marking done under in-progress filter, row plays exit animation + success toast before refetch. ## APIs - `GET /tasks` — paginated flat task list (grouping is client-side when `sortBy=date`) - `PATCH /tasks/:taskId` — update status - `GET /tasks/filter-options` — clinics + workflow steps (localized) - `GET /tasks/locate-page` — page number for a task in the sorted filtered list List items include `caseSentAt` for case headers. ## Permissions `TAB_TASKS_READ` / `TAB_TASKS_EDIT`; `LabOrgGuard` on all task routes.