Action & Workflow Views
Four view-scale layouts that handle model actions, workflow transitions, and audit history. Each builds on PageTitle from the CRUDL family. The new piece introduced here is the tone-tracked action banner: a full-bleed strip below the title that grounds the action's purpose and risk level before the user reaches the submit button.
Banner tone follows action sentiment: info for neutral confirmations, success for activations and restorations, warning for irreversible non-destructive moves, and destructive for permanent deletions (the destroy variant lives in CRUDL Views). Skipping the banner leaves users wondering what the action will actually do.
ViewAction
The generic action confirmation view: a tone-tracked banner, the records the action targets, a prompt panel restating the question, then the actions strip. It is the one action view that does not fetch anything. ViewDestroy and ViewActivate load their records and hand ModelActionForm a fetch state; ViewAction passes the primary keys straight through, which is why the rows below read as bare keys.
ViewAction also owns a form context of its own, seeded with one entry per primary key. That is what gives per-record server messages somewhere to land, as the third demo shows.
An action with input fills the extra-fields slot. The demo below is the real view with that one slot supplied by a docs-only wrapper; everything rendered is the framework's own output. Type into Reason and submit, then clear it and submit again to see the validation summary.
The dry-run pre-flight is a real request, so it can fail. Here the offline endpoint rejects the pre-flight with per-record messages, which is what a server returns when some of the selected records cannot take the action.
ViewActivate
The activate view is ModelActionForm with request-method="PATCH" and tone="success", which is what establishes the tone-tracking pattern: info for neutral confirmation, success for activate and restore, warning for irreversible non-destructive moves.
The demo below is the live component, mounted through the ModelDemo harness against the seeded showcase customer model. Confirming it sends a real PATCH to the offline endpoint.
ViewExecuteTransition
The framework confirmation for a workflow transition code with no project-supplied override. Visually it is the ViewAction layout above, unchanged: the same tone-tracked banner, the same selected-records panel, and the same prompt-then-actions-strip layout, all still ModelActionForm underneath. There is no dedicated demo below because there is nothing new to look at; see the ViewAction demos above for the shared visual pattern.
The differences are behavioral, not visual. The action's display name defaults to the matching transition's own name from the workflow metadata (falling back to a start-cased version of the transition code while metadata is still loading), and confirming submits through the workflow execute-transition endpoint — carrying transition_code — instead of the generic model-action endpoint ViewAction uses.
WARNING
This confirmation does not explain source state, target state, or why a given object is or is not eligible for the transition. It confirms the transition's display name and the selected records only, the same as any other ModelActionForm confirmation. A dry-run rejection still identifies the rejected object ids in the field errors and validation summary; it just does not render a human-readable eligibility summary alongside them. A richer, transition-aware confirmation surface is a distinct, not-yet-built concern.
theme keys: ViewExecuteTransition, ModelActionForm, ActionForm · source: ViewExecuteTransition.vue
ViewHistoryList
Audit trail for a single object, presented as the actions that produced it. One action groups every event it wrote that touches this object, and each event lists its field changes. The first row of an action carries its metadata (when, who, kind, action name), the first row of each event names the model and event type, and a left stripe ties the rows of one action together. A meta strip above the grid toggles between table and card layouts, and a pagination footer follows.
The demo below is the live component. The actions come from the offline history_list endpoint, so the grouping, the diff cells, and the pills are the framework's own output. Use the Table and Cards buttons to switch layouts.
A record with no history yet gets a dedicated empty state rather than an empty grid.
Customization surface
Every action view is ModelActionForm underneath, so the same slots and props reshape all of them:
banner-titleandbanner-descriptionreplace the generated banner lines;toneswitches the whole card, banner, and icon tile together.confirm-messagereplaces the prompt wording, and the slot of the same name replaces the panel.extra-fieldsadds action-specific inputs below the prompt.actions-hintfills the right side of the actions strip, for a shortcut or an audit note.confirm-buttonreplaces the submit button, including its label.selected-objectsreplaces the whole selected-records panel, for a project that wants richer rows than a name and a primary key.
The action banner, selected-objects panel, prompt block, and actions strip are all composed from tokens — there are no dedicated theme keys for them yet. Customization happens at the token level.
| Surface | Key tokens |
|---|---|
| Info banner | --info, --info-foreground via bg-info/8, border-info/25, text-info |
| Success banner | --success, --success-foreground via bg-success/10, border-success/30, text-success |
| Warning banner | --warning, --warning-foreground via bg-warning/10, border-warning/25, text-warning |
| Destructive banner | --destructive via bg-destructive/5, border-destructive/20 (see CRUDL Views) |
| Prompt block | --border (left rule), --muted (background tint via bg-muted/8) |
| Object list | --border (dividers, outer ring), --radius-vueda-control |
| Actions strip | --border (top hairline) |
| Diff old | --destructive via bg-destructive/5, border-destructive/20, text-destructive |
| Diff new | --success via bg-success/10, border-success/30, text-success |
| Revision stripe | --primary via border-l-2 border-primary on first cell of each revision group |
| Type pill (updated) | --info via bg-info/8, border-info/25, text-info |
| Type pill (created) | --success via bg-success/10, border-success/30, text-success |