Socotra
ConfigurationConfigurable UI (Beta)

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.

ActionWhat it does
saveSaves the form.
validateFormChecks the fields on the current step. If a check fails, nothing is saved.
refreshWorkManagementReloads the tenant's tasks and diaries, such as after a plugin changes them.
refreshAuxDataReloads the aux data keys listed in the button's actionOptions.refreshAuxData.keys. Does nothing without them.
validate, price, underwrite, accept, issue, refuse, discardMove the quote or transaction through its lifecycle, such as pricing or issuing it. validate also runs validateForm first.
copy, resetCopy 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:

  1. Checks: validateForm, wherever it is listed. If a check fails, nothing is saved.
  2. One server request: save, the lifecycle actions, and plugin actions, in the listed order. The button waits for each plugin action's response. After a save, 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.
  3. Refreshes: refreshAuxData and refreshWorkManagement.
  4. 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 copy or reset runs its actions one at a time, in the listed order.
  • A name that is neither a built-in action nor in collections.actions stops 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 actions list.
  • Underwriting flag clears: An action run when a user clears an underwriting flag.
  • Account 360 refresh: The refresh button on the accountDetails card, set with refreshAccount. 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"] }
			}
		}
	}
}
PropertyTypeDescription
automationstringThe Automation Plugin and its action, as <pluginName>/<pluginAction>.
methodstringThe HTTP method. Defaults to POST.
skipAwaitbooleanRuns the action without waiting for it; the response is not read.
skipPrecommitbooleanRuns the action without first saving the quote or transaction's unsaved changes.
dataobjectValues to send, one key each. See What the Plugin Receives.
automationPluginSetupDataobjectThe action's setup data. Replaces the tenant-level setup data in automationPluginSetupData/; never merged.
accessobjectWho can run the action, with access.execute.

The UI calls POST /plugin/<tenantLocator>/automation/WorkflowPlugin/sendToReview.

What the Plugin Receives

  • The entity's locator: quoteLocator on a quote, transactionLocator on a transaction, or accountLocator for the Account 360 refresh. The data model override sends no locator. A flag clear also sends flagLocator, and the comment entered in the clear dialog as diaryContents.
  • One key per data entry. A value is a constant (string, number, or boolean) or a field binding, { "fieldName": "<path>" }. Add "required": true to 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 error stops the button's remaining actions and shows errorMessage. Use HTTP-style error codes, such as 400, 404, and 500, so a button's messageOverrides can match them.
  • Anything else counts as success, including a body such as { "ok": false }. Report failures through error only.
  • A non-2xx status 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

  1. Declare every parameter the plugin reads: the locator, each data key, and automationPluginSetupData if used. Undeclared keys are ignored.
  2. If the plugin serves both quotes and transactions, branch on whether quoteLocator or transactionLocator is present.
  3. Treat setup data as optional, and default any missing key.
  4. Return the success or error body with a 2xx status.

For how to write and deploy the plugin itself, see Automation Plugin.

Next Steps

See Also

On this page