Socotra
ConfigurationConfigurable UI (Beta)

Editor Page

The editor is the step-by-step page users fill in to build a quote or transaction. There is one editor per product, under pages.editor. It serves quotes and every transaction type. Express the differences between them with scope on steps, sections, workflows, and journeys, rather than duplicating the editor.

An editor is built from steps, grouped into workflows. Journeys then choose which workflows a quote or transaction goes through. This skeleton, from uiConfigs/operationsWorkbench/products/HO3/config.json, shows how they nest:

{
	"pages": {
		"editor": {
			"journeys": [{ "workflows": ["submission"] }],
			"workflows": {
				"submission": {
					"display": { "label": "Submission" },
					"steps": [
						{
							"name": "Submission Details",
							"sections": [
								{ "title": "Details", "include": ["data.policyType"] }
							],
							"buttons": [
								{
									"title": "Continue",
									"type": "next",
									"actions": ["validateForm", "save"]
								}
							]
						}
					]
				}
			}
		}
	}
}

For a complete starting editor, see Starting Editor for Any Product.

Starting Editor for Any Product

A product needs only an editor that lists the fields on each step; every other page keeps the platform's default, and every label, input, and format is deduced (see Defaults). This starting editor has two workflows: a data-entry workflow that collects the product's fields, and a lifecycle workflow of read-only result steps. For a homeowners product, shortened:

{
	"display": { "label": "Homeowners HO3" },
	"pages": {
		"editor": {
			"journeys": [{ "workflows": ["default", "lifecycle"] }],
			"workflows": {
				"default": {
					"steps": [
						{
							"name": "Application Details",
							"sections": [
								{
									"hideTitle": true,
									"include": [
										"startTime",
										"endTime",
										"expirationTime",
										"currency",
										"timezone"
									]
								},
								{
									"title": "Details",
									"include": [
										"data.expireIn",
										"data.directBusiness",
										"data.brokerOfRecord"
									]
								},
								{ "title": "Applicant Details", "include": ["data.applicant"] },
								{
									"title": "Advanced Details",
									"layout": { "collapse": "collapsed" },
									"include": [
										"billingLevel",
										"billingTrigger",
										"durationBasis",
										"delinquencyPlanName"
									]
								}
							]
						},
						{
							"name": "Dwelling",
							"sections": [
								{ "title": "Dwelling", "include": ["elements.HO3Dwelling"] }
							]
						}
					]
				},
				"lifecycle": {
					"steps": [
						{
							"name": "Pricing",
							"sections": [{ "title": "Pricing", "type": "pricing-review" }]
						},
						{
							"name": "Validation",
							"sections": [
								{ "title": "Validation", "type": "validation-preview" }
							]
						},
						{
							"name": "Underwriting",
							"sections": [
								{ "title": "Underwriting", "type": "underwriting-original" }
							]
						},
						{
							"name": "Documents",
							"sections": [{ "title": "Documents", "type": "documents" }]
						},
						{
							"name": "Work Management",
							"sections": [
								{ "title": "Work Management", "type": "work-management" }
							]
						}
					]
				}
			}
		}
	}
}

The data-entry workflow follows this pattern, which works for any product:

  1. Open with an Application Details step. Its first section has no title and lists the quote-root lifecycle fields, plus the installment plan preference if the product uses one.
  2. Put all of the product's primitive root data fields (strings, numbers, booleans, and dates) into one Details section.
  3. Give each complex root data field (a nested object or custom data type) its own section.
  4. Add a collapsed Advanced Details section for administrative and billing root fields, such as billingLevel, billingTrigger, durationBasis, delinquencyPlanName, and autoRenewalPlanName.
  5. Add one step per element on the product. A single element renders flat; an array of elements keeps its accordion.

journeys sets the order of the workflows in the step list, and the first workflow opens first. See Journeys.

Steps

A step is one screen of the editor and one entry in the step list. It has sections and footer buttons. This step has a different name on quotes and renewals:

{
	"name": [
		{ "scope": ["quote"], "name": "Submission Details" },
		{ "scope": ["transaction.*.RenewalAmendment"], "name": "Renewal Details" },
		{ "name": "Quote Details" }
	],
	"sections": [
		{
			"title": "Submission",
			"include": ["data.policyType", "data.policyTerm", "data.floridaMarket"]
		}
	],
	"buttons": [
		{ "title": "Continue", "type": "next", "actions": ["validateForm", "save"] }
	]
}
  • name can be a string or a list of gated variants.
  • elementName makes the step edit one exposure, such as the dwelling. Paths in the step's sections are then the exposure's own, such as data.censusBlockGroup.
  • A step with "type": "divider" draws a separator in the step list instead of a step.
  • A step can set its own subheaders and menu, which override the workflow's or editor's.
  • A section slot in sections can hold one section, or a list of gated section variants. See Gated Variants.

Step Navigation

By default, users can't skip ahead in the step list. The editor remembers the furthest step a user has reached with a "Continue" (next) button. That step and every step before it can be opened from the step list; later steps are disabled. To let users open any step, set allowNavigationToUncompletedStep to true on the editor.

  • Opening an earlier step from the step list doesn't change the saved progress.
  • On an issued quote or transaction, every step can be opened.

Buttons and Navigation

A button runs its actions, then can go to a workflow, a step, or a page. For example:

{
	"title": "Continue",
	"type": "next",
	"actions": ["save"],
	"navigation": { "flow": "underwriting" }
}
PropertyTypeDescription
titlestringThe button text.
typestringThe button kind, such as next, previous, custom, save, reset, discard, refuse, change, renew, cancel, or reinstate.
variantstringVisual style, such as primary or destructive.
positionstringWhich side of the button row: left or right.
hidebooleanHides the button.
actionsarrayAction names to run. See Actions.
navigationobjectWhere to go after the actions run: { "flow": … }, { "flow": …, "step": … } or { "page": … }, such as { "page": "policy360" }.
accessobjectWho can see and run the button. Use access.execute to control who can run it.
messageOverridesarrayPer-button message overrides, as { key, value, message } entries, matched against a plugin's error codes.
actionOptionsobjectPer-action options: refreshAuxData: { keys }, and label: { dataKey, maxLength } for an editable button label.
  • A "Continue" (next) button on the last step of a workflow moves to the first step of the next workflow in the journey. A previous button on the first step moves back to the last step of the previous workflow. Set navigation.flow only to go somewhere else.
  • A next button also moves the user's saved progress forward. See Step Navigation.
  • A button can also be shown or hidden with its own scope, roles, when, and unless.
  • type sets the button's role, such as moving to the next step; actions sets what runs when it's clicked. A save button still lists "save" in its actions.

See Actions for the actions a button can run and the order they run in.

Workflows

A workflow groups steps under one name in the step list, such as Submission or Underwriting. workflows is a map of workflows keyed by name. Several variants of a workflow can share one id; the variant whose scope best matches the quote or transaction is used.

PropertyTypeDescription
idstringA logical ID shared by variants of the same workflow.
displayobjectlabel is the workflow's name in the step list.
subheadersarrayThe row under the page title for all of the workflow's steps. See Subheaders.
stepsarrayThe workflow's steps, in order.

Journeys

A journey picks which workflows a quote or transaction goes through, and in which order; that order is the step list. Journeys are checked in order, and the first match is used. Each journey is an access rule, so it can use scope, roles, when, and unless. In this example, quotes and two transaction types share the same workflows, and a third transaction type has its own:

{
	"journeys": [
		{
			"scope": ["quote"],
			"workflows": ["submission", "underwriting", "issuance"]
		},
		{
			"scope": [
				"transaction.*.RenewalAmendment",
				"transaction.*.GenericAmendment"
			],
			"workflows": ["submission", "underwriting", "issuance"]
		},
		{
			"scope": ["transaction.*.ApplicantAmendment"],
			"workflows": ["applicantAmendment"]
		}
	]
}
  • The first workflow in the selected journey opens first.
  • A journey with no scope applies to every entity, so put specific journeys before general ones.
  • A workflow named in a journey that doesn't resolve, because it is hidden by access.read or misspelled, is dropped from the step list.
  • Without journeys, or when no journey matches, the step list follows the order of the workflows keys. End with a journey that has no scope to set the fallback yourself.
  • There are no groupedWorkflows or entryFlow fields in this version; setting them has no effect.

Transaction-editor journeys may be resolved without the entity's data or the user's roles, so select journeys by scope for now.

Page Header, Subheaders, Menu, and Sidebar

Above the steps, every page has a header, a row of subheaders, and a ⋮ menu. The editor can also have a sidebar beside the steps.

PieceDefaultConfigure with
HeaderThe entity's identity, such as the quote or policy number.headerTemplate. Not yet applied on every editor surface.
SubheadersThe product name, then a linked "Account:" row.subheaders on a workflow or step.
MenuA default set of actions. See Menu.menu on the editor or a step.
SidebarNone.sidebar, { "name": …, "sections": [...] }.

Not every piece can be configured on every page yet:

PieceEditorPolicy 360Account 360
HeaderDefault only (headerTemplate isn't applied yet)Default onlyDefault only
SubheadersOn a workflow or stepOn policy360Default only (account number)
MenuOn the editor or a stepThe policy menu from the Details PageNone
SidebarOn the editorNoneNone

Subheaders

subheaders is an ordered array, and it is the whole row. Each entry is a predefined row ("productName" or "account"), or a literal row with a template. Any entry can carry a display.label prefix. For example:

{
	"subheaders": [
		"productName",
		{ "type": "account", "display": { "label": "Customer" } },
		{ "template": "${data.floridaMarket}", "display": { "label": "Market" } }
	]
}
  • Omit subheaders for the default row: the product name, then a labeled "Account:" row.
  • An account entry with no display.label shows the account without a label.
  • A row whose template resolves to nothing is dropped, and the account row is skipped when there is no account.
  • A step's subheaders override its workflow's.

The actions menu in the page header lists page actions. With no menu, it shows the default actions ("Reset", "Copy", and "Refuse"), each shown only when valid for the quote's or transaction's current state. A menu is an object with a buttons list, and its buttons take the same types as step buttons. To show different menus on a quote and a transaction, make menu a list of these objects, each with a scope; it is evaluated as gated variants. This example shows a different menu on quotes and on transactions:

{
	"menu": [
		{
			"scope": ["quote"],
			"buttons": [
				{ "type": "reset" },
				{ "type": "custom", "title": "Copy", "actions": ["quote_copyToGroup"] }
			]
		},
		{ "buttons": [{ "type": "reset" }, { "type": "discard" }] }
	]
}

The sidebar is a read-only panel beside every step of the editor. It has a name, its header, and sections, written like a step's sections. For example:

{
	"sidebar": {
		"name": "File Attachments",
		"sections": [{ "hideTitle": true, "include": ["data.documents"] }]
	}
}

Exposure Editor

An exposure can have its own editor, under pages.editor in exposures/<Exposure>/config.json. It lists steps directly, with no workflows or journeys. Paths in its sections are the exposure's own: data.<field> for its fields and elements.<Coverage> for a coverage on it. This example is from uiConfigs/operationsWorkbench/exposures/HO3Dwelling/config.json:

{
	"display": { "label": "Dwelling" },
	"pages": {
		"editor": {
			"steps": [
				{
					"name": "Dwelling Details",
					"sections": [
						{
							"title": "Property Address",
							"include": [
								"data.propertyStreetAddress",
								"data.propertyCity",
								"data.propertyState"
							]
						}
					]
				},
				{
					"name": "Coverages",
					"sections": [
						{ "title": "Coverages", "include": ["elements.HO3CoverageA"] }
					],
					"buttons": [
						{
							"type": "save",
							"title": "Save",
							"actions": ["validateForm", "save"]
						}
					]
				}
			]
		}
	}
}
  • The exposure editor has its own step progress, separate from the quote's. Progress moves only when a button's actions include save and the save succeeds. See Step Navigation.
  • The exposure editor follows the product editor's allowNavigationToUncompletedStep unless it sets its own.
  • The "Steps" back link at the top of the exposure editor's step list goes back to the quote step it was opened from.

On the exposure editor, headerTemplate and navigation.back are accepted but not yet applied.

Exposures with Their Own Editor on a Quote Step

Once an exposure has its own editor, a quote step that shows it renders the exposure as a read-only summary, with an edit link that opens the exposure's editor.

  • Array of exposures: Each row of the accordion has its own edit link.
  • Single exposure: The summary renders inline, and the edit link is on the right of the section header.
  • Step scoped to the exposure: When the step sets elementName, every section of the step is read-only, and the edit link is in the first section's header. There is no link when the step is the exposure's own editor.
  • Optional single exposure: When the product's contents lists the exposure with ?, the section header also has an add or remove control. The edit link shows once the exposure exists. A prepopulated exposure has no remove control.

Set these on the section's layout:

PropertyTypeDescription
buttons.editButtonbooleanShows the edit link. On a step scoped to the exposure, false on the first section removes the link and keeps the fields editable on the step.
buttons.addButtonbooleanShows the add control. Set false to hide it.
buttons.removeButtonbooleanShows the remove control. Set false to hide it.
elementEditorQueryobjectWhere the edit link opens the exposure's editor, such as { "flow": "bind", "step": 0 }.

Next Steps

See Also

On this page