Saved views

Saved views #

Classification: Restricted (describes source code structure).

The review list’s tabs are saved views: a filter, a grouping of at most two levels, a sort and columns, under a name. Search text is never part of one. This page is how tofu-web reads, draws and writes them. The decisions behind it are in the saved-views handoff (D1–D22); the list core is @bonsai/utils/extraction-list and the stored shape is bonsapi’s extraction_view.

Where they come from #

Kind Source Who changes it
All (all) Built in (config/extraction-views/all.yaml, generated into views.gen.ts). Never stored. Nobody: fixed first, never hidden, renamed or saved over.
Defaults (ap, ar, expense, bank-statement, not-done) Org views bonsapi seeds before the organization’s first read or write of views, from the same YAML, in each file’s order. name stays null until renamed, so the tab shows the translated label (i18n/view-labels.ts). Owners and admins.
Other org views POST /api/v1/organization/extraction-views Owners and admins (manageOrganizationViews).
Entity views POST /api/v1/extraction-views?entity_id= entity:extraction_view:write (Managers), owners and admins.
Suggestions SUGGESTED_VIEWS, never stored Offered by New view as a starting point.

A default whose type the entity turned off is absent from the bar, not hidden: DEFAULT_VIEW_TOGGLE in domain/extraction-views.ts maps each default key to its entity toggle (AP and AR follow the bill and invoice toggles; there is no credit-note toggle; Not done is always shown).

Reading #

data/queries/extraction-views.ts reads GET /api/v1/extraction-views once per entity and normalises it in select (extractionViewsOf): each definition is checked with isValidSavedView, valid ones are indexed by key in the default order (org views by position, then the entity’s), and the ones that no longer validate are kept apart. Those never reach the bar; More lists them under “Can’t be shown”, and a link to one opens All (D15).

tabsFor builds the bar after All: the person’s own {order, hidden} wins, views it does not name follow in the default order, hidden ones go to More. The person has one {order, hidden} per organization; a save (PUT /api/v1/users/me/extraction-view-tabs?entity_id=) replaces the keys of the organization’s views and that entity’s, and other entities’ keys keep their places.

?view and the list #

The review route carries ?view=<key>; no ?view is All. The container resolves it with resolveActiveView, a union with an explicit unresolved arm: while the views load, a key other than all draws the list’s skeleton, never All’s rows first (no wrong-default flicker). A key the views do not have, or a failed read, opens All with a notice.

Every way into the review keeps ?view (D16): commands that navigate within the review keep the current search, and the ones that arrive from elsewhere (select_entity, the summary, an upload finishing, the bare entity path) ask viewToCarry in state/extraction-list.store.ts, which carries an org view’s key to another entity and an entity view’s only within its own. The entity upload page keeps view in its search, because the list stays beside it.

The reader’s changes (filter, grouping, sort, columns, search) live in the list store, per view key, and are never in the address. changedParts compares the view as saved with the view as shown, ignoring search; the changed strip offers Reset and, for those who may, Save to view or Save as new view.

Relative dates resolve on the reader’s calendar day. useListDay ticks at local midnight and when the tab becomes visible again, and the day reaches toServerParams through listRequestsOf.

Counts #

All and the defaults show counts (D4) from one request: the window grouped by type, then status (listRequestsOf().counts). countFrom folds statuses into bands and sums each default’s types over the bands its filter keeps. A view whose filter reads anything but types and bands gets no count; the header shows the active view’s own total.

Commands #

Command Where Notes
apply_list_view features/extraction-list/commands/extraction-list.ts Data-driven by key; one palette row per view; ←/→ step with replace.
reset_list_view, set_list_columns, copy_extraction_view_link features/extraction-list/commands/extraction-views.ts The reader’s own view; reads.
hide_extraction_view_tab, show_extraction_view_tab, set_extraction_view_tabs same The person’s tabs, queued per organisation. Only hide and show are offered to the assistant.
create_, save_, rename_, move_, delete_, restore_extraction_view features/entity-setting/commands/views.ts Entity Settings commands (defineEntitySettingCommand), shared by the list’s tab menu and Settings › Views.
the same with _organization_ and restore_default_extraction_views features/organization-setting/commands/views.ts Owners and admins; each confirmation counts the entities it reaches.

Shared writes are confirm_first with a confirmDetail. A save sends the view’s updated_at; a 409 (“someone else saved first”) is reported as a conflict. Delete’s Undo puts the stored view back under the same key with a PUT, so links and tab orders keep working. Commands refuse all with a message that says why. Names and descriptions of the bonsapi-backed commands come from extractionViewTools in @bonsai/mcp-tool.

Not in v1 #

Table/gallery switch, empty groups, phone card fields, drag to reorder (Move up / Move down instead), and a description per view.