@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.
- package/dist/components/FormRenderer/FormRenderer.js +12 -17
- package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/forms/form-hidden-entire-collection.json +114 -0
- package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/input/data-hidden-entire-collection.json +20 -0
- package/dist/components/FormRenderer/clear-uncompleted-routes/test-data/output/data-hidden-entire-collection-removed.json +3 -0
- package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutes.js +9 -1
- package/dist/components/FormRenderer/helpers/clearOutUncompletedRoutes.test.js +11 -0
- package/dist/components/FormRenderer/helpers/getUpdatedSectionStates.js +6 -0
- package/dist/components/FormRenderer/helpers/getUpdatedSectionStates.test.js +20 -0
- package/dist/utils/CollectionPage/mergeCollectionPages.js +8 -2
- package/package.json +1 -1
|
@@ -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({
|