@ukhomeoffice/cop-react-form-renderer 6.6.1 → 6.11.1

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 (45) hide show
  1. package/dist/components/CheckYourAnswers/Answer.js +11 -5
  2. package/dist/components/CheckYourAnswers/Answer.test.js +67 -14
  3. package/dist/components/CheckYourAnswers/CheckYourAnswers.js +9 -5
  4. package/dist/components/CheckYourAnswers/CheckYourAnswers.test.js +156 -64
  5. package/dist/components/CollectionSummary/CollectionSummary.js +20 -3
  6. package/dist/components/CollectionSummary/CollectionSummary.test.js +66 -20
  7. package/dist/components/CollectionSummary/RenderListView.js +2 -2
  8. package/dist/components/CollectionSummary/SummaryCard.js +17 -6
  9. package/dist/components/CollectionSummary/SummaryCard.test.js +94 -37
  10. package/dist/components/CollectionSummary/SummaryCardDetails.js +78 -34
  11. package/dist/components/CollectionSummary/SummaryCardDetails.scss +9 -0
  12. package/dist/components/CollectionSummary/SummaryCardDetails.test.js +206 -10
  13. package/dist/components/FormComponent/Container.js +2 -1
  14. package/dist/components/FormComponent/Container.test.js +69 -0
  15. package/dist/components/FormComponent/helpers/getComponentFieldSet.js +1 -1
  16. package/dist/components/FormRenderer/FormRenderer.js +1 -0
  17. package/dist/components/SummaryList/SummaryList.js +8 -0
  18. package/dist/components/SummaryList/SummaryList.scss +15 -0
  19. package/dist/components/SummaryList/SummaryList.test.js +67 -7
  20. package/dist/components/SummaryList/SummaryListHeadingRowWithAction.js +53 -0
  21. package/dist/components/SummaryList/SummaryListHeadingRowWithAction.scss +38 -0
  22. package/dist/components/TaskList/TaskList.js +22 -5
  23. package/dist/components/TaskList/TaskList.scss +24 -0
  24. package/dist/components/TaskList/TaskList.test.js +160 -16
  25. package/dist/utils/CheckYourAnswers/getCYARowsForCollectionPage.js +27 -12
  26. package/dist/utils/CheckYourAnswers/getCYARowsForCollectionPage.test.js +145 -0
  27. package/dist/utils/CheckYourAnswers/{getComponentRowForCYA.js → getSummaryListRowForDetails.js} +10 -5
  28. package/dist/utils/CheckYourAnswers/getSummaryListRowForDetails.test.js +56 -0
  29. package/dist/utils/CollectionPage/getQuickEditPage.js +2 -1
  30. package/dist/utils/CollectionPage/getQuickEditPage.test.js +8 -0
  31. package/dist/utils/CollectionPage/mergeCollectionPages.js +10 -1
  32. package/dist/utils/CollectionPage/mergeCollectionPages.test.js +6 -6
  33. package/dist/utils/Component/elevateNestedComponents.js +2 -1
  34. package/dist/utils/Component/elevateNestedComponents.test.js +38 -0
  35. package/dist/utils/Component/optionIsSelected.js +5 -0
  36. package/dist/utils/Component/optionIsSelected.test.js +26 -0
  37. package/dist/utils/Operate/getLength.js +50 -0
  38. package/dist/utils/Operate/getLength.test.js +89 -0
  39. package/dist/utils/Operate/runPageOperations.js +2 -0
  40. package/dist/utils/Validate/validateComponent.js +7 -2
  41. package/dist/utils/Validate/validateComponent.test.js +31 -0
  42. package/dist/utils/Validate/validateTime.js +8 -0
  43. package/dist/utils/Validate/validateTime.test.js +46 -0
  44. package/package.json +1 -1
  45. package/dist/utils/CheckYourAnswers/getComponentRowForCYA.test.js +0 -41
@@ -19,9 +19,11 @@ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input ==
19
19
  var Answer = function Answer(_ref) {
20
20
  var value = _ref.value,
21
21
  component = _ref.component,
22
- formData = _ref.formData;
22
+ formData = _ref.formData,
23
+ placeholder = _ref.placeholder;
23
24
  if (!value) {
24
- return /*#__PURE__*/_react.default.createElement(_VisuallyHidden.default, null, "No answer");
25
+ var placeholderValue = (component === null || component === void 0 ? void 0 : component.cyaPlaceholder) || placeholder;
26
+ return placeholderValue || /*#__PURE__*/_react.default.createElement(_VisuallyHidden.default, null, "No answer");
25
27
  }
26
28
  if (!component) {
27
29
  return Object.prototype.hasOwnProperty.call(value, 'label') ? value.label : value;
@@ -36,13 +38,17 @@ var Answer = function Answer(_ref) {
36
38
  });
37
39
  };
38
40
  Answer.propTypes = {
39
- component: _propTypes.default.shape({}),
41
+ component: _propTypes.default.shape({
42
+ cyaPlaceholder: _propTypes.default.string
43
+ }),
40
44
  formData: _propTypes.default.shape({}),
41
- value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.shape({})])
45
+ value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.shape({})]),
46
+ placeholder: _propTypes.default.string
42
47
  };
43
48
  Answer.defaultProps = {
44
49
  component: null,
45
50
  formData: null,
46
- value: null
51
+ value: null,
52
+ placeholder: null
47
53
  };
48
54
  var _default = exports.default = Answer;
@@ -75,31 +75,84 @@ describe('components', function () {
75
75
  }
76
76
  }, _callee3);
77
77
  })));
78
- it('should handle a null component and an object value', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
79
- var VALUE, COMPONENT, _renderWithValidation4, container;
78
+ it('should show a placeholder value for components without a value', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
79
+ var VALUE, PLACEHOLDER, COMPONENT, _renderWithValidation4, container, answer;
80
80
  return _regeneratorRuntime().wrap(function _callee4$(_context4) {
81
81
  while (1) switch (_context4.prev = _context4.next) {
82
+ case 0:
83
+ VALUE = '';
84
+ PLACEHOLDER = 'Not entered';
85
+ COMPONENT = {
86
+ id: 'alpha',
87
+ fieldId: 'alpha',
88
+ type: 'text',
89
+ label: 'Alpha'
90
+ };
91
+ _renderWithValidation4 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_Answer.default, {
92
+ value: VALUE,
93
+ component: COMPONENT,
94
+ placeholder: PLACEHOLDER
95
+ })), container = _renderWithValidation4.container;
96
+ answer = container.childNodes[0];
97
+ expect(answer.textContent).toEqual(PLACEHOLDER);
98
+ case 6:
99
+ case "end":
100
+ return _context4.stop();
101
+ }
102
+ }, _callee4);
103
+ })));
104
+ it('should use a component\'s placeholder value if one is defined', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
105
+ var VALUE, GLOBAL_PLACEHOLDER, COMPONENT, _renderWithValidation5, container, answer;
106
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
107
+ while (1) switch (_context5.prev = _context5.next) {
108
+ case 0:
109
+ VALUE = '';
110
+ GLOBAL_PLACEHOLDER = 'Not entered';
111
+ COMPONENT = {
112
+ id: 'alpha',
113
+ fieldId: 'alpha',
114
+ type: 'text',
115
+ label: 'Alpha',
116
+ cyaPlaceholder: 'Alpha not entered'
117
+ };
118
+ _renderWithValidation5 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_Answer.default, {
119
+ value: VALUE,
120
+ component: COMPONENT,
121
+ placeholder: GLOBAL_PLACEHOLDER
122
+ })), container = _renderWithValidation5.container;
123
+ answer = container.childNodes[0];
124
+ expect(answer.textContent).toEqual(COMPONENT.cyaPlaceholder);
125
+ case 6:
126
+ case "end":
127
+ return _context5.stop();
128
+ }
129
+ }, _callee5);
130
+ })));
131
+ it('should handle a null component and an object value', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
132
+ var VALUE, COMPONENT, _renderWithValidation6, container;
133
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
134
+ while (1) switch (_context6.prev = _context6.next) {
82
135
  case 0:
83
136
  VALUE = {
84
137
  label: 'A label',
85
138
  value: 'a_value'
86
139
  };
87
140
  COMPONENT = null;
88
- _renderWithValidation4 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_Answer.default, {
141
+ _renderWithValidation6 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_Answer.default, {
89
142
  value: VALUE,
90
143
  component: COMPONENT
91
- })), container = _renderWithValidation4.container;
144
+ })), container = _renderWithValidation6.container;
92
145
  expect(container.textContent).toEqual(VALUE.label);
93
146
  case 4:
94
147
  case "end":
95
- return _context4.stop();
148
+ return _context6.stop();
96
149
  }
97
- }, _callee4);
150
+ }, _callee6);
98
151
  })));
99
- it('should handle a component that requires interpolation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
100
- var VALUE, DATA, COMPONENT, _renderWithValidation5, container, answer;
101
- return _regeneratorRuntime().wrap(function _callee5$(_context5) {
102
- while (1) switch (_context5.prev = _context5.next) {
152
+ it('should handle a component that requires interpolation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
153
+ var VALUE, DATA, COMPONENT, _renderWithValidation7, container, answer;
154
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
155
+ while (1) switch (_context7.prev = _context7.next) {
103
156
  case 0:
104
157
  VALUE = 'beta';
105
158
  DATA = {
@@ -119,20 +172,20 @@ describe('components', function () {
119
172
  }]
120
173
  }
121
174
  };
122
- _renderWithValidation5 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_Answer.default, {
175
+ _renderWithValidation7 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_Answer.default, {
123
176
  value: VALUE,
124
177
  component: COMPONENT,
125
178
  formData: DATA
126
- })), container = _renderWithValidation5.container;
179
+ })), container = _renderWithValidation7.container;
127
180
  answer = container.childNodes[0];
128
181
  expect(answer.tagName).toEqual('DIV');
129
182
  expect(answer.classList).toContain(_Readonly.DEFAULT_CLASS);
130
183
  expect(answer.textContent).toEqual('hardcoded delta');
131
184
  case 8:
132
185
  case "end":
133
- return _context5.stop();
186
+ return _context7.stop();
134
187
  }
135
- }, _callee5);
188
+ }, _callee7);
136
189
  })));
137
190
  });
138
191
  });
@@ -51,7 +51,8 @@ var CheckYourAnswers = function CheckYourAnswers(_ref) {
51
51
  groups = _ref.groups,
52
52
  sections = _ref.sections,
53
53
  type = _ref.type,
54
- hideBlankRows = _ref.hideBlankRows;
54
+ hideBlankRows = _ref.hideBlankRows,
55
+ optionalFieldPlaceholder = _ref.optionalFieldPlaceholder;
55
56
  var _useState = (0, _react.useState)([]),
56
57
  _useState2 = _slicedToArray(_useState, 2),
57
58
  pages = _useState2[0],
@@ -73,7 +74,8 @@ var CheckYourAnswers = function CheckYourAnswers(_ref) {
73
74
  key: "".concat(pageIndex, "_").concat(index),
74
75
  value: row.value,
75
76
  component: row.component,
76
- formData: page.formData
77
+ formData: page.formData,
78
+ placeholder: optionalFieldPlaceholder
77
79
  })
78
80
  });
79
81
  });
@@ -165,7 +167,7 @@ var CheckYourAnswers = function CheckYourAnswers(_ref) {
165
167
  });
166
168
  return /*#__PURE__*/_react.default.createElement(_react.Fragment, {
167
169
  key: taskIndex
168
- }, /*#__PURE__*/_react.default.createElement(_copReactComponents.MediumHeading, null, filterPages.length > 0 && task.displayName || task.name), filterPages.map(function (page, pageIndex) {
170
+ }, /*#__PURE__*/_react.default.createElement(_copReactComponents.MediumHeading, null, filterPages.length > 0 && (task.displayName || task.name)), filterPages.map(function (page, pageIndex) {
169
171
  var hideActionButtons = isGroup(page.id) || noChangeAction;
170
172
  var showHeading = !hide_page_titles && page.title && !isGroup(page.id);
171
173
  return /*#__PURE__*/_react.default.createElement(_react.Fragment, {
@@ -233,7 +235,8 @@ CheckYourAnswers.propTypes = {
233
235
  summaryListClassModifiers: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.arrayOf(_propTypes.default.string)]),
234
236
  title: _propTypes.default.string,
235
237
  type: _propTypes.default.string,
236
- hideBlankRows: _propTypes.default.bool
238
+ hideBlankRows: _propTypes.default.bool,
239
+ optionalFieldPlaceholder: _propTypes.default.string
237
240
  };
238
241
  CheckYourAnswers.defaultProps = {
239
242
  actions: [],
@@ -247,6 +250,7 @@ CheckYourAnswers.defaultProps = {
247
250
  summaryListClassModifiers: null,
248
251
  title: DEFAULT_TITLE,
249
252
  type: null,
250
- hideBlankRows: false
253
+ hideBlankRows: false,
254
+ optionalFieldPlaceholder: null
251
255
  };
252
256
  var _default = exports.default = CheckYourAnswers;
@@ -527,23 +527,37 @@ describe('components', function () {
527
527
  }
528
528
  }, _callee20);
529
529
  })));
530
- it('Show answers from multiple address fields into in one DL', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee22() {
531
- var ADDRESS_DATA, GROUP_PAGES, cya, groupedComponent, keyGroup, valueGroup, changeButtonDiv, changeButton;
530
+ it('should show task list in CYA style and not show sections without any pages', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee22() {
531
+ var sections, taskHeading1, taskHeading2;
532
532
  return _regeneratorRuntime().wrap(function _callee22$(_context22) {
533
533
  while (1) switch (_context22.prev = _context22.next) {
534
534
  case 0:
535
- ADDRESS_DATA = _utils.default.Data.setupForm(_group.default.pages, _group.default.components, _groupData.default);
536
- GROUP_PAGES = _utils.default.FormPage.getAll(_group.default.pages, _group.default.components, _objectSpread({}, ADDRESS_DATA));
537
- _context22.next = 4;
535
+ sections = [{
536
+ name: 'These are your tasks',
537
+ tasks: [{
538
+ name: 'Task 1',
539
+ displayName: 'Blue',
540
+ state: 'complete',
541
+ pages: []
542
+ }, {
543
+ name: 'Task 2',
544
+ displayName: 'Red',
545
+ state: 'complete',
546
+ pages: ['grade']
547
+ }]
548
+ }];
549
+ _context22.next = 3;
538
550
  return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee21() {
539
551
  return _regeneratorRuntime().wrap(function _callee21$(_context21) {
540
552
  while (1) switch (_context21.prev = _context21.next) {
541
553
  case 0:
542
554
  (0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
543
- pages: GROUP_PAGES,
555
+ pages: PAGES,
544
556
  onRowAction: ON_ROW_ACTION,
545
557
  onAction: ON_ACTION,
546
- hide_title: true
558
+ hide_title: true,
559
+ sections: sections,
560
+ type: "task-list-cya"
547
561
  }), container);
548
562
  case 1:
549
563
  case "end":
@@ -551,6 +565,41 @@ describe('components', function () {
551
565
  }
552
566
  }, _callee21);
553
567
  })));
568
+ case 3:
569
+ taskHeading1 = container.childNodes[0].childNodes[0];
570
+ expect(taskHeading1.textContent).toEqual('');
571
+ taskHeading2 = container.childNodes[0].childNodes[1];
572
+ expect(taskHeading2.textContent).toEqual('Red');
573
+ case 7:
574
+ case "end":
575
+ return _context22.stop();
576
+ }
577
+ }, _callee22);
578
+ })));
579
+ it('Show answers from multiple address fields into in one DL', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee24() {
580
+ var ADDRESS_DATA, GROUP_PAGES, cya, groupedComponent, keyGroup, valueGroup, changeButtonDiv, changeButton;
581
+ return _regeneratorRuntime().wrap(function _callee24$(_context24) {
582
+ while (1) switch (_context24.prev = _context24.next) {
583
+ case 0:
584
+ ADDRESS_DATA = _utils.default.Data.setupForm(_group.default.pages, _group.default.components, _groupData.default);
585
+ GROUP_PAGES = _utils.default.FormPage.getAll(_group.default.pages, _group.default.components, _objectSpread({}, ADDRESS_DATA));
586
+ _context24.next = 4;
587
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee23() {
588
+ return _regeneratorRuntime().wrap(function _callee23$(_context23) {
589
+ while (1) switch (_context23.prev = _context23.next) {
590
+ case 0:
591
+ (0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
592
+ pages: GROUP_PAGES,
593
+ onRowAction: ON_ROW_ACTION,
594
+ onAction: ON_ACTION,
595
+ hide_title: true
596
+ }), container);
597
+ case 1:
598
+ case "end":
599
+ return _context23.stop();
600
+ }
601
+ }, _callee23);
602
+ })));
554
603
  case 4:
555
604
  cya = checkCYA(container);
556
605
  groupedComponent = cya.childNodes[10];
@@ -571,20 +620,20 @@ describe('components', function () {
571
620
  expect(changeButton.textContent).toEqual('Change address details');
572
621
  case 21:
573
622
  case "end":
574
- return _context22.stop();
623
+ return _context24.stop();
575
624
  }
576
- }, _callee22);
625
+ }, _callee24);
577
626
  })));
578
- it('should render a group with one action button', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee24() {
627
+ it('should render a group with one action button', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee26() {
579
628
  var GROUP_PAGES, cya, namesGroup, firstNameRow, surname, changeButtonDiv, changeButton;
580
- return _regeneratorRuntime().wrap(function _callee24$(_context24) {
581
- while (1) switch (_context24.prev = _context24.next) {
629
+ return _regeneratorRuntime().wrap(function _callee26$(_context26) {
630
+ while (1) switch (_context26.prev = _context26.next) {
582
631
  case 0:
583
632
  GROUP_PAGES = _utils.default.FormPage.getAll(_groupOfRow.default.pages, _groupOfRow.default.components, _objectSpread({}, DATA));
584
- _context24.next = 3;
585
- return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee23() {
586
- return _regeneratorRuntime().wrap(function _callee23$(_context23) {
587
- while (1) switch (_context23.prev = _context23.next) {
633
+ _context26.next = 3;
634
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee25() {
635
+ return _regeneratorRuntime().wrap(function _callee25$(_context25) {
636
+ while (1) switch (_context25.prev = _context25.next) {
588
637
  case 0:
589
638
  (0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
590
639
  pages: GROUP_PAGES,
@@ -594,9 +643,9 @@ describe('components', function () {
594
643
  }), container);
595
644
  case 1:
596
645
  case "end":
597
- return _context23.stop();
646
+ return _context25.stop();
598
647
  }
599
- }, _callee23);
648
+ }, _callee25);
600
649
  })));
601
650
  case 3:
602
651
  cya = checkCYA(container);
@@ -620,14 +669,57 @@ describe('components', function () {
620
669
  expect(changeButton.textContent).toEqual('Change names');
621
670
  case 22:
622
671
  case "end":
623
- return _context24.stop();
672
+ return _context26.stop();
624
673
  }
625
- }, _callee24);
674
+ }, _callee26);
626
675
  })));
627
- it('should show page components corrently with interpolated title and cya_label, if label is missing', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee26() {
676
+ it('should render empty optional fields with a placeholder value when provided', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee28() {
677
+ var GROUP_PAGES, cya, namesGroup, firstNameRow, surname;
678
+ return _regeneratorRuntime().wrap(function _callee28$(_context28) {
679
+ while (1) switch (_context28.prev = _context28.next) {
680
+ case 0:
681
+ GROUP_PAGES = _utils.default.FormPage.getAll(_groupOfRow.default.pages, _groupOfRow.default.components, {});
682
+ _context28.next = 3;
683
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee27() {
684
+ return _regeneratorRuntime().wrap(function _callee27$(_context27) {
685
+ while (1) switch (_context27.prev = _context27.next) {
686
+ case 0:
687
+ (0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
688
+ pages: GROUP_PAGES,
689
+ groups: _groupOfRow.default.cya.groups,
690
+ optionalFieldPlaceholder: "Not entered"
691
+ }), container);
692
+ case 1:
693
+ case "end":
694
+ return _context27.stop();
695
+ }
696
+ }, _callee27);
697
+ })));
698
+ case 3:
699
+ cya = checkCYA(container);
700
+ namesGroup = cya.childNodes[2];
701
+ firstNameRow = namesGroup.childNodes[0].childNodes[0];
702
+ expect(firstNameRow.childNodes.length).toEqual(2);
703
+ expect(firstNameRow.childNodes[0].textContent).toEqual('First name (optional)');
704
+ expect(firstNameRow.childNodes[0].tagName).toEqual('DT');
705
+ expect(firstNameRow.childNodes[1].textContent).toEqual('Not entered');
706
+ expect(firstNameRow.childNodes[1].tagName).toEqual('DD');
707
+ surname = namesGroup.childNodes[0].childNodes[1];
708
+ expect(surname.childNodes.length).toEqual(2);
709
+ expect(surname.childNodes[0].textContent).toEqual('Last name (optional)');
710
+ expect(surname.childNodes[0].tagName).toEqual('DT');
711
+ expect(surname.childNodes[1].textContent).toEqual('Not entered');
712
+ expect(surname.childNodes[1].tagName).toEqual('DD');
713
+ case 17:
714
+ case "end":
715
+ return _context28.stop();
716
+ }
717
+ }, _callee28);
718
+ })));
719
+ it('should show page components corrently with interpolated title and cya_label, if label is missing', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee30() {
628
720
  var _PAGES, _COMPONENTS, T_PAGES, cya, _cya$childNodes7, cyaTitle, cyaChildNode, names, _names$childNodes3, firstName, surname, _firstName$childNodes, label;
629
- return _regeneratorRuntime().wrap(function _callee26$(_context26) {
630
- while (1) switch (_context26.prev = _context26.next) {
721
+ return _regeneratorRuntime().wrap(function _callee30$(_context30) {
722
+ while (1) switch (_context30.prev = _context30.next) {
631
723
  case 0:
632
724
  _PAGES = [].concat(_userProfile.default.pages); // eslint-disable-next-line no-template-curly-in-string
633
725
  _PAGES[0] = _objectSpread(_objectSpread({}, _PAGES[0]), {}, {
@@ -641,10 +733,10 @@ describe('components', function () {
641
733
  cya_label: "Text ${currentUser.familyName}"
642
734
  });
643
735
  T_PAGES = _utils.default.FormPage.getAll(_PAGES, _COMPONENTS, DATA);
644
- _context26.next = 7;
645
- return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee25() {
646
- return _regeneratorRuntime().wrap(function _callee25$(_context25) {
647
- while (1) switch (_context25.prev = _context25.next) {
736
+ _context30.next = 7;
737
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee29() {
738
+ return _regeneratorRuntime().wrap(function _callee29$(_context29) {
739
+ while (1) switch (_context29.prev = _context29.next) {
648
740
  case 0:
649
741
  (0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
650
742
  pages: T_PAGES,
@@ -653,9 +745,9 @@ describe('components', function () {
653
745
  }), container);
654
746
  case 1:
655
747
  case "end":
656
- return _context25.stop();
748
+ return _context29.stop();
657
749
  }
658
- }, _callee25);
750
+ }, _callee29);
659
751
  })));
660
752
  case 7:
661
753
  cya = checkCYA(container);
@@ -670,14 +762,14 @@ describe('components', function () {
670
762
  checkRow(surname, 'Last name', 'Smith', false);
671
763
  case 17:
672
764
  case "end":
673
- return _context26.stop();
765
+ return _context30.stop();
674
766
  }
675
- }, _callee26);
767
+ }, _callee30);
676
768
  })));
677
- it('should show page components corrently with no label, if label and cya_label are missing', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee28() {
769
+ it('should show page components corrently with no label, if label and cya_label are missing', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee32() {
678
770
  var _PAGES, _COMPONENTS, T_PAGES, cya, _cya$childNodes8, cyaChildNode, names, _names$childNodes4, firstName, surname, _firstName$childNodes2, label;
679
- return _regeneratorRuntime().wrap(function _callee28$(_context28) {
680
- while (1) switch (_context28.prev = _context28.next) {
771
+ return _regeneratorRuntime().wrap(function _callee32$(_context32) {
772
+ while (1) switch (_context32.prev = _context32.next) {
681
773
  case 0:
682
774
  _PAGES = [].concat(_userProfile.default.pages);
683
775
  _COMPONENTS = [].concat(_userProfile.default.components);
@@ -687,10 +779,10 @@ describe('components', function () {
687
779
  cya_label: undefined
688
780
  });
689
781
  T_PAGES = _utils.default.FormPage.getAll(_PAGES, _COMPONENTS, _objectSpread({}, DATA));
690
- _context28.next = 6;
691
- return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee27() {
692
- return _regeneratorRuntime().wrap(function _callee27$(_context27) {
693
- while (1) switch (_context27.prev = _context27.next) {
782
+ _context32.next = 6;
783
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee31() {
784
+ return _regeneratorRuntime().wrap(function _callee31$(_context31) {
785
+ while (1) switch (_context31.prev = _context31.next) {
694
786
  case 0:
695
787
  (0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
696
788
  pages: T_PAGES,
@@ -699,9 +791,9 @@ describe('components', function () {
699
791
  }), container);
700
792
  case 1:
701
793
  case "end":
702
- return _context27.stop();
794
+ return _context31.stop();
703
795
  }
704
- }, _callee27);
796
+ }, _callee31);
705
797
  })));
706
798
  case 6:
707
799
  cya = checkCYA(container);
@@ -715,14 +807,14 @@ describe('components', function () {
715
807
  checkRow(surname, 'Last name', 'Smith', false);
716
808
  case 15:
717
809
  case "end":
718
- return _context28.stop();
810
+ return _context32.stop();
719
811
  }
720
- }, _callee28);
812
+ }, _callee32);
721
813
  })));
722
- it('should show task list in CYA style and hide pages from skipped tasks', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee30() {
814
+ it('should show task list in CYA style and hide pages from skipped tasks', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee34() {
723
815
  var sections, taskHeading1, namesPageHeading;
724
- return _regeneratorRuntime().wrap(function _callee30$(_context30) {
725
- while (1) switch (_context30.prev = _context30.next) {
816
+ return _regeneratorRuntime().wrap(function _callee34$(_context34) {
817
+ while (1) switch (_context34.prev = _context34.next) {
726
818
  case 0:
727
819
  sections = [{
728
820
  name: 'These are your tasks',
@@ -736,10 +828,10 @@ describe('components', function () {
736
828
  pages: ['grade']
737
829
  }]
738
830
  }];
739
- _context30.next = 3;
740
- return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee29() {
741
- return _regeneratorRuntime().wrap(function _callee29$(_context29) {
742
- while (1) switch (_context29.prev = _context29.next) {
831
+ _context34.next = 3;
832
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee33() {
833
+ return _regeneratorRuntime().wrap(function _callee33$(_context33) {
834
+ while (1) switch (_context33.prev = _context33.next) {
743
835
  case 0:
744
836
  (0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
745
837
  pages: PAGES,
@@ -751,9 +843,9 @@ describe('components', function () {
751
843
  }), container);
752
844
  case 1:
753
845
  case "end":
754
- return _context29.stop();
846
+ return _context33.stop();
755
847
  }
756
- }, _callee29);
848
+ }, _callee33);
757
849
  })));
758
850
  case 3:
759
851
  taskHeading1 = container.childNodes[0].childNodes[0];
@@ -767,21 +859,21 @@ describe('components', function () {
767
859
  expect(container.childNodes[0].childNodes.length).toEqual(2); // second task skipped so not shown
768
860
  case 12:
769
861
  case "end":
770
- return _context30.stop();
862
+ return _context34.stop();
771
863
  }
772
- }, _callee30);
864
+ }, _callee34);
773
865
  })));
774
- it('Show answers from multiple address fields into in one DL correctly when hideBlankRows is true', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee32() {
866
+ it('Show answers from multiple address fields into in one DL correctly when hideBlankRows is true', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee36() {
775
867
  var ADDRESS_DATA, GROUP_PAGES, cya, groupedComponent, keyGroup, valueGroup, changeButtonDiv, changeButton;
776
- return _regeneratorRuntime().wrap(function _callee32$(_context32) {
777
- while (1) switch (_context32.prev = _context32.next) {
868
+ return _regeneratorRuntime().wrap(function _callee36$(_context36) {
869
+ while (1) switch (_context36.prev = _context36.next) {
778
870
  case 0:
779
871
  ADDRESS_DATA = _utils.default.Data.setupForm(_group.default.pages, _group.default.components, _groupData.default);
780
872
  GROUP_PAGES = _utils.default.FormPage.getAll(_group.default.pages, _group.default.components, _objectSpread({}, ADDRESS_DATA));
781
- _context32.next = 4;
782
- return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee31() {
783
- return _regeneratorRuntime().wrap(function _callee31$(_context31) {
784
- while (1) switch (_context31.prev = _context31.next) {
873
+ _context36.next = 4;
874
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee35() {
875
+ return _regeneratorRuntime().wrap(function _callee35$(_context35) {
876
+ while (1) switch (_context35.prev = _context35.next) {
785
877
  case 0:
786
878
  (0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react.default.createElement(_CheckYourAnswers.default, {
787
879
  pages: GROUP_PAGES,
@@ -792,9 +884,9 @@ describe('components', function () {
792
884
  }), container);
793
885
  case 1:
794
886
  case "end":
795
- return _context31.stop();
887
+ return _context35.stop();
796
888
  }
797
- }, _callee31);
889
+ }, _callee35);
798
890
  })));
799
891
  case 4:
800
892
  cya = checkCYA(container);
@@ -816,9 +908,9 @@ describe('components', function () {
816
908
  expect(changeButton.textContent).toEqual('Change address details');
817
909
  case 21:
818
910
  case "end":
819
- return _context32.stop();
911
+ return _context36.stop();
820
912
  }
821
- }, _callee32);
913
+ }, _callee36);
822
914
  })));
823
915
  });
824
916
  });
@@ -76,6 +76,15 @@ var CollectionSummary = function CollectionSummary(_ref) {
76
76
  var data = (0, _react.useMemo)(function () {
77
77
  return _utils.default.CollectionPage.getData(config.collectionName, formData) || [];
78
78
  }, [formData]);
79
+ var toFocusOn = Array.isArray(data) && data.length > 0 ? data.reduce(function (acc, current) {
80
+ if (current.isDuplicate) {
81
+ if (!acc || current.id > acc.id) {
82
+ return current;
83
+ }
84
+ return acc;
85
+ }
86
+ return acc;
87
+ }, null) : null;
79
88
  var masterPage = (0, _react.useMemo)(function () {
80
89
  var collectionNameParts = config.collectionName.split('.');
81
90
  var childPages = _utils.default.CollectionPage.mergePages(pages || []) || [];
@@ -247,7 +256,9 @@ var CollectionSummary = function CollectionSummary(_ref) {
247
256
  var isInError = errors.filter(function (e) {
248
257
  return e.entryId === entry.id;
249
258
  }).length > 0;
250
- var finalConfig = _objectSpread(_objectSpread(_objectSpread({}, config.card), entry.isDuplicate && config.duplicatedCard ? config.duplicatedCard : {}), isInError && config.errorCard ? config.errorCard : {});
259
+ var finalConfig = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, config.card), entry.isDuplicate && config.duplicatedCard ? config.duplicatedCard : {}), isInError && config.errorCard ? config.errorCard : {}), {}, {
260
+ focusOn: (toFocusOn === null || toFocusOn === void 0 ? void 0 : toFocusOn.id) === entry.id
261
+ });
251
262
  var key = "".concat(config.fieldId, ".summaryCard").concat(entry.id);
252
263
  return /*#__PURE__*/_react.default.createElement(_SummaryCardValidationContext.default, {
253
264
  entryId: entry.id,
@@ -293,7 +304,10 @@ var CollectionSummary = function CollectionSummary(_ref) {
293
304
  label: config.addButton.label || DEFAULT_ADD_BUTTON_LABEL,
294
305
  page: config.addButton.page,
295
306
  type: _PageAction.PageActionTypes.COLLECTION_ADD,
296
- classModifiers: ['secondary']
307
+ classModifiers: ['secondary'],
308
+ customAction: {
309
+ type: config.addButton.customAction
310
+ }
297
311
  },
298
312
  onAction: onAction
299
313
  }));
@@ -305,7 +319,10 @@ CollectionSummary.propTypes = {
305
319
  collectionName: _propTypes.default.string.isRequired,
306
320
  addButton: _propTypes.default.shape({
307
321
  label: _propTypes.default.string,
308
- page: _propTypes.default.string.isRequired
322
+ page: _propTypes.default.string.isRequired,
323
+ customAction: _propTypes.default.shape({
324
+ type: _propTypes.default.string
325
+ })
309
326
  }),
310
327
  card: _propTypes.default.shape({
311
328
  banners: _propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.shape({})])),