Technical docs
DataTable System
Purpose
- Shared table framework (TanStack Table v8) used across staff, invites, variables, MCPs, workflows, skills, scout logs, and other admin surfaces. Provides filtering UI, persisted user preferences, mobile-aware actions, and toolbar utilities.
Key Components
- `DataTable` + context providers under `context/`: wires column defs, selection, pagination, persistence, drag-select, and export helpers.
- `FilterPanel`: unified “Filters” popover with column filters plus optional custom filters slot (for example date range, roles, skills). Shows an active badge and a footer `Clear filters`.
- `DateRangeFilter`: preset selector (`all`, `today`, `week`, `month`, `quarter`) for use in the `FilterPanel` header.
- `ActiveFilterChips`: animated chips that mirror active filters outside the popover; auto-compresses to icons/hides when space is tight; clicking a chip removes that filter.
- `Pagination`, `BulkActions`, `ColumnHeader`, `ViewOptions`, and `Skeleton` utilities are exported for feature pages.
- `ViewOptions` supports searchable column visibility, drag reorder, page-size changes, reset-to-defaults, CSV export, JSON export, and print when those capabilities are configured.
- `ActionsCell` provides a shared row-actions pattern:
- desktop: inline icon buttons
- mobile: a single direct action button when only one action is available, otherwise an ellipsis dropdown menu
Persistence (localStorage)
- Keys are namespaced per tableId. Stored pieces:
- Desktop column visibility, mobile column visibility, order, sorting.
- Page size.
- Collapsed group rows.
- Column filters (multi-select values).
- Custom filters (feature-defined objects such as date range/roles/skills).
- Columns version hash (`generateColumnsVersion`) auto-invalidates stored prefs when the set of columns changes.
- Helpers: `load*`/`save*`/`clearColumnFilters`/`loadCustomFilters` in `persistence.ts`. New tables should call `validateAndClearIfNeeded(tableId, columnsVersion)` on init.
- `validateAndClearIfNeeded` currently clears stale visibility, column order, sorting, and collapsed-group state when the columns version changes. It does not clear page size, column filters, or custom filters.
Filtering Behavior
- Column filter options are passed via `ExtendedFilterConfig` (id + label + options + optional `shouldRender` gate). `FilterPanel` toggles values per column and counts active selections for the badge.
- Additional filters (children slot) supply their own state and “active count”; `onClearAdditional` is used by the footer clear button.
- The active badge counts individual selected values plus any additional-filter count supplied by the feature page.
- Chips outside the popover are driven by `activeChips` props so feature pages can surface non-column filters consistently.
Date/Time and Chips UX
- `DateRangeFilter` is label-configurable (defaults to “Added”) and uses small `Select` UI; no calendar picker yet—preset only.
- Chips support color coding (`CHIP_COLOR_CLASSES`) for type/status/role/skill/dateRange and truncate text dynamically.
Integration Notes
- Provide a stable `tableId` per route + view to avoid cross-page collisions.
- When adding/removing columns, update the columns version fed to `validateAndClearIfNeeded` to clear stale visibility/order/filter state.
- Persisted filters/visibility are read on the client; SSR paths should guard usage (`typeof window` checks exist in helpers).
- Server-pagination mode is enabled when `rowCount` and controlled pagination callbacks are provided; otherwise the table uses local pagination.
- Header search is debounced and passed through a deferred value before filtering.
- Footer controls render only when pagination is meaningful or there are selected rows.