@ukhomeoffice/cop-react-form-renderer 5.94.0 → 5.95.0

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.
@@ -31,7 +31,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } // Global
31
31
  // Styles
32
32
  var DEFAULT_CLASS = exports.DEFAULT_CLASS = 'hods-form__page';
33
33
  var FormPage = function FormPage(_ref) {
34
- var _formPage$actions, _page$actions;
34
+ var _page$customValidatio, _formPage$actions, _page$actions;
35
35
  var page = _ref.page,
36
36
  pages = _ref.pages,
37
37
  _onAction = _ref.onAction,
@@ -42,17 +42,33 @@ var FormPage = function FormPage(_ref) {
42
42
  classBlock = _ref.classBlock,
43
43
  classModifiers = _ref.classModifiers,
44
44
  className = _ref.className,
45
- submitting = _ref.submitting;
45
+ submitting = _ref.submitting,
46
+ pageId = _ref.pageId,
47
+ fromTarget = _ref.fromTarget;
46
48
  var _useState = (0, _react.useState)({}),
47
49
  _useState2 = _slicedToArray(_useState, 2),
48
50
  patch = _useState2[0],
49
51
  setPatch = _useState2[1];
50
52
  var _useValidation = (0, _hooks.useValidation)(),
51
- errors = _useValidation.errors;
53
+ errors = _useValidation.errors,
54
+ validate = _useValidation.validate;
52
55
  var _useState3 = (0, _react.useState)({}),
53
56
  _useState4 = _slicedToArray(_useState3, 2),
54
57
  patchLabel = _useState4[0],
55
58
  setPatchLabel = _useState4[1];
59
+ var _useState5 = (0, _react.useState)(false),
60
+ _useState6 = _slicedToArray(_useState5, 2),
61
+ isPageRendered = _useState6[0],
62
+ setIsPageRendered = _useState6[1];
63
+ var runOnLoad = Array.isArray(page === null || page === void 0 ? void 0 : page.customValidation) && page.customValidation.length > 0 ? ((_page$customValidatio = page.customValidation[0]) === null || _page$customValidatio === void 0 || (_page$customValidatio = _page$customValidatio.runWhen) === null || _page$customValidatio === void 0 ? void 0 : _page$customValidatio.onLoad) === true : false;
64
+ (0, _react.useEffect)(function () {
65
+ setIsPageRendered(true);
66
+ }, []);
67
+ (0, _react.useEffect)(function () {
68
+ if (isPageRendered && fromTarget && runOnLoad) {
69
+ validate.page(page);
70
+ }
71
+ }, [pageId, isPageRendered]);
56
72
 
57
73
  /**
58
74
  * Handle the state of the data directly within the page.
@@ -121,11 +137,20 @@ var FormPage = function FormPage(_ref) {
121
137
  submitting: submitting
122
138
  });
123
139
  });
140
+ var errorMessages = null;
141
+ if (runOnLoad && (errors === null || errors === void 0 ? void 0 : errors.length) > 0) {
142
+ var _page$customValidatio2;
143
+ errorMessages = [{
144
+ error: page === null || page === void 0 || (_page$customValidatio2 = page.customValidation) === null || _page$customValidatio2 === void 0 || (_page$customValidatio2 = _page$customValidatio2[0]) === null || _page$customValidatio2 === void 0 ? void 0 : _page$customValidatio2.message
145
+ }];
146
+ } else if ((errors === null || errors === void 0 ? void 0 : errors.length) > 0 && !runOnLoad) {
147
+ errorMessages = errors;
148
+ }
124
149
  return /*#__PURE__*/_react.default.createElement("div", {
125
150
  className: classes(),
126
151
  key: page.id
127
- }, (errors === null || errors === void 0 ? void 0 : errors.length) > 0 && /*#__PURE__*/_react.default.createElement(_copReactComponents.ErrorSummary, {
128
- errors: errors,
152
+ }, errorMessages && /*#__PURE__*/_react.default.createElement(_copReactComponents.ErrorSummary, {
153
+ errors: errorMessages,
129
154
  hashLink: hashLink
130
155
  }), page.fieldset && /*#__PURE__*/_react.default.createElement("fieldset", {
131
156
  className: "govuk-fieldset"
@@ -162,10 +187,18 @@ FormPage.propTypes = {
162
187
  label: _propTypes.default.string,
163
188
  required: _propTypes.default.bool,
164
189
  actions: _propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.shape({}), _propTypes.default.string])),
165
- formData: _propTypes.default.shape({}).isRequired
190
+ formData: _propTypes.default.shape({}).isRequired,
191
+ customValidation: _propTypes.default.arrayOf(_propTypes.default.shape({
192
+ runWhen: _propTypes.default.shape({
193
+ onLoad: _propTypes.default.bool
194
+ }).isRequired,
195
+ message: _propTypes.default.string.isRequired
196
+ }))
166
197
  }).isRequired,
167
198
  pages: _propTypes.default.arrayOf(_propTypes.default.shape({})),
168
- submitting: _propTypes.default.bool
199
+ submitting: _propTypes.default.bool,
200
+ fromTarget: _propTypes.default.bool,
201
+ pageId: _propTypes.default.string.isRequired
169
202
  };
170
203
  FormPage.defaultProps = {
171
204
  classBlock: DEFAULT_CLASS,
@@ -176,6 +209,7 @@ FormPage.defaultProps = {
176
209
  onTopLevelChange: undefined,
177
210
  onWrapperChange: undefined,
178
211
  pages: [],
179
- submitting: false
212
+ submitting: false,
213
+ fromTarget: false
180
214
  };
181
215
  var _default = exports.default = FormPage;
@@ -2,6 +2,7 @@
2
2
 
3
3
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
4
  var _react = require("@testing-library/react");
5
+ require("@testing-library/jest-dom");
5
6
  var _react2 = _interopRequireDefault(require("react"));
6
7
  var _models = require("../../models");
7
8
  var _setupTests = require("../../setupTests");
@@ -53,6 +54,30 @@ describe('components.FormPage', function () {
53
54
  text: VALUE
54
55
  }
55
56
  };
57
+ var PAGE_WITH_CUSTOM_VALIDATION = {
58
+ id: 'pageId',
59
+ title: 'Page with Custom Validation',
60
+ components: [TEXT],
61
+ actions: [_models.PageAction.TYPES.SUBMIT],
62
+ formData: {
63
+ text: VALUE
64
+ },
65
+ customValidation: [{
66
+ message: 'Custom validation failed',
67
+ runWhen: {
68
+ onLoad: true
69
+ }
70
+ }]
71
+ };
72
+ var PAGE_WITHOUT_CUSTOM_VALIDATION = {
73
+ id: 'pageId',
74
+ title: 'Page without Custom Validation',
75
+ components: [TEXT],
76
+ actions: [_models.PageAction.TYPES.SUBMIT],
77
+ formData: {
78
+ text: VALUE
79
+ }
80
+ };
56
81
  var PAGE_WITH_BUTTON_ACTIONS = {
57
82
  id: 'pageId',
58
83
  // eslint-disable-next-line no-template-curly-in-string
@@ -328,5 +353,41 @@ describe('components.FormPage', function () {
328
353
  }
329
354
  }, _callee5);
330
355
  })));
356
+ it('should not trigger custom validation when fromTarget is false', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
357
+ var _renderWithValidation6, queryByText;
358
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
359
+ while (1) switch (_context6.prev = _context6.next) {
360
+ case 0:
361
+ _renderWithValidation6 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react2.default.createElement(_FormPage.default, {
362
+ page: PAGE_WITH_CUSTOM_VALIDATION,
363
+ fromTarget: false,
364
+ onAction: ON_ACTION
365
+ })), queryByText = _renderWithValidation6.queryByText;
366
+ _context6.next = 3;
367
+ return (0, _react.waitFor)(function () {
368
+ expect(queryByText('Custom validation failed')).toBeNull();
369
+ });
370
+ case 3:
371
+ case "end":
372
+ return _context6.stop();
373
+ }
374
+ }, _callee6);
375
+ })));
376
+ it('should not trigger custom validation if no customValidation is provided', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
377
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
378
+ while (1) switch (_context7.prev = _context7.next) {
379
+ case 0:
380
+ (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react2.default.createElement(_FormPage.default, {
381
+ page: PAGE_WITHOUT_CUSTOM_VALIDATION,
382
+ fromTarget: true,
383
+ onAction: ON_ACTION
384
+ }));
385
+ expect(ON_ACTION_CALLS.length).toEqual(0);
386
+ case 2:
387
+ case "end":
388
+ return _context7.stop();
389
+ }
390
+ }, _callee7);
391
+ })));
331
392
  });
332
393
  });
@@ -60,7 +60,8 @@ var FormRenderer = function FormRenderer(_ref) {
60
60
  noChangeAction = _ref.noChangeAction,
61
61
  newPageId = _ref.newPageId,
62
62
  viewOnly = _ref.viewOnly,
63
- hideBlankRows = _ref.hideBlankRows;
63
+ hideBlankRows = _ref.hideBlankRows,
64
+ fromTarget = _ref.fromTarget;
64
65
  return /*#__PURE__*/_react.default.createElement(_context.HooksContextProvider, {
65
66
  overrides: hooks
66
67
  }, /*#__PURE__*/_react.default.createElement(_context.ValidationContextProvider, null, /*#__PURE__*/_react.default.createElement(InternalFormRenderer, {
@@ -80,7 +81,8 @@ var FormRenderer = function FormRenderer(_ref) {
80
81
  noChangeAction: noChangeAction,
81
82
  newPageId: newPageId,
82
83
  viewOnly: viewOnly,
83
- hideBlankRows: hideBlankRows
84
+ hideBlankRows: hideBlankRows,
85
+ fromTarget: fromTarget
84
86
  })));
85
87
  };
86
88
  var DEFAULT_CLASS = exports.DEFAULT_CLASS = 'hods-form';
@@ -102,7 +104,8 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
102
104
  noChangeAction = _ref2.noChangeAction,
103
105
  newPageId = _ref2.newPageId,
104
106
  viewOnly = _ref2.viewOnly,
105
- hideBlankRows = _ref2.hideBlankRows;
107
+ hideBlankRows = _ref2.hideBlankRows,
108
+ fromTarget = _ref2.fromTarget;
106
109
  // Set up the initial states.
107
110
  var _useState = (0, _react.useState)({}),
108
111
  _useState2 = _slicedToArray(_useState, 2),
@@ -364,7 +367,9 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
364
367
  hashLink: hashLink,
365
368
  classModifiers: formState.page.classModifiers,
366
369
  className: formState.page.className,
367
- submitting: submitting
370
+ submitting: submitting,
371
+ pageId: pageId,
372
+ fromTarget: fromTarget
368
373
  }), formState.page && !formState.cya && formState.page.collection && /*#__PURE__*/_react.default.createElement(_CollectionPage.default, {
369
374
  page: formState.page,
370
375
  pages: pages,
@@ -407,7 +412,8 @@ var propTypes = {
407
412
  /** See <a href="/?path=/docs/f-json--page#formtypes">FormTypes</a>. */
408
413
  type: _propTypes.default.oneOf([_models.FormTypes.CYA, _models.FormTypes.FORM, _models.FormTypes.HUB, _models.FormTypes.TASK, _models.FormTypes.WIZARD, _models.FormTypes.TASK_CYA, _models.FormTypes.FORM_WITH_TASK]).isRequired,
409
414
  viewOnly: _propTypes.default.bool,
410
- hideBlankRows: _propTypes.default.bool
415
+ hideBlankRows: _propTypes.default.bool,
416
+ fromTarget: _propTypes.default.bool.isRequired
411
417
  };
412
418
  var defaultProps = {
413
419
  classBlock: DEFAULT_CLASS,
@@ -215,6 +215,9 @@ var getCYARowsForCollectionPage = function getCYARowsForCollectionPage(page, onA
215
215
  }
216
216
  collectionData.forEach(function (item) {
217
217
  var _page$collection2;
218
+ if (!item) {
219
+ return; // Skip this iteration if item is undefined
220
+ }
218
221
  // Keep track of the active entry in each collection.
219
222
  // This helps us make sure the right entry is being affected
220
223
  // by change/remove links.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ukhomeoffice/cop-react-form-renderer",
3
- "version": "5.94.0",
3
+ "version": "5.95.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "clean": "rimraf dist",