@ukhomeoffice/cop-react-form-renderer 6.12.0 → 6.13.2

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/README.md CHANGED
@@ -9,10 +9,18 @@ It uses components from [COP React Design System](https://github.com/UKHomeOffic
9
9
  - `@ukhomeoffice/cop-react-components` - and offers various styles of forms. These are showcased inside of
10
10
  a [yarn storybook](Storybook) within the project.
11
11
 
12
+ To get started run `nvm use` to switch to currently supported node version (if your using node version manager). Otherwise, install node version specified in `.nvmrc`.
13
+
14
+ This library uses the yarn package manager. To install this you will need to run `npm install --global yarn` on the supported version of node.
15
+
12
16
  ## Available Scripts
13
17
 
14
18
  In the project directory, you can run:
15
19
 
20
+ ### `yarn install`
21
+
22
+ Installs the package.json dependencies.
23
+
16
24
  ### `yarn lint`
17
25
 
18
26
  Runs `eslint` against the project to check for coding issues.
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = exports.DEFAULT_CLASS = void 0;
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _react = _interopRequireWildcard(require("react"));
10
+ var _uuid = require("uuid");
10
11
  var _utils = _interopRequireDefault(require("../../utils"));
11
12
  var _FormPage = _interopRequireDefault(require("../FormPage"));
12
13
  var _FormPage2 = require("../FormPage/FormPage");
@@ -104,7 +105,7 @@ var CollectionPage = function CollectionPage(_ref) {
104
105
  // If there is no active entry in the collection, we create
105
106
  // a new entry and generate a new ID for it.
106
107
  // This ID becomes the active ID for the collection.
107
- var newId = Date.now().toString();
108
+ var newId = (0, _uuid.v4)();
108
109
  reportActiveIdChange(newId);
109
110
  reportChange([].concat(data, [_defineProperty({
110
111
  id: newId
@@ -7,6 +7,7 @@ exports.default = exports.DEFAULT_TITLE = exports.DEFAULT_LIST_CLASS = exports.D
7
7
  var _copReactComponents = require("@ukhomeoffice/cop-react-components");
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _react = _interopRequireDefault(require("react"));
10
+ var _BannerStrip = _interopRequireDefault(require("./BannerStrip"));
10
11
  var _utils = _interopRequireDefault(require("../../utils"));
11
12
  var _getSummaryListRowForDetails = _interopRequireDefault(require("../../utils/CheckYourAnswers/getSummaryListRowForDetails"));
12
13
  var _Condition = _interopRequireDefault(require("../../utils/Condition"));
@@ -37,18 +38,24 @@ var RenderListView = function RenderListView(_ref) {
37
38
  masterPage = _ref.masterPage,
38
39
  classModifiers = _ref.classModifiers,
39
40
  optionalFieldPlaceholder = _ref.optionalFieldPlaceholder;
40
- var classes = _copReactComponents.Utils.classBuilder(DEFAULT_CLASS, classModifiers);
41
+ var classes = _copReactComponents.Utils.classBuilder(DEFAULT_CLASS, classModifiers, config.className);
41
42
  var listClass = _copReactComponents.Utils.classBuilder(DEFAULT_LIST_CLASS);
42
43
  return /*#__PURE__*/_react.default.createElement("div", {
43
44
  className: classes(),
44
45
  id: id
45
46
  }, /*#__PURE__*/_react.default.createElement("div", {
46
47
  className: classes('title-wrapper', [], 'dark')
48
+ }, /*#__PURE__*/_react.default.createElement("div", {
49
+ className: classes('title-content')
47
50
  }, /*#__PURE__*/_react.default.createElement("h2", {
48
51
  className: classes('title')
49
52
  }, _copReactComponents.Utils.interpolateString(config.title || DEFAULT_TITLE, _objectSpread(_objectSpread({}, entryData), {}, {
50
53
  index: entryData.index + 1
51
- }))), /*#__PURE__*/_react.default.createElement("ul", {
54
+ }))), config.banners && /*#__PURE__*/_react.default.createElement(_BannerStrip.default, {
55
+ id: "BannerStrip".concat(entryData.id),
56
+ banners: config.banners,
57
+ formData: entryData
58
+ })), /*#__PURE__*/_react.default.createElement("ul", {
52
59
  className: classes('actions')
53
60
  }, /*#__PURE__*/_react.default.createElement("li", {
54
61
  className: classes('action')
@@ -110,6 +117,8 @@ RenderListView.propTypes = {
110
117
  index: _propTypes.default.number.isRequired
111
118
  }).isRequired,
112
119
  config: _propTypes.default.shape({
120
+ className: _propTypes.default.string,
121
+ banners: _propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.shape({})])),
113
122
  title: _propTypes.default.string,
114
123
  changeAction: _propTypes.default.shape({
115
124
  label: _propTypes.default.string,
@@ -183,6 +183,10 @@ $govuk-font-family: 'Roboto', arial, sans-serif;
183
183
  &--deleting-summary-card {
184
184
  background-color: #FCF0EE;
185
185
  }
186
+
187
+ &.error {
188
+ border-left: 7px solid red;
189
+ }
186
190
  }
187
191
 
188
192
  .govuk-summary-card__title-wrapper {
@@ -213,6 +217,11 @@ $govuk-font-family: 'Roboto', arial, sans-serif;
213
217
  }
214
218
  }
215
219
 
220
+ .govuk-summary-card__title-content {
221
+ display: flex;
222
+ flex-direction: column;
223
+ }
224
+
216
225
  .govuk-summary-card__actions {
217
226
  @include govuk-typography-responsive($size: 19);
218
227
  @include govuk-typography-weight-bold;
@@ -6,10 +6,13 @@ var _setupTests = require("../../setupTests");
6
6
  var _RenderListView = _interopRequireDefault(require("./RenderListView"));
7
7
  var _models = require("../../models");
8
8
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
- // Global imports.
10
-
9
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
10
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
13
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
14
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } // Global imports.
11
15
  // Local imports.
12
-
13
16
  describe('components.CollectionSummary.RenderListView', function () {
14
17
  var ENTRY = {
15
18
  id: '001',
@@ -78,6 +81,13 @@ describe('components.CollectionSummary.RenderListView', function () {
78
81
  label: 'Delete label'
79
82
  }
80
83
  };
84
+ var CONFIG_ERROR = _objectSpread({
85
+ className: 'error',
86
+ banners: [{
87
+ "text": "MORE DETAILS NEEDED",
88
+ "classModifiers": ["red"]
89
+ }]
90
+ }, CONFIG);
81
91
  var ID = 'testListView';
82
92
  var onChangeArgs = [];
83
93
  var onChangeCalls = 0;
@@ -180,6 +190,33 @@ describe('components.CollectionSummary.RenderListView', function () {
180
190
  // Check if the index is rendered as expected in the title
181
191
  expect(title.textContent).toContain("Title text ".concat(ENTRY.index + 1));
182
192
  });
193
+ it('should render an Error Tag with Error className when passed an error in the Banner and ClassName', function () {
194
+ var _renderWithValidation3 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react2.default.createElement(_RenderListView.default, {
195
+ id: ID,
196
+ entryData: ENTRY,
197
+ config: CONFIG_ERROR,
198
+ onFullEdit: ON_CHANGE,
199
+ onDelete: ON_DELETE,
200
+ masterPage: MASTER_PAGE,
201
+ getComponentRow: getComponentRow
202
+ })),
203
+ container = _renderWithValidation3.container;
204
+ var listViewDiv = checkSetup(container);
205
+
206
+ // Check className
207
+ expect(listViewDiv.classList).toContain('error');
208
+
209
+ // Check for presence of Banner Strip
210
+ var bannerStrip = listViewDiv.querySelector('.hods-form-banner-strip');
211
+ expect(bannerStrip).not.toBeNull();
212
+ expect(bannerStrip.id).toEqual('BannerStrip001');
213
+
214
+ // Check for presence of Error Tag with correct tagName, className, and Text content
215
+ var errorTag = listViewDiv.querySelector('.hods-form-banner-strip__tag--red');
216
+ expect(errorTag).not.toBeNull();
217
+ expect(errorTag.tagName).toBe('STRONG');
218
+ expect(errorTag.innerHTML).toContain('MORE DETAILS NEEDED');
219
+ });
183
220
  describe('Action buttons in RenderListView', function () {
184
221
  beforeEach(function () {
185
222
  onChangeArgs = [];
@@ -188,7 +225,7 @@ describe('components.CollectionSummary.RenderListView', function () {
188
225
  onDeleteCalls = 0;
189
226
  });
190
227
  it('should render and handle action buttons correctly', function () {
191
- var _renderWithValidation3 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react2.default.createElement(_RenderListView.default, {
228
+ var _renderWithValidation4 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react2.default.createElement(_RenderListView.default, {
192
229
  id: ID,
193
230
  entryData: ENTRY,
194
231
  config: CONFIG,
@@ -197,7 +234,7 @@ describe('components.CollectionSummary.RenderListView', function () {
197
234
  masterPage: MASTER_PAGE,
198
235
  getComponentRow: getComponentRow
199
236
  })),
200
- container = _renderWithValidation3.container;
237
+ container = _renderWithValidation4.container;
201
238
  var listViewDiv = container.querySelector('.govuk-summary-card');
202
239
  expect(listViewDiv).not.toBeNull();
203
240
 
@@ -8,6 +8,7 @@ exports.default = exports.DEFAULT_CLASS = void 0;
8
8
  var _copReactComponents = require("@ukhomeoffice/cop-react-components");
9
9
  var _react = _interopRequireWildcard(require("react"));
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
+ var _uuid = require("uuid");
11
12
  var _models = require("../../models");
12
13
  var _utils = _interopRequireDefault(require("../../utils"));
13
14
  var _Container = _interopRequireDefault(require("./Container"));
@@ -78,7 +79,7 @@ var Collection = function Collection(_ref) {
78
79
  while (1) switch (_context.prev = _context.next) {
79
80
  case 0:
80
81
  reportChange([].concat(value, [{
81
- id: Date.now().toString()
82
+ id: (0, _uuid.v4)()
82
83
  }]));
83
84
  case 1:
84
85
  case "end":
@@ -21,4 +21,4 @@
21
21
  float: right;
22
22
  }
23
23
  }
24
- }
24
+ }
@@ -12,8 +12,10 @@ var _models = require("../../models");
12
12
  var _utils = _interopRequireDefault(require("../../utils"));
13
13
  var _FormComponent = _interopRequireDefault(require("./FormComponent"));
14
14
  var _getSourceData = _interopRequireDefault(require("../../utils/Data/getSourceData"));
15
+ require("./Container.scss");
15
16
  var _excluded = ["container", "value", "formData", "onChange", "wrap", "onTopLevelChange"]; // Global imports
16
17
  // Local imports
18
+ // Styles
17
19
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
20
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
19
21
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -0,0 +1,15 @@
1
+ .horizonal {
2
+ flex-direction: row;
3
+ display: flex;
4
+ justify-content: space-between;
5
+ gap: 2rem;
6
+ .horizonal{
7
+ justify-content: space-around;
8
+ }
9
+ }
10
+ @media screen and (max-width: 640px) {
11
+ .horizonal {
12
+ flex-direction: column;
13
+ gap:0;
14
+ }
15
+ }
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ var _uuid = require("uuid");
7
8
  var _getCollectionPageData = _interopRequireDefault(require("./getCollectionPageData"));
8
9
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
10
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
@@ -33,7 +34,7 @@ var duplicateCollectionPageEntry = function duplicateCollectionPageEntry(collect
33
34
  if (!entryToDuplicate) {
34
35
  return null;
35
36
  }
36
- var newEntryId = Date.now().toString();
37
+ var newEntryId = (0, _uuid.v4)();
37
38
  var newEntry = _objectSpread(_objectSpread(_objectSpread({}, entryToDuplicate), fieldsToAdd), {}, {
38
39
  id: newEntryId
39
40
  });
@@ -23,32 +23,6 @@ describe('utils.CollectionPage.mergeCollectionPages', function () {
23
23
  }];
24
24
  expect((0, _mergeCollectionPages.default)(PAGES)).toEqual(PAGES);
25
25
  });
26
- it('should merge pages from the same collection into a single page', function () {
27
- var PAGES = [{
28
- id: 'page1',
29
- collection: {
30
- name: 'collection'
31
- },
32
- components: [TEXT_COMP]
33
- }, {
34
- id: 'page2',
35
- collection: {
36
- name: 'collection'
37
- },
38
- components: [DATE_COMP]
39
- }];
40
- var RESULT = (0, _mergeCollectionPages.default)(PAGES);
41
- expect(RESULT.length).toEqual(1);
42
- expect(RESULT[0]).toMatchObject({
43
- id: 'page1',
44
- collection: {
45
- name: 'collection',
46
- masterPage: true
47
- },
48
- formData: {},
49
- childPages: PAGES
50
- });
51
- });
52
26
  it('should correctly merge and nest child collection pages under their parents', function () {
53
27
  var PAGES = [{
54
28
  id: 'page1',
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ var _uuid = require("uuid");
7
8
  var isValidIndex = function isValidIndex(value) {
8
9
  return typeof value === 'number' && value >= 0;
9
10
  };
@@ -36,7 +37,7 @@ var setCollectionPageData = function setCollectionPageData(collectionName, newDa
36
37
  if (!data[name].find(function (e) {
37
38
  return e.id === formData["".concat(name, "ActiveId")];
38
39
  })) {
39
- var newEntryId = Date.now().toString();
40
+ var newEntryId = (0, _uuid.v4)();
40
41
  // eslint-disable-next-line no-param-reassign
41
42
  formData["".concat(name, "ActiveId")] = formData["".concat(name, "ActiveId")] || newEntryId;
42
43
  data[name].push({
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ /**
8
+ * Additional validator to not permit a value change if a specified item exists in formData.
9
+ * @param {object} data the changed value
10
+ * @param {object} config the config for the validation must contain
11
+ * a property 'base' holding the value for checking
12
+ * a property 'check' holding the formData item name to check if exists
13
+ * @param {object} formData the form data
14
+ * @returns false if:
15
+ * the 'base' value is not the same as the changed value AND
16
+ * the 'check' value exists in formData as an item
17
+ * otherwise returns true
18
+ */
19
+ var conditionallyPermittedChange = function conditionallyPermittedChange(data, config, _, formData) {
20
+ if (data !== config.base && formData[config.check]) {
21
+ return false;
22
+ }
23
+ return true;
24
+ };
25
+ var _default = exports.default = conditionallyPermittedChange;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ var _conditionallyPermittedChange = _interopRequireDefault(require("./conditionallyPermittedChange"));
4
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
5
+ describe('utils', function () {
6
+ describe('Validate', function () {
7
+ describe('additional', function () {
8
+ describe('conditionallyPermittedChange', function () {
9
+ var CONFIG = {
10
+ base: 'Value1',
11
+ check: 'Item1'
12
+ };
13
+ test('should pass if the base value has same value as data parameter', function () {
14
+ var DATA = 'Value1';
15
+ var FORMDATA = {};
16
+ expect((0, _conditionallyPermittedChange.default)(DATA, CONFIG, null, FORMDATA)).toEqual(true);
17
+ });
18
+ test('should fail if the base value is different to data parameter and check item exists in form data', function () {
19
+ var DATA = 'Value2';
20
+ var FORMDATA = {
21
+ Item1: "any"
22
+ };
23
+ expect((0, _conditionallyPermittedChange.default)(DATA, CONFIG, null, FORMDATA)).toEqual(false);
24
+ });
25
+ test('should pass if the base value is different to data parameter and check item not exists in form data', function () {
26
+ var DATA = 'Value2';
27
+ var FORMDATA = {};
28
+ expect((0, _conditionallyPermittedChange.default)(DATA, CONFIG, null, FORMDATA)).toEqual(true);
29
+ });
30
+ });
31
+ });
32
+ });
33
+ });
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ var _conditionallyPermittedChange = _interopRequireDefault(require("./conditionallyPermittedChange"));
7
8
  var _conditionallyRequired = _interopRequireDefault(require("./conditionallyRequired"));
8
9
  var _mustBeAfter = _interopRequireDefault(require("./mustBeAfter"));
9
10
  var _mustBeBefore = _interopRequireDefault(require("./mustBeBefore"));
@@ -25,6 +26,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
25
26
  // Local imports
26
27
 
27
28
  var functions = {
29
+ conditionallyPermittedChange: _conditionallyPermittedChange.default,
28
30
  conditionallyRequired: _conditionallyRequired.default,
29
31
  mustBeAfter: _mustBeAfter.default,
30
32
  mustBeBefore: _mustBeBefore.default,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ukhomeoffice/cop-react-form-renderer",
3
- "version": "6.12.0",
3
+ "version": "6.13.2",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "clean": "rimraf dist",
@@ -16,11 +16,12 @@
16
16
  "post-compile": "rimraf dist/*.test.* dist/**/*.test.* dist/**/*.stories.* dist/docs dist/assets"
17
17
  },
18
18
  "dependencies": {
19
- "@ukhomeoffice/cop-react-components": "^4.0.0",
19
+ "@ukhomeoffice/cop-react-components": "4.7.2",
20
20
  "axios": "^0.23.0",
21
21
  "dayjs": "^1.11.0",
22
22
  "govuk-frontend": "^5.0.0",
23
- "web-vitals": "^1.0.1"
23
+ "web-vitals": "^1.0.1",
24
+ "uuid": "^8.1.0"
24
25
  },
25
26
  "devDependencies": {
26
27
  "@babel/cli": "^7.15.4",