Actions
An action is what a button runs when it's clicked. A button's actions list can name built-in actions, such as save and validateForm, and your own actions, each of which calls an Automation Plugin (see Automation Plugin).
Built-In Actions
Built-in actions run handlers in the Operations Workbench, with no plugin. Any other name is looked up in collections.actions and run as a plugin action.
| Action | What it does |
|---|---|
save | Saves the form. |
validateForm | Checks the fields on the current step. If a check fails, nothing is saved. |
refreshWorkManagement | Reloads the tenant's tasks and diaries, such as after a plugin changes them. |
refreshAuxData | Reloads the aux data keys listed in the button's actionOptions.refreshAuxData.keys. Does nothing without them. |
validate, price, underwrite, accept, issue, refuse, discard | Move the quote or transaction through its lifecycle, such as pricing or issuing it. validate also runs validateForm first. |
copy, reset | Copy the quote, or send it back to draft. Not offered in the transaction editor. |
For example, this button checks the step's fields, saves, and accepts the quote:
{
"type": "next",
"title": "Bind Quote",
"actions": ["validateForm", "save", "accept"]
}Run Order
A button's actions run in four phases. The listed order holds only within a phase:
- Checks:
validateForm, wherever it is listed. If a check fails, nothing is saved. - One server request:
save, the lifecycle actions, and plugin actions, in the listed order. The button waits for each plugin action's response. After asave, the quote or transaction is saved before the next lifecycle or plugin action runs. A failing action stops the rest, and actions that already ran are not undone. - Refreshes:
refreshAuxDataandrefreshWorkManagement. - Plugin actions with
skipAwait: true, started last. The button doesn't wait for their response, so an error from them isn't shown.
- A button that includes
copyorresetruns its actions one at a time, in the listed order. - A name that is neither a built-in action nor in
collections.actionsstops the button, and none of its actions run. - In the transaction editor, lifecycle buttons show only when the transaction's state allows them.
Defining an Action
The typed action contract below isn't live yet. Until it is, use the { name, action } shape in this section. In the meantime, refreshAccount sends its data and the tenant-level setup data, with no locator, and dataModelOverridePlugin sends only its data.
Define actions under collections.actions in the { name, action } shape, where name is the Automation Plugin and action is the plugin action. Reference them by name from a button's actions list. This example defines an action in uiConfigs/operationsWorkbench/collections/config.json:
{
"actions": {
"quote_triggerClearanceInit": {
"name": "PolicyLifecycleOrchestrator",
"action": "run",
"automationPluginSetupData": { "socotraAction": "initial" }
}
}
}A button in a step then runs it:
{
"title": "Refresh Flags",
"type": "custom",
"actions": ["validateForm", "save", "quote_triggerClearanceInit"]
}In this shape, the plugin receives the entity's locator and the action's own automationPluginSetupData.
Typed Action Contract
The typed contract covers every place UI configuration calls an Automation Plugin. Each call uses the same endpoint, request body, and response; only the locator sent with it differs (see What the Plugin Receives):
- Button actions: Actions in a button's
actionslist. - Underwriting flag clears: An action run when a user clears an underwriting flag.
- Account 360 refresh: The refresh button on the
accountDetailscard, set withrefreshAccount. See Overview Pages. - Data model override: A product's
dataModelOverridePlugin, which returns part of the data model to use for that product, such as different coverages by state. It is merged over the tenant's data model. For now, the plugin must return the partial data model as a JSON string.
In collections/config.json, a typed action looks like this:
{
"collections": {
"actions": {
"sendToReview": {
"automation": "WorkflowPlugin/sendToReview",
"method": "POST",
"skipAwait": false,
"skipPrecommit": false,
"data": {
"queue": "underwriting",
"state": { "fieldName": "data.state", "required": true }
},
"automationPluginSetupData": { "priority": "high" },
"access": { "execute": ["Underwriter"] }
}
}
}
}| Property | Type | Description |
|---|---|---|
automation | string | The Automation Plugin and its action, as <pluginName>/<pluginAction>. |
method | string | The HTTP method. Defaults to POST. |
skipAwait | boolean | Runs the action without waiting for it; the response is not read. |
skipPrecommit | boolean | Runs the action without first saving the quote or transaction's unsaved changes. |
data | object | Values to send, one key each. See What the Plugin Receives. |
automationPluginSetupData | object | The action's setup data. Replaces the tenant-level setup data in automationPluginSetupData/; never merged. |
access | object | Who can run the action, with access.execute. |
The UI calls POST /plugin/<tenantLocator>/automation/WorkflowPlugin/sendToReview.
What the Plugin Receives
- The entity's locator:
quoteLocatoron a quote,transactionLocatoron a transaction, oraccountLocatorfor the Account 360 refresh. The data model override sends no locator. A flag clear also sendsflagLocator, and the comment entered in the clear dialog asdiaryContents. - One key per
dataentry. A value is a constant (string, number, or boolean) or a field binding,{ "fieldName": "<path>" }. Add"required": trueto skip the call, with an error message, when the value is empty. automationPluginSetupData: the action's own setup data if it has any; otherwise the tenant-level setup data.
Field bindings in data still read { "field": "<path>" }, not fieldName. Only string, number, and boolean constants are sent; object and array constants are dropped.
{
"quoteLocator": "01J…",
"queue": "underwriting",
"state": "NY",
"automationPluginSetupData": { "priority": "high" }
}A data key with the same name as the locator replaces it. The UI never sends both quoteLocator and transactionLocator, so a plugin that serves both tells them apart by which one is present.
What the Plugin Returns
The plugin returns HTTP 2xx with one of two bodies:
{ "success": { "message": "Sent to review", "responseCode": 200 } }{
"error": {
"errorCode": 404,
"errorMessage": "No addresses for the situs state"
}
}- An
errorstops the button's remaining actions and showserrorMessage. Use HTTP-style error codes, such as400,404, and500, so a button'smessageOverridescan match them. - Anything else counts as success, including a body such as
{ "ok": false }. Report failures througherroronly. - A non-
2xxstatus or a timeout shows a generic error, not your message. - On success, the button reloads the quote or transaction after its last action.
Checklist for Plugin Authors
- Declare every parameter the plugin reads: the locator, each
datakey, andautomationPluginSetupDataif used. Undeclared keys are ignored. - If the plugin serves both quotes and transactions, branch on whether
quoteLocatorortransactionLocatoris present. - Treat setup data as optional, and default any missing key.
- Return the
successorerrorbody with a2xxstatus.
For how to write and deploy the plugin itself, see Automation Plugin.