2026-07-14 03:06:56 +03:30
---
name: dyolink-today-dashboard
description: Today tab dashboard — KPIs, charts, deep links, gadget registry. Use when adding/changing Today widgets, chart clicks, or tab navigation from Today.
---
# Today dashboard
**UI:** [`frontend/src/components/ui/today/TodayDashboard.tsx` ](frontend/src/components/ui/today/TodayDashboard.tsx )
**Backend:** [`backend/src/modules/today/today.service.ts` ](backend/src/modules/today/today.service.ts )
**Registry:** [`frontend/src/components/today/widget-registry.ts` ](frontend/src/components/today/widget-registry.ts )
**Deep links:** [`frontend/src/components/today/today-deep-links.ts` ](frontend/src/components/today/today-deep-links.ts )
**Gadget order:** [`frontend/src/components/today/today-gadget-order.ts` ](frontend/src/components/today/today-gadget-order.ts )
## Adding a KPI widget
1. `TodayWidgetKey` in [`frontend/src/types/today.ts` ](frontend/src/types/today.ts )
2. Loader in `today.service.ts` (gate with same permission as target tab)
3. Entry in `TODAY_KPI_DEFINITIONS` — `isVisible` , `formatValue` , `href` or `resolveHref(widgets)` for dynamic links
4. `TODAY_KPI_GADGET_FEATURE` in `today-gadget-order.ts`
5. i18n `today.widget*` keys in **en, fa, nl **
KPIs with count `0` still register; `getVisibleTodayKpis` hides when `formatValue` returns `null` (widget missing from API).
## Deep links & chart clicks
| Source | Target |
|--------|--------|
| Task KPIs | `/tasks?…` via `todayDeepLinks` + `parseTasksSearchParams` |
| Tasks by prosthesis chart (LAB) | `tasksByProsthesis(code)` |
| Case partners chart (LAB) | `casesByClinic(clinicOrgId)` |
| Providers w/o hours (CLINIC) | `staffMissingWorkingHours(membershipIds)` — widget returns `membershipIds[]` ; Staff highlights rows (`STAFF_ROW_HIGHLIGHT_CLASS` ) |
Use `useRouter` from `@/i18n/navigation` for chart clicks. KPI cards use `Link` /`href` on `KpiCard` .
## Charts (LAB examples)
- **Tasks by prosthesis** — `TodayBarChart` + `colorForCode` from prosthesis catalog; `canViewTasks`
2026-07-19 00:37:59 +03:30
- **Cases due** — forward day buckets (next 7 / 30); active sent cases with due date + in-progress task; `canViewCases` ; empty card still shown
- **Lab task activity** — stacked lookback day chart (7 / 30); `canViewCases \|\| canViewTasks`
2026-07-14 03:06:56 +03:30
2026-07-19 00:37:59 +03:30
Week/month day labels: `useTodayDayLabelFormatter` + `mapWeekChartBuckets` .
## Chart period dropdowns
Seven time-window charts support a compact header `<select>` via `ChartCard` `headerAction` (no taller widgets). Periods persist in `localStorage` (`chart-periods.ts` ) and are sent on `GET /today/summary` .
| Chart | Periods | Direction |
|-------|---------|-----------|
| Appointments (all / mine), lab task activity, cases due | week, month | lookback (cases due = **forward ** ) |
| Treatment mix, case partners, efficiency | week, month, year | lookback |
Do **not ** put year on day-series charts. Backend: `daysForChartPeriod` + `buildLocalDayBuckets` in `today.service.ts` .
2026-07-14 03:06:56 +03:30
## Permissions (task KPIs)
`TAB_TASKS_READ` / `TAB_TASKS_EDIT` — **no owner bypass ** (unlike Cases). LAB owner needs tasks participation opt-in for task gadgets.
## Deferred / planned
- **Unread lab updates** (clinic KPI) → `/treatment?labUpdates=1` , scope `updates` , highlight first unread shipment (reuse `GET /treatments/lab-cases/unread` )
- Treatment mix bar click, lab pending send KPI, lab activity day click