/** * patient-table — Domain-Specific component * ---------------------------------------------------------------------------- * `PatientTable` is a thin composition over the kit's `data-table` engine * (AG Grid Community) specialised for the AlfaDocs patient list. It bakes in: * * • `buildPatientColumns(t, …)` (one field per column — split identity, * grouped hidden columns, dynamic custom fields) merged with a * consumer-supplied `columns` override. * • the kit data-table built-in renderers (Image / Link / Date / Currency / * Status / TagList / User) plus the three patient renderers kept for the * domain columns (NextAppointment / BalanceBadge / CarePlanStatus). * • a default toolbar — `QuickSearch` + `FilterChips` + `ColumnToggle` + * `ExportMenu` + a `BulkAction` per `props.bulkActions` — overridable * wholesale via `props.toolbar`. * • `useResponsiveColumns` (container-width column-priority tiers) when * `props.responsive` (default `true`). * • multiple row selection, pagination, archived-row tint, loading / empty * overlays. * • `useAgentRegistration(dataTableAgent, handle, gridId)` — the SAME agent * adapter `data-table` registers, keyed by `gridId`. * * The `forwardRef` exposes the inner `DataTableHandle` so consumers * (e.g. the `patients` pattern's WarningStack "View" actions) can drive the * grid imperatively — `setFilter`, `setSort`, `getSelection`, etc. * * CONSTRAINTS (CI-blocking — src/docs/23-constraints.mdx, 26-agent-readiness.mdx): * • No hardcoded colour / spacing / radius / shadow / font — token-bound `ds:` * utilities only. Row tint goes through the token-bound * `data-table-row-archived` class on the AG Grid theme bridge, never an * inline `cellStyle`. * • CSS logical properties only (`ms/me/ps/pe`, `text-start/text-end`). * • All user-visible strings via `useTranslation('ui')` → `ui.patientTable.*`. * • TypeScript strict — no `any`. `forwardRef` exposes the curated handle. * • PHI rule (PRS 26 §6): only `row.id` reaches DOM `data-*`. This component * writes no PHI attribute; AG Grid surfaces ids via its native `row-id`. */ import { type ReactNode } from 'react'; import { type BuildPatientColumnsOptions } from './columns'; import type { PatientBulkAction, PatientColumnDef, PatientCustomFieldDef, PatientRow, PatientRowAction, PatientTableHandle, PatientView } from './types'; export interface PatientTableProps { /** * Row data. `undefined` ⇒ the grid renders its loading overlay (the * data-table contract: `rowData === undefined` is the loading sentinel). Pass * `[]` for an explicit empty state. */ rowData?: PatientRow[]; /** * Override / extend the baked patient columns. When provided, these column * definitions REPLACE the kit defaults entirely (the consumer is expected to * compose `buildPatientColumns(t, …)` — re-exported from the barrel — with * their own additions). When omitted, the kit's `buildPatientColumns` output * is used. */ columns?: PatientColumnDef[]; /** * REQUIRED. Persistence key (column state → `localStorage`) AND the agent * instance address (`data-component-id`). Two tables on one page need * distinct `gridId`s. */ gridId: string; /** Row-height preset. Defaults to the engine default (`'default'`). */ density?: 'compact' | 'default' | 'expanded'; /** * Collapse the per-row actions column into a single "…" overflow trigger * independently of row `density`. When `true` the actions cells render the * collapsed menu and the column shrinks to its 88px compact footprint; when * `false` they render the inline button group at the full expanded width. * When `undefined` (the default) compactness FOLLOWS `density` — `compact` * density collapses the actions, every other density keeps them inline — so * existing consumers are unaffected. Flipping this at runtime re-reads the * actions cells via a stable ref-backed getter (no `columnDefs` rebuild, so * column state is preserved) and resizes the actions column to match. */ actionsCompact?: boolean; /** * Grid height — forwarded to the underlying `DataTable.heightClass` (a Tailwind * height class). Pass `"ds:h-full"` to fill a sized parent, or an explicit * value like `"ds:h-[75vh]"`. Omit to use the engine default (`ds:h-[500px]`). */ heightClass?: string; /** * Enable container-width column-priority responsiveness (lower-priority * columns hide as the grid narrows). Default `true`. Set `false` to leave * column visibility entirely to persistence / `ColumnToggle`. */ responsive?: boolean; /** * Saved column/filter/sort presets. When non-empty AND no custom `toolbar` * is supplied, the default toolbar renders a `Select`-based view switcher in * the FilterBar; choosing a view applies its column visibility (via the * responsive-hook lock so the choice is honoured like a manual ColumnToggle), * `filterModel` (`setFilter`) and `sortModel` (`setSort`). Omitted entirely * when empty / undefined or when `toolbar` is supplied (a custom toolbar owns * its own view UI). */ views?: PatientView[]; /** * Invoked when a per-row action button is activated, with the resolved action * descriptor and the patient row. Only `row.id` ever leaves this boundary into * persistence / agent surfaces — never PHI. */ onRowAction?: (action: PatientRowAction, patient: PatientRow) => void; /** * Toolbar bulk actions (operate on the current selection). Each renders a * `DataTable.Toolbar.BulkAction` that surfaces only while rows are selected; * its `onSelect` receives the selected row ids (never PHI). */ bulkActions?: PatientBulkAction[]; /** * Force the loading overlay independently of `rowData`. When `true` the grid * shows the loading skeleton even if `rowData` is an array (e.g. a background * refresh). `rowData === undefined` also triggers loading. */ loading?: boolean; /** * Replace the default toolbar wholesale. Pass a `…` * tree (it has access to the same toolbar context). When omitted the default * QuickSearch + FilterChips + ColumnToggle + ExportMenu + BulkActions toolbar * is rendered. */ toolbar?: ReactNode; /** * Omit the `QuickSearch` field from the DEFAULT toolbar. The rest of the * default toolbar (view switcher when `views` is supplied, FilterChips, * ColumnToggle, ExportMenu, BulkActions) is unaffected. Ignored when a custom * `toolbar` is supplied (that toolbar owns its own composition). Default * `false` (search shown). Use for surfaces that provide their own search * affordance elsewhere on the page. */ hideQuickSearch?: boolean; /** * Enable the grid's client-side pagination. When `false` (the default), every * row loads into a single virtualised, scrollable view and filter / sort act * over the WHOLE set (no pager) — the right model for a "load and filter all" * list, which is what a patient list is. Pass `true` for a surface that really * wants a pager. */ pagination?: boolean; /** * Page-size dropdown options shown in the pagination panel — forwarded to the * underlying `DataTable.paginationPageSizeSelector`. Pass `false` to hide the * page-size chooser entirely (pagination navigation is unaffected). Default * `[10, 25, 50, 100]` (the engine default). */ paginationPageSizeSelector?: number[] | false; /** * Mask sensitive contact details (email) in the Contact / Email columns. * Forwarded to `buildPatientColumns`' `hideDetails`. Ignored when `columns` * is supplied (the consumer owns their columns then). Default `false`. */ hideDetails?: boolean; /** * Derive the patient-detail href for the Identity cell, e.g. * `(row) => \`/patients/${row.id}\``. Forwarded to `buildPatientColumns`. * Ignored when `columns` is supplied. When omitted the Identity cell routes * its click through `onRowAction` with the `show` action. */ identityHref?: BuildPatientColumnsOptions['identityHref']; /** * Per-practice custom-field descriptors. Each appends one dynamic `custom:*` * column (hidden by default, toggleable via ColumnToggle) after the standard * columns. Forwarded to `buildPatientColumns`. Ignored when `columns` is * supplied (the consumer owns their columns then). */ customFields?: PatientCustomFieldDef[]; /** * ISO 4217 code for the money columns. Forwarded to `buildPatientColumns`, * ignored when `columns` is supplied. Defaults to `EUR`; a practice billing in * another currency must pass its own, or every amount claims euros. */ currency?: string; /** Override the default region aria-label (`ui.patientTable.regionLabel`). */ 'aria-label'?: string; /** Extra class names merged onto the inner grid wrapper. */ className?: string; } export declare const PatientTable: import("react").ForwardRefExoticComponent>; //# sourceMappingURL=patient-table.d.ts.map