@ukhomeoffice/cop-react-form-renderer 4.48.0 → 4.51.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.
@@ -283,7 +283,7 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
283
283
 
284
284
  var tasks = (data === null || data === void 0 ? void 0 : (_data$formStatus2 = data.formStatus) === null || _data$formStatus2 === void 0 ? void 0 : _data$formStatus2.tasks) || {};
285
285
 
286
- var updatedSections = _helpers.default.getUpdatedSectionStates(theSections, tasks, nonSequential);
286
+ var updatedSections = _helpers.default.getUpdatedSectionStates(theSections, tasks, nonSequential, data);
287
287
 
288
288
  setHubDetails(function (prev) {
289
289
  return _objectSpread(_objectSpread({}, prev), {}, {
@@ -616,7 +616,8 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
616
616
  type: type
617
617
  })), hub === _models.HubFormats.TASK && formState.pageId === _models.FormPages.HUB && /*#__PURE__*/_react.default.createElement(_TaskList.default, _extends({}, hubDetails, {
618
618
  refNumber: data.businessKey,
619
- onTaskAction: onTaskAction
619
+ onTaskAction: onTaskAction,
620
+ formData: data
620
621
  })), formState.page && !formState.cya && !formState.page.collection && /*#__PURE__*/_react.default.createElement(_FormPage.default, {
621
622
  page: formState.page,
622
623
  onAction: onPageAction
@@ -591,8 +591,8 @@ describe('components', function () {
591
591
  }
592
592
  }, _callee18);
593
593
  })));
594
- it('should handle navigating between task list pages', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee20() {
595
- var ON_SUBMIT_CALLS, ON_SUBMIT, HOOKS, taskList, firstTaskStatus, secondTaskStatus, firstTask, newPage, continueButton, seaButton, cyaPageChange, modeChangeLink, changePage, airButton, cyaPage, finalSubmit;
594
+ it('should load tasklist with notes', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee20() {
595
+ var ON_SUBMIT_CALLS, ON_SUBMIT, HOOKS, TASK_LIST_WITH_NOTES, taskList, notesText;
596
596
  return regeneratorRuntime.wrap(function _callee20$(_context20) {
597
597
  while (1) {
598
598
  switch (_context20.prev = _context20.next) {
@@ -607,13 +607,18 @@ describe('components', function () {
607
607
  HOOKS = {
608
608
  onSubmit: ON_SUBMIT
609
609
  };
610
- _context20.next = 5;
610
+ TASK_LIST_WITH_NOTES = JSON.parse(JSON.stringify(_taskList.default));
611
+ TASK_LIST_WITH_NOTES.hub.notes = {
612
+ title: "test title",
613
+ text: "test text"
614
+ };
615
+ _context20.next = 7;
611
616
  return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee19() {
612
617
  return regeneratorRuntime.wrap(function _callee19$(_context19) {
613
618
  while (1) {
614
619
  switch (_context19.prev = _context19.next) {
615
620
  case 0:
616
- (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _taskList.default, {
621
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, TASK_LIST_WITH_NOTES, {
617
622
  hooks: HOOKS
618
623
  })), container);
619
624
 
@@ -625,6 +630,52 @@ describe('components', function () {
625
630
  }, _callee19);
626
631
  })));
627
632
 
633
+ case 7:
634
+ taskList = container.childNodes[0].childNodes[1];
635
+ notesText = taskList.childNodes[3];
636
+ expect(notesText.textContent).toEqual("test text");
637
+
638
+ case 10:
639
+ case "end":
640
+ return _context20.stop();
641
+ }
642
+ }
643
+ }, _callee20);
644
+ })));
645
+ it('should handle navigating between task list pages', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee22() {
646
+ var ON_SUBMIT_CALLS, ON_SUBMIT, HOOKS, taskList, firstTaskStatus, secondTaskStatus, firstTask, newPage, continueButton, seaButton, cyaPageChange, modeChangeLink, changePage, airButton, cyaPage, finalSubmit;
647
+ return regeneratorRuntime.wrap(function _callee22$(_context22) {
648
+ while (1) {
649
+ switch (_context22.prev = _context22.next) {
650
+ case 0:
651
+ ON_SUBMIT_CALLS = [];
652
+
653
+ ON_SUBMIT = function ON_SUBMIT(type, payload, onSuccess, onError) {
654
+ ON_SUBMIT_CALLS.push(payload);
655
+ onSuccess();
656
+ };
657
+
658
+ HOOKS = {
659
+ onSubmit: ON_SUBMIT
660
+ };
661
+ _context22.next = 5;
662
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee21() {
663
+ return regeneratorRuntime.wrap(function _callee21$(_context21) {
664
+ while (1) {
665
+ switch (_context21.prev = _context21.next) {
666
+ case 0:
667
+ (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _taskList.default, {
668
+ hooks: HOOKS
669
+ })), container);
670
+
671
+ case 1:
672
+ case "end":
673
+ return _context21.stop();
674
+ }
675
+ }
676
+ }, _callee21);
677
+ })));
678
+
628
679
  case 5:
629
680
  taskList = container.childNodes[0].childNodes[1]; //Check statuses are correct
630
681
 
@@ -724,16 +775,16 @@ describe('components', function () {
724
775
 
725
776
  case 54:
726
777
  case "end":
727
- return _context20.stop();
778
+ return _context22.stop();
728
779
  }
729
780
  }
730
- }, _callee20);
781
+ }, _callee22);
731
782
  })));
732
- it('should go straight to CYA page if a complete task is selected', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee22() {
783
+ it('should go straight to CYA page if a complete task is selected', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee24() {
733
784
  var ON_SUBMIT, HOOKS, taskList, newPage;
734
- return regeneratorRuntime.wrap(function _callee22$(_context22) {
785
+ return regeneratorRuntime.wrap(function _callee24$(_context24) {
735
786
  while (1) {
736
- switch (_context22.prev = _context22.next) {
787
+ switch (_context24.prev = _context24.next) {
737
788
  case 0:
738
789
  ON_SUBMIT = function ON_SUBMIT(type, payload, onSuccess, onError) {
739
790
  onSuccess();
@@ -742,11 +793,11 @@ describe('components', function () {
742
793
  HOOKS = {
743
794
  onSubmit: ON_SUBMIT
744
795
  };
745
- _context22.next = 4;
746
- return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee21() {
747
- return regeneratorRuntime.wrap(function _callee21$(_context21) {
796
+ _context24.next = 4;
797
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee23() {
798
+ return regeneratorRuntime.wrap(function _callee23$(_context23) {
748
799
  while (1) {
749
- switch (_context21.prev = _context21.next) {
800
+ switch (_context23.prev = _context23.next) {
750
801
  case 0:
751
802
  (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _taskList.default, {
752
803
  hooks: HOOKS
@@ -754,10 +805,10 @@ describe('components', function () {
754
805
 
755
806
  case 1:
756
807
  case "end":
757
- return _context21.stop();
808
+ return _context23.stop();
758
809
  }
759
810
  }
760
- }, _callee21);
811
+ }, _callee23);
761
812
  })));
762
813
 
763
814
  case 4:
@@ -809,16 +860,16 @@ describe('components', function () {
809
860
 
810
861
  case 17:
811
862
  case "end":
812
- return _context22.stop();
863
+ return _context24.stop();
813
864
  }
814
865
  }
815
- }, _callee22);
866
+ }, _callee24);
816
867
  })));
817
- it('should go to the last page of a complete task if noTaskCYAs specified', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee24() {
868
+ it('should go to the last page of a complete task if noTaskCYAs specified', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee26() {
818
869
  var ON_SUBMIT, HOOKS, TASK_LIST_WITH_NO_TASK_CYAS, taskList, newPage;
819
- return regeneratorRuntime.wrap(function _callee24$(_context24) {
870
+ return regeneratorRuntime.wrap(function _callee26$(_context26) {
820
871
  while (1) {
821
- switch (_context24.prev = _context24.next) {
872
+ switch (_context26.prev = _context26.next) {
822
873
  case 0:
823
874
  ON_SUBMIT = function ON_SUBMIT(type, payload, onSuccess, onError) {
824
875
  onSuccess();
@@ -833,11 +884,11 @@ describe('components', function () {
833
884
  type: 'save',
834
885
  complete: true
835
886
  };
836
- _context24.next = 7;
837
- return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee23() {
838
- return regeneratorRuntime.wrap(function _callee23$(_context23) {
887
+ _context26.next = 7;
888
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee25() {
889
+ return regeneratorRuntime.wrap(function _callee25$(_context25) {
839
890
  while (1) {
840
- switch (_context23.prev = _context23.next) {
891
+ switch (_context25.prev = _context25.next) {
841
892
  case 0:
842
893
  (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, TASK_LIST_WITH_NO_TASK_CYAS, {
843
894
  hooks: HOOKS
@@ -845,10 +896,10 @@ describe('components', function () {
845
896
 
846
897
  case 1:
847
898
  case "end":
848
- return _context23.stop();
899
+ return _context25.stop();
849
900
  }
850
901
  }
851
- }, _callee23);
902
+ }, _callee25);
852
903
  })));
853
904
 
854
905
  case 7:
@@ -897,17 +948,17 @@ describe('components', function () {
897
948
 
898
949
  case 19:
899
950
  case "end":
900
- return _context24.stop();
951
+ return _context26.stop();
901
952
  }
902
953
  }
903
- }, _callee24);
954
+ }, _callee26);
904
955
  })));
905
- it('should handle cancellation from a page', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee26() {
956
+ it('should handle cancellation from a page', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee28() {
906
957
  var ON_CANCEL_CALLS, ON_CANCEL, HOOKS, form, hub, _hub$childNodes5, civilServantList, link, page, cancel;
907
958
 
908
- return regeneratorRuntime.wrap(function _callee26$(_context26) {
959
+ return regeneratorRuntime.wrap(function _callee28$(_context28) {
909
960
  while (1) {
910
- switch (_context26.prev = _context26.next) {
961
+ switch (_context28.prev = _context28.next) {
911
962
  case 0:
912
963
  ON_CANCEL_CALLS = [];
913
964
 
@@ -918,11 +969,11 @@ describe('components', function () {
918
969
  HOOKS = {
919
970
  onCancel: ON_CANCEL
920
971
  };
921
- _context26.next = 5;
922
- return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee25() {
923
- return regeneratorRuntime.wrap(function _callee25$(_context25) {
972
+ _context28.next = 5;
973
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee27() {
974
+ return regeneratorRuntime.wrap(function _callee27$(_context27) {
924
975
  while (1) {
925
- switch (_context25.prev = _context25.next) {
976
+ switch (_context27.prev = _context27.next) {
926
977
  case 0:
927
978
  (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
928
979
  data: _userProfileData.default,
@@ -931,10 +982,10 @@ describe('components', function () {
931
982
 
932
983
  case 1:
933
984
  case "end":
934
- return _context25.stop();
985
+ return _context27.stop();
935
986
  }
936
987
  }
937
- }, _callee25);
988
+ }, _callee27);
938
989
  })));
939
990
 
940
991
  case 5:
@@ -958,16 +1009,16 @@ describe('components', function () {
958
1009
 
959
1010
  case 15:
960
1011
  case "end":
961
- return _context26.stop();
1012
+ return _context28.stop();
962
1013
  }
963
1014
  }
964
- }, _callee26);
1015
+ }, _callee28);
965
1016
  })));
966
- it('should navigate to a specific page at the beginning of a task if it is set as the firstPage of a task', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee28() {
1017
+ it('should navigate to a specific page at the beginning of a task if it is set as the firstPage of a task', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee30() {
967
1018
  var ON_SUBMIT_CALLS, ON_SUBMIT, HOOKS, TASK_LIST_NON_SEQUENTIAL, taskList, firstTask, newPage;
968
- return regeneratorRuntime.wrap(function _callee28$(_context28) {
1019
+ return regeneratorRuntime.wrap(function _callee30$(_context30) {
969
1020
  while (1) {
970
- switch (_context28.prev = _context28.next) {
1021
+ switch (_context30.prev = _context30.next) {
971
1022
  case 0:
972
1023
  ON_SUBMIT_CALLS = [];
973
1024
 
@@ -981,11 +1032,11 @@ describe('components', function () {
981
1032
  };
982
1033
  TASK_LIST_NON_SEQUENTIAL = JSON.parse(JSON.stringify(_taskList.default));
983
1034
  TASK_LIST_NON_SEQUENTIAL.hub.nonSequential = true;
984
- _context28.next = 7;
985
- return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee27() {
986
- return regeneratorRuntime.wrap(function _callee27$(_context27) {
1035
+ _context30.next = 7;
1036
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee29() {
1037
+ return regeneratorRuntime.wrap(function _callee29$(_context29) {
987
1038
  while (1) {
988
- switch (_context27.prev = _context27.next) {
1039
+ switch (_context29.prev = _context29.next) {
989
1040
  case 0:
990
1041
  (0, _reactDom.render)( /*#__PURE__*/_react2.default.createElement(_FormRenderer.default, _extends({}, TASK_LIST_NON_SEQUENTIAL, {
991
1042
  hooks: HOOKS
@@ -993,10 +1044,10 @@ describe('components', function () {
993
1044
 
994
1045
  case 1:
995
1046
  case "end":
996
- return _context27.stop();
1047
+ return _context29.stop();
997
1048
  }
998
1049
  }
999
- }, _callee27);
1050
+ }, _callee29);
1000
1051
  })));
1001
1052
 
1002
1053
  case 7:
@@ -1013,10 +1064,10 @@ describe('components', function () {
1013
1064
 
1014
1065
  case 13:
1015
1066
  case "end":
1016
- return _context28.stop();
1067
+ return _context30.stop();
1017
1068
  }
1018
1069
  }
1019
- }, _callee28);
1070
+ }, _callee30);
1020
1071
  })));
1021
1072
  });
1022
1073
  });
@@ -5,8 +5,12 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
+ var _utils = _interopRequireDefault(require("../../../utils"));
9
+
8
10
  var _models = require("../../../models");
9
11
 
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
10
14
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
11
15
 
12
16
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
@@ -93,28 +97,66 @@ var updateTasks = function updateTasks(section, sectionIndex, tasks, nonSequenti
93
97
  return _objectSpread({}, a);
94
98
  });
95
99
  clone.forEach(function (task, taskIndex, taskList) {
96
- task.state = updateTaskState(task, taskIndex, taskList, tasks, nonSequential, allowFirst);
100
+ if (section.skipped) {
101
+ task.state = _models.TaskStates.TYPES.SKIPPED;
102
+ } else {
103
+ task.state = updateTaskState(task, taskIndex, taskList, tasks, nonSequential, allowFirst);
104
+ }
97
105
  });
98
106
  return clone;
99
107
  };
108
+ /**
109
+ * Checks if the previous section has been completed. If the last section
110
+ * was skipped then this function will check the section before that until
111
+ * the state of a non-skipped section can be found.
112
+ * @param {array} sections - array of sections
113
+ * @param {number} currentIndex - index of the current section
114
+ * @returns {boolean} true if the last non-skipped section is complete, false
115
+ * if not.
116
+ */
117
+
118
+
119
+ var isPreviousSectionComplete = function isPreviousSectionComplete(sections, currentIndex) {
120
+ var _sections, _sections$tasks$slice;
121
+
122
+ var lastTaskState = (_sections = sections[currentIndex - 1]) === null || _sections === void 0 ? void 0 : (_sections$tasks$slice = _sections.tasks.slice(-1)[0]) === null || _sections$tasks$slice === void 0 ? void 0 : _sections$tasks$slice.state;
123
+
124
+ if (lastTaskState === _models.TaskStates.TYPES.COMPLETE) {
125
+ return true;
126
+ }
127
+
128
+ if (lastTaskState === _models.TaskStates.TYPES.SKIPPED) {
129
+ return currentIndex - 1 === 0 ? true : isPreviousSectionComplete(sections, currentIndex - 1);
130
+ }
131
+
132
+ return false;
133
+ };
100
134
  /**
101
135
  * update task states in sections
102
136
  * @param {object[]} sections - array of sections
103
137
  * @param {object} tasks - update task states
104
138
  * @param {boolean} nonSequential - true if tasks can be performed non-sequentially
139
+ * @param {object} data - current form data
105
140
  * @returns {object[]} - updated sections - note this is a clone
106
141
  */
107
142
 
108
143
 
109
144
  var getUpdatedSectionStates = function getUpdatedSectionStates(sections, tasks) {
110
145
  var nonSequential = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
146
+ var data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
111
147
  var clone = sections.map(function (a) {
112
148
  return _objectSpread({}, a);
113
149
  });
114
150
  clone.forEach(function (section, sectionIndex, sectionList) {
115
- var _sectionList, _sectionList$tasks$sl;
151
+ var _section$show_when;
152
+
153
+ var allowFirst = sectionIndex === 0 || isPreviousSectionComplete(sectionList, sectionIndex); // Support a single show_when check on a section. Support for an
154
+ // array of checks will have to be added if required.
155
+
156
+ if (data && !_utils.default.Condition.met(section.show_when, data[(_section$show_when = section.show_when) === null || _section$show_when === void 0 ? void 0 : _section$show_when.field])) {
157
+ section.skipped = true;
158
+ }
116
159
 
117
- var allowFirst = sectionIndex === 0 || ((_sectionList = sectionList[sectionIndex - 1]) === null || _sectionList === void 0 ? void 0 : (_sectionList$tasks$sl = _sectionList.tasks.slice(-1)[0]) === null || _sectionList$tasks$sl === void 0 ? void 0 : _sectionList$tasks$sl.state) === _models.TaskStates.TYPES.COMPLETE;
118
160
  section.tasks = updateTasks(section, sectionIndex, tasks, nonSequential, allowFirst);
119
161
  });
120
162
  return clone;
@@ -114,6 +114,85 @@ describe('components.FormRenderer.helpers.getUpdatedSectionStates', function ()
114
114
  expect(updatedSections[0].tasks[0].state).toEqual(_models.TaskStates.TYPES.IN_PROGRESS);
115
115
  expect(updatedSections[0].tasks[1].state).toEqual(_models.TaskStates.TYPES.CANNOT_START_YET);
116
116
  });
117
+ it("should set the status of any tasks in a section with a failed show_when to '".concat(_models.TaskStates.TYPES.SKIPPED, "'"), function () {
118
+ var SECTIONS = [{
119
+ name: 'Add event details',
120
+ tasks: [{
121
+ name: 'Date, location and mode details',
122
+ pages: ['eventDate', 'eventMode']
123
+ }, {
124
+ name: 'Officer and agency details',
125
+ pages: ['officeDetails']
126
+ }]
127
+ }, {
128
+ name: 'Add people details',
129
+ show_when: {
130
+ field: 'field',
131
+ op: '=',
132
+ value: 'showMe'
133
+ },
134
+ tasks: [{
135
+ name: 'People details',
136
+ pages: ['firstName', 'surname']
137
+ }, {
138
+ name: 'Immigration details',
139
+ pages: ['immigrationDate']
140
+ }]
141
+ }];
142
+ var TASKS = {
143
+ 'Date, location and mode details': {
144
+ complete: true
145
+ },
146
+ 'Officer and agency details': {
147
+ complete: true
148
+ }
149
+ };
150
+ var DATA = {
151
+ field: 'hideMe'
152
+ };
153
+ var updatedSections = (0, _getUpdatedSectionStates.default)(SECTIONS, TASKS, false, DATA);
154
+ expect(updatedSections[0].tasks[0].state).toEqual(_models.TaskStates.TYPES.COMPLETE);
155
+ expect(updatedSections[0].tasks[1].state).toEqual(_models.TaskStates.TYPES.COMPLETE);
156
+ expect(updatedSections[1].skipped).toEqual(true);
157
+ expect(updatedSections[1].tasks[0].state).toEqual(_models.TaskStates.TYPES.SKIPPED);
158
+ expect(updatedSections[1].tasks[1].state).toEqual(_models.TaskStates.TYPES.SKIPPED);
159
+ });
160
+ });
161
+ it("should set the status of any tasks to '".concat(_models.TaskStates.TYPES.NOT_STARTED, "' if previous tasks have been skipped"), function () {
162
+ var SECTIONS = [{
163
+ name: 'Add event details',
164
+ show_when: {
165
+ field: 'field',
166
+ op: '=',
167
+ value: 'showMe'
168
+ },
169
+ tasks: [{
170
+ name: 'Date, location and mode details',
171
+ pages: ['eventDate', 'eventMode']
172
+ }, {
173
+ name: 'Officer and agency details',
174
+ pages: ['officeDetails']
175
+ }]
176
+ }, {
177
+ name: 'Add people details',
178
+ tasks: [{
179
+ name: 'People details',
180
+ pages: ['firstName', 'surname']
181
+ }, {
182
+ name: 'Immigration details',
183
+ pages: ['immigrationDate']
184
+ }]
185
+ }];
186
+ var TASKS = {};
187
+ var DATA = {
188
+ field: 'hideMe'
189
+ };
190
+ var updatedSections = (0, _getUpdatedSectionStates.default)(SECTIONS, TASKS, false, DATA);
191
+ expect(updatedSections[0].skipped).toEqual(true);
192
+ expect(updatedSections[0].tasks[0].state).toEqual(_models.TaskStates.TYPES.SKIPPED);
193
+ expect(updatedSections[0].tasks[1].state).toEqual(_models.TaskStates.TYPES.SKIPPED);
194
+ expect(updatedSections[1].tasks[0].state).toEqual(_models.TaskStates.TYPES.NOT_STARTED);
195
+ expect(updatedSections[1].tasks[1].state).toEqual(_models.TaskStates.TYPES.CANNOT_START_YET);
117
196
  });
118
197
  describe('non-sequential tasks', function () {
119
198
  var NON_SEQUENTIAL = true;
@@ -21,7 +21,7 @@ var _Task = _interopRequireDefault(require("./Task"));
21
21
 
22
22
  require("./TaskList.scss");
23
23
 
24
- var _excluded = ["refTitle", "refNumber", "incompleteTitle", "sections", "fieldId", "onTaskAction", "classBlock", "classModifiers", "className"];
24
+ var _excluded = ["refTitle", "refNumber", "notes", "incompleteTitle", "sections", "fieldId", "onTaskAction", "classBlock", "classModifiers", "className"];
25
25
 
26
26
  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); }
27
27
 
@@ -55,6 +55,7 @@ exports.DEFAULT_INCOMPLETE_TITLE = DEFAULT_INCOMPLETE_TITLE;
55
55
  var TaskList = function TaskList(_ref) {
56
56
  var refTitle = _ref.refTitle,
57
57
  refNumber = _ref.refNumber,
58
+ notes = _ref.notes,
58
59
  incompleteTitle = _ref.incompleteTitle,
59
60
  sections = _ref.sections,
60
61
  fieldId = _ref.fieldId,
@@ -78,6 +79,12 @@ var TaskList = function TaskList(_ref) {
78
79
  completeSections = _sections$reduce2[0],
79
80
  totalSections = _sections$reduce2[1];
80
81
 
82
+ var notesId = "".concat(attrs.id, "Notes");
83
+
84
+ var _ref2 = notes ? notes : {},
85
+ notesTitle = _ref2.title,
86
+ notesText = _ref2.text;
87
+
81
88
  var onClick = function onClick(task) {
82
89
  if (typeof onTaskAction === 'function') {
83
90
  onTaskAction(task);
@@ -98,7 +105,18 @@ var TaskList = function TaskList(_ref) {
98
105
  className: "tasklist-summary"
99
106
  }, incompleteTitle)), /*#__PURE__*/_react.default.createElement("p", {
100
107
  className: "govuk-body govuk-!-margin-bottom-7"
101
- }, "You have completed ".concat(completeSections, " of ").concat(totalSections, " sections")), sections.map(function (section, index) {
108
+ }, "You have completed ".concat(completeSections, " of ").concat(totalSections, " sections")), notesTitle && notesText && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("p", {
109
+ className: "govuk-body govuk-!-margin-bottom-0"
110
+ }, /*#__PURE__*/_react.default.createElement("strong", {
111
+ className: "tasklist-summary"
112
+ }, _copReactComponents.Utils.interpolateString(notesTitle, attrs.formData))), /*#__PURE__*/_react.default.createElement(_copReactComponents.TextArea, {
113
+ id: notesId,
114
+ fieldId: notesId,
115
+ readOnly: true,
116
+ value: _copReactComponents.Utils.interpolateString(notesText, attrs.formData)
117
+ })), sections.filter(function (section) {
118
+ return !section.skipped;
119
+ }).map(function (section, index) {
102
120
  return /*#__PURE__*/_react.default.createElement(_react.Fragment, {
103
121
  key: "".concat(section.name)
104
122
  }, /*#__PURE__*/_react.default.createElement("h2", {
@@ -118,6 +136,10 @@ var TaskList = function TaskList(_ref) {
118
136
  TaskList.propTypes = {
119
137
  refTitle: _propTypes.default.string,
120
138
  refNumber: _propTypes.default.string,
139
+ notes: _propTypes.default.shape({
140
+ title: _propTypes.default.string,
141
+ text: _propTypes.default.string
142
+ }),
121
143
  incompleteTitle: _propTypes.default.string,
122
144
  sections: _propTypes.default.arrayOf(_propTypes.default.shape({
123
145
  name: _propTypes.default.string.isRequired,
@@ -13,11 +13,13 @@ var TYPE_COMPLETE = 'complete';
13
13
  var TYPE_IN_PROGRESS = 'inProgress';
14
14
  var TYPE_NOT_STARTED = 'notStarted';
15
15
  var TYPE_CANNOT_START_YET = 'cannotStartYet';
16
+ var TYPE_SKIPPED = 'skipped';
16
17
  var StateTypes = {
17
18
  COMPLETE: TYPE_COMPLETE,
18
19
  IN_PROGRESS: TYPE_IN_PROGRESS,
19
20
  NOT_STARTED: TYPE_NOT_STARTED,
20
- CANNOT_START_YET: TYPE_CANNOT_START_YET
21
+ CANNOT_START_YET: TYPE_CANNOT_START_YET,
22
+ SKIPPED: TYPE_SKIPPED
21
23
  };
22
24
  exports.StateTypes = StateTypes;
23
25
  var StateDetails = (_StateDetails = {}, _defineProperty(_StateDetails, TYPE_COMPLETE, {
@@ -32,6 +34,9 @@ var StateDetails = (_StateDetails = {}, _defineProperty(_StateDetails, TYPE_COMP
32
34
  }), _defineProperty(_StateDetails, TYPE_CANNOT_START_YET, {
33
35
  label: 'Cannot Start Yet',
34
36
  colour: 'dark-grey'
37
+ }), _defineProperty(_StateDetails, TYPE_SKIPPED, {
38
+ label: 'Skipped',
39
+ colour: 'dark-grey'
35
40
  }), _StateDetails);
36
41
  var TaskStates = {
37
42
  TYPES: StateTypes,
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _copReactComponents = require("@ukhomeoffice/cop-react-components");
9
+
10
+ var _getSourceData = _interopRequireDefault(require("../Data/getSourceData"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ // Global imports.
15
+ // Local imports.
16
+ var getFirstOf = function getFirstOf(config, data) {
17
+ var fieldValue;
18
+
19
+ if (config !== null && config !== void 0 && config.fields) {
20
+ config.fields.find(function (field) {
21
+ var fieldPath = _copReactComponents.Utils.interpolateString(field, data);
22
+
23
+ var foundValue = (0, _getSourceData.default)(data, fieldPath);
24
+
25
+ if (foundValue) {
26
+ fieldValue = foundValue;
27
+ return true;
28
+ }
29
+
30
+ return false;
31
+ });
32
+ return fieldValue || '';
33
+ }
34
+
35
+ return (config === null || config === void 0 ? void 0 : config.value) || null;
36
+ };
37
+
38
+ var _default = getFirstOf;
39
+ exports.default = _default;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+
3
+ var _getFirstOf = _interopRequireDefault(require("./getFirstOf"));
4
+
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+
7
+ describe('Utils.Operate.addToFormData', function () {
8
+ var DATA = {
9
+ name: 'sam',
10
+ id: 1,
11
+ test: ['2', '3'],
12
+ idName: 'passport',
13
+ passportNumber: 123,
14
+ otherIdDoc: '',
15
+ anotherMadeUpId: 789
16
+ };
17
+ it('Should handle interpolated field strings', function () {
18
+ // eslint-disable-next-line no-template-curly-in-string
19
+ var CONFIG = {
20
+ fields: ['test[${id}]']
21
+ };
22
+ var result = (0, _getFirstOf.default)(CONFIG, DATA);
23
+ expect(result).toEqual(DATA.test[1]);
24
+ });
25
+ it('Should return the value provided in config if no field is specified', function () {
26
+ var CONFIG = {
27
+ value: '2'
28
+ };
29
+ var result = (0, _getFirstOf.default)(CONFIG, DATA);
30
+ expect(result).toEqual(CONFIG.value);
31
+ });
32
+ it('Should return the value of the passportNumber field given in config', function () {
33
+ var CONFIG = {
34
+ fields: ['passportNumber', 'anotherMadeUpId', 'otherIdDoc']
35
+ };
36
+ var result = (0, _getFirstOf.default)(CONFIG, DATA);
37
+ expect(result).toEqual(DATA.passportNumber);
38
+ });
39
+ it('Should return the value of the anotherMadeUpId field given in config', function () {
40
+ var CONFIG = {
41
+ fields: ['anotherMadeUpId', 'passportNumber', 'otherIdDoc']
42
+ };
43
+ var result = (0, _getFirstOf.default)(CONFIG, DATA);
44
+ expect(result).toEqual(DATA.anotherMadeUpId);
45
+ });
46
+ it('Should return the value of the otherIdDoc field given in config', function () {
47
+ var CONFIG = {
48
+ fields: ['otherIdDoc', 'passportNumber', 'anotherMadeUpId']
49
+ };
50
+ var result = (0, _getFirstOf.default)(CONFIG, DATA);
51
+ expect(result).toEqual(DATA.passportNumber);
52
+ });
53
+ it('Should return the value of the otherIdDoc field given in config, if it exists, otherwise next field next in the array', function () {
54
+ var CONFIG = {
55
+ fields: ['otherIdDoc', 'passportNumber', 'anotherMadeUpId']
56
+ };
57
+ var result = (0, _getFirstOf.default)(CONFIG, DATA);
58
+ expect(result).toEqual(DATA.passportNumber);
59
+ });
60
+ it('Should return no value if elements in config.fields are not found in data', function () {
61
+ var CONFIG = {
62
+ fields: ['otherIdDoc1', 'passportNumber1', 'anotherMadeUpId1']
63
+ };
64
+ var result = (0, _getFirstOf.default)(CONFIG, DATA);
65
+ expect(result).toEqual('');
66
+ });
67
+ it('Should return null when an invalid config is used', function () {
68
+ var result = (0, _getFirstOf.default)(null, DATA);
69
+ expect(result).toEqual(null);
70
+ });
71
+ it('Should return null when invalid data is used', function () {
72
+ var CONFIG = {
73
+ field: 'a'
74
+ };
75
+ var result = (0, _getFirstOf.default)(CONFIG, null);
76
+ expect(result).toEqual(null);
77
+ });
78
+ });
@@ -19,6 +19,8 @@ var _shouldRun = _interopRequireDefault(require("./shouldRun"));
19
19
 
20
20
  var _setDataItem = _interopRequireDefault(require("../Data/setDataItem"));
21
21
 
22
+ var _getFirstOf = _interopRequireDefault(require("./getFirstOf"));
23
+
22
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
25
 
24
26
  // Global imports.
@@ -27,7 +29,8 @@ var functions = {
27
29
  checkValueIsTruthy: _checkValueIsTruthy.default,
28
30
  getIndexOfMatchingValueIn: _getIndexOfMatchingValueIn.default,
29
31
  persistValueInFormData: _persistValueInFormData.default,
30
- setValueInFormData: _setValueInFormData.default
32
+ setValueInFormData: _setValueInFormData.default,
33
+ getFirstOf: _getFirstOf.default
31
34
  };
32
35
 
33
36
  var doOperation = function doOperation(config, data, onChange) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ukhomeoffice/cop-react-form-renderer",
3
- "version": "4.48.0",
3
+ "version": "4.51.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "clean": "rimraf dist",
@@ -97,4 +97,4 @@
97
97
  "last 1 safari version"
98
98
  ]
99
99
  }
100
- }
100
+ }