@ukhomeoffice/cop-react-form-renderer 6.15.12-accessibilty → 6.15.12

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.
@@ -129,17 +129,6 @@ const InternalFormRenderer = _ref2 => {
129
129
  validate
130
130
  } = (0, _hooks.useValidation)();
131
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) {
137
- header.setAttribute('tabIndex', '-1');
138
- header.focus();
139
- }
140
- }
141
- };
142
-
143
132
  // Need to set submission data when going back
144
133
  window.onpopstate = e => {
145
134
  var _formState$page;
@@ -156,12 +145,23 @@ const InternalFormRenderer = _ref2 => {
156
145
  }
157
146
  clearErrors();
158
147
  setGoingBack(true);
159
- hooks.onGoingBack(e.state ? e.state : null);
148
+ hooks.onGoingBack.apply(hooks, [e.state ? e.state : null].concat(formState.page.formData));
160
149
  if (components && pages && data && (_formState$page = formState.page) !== null && _formState$page !== void 0 && _formState$page.formData && pagePoint === undefined) {
150
+ var _submissionData$formS;
161
151
  const submissionData = _utils.default.Format.form({
162
152
  pages,
163
153
  components
164
154
  }, _objectSpread(_objectSpread({}, data), formState.page.formData), _models.EventTypes.SUBMIT);
155
+ if (submissionData !== null && submissionData !== void 0 && (_submissionData$formS = submissionData.formStatus) !== null && _submissionData$formS !== void 0 && _submissionData$formS.taskPage) {
156
+ const object = submissionData.formStatus.tasks;
157
+ Object.keys(object).forEach(key => {
158
+ const value = object[key];
159
+ if (value.currentPage && !value.complete) {
160
+ delete object[key].currentPage;
161
+ }
162
+ });
163
+ delete submissionData.formStatus.taskPage;
164
+ }
165
165
  setData(submissionData);
166
166
  }
167
167
  };
@@ -203,11 +203,6 @@ const InternalFormRenderer = _ref2 => {
203
203
  setFormState(_helpers.default.getFormState(pageId, pages, hub));
204
204
  }, [pages, hub, pageId, setFormState, type, goingBack, data, formState.page]);
205
205
 
206
- // Set focus to heading for accessibility
207
- (0, _react.useEffect)(() => {
208
- setFocusToHeading();
209
- }, [formState]);
210
-
211
206
  // Call the onFormLoad hook just when this component first renders.
212
207
  (0, _react.useEffect)(() => {
213
208
  setPagePoint(undefined);
@@ -0,0 +1,114 @@
1
+ {
2
+ "id": "example-form",
3
+ "cleanseHiddenData": true,
4
+ "version": "0.0.1",
5
+ "name": "example-form",
6
+ "title": "Example form",
7
+ "type": "form",
8
+ "components": [
9
+ {
10
+ "id": "itemCategory",
11
+ "fieldId": "itemCategory",
12
+ "label": "Item category",
13
+ "type": "text"
14
+ },
15
+ {
16
+ "id": "itemSubCategory",
17
+ "fieldId": "itemSubCategory",
18
+ "label": "Item Sub category",
19
+ "type": "text"
20
+ },
21
+ {
22
+ "id": "abvDetails",
23
+ "fieldId": "abvDetails",
24
+ "label": "AbvDetails",
25
+ "type": "text"
26
+ },
27
+ {
28
+ "id": "firearmCheck",
29
+ "fieldId": "firearmCheck",
30
+ "label": "FirearmCheck",
31
+ "type": "text"
32
+ },
33
+ {
34
+ "id": "brandText",
35
+ "fieldId": "brandText",
36
+ "label": "BrandText",
37
+ "type": "text"
38
+ }
39
+ ],
40
+ "pages": [
41
+ {
42
+ "id": "item-seal-details",
43
+ "name": "item-seal-details",
44
+ "title": "Item seal details",
45
+ "components": [
46
+ {
47
+ "use": "itemCategory"
48
+ },
49
+ {
50
+ "use": "itemSubCategory"
51
+ }
52
+ ],
53
+ "collection": {
54
+ "show_when": {
55
+ "op": "=",
56
+ "field": "alpha",
57
+ "value": "NOT-alpha-value"
58
+ },
59
+ "name": "items",
60
+ "actionPosition": "inHeading",
61
+ "labels": {
62
+ "item": "Item ${index}"
63
+ }
64
+ }
65
+ },
66
+ {
67
+ "id": "alcohol",
68
+ "name": "alcohol",
69
+ "title": "Alcohol",
70
+ "collection": {
71
+ "name": "items",
72
+ "waitForFormData": true,
73
+ "heading": {
74
+ "text": "Alcohol",
75
+ "size": "m",
76
+ "changeLink": true
77
+ }
78
+ },
79
+ "components": [
80
+ {
81
+ "use": "brandText",
82
+ "label": "Model or brand"
83
+ },
84
+ {
85
+ "use": "abvDetails",
86
+ "label": ""
87
+ }
88
+ ]
89
+ },
90
+ {
91
+ "id": "firearm",
92
+ "name": "firearm",
93
+ "title": "Firearm",
94
+ "collection": {
95
+ "name": "items",
96
+ "waitForFormData": true,
97
+ "heading": {
98
+ "text": "Firearm",
99
+ "size": "m",
100
+ "changeLink": true
101
+ }
102
+ },
103
+ "components": [
104
+ {
105
+ "use": "brandText",
106
+ "label": "Model or brand"
107
+ },
108
+ {
109
+ "use": "firearmCheck"
110
+ }
111
+ ]
112
+ }
113
+ ]
114
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "alpha": "alpha-value",
3
+ "itemsActiveId": "8b9b7671-d06d-447e-a907-e9215072741a",
4
+ "items": [
5
+ {
6
+ "id": "da056129-34e9-4218-8e98-574856977727",
7
+ "itemCategory": "alcohol",
8
+ "itemSubCategory": "itemSubCategory-value",
9
+ "brandText": "brandText-value",
10
+ "abvDetails": "abv-value"
11
+ },
12
+ {
13
+ "id": "da056129-34e9-4218-8e98-574856977727",
14
+ "itemCategory": "weapons",
15
+ "itemSubCategory": "ARM",
16
+ "brandText": "brandText-value",
17
+ "firearmCheck": "firearmCheck-value"
18
+ }
19
+ ]
20
+ }
@@ -212,7 +212,10 @@ const resolveComponentDependenciesGraph = (allDependencyRelationships, allCompon
212
212
  * rules for each payload object.
213
213
  *
214
214
  * Some of the rules may be dependent on payload items outside the collection. These will already have been cleansed
215
- * so will be in a reliable state.
215
+ * so will be in a reliable state.
216
+ *
217
+ * It is possible in the form spec to specify in the master page that the whole collection has a show_when rule.
218
+ * If this is the case, evaluate the rule and if false delete the entire collection array.
216
219
  *
217
220
  * @param {Map} allCollections A map of collection objects, which are a grouping of the pages that make up a single collection
218
221
  * @param {Object} formData The form payload
@@ -221,6 +224,11 @@ const resolveComponentDependenciesGraph = (allDependencyRelationships, allCompon
221
224
  */
222
225
  const cleanseCollectionData = (allCollections, formData, componentByIdMap, componentByFieldIdMap) => {
223
226
  allCollections === null || allCollections === void 0 || allCollections.forEach((collection, collectionName) => {
227
+ if (!Utils.isShowEntity(collection, formData)) {
228
+ // Delete the entire collection array (including activeId) if the master page has an unmet rule
229
+ delete formData[collectionName];
230
+ delete formData["".concat(collectionName, "ActiveId")];
231
+ }
224
232
  const collectionDataArray = formData[collectionName];
225
233
  collectionDataArray === null || collectionDataArray === void 0 || collectionDataArray.forEach(collectionDataEntry => {
226
234
  var _collection$childPage2;
@@ -75,6 +75,9 @@ var _dataChainedComponentShowWhensTargetComponentNestedRemoved = _interopRequire
75
75
  var _formHiddenPageCollection = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/forms/form-hidden-page-collection.json"));
76
76
  var _dataHiddenPageCollection = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/input/data-hidden-page-collection.json"));
77
77
  var _dataHiddenPageCollectionRemoved = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/output/data-hidden-page-collection-removed.json"));
78
+ var _formHiddenEntireCollection = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/forms/form-hidden-entire-collection.json"));
79
+ var _dataHiddenEntireCollection = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/input/data-hidden-entire-collection.json"));
80
+ var _dataHiddenEntireCollectionRemoved = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/output/data-hidden-entire-collection-removed.json"));
78
81
  var _formHiddenCollectionComponentDependentOnExternalData = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/forms/form-hidden-collection-component-dependent-on-external-data.json"));
79
82
  var _dataHiddenCollectionComponentDependentOnExternalData = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/input/data-hidden-collection-component-dependent-on-external-data.json"));
80
83
  var _dataHiddenCollectionComponentDependentOnExternalDataRemoved = _interopRequireDefault(require("../clear-uncompleted-routes/test-data/output/data-hidden-collection-component-dependent-on-external-data-removed.json"));
@@ -149,6 +152,8 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
149
152
 
150
153
  // Hidden page collection
151
154
 
155
+ // Should remove all collection components if show_when at the master page level
156
+
152
157
  // Hidden collection component, dependent on data external to and internal to collection payload
153
158
 
154
159
  // Mandec business interests
@@ -296,6 +301,12 @@ describe('FormRenderer', () => {
296
301
  const result = _index.default.clearOutUncompletedRoutes(true, form, submissionData);
297
302
  expect(result).toEqual(_dataHiddenPageComponentUsedElsewhereRemoved.default);
298
303
  });
304
+ it('should remove all collection components if show_when at the master page level.', () => {
305
+ const submissionData = JSON.parse(JSON.stringify(_dataHiddenEntireCollection.default));
306
+ const form = JSON.parse(JSON.stringify(_formHiddenEntireCollection.default));
307
+ const result = _index.default.clearOutUncompletedRoutes(true, form, submissionData);
308
+ expect(result).toEqual(_dataHiddenEntireCollectionRemoved.default);
309
+ });
299
310
  it('chained show_whens should be resolved from the end of the chain backup to the start.', () => {
300
311
  const submissionData = JSON.parse(JSON.stringify(_dataChainedComponentShowWhens.default));
301
312
  const form = JSON.parse(JSON.stringify(_formChainedComponentShowWhens.default));
@@ -30,6 +30,12 @@ const getCurrentTaskState = function (_ref) {
30
30
  if (currentPage) {
31
31
  return _models.TaskStates.TYPES.IN_PROGRESS;
32
32
  }
33
+ // If the user has clicked on the back link (see FormRenderer.jsx window.onpopstate event handler)
34
+ // the task will be incomplete and the currentPage deleted
35
+ // and the task state should be recognised as 'In progress'.
36
+ if (complete !== undefined && !complete && currentPage === undefined) {
37
+ return _models.TaskStates.TYPES.IN_PROGRESS;
38
+ }
33
39
  return defaultState;
34
40
  };
35
41
 
@@ -115,6 +115,26 @@ describe('components.FormRenderer.helpers.getUpdatedSectionStates', () => {
115
115
  expect(updatedSections[0].tasks[0].state).toEqual(_models.TaskStates.TYPES.IN_PROGRESS);
116
116
  expect(updatedSections[0].tasks[1].state).toEqual(_models.TaskStates.TYPES.CANNOT_START_YET);
117
117
  });
118
+ it("should set tasks to '".concat(_models.TaskStates.TYPES.IN_PROGRESS, "' if they have no current page and are not complete"), () => {
119
+ const SECTIONS = [{
120
+ name: 'Add event details',
121
+ tasks: [{
122
+ name: 'Date, location and mode details',
123
+ pages: ['eventDate', 'eventMode']
124
+ }, {
125
+ name: 'Officer and agency details',
126
+ pages: ['officeDetails']
127
+ }]
128
+ }];
129
+ const TASKS = {
130
+ 'Date, location and mode details': {
131
+ complete: false
132
+ }
133
+ };
134
+ const updatedSections = (0, _getUpdatedSectionStates.default)(SECTIONS, TASKS);
135
+ expect(updatedSections[0].tasks[0].state).toEqual(_models.TaskStates.TYPES.IN_PROGRESS);
136
+ expect(updatedSections[0].tasks[1].state).toEqual(_models.TaskStates.TYPES.CANNOT_START_YET);
137
+ });
118
138
  it("should set the status of any tasks in a section with a failed show_when to '".concat(_models.TaskStates.TYPES.SKIPPED, "'"), () => {
119
139
  const SECTIONS = [{
120
140
  name: 'Add event details',
@@ -25,11 +25,17 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
25
25
  * can be one of either:
26
26
  * - A regular form page.
27
27
  * - The master page for a child collection, with its own array of child pages.
28
+ *
29
+ * To specify that an entire collection (including labels and actions) is hidden,
30
+ * then add a show_when to the 1st collection entry in the form.
28
31
  */
29
32
 
30
- const createMasterPage = page => ({
33
+ const createMasterPage = page => _objectSpread(_objectSpread({
31
34
  id: page.id,
32
- name: page.name,
35
+ name: page.name
36
+ }, page.collection.show_when && {
37
+ show_when: page.collection.show_when
38
+ }), {}, {
33
39
  orderInForm: page.orderInForm,
34
40
  deleteCollectionWhenHidden: page.deleteCollectionWhenHidden,
35
41
  collection: _objectSpread({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ukhomeoffice/cop-react-form-renderer",
3
- "version": "6.15.12-accessibilty",
3
+ "version": "6.15.12",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "clean": "rimraf dist",