Wizard Component
UI Component
Changed on:
5 Sept 2025
Overview
The Wizard page component is an alternative top-level layout component for displaying multi-step wizard-like flows, like the wave pick/pack process.It takes a set of "step" configurations, and chooses which user actions and other descendants to display based on the conditions provided in those steps. Describes the usage of `fc.page.wizard.action`.
| Plugin Name | OMS |
|---|
Alias
fc.page.wizard
Detailed technical description
In case some information should be pre-filled, overrides should be used, e.g.,
Properties
| Name | Type | Required | Default | Description |
| title | `string` | no | Text to be shown on the left of the page header. Accepts a Template String. | |
| closePath | `string` | yes | Navigation link of the close button. | |
| steps | `Step[]` | yes | List of steps in the wizard. The first step with a matching condition will be displayed as the content of this page. |
Step
| Name | Type | Required | Default | Description |
| title | string | no | Text to be shown in the page header. Accepts a Template String. | |
| condition | StepCondition[] | yes | Condition to check as to whether this step should be considered active. Typically this would reference the entity status, so that as user actions are submitted and the status changes the wizard progresses to the next step. For example: `"condition": {`` "value": "{{waveById.status}}",`` "matches": "PICK"``}`` `` ``/* vs */`` `` ``"condition": {`` "value": "{{waveById.status}}",`` "matches": "PACK"``}` | |
| action | UserAction | no | The user action to be displayed on this page. If the user action would display a form, this form will appear in the page body in the location defined in the descendants (or first, if not defined there). Note: in cases where there are more than one User Action of the same name, the first will be selected. Below is an example of how to submit a UserAction then navigate to another page: `"action": { `` "name": "WaveComplete",`` "config": { `` "noSuccessMessage": false, `` "extension": { `` "postSubmit": { `` "type": "navigate",`` "link": "waves" `` } `` } `` } ``}` | |
| descendants | MystiqueComponent[] | no | show only the user action form on the page | The components to display when this step is active. These are just regular component definitions, aside from a special case to allow positioning the step action between other components. To do this, use the `fc.page.wizard.action` component. E.g:`descendants: [`` { component: 'fc.page.section.header', props: { title:'Before action' } },`` { component: 'fc.page.wizard.action', props: { width:'full' } },`` { component: 'fc.page.section.header', props: { title:'After action' } }``]` |
| icon | string | no | Icon to be shown in the page header. |
StepCondition
| Name | Type | Required | Default | Description |
| value | string | yes | Template string to match against. | |
| matches | string / string[] | yes | Set of values to match the value against. If any match, the condition is true. |
UserAction
| Name | Type | Required | Default | Description |
| name | string | yes | Name of the user action to submit. | |
| config | UseUserActionFormConfig | no | Configuration of what to do after submitting a user action |
UseUserActionFormConfig
| Name | Type | Required | Default | Description |
| noSuccessMessage | boolean | yes | Don't display a toast after clicking the user action button. This is required to be 'false' if you want to navigate to a page after clicking a UserAction button in a step of the wizard See the example in the manifest below. | |
| extension | UserActionExtension | no | Configuration of what to do after submitting a user action | |
| overrides | key / value (`ExtendedFormField`) | yes | n/a | Field-level overrides to be used when generating a form for the user action. Key is the name of the field. This can be used to change labels, set a source, or replace default field components with SDK-based variants. All values are optional - original values will be used where no override is provided. |
ExtendedFormField
| Name | Type | Required | Default | Description |
| component | `string` | no | none | FieldRegistry alias for an alternate field component that should be used for this field, only for this user action. |
| source | `string` | no | none | The name of a setting that provides options, turning a regular text field into a radio set or dropdown. |
| label | `string` | no | none | Set a different label for this field (supports i18n keys). |
| value | any | no | none | Lock in the value of this field. The field will no longer appear in the form as the provided value will be used instead. |
| defaultValue | any | no | none | Set the initial value of the field. The field will appear in the form and can be changed by the user. |
| helperText | `string` | no | none | User helper text to be presented alongside the field. |
| options | key / value (`string`) | no | none | Value options for this field (e.g. in a 'select' or 'radio group'). |
| sortPrefix | `string` | no | none | Set the position of a field in a form. |
| condition | `string` | no | none | Show a field depending on the condition. Used in cases where the value has one type.`{`` "overrides": {`` "value": {`` "sortPrefix": "5",`` "condition": "{{in valueType 'BOOLEAN' 'INTEGER' 'LOB' 'STRING'}}"`` },`` "lobValue": {`` "component": "fc.attribute.jsoneditor",`` "sortPrefix": "6",`` "condition": "{{in valueType 'JSON'}}"`` }`` }``}` |
| select | `SelectConfig` | no | none | Show a field depending on the condition. Used when a value can have more than one type. First condition which matches the criterion will be applied.`{`` "select": [{`` "inputType": "float",`` "condition": "{{in valueType 'INTEGER'}}"`` }, {`` "inputType": "input",`` "condition": "{{in valueType 'STRING'}}"`` }]``}` |
SelectConfig
| Name | Type | Required | Default | Description |
| condition | `string` | yes | none | Condition upon which the field will be displayed. |
| inputType | `string` | yes | none | FieldRegistry alias for an alternate field component that should be used for the field, only for mutation action. |
| label | `string` | no | none | The human-readable label of the field. |
| options | key / value (`string`) | no | none | Value options for the field (e.g. in 'select' or 'radio group'). |
UserActionExtension
| Name | Type | Required | Default | Description |
| postSubmit | PostSubmitType | yes | Define the navigation varirables for the user action button |
PostSubmitType
| Name | Type | Required | Default | Description |
| type | string | yes | navigate | Specify that the PostSubmitType is a navigation object |
| link | string | yes | The link to navigate to. |
Configuration example
1{
2 "type": "page",
3 "path": "waves-wiz/:id",
4 "fullScreen": true,
5 "component": "fc.page.wizard",
6 "props": {
7 "title": "Wave #{{waveById.id}}",
8 "actions": true,
9 "closePath": "waves",
10 "steps": [
11 {
12 "title": "Step 1 of 3: Pick",
13 "subTitle": "Wave #${waveById.id}",
14 "action": {
15 "name": "PickConfirm",
16 "config":{
17 "overrides":{
18 "actionedBy":{
19 "value":"{{me.username}}"
20 }
21 }
22 }
23 },
24 "condition": {
25 "value": "{{waveById.status}}",
26 "matches": "PICK"
27 },
28 "icon": "MdShoppingBasket",
29 "descendants": [
30 { "component": "fc.page.section.header", "props": { "title":"Pick" } },
31 { "component": "fc.page.wizard.action", "props": { "width":"full" } }
32 ]
33 },
34 {
35 "title": "Step 2 of 3: Pack",
36 "subTitle": "Wave #${waveById.id}",
37 "action": {
38 "name": "WaveDispatch"
39 },
40 "condition": {
41 "value": "{{waveById.status}}",
42 "matches": "PACK"
43 },
44 "icon": "FaBox",
45 "descendants": [
46 {
47 "component": "fc.button.bar",
48 "descendants": [
49 {
50 "component": "fc.button.print.download",
51 "props": {
52 "label": "i18n:fc.sf.ui.waves.detail.action.packingSlip.download.label",
53 "href": "/api/v4.1/wave/{{id}}/pickingList",
54 "filename": "packing-slip.pdf"
55 }
56 }
57 ]
58 },
59 {
60 "component": "fc.list",
61 "dataSource": "fulfilments",
62 "props": {
63 "title": "i18n:fc.sf.ui.wave.pickAndPack.list.pack.title_plural",
64 "attributes": [
65 {
66 "label": "i18n:fc.sf.ui.waves.detail.list.fulfilments.column.order.heading",
67 "value": "{{node.order.ref}}",
68 "link": "#/order/{{node.order.id}}"
69 },
70 {
71 "label": "i18n:fc.sf.ui.waves.detail.list.fulfilments.column.customer.heading",
72 "value": "{{node.order.customer.firstName}}, {{node.order.customer.lastName}}"
73 },
74 {
75 "label": "i18n:fc.sf.ui.waves.detail.list.fulfilments.column.orderType.heading",
76 "value": "{{node.order.type}}"
77 },
78 {
79 "label": "i18n:fc.sf.ui.waves.detail.list.fulfilments.column.carrier.heading",
80 "value": "{{node.articles.edges.0.node.consignmentArticles.edges.0.node.consignment.carrier.name}}"
81 },
82 {
83 "label": "i18n:fc.sf.ui.waves.detail.list.fulfilments.column.fulfilmentStatus.heading",
84 "value": "{{node.status}}"
85 }
86 ]
87 }
88 }
89 ]
90 },
91 {
92 "title": "Step 3 of 3: Dispatch",
93 "subTitle": "Wave #${waveById.id}",
94 "action": {
95 "name": "WaveComplete",
96 "config": {
97 "noSuccessMessage": false,
98 "extension": {
99 "postSubmit": {
100 "type": "navigate",
101 "link": "waves"
102 }
103 }
104 }
105 },
106 "condition": {
107 "value": "{{waveById.status}}",
108 "matches": [
109 "DISPATCH",
110 "COMPLETE"
111 ]
112 },
113 "icon": "FaTruck",
114 "descendants": [
115 {
116 "component": "fc.page.refresh"
117 },
118 {
119 "component": "fc.list",
120 "dataSource": "fulfilments",
121 "props": {
122 "title": "i18n:fc.sf.ui.waves.detail.list.fulfilments.title",
123 "attributes": [
124 {
125 "label": "i18n:fc.sf.ui.waves.detail.list.fulfilments.column.order.heading",
126 "value": "{{node.order.ref}}"
127 },
128 {
129 "label": "i18n:fc.sf.ui.waves.detail.list.fulfilments.column.customer.heading",
130 "value": "{{node.order.customer.firstName}} {{node.order.customer.lastName}}"
131 },
132 {
133 "label": "i18n:fc.sf.ui.waves.detail.list.fulfilments.column.orderType.heading",
134 "value": "{{node.order.type}}"
135 },
136 {
137 "label": "i18n:fc.gql.fulfilment.deliveryType.label",
138 "value": "{{node.order.fulfilmentChoice.deliveryType}}"
139 },
140 {
141 "label": "i18n:fc.sf.ui.waves.detail.list.fulfilments.column.fulfilmentStatus.heading",
142 "value": "{{node.status}}"
143 },
144 {
145 "label": "i18n:fc.sf.ui.waves.detail.list.fulfilments.column.carrier.heading",
146 "value": "{{node.articles.edges.0.node.consignmentArticles.edges.0.node.consignment.carrier.name}}"
147 },
148 {
149 "label": "i18n:fc.sf.ui.courierCollections.detail.list.awaitingCollection.column.consigmentStatus.heading",
150 "value": "{{node.articles.edges.0.node.consignmentArticles.edges.0.node.consignment.status}}"
151 }
152 ]
153 }
154 }
155 ]
156 }
157 ]
158 },
159 "data": {
160 "query": "query ($id: ID!) { waveById(id: $id) { id ref status location { id ref } fulfilments { edges { node { id ref status toAddress { id ref } items { edges { node { ref } } } order { id ref type status fulfilmentChoice{ deliveryType } customer { firstName lastName primaryEmail primaryPhone } } articles { edges { node { ref consignmentArticles { edges { node { consignment { id ref carrier { name } trackingLabel status updatedOn } } } } } } } } } } } me { username } } ",
161 "variables": {
162 "id": "{{params.id}}"
163 }
164 }
165}Version History
Recommended Placement
None

