Actions & row actions
A view can carry toolbar actions (buttons above the grid), row actions (per-row buttons or menu items), a quick-search box, and pre-execute filters. This page covers all four, plus the CSP-safe dispatch envelope that lets server SQL drive the client.
Toolbar actions & row actions
Section titled “Toolbar actions & row actions”<Actions> <Action Name="ExportCsv" Icon="fa fa-file-csv" ExportHandler="Csv">exportTable('Customer');</Action></Actions>
<RowActions> <Action Name="Deactivate" Icon="fa fa-ban" Color="warning" Confirm="Sure?" DisplayExpression="row.IsActive == true"> <Sql>UPDATE Sales.Customers SET IsActive = 0 WHERE Id = @Id;</Sql> </Action> <Action Name="AdjustCredit" Icon="fa fa-sliders"> <Sql>UPDATE Sales.Customers SET CreditLimit = @NewLimit WHERE Id = @Id;</Sql> <Prompt Message="New credit limit" ConfirmLabel="Apply"> <Number Name="NewLimit" Label="New Credit Limit" Required="true" MinValue="0" /> </Prompt> </Action> <Action Name="Site" Icon="fa fa-globe" Url="{Website}" Target="_blank" DisplayColumn="Website" /></RowActions>A toolbar <Action> carries an OnClick script (element body), optional Icon, Confirm,
ExportHandler. A row <Action> resolves its body by precedence <Sql> > Url (link) >
OnClick/script, plus Name, Icon, Color, Confirm, Target, Permission,
DisplayExpression/DisplayColumn (conditional visibility — see
expressions), and an
optional <Prompt> (Message, ConfirmLabel + editor fields collected before the action runs).
Dispatch callbacks (server-driven client actions)
Section titled “Dispatch callbacks (server-driven client actions)”A <Sql> block (in a row action, submit, delete, or an RPC) can drive a client-side action
instead of just returning a value. Return a result set whose first column is named FunctionName;
the engine serializes each row into a CSP-safe Dispatch envelope ({ FunctionName, Param1, Param2, … },
positional in column order, SQL NULL → JS null) and the React UI runs each row through a closed
registry — no eval, no inline JS. Multiple rows run in sequence (each awaited, so a workflow
transition completes before a following refresh). Names must match ^[A-Za-z_][A-Za-z0-9_]*$.
-- Validation message that keeps the form/grid open:SELECT 'showAlert' FunctionName, 'error', 'Invalid Work Package Dates', 'Each work package must stay within project start/end dates.';
-- Refresh the grid after a successful update:UPDATE … ; SELECT 'refreshTable' FunctionName;Supported FunctionName values and their positional params:
FunctionName |
Params | Effect |
|---|---|---|
refreshTable |
— | Reload the surrounding grid/record |
showAlert |
severity, title, message | Blocking dialog; severity = error/success/info/warning |
showSuccess |
title, message | Blocking success dialog |
showError |
title, message | Blocking error dialog |
swal |
title, message, severity | Legacy alias for showAlert (severity defaults to error) |
closeModal |
— | Dismiss the surrounding modal |
navigate |
url | Same-origin redirect (internal routes navigate in-app; javascript: refused) |
historyBack |
— | Browser back |
openWindow |
url, target, features | window.open (defaults _blank, noopener,noreferrer; javascript: refused) |
transitionWorkflow |
instanceId, transitionLabel, returnUrl | Advance a workflow instance, then navigate to returnUrl |
workflowSubmitApproval |
instanceId, nodeKey, decision, comment | Submit an approval decision, then refresh |
startWorkflowsBatch |
definitionName, entityType, entityIdsJson, contextLabel, redirectUrl, initialDataJson | Start a workflow per id (JSON array of ids), report, then redirect |
The client registry lives in src/ui/genie-engine-ui/src/components/genieActions.ts; it is wired into
every mutation handler so any <Sql> that returns this shape is dispatched automatically. The
workflow functions integrate with Wizards & workflows.
Toolbar quick-search
Section titled “Toolbar quick-search”Marking one or more columns Search="true"
enables a search box in the table toolbar. On submit (Enter or the Search button) the typed term is
applied server-side as a single LIKE '%term%' predicate OR-gated across all searchable columns,
then AND-combined with any active column filters — e.g.
(Name LIKE @t OR Email LIKE @t) AND Status = @s. The box appears only when the view declares at least
one searchable column; the term itself is always parameterized and the searchable set is derived from
the view config server-side (the client never picks the columns). SQL-backed views only.
Filters (pre-execute)
Section titled “Filters (pre-execute)”<Filters Toggle="Collapsed"> <!-- Active | Collapsed --> <Select Name="CustomerType" Label="Type"><DataSet Type="static"> … </DataSet></Select> <Date Name="RegisteredFrom" Label="Registered from" /></Filters>Filter fields become @parameters available to <Sql> (guard with (@Param IS NULL OR …)). Children
are editor fields (or <Filter Name="" Type="" /> shorthand); an optional <Layout> lays them out.
Filter <Select>s use the same dataset system as
editor fields.
Worked example: sample/Inventory/models/views/Products.view.xml — toolbar CSV export, row actions
with <Sql> + a <Prompt> + refreshTable/showAlert dispatch, quick-search columns, and
model/sql/static <Filters>.