@ukhomeoffice/cop-react-form-renderer 4.68.1 → 4.69.2

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.
@@ -20,6 +20,7 @@ var _handlers = _interopRequireDefault(require("./handlers"));
20
20
  var _helpers = _interopRequireDefault(require("./helpers"));
21
21
  var _onCYAAction = _interopRequireDefault(require("./onCYAAction"));
22
22
  var _onPageAction = _interopRequireDefault(require("./onPageAction"));
23
+ var _onTaskAction2 = _interopRequireDefault(require("./onTaskAction"));
23
24
  require("./FormRenderer.scss");
24
25
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
26
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -292,7 +293,7 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
292
293
  hubDetails.sections.every(function (section) {
293
294
  return section.tasks.every(function (task) {
294
295
  if (task.pages.includes(page.pageId) && task.name !== currentTask.name) {
295
- onTaskAction(task);
296
+ (0, _onTaskAction2.default)(task, pages, setCurrentTask, hubDetails, data, onPageChange, _models.FormPages);
296
297
  return false;
297
298
  }
298
299
  return true;
@@ -303,37 +304,6 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
303
304
  _handlers.default.cyaAction(page, pageId, onPageChange);
304
305
  }
305
306
  };
306
-
307
- //Kick off a task, gather required pages and move to the correct point
308
- var onTaskAction = function onTaskAction(currentTask) {
309
- if (currentTask) {
310
- currentTask.fullPages = [];
311
- currentTask.pages.forEach(function (page) {
312
- currentTask.fullPages.push(_helpers.default.getPage(page, pages));
313
- });
314
- setCurrentTask(currentTask);
315
- var state = _objectSpread({}, currentTask);
316
- if (currentTask.state === _models.TaskStates.TYPES.COMPLETE) {
317
- if (hubDetails !== null && hubDetails !== void 0 && hubDetails.noTaskCYAs) {
318
- // If the task is complete and there are no CYA's then show user first page
319
- var currentPage = data.formStatus.tasks[currentTask.name].currentPage;
320
- onPageChange(currentTask.pages[0] || currentPage);
321
- } else if (currentTask.customCYA) {
322
- onPageChange(currentTask.customCYA);
323
- } else {
324
- onPageChange(_models.FormPages.CYA, state);
325
- }
326
- } else if (currentTask.state === _models.TaskStates.TYPES.IN_PROGRESS) {
327
- var _currentPage = data.formStatus.tasks[currentTask.name].currentPage;
328
- onPageChange(_currentPage || currentTask.pages[0], state);
329
- } else if (currentTask.firstPage) {
330
- var _currentPage2 = currentTask.firstPage;
331
- onPageChange(_currentPage2 || currentTask.pages[0], state);
332
- } else {
333
- onPageChange(currentTask.pages[0], state);
334
- }
335
- }
336
- };
337
307
  var classes = _utils.default.classBuilder(classBlock, classModifiers, className);
338
308
  if (hub === _models.HubFormats.TASK) {
339
309
  cya.actions = [_models.PageAction.TYPES.SAVE_AND_CONTINUE, _models.PageAction.TYPES.SAVE_AND_RETURN];
@@ -359,7 +329,9 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
359
329
  type: type
360
330
  })), hub === _models.HubFormats.TASK && formState.pageId === _models.FormPages.HUB && /*#__PURE__*/_react.default.createElement(_TaskList.default, _extends({}, hubDetails, {
361
331
  refNumber: data.businessKey,
362
- onTaskAction: onTaskAction,
332
+ onTaskAction: function onTaskAction(task) {
333
+ (0, _onTaskAction2.default)(task, pages, setCurrentTask, hubDetails, data, onPageChange, _models.FormPages);
334
+ },
363
335
  formData: data
364
336
  })), formState.page && !formState.cya && !formState.page.collection && /*#__PURE__*/_react.default.createElement(_FormPage.default, {
365
337
  page: formState.page,
@@ -4,13 +4,15 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ var _optionIsSelected = _interopRequireDefault(require("../../../utils/Component/optionIsSelected"));
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
7
9
  function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
8
10
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
9
11
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
10
12
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
13
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
12
14
  function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
13
- var parentComponents = ['radios'];
15
+ var parentComponents = ['radios', 'checkboxes'];
14
16
  var cleanHiddenNestedData = function cleanHiddenNestedData(patch, page) {
15
17
  page.components.forEach(function (component) {
16
18
  if (!parentComponents.includes(component.type)) {
@@ -22,10 +24,12 @@ var cleanHiddenNestedData = function cleanHiddenNestedData(patch, page) {
22
24
  });
23
25
  });
24
26
  if (page.collection && patch[page.collection.name]) {
27
+ var _page$formData;
28
+ var activeId = patch["".concat(page.collection.name, "ActiveId")] || ((_page$formData = page.formData) === null || _page$formData === void 0 ? void 0 : _page$formData["".concat(page.collection.name, "ActiveId")]);
25
29
  patch[page.collection.name] = patch[page.collection.name].map(function (entry) {
26
- return cleanHiddenNestedData(entry, _objectSpread(_objectSpread({}, page), {}, {
30
+ return entry.id === activeId ? cleanHiddenNestedData(entry, _objectSpread(_objectSpread({}, page), {}, {
27
31
  collection: undefined
28
- }));
32
+ })) : entry;
29
33
  });
30
34
  }
31
35
  return patch;
@@ -34,7 +38,7 @@ function getIdsToDelete(component, selectedValue) {
34
38
  var _component$data, _component$data$optio;
35
39
  var idsToDelete = [];
36
40
  component === null || component === void 0 ? void 0 : (_component$data = component.data) === null || _component$data === void 0 ? void 0 : (_component$data$optio = _component$data.options) === null || _component$data$optio === void 0 ? void 0 : _component$data$optio.forEach(function (option) {
37
- if (option.value !== selectedValue && option.nested) {
41
+ if (!(0, _optionIsSelected.default)(selectedValue, option) && option.nested) {
38
42
  option.nested.forEach(function (nested) {
39
43
  idsToDelete.push(nested.id);
40
44
  });
@@ -8,13 +8,13 @@ describe('components', function () {
8
8
  describe('FormRenderer', function () {
9
9
  describe('helpers', function () {
10
10
  describe('cleanHiddenNestedData', function () {
11
- it('remove data corresponding to hidden nested components', function () {
12
- var patch = {
11
+ it('should remove data corresponding to hidden nested components in radios', function () {
12
+ var patchRadios = {
13
13
  parent: 'option2',
14
14
  nested1: 'should not be included',
15
15
  nested2: 'should be included'
16
16
  };
17
- var page = {
17
+ var pageRadios = {
18
18
  id: 'page',
19
19
  name: 'page',
20
20
  title: 'Page',
@@ -39,17 +39,55 @@ describe('components', function () {
39
39
  }
40
40
  }]
41
41
  };
42
- var updatedPatch = (0, _cleanHiddenNestedData.default)(patch, page);
43
- expect(updatedPatch['nested1']).toBeFalsy();
44
- expect(updatedPatch['nested2']).toBeTruthy();
42
+ var updatedPatchRadios = (0, _cleanHiddenNestedData.default)(patchRadios, pageRadios);
43
+ expect(updatedPatchRadios['nested1']).toBeFalsy();
44
+ expect(updatedPatchRadios['nested2']).toBeTruthy();
45
45
  });
46
- it('remove data corresponding to hidden nested components within a collection', function () {
46
+ it('should remove data corresponding to hidden nested components in checkboxes', function () {
47
+ var patchCheckboxes = {
48
+ parent: ['option2'],
49
+ nested1: 'should not be included',
50
+ nested2: 'should be included'
51
+ };
52
+ var pageCheckboxes = {
53
+ id: 'page',
54
+ name: 'page',
55
+ title: 'Page',
56
+ components: [{
57
+ id: 'parent',
58
+ fieldId: 'parent',
59
+ type: 'checkboxes',
60
+ data: {
61
+ options: [{
62
+ value: 'option1',
63
+ nested: [{
64
+ id: 'nested1',
65
+ fieldId: 'nested1'
66
+ }]
67
+ }, {
68
+ value: 'option2',
69
+ nested: [{
70
+ id: 'nested2',
71
+ fieldId: 'nested2'
72
+ }]
73
+ }]
74
+ }
75
+ }]
76
+ };
77
+ var updatedPatchCheckboxes = (0, _cleanHiddenNestedData.default)(patchCheckboxes, pageCheckboxes);
78
+ expect(updatedPatchCheckboxes['nested1']).toBeFalsy();
79
+ expect(updatedPatchCheckboxes['nested2']).toBeTruthy();
80
+ });
81
+ it('remove data corresponding to hidden nested components within the active collection entry', function () {
47
82
  var patch = {
83
+ collectionNameActiveId: '456',
48
84
  collectionName: [{
85
+ id: '123',
49
86
  parent: 'option1',
50
87
  nested1: 'should be included',
51
- nested2: 'should not be included'
88
+ nested2: 'should be included'
52
89
  }, {
90
+ id: '456',
53
91
  parent: 'option2',
54
92
  nested1: 'should not be included',
55
93
  nested2: 'should be included'
@@ -84,7 +122,7 @@ describe('components', function () {
84
122
  };
85
123
  var updatedPatch = (0, _cleanHiddenNestedData.default)(patch, page);
86
124
  expect(updatedPatch['collectionName'][0]['nested1']).toBeTruthy();
87
- expect(updatedPatch['collectionName'][0]['nested2']).toBeFalsy();
125
+ expect(updatedPatch['collectionName'][0]['nested2']).toBeTruthy();
88
126
  expect(updatedPatch['collectionName'][1]['nested1']).toBeFalsy();
89
127
  expect(updatedPatch['collectionName'][1]['nested2']).toBeTruthy();
90
128
  });
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _models = require("../../models");
8
+ var _helpers = _interopRequireDefault(require("./helpers"));
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
11
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
12
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
13
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
14
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
15
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
16
+ var onTaskAction = function onTaskAction(currentTask, pages, setCurrentTask, hubDetails, data, onPageChange, FormPages) {
17
+ if (currentTask) {
18
+ currentTask.fullPages = [];
19
+ currentTask.pages.forEach(function (page) {
20
+ currentTask.fullPages.push(_helpers.default.getPage(page, pages));
21
+ });
22
+ setCurrentTask(currentTask);
23
+ var state = _objectSpread({}, currentTask);
24
+ if (currentTask.state === _models.TaskStates.TYPES.COMPLETE) {
25
+ if (hubDetails !== null && hubDetails !== void 0 && hubDetails.noTaskCYAs) {
26
+ // If the task is complete and there are no CYA's then show user first page
27
+ var currentPage = data.formStatus.tasks[currentTask.name].currentPage;
28
+ onPageChange(currentTask.pages[0] || currentPage);
29
+ } else if (currentTask.customCYA) {
30
+ onPageChange(currentTask.customCYA);
31
+ } else {
32
+ onPageChange(FormPages.CYA, state);
33
+ }
34
+ } else if (currentTask.state === _models.TaskStates.TYPES.IN_PROGRESS) {
35
+ var _currentPage = data.formStatus.tasks[currentTask.name].currentPage;
36
+ onPageChange(_currentPage || currentTask.pages[0], state);
37
+ } else if (currentTask.firstPage) {
38
+ onPageChange(currentTask.firstPage, state);
39
+ } else {
40
+ onPageChange(currentTask.pages[0], state);
41
+ }
42
+ }
43
+ };
44
+ var _default = onTaskAction;
45
+ exports.default = _default;
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+
3
+ var _models = require("../../models");
4
+ var _helpers = _interopRequireDefault(require("./helpers"));
5
+ var _onTaskAction = _interopRequireDefault(require("./onTaskAction"));
6
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
7
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
8
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
9
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
10
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
12
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
13
+ jest.mock('./helpers', function () {
14
+ return {
15
+ getPageArgs: [],
16
+ getPage: function getPage(page, pages) {
17
+ this.getPageArgs.push({
18
+ page: page,
19
+ pages: pages
20
+ });
21
+ },
22
+ reset: function reset() {
23
+ this.getPageArgs = [];
24
+ }
25
+ };
26
+ });
27
+ describe('components.FormRenderer.onTaskAction', function () {
28
+ var setCurrentTaskArgs = [];
29
+ var mockSetCurrentTask = function mockSetCurrentTask(task) {
30
+ setCurrentTaskArgs.push(task);
31
+ };
32
+ var onPageChangeArgs = [];
33
+ var mockOnPageChange = function mockOnPageChange(page, state) {
34
+ onPageChangeArgs.push({
35
+ page: page,
36
+ state: state
37
+ });
38
+ };
39
+ var PAGES = [{
40
+ id: 'page1'
41
+ }, {
42
+ id: 'page2'
43
+ }, {
44
+ id: 'page3'
45
+ }, {
46
+ id: 'customCya'
47
+ }];
48
+ var DATA = {
49
+ formStatus: {
50
+ tasks: {
51
+ task1: {
52
+ currentPage: 'page1'
53
+ },
54
+ task2: {
55
+ currentPage: 'page2'
56
+ },
57
+ taskNoCurrentPage: {}
58
+ }
59
+ }
60
+ };
61
+ var ARGS = {
62
+ currentTask: null,
63
+ pages: PAGES,
64
+ setCurrentTask: mockSetCurrentTask,
65
+ hubDetails: {},
66
+ data: DATA,
67
+ onPageChange: mockOnPageChange,
68
+ FormPages: {
69
+ CYA: 'cyaPage'
70
+ }
71
+ };
72
+ var genericChecks = function genericChecks(currentTask) {
73
+ expect(_helpers.default.getPageArgs.length).toEqual(currentTask.pages.length);
74
+ expect(currentTask.fullPages.length).toEqual(currentTask.pages.length);
75
+ expect(setCurrentTaskArgs.length).toEqual(1);
76
+ expect(setCurrentTaskArgs[0]).toEqual(currentTask);
77
+ };
78
+ beforeEach(function () {
79
+ setCurrentTaskArgs = [];
80
+ onPageChangeArgs = [];
81
+ _helpers.default.reset();
82
+ });
83
+ it('should do nothing if currentTask is null', function () {
84
+ _onTaskAction.default.apply(void 0, Object.values(ARGS));
85
+ expect(_helpers.default.getPageArgs.length).toEqual(0);
86
+ expect(setCurrentTaskArgs.length).toEqual(0);
87
+ expect(onPageChangeArgs.length).toEqual(0);
88
+ });
89
+ describe("when currentTask has a state of ".concat(_models.TaskStates.TYPES.COMPLETE), function () {
90
+ var TASK = {
91
+ name: 'task1',
92
+ state: _models.TaskStates.TYPES.COMPLETE,
93
+ pages: ['page1', 'page2', 'page3']
94
+ };
95
+ it('should handle task CYAs not being shown', function () {
96
+ var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
97
+ currentTask: TASK,
98
+ hubDetails: {
99
+ noTaskCYAs: true
100
+ }
101
+ });
102
+ _onTaskAction.default.apply(void 0, Object.values(CUSTOM_ARGS));
103
+ genericChecks(CUSTOM_ARGS.currentTask);
104
+ expect(onPageChangeArgs.length).toEqual(1);
105
+ expect(onPageChangeArgs[0].page).toEqual(CUSTOM_ARGS.currentTask.pages[0]);
106
+ });
107
+ it('should handle task CYAs not being shown and no pages being provided on currentTask', function () {
108
+ var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
109
+ currentTask: _objectSpread(_objectSpread({}, TASK), {}, {
110
+ pages: []
111
+ }),
112
+ hubDetails: {
113
+ noTaskCYAs: true
114
+ }
115
+ });
116
+ _onTaskAction.default.apply(void 0, Object.values(CUSTOM_ARGS));
117
+ genericChecks(CUSTOM_ARGS.currentTask);
118
+ expect(onPageChangeArgs.length).toEqual(1);
119
+ expect(onPageChangeArgs[0].page).toEqual(CUSTOM_ARGS.data.formStatus.tasks[CUSTOM_ARGS.currentTask.name].currentPage);
120
+ });
121
+ it('should handle a custom CYA being provided', function () {
122
+ var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
123
+ currentTask: _objectSpread(_objectSpread({}, TASK), {}, {
124
+ customCYA: 'customCya'
125
+ })
126
+ });
127
+ _onTaskAction.default.apply(void 0, Object.values(CUSTOM_ARGS));
128
+ genericChecks(CUSTOM_ARGS.currentTask);
129
+ expect(onPageChangeArgs.length).toEqual(1);
130
+ expect(onPageChangeArgs[0].page).toEqual(CUSTOM_ARGS.currentTask.customCYA);
131
+ });
132
+ it('should handle navigation to a normal CYA page', function () {
133
+ var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
134
+ currentTask: TASK
135
+ });
136
+ _onTaskAction.default.apply(void 0, Object.values(CUSTOM_ARGS));
137
+ genericChecks(CUSTOM_ARGS.currentTask);
138
+ expect(onPageChangeArgs.length).toEqual(1);
139
+ expect(onPageChangeArgs[0].page).toEqual(CUSTOM_ARGS.FormPages.CYA);
140
+ expect(onPageChangeArgs[0].state).toEqual(CUSTOM_ARGS.currentTask);
141
+ });
142
+ });
143
+ describe("when currentTask has a state of ".concat(_models.TaskStates.TYPES.IN_PROGRESS), function () {
144
+ it('should handle page change when formStatus has a current page for the task', function () {
145
+ var TASK = {
146
+ name: 'task1',
147
+ state: _models.TaskStates.TYPES.IN_PROGRESS,
148
+ pages: ['page1', 'page2', 'page3']
149
+ };
150
+ var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
151
+ currentTask: TASK
152
+ });
153
+ _onTaskAction.default.apply(void 0, Object.values(CUSTOM_ARGS));
154
+ genericChecks(CUSTOM_ARGS.currentTask);
155
+ expect(onPageChangeArgs.length).toEqual(1);
156
+ expect(onPageChangeArgs[0].page).toEqual(CUSTOM_ARGS.data.formStatus.tasks[CUSTOM_ARGS.currentTask.name].currentPage);
157
+ expect(onPageChangeArgs[0].state).toEqual(CUSTOM_ARGS.currentTask);
158
+ });
159
+ it('should handle page change when formStatus does not have a current page for the task', function () {
160
+ var TASK = {
161
+ name: 'taskNoCurrentPage',
162
+ state: _models.TaskStates.TYPES.IN_PROGRESS,
163
+ pages: ['page1', 'page2', 'page3']
164
+ };
165
+ var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
166
+ currentTask: TASK
167
+ });
168
+ _onTaskAction.default.apply(void 0, Object.values(CUSTOM_ARGS));
169
+ genericChecks(CUSTOM_ARGS.currentTask);
170
+ expect(onPageChangeArgs.length).toEqual(1);
171
+ expect(onPageChangeArgs[0].page).toEqual(CUSTOM_ARGS.currentTask.pages[0]);
172
+ expect(onPageChangeArgs[0].state).toEqual(CUSTOM_ARGS.currentTask);
173
+ });
174
+ });
175
+ var otherStates = Object.values(_models.TaskStates.TYPES).filter(function (t) {
176
+ return t !== _models.TaskStates.TYPES.IN_PROGRESS && t !== _models.TaskStates.TYPES.COMPLETE;
177
+ });
178
+ otherStates.forEach(function (state) {
179
+ describe("when currentTask has a state of ".concat(state), function () {
180
+ var TASK = {
181
+ name: 'task1',
182
+ state: state,
183
+ pages: ['page1', 'page2', 'page3']
184
+ };
185
+ it('should handle the task having a specific first page defined', function () {
186
+ var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
187
+ currentTask: _objectSpread(_objectSpread({}, TASK), {}, {
188
+ firstPage: 'page2'
189
+ })
190
+ });
191
+ _onTaskAction.default.apply(void 0, Object.values(CUSTOM_ARGS));
192
+ genericChecks(CUSTOM_ARGS.currentTask);
193
+ expect(onPageChangeArgs.length).toEqual(1);
194
+ expect(onPageChangeArgs[0].page).toEqual(CUSTOM_ARGS.currentTask.firstPage);
195
+ expect(onPageChangeArgs[0].state).toEqual(CUSTOM_ARGS.currentTask);
196
+ });
197
+ it('should handle the task having the first page defined as null', function () {
198
+ var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
199
+ currentTask: _objectSpread(_objectSpread({}, TASK), {}, {
200
+ firstPage: null
201
+ })
202
+ });
203
+ _onTaskAction.default.apply(void 0, Object.values(CUSTOM_ARGS));
204
+ genericChecks(CUSTOM_ARGS.currentTask);
205
+ expect(onPageChangeArgs.length).toEqual(1);
206
+ expect(onPageChangeArgs[0].page).toEqual(CUSTOM_ARGS.currentTask.pages[0]);
207
+ expect(onPageChangeArgs[0].state).toEqual(CUSTOM_ARGS.currentTask);
208
+ });
209
+ it('should handle the task not having a specific first page defined', function () {
210
+ var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
211
+ currentTask: TASK
212
+ });
213
+ _onTaskAction.default.apply(void 0, Object.values(CUSTOM_ARGS));
214
+ genericChecks(CUSTOM_ARGS.currentTask);
215
+ expect(onPageChangeArgs.length).toEqual(1);
216
+ expect(onPageChangeArgs[0].page).toEqual(CUSTOM_ARGS.currentTask.pages[0]);
217
+ });
218
+ });
219
+ });
220
+ });
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _copReactComponents = require("@ukhomeoffice/cop-react-components");
8
8
  var _Component = _interopRequireDefault(require("../Component"));
9
+ var _optionIsSelected = _interopRequireDefault(require("../Component/optionIsSelected"));
9
10
  var _getCYAAction = _interopRequireDefault(require("./getCYAAction"));
10
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
12
  // Global imports
@@ -43,7 +44,7 @@ var setNestedValue = function setNestedValue(component, page) {
43
44
  var _component$data, _component$data$optio;
44
45
  (_component$data = component.data) === null || _component$data === void 0 ? void 0 : (_component$data$optio = _component$data.options) === null || _component$data$optio === void 0 ? void 0 : _component$data$optio.forEach(function (option) {
45
46
  //check if option is selected and has nested component
46
- if (Array.isArray(option.nested) && page.formData[component.id] === option.value) {
47
+ if (Array.isArray(option.nested) && (0, _optionIsSelected.default)(page.formData[component.id], option)) {
47
48
  option.nested.forEach(function (child) {
48
49
  child.value = page.formData[child.id];
49
50
  });
@@ -134,7 +134,7 @@ describe('utils', function () {
134
134
  onAction: ON_ACTION
135
135
  });
136
136
  });
137
- it('should update any nested components with corresponding values from the stored formdata', function () {
137
+ it('should update any nested components in radios with corresponding values from the stored formdata', function () {
138
138
  var SELECTED_VALUE = 'selectedValue';
139
139
  var NESTED_ID = 'nestedId';
140
140
  var NESTED_VALUE = 'nestedValue';
@@ -161,7 +161,7 @@ describe('utils', function () {
161
161
  var ROW = (0, _getCYARow.default)(PAGE, COMPONENT, function () {});
162
162
  expect(ROW.component.data.options[0].nested[0].value).toEqual(NESTED_VALUE);
163
163
  });
164
- it('should handle an undefined formData when attempting to set nested values', function () {
164
+ it('should handle an undefined formData when attempting to set nested values in radios', function () {
165
165
  var SELECTED_VALUE = 'selectedValue';
166
166
  var NESTED_ID = 'nestedId';
167
167
  var PAGE = {
@@ -184,6 +184,56 @@ describe('utils', function () {
184
184
  var ROW = (0, _getCYARow.default)(PAGE, COMPONENT, function () {});
185
185
  expect(ROW.component.data.options[0].nested[0].value).toBeUndefined();
186
186
  });
187
+ it('should update any nested components in checkboxes with corresponding values from the stored formdata', function () {
188
+ var SELECTED_VALUE = 'selectedValue';
189
+ var NESTED_ID = 'nestedId';
190
+ var NESTED_VALUE = 'nestedValue';
191
+ var PAGE = {
192
+ id: 'page',
193
+ formData: _defineProperty({
194
+ a: [SELECTED_VALUE]
195
+ }, NESTED_ID, NESTED_VALUE),
196
+ cya_link: {}
197
+ };
198
+ var COMPONENT = {
199
+ type: 'checkboxes',
200
+ id: 'a',
201
+ fieldId: 'a',
202
+ data: {
203
+ options: [{
204
+ value: SELECTED_VALUE,
205
+ nested: [{
206
+ id: NESTED_ID
207
+ }]
208
+ }]
209
+ }
210
+ };
211
+ var ROW = (0, _getCYARow.default)(PAGE, COMPONENT, function () {});
212
+ expect(ROW.component.data.options[0].nested[0].value).toEqual(NESTED_VALUE);
213
+ });
214
+ it('should handle an undefined formData when attempting to set nested values in checkboxes', function () {
215
+ var SELECTED_VALUE = 'selectedValue';
216
+ var NESTED_ID = 'nestedId';
217
+ var PAGE = {
218
+ id: 'page',
219
+ cya_link: {}
220
+ };
221
+ var COMPONENT = {
222
+ type: 'checkboxes',
223
+ id: 'a',
224
+ fieldId: 'a',
225
+ data: {
226
+ options: [{
227
+ value: SELECTED_VALUE,
228
+ nested: [{
229
+ id: NESTED_ID
230
+ }]
231
+ }]
232
+ }
233
+ };
234
+ var ROW = (0, _getCYARow.default)(PAGE, COMPONENT, function () {});
235
+ expect(ROW.component.data.options[0].nested[0].value).toBeUndefined();
236
+ });
187
237
  it('should get an appropriate row for a readonly text component with no value and interpolated label', function () {
188
238
  var PAGE = {
189
239
  id: 'page',
@@ -51,6 +51,12 @@ var getCheckboxes = function getCheckboxes(config) {
51
51
  _Data.default.getOptions(config, function (val) {
52
52
  options = val;
53
53
  });
54
+ options.forEach(function (option) {
55
+ if (!Array.isArray(option.nested)) {
56
+ return;
57
+ }
58
+ option.children = getChildrenJsx(config, option.nested);
59
+ });
54
60
  var attrs = (0, _cleanAttributes.default)(config);
55
61
  return /*#__PURE__*/_react.default.createElement(_copReactComponents.Checkboxes, _extends({}, attrs, {
56
62
  options: options
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ /**
8
+ * Checks whether an option for a component has been selected.
9
+ *
10
+ * @param {object} componentValue The option's value selected for that component.
11
+ * @param {object} option The option of the component being tested.
12
+ *
13
+ * @returns A boolean of whether the option is selected.
14
+ */
15
+ var optionIsSelected = function optionIsSelected(componentValue, option) {
16
+ if (Array.isArray(componentValue)) {
17
+ return componentValue.includes(option.value);
18
+ }
19
+ return componentValue === option.value;
20
+ };
21
+ var _default = optionIsSelected;
22
+ exports.default = _default;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ var _optionIsSelected = _interopRequireDefault(require("./optionIsSelected"));
4
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
5
+ // Local imports
6
+
7
+ describe('utils.Component.isSelected', function () {
8
+ var SELECTED_VALUE = 'selectedValue';
9
+ var NOT_SELECTED_VALUE = 'notSelectedValue';
10
+ var OPTIONS = [{
11
+ value: SELECTED_VALUE
12
+ }, {
13
+ value: NOT_SELECTED_VALUE
14
+ }];
15
+ var COMPONENT = {
16
+ id: 'a',
17
+ fieldId: 'a',
18
+ data: {
19
+ options: OPTIONS
20
+ }
21
+ };
22
+ it('should properly identify which option is selected for checkboxes', function () {
23
+ var PAGE = {
24
+ formData: {
25
+ a: [SELECTED_VALUE]
26
+ }
27
+ };
28
+ COMPONENT.type = 'checkboxes';
29
+ expect((0, _optionIsSelected.default)(PAGE.formData[COMPONENT.id], OPTIONS[0])).toEqual(true);
30
+ expect((0, _optionIsSelected.default)(PAGE.formData[COMPONENT.id], OPTIONS[1])).toEqual(false);
31
+ });
32
+ it('should properly identify which option is selected for radios', function () {
33
+ var PAGE = {
34
+ formData: {
35
+ a: SELECTED_VALUE
36
+ }
37
+ };
38
+ COMPONENT.type = 'radios';
39
+ expect((0, _optionIsSelected.default)(PAGE.formData[COMPONENT.id], OPTIONS[0])).toEqual(true);
40
+ expect((0, _optionIsSelected.default)(PAGE.formData[COMPONENT.id], OPTIONS[1])).toEqual(false);
41
+ });
42
+ });
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _models = require("../../models");
8
+ var _optionIsSelected = _interopRequireDefault(require("../Component/optionIsSelected"));
8
9
  var _showComponent = _interopRequireDefault(require("../Component/showComponent"));
9
10
  var _additional = _interopRequireDefault(require("./additional"));
10
11
  var _validateCollection = _interopRequireDefault(require("./validateCollection"));
@@ -57,10 +58,11 @@ var validateComponent = function validateComponent(component, outerData, formDat
57
58
  properties = propsInError;
58
59
  error = message;
59
60
  break;
61
+ case _models.ComponentTypes.CHECKBOXES:
60
62
  case _models.ComponentTypes.RADIOS:
61
63
  var nestedErrors = [];
62
64
  (_component$data$optio = component.data.options) === null || _component$data$optio === void 0 ? void 0 : _component$data$optio.forEach(function (option) {
63
- if (option.nested && formData[component.id] === option.value) {
65
+ if (option.nested && (0, _optionIsSelected.default)(formData[component.id], option)) {
64
66
  nestedErrors = nestedErrors.concat((0, _validateContainer.default)({
65
67
  components: option.nested
66
68
  }, formData));
@@ -245,5 +245,121 @@ describe('utils.Validate.Component', function () {
245
245
  };
246
246
  expect((0, _validateComponent.default)(COMPONENT, undefined, {})).toBeUndefined();
247
247
  });
248
+ it('should return no error when the checkbox component contains nested components without errors', function () {
249
+ var NESTED_ID = 'nestedId';
250
+ var NESTED_VALUE = 'nestedValue';
251
+ var FORMDATA = _defineProperty({}, NESTED_ID, NESTED_VALUE);
252
+ var COMPONENT = {
253
+ type: 'checkboxes',
254
+ id: 'a',
255
+ data: {
256
+ options: [{
257
+ nested: [{
258
+ type: 'text',
259
+ fieldId: NESTED_ID,
260
+ id: NESTED_ID,
261
+ required: true
262
+ }]
263
+ }]
264
+ }
265
+ };
266
+ expect((0, _validateComponent.default)(COMPONENT, undefined, FORMDATA)).toBeUndefined();
267
+ });
268
+ it('should return an error when the checkbox component contains nested components with errors', function () {
269
+ var NESTED_ID = 'nestedId';
270
+ var OPTION_VALUE = 'optionValue';
271
+ var FORMDATA = {
272
+ 'a': [OPTION_VALUE]
273
+ };
274
+ var COMPONENT = {
275
+ type: 'checkboxes',
276
+ id: 'a',
277
+ data: {
278
+ options: [{
279
+ value: OPTION_VALUE,
280
+ nested: [{
281
+ type: 'text',
282
+ fieldId: NESTED_ID,
283
+ id: NESTED_ID,
284
+ required: true
285
+ }]
286
+ }]
287
+ }
288
+ };
289
+ expect((0, _validateComponent.default)(COMPONENT, undefined, FORMDATA)).toEqual([{
290
+ id: NESTED_ID,
291
+ error: "Field is required"
292
+ }]);
293
+ });
294
+ it('should return no error when a non selected checkbox component contains nested components with errors', function () {
295
+ var NESTED_ID_NOT_SELECTED = 'nestedIdNotSelected';
296
+ var NESTED_ID_SELECTED = 'nestedIdSelected';
297
+ var NESTED_VALUE_SELECTED = 'nestedValueSelected';
298
+ var FORMDATA = _defineProperty({
299
+ 'a': ['optionValueSelected']
300
+ }, NESTED_ID_SELECTED, NESTED_VALUE_SELECTED);
301
+ var COMPONENT = {
302
+ type: 'checkboxes',
303
+ id: 'a',
304
+ data: {
305
+ options: [{
306
+ id: 'optionIdNotSelected',
307
+ value: 'optionValueNotSelected',
308
+ nested: [{
309
+ type: 'text',
310
+ fieldId: NESTED_ID_NOT_SELECTED,
311
+ id: NESTED_ID_NOT_SELECTED,
312
+ required: true
313
+ }]
314
+ }, {
315
+ id: 'optionIdSelected',
316
+ value: 'optionValueSelected',
317
+ nested: [{
318
+ type: 'text',
319
+ fieldId: NESTED_ID_SELECTED,
320
+ id: NESTED_ID_SELECTED,
321
+ required: true
322
+ }]
323
+ }]
324
+ }
325
+ };
326
+ expect((0, _validateComponent.default)(COMPONENT, undefined, FORMDATA)).toBeUndefined();
327
+ });
328
+ it('should return no error when all selected checkbox components contains nested components without errors', function () {
329
+ var _FORMDATA4;
330
+ var NESTED_ID_SELECTED_1 = 'nestedIdSelected1';
331
+ var NESTED_ID_SELECTED_2 = 'nestedIdSelected2';
332
+ var NESTED_VALUE_SELECTED_1 = 'nestedValueSelected1';
333
+ var NESTED_VALUE_SELECTED_2 = 'nestedValueSelected2';
334
+ var FORMDATA = (_FORMDATA4 = {
335
+ 'a': ['optionValueSelected1', 'optionValueSelected2']
336
+ }, _defineProperty(_FORMDATA4, NESTED_ID_SELECTED_1, NESTED_VALUE_SELECTED_1), _defineProperty(_FORMDATA4, NESTED_ID_SELECTED_2, NESTED_VALUE_SELECTED_2), _FORMDATA4);
337
+ var COMPONENT = {
338
+ type: 'checkboxes',
339
+ id: 'a',
340
+ data: {
341
+ options: [{
342
+ id: 'optionIdSelected1',
343
+ value: 'optionValueSelected1',
344
+ nested: [{
345
+ type: 'text',
346
+ fieldId: NESTED_ID_SELECTED_1,
347
+ id: NESTED_ID_SELECTED_1,
348
+ required: true
349
+ }]
350
+ }, {
351
+ id: 'optionIdSelected2',
352
+ value: 'optionValueSelected2',
353
+ nested: [{
354
+ type: 'text',
355
+ fieldId: NESTED_ID_SELECTED_2,
356
+ id: NESTED_ID_SELECTED_2,
357
+ required: true
358
+ }]
359
+ }]
360
+ }
361
+ };
362
+ expect((0, _validateComponent.default)(COMPONENT, undefined, FORMDATA)).toBeUndefined();
363
+ });
248
364
  });
249
365
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ukhomeoffice/cop-react-form-renderer",
3
- "version": "4.68.1",
3
+ "version": "4.69.2",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "clean": "rimraf dist",
@@ -16,7 +16,7 @@
16
16
  "post-compile": "rimraf dist/*.test.* dist/**/*.test.* dist/**/*.stories.* dist/docs dist/assets"
17
17
  },
18
18
  "dependencies": {
19
- "@ukhomeoffice/cop-react-components": "^2.12.0-alpha",
19
+ "@ukhomeoffice/cop-react-components": "^2.14.3",
20
20
  "axios": "^0.23.0",
21
21
  "dayjs": "^1.11.0",
22
22
  "govuk-frontend": "^4.3.1",