@ukhomeoffice/cop-react-form-renderer 6.15.11-alpha → 6.15.12-accessibility

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/components/FormComponent/FormComponent.js +6 -0
  2. package/dist/components/FormComponent/helpers/addLabel.js +3 -2
  3. package/dist/components/FormPage/FormPage.js +20 -7
  4. package/dist/components/FormPage/FormPage.test.js +53 -0
  5. package/dist/components/FormRenderer/FormRenderer.js +25 -3
  6. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/cop-reassign-task-to-rcc.json +446 -0
  7. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-chained-component-show-whens-containerised.json +1 -0
  8. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-chained-component-show-whens-dependent-component-nested-block.json +1 -0
  9. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-chained-component-show-whens-dependent-component-nested.json +1 -0
  10. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-chained-component-show-whens-refdata.json +1 -0
  11. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-chained-component-show-whens-target-component-nested.json +1 -0
  12. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-chained-component-show-whens.json +1 -0
  13. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-chained-show-whens-page-hidden.json +1 -0
  14. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-cop-airpax.json +1 -0
  15. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-cop-mandec.json +1 -0
  16. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-collection-component-dependent-on-external-data.json +1 -0
  17. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-collection-component.json +1 -0
  18. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-component-referring-to-collection.json +1 -0
  19. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-component-referring-to-hidden-collection.json +1 -0
  20. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-component-show-when-in-component-and-page.json +1 -0
  21. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-component-with-nested-questions.json +1 -0
  22. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-component.json +1 -0
  23. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-containerised-component.json +1 -0
  24. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-embedded-collection-component.json +1 -0
  25. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-embedded-component.json +1 -0
  26. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-multilevel-containerised-component-leaf-hidden.json +1 -0
  27. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-multilevel-containerised-component.json +1 -0
  28. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-options.json +1 -0
  29. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-page-collection.json +1 -0
  30. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-page-component-used-elsewhere.json +1 -0
  31. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-page-same-component-reused.json +1 -0
  32. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-page.json +1 -0
  33. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-nested-answers-hidden-by-option.json +1 -0
  34. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-page-nested-radio-component.json +201 -0
  35. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-page-same-component-reused-one-shown.json +1 -0
  36. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-variance-breach.json +4272 -0
  37. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/cop-airpax-carrier.json +407 -0
  38. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/cop-variance-breach-with-upload-files.json +1264 -0
  39. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/data-page-nested-radio-component.json +45 -0
  40. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/reassign-to-rcc.json +72 -0
  41. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/output/data-page-nested-radio-component-removed.json +45 -0
  42. package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutes.js +32 -18
  43. package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutes.test.js +73 -31
  44. package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutesUtils.js +15 -7
  45. package/dist/components/FormRenderer/onCYAAction.js +3 -3
  46. package/dist/components/FormRenderer/onCYAAction.test.js +2 -1
  47. package/dist/components/FormRenderer/onPageAction.js +2 -2
  48. package/dist/components/FormRenderer/onPageAction.test.js +2 -1
  49. package/dist/utils/Component/getComponentTests/getComponent.multifile.test.js +2 -1
  50. package/package.json +5 -4
@@ -76,6 +76,12 @@ const FormComponent = _ref => {
76
76
 
77
77
  // eslint-disable-next-line no-param-reassign
78
78
  target = (0, _helpers.addLabel)(target, component, data);
79
+ if (component.type === _models.ComponentTypes.SELECT && target.value === '') {
80
+ // eslint-disable-next-line no-param-reassign
81
+ target.value = null;
82
+ // eslint-disable-next-line no-param-reassign
83
+ target.label = null;
84
+ }
79
85
  onChange({
80
86
  target
81
87
  });
@@ -10,13 +10,14 @@ exports.default = void 0;
10
10
  * @returns The updated target.
11
11
  */
12
12
  const addLabel = (paramTarget, component, data) => {
13
+ var _target$value;
13
14
  const target = paramTarget;
14
15
  // target.value can be an object in which case use value in object attribute
15
- const value = typeof target.value === 'object' ? target.value.value : target.value;
16
+ const value = typeof target.value === 'object' ? (_target$value = target.value) === null || _target$value === void 0 ? void 0 : _target$value.value : target.value;
16
17
  // find the reference data item using the value
17
18
  const item = data.find(e => String(e.id) === value);
18
19
  // if item is null it means that the target.value can be used as a label otherwise use item.label
19
- target.label = item === undefined ? target.value : item.label;
20
+ target.label = item === undefined ? target.value || '' : item.label;
20
21
  target.component = component.cya_label;
21
22
  return target;
22
23
  };
@@ -19,6 +19,8 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
19
19
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
20
20
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
21
21
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
22
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var s = Object.getOwnPropertySymbols(e); for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
23
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
22
24
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
23
25
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // Global imports
24
26
  // Local imports.
@@ -67,20 +69,31 @@ const FormPage = _ref => {
67
69
  target
68
70
  } = _ref2;
69
71
  const formPage = page;
70
- if (target.value == null) {
72
+ const {
73
+ value
74
+ } = target;
75
+ if (!value) {
71
76
  delete formPage.formData[target.name];
72
77
  setPatch(prev => {
73
- const data = prev;
74
- return delete data[target.name];
78
+ const _target$name = target.name,
79
+ {
80
+ [_target$name]: removedValue
81
+ } = prev,
82
+ newState = _objectWithoutProperties(prev, [_target$name].map(_toPropertyKey));
83
+ return newState;
75
84
  });
76
85
  setPatchLabel(prev => {
77
- const data = prev;
78
- return delete data[target.component];
86
+ const _target$component = target.component,
87
+ {
88
+ [_target$component]: removedValue
89
+ } = prev,
90
+ newState = _objectWithoutProperties(prev, [_target$component].map(_toPropertyKey));
91
+ return newState;
79
92
  });
80
93
  } else {
81
- formPage.formData[target.name] = target.value;
94
+ formPage.formData[target.name] = value;
82
95
  setPatch(prev => _objectSpread(_objectSpread({}, prev), {}, {
83
- [target.name]: target.value
96
+ [target.name]: value
84
97
  }));
85
98
  setPatchLabel(prev => _objectSpread(_objectSpread({}, prev), {}, {
86
99
  [target.component]: target.label
@@ -337,5 +337,58 @@ describe('components.FormPage', () => {
337
337
  }));
338
338
  expect(ON_ACTION_CALLS.length).toEqual(0);
339
339
  });
340
+ it('removed field from the form data when the value is set to null', () => {
341
+ const AUTOCOMPLETE = {
342
+ id: 'autocomplete',
343
+ fieldId: 'autocomplete',
344
+ label: 'autocomplete',
345
+ hint: '',
346
+ type: 'autocomplete',
347
+ required: true,
348
+ source: [{
349
+ id: 'a',
350
+ name: 'apple'
351
+ }, {
352
+ id: 'b',
353
+ name: 'banana'
354
+ }, {
355
+ id: 'c',
356
+ name: 'cherry'
357
+ }, {
358
+ id: 'd',
359
+ name: 'DURIAN'
360
+ }],
361
+ disabled: false
362
+ };
363
+ const page = {
364
+ id: 'page1',
365
+ title: 'Page title',
366
+ label: 'Page label',
367
+ components: [AUTOCOMPLETE],
368
+ formData: {
369
+ autocomplete: 'autocomplete value example'
370
+ },
371
+ actions: []
372
+ };
373
+ const onChangeMock = jest.fn();
374
+ const {
375
+ getByLabelText
376
+ } = (0, _setupTests.renderWithValidation)(/*#__PURE__*/_react2.default.createElement(_FormPage.default, {
377
+ page: page,
378
+ fromTarget: true,
379
+ onAction: onChangeMock,
380
+ onChange: onChangeMock
381
+ }));
382
+ const input = getByLabelText('autocomplete');
383
+ _react.fireEvent.change(input, {
384
+ target: {
385
+ name: 'autocomplete',
386
+ value: '',
387
+ component: 'autocomplete'
388
+ }
389
+ });
390
+ const updatedState = onChangeMock.mock.calls.pop()[0];
391
+ expect(updatedState.autocomplete).toBeUndefined();
392
+ });
340
393
  });
341
394
  });
@@ -39,6 +39,7 @@ const FormRenderer = _ref => {
39
39
  let {
40
40
  title,
41
41
  type,
42
+ cleanseHiddenData,
42
43
  components,
43
44
  pages,
44
45
  hub,
@@ -61,6 +62,7 @@ const FormRenderer = _ref => {
61
62
  }, /*#__PURE__*/_react.default.createElement(_context.ValidationContextProvider, null, /*#__PURE__*/_react.default.createElement(InternalFormRenderer, {
62
63
  title: title,
63
64
  type: type,
65
+ cleanseHiddenData: cleanseHiddenData,
64
66
  components: components,
65
67
  pages: pages,
66
68
  hub: hub,
@@ -84,6 +86,7 @@ const InternalFormRenderer = _ref2 => {
84
86
  let {
85
87
  title,
86
88
  type,
89
+ cleanseHiddenData,
87
90
  components,
88
91
  pages: _pages,
89
92
  hub: _hub,
@@ -126,6 +129,18 @@ const InternalFormRenderer = _ref2 => {
126
129
  validate
127
130
  } = (0, _hooks.useValidation)();
128
131
 
132
+ // Set focus to header for accessibility, Screen reader to anounce the page heading
133
+ const setFocusToHeading = () => {
134
+ if (document) {
135
+ const header = Array.from(document.getElementsByTagName('h1')).pop();
136
+ if (header && document.activeElement !== header) {
137
+ header.setAttribute('tabIndex', '-1');
138
+ header.focus();
139
+ header.removeAttribute('tabIndex');
140
+ }
141
+ }
142
+ };
143
+
129
144
  // Need to set submission data when going back
130
145
  window.onpopstate = e => {
131
146
  var _formState$page;
@@ -189,6 +204,11 @@ const InternalFormRenderer = _ref2 => {
189
204
  setFormState(_helpers.default.getFormState(pageId, pages, hub));
190
205
  }, [pages, hub, pageId, setFormState, type, goingBack, data, formState.page]);
191
206
 
207
+ // Set focus to heading for accessibility
208
+ (0, _react.useEffect)(() => {
209
+ setFocusToHeading();
210
+ }, [formState]);
211
+
192
212
  // Call the onFormLoad hook just when this component first renders.
193
213
  (0, _react.useEffect)(() => {
194
214
  setPagePoint(undefined);
@@ -295,7 +315,7 @@ const InternalFormRenderer = _ref2 => {
295
315
  actions: (_formState$page$actio = formState.page.actions) === null || _formState$page$actio === void 0 ? void 0 : _formState$page$actio.filter(action => _utils.default.Component.show(action, data))
296
316
  }, formState.cya, {
297
317
  onAction: action => {
298
- (0, _onCYAAction.default)(setPagePoint, action, pages, validate, components, data, setData, type, pageId, currentTask, hooks, addErrors, hub, onPageChange, formState, submitting, setSubmitting);
318
+ (0, _onCYAAction.default)(setPagePoint, action, pages, validate, cleanseHiddenData, components, data, setData, type, pageId, currentTask, hooks, addErrors, hub, onPageChange, formState, submitting, setSubmitting);
299
319
  },
300
320
  onRowAction: onCYARowAction,
301
321
  summaryListClassModifiers: summaryListClassModifiers,
@@ -316,7 +336,7 @@ const InternalFormRenderer = _ref2 => {
316
336
  page: formState.page,
317
337
  pages: [].concat(pages),
318
338
  onAction: (action, patch, patchLabel) => {
319
- (0, _onPageAction.default)(action, patch, patchLabel, hooks, data, formState, validate, onPageChange, type, pages, components, pageId, setPagePoint, currentTask, setData, hubDetails, setSubmitted, addErrors, submitting, setSubmitting, errors);
339
+ (0, _onPageAction.default)(action, patch, patchLabel, hooks, data, formState, validate, onPageChange, type, cleanseHiddenData, pages, components, pageId, setPagePoint, currentTask, setData, hubDetails, setSubmitted, addErrors, submitting, setSubmitting, errors);
320
340
  },
321
341
  onChange: onChange,
322
342
  hashLink: hashLink,
@@ -329,7 +349,7 @@ const InternalFormRenderer = _ref2 => {
329
349
  pages: pages,
330
350
  onCollectionChange: onChange,
331
351
  onAction: (action, patch, patchLabel) => {
332
- (0, _onPageAction.default)(action, patch, patchLabel, hooks, data, formState, validate, onPageChange, type, pages, components, pageId, setPagePoint, currentTask, setData, hubDetails, setSubmitted, addErrors, submitting, setSubmitting, errors);
352
+ (0, _onPageAction.default)(action, patch, patchLabel, hooks, data, formState, validate, onPageChange, type, cleanseHiddenData, pages, components, pageId, setPagePoint, currentTask, setData, hubDetails, setSubmitted, addErrors, submitting, setSubmitting, errors);
333
353
  },
334
354
  hashLink: hashLink,
335
355
  classModifiers: formState.page.classModifiers,
@@ -363,6 +383,7 @@ const propTypes = {
363
383
  pages: _propTypes.default.arrayOf(_propTypes.default.shape({})).isRequired,
364
384
  summaryListClassModifiers: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.arrayOf(_propTypes.default.string)]),
365
385
  title: _propTypes.default.string,
386
+ cleanseHiddenData: _propTypes.default.bool,
366
387
  /** See <a href="/?path=/docs/f-json--page#formtypes">FormTypes</a>. */
367
388
  type: _propTypes.default.oneOf([_models.FormTypes.CYA, _models.FormTypes.FORM, _models.FormTypes.HUB, _models.FormTypes.TASK, _models.FormTypes.WIZARD, _models.FormTypes.TASK_CYA, _models.FormTypes.FORM_WITH_TASK]).isRequired,
368
389
  viewOnly: _propTypes.default.bool,
@@ -388,6 +409,7 @@ const defaultProps = {
388
409
  noChangeAction: false,
389
410
  summaryListClassModifiers: [],
390
411
  title: '',
412
+ cleanseHiddenData: false,
391
413
  viewOnly: true,
392
414
  hideBlankRows: false
393
415
  };
@@ -0,0 +1,446 @@
1
+ {
2
+ "cleanseHiddenData": true,
3
+ "cya": {
4
+ "actions": [
5
+ {
6
+ "type": "submit",
7
+ "label": "Submit",
8
+ "validate": true
9
+ }
10
+ ],
11
+ "confirm": [
12
+ {
13
+ "title": "Task kept with NCC",
14
+ "message": [
15
+ "<h2 class='govuk-heading-m'>What happens next</h2>",
16
+ "<p class='govuk-body'>Review the task by ${reviewTimeP} on ${reviewDateP}.</p>",
17
+ "<p class='govuk-body'>To view the task, go to <a href='/tms/open-tasks'>open NCC tasks</a>. You can track updates in the task's timeline.</p>",
18
+ "<p class='govuk-body'><a href='/'>Go to homepage</a></p>",
19
+ "<p class='govuk-body'><a href='https://lssiprod.service-now.com/ess?id=take_survey&type_id=e0e2125b1bdd1110f8655946464bcbf7'>What do you think of this service?</a></p>"
20
+ ],
21
+ "show_when": [
22
+ {
23
+ "op": "=",
24
+ "field": "assignWhere",
25
+ "value": "NCC"
26
+ }
27
+ ]
28
+ },
29
+ {
30
+ "title": "Task assigned to RCC",
31
+ "message": [
32
+ "<h2 class='govuk-heading-m'>What happens next</h2>",
33
+ "<p>This task will automatically close at 23:59 on ${autoClose} - the day after the event date.</p>",
34
+ "<p>To view the task, go to <a href='/tms/open-tasks'>open NCC tasks</a>. You can track updates in the task's timeline.</p>",
35
+ "<p>You can only work on the task when it is assigned to NCC.</p>",
36
+ "<p><a href='/'>Go to homepage</a></p>",
37
+ "<p><a href='https://lssiprod.service-now.com/ess?id=take_survey&type_id=e0e2125b1bdd1110f8655946464bcbf7'>What do you think of this service?</a></p>"
38
+ ],
39
+ "show_when": [
40
+ {
41
+ "type": "and",
42
+ "conditions": [
43
+ {
44
+ "op": "=",
45
+ "field": "assignWhere",
46
+ "value": "RCC"
47
+ },
48
+ {
49
+ "op": "=",
50
+ "field": "responseNeeded",
51
+ "value": "No"
52
+ }
53
+ ]
54
+ }
55
+ ]
56
+ },
57
+ {
58
+ "title": "Task assigned to RCC",
59
+ "message": [
60
+ "<h2 class='govuk-heading-m'>What happens next</h2>",
61
+ "<p class='govuk-body'>You set a review date of ${reviewTimeP} on ${reviewDateP}.</p>",
62
+ "<p class='govuk-body'>To view the task, go to <a href='/tms/open-tasks'>open NCC tasks</a>. You can track updates in the task's timeline.</p>",
63
+ "<p class='govuk-body'>You can only work on the task when it is assigned to NCC.</p>",
64
+ "<p class='govuk-body'><a href='/'>Go to homepage</a></p>",
65
+ "<p class='govuk-body'><a href='https://lssiprod.service-now.com/ess?id=take_survey&type_id=e0e2125b1bdd1110f8655946464bcbf7'>What do you think of this service?</a></p>"
66
+ ],
67
+ "show_when": [
68
+ {
69
+ "type": "and",
70
+ "conditions": [
71
+ {
72
+ "op": "=",
73
+ "field": "assignWhere",
74
+ "value": "RCC"
75
+ },
76
+ {
77
+ "op": "=",
78
+ "field": "responseNeeded",
79
+ "value": "Yes"
80
+ }
81
+ ]
82
+ }
83
+ ]
84
+ },
85
+ {
86
+ "title": "Task assigned to RCC",
87
+ "message": [
88
+ "<h2 class='govuk-heading-m'>What happens next</h2>",
89
+ "<p class='govuk-body'>RCC will review this task.</p>",
90
+ "<p class='govuk-body'><a href='/'>Go to homepage</a></p>",
91
+ "<p class='govuk-body'><a href='https://lssiprod.service-now.com/ess?id=take_survey&type_id=e0e2125b1bdd1110f8655946464bcbf7'>What do you think of this service?</a></p>"
92
+ ],
93
+ "show_when": [
94
+ {
95
+ "type": "and",
96
+ "conditions": [
97
+ {
98
+ "op": "!includes",
99
+ "field": "keycloakContext.groups",
100
+ "value": "/BFNCC"
101
+ }
102
+ ]
103
+ }
104
+ ]
105
+ }
106
+ ],
107
+ "insertDateTime": true
108
+ },
109
+ "name": "cop-reassign-task-to-rcc",
110
+ "type": "cya",
111
+ "pages": [
112
+ {
113
+ "id": "assignTask",
114
+ "name": "assignTask",
115
+ "title": "Assign Task",
116
+ "actions": [
117
+ {
118
+ "page": "assignTaskToRCC",
119
+ "type": "next",
120
+ "label": "Continue",
121
+ "validate": true,
122
+ "show_when": {
123
+ "type": "or",
124
+ "conditions": [
125
+ {
126
+ "op": "=",
127
+ "field": "assignWhere",
128
+ "value": "RCC"
129
+ }
130
+ ]
131
+ }
132
+ },
133
+ {
134
+ "page": "reviewDateAndTime",
135
+ "type": "saveAndNavigate",
136
+ "label": "Continue",
137
+ "validate": true,
138
+ "show_when": {
139
+ "type": "or",
140
+ "conditions": [
141
+ {
142
+ "op": "!=",
143
+ "field": "assignWhere",
144
+ "value": "RCC"
145
+ }
146
+ ]
147
+ }
148
+ }
149
+ ],
150
+ "cya_link": {},
151
+ "show_when": [
152
+ {
153
+ "op": "includes",
154
+ "field": "keycloakContext.groups",
155
+ "value": "/BFNCC"
156
+ }
157
+ ],
158
+ "components": [
159
+ {
160
+ "use": "assignWhere"
161
+ }
162
+ ]
163
+ },
164
+ {
165
+ "id": "assignTaskToRCC",
166
+ "name": "assignTaskToRCC",
167
+ "title": "Assign task to RCC",
168
+ "actions": [
169
+ {
170
+ "type": "next",
171
+ "label": "Continue",
172
+ "validate": true
173
+ }
174
+ ],
175
+ "cya_link": {},
176
+ "show_when": {
177
+ "conditions": [
178
+ {
179
+ "op": "=",
180
+ "field": "assignWhere",
181
+ "value": "RCC"
182
+ }
183
+ ]
184
+ },
185
+ "components": [
186
+ {
187
+ "use": "regionalCommandCentre",
188
+ "show_when": {
189
+ "type": "and",
190
+ "conditions": [
191
+ {
192
+ "op": "!=",
193
+ "field": "definitionKey",
194
+ "value": "cop-variance-breach-v2"
195
+ }
196
+ ]
197
+ }
198
+ },
199
+ {
200
+ "use": "regionalCommandCentreDisplay",
201
+ "show_when": {
202
+ "type": "or",
203
+ "conditions": [
204
+ {
205
+ "op": "=",
206
+ "field": "definitionKey",
207
+ "value": "cop-variance-breach-v2"
208
+ }
209
+ ]
210
+ }
211
+ },
212
+ {
213
+ "use": "responseNeeded",
214
+ "show_when": {
215
+ "type": "or",
216
+ "conditions": [
217
+ {
218
+ "op": "includes",
219
+ "field": "keycloakContext.groups",
220
+ "value": "/BFNCC"
221
+ }
222
+ ]
223
+ }
224
+ },
225
+ {
226
+ "use": "assignMessage"
227
+ }
228
+ ],
229
+ "operations": [
230
+ {
231
+ "field": "reviewDateTime",
232
+ "function": "deleteValueInFormData",
233
+ "run_when": {
234
+ "field": "responseNeeded",
235
+ "condition": "changes"
236
+ },
237
+ "component": " "
238
+ }
239
+ ]
240
+ },
241
+ {
242
+ "id": "reviewDateAndTime",
243
+ "name": "reviewDateAndTime",
244
+ "title": "Set a review date and time",
245
+ "actions": [
246
+ {
247
+ "type": "next",
248
+ "label": "Continue",
249
+ "validate": true
250
+ }
251
+ ],
252
+ "cya_link": {},
253
+ "show_when": [
254
+ {
255
+ "type": "or",
256
+ "conditions": [
257
+ {
258
+ "op": "=",
259
+ "field": "responseNeeded",
260
+ "value": "Yes"
261
+ },
262
+ {
263
+ "op": "=",
264
+ "field": "assignWhere",
265
+ "value": "NCC"
266
+ }
267
+ ]
268
+ }
269
+ ],
270
+ "components": [
271
+ {
272
+ "use": "reviewDateTime"
273
+ },
274
+ {
275
+ "use": "responseNeeded",
276
+ "label": "",
277
+ "value": "Yes",
278
+ "hidden": true,
279
+ "required": true,
280
+ "show_on_cya": false,
281
+ "defaultValue": "Yes"
282
+ }
283
+ ]
284
+ }
285
+ ],
286
+ "title": "Assign task to RCC",
287
+ "components": [
288
+ {
289
+ "id": "assignMessage",
290
+ "type": "textarea",
291
+ "label": "Message",
292
+ "fieldId": "assignMessage",
293
+ "cya_link": {},
294
+ "required": true,
295
+ "custom_errors": [
296
+ {
297
+ "type": "required",
298
+ "message": "Enter a message"
299
+ }
300
+ ]
301
+ },
302
+ {
303
+ "id": "assignWhere",
304
+ "data": {
305
+ "options": [
306
+ {
307
+ "hint": "Set a review date and time.",
308
+ "label": "Keep task with NCC",
309
+ "value": "NCC"
310
+ },
311
+ {
312
+ "hint": "Either set a review date and time or set the task to automatically close.",
313
+ "label": "Assign task to RCC",
314
+ "value": "RCC"
315
+ }
316
+ ]
317
+ },
318
+ "type": "radios",
319
+ "label": " ",
320
+ "fieldId": "assignWhere",
321
+ "preserveInPayload": true,
322
+ "required": true,
323
+ "cya_label": "Assign task",
324
+ "custom_errors": [
325
+ {
326
+ "type": "required",
327
+ "message": "Select where you want to assign this task"
328
+ }
329
+ ],
330
+ "showAllValues": "true"
331
+ },
332
+ {
333
+ "id": "regionalCommandCentre",
334
+ "data": {
335
+ "url": "${environmentContext.referenceDataUrl}/v2/entities/branch?mode=dataOnly&filter=directorateid.eq=2&filter=code=in.(BFSEEU,BFHROW,BFSOUTH,BFNORTH,BFCENT)"
336
+ },
337
+ "hint": "Type to search",
338
+ "item": {
339
+ "label": "name",
340
+ "value": "id"
341
+ },
342
+ "type": "autocomplete",
343
+ "label": "Regional Command Centre",
344
+ "fieldId": "regionalCommandCentre",
345
+ "required": true,
346
+ "cya_label": "RCC",
347
+ "custom_errors": [
348
+ {
349
+ "type": "required",
350
+ "message": "Select a Regional Command Centre"
351
+ }
352
+ ],
353
+ "showAllValues": true
354
+ },
355
+ {
356
+ "id": "regionalCommandCentreDisplay",
357
+ "data": {
358
+ "url": "${environmentContext.referenceDataUrl}/v2/entities/branch?mode=dataOnly&filter=directorateid.eq=2&filter=code=in.(BFSEEU,BFHROW,BFSOUTH,BFNORTH,BFCENT)"
359
+ },
360
+ "item": {
361
+ "label": "name",
362
+ "value": "id"
363
+ },
364
+ "type": "autocomplete",
365
+ "label": "Regional Command Centre",
366
+ "fieldId": "regionalCommandCentre",
367
+ "disabled": true,
368
+ "required": true,
369
+ "cya_label": "RCC",
370
+ "showAllValues": true
371
+ },
372
+ {
373
+ "id": "reviewDateTime",
374
+ "type": "container",
375
+ "label": " ",
376
+ "fieldId": "reviewDateTime",
377
+ "required": true,
378
+ "components": [
379
+ {
380
+ "type": "html",
381
+ "content": "The review date and time will display on the open NCC tasks screen."
382
+ },
383
+ {
384
+ "id": "reviewDate",
385
+ "hint": "For example, 20 2 2023.",
386
+ "type": "date",
387
+ "label": "Review date",
388
+ "fieldId": "reviewDate",
389
+ "cya_link": {},
390
+ "required": true,
391
+ "custom_errors": [
392
+ {
393
+ "type": "required",
394
+ "message": "Enter a review date"
395
+ }
396
+ ],
397
+ "additionalValidation": [
398
+ {
399
+ "message": "Review date must be today or in the future",
400
+ "function": "mustBeInTheFuture",
401
+ "todayAllowed": true
402
+ }
403
+ ]
404
+ },
405
+ {
406
+ "id": "reviewTime",
407
+ "hint": "Use 24-hour. For example, 19:45.",
408
+ "type": "time",
409
+ "label": "Review time",
410
+ "fieldId": "reviewTime",
411
+ "cya_link": {},
412
+ "required": true,
413
+ "custom_errors": [
414
+ {
415
+ "type": "required",
416
+ "message": "Enter a review time"
417
+ }
418
+ ]
419
+ }
420
+ ]
421
+ },
422
+ {
423
+ "id": "responseNeeded",
424
+ "data": {
425
+ "options": [
426
+ {
427
+ "hint": "Set a review date for the task.",
428
+ "label": "Yes",
429
+ "value": "Yes"
430
+ },
431
+ {
432
+ "hint": "The task will automatically close at 23:59 on ${autoClose} - the day after the event date.",
433
+ "label": "No",
434
+ "value": "No"
435
+ }
436
+ ]
437
+ },
438
+ "type": "radios",
439
+ "label": "Do you need a response?",
440
+ "fieldId": "responseNeeded",
441
+ "required": true,
442
+ "showAllValues": "true"
443
+ }
444
+ ],
445
+ "version": "7b941ec0bb281e2b93ba32058b81e1a88f0f0a9a"
446
+ }