@ukhomeoffice/cop-react-form-renderer 0.1.0-gamma → 1.0.0-alpha

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 (62) hide show
  1. package/dist/components/CheckYourAnswers/Answer.test.js +94 -0
  2. package/dist/components/CheckYourAnswers/CheckYourAnswers.js +79 -27
  3. package/dist/components/CheckYourAnswers/CheckYourAnswers.scss +0 -7
  4. package/dist/components/CheckYourAnswers/CheckYourAnswers.stories.mdx +78 -1
  5. package/dist/components/CheckYourAnswers/CheckYourAnswers.test.js +332 -0
  6. package/dist/components/FormPage/FormPage.test.js +3 -1
  7. package/dist/components/FormRenderer/FormRenderer.js +75 -54
  8. package/dist/components/FormRenderer/FormRenderer.stories.mdx +35 -7
  9. package/dist/components/FormRenderer/FormRenderer.test.js +471 -0
  10. package/dist/components/FormRenderer/handlers/cyaAction.js +28 -0
  11. package/dist/components/FormRenderer/handlers/getPageId.js +28 -0
  12. package/dist/components/FormRenderer/handlers/getPageId.test.js +61 -0
  13. package/dist/components/FormRenderer/handlers/handlers.test.js +97 -0
  14. package/dist/components/FormRenderer/handlers/index.js +23 -0
  15. package/dist/components/FormRenderer/handlers/navigate.js +28 -0
  16. package/dist/components/FormRenderer/handlers/submissionError.js +20 -0
  17. package/dist/components/FormRenderer/helpers/canCYASubmit.js +42 -0
  18. package/dist/components/FormRenderer/helpers/canCYASubmit.test.js +155 -0
  19. package/dist/components/FormRenderer/helpers/getCYA.js +2 -2
  20. package/dist/components/FormRenderer/helpers/getCYA.test.js +5 -5
  21. package/dist/components/FormRenderer/helpers/getFormState.test.js +7 -7
  22. package/dist/components/FormRenderer/helpers/getNextPageId.js +65 -0
  23. package/dist/components/FormRenderer/helpers/getNextPageId.test.js +90 -0
  24. package/dist/components/FormRenderer/helpers/getPage.js +1 -1
  25. package/dist/components/FormRenderer/helpers/getPage.test.js +3 -3
  26. package/dist/components/FormRenderer/helpers/index.js +17 -13
  27. package/dist/components/PageActions/ActionButton.js +5 -9
  28. package/dist/components/PageActions/ActionButton.test.js +3 -1
  29. package/dist/components/PageActions/PageActions.test.js +4 -2
  30. package/dist/components/SummaryList/RowAction.js +1 -1
  31. package/dist/components/SummaryList/RowAction.test.js +8 -18
  32. package/dist/components/SummaryList/SummaryList.js +4 -4
  33. package/dist/components/SummaryList/SummaryList.scss +7 -0
  34. package/dist/components/SummaryList/SummaryList.stories.mdx +36 -0
  35. package/dist/components/SummaryList/SummaryList.test.js +197 -0
  36. package/dist/hooks/useHooks.js +12 -15
  37. package/dist/index.js +3 -1
  38. package/dist/index.test.js +18 -0
  39. package/dist/models/EventTypes.js +14 -0
  40. package/dist/models/FormPages.js +14 -0
  41. package/dist/models/PageAction.js +40 -0
  42. package/dist/models/index.js +24 -0
  43. package/dist/utils/CheckYourAnswers/getCYAAction.js +9 -0
  44. package/dist/utils/CheckYourAnswers/getCYARow.js +10 -0
  45. package/dist/utils/CheckYourAnswers/getCYARowsForPage.js +9 -0
  46. package/dist/utils/CheckYourAnswers/showComponentCYA.js +6 -5
  47. package/dist/utils/Component/getComponent.test.js +1 -1
  48. package/dist/utils/Format/formatData.js +32 -0
  49. package/dist/utils/Format/formatData.test.js +46 -0
  50. package/dist/utils/Format/formatDataForComponent.js +41 -0
  51. package/dist/utils/Format/formatDataForComponent.test.js +161 -0
  52. package/dist/utils/Format/formatDataForForm.js +33 -0
  53. package/dist/utils/Format/formatDataForForm.test.js +78 -0
  54. package/dist/utils/Format/formatDataForPage.js +37 -0
  55. package/dist/utils/Format/formatDataForPage.test.js +96 -0
  56. package/dist/utils/Format/index.js +26 -0
  57. package/dist/utils/Hub/getFormHub.js +14 -0
  58. package/dist/utils/Validate/validatePage.test.js +1 -1
  59. package/dist/utils/index.js +3 -0
  60. package/package.json +6 -3
  61. package/dist/components/FormRenderer/helpers.js +0 -66
  62. package/dist/components/FormRenderer/helpers.test.js +0 -158
@@ -6,6 +6,8 @@ var _react = require("@testing-library/react");
6
6
 
7
7
  var _react2 = _interopRequireDefault(require("react"));
8
8
 
9
+ var _models = require("../../models");
10
+
9
11
  var _ActionButton = require("../PageActions/ActionButton");
10
12
 
11
13
  var _FormPage = _interopRequireWildcard(require("./FormPage"));
@@ -171,7 +173,7 @@ describe('components', function () {
171
173
 
172
174
  expect(ON_ACTION_CALLS.length).toEqual(1);
173
175
  expect(PAGE.formData.text).toEqual(NEW_VALUE);
174
- expect(ON_ACTION_CALLS[0].action).toEqual(_ActionButton.DEFAULT_ACTIONS.submit);
176
+ expect(ON_ACTION_CALLS[0].action).toEqual(_models.PageAction.DEFAULTS.submit);
175
177
  expect(ON_ACTION_CALLS[0].patch).toEqual({
176
178
  text: NEW_VALUE
177
179
  });
@@ -5,7 +5,7 @@ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "functi
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.default = void 0;
8
+ exports.default = exports.DEFAULT_CLASS = void 0;
9
9
 
10
10
  var _copReactComponents = require("@ukhomeoffice/cop-react-components");
11
11
 
@@ -23,7 +23,9 @@ var _CheckYourAnswers = _interopRequireDefault(require("../CheckYourAnswers"));
23
23
 
24
24
  var _FormPage = _interopRequireDefault(require("../FormPage"));
25
25
 
26
- var _helpers = require("./helpers");
26
+ var _handlers = _interopRequireDefault(require("./handlers"));
27
+
28
+ var _helpers = _interopRequireDefault(require("./helpers"));
27
29
 
28
30
  require("./FormRenderer.scss");
29
31
 
@@ -54,6 +56,7 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
54
56
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
55
57
 
56
58
  var DEFAULT_CLASS = 'hods-form';
59
+ exports.DEFAULT_CLASS = DEFAULT_CLASS;
57
60
 
58
61
  var FormRenderer = function FormRenderer(_ref) {
59
62
  var title = _ref.title,
@@ -61,7 +64,7 @@ var FormRenderer = function FormRenderer(_ref) {
61
64
  components = _ref.components,
62
65
  _pages = _ref.pages,
63
66
  _hub = _ref.hub,
64
- _cya = _ref.cya,
67
+ cya = _ref.cya,
65
68
  _data = _ref.data,
66
69
  _hooks = _ref.hooks,
67
70
  classBlock = _ref.classBlock,
@@ -74,30 +77,25 @@ var FormRenderer = function FormRenderer(_ref) {
74
77
  data = _useState2[0],
75
78
  setData = _useState2[1];
76
79
 
77
- var _useState3 = (0, _react.useState)(0),
80
+ var _useState3 = (0, _react.useState)([]),
78
81
  _useState4 = _slicedToArray(_useState3, 2),
79
- redoPages = _useState4[0],
80
- setRedoPages = _useState4[1];
82
+ pages = _useState4[0],
83
+ setPages = _useState4[1];
81
84
 
82
- var _useState5 = (0, _react.useState)([]),
85
+ var _useState5 = (0, _react.useState)(undefined),
83
86
  _useState6 = _slicedToArray(_useState5, 2),
84
- pages = _useState6[0],
85
- setPages = _useState6[1];
87
+ hub = _useState6[0],
88
+ setHub = _useState6[1];
86
89
 
87
- var _useState7 = (0, _react.useState)(undefined),
90
+ var _useState7 = (0, _react.useState)(_helpers.default.getNextPageId(type, _pages)),
88
91
  _useState8 = _slicedToArray(_useState7, 2),
89
- hub = _useState8[0],
90
- setHub = _useState8[1];
92
+ pageId = _useState8[0],
93
+ setPageId = _useState8[1];
91
94
 
92
- var _useState9 = (0, _react.useState)('hub'),
95
+ var _useState9 = (0, _react.useState)(_helpers.default.getFormState(pageId, pages, hub)),
93
96
  _useState10 = _slicedToArray(_useState9, 2),
94
- pageId = _useState10[0],
95
- setPageId = _useState10[1];
96
-
97
- var _useState11 = (0, _react.useState)((0, _helpers.getFormState)(pageId, pages, hub)),
98
- _useState12 = _slicedToArray(_useState11, 2),
99
- formState = _useState12[0],
100
- setFormState = _useState12[1]; // Set up hooks.
97
+ formState = _useState10[0],
98
+ setFormState = _useState10[1]; // Set up hooks.
101
99
 
102
100
 
103
101
  var _useHooks = (0, _hooks2.useHooks)(),
@@ -118,75 +116,95 @@ var FormRenderer = function FormRenderer(_ref) {
118
116
 
119
117
  (0, _react.useEffect)(function () {
120
118
  setPages(_utils.default.FormPage.getAll(_pages, components, _objectSpread({}, data)));
121
- }, [components, _pages, data, redoPages, setPages]); // Setup hub.
119
+ }, [components, _pages, data, setPages]); // Setup hub.
122
120
 
123
121
  (0, _react.useEffect)(function () {
124
122
  setHub(_utils.default.Hub.get(type, _hub, components, _objectSpread({}, data)));
125
123
  }, [type, _hub, data, components, setHub]); // Form state.
126
124
 
127
125
  (0, _react.useEffect)(function () {
128
- setFormState((0, _helpers.getFormState)(pageId, pages, hub));
126
+ setFormState(_helpers.default.getFormState(pageId, pages, hub));
129
127
  }, [pages, hub, pageId, setFormState]); // Call the onFormLoad hook just when this component first renders.
130
128
 
131
129
  (0, _react.useEffect)(function () {
132
130
  hooks.onFormLoad();
133
- }, [hooks]); // Handle actions from pages.
131
+ }, [hooks]);
132
+
133
+ var onPageChange = function onPageChange(newPageId) {
134
+ setPageId(newPageId);
135
+ hooks.onPageChange(newPageId);
136
+ }; // Handle actions from pages.
134
137
 
135
- var onAction = function onAction(action, patch, onError) {
136
- // First check the validity of the
137
- if ((0, _helpers.canActionProceed)(action, formState.page, onError)) {
138
+
139
+ var onPageAction = function onPageAction(action, patch, onError) {
140
+ // Check to see whether the action is able to proceed, which in
141
+ // in the case of a submission will validate the fields in the page.
142
+ if (_helpers.default.canActionProceed(action, formState.page, onError)) {
138
143
  if (action.type === 'navigate') {
139
- var newPageId = action.url.replace('/', '');
140
- setPageId(newPageId);
141
- hooks.onPageChange(newPageId);
142
- } else if (action.type === 'cancel') {
143
- setRedoPages(Date.now);
144
- setPageId('hub');
145
- hooks.onPageChange('hub');
144
+ _handlers.default.navigate(action, pageId, onPageChange);
146
145
  } else {
147
146
  // Submit.
147
+ var submissionData = _utils.default.Format.form({
148
+ pages: pages,
149
+ components: components
150
+ }, _objectSpread(_objectSpread({}, data), patch), _models.EventTypes.SUBMIT);
151
+
148
152
  if (patch) {
149
- setData(function (prev) {
150
- return _objectSpread(_objectSpread({}, prev), patch);
151
- });
153
+ setData(submissionData);
152
154
  } // Now submit the data to the backend...
153
155
 
154
156
 
155
- hooks.onSubmit(action.type, _objectSpread(_objectSpread({}, data), patch), function () {
156
- setPageId('hub');
157
- hooks.onPageChange('hub');
157
+ hooks.onSubmit(action.type, submissionData, function () {
158
+ var nextPageId = _helpers.default.getNextPageId(type, pages, pageId, action);
159
+
160
+ onPageChange(nextPageId);
158
161
  }, function (errors) {
159
- // Handle the errors.
160
- console.error('Submission errors', errors);
162
+ _handlers.default.submissionError(errors, onError);
161
163
  });
162
164
  }
163
165
  }
164
166
  }; // Handle navigation from "Check your answers".
165
167
 
166
168
 
167
- var onCheckYourAnswerChange = function onCheckYourAnswerChange(page) {
168
- var action = page.action;
169
- var newPageId = page.pageId;
169
+ var onCYARowAction = function onCYARowAction(page) {
170
+ _handlers.default.cyaAction(page, pageId, onPageChange);
171
+ }; // Handle actions from "Check your answers".
170
172
 
171
- if (action && action.href) {
172
- newPageId = action.href.replace('/', '');
173
- }
174
173
 
175
- setPageId(newPageId);
176
- hooks.onPageChange(newPageId);
174
+ var onCYAAction = function onCYAAction(action, onError) {
175
+ // Check to see whether the action is able to proceed, which in
176
+ // in the case of a submission will validate the fields in the page.
177
+ if (action.type === _models.PageAction.TYPES.SUBMIT) {
178
+ if (_helpers.default.canCYASubmit(pages, onError)) {
179
+ // Submit.
180
+ var submissionData = _utils.default.Format.form({
181
+ pages: pages,
182
+ components: components
183
+ }, _objectSpread({}, data), _models.EventTypes.SUBMIT);
184
+
185
+ setData(submissionData); // Now submit the data to the backend...
186
+
187
+ hooks.onSubmit(action.type, submissionData, function () {
188
+ hooks.onFormComplete();
189
+ }, function (errors) {
190
+ _handlers.default.submissionError(errors, onError);
191
+ });
192
+ }
193
+ }
177
194
  };
178
195
 
179
196
  var classes = _utils.default.classBuilder(classBlock, classModifiers, className);
180
197
 
181
198
  return /*#__PURE__*/_react.default.createElement("div", {
182
199
  className: classes()
183
- }, title && pageId === 'hub' && /*#__PURE__*/_react.default.createElement(_copReactComponents.LargeHeading, null, title), formState.cya && /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, _extends({
200
+ }, title && pageId === _models.FormPages.HUB && /*#__PURE__*/_react.default.createElement(_copReactComponents.LargeHeading, null, title), formState.cya && /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, _extends({
184
201
  pages: pages
185
- }, _cya, formState.cya, {
186
- onAction: onCheckYourAnswerChange
202
+ }, cya, formState.cya, {
203
+ onAction: onCYAAction,
204
+ onRowAction: onCYARowAction
187
205
  })), formState.page && /*#__PURE__*/_react.default.createElement(_FormPage.default, {
188
206
  page: formState.page,
189
- onAction: onAction
207
+ onAction: onPageAction
190
208
  }));
191
209
  };
192
210
 
@@ -201,7 +219,10 @@ FormRenderer.propTypes = {
201
219
  cya: _propTypes.default.object,
202
220
  data: _propTypes.default.object,
203
221
  hooks: _propTypes.default.shape({
204
- onRequest: _propTypes.default.func
222
+ onFormLoad: _propTypes.default.func,
223
+ onPageChange: _propTypes.default.func,
224
+ onRequest: _propTypes.default.func,
225
+ onSubmit: _propTypes.default.func
205
226
  }),
206
227
  classBlock: _propTypes.default.string,
207
228
  classModifiers: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.arrayOf(_propTypes.default.string)]),
@@ -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,17 +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
- // In whatever consumes this, do it as:
77
- // intercepts.add('onSubmit', (...) => { ... })
78
84
  addHook('onSubmit', (type, payload, onSuccess, onError) => {
79
85
  console.log('onSubmit called of type', type, 'called, with the payload', payload);
80
86
  onSuccess();
81
87
  });
88
+ const reset = () => {
89
+ setComplete(false);
90
+ setReturnLater(false);
91
+ };
82
92
  return (
83
- <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
+ </>
84
112
  );
85
113
  }}
86
114
  </Story>