@ukhomeoffice/cop-react-form-renderer 6.0.6-peter → 6.5.1-peter

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 (72) hide show
  1. package/dist/components/CheckYourAnswers/CheckYourAnswers.scss +2 -2
  2. package/dist/components/CollectionPage/CollectionPage.js +8 -2
  3. package/dist/components/CollectionSummary/BannerStrip.js +3 -2
  4. package/dist/components/CollectionSummary/BannerStrip.scss +2 -2
  5. package/dist/components/CollectionSummary/BannerStrip.test.js +39 -4
  6. package/dist/components/CollectionSummary/CollectionSummary.js +82 -63
  7. package/dist/components/CollectionSummary/CollectionSummary.scss +1 -1
  8. package/dist/components/CollectionSummary/CollectionSummary.test.js +40 -80
  9. package/dist/components/CollectionSummary/Confirmation.scss +1 -1
  10. package/dist/components/CollectionSummary/RenderListView.js +24 -20
  11. package/dist/components/CollectionSummary/RenderListView.scss +10 -1
  12. package/dist/components/CollectionSummary/RenderListView.test.js +14 -4
  13. package/dist/components/CollectionSummary/SummaryCard.js +59 -38
  14. package/dist/components/CollectionSummary/SummaryCard.scss +2 -1
  15. package/dist/components/CollectionSummary/SummaryCard.test.js +193 -150
  16. package/dist/components/CollectionSummary/SummaryCardDetails.js +70 -13
  17. package/dist/components/CollectionSummary/SummaryCardDetails.scss +43 -6
  18. package/dist/components/CollectionSummary/SummaryCardDetails.test.js +174 -26
  19. package/dist/components/CollectionSummary/SummaryCardValidationContext.js +15 -5
  20. package/dist/components/CollectionSummary/SummaryCardValidationContext.test.js +5 -4
  21. package/dist/components/FormComponent/Collection.js +24 -17
  22. package/dist/components/FormComponent/Collection.test.js +138 -0
  23. package/dist/components/FormComponent/FormComponent.js +12 -0
  24. package/dist/components/FormPage/FormPage.scss +1 -1
  25. package/dist/components/FormRenderer/FormRenderer.js +7 -4
  26. package/dist/components/FormRenderer/FormRenderer.scss +1 -1
  27. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/cop-airpax-after.json +429 -0
  28. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/cop-airpax-before.json +449 -0
  29. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/cop-airpax-form.json +15219 -0
  30. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/cop-eab-2-data-after.json +516 -0
  31. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/cop-eab-2-data-before.json +593 -0
  32. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/cop-eab2-form.json +15219 -0
  33. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/cop-mandec-data-after.json +84 -0
  34. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/cop-mandec-data-before.json +98 -0
  35. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/cop-mandec-form.json +9158 -0
  36. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/test.json +1605 -0
  37. package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/test2.json +205 -0
  38. package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutes.js +69 -38
  39. package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutes.test.js +30 -0
  40. package/dist/components/FormRenderer/helpers/deleteNodeByPath.js +8 -2
  41. package/dist/components/FormRenderer/onPageAction.js +6 -1
  42. package/dist/components/FormRenderer/onPageAction.test.js +18 -4
  43. package/dist/components/SummaryList/SummaryList.scss +2 -2
  44. package/dist/components/TaskList/TaskList.scss +1 -1
  45. package/dist/context/ValidationContext/ValidationContext.js +49 -5
  46. package/dist/context/ValidationContext/ValidationContext.test.js +16 -7
  47. package/dist/hooks/useRefData.js +1 -1
  48. package/dist/utils/CheckYourAnswers/showComponentCYA.js +1 -2
  49. package/dist/utils/CheckYourAnswers/showComponentCYA.test.js +5 -0
  50. package/dist/utils/CollectionPage/addCollectionPageEntry.js +1 -2
  51. package/dist/utils/CollectionPage/addCollectionPageEntry.test.js +4 -24
  52. package/dist/utils/CollectionPage/duplicateCollectionPageEntry.js +13 -1
  53. package/dist/utils/CollectionPage/duplicateCollectionPageEntry.test.js +17 -2
  54. package/dist/utils/CollectionPage/getErrorsForCollection.js +55 -0
  55. package/dist/utils/CollectionPage/getErrorsForCollection.test.js +155 -0
  56. package/dist/utils/CollectionPage/getQuickEditPage.js +7 -1
  57. package/dist/utils/CollectionPage/index.js +2 -0
  58. package/dist/utils/CollectionPage/setCollectionPageData.js +9 -4
  59. package/dist/utils/CollectionPage/setCollectionPageData.test.js +18 -0
  60. package/dist/utils/Component/isEditable.js +1 -1
  61. package/dist/utils/Condition/meetsCondition.js +18 -0
  62. package/dist/utils/Condition/meetsCondition.test.js +100 -0
  63. package/dist/utils/Data/getOptions.js +10 -0
  64. package/dist/utils/Data/getOptions.test.js +73 -0
  65. package/dist/utils/Data/nestInRefdataOptions.js +49 -0
  66. package/dist/utils/Data/nestInRefdataOptions.test.js +236 -0
  67. package/dist/utils/Validate/validateContainer.js +3 -1
  68. package/dist/utils/Validate/validateContainer.test.js +33 -0
  69. package/dist/utils/Validate/validateEmail.js +1 -1
  70. package/dist/utils/Validate/validatePage.js +10 -1
  71. package/dist/utils/Validate/validatePage.test.js +69 -0
  72. package/package.json +4 -4
@@ -0,0 +1,205 @@
1
+ {
2
+ "id": "deb97e25-c4e4-11ee-8f7e-2e10af5884e4",
3
+ "businessKey": "DEV-20240206-415",
4
+ "modeOfTransport": {
5
+ "id": 2,
6
+ "mode": "Scheduled Air Passenger",
7
+ "modecode": "airpass",
8
+ "crossingtype": [
9
+ "air"
10
+ ],
11
+ "value": "Scheduled Air Passenger",
12
+ "label": "Scheduled Air Passenger"
13
+ },
14
+ "port": {
15
+ "id": 3415,
16
+ "name": "Luton",
17
+ "sea": false,
18
+ "air": true,
19
+ "land": false,
20
+ "rail": false,
21
+ "countryid": 234,
22
+ "iata": "LTN",
23
+ "value": "3415",
24
+ "label": "Luton"
25
+ },
26
+ "formStatus": {
27
+ "tasks": {
28
+ "undefined": {},
29
+ "Enter event details": {
30
+ "complete": true,
31
+ "currentPage": "eventDetailsCya"
32
+ },
33
+ "Enter item and storage details": {
34
+ "complete": true,
35
+ "currentPage": "whatHappensNext"
36
+ },
37
+ "Journey-details-item-abandoned": {
38
+ "complete": true,
39
+ "currentPage": "journeyCya"
40
+ },
41
+ "Accept and submit": {
42
+ "complete": false,
43
+ "currentPage": "submitForm"
44
+ }
45
+ },
46
+ "taskPage": "submitForm"
47
+ },
48
+ "formInstanceId": "bc81a157-cbd9-4c14-87fb-3b52d02bf71d",
49
+ "links": [
50
+ {
51
+ "method": "GET",
52
+ "href": "https://blue.dev.cop.homeoffice.gov.uk/camunda/engine-rest/process-instance/deb97e25-c4e4-11ee-8f7e-2e10af5884e4",
53
+ "rel": "self"
54
+ }
55
+ ],
56
+ "definitionId": "cop-addABorderEvent:9:113b6e67-b48d-11ee-8088-52b814b55f74",
57
+ "caseInstanceId": null,
58
+ "ended": false,
59
+ "suspended": false,
60
+ "tenantId": null,
61
+ "whatHappened": "items",
62
+ "eventDateTime": {
63
+ "eventDate": "06-02-2024",
64
+ "eventTime": "01:01"
65
+ },
66
+ "terminal": {
67
+ "id": 9,
68
+ "name": "Western Docks",
69
+ "validfrom": "2019-01-01T00:01:00.000Z",
70
+ "validto": null,
71
+ "updatedby": null,
72
+ "value": "9",
73
+ "label": "Western Docks"
74
+ },
75
+ "subLocation": {
76
+ "id": 10,
77
+ "sublocation": "Warehouse",
78
+ "description": null,
79
+ "validfrom": "2021-05-07T00:00:03.000Z",
80
+ "validto": null,
81
+ "updatedby": "BethStephenson",
82
+ "uoflocation": false,
83
+ "value": "10",
84
+ "label": "Warehouse"
85
+ },
86
+ "centaurReference": "E1234567",
87
+ "leadOfficerEmail": {
88
+ "email": "jyoti.shetty@digital.homeoffice.gov.uk",
89
+ "label": "jyoti.shetty@digital.homeoffice.gov.uk",
90
+ "value": "jyoti.shetty@digital.homeoffice.gov.uk",
91
+ "defaultteamid": "de8053bf-8ce6-4e60-a4a1-de6862fe158f"
92
+ },
93
+ "officerEmails": [],
94
+ "operationOrExercise": "no",
95
+ "itemsActiveId": "1707219813475",
96
+ "itemsNumberedIndex": 1,
97
+ "items": [
98
+ {
99
+ "id": "1707219813475",
100
+ "sealNumber": "876dsadadad",
101
+ "exhibitReference": "Exh123",
102
+ "itemCategory": {
103
+ "id": 8,
104
+ "category": "Firearms",
105
+ "description": "Both lethal and non-lethal firearms.",
106
+ "validfrom": "2023-01-10T00:00:01.000Z",
107
+ "validto": null,
108
+ "updatedby": "Mohammed Abdul Odud",
109
+ "synonyms": [
110
+ "'Guns'"
111
+ ],
112
+ "value": "8",
113
+ "label": "Firearms"
114
+ },
115
+ "itemSubCategory": {
116
+ "id": 1426,
117
+ "name": "Military weapons component",
118
+ "description": null,
119
+ "itemcategoriesid": 8,
120
+ "cites": false,
121
+ "poao": false,
122
+ "cbrn": false,
123
+ "document": false,
124
+ "tobacco": false,
125
+ "alcohol": false,
126
+ "weapons": false,
127
+ "firearms": true,
128
+ "ipr": true,
129
+ "strategic": false,
130
+ "avtc": false,
131
+ "oils": false,
132
+ "commodity": false,
133
+ "good": false,
134
+ "plant": false,
135
+ "animal": false,
136
+ "drugs": false,
137
+ "financial": false,
138
+ "indecent": false,
139
+ "vehicle": false,
140
+ "medical": false,
141
+ "unitid": 5,
142
+ "seizureqty": null,
143
+ "ienqty": null,
144
+ "validfrom": "2023-01-10T00:00:01.000Z",
145
+ "validto": null,
146
+ "updatedby": "Mohammed Abdul Odud",
147
+ "uof": false,
148
+ "epmscode": 1024,
149
+ "epmscategory": "ARP",
150
+ "unitarray": [
151
+ 5
152
+ ],
153
+ "categoryarray": [
154
+ 8,
155
+ 9
156
+ ],
157
+ "lethalfirearm": null,
158
+ "nonlethalfirearm": null,
159
+ "value": "1426",
160
+ "label": "Military weapons component"
161
+ },
162
+ "seizedOrDetained": "detained",
163
+ "legalReasonForDetaining": {
164
+ "id": 3,
165
+ "epmsvalue": 18,
166
+ "reason": "Immigration Act",
167
+ "description": "Immigration Act",
168
+ "validfrom": "2022-09-21T00:00:01.000Z",
169
+ "validto": null,
170
+ "updatedby": "Mohammed Abdul Odud",
171
+ "value": "3",
172
+ "label": "Immigration Act"
173
+ },
174
+ "whatIsTheInitialMovement?": {
175
+ "id": 3,
176
+ "epmscode": 5,
177
+ "description": "Sent For Forensic Examination",
178
+ "inuse": true,
179
+ "validfrom": "2022-08-18T00:00:01.000Z",
180
+ "validto": null,
181
+ "updatedby": "Mohammed Abdul Odud",
182
+ "value": "3",
183
+ "label": "Sent For Forensic Examination"
184
+ },
185
+ "giveAReason": "sadad"
186
+ }
187
+ ],
188
+ "lockup": {
189
+ "value": "LTN",
190
+ "label": "Luton Airport Lockup",
191
+ "hidden": true
192
+ },
193
+ "epmsSubmitted": true,
194
+ "doYouHaveTheirFlightNumber": "no",
195
+ "form": {
196
+ "formVersionId": "ed41c96b78388228eb887927e45dc8a150a8b333",
197
+ "title": "Add a border event",
198
+ "name": "cop-addABorderEvent",
199
+ "submissionDate": "2024-02-06T11:53:56.499Z",
200
+ "submittedBy": "jyoti.shetty@digital.homeoffice.gov.uk",
201
+ "submittingUsersName": "Jyoti",
202
+ "submissionTeam": "de8053bf-8ce6-4e60-a4a1-de6862fe158f",
203
+ "formInstanceId": "bc81a157-cbd9-4c14-87fb-3b52d02bf71d"
204
+ }
205
+ }
@@ -4,13 +4,23 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _showComponent = _interopRequireDefault(require("../../../utils/Component/showComponent"));
8
7
  var _mergeCollectionPages = _interopRequireDefault(require("../../../utils/CollectionPage/mergeCollectionPages"));
9
8
  var _deleteNodeByPath = _interopRequireDefault(require("./deleteNodeByPath"));
10
9
  var _optionIsSelected = _interopRequireDefault(require("../../../utils/Component/optionIsSelected"));
10
+ var _Condition = _interopRequireDefault(require("../../../utils/Condition"));
11
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
12
  /* eslint-disable no-param-reassign */
13
13
 
14
+ var showComponentIncludeHiddenAndDisabled = function showComponentIncludeHiddenAndDisabled(component, data) {
15
+ var _component$show_when;
16
+ if (!component) {
17
+ return false;
18
+ }
19
+ if (((_component$show_when = component.show_when) === null || _component$show_when === void 0 ? void 0 : _component$show_when.type) === "or") {
20
+ return _Condition.default.meetsOne(component, data);
21
+ }
22
+ return _Condition.default.meetsAll(component, data);
23
+ };
14
24
  var recurseCheckForHiddenComponents = function recurseCheckForHiddenComponents(component, formData, path, candidateComponentForDeletion) {
15
25
  path = path ? "".concat(path, ".").concat(component.fieldId) : component.fieldId;
16
26
  if (component) {
@@ -19,7 +29,7 @@ var recurseCheckForHiddenComponents = function recurseCheckForHiddenComponents(c
19
29
  (_component$components = component.components) === null || _component$components === void 0 || _component$components.forEach(function (c) {
20
30
  recurseCheckForHiddenComponents(c, formData, path, candidateComponentForDeletion);
21
31
  });
22
- } else if ((0, _showComponent.default)(component, formData)) {
32
+ } else if (showComponentIncludeHiddenAndDisabled(component, formData)) {
23
33
  var _component$data;
24
34
  if (component !== null && component !== void 0 && (_component$data = component.data) !== null && _component$data !== void 0 && _component$data.options) {
25
35
  var _component$data2;
@@ -34,7 +44,7 @@ var recurseCheckForHiddenComponents = function recurseCheckForHiddenComponents(c
34
44
  }
35
45
  });
36
46
  }
37
- } else if (!(0, _showComponent.default)(component, formData)) {
47
+ } else if (!showComponentIncludeHiddenAndDisabled(component, formData)) {
38
48
  if (path) {
39
49
  candidateComponentForDeletion.set(path, component);
40
50
  }
@@ -50,8 +60,8 @@ var buildListOfComponentsUsedInVisiblePages = function buildListOfComponentsUsed
50
60
  })) !== null && _form$components$find !== void 0 ? _form$components$find : form.components.find(function (c) {
51
61
  return c.id === component.use;
52
62
  })) !== null && _ref !== void 0 ? _ref : component;
53
- if (page && (0, _showComponent.default)(page, formData)) {
54
- if (componentObj && (0, _showComponent.default)(componentObj, formData)) {
63
+ if (page && showComponentIncludeHiddenAndDisabled(page, formData)) {
64
+ if (componentObj && showComponentIncludeHiddenAndDisabled(componentObj, formData)) {
55
65
  if (componentObj.fieldId) {
56
66
  componentsUsedInVisiblePagesIds.push(componentObj.fieldId);
57
67
  } else if (componentObj.id) {
@@ -61,20 +71,22 @@ var buildListOfComponentsUsedInVisiblePages = function buildListOfComponentsUsed
61
71
  }
62
72
  });
63
73
  };
64
- var recurseDeleteComponents = function recurseDeleteComponents(component, formData, path, checkIfComponentHidden) {
74
+ var recursePopulateComponentPaths = function recursePopulateComponentPaths(component, formData, path, componentPaths, checkIfHidden) {
65
75
  path = path ? "".concat(path, ".").concat(component.fieldId) : component.fieldId;
66
76
  if (component) {
67
77
  if (component.components) {
68
78
  var _component$components2;
69
79
  (_component$components2 = component.components) === null || _component$components2 === void 0 || _component$components2.forEach(function (c) {
70
- recurseDeleteComponents(c, formData, path, checkIfComponentHidden);
80
+ recursePopulateComponentPaths(c, formData, path, componentPaths);
71
81
  });
72
- } else if (checkIfComponentHidden) {
73
- if (!(0, _showComponent.default)(component, formData)) {
74
- delete formData[path];
82
+ } else if (path) {
83
+ if (checkIfHidden) {
84
+ if (showComponentIncludeHiddenAndDisabled(component, formData)) {
85
+ componentPaths.push(path);
86
+ }
87
+ } else {
88
+ componentPaths.push(path);
75
89
  }
76
- } else {
77
- delete formData[path];
78
90
  }
79
91
  }
80
92
  };
@@ -90,34 +102,34 @@ var markComponentsForDeletion = function markComponentsForDeletion(page, form, f
90
102
  })) !== null && _form$components$find2 !== void 0 ? _form$components$find2 : form.components.find(function (c) {
91
103
  return c.id === component.use;
92
104
  })) !== null && _ref2 !== void 0 ? _ref2 : component;
93
- if (page && (0, _showComponent.default)(page, formData)) {
105
+ if (page && showComponentIncludeHiddenAndDisabled(page, formData)) {
94
106
  buildListOfComponentsUsedInVisiblePages(page, form, formData, componentsUsedInVisiblePages);
95
107
  recurseCheckForHiddenComponents(componentObj, formData, null, candidateComponentForDeletion);
96
- } else if (componentObj.fieldId) {
97
- candidateComponentForDeletion.set(componentObj.fieldId, componentObj);
98
- } else if (componentObj.id) {
99
- candidateComponentForDeletion.set(componentObj.id, componentObj);
108
+ } else {
109
+ if (componentObj.fieldId) {
110
+ candidateComponentForDeletion.set(componentObj.fieldId, componentObj);
111
+ }
112
+ if (componentObj.id) {
113
+ candidateComponentForDeletion.set(componentObj.id, componentObj);
114
+ }
100
115
  }
101
116
  });
102
117
  };
103
- var deleteHiddenComponent = function deleteHiddenComponent(page, form, collectionData, formData) {
104
- if (page.disableClearWhenHidden) {
105
- return;
106
- }
107
- if (page && (0, _showComponent.default)(page, formData)) {
108
- var _page$components3;
109
- (_page$components3 = page.components) === null || _page$components3 === void 0 || _page$components3.forEach(function (component) {
110
- var _ref3, _form$components$find3;
111
- var componentObj = (_ref3 = (_form$components$find3 = form.components.find(function (c) {
112
- return c.fieldId === component.use;
113
- })) !== null && _form$components$find3 !== void 0 ? _form$components$find3 : form.components.find(function (c) {
114
- return c.id === component.use;
115
- })) !== null && _ref3 !== void 0 ? _ref3 : component;
116
- recurseDeleteComponents(componentObj, collectionData, null, true);
117
- });
118
- } else {
118
+ var populateComponentPaths = function populateComponentPaths(page, form, collectionData, formData, nonDeleteComponentPaths, allComponentPaths) {
119
+ if (page) {
119
120
  var _page$components4;
120
- // recursively delete all components on the page
121
+ if (showComponentIncludeHiddenAndDisabled(page, formData) || showComponentIncludeHiddenAndDisabled(page, collectionData)) {
122
+ var _page$components3;
123
+ (_page$components3 = page.components) === null || _page$components3 === void 0 || _page$components3.forEach(function (component) {
124
+ var _ref3, _form$components$find3;
125
+ var componentObj = (_ref3 = (_form$components$find3 = form.components.find(function (c) {
126
+ return c.fieldId === component.use;
127
+ })) !== null && _form$components$find3 !== void 0 ? _form$components$find3 : form.components.find(function (c) {
128
+ return c.id === component.use;
129
+ })) !== null && _ref3 !== void 0 ? _ref3 : component;
130
+ recursePopulateComponentPaths(componentObj, collectionData, null, nonDeleteComponentPaths, true);
131
+ });
132
+ }
121
133
  (_page$components4 = page.components) === null || _page$components4 === void 0 || _page$components4.forEach(function (component) {
122
134
  var _ref4, _form$components$find4;
123
135
  var componentObj = (_ref4 = (_form$components$find4 = form.components.find(function (c) {
@@ -125,27 +137,44 @@ var deleteHiddenComponent = function deleteHiddenComponent(page, form, collectio
125
137
  })) !== null && _form$components$find4 !== void 0 ? _form$components$find4 : form.components.find(function (c) {
126
138
  return c.id === component.use;
127
139
  })) !== null && _ref4 !== void 0 ? _ref4 : component;
128
- recurseDeleteComponents(componentObj, collectionData, null, false);
140
+ recursePopulateComponentPaths(componentObj, collectionData, null, allComponentPaths, false);
129
141
  });
130
142
  }
131
143
  };
132
144
  function clearUncompletedRoutesForCollections(formData, page, form) {
133
145
  var _page$collection;
146
+ var nonDeleteComponentPaths = [];
147
+ var allComponentPaths = [];
134
148
  var collectionDatas = formData[page === null || page === void 0 || (_page$collection = page.collection) === null || _page$collection === void 0 ? void 0 : _page$collection.name];
135
149
  if (collectionDatas) {
136
150
  collectionDatas.forEach(function (collectionData) {
137
151
  var _page$childPages;
138
152
  /* eslint-disable consistent-return */
139
153
  (_page$childPages = page.childPages) === null || _page$childPages === void 0 || _page$childPages.forEach(function (childPage) {
154
+ if (childPage.disableClearWhenHidden) {
155
+ return;
156
+ }
140
157
  if (childPage.deleteCollectionWhenHidden) {
141
- if (childPage && !(0, _showComponent.default)(childPage, formData)) {
158
+ if (!showComponentIncludeHiddenAndDisabled(childPage, formData)) {
142
159
  delete formData[childPage.collection.name];
143
160
  return false;
144
161
  }
145
162
  }
146
- deleteHiddenComponent(childPage, form, collectionData, formData);
163
+ populateComponentPaths(childPage, form, collectionData, formData, nonDeleteComponentPaths, allComponentPaths);
147
164
  });
148
165
  });
166
+ nonDeleteComponentPaths = nonDeleteComponentPaths.filter(function (value, index, self) {
167
+ return self.indexOf(value) === index;
168
+ });
169
+ allComponentPaths = allComponentPaths.filter(function (value, index, self) {
170
+ return self.indexOf(value) === index;
171
+ });
172
+ // delete fields not visible
173
+ allComponentPaths.forEach(function (key) {
174
+ if (!nonDeleteComponentPaths.includes(key)) {
175
+ (0, _deleteNodeByPath.default)(collectionDatas, key);
176
+ }
177
+ });
149
178
  }
150
179
  }
151
180
  var clearOutUncompletedRoutes = function clearOutUncompletedRoutes(form, formData) {
@@ -163,7 +192,9 @@ var clearOutUncompletedRoutes = function clearOutUncompletedRoutes(form, formDat
163
192
  markComponentsForDeletion(page, form, formData, candidateComponentForDeletion, componentsUsedInVisiblePagesIds);
164
193
  }
165
194
  });
166
- componentsUsedInVisiblePagesIds = [].concat(new Set(componentsUsedInVisiblePagesIds));
195
+ componentsUsedInVisiblePagesIds = componentsUsedInVisiblePagesIds.filter(function (value, index, self) {
196
+ return self.indexOf(value) === index;
197
+ });
167
198
  componentsUsedInVisiblePagesIds.forEach(function (componentId) {
168
199
  return candidateComponentForDeletion.delete(componentId);
169
200
  });
@@ -14,10 +14,40 @@ var _dataWithComponentsRemoved = _interopRequireDefault(require("../clear-uncomp
14
14
  var _formForNestedComponents = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/form-for-nested-components.json"));
15
15
  var _dataWithNestedComponents = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/data-with-nested-components.json"));
16
16
  var _dataWithNestedComponentRemoved = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/data-with-nested-component-removed.json"));
17
+ var _copEab2Form = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/cop-eab2-form.json"));
18
+ var _copEab2DataBefore = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/cop-eab-2-data-before.json"));
19
+ var _copEab2DataAfter = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/cop-eab-2-data-after.json"));
20
+ var _copMandecForm = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/cop-mandec-form.json"));
21
+ var _copMandecDataBefore = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/cop-mandec-data-before.json"));
22
+ var _copMandecDataAfter = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/cop-mandec-data-after.json"));
23
+ var _copAirpaxBefore = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/cop-airpax-before.json"));
24
+ var _copAirpaxAfter = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/cop-airpax-after.json"));
25
+ var _copAirpaxForm = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/cop-airpax-form.json"));
17
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
27
  describe('FormRenderer', function () {
19
28
  describe('helpers', function () {
20
29
  describe('clearOutUncompletedRoutes', function () {
30
+ it('should clear out for cop-eab 2 civil penalty', function () {
31
+ var form = JSON.parse(JSON.stringify(_copEab2Form.default));
32
+ var formData = JSON.parse(JSON.stringify(_copEab2DataBefore.default));
33
+ var clearedFormData = JSON.parse(JSON.stringify(_copEab2DataAfter.default));
34
+ var result = _index.default.clearOutUncompletedRoutes(form, formData);
35
+ expect(result).toEqual(clearedFormData);
36
+ });
37
+ it('should clear out for cop-eab 2 airpax', function () {
38
+ var form = JSON.parse(JSON.stringify(_copAirpaxForm.default));
39
+ var formData = JSON.parse(JSON.stringify(_copAirpaxBefore.default));
40
+ var clearedFormData = JSON.parse(JSON.stringify(_copAirpaxAfter.default));
41
+ var result = _index.default.clearOutUncompletedRoutes(form, formData);
42
+ expect(result).toEqual(clearedFormData);
43
+ });
44
+ it('should clear out for cop-mandec', function () {
45
+ var form = JSON.parse(JSON.stringify(_copMandecForm.default));
46
+ var formData = JSON.parse(JSON.stringify(_copMandecDataBefore.default));
47
+ var clearedFormData = JSON.parse(JSON.stringify(_copMandecDataAfter.default));
48
+ var result = _index.default.clearOutUncompletedRoutes(form, formData);
49
+ expect(result).toEqual(clearedFormData);
50
+ });
21
51
  it('should not remove hidden component where it is visible in another page', function () {
22
52
  var form = JSON.parse(JSON.stringify(_componentUsedInMultiplePagesForm.default));
23
53
  var formData = JSON.parse(JSON.stringify(_componentUsedInMultiplePagesData.default));
@@ -6,10 +6,16 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  /* eslint-disable consistent-return */
8
8
  var deleteNodeByPath = function deleteNodeByPath(obj, path) {
9
+ if (Array.isArray(obj)) {
10
+ // If obj is an array, recursively call deleteNodeByPath on each element
11
+ for (var i = 0; i < obj.length; i += 1) {
12
+ deleteNodeByPath(obj[i], path);
13
+ }
14
+ }
9
15
  var keys = path.split('.');
10
16
  var current = obj;
11
- for (var i = 0; i < keys.length - 1; i += 1) {
12
- current = current[keys[i]];
17
+ for (var _i = 0; _i < keys.length - 1; _i += 1) {
18
+ current = current[keys[_i]];
13
19
  if (current === undefined) {
14
20
  return;
15
21
  }
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _models = require("../../models");
8
8
  var _utils = _interopRequireDefault(require("../../utils"));
9
+ var _setCollectionPageData = _interopRequireDefault(require("../../utils/CollectionPage/setCollectionPageData"));
9
10
  var _handlers = _interopRequireDefault(require("./handlers"));
10
11
  var _helpers = _interopRequireDefault(require("./helpers"));
11
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -48,7 +49,11 @@ var onPageAction = function onPageAction(action, patch, patchLabel, hooks, data,
48
49
  if (action.addToFormData) {
49
50
  var operations = Array.isArray(action.addToFormData) ? action.addToFormData : [action.addToFormData];
50
51
  operations.forEach(function (op) {
51
- _utils.default.Data.setDataItem(formState.page.formData, op.field, op.value);
52
+ if (op.isCollection) {
53
+ (0, _setCollectionPageData.default)(op.field, op.value, formState.page.formData);
54
+ } else {
55
+ _utils.default.Data.setDataItem(formState.page.formData, op.field, op.value);
56
+ }
52
57
  });
53
58
  form.page.formData[action.addToFormData.field] = action.addToFormData.value;
54
59
  }
@@ -581,10 +581,16 @@ describe('components.FormRenderer.onPageAction', function () {
581
581
  var ACTION = {
582
582
  type: actionType,
583
583
  collection: 'testCollection',
584
- addToFormData: {
584
+ addToFormData: [{
585
585
  field: 'alpha',
586
586
  value: '123'
587
- }
587
+ }, {
588
+ field: 'parent.child',
589
+ value: [{
590
+ id: '12345'
591
+ }],
592
+ isCollection: true
593
+ }]
588
594
  };
589
595
  var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
590
596
  formState: FORM_STATE,
@@ -596,6 +602,7 @@ describe('components.FormRenderer.onPageAction', function () {
596
602
  expect(FORM_STATE.page.formData).toMatchObject({
597
603
  alpha: '123'
598
604
  });
605
+ expect(FORM_STATE.page.formData.parent[0].child[0].id).toEqual('12345');
599
606
  });
600
607
  });
601
608
  it("should work for the ".concat(_models.PageAction.TYPES.NAVIGATE, " action type"), function () {
@@ -609,10 +616,16 @@ describe('components.FormRenderer.onPageAction', function () {
609
616
  var ACTION = {
610
617
  type: _models.PageAction.TYPES.NAVIGATE,
611
618
  collection: 'testCollection',
612
- addToFormData: {
619
+ addToFormData: [{
613
620
  field: 'alpha',
614
621
  value: '123'
615
- }
622
+ }, {
623
+ field: 'parent.child',
624
+ value: [{
625
+ id: '12345'
626
+ }],
627
+ isCollection: true
628
+ }]
616
629
  };
617
630
  var CUSTOM_ARGS = _objectSpread(_objectSpread({}, ARGS), {}, {
618
631
  formState: FORM_STATE,
@@ -626,6 +639,7 @@ describe('components.FormRenderer.onPageAction', function () {
626
639
  expect(FORM_STATE.page.formData).toMatchObject({
627
640
  alpha: '123'
628
641
  });
642
+ expect(FORM_STATE.page.formData.parent[0].child[0].id).toEqual('12345');
629
643
  });
630
644
  it('should work for an array of formData', function () {
631
645
  var FORM_STATE = {
@@ -1,5 +1,5 @@
1
- @import 'node_modules/govuk-frontend/govuk/_base';
2
- @import 'node_modules/govuk-frontend/govuk/components/summary-list/_summary-list';
1
+ @import 'govuk-frontend/dist/govuk/_base';
2
+ @import 'govuk-frontend/dist/govuk/components/summary-list/_summary-list';
3
3
 
4
4
  .govuk-summary-list__title {
5
5
  width: 100%;
@@ -1,4 +1,4 @@
1
- @import 'node_modules/govuk-frontend/govuk/_base';
1
+ @import 'govuk-frontend/dist/govuk/_base';
2
2
 
3
3
  // Task list pattern
4
4
 
@@ -31,6 +31,45 @@ var ValidationContextProvider = function ValidationContextProvider(_ref) {
31
31
  _useState2 = _slicedToArray(_useState, 2),
32
32
  errors = _useState2[0],
33
33
  setErrors = _useState2[1];
34
+ var _useState3 = (0, _react.useState)([]),
35
+ _useState4 = _slicedToArray(_useState3, 2),
36
+ queuedErrors = _useState4[0],
37
+ setQueuedErrors = _useState4[1];
38
+
39
+ /**
40
+ * Queues errors to be displayed when the next validation takes place.
41
+ *
42
+ * @param {array} errors An array of errors to queue.
43
+ */
44
+ var enqueueErrors = function enqueueErrors(errors) {
45
+ setQueuedErrors(function (prev) {
46
+ return [].concat(prev, errors).filter(function (e) {
47
+ return !!e;
48
+ });
49
+ });
50
+ };
51
+
52
+ /**
53
+ * Removed errors from the queue if they match the given criteria.
54
+ *
55
+ * @param {function} matcher A function that should take an error and return true if that
56
+ * error should be removed from the queue.
57
+ */
58
+ var dequeueErrors = function dequeueErrors(matcher) {
59
+ if (typeof matcher !== 'function') {
60
+ return;
61
+ }
62
+ setQueuedErrors(function (prev) {
63
+ return prev.filter(function (e) {
64
+ return !matcher(e);
65
+ });
66
+ });
67
+ };
68
+ var clearQueuedErrors = function clearQueuedErrors() {
69
+ if (queuedErrors.length) {
70
+ setQueuedErrors([]);
71
+ }
72
+ };
34
73
  var addErrors = /*#__PURE__*/function () {
35
74
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(errors) {
36
75
  return _regeneratorRuntime().wrap(function _callee$(_context) {
@@ -56,8 +95,9 @@ var ValidationContextProvider = function ValidationContextProvider(_ref) {
56
95
  return _regeneratorRuntime().wrap(function _callee2$(_context2) {
57
96
  while (1) switch (_context2.prev = _context2.next) {
58
97
  case 0:
98
+ setQueuedErrors([]);
59
99
  setErrors([]);
60
- case 1:
100
+ case 2:
61
101
  case "end":
62
102
  return _context2.stop();
63
103
  }
@@ -69,17 +109,17 @@ var ValidationContextProvider = function ValidationContextProvider(_ref) {
69
109
  }();
70
110
  var validate = {
71
111
  page: function page(_page) {
72
- var pageErrors = _utils.default.Validate.page(_page);
112
+ var pageErrors = _utils.default.Validate.page(_page, queuedErrors);
73
113
  var allErrors = hooks.onValidate(_page, pageErrors);
74
114
  setErrors(allErrors);
75
115
  return allErrors;
76
116
  },
77
117
  pages: function pages(_pages) {
78
- var allPagesErrors = _pages.map(function (page) {
79
- return _utils.default.Validate.page(page);
118
+ var pageErrors = _pages.map(function (page) {
119
+ return _utils.default.Validate.page(page, queuedErrors);
80
120
  });
81
121
  var allErrors = _pages.flatMap(function (page, index) {
82
- return hooks.onValidate(page, allPagesErrors[index]);
122
+ return hooks.onValidate(page, pageErrors[index]);
83
123
  });
84
124
  setErrors(allErrors);
85
125
  return allErrors;
@@ -90,6 +130,10 @@ var ValidationContextProvider = function ValidationContextProvider(_ref) {
90
130
  errors: errors,
91
131
  addErrors: addErrors,
92
132
  clearErrors: clearErrors,
133
+ queuedErrors: queuedErrors,
134
+ enqueueErrors: enqueueErrors,
135
+ dequeueErrors: dequeueErrors,
136
+ clearQueuedErrors: clearQueuedErrors,
93
137
  validate: validate
94
138
  }
95
139
  }, children);