@bpmn-io/form-js-viewer 1.6.0 → 1.6.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/LICENSE +22 -22
- package/README.md +189 -189
- package/dist/assets/form-js-base.css +1244 -1244
- package/dist/index.cjs +777 -684
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +778 -685
- package/dist/index.es.js.map +1 -1
- package/dist/types/render/components/util/sanitizerUtil.d.ts +1 -0
- package/dist/types/render/hooks/useFlushDebounce.d.ts +2 -0
- package/dist/types/render/hooks/useGetLabelCorrelation.d.ts +5 -0
- package/dist/types/types.d.ts +35 -35
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -7,6 +7,7 @@ var classNames = require('classnames');
|
|
|
7
7
|
var jsxRuntime = require('preact/jsx-runtime');
|
|
8
8
|
var hooks = require('preact/hooks');
|
|
9
9
|
var preact = require('preact');
|
|
10
|
+
var isEqual = require('lodash/isEqual');
|
|
10
11
|
var flatpickr = require('flatpickr');
|
|
11
12
|
var React = require('preact/compat');
|
|
12
13
|
var Markup = require('preact-markup');
|
|
@@ -73,26 +74,26 @@ const getFlavouredFeelVariableNames = (feelString, feelFlavour = 'expression', o
|
|
|
73
74
|
return [...new Set(variables)];
|
|
74
75
|
};
|
|
75
76
|
|
|
76
|
-
/**
|
|
77
|
-
* Get the variable name at the specified index in a given path expression.
|
|
78
|
-
*
|
|
79
|
-
* @param {Object} root - The root node of the path expression tree.
|
|
80
|
-
* @param {number} index - The index of the variable name to retrieve.
|
|
81
|
-
* @returns {string|null} The variable name at the specified index or null if index is out of bounds.
|
|
77
|
+
/**
|
|
78
|
+
* Get the variable name at the specified index in a given path expression.
|
|
79
|
+
*
|
|
80
|
+
* @param {Object} root - The root node of the path expression tree.
|
|
81
|
+
* @param {number} index - The index of the variable name to retrieve.
|
|
82
|
+
* @returns {string|null} The variable name at the specified index or null if index is out of bounds.
|
|
82
83
|
*/
|
|
83
84
|
const _getVariableNameAtPathIndex = (root, index) => {
|
|
84
85
|
const nodes = _linearizePathExpression(root);
|
|
85
86
|
return nodes[index].variableName || null;
|
|
86
87
|
};
|
|
87
88
|
|
|
88
|
-
/**
|
|
89
|
-
* Extracts the variables which are required of the external context for a given path expression.
|
|
90
|
-
* This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
|
|
91
|
-
*
|
|
92
|
-
* @param {Object} node - The root node of the path expression tree.
|
|
93
|
-
* @param {number} initialDepth - The depth at which the root node is located in the outer context.
|
|
94
|
-
* @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
|
|
95
|
-
* @returns {Set} - A set containing the extracted variable names.
|
|
89
|
+
/**
|
|
90
|
+
* Extracts the variables which are required of the external context for a given path expression.
|
|
91
|
+
* This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
|
|
92
|
+
*
|
|
93
|
+
* @param {Object} node - The root node of the path expression tree.
|
|
94
|
+
* @param {number} initialDepth - The depth at which the root node is located in the outer context.
|
|
95
|
+
* @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
|
|
96
|
+
* @returns {Set} - A set containing the extracted variable names.
|
|
96
97
|
*/
|
|
97
98
|
const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) => {
|
|
98
99
|
// depth info represents the previous (initialised as null) and current depth of the current accessor in the path expression
|
|
@@ -138,11 +139,11 @@ const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) =
|
|
|
138
139
|
return new Set(extractedVariables);
|
|
139
140
|
};
|
|
140
141
|
|
|
141
|
-
/**
|
|
142
|
-
* Deconstructs a path expression tree into an array of components.
|
|
143
|
-
*
|
|
144
|
-
* @param {Object} root - The root node of the path expression tree.
|
|
145
|
-
* @returns {Array<object>} An array of components in the path expression, in the correct order.
|
|
142
|
+
/**
|
|
143
|
+
* Deconstructs a path expression tree into an array of components.
|
|
144
|
+
*
|
|
145
|
+
* @param {Object} root - The root node of the path expression tree.
|
|
146
|
+
* @returns {Array<object>} An array of components in the path expression, in the correct order.
|
|
146
147
|
*/
|
|
147
148
|
const _linearizePathExpression = root => {
|
|
148
149
|
let node = root;
|
|
@@ -161,13 +162,13 @@ const _linearizePathExpression = root => {
|
|
|
161
162
|
return parts.reverse();
|
|
162
163
|
};
|
|
163
164
|
|
|
164
|
-
/**
|
|
165
|
-
* Builds a simplified feel structure tree from the given parse tree and feel string.
|
|
166
|
-
* The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
|
|
167
|
-
*
|
|
168
|
-
* @param {Object} parseTree - The parse tree generated by a parser.
|
|
169
|
-
* @param {string} feelString - The feel string used for parsing.
|
|
170
|
-
* @returns {Object} The simplified feel structure tree.
|
|
165
|
+
/**
|
|
166
|
+
* Builds a simplified feel structure tree from the given parse tree and feel string.
|
|
167
|
+
* The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
|
|
168
|
+
*
|
|
169
|
+
* @param {Object} parseTree - The parse tree generated by a parser.
|
|
170
|
+
* @param {string} feelString - The feel string used for parsing.
|
|
171
|
+
* @returns {Object} The simplified feel structure tree.
|
|
171
172
|
*/
|
|
172
173
|
const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
|
|
173
174
|
const stack = [{
|
|
@@ -193,9 +194,9 @@ const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
|
|
|
193
194
|
return _extractFilterExpressions(stack[0].children[0]);
|
|
194
195
|
};
|
|
195
196
|
|
|
196
|
-
/**
|
|
197
|
-
* Restructure the tree in such a way to bring filters (which create new contexts) to the root of the tree.
|
|
198
|
-
* This is done to simplify the extraction of variables and match the context hierarchy.
|
|
197
|
+
/**
|
|
198
|
+
* Restructure the tree in such a way to bring filters (which create new contexts) to the root of the tree.
|
|
199
|
+
* This is done to simplify the extraction of variables and match the context hierarchy.
|
|
199
200
|
*/
|
|
200
201
|
const _extractFilterExpressions = tree => {
|
|
201
202
|
const flattenedExpressionTree = {
|
|
@@ -236,25 +237,25 @@ class FeelExpressionLanguage {
|
|
|
236
237
|
this._eventBus = eventBus;
|
|
237
238
|
}
|
|
238
239
|
|
|
239
|
-
/**
|
|
240
|
-
* Determines if the given value is a FEEL expression.
|
|
241
|
-
*
|
|
242
|
-
* @param {any} value
|
|
243
|
-
* @returns {boolean}
|
|
244
|
-
*
|
|
240
|
+
/**
|
|
241
|
+
* Determines if the given value is a FEEL expression.
|
|
242
|
+
*
|
|
243
|
+
* @param {any} value
|
|
244
|
+
* @returns {boolean}
|
|
245
|
+
*
|
|
245
246
|
*/
|
|
246
247
|
isExpression(value) {
|
|
247
248
|
return minDash.isString(value) && value.startsWith('=');
|
|
248
249
|
}
|
|
249
250
|
|
|
250
|
-
/**
|
|
251
|
-
* Retrieve variable names from a given FEEL expression.
|
|
252
|
-
*
|
|
253
|
-
* @param {string} expression
|
|
254
|
-
* @param {object} [options]
|
|
255
|
-
* @param {string} [options.type]
|
|
256
|
-
*
|
|
257
|
-
* @returns {string[]}
|
|
251
|
+
/**
|
|
252
|
+
* Retrieve variable names from a given FEEL expression.
|
|
253
|
+
*
|
|
254
|
+
* @param {string} expression
|
|
255
|
+
* @param {object} [options]
|
|
256
|
+
* @param {string} [options.type]
|
|
257
|
+
*
|
|
258
|
+
* @returns {string[]}
|
|
258
259
|
*/
|
|
259
260
|
getVariableNames(expression, options = {}) {
|
|
260
261
|
const {
|
|
@@ -269,13 +270,13 @@ class FeelExpressionLanguage {
|
|
|
269
270
|
return getFlavouredFeelVariableNames(expression, type);
|
|
270
271
|
}
|
|
271
272
|
|
|
272
|
-
/**
|
|
273
|
-
* Evaluate an expression.
|
|
274
|
-
*
|
|
275
|
-
* @param {string} expression
|
|
276
|
-
* @param {import('../../types').Data} [data]
|
|
277
|
-
*
|
|
278
|
-
* @returns {any}
|
|
273
|
+
/**
|
|
274
|
+
* Evaluate an expression.
|
|
275
|
+
*
|
|
276
|
+
* @param {string} expression
|
|
277
|
+
* @param {import('../../types').Data} [data]
|
|
278
|
+
*
|
|
279
|
+
* @returns {any}
|
|
279
280
|
*/
|
|
280
281
|
evaluate(expression, data = {}) {
|
|
281
282
|
if (!expression) {
|
|
@@ -300,23 +301,23 @@ FeelExpressionLanguage.$inject = ['eventBus'];
|
|
|
300
301
|
class FeelersTemplating {
|
|
301
302
|
constructor() {}
|
|
302
303
|
|
|
303
|
-
/**
|
|
304
|
-
* Determines if the given value is a feelers template.
|
|
305
|
-
*
|
|
306
|
-
* @param {any} value
|
|
307
|
-
* @returns {boolean}
|
|
308
|
-
*
|
|
304
|
+
/**
|
|
305
|
+
* Determines if the given value is a feelers template.
|
|
306
|
+
*
|
|
307
|
+
* @param {any} value
|
|
308
|
+
* @returns {boolean}
|
|
309
|
+
*
|
|
309
310
|
*/
|
|
310
311
|
isTemplate(value) {
|
|
311
312
|
return minDash.isString(value) && (value.startsWith('=') || /{{.*?}}/.test(value));
|
|
312
313
|
}
|
|
313
314
|
|
|
314
|
-
/**
|
|
315
|
-
* Retrieve variable names from a given feelers template.
|
|
316
|
-
*
|
|
317
|
-
* @param {string} template
|
|
318
|
-
*
|
|
319
|
-
* @returns {string[]}
|
|
315
|
+
/**
|
|
316
|
+
* Retrieve variable names from a given feelers template.
|
|
317
|
+
*
|
|
318
|
+
* @param {string} template
|
|
319
|
+
*
|
|
320
|
+
* @returns {string[]}
|
|
320
321
|
*/
|
|
321
322
|
getVariableNames(template) {
|
|
322
323
|
if (!this.isTemplate(template)) {
|
|
@@ -342,17 +343,17 @@ class FeelersTemplating {
|
|
|
342
343
|
}, []);
|
|
343
344
|
}
|
|
344
345
|
|
|
345
|
-
/**
|
|
346
|
-
* Evaluate a template.
|
|
347
|
-
*
|
|
348
|
-
* @param {string} template
|
|
349
|
-
* @param {Object<string, any>} context
|
|
350
|
-
* @param {Object} options
|
|
351
|
-
* @param {boolean} [options.debug = false]
|
|
352
|
-
* @param {boolean} [options.strict = false]
|
|
353
|
-
* @param {Function} [options.buildDebugString]
|
|
354
|
-
*
|
|
355
|
-
* @returns
|
|
346
|
+
/**
|
|
347
|
+
* Evaluate a template.
|
|
348
|
+
*
|
|
349
|
+
* @param {string} template
|
|
350
|
+
* @param {Object<string, any>} context
|
|
351
|
+
* @param {Object} options
|
|
352
|
+
* @param {boolean} [options.debug = false]
|
|
353
|
+
* @param {boolean} [options.strict = false]
|
|
354
|
+
* @param {Function} [options.buildDebugString]
|
|
355
|
+
*
|
|
356
|
+
* @returns
|
|
356
357
|
*/
|
|
357
358
|
evaluate(template, context = {}, options = {}) {
|
|
358
359
|
const {
|
|
@@ -367,22 +368,22 @@ class FeelersTemplating {
|
|
|
367
368
|
});
|
|
368
369
|
}
|
|
369
370
|
|
|
370
|
-
/**
|
|
371
|
-
* @typedef {Object} ExpressionWithDepth
|
|
372
|
-
* @property {number} depth - The depth of the expression in the syntax tree.
|
|
373
|
-
* @property {string} expression - The extracted expression
|
|
371
|
+
/**
|
|
372
|
+
* @typedef {Object} ExpressionWithDepth
|
|
373
|
+
* @property {number} depth - The depth of the expression in the syntax tree.
|
|
374
|
+
* @property {string} expression - The extracted expression
|
|
374
375
|
*/
|
|
375
376
|
|
|
376
|
-
/**
|
|
377
|
-
* Extracts all feel expressions in the template along with their depth in the syntax tree.
|
|
378
|
-
* The depth is incremented for child expressions of loops to account for context drilling.
|
|
379
|
-
|
|
380
|
-
* @param {string} template - A feelers template string.
|
|
381
|
-
* @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
|
|
382
|
-
*
|
|
383
|
-
* @example
|
|
384
|
-
* const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
|
|
385
|
-
* const extractedExpressions = _extractExpressionsWithDepth(template);
|
|
377
|
+
/**
|
|
378
|
+
* Extracts all feel expressions in the template along with their depth in the syntax tree.
|
|
379
|
+
* The depth is incremented for child expressions of loops to account for context drilling.
|
|
380
|
+
* @name extractExpressionsWithDepth
|
|
381
|
+
* @param {string} template - A feelers template string.
|
|
382
|
+
* @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
|
|
386
|
+
* const extractedExpressions = _extractExpressionsWithDepth(template);
|
|
386
387
|
*/
|
|
387
388
|
_extractExpressionsWithDepth(template) {
|
|
388
389
|
// build simplified feelers syntax tree
|
|
@@ -488,10 +489,10 @@ function createInjector(bootstrapModules) {
|
|
|
488
489
|
return injector;
|
|
489
490
|
}
|
|
490
491
|
|
|
491
|
-
/**
|
|
492
|
-
* @param {string?} prefix
|
|
493
|
-
*
|
|
494
|
-
* @returns Element
|
|
492
|
+
/**
|
|
493
|
+
* @param {string?} prefix
|
|
494
|
+
*
|
|
495
|
+
* @returns Element
|
|
495
496
|
*/
|
|
496
497
|
function createFormContainer(prefix = 'fjs') {
|
|
497
498
|
const container = document.createElement('div');
|
|
@@ -622,11 +623,11 @@ const LocalExpressionContext = preact.createContext({
|
|
|
622
623
|
});
|
|
623
624
|
var LocalExpressionContext$1 = LocalExpressionContext;
|
|
624
625
|
|
|
625
|
-
/**
|
|
626
|
-
* @param {string} type
|
|
627
|
-
* @param {boolean} [strict]
|
|
628
|
-
*
|
|
629
|
-
* @returns {any}
|
|
626
|
+
/**
|
|
627
|
+
* @param {string} type
|
|
628
|
+
* @param {boolean} [strict]
|
|
629
|
+
*
|
|
630
|
+
* @returns {any}
|
|
630
631
|
*/
|
|
631
632
|
function getService(type, strict) {}
|
|
632
633
|
const FormContext = preact.createContext({
|
|
@@ -669,21 +670,21 @@ function generateIdForType(type) {
|
|
|
669
670
|
return `${type}${generateIndexForType(type)}`;
|
|
670
671
|
}
|
|
671
672
|
|
|
672
|
-
/**
|
|
673
|
-
* @template T
|
|
674
|
-
* @param {T} data
|
|
675
|
-
* @param {(this: any, key: string, value: any) => any} [replacer]
|
|
676
|
-
* @return {T}
|
|
673
|
+
/**
|
|
674
|
+
* @template T
|
|
675
|
+
* @param {T} data
|
|
676
|
+
* @param {(this: any, key: string, value: any) => any} [replacer]
|
|
677
|
+
* @return {T}
|
|
677
678
|
*/
|
|
678
679
|
function clone(data, replacer) {
|
|
679
680
|
return JSON.parse(JSON.stringify(data, replacer));
|
|
680
681
|
}
|
|
681
682
|
|
|
682
|
-
/**
|
|
683
|
-
* Transform a LocalExpressionContext object into a usable FEEL context.
|
|
684
|
-
*
|
|
685
|
-
* @param {Object} context - The LocalExpressionContext object.
|
|
686
|
-
* @returns {Object} The usable FEEL context.
|
|
683
|
+
/**
|
|
684
|
+
* Transform a LocalExpressionContext object into a usable FEEL context.
|
|
685
|
+
*
|
|
686
|
+
* @param {Object} context - The LocalExpressionContext object.
|
|
687
|
+
* @returns {Object} The usable FEEL context.
|
|
687
688
|
*/
|
|
688
689
|
|
|
689
690
|
function buildExpressionContext(context) {
|
|
@@ -715,12 +716,12 @@ function _wrapObjectKeysWithUnderscores(obj) {
|
|
|
715
716
|
return newObj;
|
|
716
717
|
}
|
|
717
718
|
|
|
718
|
-
/**
|
|
719
|
-
* Evaluate if condition is met reactively based on the conditionChecker and form data.
|
|
720
|
-
*
|
|
721
|
-
* @param {string | undefined} condition
|
|
722
|
-
*
|
|
723
|
-
* @returns {boolean} true if condition is met or no condition or condition checker exists
|
|
719
|
+
/**
|
|
720
|
+
* Evaluate if condition is met reactively based on the conditionChecker and form data.
|
|
721
|
+
*
|
|
722
|
+
* @param {string | undefined} condition
|
|
723
|
+
*
|
|
724
|
+
* @returns {boolean} true if condition is met or no condition or condition checker exists
|
|
724
725
|
*/
|
|
725
726
|
function useCondition(condition) {
|
|
726
727
|
const conditionChecker = useService('conditionChecker', false);
|
|
@@ -730,17 +731,17 @@ function useCondition(condition) {
|
|
|
730
731
|
}, [conditionChecker, condition, expressionContextInfo]);
|
|
731
732
|
}
|
|
732
733
|
|
|
733
|
-
/**
|
|
734
|
-
* Custom hook to scroll an element into view only when it is not visible within the viewport.
|
|
735
|
-
*
|
|
736
|
-
* @param {Object} targetRef - A ref pointing to the DOM element to scroll into view.
|
|
737
|
-
* @param {Array} deps - An array of dependencies that trigger the effect.
|
|
738
|
-
* @param {Array} flagRefs - An array of refs that are used as flags to control when to scroll.
|
|
739
|
-
* @param {Object} [scrollOptions={}] - Options defining the behavior of the scrolling.
|
|
740
|
-
* @param {String} [scrollOptions.align='center'] - The alignment of the element within the viewport.
|
|
741
|
-
* @param {String} [scrollOptions.behavior='auto'] - The scrolling behavior.
|
|
742
|
-
* @param {Number} [scrollOptions.offset=0] - An offset that is added to the scroll position.
|
|
743
|
-
* @param {Boolean} [scrollOptions.scrollIfVisible=false] - Whether to scroll even if the element is visible.
|
|
734
|
+
/**
|
|
735
|
+
* Custom hook to scroll an element into view only when it is not visible within the viewport.
|
|
736
|
+
*
|
|
737
|
+
* @param {Object} targetRef - A ref pointing to the DOM element to scroll into view.
|
|
738
|
+
* @param {Array} deps - An array of dependencies that trigger the effect.
|
|
739
|
+
* @param {Array} flagRefs - An array of refs that are used as flags to control when to scroll.
|
|
740
|
+
* @param {Object} [scrollOptions={}] - Options defining the behavior of the scrolling.
|
|
741
|
+
* @param {String} [scrollOptions.align='center'] - The alignment of the element within the viewport.
|
|
742
|
+
* @param {String} [scrollOptions.behavior='auto'] - The scrolling behavior.
|
|
743
|
+
* @param {Number} [scrollOptions.offset=0] - An offset that is added to the scroll position.
|
|
744
|
+
* @param {Boolean} [scrollOptions.scrollIfVisible=false] - Whether to scroll even if the element is visible.
|
|
744
745
|
*/
|
|
745
746
|
function useScrollIntoView(targetRef, deps, scrollOptions = null, flagRefs = []) {
|
|
746
747
|
hooks.useEffect(() => {
|
|
@@ -805,13 +806,13 @@ function _getTopOffset(item, scrollContainer, options) {
|
|
|
805
806
|
return 0;
|
|
806
807
|
}
|
|
807
808
|
|
|
808
|
-
/**
|
|
809
|
-
* Evaluate a string reactively based on the expressionLanguage and form data.
|
|
810
|
-
* If the string is not an expression, it is returned as is.
|
|
811
|
-
* The function is memoized to minimize re-renders.
|
|
812
|
-
*
|
|
813
|
-
* @param {string} value - The string to evaluate.
|
|
814
|
-
* @returns {any} - Evaluated value or the original value if not an expression.
|
|
809
|
+
/**
|
|
810
|
+
* Evaluate a string reactively based on the expressionLanguage and form data.
|
|
811
|
+
* If the string is not an expression, it is returned as is.
|
|
812
|
+
* The function is memoized to minimize re-renders.
|
|
813
|
+
*
|
|
814
|
+
* @param {string} value - The string to evaluate.
|
|
815
|
+
* @returns {any} - Evaluated value or the original value if not an expression.
|
|
815
816
|
*/
|
|
816
817
|
function useExpressionEvaluation(value) {
|
|
817
818
|
const expressionLanguage = useService('expressionLanguage');
|
|
@@ -824,11 +825,11 @@ function useExpressionEvaluation(value) {
|
|
|
824
825
|
}, [expressionLanguage, expressionContextInfo, value]);
|
|
825
826
|
}
|
|
826
827
|
|
|
827
|
-
/**
|
|
828
|
-
* Returns the conditionally filtered data of a form reactively.
|
|
829
|
-
* Memoised to minimize re-renders
|
|
830
|
-
*
|
|
831
|
-
* Warning: costly operation, use with care
|
|
828
|
+
/**
|
|
829
|
+
* Returns the conditionally filtered data of a form reactively.
|
|
830
|
+
* Memoised to minimize re-renders
|
|
831
|
+
*
|
|
832
|
+
* Warning: costly operation, use with care
|
|
832
833
|
*/
|
|
833
834
|
function useFilteredFormData() {
|
|
834
835
|
const {
|
|
@@ -861,16 +862,16 @@ function useKeyDownAction(targetKey, action, listenerElement = window) {
|
|
|
861
862
|
});
|
|
862
863
|
}
|
|
863
864
|
|
|
864
|
-
/**
|
|
865
|
-
* Retrieve readonly value of a form field, given it can be an
|
|
866
|
-
* expression optionally or configured globally.
|
|
867
|
-
*
|
|
868
|
-
* @typedef { import('../../types').FormProperties } FormProperties
|
|
869
|
-
*
|
|
870
|
-
* @param {any} formField
|
|
871
|
-
* @param {FormProperties} properties
|
|
872
|
-
*
|
|
873
|
-
* @returns {boolean}
|
|
865
|
+
/**
|
|
866
|
+
* Retrieve readonly value of a form field, given it can be an
|
|
867
|
+
* expression optionally or configured globally.
|
|
868
|
+
*
|
|
869
|
+
* @typedef { import('../../types').FormProperties } FormProperties
|
|
870
|
+
*
|
|
871
|
+
* @param {any} formField
|
|
872
|
+
* @param {FormProperties} properties
|
|
873
|
+
*
|
|
874
|
+
* @returns {boolean}
|
|
874
875
|
*/
|
|
875
876
|
function useReadonly(formField, properties = {}) {
|
|
876
877
|
const expressionLanguage = useService('expressionLanguage');
|
|
@@ -894,12 +895,12 @@ function usePrevious(value, defaultValue, dependencies) {
|
|
|
894
895
|
return ref.current;
|
|
895
896
|
}
|
|
896
897
|
|
|
897
|
-
/**
|
|
898
|
-
* A custom hook to manage state changes with deep comparison.
|
|
899
|
-
*
|
|
900
|
-
* @param {any} value - The current value to manage.
|
|
901
|
-
* @param {any} defaultValue - The initial default value for the state.
|
|
902
|
-
* @returns {any} - Returns the current state.
|
|
898
|
+
/**
|
|
899
|
+
* A custom hook to manage state changes with deep comparison.
|
|
900
|
+
*
|
|
901
|
+
* @param {any} value - The current value to manage.
|
|
902
|
+
* @param {any} defaultValue - The initial default value for the state.
|
|
903
|
+
* @returns {any} - Returns the current state.
|
|
903
904
|
*/
|
|
904
905
|
function useDeepCompareState(value, defaultValue) {
|
|
905
906
|
const [state, setState] = hooks.useState(defaultValue);
|
|
@@ -919,16 +920,16 @@ function compare(a, b) {
|
|
|
919
920
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
920
921
|
}
|
|
921
922
|
|
|
922
|
-
/**
|
|
923
|
-
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
924
|
-
* Memoised to minimize re-renders
|
|
925
|
-
*
|
|
926
|
-
* @param {string} value
|
|
927
|
-
* @param {Object} options
|
|
928
|
-
* @param {boolean} [options.debug = false]
|
|
929
|
-
* @param {boolean} [options.strict = false]
|
|
930
|
-
* @param {Function} [options.buildDebugString]
|
|
931
|
-
*
|
|
923
|
+
/**
|
|
924
|
+
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
925
|
+
* Memoised to minimize re-renders
|
|
926
|
+
*
|
|
927
|
+
* @param {string} value
|
|
928
|
+
* @param {Object} options
|
|
929
|
+
* @param {boolean} [options.debug = false]
|
|
930
|
+
* @param {boolean} [options.strict = false]
|
|
931
|
+
* @param {Function} [options.buildDebugString]
|
|
932
|
+
*
|
|
932
933
|
*/
|
|
933
934
|
function useTemplateEvaluation(value, options = {}) {
|
|
934
935
|
const templating = useService('templating');
|
|
@@ -941,17 +942,17 @@ function useTemplateEvaluation(value, options = {}) {
|
|
|
941
942
|
}, [templating, value, expressionContextInfo, options]);
|
|
942
943
|
}
|
|
943
944
|
|
|
944
|
-
/**
|
|
945
|
-
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
946
|
-
* If the string contains multiple lines, only the first line is returned.
|
|
947
|
-
* Memoised to minimize re-renders
|
|
948
|
-
*
|
|
949
|
-
* @param {string} value
|
|
950
|
-
* @param {Object} [options]
|
|
951
|
-
* @param {boolean} [options.debug = false]
|
|
952
|
-
* @param {boolean} [options.strict = false]
|
|
953
|
-
* @param {Function} [options.buildDebugString]
|
|
954
|
-
*
|
|
945
|
+
/**
|
|
946
|
+
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
947
|
+
* If the string contains multiple lines, only the first line is returned.
|
|
948
|
+
* Memoised to minimize re-renders
|
|
949
|
+
*
|
|
950
|
+
* @param {string} value
|
|
951
|
+
* @param {Object} [options]
|
|
952
|
+
* @param {boolean} [options.debug = false]
|
|
953
|
+
* @param {boolean} [options.strict = false]
|
|
954
|
+
* @param {Function} [options.buildDebugString]
|
|
955
|
+
*
|
|
955
956
|
*/
|
|
956
957
|
function useSingleLineTemplateEvaluation(value, options = {}) {
|
|
957
958
|
const evaluatedTemplate = useTemplateEvaluation(value, options);
|
|
@@ -1104,39 +1105,58 @@ function getOptionsData(formField, formData) {
|
|
|
1104
1105
|
|
|
1105
1106
|
// transforms the provided options into a normalized format, trimming invalid options
|
|
1106
1107
|
function normalizeOptionsData(optionsData) {
|
|
1107
|
-
return optionsData.filter(
|
|
1108
|
+
return optionsData.filter(_isAllowedValue).map(_normalizeOption).filter(o => !minDash.isNil(o));
|
|
1108
1109
|
}
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1110
|
+
|
|
1111
|
+
/**
|
|
1112
|
+
* Converts the provided option to a normalized format.
|
|
1113
|
+
* If the option is not valid, null is returned.
|
|
1114
|
+
*
|
|
1115
|
+
* @param {object} option
|
|
1116
|
+
* @param {string} option.label
|
|
1117
|
+
* @param {*} option.value
|
|
1118
|
+
*
|
|
1119
|
+
* @returns
|
|
1120
|
+
*/
|
|
1121
|
+
function _normalizeOption(option) {
|
|
1122
|
+
// (1) simple primitive case, use it as both label and value
|
|
1123
|
+
if (_isAllowedPrimitive(option)) {
|
|
1112
1124
|
return {
|
|
1113
|
-
value:
|
|
1114
|
-
label: `${
|
|
1125
|
+
value: option,
|
|
1126
|
+
label: `${option}`
|
|
1115
1127
|
};
|
|
1116
1128
|
}
|
|
1117
|
-
if (
|
|
1118
|
-
|
|
1119
|
-
|
|
1129
|
+
if (minDash.isObject(option)) {
|
|
1130
|
+
const isValidLabel = _isValidLabel(option.label);
|
|
1131
|
+
|
|
1132
|
+
// (2) no label provided, but value is a simple primitive, use it as label and value
|
|
1133
|
+
if (!isValidLabel && _isAllowedPrimitive(option.value)) {
|
|
1120
1134
|
return {
|
|
1121
|
-
value:
|
|
1122
|
-
label: `${
|
|
1135
|
+
value: option.value,
|
|
1136
|
+
label: `${option.value}`
|
|
1123
1137
|
};
|
|
1124
1138
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1139
|
+
|
|
1140
|
+
// (3) both label and value are provided, use them as is
|
|
1141
|
+
if (isValidLabel && _isAllowedValue(option.value)) {
|
|
1142
|
+
return option;
|
|
1128
1143
|
}
|
|
1129
1144
|
}
|
|
1130
1145
|
return null;
|
|
1131
1146
|
}
|
|
1132
|
-
function
|
|
1133
|
-
|
|
1147
|
+
function _isAllowedPrimitive(value) {
|
|
1148
|
+
const isAllowedPrimitiveType = ['number', 'string', 'boolean'].includes(typeof value);
|
|
1149
|
+
const isValid = value || value === 0 || value === false;
|
|
1150
|
+
return isAllowedPrimitiveType && isValid;
|
|
1134
1151
|
}
|
|
1135
|
-
function
|
|
1136
|
-
return
|
|
1152
|
+
function _isValidLabel(label) {
|
|
1153
|
+
return label && minDash.isString(label);
|
|
1137
1154
|
}
|
|
1138
|
-
function
|
|
1139
|
-
|
|
1155
|
+
function _isAllowedValue(value) {
|
|
1156
|
+
if (minDash.isObject(value)) {
|
|
1157
|
+
return Object.keys(value).length > 0;
|
|
1158
|
+
}
|
|
1159
|
+
return _isAllowedPrimitive(value);
|
|
1140
1160
|
}
|
|
1141
1161
|
function createEmptyOptions(options = {}) {
|
|
1142
1162
|
const defaults = {};
|
|
@@ -1154,8 +1174,8 @@ function createEmptyOptions(options = {}) {
|
|
|
1154
1174
|
};
|
|
1155
1175
|
}
|
|
1156
1176
|
|
|
1157
|
-
/**
|
|
1158
|
-
* @enum { String }
|
|
1177
|
+
/**
|
|
1178
|
+
* @enum { String }
|
|
1159
1179
|
*/
|
|
1160
1180
|
const LOAD_STATES = {
|
|
1161
1181
|
LOADING: 'loading',
|
|
@@ -1163,17 +1183,17 @@ const LOAD_STATES = {
|
|
|
1163
1183
|
ERROR: 'error'
|
|
1164
1184
|
};
|
|
1165
1185
|
|
|
1166
|
-
/**
|
|
1167
|
-
* @typedef {Object} OptionsGetter
|
|
1168
|
-
* @property {Object[]} options - The options data
|
|
1169
|
-
* @property {(LOAD_STATES)} loadState - The options data's loading state, to use for conditional rendering
|
|
1186
|
+
/**
|
|
1187
|
+
* @typedef {Object} OptionsGetter
|
|
1188
|
+
* @property {Object[]} options - The options data
|
|
1189
|
+
* @property {(LOAD_STATES)} loadState - The options data's loading state, to use for conditional rendering
|
|
1170
1190
|
*/
|
|
1171
1191
|
|
|
1172
|
-
/**
|
|
1173
|
-
* A hook to load options for single and multiselect components.
|
|
1174
|
-
*
|
|
1175
|
-
* @param {Object} field - The form field to handle options for
|
|
1176
|
-
* @return {OptionsGetter} optionsGetter - A options getter object providing loading state and options
|
|
1192
|
+
/**
|
|
1193
|
+
* A hook to load options for single and multiselect components.
|
|
1194
|
+
*
|
|
1195
|
+
* @param {Object} field - The form field to handle options for
|
|
1196
|
+
* @return {OptionsGetter} optionsGetter - A options getter object providing loading state and options
|
|
1177
1197
|
*/
|
|
1178
1198
|
function useOptionsAsync (field) {
|
|
1179
1199
|
const {
|
|
@@ -1230,30 +1250,6 @@ const buildLoadedState = options => ({
|
|
|
1230
1250
|
loadState: LOAD_STATES.LOADED
|
|
1231
1251
|
});
|
|
1232
1252
|
|
|
1233
|
-
function useCleanupMultiSelectValues (props) {
|
|
1234
|
-
const {
|
|
1235
|
-
field,
|
|
1236
|
-
options,
|
|
1237
|
-
loadState,
|
|
1238
|
-
onChange,
|
|
1239
|
-
values
|
|
1240
|
-
} = props;
|
|
1241
|
-
|
|
1242
|
-
// Ensures that the values are always a subset of the possible options
|
|
1243
|
-
hooks.useEffect(() => {
|
|
1244
|
-
if (loadState !== LOAD_STATES.LOADED) {
|
|
1245
|
-
return;
|
|
1246
|
-
}
|
|
1247
|
-
const hasValuesNotInOptions = values.some(v => !options.map(o => o.value).includes(v));
|
|
1248
|
-
if (hasValuesNotInOptions) {
|
|
1249
|
-
onChange({
|
|
1250
|
-
field,
|
|
1251
|
-
value: values.filter(v => options.map(o => o.value).includes(v))
|
|
1252
|
-
});
|
|
1253
|
-
}
|
|
1254
|
-
}, [field, options, onChange, JSON.stringify(values), loadState]);
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
1253
|
const ENTER_KEYDOWN_EVENT = new KeyboardEvent('keydown', {
|
|
1258
1254
|
code: 'Enter',
|
|
1259
1255
|
key: 'Enter',
|
|
@@ -1429,6 +1425,12 @@ function sanitizeDateTimePickerValue(options) {
|
|
|
1429
1425
|
if (subtype === DATETIME_SUBTYPES.DATETIME && (isInvalidDateString(value) || !isDateTimeInputInformationSufficient(value))) return null;
|
|
1430
1426
|
return value;
|
|
1431
1427
|
}
|
|
1428
|
+
function hasEqualValue(value, array) {
|
|
1429
|
+
if (!Array.isArray(array)) {
|
|
1430
|
+
return false;
|
|
1431
|
+
}
|
|
1432
|
+
return array.some(element => isEqual(value, element));
|
|
1433
|
+
}
|
|
1432
1434
|
function sanitizeSingleSelectValue(options) {
|
|
1433
1435
|
const {
|
|
1434
1436
|
formField,
|
|
@@ -1437,7 +1439,7 @@ function sanitizeSingleSelectValue(options) {
|
|
|
1437
1439
|
} = options;
|
|
1438
1440
|
try {
|
|
1439
1441
|
const validValues = normalizeOptionsData(getOptionsData(formField, data)).map(v => v.value);
|
|
1440
|
-
return
|
|
1442
|
+
return hasEqualValue(value, validValues) ? value : null;
|
|
1441
1443
|
} catch (error) {
|
|
1442
1444
|
// use default value in case of formatting error
|
|
1443
1445
|
// TODO(@Skaiir): log a warning when this happens - https://github.com/bpmn-io/form-js/issues/289
|
|
@@ -1452,7 +1454,7 @@ function sanitizeMultiSelectValue(options) {
|
|
|
1452
1454
|
} = options;
|
|
1453
1455
|
try {
|
|
1454
1456
|
const validValues = normalizeOptionsData(getOptionsData(formField, data)).map(v => v.value);
|
|
1455
|
-
return value.filter(v =>
|
|
1457
|
+
return value.filter(v => hasEqualValue(v, validValues));
|
|
1456
1458
|
} catch (error) {
|
|
1457
1459
|
// use default value in case of formatting error
|
|
1458
1460
|
// TODO(@Skaiir): log a warning when this happens - https://github.com/bpmn-io/form-js/issues/289
|
|
@@ -1460,6 +1462,31 @@ function sanitizeMultiSelectValue(options) {
|
|
|
1460
1462
|
}
|
|
1461
1463
|
}
|
|
1462
1464
|
|
|
1465
|
+
function useCleanupMultiSelectValues (props) {
|
|
1466
|
+
const {
|
|
1467
|
+
field,
|
|
1468
|
+
options,
|
|
1469
|
+
loadState,
|
|
1470
|
+
onChange,
|
|
1471
|
+
values
|
|
1472
|
+
} = props;
|
|
1473
|
+
|
|
1474
|
+
// Ensures that the values are always a subset of the possible options
|
|
1475
|
+
hooks.useEffect(() => {
|
|
1476
|
+
if (loadState !== LOAD_STATES.LOADED) {
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
const optionValues = options.map(o => o.value);
|
|
1480
|
+
const hasValuesNotInOptions = values.some(v => !hasEqualValue(v, optionValues));
|
|
1481
|
+
if (hasValuesNotInOptions) {
|
|
1482
|
+
onChange({
|
|
1483
|
+
field,
|
|
1484
|
+
value: values.filter(v => hasEqualValue(v, optionValues))
|
|
1485
|
+
});
|
|
1486
|
+
}
|
|
1487
|
+
}, [field, options, onChange, JSON.stringify(values), loadState]);
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1463
1490
|
const type$d = 'checklist';
|
|
1464
1491
|
function Checklist(props) {
|
|
1465
1492
|
const {
|
|
@@ -1482,16 +1509,11 @@ function Checklist(props) {
|
|
|
1482
1509
|
const {
|
|
1483
1510
|
required
|
|
1484
1511
|
} = validate;
|
|
1485
|
-
const toggleCheckbox =
|
|
1486
|
-
|
|
1487
|
-
if (!newValue.includes(v)) {
|
|
1488
|
-
newValue.push(v);
|
|
1489
|
-
} else {
|
|
1490
|
-
newValue = newValue.filter(x => x != v);
|
|
1491
|
-
}
|
|
1512
|
+
const toggleCheckbox = toggledValue => {
|
|
1513
|
+
const newValues = hasEqualValue(toggledValue, values) ? values.filter(value => !isEqual(value, toggledValue)) : [...values, toggledValue];
|
|
1492
1514
|
props.onChange({
|
|
1493
1515
|
field,
|
|
1494
|
-
value:
|
|
1516
|
+
value: newValues
|
|
1495
1517
|
});
|
|
1496
1518
|
};
|
|
1497
1519
|
const onCheckboxBlur = e => {
|
|
@@ -1529,15 +1551,16 @@ function Checklist(props) {
|
|
|
1529
1551
|
required: required
|
|
1530
1552
|
}), loadState == LOAD_STATES.LOADED && options.map((o, index) => {
|
|
1531
1553
|
const itemDomId = `${domId}-${index}`;
|
|
1554
|
+
const isChecked = hasEqualValue(o.value, values);
|
|
1532
1555
|
return jsxRuntime.jsx(Label, {
|
|
1533
1556
|
id: itemDomId,
|
|
1534
1557
|
label: o.label,
|
|
1535
1558
|
class: classNames({
|
|
1536
|
-
'fjs-checked':
|
|
1559
|
+
'fjs-checked': isChecked
|
|
1537
1560
|
}),
|
|
1538
1561
|
required: false,
|
|
1539
1562
|
children: jsxRuntime.jsx("input", {
|
|
1540
|
-
checked:
|
|
1563
|
+
checked: isChecked,
|
|
1541
1564
|
class: "fjs-input",
|
|
1542
1565
|
disabled: disabled,
|
|
1543
1566
|
readOnly: readonly,
|
|
@@ -1817,12 +1840,12 @@ FormComponent$1.config = {
|
|
|
1817
1840
|
})
|
|
1818
1841
|
};
|
|
1819
1842
|
|
|
1820
|
-
/**
|
|
1821
|
-
* Returns date format for the provided locale.
|
|
1822
|
-
* If the locale is not provided, uses the browser's locale.
|
|
1823
|
-
*
|
|
1824
|
-
* @param {string} [locale] - The locale to get date format for.
|
|
1825
|
-
* @returns {string} The date format for the locale.
|
|
1843
|
+
/**
|
|
1844
|
+
* Returns date format for the provided locale.
|
|
1845
|
+
* If the locale is not provided, uses the browser's locale.
|
|
1846
|
+
*
|
|
1847
|
+
* @param {string} [locale] - The locale to get date format for.
|
|
1848
|
+
* @returns {string} The date format for the locale.
|
|
1826
1849
|
*/
|
|
1827
1850
|
function getLocaleDateFormat(locale = 'default') {
|
|
1828
1851
|
const parts = new Intl.DateTimeFormat(locale).formatToParts(new Date(Date.UTC(2020, 5, 5)));
|
|
@@ -1841,12 +1864,12 @@ function getLocaleDateFormat(locale = 'default') {
|
|
|
1841
1864
|
}).join('');
|
|
1842
1865
|
}
|
|
1843
1866
|
|
|
1844
|
-
/**
|
|
1845
|
-
* Returns readable date format for the provided locale.
|
|
1846
|
-
* If the locale is not provided, uses the browser's locale.
|
|
1847
|
-
*
|
|
1848
|
-
* @param {string} [locale] - The locale to get readable date format for.
|
|
1849
|
-
* @returns {string} The readable date format for the locale.
|
|
1867
|
+
/**
|
|
1868
|
+
* Returns readable date format for the provided locale.
|
|
1869
|
+
* If the locale is not provided, uses the browser's locale.
|
|
1870
|
+
*
|
|
1871
|
+
* @param {string} [locale] - The locale to get readable date format for.
|
|
1872
|
+
* @returns {string} The readable date format for the locale.
|
|
1850
1873
|
*/
|
|
1851
1874
|
function getLocaleReadableDateFormat(locale) {
|
|
1852
1875
|
let format = getLocaleDateFormat(locale).toLowerCase();
|
|
@@ -1863,12 +1886,12 @@ function getLocaleReadableDateFormat(locale) {
|
|
|
1863
1886
|
return format;
|
|
1864
1887
|
}
|
|
1865
1888
|
|
|
1866
|
-
/**
|
|
1867
|
-
* Returns flatpickr config for the provided locale.
|
|
1868
|
-
* If the locale is not provided, uses the browser's locale.
|
|
1869
|
-
*
|
|
1870
|
-
* @param {string} [locale] - The locale to get flatpickr config for.
|
|
1871
|
-
* @returns {object} The flatpickr config for the locale.
|
|
1889
|
+
/**
|
|
1890
|
+
* Returns flatpickr config for the provided locale.
|
|
1891
|
+
* If the locale is not provided, uses the browser's locale.
|
|
1892
|
+
*
|
|
1893
|
+
* @param {string} [locale] - The locale to get flatpickr config for.
|
|
1894
|
+
* @returns {object} The flatpickr config for the locale.
|
|
1872
1895
|
*/
|
|
1873
1896
|
function getLocaleDateFlatpickrConfig(locale) {
|
|
1874
1897
|
return flatpickerizeDateFormat(getLocaleDateFormat(locale));
|
|
@@ -2580,10 +2603,10 @@ Datetime.config = {
|
|
|
2580
2603
|
}
|
|
2581
2604
|
};
|
|
2582
2605
|
|
|
2583
|
-
/**
|
|
2584
|
-
* This file must not be changed or exchanged.
|
|
2585
|
-
*
|
|
2586
|
-
* @see http://bpmn.io/license for more information.
|
|
2606
|
+
/**
|
|
2607
|
+
* This file must not be changed or exchanged.
|
|
2608
|
+
*
|
|
2609
|
+
* @see http://bpmn.io/license for more information.
|
|
2587
2610
|
*/
|
|
2588
2611
|
function Logo() {
|
|
2589
2612
|
return jsxRuntime.jsxs("svg", {
|
|
@@ -2769,11 +2792,11 @@ const ATTR_WHITESPACE_PATTERN = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u
|
|
|
2769
2792
|
|
|
2770
2793
|
const FORM_ELEMENT = document.createElement('form');
|
|
2771
2794
|
|
|
2772
|
-
/**
|
|
2773
|
-
* Sanitize a HTML string and return the cleaned, safe version.
|
|
2774
|
-
*
|
|
2775
|
-
* @param {string} html
|
|
2776
|
-
* @return {string}
|
|
2795
|
+
/**
|
|
2796
|
+
* Sanitize a HTML string and return the cleaned, safe version.
|
|
2797
|
+
*
|
|
2798
|
+
* @param {string} html
|
|
2799
|
+
* @return {string}
|
|
2777
2800
|
*/
|
|
2778
2801
|
|
|
2779
2802
|
// see https://github.com/developit/snarkdown/issues/70
|
|
@@ -2791,41 +2814,41 @@ function sanitizeHTML(html) {
|
|
|
2791
2814
|
}
|
|
2792
2815
|
}
|
|
2793
2816
|
|
|
2794
|
-
/**
|
|
2795
|
-
* Sanitizes an image source to ensure we only allow for data URI and links
|
|
2796
|
-
* that start with http(s).
|
|
2797
|
-
*
|
|
2798
|
-
* Note: Most browsers anyway do not support script execution in <img> elements.
|
|
2799
|
-
*
|
|
2800
|
-
* @param {string} src
|
|
2801
|
-
* @returns {string}
|
|
2817
|
+
/**
|
|
2818
|
+
* Sanitizes an image source to ensure we only allow for data URI and links
|
|
2819
|
+
* that start with http(s).
|
|
2820
|
+
*
|
|
2821
|
+
* Note: Most browsers anyway do not support script execution in <img> elements.
|
|
2822
|
+
*
|
|
2823
|
+
* @param {string} src
|
|
2824
|
+
* @returns {string}
|
|
2802
2825
|
*/
|
|
2803
2826
|
function sanitizeImageSource(src) {
|
|
2804
2827
|
const valid = ALLOWED_IMAGE_SRC_PATTERN.test(src);
|
|
2805
2828
|
return valid ? src : '';
|
|
2806
2829
|
}
|
|
2807
2830
|
|
|
2808
|
-
/**
|
|
2809
|
-
* Sanitizes an iframe source to ensure we only allow for links
|
|
2810
|
-
* that start with http(s).
|
|
2811
|
-
*
|
|
2812
|
-
* @param {string} src
|
|
2813
|
-
* @returns {string}
|
|
2831
|
+
/**
|
|
2832
|
+
* Sanitizes an iframe source to ensure we only allow for links
|
|
2833
|
+
* that start with http(s).
|
|
2834
|
+
*
|
|
2835
|
+
* @param {string} src
|
|
2836
|
+
* @returns {string}
|
|
2814
2837
|
*/
|
|
2815
2838
|
function sanitizeIFrameSource(src) {
|
|
2816
2839
|
const valid = ALLOWED_IFRAME_SRC_PATTERN.test(src);
|
|
2817
2840
|
return valid ? src : '';
|
|
2818
2841
|
}
|
|
2819
2842
|
|
|
2820
|
-
/**
|
|
2821
|
-
* Recursively sanitize a HTML node, potentially
|
|
2822
|
-
* removing it, its children or attributes.
|
|
2823
|
-
*
|
|
2824
|
-
* Inspired by https://github.com/developit/snarkdown/issues/70
|
|
2825
|
-
* and https://github.com/cure53/DOMPurify. Simplified
|
|
2826
|
-
* for our use-case.
|
|
2827
|
-
*
|
|
2828
|
-
* @param {Element} node
|
|
2843
|
+
/**
|
|
2844
|
+
* Recursively sanitize a HTML node, potentially
|
|
2845
|
+
* removing it, its children or attributes.
|
|
2846
|
+
*
|
|
2847
|
+
* Inspired by https://github.com/developit/snarkdown/issues/70
|
|
2848
|
+
* and https://github.com/cure53/DOMPurify. Simplified
|
|
2849
|
+
* for our use-case.
|
|
2850
|
+
*
|
|
2851
|
+
* @param {Element} node
|
|
2829
2852
|
*/
|
|
2830
2853
|
function sanitizeNode(node) {
|
|
2831
2854
|
// allow text nodes
|
|
@@ -2869,13 +2892,13 @@ function sanitizeNode(node) {
|
|
|
2869
2892
|
}
|
|
2870
2893
|
}
|
|
2871
2894
|
|
|
2872
|
-
/**
|
|
2873
|
-
* Validates attributes for validity.
|
|
2874
|
-
*
|
|
2875
|
-
* @param {string} lcTag
|
|
2876
|
-
* @param {string} lcName
|
|
2877
|
-
* @param {string} value
|
|
2878
|
-
* @return {boolean}
|
|
2895
|
+
/**
|
|
2896
|
+
* Validates attributes for validity.
|
|
2897
|
+
*
|
|
2898
|
+
* @param {string} lcTag
|
|
2899
|
+
* @param {string} lcName
|
|
2900
|
+
* @param {string} value
|
|
2901
|
+
* @return {boolean}
|
|
2879
2902
|
*/
|
|
2880
2903
|
function isValidAttribute(lcTag, lcName, value) {
|
|
2881
2904
|
// disallow most attributes based on whitelist
|
|
@@ -2938,7 +2961,7 @@ function IFrame(props) {
|
|
|
2938
2961
|
height: height,
|
|
2939
2962
|
class: "fjs-iframe",
|
|
2940
2963
|
id: prefixId(id, formId),
|
|
2941
|
-
sandbox: ""
|
|
2964
|
+
sandbox: "allow-scripts"
|
|
2942
2965
|
}), evaluatedUrl && !safeUrl && jsxRuntime.jsx(IFramePlaceholder, {
|
|
2943
2966
|
text: "External content couldn't be loaded."
|
|
2944
2967
|
})]
|
|
@@ -3055,6 +3078,40 @@ Image.config = {
|
|
|
3055
3078
|
})
|
|
3056
3079
|
};
|
|
3057
3080
|
|
|
3081
|
+
function useFlushDebounce(func, additionalDeps = []) {
|
|
3082
|
+
const timeoutRef = hooks.useRef(null);
|
|
3083
|
+
const lastArgsRef = hooks.useRef(null);
|
|
3084
|
+
const config = useService('config', false);
|
|
3085
|
+
const debounce = config && config.debounce;
|
|
3086
|
+
const shouldDebounce = debounce !== false && debounce !== 0;
|
|
3087
|
+
const delay = typeof debounce === 'number' ? debounce : 300;
|
|
3088
|
+
const debounceFunc = hooks.useCallback((...args) => {
|
|
3089
|
+
if (!shouldDebounce) {
|
|
3090
|
+
func(...args);
|
|
3091
|
+
return;
|
|
3092
|
+
}
|
|
3093
|
+
lastArgsRef.current = args;
|
|
3094
|
+
if (timeoutRef.current) {
|
|
3095
|
+
clearTimeout(timeoutRef.current);
|
|
3096
|
+
}
|
|
3097
|
+
timeoutRef.current = setTimeout(() => {
|
|
3098
|
+
func(...lastArgsRef.current);
|
|
3099
|
+
lastArgsRef.current = null;
|
|
3100
|
+
}, delay);
|
|
3101
|
+
}, [func, delay, shouldDebounce, ...additionalDeps]);
|
|
3102
|
+
const flushFunc = hooks.useCallback(() => {
|
|
3103
|
+
if (timeoutRef.current) {
|
|
3104
|
+
clearTimeout(timeoutRef.current);
|
|
3105
|
+
if (lastArgsRef.current !== null) {
|
|
3106
|
+
func(...lastArgsRef.current);
|
|
3107
|
+
lastArgsRef.current = null;
|
|
3108
|
+
}
|
|
3109
|
+
timeoutRef.current = null;
|
|
3110
|
+
}
|
|
3111
|
+
}, [func, ...additionalDeps]);
|
|
3112
|
+
return [debounceFunc, flushFunc];
|
|
3113
|
+
}
|
|
3114
|
+
|
|
3058
3115
|
function TemplatedInputAdorner(props) {
|
|
3059
3116
|
const {
|
|
3060
3117
|
pre,
|
|
@@ -3145,8 +3202,7 @@ function Numberfield(props) {
|
|
|
3145
3202
|
onFocus,
|
|
3146
3203
|
field,
|
|
3147
3204
|
value,
|
|
3148
|
-
readonly
|
|
3149
|
-
onChange
|
|
3205
|
+
readonly
|
|
3150
3206
|
} = props;
|
|
3151
3207
|
const {
|
|
3152
3208
|
description,
|
|
@@ -3166,6 +3222,16 @@ function Numberfield(props) {
|
|
|
3166
3222
|
} = validate;
|
|
3167
3223
|
const inputRef = hooks.useRef();
|
|
3168
3224
|
const [stringValueCache, setStringValueCache] = hooks.useState('');
|
|
3225
|
+
const [onChangeDebounced, flushOnChange] = useFlushDebounce(params => {
|
|
3226
|
+
props.onChange(params);
|
|
3227
|
+
}, [props.onChange]);
|
|
3228
|
+
const onInputBlur = () => {
|
|
3229
|
+
flushOnChange && flushOnChange();
|
|
3230
|
+
onBlur && onBlur();
|
|
3231
|
+
};
|
|
3232
|
+
const onInputFocus = () => {
|
|
3233
|
+
onFocus && onFocus();
|
|
3234
|
+
};
|
|
3169
3235
|
|
|
3170
3236
|
// checks whether the value currently in the form data is practically different from the one in the input field cache
|
|
3171
3237
|
// this allows us to guarantee the field always displays valid form data, but without auto-simplifying values like 1.000 to 1
|
|
@@ -3189,7 +3255,7 @@ function Numberfield(props) {
|
|
|
3189
3255
|
const setValue = hooks.useCallback(stringValue => {
|
|
3190
3256
|
if (isNullEquivalentValue(stringValue)) {
|
|
3191
3257
|
setStringValueCache('');
|
|
3192
|
-
|
|
3258
|
+
onChangeDebounced({
|
|
3193
3259
|
field,
|
|
3194
3260
|
value: null
|
|
3195
3261
|
});
|
|
@@ -3204,18 +3270,18 @@ function Numberfield(props) {
|
|
|
3204
3270
|
}
|
|
3205
3271
|
if (isNaN(Number(stringValue))) {
|
|
3206
3272
|
setStringValueCache('NaN');
|
|
3207
|
-
|
|
3273
|
+
onChangeDebounced({
|
|
3208
3274
|
field,
|
|
3209
3275
|
value: 'NaN'
|
|
3210
3276
|
});
|
|
3211
3277
|
return;
|
|
3212
3278
|
}
|
|
3213
3279
|
setStringValueCache(stringValue);
|
|
3214
|
-
|
|
3280
|
+
onChangeDebounced({
|
|
3215
3281
|
field,
|
|
3216
3282
|
value: serializeToString ? stringValue : Number(stringValue)
|
|
3217
3283
|
});
|
|
3218
|
-
}, [field,
|
|
3284
|
+
}, [field, onChangeDebounced, serializeToString]);
|
|
3219
3285
|
const increment = () => {
|
|
3220
3286
|
if (readonly) {
|
|
3221
3287
|
return;
|
|
@@ -3299,8 +3365,8 @@ function Numberfield(props) {
|
|
|
3299
3365
|
id: domId,
|
|
3300
3366
|
onKeyDown: onKeyDown,
|
|
3301
3367
|
onKeyPress: onKeyPress,
|
|
3302
|
-
onBlur:
|
|
3303
|
-
onFocus:
|
|
3368
|
+
onBlur: onInputBlur,
|
|
3369
|
+
onFocus: onInputFocus
|
|
3304
3370
|
|
|
3305
3371
|
// @ts-ignore
|
|
3306
3372
|
,
|
|
@@ -3377,7 +3443,8 @@ function useCleanupSingleSelectValue (props) {
|
|
|
3377
3443
|
if (loadState !== LOAD_STATES.LOADED) {
|
|
3378
3444
|
return;
|
|
3379
3445
|
}
|
|
3380
|
-
const
|
|
3446
|
+
const optionValues = options.map(o => o.value);
|
|
3447
|
+
const hasValueNotInOptions = value && !hasEqualValue(value, optionValues);
|
|
3381
3448
|
if (hasValueNotInOptions) {
|
|
3382
3449
|
onChange({
|
|
3383
3450
|
field,
|
|
@@ -3450,15 +3517,16 @@ function Radio(props) {
|
|
|
3450
3517
|
required: required
|
|
3451
3518
|
}), loadState == LOAD_STATES.LOADED && options.map((option, index) => {
|
|
3452
3519
|
const itemDomId = `${domId}-${index}`;
|
|
3520
|
+
const isChecked = isEqual(option.value, value);
|
|
3453
3521
|
return jsxRuntime.jsx(Label, {
|
|
3454
3522
|
id: itemDomId,
|
|
3455
3523
|
label: option.label,
|
|
3456
3524
|
class: classNames({
|
|
3457
|
-
'fjs-checked':
|
|
3525
|
+
'fjs-checked': isChecked
|
|
3458
3526
|
}),
|
|
3459
3527
|
required: false,
|
|
3460
3528
|
children: jsxRuntime.jsx("input", {
|
|
3461
|
-
checked:
|
|
3529
|
+
checked: isChecked,
|
|
3462
3530
|
class: "fjs-input",
|
|
3463
3531
|
disabled: disabled,
|
|
3464
3532
|
readOnly: readonly,
|
|
@@ -3488,6 +3556,21 @@ Radio.config = {
|
|
|
3488
3556
|
create: createEmptyOptions
|
|
3489
3557
|
};
|
|
3490
3558
|
|
|
3559
|
+
/**
|
|
3560
|
+
* This hook allows us to retrieve the label from a value in linear time by caching it in a map
|
|
3561
|
+
* @param {Array} options
|
|
3562
|
+
*/
|
|
3563
|
+
function useGetLabelCorrelation(options) {
|
|
3564
|
+
// This allows us to retrieve the label from a value in linear time
|
|
3565
|
+
const labelMap = hooks.useMemo(() => Object.assign({}, ...options.map(o => ({
|
|
3566
|
+
[_getValueHash(o.value)]: o.label
|
|
3567
|
+
}))), [options]);
|
|
3568
|
+
return hooks.useCallback(value => labelMap[_getValueHash(value)], [labelMap]);
|
|
3569
|
+
}
|
|
3570
|
+
const _getValueHash = value => {
|
|
3571
|
+
return minDash.isObject(value) ? JSON.stringify(value) : value;
|
|
3572
|
+
};
|
|
3573
|
+
|
|
3491
3574
|
var _path$q;
|
|
3492
3575
|
function _extends$r() { _extends$r = 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$r.apply(this, arguments); }
|
|
3493
3576
|
var SvgXMark = function SvgXMark(props) {
|
|
@@ -3519,7 +3602,7 @@ function SearchableSelect(props) {
|
|
|
3519
3602
|
} = props;
|
|
3520
3603
|
const [filter, setFilter] = hooks.useState('');
|
|
3521
3604
|
const [isDropdownExpanded, setIsDropdownExpanded] = hooks.useState(false);
|
|
3522
|
-
const [
|
|
3605
|
+
const [isFilterActive, setIsFilterActive] = hooks.useState(true);
|
|
3523
3606
|
const [isEscapeClosed, setIsEscapeClose] = hooks.useState(false);
|
|
3524
3607
|
const searchbarRef = hooks.useRef();
|
|
3525
3608
|
const eventBus = useService('eventBus');
|
|
@@ -3534,23 +3617,22 @@ function SearchableSelect(props) {
|
|
|
3534
3617
|
value,
|
|
3535
3618
|
onChange: props.onChange
|
|
3536
3619
|
});
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
const valueToOptionMap = hooks.useMemo(() => Object.assign({}, ...options.map((o, x) => ({
|
|
3540
|
-
[o.value]: options[x]
|
|
3541
|
-
}))), [options]);
|
|
3542
|
-
const valueLabel = hooks.useMemo(() => value && valueToOptionMap[value] && valueToOptionMap[value].label || '', [value, valueToOptionMap]);
|
|
3620
|
+
const getLabelCorrelation = useGetLabelCorrelation(options);
|
|
3621
|
+
const label = hooks.useMemo(() => value && getLabelCorrelation(value), [value, getLabelCorrelation]);
|
|
3543
3622
|
|
|
3544
3623
|
// whenever we change the underlying value, set the label to it
|
|
3545
3624
|
hooks.useEffect(() => {
|
|
3546
|
-
setFilter(
|
|
3547
|
-
}, [
|
|
3625
|
+
setFilter(label);
|
|
3626
|
+
}, [label]);
|
|
3548
3627
|
const filteredOptions = hooks.useMemo(() => {
|
|
3549
|
-
if (loadState
|
|
3550
|
-
return
|
|
3628
|
+
if (loadState !== LOAD_STATES.LOADED) {
|
|
3629
|
+
return [];
|
|
3551
3630
|
}
|
|
3552
|
-
|
|
3553
|
-
|
|
3631
|
+
if (!filter || !isFilterActive) {
|
|
3632
|
+
return options;
|
|
3633
|
+
}
|
|
3634
|
+
return options.filter(o => o.label && o.value && o.label.toLowerCase().includes(filter.toLowerCase()));
|
|
3635
|
+
}, [filter, loadState, options, isFilterActive]);
|
|
3554
3636
|
const setValue = hooks.useCallback(option => {
|
|
3555
3637
|
setFilter(option && option.label || '');
|
|
3556
3638
|
props.onChange({
|
|
@@ -3577,7 +3659,7 @@ function SearchableSelect(props) {
|
|
|
3577
3659
|
}) => {
|
|
3578
3660
|
setIsEscapeClose(false);
|
|
3579
3661
|
setIsDropdownExpanded(true);
|
|
3580
|
-
|
|
3662
|
+
setIsFilterActive(true);
|
|
3581
3663
|
setFilter(target.value || '');
|
|
3582
3664
|
eventBus.fire('formField.search', {
|
|
3583
3665
|
formField: field,
|
|
@@ -3593,7 +3675,7 @@ function SearchableSelect(props) {
|
|
|
3593
3675
|
{
|
|
3594
3676
|
if (!isDropdownExpanded) {
|
|
3595
3677
|
setIsDropdownExpanded(true);
|
|
3596
|
-
|
|
3678
|
+
setIsFilterActive(false);
|
|
3597
3679
|
}
|
|
3598
3680
|
keyDownEvent.preventDefault();
|
|
3599
3681
|
break;
|
|
@@ -3611,7 +3693,7 @@ function SearchableSelect(props) {
|
|
|
3611
3693
|
const onInputMouseDown = hooks.useCallback(() => {
|
|
3612
3694
|
setIsEscapeClose(false);
|
|
3613
3695
|
setIsDropdownExpanded(true);
|
|
3614
|
-
|
|
3696
|
+
setIsFilterActive(false);
|
|
3615
3697
|
}, []);
|
|
3616
3698
|
const onInputFocus = hooks.useCallback(() => {
|
|
3617
3699
|
setIsEscapeClose(false);
|
|
@@ -3620,9 +3702,9 @@ function SearchableSelect(props) {
|
|
|
3620
3702
|
}, [onFocus]);
|
|
3621
3703
|
const onInputBlur = hooks.useCallback(() => {
|
|
3622
3704
|
setIsDropdownExpanded(false);
|
|
3623
|
-
setFilter(
|
|
3705
|
+
setFilter(label);
|
|
3624
3706
|
onBlur && onBlur();
|
|
3625
|
-
}, [onBlur,
|
|
3707
|
+
}, [onBlur, label]);
|
|
3626
3708
|
return jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
3627
3709
|
children: [jsxRuntime.jsxs("div", {
|
|
3628
3710
|
class: classNames('fjs-input-group', {
|
|
@@ -3699,12 +3781,8 @@ function SimpleSelect(props) {
|
|
|
3699
3781
|
value,
|
|
3700
3782
|
onChange: props.onChange
|
|
3701
3783
|
});
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
const valueToOptionMap = hooks.useMemo(() => Object.assign({}, ...options.map((o, x) => ({
|
|
3705
|
-
[o.value]: options[x]
|
|
3706
|
-
}))), [options]);
|
|
3707
|
-
const valueLabel = hooks.useMemo(() => value && valueToOptionMap[value] && valueToOptionMap[value].label || '', [value, valueToOptionMap]);
|
|
3784
|
+
const getLabelCorrelation = useGetLabelCorrelation(options);
|
|
3785
|
+
const valueLabel = hooks.useMemo(() => value && getLabelCorrelation(value), [value, getLabelCorrelation]);
|
|
3708
3786
|
const setValue = hooks.useCallback(option => {
|
|
3709
3787
|
props.onChange({
|
|
3710
3788
|
value: option && option.value || null,
|
|
@@ -4019,11 +4097,7 @@ function Taglist(props) {
|
|
|
4019
4097
|
values,
|
|
4020
4098
|
onChange: props.onChange
|
|
4021
4099
|
});
|
|
4022
|
-
|
|
4023
|
-
// We cache a map of option values to their index so that we don't need to search the whole options array every time to correlate the label
|
|
4024
|
-
const valueToOptionMap = hooks.useMemo(() => Object.assign({}, ...options.map((o, x) => ({
|
|
4025
|
-
[o.value]: options[x]
|
|
4026
|
-
}))), [options]);
|
|
4100
|
+
const getLabelCorrelation = useGetLabelCorrelation(options);
|
|
4027
4101
|
const hasOptionsLeft = hooks.useMemo(() => options.length > values.length, [options.length, values.length]);
|
|
4028
4102
|
|
|
4029
4103
|
// Usage of stringify is necessary here because we want this effect to only trigger when there is a value change to the array
|
|
@@ -4031,12 +4105,14 @@ function Taglist(props) {
|
|
|
4031
4105
|
if (loadState !== LOAD_STATES.LOADED) {
|
|
4032
4106
|
return [];
|
|
4033
4107
|
}
|
|
4034
|
-
|
|
4108
|
+
const isValidFilteredOption = option => {
|
|
4109
|
+
const filterMatches = option.label.toLowerCase().includes(filter.toLowerCase());
|
|
4110
|
+
return filterMatches && !hasEqualValue(option.value, values);
|
|
4111
|
+
};
|
|
4112
|
+
return options.filter(isValidFilteredOption);
|
|
4035
4113
|
}, [filter, options, JSON.stringify(values), loadState]);
|
|
4036
4114
|
const selectValue = value => {
|
|
4037
|
-
|
|
4038
|
-
setFilter('');
|
|
4039
|
-
}
|
|
4115
|
+
setFilter('');
|
|
4040
4116
|
|
|
4041
4117
|
// Ensure values cannot be double selected due to latency
|
|
4042
4118
|
if (values.at(-1) === value) {
|
|
@@ -4048,8 +4124,9 @@ function Taglist(props) {
|
|
|
4048
4124
|
});
|
|
4049
4125
|
};
|
|
4050
4126
|
const deselectValue = value => {
|
|
4127
|
+
const newValues = values.filter(v => !isEqual(v, value));
|
|
4051
4128
|
props.onChange({
|
|
4052
|
-
value:
|
|
4129
|
+
value: newValues,
|
|
4053
4130
|
field
|
|
4054
4131
|
});
|
|
4055
4132
|
};
|
|
@@ -4159,7 +4236,7 @@ function Taglist(props) {
|
|
|
4159
4236
|
onMouseDown: e => e.preventDefault(),
|
|
4160
4237
|
children: [jsxRuntime.jsx("span", {
|
|
4161
4238
|
class: "fjs-taglist-tag-label",
|
|
4162
|
-
children:
|
|
4239
|
+
children: getLabelCorrelation(v)
|
|
4163
4240
|
}), !disabled && !readonly && jsxRuntime.jsx("button", {
|
|
4164
4241
|
type: "button",
|
|
4165
4242
|
title: "Remove tag",
|
|
@@ -4325,13 +4402,20 @@ function Textfield(props) {
|
|
|
4325
4402
|
const {
|
|
4326
4403
|
required
|
|
4327
4404
|
} = validate;
|
|
4328
|
-
const
|
|
4405
|
+
const [onInputChange, flushOnChange] = useFlushDebounce(({
|
|
4329
4406
|
target
|
|
4330
4407
|
}) => {
|
|
4331
4408
|
props.onChange({
|
|
4332
4409
|
field,
|
|
4333
4410
|
value: target.value
|
|
4334
4411
|
});
|
|
4412
|
+
}, [props.onChange]);
|
|
4413
|
+
const onInputBlur = () => {
|
|
4414
|
+
flushOnChange && flushOnChange();
|
|
4415
|
+
onBlur && onBlur();
|
|
4416
|
+
};
|
|
4417
|
+
const onInputFocus = () => {
|
|
4418
|
+
onFocus && onFocus();
|
|
4335
4419
|
};
|
|
4336
4420
|
return jsxRuntime.jsxs("div", {
|
|
4337
4421
|
class: formFieldClasses(type$2, {
|
|
@@ -4353,9 +4437,9 @@ function Textfield(props) {
|
|
|
4353
4437
|
disabled: disabled,
|
|
4354
4438
|
readOnly: readonly,
|
|
4355
4439
|
id: domId,
|
|
4356
|
-
onInput:
|
|
4357
|
-
onBlur:
|
|
4358
|
-
onFocus:
|
|
4440
|
+
onInput: onInputChange,
|
|
4441
|
+
onBlur: onInputBlur,
|
|
4442
|
+
onFocus: onInputFocus,
|
|
4359
4443
|
type: "text",
|
|
4360
4444
|
value: value,
|
|
4361
4445
|
"aria-describedby": errorMessageId
|
|
@@ -4414,13 +4498,20 @@ function Textarea(props) {
|
|
|
4414
4498
|
required
|
|
4415
4499
|
} = validate;
|
|
4416
4500
|
const textareaRef = hooks.useRef();
|
|
4417
|
-
const
|
|
4501
|
+
const [onInputChange, flushOnChange] = useFlushDebounce(({
|
|
4418
4502
|
target
|
|
4419
4503
|
}) => {
|
|
4420
4504
|
props.onChange({
|
|
4421
4505
|
field,
|
|
4422
4506
|
value: target.value
|
|
4423
4507
|
});
|
|
4508
|
+
}, [props.onChange]);
|
|
4509
|
+
const onInputBlur = () => {
|
|
4510
|
+
flushOnChange && flushOnChange();
|
|
4511
|
+
onBlur && onBlur();
|
|
4512
|
+
};
|
|
4513
|
+
const onInputFocus = () => {
|
|
4514
|
+
onFocus && onFocus();
|
|
4424
4515
|
};
|
|
4425
4516
|
hooks.useLayoutEffect(() => {
|
|
4426
4517
|
autoSizeTextarea(textareaRef.current);
|
|
@@ -4443,9 +4534,9 @@ function Textarea(props) {
|
|
|
4443
4534
|
disabled: disabled,
|
|
4444
4535
|
readonly: readonly,
|
|
4445
4536
|
id: domId,
|
|
4446
|
-
onInput:
|
|
4447
|
-
onBlur:
|
|
4448
|
-
onFocus:
|
|
4537
|
+
onInput: onInputChange,
|
|
4538
|
+
onBlur: onInputBlur,
|
|
4539
|
+
onFocus: onInputFocus,
|
|
4449
4540
|
value: value,
|
|
4450
4541
|
ref: textareaRef,
|
|
4451
4542
|
"aria-describedby": errorMessageId
|
|
@@ -4545,28 +4636,28 @@ var CaretRightIcon = SvgCaretRight;
|
|
|
4545
4636
|
|
|
4546
4637
|
const type = 'table';
|
|
4547
4638
|
|
|
4548
|
-
/**
|
|
4549
|
-
* @typedef {('asc'|'desc')} Direction
|
|
4550
|
-
*
|
|
4551
|
-
* @typedef Sorting
|
|
4552
|
-
* @property {string} key
|
|
4553
|
-
* @property {Direction} direction
|
|
4554
|
-
*
|
|
4555
|
-
* @typedef Column
|
|
4556
|
-
* @property {string} label
|
|
4557
|
-
* @property {string} key
|
|
4558
|
-
*
|
|
4559
|
-
* @typedef Props
|
|
4560
|
-
* @property {Object} field
|
|
4561
|
-
* @property {string} field.id
|
|
4562
|
-
* @property {Array<Column>} [field.columns]
|
|
4563
|
-
* @property {string} [field.columnsExpression]
|
|
4564
|
-
* @property {string} [field.label]
|
|
4565
|
-
* @property {number} [field.rowCount]
|
|
4566
|
-
* @property {string} [field.dataSource]
|
|
4567
|
-
*
|
|
4568
|
-
* @param {Props} props
|
|
4569
|
-
* @returns {import("preact").JSX.Element}
|
|
4639
|
+
/**
|
|
4640
|
+
* @typedef {('asc'|'desc')} Direction
|
|
4641
|
+
*
|
|
4642
|
+
* @typedef Sorting
|
|
4643
|
+
* @property {string} key
|
|
4644
|
+
* @property {Direction} direction
|
|
4645
|
+
*
|
|
4646
|
+
* @typedef Column
|
|
4647
|
+
* @property {string} label
|
|
4648
|
+
* @property {string} key
|
|
4649
|
+
*
|
|
4650
|
+
* @typedef Props
|
|
4651
|
+
* @property {Object} field
|
|
4652
|
+
* @property {string} field.id
|
|
4653
|
+
* @property {Array<Column>} [field.columns]
|
|
4654
|
+
* @property {string} [field.columnsExpression]
|
|
4655
|
+
* @property {string} [field.label]
|
|
4656
|
+
* @property {number} [field.rowCount]
|
|
4657
|
+
* @property {string} [field.dataSource]
|
|
4658
|
+
*
|
|
4659
|
+
* @param {Props} props
|
|
4660
|
+
* @returns {import("preact").JSX.Element}
|
|
4570
4661
|
*/
|
|
4571
4662
|
function Table(props) {
|
|
4572
4663
|
const {
|
|
@@ -4776,10 +4867,10 @@ Table.config = {
|
|
|
4776
4867
|
|
|
4777
4868
|
// helpers /////////////////////////////
|
|
4778
4869
|
|
|
4779
|
-
/**
|
|
4780
|
-
* @param {string|void} columnsExpression
|
|
4781
|
-
* @param {Column[]} fallbackColumns
|
|
4782
|
-
* @returns {Column[]}
|
|
4870
|
+
/**
|
|
4871
|
+
* @param {string|void} columnsExpression
|
|
4872
|
+
* @param {Column[]} fallbackColumns
|
|
4873
|
+
* @returns {Column[]}
|
|
4783
4874
|
*/
|
|
4784
4875
|
function useEvaluatedColumns(columnsExpression, fallbackColumns) {
|
|
4785
4876
|
/** @type {Column[]|null} */
|
|
@@ -4787,18 +4878,18 @@ function useEvaluatedColumns(columnsExpression, fallbackColumns) {
|
|
|
4787
4878
|
return Array.isArray(evaluation) && evaluation.every(isColumn) ? evaluation : fallbackColumns;
|
|
4788
4879
|
}
|
|
4789
4880
|
|
|
4790
|
-
/**
|
|
4791
|
-
* @param {any} column
|
|
4792
|
-
* @returns {column is Column}
|
|
4881
|
+
/**
|
|
4882
|
+
* @param {any} column
|
|
4883
|
+
* @returns {column is Column}
|
|
4793
4884
|
*/
|
|
4794
4885
|
function isColumn(column) {
|
|
4795
4886
|
return minDash.isObject(column) && minDash.isString(column['label']) && minDash.isString(column['key']);
|
|
4796
4887
|
}
|
|
4797
4888
|
|
|
4798
|
-
/**
|
|
4799
|
-
* @param {Array} array
|
|
4800
|
-
* @param {number} size
|
|
4801
|
-
* @returns {Array}
|
|
4889
|
+
/**
|
|
4890
|
+
* @param {Array} array
|
|
4891
|
+
* @param {number} size
|
|
4892
|
+
* @returns {Array}
|
|
4802
4893
|
*/
|
|
4803
4894
|
function chunk(array, size) {
|
|
4804
4895
|
return array.reduce((chunks, item, index) => {
|
|
@@ -4811,11 +4902,11 @@ function chunk(array, size) {
|
|
|
4811
4902
|
}, []);
|
|
4812
4903
|
}
|
|
4813
4904
|
|
|
4814
|
-
/**
|
|
4815
|
-
* @param {unknown[]} array
|
|
4816
|
-
* @param {string} key
|
|
4817
|
-
* @param {Direction} direction
|
|
4818
|
-
* @returns {unknown[]}
|
|
4905
|
+
/**
|
|
4906
|
+
* @param {unknown[]} array
|
|
4907
|
+
* @param {string} key
|
|
4908
|
+
* @param {Direction} direction
|
|
4909
|
+
* @returns {unknown[]}
|
|
4819
4910
|
*/
|
|
4820
4911
|
function sortByColumn(array, key, direction) {
|
|
4821
4912
|
return [...array].sort((a, b) => {
|
|
@@ -4829,10 +4920,10 @@ function sortByColumn(array, key, direction) {
|
|
|
4829
4920
|
});
|
|
4830
4921
|
}
|
|
4831
4922
|
|
|
4832
|
-
/**
|
|
4833
|
-
* @param {null|Sorting} sortBy
|
|
4834
|
-
* @param {string} key
|
|
4835
|
-
* @param {string} label
|
|
4923
|
+
/**
|
|
4924
|
+
* @param {null|Sorting} sortBy
|
|
4925
|
+
* @param {string} key
|
|
4926
|
+
* @param {string} label
|
|
4836
4927
|
*/
|
|
4837
4928
|
function getHeaderAriaLabel(sortBy, key, label) {
|
|
4838
4929
|
if (sortBy === null || sortBy.key !== key) {
|
|
@@ -5207,37 +5298,37 @@ class FormFields {
|
|
|
5207
5298
|
const EXPRESSION_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'conditional.hide', 'description', 'label', 'source', 'readonly', 'text', 'validate.min', 'validate.max', 'validate.minLength', 'validate.maxLength', 'valuesExpression', 'url', 'dataSource', 'columnsExpression'];
|
|
5208
5299
|
const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'description', 'label', 'source', 'text', 'url'];
|
|
5209
5300
|
|
|
5210
|
-
/**
|
|
5211
|
-
* @typedef { import('../types').Schema } Schema
|
|
5301
|
+
/**
|
|
5302
|
+
* @typedef { import('../types').Schema } Schema
|
|
5212
5303
|
*/
|
|
5213
5304
|
|
|
5214
|
-
/**
|
|
5215
|
-
* Parse the schema for variables a form might make use of.
|
|
5216
|
-
*
|
|
5217
|
-
* @example
|
|
5218
|
-
*
|
|
5219
|
-
* // retrieve variables from schema
|
|
5220
|
-
* const variables = getSchemaVariables(schema);
|
|
5221
|
-
*
|
|
5222
|
-
* @example
|
|
5223
|
-
*
|
|
5224
|
-
* // retrieve input variables from schema
|
|
5225
|
-
* const inputVariables = getSchemaVariables(schema, { outputs: false });
|
|
5226
|
-
*
|
|
5227
|
-
* @example
|
|
5228
|
-
*
|
|
5229
|
-
* // retrieve output variables from schema
|
|
5230
|
-
* const outputVariables = getSchemaVariables(schema, { inputs: false });
|
|
5231
|
-
*
|
|
5232
|
-
* @param {Schema} schema
|
|
5233
|
-
* @param {object} [options]
|
|
5234
|
-
* @param {any} [options.expressionLanguage]
|
|
5235
|
-
* @param {any} [options.templating]
|
|
5236
|
-
* @param {any} [options.formFields]
|
|
5237
|
-
* @param {boolean} [options.inputs=true]
|
|
5238
|
-
* @param {boolean} [options.outputs=true]
|
|
5239
|
-
*
|
|
5240
|
-
* @return {string[]}
|
|
5305
|
+
/**
|
|
5306
|
+
* Parse the schema for variables a form might make use of.
|
|
5307
|
+
*
|
|
5308
|
+
* @example
|
|
5309
|
+
*
|
|
5310
|
+
* // retrieve variables from schema
|
|
5311
|
+
* const variables = getSchemaVariables(schema);
|
|
5312
|
+
*
|
|
5313
|
+
* @example
|
|
5314
|
+
*
|
|
5315
|
+
* // retrieve input variables from schema
|
|
5316
|
+
* const inputVariables = getSchemaVariables(schema, { outputs: false });
|
|
5317
|
+
*
|
|
5318
|
+
* @example
|
|
5319
|
+
*
|
|
5320
|
+
* // retrieve output variables from schema
|
|
5321
|
+
* const outputVariables = getSchemaVariables(schema, { inputs: false });
|
|
5322
|
+
*
|
|
5323
|
+
* @param {Schema} schema
|
|
5324
|
+
* @param {object} [options]
|
|
5325
|
+
* @param {any} [options.expressionLanguage]
|
|
5326
|
+
* @param {any} [options.templating]
|
|
5327
|
+
* @param {any} [options.formFields]
|
|
5328
|
+
* @param {boolean} [options.inputs=true]
|
|
5329
|
+
* @param {boolean} [options.outputs=true]
|
|
5330
|
+
*
|
|
5331
|
+
* @return {string[]}
|
|
5241
5332
|
*/
|
|
5242
5333
|
function getSchemaVariables(schema, options = {}) {
|
|
5243
5334
|
const {
|
|
@@ -5313,13 +5404,13 @@ function getSchemaVariables(schema, options = {}) {
|
|
|
5313
5404
|
return Array.from(new Set(variables));
|
|
5314
5405
|
}
|
|
5315
5406
|
|
|
5316
|
-
/**
|
|
5317
|
-
* Get the ancestry list of a form field.
|
|
5318
|
-
*
|
|
5319
|
-
* @param {string} formFieldId
|
|
5320
|
-
* @param {import('../core/FormFieldRegistry').default} formFieldRegistry
|
|
5321
|
-
*
|
|
5322
|
-
* @return {Array<string>} ancestry list
|
|
5407
|
+
/**
|
|
5408
|
+
* Get the ancestry list of a form field.
|
|
5409
|
+
*
|
|
5410
|
+
* @param {string} formFieldId
|
|
5411
|
+
* @param {import('../core/FormFieldRegistry').default} formFieldRegistry
|
|
5412
|
+
*
|
|
5413
|
+
* @return {Array<string>} ancestry list
|
|
5323
5414
|
*/
|
|
5324
5415
|
const getAncestryList = (formFieldId, formFieldRegistry) => {
|
|
5325
5416
|
const ids = [];
|
|
@@ -5331,9 +5422,9 @@ const getAncestryList = (formFieldId, formFieldRegistry) => {
|
|
|
5331
5422
|
return ids;
|
|
5332
5423
|
};
|
|
5333
5424
|
|
|
5334
|
-
/**
|
|
5335
|
-
* @typedef {object} Condition
|
|
5336
|
-
* @property {string} [hide]
|
|
5425
|
+
/**
|
|
5426
|
+
* @typedef {object} Condition
|
|
5427
|
+
* @property {string} [hide]
|
|
5337
5428
|
*/
|
|
5338
5429
|
|
|
5339
5430
|
class ConditionChecker {
|
|
@@ -5343,14 +5434,14 @@ class ConditionChecker {
|
|
|
5343
5434
|
this._eventBus = eventBus;
|
|
5344
5435
|
}
|
|
5345
5436
|
|
|
5346
|
-
/**
|
|
5347
|
-
* For given data, remove properties based on condition.
|
|
5348
|
-
*
|
|
5349
|
-
* @param {Object<string, any>} data
|
|
5350
|
-
* @param {Object<string, any>} contextData
|
|
5351
|
-
* @param {Object} [options]
|
|
5352
|
-
* @param {Function} [options.getFilterPath]
|
|
5353
|
-
* @param {boolean} [options.leafNodeDeletionOnly]
|
|
5437
|
+
/**
|
|
5438
|
+
* For given data, remove properties based on condition.
|
|
5439
|
+
*
|
|
5440
|
+
* @param {Object<string, any>} data
|
|
5441
|
+
* @param {Object<string, any>} contextData
|
|
5442
|
+
* @param {Object} [options]
|
|
5443
|
+
* @param {Function} [options.getFilterPath]
|
|
5444
|
+
* @param {boolean} [options.leafNodeDeletionOnly]
|
|
5354
5445
|
*/
|
|
5355
5446
|
applyConditions(data, contextData = {}, options = {}) {
|
|
5356
5447
|
const workingData = clone(data);
|
|
@@ -5444,13 +5535,13 @@ class ConditionChecker {
|
|
|
5444
5535
|
return workingData;
|
|
5445
5536
|
}
|
|
5446
5537
|
|
|
5447
|
-
/**
|
|
5448
|
-
* Check if given condition is met. Returns null for invalid/missing conditions.
|
|
5449
|
-
*
|
|
5450
|
-
* @param {string} condition
|
|
5451
|
-
* @param {import('../../types').Data} [data]
|
|
5452
|
-
*
|
|
5453
|
-
* @returns {boolean|null}
|
|
5538
|
+
/**
|
|
5539
|
+
* Check if given condition is met. Returns null for invalid/missing conditions.
|
|
5540
|
+
*
|
|
5541
|
+
* @param {string} condition
|
|
5542
|
+
* @param {import('../../types').Data} [data]
|
|
5543
|
+
*
|
|
5544
|
+
* @returns {boolean|null}
|
|
5454
5545
|
*/
|
|
5455
5546
|
check(condition, data = {}) {
|
|
5456
5547
|
if (!condition) {
|
|
@@ -5471,12 +5562,12 @@ class ConditionChecker {
|
|
|
5471
5562
|
}
|
|
5472
5563
|
}
|
|
5473
5564
|
|
|
5474
|
-
/**
|
|
5475
|
-
* Check if hide condition is met.
|
|
5476
|
-
*
|
|
5477
|
-
* @param {Condition} condition
|
|
5478
|
-
* @param {Object<string, any>} data
|
|
5479
|
-
* @returns {boolean}
|
|
5565
|
+
/**
|
|
5566
|
+
* Check if hide condition is met.
|
|
5567
|
+
*
|
|
5568
|
+
* @param {Condition} condition
|
|
5569
|
+
* @param {Object<string, any>} data
|
|
5570
|
+
* @returns {boolean}
|
|
5480
5571
|
*/
|
|
5481
5572
|
_checkHideCondition(condition, data) {
|
|
5482
5573
|
if (!condition.hide) {
|
|
@@ -5518,12 +5609,12 @@ class MarkdownRenderer {
|
|
|
5518
5609
|
this._converter = new showdown.Converter();
|
|
5519
5610
|
}
|
|
5520
5611
|
|
|
5521
|
-
/**
|
|
5522
|
-
* Render markdown to HTML.
|
|
5523
|
-
*
|
|
5524
|
-
* @param {string} markdown - The markdown to render
|
|
5525
|
-
*
|
|
5526
|
-
* @returns {string} HTML
|
|
5612
|
+
/**
|
|
5613
|
+
* Render markdown to HTML.
|
|
5614
|
+
*
|
|
5615
|
+
* @param {string} markdown - The markdown to render
|
|
5616
|
+
*
|
|
5617
|
+
* @returns {string} HTML
|
|
5527
5618
|
*/
|
|
5528
5619
|
render(markdown) {
|
|
5529
5620
|
return this._converter.makeHtml(markdown);
|
|
@@ -6144,11 +6235,11 @@ class RepeatRenderManager {
|
|
|
6144
6235
|
this.RepeatFooter = this.RepeatFooter.bind(this);
|
|
6145
6236
|
}
|
|
6146
6237
|
|
|
6147
|
-
/**
|
|
6148
|
-
* Checks whether a field is currently repeating its children.
|
|
6149
|
-
*
|
|
6150
|
-
* @param {string} id - The id of the field to check
|
|
6151
|
-
* @returns {boolean} - True if repeatable, false otherwise
|
|
6238
|
+
/**
|
|
6239
|
+
* Checks whether a field is currently repeating its children.
|
|
6240
|
+
*
|
|
6241
|
+
* @param {string} id - The id of the field to check
|
|
6242
|
+
* @returns {boolean} - True if repeatable, false otherwise
|
|
6152
6243
|
*/
|
|
6153
6244
|
isFieldRepeating(id) {
|
|
6154
6245
|
if (!id) {
|
|
@@ -6908,8 +6999,8 @@ Validator.$inject = ['expressionLanguage', 'conditionChecker', 'form'];
|
|
|
6908
6999
|
|
|
6909
7000
|
// helpers //////////
|
|
6910
7001
|
|
|
6911
|
-
/**
|
|
6912
|
-
* Helper function to evaluate optional FEEL validation values.
|
|
7002
|
+
/**
|
|
7003
|
+
* Helper function to evaluate optional FEEL validation values.
|
|
6913
7004
|
*/
|
|
6914
7005
|
function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form) {
|
|
6915
7006
|
const evaluatedValidate = {
|
|
@@ -6943,12 +7034,12 @@ function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form
|
|
|
6943
7034
|
}
|
|
6944
7035
|
|
|
6945
7036
|
class Importer {
|
|
6946
|
-
/**
|
|
6947
|
-
* @constructor
|
|
6948
|
-
* @param { import('./FormFieldRegistry').default } formFieldRegistry
|
|
6949
|
-
* @param { import('./PathRegistry').default } pathRegistry
|
|
6950
|
-
* @param { import('./FieldFactory').default } fieldFactory
|
|
6951
|
-
* @param { import('./FormLayouter').default } formLayouter
|
|
7037
|
+
/**
|
|
7038
|
+
* @constructor
|
|
7039
|
+
* @param { import('./FormFieldRegistry').default } formFieldRegistry
|
|
7040
|
+
* @param { import('./PathRegistry').default } pathRegistry
|
|
7041
|
+
* @param { import('./FieldFactory').default } fieldFactory
|
|
7042
|
+
* @param { import('./FormLayouter').default } formLayouter
|
|
6952
7043
|
*/
|
|
6953
7044
|
constructor(formFieldRegistry, pathRegistry, fieldFactory, formLayouter) {
|
|
6954
7045
|
this._formFieldRegistry = formFieldRegistry;
|
|
@@ -6957,21 +7048,21 @@ class Importer {
|
|
|
6957
7048
|
this._formLayouter = formLayouter;
|
|
6958
7049
|
}
|
|
6959
7050
|
|
|
6960
|
-
/**
|
|
6961
|
-
* Import schema creating rows, fields, attaching additional
|
|
6962
|
-
* information to each field and adding fields to the
|
|
6963
|
-
* field registry.
|
|
6964
|
-
*
|
|
6965
|
-
* Additional information attached:
|
|
6966
|
-
*
|
|
6967
|
-
* * `id` (unless present)
|
|
6968
|
-
* * `_parent`
|
|
6969
|
-
* * `_path`
|
|
6970
|
-
*
|
|
6971
|
-
* @param {any} schema
|
|
6972
|
-
*
|
|
6973
|
-
* @typedef {{ warnings: Error[], schema: any }} ImportResult
|
|
6974
|
-
* @returns {ImportResult}
|
|
7051
|
+
/**
|
|
7052
|
+
* Import schema creating rows, fields, attaching additional
|
|
7053
|
+
* information to each field and adding fields to the
|
|
7054
|
+
* field registry.
|
|
7055
|
+
*
|
|
7056
|
+
* Additional information attached:
|
|
7057
|
+
*
|
|
7058
|
+
* * `id` (unless present)
|
|
7059
|
+
* * `_parent`
|
|
7060
|
+
* * `_path`
|
|
7061
|
+
*
|
|
7062
|
+
* @param {any} schema
|
|
7063
|
+
*
|
|
7064
|
+
* @typedef {{ warnings: Error[], schema: any }} ImportResult
|
|
7065
|
+
* @returns {ImportResult}
|
|
6975
7066
|
*/
|
|
6976
7067
|
importSchema(schema) {
|
|
6977
7068
|
// TODO: Add warnings
|
|
@@ -6996,12 +7087,12 @@ class Importer {
|
|
|
6996
7087
|
this._pathRegistry.clear();
|
|
6997
7088
|
}
|
|
6998
7089
|
|
|
6999
|
-
/**
|
|
7000
|
-
* @param {{[x: string]: any}} fieldAttrs
|
|
7001
|
-
* @param {String} [parentId]
|
|
7002
|
-
* @param {number} [index]
|
|
7003
|
-
*
|
|
7004
|
-
* @return {any} field
|
|
7090
|
+
/**
|
|
7091
|
+
* @param {{[x: string]: any}} fieldAttrs
|
|
7092
|
+
* @param {String} [parentId]
|
|
7093
|
+
* @param {number} [index]
|
|
7094
|
+
*
|
|
7095
|
+
* @return {any} field
|
|
7005
7096
|
*/
|
|
7006
7097
|
importFormField(fieldAttrs, parentId, index) {
|
|
7007
7098
|
const {
|
|
@@ -7026,11 +7117,11 @@ class Importer {
|
|
|
7026
7117
|
return field;
|
|
7027
7118
|
}
|
|
7028
7119
|
|
|
7029
|
-
/**
|
|
7030
|
-
* @param {Array<any>} components
|
|
7031
|
-
* @param {string} parentId
|
|
7032
|
-
*
|
|
7033
|
-
* @return {Array<any>} imported components
|
|
7120
|
+
/**
|
|
7121
|
+
* @param {Array<any>} components
|
|
7122
|
+
* @param {string} parentId
|
|
7123
|
+
*
|
|
7124
|
+
* @return {Array<any>} imported components
|
|
7034
7125
|
*/
|
|
7035
7126
|
importFormFields(components, parentId) {
|
|
7036
7127
|
return components.map((component, index) => {
|
|
@@ -7041,11 +7132,11 @@ class Importer {
|
|
|
7041
7132
|
Importer.$inject = ['formFieldRegistry', 'pathRegistry', 'fieldFactory', 'formLayouter'];
|
|
7042
7133
|
|
|
7043
7134
|
class FieldFactory {
|
|
7044
|
-
/**
|
|
7045
|
-
* @constructor
|
|
7046
|
-
*
|
|
7047
|
-
* @param formFieldRegistry
|
|
7048
|
-
* @param formFields
|
|
7135
|
+
/**
|
|
7136
|
+
* @constructor
|
|
7137
|
+
*
|
|
7138
|
+
* @param formFieldRegistry
|
|
7139
|
+
* @param formFields
|
|
7049
7140
|
*/
|
|
7050
7141
|
constructor(formFieldRegistry, pathRegistry, formFields) {
|
|
7051
7142
|
this._formFieldRegistry = formFieldRegistry;
|
|
@@ -7155,36 +7246,36 @@ class FieldFactory {
|
|
|
7155
7246
|
}
|
|
7156
7247
|
FieldFactory.$inject = ['formFieldRegistry', 'pathRegistry', 'formFields'];
|
|
7157
7248
|
|
|
7158
|
-
/**
|
|
7159
|
-
* The PathRegistry class manages a hierarchical structure of paths associated with form fields.
|
|
7160
|
-
* It enables claiming, unclaiming, and validating paths within this structure.
|
|
7161
|
-
*
|
|
7162
|
-
* Example Tree Structure:
|
|
7163
|
-
*
|
|
7164
|
-
* [
|
|
7165
|
-
* {
|
|
7166
|
-
* segment: 'root',
|
|
7167
|
-
* claimCount: 1,
|
|
7168
|
-
* children: [
|
|
7169
|
-
* {
|
|
7170
|
-
* segment: 'child1',
|
|
7171
|
-
* claimCount: 2,
|
|
7172
|
-
* children: null // A leaf node (closed path)
|
|
7173
|
-
* },
|
|
7174
|
-
* {
|
|
7175
|
-
* segment: 'child2',
|
|
7176
|
-
* claimCount: 1,
|
|
7177
|
-
* children: [
|
|
7178
|
-
* {
|
|
7179
|
-
* segment: 'subChild1',
|
|
7180
|
-
* claimCount: 1,
|
|
7181
|
-
* children: [] // An open node (open path)
|
|
7182
|
-
* }
|
|
7183
|
-
* ]
|
|
7184
|
-
* }
|
|
7185
|
-
* ]
|
|
7186
|
-
* }
|
|
7187
|
-
* ]
|
|
7249
|
+
/**
|
|
7250
|
+
* The PathRegistry class manages a hierarchical structure of paths associated with form fields.
|
|
7251
|
+
* It enables claiming, unclaiming, and validating paths within this structure.
|
|
7252
|
+
*
|
|
7253
|
+
* Example Tree Structure:
|
|
7254
|
+
*
|
|
7255
|
+
* [
|
|
7256
|
+
* {
|
|
7257
|
+
* segment: 'root',
|
|
7258
|
+
* claimCount: 1,
|
|
7259
|
+
* children: [
|
|
7260
|
+
* {
|
|
7261
|
+
* segment: 'child1',
|
|
7262
|
+
* claimCount: 2,
|
|
7263
|
+
* children: null // A leaf node (closed path)
|
|
7264
|
+
* },
|
|
7265
|
+
* {
|
|
7266
|
+
* segment: 'child2',
|
|
7267
|
+
* claimCount: 1,
|
|
7268
|
+
* children: [
|
|
7269
|
+
* {
|
|
7270
|
+
* segment: 'subChild1',
|
|
7271
|
+
* claimCount: 1,
|
|
7272
|
+
* children: [] // An open node (open path)
|
|
7273
|
+
* }
|
|
7274
|
+
* ]
|
|
7275
|
+
* }
|
|
7276
|
+
* ]
|
|
7277
|
+
* }
|
|
7278
|
+
* ]
|
|
7188
7279
|
*/
|
|
7189
7280
|
class PathRegistry {
|
|
7190
7281
|
constructor(formFieldRegistry, formFields, injector) {
|
|
@@ -7300,16 +7391,16 @@ class PathRegistry {
|
|
|
7300
7391
|
}
|
|
7301
7392
|
}
|
|
7302
7393
|
|
|
7303
|
-
/**
|
|
7304
|
-
* Applies a function (fn) recursively on a given field and its children.
|
|
7305
|
-
*
|
|
7306
|
-
* - `field`: Starting field object.
|
|
7307
|
-
* - `fn`: Function to apply.
|
|
7308
|
-
* - `context`: Optional object for passing data between calls.
|
|
7309
|
-
*
|
|
7310
|
-
* Stops early if `fn` returns `false`. Useful for traversing the form field tree.
|
|
7311
|
-
*
|
|
7312
|
-
* @returns {boolean} Success status based on function execution.
|
|
7394
|
+
/**
|
|
7395
|
+
* Applies a function (fn) recursively on a given field and its children.
|
|
7396
|
+
*
|
|
7397
|
+
* - `field`: Starting field object.
|
|
7398
|
+
* - `fn`: Function to apply.
|
|
7399
|
+
* - `context`: Optional object for passing data between calls.
|
|
7400
|
+
*
|
|
7401
|
+
* Stops early if `fn` returns `false`. Useful for traversing the form field tree.
|
|
7402
|
+
*
|
|
7403
|
+
* @returns {boolean} Success status based on function execution.
|
|
7313
7404
|
*/
|
|
7314
7405
|
executeRecursivelyOnFields(field, fn, context = {}) {
|
|
7315
7406
|
let result = true;
|
|
@@ -7350,16 +7441,16 @@ class PathRegistry {
|
|
|
7350
7441
|
return result;
|
|
7351
7442
|
}
|
|
7352
7443
|
|
|
7353
|
-
/**
|
|
7354
|
-
* Generates an array representing the binding path to an underlying data object for a form field.
|
|
7355
|
-
*
|
|
7356
|
-
* @param {Object} field - The field object with properties: `key`, `path`, `id`, and optionally `_parent`.
|
|
7357
|
-
* @param {Object} [options={}] - Configuration options.
|
|
7358
|
-
* @param {Object} [options.replacements={}] - A map of field IDs to alternative path arrays.
|
|
7359
|
-
* @param {Object} [options.indexes=null] - A map of parent IDs to the index of the field within said parent, leave null to get an unindexed path.
|
|
7360
|
-
* @param {Object} [options.cutoffNode] - The ID of the parent field at which to stop generating the path.
|
|
7361
|
-
*
|
|
7362
|
-
* @returns {(Array<string>|undefined)} An array of strings representing the binding path, or undefined if not determinable.
|
|
7444
|
+
/**
|
|
7445
|
+
* Generates an array representing the binding path to an underlying data object for a form field.
|
|
7446
|
+
*
|
|
7447
|
+
* @param {Object} field - The field object with properties: `key`, `path`, `id`, and optionally `_parent`.
|
|
7448
|
+
* @param {Object} [options={}] - Configuration options.
|
|
7449
|
+
* @param {Object} [options.replacements={}] - A map of field IDs to alternative path arrays.
|
|
7450
|
+
* @param {Object} [options.indexes=null] - A map of parent IDs to the index of the field within said parent, leave null to get an unindexed path.
|
|
7451
|
+
* @param {Object} [options.cutoffNode] - The ID of the parent field at which to stop generating the path.
|
|
7452
|
+
*
|
|
7453
|
+
* @returns {(Array<string>|undefined)} An array of strings representing the binding path, or undefined if not determinable.
|
|
7363
7454
|
*/
|
|
7364
7455
|
getValuePath(field, options = {}) {
|
|
7365
7456
|
const {
|
|
@@ -7420,23 +7511,23 @@ const _getNextSegment = (node, segment) => {
|
|
|
7420
7511
|
};
|
|
7421
7512
|
PathRegistry.$inject = ['formFieldRegistry', 'formFields', 'injector'];
|
|
7422
7513
|
|
|
7423
|
-
/**
|
|
7424
|
-
* @typedef { { id: String, components: Array<String> } } FormRow
|
|
7425
|
-
* @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
|
|
7514
|
+
/**
|
|
7515
|
+
* @typedef { { id: String, components: Array<String> } } FormRow
|
|
7516
|
+
* @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
|
|
7426
7517
|
*/
|
|
7427
7518
|
|
|
7428
|
-
/**
|
|
7429
|
-
* Maintains the Form layout in a given structure, for example
|
|
7430
|
-
*
|
|
7431
|
-
* [
|
|
7432
|
-
* {
|
|
7433
|
-
* formFieldId: 'FormField_1',
|
|
7434
|
-
* rows: [
|
|
7435
|
-
* { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
|
|
7436
|
-
* ]
|
|
7437
|
-
* }
|
|
7438
|
-
* ]
|
|
7439
|
-
*
|
|
7519
|
+
/**
|
|
7520
|
+
* Maintains the Form layout in a given structure, for example
|
|
7521
|
+
*
|
|
7522
|
+
* [
|
|
7523
|
+
* {
|
|
7524
|
+
* formFieldId: 'FormField_1',
|
|
7525
|
+
* rows: [
|
|
7526
|
+
* { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
|
|
7527
|
+
* ]
|
|
7528
|
+
* }
|
|
7529
|
+
* ]
|
|
7530
|
+
*
|
|
7440
7531
|
*/
|
|
7441
7532
|
class FormLayouter {
|
|
7442
7533
|
constructor(eventBus) {
|
|
@@ -7446,8 +7537,8 @@ class FormLayouter {
|
|
|
7446
7537
|
this._eventBus = eventBus;
|
|
7447
7538
|
}
|
|
7448
7539
|
|
|
7449
|
-
/**
|
|
7450
|
-
* @param {FormRow} row
|
|
7540
|
+
/**
|
|
7541
|
+
* @param {FormRow} row
|
|
7451
7542
|
*/
|
|
7452
7543
|
addRow(formFieldId, row) {
|
|
7453
7544
|
let rowsPerComponent = this._rows.find(r => r.formFieldId === formFieldId);
|
|
@@ -7461,18 +7552,18 @@ class FormLayouter {
|
|
|
7461
7552
|
rowsPerComponent.rows.push(row);
|
|
7462
7553
|
}
|
|
7463
7554
|
|
|
7464
|
-
/**
|
|
7465
|
-
* @param {String} id
|
|
7466
|
-
* @returns {FormRow}
|
|
7555
|
+
/**
|
|
7556
|
+
* @param {String} id
|
|
7557
|
+
* @returns {FormRow}
|
|
7467
7558
|
*/
|
|
7468
7559
|
getRow(id) {
|
|
7469
7560
|
const rows = allRows(this._rows);
|
|
7470
7561
|
return rows.find(r => r.id === id);
|
|
7471
7562
|
}
|
|
7472
7563
|
|
|
7473
|
-
/**
|
|
7474
|
-
* @param {any} formField
|
|
7475
|
-
* @returns {FormRow}
|
|
7564
|
+
/**
|
|
7565
|
+
* @param {any} formField
|
|
7566
|
+
* @returns {FormRow}
|
|
7476
7567
|
*/
|
|
7477
7568
|
getRowForField(formField) {
|
|
7478
7569
|
return allRows(this._rows).find(r => {
|
|
@@ -7483,9 +7574,9 @@ class FormLayouter {
|
|
|
7483
7574
|
});
|
|
7484
7575
|
}
|
|
7485
7576
|
|
|
7486
|
-
/**
|
|
7487
|
-
* @param {String} formFieldId
|
|
7488
|
-
* @returns { Array<FormRow> }
|
|
7577
|
+
/**
|
|
7578
|
+
* @param {String} formFieldId
|
|
7579
|
+
* @returns { Array<FormRow> }
|
|
7489
7580
|
*/
|
|
7490
7581
|
getRows(formFieldId) {
|
|
7491
7582
|
const rowsForField = this._rows.find(r => formFieldId === r.formFieldId);
|
|
@@ -7495,15 +7586,15 @@ class FormLayouter {
|
|
|
7495
7586
|
return rowsForField.rows;
|
|
7496
7587
|
}
|
|
7497
7588
|
|
|
7498
|
-
/**
|
|
7499
|
-
* @returns {string}
|
|
7589
|
+
/**
|
|
7590
|
+
* @returns {string}
|
|
7500
7591
|
*/
|
|
7501
7592
|
nextRowId() {
|
|
7502
7593
|
return this._ids.nextPrefixed('Row_');
|
|
7503
7594
|
}
|
|
7504
7595
|
|
|
7505
|
-
/**
|
|
7506
|
-
* @param {any} formField
|
|
7596
|
+
/**
|
|
7597
|
+
* @param {any} formField
|
|
7507
7598
|
*/
|
|
7508
7599
|
calculateLayout(formField) {
|
|
7509
7600
|
const {
|
|
@@ -7557,9 +7648,9 @@ function groupByRow(components, ids) {
|
|
|
7557
7648
|
});
|
|
7558
7649
|
}
|
|
7559
7650
|
|
|
7560
|
-
/**
|
|
7561
|
-
* @param {Array<FormRows>} formRows
|
|
7562
|
-
* @returns {Array<FormRow>}
|
|
7651
|
+
/**
|
|
7652
|
+
* @param {Array<FormRows>} formRows
|
|
7653
|
+
* @returns {Array<FormRow>}
|
|
7563
7654
|
*/
|
|
7564
7655
|
function allRows(formRows) {
|
|
7565
7656
|
return minDash.flatten(formRows.map(c => c.rows));
|
|
@@ -7684,55 +7775,55 @@ var core = {
|
|
|
7684
7775
|
validator: ['type', Validator]
|
|
7685
7776
|
};
|
|
7686
7777
|
|
|
7687
|
-
/**
|
|
7688
|
-
* @typedef { import('./types').Injector } Injector
|
|
7689
|
-
* @typedef { import('./types').Data } Data
|
|
7690
|
-
* @typedef { import('./types').Errors } Errors
|
|
7691
|
-
* @typedef { import('./types').Schema } Schema
|
|
7692
|
-
* @typedef { import('./types').FormProperties } FormProperties
|
|
7693
|
-
* @typedef { import('./types').FormProperty } FormProperty
|
|
7694
|
-
* @typedef { import('./types').FormEvent } FormEvent
|
|
7695
|
-
* @typedef { import('./types').FormOptions } FormOptions
|
|
7696
|
-
*
|
|
7697
|
-
* @typedef { {
|
|
7698
|
-
* data: Data,
|
|
7699
|
-
* initialData: Data,
|
|
7700
|
-
* errors: Errors,
|
|
7701
|
-
* properties: FormProperties,
|
|
7702
|
-
* schema: Schema
|
|
7703
|
-
* } } State
|
|
7704
|
-
*
|
|
7705
|
-
* @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority
|
|
7706
|
-
* @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority
|
|
7707
|
-
* @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
|
|
7778
|
+
/**
|
|
7779
|
+
* @typedef { import('./types').Injector } Injector
|
|
7780
|
+
* @typedef { import('./types').Data } Data
|
|
7781
|
+
* @typedef { import('./types').Errors } Errors
|
|
7782
|
+
* @typedef { import('./types').Schema } Schema
|
|
7783
|
+
* @typedef { import('./types').FormProperties } FormProperties
|
|
7784
|
+
* @typedef { import('./types').FormProperty } FormProperty
|
|
7785
|
+
* @typedef { import('./types').FormEvent } FormEvent
|
|
7786
|
+
* @typedef { import('./types').FormOptions } FormOptions
|
|
7787
|
+
*
|
|
7788
|
+
* @typedef { {
|
|
7789
|
+
* data: Data,
|
|
7790
|
+
* initialData: Data,
|
|
7791
|
+
* errors: Errors,
|
|
7792
|
+
* properties: FormProperties,
|
|
7793
|
+
* schema: Schema
|
|
7794
|
+
* } } State
|
|
7795
|
+
*
|
|
7796
|
+
* @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority
|
|
7797
|
+
* @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority
|
|
7798
|
+
* @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
|
|
7708
7799
|
*/
|
|
7709
7800
|
|
|
7710
7801
|
const ids = new Ids([32, 36, 1]);
|
|
7711
7802
|
|
|
7712
|
-
/**
|
|
7713
|
-
* The form.
|
|
7803
|
+
/**
|
|
7804
|
+
* The form.
|
|
7714
7805
|
*/
|
|
7715
7806
|
class Form {
|
|
7716
|
-
/**
|
|
7717
|
-
* @constructor
|
|
7718
|
-
* @param {FormOptions} options
|
|
7807
|
+
/**
|
|
7808
|
+
* @constructor
|
|
7809
|
+
* @param {FormOptions} options
|
|
7719
7810
|
*/
|
|
7720
7811
|
constructor(options = {}) {
|
|
7721
|
-
/**
|
|
7722
|
-
* @public
|
|
7723
|
-
* @type {OnEventType}
|
|
7812
|
+
/**
|
|
7813
|
+
* @public
|
|
7814
|
+
* @type {OnEventType}
|
|
7724
7815
|
*/
|
|
7725
7816
|
this.on = this._onEvent;
|
|
7726
7817
|
|
|
7727
|
-
/**
|
|
7728
|
-
* @public
|
|
7729
|
-
* @type {String}
|
|
7818
|
+
/**
|
|
7819
|
+
* @public
|
|
7820
|
+
* @type {String}
|
|
7730
7821
|
*/
|
|
7731
7822
|
this._id = ids.next();
|
|
7732
7823
|
|
|
7733
|
-
/**
|
|
7734
|
-
* @private
|
|
7735
|
-
* @type {Element}
|
|
7824
|
+
/**
|
|
7825
|
+
* @private
|
|
7826
|
+
* @type {Element}
|
|
7736
7827
|
*/
|
|
7737
7828
|
this._container = createFormContainer();
|
|
7738
7829
|
const {
|
|
@@ -7741,9 +7832,9 @@ class Form {
|
|
|
7741
7832
|
properties = {}
|
|
7742
7833
|
} = options;
|
|
7743
7834
|
|
|
7744
|
-
/**
|
|
7745
|
-
* @private
|
|
7746
|
-
* @type {State}
|
|
7835
|
+
/**
|
|
7836
|
+
* @private
|
|
7837
|
+
* @type {State}
|
|
7747
7838
|
*/
|
|
7748
7839
|
this._state = {
|
|
7749
7840
|
initialData: null,
|
|
@@ -7767,9 +7858,9 @@ class Form {
|
|
|
7767
7858
|
this._emit('form.clear');
|
|
7768
7859
|
}
|
|
7769
7860
|
|
|
7770
|
-
/**
|
|
7771
|
-
* Destroy the form, removing it from DOM,
|
|
7772
|
-
* if attached.
|
|
7861
|
+
/**
|
|
7862
|
+
* Destroy the form, removing it from DOM,
|
|
7863
|
+
* if attached.
|
|
7773
7864
|
*/
|
|
7774
7865
|
destroy() {
|
|
7775
7866
|
// destroy form services
|
|
@@ -7780,13 +7871,13 @@ class Form {
|
|
|
7780
7871
|
this._detach(false);
|
|
7781
7872
|
}
|
|
7782
7873
|
|
|
7783
|
-
/**
|
|
7784
|
-
* Open a form schema with the given initial data.
|
|
7785
|
-
*
|
|
7786
|
-
* @param {Schema} schema
|
|
7787
|
-
* @param {Data} [data]
|
|
7788
|
-
*
|
|
7789
|
-
* @return Promise<{ warnings: Array<any> }>
|
|
7874
|
+
/**
|
|
7875
|
+
* Open a form schema with the given initial data.
|
|
7876
|
+
*
|
|
7877
|
+
* @param {Schema} schema
|
|
7878
|
+
* @param {Data} [data]
|
|
7879
|
+
*
|
|
7880
|
+
* @return Promise<{ warnings: Array<any> }>
|
|
7790
7881
|
*/
|
|
7791
7882
|
importSchema(schema, data = {}) {
|
|
7792
7883
|
return new Promise((resolve, reject) => {
|
|
@@ -7819,10 +7910,10 @@ class Form {
|
|
|
7819
7910
|
});
|
|
7820
7911
|
}
|
|
7821
7912
|
|
|
7822
|
-
/**
|
|
7823
|
-
* Submit the form, triggering all field validations.
|
|
7824
|
-
*
|
|
7825
|
-
* @returns { { data: Data, errors: Errors } }
|
|
7913
|
+
/**
|
|
7914
|
+
* Submit the form, triggering all field validations.
|
|
7915
|
+
*
|
|
7916
|
+
* @returns { { data: Data, errors: Errors } }
|
|
7826
7917
|
*/
|
|
7827
7918
|
submit() {
|
|
7828
7919
|
const {
|
|
@@ -7848,8 +7939,8 @@ class Form {
|
|
|
7848
7939
|
});
|
|
7849
7940
|
}
|
|
7850
7941
|
|
|
7851
|
-
/**
|
|
7852
|
-
* @returns {Errors}
|
|
7942
|
+
/**
|
|
7943
|
+
* @returns {Errors}
|
|
7853
7944
|
*/
|
|
7854
7945
|
validate() {
|
|
7855
7946
|
const formFields = this.get('formFields'),
|
|
@@ -7921,8 +8012,8 @@ class Form {
|
|
|
7921
8012
|
return filteredErrors;
|
|
7922
8013
|
}
|
|
7923
8014
|
|
|
7924
|
-
/**
|
|
7925
|
-
* @param {Element|string} parentNode
|
|
8015
|
+
/**
|
|
8016
|
+
* @param {Element|string} parentNode
|
|
7926
8017
|
*/
|
|
7927
8018
|
attachTo(parentNode) {
|
|
7928
8019
|
if (!parentNode) {
|
|
@@ -7940,10 +8031,10 @@ class Form {
|
|
|
7940
8031
|
this._detach();
|
|
7941
8032
|
}
|
|
7942
8033
|
|
|
7943
|
-
/**
|
|
7944
|
-
* @private
|
|
7945
|
-
*
|
|
7946
|
-
* @param {boolean} [emit]
|
|
8034
|
+
/**
|
|
8035
|
+
* @private
|
|
8036
|
+
*
|
|
8037
|
+
* @param {boolean} [emit]
|
|
7947
8038
|
*/
|
|
7948
8039
|
_detach(emit = true) {
|
|
7949
8040
|
const container = this._container,
|
|
@@ -7957,9 +8048,9 @@ class Form {
|
|
|
7957
8048
|
parentNode.removeChild(container);
|
|
7958
8049
|
}
|
|
7959
8050
|
|
|
7960
|
-
/**
|
|
7961
|
-
* @param {FormProperty} property
|
|
7962
|
-
* @param {any} value
|
|
8051
|
+
/**
|
|
8052
|
+
* @param {FormProperty} property
|
|
8053
|
+
* @param {any} value
|
|
7963
8054
|
*/
|
|
7964
8055
|
setProperty(property, value) {
|
|
7965
8056
|
const properties = minDash.set(this._getState().properties, [property], value);
|
|
@@ -7968,50 +8059,52 @@ class Form {
|
|
|
7968
8059
|
});
|
|
7969
8060
|
}
|
|
7970
8061
|
|
|
7971
|
-
/**
|
|
7972
|
-
* @param {FormEvent} type
|
|
7973
|
-
* @param {Function} handler
|
|
8062
|
+
/**
|
|
8063
|
+
* @param {FormEvent} type
|
|
8064
|
+
* @param {Function} handler
|
|
7974
8065
|
*/
|
|
7975
8066
|
off(type, handler) {
|
|
7976
8067
|
this.get('eventBus').off(type, handler);
|
|
7977
8068
|
}
|
|
7978
8069
|
|
|
7979
|
-
/**
|
|
7980
|
-
* @private
|
|
7981
|
-
*
|
|
7982
|
-
* @param {FormOptions} options
|
|
7983
|
-
* @param {Element} container
|
|
7984
|
-
*
|
|
7985
|
-
* @returns {Injector}
|
|
8070
|
+
/**
|
|
8071
|
+
* @private
|
|
8072
|
+
*
|
|
8073
|
+
* @param {FormOptions} options
|
|
8074
|
+
* @param {Element} container
|
|
8075
|
+
*
|
|
8076
|
+
* @returns {Injector}
|
|
7986
8077
|
*/
|
|
7987
8078
|
_createInjector(options, container) {
|
|
7988
8079
|
const {
|
|
8080
|
+
modules = this._getModules(),
|
|
7989
8081
|
additionalModules = [],
|
|
7990
|
-
|
|
8082
|
+
...config
|
|
7991
8083
|
} = options;
|
|
7992
|
-
const
|
|
8084
|
+
const enrichedConfig = {
|
|
8085
|
+
...config,
|
|
7993
8086
|
renderer: {
|
|
7994
8087
|
container
|
|
7995
8088
|
}
|
|
7996
8089
|
};
|
|
7997
8090
|
return createInjector([{
|
|
7998
|
-
config: ['value',
|
|
8091
|
+
config: ['value', enrichedConfig]
|
|
7999
8092
|
}, {
|
|
8000
8093
|
form: ['value', this]
|
|
8001
8094
|
}, core, ...modules, ...additionalModules]);
|
|
8002
8095
|
}
|
|
8003
8096
|
|
|
8004
|
-
/**
|
|
8005
|
-
* @private
|
|
8097
|
+
/**
|
|
8098
|
+
* @private
|
|
8006
8099
|
*/
|
|
8007
8100
|
_emit(type, data) {
|
|
8008
8101
|
this.get('eventBus').fire(type, data);
|
|
8009
8102
|
}
|
|
8010
8103
|
|
|
8011
|
-
/**
|
|
8012
|
-
* @internal
|
|
8013
|
-
*
|
|
8014
|
-
* @param { { add?: boolean, field: any, indexes: object, remove?: number, value?: any } } update
|
|
8104
|
+
/**
|
|
8105
|
+
* @internal
|
|
8106
|
+
*
|
|
8107
|
+
* @param { { add?: boolean, field: any, indexes: object, remove?: number, value?: any } } update
|
|
8015
8108
|
*/
|
|
8016
8109
|
_update(update) {
|
|
8017
8110
|
const {
|
|
@@ -8037,15 +8130,15 @@ class Form {
|
|
|
8037
8130
|
});
|
|
8038
8131
|
}
|
|
8039
8132
|
|
|
8040
|
-
/**
|
|
8041
|
-
* @internal
|
|
8133
|
+
/**
|
|
8134
|
+
* @internal
|
|
8042
8135
|
*/
|
|
8043
8136
|
_getState() {
|
|
8044
8137
|
return this._state;
|
|
8045
8138
|
}
|
|
8046
8139
|
|
|
8047
|
-
/**
|
|
8048
|
-
* @internal
|
|
8140
|
+
/**
|
|
8141
|
+
* @internal
|
|
8049
8142
|
*/
|
|
8050
8143
|
_setState(state) {
|
|
8051
8144
|
this._state = {
|
|
@@ -8055,22 +8148,22 @@ class Form {
|
|
|
8055
8148
|
this._emit('changed', this._getState());
|
|
8056
8149
|
}
|
|
8057
8150
|
|
|
8058
|
-
/**
|
|
8059
|
-
* @internal
|
|
8151
|
+
/**
|
|
8152
|
+
* @internal
|
|
8060
8153
|
*/
|
|
8061
8154
|
_getModules() {
|
|
8062
8155
|
return [ExpressionLanguageModule, MarkdownModule, ViewerCommandsModule, RepeatRenderModule];
|
|
8063
8156
|
}
|
|
8064
8157
|
|
|
8065
|
-
/**
|
|
8066
|
-
* @internal
|
|
8158
|
+
/**
|
|
8159
|
+
* @internal
|
|
8067
8160
|
*/
|
|
8068
8161
|
_onEvent(type, priority, handler) {
|
|
8069
8162
|
this.get('eventBus').on(type, priority, handler);
|
|
8070
8163
|
}
|
|
8071
8164
|
|
|
8072
|
-
/**
|
|
8073
|
-
* @internal
|
|
8165
|
+
/**
|
|
8166
|
+
* @internal
|
|
8074
8167
|
*/
|
|
8075
8168
|
_getSubmitData() {
|
|
8076
8169
|
const formFieldRegistry = this.get('formFieldRegistry');
|
|
@@ -8127,16 +8220,16 @@ class Form {
|
|
|
8127
8220
|
return this._applyConditions(workingSubmitData, formData);
|
|
8128
8221
|
}
|
|
8129
8222
|
|
|
8130
|
-
/**
|
|
8131
|
-
* @internal
|
|
8223
|
+
/**
|
|
8224
|
+
* @internal
|
|
8132
8225
|
*/
|
|
8133
8226
|
_applyConditions(toFilter, data, options = {}) {
|
|
8134
8227
|
const conditionChecker = this.get('conditionChecker');
|
|
8135
8228
|
return conditionChecker.applyConditions(toFilter, data, options);
|
|
8136
8229
|
}
|
|
8137
8230
|
|
|
8138
|
-
/**
|
|
8139
|
-
* @internal
|
|
8231
|
+
/**
|
|
8232
|
+
* @internal
|
|
8140
8233
|
*/
|
|
8141
8234
|
_getInitializedFieldData(data, options = {}) {
|
|
8142
8235
|
const formFieldRegistry = this.get('formFieldRegistry');
|
|
@@ -8242,9 +8335,9 @@ function createForm(options) {
|
|
|
8242
8335
|
const {
|
|
8243
8336
|
data,
|
|
8244
8337
|
schema,
|
|
8245
|
-
...
|
|
8338
|
+
...formOptions
|
|
8246
8339
|
} = options;
|
|
8247
|
-
const form = new Form(
|
|
8340
|
+
const form = new Form(formOptions);
|
|
8248
8341
|
return form.importSchema(schema, data).then(function () {
|
|
8249
8342
|
return form;
|
|
8250
8343
|
});
|