@ukhomeoffice/cop-react-form-renderer 2.2.0 → 2.5.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 (51) hide show
  1. package/dist/components/FormRenderer/FormRenderer.js +105 -6
  2. package/dist/components/FormRenderer/FormRenderer.test.js +235 -0
  3. package/dist/components/FormRenderer/helpers/getNextPageId.js +3 -0
  4. package/dist/components/FormRenderer/helpers/getNextPageId.test.js +6 -0
  5. package/dist/components/FormRenderer/helpers/getPage.js +1 -1
  6. package/dist/components/FormRenderer/helpers/getSubmissionStatus.js +18 -1
  7. package/dist/components/FormRenderer/helpers/getSubmissionStatus.test.js +44 -6
  8. package/dist/components/FormRenderer/helpers/getUpdatedSectionStates.js +50 -0
  9. package/dist/components/FormRenderer/helpers/getUpdatedSectionStates.test.js +122 -0
  10. package/dist/components/FormRenderer/helpers/index.js +7 -1
  11. package/dist/components/TaskList/Task.js +83 -0
  12. package/dist/components/TaskList/Task.test.js +112 -0
  13. package/dist/components/TaskList/TaskList.js +112 -0
  14. package/dist/components/TaskList/TaskList.scss +70 -0
  15. package/dist/components/TaskList/TaskList.stories.mdx +57 -0
  16. package/dist/components/TaskList/TaskList.test.js +223 -0
  17. package/dist/components/TaskList/TaskState.js +42 -0
  18. package/dist/components/TaskList/TaskState.test.js +99 -0
  19. package/dist/components/TaskList/index.js +13 -0
  20. package/dist/json/taskList.json +228 -0
  21. package/dist/json/userProfile.data.json +2 -1
  22. package/dist/models/ComponentTypes.js +3 -1
  23. package/dist/models/FormTypes.js +2 -0
  24. package/dist/models/HubFormats.js +3 -1
  25. package/dist/models/PageAction.js +5 -0
  26. package/dist/models/TaskStates.js +41 -0
  27. package/dist/models/index.js +8 -0
  28. package/dist/utils/Component/cleanAttributes.js +1 -1
  29. package/dist/utils/Component/getComponent.js +8 -0
  30. package/dist/utils/Component/isEditable.js +1 -1
  31. package/dist/utils/FormPage/getPageActions.js +6 -0
  32. package/dist/utils/Hub/getFormHub.js +4 -0
  33. package/dist/utils/Hub/getFormHub.test.js +10 -2
  34. package/dist/utils/Validate/additional/index.js +55 -0
  35. package/dist/utils/Validate/additional/index.test.js +69 -0
  36. package/dist/utils/Validate/additional/mustBeAfter.js +37 -0
  37. package/dist/utils/Validate/additional/mustBeAfter.test.js +98 -0
  38. package/dist/utils/Validate/additional/mustBeBefore.js +35 -0
  39. package/dist/utils/Validate/additional/mustBeBefore.test.js +66 -0
  40. package/dist/utils/Validate/additional/mustBeInTheFuture.js +42 -0
  41. package/dist/utils/Validate/additional/mustBeInTheFuture.test.js +34 -0
  42. package/dist/utils/Validate/additional/mustBeInThePast.js +44 -0
  43. package/dist/utils/Validate/additional/mustBeInThePast.test.js +34 -0
  44. package/dist/utils/Validate/additional/utils.js +66 -0
  45. package/dist/utils/Validate/validateComponent.js +37 -0
  46. package/dist/utils/Validate/validateComponent.test.js +48 -2
  47. package/dist/utils/Validate/validateDate.js +144 -0
  48. package/dist/utils/Validate/validateDate.test.js +112 -0
  49. package/dist/utils/Validate/validateTime.js +76 -0
  50. package/dist/utils/Validate/validateTime.test.js +55 -0
  51. package/package.json +3 -2
@@ -23,6 +23,8 @@ var _CheckYourAnswers = _interopRequireDefault(require("../CheckYourAnswers"));
23
23
 
24
24
  var _FormPage = _interopRequireDefault(require("../FormPage"));
25
25
 
26
+ var _TaskList = _interopRequireDefault(require("../TaskList"));
27
+
26
28
  var _handlers = _interopRequireDefault(require("./handlers"));
27
29
 
28
30
  var _helpers = _interopRequireDefault(require("./helpers"));
@@ -98,7 +100,17 @@ var FormRenderer = function FormRenderer(_ref) {
98
100
  var _useState9 = (0, _react.useState)(_helpers.default.getFormState(pageId, pages, hub)),
99
101
  _useState10 = _slicedToArray(_useState9, 2),
100
102
  formState = _useState10[0],
101
- setFormState = _useState10[1]; // Set up hooks.
103
+ setFormState = _useState10[1];
104
+
105
+ var _useState11 = (0, _react.useState)({}),
106
+ _useState12 = _slicedToArray(_useState11, 2),
107
+ currentTask = _useState12[0],
108
+ setCurrentTask = _useState12[1];
109
+
110
+ var _useState13 = (0, _react.useState)({}),
111
+ _useState14 = _slicedToArray(_useState13, 2),
112
+ hubDetails = _useState14[0],
113
+ setHubDetails = _useState14[1]; // Set up hooks.
102
114
 
103
115
 
104
116
  var _useHooks = (0, _hooks2.useHooks)(),
@@ -146,6 +158,36 @@ var FormRenderer = function FormRenderer(_ref) {
146
158
  (0, _react.useEffect)(function () {
147
159
  hooks.onFormLoad();
148
160
  }, [hooks]);
161
+ (0, _react.useEffect)(function () {
162
+ setHubDetails(_hub);
163
+ }, [_hub]); // Update task list pages with form data and update states
164
+
165
+ (0, _react.useEffect)(function () {
166
+ var pages = currentTask.fullPages;
167
+
168
+ if (pages) {
169
+ pages.forEach(function (page) {
170
+ page.formData = data;
171
+ });
172
+ setCurrentTask(function (prev) {
173
+ return _objectSpread(_objectSpread({}, prev), {}, {
174
+ fullPages: pages
175
+ });
176
+ });
177
+ }
178
+
179
+ if (hubDetails !== null && hubDetails !== void 0 && hubDetails.sections) {
180
+ var _data$formStatus2;
181
+
182
+ var tasks = data !== null && data !== void 0 && (_data$formStatus2 = data.formStatus) !== null && _data$formStatus2 !== void 0 && _data$formStatus2.tasks ? data.formStatus.tasks : {};
183
+
184
+ var updatedSections = _helpers.default.getUpdatedSectionStates(hubDetails.sections, tasks);
185
+
186
+ setHubDetails(function (prev) {
187
+ return _objectSpread(_objectSpread({}, prev), updatedSections);
188
+ });
189
+ }
190
+ }, [currentTask.fullPages, data, hubDetails === null || hubDetails === void 0 ? void 0 : hubDetails.sections]);
149
191
 
150
192
  var onPageChange = function onPageChange(newPageId) {
151
193
  setPageId(newPageId);
@@ -166,10 +208,20 @@ var FormRenderer = function FormRenderer(_ref) {
166
208
  components: components
167
209
  }, _objectSpread(_objectSpread({}, data), patch), _models.EventTypes.SUBMIT);
168
210
 
169
- submissionData.formStatus = _helpers.default.getSubmissionStatus(type, pages, pageId, action, submissionData);
211
+ submissionData.formStatus = _helpers.default.getSubmissionStatus(type, pages, pageId, action, submissionData, currentTask);
170
212
 
171
213
  if (patch) {
172
214
  setData(submissionData);
215
+ }
216
+
217
+ var pageUpdate = function pageUpdate(next) {
218
+ return onPageChange(_helpers.default.getNextPageId(type, pages, pageId, action, next));
219
+ };
220
+
221
+ if (action.type === _models.PageAction.TYPES.SAVE_AND_NAVIGATE) {
222
+ pageUpdate = function pageUpdate() {
223
+ return _handlers.default.navigate(action, pageId, onPageChange);
224
+ };
173
225
  } // Now submit the data to the backend...
174
226
 
175
227
 
@@ -178,7 +230,7 @@ var FormRenderer = function FormRenderer(_ref) {
178
230
  setData(function (prev) {
179
231
  var next = _objectSpread(_objectSpread({}, prev), response);
180
232
 
181
- onPageChange(_helpers.default.getNextPageId(type, pages, pageId, action, next));
233
+ pageUpdate(next);
182
234
  return next;
183
235
  });
184
236
  }, function (errors) {
@@ -191,6 +243,23 @@ var FormRenderer = function FormRenderer(_ref) {
191
243
 
192
244
  var onCYARowAction = function onCYARowAction(page) {
193
245
  _handlers.default.cyaAction(page, pageId, onPageChange);
246
+ }; //Kick off a task, gather required pages and move to the correct point
247
+
248
+
249
+ var onTaskAction = function onTaskAction(currentTask) {
250
+ if (currentTask) {
251
+ currentTask.fullPages = [];
252
+ currentTask.pages.forEach(function (page) {
253
+ currentTask.fullPages.push(_helpers.default.getPage(page, pages));
254
+ });
255
+ setCurrentTask(currentTask);
256
+
257
+ if (currentTask.state === _models.TaskStates.TYPES.COMPLETE) {
258
+ onPageChange(_models.FormPages.CYA);
259
+ } else {
260
+ onPageChange(currentTask.pages[0]);
261
+ }
262
+ }
194
263
  }; // Handle actions from "Check your answers".
195
264
 
196
265
 
@@ -215,21 +284,51 @@ var FormRenderer = function FormRenderer(_ref) {
215
284
  });
216
285
  }
217
286
  }
287
+
288
+ if (action.type === _models.PageAction.TYPES.SAVE_AND_RETURN) {
289
+ if (_helpers.default.canCYASubmit(currentTask.fullPages, onError)) {
290
+ var _submissionData = _utils.default.Format.form({
291
+ pages: pages,
292
+ components: components
293
+ }, _objectSpread({}, data), _models.EventTypes.SUBMIT);
294
+
295
+ _submissionData.formStatus = _helpers.default.getSubmissionStatus(type, pages, pageId, action, _submissionData, currentTask);
296
+ setData(_submissionData);
297
+ hooks.onSubmit(action.type, _submissionData, function () {
298
+ return onPageChange(_models.FormPages.HUB);
299
+ }, function (errors) {
300
+ return _handlers.default.submissionError(errors, onError);
301
+ });
302
+ }
303
+ }
218
304
  };
219
305
 
220
306
  var classes = _utils.default.classBuilder(classBlock, classModifiers, className);
221
307
 
308
+ if (hub === _models.HubFormats.TASK) {
309
+ cya.actions = [{
310
+ type: _models.PageAction.TYPES.SAVE_AND_RETURN,
311
+ label: 'Submit',
312
+ validate: true
313
+ }];
314
+ }
315
+
222
316
  return /*#__PURE__*/_react.default.createElement("div", {
223
317
  className: classes()
224
318
  }, title && !hide_title && pageId === _models.FormPages.HUB && /*#__PURE__*/_react.default.createElement(_copReactComponents.LargeHeading, null, title), formState.cya && /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, _extends({
225
- pages: pages
319
+ pages: currentTask.fullPages ? currentTask.fullPages : pages
226
320
  }, cya, formState.cya, {
227
321
  onAction: onCYAAction,
228
322
  onRowAction: onCYARowAction,
229
323
  summaryListClassModifiers: summaryListClassModifiers,
230
324
  hide_title: hide_title,
231
325
  noChangeAction: noChangeAction
232
- })), formState.page && /*#__PURE__*/_react.default.createElement(_FormPage.default, {
326
+ })), hub === _models.HubFormats.TASK && formState.pageId === _models.FormPages.HUB && /*#__PURE__*/_react.default.createElement(_TaskList.default, {
327
+ sections: hubDetails.sections,
328
+ refNumber: data['businessKey'],
329
+ refTitle: _hub.refTitle,
330
+ onTaskAction: onTaskAction
331
+ }), formState.page && /*#__PURE__*/_react.default.createElement(_FormPage.default, {
233
332
  page: formState.page,
234
333
  onAction: onPageAction
235
334
  }));
@@ -239,7 +338,7 @@ FormRenderer.propTypes = {
239
338
  title: _propTypes.default.string,
240
339
 
241
340
  /** See <a href="/?path=/docs/f-json--page#formtypes">FormTypes</a>. */
242
- type: _propTypes.default.oneOf([_models.FormTypes.CYA, _models.FormTypes.FORM, _models.FormTypes.HUB, _models.FormTypes.WIZARD]).isRequired,
341
+ type: _propTypes.default.oneOf([_models.FormTypes.CYA, _models.FormTypes.FORM, _models.FormTypes.HUB, _models.FormTypes.TASK, _models.FormTypes.WIZARD]).isRequired,
243
342
  components: _propTypes.default.arrayOf(_propTypes.default.object).isRequired,
244
343
  pages: _propTypes.default.arrayOf(_propTypes.default.object).isRequired,
245
344
  hub: _propTypes.default.object,
@@ -18,6 +18,8 @@ var _models = require("../../models");
18
18
 
19
19
  var _CheckYourAnswers = require("../CheckYourAnswers/CheckYourAnswers");
20
20
 
21
+ var _TaskList = require("../TaskList/TaskList");
22
+
21
23
  var _FormRenderer = _interopRequireWildcard(require("./FormRenderer"));
22
24
 
23
25
  var _areYouACivilServant = _interopRequireDefault(require("../../json/areYouACivilServant.json"));
@@ -30,6 +32,8 @@ var _userProfileData = _interopRequireDefault(require("../../json/userProfile.da
30
32
 
31
33
  var _userProfile = _interopRequireDefault(require("../../json/userProfile.json"));
32
34
 
35
+ var _taskList = _interopRequireDefault(require("../../json/taskList.json"));
36
+
33
37
  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); }
34
38
 
35
39
  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; }
@@ -507,5 +511,236 @@ describe('components', function () {
507
511
  }
508
512
  }, _callee14);
509
513
  })));
514
+ it('should render a tasklist', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee16() {
515
+ var taskList;
516
+ return regeneratorRuntime.wrap(function _callee16$(_context16) {
517
+ while (1) {
518
+ switch (_context16.prev = _context16.next) {
519
+ case 0:
520
+ _context16.next = 2;
521
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee15() {
522
+ return regeneratorRuntime.wrap(function _callee15$(_context15) {
523
+ while (1) {
524
+ switch (_context15.prev = _context15.next) {
525
+ case 0:
526
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _taskList.default), container);
527
+
528
+ case 1:
529
+ case "end":
530
+ return _context15.stop();
531
+ }
532
+ }
533
+ }, _callee15);
534
+ })));
535
+
536
+ case 2:
537
+ taskList = container.childNodes[0].childNodes[1];
538
+ expect(taskList.classList).toContain(_TaskList.DEFAULT_CLASS);
539
+
540
+ case 4:
541
+ case "end":
542
+ return _context16.stop();
543
+ }
544
+ }
545
+ }, _callee16);
546
+ })));
547
+ it('should handle navigating between task list pages', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee18() {
548
+ var ON_SUBMIT_CALLS, ON_SUBMIT, HOOKS, taskList, firstTaskStatus, secondTaskStatus, firstTask, newPage, continueButton, cyaPage, finalSubmit;
549
+ return regeneratorRuntime.wrap(function _callee18$(_context18) {
550
+ while (1) {
551
+ switch (_context18.prev = _context18.next) {
552
+ case 0:
553
+ ON_SUBMIT_CALLS = [];
554
+
555
+ ON_SUBMIT = function ON_SUBMIT(type, payload, onSuccess, onError) {
556
+ ON_SUBMIT_CALLS.push(payload);
557
+ onSuccess();
558
+ };
559
+
560
+ HOOKS = {
561
+ onSubmit: ON_SUBMIT
562
+ };
563
+ _context18.next = 5;
564
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee17() {
565
+ return regeneratorRuntime.wrap(function _callee17$(_context17) {
566
+ while (1) {
567
+ switch (_context17.prev = _context17.next) {
568
+ case 0:
569
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _taskList.default, {
570
+ hooks: HOOKS
571
+ })), container);
572
+
573
+ case 1:
574
+ case "end":
575
+ return _context17.stop();
576
+ }
577
+ }
578
+ }, _callee17);
579
+ })));
580
+
581
+ case 5:
582
+ taskList = container.childNodes[0].childNodes[1]; //Check status's are correct
583
+
584
+ firstTaskStatus = taskList.childNodes[4].childNodes[0].childNodes[1];
585
+ expect(firstTaskStatus.textContent).toEqual(_models.TaskStates.DETAILS[_models.TaskStates.TYPES.NOT_STARTED].label);
586
+ secondTaskStatus = taskList.childNodes[4].childNodes[1].childNodes[1];
587
+ expect(secondTaskStatus.textContent).toEqual(_models.TaskStates.DETAILS[_models.TaskStates.TYPES.CANNOT_START_YET].label); //Launch first task
588
+
589
+ firstTask = taskList.childNodes[4].childNodes[0].childNodes[0].childNodes[0];
590
+ expect(firstTask.textContent).toEqual('Date, location and mode details');
591
+
592
+ _react.fireEvent.click(firstTask, {}); //Fill first page and navigate
593
+
594
+
595
+ newPage = container.childNodes[0].childNodes[0];
596
+ expect(newPage.childNodes[0].textContent).toEqual('Event Date');
597
+
598
+ _react.fireEvent.change(newPage.childNodes[1].childNodes[2].childNodes[0].childNodes[1], {
599
+ target: {
600
+ name: 'date-day',
601
+ value: '7'
602
+ }
603
+ });
604
+
605
+ _react.fireEvent.change(newPage.childNodes[1].childNodes[2].childNodes[1].childNodes[1], {
606
+ target: {
607
+ name: 'date-month',
608
+ value: '7'
609
+ }
610
+ });
611
+
612
+ _react.fireEvent.change(newPage.childNodes[1].childNodes[2].childNodes[2].childNodes[1], {
613
+ target: {
614
+ name: 'date-year',
615
+ value: '2022'
616
+ }
617
+ });
618
+
619
+ continueButton = newPage.childNodes[2].childNodes[0];
620
+
621
+ _react.fireEvent.click(continueButton, {}); //Fill second page and navigate
622
+
623
+
624
+ newPage = container.childNodes[0].childNodes[0];
625
+ expect(newPage.childNodes[0].textContent).toEqual('Event Mode');
626
+
627
+ _react.fireEvent.click(newPage.childNodes[1].childNodes[2].childNodes[0].childNodes[0], {});
628
+
629
+ continueButton = newPage.childNodes[2].childNodes[0];
630
+
631
+ _react.fireEvent.click(continueButton, {}); //Continue on from CYA page
632
+
633
+
634
+ cyaPage = container.childNodes[0].childNodes[0];
635
+ expect(cyaPage.childNodes[0].textContent).toEqual('Check your answers');
636
+ expect(cyaPage.childNodes[5].textContent).toEqual('Submit');
637
+
638
+ _react.fireEvent.click(cyaPage.childNodes[5].childNodes[0], {}); //Should be back at task list
639
+
640
+
641
+ expect(container.childNodes[0].childNodes[0].textContent).toEqual('Event at the border'); //Check status's are correct
642
+
643
+ firstTaskStatus = container.childNodes[0].childNodes[1].childNodes[4].childNodes[0].childNodes[1];
644
+ expect(firstTaskStatus.textContent).toEqual(_models.TaskStates.DETAILS[_models.TaskStates.TYPES.COMPLETE].label);
645
+ secondTaskStatus = container.childNodes[0].childNodes[1].childNodes[4].childNodes[1].childNodes[1];
646
+ expect(secondTaskStatus.textContent).toEqual(_models.TaskStates.DETAILS[_models.TaskStates.TYPES.NOT_STARTED].label); //Check final data submitted to backend is as expected
647
+
648
+ finalSubmit = ON_SUBMIT_CALLS[ON_SUBMIT_CALLS.length - 1];
649
+ expect(finalSubmit.date).toEqual('7-7-2022');
650
+ expect(finalSubmit.mode).toEqual('sea');
651
+ expect(finalSubmit.formStatus.tasks['Date, location and mode details'].complete).toEqual(true);
652
+
653
+ case 38:
654
+ case "end":
655
+ return _context18.stop();
656
+ }
657
+ }
658
+ }, _callee18);
659
+ })));
660
+ it('should go straight to CYA page if a complete task is selected', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee20() {
661
+ var ON_SUBMIT, HOOKS, taskList, newPage;
662
+ return regeneratorRuntime.wrap(function _callee20$(_context20) {
663
+ while (1) {
664
+ switch (_context20.prev = _context20.next) {
665
+ case 0:
666
+ ON_SUBMIT = function ON_SUBMIT(type, payload, onSuccess, onError) {
667
+ onSuccess();
668
+ };
669
+
670
+ HOOKS = {
671
+ onSubmit: ON_SUBMIT
672
+ };
673
+ _context20.next = 4;
674
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee19() {
675
+ return regeneratorRuntime.wrap(function _callee19$(_context19) {
676
+ while (1) {
677
+ switch (_context19.prev = _context19.next) {
678
+ case 0:
679
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _taskList.default, {
680
+ hooks: HOOKS
681
+ })), container);
682
+
683
+ case 1:
684
+ case "end":
685
+ return _context19.stop();
686
+ }
687
+ }
688
+ }, _callee19);
689
+ })));
690
+
691
+ case 4:
692
+ taskList = container.childNodes[0].childNodes[1]; //Launch first task
693
+
694
+ _react.fireEvent.click(taskList.childNodes[4].childNodes[0].childNodes[0].childNodes[0], {}); //Fill first page and navigate
695
+
696
+
697
+ newPage = container.childNodes[0].childNodes[0];
698
+
699
+ _react.fireEvent.change(newPage.childNodes[1].childNodes[2].childNodes[0].childNodes[1], {
700
+ target: {
701
+ name: 'date-day',
702
+ value: '7'
703
+ }
704
+ });
705
+
706
+ _react.fireEvent.change(newPage.childNodes[1].childNodes[2].childNodes[1].childNodes[1], {
707
+ target: {
708
+ name: 'date-month',
709
+ value: '7'
710
+ }
711
+ });
712
+
713
+ _react.fireEvent.change(newPage.childNodes[1].childNodes[2].childNodes[2].childNodes[1], {
714
+ target: {
715
+ name: 'date-year',
716
+ value: '2022'
717
+ }
718
+ });
719
+
720
+ _react.fireEvent.click(newPage.childNodes[2].childNodes[0], {}); //Fill second page and navigate
721
+
722
+
723
+ newPage = container.childNodes[0].childNodes[0];
724
+
725
+ _react.fireEvent.click(newPage.childNodes[1].childNodes[2].childNodes[0].childNodes[0], {});
726
+
727
+ _react.fireEvent.click(newPage.childNodes[2].childNodes[0], {}); //Continue on from CYA page
728
+
729
+
730
+ _react.fireEvent.click(container.childNodes[0].childNodes[0].childNodes[5].childNodes[0], {}); //Launch same task again
731
+
732
+
733
+ _react.fireEvent.click(container.childNodes[0].childNodes[1].childNodes[4].childNodes[0].childNodes[0].childNodes[0], {}); //Should be at CYA page
734
+
735
+
736
+ expect(container.childNodes[0].childNodes[0].childNodes[0].textContent).toEqual('Check your answers');
737
+
738
+ case 17:
739
+ case "end":
740
+ return _context20.stop();
741
+ }
742
+ }
743
+ }, _callee20);
744
+ })));
510
745
  });
511
746
  });
@@ -60,6 +60,9 @@ var getNextPageId = function getNextPageId(formType, pages, currentPageId, actio
60
60
  case _models.FormTypes.CYA:
61
61
  return getNextCYAPageId(pages, currentPageId, formData);
62
62
 
63
+ case _models.FormTypes.TASK:
64
+ return getNextHubPageId(action);
65
+
63
66
  case _models.FormTypes.WIZARD:
64
67
  return getNextWizardPageId(pages, currentPageId, formData);
65
68
 
@@ -166,6 +166,12 @@ describe('components', function () {
166
166
  expect((0, _getNextPageId.default)(FORM_TYPE, [])).toBeUndefined();
167
167
  });
168
168
  });
169
+ describe("when the form type is '".concat(_models.FormTypes.TASK, "'"), function () {
170
+ var FORM_TYPE = _models.FormTypes.TASK;
171
+ it("should return '".concat(_models.FormPages.HUB, "' by default"), function () {
172
+ expect((0, _getNextPageId.default)(FORM_TYPE, PAGES)).toEqual(_models.FormPages.HUB);
173
+ });
174
+ });
169
175
  });
170
176
  });
171
177
  });
@@ -19,7 +19,7 @@ var _models = require("../../../models");
19
19
  var getPage = function getPage(pageId, pages, hub) {
20
20
  if (pageId) {
21
21
  if (pageId === _models.FormPages.HUB) {
22
- return hub === _models.HubFormats.CYA ? undefined : hub;
22
+ return hub === _models.HubFormats.CYA || hub === _models.HubFormats.TASK ? undefined : hub;
23
23
  }
24
24
 
25
25
  return pages.find(function (p) {
@@ -11,7 +11,24 @@ var _getNextPageId = _interopRequireDefault(require("./getNextPageId"));
11
11
 
12
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
13
 
14
- var getSubmissionStatus = function getSubmissionStatus(formType, pages, currentPageId, action, formData) {
14
+ var getSubmissionStatus = function getSubmissionStatus(formType, pages, currentPageId, action, formData, currentTask) {
15
+ if (formType === _models.FormTypes.TASK) {
16
+ var formStatus = formData.formStatus ? formData.formStatus : {};
17
+ formStatus.tasks = formStatus.tasks ? formStatus.tasks : {};
18
+ formStatus.tasks[currentTask.name] = formStatus.tasks[currentTask.name] ? formStatus.tasks[currentTask.name] : {};
19
+
20
+ if (currentPageId === _models.FormPages.CYA) {
21
+ formStatus.tasks[currentTask.name].complete = true;
22
+ } else {
23
+ formStatus.tasks[currentTask.name] = {
24
+ complete: false,
25
+ currentPage: action.page
26
+ };
27
+ }
28
+
29
+ return formStatus;
30
+ }
31
+
15
32
  if ((action === null || action === void 0 ? void 0 : action.type) === _models.PageAction.TYPES.SAVE_AND_RETURN) {
16
33
  return {
17
34
  page: currentPageId
@@ -2,11 +2,14 @@
2
2
 
3
3
  var _models = require("../../../models");
4
4
 
5
+ var _PageAction = require("../../../models/PageAction");
6
+
5
7
  var _getSubmissionStatus = _interopRequireDefault(require("./getSubmissionStatus"));
6
8
 
7
9
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8
10
 
9
- // Local imports
11
+ 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; }
12
+
10
13
  describe('components', function () {
11
14
  describe('FormRenderer', function () {
12
15
  describe('helpers', function () {
@@ -100,12 +103,14 @@ describe('components', function () {
100
103
  });
101
104
  describe("when the action type is '".concat(_models.PageAction.TYPES.SAVE_AND_RETURN, "'"), function () {
102
105
  Object.values(_models.FormTypes).forEach(function (formType) {
103
- it("should return the current page if the form type is '".concat(formType, "'"), function () {
104
- var ACTION = _models.PageAction.DEFAULTS.saveAndReturn;
105
- expect((0, _getSubmissionStatus.default)(formType, PAGES, PAGES[0].id, ACTION, FORM_DATA)).toMatchObject({
106
- page: PAGES[0].id
106
+ if (formType !== _models.FormTypes.TASK) {
107
+ it("should return the current page if the form type is '".concat(formType, "'"), function () {
108
+ var ACTION = _models.PageAction.DEFAULTS.saveAndReturn;
109
+ expect((0, _getSubmissionStatus.default)(formType, PAGES, PAGES[0].id, ACTION, FORM_DATA)).toMatchObject({
110
+ page: PAGES[0].id
111
+ });
107
112
  });
108
- });
113
+ }
109
114
  });
110
115
  });
111
116
  describe("when the form type is '".concat(_models.FormTypes.HUB, "'"), function () {
@@ -203,6 +208,39 @@ describe('components', function () {
203
208
  });
204
209
  });
205
210
  });
211
+ describe("when the form type is '".concat(_models.FormTypes.TASK, "'"), function () {
212
+ var FORM_TYPE = _models.FormTypes.TASK;
213
+ it("should mark the current task as complete if the current page is '".concat(_models.FormPages.CYA, "'"), function () {
214
+ var CURRENT_PAGE_ID = _models.FormPages.CYA;
215
+ var TASK_NAME = 'taskName';
216
+ var CURRENT_TASK = {
217
+ name: TASK_NAME
218
+ };
219
+ expect((0, _getSubmissionStatus.default)(FORM_TYPE, PAGES, CURRENT_PAGE_ID, undefined, {}, CURRENT_TASK)).toMatchObject({
220
+ tasks: _defineProperty({}, TASK_NAME, {
221
+ complete: true
222
+ })
223
+ });
224
+ });
225
+ it("should update the current task with the next page and a false complete flag if the current page is not '".concat(_models.FormPages.CYA, "'"), function () {
226
+ var CURRENT_PAGE_ID = 'eventDate';
227
+ var TASK_NAME = 'taskName';
228
+ var CURRENT_TASK = {
229
+ name: TASK_NAME
230
+ };
231
+ var NEXT_PAGE_ID = 'eventMode';
232
+ var ACTION = {
233
+ type: _PageAction.PageActionTypes.SAVE_AND_NAVIGATE,
234
+ page: NEXT_PAGE_ID
235
+ };
236
+ expect((0, _getSubmissionStatus.default)(FORM_TYPE, PAGES, CURRENT_PAGE_ID, ACTION, {}, CURRENT_TASK)).toMatchObject({
237
+ tasks: _defineProperty({}, TASK_NAME, {
238
+ complete: false,
239
+ currentPage: NEXT_PAGE_ID
240
+ })
241
+ });
242
+ });
243
+ });
206
244
  });
207
245
  });
208
246
  });
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _models = require("../../../models");
9
+
10
+ /**
11
+ * Updates the given task list sections with the latest states
12
+ * @param {object} sections The JSON defining the sections in the task list
13
+ * @param {object} tasks object with entry for each task containing currentPage and complete boolean flag
14
+ * {
15
+ "TaskName": {
16
+ "complete": true,
17
+ "currentPage": "pageId"
18
+ }
19
+ }
20
+ * @returns An JSON representation of the task list sections with up to date states
21
+ */
22
+ var getUpdatedSectionStates = function getUpdatedSectionStates(sections, tasks) {
23
+ return sections.map(function (section, sectionIndex, sectionArray) {
24
+ return section.tasks.map(function (task, taskIndex, taskArray) {
25
+ if (tasks[task.name]) {
26
+ if (tasks[task.name].complete) {
27
+ task.state = _models.TaskStates.TYPES.COMPLETE;
28
+ } else if (tasks[task.name].currentPage) {
29
+ task.state = _models.TaskStates.TYPES.IN_PROGRESS;
30
+ }
31
+ } else {
32
+ var _taskArray, _sectionArray, _sectionArray$tasks$s;
33
+
34
+ if (taskIndex === 0 && sectionIndex === 0 || //First task in tasklist
35
+ ((_taskArray = taskArray[taskIndex - 1]) === null || _taskArray === void 0 ? void 0 : _taskArray.state) === _models.TaskStates.TYPES.COMPLETE || //any task after a complete task in same section
36
+ taskIndex === 0 && ((_sectionArray = sectionArray[sectionIndex - 1]) === null || _sectionArray === void 0 ? void 0 : (_sectionArray$tasks$s = _sectionArray.tasks.slice(-1)[0]) === null || _sectionArray$tasks$s === void 0 ? void 0 : _sectionArray$tasks$s.state) === _models.TaskStates.TYPES.COMPLETE //any task after a complete task in the preceeding section
37
+ ) {
38
+ task.state = _models.TaskStates.TYPES.NOT_STARTED;
39
+ } else {
40
+ task.state = _models.TaskStates.TYPES.CANNOT_START_YET;
41
+ }
42
+ }
43
+
44
+ return task;
45
+ });
46
+ });
47
+ };
48
+
49
+ var _default = getUpdatedSectionStates;
50
+ exports.default = _default;