UIInternal UI

Blocks

DataViewSource / DataViewWrites

@randall-enterprises/ui/components/data-view/data-view-source

The two objects a DataView is built from. `source` is where the rows come from and how a row names itself; `writes` is everything the view may send back. Declare them as typed constants and the compound parts read them through the context — nothing else reaches the data.

const source: DataViewSource<Campaign> = {
  rows,
  fields: CAMPAIGN_FIELDS,
  getRowId: (row) => row.id,
  getRowTitle: (row) => row.name,
  titleFieldKey: "name",          // the table's title column gets a real editor
  getRowIcon: (row) => <Avatar src={row.avatarUrl} />,
  parent: { getId: (r) => r.parentId ?? null, fieldKey: "parentId" },
  label: { singular: "ticket", plural: "tickets" },  // names the empty state
  databaseId: "tickets",          // opens the dynamic-schema surfaces
  partial: hasMore,               // captions the chart instead of lying about totals
  fetchAll: fetchEveryMatchingRow,
};

const writes: DataViewWrites = {
  updateRow: (id, patch) => update.mutate({ id, patch }),
  updateRows: (ids, patch) => bulkUpdate.mutate({ ids, patch }),
  deleteRows: (ids) => setPendingDelete(ids),
  duplicateRows: (ids) => duplicate.mutate(ids),
  delete: { label: "Move to Trash", confirmedByHost: true },
};

<DataView source={source} writes={writes} config={config} onConfigChange={setConfig}>
  <DataView.SavedViews views={views} onViewsChange={setViews} />
  <DataView.Toolbar>
    <DataView.Toolbar.Search />
    <DataView.Toolbar.Settings />
    <DataView.Toolbar.Actions add={{ onAdd, label: "New ticket" }} />
  </DataView.Toolbar>
  <DataView.Body />
</DataView>