@ukhomeoffice/cop-react-form-renderer 1.0.0-delta → 2.0.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.
Files changed (65) hide show
  1. package/dist/components/CheckYourAnswers/CheckYourAnswers.js +32 -6
  2. package/dist/components/CheckYourAnswers/CheckYourAnswers.stories.mdx +53 -4
  3. package/dist/components/CheckYourAnswers/CheckYourAnswers.test.js +17 -2
  4. package/dist/components/FormPage/FormPage.js +8 -2
  5. package/dist/components/FormPage/FormPage.test.js +3 -3
  6. package/dist/components/FormRenderer/FormRenderer.js +54 -9
  7. package/dist/components/FormRenderer/FormRenderer.stories.mdx +35 -10
  8. package/dist/components/FormRenderer/FormRenderer.test.js +24 -22
  9. package/dist/components/FormRenderer/handlers/getPageId.js +1 -10
  10. package/dist/components/FormRenderer/handlers/getPageId.test.js +5 -31
  11. package/dist/components/FormRenderer/handlers/handlers.test.js +2 -2
  12. package/dist/components/FormRenderer/helpers/getNextPageId.js +33 -26
  13. package/dist/components/FormRenderer/helpers/getNextPageId.test.js +89 -7
  14. package/dist/components/FormRenderer/helpers/getSubmissionStatus.js +27 -0
  15. package/dist/components/FormRenderer/helpers/getSubmissionStatus.test.js +209 -0
  16. package/dist/components/FormRenderer/helpers/index.js +4 -1
  17. package/dist/components/PageActions/ActionButton.test.js +1 -1
  18. package/dist/components/PageActions/PageActions.stories.mdx +1 -1
  19. package/dist/components/PageActions/PageActions.test.js +5 -5
  20. package/dist/components/SummaryList/RowAction.js +1 -1
  21. package/dist/components/SummaryList/RowAction.test.js +6 -6
  22. package/dist/components/SummaryList/SummaryList.js +1 -1
  23. package/dist/components/SummaryList/helpers/getRowActionAttributes.js +2 -2
  24. package/dist/components/SummaryList/helpers/getRowActionAttributes.test.js +4 -4
  25. package/dist/components/index.js +8 -0
  26. package/dist/json/areYouACivilServant.json +7 -0
  27. package/dist/json/firstForm.json +94 -0
  28. package/dist/json/grade.json +108 -0
  29. package/dist/json/saveAndContinue.json +98 -0
  30. package/dist/json/team.json +17351 -0
  31. package/dist/json/userProfile.data.json +14 -0
  32. package/dist/json/userProfile.json +276 -0
  33. package/dist/models/ComponentTypes.js +7 -1
  34. package/dist/models/PageAction.js +9 -7
  35. package/dist/utils/CheckYourAnswers/getCYAAction.js +24 -3
  36. package/dist/utils/CheckYourAnswers/getCYAAction.test.js +62 -15
  37. package/dist/utils/CheckYourAnswers/getCYARow.js +8 -2
  38. package/dist/utils/CheckYourAnswers/getCYARowsForPage.js +11 -5
  39. package/dist/utils/Component/getComponent.js +32 -0
  40. package/dist/utils/Component/getComponentTests/getComponent.autocomplete.test.js +75 -0
  41. package/dist/utils/Component/getComponentTests/getComponent.checkboxes.test.js +129 -0
  42. package/dist/utils/Component/getComponentTests/getComponent.date.test.js +129 -0
  43. package/dist/utils/Component/getComponentTests/getComponent.email.test.js +80 -0
  44. package/dist/utils/Component/getComponentTests/getComponent.heading.test.js +33 -0
  45. package/dist/utils/Component/getComponentTests/getComponent.html.test.js +45 -0
  46. package/dist/utils/Component/getComponentTests/getComponent.insetText.test.js +31 -0
  47. package/dist/utils/Component/getComponentTests/getComponent.phoneNumber.test.js +80 -0
  48. package/dist/utils/Component/getComponentTests/getComponent.radios.test.js +125 -0
  49. package/dist/utils/Component/getComponentTests/getComponent.text.test.js +80 -0
  50. package/dist/utils/Component/getComponentTests/getComponent.textarea.test.js +76 -0
  51. package/dist/utils/Component/getComponentTests/getComponent.unknown.test.js +14 -0
  52. package/dist/utils/Component/isEditable.js +1 -1
  53. package/dist/utils/Data/refDataToOptions.js +4 -0
  54. package/dist/utils/Data/refDataToOptions.test.js +30 -0
  55. package/dist/utils/FormPage/getEditableComponents.js +28 -0
  56. package/dist/utils/FormPage/getEditableComponents.test.js +75 -0
  57. package/dist/utils/FormPage/getFormPage.js +5 -1
  58. package/dist/utils/FormPage/getPageActions.js +66 -0
  59. package/dist/utils/FormPage/getPageActions.test.js +89 -0
  60. package/dist/utils/FormPage/index.js +7 -1
  61. package/dist/utils/FormPage/showFormPage.js +81 -0
  62. package/dist/utils/FormPage/showFormPage.test.js +131 -0
  63. package/dist/utils/Validate/validateComponent.js +4 -2
  64. package/package.json +9 -5
  65. package/dist/utils/Component/getComponent.test.js +0 -329
@@ -15,6 +15,8 @@ var _react = _interopRequireWildcard(require("react"));
15
15
 
16
16
  var _utils = _interopRequireDefault(require("../../utils"));
17
17
 
18
+ var _PageActions = _interopRequireDefault(require("../PageActions"));
19
+
18
20
  var _SummaryList = _interopRequireDefault(require("../SummaryList"));
19
21
 
20
22
  var _Answer = _interopRequireDefault(require("./Answer"));
@@ -55,17 +57,25 @@ exports.DEFAULT_MARGIN_BOTTOM = DEFAULT_MARGIN_BOTTOM;
55
57
  var CheckYourAnswers = function CheckYourAnswers(_ref) {
56
58
  var title = _ref.title,
57
59
  _pages = _ref.pages,
60
+ actions = _ref.actions,
61
+ _onAction = _ref.onAction,
62
+ onRowAction = _ref.onRowAction,
58
63
  hide_page_titles = _ref.hide_page_titles,
59
- onAction = _ref.onAction;
64
+ hide_actions = _ref.hide_actions;
60
65
 
61
66
  var _useState = (0, _react.useState)([]),
62
67
  _useState2 = _slicedToArray(_useState, 2),
63
68
  pages = _useState2[0],
64
69
  setPages = _useState2[1];
65
70
 
71
+ var _useState3 = (0, _react.useState)([]),
72
+ _useState4 = _slicedToArray(_useState3, 2),
73
+ errors = _useState4[0],
74
+ setErrors = _useState4[1];
75
+
66
76
  (0, _react.useEffect)(function () {
67
77
  var getRows = function getRows(page, pageIndex) {
68
- var rows = _utils.default.CheckYourAnswers.getRows(page, onAction);
78
+ var rows = _utils.default.CheckYourAnswers.getRows(page, onRowAction);
69
79
 
70
80
  return rows.map(function (row, index) {
71
81
  return _objectSpread(_objectSpread({}, row), {}, {
@@ -86,18 +96,24 @@ var CheckYourAnswers = function CheckYourAnswers(_ref) {
86
96
  }).filter(function (p) {
87
97
  return !!p;
88
98
  }));
89
- }, [_pages, onAction, setPages]);
99
+ }, [_pages, onRowAction, setPages]);
90
100
  var listMarginBottom = hide_page_titles ? 0 : DEFAULT_MARGIN_BOTTOM;
91
101
 
92
102
  var isLastPage = function isLastPage(index) {
93
103
  return index === pages.length - 1;
94
104
  };
95
105
 
106
+ var onError = function onError(errors) {
107
+ setErrors(errors);
108
+ };
109
+
96
110
  return /*#__PURE__*/_react.default.createElement("div", {
97
111
  className: DEFAULT_CLASS
98
112
  }, title && /*#__PURE__*/_react.default.createElement(_copReactComponents.LargeHeading, {
99
113
  key: "heading"
100
- }, title), pages && pages.map(function (page, pageIndex) {
114
+ }, title), errors && errors.length > 0 && /*#__PURE__*/_react.default.createElement(_copReactComponents.ErrorSummary, {
115
+ errors: errors
116
+ }), pages && pages.map(function (page, pageIndex) {
101
117
  var pageMarginBottom = isLastPage(pageIndex) ? DEFAULT_MARGIN_BOTTOM : listMarginBottom;
102
118
  var className = "govuk-!-margin-bottom-".concat(pageMarginBottom);
103
119
  return /*#__PURE__*/_react.default.createElement(_react.Fragment, {
@@ -106,17 +122,27 @@ var CheckYourAnswers = function CheckYourAnswers(_ref) {
106
122
  className: className,
107
123
  rows: page.rows
108
124
  }));
125
+ }), !hide_actions && /*#__PURE__*/_react.default.createElement(_PageActions.default, {
126
+ actions: actions,
127
+ onAction: function onAction(action) {
128
+ return _onAction(action, onError);
129
+ }
109
130
  }));
110
131
  };
111
132
 
112
133
  CheckYourAnswers.propTypes = {
113
134
  title: _propTypes.default.string.isRequired,
114
135
  pages: _propTypes.default.arrayOf(_propTypes.default.object).isRequired,
115
- hide_page_titles: _propTypes.default.bool
136
+ actions: _propTypes.default.arrayOf(_propTypes.default.object),
137
+ onAction: _propTypes.default.func.isRequired,
138
+ onRowAction: _propTypes.default.func.isRequired,
139
+ hide_page_titles: _propTypes.default.bool,
140
+ hide_actions: _propTypes.default.bool
116
141
  };
117
142
  CheckYourAnswers.defaultProps = {
118
143
  title: DEFAULT_TITLE,
119
- hide_page_titles: false
144
+ hide_page_titles: false,
145
+ hide_actions: false
120
146
  };
121
147
  var _default = CheckYourAnswers;
122
148
  exports.default = _default;
@@ -13,6 +13,7 @@ import GRADE from '../../json/grade.json';
13
13
  import TEAMS from '../../json/team.json';
14
14
  import USER_PROFILE_DATA from '../../json/userProfile.data.json';
15
15
  import USER_PROFILE from '../../json/userProfile.json';
16
+ import FIRST_FORM from '../../json/firstForm.json';
16
17
 
17
18
  <Meta title="Components/Check your answers" id="D-CheckYourAnswers" component={ CheckYourAnswers } decorators={[withMock]} />
18
19
 
@@ -44,13 +45,16 @@ Renders the **Check your answers** screen for a form.
44
45
  ]
45
46
  }}>
46
47
  {() => {
47
- const DATA = Utils.Data.setupForm(USER_PROFILE.pages, USER_PROFILE.components, USER_PROFILE_DATA)
48
+ const DATA = Utils.Data.setupForm(USER_PROFILE.pages, USER_PROFILE.components, USER_PROFILE_DATA);
48
49
  const PAGES = Utils.FormPage.getAll(USER_PROFILE.pages, USER_PROFILE.components, { ...DATA });
49
50
  const ON_ACTION = (action, patch, onError) => {
50
51
  console.log('action invoked', action, patch);
51
52
  };
53
+ const ON_ROW_ACTION = (page) => {
54
+ console.log('row action invoked', page);
55
+ };
52
56
  return (
53
- <CheckYourAnswers pages={PAGES} onAction={ON_ACTION} />
57
+ <CheckYourAnswers pages={PAGES} onAction={ON_ACTION} onRowAction={ON_ROW_ACTION} />
54
58
  );
55
59
  }}
56
60
  </Story>
@@ -87,13 +91,58 @@ Renders the **Check your answers** screen for a form.
87
91
  ]
88
92
  }}>
89
93
  {() => {
90
- const DATA = Utils.Data.setupForm(USER_PROFILE.pages, USER_PROFILE.components, USER_PROFILE_DATA)
94
+ const DATA = Utils.Data.setupForm(USER_PROFILE.pages, USER_PROFILE.components, USER_PROFILE_DATA);
91
95
  const PAGES = Utils.FormPage.getAll(USER_PROFILE.pages, USER_PROFILE.components, { ...DATA });
92
96
  const ON_ACTION = (action, patch, onError) => {
93
97
  console.log('action invoked', action, patch);
94
98
  };
99
+ const ON_ROW_ACTION = (page) => {
100
+ console.log('row action invoked', page);
101
+ };
102
+ return (
103
+ <CheckYourAnswers pages={PAGES} hide_page_titles={true} onAction={ON_ACTION} onRowAction={ON_ROW_ACTION} />
104
+ );
105
+ }}
106
+ </Story>
107
+ </Canvas>
108
+
109
+ ### With actions
110
+
111
+ <Canvas>
112
+ <Story name="With actions" parameters={{
113
+ mockData: [
114
+ {
115
+ url: `${USER_PROFILE_DATA.urls.refData}/areYouACivilServant`,
116
+ method: 'GET',
117
+ status: 200,
118
+ response: CIVIL_SERVANT
119
+ },
120
+ {
121
+ url: `${USER_PROFILE_DATA.urls.refData}/grade`,
122
+ method: 'GET',
123
+ status: 200,
124
+ response: GRADE
125
+ },
126
+ {
127
+ url: `${USER_PROFILE_DATA.urls.refData}/team`,
128
+ method: 'GET',
129
+ status: 200,
130
+ response: TEAMS
131
+ }
132
+ ]
133
+ }}>
134
+ {() => {
135
+ const DATA = { firstName: 'John', surname: 'Smith', age: 41 };
136
+ const PAGES = Utils.FormPage.getAll(FIRST_FORM.pages, FIRST_FORM.components, { ...DATA });
137
+ const ACTIONS = FIRST_FORM.cya.actions;
138
+ const ON_ACTION = (action, patch, onError) => {
139
+ console.log('action invoked', action, patch);
140
+ };
141
+ const ON_ROW_ACTION = (page) => {
142
+ console.log('row action invoked', page);
143
+ };
95
144
  return (
96
- <CheckYourAnswers pages={PAGES} hide_page_titles={true} onAction={ON_ACTION} />
145
+ <CheckYourAnswers pages={PAGES} hide_page_titles={true} actions={ACTIONS} onAction={ON_ACTION} onRowAction={ON_ROW_ACTION} />
97
146
  );
98
147
  }}
99
148
  </Story>
@@ -62,10 +62,19 @@ describe('components', function () {
62
62
 
63
63
  var PAGES = _utils.default.FormPage.getAll(_userProfile.default.pages, _userProfile.default.components, _objectSpread({}, DATA));
64
64
 
65
+ var ON_ROW_ACTION_CALLS = [];
66
+
67
+ var ON_ROW_ACTION = function ON_ROW_ACTION(row) {
68
+ ON_ROW_ACTION_CALLS.push(row);
69
+ };
70
+
65
71
  var ON_ACTION_CALLS = [];
66
72
 
67
- var ON_ACTION = function ON_ACTION(row) {
68
- ON_ACTION_CALLS.push(row);
73
+ var ON_ACTION = function ON_ACTION(action, onError) {
74
+ ON_ACTION_CALLS.push({
75
+ action: action,
76
+ onError: onError
77
+ });
69
78
  };
70
79
 
71
80
  var container = null;
@@ -75,6 +84,7 @@ describe('components', function () {
75
84
  };
76
85
 
77
86
  beforeEach(function () {
87
+ ON_ROW_ACTION_CALLS.length = 0;
78
88
  ON_ACTION_CALLS.length = 0;
79
89
  container = document.createElement('div');
80
90
  document.body.appendChild(container);
@@ -121,6 +131,7 @@ describe('components', function () {
121
131
  case 0:
122
132
  (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
123
133
  pages: PAGES,
134
+ onRowAction: ON_ROW_ACTION,
124
135
  onAction: ON_ACTION
125
136
  }), container);
126
137
 
@@ -161,6 +172,7 @@ describe('components', function () {
161
172
  (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
162
173
  title: TITLE,
163
174
  pages: PAGES,
175
+ onRowAction: ON_ROW_ACTION,
164
176
  onAction: ON_ACTION
165
177
  }), container);
166
178
 
@@ -200,6 +212,7 @@ describe('components', function () {
200
212
  case 0:
201
213
  (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
202
214
  pages: PAGES,
215
+ onRowAction: ON_ROW_ACTION,
203
216
  onAction: ON_ACTION
204
217
  }), container);
205
218
 
@@ -242,6 +255,7 @@ describe('components', function () {
242
255
  case 0:
243
256
  (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
244
257
  pages: PAGES,
258
+ onRowAction: ON_ROW_ACTION,
245
259
  onAction: ON_ACTION
246
260
  }), container);
247
261
 
@@ -284,6 +298,7 @@ describe('components', function () {
284
298
  case 0:
285
299
  (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
286
300
  pages: PAGES,
301
+ onRowAction: ON_ROW_ACTION,
287
302
  onAction: ON_ACTION,
288
303
  hide_page_titles: true
289
304
  }), container);
@@ -79,6 +79,10 @@ var FormPage = function FormPage(_ref) {
79
79
  });
80
80
  };
81
81
 
82
+ var onError = function onError(errors) {
83
+ setErrors(errors);
84
+ };
85
+
82
86
  var classes = _utils.default.classBuilder(classBlock, classModifiers, className);
83
87
 
84
88
  return /*#__PURE__*/_react.default.createElement("div", {
@@ -86,7 +90,9 @@ var FormPage = function FormPage(_ref) {
86
90
  key: page.id
87
91
  }, page.title && /*#__PURE__*/_react.default.createElement(_copReactComponents.LargeHeading, null, page.title), errors && errors.length > 0 && /*#__PURE__*/_react.default.createElement(_copReactComponents.ErrorSummary, {
88
92
  errors: errors
89
- }), page.components.map(function (component, index) {
93
+ }), page.components.filter(function (c) {
94
+ return _utils.default.Component.show(c, page.formData);
95
+ }).map(function (component, index) {
90
96
  return /*#__PURE__*/_react.default.createElement(_FormComponent.default, {
91
97
  key: index,
92
98
  component: component,
@@ -96,7 +102,7 @@ var FormPage = function FormPage(_ref) {
96
102
  }), /*#__PURE__*/_react.default.createElement(_PageActions.default, {
97
103
  actions: page.actions,
98
104
  onAction: function onAction(action) {
99
- return _onAction(action, patch, setErrors);
105
+ return _onAction(action, patch, onError);
100
106
  }
101
107
  }));
102
108
  };
@@ -36,7 +36,7 @@ describe('components', function () {
36
36
  id: 'pageId',
37
37
  title: 'Page 1',
38
38
  components: [TEXT],
39
- actions: ['submit'],
39
+ actions: [_models.PageAction.TYPES.SUBMIT],
40
40
  formData: {
41
41
  text: VALUE
42
42
  }
@@ -93,10 +93,10 @@ describe('components', function () {
93
93
  expect(input.value).toEqual(VALUE);
94
94
  buttonGroup = page.childNodes[2];
95
95
  expect(buttonGroup.tagName).toEqual('DIV');
96
- expect(buttonGroup.classList).toContain('govuk-button-group');
96
+ expect(buttonGroup.classList).toContain('hods-button-group');
97
97
  button = buttonGroup.childNodes[0];
98
98
  expect(button.tagName).toEqual('BUTTON');
99
- expect(button.classList).toContain('govuk-button');
99
+ expect(button.classList).toContain('hods-button');
100
100
  expect(button.textContent).toEqual(_ActionButton.DEFAULT_LABEL);
101
101
 
102
102
  case 31:
@@ -111,12 +111,26 @@ var FormRenderer = function FormRenderer(_ref) {
111
111
  }, [_hooks, addHook]); // Setup data.
112
112
 
113
113
  (0, _react.useEffect)(function () {
114
- setData(_utils.default.Data.setupForm(_pages, components, _data));
114
+ if (components && _pages && _data) {
115
+ var _data$formStatus;
116
+
117
+ setData(_utils.default.Data.setupForm(_pages, components, _data));
118
+
119
+ if ((_data$formStatus = _data.formStatus) !== null && _data$formStatus !== void 0 && _data$formStatus.page) {
120
+ setPageId(_data.formStatus.page);
121
+ }
122
+ }
115
123
  }, [components, _pages, _data, setData]); // Setup pages.
116
124
 
117
125
  (0, _react.useEffect)(function () {
118
126
  setPages(_utils.default.FormPage.getAll(_pages, components, _objectSpread({}, data)));
119
- }, [components, _pages, data, setPages]); // Setup hub.
127
+ }, [components, _pages, data, setPages]); // Setup initial pageId.
128
+
129
+ (0, _react.useEffect)(function () {
130
+ setPageId(function (prev) {
131
+ return prev || _helpers.default.getNextPageId(type, pages);
132
+ });
133
+ }, [type, pages, setPageId]); // Setup hub.
120
134
 
121
135
  (0, _react.useEffect)(function () {
122
136
  setHub(_utils.default.Hub.get(type, _hub, components, _objectSpread({}, data)));
@@ -140,24 +154,30 @@ var FormRenderer = function FormRenderer(_ref) {
140
154
  // Check to see whether the action is able to proceed, which in
141
155
  // in the case of a submission will validate the fields in the page.
142
156
  if (_helpers.default.canActionProceed(action, formState.page, onError)) {
143
- if (action.type === 'navigate') {
157
+ if (action.type === _models.PageAction.TYPES.NAVIGATE) {
144
158
  _handlers.default.navigate(action, pageId, onPageChange);
145
159
  } else {
146
- // Submit.
160
+ // Save draft or submit.
147
161
  var submissionData = _utils.default.Format.form({
148
162
  pages: pages,
149
163
  components: components
150
164
  }, _objectSpread(_objectSpread({}, data), patch), _models.EventTypes.SUBMIT);
151
165
 
166
+ submissionData.formStatus = _helpers.default.getSubmissionStatus(type, pages, pageId, action, submissionData);
167
+
152
168
  if (patch) {
153
169
  setData(submissionData);
154
170
  } // Now submit the data to the backend...
155
171
 
156
172
 
157
- hooks.onSubmit(action.type, submissionData, function () {
158
- var nextPageId = _helpers.default.getNextPageId(type, pages, pageId, action);
173
+ hooks.onSubmit(action.type, submissionData, function (response) {
174
+ // The backend response may well contain data we need so apply it.
175
+ setData(function (prev) {
176
+ var next = _objectSpread(_objectSpread({}, prev), response);
159
177
 
160
- onPageChange(nextPageId);
178
+ onPageChange(_helpers.default.getNextPageId(type, pages, pageId, action, next));
179
+ return next;
180
+ });
161
181
  }, function (errors) {
162
182
  _handlers.default.submissionError(errors, onError);
163
183
  });
@@ -166,8 +186,32 @@ var FormRenderer = function FormRenderer(_ref) {
166
186
  }; // Handle navigation from "Check your answers".
167
187
 
168
188
 
169
- var onCYAAction = function onCYAAction(page) {
189
+ var onCYARowAction = function onCYARowAction(page) {
170
190
  _handlers.default.cyaAction(page, pageId, onPageChange);
191
+ }; // Handle actions from "Check your answers".
192
+
193
+
194
+ var onCYAAction = function onCYAAction(action, onError) {
195
+ // Check to see whether the action is able to proceed, which in
196
+ // in the case of a submission will validate the fields in the page.
197
+ if (action.type === _models.PageAction.TYPES.SUBMIT) {
198
+ if (_helpers.default.canCYASubmit(pages, onError)) {
199
+ // Submit.
200
+ var submissionData = _utils.default.Format.form({
201
+ pages: pages,
202
+ components: components
203
+ }, _objectSpread({}, data), _models.EventTypes.SUBMIT);
204
+
205
+ submissionData.formStatus = _helpers.default.getSubmissionStatus(type, pages, pageId, action);
206
+ setData(submissionData); // Now submit the data to the backend...
207
+
208
+ hooks.onSubmit(action.type, submissionData, function () {
209
+ return hooks.onFormComplete();
210
+ }, function (errors) {
211
+ return _handlers.default.submissionError(errors, onError);
212
+ });
213
+ }
214
+ }
171
215
  };
172
216
 
173
217
  var classes = _utils.default.classBuilder(classBlock, classModifiers, className);
@@ -177,7 +221,8 @@ var FormRenderer = function FormRenderer(_ref) {
177
221
  }, title && pageId === _models.FormPages.HUB && /*#__PURE__*/_react.default.createElement(_copReactComponents.LargeHeading, null, title), formState.cya && /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, _extends({
178
222
  pages: pages
179
223
  }, cya, formState.cya, {
180
- onAction: onCYAAction
224
+ onAction: onCYAAction,
225
+ onRowAction: onCYARowAction
181
226
  })), formState.page && /*#__PURE__*/_react.default.createElement(_FormPage.default, {
182
227
  page: formState.page,
183
228
  onAction: onPageAction
@@ -1,6 +1,7 @@
1
1
  <!-- Global imports -->
2
2
  import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
3
- import { Details, Heading, Link } from '@ukhomeoffice/cop-react-components';
3
+ import { Button, Details, Heading, Link, Panel } from '@ukhomeoffice/cop-react-components';
4
+ import { useState } from 'react';
4
5
  import withMock from 'storybook-addon-mock';
5
6
 
6
7
  <!-- Local imports -->
@@ -9,11 +10,11 @@ import FormRenderer from './FormRenderer';
9
10
 
10
11
  <!-- JSON documents -->
11
12
  import CIVIL_SERVANT from '../../json/areYouACivilServant.json';
13
+ import FIRST_FORM from '../../json/firstForm.json';
12
14
  import GRADE from '../../json/grade.json';
13
15
  import TEAMS from '../../json/team.json';
14
16
  import USER_PROFILE_DATA from '../../json/userProfile.data.json';
15
17
  import USER_PROFILE from '../../json/userProfile.json';
16
- import SAVE_AND_CONTINUE from '../../json/saveAndContinue.json';
17
18
 
18
19
  <Meta title="Components/Form renderer" id="D-FormRenderer" component={ FormRenderer } decorators={[withMock]} />
19
20
 
@@ -57,11 +58,13 @@ on the basis of a <Link href="/?path=/docs/f-json-form">JSON</Link> that describ
57
58
  <ArgsTable of={ FormRenderer } />
58
59
  </Details>
59
60
 
60
- ## Custom hooks
61
+ ## CYA type
61
62
 
62
63
  <Canvas>
63
- <Story name="Save and continue">
64
+ <Story name="CYA">
64
65
  {() => {
66
+ const [complete, setComplete] = useState(false);
67
+ const [returnLater, setReturnLater] = useState(false);
65
68
  addHook('onRequest', (req) => {
66
69
  // Do whatever you need to do to the request in here, such as adding an Authorization header.
67
70
  console.log('onRequest hook called');
@@ -70,20 +73,42 @@ on the basis of a <Link href="/?path=/docs/f-json-form">JSON</Link> that describ
70
73
  addHook('onFormLoad', () => {
71
74
  console.log('onFormLoad called');
72
75
  });
76
+ addHook('onFormComplete', () => {
77
+ console.log('onFormComplete called');
78
+ setComplete(true);
79
+ });
73
80
  addHook('onPageChange', (pageId) => {
74
81
  console.log('onPageChange called', pageId);
82
+ setReturnLater(!!pageId === false);
75
83
  });
76
-
77
- /**
78
- * In whatever consumes this, do it as:
79
- * intercepts.add('onSubmit', (...) => { ... })
80
- */
81
84
  addHook('onSubmit', (type, payload, onSuccess, onError) => {
82
85
  console.log('onSubmit called of type', type, 'called, with the payload', payload);
83
86
  onSuccess();
84
87
  });
88
+ const reset = () => {
89
+ setComplete(false);
90
+ setReturnLater(false);
91
+ };
85
92
  return (
86
- <FormRenderer {...SAVE_AND_CONTINUE} data={{}} />
93
+ <>
94
+ {!complete && !returnLater && <FormRenderer {...FIRST_FORM} data={{}} />}
95
+ {complete &&
96
+ <div>
97
+ <Panel title="Submission successful">
98
+ Your submission was successful.
99
+ </Panel>
100
+ <Button onClick={() => reset()}>Start again</Button>
101
+ </div>
102
+ }
103
+ {!complete && returnLater &&
104
+ <div>
105
+ <Panel title="Saved to return later">
106
+ You clicked on "Save and return later".
107
+ </Panel>
108
+ <Button onClick={() => reset()}>Start again</Button>
109
+ </div>
110
+ }
111
+ </>
87
112
  );
88
113
  }}
89
114
  </Story>
@@ -2,18 +2,24 @@
2
2
 
3
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
4
 
5
+ var _react = require("@testing-library/react");
6
+
5
7
  var _axios = _interopRequireDefault(require("axios"));
6
8
 
7
9
  var _axiosMockAdapter = _interopRequireDefault(require("axios-mock-adapter"));
8
10
 
9
- var _react = _interopRequireDefault(require("react"));
10
-
11
- var _react2 = require("@testing-library/react");
11
+ var _react2 = _interopRequireDefault(require("react"));
12
12
 
13
13
  var _reactDom = require("react-dom");
14
14
 
15
15
  var _testUtils = require("react-dom/test-utils");
16
16
 
17
+ var _models = require("../../models");
18
+
19
+ var _CheckYourAnswers = require("../CheckYourAnswers/CheckYourAnswers");
20
+
21
+ var _FormRenderer = _interopRequireWildcard(require("./FormRenderer"));
22
+
17
23
  var _areYouACivilServant = _interopRequireDefault(require("../../json/areYouACivilServant.json"));
18
24
 
19
25
  var _grade = _interopRequireDefault(require("../../json/grade.json"));
@@ -24,10 +30,6 @@ var _userProfileData = _interopRequireDefault(require("../../json/userProfile.da
24
30
 
25
31
  var _userProfile = _interopRequireDefault(require("../../json/userProfile.json"));
26
32
 
27
- var _FormRenderer = _interopRequireWildcard(require("./FormRenderer"));
28
-
29
- var _CheckYourAnswers = require("../CheckYourAnswers/CheckYourAnswers");
30
-
31
33
  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); }
32
34
 
33
35
  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; }
@@ -105,7 +107,7 @@ describe('components', function () {
105
107
  while (1) {
106
108
  switch (_context.prev = _context.next) {
107
109
  case 0:
108
- (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
110
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
109
111
  data: _userProfileData.default
110
112
  })), container);
111
113
 
@@ -156,7 +158,7 @@ describe('components', function () {
156
158
  while (1) {
157
159
  switch (_context3.prev = _context3.next) {
158
160
  case 0:
159
- (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
161
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
160
162
  data: _userProfileData.default,
161
163
  hooks: HOOKS
162
164
  })), container);
@@ -201,7 +203,7 @@ describe('components', function () {
201
203
  while (1) {
202
204
  switch (_context5.prev = _context5.next) {
203
205
  case 0:
204
- (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
206
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
205
207
  data: _userProfileData.default,
206
208
  hooks: HOOKS
207
209
  })), container);
@@ -222,7 +224,7 @@ describe('components', function () {
222
224
  link = getChangeLink(civilServantList);
223
225
  expect(ON_PAGE_CHANGE_CALLS.length).toEqual(0);
224
226
 
225
- _react2.fireEvent.click(link, {});
227
+ _react.fireEvent.click(link, {});
226
228
 
227
229
  expect(ON_PAGE_CHANGE_CALLS.length).toEqual(1);
228
230
  expect(ON_PAGE_CHANGE_CALLS[0]).toEqual(_userProfile.default.pages[1].id); // The form layout should have changed to the current page.
@@ -269,7 +271,7 @@ describe('components', function () {
269
271
  while (1) {
270
272
  switch (_context7.prev = _context7.next) {
271
273
  case 0:
272
- (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
274
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
273
275
  data: _userProfileData.default,
274
276
  hooks: HOOKS
275
277
  })), container);
@@ -290,17 +292,17 @@ describe('components', function () {
290
292
  _hub$childNodes2 = _slicedToArray(hub.childNodes, 3), civilServantList = _hub$childNodes2[2];
291
293
  link = getChangeLink(civilServantList);
292
294
 
293
- _react2.fireEvent.click(link, {}); // Should already be answered "Yes", so simply click "Continue".
295
+ _react.fireEvent.click(link, {}); // Should already be answered "Yes", so simply click "Continue".
294
296
 
295
297
 
296
298
  page = form.childNodes[0];
297
299
  continueButton = getContinueButton(page);
298
300
  expect(ON_SUBMIT_CALLS.length).toEqual(0);
299
301
 
300
- _react2.fireEvent.click(continueButton, {});
302
+ _react.fireEvent.click(continueButton, {});
301
303
 
302
304
  expect(ON_SUBMIT_CALLS.length).toEqual(1);
303
- expect(ON_SUBMIT_CALLS[0].type).toEqual('submit');
305
+ expect(ON_SUBMIT_CALLS[0].type).toEqual(_models.PageAction.TYPES.SUBMIT);
304
306
  expect(ON_SUBMIT_CALLS[0].payload.areYouACivilServant).toEqual('yes'); // And we should be back on the hub.
305
307
 
306
308
  expect(form.childNodes.length).toEqual(2); // Title + Hub page (= CYA)
@@ -347,7 +349,7 @@ describe('components', function () {
347
349
  while (1) {
348
350
  switch (_context9.prev = _context9.next) {
349
351
  case 0:
350
- (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
352
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
351
353
  data: _userProfileData.default,
352
354
  hooks: HOOKS
353
355
  })), container);
@@ -368,17 +370,17 @@ describe('components', function () {
368
370
  _hub$childNodes3 = _slicedToArray(hub.childNodes, 3), civilServantList = _hub$childNodes3[2];
369
371
  link = getChangeLink(civilServantList);
370
372
 
371
- _react2.fireEvent.click(link, {}); // Should already be answered "Yes", so simply click "Continue".
373
+ _react.fireEvent.click(link, {}); // Should already be answered "Yes", so simply click "Continue".
372
374
 
373
375
 
374
376
  page = form.childNodes[0];
375
377
  continueButton = getContinueButton(page);
376
378
  expect(ON_SUBMIT_CALLS.length).toEqual(0);
377
379
 
378
- _react2.fireEvent.click(continueButton, {});
380
+ _react.fireEvent.click(continueButton, {});
379
381
 
380
382
  expect(ON_SUBMIT_CALLS.length).toEqual(1);
381
- expect(ON_SUBMIT_CALLS[0].type).toEqual('submit');
383
+ expect(ON_SUBMIT_CALLS[0].type).toEqual(_models.PageAction.TYPES.SUBMIT);
382
384
  expect(ON_SUBMIT_CALLS[0].payload.areYouACivilServant).toEqual('yes'); // And we should be kept on the same page.
383
385
 
384
386
  expect(form.childNodes.length).toEqual(1); // Just the page.
@@ -416,7 +418,7 @@ describe('components', function () {
416
418
  while (1) {
417
419
  switch (_context11.prev = _context11.next) {
418
420
  case 0:
419
- (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
421
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
420
422
  data: _userProfileData.default,
421
423
  hooks: HOOKS
422
424
  })), container);
@@ -438,7 +440,7 @@ describe('components', function () {
438
440
  link = getChangeLink(lineManagerList);
439
441
  expect(ON_PAGE_CHANGE_CALLS.length).toEqual(0);
440
442
 
441
- _react2.fireEvent.click(link, {});
443
+ _react.fireEvent.click(link, {});
442
444
 
443
445
  expect(ON_PAGE_CHANGE_CALLS[0]).toEqual(_userProfile.default.pages[4].id); // Should be on the page explaining what changing the line manager means.
444
446
 
@@ -450,7 +452,7 @@ describe('components', function () {
450
452
  continueButton = getContinueButton(page);
451
453
  expect(ON_PAGE_CHANGE_CALLS.length).toEqual(1);
452
454
 
453
- _react2.fireEvent.click(continueButton, {});
455
+ _react.fireEvent.click(continueButton, {});
454
456
 
455
457
  expect(ON_PAGE_CHANGE_CALLS.length).toEqual(2);
456
458
  expect(ON_PAGE_CHANGE_CALLS[1]).toEqual(_userProfile.default.pages[5].id);