@ukhomeoffice/cop-react-form-renderer 5.71.8 → 5.73.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.
- package/dist/components/CollectionSummary/RenderListView.js +1 -1
- package/dist/components/FormComponent/Collection.js +24 -17
- package/dist/components/FormComponent/Collection.test.js +138 -0
- package/dist/utils/Validate/additional/mustBeUniqueInCollection.js +4 -0
- package/dist/utils/Validate/additional/mustBeUniqueInCollection.test.js +36 -0
- package/package.json +1 -1
|
@@ -92,7 +92,7 @@ var RenderListView = function RenderListView(_ref) {
|
|
|
92
92
|
var component = elevatedComponents.find(function (comp) {
|
|
93
93
|
return comp.fieldId === fieldId;
|
|
94
94
|
});
|
|
95
|
-
if (!component
|
|
95
|
+
if (!component) {
|
|
96
96
|
return null;
|
|
97
97
|
}
|
|
98
98
|
return (0, _getComponentRowForCYA.default)(childPage, component, listClass, entryData);
|
|
@@ -90,22 +90,6 @@ var Collection = function Collection(_ref) {
|
|
|
90
90
|
return _ref3.apply(this, arguments);
|
|
91
91
|
};
|
|
92
92
|
}();
|
|
93
|
-
(0, _react.useEffect)(function () {
|
|
94
|
-
if (config.focusOnAdd && Array.isArray(value) && value.length) {
|
|
95
|
-
if (value.length > config.minimumEntries || !config.minimumEntries) {
|
|
96
|
-
var _value2, _document$getElementB, _focusable$;
|
|
97
|
-
var containerId = (_value2 = value[value.length - 1]) === null || _value2 === void 0 ? void 0 : _value2.id;
|
|
98
|
-
var container = (_document$getElementB = document.getElementById(containerId)) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.childNodes[0];
|
|
99
|
-
var focusable = container === null || container === void 0 ? void 0 : container.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
100
|
-
(_focusable$ = focusable[0]) === null || _focusable$ === void 0 || _focusable$.focus();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}, [value.length, config.focusOnAdd, config.minimumEntries]);
|
|
104
|
-
(0, _react.useEffect)(function () {
|
|
105
|
-
if (config.minimumEntries && !value.length) {
|
|
106
|
-
onAddAnother();
|
|
107
|
-
}
|
|
108
|
-
}, [config.minimumEntries, value.length]);
|
|
109
93
|
var onRemoveItem = /*#__PURE__*/function () {
|
|
110
94
|
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(item) {
|
|
111
95
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
@@ -124,6 +108,28 @@ var Collection = function Collection(_ref) {
|
|
|
124
108
|
return _ref4.apply(this, arguments);
|
|
125
109
|
};
|
|
126
110
|
}();
|
|
111
|
+
var getAddLabel = function getAddLabel(labels) {
|
|
112
|
+
if (labels.initial && !value.length) {
|
|
113
|
+
return labels.initial;
|
|
114
|
+
}
|
|
115
|
+
return labels.add;
|
|
116
|
+
};
|
|
117
|
+
(0, _react.useEffect)(function () {
|
|
118
|
+
if (config.focusOnAdd && Array.isArray(value) && value.length) {
|
|
119
|
+
if (value.length > config.minimumEntries || !config.minimumEntries) {
|
|
120
|
+
var _value2, _document$getElementB, _focusable$;
|
|
121
|
+
var containerId = (_value2 = value[value.length - 1]) === null || _value2 === void 0 ? void 0 : _value2.id;
|
|
122
|
+
var container = (_document$getElementB = document.getElementById(containerId)) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.childNodes[0];
|
|
123
|
+
var focusable = container === null || container === void 0 ? void 0 : container.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
124
|
+
(_focusable$ = focusable[0]) === null || _focusable$ === void 0 || _focusable$.focus();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}, [value.length, config.focusOnAdd, config.minimumEntries]);
|
|
128
|
+
(0, _react.useEffect)(function () {
|
|
129
|
+
if (config.minimumEntries && !value.length) {
|
|
130
|
+
onAddAnother();
|
|
131
|
+
}
|
|
132
|
+
}, [config.minimumEntries, value.length]);
|
|
127
133
|
var labels = _objectSpread(_objectSpread({}, _models.CollectionLabels), config.labels);
|
|
128
134
|
var classes = _utils.default.classBuilder(DEFAULT_CLASS, [], config.className);
|
|
129
135
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
@@ -203,7 +209,7 @@ var Collection = function Collection(_ref) {
|
|
|
203
209
|
}), !config.disableAddAndRemove && /*#__PURE__*/_react.default.createElement(_copReactComponents.ButtonGroup, null, /*#__PURE__*/_react.default.createElement(_copReactComponents.Button, {
|
|
204
210
|
onClick: onAddAnother,
|
|
205
211
|
classModifiers: "secondary"
|
|
206
|
-
}, labels
|
|
212
|
+
}, getAddLabel(labels))));
|
|
207
213
|
};
|
|
208
214
|
Collection.propTypes = {
|
|
209
215
|
config: _propTypes.default.shape({
|
|
@@ -220,6 +226,7 @@ Collection.propTypes = {
|
|
|
220
226
|
})),
|
|
221
227
|
label: _propTypes.default.string,
|
|
222
228
|
labels: _propTypes.default.shape({
|
|
229
|
+
initial: _propTypes.default.string,
|
|
223
230
|
item: _propTypes.default.string,
|
|
224
231
|
add: _propTypes.default.string,
|
|
225
232
|
remove: _propTypes.default.string
|
|
@@ -964,4 +964,142 @@ describe('components.FormComponent.Collection', function () {
|
|
|
964
964
|
}
|
|
965
965
|
}, _callee18);
|
|
966
966
|
})));
|
|
967
|
+
it('should display the initial cta add label and revert to default cta label on subsequent additions', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee20() {
|
|
968
|
+
var COLLECTION, container, c, addButton, item, label;
|
|
969
|
+
return _regeneratorRuntime().wrap(function _callee20$(_context20) {
|
|
970
|
+
while (1) switch (_context20.prev = _context20.next) {
|
|
971
|
+
case 0:
|
|
972
|
+
COLLECTION = {
|
|
973
|
+
id: ID,
|
|
974
|
+
fieldId: ID,
|
|
975
|
+
type: _models.ComponentTypes.COLLECTION,
|
|
976
|
+
item: [TEXT_COMPONENT],
|
|
977
|
+
// eslint-disable-next-line no-template-curly-in-string
|
|
978
|
+
labels: {
|
|
979
|
+
add: 'Add another item',
|
|
980
|
+
initial: 'Add an item',
|
|
981
|
+
item: 'Item ${index}'
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
container = document.createElement('div');
|
|
985
|
+
document.body.appendChild(container);
|
|
986
|
+
_context20.next = 5;
|
|
987
|
+
return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee19() {
|
|
988
|
+
return _regeneratorRuntime().wrap(function _callee19$(_context19) {
|
|
989
|
+
while (1) switch (_context19.prev = _context19.next) {
|
|
990
|
+
case 0:
|
|
991
|
+
(0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react2.default.createElement(_FormComponent.default, {
|
|
992
|
+
component: COLLECTION
|
|
993
|
+
}), container);
|
|
994
|
+
case 1:
|
|
995
|
+
case "end":
|
|
996
|
+
return _context19.stop();
|
|
997
|
+
}
|
|
998
|
+
}, _callee19);
|
|
999
|
+
})));
|
|
1000
|
+
case 5:
|
|
1001
|
+
// Check the container itself.
|
|
1002
|
+
c = container.childNodes[0];
|
|
1003
|
+
expect(c.tagName).toEqual('DIV');
|
|
1004
|
+
expect(c.classList).toContain(_Collection.DEFAULT_CLASS);
|
|
1005
|
+
|
|
1006
|
+
// And now make sure it has no children OTHER than the button to add an item.
|
|
1007
|
+
expect(c.childNodes.length).toEqual(1);
|
|
1008
|
+
|
|
1009
|
+
// Get hold of that "Add another" button and click it.
|
|
1010
|
+
addButton = c.childNodes[0].childNodes[0];
|
|
1011
|
+
expect(addButton.textContent).toContain('Add an item');
|
|
1012
|
+
_react.fireEvent.click(addButton, {});
|
|
1013
|
+
|
|
1014
|
+
// Make sure an item has been added.
|
|
1015
|
+
expect(c.childNodes.length).toEqual(2);
|
|
1016
|
+
item = c.childNodes[0];
|
|
1017
|
+
label = item.childNodes[0];
|
|
1018
|
+
expect(label.textContent).toContain(_utils.default.interpolateString(_models.CollectionLabels.item, {
|
|
1019
|
+
index: 1
|
|
1020
|
+
}));
|
|
1021
|
+
|
|
1022
|
+
// Check label of subsequent call to action button has updated
|
|
1023
|
+
expect(addButton.textContent).toContain('Add another item');
|
|
1024
|
+
case 17:
|
|
1025
|
+
case "end":
|
|
1026
|
+
return _context20.stop();
|
|
1027
|
+
}
|
|
1028
|
+
}, _callee20);
|
|
1029
|
+
})));
|
|
1030
|
+
it('should revert back to the initial cta add label on adding and removing an item', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee22() {
|
|
1031
|
+
var COLLECTION, container, c, addButton, item, label, removeButton;
|
|
1032
|
+
return _regeneratorRuntime().wrap(function _callee22$(_context22) {
|
|
1033
|
+
while (1) switch (_context22.prev = _context22.next) {
|
|
1034
|
+
case 0:
|
|
1035
|
+
COLLECTION = {
|
|
1036
|
+
id: ID,
|
|
1037
|
+
fieldId: ID,
|
|
1038
|
+
type: _models.ComponentTypes.COLLECTION,
|
|
1039
|
+
item: [TEXT_COMPONENT],
|
|
1040
|
+
// eslint-disable-next-line no-template-curly-in-string
|
|
1041
|
+
labels: {
|
|
1042
|
+
add: 'Add another item',
|
|
1043
|
+
initial: 'Add an item',
|
|
1044
|
+
item: 'Item ${index}'
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
container = document.createElement('div');
|
|
1048
|
+
document.body.appendChild(container);
|
|
1049
|
+
_context22.next = 5;
|
|
1050
|
+
return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee21() {
|
|
1051
|
+
return _regeneratorRuntime().wrap(function _callee21$(_context21) {
|
|
1052
|
+
while (1) switch (_context21.prev = _context21.next) {
|
|
1053
|
+
case 0:
|
|
1054
|
+
(0, _setupTests.renderDomWithValidation)( /*#__PURE__*/_react2.default.createElement(_FormComponent.default, {
|
|
1055
|
+
component: COLLECTION
|
|
1056
|
+
}), container);
|
|
1057
|
+
case 1:
|
|
1058
|
+
case "end":
|
|
1059
|
+
return _context21.stop();
|
|
1060
|
+
}
|
|
1061
|
+
}, _callee21);
|
|
1062
|
+
})));
|
|
1063
|
+
case 5:
|
|
1064
|
+
// Check the container itself.
|
|
1065
|
+
c = container.childNodes[0];
|
|
1066
|
+
expect(c.tagName).toEqual('DIV');
|
|
1067
|
+
expect(c.classList).toContain(_Collection.DEFAULT_CLASS);
|
|
1068
|
+
|
|
1069
|
+
// And now make sure it has no children OTHER than the button to add an item.
|
|
1070
|
+
expect(c.childNodes.length).toEqual(1);
|
|
1071
|
+
|
|
1072
|
+
// Get hold of that "Add another" button and click it.
|
|
1073
|
+
addButton = c.childNodes[0].childNodes[0];
|
|
1074
|
+
expect(addButton.textContent).toContain('Add an item');
|
|
1075
|
+
_react.fireEvent.click(addButton, {});
|
|
1076
|
+
|
|
1077
|
+
// Make sure an item has been added.
|
|
1078
|
+
expect(c.childNodes.length).toEqual(2);
|
|
1079
|
+
item = c.childNodes[0];
|
|
1080
|
+
label = item.childNodes[0];
|
|
1081
|
+
expect(label.textContent).toContain(_utils.default.interpolateString(_models.CollectionLabels.item, {
|
|
1082
|
+
index: 1
|
|
1083
|
+
}));
|
|
1084
|
+
|
|
1085
|
+
// Check label of subsequent call to action button has updated
|
|
1086
|
+
expect(addButton.textContent).toContain('Add another item');
|
|
1087
|
+
|
|
1088
|
+
// Get hold of the newly-add item's "Remove" button.
|
|
1089
|
+
removeButton = label.childNodes[1];
|
|
1090
|
+
expect(removeButton.tagName).toEqual('BUTTON');
|
|
1091
|
+
expect(removeButton.classList).toContain('hods-button--secondary');
|
|
1092
|
+
expect(removeButton.textContent).toContain(_models.CollectionLabels.remove);
|
|
1093
|
+
|
|
1094
|
+
// Click the "Remove" button
|
|
1095
|
+
_react.fireEvent.click(removeButton, {});
|
|
1096
|
+
|
|
1097
|
+
// Check label of subsequent call to action button has updated
|
|
1098
|
+
expect(addButton.textContent).toContain('Add an item');
|
|
1099
|
+
case 23:
|
|
1100
|
+
case "end":
|
|
1101
|
+
return _context22.stop();
|
|
1102
|
+
}
|
|
1103
|
+
}, _callee22);
|
|
1104
|
+
})));
|
|
967
1105
|
});
|
|
@@ -10,6 +10,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
10
10
|
/**
|
|
11
11
|
* @param {*} value - the value to check.
|
|
12
12
|
* @param {string} config.collectionPath - the path to the collection within formData
|
|
13
|
+
* @param {string} config.caseInsensitive - true to ignore case, assumes string values
|
|
13
14
|
* @param {object} component - the component definition
|
|
14
15
|
* @param {object} formData - the current form data
|
|
15
16
|
* @returns true if components value is not the same in any other entry in the collection
|
|
@@ -28,6 +29,9 @@ var mustBeUniqueInCollection = function mustBeUniqueInCollection(value, config,
|
|
|
28
29
|
return false;
|
|
29
30
|
}
|
|
30
31
|
;
|
|
32
|
+
if (config.caseInsensitive && typeof value === 'string' && typeof entry[component.id] === 'string') {
|
|
33
|
+
return entry[component.id].toUpperCase() === value.toUpperCase();
|
|
34
|
+
}
|
|
31
35
|
return entry[component.id] === value;
|
|
32
36
|
});
|
|
33
37
|
return !result;
|
|
@@ -121,6 +121,42 @@ describe('utils', function () {
|
|
|
121
121
|
}), COMPONENT_NESTED, FORM_DATA);
|
|
122
122
|
expect(result).toBeFalsy();
|
|
123
123
|
});
|
|
124
|
+
test('should return true if other entries have the same value for this field in a different case', function () {
|
|
125
|
+
var FORM_DATA = {
|
|
126
|
+
namesActiveId: 2,
|
|
127
|
+
names: [{
|
|
128
|
+
id: 1,
|
|
129
|
+
firstName: 'ALPHA'
|
|
130
|
+
}, {
|
|
131
|
+
id: 2,
|
|
132
|
+
firstName: 'alpha'
|
|
133
|
+
}, {
|
|
134
|
+
id: 3,
|
|
135
|
+
firstName: 'bravo'
|
|
136
|
+
}]
|
|
137
|
+
};
|
|
138
|
+
var result = (0, _mustBeUniqueInCollection.default)('alpha', CONFIG, COMPONENT, FORM_DATA);
|
|
139
|
+
expect(result).toBeTruthy();
|
|
140
|
+
});
|
|
141
|
+
test('should return false if other entries have the same value for this field in a different case and caseInsensitive is true', function () {
|
|
142
|
+
var FORM_DATA = {
|
|
143
|
+
namesActiveId: 2,
|
|
144
|
+
names: [{
|
|
145
|
+
id: 1,
|
|
146
|
+
firstName: 'ALPHA'
|
|
147
|
+
}, {
|
|
148
|
+
id: 2,
|
|
149
|
+
firstName: 'alpha'
|
|
150
|
+
}, {
|
|
151
|
+
id: 3,
|
|
152
|
+
firstName: 'bravo'
|
|
153
|
+
}]
|
|
154
|
+
};
|
|
155
|
+
var result = (0, _mustBeUniqueInCollection.default)('alpha', _objectSpread(_objectSpread({}, CONFIG), {}, {
|
|
156
|
+
caseInsensitive: true
|
|
157
|
+
}), COMPONENT, FORM_DATA);
|
|
158
|
+
expect(result).toBeFalsy();
|
|
159
|
+
});
|
|
124
160
|
});
|
|
125
161
|
});
|
|
126
162
|
});
|