@ukhomeoffice/cop-react-form-renderer 6.15.7-alpha → 6.15.7

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 (43) hide show
  1. package/dist/components/CollectionSummary/BannerStrip.scss +4 -0
  2. package/dist/components/FormComponent/FormComponent.js +6 -0
  3. package/dist/components/FormComponent/helpers/addLabel.js +3 -2
  4. package/dist/components/FormPage/FormPage.js +28 -17
  5. package/dist/components/FormPage/FormPage.test.js +53 -0
  6. package/dist/components/FormRenderer/FormRenderer.js +5 -10
  7. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/cop-reassign-task-to-rcc.json +445 -0
  8. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-component-show-when-in-component-and-page.json +62 -0
  9. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-page-same-component-reused.json +61 -0
  10. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-page-same-component-reused-one-shown.json +74 -0
  11. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/cop-airpax-carrier.json +407 -0
  12. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/cop-airpax-change-what-happened-before.json +300 -0
  13. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/data-hidden-component-show-when-in-component-and-page.json +6 -0
  14. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/data-hidden-page-same-component-reused.json +6 -0
  15. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/data-page-same-component-reused-one-shown.json +8 -0
  16. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/reassign-to-rcc.json +72 -0
  17. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/output/cop-airpax-change-what-happened-after.json +280 -0
  18. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/output/data-hidden-component-show-when-in-component-and-page-removed.json +5 -0
  19. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/output/data-hidden-page-same-component-reused-removed.json +5 -0
  20. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/output/data-page-same-component-reused-one-shown-removed.json +7 -0
  21. package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutes.js +259 -289
  22. package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutes.test.js +89 -27
  23. package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutesUtils.js +389 -0
  24. package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutesUtils.test.js +559 -0
  25. package/dist/components/FormRenderer/onCYAAction.js +0 -2
  26. package/dist/components/FormRenderer/onCYAAction.test.js +5 -0
  27. package/dist/components/FormRenderer/onPageAction.js +0 -1
  28. package/dist/hooks/useGetRequest.js +15 -15
  29. package/dist/hooks/useRefData.js +3 -2
  30. package/dist/utils/Component/getComponentTests/getComponent.multifile.test.js +2 -1
  31. package/dist/utils/Component/getDefaultValueFromConfig.js +2 -1
  32. package/dist/utils/Condition/meetsCondition.js +26 -12
  33. package/dist/utils/Condition/meetsCondition.test.js +21 -0
  34. package/dist/utils/Data/getAutocompleteSource.js +68 -51
  35. package/dist/utils/Data/getAutocompleteSource.test.js +31 -18
  36. package/dist/utils/Operate/doesContainValue.js +34 -0
  37. package/dist/utils/Operate/doesContainValue.test.js +75 -0
  38. package/dist/utils/Operate/runPageOperations.js +2 -0
  39. package/dist/utils/Validate/validateOnPageLoad.js +23 -0
  40. package/dist/utils/Validate/validateOnPageLoad.test.js +88 -0
  41. package/package.json +4 -4
  42. package/dist/components/FormRenderer/helpers/deleteNodeByPath.js +0 -29
  43. package/dist/components/FormRenderer/helpers/deleteNodeByPath.test.js +0 -56
@@ -39,6 +39,10 @@
39
39
  }
40
40
  }
41
41
 
42
+ .hods-form-banner-strip__tag--fit-content{
43
+ max-width: fit-content;
44
+ }
45
+
42
46
  @mixin banner-tag-colours($colour) {
43
47
  .hods-form-banner-strip__tag--#{$colour} {
44
48
  @extend .govuk-tag--#{$colour};
@@ -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
  };
@@ -12,19 +12,22 @@ var _utils = _interopRequireDefault(require("../../utils"));
12
12
  var _FormComponent = _interopRequireDefault(require("../FormComponent"));
13
13
  var _PageActions = _interopRequireDefault(require("../PageActions"));
14
14
  require("./FormPage.scss");
15
+ var _validateOnPageLoad = require("../../utils/Validate/validateOnPageLoad");
15
16
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
17
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
17
18
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
18
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; }
19
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; }
20
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; }
21
24
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
22
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
23
26
  // Local imports.
24
27
  // Styles
25
28
  const DEFAULT_CLASS = exports.DEFAULT_CLASS = 'hods-form__page';
26
29
  const FormPage = _ref => {
27
- var _page$customValidatio, _formPage$actions, _page$actions;
30
+ var _formPage$actions, _page$actions;
28
31
  let {
29
32
  page,
30
33
  pages,
@@ -37,8 +40,7 @@ const FormPage = _ref => {
37
40
  classModifiers,
38
41
  className,
39
42
  submitting,
40
- pageId,
41
- fromTarget
43
+ pageId
42
44
  } = _ref;
43
45
  const [patch, setPatch] = (0, _react.useState)({});
44
46
  const {
@@ -47,12 +49,12 @@ const FormPage = _ref => {
47
49
  } = (0, _hooks.useValidation)();
48
50
  const [patchLabel, setPatchLabel] = (0, _react.useState)({});
49
51
  const [isPageRendered, setIsPageRendered] = (0, _react.useState)(false);
50
- const runOnLoad = Array.isArray(page === null || page === void 0 ? void 0 : page.customValidation) && page.customValidation.length > 0 ? ((_page$customValidatio = page.customValidation[0]) === null || _page$customValidatio === void 0 || (_page$customValidatio = _page$customValidatio.runWhen) === null || _page$customValidatio === void 0 ? void 0 : _page$customValidatio.onLoad) === true : false;
52
+ const runOnLoad = (0, _react.useMemo)(() => (0, _validateOnPageLoad.doValidateOnPageLoad)(page), [page]);
51
53
  (0, _react.useEffect)(() => {
52
54
  setIsPageRendered(true);
53
55
  }, []);
54
56
  (0, _react.useEffect)(() => {
55
- if (isPageRendered && fromTarget && runOnLoad) {
57
+ if (isPageRendered && runOnLoad) {
56
58
  validate.page(page);
57
59
  }
58
60
  }, [pageId, isPageRendered]);
@@ -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
@@ -120,9 +133,9 @@ const FormPage = _ref => {
120
133
  }));
121
134
  let errorMessages = null;
122
135
  if (runOnLoad && (errors === null || errors === void 0 ? void 0 : errors.length) > 0) {
123
- var _page$customValidatio2;
136
+ var _page$customValidatio;
124
137
  errorMessages = [{
125
- error: page === null || page === void 0 || (_page$customValidatio2 = page.customValidation) === null || _page$customValidatio2 === void 0 || (_page$customValidatio2 = _page$customValidatio2[0]) === null || _page$customValidatio2 === void 0 ? void 0 : _page$customValidatio2.message
138
+ error: page === null || page === void 0 || (_page$customValidatio = page.customValidation) === null || _page$customValidatio === void 0 || (_page$customValidatio = _page$customValidatio[0]) === null || _page$customValidatio === void 0 ? void 0 : _page$customValidatio.message
126
139
  }];
127
140
  } else if ((errors === null || errors === void 0 ? void 0 : errors.length) > 0 && !runOnLoad) {
128
141
  errorMessages = errors;
@@ -174,7 +187,6 @@ FormPage.propTypes = {
174
187
  }).isRequired,
175
188
  pages: _propTypes.default.arrayOf(_propTypes.default.shape({})),
176
189
  submitting: _propTypes.default.bool,
177
- fromTarget: _propTypes.default.bool,
178
190
  pageId: _propTypes.default.string.isRequired
179
191
  };
180
192
  FormPage.defaultProps = {
@@ -186,7 +198,6 @@ FormPage.defaultProps = {
186
198
  onTopLevelChange: undefined,
187
199
  onWrapperChange: undefined,
188
200
  pages: [],
189
- submitting: false,
190
- fromTarget: false
201
+ submitting: false
191
202
  };
192
203
  var _default = exports.default = FormPage;
@@ -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
  });
@@ -54,8 +54,7 @@ const FormRenderer = _ref => {
54
54
  noChangeAction,
55
55
  newPageId,
56
56
  viewOnly,
57
- hideBlankRows,
58
- fromTarget
57
+ hideBlankRows
59
58
  } = _ref;
60
59
  return /*#__PURE__*/_react.default.createElement(_context.HooksContextProvider, {
61
60
  overrides: hooks
@@ -76,8 +75,7 @@ const FormRenderer = _ref => {
76
75
  noChangeAction: noChangeAction,
77
76
  newPageId: newPageId,
78
77
  viewOnly: viewOnly,
79
- hideBlankRows: hideBlankRows,
80
- fromTarget: fromTarget
78
+ hideBlankRows: hideBlankRows
81
79
  })));
82
80
  };
83
81
  const DEFAULT_CLASS = exports.DEFAULT_CLASS = 'hods-form';
@@ -100,8 +98,7 @@ const InternalFormRenderer = _ref2 => {
100
98
  noChangeAction,
101
99
  newPageId,
102
100
  viewOnly,
103
- hideBlankRows,
104
- fromTarget
101
+ hideBlankRows
105
102
  } = _ref2;
106
103
  // Set up the initial states.
107
104
  const [data, setData] = (0, _react.useState)({});
@@ -326,8 +323,7 @@ const InternalFormRenderer = _ref2 => {
326
323
  classModifiers: formState.page.classModifiers,
327
324
  className: formState.page.className,
328
325
  submitting: submitting,
329
- pageId: pageId,
330
- fromTarget: fromTarget
326
+ pageId: pageId
331
327
  }), formState.page && !formState.cya && formState.page.collection && /*#__PURE__*/_react.default.createElement(_CollectionPage.default, {
332
328
  page: formState.page,
333
329
  pages: pages,
@@ -370,8 +366,7 @@ const propTypes = {
370
366
  /** See <a href="/?path=/docs/f-json--page#formtypes">FormTypes</a>. */
371
367
  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,
372
368
  viewOnly: _propTypes.default.bool,
373
- hideBlankRows: _propTypes.default.bool,
374
- fromTarget: _propTypes.default.bool.isRequired
369
+ hideBlankRows: _propTypes.default.bool
375
370
  };
376
371
  const defaultProps = {
377
372
  classBlock: DEFAULT_CLASS,