@ukhomeoffice/cop-react-form-renderer 3.0.3 → 3.2.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.
- package/dist/components/FormComponent/Collection.js +1 -5
- package/dist/components/FormComponent/Collection.test.js +322 -0
- package/dist/components/FormRenderer/FormRenderer.js +36 -13
- package/dist/components/FormRenderer/helpers/cleanHiddenNestedData.js +38 -0
- package/dist/components/FormRenderer/helpers/cleanHiddenNestedData.test.js +50 -0
- package/dist/components/FormRenderer/helpers/index.js +3 -0
- package/dist/context/HooksContext/HooksContext.js +8 -2
- package/dist/utils/CheckYourAnswers/getCYARow.js +3 -1
- package/dist/utils/CheckYourAnswers/getCYARow.test.js +3 -3
- package/dist/utils/Component/cleanAttributes.js +1 -1
- package/dist/utils/Component/getComponent.js +38 -20
- package/dist/utils/Component/getComponentTests/getComponent.nested.test.js +49 -26
- package/dist/utils/Component/getComponentTests/getComponent.time.test.js +106 -0
- package/dist/utils/Component/showComponent.js +6 -0
- package/dist/utils/Component/showComponent.test.js +63 -0
- package/dist/utils/Component/wrapInFormGroup.js +5 -2
- package/dist/utils/Condition/index.js +3 -0
- package/dist/utils/Condition/meetsOneCondition.js +40 -0
- package/dist/utils/Condition/meetsOneCondition.test.js +101 -0
- package/dist/utils/Condition/setupConditions.js +5 -4
- package/dist/utils/Container/showContainer.js +4 -0
- package/dist/utils/Container/showContainer.test.js +51 -0
- package/dist/utils/FormPage/showFormPage.js +4 -0
- package/dist/utils/FormPage/showFormPage.test.js +51 -0
- package/dist/utils/Validate/validateComponent.js +8 -15
- package/dist/utils/Validate/validateComponent.test.js +13 -14
- package/package.json +2 -2
|
@@ -67,15 +67,11 @@ var Collection = function Collection(_ref) {
|
|
|
67
67
|
onChange = _ref.onChange,
|
|
68
68
|
wrap = _ref.wrap;
|
|
69
69
|
|
|
70
|
-
var _useState = (0, _react.useState)(),
|
|
70
|
+
var _useState = (0, _react.useState)(_value),
|
|
71
71
|
_useState2 = _slicedToArray(_useState, 2),
|
|
72
72
|
value = _useState2[0],
|
|
73
73
|
setValue = _useState2[1];
|
|
74
74
|
|
|
75
|
-
(0, _react.useEffect)(function () {
|
|
76
|
-
setValue(_value || []);
|
|
77
|
-
}, [_value, setValue]);
|
|
78
|
-
|
|
79
75
|
var reportChange = function reportChange(newValue) {
|
|
80
76
|
setValue(newValue);
|
|
81
77
|
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = require("@testing-library/react");
|
|
4
|
+
|
|
5
|
+
var _react2 = _interopRequireDefault(require("react"));
|
|
6
|
+
|
|
7
|
+
var _testUtils = require("react-dom/test-utils");
|
|
8
|
+
|
|
9
|
+
var _models = require("../../models");
|
|
10
|
+
|
|
11
|
+
var _setupTests = require("../../setupTests");
|
|
12
|
+
|
|
13
|
+
var _utils = _interopRequireDefault(require("../../utils"));
|
|
14
|
+
|
|
15
|
+
var _Collection = require("./Collection");
|
|
16
|
+
|
|
17
|
+
var _Container = require("./Container");
|
|
18
|
+
|
|
19
|
+
var _FormComponent = _interopRequireDefault(require("./FormComponent"));
|
|
20
|
+
|
|
21
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
22
|
+
|
|
23
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
24
|
+
|
|
25
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
26
|
+
|
|
27
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
28
|
+
|
|
29
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
30
|
+
|
|
31
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
32
|
+
|
|
33
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
34
|
+
|
|
35
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
36
|
+
|
|
37
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
38
|
+
|
|
39
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
40
|
+
|
|
41
|
+
describe('components.FormComponent.Collection', function () {
|
|
42
|
+
var ID = 'collection';
|
|
43
|
+
var TEXT_ID = 'text';
|
|
44
|
+
var TEXT_VALUE = 'alpha';
|
|
45
|
+
|
|
46
|
+
var FORM_DATA = _defineProperty({}, ID, [_defineProperty({
|
|
47
|
+
id: '1'
|
|
48
|
+
}, TEXT_ID, TEXT_VALUE)]);
|
|
49
|
+
|
|
50
|
+
var TEXT_COMPONENT = {
|
|
51
|
+
id: TEXT_ID,
|
|
52
|
+
fieldId: TEXT_ID,
|
|
53
|
+
type: _models.ComponentTypes.TEXT,
|
|
54
|
+
label: 'Text component',
|
|
55
|
+
hint: 'Text hint'
|
|
56
|
+
};
|
|
57
|
+
it('should render a collection component appropriately', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
|
|
58
|
+
var COLLECTION, _renderWithValidation, container, c, item, _item$childNodes, title, itemContainer, formGroup, label, hint, input;
|
|
59
|
+
|
|
60
|
+
return regeneratorRuntime.wrap(function _callee$(_context) {
|
|
61
|
+
while (1) {
|
|
62
|
+
switch (_context.prev = _context.next) {
|
|
63
|
+
case 0:
|
|
64
|
+
COLLECTION = {
|
|
65
|
+
id: ID,
|
|
66
|
+
fieldId: ID,
|
|
67
|
+
type: _models.ComponentTypes.COLLECTION,
|
|
68
|
+
item: [TEXT_COMPONENT]
|
|
69
|
+
};
|
|
70
|
+
_renderWithValidation = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react2.default.createElement(_FormComponent.default, {
|
|
71
|
+
component: COLLECTION,
|
|
72
|
+
value: FORM_DATA[ID],
|
|
73
|
+
formData: FORM_DATA
|
|
74
|
+
})), container = _renderWithValidation.container; // Check the container itself.
|
|
75
|
+
|
|
76
|
+
c = container.childNodes[0];
|
|
77
|
+
expect(c.tagName).toEqual('DIV');
|
|
78
|
+
expect(c.classList).toContain(_Collection.DEFAULT_CLASS); // And now check the single text component within it.
|
|
79
|
+
|
|
80
|
+
item = c.childNodes[0];
|
|
81
|
+
expect(item.tagName).toEqual('DIV');
|
|
82
|
+
expect(item.classList).toContain("".concat(_Collection.DEFAULT_CLASS, "__item"));
|
|
83
|
+
_item$childNodes = _slicedToArray(item.childNodes, 2), title = _item$childNodes[0], itemContainer = _item$childNodes[1];
|
|
84
|
+
expect(title.tagName).toEqual('LABEL');
|
|
85
|
+
expect(title.classList).toContain("".concat(_Collection.DEFAULT_CLASS, "__item-title"));
|
|
86
|
+
expect(itemContainer.tagName).toEqual('DIV');
|
|
87
|
+
expect(itemContainer.classList).toContain(_Container.DEFAULT_CLASS);
|
|
88
|
+
formGroup = itemContainer.childNodes[0];
|
|
89
|
+
expect(formGroup.tagName).toEqual('DIV');
|
|
90
|
+
expect(formGroup.classList).toContain('govuk-form-group');
|
|
91
|
+
label = formGroup.childNodes[0];
|
|
92
|
+
expect(label.tagName).toEqual('LABEL');
|
|
93
|
+
expect(label.classList).toContain('govuk-label');
|
|
94
|
+
expect(label.textContent).toEqual("".concat(TEXT_COMPONENT.label, " (optional)"));
|
|
95
|
+
expect(label.getAttribute('for')).toEqual("".concat(ID, "[0].").concat(TEXT_ID));
|
|
96
|
+
hint = formGroup.childNodes[1];
|
|
97
|
+
expect(hint.tagName).toEqual('SPAN');
|
|
98
|
+
expect(hint.classList).toContain('govuk-hint');
|
|
99
|
+
expect(hint.textContent).toEqual(TEXT_COMPONENT.hint);
|
|
100
|
+
input = formGroup.childNodes[2];
|
|
101
|
+
expect(input.tagName).toEqual('INPUT');
|
|
102
|
+
expect(input.classList).toContain('govuk-input');
|
|
103
|
+
expect(input.id).toEqual("".concat(ID, "[0].").concat(TEXT_ID));
|
|
104
|
+
expect(input.value).toEqual(TEXT_VALUE);
|
|
105
|
+
|
|
106
|
+
case 30:
|
|
107
|
+
case "end":
|
|
108
|
+
return _context.stop();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}, _callee);
|
|
112
|
+
})));
|
|
113
|
+
it('should handle a change to a component appropriately', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
|
|
114
|
+
var ON_CHANGE_EVENTS, ON_CHANGE, COLLECTION, _renderWithValidation2, container, c, item, formGroup, input, NEW_TEXT_VALUE, EVENT;
|
|
115
|
+
|
|
116
|
+
return regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
117
|
+
while (1) {
|
|
118
|
+
switch (_context2.prev = _context2.next) {
|
|
119
|
+
case 0:
|
|
120
|
+
ON_CHANGE_EVENTS = [];
|
|
121
|
+
|
|
122
|
+
ON_CHANGE = function ON_CHANGE(e) {
|
|
123
|
+
ON_CHANGE_EVENTS.push(e);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
COLLECTION = {
|
|
127
|
+
id: ID,
|
|
128
|
+
fieldId: ID,
|
|
129
|
+
type: _models.ComponentTypes.COLLECTION,
|
|
130
|
+
item: [{
|
|
131
|
+
id: TEXT_ID,
|
|
132
|
+
fieldId: TEXT_ID,
|
|
133
|
+
type: _models.ComponentTypes.TEXT,
|
|
134
|
+
label: 'Text component'
|
|
135
|
+
}]
|
|
136
|
+
};
|
|
137
|
+
_renderWithValidation2 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react2.default.createElement(_FormComponent.default, {
|
|
138
|
+
component: COLLECTION,
|
|
139
|
+
value: FORM_DATA[ID],
|
|
140
|
+
formData: FORM_DATA,
|
|
141
|
+
onChange: ON_CHANGE
|
|
142
|
+
})), container = _renderWithValidation2.container; // Get hold of the text input.
|
|
143
|
+
|
|
144
|
+
c = container.childNodes[0];
|
|
145
|
+
item = c.childNodes[0];
|
|
146
|
+
formGroup = item.childNodes[1].childNodes[0];
|
|
147
|
+
input = formGroup.childNodes[2];
|
|
148
|
+
NEW_TEXT_VALUE = 'bravo';
|
|
149
|
+
EVENT = {
|
|
150
|
+
target: {
|
|
151
|
+
name: TEXT_ID,
|
|
152
|
+
value: NEW_TEXT_VALUE
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
_react.fireEvent.change(input, EVENT); // And confirm the formData has been changed.
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
expect(ON_CHANGE_EVENTS.length).toEqual(1);
|
|
160
|
+
expect(ON_CHANGE_EVENTS[0].target.name).toEqual(ID);
|
|
161
|
+
expect(ON_CHANGE_EVENTS[0].target.value[0][TEXT_ID]).toEqual(NEW_TEXT_VALUE);
|
|
162
|
+
|
|
163
|
+
case 14:
|
|
164
|
+
case "end":
|
|
165
|
+
return _context2.stop();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}, _callee2);
|
|
169
|
+
})));
|
|
170
|
+
it('should handle a null value appropriately', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
|
|
171
|
+
var COLLECTION, _renderWithValidation3, container, c, buttonGroup, button;
|
|
172
|
+
|
|
173
|
+
return regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
174
|
+
while (1) {
|
|
175
|
+
switch (_context3.prev = _context3.next) {
|
|
176
|
+
case 0:
|
|
177
|
+
COLLECTION = {
|
|
178
|
+
id: ID,
|
|
179
|
+
fieldId: ID,
|
|
180
|
+
type: _models.ComponentTypes.COLLECTION,
|
|
181
|
+
item: [TEXT_COMPONENT]
|
|
182
|
+
};
|
|
183
|
+
_renderWithValidation3 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react2.default.createElement(_FormComponent.default, {
|
|
184
|
+
component: COLLECTION
|
|
185
|
+
})), container = _renderWithValidation3.container; // Check the container itself.
|
|
186
|
+
|
|
187
|
+
c = container.childNodes[0];
|
|
188
|
+
expect(c.tagName).toEqual('DIV');
|
|
189
|
+
expect(c.classList).toContain(_Collection.DEFAULT_CLASS); // And now make sure it has no children OTHER than the button to add an item.
|
|
190
|
+
|
|
191
|
+
expect(c.childNodes.length).toEqual(1);
|
|
192
|
+
buttonGroup = c.childNodes[0];
|
|
193
|
+
expect(buttonGroup.tagName).toEqual('DIV');
|
|
194
|
+
expect(buttonGroup.classList).toContain('hods-button-group');
|
|
195
|
+
button = buttonGroup.childNodes[0];
|
|
196
|
+
expect(button.tagName).toEqual('BUTTON');
|
|
197
|
+
expect(button.classList).toContain('hods-button');
|
|
198
|
+
expect(button.classList).toContain('hods-button--secondary');
|
|
199
|
+
expect(button.textContent).toContain(_models.CollectionLabels.add);
|
|
200
|
+
|
|
201
|
+
case 14:
|
|
202
|
+
case "end":
|
|
203
|
+
return _context3.stop();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}, _callee3);
|
|
207
|
+
})));
|
|
208
|
+
it('should handle a collection label appropriately', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
|
|
209
|
+
var LABEL, COLLECTION, _renderWithValidation4, container, c, _c$childNodes, title, buttonGroup, button;
|
|
210
|
+
|
|
211
|
+
return regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
212
|
+
while (1) {
|
|
213
|
+
switch (_context4.prev = _context4.next) {
|
|
214
|
+
case 0:
|
|
215
|
+
LABEL = 'Alpha Collection';
|
|
216
|
+
COLLECTION = {
|
|
217
|
+
id: ID,
|
|
218
|
+
fieldId: ID,
|
|
219
|
+
type: _models.ComponentTypes.COLLECTION,
|
|
220
|
+
item: [TEXT_COMPONENT],
|
|
221
|
+
label: LABEL
|
|
222
|
+
};
|
|
223
|
+
_renderWithValidation4 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react2.default.createElement(_FormComponent.default, {
|
|
224
|
+
component: COLLECTION
|
|
225
|
+
})), container = _renderWithValidation4.container; // Check the container itself.
|
|
226
|
+
|
|
227
|
+
c = container.childNodes[0];
|
|
228
|
+
expect(c.tagName).toEqual('DIV');
|
|
229
|
+
expect(c.classList).toContain(_Collection.DEFAULT_CLASS); // And now make sure it has no children OTHER than the button to add an item.
|
|
230
|
+
|
|
231
|
+
expect(c.childNodes.length).toEqual(2);
|
|
232
|
+
_c$childNodes = _slicedToArray(c.childNodes, 2), title = _c$childNodes[0], buttonGroup = _c$childNodes[1];
|
|
233
|
+
expect(title.tagName).toEqual('LABEL');
|
|
234
|
+
expect(title.classList).toContain("".concat(_Collection.DEFAULT_CLASS, "__title"));
|
|
235
|
+
expect(title.getAttribute('for')).toEqual(ID);
|
|
236
|
+
expect(title.textContent).toContain(LABEL);
|
|
237
|
+
expect(buttonGroup.tagName).toEqual('DIV');
|
|
238
|
+
expect(buttonGroup.classList).toContain('hods-button-group');
|
|
239
|
+
button = buttonGroup.childNodes[0];
|
|
240
|
+
expect(button.tagName).toEqual('BUTTON');
|
|
241
|
+
expect(button.classList).toContain('hods-button');
|
|
242
|
+
expect(button.classList).toContain('hods-button--secondary');
|
|
243
|
+
expect(button.textContent).toContain(_models.CollectionLabels.add);
|
|
244
|
+
|
|
245
|
+
case 19:
|
|
246
|
+
case "end":
|
|
247
|
+
return _context4.stop();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}, _callee4);
|
|
251
|
+
})));
|
|
252
|
+
it('should handle the addition and removal of an item', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {
|
|
253
|
+
var COLLECTION, container, c, addButton, item, label, removeButton;
|
|
254
|
+
return regeneratorRuntime.wrap(function _callee6$(_context6) {
|
|
255
|
+
while (1) {
|
|
256
|
+
switch (_context6.prev = _context6.next) {
|
|
257
|
+
case 0:
|
|
258
|
+
COLLECTION = {
|
|
259
|
+
id: ID,
|
|
260
|
+
fieldId: ID,
|
|
261
|
+
type: _models.ComponentTypes.COLLECTION,
|
|
262
|
+
item: [TEXT_COMPONENT]
|
|
263
|
+
};
|
|
264
|
+
container = document.createElement('div');
|
|
265
|
+
document.body.appendChild(container);
|
|
266
|
+
_context6.next = 5;
|
|
267
|
+
return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {
|
|
268
|
+
return regeneratorRuntime.wrap(function _callee5$(_context5) {
|
|
269
|
+
while (1) {
|
|
270
|
+
switch (_context5.prev = _context5.next) {
|
|
271
|
+
case 0:
|
|
272
|
+
(0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react2.default.createElement(_FormComponent.default, {
|
|
273
|
+
component: COLLECTION
|
|
274
|
+
}), container);
|
|
275
|
+
|
|
276
|
+
case 1:
|
|
277
|
+
case "end":
|
|
278
|
+
return _context5.stop();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}, _callee5);
|
|
282
|
+
})));
|
|
283
|
+
|
|
284
|
+
case 5:
|
|
285
|
+
// Check the container itself.
|
|
286
|
+
c = container.childNodes[0];
|
|
287
|
+
expect(c.tagName).toEqual('DIV');
|
|
288
|
+
expect(c.classList).toContain(_Collection.DEFAULT_CLASS); // And now make sure it has no children OTHER than the button to add an item.
|
|
289
|
+
|
|
290
|
+
expect(c.childNodes.length).toEqual(1); // Get hold of that "Add another" button and click it.
|
|
291
|
+
|
|
292
|
+
addButton = c.childNodes[0].childNodes[0];
|
|
293
|
+
|
|
294
|
+
_react.fireEvent.click(addButton, {}); // Make sure an item has been added.
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
expect(c.childNodes.length).toEqual(2);
|
|
298
|
+
item = c.childNodes[0];
|
|
299
|
+
label = item.childNodes[0];
|
|
300
|
+
expect(label.textContent).toContain(_utils.default.interpolateString(_models.CollectionLabels.item, {
|
|
301
|
+
index: 1
|
|
302
|
+
})); // Get hold of the newly-add item's "Remove" button.
|
|
303
|
+
|
|
304
|
+
removeButton = label.childNodes[1];
|
|
305
|
+
expect(removeButton.tagName).toEqual('BUTTON');
|
|
306
|
+
expect(removeButton.classList).toContain('hods-button--secondary');
|
|
307
|
+
expect(removeButton.textContent).toContain(_models.CollectionLabels.remove); // Click the "Remove" button
|
|
308
|
+
|
|
309
|
+
_react.fireEvent.click(removeButton, {}); // Make sure the item has been removed.
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
expect(c.childNodes.length).toEqual(1);
|
|
313
|
+
expect(c.childNodes[0].classList).toContain('hods-button-group');
|
|
314
|
+
|
|
315
|
+
case 22:
|
|
316
|
+
case "end":
|
|
317
|
+
return _context6.stop();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}, _callee6);
|
|
321
|
+
})));
|
|
322
|
+
});
|
|
@@ -246,20 +246,43 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
|
|
|
246
246
|
var onPageAction = function onPageAction(action, patch) {
|
|
247
247
|
// Check to see whether the action is able to proceed, which in
|
|
248
248
|
// in the case of a submission will validate the fields in the page.
|
|
249
|
+
if (action.type === _models.PageAction.TYPES.SUBMIT) {
|
|
250
|
+
if (_helpers.default.canCYASubmit(pages, validate.pages)) {
|
|
251
|
+
// Submit.
|
|
252
|
+
var submissionData = _utils.default.Format.form({
|
|
253
|
+
pages: pages,
|
|
254
|
+
components: components
|
|
255
|
+
}, _objectSpread({}, data), _models.EventTypes.SUBMIT);
|
|
256
|
+
|
|
257
|
+
submissionData.formStatus = _helpers.default.getSubmissionStatus(type, pages, pageId, action, submissionData, currentTask, true);
|
|
258
|
+
setData(submissionData); // Now submit the data to the backend...
|
|
259
|
+
|
|
260
|
+
hooks.onSubmit(action.type, submissionData, function () {
|
|
261
|
+
return hooks.onFormComplete();
|
|
262
|
+
}, function (errors) {
|
|
263
|
+
return _handlers.default.submissionError(errors, addErrors);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
} // Check to see whether the action is able to proceed, which in
|
|
267
|
+
// in the case of a submission will validate the fields in the page.
|
|
268
|
+
|
|
269
|
+
|
|
249
270
|
if (_helpers.default.canActionProceed(action, formState.page, validate.page)) {
|
|
271
|
+
patch = _helpers.default.cleanHiddenNestedData(patch, formState.page);
|
|
272
|
+
|
|
250
273
|
if (action.type === _models.PageAction.TYPES.NAVIGATE) {
|
|
251
274
|
_handlers.default.navigate(action, pageId, onPageChange);
|
|
252
275
|
} else {
|
|
253
276
|
// Save draft or submit.
|
|
254
|
-
var
|
|
277
|
+
var _submissionData = _utils.default.Format.form({
|
|
255
278
|
pages: pages,
|
|
256
279
|
components: components
|
|
257
280
|
}, _objectSpread(_objectSpread({}, data), patch), _models.EventTypes.SUBMIT);
|
|
258
281
|
|
|
259
|
-
|
|
282
|
+
_submissionData.formStatus = _helpers.default.getSubmissionStatus(type, pages, pageId, action, _submissionData, currentTask, true);
|
|
260
283
|
|
|
261
284
|
if (patch) {
|
|
262
|
-
setData(
|
|
285
|
+
setData(_submissionData);
|
|
263
286
|
}
|
|
264
287
|
|
|
265
288
|
var pageUpdate = function pageUpdate(next) {
|
|
@@ -275,10 +298,10 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
|
|
|
275
298
|
} // Now submit the data to the backend...
|
|
276
299
|
|
|
277
300
|
|
|
278
|
-
hooks.onSubmit(action.type,
|
|
301
|
+
hooks.onSubmit(action.type, _submissionData, function (response) {
|
|
279
302
|
// The backend response may well contain data we need so apply it...
|
|
280
303
|
// ... but this needs to happen in a useEffect, not right away.
|
|
281
|
-
var sData = _objectSpread(_objectSpread({},
|
|
304
|
+
var sData = _objectSpread(_objectSpread({}, _submissionData), response);
|
|
282
305
|
|
|
283
306
|
setSubmitted({
|
|
284
307
|
data: sData
|
|
@@ -341,14 +364,14 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
|
|
|
341
364
|
|
|
342
365
|
if (action.type === _models.PageAction.TYPES.SAVE_AND_CONTINUE && hub === _models.HubFormats.TASK) {
|
|
343
366
|
if (_helpers.default.canCYASubmit(currentTask.fullPages, validate.pages)) {
|
|
344
|
-
var
|
|
367
|
+
var _submissionData2 = _utils.default.Format.form({
|
|
345
368
|
pages: pages,
|
|
346
369
|
components: components
|
|
347
370
|
}, _objectSpread({}, data), _models.EventTypes.SUBMIT);
|
|
348
371
|
|
|
349
|
-
|
|
350
|
-
setData(
|
|
351
|
-
hooks.onSubmit(action.type,
|
|
372
|
+
_submissionData2.formStatus = _helpers.default.getSubmissionStatus(type, pages, pageId, action, _submissionData2, currentTask, true);
|
|
373
|
+
setData(_submissionData2);
|
|
374
|
+
hooks.onSubmit(action.type, _submissionData2, function () {
|
|
352
375
|
return onPageChange(_models.FormPages.HUB);
|
|
353
376
|
}, function (errors) {
|
|
354
377
|
return _handlers.default.submissionError(errors, addErrors);
|
|
@@ -358,14 +381,14 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
|
|
|
358
381
|
|
|
359
382
|
if (action.type === _models.PageAction.TYPES.SAVE_AND_RETURN) {
|
|
360
383
|
if (_helpers.default.canCYASubmit(currentTask.fullPages, validate.pages)) {
|
|
361
|
-
var
|
|
384
|
+
var _submissionData3 = _utils.default.Format.form({
|
|
362
385
|
pages: pages,
|
|
363
386
|
components: components
|
|
364
387
|
}, _objectSpread({}, data), _models.EventTypes.SUBMIT);
|
|
365
388
|
|
|
366
|
-
|
|
367
|
-
setData(
|
|
368
|
-
hooks.onSubmit(action.type,
|
|
389
|
+
_submissionData3.formStatus = _helpers.default.getSubmissionStatus(type, pages, pageId, action, _submissionData3, currentTask);
|
|
390
|
+
setData(_submissionData3);
|
|
391
|
+
hooks.onSubmit(action.type, _submissionData3, function () {
|
|
369
392
|
if (type === _models.FormTypes.TASK) {
|
|
370
393
|
onPageChange(undefined);
|
|
371
394
|
} else {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var parentComponents = ['radios'];
|
|
8
|
+
|
|
9
|
+
var cleanHiddenNestedData = function cleanHiddenNestedData(patch, page) {
|
|
10
|
+
page.components.forEach(function (component) {
|
|
11
|
+
if (!parentComponents.includes(component.type)) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
var idsToDelete = getIdsToDelete(component, patch[component.id]);
|
|
16
|
+
idsToDelete.forEach(function (id) {
|
|
17
|
+
delete patch[id];
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
return patch;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function getIdsToDelete(component, selectedValue) {
|
|
24
|
+
var _component$data, _component$data$optio;
|
|
25
|
+
|
|
26
|
+
var idsToDelete = [];
|
|
27
|
+
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) {
|
|
28
|
+
if (option.value !== selectedValue && option.nested) {
|
|
29
|
+
option.nested.forEach(function (nested) {
|
|
30
|
+
idsToDelete.push(nested.id);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return idsToDelete;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var _default = cleanHiddenNestedData;
|
|
38
|
+
exports.default = _default;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _cleanHiddenNestedData = _interopRequireDefault(require("./cleanHiddenNestedData"));
|
|
4
|
+
|
|
5
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
6
|
+
|
|
7
|
+
// Local imports
|
|
8
|
+
describe('components', function () {
|
|
9
|
+
describe('FormRenderer', function () {
|
|
10
|
+
describe('helpers', function () {
|
|
11
|
+
describe('cleanHiddenNestedData', function () {
|
|
12
|
+
it('remove data corresponding to hidden nested components', function () {
|
|
13
|
+
var patch = {
|
|
14
|
+
parent: 'option2',
|
|
15
|
+
nested1: 'should not be included',
|
|
16
|
+
nested2: 'should be included'
|
|
17
|
+
};
|
|
18
|
+
var page = {
|
|
19
|
+
id: 'page',
|
|
20
|
+
name: 'page',
|
|
21
|
+
title: 'Page',
|
|
22
|
+
components: [{
|
|
23
|
+
id: 'parent',
|
|
24
|
+
fieldId: 'parent',
|
|
25
|
+
type: 'radios',
|
|
26
|
+
data: {
|
|
27
|
+
options: [{
|
|
28
|
+
value: 'option1',
|
|
29
|
+
nested: [{
|
|
30
|
+
id: 'nested1',
|
|
31
|
+
fieldId: 'nested1'
|
|
32
|
+
}]
|
|
33
|
+
}, {
|
|
34
|
+
value: 'option2',
|
|
35
|
+
nested: [{
|
|
36
|
+
id: 'nested2',
|
|
37
|
+
fieldId: 'nested2'
|
|
38
|
+
}]
|
|
39
|
+
}]
|
|
40
|
+
}
|
|
41
|
+
}]
|
|
42
|
+
};
|
|
43
|
+
var updatedPatch = (0, _cleanHiddenNestedData.default)(patch, page);
|
|
44
|
+
expect(updatedPatch['nested1']).toBeFalsy();
|
|
45
|
+
expect(updatedPatch['nested2']).toBeTruthy();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -9,6 +9,8 @@ var _canActionProceed = _interopRequireDefault(require("./canActionProceed"));
|
|
|
9
9
|
|
|
10
10
|
var _canCYASubmit = _interopRequireDefault(require("./canCYASubmit"));
|
|
11
11
|
|
|
12
|
+
var _cleanHiddenNestedData = _interopRequireDefault(require("./cleanHiddenNestedData"));
|
|
13
|
+
|
|
12
14
|
var _getFormState = _interopRequireDefault(require("./getFormState"));
|
|
13
15
|
|
|
14
16
|
var _getNextPageId = _interopRequireDefault(require("./getNextPageId"));
|
|
@@ -25,6 +27,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
25
27
|
var helpers = {
|
|
26
28
|
canActionProceed: _canActionProceed.default,
|
|
27
29
|
canCYASubmit: _canCYASubmit.default,
|
|
30
|
+
cleanHiddenNestedData: _cleanHiddenNestedData.default,
|
|
28
31
|
getFormState: _getFormState.default,
|
|
29
32
|
getNextPageId: _getNextPageId.default,
|
|
30
33
|
getPage: _getPage.default,
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
4
|
+
|
|
3
5
|
Object.defineProperty(exports, "__esModule", {
|
|
4
6
|
value: true
|
|
5
7
|
});
|
|
6
8
|
exports.default = exports.HooksContext = exports.ALLOWED_HOOKS = void 0;
|
|
7
9
|
|
|
8
|
-
var _react = require("react");
|
|
10
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
+
|
|
12
|
+
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); }
|
|
13
|
+
|
|
14
|
+
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; }
|
|
9
15
|
|
|
10
16
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
11
17
|
|
|
@@ -78,7 +84,7 @@ var HooksContextProvider = function HooksContextProvider(_ref) {
|
|
|
78
84
|
}
|
|
79
85
|
};
|
|
80
86
|
|
|
81
|
-
return /*#__PURE__*/
|
|
87
|
+
return /*#__PURE__*/_react.default.createElement(HooksContext.Provider, {
|
|
82
88
|
value: {
|
|
83
89
|
hooks: hooks,
|
|
84
90
|
addHook: addHook,
|
|
@@ -49,7 +49,9 @@ var setNestedValue = function setNestedValue(component, page) {
|
|
|
49
49
|
(_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, index) {
|
|
50
50
|
//check if option is selected and has nested component
|
|
51
51
|
if (page.formData[component.id] === option.value && option.nested) {
|
|
52
|
-
|
|
52
|
+
option.nested.forEach(function (child) {
|
|
53
|
+
child.value = page.formData[child.id];
|
|
54
|
+
});
|
|
53
55
|
}
|
|
54
56
|
});
|
|
55
57
|
};
|
|
@@ -162,14 +162,14 @@ describe('utils', function () {
|
|
|
162
162
|
data: {
|
|
163
163
|
options: [{
|
|
164
164
|
value: SELECTED_VALUE,
|
|
165
|
-
nested: {
|
|
165
|
+
nested: [{
|
|
166
166
|
id: NESTED_ID
|
|
167
|
-
}
|
|
167
|
+
}]
|
|
168
168
|
}]
|
|
169
169
|
}
|
|
170
170
|
};
|
|
171
171
|
var ROW = (0, _getCYARow.default)(PAGE, COMPONENT, function () {});
|
|
172
|
-
expect(ROW.component.data.options[0].nested.value).toEqual(NESTED_VALUE);
|
|
172
|
+
expect(ROW.component.data.options[0].nested[0].value).toEqual(NESTED_VALUE);
|
|
173
173
|
});
|
|
174
174
|
});
|
|
175
175
|
});
|
|
@@ -19,7 +19,7 @@ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToAr
|
|
|
19
19
|
|
|
20
20
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
21
21
|
|
|
22
|
-
var JSON_ONLY_PROPERTIES = ['source', 'use', 'show_when', 'options', 'additionalValidation', 'full_path', '
|
|
22
|
+
var JSON_ONLY_PROPERTIES = ['source', 'use', 'show_when', 'options', 'additionalValidation', 'full_path', 'formData'];
|
|
23
23
|
/**
|
|
24
24
|
* This method removes and properties that are entirely specific to the JSON
|
|
25
25
|
* configuration and that should not be used as HTML attributes.
|