R2-D2
Dashboard
Node Red
Restreaming
The Force
UpdatedNever
v1.0.0

Overview

Loading…
R2-D2
Dashboard
Node Red
Restreaming
The Force
UpdatedNever
v1.0.0
DDroidspeak / Docs
Operator handbook
Droidspeak
What is R2-D2?
Runtime architectureAuth — Keycloak migration plan
FleetRestreamingGalaxy MapThe RepublicTemple ArchivesSTANAG 4817The Force
Tech StackNext.js 15 + React 19Tailwind v4ZustandTanStack Table + DataViewhls.jsLow-latency playerreagraphoglreact-grid-layoutMonacoScalar API Referencefumadocs
Cluster InfraTrailBaseReductStoreRestreamer (datarhei/core)TBMQKeycloakLonghornkube-vipIngress (Caddy + nginx-ingress + Traefik)Netbird
Operator QA Runbook
Install — RKE2Install — Dokploy
Contributor guideRelease Notes
Tech Stack

TanStack Table + DataView

The only sanctioned way to render a list. Never hand-roll a <table>.

@tanstack/react-table (^8.21.3) is the dashboard's table engine. It sits behind a small set of in-repo primitives under src/components/table/, exposed as a DataView component that toggles between grid, list, and table views with a shared toolbar (search, filter, export).

Never hand-roll a <table>. If you find yourself writing <thead>, <tbody>, manual sort handlers, or a "just for this one page" filter input — stop, and use DataView. Every list surface in the dashboard runs through this primitive.

Why TanStack (and not a UI table component)

We need:

  • Three render modes from one source of truth (grid card, list row, table row).
  • Column virtualization for large feed/instance counts.
  • Headless — the dashboard's row, header, and toolbar visuals are bespoke; we don't want a styled table fighting our Tailwind tokens.

TanStack is headless and supports all three concerns. The thin DataView wrapper provides the dashboard-flavored chrome.

Where it lives in src/

FileRole
src/components/table/DataView.tsxThe top-level component — takes columns + rows + view mode, dispatches to grid/list/table renderers
src/components/table/ (siblings)Toolbar, filter chips, search input, export buttons, view toggle
src/components/FilterBar.tsxThe reusable filter-chip bar used by every plane
src/components/ViewToggle.tsxGrid / list / table radio toggle
src/hooks/useViewMode.tslocalStorage-backed view-mode preference per route
src/lib/downloadCsv.ts, src/lib/downloadJson.tsExport helpers wired into the toolbar

Existing consumers

PageComponentMode default
Fleet → InstancesInstanceTable / InstanceGridView / InstanceListTable
Fleet → Instance ManagementInstancesManagementTableTable
Fleet → FlowsFlowTable / FlowGridViewGrid
Restreaming → HoloVids (feed picker)HoloVidsAssignmentEditor (uses DataView for source feeds)Grid
RepublicRepublic tables (member nations, holdings)Table
Temple ArchivesPer-archive listsTable

Column definition pattern

Every consumer defines columns the same way:

const columns: ColumnDef<Row>[] = [
  { accessorKey: 'id', header: 'ID', cell: ({ row }) => row.original.id },
  { accessorKey: 'status', header: 'Status', cell: StatusPillCell },
  // ...
];

The cell renderer is shared across all three view modes — the grid card and the table row pull from the same React node tree, just laid out differently by the parent.

Toolbar contract

A DataView toolbar always includes:

  1. Search input (filters across all string columns by default).
  2. Filter chips (driven by FilterBar).
  3. View toggle (grid / list / table).
  4. Export buttons (CSV / JSON via downloadCsv / downloadJson).

Pages that need a "create" or "bulk" button add it to the left of the toolbar via the toolbarLeft prop. Pages that need a per-row action add it as a column with a custom cell renderer.

Memory rule

The constraint is stricter than "prefer this primitive" — it's a project rule:

Never hand-roll a <table>; use DataView/TanStack from src/components/table/.

Hand-rolled tables drift on sort behavior, keyboard nav, export semantics, and the view-toggle interaction. They've been caught and replaced; don't reintroduce them.

Extension points

  • New column type — write a cell renderer component and import it; don't extend the column-def shape.
  • New view mode — extend DataView itself. Don't fork.
  • New export format — add a helper to src/lib/ and a button to the toolbar.

See also

  • Components — every plane that lists things
  • Tailwind v4 — table chrome tokens

Zustand

The four stores that hold cross-page client state — and why there are only four.

hls.js

The current HLS playback engine — latency profile, error recovery, snapshot poster fallback.

On this page

Why TanStack (and not a UI table component)Where it lives in src/Existing consumersColumn definition patternToolbar contractMemory ruleExtension pointsSee also