@ukhomeoffice/cop-react-form-renderer 4.0.2 → 4.4.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.
@@ -115,7 +115,7 @@ var CollectionPage = function CollectionPage(_ref) {
115
115
 
116
116
  return /*#__PURE__*/_react.default.createElement(_FormPage.default, {
117
117
  page: _objectSpread(_objectSpread({}, page), {}, {
118
- formData: _objectSpread(_objectSpread({}, page.formData), data[activeIndex])
118
+ formData: _objectSpread(_objectSpread(_objectSpread({}, page.formData), data[activeIndex]), {}, _defineProperty({}, "".concat(page.collection.name, "ActiveIndex"), activeIndex))
119
119
  }),
120
120
  onAction: onInnerPageAction,
121
121
  onWrapperChange: onInnerPageChange,
@@ -148,6 +148,7 @@ var FormComponent = function FormComponent(_ref) {
148
148
  return _utils.default.Component.get(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, attrs), component), {}, {
149
149
  id: component.full_path || component.id
150
150
  }, (0, _helpers.getComponentError)(component, validation === null || validation === void 0 ? void 0 : validation.errors)), {}, {
151
+ disabled: (0, _helpers.getComponentDisabled)(component.disabled, formData),
151
152
  label: _utils.default.interpolateString(component.label, formData),
152
153
  content: _utils.default.interpolateString(component.content, formData),
153
154
  hint: _utils.default.interpolateString(component.hint, formData),
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _Utils = _interopRequireDefault(require("@ukhomeoffice/cop-react-components/dist/utils/Utils"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ var getComponentDisabled = function getComponentDisabled(disabled, formData) {
13
+ if (typeof disabled === 'string') {
14
+ return !!_Utils.default.interpolateString(disabled, formData);
15
+ }
16
+
17
+ return !!disabled;
18
+ };
19
+
20
+ var _default = getComponentDisabled;
21
+ exports.default = _default;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ var _getComponentDisabled = _interopRequireDefault(require("./getComponentDisabled"));
4
+
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+
7
+ describe('components.FormComponent.helpers.getComponentDisabled', function () {
8
+ var DATA = {
9
+ shouldDisable: true
10
+ };
11
+ it('should return false if disabled is undefined', function () {
12
+ expect((0, _getComponentDisabled.default)(undefined, DATA)).toEqual(false);
13
+ });
14
+ it('should return false if disabled is boolean false', function () {
15
+ expect((0, _getComponentDisabled.default)(false, DATA)).toEqual(false);
16
+ });
17
+ it('should return true if disabled is boolean true', function () {
18
+ expect((0, _getComponentDisabled.default)(true, DATA)).toEqual(true);
19
+ });
20
+ it('should interpolate correctly if disabled is a field path', function () {
21
+ expect((0, _getComponentDisabled.default)('${shouldDisable}', DATA)).toEqual(true);
22
+ });
23
+ it('should return false if interpolating a field that does not exist', function () {
24
+ expect((0, _getComponentDisabled.default)('${notARealField}', DATA)).toEqual(false);
25
+ });
26
+ });
@@ -3,6 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ Object.defineProperty(exports, "getComponentDisabled", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _getComponentDisabled.default;
10
+ }
11
+ });
6
12
  Object.defineProperty(exports, "getComponentError", {
7
13
  enumerable: true,
8
14
  get: function get() {
@@ -10,6 +16,8 @@ Object.defineProperty(exports, "getComponentError", {
10
16
  }
11
17
  });
12
18
 
19
+ var _getComponentDisabled = _interopRequireDefault(require("./getComponentDisabled"));
20
+
13
21
  var _getComponentError = _interopRequireDefault(require("./getComponentError"));
14
22
 
15
23
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -89,7 +89,10 @@ var FormPage = function FormPage(_ref) {
89
89
  label: _utils.default.interpolateString(action.label, page.formData)
90
90
  }) : action;
91
91
  });
92
- page.formData = _objectSpread(_objectSpread({}, page.formData), patch);
92
+
93
+ var operationResults = _utils.default.Operate.runPageOperations(page, _objectSpread(_objectSpread({}, page.formData), patch));
94
+
95
+ page.formData = _objectSpread(_objectSpread(_objectSpread({}, page.formData), patch), operationResults);
93
96
  return /*#__PURE__*/_react.default.createElement("div", {
94
97
  className: classes('page'),
95
98
  key: page.id
@@ -0,0 +1,35 @@
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
+
17
+ /**
18
+ * Simple operation to check if a given value in data is truthy or not.
19
+ * Supports getting a value from an interpolated field string.
20
+ * @param {object} config The operation config.
21
+ * @param {object} data The page's formData.
22
+ * @returns true if the value is truthy, false if it isn't or doesn't exist.
23
+ */
24
+ var checkValueIsTruthy = function checkValueIsTruthy(config, data) {
25
+ if (config !== null && config !== void 0 && config.field) {
26
+ var fieldPath = _copReactComponents.Utils.interpolateString(config.field, data);
27
+
28
+ return !!(0, _getSourceData.default)(data, fieldPath);
29
+ }
30
+
31
+ return false;
32
+ };
33
+
34
+ var _default = checkValueIsTruthy;
35
+ exports.default = _default;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ var _checkValueIsTruthy = _interopRequireDefault(require("./checkValueIsTruthy"));
4
+
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+
7
+ describe('Utils.Operate.checkValueIsTruthy', function () {
8
+ var DATA = {
9
+ alpha: 'abc',
10
+ bravo: ''
11
+ };
12
+ it('Should return true is the value of the field is truthy', function () {
13
+ var CONFIG = {
14
+ field: 'alpha'
15
+ };
16
+ var result = (0, _checkValueIsTruthy.default)(CONFIG, DATA);
17
+ expect(result).toEqual(true);
18
+ });
19
+ it('Should return false if the value of the field is falsy', function () {
20
+ var CONFIG = {
21
+ field: 'bravo'
22
+ };
23
+ var result = (0, _checkValueIsTruthy.default)(CONFIG, DATA);
24
+ expect(result).toEqual(false);
25
+ });
26
+ it('Should return false if the field does not exist', function () {
27
+ var CONFIG = {
28
+ field: 'charlie'
29
+ };
30
+ var result = (0, _checkValueIsTruthy.default)(CONFIG, DATA);
31
+ expect(result).toEqual(false);
32
+ });
33
+ it('Should return false when an invalid config is used', function () {
34
+ var result = (0, _checkValueIsTruthy.default)(null, DATA);
35
+ expect(result).toEqual(false);
36
+ });
37
+ it('Should return false when invalid data is used', function () {
38
+ var CONFIG = {
39
+ field: 'alpha'
40
+ };
41
+ var result = (0, _checkValueIsTruthy.default)(CONFIG, null);
42
+ expect(result).toEqual(false);
43
+ });
44
+ });
@@ -0,0 +1,72 @@
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 getValueOrField = function getValueOrField(config, data) {
17
+ if (config !== null && config !== void 0 && config.value) {
18
+ return config.value;
19
+ }
20
+
21
+ var path = _copReactComponents.Utils.interpolateString(config === null || config === void 0 ? void 0 : config.field, data);
22
+
23
+ return (0, _getSourceData.default)(data, path);
24
+ };
25
+ /**
26
+ * Searches for a value in an array in data that matches a value given
27
+ * in config. A cutoff index can be provided in config if the search
28
+ * should stop after a certain number of entries. An index to ignore
29
+ * can also be provided.
30
+ * @param {object} config The config of the operation.
31
+ * @param {object} data A page's formData.
32
+ * @returns The index of the matching value if one exists, or null.
33
+ */
34
+
35
+
36
+ var getIndexOfMatchingValueIn = function getIndexOfMatchingValueIn(config, data) {
37
+ if (!config || !data) {
38
+ return null;
39
+ }
40
+
41
+ var targetPath = _copReactComponents.Utils.interpolateString(config.target, data);
42
+
43
+ var target = (0, _getSourceData.default)(data, targetPath);
44
+ var value = getValueOrField(config, data);
45
+ var cutoff = getValueOrField(config.cutoff, data);
46
+ var ignore = getValueOrField(config.ignore, data);
47
+ var result = null;
48
+
49
+ if (target && value && Array.isArray(target)) {
50
+ target.every(function (entry, index) {
51
+ if (index === cutoff) {
52
+ return false;
53
+ }
54
+
55
+ if (index === ignore) {
56
+ return true;
57
+ }
58
+
59
+ if (entry === value || config.key && entry[config.key] === value) {
60
+ result = index;
61
+ return false;
62
+ }
63
+
64
+ return true;
65
+ });
66
+ }
67
+
68
+ return typeof result === 'number' ? result.toString() : result;
69
+ };
70
+
71
+ var _default = getIndexOfMatchingValueIn;
72
+ exports.default = _default;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+
3
+ var _getIndexOfMatchingValueIn = _interopRequireDefault(require("./getIndexOfMatchingValueIn"));
4
+
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+
7
+ describe('Utils.Operate.getIndexOfPriorMatchingValueIn', function () {
8
+ var DATA = {
9
+ arrayOfValues: ['abc', 'bcd', 'cde', 'def'],
10
+ cutoffIndex: 1,
11
+ ignoreIndex: 2,
12
+ valueToSearchFor: 'cde',
13
+ targetName: 'arrayOfValues',
14
+ fieldName: 'valueToSearchFor',
15
+ cutoffName: 'cutoffIndex',
16
+ ignoreName: 'ignoreIndex'
17
+ };
18
+ it('Should return the index of a matching value if one exists', function () {
19
+ var CONFIG = {
20
+ target: 'arrayOfValues',
21
+ value: 'cde'
22
+ };
23
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
24
+ expect(result).toEqual('2');
25
+ });
26
+ it('Should handle getting value from given field', function () {
27
+ var CONFIG = {
28
+ target: 'arrayOfValues',
29
+ field: 'valueToSearchFor'
30
+ };
31
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
32
+ expect(result).toEqual('2');
33
+ });
34
+ it('Should handle interpolated string for field', function () {
35
+ var CONFIG = {
36
+ target: 'arrayOfValues',
37
+ field: '${fieldName}'
38
+ };
39
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
40
+ expect(result).toEqual('2');
41
+ });
42
+ it('Should handle a cutoff value being specified', function () {
43
+ var CONFIG = {
44
+ target: 'arrayOfValues',
45
+ value: 'cde',
46
+ cutoff: {
47
+ value: 1
48
+ }
49
+ };
50
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
51
+ expect(result).toEqual(null); // Cutoff occurs before matching value is reached.
52
+ });
53
+ it('Should handle a cutoff field being specified', function () {
54
+ var CONFIG = {
55
+ target: 'arrayOfValues',
56
+ value: 'cde',
57
+ cutoff: {
58
+ field: 'cutoffIndex'
59
+ }
60
+ };
61
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
62
+ expect(result).toEqual(null); // Cutoff occurs before matching value is reached.
63
+ });
64
+ it('Should handle interpolated string for cutoff.field', function () {
65
+ var CONFIG = {
66
+ target: 'arrayOfValues',
67
+ value: 'cde',
68
+ cutoff: {
69
+ field: '${cutoffName}'
70
+ }
71
+ };
72
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
73
+ expect(result).toEqual(null); // Cutoff occurs before matching value is reached.
74
+ });
75
+ it('Should handle an ignore value being specified', function () {
76
+ var CONFIG = {
77
+ target: 'arrayOfValues',
78
+ value: 'cde',
79
+ ignore: {
80
+ value: 2
81
+ }
82
+ };
83
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
84
+ expect(result).toEqual(null); // Should ignore the matching value.
85
+ });
86
+ it('Should handle an ignore field being specified', function () {
87
+ var CONFIG = {
88
+ target: 'arrayOfValues',
89
+ value: 'cde',
90
+ ignore: {
91
+ field: 'ignoreIndex'
92
+ }
93
+ };
94
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
95
+ expect(result).toEqual(null); // Should ignore the matching value.
96
+ });
97
+ it('Should handle interpolated string for ignore.field', function () {
98
+ var CONFIG = {
99
+ target: 'arrayOfValues',
100
+ value: 'cde',
101
+ ignore: {
102
+ field: '${ignoreName}'
103
+ }
104
+ };
105
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
106
+ expect(result).toEqual(null); // Should ignore the matching value.
107
+ });
108
+ it('Should handle interpolated string for target', function () {
109
+ var CONFIG = {
110
+ target: '${targetName}',
111
+ value: 'cde'
112
+ };
113
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
114
+ expect(result).toEqual('2');
115
+ });
116
+ it('Should return null when the target does not exist', function () {
117
+ var CONFIG = {
118
+ target: 'notARealTarget',
119
+ value: 'cde'
120
+ };
121
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
122
+ expect(result).toEqual(null);
123
+ });
124
+ it('Should return null when config is missing fields', function () {
125
+ var CONFIG = {};
126
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, DATA);
127
+ expect(result).toEqual(null);
128
+ });
129
+ it('Should return null when config is invalid', function () {
130
+ var result = (0, _getIndexOfMatchingValueIn.default)(null, DATA);
131
+ expect(result).toEqual(null);
132
+ });
133
+ it('Should return null when data is invalid', function () {
134
+ var CONFIG = {
135
+ target: 'arrayOfValues',
136
+ value: 'cde'
137
+ };
138
+ var result = (0, _getIndexOfMatchingValueIn.default)(CONFIG, null);
139
+ expect(result).toEqual(null);
140
+ });
141
+ });
@@ -0,0 +1,27 @@
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 getValueFromFormData = function getValueFromFormData(config, data) {
17
+ if (config !== null && config !== void 0 && config.field) {
18
+ var fieldPath = _copReactComponents.Utils.interpolateString(config.field, data);
19
+
20
+ return (0, _getSourceData.default)(data, fieldPath) || null;
21
+ }
22
+
23
+ return (config === null || config === void 0 ? void 0 : config.value) || null;
24
+ };
25
+
26
+ var _default = getValueFromFormData;
27
+ exports.default = _default;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ var _getValueFromFormData = _interopRequireDefault(require("./getValueFromFormData"));
4
+
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+
7
+ describe('Utils.Operate.addToFormData', function () {
8
+ var DATA = {
9
+ a: '1',
10
+ b: ['2', '3'],
11
+ indexOfThree: 1
12
+ };
13
+ it('Should return the value provided in config if no field is specified', function () {
14
+ var CONFIG = {
15
+ value: '2'
16
+ };
17
+ var result = (0, _getValueFromFormData.default)(CONFIG, DATA);
18
+ expect(result).toEqual(CONFIG.value);
19
+ });
20
+ it('Should return the value of the field given in config, if it exists', function () {
21
+ var CONFIG = {
22
+ field: 'a'
23
+ };
24
+ var result = (0, _getValueFromFormData.default)(CONFIG, DATA);
25
+ expect(result).toEqual(DATA.a);
26
+ });
27
+ it('Should handle interpolated field strings', function () {
28
+ var CONFIG = {
29
+ field: 'b[${indexOfThree}]'
30
+ };
31
+ var result = (0, _getValueFromFormData.default)(CONFIG, DATA);
32
+ expect(result).toEqual(DATA.b[1]);
33
+ });
34
+ it('Should return null when an invalid config is used', function () {
35
+ var result = (0, _getValueFromFormData.default)(null, DATA);
36
+ expect(result).toEqual(null);
37
+ });
38
+ it('Should return null when invalid data is used', function () {
39
+ var CONFIG = {
40
+ field: 'a'
41
+ };
42
+ var result = (0, _getValueFromFormData.default)(CONFIG, null);
43
+ expect(result).toEqual(null);
44
+ });
45
+ });
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _runPageOperations = _interopRequireDefault(require("./runPageOperations"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ var Operate = {
13
+ runPageOperations: _runPageOperations.default
14
+ };
15
+ var _default = Operate;
16
+ exports.default = _default;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _checkValueIsTruthy = _interopRequireDefault(require("./checkValueIsTruthy"));
9
+
10
+ var _getIndexOfMatchingValueIn = _interopRequireDefault(require("./getIndexOfMatchingValueIn"));
11
+
12
+ var _getValueFromFormData = _interopRequireDefault(require("./getValueFromFormData"));
13
+
14
+ var _shouldRun = _interopRequireDefault(require("./shouldRun"));
15
+
16
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
+
18
+ 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; }
19
+
20
+ 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; }
21
+
22
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
23
+
24
+ var functions = {
25
+ checkValueIsTruthy: _checkValueIsTruthy.default,
26
+ getIndexOfMatchingValueIn: _getIndexOfMatchingValueIn.default,
27
+ getValueFromFormData: _getValueFromFormData.default
28
+ };
29
+
30
+ var doOperation = function doOperation(config, data) {
31
+ var fn = functions[config.function];
32
+
33
+ if (typeof fn === 'function') {
34
+ return fn(config, data);
35
+ }
36
+
37
+ return undefined;
38
+ };
39
+ /**
40
+ * Run operations specified in a page's config on formData.
41
+ * The results of any operations are stored in an object with
42
+ * the format of { operation_name: result, ... }.
43
+ *
44
+ * If the page has no 'operations' field, or no valid operations
45
+ * are given, then an empty object is returned.
46
+ *
47
+ * @param {object} config The config for the page.
48
+ * @param {object} data The page's formData.
49
+ * @returns An object containing the results of the operations.
50
+ */
51
+
52
+
53
+ var runPageOperations = function runPageOperations(config, data) {
54
+ var result = {};
55
+
56
+ if (config !== null && config !== void 0 && config.operations && data) {
57
+ config.operations.forEach(function (op) {
58
+ if (op.output) {
59
+ if ((0, _shouldRun.default)(op.run_when, data)) {
60
+ result[op.output] = doOperation(op, _objectSpread(_objectSpread({}, data), result));
61
+ }
62
+ }
63
+ });
64
+ }
65
+
66
+ return result;
67
+ };
68
+
69
+ var _default = runPageOperations;
70
+ exports.default = _default;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+
3
+ var _runPageOperations = _interopRequireDefault(require("./runPageOperations"));
4
+
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+
7
+ describe('Utils.Operate.runPageOperations', function () {
8
+ var DATA = {
9
+ alpha: 'abc',
10
+ bravo: ['bcd', 'cde', 'charlie'],
11
+ charlie: 'def'
12
+ };
13
+ it('Should return an empty object when no operations are specified', function () {
14
+ var PAGE = {};
15
+ var result = (0, _runPageOperations.default)(PAGE, DATA);
16
+ expect(result).toEqual({});
17
+ });
18
+ it('Should handle a single operation correctly', function () {
19
+ var PAGE = {
20
+ operations: [{
21
+ output: 'firstOpResult',
22
+ function: 'getValueFromFormData',
23
+ field: 'alpha'
24
+ }]
25
+ };
26
+ var result = (0, _runPageOperations.default)(PAGE, DATA);
27
+ expect(result).toEqual({
28
+ firstOpResult: 'abc'
29
+ });
30
+ });
31
+ it('Should handle a multiple operations correctly', function () {
32
+ var PAGE = {
33
+ operations: [{
34
+ output: 'firstOpResult',
35
+ function: 'getValueFromFormData',
36
+ field: 'alpha'
37
+ }, {
38
+ output: 'secondOpResult',
39
+ function: 'getValueFromFormData',
40
+ field: 'bravo[1]'
41
+ }]
42
+ };
43
+ var result = (0, _runPageOperations.default)(PAGE, DATA);
44
+ expect(result).toEqual({
45
+ firstOpResult: 'abc',
46
+ secondOpResult: 'cde'
47
+ });
48
+ });
49
+ it('Should handle chained operations correctly', function () {
50
+ var PAGE = {
51
+ operations: [{
52
+ output: 'firstOpResult',
53
+ function: 'getValueFromFormData',
54
+ field: 'bravo[2]'
55
+ }, {
56
+ output: 'secondOpResult',
57
+ function: 'getValueFromFormData',
58
+ field: '${firstOpResult}'
59
+ }]
60
+ };
61
+ var result = (0, _runPageOperations.default)(PAGE, DATA);
62
+ expect(result).toEqual({
63
+ firstOpResult: 'charlie',
64
+ secondOpResult: 'def'
65
+ });
66
+ });
67
+ });
@@ -0,0 +1,67 @@
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
+
17
+ /**
18
+ * Checks whether or not a page operation should run
19
+ * based on the provided run_when config.
20
+ * @param {object} config The run_when config.
21
+ * @param {object} data The page's formData.
22
+ * @returns
23
+ */
24
+ var shouldRun = function shouldRun(config, data) {
25
+ if (config !== null && config !== void 0 && config.condition) {
26
+ var fieldPath = _copReactComponents.Utils.interpolateString(config.field, data);
27
+
28
+ var fieldValue = (0, _getSourceData.default)(data, fieldPath);
29
+
30
+ switch (config.condition) {
31
+ // Only run the operation if a given field's value has changed.
32
+ case 'changes':
33
+ var lastPath = "".concat(fieldPath, "LastValue");
34
+ var lastValue = config[lastPath] || null;
35
+
36
+ if (lastValue === null) {
37
+ // If there isn't a last value then we assume
38
+ // that this is the first render.
39
+ config[lastPath] = fieldValue;
40
+ return false;
41
+ }
42
+
43
+ if (fieldValue !== lastValue) {
44
+ config[lastPath] = fieldValue;
45
+ return true;
46
+ }
47
+
48
+ return false;
49
+ // Only run the operation if a given field's value is truthy.
50
+
51
+ case 'isTruthy':
52
+ return !!fieldValue;
53
+ // Only run the operation if a given field's value is falsy.
54
+
55
+ case 'isFalsy':
56
+ return !fieldValue;
57
+
58
+ default:
59
+ return false;
60
+ }
61
+ }
62
+
63
+ return true;
64
+ };
65
+
66
+ var _default = shouldRun;
67
+ exports.default = _default;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+
3
+ var _shouldRun = _interopRequireDefault(require("./shouldRun"));
4
+
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+
7
+ 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; }
8
+
9
+ 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; }
10
+
11
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
12
+
13
+ describe('Utils.Operate.shouldRun', function () {
14
+ var DATA = {
15
+ alpha: 'abc',
16
+ bravo: ''
17
+ };
18
+ it('Should return true if the run_when config is invalid', function () {
19
+ expect((0, _shouldRun.default)(null, DATA)).toEqual(true);
20
+ });
21
+ it('Should return true when the condition is \'changes\' and target value has changed', function () {
22
+ var CONFIG = {
23
+ condition: 'changes',
24
+ field: 'alpha'
25
+ };
26
+ var result = (0, _shouldRun.default)(CONFIG, DATA);
27
+ expect(result).toEqual(false); // Expect false as this is the first render.
28
+
29
+ result = (0, _shouldRun.default)(CONFIG, DATA);
30
+ expect(result).toEqual(false); // Expect false as the field hasn't changed.
31
+
32
+ result = (0, _shouldRun.default)(CONFIG, _objectSpread(_objectSpread({}, DATA), {}, {
33
+ alpha: 'bcd'
34
+ }));
35
+ expect(result).toEqual(true); // Expect true as the field's value has been updated.
36
+ });
37
+ it('Should return true when the condition is \'isTruthy\' and target value is truthy', function () {
38
+ var CONFIG = {
39
+ condition: 'isTruthy',
40
+ field: 'alpha'
41
+ };
42
+ var result = (0, _shouldRun.default)(CONFIG, DATA);
43
+ expect(result).toEqual(true);
44
+ });
45
+ it('Should return false when the condition is \'isTruthy\' and target value is falsy', function () {
46
+ var CONFIG = {
47
+ condition: 'isTruthy',
48
+ field: 'bravo'
49
+ };
50
+ var result = (0, _shouldRun.default)(CONFIG, DATA);
51
+ expect(result).toEqual(false);
52
+ });
53
+ it('Should return true when the condition is \'isFalsy\' and target value is falsy', function () {
54
+ var CONFIG = {
55
+ condition: 'isFalsy',
56
+ field: 'bravo'
57
+ };
58
+ var result = (0, _shouldRun.default)(CONFIG, DATA);
59
+ expect(result).toEqual(true);
60
+ });
61
+ it('Should return false when the condition is \'isFalsy\' and target value is truthy', function () {
62
+ var CONFIG = {
63
+ condition: 'isFalsy',
64
+ field: 'alpha'
65
+ };
66
+ var result = (0, _shouldRun.default)(CONFIG, DATA);
67
+ expect(result).toEqual(false);
68
+ });
69
+ });
@@ -27,6 +27,8 @@ var _Hub = _interopRequireDefault(require("./Hub"));
27
27
 
28
28
  var _Meta = _interopRequireDefault(require("./Meta"));
29
29
 
30
+ var _Operate = _interopRequireDefault(require("./Operate"));
31
+
30
32
  var _Validate = _interopRequireDefault(require("./Validate"));
31
33
 
32
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -48,6 +50,7 @@ var Utils = _objectSpread({
48
50
  FormPage: _FormPage.default,
49
51
  Hub: _Hub.default,
50
52
  Meta: _Meta.default,
53
+ Operate: _Operate.default,
51
54
  Validate: _Validate.default
52
55
  }, _copReactComponents.Utils);
53
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ukhomeoffice/cop-react-form-renderer",
3
- "version": "4.0.2",
3
+ "version": "4.4.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "clean": "rimraf dist",
@@ -16,7 +16,7 @@
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": "2.0.3",
19
+ "@ukhomeoffice/cop-react-components": "2.1.0",
20
20
  "axios": "^0.23.0",
21
21
  "dayjs": "^1.11.0",
22
22
  "govuk-frontend": "^4.3.1",