@bpmn-io/form-js-viewer 1.0.0 → 1.3.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -22
- package/README.md +164 -164
- package/dist/assets/form-js-base.css +985 -917
- package/dist/assets/form-js.css +69 -1
- package/dist/index.cjs +1982 -859
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +1977 -860
- package/dist/index.es.js.map +1 -1
- package/dist/types/Form.d.ts +12 -26
- package/dist/types/core/FieldFactory.d.ts +19 -0
- package/dist/types/core/FormFieldRegistry.d.ts +0 -1
- package/dist/types/core/Importer.d.ts +56 -0
- package/dist/types/core/PathRegistry.d.ts +71 -0
- package/dist/types/core/index.d.ts +9 -5
- package/dist/types/features/expression-language/ConditionChecker.d.ts +3 -2
- package/dist/types/features/expression-language/variableExtractionHelpers.d.ts +1 -1
- package/dist/types/features/index.d.ts +2 -0
- package/dist/types/features/viewerCommands/ViewerCommands.d.ts +14 -0
- package/dist/types/features/viewerCommands/cmd/UpdateFieldValidationHandler.d.ts +11 -0
- package/dist/types/features/viewerCommands/index.d.ts +8 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/render/components/form-fields/Checklist.d.ts +2 -6
- package/dist/types/render/components/form-fields/Default.d.ts +3 -3
- package/dist/types/render/components/form-fields/Group.d.ts +14 -0
- package/dist/types/render/components/form-fields/Radio.d.ts +2 -6
- package/dist/types/render/components/form-fields/Select.d.ts +2 -6
- package/dist/types/render/components/form-fields/Spacer.d.ts +14 -0
- package/dist/types/render/components/form-fields/Taglist.d.ts +2 -6
- package/dist/types/render/components/form-fields/parts/Grid.d.ts +1 -0
- package/dist/types/render/components/index.d.ts +4 -2
- package/dist/types/render/components/util/localisationUtil.d.ts +24 -0
- package/dist/types/render/components/util/valuesUtil.d.ts +6 -0
- package/dist/types/render/context/FormRenderContext.d.ts +3 -0
- package/dist/types/types.d.ts +35 -35
- package/dist/types/util/index.d.ts +2 -5
- package/package.json +5 -4
- package/dist/types/import/Importer.d.ts +0 -45
- package/dist/types/import/index.d.ts +0 -5
package/dist/index.cjs
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
var Ids = require('ids');
|
|
4
4
|
var minDash = require('min-dash');
|
|
5
|
+
var Big = require('big.js');
|
|
5
6
|
var feelin = require('feelin');
|
|
6
7
|
var feelers = require('feelers');
|
|
7
|
-
var showdown = require('showdown');
|
|
8
|
-
var Big = require('big.js');
|
|
9
8
|
var classNames = require('classnames');
|
|
10
9
|
var jsxRuntime = require('preact/jsx-runtime');
|
|
11
10
|
var hooks = require('preact/hooks');
|
|
@@ -14,6 +13,7 @@ var React = require('preact/compat');
|
|
|
14
13
|
var flatpickr = require('flatpickr');
|
|
15
14
|
var Markup = require('preact-markup');
|
|
16
15
|
var didi = require('didi');
|
|
16
|
+
var showdown = require('showdown');
|
|
17
17
|
|
|
18
18
|
function _interopNamespaceDefault(e) {
|
|
19
19
|
var n = Object.create(null);
|
|
@@ -34,15 +34,15 @@ function _interopNamespaceDefault(e) {
|
|
|
34
34
|
|
|
35
35
|
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
36
36
|
|
|
37
|
-
const getFlavouredFeelVariableNames = (feelString, feelFlavour, options = {}) => {
|
|
37
|
+
const getFlavouredFeelVariableNames = (feelString, feelFlavour = 'expression', options = {}) => {
|
|
38
38
|
const {
|
|
39
39
|
depth = 0,
|
|
40
40
|
specialDepthAccessors = {}
|
|
41
41
|
} = options;
|
|
42
42
|
if (!['expression', 'unaryTest'].includes(feelFlavour)) return [];
|
|
43
|
-
const tree = feelFlavour === 'expression' ? feelin.
|
|
43
|
+
const tree = feelFlavour === 'expression' ? feelin.parseExpression(feelString) : feelin.parseUnaryTests(feelString);
|
|
44
44
|
const simpleExpressionTree = _buildSimpleFeelStructureTree(tree, feelString);
|
|
45
|
-
|
|
45
|
+
const variables = function _unfoldVariables(node) {
|
|
46
46
|
if (node.name === 'PathExpression') {
|
|
47
47
|
if (Object.keys(specialDepthAccessors).length === 0) {
|
|
48
48
|
return depth === 0 ? [_getVariableNameAtPathIndex(node, 0)] : [];
|
|
@@ -55,34 +55,38 @@ const getFlavouredFeelVariableNames = (feelString, feelFlavour, options = {}) =>
|
|
|
55
55
|
|
|
56
56
|
// for any other kind of node, traverse its children and flatten the result
|
|
57
57
|
if (node.children) {
|
|
58
|
-
|
|
58
|
+
const variables = node.children.reduce((acc, child) => {
|
|
59
59
|
return acc.concat(_unfoldVariables(child));
|
|
60
60
|
}, []);
|
|
61
|
+
|
|
62
|
+
// if we are within a filter context, we need to remove the item variable as it is used for iteration there
|
|
63
|
+
return node.name === 'FilterContext' ? variables.filter(name => name !== 'item') : variables;
|
|
61
64
|
}
|
|
62
65
|
return [];
|
|
63
66
|
}(simpleExpressionTree);
|
|
67
|
+
return [...new Set(variables)];
|
|
64
68
|
};
|
|
65
69
|
|
|
66
|
-
/**
|
|
67
|
-
* Get the variable name at the specified index in a given path expression.
|
|
68
|
-
*
|
|
69
|
-
* @param {Object} root - The root node of the path expression tree.
|
|
70
|
-
* @param {number} index - The index of the variable name to retrieve.
|
|
71
|
-
* @returns {string|null} The variable name at the specified index or null if index is out of bounds.
|
|
70
|
+
/**
|
|
71
|
+
* Get the variable name at the specified index in a given path expression.
|
|
72
|
+
*
|
|
73
|
+
* @param {Object} root - The root node of the path expression tree.
|
|
74
|
+
* @param {number} index - The index of the variable name to retrieve.
|
|
75
|
+
* @returns {string|null} The variable name at the specified index or null if index is out of bounds.
|
|
72
76
|
*/
|
|
73
77
|
const _getVariableNameAtPathIndex = (root, index) => {
|
|
74
78
|
const accessors = _deconstructPathExpression(root);
|
|
75
79
|
return accessors[index] || null;
|
|
76
80
|
};
|
|
77
81
|
|
|
78
|
-
/**
|
|
79
|
-
* Extracts the variables which are required of the external context for a given path expression.
|
|
80
|
-
* This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
|
|
81
|
-
*
|
|
82
|
-
* @param {Object} node - The root node of the path expression tree.
|
|
83
|
-
* @param {number} initialDepth - The depth at which the root node is located in the outer context.
|
|
84
|
-
* @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
|
|
85
|
-
* @returns {Set} - A set containing the extracted variable names.
|
|
82
|
+
/**
|
|
83
|
+
* Extracts the variables which are required of the external context for a given path expression.
|
|
84
|
+
* This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
|
|
85
|
+
*
|
|
86
|
+
* @param {Object} node - The root node of the path expression tree.
|
|
87
|
+
* @param {number} initialDepth - The depth at which the root node is located in the outer context.
|
|
88
|
+
* @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
|
|
89
|
+
* @returns {Set} - A set containing the extracted variable names.
|
|
86
90
|
*/
|
|
87
91
|
const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) => {
|
|
88
92
|
// depth info represents the previous (initialised as null) and current depth of the current accessor in the path expression
|
|
@@ -128,11 +132,11 @@ const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) =
|
|
|
128
132
|
return new Set(extractedVariables);
|
|
129
133
|
};
|
|
130
134
|
|
|
131
|
-
/**
|
|
132
|
-
* Deconstructs a path expression tree into an array of components.
|
|
133
|
-
*
|
|
134
|
-
* @param {Object} root - The root node of the path expression tree.
|
|
135
|
-
* @returns {Array<string>} An array of components in the path expression, in the correct order.
|
|
135
|
+
/**
|
|
136
|
+
* Deconstructs a path expression tree into an array of components.
|
|
137
|
+
*
|
|
138
|
+
* @param {Object} root - The root node of the path expression tree.
|
|
139
|
+
* @returns {Array<string>} An array of components in the path expression, in the correct order.
|
|
136
140
|
*/
|
|
137
141
|
const _deconstructPathExpression = root => {
|
|
138
142
|
let node = root;
|
|
@@ -151,13 +155,13 @@ const _deconstructPathExpression = root => {
|
|
|
151
155
|
return parts.reverse();
|
|
152
156
|
};
|
|
153
157
|
|
|
154
|
-
/**
|
|
155
|
-
* Builds a simplified feel structure tree from the given parse tree and feel string.
|
|
156
|
-
* The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
|
|
157
|
-
*
|
|
158
|
-
* @param {Object} parseTree - The parse tree generated by a parser.
|
|
159
|
-
* @param {string} feelString - The feel string used for parsing.
|
|
160
|
-
* @returns {Object} The simplified feel structure tree.
|
|
158
|
+
/**
|
|
159
|
+
* Builds a simplified feel structure tree from the given parse tree and feel string.
|
|
160
|
+
* The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
|
|
161
|
+
*
|
|
162
|
+
* @param {Object} parseTree - The parse tree generated by a parser.
|
|
163
|
+
* @param {string} feelString - The feel string used for parsing.
|
|
164
|
+
* @returns {Object} The simplified feel structure tree.
|
|
161
165
|
*/
|
|
162
166
|
const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
|
|
163
167
|
const stack = [{
|
|
@@ -180,7 +184,45 @@ const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
|
|
|
180
184
|
parent.children.push(result);
|
|
181
185
|
}
|
|
182
186
|
});
|
|
183
|
-
return stack[0].children[0];
|
|
187
|
+
return _extractFilterExpressions(stack[0].children[0]);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Restructure the tree in such a way to bring filters (which create new contexts) to the root of the tree.
|
|
192
|
+
* This is done to simplify the extraction of variables and match the context hierarchy.
|
|
193
|
+
*/
|
|
194
|
+
const _extractFilterExpressions = tree => {
|
|
195
|
+
const flattenedExpressionTree = {
|
|
196
|
+
name: 'Root',
|
|
197
|
+
children: [tree]
|
|
198
|
+
};
|
|
199
|
+
const iterate = node => {
|
|
200
|
+
if (node.children) {
|
|
201
|
+
for (let x = 0; x < node.children.length; x++) {
|
|
202
|
+
if (node.children[x].name === 'FilterExpression') {
|
|
203
|
+
const filterTarget = node.children[x].children[0];
|
|
204
|
+
const filterExpression = node.children[x].children[2];
|
|
205
|
+
|
|
206
|
+
// bypass the filter expression
|
|
207
|
+
node.children[x] = filterTarget;
|
|
208
|
+
const taggedFilterExpression = {
|
|
209
|
+
name: 'FilterContext',
|
|
210
|
+
children: [filterExpression]
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// append the filter expression to the root
|
|
214
|
+
flattenedExpressionTree.children.push(taggedFilterExpression);
|
|
215
|
+
|
|
216
|
+
// recursively iterate the expression
|
|
217
|
+
iterate(filterExpression);
|
|
218
|
+
} else {
|
|
219
|
+
iterate(node.children[x]);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
iterate(tree);
|
|
225
|
+
return flattenedExpressionTree;
|
|
184
226
|
};
|
|
185
227
|
|
|
186
228
|
class FeelExpressionLanguage {
|
|
@@ -188,25 +230,25 @@ class FeelExpressionLanguage {
|
|
|
188
230
|
this._eventBus = eventBus;
|
|
189
231
|
}
|
|
190
232
|
|
|
191
|
-
/**
|
|
192
|
-
* Determines if the given value is a FEEL expression.
|
|
193
|
-
*
|
|
194
|
-
* @param {any} value
|
|
195
|
-
* @returns {boolean}
|
|
196
|
-
*
|
|
233
|
+
/**
|
|
234
|
+
* Determines if the given value is a FEEL expression.
|
|
235
|
+
*
|
|
236
|
+
* @param {any} value
|
|
237
|
+
* @returns {boolean}
|
|
238
|
+
*
|
|
197
239
|
*/
|
|
198
240
|
isExpression(value) {
|
|
199
241
|
return minDash.isString(value) && value.startsWith('=');
|
|
200
242
|
}
|
|
201
243
|
|
|
202
|
-
/**
|
|
203
|
-
* Retrieve variable names from a given FEEL expression.
|
|
204
|
-
*
|
|
205
|
-
* @param {string} expression
|
|
206
|
-
* @param {object} [options]
|
|
207
|
-
* @param {string} [options.type]
|
|
208
|
-
*
|
|
209
|
-
* @returns {string[]}
|
|
244
|
+
/**
|
|
245
|
+
* Retrieve variable names from a given FEEL expression.
|
|
246
|
+
*
|
|
247
|
+
* @param {string} expression
|
|
248
|
+
* @param {object} [options]
|
|
249
|
+
* @param {string} [options.type]
|
|
250
|
+
*
|
|
251
|
+
* @returns {string[]}
|
|
210
252
|
*/
|
|
211
253
|
getVariableNames(expression, options = {}) {
|
|
212
254
|
const {
|
|
@@ -221,13 +263,13 @@ class FeelExpressionLanguage {
|
|
|
221
263
|
return getFlavouredFeelVariableNames(expression, type);
|
|
222
264
|
}
|
|
223
265
|
|
|
224
|
-
/**
|
|
225
|
-
* Evaluate an expression.
|
|
226
|
-
*
|
|
227
|
-
* @param {string} expression
|
|
228
|
-
* @param {import('../../types').Data} [data]
|
|
229
|
-
*
|
|
230
|
-
* @returns {any}
|
|
266
|
+
/**
|
|
267
|
+
* Evaluate an expression.
|
|
268
|
+
*
|
|
269
|
+
* @param {string} expression
|
|
270
|
+
* @param {import('../../types').Data} [data]
|
|
271
|
+
*
|
|
272
|
+
* @returns {any}
|
|
231
273
|
*/
|
|
232
274
|
evaluate(expression, data = {}) {
|
|
233
275
|
if (!expression) {
|
|
@@ -252,23 +294,23 @@ FeelExpressionLanguage.$inject = ['eventBus'];
|
|
|
252
294
|
class FeelersTemplating {
|
|
253
295
|
constructor() {}
|
|
254
296
|
|
|
255
|
-
/**
|
|
256
|
-
* Determines if the given value is a feelers template.
|
|
257
|
-
*
|
|
258
|
-
* @param {any} value
|
|
259
|
-
* @returns {boolean}
|
|
260
|
-
*
|
|
297
|
+
/**
|
|
298
|
+
* Determines if the given value is a feelers template.
|
|
299
|
+
*
|
|
300
|
+
* @param {any} value
|
|
301
|
+
* @returns {boolean}
|
|
302
|
+
*
|
|
261
303
|
*/
|
|
262
304
|
isTemplate(value) {
|
|
263
305
|
return minDash.isString(value) && (value.startsWith('=') || /{{.*?}}/.test(value));
|
|
264
306
|
}
|
|
265
307
|
|
|
266
|
-
/**
|
|
267
|
-
* Retrieve variable names from a given feelers template.
|
|
268
|
-
*
|
|
269
|
-
* @param {string} template
|
|
270
|
-
*
|
|
271
|
-
* @returns {string[]}
|
|
308
|
+
/**
|
|
309
|
+
* Retrieve variable names from a given feelers template.
|
|
310
|
+
*
|
|
311
|
+
* @param {string} template
|
|
312
|
+
*
|
|
313
|
+
* @returns {string[]}
|
|
272
314
|
*/
|
|
273
315
|
getVariableNames(template) {
|
|
274
316
|
if (!this.isTemplate(template)) {
|
|
@@ -294,17 +336,17 @@ class FeelersTemplating {
|
|
|
294
336
|
}, []);
|
|
295
337
|
}
|
|
296
338
|
|
|
297
|
-
/**
|
|
298
|
-
* Evaluate a template.
|
|
299
|
-
*
|
|
300
|
-
* @param {string} template
|
|
301
|
-
* @param {Object<string, any>} context
|
|
302
|
-
* @param {Object} options
|
|
303
|
-
* @param {boolean} [options.debug = false]
|
|
304
|
-
* @param {boolean} [options.strict = false]
|
|
305
|
-
* @param {Function} [options.buildDebugString]
|
|
306
|
-
*
|
|
307
|
-
* @returns
|
|
339
|
+
/**
|
|
340
|
+
* Evaluate a template.
|
|
341
|
+
*
|
|
342
|
+
* @param {string} template
|
|
343
|
+
* @param {Object<string, any>} context
|
|
344
|
+
* @param {Object} options
|
|
345
|
+
* @param {boolean} [options.debug = false]
|
|
346
|
+
* @param {boolean} [options.strict = false]
|
|
347
|
+
* @param {Function} [options.buildDebugString]
|
|
348
|
+
*
|
|
349
|
+
* @returns
|
|
308
350
|
*/
|
|
309
351
|
evaluate(template, context = {}, options = {}) {
|
|
310
352
|
const {
|
|
@@ -319,22 +361,22 @@ class FeelersTemplating {
|
|
|
319
361
|
});
|
|
320
362
|
}
|
|
321
363
|
|
|
322
|
-
/**
|
|
323
|
-
* @typedef {Object} ExpressionWithDepth
|
|
324
|
-
* @property {number} depth - The depth of the expression in the syntax tree.
|
|
325
|
-
* @property {string} expression - The extracted expression
|
|
364
|
+
/**
|
|
365
|
+
* @typedef {Object} ExpressionWithDepth
|
|
366
|
+
* @property {number} depth - The depth of the expression in the syntax tree.
|
|
367
|
+
* @property {string} expression - The extracted expression
|
|
326
368
|
*/
|
|
327
369
|
|
|
328
|
-
/**
|
|
329
|
-
* Extracts all feel expressions in the template along with their depth in the syntax tree.
|
|
330
|
-
* The depth is incremented for child expressions of loops to account for context drilling.
|
|
331
|
-
|
|
332
|
-
* @param {string} template - A feelers template string.
|
|
333
|
-
* @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
|
|
334
|
-
*
|
|
335
|
-
* @example
|
|
336
|
-
* const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
|
|
337
|
-
* const extractedExpressions = _extractExpressionsWithDepth(template);
|
|
370
|
+
/**
|
|
371
|
+
* Extracts all feel expressions in the template along with their depth in the syntax tree.
|
|
372
|
+
* The depth is incremented for child expressions of loops to account for context drilling.
|
|
373
|
+
* @name extractExpressionsWithDepth
|
|
374
|
+
* @param {string} template - A feelers template string.
|
|
375
|
+
* @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
|
|
379
|
+
* const extractedExpressions = _extractExpressionsWithDepth(template);
|
|
338
380
|
*/
|
|
339
381
|
_extractExpressionsWithDepth(template) {
|
|
340
382
|
// build simplified feelers syntax tree
|
|
@@ -365,47 +407,271 @@ class FeelersTemplating {
|
|
|
365
407
|
}
|
|
366
408
|
FeelersTemplating.$inject = [];
|
|
367
409
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
410
|
+
// config ///////////////////
|
|
411
|
+
|
|
412
|
+
const MINUTES_IN_DAY = 60 * 24;
|
|
413
|
+
const DATETIME_SUBTYPES = {
|
|
414
|
+
DATE: 'date',
|
|
415
|
+
TIME: 'time',
|
|
416
|
+
DATETIME: 'datetime'
|
|
417
|
+
};
|
|
418
|
+
const TIME_SERIALISING_FORMATS = {
|
|
419
|
+
UTC_OFFSET: 'utc_offset',
|
|
420
|
+
UTC_NORMALIZED: 'utc_normalized',
|
|
421
|
+
NO_TIMEZONE: 'no_timezone'
|
|
422
|
+
};
|
|
423
|
+
const DATETIME_SUBTYPES_LABELS = {
|
|
424
|
+
[DATETIME_SUBTYPES.DATE]: 'Date',
|
|
425
|
+
[DATETIME_SUBTYPES.TIME]: 'Time',
|
|
426
|
+
[DATETIME_SUBTYPES.DATETIME]: 'Date & Time'
|
|
427
|
+
};
|
|
428
|
+
const TIME_SERIALISINGFORMAT_LABELS = {
|
|
429
|
+
[TIME_SERIALISING_FORMATS.UTC_OFFSET]: 'UTC offset',
|
|
430
|
+
[TIME_SERIALISING_FORMATS.UTC_NORMALIZED]: 'UTC normalized',
|
|
431
|
+
[TIME_SERIALISING_FORMATS.NO_TIMEZONE]: 'No timezone'
|
|
432
|
+
};
|
|
433
|
+
const DATETIME_SUBTYPE_PATH = ['subtype'];
|
|
434
|
+
const DATE_LABEL_PATH = ['dateLabel'];
|
|
435
|
+
const DATE_DISALLOW_PAST_PATH = ['disallowPassedDates'];
|
|
436
|
+
const TIME_LABEL_PATH = ['timeLabel'];
|
|
437
|
+
const TIME_USE24H_PATH = ['use24h'];
|
|
438
|
+
const TIME_INTERVAL_PATH = ['timeInterval'];
|
|
439
|
+
const TIME_SERIALISING_FORMAT_PATH = ['timeSerializingFormat'];
|
|
440
|
+
|
|
441
|
+
// config ///////////////////
|
|
442
|
+
|
|
443
|
+
const VALUES_SOURCES = {
|
|
444
|
+
STATIC: 'static',
|
|
445
|
+
INPUT: 'input',
|
|
446
|
+
EXPRESSION: 'expression'
|
|
447
|
+
};
|
|
448
|
+
const VALUES_SOURCE_DEFAULT = VALUES_SOURCES.STATIC;
|
|
449
|
+
const VALUES_SOURCES_LABELS = {
|
|
450
|
+
[VALUES_SOURCES.STATIC]: 'Static',
|
|
451
|
+
[VALUES_SOURCES.INPUT]: 'Input data',
|
|
452
|
+
[VALUES_SOURCES.EXPRESSION]: 'Expression'
|
|
453
|
+
};
|
|
454
|
+
const VALUES_SOURCES_PATHS = {
|
|
455
|
+
[VALUES_SOURCES.STATIC]: ['values'],
|
|
456
|
+
[VALUES_SOURCES.INPUT]: ['valuesKey'],
|
|
457
|
+
[VALUES_SOURCES.EXPRESSION]: ['valuesExpression']
|
|
458
|
+
};
|
|
459
|
+
const VALUES_SOURCES_DEFAULTS = {
|
|
460
|
+
[VALUES_SOURCES.STATIC]: [{
|
|
461
|
+
label: 'Value',
|
|
462
|
+
value: 'value'
|
|
463
|
+
}],
|
|
464
|
+
[VALUES_SOURCES.INPUT]: '',
|
|
465
|
+
[VALUES_SOURCES.EXPRESSION]: '='
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
// helpers ///////////////////
|
|
469
|
+
|
|
470
|
+
function getValuesSource(field) {
|
|
471
|
+
for (const source of Object.values(VALUES_SOURCES)) {
|
|
472
|
+
if (minDash.get(field, VALUES_SOURCES_PATHS[source]) !== undefined) {
|
|
473
|
+
return source;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return VALUES_SOURCE_DEFAULT;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function createInjector(bootstrapModules) {
|
|
480
|
+
const injector = new didi.Injector(bootstrapModules);
|
|
481
|
+
injector.init();
|
|
482
|
+
return injector;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* @param {string?} prefix
|
|
487
|
+
*
|
|
488
|
+
* @returns Element
|
|
489
|
+
*/
|
|
490
|
+
function createFormContainer(prefix = 'fjs') {
|
|
491
|
+
const container = document.createElement('div');
|
|
492
|
+
container.classList.add(`${prefix}-container`);
|
|
493
|
+
return container;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const EXPRESSION_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'conditional.hide', 'description', 'label', 'source', 'readonly', 'text', 'validate.min', 'validate.max', 'validate.minLength', 'validate.maxLength', 'valuesExpression'];
|
|
497
|
+
const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'description', 'label', 'source', 'text'];
|
|
498
|
+
function isRequired(field) {
|
|
499
|
+
return field.required;
|
|
500
|
+
}
|
|
501
|
+
function pathParse(path) {
|
|
502
|
+
if (!path) {
|
|
503
|
+
return [];
|
|
504
|
+
}
|
|
505
|
+
return path.split('.').map(key => {
|
|
506
|
+
return isNaN(parseInt(key)) ? key : parseInt(key);
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
function pathsEqual(a, b) {
|
|
510
|
+
return a && b && a.length === b.length && a.every((value, index) => value === b[index]);
|
|
511
|
+
}
|
|
512
|
+
const indices = {};
|
|
513
|
+
function generateIndexForType(type) {
|
|
514
|
+
if (type in indices) {
|
|
515
|
+
indices[type]++;
|
|
516
|
+
} else {
|
|
517
|
+
indices[type] = 1;
|
|
518
|
+
}
|
|
519
|
+
return indices[type];
|
|
520
|
+
}
|
|
521
|
+
function generateIdForType(type) {
|
|
522
|
+
return `${type}${generateIndexForType(type)}`;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* @template T
|
|
527
|
+
* @param {T} data
|
|
528
|
+
* @param {(this: any, key: string, value: any) => any} [replacer]
|
|
529
|
+
* @return {T}
|
|
530
|
+
*/
|
|
531
|
+
function clone(data, replacer) {
|
|
532
|
+
return JSON.parse(JSON.stringify(data, replacer));
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Parse the schema for input variables a form might make use of
|
|
537
|
+
*
|
|
538
|
+
* @param {any} schema
|
|
539
|
+
*
|
|
540
|
+
* @return {string[]}
|
|
541
|
+
*/
|
|
542
|
+
function getSchemaVariables(schema, options = {}) {
|
|
543
|
+
const {
|
|
544
|
+
expressionLanguage = new FeelExpressionLanguage(null),
|
|
545
|
+
templating = new FeelersTemplating(),
|
|
546
|
+
inputs = true,
|
|
547
|
+
outputs = true
|
|
548
|
+
} = options;
|
|
549
|
+
if (!schema.components) {
|
|
550
|
+
return [];
|
|
551
|
+
}
|
|
552
|
+
const getAllComponents = node => {
|
|
553
|
+
const components = [];
|
|
554
|
+
if (node.components) {
|
|
555
|
+
node.components.forEach(component => {
|
|
556
|
+
components.push(component);
|
|
557
|
+
components.push(...getAllComponents(component));
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
return components;
|
|
561
|
+
};
|
|
562
|
+
const variables = getAllComponents(schema).reduce((variables, component) => {
|
|
563
|
+
const {
|
|
564
|
+
valuesKey
|
|
565
|
+
} = component;
|
|
566
|
+
|
|
567
|
+
// collect input-only variables
|
|
568
|
+
if (inputs) {
|
|
569
|
+
if (valuesKey) {
|
|
570
|
+
variables = [...variables, valuesKey];
|
|
571
|
+
}
|
|
572
|
+
EXPRESSION_PROPERTIES.forEach(prop => {
|
|
573
|
+
const property = minDash.get(component, prop.split('.'));
|
|
574
|
+
if (property && expressionLanguage.isExpression(property)) {
|
|
575
|
+
const expressionVariables = expressionLanguage.getVariableNames(property, {
|
|
576
|
+
type: 'expression'
|
|
577
|
+
});
|
|
578
|
+
variables = [...variables, ...expressionVariables];
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
TEMPLATE_PROPERTIES.forEach(prop => {
|
|
582
|
+
const property = minDash.get(component, prop.split('.'));
|
|
583
|
+
if (property && !expressionLanguage.isExpression(property) && templating.isTemplate(property)) {
|
|
584
|
+
const templateVariables = templating.getVariableNames(property);
|
|
585
|
+
variables = [...variables, ...templateVariables];
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
return variables.filter(variable => variable !== undefined || variable !== null);
|
|
590
|
+
}, []);
|
|
591
|
+
const getBindingVariables = node => {
|
|
592
|
+
const bindingVariable = [];
|
|
593
|
+
|
|
594
|
+
// c.f. https://github.com/bpmn-io/form-js/issues/778 @Skaiir to remove?
|
|
595
|
+
if (node.type === 'button') {
|
|
596
|
+
return [];
|
|
597
|
+
} else if (node.key) {
|
|
598
|
+
return [node.key.split('.')[0]];
|
|
599
|
+
} else if (node.path) {
|
|
600
|
+
return [node.path.split('.')[0]];
|
|
601
|
+
} else if (node.components) {
|
|
602
|
+
node.components.forEach(component => {
|
|
603
|
+
bindingVariable.push(...getBindingVariables(component));
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
return bindingVariable;
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
// collect binding variables
|
|
610
|
+
if (inputs || outputs) {
|
|
611
|
+
variables.push(...getBindingVariables(schema));
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// remove duplicates
|
|
615
|
+
return Array.from(new Set(variables));
|
|
616
|
+
}
|
|
617
|
+
function runRecursively(formField, fn) {
|
|
618
|
+
const components = formField.components || [];
|
|
619
|
+
components.forEach((component, index) => {
|
|
620
|
+
runRecursively(component, fn);
|
|
621
|
+
});
|
|
622
|
+
fn(formField);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* @typedef {object} Condition
|
|
627
|
+
* @property {string} [hide]
|
|
371
628
|
*/
|
|
372
629
|
|
|
373
630
|
class ConditionChecker {
|
|
374
|
-
constructor(formFieldRegistry, eventBus) {
|
|
631
|
+
constructor(formFieldRegistry, pathRegistry, eventBus) {
|
|
375
632
|
this._formFieldRegistry = formFieldRegistry;
|
|
633
|
+
this._pathRegistry = pathRegistry;
|
|
376
634
|
this._eventBus = eventBus;
|
|
377
635
|
}
|
|
378
636
|
|
|
379
|
-
/**
|
|
380
|
-
* For given data, remove properties based on condition.
|
|
381
|
-
*
|
|
382
|
-
* @param {Object<string, any>} properties
|
|
383
|
-
* @param {Object<string, any>} data
|
|
637
|
+
/**
|
|
638
|
+
* For given data, remove properties based on condition.
|
|
639
|
+
*
|
|
640
|
+
* @param {Object<string, any>} properties
|
|
641
|
+
* @param {Object<string, any>} data
|
|
384
642
|
*/
|
|
385
643
|
applyConditions(properties, data = {}) {
|
|
386
|
-
const
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
for (const {
|
|
391
|
-
key,
|
|
392
|
-
condition
|
|
393
|
-
} of conditions) {
|
|
394
|
-
const shouldRemove = this._checkHideCondition(condition, data);
|
|
395
|
-
if (shouldRemove) {
|
|
396
|
-
delete newProperties[key];
|
|
397
|
-
}
|
|
644
|
+
const newProperties = clone(properties);
|
|
645
|
+
const form = this._formFieldRegistry.getAll().find(field => field.type === 'default');
|
|
646
|
+
if (!form) {
|
|
647
|
+
throw new Error('form field registry has no form');
|
|
398
648
|
}
|
|
649
|
+
this._pathRegistry.executeRecursivelyOnFields(form, ({
|
|
650
|
+
field,
|
|
651
|
+
isClosed,
|
|
652
|
+
context
|
|
653
|
+
}) => {
|
|
654
|
+
const {
|
|
655
|
+
conditional: condition
|
|
656
|
+
} = field;
|
|
657
|
+
context.isHidden = context.isHidden || condition && this._checkHideCondition(condition, data);
|
|
658
|
+
|
|
659
|
+
// only clear the leaf nodes, as groups may both point to the same path
|
|
660
|
+
if (context.isHidden && isClosed) {
|
|
661
|
+
const valuePath = this._pathRegistry.getValuePath(field);
|
|
662
|
+
this._clearObjectValueRecursively(valuePath, newProperties);
|
|
663
|
+
}
|
|
664
|
+
});
|
|
399
665
|
return newProperties;
|
|
400
666
|
}
|
|
401
667
|
|
|
402
|
-
/**
|
|
403
|
-
* Check if given condition is met. Returns null for invalid/missing conditions.
|
|
404
|
-
*
|
|
405
|
-
* @param {string} condition
|
|
406
|
-
* @param {import('../../types').Data} [data]
|
|
407
|
-
*
|
|
408
|
-
* @returns {boolean|null}
|
|
668
|
+
/**
|
|
669
|
+
* Check if given condition is met. Returns null for invalid/missing conditions.
|
|
670
|
+
*
|
|
671
|
+
* @param {string} condition
|
|
672
|
+
* @param {import('../../types').Data} [data]
|
|
673
|
+
*
|
|
674
|
+
* @returns {boolean|null}
|
|
409
675
|
*/
|
|
410
676
|
check(condition, data = {}) {
|
|
411
677
|
if (!condition) {
|
|
@@ -426,12 +692,12 @@ class ConditionChecker {
|
|
|
426
692
|
}
|
|
427
693
|
}
|
|
428
694
|
|
|
429
|
-
/**
|
|
430
|
-
* Check if hide condition is met.
|
|
431
|
-
*
|
|
432
|
-
* @param {Condition} condition
|
|
433
|
-
* @param {Object<string, any>} data
|
|
434
|
-
* @returns {boolean}
|
|
695
|
+
/**
|
|
696
|
+
* Check if hide condition is met.
|
|
697
|
+
*
|
|
698
|
+
* @param {Condition} condition
|
|
699
|
+
* @param {Object<string, any>} data
|
|
700
|
+
* @returns {boolean}
|
|
435
701
|
*/
|
|
436
702
|
_checkHideCondition(condition, data) {
|
|
437
703
|
if (!condition.hide) {
|
|
@@ -440,24 +706,18 @@ class ConditionChecker {
|
|
|
440
706
|
const result = this.check(condition.hide, data);
|
|
441
707
|
return result === true;
|
|
442
708
|
}
|
|
443
|
-
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
key,
|
|
453
|
-
condition
|
|
454
|
-
}];
|
|
455
|
-
}
|
|
456
|
-
return conditions;
|
|
457
|
-
}, []);
|
|
709
|
+
_clearObjectValueRecursively(valuePath, obj) {
|
|
710
|
+
const workingValuePath = [...valuePath];
|
|
711
|
+
let recurse = false;
|
|
712
|
+
do {
|
|
713
|
+
minDash.set(obj, workingValuePath, undefined);
|
|
714
|
+
workingValuePath.pop();
|
|
715
|
+
const parentObject = minDash.get(obj, workingValuePath);
|
|
716
|
+
recurse = minDash.isObject(parentObject) && !minDash.values(parentObject).length && !!workingValuePath.length;
|
|
717
|
+
} while (recurse);
|
|
458
718
|
}
|
|
459
719
|
}
|
|
460
|
-
ConditionChecker.$inject = ['formFieldRegistry', 'eventBus'];
|
|
720
|
+
ConditionChecker.$inject = ['formFieldRegistry', 'pathRegistry', 'eventBus'];
|
|
461
721
|
|
|
462
722
|
var ExpressionLanguageModule = {
|
|
463
723
|
__init__: ['expressionLanguage', 'templating', 'conditionChecker'],
|
|
@@ -473,12 +733,12 @@ class MarkdownRenderer {
|
|
|
473
733
|
this._converter = new showdown.Converter();
|
|
474
734
|
}
|
|
475
735
|
|
|
476
|
-
/**
|
|
477
|
-
* Render markdown to HTML.
|
|
478
|
-
*
|
|
479
|
-
* @param {string} markdown - The markdown to render
|
|
480
|
-
*
|
|
481
|
-
* @returns {string} HTML
|
|
736
|
+
/**
|
|
737
|
+
* Render markdown to HTML.
|
|
738
|
+
*
|
|
739
|
+
* @param {string} markdown - The markdown to render
|
|
740
|
+
*
|
|
741
|
+
* @returns {string} HTML
|
|
482
742
|
*/
|
|
483
743
|
render(markdown) {
|
|
484
744
|
return this._converter.makeHtml(markdown);
|
|
@@ -491,6 +751,538 @@ var MarkdownModule = {
|
|
|
491
751
|
markdownRenderer: ['type', MarkdownRenderer]
|
|
492
752
|
};
|
|
493
753
|
|
|
754
|
+
/**
|
|
755
|
+
* @typedef {import('didi').Injector} Injector
|
|
756
|
+
*
|
|
757
|
+
* @typedef {import('../core/Types').ElementLike} ElementLike
|
|
758
|
+
*
|
|
759
|
+
* @typedef {import('../core/EventBus').default} EventBus
|
|
760
|
+
* @typedef {import('./CommandHandler').default} CommandHandler
|
|
761
|
+
*
|
|
762
|
+
* @typedef { any } CommandContext
|
|
763
|
+
* @typedef { {
|
|
764
|
+
* new (...args: any[]) : CommandHandler
|
|
765
|
+
* } } CommandHandlerConstructor
|
|
766
|
+
* @typedef { {
|
|
767
|
+
* [key: string]: CommandHandler;
|
|
768
|
+
* } } CommandHandlerMap
|
|
769
|
+
* @typedef { {
|
|
770
|
+
* command: string;
|
|
771
|
+
* context: any;
|
|
772
|
+
* id?: any;
|
|
773
|
+
* } } CommandStackAction
|
|
774
|
+
* @typedef { {
|
|
775
|
+
* actions: CommandStackAction[];
|
|
776
|
+
* dirty: ElementLike[];
|
|
777
|
+
* trigger: 'execute' | 'undo' | 'redo' | 'clear' | null;
|
|
778
|
+
* atomic?: boolean;
|
|
779
|
+
* } } CurrentExecution
|
|
780
|
+
*/
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* A service that offers un- and redoable execution of commands.
|
|
784
|
+
*
|
|
785
|
+
* The command stack is responsible for executing modeling actions
|
|
786
|
+
* in a un- and redoable manner. To do this it delegates the actual
|
|
787
|
+
* command execution to {@link CommandHandler}s.
|
|
788
|
+
*
|
|
789
|
+
* Command handlers provide {@link CommandHandler#execute(ctx)} and
|
|
790
|
+
* {@link CommandHandler#revert(ctx)} methods to un- and redo a command
|
|
791
|
+
* identified by a command context.
|
|
792
|
+
*
|
|
793
|
+
*
|
|
794
|
+
* ## Life-Cycle events
|
|
795
|
+
*
|
|
796
|
+
* In the process the command stack fires a number of life-cycle events
|
|
797
|
+
* that other components to participate in the command execution.
|
|
798
|
+
*
|
|
799
|
+
* * preExecute
|
|
800
|
+
* * preExecuted
|
|
801
|
+
* * execute
|
|
802
|
+
* * executed
|
|
803
|
+
* * postExecute
|
|
804
|
+
* * postExecuted
|
|
805
|
+
* * revert
|
|
806
|
+
* * reverted
|
|
807
|
+
*
|
|
808
|
+
* A special event is used for validating, whether a command can be
|
|
809
|
+
* performed prior to its execution.
|
|
810
|
+
*
|
|
811
|
+
* * canExecute
|
|
812
|
+
*
|
|
813
|
+
* Each of the events is fired as `commandStack.{eventName}` and
|
|
814
|
+
* `commandStack.{commandName}.{eventName}`, respectively. This gives
|
|
815
|
+
* components fine grained control on where to hook into.
|
|
816
|
+
*
|
|
817
|
+
* The event object fired transports `command`, the name of the
|
|
818
|
+
* command and `context`, the command context.
|
|
819
|
+
*
|
|
820
|
+
*
|
|
821
|
+
* ## Creating Command Handlers
|
|
822
|
+
*
|
|
823
|
+
* Command handlers should provide the {@link CommandHandler#execute(ctx)}
|
|
824
|
+
* and {@link CommandHandler#revert(ctx)} methods to implement
|
|
825
|
+
* redoing and undoing of a command.
|
|
826
|
+
*
|
|
827
|
+
* A command handler _must_ ensure undo is performed properly in order
|
|
828
|
+
* not to break the undo chain. It must also return the shapes that
|
|
829
|
+
* got changed during the `execute` and `revert` operations.
|
|
830
|
+
*
|
|
831
|
+
* Command handlers may execute other modeling operations (and thus
|
|
832
|
+
* commands) in their `preExecute(d)` and `postExecute(d)` phases. The command
|
|
833
|
+
* stack will properly group all commands together into a logical unit
|
|
834
|
+
* that may be re- and undone atomically.
|
|
835
|
+
*
|
|
836
|
+
* Command handlers must not execute other commands from within their
|
|
837
|
+
* core implementation (`execute`, `revert`).
|
|
838
|
+
*
|
|
839
|
+
*
|
|
840
|
+
* ## Change Tracking
|
|
841
|
+
*
|
|
842
|
+
* During the execution of the CommandStack it will keep track of all
|
|
843
|
+
* elements that have been touched during the command's execution.
|
|
844
|
+
*
|
|
845
|
+
* At the end of the CommandStack execution it will notify interested
|
|
846
|
+
* components via an 'elements.changed' event with all the dirty
|
|
847
|
+
* elements.
|
|
848
|
+
*
|
|
849
|
+
* The event can be picked up by components that are interested in the fact
|
|
850
|
+
* that elements have been changed. One use case for this is updating
|
|
851
|
+
* their graphical representation after moving / resizing or deletion.
|
|
852
|
+
*
|
|
853
|
+
* @see CommandHandler
|
|
854
|
+
*
|
|
855
|
+
* @param {EventBus} eventBus
|
|
856
|
+
* @param {Injector} injector
|
|
857
|
+
*/
|
|
858
|
+
function CommandStack(eventBus, injector) {
|
|
859
|
+
/**
|
|
860
|
+
* A map of all registered command handlers.
|
|
861
|
+
*
|
|
862
|
+
* @type {CommandHandlerMap}
|
|
863
|
+
*/
|
|
864
|
+
this._handlerMap = {};
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* A stack containing all re/undoable actions on the diagram
|
|
868
|
+
*
|
|
869
|
+
* @type {CommandStackAction[]}
|
|
870
|
+
*/
|
|
871
|
+
this._stack = [];
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* The current index on the stack
|
|
875
|
+
*
|
|
876
|
+
* @type {number}
|
|
877
|
+
*/
|
|
878
|
+
this._stackIdx = -1;
|
|
879
|
+
|
|
880
|
+
/**
|
|
881
|
+
* Current active commandStack execution
|
|
882
|
+
*
|
|
883
|
+
* @type {CurrentExecution}
|
|
884
|
+
*/
|
|
885
|
+
this._currentExecution = {
|
|
886
|
+
actions: [],
|
|
887
|
+
dirty: [],
|
|
888
|
+
trigger: null
|
|
889
|
+
};
|
|
890
|
+
|
|
891
|
+
/**
|
|
892
|
+
* @type {Injector}
|
|
893
|
+
*/
|
|
894
|
+
this._injector = injector;
|
|
895
|
+
|
|
896
|
+
/**
|
|
897
|
+
* @type EventBus
|
|
898
|
+
*/
|
|
899
|
+
this._eventBus = eventBus;
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* @type { number }
|
|
903
|
+
*/
|
|
904
|
+
this._uid = 1;
|
|
905
|
+
eventBus.on(['diagram.destroy', 'diagram.clear'], function () {
|
|
906
|
+
this.clear(false);
|
|
907
|
+
}, this);
|
|
908
|
+
}
|
|
909
|
+
CommandStack.$inject = ['eventBus', 'injector'];
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* Execute a command.
|
|
913
|
+
*
|
|
914
|
+
* @param {string} command The command to execute.
|
|
915
|
+
* @param {CommandContext} context The context with which to execute the command.
|
|
916
|
+
*/
|
|
917
|
+
CommandStack.prototype.execute = function (command, context) {
|
|
918
|
+
if (!command) {
|
|
919
|
+
throw new Error('command required');
|
|
920
|
+
}
|
|
921
|
+
this._currentExecution.trigger = 'execute';
|
|
922
|
+
const action = {
|
|
923
|
+
command: command,
|
|
924
|
+
context: context
|
|
925
|
+
};
|
|
926
|
+
this._pushAction(action);
|
|
927
|
+
this._internalExecute(action);
|
|
928
|
+
this._popAction();
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* Check whether a command can be executed.
|
|
933
|
+
*
|
|
934
|
+
* Implementors may hook into the mechanism on two ways:
|
|
935
|
+
*
|
|
936
|
+
* * in event listeners:
|
|
937
|
+
*
|
|
938
|
+
* Users may prevent the execution via an event listener.
|
|
939
|
+
* It must prevent the default action for `commandStack.(<command>.)canExecute` events.
|
|
940
|
+
*
|
|
941
|
+
* * in command handlers:
|
|
942
|
+
*
|
|
943
|
+
* If the method {@link CommandHandler#canExecute} is implemented in a handler
|
|
944
|
+
* it will be called to figure out whether the execution is allowed.
|
|
945
|
+
*
|
|
946
|
+
* @param {string} command The command to execute.
|
|
947
|
+
* @param {CommandContext} context The context with which to execute the command.
|
|
948
|
+
*
|
|
949
|
+
* @return {boolean} Whether the command can be executed with the given context.
|
|
950
|
+
*/
|
|
951
|
+
CommandStack.prototype.canExecute = function (command, context) {
|
|
952
|
+
const action = {
|
|
953
|
+
command: command,
|
|
954
|
+
context: context
|
|
955
|
+
};
|
|
956
|
+
const handler = this._getHandler(command);
|
|
957
|
+
let result = this._fire(command, 'canExecute', action);
|
|
958
|
+
|
|
959
|
+
// handler#canExecute will only be called if no listener
|
|
960
|
+
// decided on a result already
|
|
961
|
+
if (result === undefined) {
|
|
962
|
+
if (!handler) {
|
|
963
|
+
return false;
|
|
964
|
+
}
|
|
965
|
+
if (handler.canExecute) {
|
|
966
|
+
result = handler.canExecute(context);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
return result;
|
|
970
|
+
};
|
|
971
|
+
|
|
972
|
+
/**
|
|
973
|
+
* Clear the command stack, erasing all undo / redo history.
|
|
974
|
+
*
|
|
975
|
+
* @param {boolean} [emit=true] Whether to fire an event. Defaults to `true`.
|
|
976
|
+
*/
|
|
977
|
+
CommandStack.prototype.clear = function (emit) {
|
|
978
|
+
this._stack.length = 0;
|
|
979
|
+
this._stackIdx = -1;
|
|
980
|
+
if (emit !== false) {
|
|
981
|
+
this._fire('changed', {
|
|
982
|
+
trigger: 'clear'
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* Undo last command(s)
|
|
989
|
+
*/
|
|
990
|
+
CommandStack.prototype.undo = function () {
|
|
991
|
+
let action = this._getUndoAction(),
|
|
992
|
+
next;
|
|
993
|
+
if (action) {
|
|
994
|
+
this._currentExecution.trigger = 'undo';
|
|
995
|
+
this._pushAction(action);
|
|
996
|
+
while (action) {
|
|
997
|
+
this._internalUndo(action);
|
|
998
|
+
next = this._getUndoAction();
|
|
999
|
+
if (!next || next.id !== action.id) {
|
|
1000
|
+
break;
|
|
1001
|
+
}
|
|
1002
|
+
action = next;
|
|
1003
|
+
}
|
|
1004
|
+
this._popAction();
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* Redo last command(s)
|
|
1010
|
+
*/
|
|
1011
|
+
CommandStack.prototype.redo = function () {
|
|
1012
|
+
let action = this._getRedoAction(),
|
|
1013
|
+
next;
|
|
1014
|
+
if (action) {
|
|
1015
|
+
this._currentExecution.trigger = 'redo';
|
|
1016
|
+
this._pushAction(action);
|
|
1017
|
+
while (action) {
|
|
1018
|
+
this._internalExecute(action, true);
|
|
1019
|
+
next = this._getRedoAction();
|
|
1020
|
+
if (!next || next.id !== action.id) {
|
|
1021
|
+
break;
|
|
1022
|
+
}
|
|
1023
|
+
action = next;
|
|
1024
|
+
}
|
|
1025
|
+
this._popAction();
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
|
|
1029
|
+
/**
|
|
1030
|
+
* Register a handler instance with the command stack.
|
|
1031
|
+
*
|
|
1032
|
+
* @param {string} command Command to be executed.
|
|
1033
|
+
* @param {CommandHandler} handler Handler to execute the command.
|
|
1034
|
+
*/
|
|
1035
|
+
CommandStack.prototype.register = function (command, handler) {
|
|
1036
|
+
this._setHandler(command, handler);
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
/**
|
|
1040
|
+
* Register a handler type with the command stack by instantiating it and
|
|
1041
|
+
* injecting its dependencies.
|
|
1042
|
+
*
|
|
1043
|
+
* @param {string} command Command to be executed.
|
|
1044
|
+
* @param {CommandHandlerConstructor} handlerCls Constructor to instantiate a {@link CommandHandler}.
|
|
1045
|
+
*/
|
|
1046
|
+
CommandStack.prototype.registerHandler = function (command, handlerCls) {
|
|
1047
|
+
if (!command || !handlerCls) {
|
|
1048
|
+
throw new Error('command and handlerCls must be defined');
|
|
1049
|
+
}
|
|
1050
|
+
const handler = this._injector.instantiate(handlerCls);
|
|
1051
|
+
this.register(command, handler);
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* @return {boolean}
|
|
1056
|
+
*/
|
|
1057
|
+
CommandStack.prototype.canUndo = function () {
|
|
1058
|
+
return !!this._getUndoAction();
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* @return {boolean}
|
|
1063
|
+
*/
|
|
1064
|
+
CommandStack.prototype.canRedo = function () {
|
|
1065
|
+
return !!this._getRedoAction();
|
|
1066
|
+
};
|
|
1067
|
+
|
|
1068
|
+
// stack access //////////////////////
|
|
1069
|
+
|
|
1070
|
+
CommandStack.prototype._getRedoAction = function () {
|
|
1071
|
+
return this._stack[this._stackIdx + 1];
|
|
1072
|
+
};
|
|
1073
|
+
CommandStack.prototype._getUndoAction = function () {
|
|
1074
|
+
return this._stack[this._stackIdx];
|
|
1075
|
+
};
|
|
1076
|
+
|
|
1077
|
+
// internal functionality //////////////////////
|
|
1078
|
+
|
|
1079
|
+
CommandStack.prototype._internalUndo = function (action) {
|
|
1080
|
+
const command = action.command,
|
|
1081
|
+
context = action.context;
|
|
1082
|
+
const handler = this._getHandler(command);
|
|
1083
|
+
|
|
1084
|
+
// guard against illegal nested command stack invocations
|
|
1085
|
+
this._atomicDo(() => {
|
|
1086
|
+
this._fire(command, 'revert', action);
|
|
1087
|
+
if (handler.revert) {
|
|
1088
|
+
this._markDirty(handler.revert(context));
|
|
1089
|
+
}
|
|
1090
|
+
this._revertedAction(action);
|
|
1091
|
+
this._fire(command, 'reverted', action);
|
|
1092
|
+
});
|
|
1093
|
+
};
|
|
1094
|
+
CommandStack.prototype._fire = function (command, qualifier, event) {
|
|
1095
|
+
if (arguments.length < 3) {
|
|
1096
|
+
event = qualifier;
|
|
1097
|
+
qualifier = null;
|
|
1098
|
+
}
|
|
1099
|
+
const names = qualifier ? [command + '.' + qualifier, qualifier] : [command];
|
|
1100
|
+
let result;
|
|
1101
|
+
event = this._eventBus.createEvent(event);
|
|
1102
|
+
for (const name of names) {
|
|
1103
|
+
result = this._eventBus.fire('commandStack.' + name, event);
|
|
1104
|
+
if (event.cancelBubble) {
|
|
1105
|
+
break;
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
return result;
|
|
1109
|
+
};
|
|
1110
|
+
CommandStack.prototype._createId = function () {
|
|
1111
|
+
return this._uid++;
|
|
1112
|
+
};
|
|
1113
|
+
CommandStack.prototype._atomicDo = function (fn) {
|
|
1114
|
+
const execution = this._currentExecution;
|
|
1115
|
+
execution.atomic = true;
|
|
1116
|
+
try {
|
|
1117
|
+
fn();
|
|
1118
|
+
} finally {
|
|
1119
|
+
execution.atomic = false;
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
CommandStack.prototype._internalExecute = function (action, redo) {
|
|
1123
|
+
const command = action.command,
|
|
1124
|
+
context = action.context;
|
|
1125
|
+
const handler = this._getHandler(command);
|
|
1126
|
+
if (!handler) {
|
|
1127
|
+
throw new Error('no command handler registered for <' + command + '>');
|
|
1128
|
+
}
|
|
1129
|
+
this._pushAction(action);
|
|
1130
|
+
if (!redo) {
|
|
1131
|
+
this._fire(command, 'preExecute', action);
|
|
1132
|
+
if (handler.preExecute) {
|
|
1133
|
+
handler.preExecute(context);
|
|
1134
|
+
}
|
|
1135
|
+
this._fire(command, 'preExecuted', action);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
// guard against illegal nested command stack invocations
|
|
1139
|
+
this._atomicDo(() => {
|
|
1140
|
+
this._fire(command, 'execute', action);
|
|
1141
|
+
if (handler.execute) {
|
|
1142
|
+
// actual execute + mark return results as dirty
|
|
1143
|
+
this._markDirty(handler.execute(context));
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// log to stack
|
|
1147
|
+
this._executedAction(action, redo);
|
|
1148
|
+
this._fire(command, 'executed', action);
|
|
1149
|
+
});
|
|
1150
|
+
if (!redo) {
|
|
1151
|
+
this._fire(command, 'postExecute', action);
|
|
1152
|
+
if (handler.postExecute) {
|
|
1153
|
+
handler.postExecute(context);
|
|
1154
|
+
}
|
|
1155
|
+
this._fire(command, 'postExecuted', action);
|
|
1156
|
+
}
|
|
1157
|
+
this._popAction();
|
|
1158
|
+
};
|
|
1159
|
+
CommandStack.prototype._pushAction = function (action) {
|
|
1160
|
+
const execution = this._currentExecution,
|
|
1161
|
+
actions = execution.actions;
|
|
1162
|
+
const baseAction = actions[0];
|
|
1163
|
+
if (execution.atomic) {
|
|
1164
|
+
throw new Error('illegal invocation in <execute> or <revert> phase (action: ' + action.command + ')');
|
|
1165
|
+
}
|
|
1166
|
+
if (!action.id) {
|
|
1167
|
+
action.id = baseAction && baseAction.id || this._createId();
|
|
1168
|
+
}
|
|
1169
|
+
actions.push(action);
|
|
1170
|
+
};
|
|
1171
|
+
CommandStack.prototype._popAction = function () {
|
|
1172
|
+
const execution = this._currentExecution,
|
|
1173
|
+
trigger = execution.trigger,
|
|
1174
|
+
actions = execution.actions,
|
|
1175
|
+
dirty = execution.dirty;
|
|
1176
|
+
actions.pop();
|
|
1177
|
+
if (!actions.length) {
|
|
1178
|
+
this._eventBus.fire('elements.changed', {
|
|
1179
|
+
elements: minDash.uniqueBy('id', dirty.reverse())
|
|
1180
|
+
});
|
|
1181
|
+
dirty.length = 0;
|
|
1182
|
+
this._fire('changed', {
|
|
1183
|
+
trigger: trigger
|
|
1184
|
+
});
|
|
1185
|
+
execution.trigger = null;
|
|
1186
|
+
}
|
|
1187
|
+
};
|
|
1188
|
+
CommandStack.prototype._markDirty = function (elements) {
|
|
1189
|
+
const execution = this._currentExecution;
|
|
1190
|
+
if (!elements) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
elements = minDash.isArray(elements) ? elements : [elements];
|
|
1194
|
+
execution.dirty = execution.dirty.concat(elements);
|
|
1195
|
+
};
|
|
1196
|
+
CommandStack.prototype._executedAction = function (action, redo) {
|
|
1197
|
+
const stackIdx = ++this._stackIdx;
|
|
1198
|
+
if (!redo) {
|
|
1199
|
+
this._stack.splice(stackIdx, this._stack.length, action);
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
CommandStack.prototype._revertedAction = function (action) {
|
|
1203
|
+
this._stackIdx--;
|
|
1204
|
+
};
|
|
1205
|
+
CommandStack.prototype._getHandler = function (command) {
|
|
1206
|
+
return this._handlerMap[command];
|
|
1207
|
+
};
|
|
1208
|
+
CommandStack.prototype._setHandler = function (command, handler) {
|
|
1209
|
+
if (!command || !handler) {
|
|
1210
|
+
throw new Error('command and handler required');
|
|
1211
|
+
}
|
|
1212
|
+
if (this._handlerMap[command]) {
|
|
1213
|
+
throw new Error('overriding handler for command <' + command + '>');
|
|
1214
|
+
}
|
|
1215
|
+
this._handlerMap[command] = handler;
|
|
1216
|
+
};
|
|
1217
|
+
|
|
1218
|
+
/**
|
|
1219
|
+
* @type { import('didi').ModuleDeclaration }
|
|
1220
|
+
*/
|
|
1221
|
+
var commandModule = {
|
|
1222
|
+
commandStack: ['type', CommandStack]
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
class UpdateFieldValidationHandler {
|
|
1226
|
+
constructor(form, validator) {
|
|
1227
|
+
this._form = form;
|
|
1228
|
+
this._validator = validator;
|
|
1229
|
+
}
|
|
1230
|
+
execute(context) {
|
|
1231
|
+
const {
|
|
1232
|
+
field,
|
|
1233
|
+
value
|
|
1234
|
+
} = context;
|
|
1235
|
+
const {
|
|
1236
|
+
errors
|
|
1237
|
+
} = this._form._getState();
|
|
1238
|
+
context.oldErrors = clone(errors);
|
|
1239
|
+
const fieldErrors = this._validator.validateField(field, value);
|
|
1240
|
+
const updatedErrors = minDash.set(errors, [field.id], fieldErrors.length ? fieldErrors : undefined);
|
|
1241
|
+
this._form._setState({
|
|
1242
|
+
errors: updatedErrors
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
revert(context) {
|
|
1246
|
+
this._form._setState({
|
|
1247
|
+
errors: context.oldErrors
|
|
1248
|
+
});
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
UpdateFieldValidationHandler.$inject = ['form', 'validator'];
|
|
1252
|
+
|
|
1253
|
+
class ViewerCommands {
|
|
1254
|
+
constructor(commandStack, eventBus) {
|
|
1255
|
+
this._commandStack = commandStack;
|
|
1256
|
+
eventBus.on('form.init', () => {
|
|
1257
|
+
this.registerHandlers();
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
registerHandlers() {
|
|
1261
|
+
Object.entries(this.getHandlers()).forEach(([id, handler]) => {
|
|
1262
|
+
this._commandStack.registerHandler(id, handler);
|
|
1263
|
+
});
|
|
1264
|
+
}
|
|
1265
|
+
getHandlers() {
|
|
1266
|
+
return {
|
|
1267
|
+
'formField.validation.update': UpdateFieldValidationHandler
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
updateFieldValidation(field, value) {
|
|
1271
|
+
const context = {
|
|
1272
|
+
field,
|
|
1273
|
+
value
|
|
1274
|
+
};
|
|
1275
|
+
this._commandStack.execute('formField.validation.update', context);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
ViewerCommands.$inject = ['commandStack', 'eventBus'];
|
|
1279
|
+
|
|
1280
|
+
var ViewerCommandsModule = {
|
|
1281
|
+
__depends__: [commandModule],
|
|
1282
|
+
__init__: ['viewerCommands'],
|
|
1283
|
+
viewerCommands: ['type', ViewerCommands]
|
|
1284
|
+
};
|
|
1285
|
+
|
|
494
1286
|
var FN_REF = '__fn';
|
|
495
1287
|
var DEFAULT_PRIORITY = 1000;
|
|
496
1288
|
var slice = Array.prototype.slice;
|
|
@@ -1094,8 +1886,8 @@ Validator.$inject = ['expressionLanguage', 'conditionChecker', 'form'];
|
|
|
1094
1886
|
|
|
1095
1887
|
// helpers //////////
|
|
1096
1888
|
|
|
1097
|
-
/**
|
|
1098
|
-
* Helper function to evaluate optional FEEL validation values.
|
|
1889
|
+
/**
|
|
1890
|
+
* Helper function to evaluate optional FEEL validation values.
|
|
1099
1891
|
*/
|
|
1100
1892
|
function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form) {
|
|
1101
1893
|
const evaluatedValidate = {
|
|
@@ -1128,72 +1920,415 @@ function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form
|
|
|
1128
1920
|
return evaluatedValidate;
|
|
1129
1921
|
}
|
|
1130
1922
|
|
|
1131
|
-
class
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1923
|
+
class Importer {
|
|
1924
|
+
/**
|
|
1925
|
+
* @constructor
|
|
1926
|
+
* @param { import('./FormFieldRegistry').default } formFieldRegistry
|
|
1927
|
+
* @param { import('./PathRegistry').default } pathRegistry
|
|
1928
|
+
* @param { import('./FieldFactory').default } fieldFactory
|
|
1929
|
+
* @param { import('./FormLayouter').default } formLayouter
|
|
1930
|
+
*/
|
|
1931
|
+
constructor(formFieldRegistry, pathRegistry, fieldFactory, formLayouter) {
|
|
1932
|
+
this._formFieldRegistry = formFieldRegistry;
|
|
1933
|
+
this._pathRegistry = pathRegistry;
|
|
1934
|
+
this._fieldFactory = fieldFactory;
|
|
1935
|
+
this._formLayouter = formLayouter;
|
|
1138
1936
|
}
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1937
|
+
|
|
1938
|
+
/**
|
|
1939
|
+
* Import schema creating rows, fields, attaching additional
|
|
1940
|
+
* information to each field and adding fields to the
|
|
1941
|
+
* field registry.
|
|
1942
|
+
*
|
|
1943
|
+
* Additional information attached:
|
|
1944
|
+
*
|
|
1945
|
+
* * `id` (unless present)
|
|
1946
|
+
* * `_parent`
|
|
1947
|
+
* * `_path`
|
|
1948
|
+
*
|
|
1949
|
+
* @param {any} schema
|
|
1950
|
+
*
|
|
1951
|
+
* @typedef {{ warnings: Error[], schema: any }} ImportResult
|
|
1952
|
+
* @returns {ImportResult}
|
|
1953
|
+
*/
|
|
1954
|
+
importSchema(schema) {
|
|
1955
|
+
// TODO: Add warnings
|
|
1956
|
+
const warnings = [];
|
|
1957
|
+
try {
|
|
1958
|
+
this._cleanup();
|
|
1959
|
+
const importedSchema = this.importFormField(clone(schema));
|
|
1960
|
+
this._formLayouter.calculateLayout(clone(importedSchema));
|
|
1961
|
+
return {
|
|
1962
|
+
schema: importedSchema,
|
|
1963
|
+
warnings
|
|
1964
|
+
};
|
|
1965
|
+
} catch (err) {
|
|
1966
|
+
this._cleanup();
|
|
1967
|
+
err.warnings = warnings;
|
|
1968
|
+
throw err;
|
|
1145
1969
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1970
|
+
}
|
|
1971
|
+
_cleanup() {
|
|
1972
|
+
this._formLayouter.clear();
|
|
1973
|
+
this._formFieldRegistry.clear();
|
|
1974
|
+
this._pathRegistry.clear();
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
/**
|
|
1978
|
+
* @param {{[x: string]: any}} fieldAttrs
|
|
1979
|
+
* @param {String} [parentId]
|
|
1980
|
+
* @param {number} [index]
|
|
1981
|
+
*
|
|
1982
|
+
* @return {any} field
|
|
1983
|
+
*/
|
|
1984
|
+
importFormField(fieldAttrs, parentId, index) {
|
|
1985
|
+
const {
|
|
1986
|
+
components
|
|
1987
|
+
} = fieldAttrs;
|
|
1988
|
+
let parent, path;
|
|
1989
|
+
if (parentId) {
|
|
1990
|
+
parent = this._formFieldRegistry.get(parentId);
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
// set form field path
|
|
1994
|
+
path = parent ? [...parent._path, 'components', index] : [];
|
|
1995
|
+
const field = this._fieldFactory.create({
|
|
1996
|
+
...fieldAttrs,
|
|
1997
|
+
_path: path,
|
|
1998
|
+
_parent: parentId
|
|
1999
|
+
}, false);
|
|
2000
|
+
this._formFieldRegistry.add(field);
|
|
2001
|
+
if (components) {
|
|
2002
|
+
field.components = this.importFormFields(components, field.id);
|
|
2003
|
+
}
|
|
2004
|
+
return field;
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
/**
|
|
2008
|
+
* @param {Array<any>} components
|
|
2009
|
+
* @param {string} parentId
|
|
2010
|
+
*
|
|
2011
|
+
* @return {Array<any>} imported components
|
|
2012
|
+
*/
|
|
2013
|
+
importFormFields(components, parentId) {
|
|
2014
|
+
return components.map((component, index) => {
|
|
2015
|
+
return this.importFormField(component, parentId, index);
|
|
1148
2016
|
});
|
|
1149
|
-
this._formFields[id] = formField;
|
|
1150
2017
|
}
|
|
1151
|
-
|
|
2018
|
+
}
|
|
2019
|
+
Importer.$inject = ['formFieldRegistry', 'pathRegistry', 'fieldFactory', 'formLayouter'];
|
|
2020
|
+
|
|
2021
|
+
class FieldFactory {
|
|
2022
|
+
/**
|
|
2023
|
+
* @constructor
|
|
2024
|
+
*
|
|
2025
|
+
* @param formFieldRegistry
|
|
2026
|
+
* @param formFields
|
|
2027
|
+
*/
|
|
2028
|
+
constructor(formFieldRegistry, pathRegistry, formFields) {
|
|
2029
|
+
this._formFieldRegistry = formFieldRegistry;
|
|
2030
|
+
this._pathRegistry = pathRegistry;
|
|
2031
|
+
this._formFields = formFields;
|
|
2032
|
+
}
|
|
2033
|
+
create(attrs, applyDefaults = true) {
|
|
1152
2034
|
const {
|
|
1153
|
-
id
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
2035
|
+
id,
|
|
2036
|
+
type,
|
|
2037
|
+
key,
|
|
2038
|
+
path,
|
|
2039
|
+
_parent
|
|
2040
|
+
} = attrs;
|
|
2041
|
+
const fieldDefinition = this._formFields.get(type);
|
|
2042
|
+
if (!fieldDefinition) {
|
|
2043
|
+
throw new Error(`form field of type <${type}> not supported`);
|
|
1157
2044
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
2045
|
+
const {
|
|
2046
|
+
config
|
|
2047
|
+
} = fieldDefinition;
|
|
2048
|
+
if (!config) {
|
|
2049
|
+
throw new Error(`form field of type <${type}> has no config`);
|
|
2050
|
+
}
|
|
2051
|
+
if (id && this._formFieldRegistry._ids.assigned(id)) {
|
|
2052
|
+
throw new Error(`form field with id <${id}> already exists`);
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
// ensure that we can claim the path
|
|
2056
|
+
|
|
2057
|
+
const parent = _parent && this._formFieldRegistry.get(_parent);
|
|
2058
|
+
const parentPath = parent && this._pathRegistry.getValuePath(parent) || [];
|
|
2059
|
+
if (config.keyed && key && !this._pathRegistry.canClaimPath([...parentPath, ...key.split('.')], true)) {
|
|
2060
|
+
throw new Error(`binding path '${[...parentPath, key].join('.')}' is already claimed`);
|
|
2061
|
+
}
|
|
2062
|
+
if (config.pathed && path && !this._pathRegistry.canClaimPath([...parentPath, ...path.split('.')], false)) {
|
|
2063
|
+
throw new Error(`binding path '${[...parentPath, ...path.split('.')].join('.')}' is already claimed`);
|
|
2064
|
+
}
|
|
2065
|
+
const labelAttrs = applyDefaults && config.label ? {
|
|
2066
|
+
label: config.label
|
|
2067
|
+
} : {};
|
|
2068
|
+
const field = config.create({
|
|
2069
|
+
...labelAttrs,
|
|
2070
|
+
...attrs
|
|
1160
2071
|
});
|
|
1161
|
-
|
|
2072
|
+
this._ensureId(field);
|
|
2073
|
+
if (config.keyed) {
|
|
2074
|
+
this._ensureKey(field);
|
|
2075
|
+
}
|
|
2076
|
+
if (config.pathed && path) {
|
|
2077
|
+
this._pathRegistry.claimPath(this._pathRegistry.getValuePath(field), false);
|
|
2078
|
+
}
|
|
2079
|
+
return field;
|
|
1162
2080
|
}
|
|
1163
|
-
|
|
1164
|
-
|
|
2081
|
+
_ensureId(field) {
|
|
2082
|
+
if (field.id) {
|
|
2083
|
+
this._formFieldRegistry._ids.claim(field.id, field);
|
|
2084
|
+
return;
|
|
2085
|
+
}
|
|
2086
|
+
let prefix = 'Field';
|
|
2087
|
+
if (field.type === 'default') {
|
|
2088
|
+
prefix = 'Form';
|
|
2089
|
+
}
|
|
2090
|
+
field.id = this._formFieldRegistry._ids.nextPrefixed(`${prefix}_`, field);
|
|
2091
|
+
}
|
|
2092
|
+
_ensureKey(field) {
|
|
2093
|
+
if (!field.key) {
|
|
2094
|
+
let random;
|
|
2095
|
+
const parent = this._formFieldRegistry.get(field._parent);
|
|
2096
|
+
|
|
2097
|
+
// ensure key uniqueness at level
|
|
2098
|
+
do {
|
|
2099
|
+
random = Math.random().toString(36).substring(7);
|
|
2100
|
+
} while (parent && parent.components.some(child => child.key === random));
|
|
2101
|
+
field.key = `${field.type}_${random}`;
|
|
2102
|
+
}
|
|
2103
|
+
this._pathRegistry.claimPath(this._pathRegistry.getValuePath(field), true);
|
|
1165
2104
|
}
|
|
1166
|
-
|
|
1167
|
-
|
|
2105
|
+
}
|
|
2106
|
+
FieldFactory.$inject = ['formFieldRegistry', 'pathRegistry', 'formFields'];
|
|
2107
|
+
|
|
2108
|
+
/**
|
|
2109
|
+
* The PathRegistry class manages a hierarchical structure of paths associated with form fields.
|
|
2110
|
+
* It enables claiming, unclaiming, and validating paths within this structure.
|
|
2111
|
+
*
|
|
2112
|
+
* Example Tree Structure:
|
|
2113
|
+
*
|
|
2114
|
+
* [
|
|
2115
|
+
* {
|
|
2116
|
+
* segment: 'root',
|
|
2117
|
+
* claimCount: 1,
|
|
2118
|
+
* children: [
|
|
2119
|
+
* {
|
|
2120
|
+
* segment: 'child1',
|
|
2121
|
+
* claimCount: 2,
|
|
2122
|
+
* children: null // A leaf node (closed path)
|
|
2123
|
+
* },
|
|
2124
|
+
* {
|
|
2125
|
+
* segment: 'child2',
|
|
2126
|
+
* claimCount: 1,
|
|
2127
|
+
* children: [
|
|
2128
|
+
* {
|
|
2129
|
+
* segment: 'subChild1',
|
|
2130
|
+
* claimCount: 1,
|
|
2131
|
+
* children: [] // An open node (open path)
|
|
2132
|
+
* }
|
|
2133
|
+
* ]
|
|
2134
|
+
* }
|
|
2135
|
+
* ]
|
|
2136
|
+
* }
|
|
2137
|
+
* ]
|
|
2138
|
+
*/
|
|
2139
|
+
class PathRegistry {
|
|
2140
|
+
constructor(formFieldRegistry, formFields) {
|
|
2141
|
+
this._formFieldRegistry = formFieldRegistry;
|
|
2142
|
+
this._formFields = formFields;
|
|
2143
|
+
this._dataPaths = [];
|
|
1168
2144
|
}
|
|
1169
|
-
|
|
1170
|
-
|
|
2145
|
+
canClaimPath(path, closed = false) {
|
|
2146
|
+
let node = {
|
|
2147
|
+
children: this._dataPaths
|
|
2148
|
+
};
|
|
2149
|
+
for (const segment of path) {
|
|
2150
|
+
node = _getNextSegment(node, segment);
|
|
2151
|
+
|
|
2152
|
+
// if no node at that path, we can claim it no matter what
|
|
2153
|
+
if (!node) {
|
|
2154
|
+
return true;
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2157
|
+
// if we reach a leaf node, definitely not claimable
|
|
2158
|
+
if (node.children === null) {
|
|
2159
|
+
return false;
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
// if after all segments we reach a node with children, we can claim it only openly
|
|
2164
|
+
return !closed;
|
|
2165
|
+
}
|
|
2166
|
+
claimPath(path, closed = false) {
|
|
2167
|
+
if (!this.canClaimPath(path, closed)) {
|
|
2168
|
+
throw new Error(`cannot claim path '${path.join('.')}'`);
|
|
2169
|
+
}
|
|
2170
|
+
let node = {
|
|
2171
|
+
children: this._dataPaths
|
|
2172
|
+
};
|
|
2173
|
+
for (const segment of path) {
|
|
2174
|
+
let child = _getNextSegment(node, segment);
|
|
2175
|
+
if (!child) {
|
|
2176
|
+
child = {
|
|
2177
|
+
segment,
|
|
2178
|
+
claimCount: 1,
|
|
2179
|
+
children: []
|
|
2180
|
+
};
|
|
2181
|
+
node.children.push(child);
|
|
2182
|
+
} else {
|
|
2183
|
+
child.claimCount++;
|
|
2184
|
+
}
|
|
2185
|
+
node = child;
|
|
2186
|
+
}
|
|
2187
|
+
if (closed) {
|
|
2188
|
+
node.children = null;
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
unclaimPath(path) {
|
|
2192
|
+
// verification Pass
|
|
2193
|
+
let node = {
|
|
2194
|
+
children: this._dataPaths
|
|
2195
|
+
};
|
|
2196
|
+
for (const segment of path) {
|
|
2197
|
+
const child = _getNextSegment(node, segment);
|
|
2198
|
+
if (!child) {
|
|
2199
|
+
throw new Error(`no open path found for '${path.join('.')}'`);
|
|
2200
|
+
}
|
|
2201
|
+
node = child;
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2204
|
+
// mutation Pass
|
|
2205
|
+
node = {
|
|
2206
|
+
children: this._dataPaths
|
|
2207
|
+
};
|
|
2208
|
+
for (const segment of path) {
|
|
2209
|
+
const child = _getNextSegment(node, segment);
|
|
2210
|
+
child.claimCount--;
|
|
2211
|
+
if (child.claimCount === 0) {
|
|
2212
|
+
node.children.splice(node.children.indexOf(child), 1);
|
|
2213
|
+
break; // Abort early if claimCount reaches zero
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
node = child;
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
/**
|
|
2221
|
+
* Applies a function (fn) recursively on a given field and its children.
|
|
2222
|
+
*
|
|
2223
|
+
* - `field`: Starting field object.
|
|
2224
|
+
* - `fn`: Function to apply.
|
|
2225
|
+
* - `context`: Optional object for passing data between calls.
|
|
2226
|
+
*
|
|
2227
|
+
* Stops early if `fn` returns `false`. Useful for traversing the form field tree.
|
|
2228
|
+
*
|
|
2229
|
+
* @returns {boolean} Success status based on function execution.
|
|
2230
|
+
*/
|
|
2231
|
+
executeRecursivelyOnFields(field, fn, context = {}) {
|
|
2232
|
+
let result = true;
|
|
2233
|
+
const formFieldConfig = this._formFields.get(field.type).config;
|
|
2234
|
+
if (formFieldConfig.keyed) {
|
|
2235
|
+
const callResult = fn({
|
|
2236
|
+
field,
|
|
2237
|
+
isClosed: true,
|
|
2238
|
+
context
|
|
2239
|
+
});
|
|
2240
|
+
return result && callResult;
|
|
2241
|
+
} else if (formFieldConfig.pathed) {
|
|
2242
|
+
const callResult = fn({
|
|
2243
|
+
field,
|
|
2244
|
+
isClosed: false,
|
|
2245
|
+
context
|
|
2246
|
+
});
|
|
2247
|
+
result = result && callResult;
|
|
2248
|
+
}
|
|
2249
|
+
if (field.components) {
|
|
2250
|
+
for (const child of field.components) {
|
|
2251
|
+
const callResult = this.executeRecursivelyOnFields(child, fn, clone(context));
|
|
2252
|
+
result = result && callResult;
|
|
2253
|
+
|
|
2254
|
+
// only stop executing if false is specifically returned, not if undefined
|
|
2255
|
+
if (result === false) {
|
|
2256
|
+
return result;
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
return result;
|
|
2261
|
+
}
|
|
2262
|
+
|
|
2263
|
+
/**
|
|
2264
|
+
* Generates an array representing the binding path to an underlying data object for a form field.
|
|
2265
|
+
*
|
|
2266
|
+
* @param {Object} field - The field object with properties: `key`, `path`, `id`, and optionally `_parent`.
|
|
2267
|
+
* @param {Object} [options={}] - Configuration options.
|
|
2268
|
+
* @param {Object} [options.replacements={}] - A map of field IDs to alternative path arrays.
|
|
2269
|
+
* @param {Object} [options.cutoffNode] - The ID of the parent field at which to stop generating the path.
|
|
2270
|
+
*
|
|
2271
|
+
* @returns {(Array<string>|undefined)} An array of strings representing the binding path, or undefined if not determinable.
|
|
2272
|
+
*/
|
|
2273
|
+
getValuePath(field, options = {}) {
|
|
2274
|
+
const {
|
|
2275
|
+
replacements = {},
|
|
2276
|
+
cutoffNode = null
|
|
2277
|
+
} = options;
|
|
2278
|
+
let localValuePath = [];
|
|
2279
|
+
const hasReplacement = Object.prototype.hasOwnProperty.call(replacements, field.id);
|
|
2280
|
+
const formFieldConfig = this._formFields.get(field.type).config;
|
|
2281
|
+
if (hasReplacement) {
|
|
2282
|
+
const replacement = replacements[field.id];
|
|
2283
|
+
if (replacement === null || replacement === undefined || replacement === '') {
|
|
2284
|
+
localValuePath = [];
|
|
2285
|
+
} else if (typeof replacement === 'string') {
|
|
2286
|
+
localValuePath = replacement.split('.');
|
|
2287
|
+
} else if (Array.isArray(replacement)) {
|
|
2288
|
+
localValuePath = replacement;
|
|
2289
|
+
} else {
|
|
2290
|
+
throw new Error(`replacements for field ${field.id} must be a string, array or null/undefined`);
|
|
2291
|
+
}
|
|
2292
|
+
} else if (formFieldConfig.keyed) {
|
|
2293
|
+
localValuePath = field.key.split('.');
|
|
2294
|
+
} else if (formFieldConfig.pathed && field.path) {
|
|
2295
|
+
localValuePath = field.path.split('.');
|
|
2296
|
+
}
|
|
2297
|
+
if (field._parent && field._parent !== cutoffNode) {
|
|
2298
|
+
const parent = this._formFieldRegistry.get(field._parent);
|
|
2299
|
+
return [...(this.getValuePath(parent, options) || []), ...localValuePath];
|
|
2300
|
+
}
|
|
2301
|
+
return localValuePath;
|
|
1171
2302
|
}
|
|
1172
2303
|
clear() {
|
|
1173
|
-
this.
|
|
1174
|
-
this._ids.clear();
|
|
1175
|
-
this._keys.clear();
|
|
2304
|
+
this._dataPaths = [];
|
|
1176
2305
|
}
|
|
1177
2306
|
}
|
|
1178
|
-
|
|
2307
|
+
const _getNextSegment = (node, segment) => {
|
|
2308
|
+
if (minDash.isArray(node.children)) {
|
|
2309
|
+
return node.children.find(node => node.segment === segment) || null;
|
|
2310
|
+
}
|
|
2311
|
+
return null;
|
|
2312
|
+
};
|
|
2313
|
+
PathRegistry.$inject = ['formFieldRegistry', 'formFields'];
|
|
1179
2314
|
|
|
1180
|
-
/**
|
|
1181
|
-
* @typedef { { id: String, components: Array<String> } } FormRow
|
|
1182
|
-
* @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
|
|
2315
|
+
/**
|
|
2316
|
+
* @typedef { { id: String, components: Array<String> } } FormRow
|
|
2317
|
+
* @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
|
|
1183
2318
|
*/
|
|
1184
2319
|
|
|
1185
|
-
/**
|
|
1186
|
-
* Maintains the Form layout in a given structure, for example
|
|
1187
|
-
*
|
|
1188
|
-
* [
|
|
1189
|
-
* {
|
|
1190
|
-
* formFieldId: 'FormField_1',
|
|
1191
|
-
* rows: [
|
|
1192
|
-
* { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
|
|
1193
|
-
* ]
|
|
1194
|
-
* }
|
|
1195
|
-
* ]
|
|
1196
|
-
*
|
|
2320
|
+
/**
|
|
2321
|
+
* Maintains the Form layout in a given structure, for example
|
|
2322
|
+
*
|
|
2323
|
+
* [
|
|
2324
|
+
* {
|
|
2325
|
+
* formFieldId: 'FormField_1',
|
|
2326
|
+
* rows: [
|
|
2327
|
+
* { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
|
|
2328
|
+
* ]
|
|
2329
|
+
* }
|
|
2330
|
+
* ]
|
|
2331
|
+
*
|
|
1197
2332
|
*/
|
|
1198
2333
|
class FormLayouter {
|
|
1199
2334
|
constructor(eventBus) {
|
|
@@ -1203,8 +2338,8 @@ class FormLayouter {
|
|
|
1203
2338
|
this._eventBus = eventBus;
|
|
1204
2339
|
}
|
|
1205
2340
|
|
|
1206
|
-
/**
|
|
1207
|
-
* @param {FormRow} row
|
|
2341
|
+
/**
|
|
2342
|
+
* @param {FormRow} row
|
|
1208
2343
|
*/
|
|
1209
2344
|
addRow(formFieldId, row) {
|
|
1210
2345
|
let rowsPerComponent = this._rows.find(r => r.formFieldId === formFieldId);
|
|
@@ -1218,18 +2353,18 @@ class FormLayouter {
|
|
|
1218
2353
|
rowsPerComponent.rows.push(row);
|
|
1219
2354
|
}
|
|
1220
2355
|
|
|
1221
|
-
/**
|
|
1222
|
-
* @param {String} id
|
|
1223
|
-
* @returns {FormRow}
|
|
2356
|
+
/**
|
|
2357
|
+
* @param {String} id
|
|
2358
|
+
* @returns {FormRow}
|
|
1224
2359
|
*/
|
|
1225
2360
|
getRow(id) {
|
|
1226
2361
|
const rows = allRows(this._rows);
|
|
1227
2362
|
return rows.find(r => r.id === id);
|
|
1228
2363
|
}
|
|
1229
2364
|
|
|
1230
|
-
/**
|
|
1231
|
-
* @param {any} formField
|
|
1232
|
-
* @returns {FormRow}
|
|
2365
|
+
/**
|
|
2366
|
+
* @param {any} formField
|
|
2367
|
+
* @returns {FormRow}
|
|
1233
2368
|
*/
|
|
1234
2369
|
getRowForField(formField) {
|
|
1235
2370
|
return allRows(this._rows).find(r => {
|
|
@@ -1240,9 +2375,9 @@ class FormLayouter {
|
|
|
1240
2375
|
});
|
|
1241
2376
|
}
|
|
1242
2377
|
|
|
1243
|
-
/**
|
|
1244
|
-
* @param {String} formFieldId
|
|
1245
|
-
* @returns { Array<FormRow> }
|
|
2378
|
+
/**
|
|
2379
|
+
* @param {String} formFieldId
|
|
2380
|
+
* @returns { Array<FormRow> }
|
|
1246
2381
|
*/
|
|
1247
2382
|
getRows(formFieldId) {
|
|
1248
2383
|
const rowsForField = this._rows.find(r => formFieldId === r.formFieldId);
|
|
@@ -1252,22 +2387,22 @@ class FormLayouter {
|
|
|
1252
2387
|
return rowsForField.rows;
|
|
1253
2388
|
}
|
|
1254
2389
|
|
|
1255
|
-
/**
|
|
1256
|
-
* @returns {string}
|
|
2390
|
+
/**
|
|
2391
|
+
* @returns {string}
|
|
1257
2392
|
*/
|
|
1258
2393
|
nextRowId() {
|
|
1259
2394
|
return this._ids.nextPrefixed('Row_');
|
|
1260
2395
|
}
|
|
1261
2396
|
|
|
1262
|
-
/**
|
|
1263
|
-
* @param {any} formField
|
|
2397
|
+
/**
|
|
2398
|
+
* @param {any} formField
|
|
1264
2399
|
*/
|
|
1265
2400
|
calculateLayout(formField) {
|
|
1266
2401
|
const {
|
|
1267
2402
|
type,
|
|
1268
2403
|
components
|
|
1269
2404
|
} = formField;
|
|
1270
|
-
if (type !== 'default' || !components) {
|
|
2405
|
+
if (type !== 'default' && type !== 'group' || !components) {
|
|
1271
2406
|
return;
|
|
1272
2407
|
}
|
|
1273
2408
|
|
|
@@ -1289,363 +2424,85 @@ class FormLayouter {
|
|
|
1289
2424
|
rows: this._rows
|
|
1290
2425
|
});
|
|
1291
2426
|
}
|
|
1292
|
-
clear() {
|
|
1293
|
-
this._rows = [];
|
|
1294
|
-
this._ids.clear();
|
|
1295
|
-
|
|
1296
|
-
// fire event to notify interested parties
|
|
1297
|
-
this._eventBus.fire('form.layoutCleared');
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
FormLayouter.$inject = ['eventBus'];
|
|
1301
|
-
|
|
1302
|
-
// helpers //////
|
|
1303
|
-
|
|
1304
|
-
function groupByRow(components, ids) {
|
|
1305
|
-
return minDash.groupBy(components, c => {
|
|
1306
|
-
// mitigate missing row by creating new (handle legacy)
|
|
1307
|
-
const {
|
|
1308
|
-
layout
|
|
1309
|
-
} = c;
|
|
1310
|
-
if (!layout || !layout.row) {
|
|
1311
|
-
return ids.nextPrefixed('Row_');
|
|
1312
|
-
}
|
|
1313
|
-
return layout.row;
|
|
1314
|
-
});
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
|
-
/**
|
|
1318
|
-
* @param {Array<FormRows>} formRows
|
|
1319
|
-
* @returns {Array<FormRow>}
|
|
1320
|
-
*/
|
|
1321
|
-
function allRows(formRows) {
|
|
1322
|
-
return minDash.flatten(formRows.map(c => c.rows));
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
// config ///////////////////
|
|
1326
|
-
|
|
1327
|
-
const MINUTES_IN_DAY = 60 * 24;
|
|
1328
|
-
const DATETIME_SUBTYPES = {
|
|
1329
|
-
DATE: 'date',
|
|
1330
|
-
TIME: 'time',
|
|
1331
|
-
DATETIME: 'datetime'
|
|
1332
|
-
};
|
|
1333
|
-
const TIME_SERIALISING_FORMATS = {
|
|
1334
|
-
UTC_OFFSET: 'utc_offset',
|
|
1335
|
-
UTC_NORMALIZED: 'utc_normalized',
|
|
1336
|
-
NO_TIMEZONE: 'no_timezone'
|
|
1337
|
-
};
|
|
1338
|
-
const DATETIME_SUBTYPES_LABELS = {
|
|
1339
|
-
[DATETIME_SUBTYPES.DATE]: 'Date',
|
|
1340
|
-
[DATETIME_SUBTYPES.TIME]: 'Time',
|
|
1341
|
-
[DATETIME_SUBTYPES.DATETIME]: 'Date & Time'
|
|
1342
|
-
};
|
|
1343
|
-
const TIME_SERIALISINGFORMAT_LABELS = {
|
|
1344
|
-
[TIME_SERIALISING_FORMATS.UTC_OFFSET]: 'UTC offset',
|
|
1345
|
-
[TIME_SERIALISING_FORMATS.UTC_NORMALIZED]: 'UTC normalized',
|
|
1346
|
-
[TIME_SERIALISING_FORMATS.NO_TIMEZONE]: 'No timezone'
|
|
1347
|
-
};
|
|
1348
|
-
const DATETIME_SUBTYPE_PATH = ['subtype'];
|
|
1349
|
-
const DATE_LABEL_PATH = ['dateLabel'];
|
|
1350
|
-
const DATE_DISALLOW_PAST_PATH = ['disallowPassedDates'];
|
|
1351
|
-
const TIME_LABEL_PATH = ['timeLabel'];
|
|
1352
|
-
const TIME_USE24H_PATH = ['use24h'];
|
|
1353
|
-
const TIME_INTERVAL_PATH = ['timeInterval'];
|
|
1354
|
-
const TIME_SERIALISING_FORMAT_PATH = ['timeSerializingFormat'];
|
|
1355
|
-
|
|
1356
|
-
// config ///////////////////
|
|
1357
|
-
|
|
1358
|
-
const VALUES_SOURCES = {
|
|
1359
|
-
STATIC: 'static',
|
|
1360
|
-
INPUT: 'input',
|
|
1361
|
-
EXPRESSION: 'expression'
|
|
1362
|
-
};
|
|
1363
|
-
const VALUES_SOURCE_DEFAULT = VALUES_SOURCES.STATIC;
|
|
1364
|
-
const VALUES_SOURCES_LABELS = {
|
|
1365
|
-
[VALUES_SOURCES.STATIC]: 'Static',
|
|
1366
|
-
[VALUES_SOURCES.INPUT]: 'Input data',
|
|
1367
|
-
[VALUES_SOURCES.EXPRESSION]: 'Expression'
|
|
1368
|
-
};
|
|
1369
|
-
const VALUES_SOURCES_PATHS = {
|
|
1370
|
-
[VALUES_SOURCES.STATIC]: ['values'],
|
|
1371
|
-
[VALUES_SOURCES.INPUT]: ['valuesKey'],
|
|
1372
|
-
[VALUES_SOURCES.EXPRESSION]: ['valuesExpression']
|
|
1373
|
-
};
|
|
1374
|
-
const VALUES_SOURCES_DEFAULTS = {
|
|
1375
|
-
[VALUES_SOURCES.STATIC]: [{
|
|
1376
|
-
label: 'Value',
|
|
1377
|
-
value: 'value'
|
|
1378
|
-
}],
|
|
1379
|
-
[VALUES_SOURCES.INPUT]: '',
|
|
1380
|
-
[VALUES_SOURCES.EXPRESSION]: '='
|
|
1381
|
-
};
|
|
1382
|
-
|
|
1383
|
-
// helpers ///////////////////
|
|
1384
|
-
|
|
1385
|
-
function getValuesSource(field) {
|
|
1386
|
-
for (const source of Object.values(VALUES_SOURCES)) {
|
|
1387
|
-
if (minDash.get(field, VALUES_SOURCES_PATHS[source]) !== undefined) {
|
|
1388
|
-
return source;
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1391
|
-
return VALUES_SOURCE_DEFAULT;
|
|
1392
|
-
}
|
|
1393
|
-
|
|
1394
|
-
function createInjector(bootstrapModules) {
|
|
1395
|
-
const injector = new didi.Injector(bootstrapModules);
|
|
1396
|
-
injector.init();
|
|
1397
|
-
return injector;
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
/**
|
|
1401
|
-
* @param {string?} prefix
|
|
1402
|
-
*
|
|
1403
|
-
* @returns Element
|
|
1404
|
-
*/
|
|
1405
|
-
function createFormContainer(prefix = 'fjs') {
|
|
1406
|
-
const container = document.createElement('div');
|
|
1407
|
-
container.classList.add(`${prefix}-container`);
|
|
1408
|
-
return container;
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
|
-
const EXPRESSION_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'conditional.hide', 'description', 'label', 'source', 'readonly', 'text', 'validate.min', 'validate.max', 'validate.minLength', 'validate.maxLength', 'valuesExpression'];
|
|
1412
|
-
const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'description', 'label', 'source', 'text'];
|
|
1413
|
-
function findErrors(errors, path) {
|
|
1414
|
-
return errors[pathStringify(path)];
|
|
1415
|
-
}
|
|
1416
|
-
function isRequired(field) {
|
|
1417
|
-
return field.required;
|
|
1418
|
-
}
|
|
1419
|
-
function pathParse(path) {
|
|
1420
|
-
if (!path) {
|
|
1421
|
-
return [];
|
|
1422
|
-
}
|
|
1423
|
-
return path.split('.').map(key => {
|
|
1424
|
-
return isNaN(parseInt(key)) ? key : parseInt(key);
|
|
1425
|
-
});
|
|
1426
|
-
}
|
|
1427
|
-
function pathsEqual(a, b) {
|
|
1428
|
-
return a && b && a.length === b.length && a.every((value, index) => value === b[index]);
|
|
1429
|
-
}
|
|
1430
|
-
function pathStringify(path) {
|
|
1431
|
-
if (!path) {
|
|
1432
|
-
return '';
|
|
1433
|
-
}
|
|
1434
|
-
return path.join('.');
|
|
1435
|
-
}
|
|
1436
|
-
const indices = {};
|
|
1437
|
-
function generateIndexForType(type) {
|
|
1438
|
-
if (type in indices) {
|
|
1439
|
-
indices[type]++;
|
|
1440
|
-
} else {
|
|
1441
|
-
indices[type] = 1;
|
|
1442
|
-
}
|
|
1443
|
-
return indices[type];
|
|
1444
|
-
}
|
|
1445
|
-
function generateIdForType(type) {
|
|
1446
|
-
return `${type}${generateIndexForType(type)}`;
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
/**
|
|
1450
|
-
* @template T
|
|
1451
|
-
* @param {T} data
|
|
1452
|
-
* @param {(this: any, key: string, value: any) => any} [replacer]
|
|
1453
|
-
* @return {T}
|
|
1454
|
-
*/
|
|
1455
|
-
function clone(data, replacer) {
|
|
1456
|
-
return JSON.parse(JSON.stringify(data, replacer));
|
|
1457
|
-
}
|
|
1458
|
-
|
|
1459
|
-
/**
|
|
1460
|
-
* Parse the schema for input variables a form might make use of
|
|
1461
|
-
*
|
|
1462
|
-
* @param {any} schema
|
|
1463
|
-
*
|
|
1464
|
-
* @return {string[]}
|
|
1465
|
-
*/
|
|
1466
|
-
function getSchemaVariables(schema, expressionLanguage = new FeelExpressionLanguage(null), templating = new FeelersTemplating()) {
|
|
1467
|
-
if (!schema.components) {
|
|
1468
|
-
return [];
|
|
1469
|
-
}
|
|
1470
|
-
const variables = schema.components.reduce((variables, component) => {
|
|
1471
|
-
const {
|
|
1472
|
-
key,
|
|
1473
|
-
valuesKey,
|
|
1474
|
-
type
|
|
1475
|
-
} = component;
|
|
1476
|
-
if (['button'].includes(type)) {
|
|
1477
|
-
return variables;
|
|
1478
|
-
}
|
|
1479
|
-
if (key) {
|
|
1480
|
-
variables = [...variables, key];
|
|
1481
|
-
}
|
|
1482
|
-
if (valuesKey) {
|
|
1483
|
-
variables = [...variables, valuesKey];
|
|
1484
|
-
}
|
|
1485
|
-
EXPRESSION_PROPERTIES.forEach(prop => {
|
|
1486
|
-
const property = minDash.get(component, prop.split('.'));
|
|
1487
|
-
if (property && expressionLanguage.isExpression(property)) {
|
|
1488
|
-
const expressionVariables = expressionLanguage.getVariableNames(property, {
|
|
1489
|
-
type: 'expression'
|
|
1490
|
-
});
|
|
1491
|
-
variables = [...variables, ...expressionVariables];
|
|
1492
|
-
}
|
|
1493
|
-
});
|
|
1494
|
-
TEMPLATE_PROPERTIES.forEach(prop => {
|
|
1495
|
-
const property = minDash.get(component, prop.split('.'));
|
|
1496
|
-
if (property && !expressionLanguage.isExpression(property) && templating.isTemplate(property)) {
|
|
1497
|
-
const templateVariables = templating.getVariableNames(property);
|
|
1498
|
-
variables = [...variables, ...templateVariables];
|
|
1499
|
-
}
|
|
1500
|
-
});
|
|
1501
|
-
return variables;
|
|
1502
|
-
}, []);
|
|
1503
|
-
|
|
1504
|
-
// remove duplicates
|
|
1505
|
-
return Array.from(new Set(variables));
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
|
-
class Importer {
|
|
1509
|
-
/**
|
|
1510
|
-
* @constructor
|
|
1511
|
-
* @param { import('../core').FormFieldRegistry } formFieldRegistry
|
|
1512
|
-
* @param { import('../render/FormFields').default } formFields
|
|
1513
|
-
* @param { import('../core').FormLayouter } formLayouter
|
|
1514
|
-
*/
|
|
1515
|
-
constructor(formFieldRegistry, formFields, formLayouter) {
|
|
1516
|
-
this._formFieldRegistry = formFieldRegistry;
|
|
1517
|
-
this._formFields = formFields;
|
|
1518
|
-
this._formLayouter = formLayouter;
|
|
1519
|
-
}
|
|
2427
|
+
clear() {
|
|
2428
|
+
this._rows = [];
|
|
2429
|
+
this._ids.clear();
|
|
1520
2430
|
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
* information to each field and adding it to the
|
|
1524
|
-
* form field registry.
|
|
1525
|
-
*
|
|
1526
|
-
* @param {any} schema
|
|
1527
|
-
* @param {any} [data]
|
|
1528
|
-
*
|
|
1529
|
-
* @return { { warnings: Array<any>, schema: any, data: any } }
|
|
1530
|
-
*/
|
|
1531
|
-
importSchema(schema, data = {}) {
|
|
1532
|
-
// TODO: Add warnings - https://github.com/bpmn-io/form-js/issues/289
|
|
1533
|
-
const warnings = [];
|
|
1534
|
-
try {
|
|
1535
|
-
this._formLayouter.clear();
|
|
1536
|
-
const importedSchema = this.importFormField(clone(schema)),
|
|
1537
|
-
initializedData = this.initializeFieldValues(clone(data));
|
|
1538
|
-
this._formLayouter.calculateLayout(clone(importedSchema));
|
|
1539
|
-
return {
|
|
1540
|
-
warnings,
|
|
1541
|
-
schema: importedSchema,
|
|
1542
|
-
data: initializedData
|
|
1543
|
-
};
|
|
1544
|
-
} catch (err) {
|
|
1545
|
-
err.warnings = warnings;
|
|
1546
|
-
throw err;
|
|
1547
|
-
}
|
|
2431
|
+
// fire event to notify interested parties
|
|
2432
|
+
this._eventBus.fire('form.layoutCleared');
|
|
1548
2433
|
}
|
|
2434
|
+
}
|
|
2435
|
+
FormLayouter.$inject = ['eventBus'];
|
|
1549
2436
|
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
*/
|
|
1556
|
-
importFormField(formField, parentId) {
|
|
2437
|
+
// helpers //////
|
|
2438
|
+
|
|
2439
|
+
function groupByRow(components, ids) {
|
|
2440
|
+
return minDash.groupBy(components, c => {
|
|
2441
|
+
// mitigate missing row by creating new (handle legacy)
|
|
1557
2442
|
const {
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
} = formField;
|
|
1563
|
-
if (parentId) {
|
|
1564
|
-
// set form field parent
|
|
1565
|
-
formField._parent = parentId;
|
|
1566
|
-
}
|
|
1567
|
-
if (!this._formFields.get(type)) {
|
|
1568
|
-
throw new Error(`form field of type <${type}> not supported`);
|
|
2443
|
+
layout
|
|
2444
|
+
} = c;
|
|
2445
|
+
if (!layout || !layout.row) {
|
|
2446
|
+
return ids.nextPrefixed('Row_');
|
|
1569
2447
|
}
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
throw new Error(`form field with key <${key}> already exists`);
|
|
1574
|
-
}
|
|
1575
|
-
this._formFieldRegistry._keys.claim(key, formField);
|
|
2448
|
+
return layout.row;
|
|
2449
|
+
});
|
|
2450
|
+
}
|
|
1576
2451
|
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
// validate <id> uniqueness
|
|
1585
|
-
if (this._formFieldRegistry._ids.assigned(id)) {
|
|
1586
|
-
throw new Error(`form field with id <${id}> already exists`);
|
|
1587
|
-
}
|
|
1588
|
-
this._formFieldRegistry._ids.claim(id, formField);
|
|
1589
|
-
}
|
|
2452
|
+
/**
|
|
2453
|
+
* @param {Array<FormRows>} formRows
|
|
2454
|
+
* @returns {Array<FormRow>}
|
|
2455
|
+
*/
|
|
2456
|
+
function allRows(formRows) {
|
|
2457
|
+
return minDash.flatten(formRows.map(c => c.rows));
|
|
2458
|
+
}
|
|
1590
2459
|
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
this.
|
|
1594
|
-
|
|
1595
|
-
|
|
2460
|
+
class FormFieldRegistry {
|
|
2461
|
+
constructor(eventBus) {
|
|
2462
|
+
this._eventBus = eventBus;
|
|
2463
|
+
this._formFields = {};
|
|
2464
|
+
eventBus.on('form.clear', () => this.clear());
|
|
2465
|
+
this._ids = new Ids([32, 36, 1]);
|
|
2466
|
+
}
|
|
2467
|
+
add(formField) {
|
|
2468
|
+
const {
|
|
2469
|
+
id
|
|
2470
|
+
} = formField;
|
|
2471
|
+
if (this._formFields[id]) {
|
|
2472
|
+
throw new Error(`form field with ID ${id} already exists`);
|
|
1596
2473
|
}
|
|
1597
|
-
|
|
2474
|
+
this._eventBus.fire('formField.add', {
|
|
2475
|
+
formField
|
|
2476
|
+
});
|
|
2477
|
+
this._formFields[id] = formField;
|
|
1598
2478
|
}
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
2479
|
+
remove(formField) {
|
|
2480
|
+
const {
|
|
2481
|
+
id
|
|
2482
|
+
} = formField;
|
|
2483
|
+
if (!this._formFields[id]) {
|
|
2484
|
+
return;
|
|
2485
|
+
}
|
|
2486
|
+
this._eventBus.fire('formField.remove', {
|
|
2487
|
+
formField
|
|
1602
2488
|
});
|
|
2489
|
+
delete this._formFields[id];
|
|
1603
2490
|
}
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
} = formField;
|
|
1617
|
-
|
|
1618
|
-
// try to get value from data
|
|
1619
|
-
// if unavailable - try to get default value from form field
|
|
1620
|
-
// if unavailable - get empty value from form field
|
|
1621
|
-
|
|
1622
|
-
if (_path) {
|
|
1623
|
-
const {
|
|
1624
|
-
config: fieldConfig
|
|
1625
|
-
} = this._formFields.get(type);
|
|
1626
|
-
let valueData = minDash.get(data, _path);
|
|
1627
|
-
if (!minDash.isUndefined(valueData) && fieldConfig.sanitizeValue) {
|
|
1628
|
-
valueData = fieldConfig.sanitizeValue({
|
|
1629
|
-
formField,
|
|
1630
|
-
data,
|
|
1631
|
-
value: valueData
|
|
1632
|
-
});
|
|
1633
|
-
}
|
|
1634
|
-
const initializedFieldValue = !minDash.isUndefined(valueData) ? valueData : !minDash.isUndefined(defaultValue) ? defaultValue : fieldConfig.emptyValue;
|
|
1635
|
-
initializedData = {
|
|
1636
|
-
...initializedData,
|
|
1637
|
-
[_path[0]]: initializedFieldValue
|
|
1638
|
-
};
|
|
1639
|
-
}
|
|
1640
|
-
return initializedData;
|
|
1641
|
-
}, data);
|
|
2491
|
+
get(id) {
|
|
2492
|
+
return this._formFields[id];
|
|
2493
|
+
}
|
|
2494
|
+
getAll() {
|
|
2495
|
+
return Object.values(this._formFields);
|
|
2496
|
+
}
|
|
2497
|
+
forEach(callback) {
|
|
2498
|
+
this.getAll().forEach(formField => callback(formField));
|
|
2499
|
+
}
|
|
2500
|
+
clear() {
|
|
2501
|
+
this._formFields = {};
|
|
2502
|
+
this._ids.clear();
|
|
1642
2503
|
}
|
|
1643
2504
|
}
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
var importModule = {
|
|
1647
|
-
importer: ['type', Importer]
|
|
1648
|
-
};
|
|
2505
|
+
FormFieldRegistry.$inject = ['eventBus'];
|
|
1649
2506
|
|
|
1650
2507
|
function formFieldClasses(type, {
|
|
1651
2508
|
errors = [],
|
|
@@ -1679,7 +2536,7 @@ function prefixId(id, formId) {
|
|
|
1679
2536
|
return `fjs-form-${id}`;
|
|
1680
2537
|
}
|
|
1681
2538
|
|
|
1682
|
-
const type$
|
|
2539
|
+
const type$c = 'button';
|
|
1683
2540
|
function Button(props) {
|
|
1684
2541
|
const {
|
|
1685
2542
|
disabled,
|
|
@@ -1689,7 +2546,7 @@ function Button(props) {
|
|
|
1689
2546
|
action = 'submit'
|
|
1690
2547
|
} = field;
|
|
1691
2548
|
return jsxRuntime.jsx("div", {
|
|
1692
|
-
class: formFieldClasses(type$
|
|
2549
|
+
class: formFieldClasses(type$c),
|
|
1693
2550
|
children: jsxRuntime.jsx("button", {
|
|
1694
2551
|
class: "fjs-button",
|
|
1695
2552
|
type: action,
|
|
@@ -1699,8 +2556,8 @@ function Button(props) {
|
|
|
1699
2556
|
});
|
|
1700
2557
|
}
|
|
1701
2558
|
Button.config = {
|
|
1702
|
-
type: type$
|
|
1703
|
-
keyed:
|
|
2559
|
+
type: type$c,
|
|
2560
|
+
keyed: false,
|
|
1704
2561
|
label: 'Button',
|
|
1705
2562
|
group: 'action',
|
|
1706
2563
|
create: (options = {}) => ({
|
|
@@ -1710,6 +2567,9 @@ Button.config = {
|
|
|
1710
2567
|
};
|
|
1711
2568
|
|
|
1712
2569
|
const FormRenderContext = preact.createContext({
|
|
2570
|
+
EmptyRoot: props => {
|
|
2571
|
+
return null;
|
|
2572
|
+
},
|
|
1713
2573
|
Empty: props => {
|
|
1714
2574
|
return null;
|
|
1715
2575
|
},
|
|
@@ -1739,15 +2599,19 @@ const FormRenderContext = preact.createContext({
|
|
|
1739
2599
|
class: props.class,
|
|
1740
2600
|
children: props.children
|
|
1741
2601
|
});
|
|
2602
|
+
},
|
|
2603
|
+
hoveredId: [],
|
|
2604
|
+
setHoveredId: newValue => {
|
|
2605
|
+
console.log(`setHoveredId not defined, called with '${newValue}'`);
|
|
1742
2606
|
}
|
|
1743
2607
|
});
|
|
1744
2608
|
var FormRenderContext$1 = FormRenderContext;
|
|
1745
2609
|
|
|
1746
|
-
/**
|
|
1747
|
-
* @param {string} type
|
|
1748
|
-
* @param {boolean} [strict]
|
|
1749
|
-
*
|
|
1750
|
-
* @returns {any}
|
|
2610
|
+
/**
|
|
2611
|
+
* @param {string} type
|
|
2612
|
+
* @param {boolean} [strict]
|
|
2613
|
+
*
|
|
2614
|
+
* @returns {any}
|
|
1751
2615
|
*/
|
|
1752
2616
|
function getService(type, strict) {}
|
|
1753
2617
|
const FormContext = preact.createContext({
|
|
@@ -1763,10 +2627,10 @@ function useService(type, strict) {
|
|
|
1763
2627
|
return getService(type, strict);
|
|
1764
2628
|
}
|
|
1765
2629
|
|
|
1766
|
-
/**
|
|
1767
|
-
* Returns the conditionally filtered data of a form reactively.
|
|
1768
|
-
* Memoised to minimize re-renders
|
|
1769
|
-
*
|
|
2630
|
+
/**
|
|
2631
|
+
* Returns the conditionally filtered data of a form reactively.
|
|
2632
|
+
* Memoised to minimize re-renders
|
|
2633
|
+
*
|
|
1770
2634
|
*/
|
|
1771
2635
|
function useFilteredFormData() {
|
|
1772
2636
|
const {
|
|
@@ -1783,12 +2647,12 @@ function useFilteredFormData() {
|
|
|
1783
2647
|
}, [conditionChecker, data, initialData]);
|
|
1784
2648
|
}
|
|
1785
2649
|
|
|
1786
|
-
/**
|
|
1787
|
-
* Evaluate if condition is met reactively based on the conditionChecker and form data.
|
|
1788
|
-
*
|
|
1789
|
-
* @param {string | undefined} condition
|
|
1790
|
-
*
|
|
1791
|
-
* @returns {boolean} true if condition is met or no condition or condition checker exists
|
|
2650
|
+
/**
|
|
2651
|
+
* Evaluate if condition is met reactively based on the conditionChecker and form data.
|
|
2652
|
+
*
|
|
2653
|
+
* @param {string | undefined} condition
|
|
2654
|
+
*
|
|
2655
|
+
* @returns {boolean} true if condition is met or no condition or condition checker exists
|
|
1792
2656
|
*/
|
|
1793
2657
|
function useCondition(condition) {
|
|
1794
2658
|
const conditionChecker = useService('conditionChecker', false);
|
|
@@ -1798,13 +2662,13 @@ function useCondition(condition) {
|
|
|
1798
2662
|
}, [conditionChecker, condition, filteredData]);
|
|
1799
2663
|
}
|
|
1800
2664
|
|
|
1801
|
-
/**
|
|
1802
|
-
* Evaluate a string reactively based on the expressionLanguage and form data.
|
|
1803
|
-
* If the string is not an expression, it is returned as is.
|
|
1804
|
-
* Memoised to minimize re-renders.
|
|
1805
|
-
*
|
|
1806
|
-
* @param {string} value
|
|
1807
|
-
*
|
|
2665
|
+
/**
|
|
2666
|
+
* Evaluate a string reactively based on the expressionLanguage and form data.
|
|
2667
|
+
* If the string is not an expression, it is returned as is.
|
|
2668
|
+
* Memoised to minimize re-renders.
|
|
2669
|
+
*
|
|
2670
|
+
* @param {string} value
|
|
2671
|
+
*
|
|
1808
2672
|
*/
|
|
1809
2673
|
function useExpressionEvaluation(value) {
|
|
1810
2674
|
const formData = useFilteredFormData();
|
|
@@ -1833,16 +2697,16 @@ function useKeyDownAction(targetKey, action, listenerElement = window) {
|
|
|
1833
2697
|
});
|
|
1834
2698
|
}
|
|
1835
2699
|
|
|
1836
|
-
/**
|
|
1837
|
-
* Retrieve readonly value of a form field, given it can be an
|
|
1838
|
-
* expression optionally or configured globally.
|
|
1839
|
-
*
|
|
1840
|
-
* @typedef { import('../../types').FormProperties } FormProperties
|
|
1841
|
-
*
|
|
1842
|
-
* @param {any} formField
|
|
1843
|
-
* @param {FormProperties} properties
|
|
1844
|
-
*
|
|
1845
|
-
* @returns {boolean}
|
|
2700
|
+
/**
|
|
2701
|
+
* Retrieve readonly value of a form field, given it can be an
|
|
2702
|
+
* expression optionally or configured globally.
|
|
2703
|
+
*
|
|
2704
|
+
* @typedef { import('../../types').FormProperties } FormProperties
|
|
2705
|
+
*
|
|
2706
|
+
* @param {any} formField
|
|
2707
|
+
* @param {FormProperties} properties
|
|
2708
|
+
*
|
|
2709
|
+
* @returns {boolean}
|
|
1846
2710
|
*/
|
|
1847
2711
|
function useReadonly(formField, properties = {}) {
|
|
1848
2712
|
const expressionLanguage = useService('expressionLanguage');
|
|
@@ -1860,16 +2724,16 @@ function useReadonly(formField, properties = {}) {
|
|
|
1860
2724
|
return readonly || false;
|
|
1861
2725
|
}
|
|
1862
2726
|
|
|
1863
|
-
/**
|
|
1864
|
-
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
1865
|
-
* Memoised to minimize re-renders
|
|
1866
|
-
*
|
|
1867
|
-
* @param {string} value
|
|
1868
|
-
* @param {Object} options
|
|
1869
|
-
* @param {boolean} [options.debug = false]
|
|
1870
|
-
* @param {boolean} [options.strict = false]
|
|
1871
|
-
* @param {Function} [options.buildDebugString]
|
|
1872
|
-
*
|
|
2727
|
+
/**
|
|
2728
|
+
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
2729
|
+
* Memoised to minimize re-renders
|
|
2730
|
+
*
|
|
2731
|
+
* @param {string} value
|
|
2732
|
+
* @param {Object} options
|
|
2733
|
+
* @param {boolean} [options.debug = false]
|
|
2734
|
+
* @param {boolean} [options.strict = false]
|
|
2735
|
+
* @param {Function} [options.buildDebugString]
|
|
2736
|
+
*
|
|
1873
2737
|
*/
|
|
1874
2738
|
function useTemplateEvaluation(value, options) {
|
|
1875
2739
|
const filteredData = useFilteredFormData();
|
|
@@ -1882,17 +2746,17 @@ function useTemplateEvaluation(value, options) {
|
|
|
1882
2746
|
}, [filteredData, templating, value, options]);
|
|
1883
2747
|
}
|
|
1884
2748
|
|
|
1885
|
-
/**
|
|
1886
|
-
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
1887
|
-
* If the string contains multiple lines, only the first line is returned.
|
|
1888
|
-
* Memoised to minimize re-renders
|
|
1889
|
-
*
|
|
1890
|
-
* @param {string} value
|
|
1891
|
-
* @param {Object} [options]
|
|
1892
|
-
* @param {boolean} [options.debug = false]
|
|
1893
|
-
* @param {boolean} [options.strict = false]
|
|
1894
|
-
* @param {Function} [options.buildDebugString]
|
|
1895
|
-
*
|
|
2749
|
+
/**
|
|
2750
|
+
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
2751
|
+
* If the string contains multiple lines, only the first line is returned.
|
|
2752
|
+
* Memoised to minimize re-renders
|
|
2753
|
+
*
|
|
2754
|
+
* @param {string} value
|
|
2755
|
+
* @param {Object} [options]
|
|
2756
|
+
* @param {boolean} [options.debug = false]
|
|
2757
|
+
* @param {boolean} [options.strict = false]
|
|
2758
|
+
* @param {Function} [options.buildDebugString]
|
|
2759
|
+
*
|
|
1896
2760
|
*/
|
|
1897
2761
|
function useSingleLineTemplateEvaluation(value, options = {}) {
|
|
1898
2762
|
const evaluatedTemplate = useTemplateEvaluation(value, options);
|
|
@@ -1959,11 +2823,12 @@ function Label(props) {
|
|
|
1959
2823
|
});
|
|
1960
2824
|
}
|
|
1961
2825
|
|
|
1962
|
-
const type$
|
|
2826
|
+
const type$b = 'checkbox';
|
|
1963
2827
|
function Checkbox(props) {
|
|
1964
2828
|
const {
|
|
1965
2829
|
disabled,
|
|
1966
2830
|
errors = [],
|
|
2831
|
+
onBlur,
|
|
1967
2832
|
field,
|
|
1968
2833
|
readonly,
|
|
1969
2834
|
value = false
|
|
@@ -1990,7 +2855,7 @@ function Checkbox(props) {
|
|
|
1990
2855
|
} = hooks.useContext(FormContext$1);
|
|
1991
2856
|
const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`;
|
|
1992
2857
|
return jsxRuntime.jsxs("div", {
|
|
1993
|
-
class: classNames(formFieldClasses(type$
|
|
2858
|
+
class: classNames(formFieldClasses(type$b, {
|
|
1994
2859
|
errors,
|
|
1995
2860
|
disabled,
|
|
1996
2861
|
readonly
|
|
@@ -2009,6 +2874,7 @@ function Checkbox(props) {
|
|
|
2009
2874
|
id: prefixId(id, formId),
|
|
2010
2875
|
type: "checkbox",
|
|
2011
2876
|
onChange: onChange,
|
|
2877
|
+
onBlur: onBlur,
|
|
2012
2878
|
"aria-describedby": errorMessageId
|
|
2013
2879
|
})
|
|
2014
2880
|
}), jsxRuntime.jsx(Description, {
|
|
@@ -2020,7 +2886,7 @@ function Checkbox(props) {
|
|
|
2020
2886
|
});
|
|
2021
2887
|
}
|
|
2022
2888
|
Checkbox.config = {
|
|
2023
|
-
type: type$
|
|
2889
|
+
type: type$b,
|
|
2024
2890
|
keyed: true,
|
|
2025
2891
|
label: 'Checkbox',
|
|
2026
2892
|
group: 'selection',
|
|
@@ -2078,9 +2944,24 @@ function _isReadableType(value) {
|
|
|
2078
2944
|
function _isValueSomething(value) {
|
|
2079
2945
|
return value || value === 0 || value === false;
|
|
2080
2946
|
}
|
|
2947
|
+
function createEmptyOptions(options = {}) {
|
|
2948
|
+
const defaults = {};
|
|
2081
2949
|
|
|
2082
|
-
|
|
2083
|
-
|
|
2950
|
+
// provide default values if valuesKey and valuesExpression are not set
|
|
2951
|
+
if (!options.valuesKey && !options.valuesExpression) {
|
|
2952
|
+
defaults.values = [{
|
|
2953
|
+
label: 'Value',
|
|
2954
|
+
value: 'value'
|
|
2955
|
+
}];
|
|
2956
|
+
}
|
|
2957
|
+
return {
|
|
2958
|
+
...defaults,
|
|
2959
|
+
...options
|
|
2960
|
+
};
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
/**
|
|
2964
|
+
* @enum { String }
|
|
2084
2965
|
*/
|
|
2085
2966
|
const LOAD_STATES = {
|
|
2086
2967
|
LOADING: 'loading',
|
|
@@ -2088,17 +2969,17 @@ const LOAD_STATES = {
|
|
|
2088
2969
|
ERROR: 'error'
|
|
2089
2970
|
};
|
|
2090
2971
|
|
|
2091
|
-
/**
|
|
2092
|
-
* @typedef {Object} ValuesGetter
|
|
2093
|
-
* @property {Object[]} values - The values data
|
|
2094
|
-
* @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
|
|
2972
|
+
/**
|
|
2973
|
+
* @typedef {Object} ValuesGetter
|
|
2974
|
+
* @property {Object[]} values - The values data
|
|
2975
|
+
* @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
|
|
2095
2976
|
*/
|
|
2096
2977
|
|
|
2097
|
-
/**
|
|
2098
|
-
* A hook to load values for single and multiselect components.
|
|
2099
|
-
*
|
|
2100
|
-
* @param {Object} field - The form field to handle values for
|
|
2101
|
-
* @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
|
|
2978
|
+
/**
|
|
2979
|
+
* A hook to load values for single and multiselect components.
|
|
2980
|
+
*
|
|
2981
|
+
* @param {Object} field - The form field to handle values for
|
|
2982
|
+
* @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
|
|
2102
2983
|
*/
|
|
2103
2984
|
function useValuesAsync (field) {
|
|
2104
2985
|
const {
|
|
@@ -2363,11 +3244,12 @@ function sanitizeMultiSelectValue(options) {
|
|
|
2363
3244
|
}
|
|
2364
3245
|
}
|
|
2365
3246
|
|
|
2366
|
-
const type$
|
|
3247
|
+
const type$a = 'checklist';
|
|
2367
3248
|
function Checklist(props) {
|
|
2368
3249
|
const {
|
|
2369
3250
|
disabled,
|
|
2370
3251
|
errors = [],
|
|
3252
|
+
onBlur,
|
|
2371
3253
|
field,
|
|
2372
3254
|
readonly,
|
|
2373
3255
|
value = []
|
|
@@ -2378,6 +3260,7 @@ function Checklist(props) {
|
|
|
2378
3260
|
label,
|
|
2379
3261
|
validate = {}
|
|
2380
3262
|
} = field;
|
|
3263
|
+
const outerDivRef = hooks.useRef();
|
|
2381
3264
|
const {
|
|
2382
3265
|
required
|
|
2383
3266
|
} = validate;
|
|
@@ -2393,6 +3276,12 @@ function Checklist(props) {
|
|
|
2393
3276
|
value: newValue
|
|
2394
3277
|
});
|
|
2395
3278
|
};
|
|
3279
|
+
const onCheckboxBlur = e => {
|
|
3280
|
+
if (outerDivRef.current.contains(e.relatedTarget)) {
|
|
3281
|
+
return;
|
|
3282
|
+
}
|
|
3283
|
+
onBlur();
|
|
3284
|
+
};
|
|
2396
3285
|
const {
|
|
2397
3286
|
state: loadState,
|
|
2398
3287
|
values: options
|
|
@@ -2402,11 +3291,12 @@ function Checklist(props) {
|
|
|
2402
3291
|
} = hooks.useContext(FormContext$1);
|
|
2403
3292
|
const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`;
|
|
2404
3293
|
return jsxRuntime.jsxs("div", {
|
|
2405
|
-
class: classNames(formFieldClasses(type$
|
|
3294
|
+
class: classNames(formFieldClasses(type$a, {
|
|
2406
3295
|
errors,
|
|
2407
3296
|
disabled,
|
|
2408
3297
|
readonly
|
|
2409
3298
|
})),
|
|
3299
|
+
ref: outerDivRef,
|
|
2410
3300
|
children: [jsxRuntime.jsx(Label, {
|
|
2411
3301
|
label: label,
|
|
2412
3302
|
required: required
|
|
@@ -2426,6 +3316,7 @@ function Checklist(props) {
|
|
|
2426
3316
|
id: prefixId(`${id}-${index}`, formId),
|
|
2427
3317
|
type: "checkbox",
|
|
2428
3318
|
onClick: () => toggleCheckbox(v.value),
|
|
3319
|
+
onBlur: onCheckboxBlur,
|
|
2429
3320
|
"aria-describedby": errorMessageId
|
|
2430
3321
|
})
|
|
2431
3322
|
}, `${id}-${index}`);
|
|
@@ -2438,27 +3329,13 @@ function Checklist(props) {
|
|
|
2438
3329
|
});
|
|
2439
3330
|
}
|
|
2440
3331
|
Checklist.config = {
|
|
2441
|
-
type: type$
|
|
3332
|
+
type: type$a,
|
|
2442
3333
|
keyed: true,
|
|
2443
3334
|
label: 'Checklist',
|
|
2444
3335
|
group: 'selection',
|
|
2445
3336
|
emptyValue: [],
|
|
2446
3337
|
sanitizeValue: sanitizeMultiSelectValue,
|
|
2447
|
-
create:
|
|
2448
|
-
const defaults = {};
|
|
2449
|
-
|
|
2450
|
-
// provide default values if valuesKey isn't set
|
|
2451
|
-
if (!options.valuesKey) {
|
|
2452
|
-
defaults.values = [{
|
|
2453
|
-
label: 'Value',
|
|
2454
|
-
value: 'value'
|
|
2455
|
-
}];
|
|
2456
|
-
}
|
|
2457
|
-
return {
|
|
2458
|
-
...defaults,
|
|
2459
|
-
...options
|
|
2460
|
-
};
|
|
2461
|
-
}
|
|
3338
|
+
create: createEmptyOptions
|
|
2462
3339
|
};
|
|
2463
3340
|
|
|
2464
3341
|
const noop$1 = () => false;
|
|
@@ -2468,8 +3345,11 @@ function FormField(props) {
|
|
|
2468
3345
|
onChange
|
|
2469
3346
|
} = props;
|
|
2470
3347
|
const formFields = useService('formFields'),
|
|
3348
|
+
viewerCommands = useService('viewerCommands', false),
|
|
3349
|
+
pathRegistry = useService('pathRegistry'),
|
|
2471
3350
|
form = useService('form');
|
|
2472
3351
|
const {
|
|
3352
|
+
initialData,
|
|
2473
3353
|
data,
|
|
2474
3354
|
errors,
|
|
2475
3355
|
properties
|
|
@@ -2483,12 +3363,23 @@ function FormField(props) {
|
|
|
2483
3363
|
if (!FormFieldComponent) {
|
|
2484
3364
|
throw new Error(`cannot render field <${field.type}>`);
|
|
2485
3365
|
}
|
|
2486
|
-
const
|
|
2487
|
-
const
|
|
3366
|
+
const valuePath = hooks.useMemo(() => pathRegistry.getValuePath(field), [field, pathRegistry]);
|
|
3367
|
+
const initialValue = hooks.useMemo(() => minDash.get(initialData, valuePath), [initialData, valuePath]);
|
|
2488
3368
|
const readonly = useReadonly(field, properties);
|
|
3369
|
+
const value = minDash.get(data, valuePath);
|
|
2489
3370
|
|
|
2490
3371
|
// add precedence: global readonly > form field disabled
|
|
2491
3372
|
const disabled = !properties.readOnly && (properties.disabled || field.disabled || false);
|
|
3373
|
+
const onBlur = hooks.useCallback(() => {
|
|
3374
|
+
if (viewerCommands) {
|
|
3375
|
+
viewerCommands.updateFieldValidation(field, value);
|
|
3376
|
+
}
|
|
3377
|
+
}, [viewerCommands, field, value]);
|
|
3378
|
+
hooks.useEffect(() => {
|
|
3379
|
+
if (viewerCommands && initialValue) {
|
|
3380
|
+
viewerCommands.updateFieldValidation(field, initialValue);
|
|
3381
|
+
}
|
|
3382
|
+
}, [viewerCommands, field, initialValue]);
|
|
2492
3383
|
const hidden = useCondition(field.conditional && field.conditional.hide || null);
|
|
2493
3384
|
if (hidden) {
|
|
2494
3385
|
return jsxRuntime.jsx(Empty, {});
|
|
@@ -2502,8 +3393,9 @@ function FormField(props) {
|
|
|
2502
3393
|
children: jsxRuntime.jsx(FormFieldComponent, {
|
|
2503
3394
|
...props,
|
|
2504
3395
|
disabled: disabled,
|
|
2505
|
-
errors:
|
|
3396
|
+
errors: errors[field.id],
|
|
2506
3397
|
onChange: disabled || readonly ? noop$1 : onChange,
|
|
3398
|
+
onBlur: disabled || readonly ? noop$1 : onBlur,
|
|
2507
3399
|
readonly: readonly,
|
|
2508
3400
|
value: value
|
|
2509
3401
|
})
|
|
@@ -2511,14 +3403,14 @@ function FormField(props) {
|
|
|
2511
3403
|
});
|
|
2512
3404
|
}
|
|
2513
3405
|
|
|
2514
|
-
function
|
|
3406
|
+
function Grid(props) {
|
|
2515
3407
|
const {
|
|
2516
3408
|
Children,
|
|
2517
|
-
Empty,
|
|
2518
3409
|
Row
|
|
2519
3410
|
} = hooks.useContext(FormRenderContext$1);
|
|
2520
3411
|
const {
|
|
2521
|
-
field
|
|
3412
|
+
field,
|
|
3413
|
+
Empty
|
|
2522
3414
|
} = props;
|
|
2523
3415
|
const {
|
|
2524
3416
|
id,
|
|
@@ -2555,7 +3447,20 @@ function Default(props) {
|
|
|
2555
3447
|
}), components.length ? null : jsxRuntime.jsx(Empty, {})]
|
|
2556
3448
|
});
|
|
2557
3449
|
}
|
|
2558
|
-
|
|
3450
|
+
|
|
3451
|
+
function FormComponent$1(props) {
|
|
3452
|
+
const {
|
|
3453
|
+
EmptyRoot
|
|
3454
|
+
} = hooks.useContext(FormRenderContext$1);
|
|
3455
|
+
const fullProps = {
|
|
3456
|
+
...props,
|
|
3457
|
+
Empty: EmptyRoot
|
|
3458
|
+
};
|
|
3459
|
+
return jsxRuntime.jsx(Grid, {
|
|
3460
|
+
...fullProps
|
|
3461
|
+
});
|
|
3462
|
+
}
|
|
3463
|
+
FormComponent$1.config = {
|
|
2559
3464
|
type: 'default',
|
|
2560
3465
|
keyed: false,
|
|
2561
3466
|
label: null,
|
|
@@ -2566,16 +3471,16 @@ Default.config = {
|
|
|
2566
3471
|
})
|
|
2567
3472
|
};
|
|
2568
3473
|
|
|
2569
|
-
var _path$
|
|
2570
|
-
function _extends$
|
|
3474
|
+
var _path$h;
|
|
3475
|
+
function _extends$k() { _extends$k = 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$k.apply(this, arguments); }
|
|
2571
3476
|
var SvgCalendar = function SvgCalendar(props) {
|
|
2572
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
3477
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$k({
|
|
2573
3478
|
xmlns: "http://www.w3.org/2000/svg",
|
|
2574
3479
|
width: 14,
|
|
2575
3480
|
height: 15,
|
|
2576
3481
|
fill: "none",
|
|
2577
3482
|
viewBox: "0 0 28 30"
|
|
2578
|
-
}, props), _path$
|
|
3483
|
+
}, props), _path$h || (_path$h = /*#__PURE__*/React__namespace.createElement("path", {
|
|
2579
3484
|
fill: "currentColor",
|
|
2580
3485
|
fillRule: "evenodd",
|
|
2581
3486
|
d: "M19 2H9V0H7v2H2a2 2 0 0 0-2 2v24a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2h-5V0h-2v2ZM7 7V4H2v5h24V4h-5v3h-2V4H9v3H7Zm-5 4v17h24V11H2Z",
|
|
@@ -2584,6 +3489,74 @@ var SvgCalendar = function SvgCalendar(props) {
|
|
|
2584
3489
|
};
|
|
2585
3490
|
var CalendarIcon = SvgCalendar;
|
|
2586
3491
|
|
|
3492
|
+
/**
|
|
3493
|
+
* Returns date format for the provided locale.
|
|
3494
|
+
* If the locale is not provided, uses the browser's locale.
|
|
3495
|
+
*
|
|
3496
|
+
* @param {string} [locale] - The locale to get date format for.
|
|
3497
|
+
* @returns {string} The date format for the locale.
|
|
3498
|
+
*/
|
|
3499
|
+
function getLocaleDateFormat(locale = 'default') {
|
|
3500
|
+
const parts = new Intl.DateTimeFormat(locale).formatToParts(new Date(Date.UTC(2020, 5, 5)));
|
|
3501
|
+
return parts.map(part => {
|
|
3502
|
+
const len = part.value.length;
|
|
3503
|
+
switch (part.type) {
|
|
3504
|
+
case 'day':
|
|
3505
|
+
return 'd'.repeat(len);
|
|
3506
|
+
case 'month':
|
|
3507
|
+
return 'M'.repeat(len);
|
|
3508
|
+
case 'year':
|
|
3509
|
+
return 'y'.repeat(len);
|
|
3510
|
+
default:
|
|
3511
|
+
return part.value;
|
|
3512
|
+
}
|
|
3513
|
+
}).join('');
|
|
3514
|
+
}
|
|
3515
|
+
|
|
3516
|
+
/**
|
|
3517
|
+
* Returns readable date format for the provided locale.
|
|
3518
|
+
* If the locale is not provided, uses the browser's locale.
|
|
3519
|
+
*
|
|
3520
|
+
* @param {string} [locale] - The locale to get readable date format for.
|
|
3521
|
+
* @returns {string} The readable date format for the locale.
|
|
3522
|
+
*/
|
|
3523
|
+
function getLocaleReadableDateFormat(locale) {
|
|
3524
|
+
let format = getLocaleDateFormat(locale).toLowerCase();
|
|
3525
|
+
|
|
3526
|
+
// Ensure month is in 'mm' format
|
|
3527
|
+
if (!format.includes('mm')) {
|
|
3528
|
+
format = format.replace('m', 'mm');
|
|
3529
|
+
}
|
|
3530
|
+
|
|
3531
|
+
// Ensure day is in 'dd' format
|
|
3532
|
+
if (!format.includes('dd')) {
|
|
3533
|
+
format = format.replace('d', 'dd');
|
|
3534
|
+
}
|
|
3535
|
+
return format;
|
|
3536
|
+
}
|
|
3537
|
+
|
|
3538
|
+
/**
|
|
3539
|
+
* Returns flatpickr config for the provided locale.
|
|
3540
|
+
* If the locale is not provided, uses the browser's locale.
|
|
3541
|
+
*
|
|
3542
|
+
* @param {string} [locale] - The locale to get flatpickr config for.
|
|
3543
|
+
* @returns {object} The flatpickr config for the locale.
|
|
3544
|
+
*/
|
|
3545
|
+
function getLocaleDateFlatpickrConfig(locale) {
|
|
3546
|
+
return flatpickerizeDateFormat(getLocaleDateFormat(locale));
|
|
3547
|
+
}
|
|
3548
|
+
function flatpickerizeDateFormat(dateFormat) {
|
|
3549
|
+
const useLeadingZero = {
|
|
3550
|
+
day: dateFormat.includes('dd'),
|
|
3551
|
+
month: dateFormat.includes('MM'),
|
|
3552
|
+
year: dateFormat.includes('yyyy')
|
|
3553
|
+
};
|
|
3554
|
+
dateFormat = useLeadingZero.day ? dateFormat.replace('dd', 'd') : dateFormat.replace('d', 'j');
|
|
3555
|
+
dateFormat = useLeadingZero.month ? dateFormat.replace('MM', 'm') : dateFormat.replace('M', 'n');
|
|
3556
|
+
dateFormat = useLeadingZero.year ? dateFormat.replace('yyyy', 'Y') : dateFormat.replace('yy', 'y');
|
|
3557
|
+
return dateFormat;
|
|
3558
|
+
}
|
|
3559
|
+
|
|
2587
3560
|
function InputAdorner(props) {
|
|
2588
3561
|
const {
|
|
2589
3562
|
pre,
|
|
@@ -2627,6 +3600,7 @@ function Datepicker(props) {
|
|
|
2627
3600
|
id,
|
|
2628
3601
|
label,
|
|
2629
3602
|
collapseLabelOnEmpty,
|
|
3603
|
+
onDateTimeBlur,
|
|
2630
3604
|
formId,
|
|
2631
3605
|
required,
|
|
2632
3606
|
disabled,
|
|
@@ -2657,7 +3631,7 @@ function Datepicker(props) {
|
|
|
2657
3631
|
hooks.useEffect(() => {
|
|
2658
3632
|
let config = {
|
|
2659
3633
|
allowInput: true,
|
|
2660
|
-
dateFormat:
|
|
3634
|
+
dateFormat: getLocaleDateFlatpickrConfig(),
|
|
2661
3635
|
static: true,
|
|
2662
3636
|
clickOpens: false,
|
|
2663
3637
|
// TODO: support dates prior to 1900 (https://github.com/bpmn-io/form-js/issues/533)
|
|
@@ -2721,7 +3695,8 @@ function Datepicker(props) {
|
|
|
2721
3695
|
if (!isInputDirty || e.relatedTarget && e.relatedTarget.classList.contains('flatpickr-day')) return;
|
|
2722
3696
|
dateInputRef.current.dispatchEvent(ENTER_KEYDOWN_EVENT);
|
|
2723
3697
|
setIsInputDirty(false);
|
|
2724
|
-
|
|
3698
|
+
onDateTimeBlur(e);
|
|
3699
|
+
}, [isInputDirty, onDateTimeBlur]);
|
|
2725
3700
|
const fullId = `${prefixId(id, formId)}--date`;
|
|
2726
3701
|
return jsxRuntime.jsxs("div", {
|
|
2727
3702
|
class: "fjs-datetime-subsection",
|
|
@@ -2748,7 +3723,7 @@ function Datepicker(props) {
|
|
|
2748
3723
|
class: "fjs-input",
|
|
2749
3724
|
disabled: disabled,
|
|
2750
3725
|
readOnly: readonly,
|
|
2751
|
-
placeholder:
|
|
3726
|
+
placeholder: getLocaleReadableDateFormat(),
|
|
2752
3727
|
autoComplete: "off",
|
|
2753
3728
|
onFocus: onInputFocus,
|
|
2754
3729
|
onKeyDown: onInputKeyDown,
|
|
@@ -2763,19 +3738,19 @@ function Datepicker(props) {
|
|
|
2763
3738
|
});
|
|
2764
3739
|
}
|
|
2765
3740
|
|
|
2766
|
-
var _path$
|
|
2767
|
-
function _extends$
|
|
3741
|
+
var _path$g, _path2$4;
|
|
3742
|
+
function _extends$j() { _extends$j = 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$j.apply(this, arguments); }
|
|
2768
3743
|
var SvgClock = function SvgClock(props) {
|
|
2769
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
3744
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$j({
|
|
2770
3745
|
xmlns: "http://www.w3.org/2000/svg",
|
|
2771
3746
|
width: 16,
|
|
2772
3747
|
height: 16,
|
|
2773
3748
|
fill: "none",
|
|
2774
3749
|
viewBox: "0 0 28 29"
|
|
2775
|
-
}, props), _path$
|
|
3750
|
+
}, props), _path$g || (_path$g = /*#__PURE__*/React__namespace.createElement("path", {
|
|
2776
3751
|
fill: "currentColor",
|
|
2777
3752
|
d: "M13 14.41 18.59 20 20 18.59l-5-5.01V5h-2v9.41Z"
|
|
2778
|
-
})), _path2$
|
|
3753
|
+
})), _path2$4 || (_path2$4 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
2779
3754
|
fill: "currentColor",
|
|
2780
3755
|
fillRule: "evenodd",
|
|
2781
3756
|
d: "M6.222 25.64A14 14 0 1 0 21.778 2.36 14 14 0 0 0 6.222 25.64ZM7.333 4.023a12 12 0 1 1 13.334 19.955A12 12 0 0 1 7.333 4.022Z",
|
|
@@ -2884,6 +3859,7 @@ function Timepicker(props) {
|
|
|
2884
3859
|
id,
|
|
2885
3860
|
label,
|
|
2886
3861
|
collapseLabelOnEmpty,
|
|
3862
|
+
onDateTimeBlur,
|
|
2887
3863
|
formId,
|
|
2888
3864
|
required,
|
|
2889
3865
|
disabled,
|
|
@@ -2983,6 +3959,7 @@ function Timepicker(props) {
|
|
|
2983
3959
|
const onInputBlur = e => {
|
|
2984
3960
|
setDropdownIsOpen(false);
|
|
2985
3961
|
propagateRawToMinute();
|
|
3962
|
+
onDateTimeBlur(e);
|
|
2986
3963
|
};
|
|
2987
3964
|
const onDropdownValueSelected = value => {
|
|
2988
3965
|
setDropdownIsOpen(false);
|
|
@@ -3038,11 +4015,12 @@ function Timepicker(props) {
|
|
|
3038
4015
|
});
|
|
3039
4016
|
}
|
|
3040
4017
|
|
|
3041
|
-
const type$
|
|
4018
|
+
const type$9 = 'datetime';
|
|
3042
4019
|
function Datetime(props) {
|
|
3043
4020
|
const {
|
|
3044
4021
|
disabled,
|
|
3045
4022
|
errors = [],
|
|
4023
|
+
onBlur,
|
|
3046
4024
|
field,
|
|
3047
4025
|
onChange,
|
|
3048
4026
|
readonly,
|
|
@@ -3066,6 +4044,7 @@ function Datetime(props) {
|
|
|
3066
4044
|
const {
|
|
3067
4045
|
formId
|
|
3068
4046
|
} = hooks.useContext(FormContext$1);
|
|
4047
|
+
const dateTimeGroupRef = hooks.useRef();
|
|
3069
4048
|
const getNullDateTime = () => ({
|
|
3070
4049
|
date: new Date(Date.parse(null)),
|
|
3071
4050
|
time: null
|
|
@@ -3076,6 +4055,12 @@ function Datetime(props) {
|
|
|
3076
4055
|
const isValidTime = time => !isNaN(parseInt(time));
|
|
3077
4056
|
const useDatePicker = hooks.useMemo(() => subtype === DATETIME_SUBTYPES.DATE || subtype === DATETIME_SUBTYPES.DATETIME, [subtype]);
|
|
3078
4057
|
const useTimePicker = hooks.useMemo(() => subtype === DATETIME_SUBTYPES.TIME || subtype === DATETIME_SUBTYPES.DATETIME, [subtype]);
|
|
4058
|
+
const onDateTimeBlur = hooks.useCallback(e => {
|
|
4059
|
+
if (e.relatedTarget && dateTimeGroupRef.current.contains(e.relatedTarget)) {
|
|
4060
|
+
return;
|
|
4061
|
+
}
|
|
4062
|
+
onBlur();
|
|
4063
|
+
}, [onBlur]);
|
|
3079
4064
|
hooks.useEffect(() => {
|
|
3080
4065
|
let {
|
|
3081
4066
|
date,
|
|
@@ -3167,6 +4152,7 @@ function Datetime(props) {
|
|
|
3167
4152
|
id,
|
|
3168
4153
|
label: dateLabel,
|
|
3169
4154
|
collapseLabelOnEmpty: !timeLabel,
|
|
4155
|
+
onDateTimeBlur,
|
|
3170
4156
|
formId,
|
|
3171
4157
|
required,
|
|
3172
4158
|
disabled,
|
|
@@ -3180,6 +4166,7 @@ function Datetime(props) {
|
|
|
3180
4166
|
id,
|
|
3181
4167
|
label: timeLabel,
|
|
3182
4168
|
collapseLabelOnEmpty: !dateLabel,
|
|
4169
|
+
onDateTimeBlur,
|
|
3183
4170
|
formId,
|
|
3184
4171
|
required,
|
|
3185
4172
|
disabled,
|
|
@@ -3191,13 +4178,14 @@ function Datetime(props) {
|
|
|
3191
4178
|
'aria-describedby': errorMessageId
|
|
3192
4179
|
};
|
|
3193
4180
|
return jsxRuntime.jsxs("div", {
|
|
3194
|
-
class: formFieldClasses(type$
|
|
4181
|
+
class: formFieldClasses(type$9, {
|
|
3195
4182
|
errors: allErrors,
|
|
3196
4183
|
disabled,
|
|
3197
4184
|
readonly
|
|
3198
4185
|
}),
|
|
3199
4186
|
children: [jsxRuntime.jsxs("div", {
|
|
3200
4187
|
class: classNames('fjs-vertical-group'),
|
|
4188
|
+
ref: dateTimeGroupRef,
|
|
3201
4189
|
children: [useDatePicker && jsxRuntime.jsx(Datepicker, {
|
|
3202
4190
|
...datePickerProps
|
|
3203
4191
|
}), useTimePicker && useDatePicker && jsxRuntime.jsx("div", {
|
|
@@ -3214,7 +4202,7 @@ function Datetime(props) {
|
|
|
3214
4202
|
});
|
|
3215
4203
|
}
|
|
3216
4204
|
Datetime.config = {
|
|
3217
|
-
type: type$
|
|
4205
|
+
type: type$9,
|
|
3218
4206
|
keyed: true,
|
|
3219
4207
|
label: 'Date time',
|
|
3220
4208
|
group: 'basic-input',
|
|
@@ -3231,10 +4219,10 @@ Datetime.config = {
|
|
|
3231
4219
|
}
|
|
3232
4220
|
};
|
|
3233
4221
|
|
|
3234
|
-
/**
|
|
3235
|
-
* This file must not be changed or exchanged.
|
|
3236
|
-
*
|
|
3237
|
-
* @see http://bpmn.io/license for more information.
|
|
4222
|
+
/**
|
|
4223
|
+
* This file must not be changed or exchanged.
|
|
4224
|
+
*
|
|
4225
|
+
* @see http://bpmn.io/license for more information.
|
|
3238
4226
|
*/
|
|
3239
4227
|
function Logo() {
|
|
3240
4228
|
return jsxRuntime.jsxs("svg", {
|
|
@@ -3356,6 +4344,52 @@ function FormComponent(props) {
|
|
|
3356
4344
|
});
|
|
3357
4345
|
}
|
|
3358
4346
|
|
|
4347
|
+
function Group(props) {
|
|
4348
|
+
const {
|
|
4349
|
+
field
|
|
4350
|
+
} = props;
|
|
4351
|
+
const {
|
|
4352
|
+
label,
|
|
4353
|
+
id,
|
|
4354
|
+
type,
|
|
4355
|
+
showOutline
|
|
4356
|
+
} = field;
|
|
4357
|
+
const {
|
|
4358
|
+
formId
|
|
4359
|
+
} = hooks.useContext(FormContext$1);
|
|
4360
|
+
const {
|
|
4361
|
+
Empty
|
|
4362
|
+
} = hooks.useContext(FormRenderContext$1);
|
|
4363
|
+
const fullProps = {
|
|
4364
|
+
...props,
|
|
4365
|
+
Empty
|
|
4366
|
+
};
|
|
4367
|
+
return jsxRuntime.jsxs("div", {
|
|
4368
|
+
className: classNames(formFieldClasses(type), {
|
|
4369
|
+
'fjs-outlined': showOutline
|
|
4370
|
+
}),
|
|
4371
|
+
role: "group",
|
|
4372
|
+
"aria-labelledby": prefixId(id, formId),
|
|
4373
|
+
children: [jsxRuntime.jsx(Label, {
|
|
4374
|
+
id: prefixId(id, formId),
|
|
4375
|
+
label: label
|
|
4376
|
+
}), jsxRuntime.jsx(Grid, {
|
|
4377
|
+
...fullProps
|
|
4378
|
+
})]
|
|
4379
|
+
});
|
|
4380
|
+
}
|
|
4381
|
+
Group.config = {
|
|
4382
|
+
type: 'group',
|
|
4383
|
+
pathed: true,
|
|
4384
|
+
label: 'Group',
|
|
4385
|
+
group: 'presentation',
|
|
4386
|
+
create: (options = {}) => ({
|
|
4387
|
+
components: [],
|
|
4388
|
+
showOutline: true,
|
|
4389
|
+
...options
|
|
4390
|
+
})
|
|
4391
|
+
};
|
|
4392
|
+
|
|
3359
4393
|
const NODE_TYPE_TEXT = 3,
|
|
3360
4394
|
NODE_TYPE_ELEMENT = 1;
|
|
3361
4395
|
const ALLOWED_NODES = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'em', 'a', 'p', 'div', 'ul', 'ol', 'li', 'hr', 'blockquote', 'img', 'pre', 'code', 'br', 'strong', 'table', 'thead', 'tbody', 'tr', 'th', 'td'];
|
|
@@ -3366,11 +4400,11 @@ const ATTR_WHITESPACE_PATTERN = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u
|
|
|
3366
4400
|
|
|
3367
4401
|
const FORM_ELEMENT = document.createElement('form');
|
|
3368
4402
|
|
|
3369
|
-
/**
|
|
3370
|
-
* Sanitize a HTML string and return the cleaned, safe version.
|
|
3371
|
-
*
|
|
3372
|
-
* @param {string} html
|
|
3373
|
-
* @return {string}
|
|
4403
|
+
/**
|
|
4404
|
+
* Sanitize a HTML string and return the cleaned, safe version.
|
|
4405
|
+
*
|
|
4406
|
+
* @param {string} html
|
|
4407
|
+
* @return {string}
|
|
3374
4408
|
*/
|
|
3375
4409
|
|
|
3376
4410
|
// see https://github.com/developit/snarkdown/issues/70
|
|
@@ -3388,29 +4422,29 @@ function sanitizeHTML(html) {
|
|
|
3388
4422
|
}
|
|
3389
4423
|
}
|
|
3390
4424
|
|
|
3391
|
-
/**
|
|
3392
|
-
* Sanitizes an image source to ensure we only allow for data URI and links
|
|
3393
|
-
* that start with http(s).
|
|
3394
|
-
*
|
|
3395
|
-
* Note: Most browsers anyway do not support script execution in <img> elements.
|
|
3396
|
-
*
|
|
3397
|
-
* @param {string} src
|
|
3398
|
-
* @returns {string}
|
|
4425
|
+
/**
|
|
4426
|
+
* Sanitizes an image source to ensure we only allow for data URI and links
|
|
4427
|
+
* that start with http(s).
|
|
4428
|
+
*
|
|
4429
|
+
* Note: Most browsers anyway do not support script execution in <img> elements.
|
|
4430
|
+
*
|
|
4431
|
+
* @param {string} src
|
|
4432
|
+
* @returns {string}
|
|
3399
4433
|
*/
|
|
3400
4434
|
function sanitizeImageSource(src) {
|
|
3401
4435
|
const valid = ALLOWED_IMAGE_SRC_PATTERN.test(src);
|
|
3402
4436
|
return valid ? src : '';
|
|
3403
4437
|
}
|
|
3404
4438
|
|
|
3405
|
-
/**
|
|
3406
|
-
* Recursively sanitize a HTML node, potentially
|
|
3407
|
-
* removing it, its children or attributes.
|
|
3408
|
-
*
|
|
3409
|
-
* Inspired by https://github.com/developit/snarkdown/issues/70
|
|
3410
|
-
* and https://github.com/cure53/DOMPurify. Simplified
|
|
3411
|
-
* for our use-case.
|
|
3412
|
-
*
|
|
3413
|
-
* @param {Element} node
|
|
4439
|
+
/**
|
|
4440
|
+
* Recursively sanitize a HTML node, potentially
|
|
4441
|
+
* removing it, its children or attributes.
|
|
4442
|
+
*
|
|
4443
|
+
* Inspired by https://github.com/developit/snarkdown/issues/70
|
|
4444
|
+
* and https://github.com/cure53/DOMPurify. Simplified
|
|
4445
|
+
* for our use-case.
|
|
4446
|
+
*
|
|
4447
|
+
* @param {Element} node
|
|
3414
4448
|
*/
|
|
3415
4449
|
function sanitizeNode(node) {
|
|
3416
4450
|
// allow text nodes
|
|
@@ -3454,13 +4488,13 @@ function sanitizeNode(node) {
|
|
|
3454
4488
|
}
|
|
3455
4489
|
}
|
|
3456
4490
|
|
|
3457
|
-
/**
|
|
3458
|
-
* Validates attributes for validity.
|
|
3459
|
-
*
|
|
3460
|
-
* @param {string} lcTag
|
|
3461
|
-
* @param {string} lcName
|
|
3462
|
-
* @param {string} value
|
|
3463
|
-
* @return {boolean}
|
|
4491
|
+
/**
|
|
4492
|
+
* Validates attributes for validity.
|
|
4493
|
+
*
|
|
4494
|
+
* @param {string} lcTag
|
|
4495
|
+
* @param {string} lcName
|
|
4496
|
+
* @param {string} value
|
|
4497
|
+
* @return {boolean}
|
|
3464
4498
|
*/
|
|
3465
4499
|
function isValidAttribute(lcTag, lcName, value) {
|
|
3466
4500
|
// disallow most attributes based on whitelist
|
|
@@ -3483,9 +4517,9 @@ function isValidAttribute(lcTag, lcName, value) {
|
|
|
3483
4517
|
return true;
|
|
3484
4518
|
}
|
|
3485
4519
|
|
|
3486
|
-
function _extends$
|
|
4520
|
+
function _extends$i() { _extends$i = 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$i.apply(this, arguments); }
|
|
3487
4521
|
var SvgImagePlaceholder = function SvgImagePlaceholder(props) {
|
|
3488
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
4522
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$i({
|
|
3489
4523
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3490
4524
|
xmlSpace: "preserve",
|
|
3491
4525
|
width: 64,
|
|
@@ -3524,7 +4558,7 @@ var SvgImagePlaceholder = function SvgImagePlaceholder(props) {
|
|
|
3524
4558
|
};
|
|
3525
4559
|
var ImagePlaceholder = SvgImagePlaceholder;
|
|
3526
4560
|
|
|
3527
|
-
const type$
|
|
4561
|
+
const type$8 = 'image';
|
|
3528
4562
|
function Image(props) {
|
|
3529
4563
|
const {
|
|
3530
4564
|
field
|
|
@@ -3545,7 +4579,7 @@ function Image(props) {
|
|
|
3545
4579
|
formId
|
|
3546
4580
|
} = hooks.useContext(FormContext$1);
|
|
3547
4581
|
return jsxRuntime.jsx("div", {
|
|
3548
|
-
class: formFieldClasses(type$
|
|
4582
|
+
class: formFieldClasses(type$8),
|
|
3549
4583
|
children: jsxRuntime.jsxs("div", {
|
|
3550
4584
|
class: "fjs-image-container",
|
|
3551
4585
|
children: [safeSource && jsxRuntime.jsx("img", {
|
|
@@ -3563,7 +4597,7 @@ function Image(props) {
|
|
|
3563
4597
|
});
|
|
3564
4598
|
}
|
|
3565
4599
|
Image.config = {
|
|
3566
|
-
type: type$
|
|
4600
|
+
type: type$8,
|
|
3567
4601
|
keyed: false,
|
|
3568
4602
|
label: 'Image view',
|
|
3569
4603
|
group: 'presentation',
|
|
@@ -3590,14 +4624,14 @@ function TemplatedInputAdorner(props) {
|
|
|
3590
4624
|
});
|
|
3591
4625
|
}
|
|
3592
4626
|
|
|
3593
|
-
var _path$
|
|
3594
|
-
function _extends$
|
|
4627
|
+
var _path$f;
|
|
4628
|
+
function _extends$h() { _extends$h = 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$h.apply(this, arguments); }
|
|
3595
4629
|
var SvgAngelDown = function SvgAngelDown(props) {
|
|
3596
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
4630
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$h({
|
|
3597
4631
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3598
4632
|
width: 8,
|
|
3599
4633
|
height: 8
|
|
3600
|
-
}, props), _path$
|
|
4634
|
+
}, props), _path$f || (_path$f = /*#__PURE__*/React__namespace.createElement("path", {
|
|
3601
4635
|
fill: "currentColor",
|
|
3602
4636
|
fillRule: "evenodd",
|
|
3603
4637
|
stroke: "currentColor",
|
|
@@ -3608,14 +4642,14 @@ var SvgAngelDown = function SvgAngelDown(props) {
|
|
|
3608
4642
|
};
|
|
3609
4643
|
var AngelDownIcon = SvgAngelDown;
|
|
3610
4644
|
|
|
3611
|
-
var _path$
|
|
3612
|
-
function _extends$
|
|
4645
|
+
var _path$e;
|
|
4646
|
+
function _extends$g() { _extends$g = 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$g.apply(this, arguments); }
|
|
3613
4647
|
var SvgAngelUp = function SvgAngelUp(props) {
|
|
3614
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
4648
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$g({
|
|
3615
4649
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3616
4650
|
width: 8,
|
|
3617
4651
|
height: 8
|
|
3618
|
-
}, props), _path$
|
|
4652
|
+
}, props), _path$e || (_path$e = /*#__PURE__*/React__namespace.createElement("path", {
|
|
3619
4653
|
fill: "currentColor",
|
|
3620
4654
|
fillRule: "evenodd",
|
|
3621
4655
|
stroke: "currentColor",
|
|
@@ -3626,11 +4660,12 @@ var SvgAngelUp = function SvgAngelUp(props) {
|
|
|
3626
4660
|
};
|
|
3627
4661
|
var AngelUpIcon = SvgAngelUp;
|
|
3628
4662
|
|
|
3629
|
-
const type$
|
|
4663
|
+
const type$7 = 'number';
|
|
3630
4664
|
function Numberfield(props) {
|
|
3631
4665
|
const {
|
|
3632
4666
|
disabled,
|
|
3633
4667
|
errors = [],
|
|
4668
|
+
onBlur,
|
|
3634
4669
|
field,
|
|
3635
4670
|
value,
|
|
3636
4671
|
readonly,
|
|
@@ -3763,7 +4798,7 @@ function Numberfield(props) {
|
|
|
3763
4798
|
} = hooks.useContext(FormContext$1);
|
|
3764
4799
|
const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`;
|
|
3765
4800
|
return jsxRuntime.jsxs("div", {
|
|
3766
|
-
class: formFieldClasses(type$
|
|
4801
|
+
class: formFieldClasses(type$7, {
|
|
3767
4802
|
errors,
|
|
3768
4803
|
disabled,
|
|
3769
4804
|
readonly
|
|
@@ -3791,7 +4826,8 @@ function Numberfield(props) {
|
|
|
3791
4826
|
readOnly: readonly,
|
|
3792
4827
|
id: prefixId(id, formId),
|
|
3793
4828
|
onKeyDown: onKeyDown,
|
|
3794
|
-
onKeyPress: onKeyPress
|
|
4829
|
+
onKeyPress: onKeyPress,
|
|
4830
|
+
onBlur: onBlur
|
|
3795
4831
|
|
|
3796
4832
|
// @ts-ignore
|
|
3797
4833
|
,
|
|
@@ -3834,7 +4870,7 @@ function Numberfield(props) {
|
|
|
3834
4870
|
});
|
|
3835
4871
|
}
|
|
3836
4872
|
Numberfield.config = {
|
|
3837
|
-
type: type$
|
|
4873
|
+
type: type$7,
|
|
3838
4874
|
keyed: true,
|
|
3839
4875
|
label: 'Number',
|
|
3840
4876
|
group: 'basic-input',
|
|
@@ -3857,11 +4893,12 @@ Numberfield.config = {
|
|
|
3857
4893
|
})
|
|
3858
4894
|
};
|
|
3859
4895
|
|
|
3860
|
-
const type$
|
|
4896
|
+
const type$6 = 'radio';
|
|
3861
4897
|
function Radio(props) {
|
|
3862
4898
|
const {
|
|
3863
4899
|
disabled,
|
|
3864
4900
|
errors = [],
|
|
4901
|
+
onBlur,
|
|
3865
4902
|
field,
|
|
3866
4903
|
readonly,
|
|
3867
4904
|
value
|
|
@@ -3872,6 +4909,7 @@ function Radio(props) {
|
|
|
3872
4909
|
label,
|
|
3873
4910
|
validate = {}
|
|
3874
4911
|
} = field;
|
|
4912
|
+
const outerDivRef = hooks.useRef();
|
|
3875
4913
|
const {
|
|
3876
4914
|
required
|
|
3877
4915
|
} = validate;
|
|
@@ -3881,6 +4919,12 @@ function Radio(props) {
|
|
|
3881
4919
|
value: v
|
|
3882
4920
|
});
|
|
3883
4921
|
};
|
|
4922
|
+
const onRadioBlur = e => {
|
|
4923
|
+
if (outerDivRef.current.contains(e.relatedTarget)) {
|
|
4924
|
+
return;
|
|
4925
|
+
}
|
|
4926
|
+
onBlur();
|
|
4927
|
+
};
|
|
3884
4928
|
const {
|
|
3885
4929
|
state: loadState,
|
|
3886
4930
|
values: options
|
|
@@ -3890,11 +4934,12 @@ function Radio(props) {
|
|
|
3890
4934
|
} = hooks.useContext(FormContext$1);
|
|
3891
4935
|
const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`;
|
|
3892
4936
|
return jsxRuntime.jsxs("div", {
|
|
3893
|
-
class: formFieldClasses(type$
|
|
4937
|
+
class: formFieldClasses(type$6, {
|
|
3894
4938
|
errors,
|
|
3895
4939
|
disabled,
|
|
3896
4940
|
readonly
|
|
3897
4941
|
}),
|
|
4942
|
+
ref: outerDivRef,
|
|
3898
4943
|
children: [jsxRuntime.jsx(Label, {
|
|
3899
4944
|
label: label,
|
|
3900
4945
|
required: required
|
|
@@ -3914,6 +4959,7 @@ function Radio(props) {
|
|
|
3914
4959
|
id: prefixId(`${id}-${index}`, formId),
|
|
3915
4960
|
type: "radio",
|
|
3916
4961
|
onClick: () => onChange(option.value),
|
|
4962
|
+
onBlur: onRadioBlur,
|
|
3917
4963
|
"aria-describedby": errorMessageId
|
|
3918
4964
|
})
|
|
3919
4965
|
}, `${id}-${index}`);
|
|
@@ -3926,37 +4972,23 @@ function Radio(props) {
|
|
|
3926
4972
|
});
|
|
3927
4973
|
}
|
|
3928
4974
|
Radio.config = {
|
|
3929
|
-
type: type$
|
|
4975
|
+
type: type$6,
|
|
3930
4976
|
keyed: true,
|
|
3931
4977
|
label: 'Radio',
|
|
3932
4978
|
group: 'selection',
|
|
3933
4979
|
emptyValue: null,
|
|
3934
4980
|
sanitizeValue: sanitizeSingleSelectValue,
|
|
3935
|
-
create:
|
|
3936
|
-
const defaults = {};
|
|
3937
|
-
|
|
3938
|
-
// provide default values if valuesKey isn't set
|
|
3939
|
-
if (!options.valuesKey) {
|
|
3940
|
-
defaults.values = [{
|
|
3941
|
-
label: 'Value',
|
|
3942
|
-
value: 'value'
|
|
3943
|
-
}];
|
|
3944
|
-
}
|
|
3945
|
-
return {
|
|
3946
|
-
...defaults,
|
|
3947
|
-
...options
|
|
3948
|
-
};
|
|
3949
|
-
}
|
|
4981
|
+
create: createEmptyOptions
|
|
3950
4982
|
};
|
|
3951
4983
|
|
|
3952
|
-
var _path$
|
|
3953
|
-
function _extends$
|
|
4984
|
+
var _path$d;
|
|
4985
|
+
function _extends$f() { _extends$f = 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$f.apply(this, arguments); }
|
|
3954
4986
|
var SvgXMark = function SvgXMark(props) {
|
|
3955
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
4987
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$f({
|
|
3956
4988
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3957
4989
|
width: 8,
|
|
3958
4990
|
height: 8
|
|
3959
|
-
}, props), _path$
|
|
4991
|
+
}, props), _path$d || (_path$d = /*#__PURE__*/React__namespace.createElement("path", {
|
|
3960
4992
|
fill: "currentColor",
|
|
3961
4993
|
fillRule: "evenodd",
|
|
3962
4994
|
stroke: "currentColor",
|
|
@@ -3972,6 +5004,7 @@ function SearchableSelect(props) {
|
|
|
3972
5004
|
id,
|
|
3973
5005
|
disabled,
|
|
3974
5006
|
errors,
|
|
5007
|
+
onBlur,
|
|
3975
5008
|
field,
|
|
3976
5009
|
readonly,
|
|
3977
5010
|
value
|
|
@@ -4091,6 +5124,7 @@ function SearchableSelect(props) {
|
|
|
4091
5124
|
onBlur: () => {
|
|
4092
5125
|
setIsDropdownExpanded(false);
|
|
4093
5126
|
setFilter(valueLabel);
|
|
5127
|
+
onBlur();
|
|
4094
5128
|
},
|
|
4095
5129
|
"aria-describedby": props['aria-describedby']
|
|
4096
5130
|
}), displayState.displayCross && jsxRuntime.jsxs("span", {
|
|
@@ -4125,6 +5159,7 @@ function SimpleSelect(props) {
|
|
|
4125
5159
|
id,
|
|
4126
5160
|
disabled,
|
|
4127
5161
|
errors,
|
|
5162
|
+
onBlur,
|
|
4128
5163
|
field,
|
|
4129
5164
|
readonly,
|
|
4130
5165
|
value
|
|
@@ -4179,7 +5214,10 @@ function SimpleSelect(props) {
|
|
|
4179
5214
|
'hasErrors': errors.length
|
|
4180
5215
|
}),
|
|
4181
5216
|
onFocus: () => setIsDropdownExpanded(true),
|
|
4182
|
-
onBlur: () =>
|
|
5217
|
+
onBlur: () => {
|
|
5218
|
+
setIsDropdownExpanded(false);
|
|
5219
|
+
onBlur();
|
|
5220
|
+
},
|
|
4183
5221
|
onMouseDown: onMouseDown,
|
|
4184
5222
|
children: [jsxRuntime.jsx("div", {
|
|
4185
5223
|
class: classNames('fjs-select-display', {
|
|
@@ -4221,11 +5259,12 @@ function SimpleSelect(props) {
|
|
|
4221
5259
|
});
|
|
4222
5260
|
}
|
|
4223
5261
|
|
|
4224
|
-
const type$
|
|
5262
|
+
const type$5 = 'select';
|
|
4225
5263
|
function Select(props) {
|
|
4226
5264
|
const {
|
|
4227
5265
|
disabled,
|
|
4228
5266
|
errors = [],
|
|
5267
|
+
onBlur,
|
|
4229
5268
|
field,
|
|
4230
5269
|
onChange,
|
|
4231
5270
|
readonly,
|
|
@@ -4249,14 +5288,15 @@ function Select(props) {
|
|
|
4249
5288
|
id,
|
|
4250
5289
|
disabled,
|
|
4251
5290
|
errors,
|
|
5291
|
+
onBlur,
|
|
4252
5292
|
field,
|
|
4253
5293
|
value,
|
|
4254
5294
|
onChange,
|
|
4255
5295
|
readonly,
|
|
4256
5296
|
'aria-describedby': errorMessageId
|
|
4257
|
-
}), [disabled, errors, field, id, value, onChange, readonly, errorMessageId]);
|
|
5297
|
+
}), [disabled, errors, field, id, value, onChange, onBlur, readonly, errorMessageId]);
|
|
4258
5298
|
return jsxRuntime.jsxs("div", {
|
|
4259
|
-
class: formFieldClasses(type$
|
|
5299
|
+
class: formFieldClasses(type$5, {
|
|
4260
5300
|
errors,
|
|
4261
5301
|
disabled,
|
|
4262
5302
|
readonly
|
|
@@ -4284,27 +5324,39 @@ function Select(props) {
|
|
|
4284
5324
|
});
|
|
4285
5325
|
}
|
|
4286
5326
|
Select.config = {
|
|
4287
|
-
type: type$
|
|
5327
|
+
type: type$5,
|
|
4288
5328
|
keyed: true,
|
|
4289
5329
|
label: 'Select',
|
|
4290
5330
|
group: 'selection',
|
|
4291
5331
|
emptyValue: null,
|
|
4292
5332
|
sanitizeValue: sanitizeSingleSelectValue,
|
|
4293
|
-
create:
|
|
4294
|
-
|
|
5333
|
+
create: createEmptyOptions
|
|
5334
|
+
};
|
|
4295
5335
|
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
5336
|
+
const type$4 = 'spacer';
|
|
5337
|
+
function Spacer(props) {
|
|
5338
|
+
const {
|
|
5339
|
+
field
|
|
5340
|
+
} = props;
|
|
5341
|
+
const {
|
|
5342
|
+
height = 60
|
|
5343
|
+
} = field;
|
|
5344
|
+
return jsxRuntime.jsx("div", {
|
|
5345
|
+
class: formFieldClasses(type$4),
|
|
5346
|
+
style: {
|
|
5347
|
+
height: height
|
|
4302
5348
|
}
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
5349
|
+
});
|
|
5350
|
+
}
|
|
5351
|
+
Spacer.config = {
|
|
5352
|
+
type: type$4,
|
|
5353
|
+
keyed: false,
|
|
5354
|
+
label: 'Spacer',
|
|
5355
|
+
group: 'presentation',
|
|
5356
|
+
create: (options = {}) => ({
|
|
5357
|
+
height: 60,
|
|
5358
|
+
...options
|
|
5359
|
+
})
|
|
4308
5360
|
};
|
|
4309
5361
|
|
|
4310
5362
|
const type$3 = 'taglist';
|
|
@@ -4312,6 +5364,7 @@ function Taglist(props) {
|
|
|
4312
5364
|
const {
|
|
4313
5365
|
disabled,
|
|
4314
5366
|
errors = [],
|
|
5367
|
+
onBlur,
|
|
4315
5368
|
field,
|
|
4316
5369
|
readonly,
|
|
4317
5370
|
value: values = []
|
|
@@ -4404,9 +5457,10 @@ function Taglist(props) {
|
|
|
4404
5457
|
break;
|
|
4405
5458
|
}
|
|
4406
5459
|
};
|
|
4407
|
-
const
|
|
5460
|
+
const onComponentBlur = () => {
|
|
4408
5461
|
setIsDropdownExpanded(false);
|
|
4409
5462
|
setFilter('');
|
|
5463
|
+
onBlur();
|
|
4410
5464
|
};
|
|
4411
5465
|
const onTagRemoveClick = (event, value) => {
|
|
4412
5466
|
const {
|
|
@@ -4477,9 +5531,7 @@ function Taglist(props) {
|
|
|
4477
5531
|
onKeyDown: onInputKeyDown,
|
|
4478
5532
|
onMouseDown: () => setIsEscapeClose(false),
|
|
4479
5533
|
onFocus: () => !readonly && setIsDropdownExpanded(true),
|
|
4480
|
-
onBlur: () =>
|
|
4481
|
-
!readonly && onBlur();
|
|
4482
|
-
},
|
|
5534
|
+
onBlur: () => !readonly && onComponentBlur(),
|
|
4483
5535
|
"aria-describedby": errorMessageId
|
|
4484
5536
|
})]
|
|
4485
5537
|
}), jsxRuntime.jsx("div", {
|
|
@@ -4506,21 +5558,7 @@ Taglist.config = {
|
|
|
4506
5558
|
group: 'selection',
|
|
4507
5559
|
emptyValue: [],
|
|
4508
5560
|
sanitizeValue: sanitizeMultiSelectValue,
|
|
4509
|
-
create:
|
|
4510
|
-
const defaults = {};
|
|
4511
|
-
|
|
4512
|
-
// provide default values if valuesKey isn't set
|
|
4513
|
-
if (!options.valuesKey) {
|
|
4514
|
-
defaults.values = [{
|
|
4515
|
-
label: 'Value',
|
|
4516
|
-
value: 'value'
|
|
4517
|
-
}];
|
|
4518
|
-
}
|
|
4519
|
-
return {
|
|
4520
|
-
...defaults,
|
|
4521
|
-
...options
|
|
4522
|
-
};
|
|
4523
|
-
}
|
|
5561
|
+
create: createEmptyOptions
|
|
4524
5562
|
};
|
|
4525
5563
|
|
|
4526
5564
|
const type$2 = 'text';
|
|
@@ -4612,6 +5650,7 @@ function Textfield(props) {
|
|
|
4612
5650
|
const {
|
|
4613
5651
|
disabled,
|
|
4614
5652
|
errors = [],
|
|
5653
|
+
onBlur,
|
|
4615
5654
|
field,
|
|
4616
5655
|
readonly,
|
|
4617
5656
|
value = ''
|
|
@@ -4663,6 +5702,7 @@ function Textfield(props) {
|
|
|
4663
5702
|
readOnly: readonly,
|
|
4664
5703
|
id: prefixId(id, formId),
|
|
4665
5704
|
onInput: onChange,
|
|
5705
|
+
onBlur: onBlur,
|
|
4666
5706
|
type: "text",
|
|
4667
5707
|
value: value,
|
|
4668
5708
|
"aria-describedby": errorMessageId
|
|
@@ -4704,6 +5744,7 @@ function Textarea(props) {
|
|
|
4704
5744
|
const {
|
|
4705
5745
|
disabled,
|
|
4706
5746
|
errors = [],
|
|
5747
|
+
onBlur,
|
|
4707
5748
|
field,
|
|
4708
5749
|
readonly,
|
|
4709
5750
|
value = ''
|
|
@@ -4726,22 +5767,12 @@ function Textarea(props) {
|
|
|
4726
5767
|
value: target.value
|
|
4727
5768
|
});
|
|
4728
5769
|
};
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
const computed = window.getComputedStyle(textarea);
|
|
4733
|
-
const calculatedHeight = parseInt(computed.getPropertyValue('border-top-width')) + parseInt(computed.getPropertyValue('padding-top')) + textarea.scrollHeight + parseInt(computed.getPropertyValue('padding-bottom')) + parseInt(computed.getPropertyValue('border-bottom-width'));
|
|
4734
|
-
const minHeight = 75;
|
|
4735
|
-
const maxHeight = 350;
|
|
4736
|
-
const displayHeight = Math.max(Math.min(calculatedHeight, maxHeight), minHeight);
|
|
4737
|
-
textarea.style.height = `${displayHeight}px`;
|
|
4738
|
-
|
|
4739
|
-
// Overflow is hidden by default to hide scrollbar flickering
|
|
4740
|
-
textarea.style.overflow = calculatedHeight > maxHeight ? 'visible' : 'hidden';
|
|
4741
|
-
}, []);
|
|
5770
|
+
hooks.useLayoutEffect(() => {
|
|
5771
|
+
autoSizeTextarea(textareaRef.current);
|
|
5772
|
+
}, [value]);
|
|
4742
5773
|
hooks.useEffect(() => {
|
|
4743
5774
|
autoSizeTextarea(textareaRef.current);
|
|
4744
|
-
}, [
|
|
5775
|
+
}, []);
|
|
4745
5776
|
const {
|
|
4746
5777
|
formId
|
|
4747
5778
|
} = hooks.useContext(FormContext$1);
|
|
@@ -4762,6 +5793,7 @@ function Textarea(props) {
|
|
|
4762
5793
|
readonly: readonly,
|
|
4763
5794
|
id: prefixId(id, formId),
|
|
4764
5795
|
onInput: onInput,
|
|
5796
|
+
onBlur: onBlur,
|
|
4765
5797
|
value: value,
|
|
4766
5798
|
ref: textareaRef,
|
|
4767
5799
|
"aria-describedby": errorMessageId
|
|
@@ -4786,40 +5818,58 @@ Textarea.config = {
|
|
|
4786
5818
|
...options
|
|
4787
5819
|
})
|
|
4788
5820
|
};
|
|
5821
|
+
const autoSizeTextarea = textarea => {
|
|
5822
|
+
// Ensures the textarea shrinks back, and improves resizing behavior consistency
|
|
5823
|
+
textarea.style.height = '0px';
|
|
5824
|
+
const computed = window.getComputedStyle(textarea);
|
|
5825
|
+
const heightFromLines = () => {
|
|
5826
|
+
const lineHeight = parseInt(computed.getPropertyValue('line-height').replace('px', '')) || 0;
|
|
5827
|
+
const lines = textarea.value ? textarea.value.toString().split('\n').length : 0;
|
|
5828
|
+
return lines * lineHeight;
|
|
5829
|
+
};
|
|
5830
|
+
const calculatedHeight = parseInt(computed.getPropertyValue('border-top-width')) + parseInt(computed.getPropertyValue('padding-top')) + (textarea.scrollHeight || heightFromLines()) + parseInt(computed.getPropertyValue('padding-bottom')) + parseInt(computed.getPropertyValue('border-bottom-width'));
|
|
5831
|
+
const minHeight = 75;
|
|
5832
|
+
const maxHeight = 350;
|
|
5833
|
+
const displayHeight = Math.max(Math.min(calculatedHeight || 0, maxHeight), minHeight);
|
|
5834
|
+
textarea.style.height = `${displayHeight}px`;
|
|
5835
|
+
|
|
5836
|
+
// Overflow is hidden by default to hide scrollbar flickering
|
|
5837
|
+
textarea.style.overflow = calculatedHeight > maxHeight ? 'visible' : 'hidden';
|
|
5838
|
+
};
|
|
4789
5839
|
|
|
4790
|
-
var _path$
|
|
4791
|
-
function _extends$
|
|
5840
|
+
var _path$c;
|
|
5841
|
+
function _extends$e() { _extends$e = 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$e.apply(this, arguments); }
|
|
4792
5842
|
var SvgButton = function SvgButton(props) {
|
|
4793
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
5843
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$e({
|
|
4794
5844
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4795
5845
|
width: 54,
|
|
4796
5846
|
height: 54,
|
|
4797
5847
|
fill: "currentcolor"
|
|
4798
|
-
}, props), _path$
|
|
5848
|
+
}, props), _path$c || (_path$c = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4799
5849
|
fillRule: "evenodd",
|
|
4800
5850
|
d: "M45 17a3 3 0 0 1 3 3v14a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V20a3 3 0 0 1 3-3h36zm-9 8.889H18v2.222h18v-2.222z"
|
|
4801
5851
|
})));
|
|
4802
5852
|
};
|
|
4803
5853
|
var ButtonIcon = SvgButton;
|
|
4804
5854
|
|
|
4805
|
-
var _path$
|
|
4806
|
-
function _extends$
|
|
5855
|
+
var _path$b;
|
|
5856
|
+
function _extends$d() { _extends$d = 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$d.apply(this, arguments); }
|
|
4807
5857
|
var SvgCheckbox = function SvgCheckbox(props) {
|
|
4808
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
5858
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$d({
|
|
4809
5859
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4810
5860
|
width: 54,
|
|
4811
5861
|
height: 54,
|
|
4812
5862
|
fill: "currentcolor"
|
|
4813
|
-
}, props), _path$
|
|
5863
|
+
}, props), _path$b || (_path$b = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4814
5864
|
d: "M34 18H20a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V20a2 2 0 0 0-2-2zm-9 14-5-5 1.41-1.41L25 29.17l7.59-7.59L34 23l-9 9z"
|
|
4815
5865
|
})));
|
|
4816
5866
|
};
|
|
4817
5867
|
var CheckboxIcon = SvgCheckbox;
|
|
4818
5868
|
|
|
4819
5869
|
var _g, _use, _use2, _use3, _defs;
|
|
4820
|
-
function _extends$
|
|
5870
|
+
function _extends$c() { _extends$c = 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$c.apply(this, arguments); }
|
|
4821
5871
|
var SvgChecklist = function SvgChecklist(props) {
|
|
4822
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
5872
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$c({
|
|
4823
5873
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4824
5874
|
xmlnsXlink: "http://www.w3.org/1999/xlink",
|
|
4825
5875
|
width: 54,
|
|
@@ -4853,18 +5903,18 @@ var SvgChecklist = function SvgChecklist(props) {
|
|
|
4853
5903
|
};
|
|
4854
5904
|
var ChecklistIcon = SvgChecklist;
|
|
4855
5905
|
|
|
4856
|
-
var _path$
|
|
4857
|
-
function _extends$
|
|
5906
|
+
var _path$a, _path2$3, _path3;
|
|
5907
|
+
function _extends$b() { _extends$b = 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$b.apply(this, arguments); }
|
|
4858
5908
|
var SvgDatetime = function SvgDatetime(props) {
|
|
4859
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
5909
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$b({
|
|
4860
5910
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4861
5911
|
width: 54,
|
|
4862
5912
|
height: 54,
|
|
4863
5913
|
fill: "currentcolor"
|
|
4864
|
-
}, props), _path$
|
|
5914
|
+
}, props), _path$a || (_path$a = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4865
5915
|
fillRule: "evenodd",
|
|
4866
5916
|
d: "M37.908 13.418h-5.004v-2.354h-1.766v2.354H21.13v-2.354h-1.766v2.354H14.36a2.07 2.07 0 0 0-2.06 2.06v23.549a2.07 2.07 0 0 0 2.06 2.06h6.77v-1.766h-6.358a.707.707 0 0 1-.706-.706V15.89c0-.39.316-.707.706-.707h4.592v2.355h1.766v-2.355h10.008v2.355h1.766v-2.355h4.592a.71.71 0 0 1 .707.707v6.358h1.765v-6.77c0-1.133-.927-2.06-2.06-2.06z"
|
|
4867
|
-
})), _path2$
|
|
5917
|
+
})), _path2$3 || (_path2$3 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4868
5918
|
d: "m35.13 37.603 1.237-1.237-3.468-3.475v-5.926h-1.754v6.654l3.984 3.984Z"
|
|
4869
5919
|
})), _path3 || (_path3 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4870
5920
|
fillRule: "evenodd",
|
|
@@ -4873,27 +5923,27 @@ var SvgDatetime = function SvgDatetime(props) {
|
|
|
4873
5923
|
};
|
|
4874
5924
|
var DatetimeIcon = SvgDatetime;
|
|
4875
5925
|
|
|
4876
|
-
var _path$
|
|
4877
|
-
function _extends$
|
|
5926
|
+
var _path$9, _path2$2;
|
|
5927
|
+
function _extends$a() { _extends$a = 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$a.apply(this, arguments); }
|
|
4878
5928
|
var SvgTaglist = function SvgTaglist(props) {
|
|
4879
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
5929
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$a({
|
|
4880
5930
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4881
5931
|
width: 54,
|
|
4882
5932
|
height: 54,
|
|
4883
5933
|
fill: "currentcolor"
|
|
4884
|
-
}, props), _path$
|
|
5934
|
+
}, props), _path$9 || (_path$9 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4885
5935
|
fillRule: "evenodd",
|
|
4886
5936
|
d: "M45 16a3 3 0 0 1 3 3v16a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V19a3 3 0 0 1 3-3h36Zm0 2H9a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h36a1 1 0 0 0 1-1V19a1 1 0 0 0-1-1Z"
|
|
4887
|
-
})), _path2$
|
|
5937
|
+
})), _path2$2 || (_path2$2 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4888
5938
|
d: "M11 22a1 1 0 0 1 1-1h19a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H12a1 1 0 0 1-1-1V22Z"
|
|
4889
5939
|
})));
|
|
4890
5940
|
};
|
|
4891
5941
|
var TaglistIcon = SvgTaglist;
|
|
4892
5942
|
|
|
4893
5943
|
var _rect, _rect2, _rect3;
|
|
4894
|
-
function _extends$
|
|
5944
|
+
function _extends$9() { _extends$9 = 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$9.apply(this, arguments); }
|
|
4895
5945
|
var SvgForm = function SvgForm(props) {
|
|
4896
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
5946
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$9({
|
|
4897
5947
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4898
5948
|
width: 54,
|
|
4899
5949
|
height: 54
|
|
@@ -4919,63 +5969,87 @@ var SvgForm = function SvgForm(props) {
|
|
|
4919
5969
|
};
|
|
4920
5970
|
var FormIcon = SvgForm;
|
|
4921
5971
|
|
|
5972
|
+
var _path$8;
|
|
5973
|
+
function _extends$8() { _extends$8 = 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$8.apply(this, arguments); }
|
|
5974
|
+
var SvgGroup = function SvgGroup(props) {
|
|
5975
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$8({
|
|
5976
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5977
|
+
width: 54,
|
|
5978
|
+
height: 54,
|
|
5979
|
+
fill: "currentcolor"
|
|
5980
|
+
}, props), _path$8 || (_path$8 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
5981
|
+
fillRule: "evenodd",
|
|
5982
|
+
d: "M8 33v5a1 1 0 0 0 1 1h4v2H9a3 3 0 0 1-3-3v-5h2Zm18 6v2H15v-2h11Zm13 0v2H28v-2h11Zm9-6v5a3 3 0 0 1-3 3h-4v-2h4a1 1 0 0 0 .993-.883L46 38v-5h2ZM8 22v9H6v-9h2Zm40 0v9h-2v-9h2Zm-35-9v2H9a1 1 0 0 0-.993.883L8 16v4H6v-4a3 3 0 0 1 3-3h4Zm32 0a3 3 0 0 1 3 3v4h-2v-4a1 1 0 0 0-.883-.993L45 15h-4v-2h4Zm-6 0v2H28v-2h11Zm-13 0v2H15v-2h11Z"
|
|
5983
|
+
})));
|
|
5984
|
+
};
|
|
5985
|
+
var GroupIcon = SvgGroup;
|
|
5986
|
+
|
|
4922
5987
|
var _path$7;
|
|
4923
5988
|
function _extends$7() { _extends$7 = 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$7.apply(this, arguments); }
|
|
4924
|
-
var
|
|
5989
|
+
var SvgNumber = function SvgNumber(props) {
|
|
4925
5990
|
return /*#__PURE__*/React__namespace.createElement("svg", _extends$7({
|
|
4926
5991
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4927
5992
|
width: 54,
|
|
4928
|
-
height: 54
|
|
5993
|
+
height: 54,
|
|
5994
|
+
fill: "currentcolor"
|
|
4929
5995
|
}, props), _path$7 || (_path$7 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4930
5996
|
fillRule: "evenodd",
|
|
4931
|
-
d: "
|
|
5997
|
+
d: "M45 16a3 3 0 0 1 3 3v16a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V19a3 3 0 0 1 3-3h36zm0 2H9a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h36a1 1 0 0 0 1-1V19a1 1 0 0 0-1-1zM35 28.444h7l-3.5 4-3.5-4zM35 26h7l-3.5-4-3.5 4z"
|
|
4932
5998
|
})));
|
|
4933
5999
|
};
|
|
4934
|
-
var
|
|
6000
|
+
var NumberIcon = SvgNumber;
|
|
4935
6001
|
|
|
4936
6002
|
var _path$6;
|
|
4937
6003
|
function _extends$6() { _extends$6 = 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$6.apply(this, arguments); }
|
|
4938
|
-
var
|
|
6004
|
+
var SvgRadio = function SvgRadio(props) {
|
|
4939
6005
|
return /*#__PURE__*/React__namespace.createElement("svg", _extends$6({
|
|
4940
6006
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4941
6007
|
width: 54,
|
|
4942
6008
|
height: 54,
|
|
4943
6009
|
fill: "currentcolor"
|
|
4944
6010
|
}, props), _path$6 || (_path$6 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4945
|
-
|
|
4946
|
-
d: "M45 16a3 3 0 0 1 3 3v16a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V19a3 3 0 0 1 3-3h36zm0 2H9a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h36a1 1 0 0 0 1-1V19a1 1 0 0 0-1-1zM35 28.444h7l-3.5 4-3.5-4zM35 26h7l-3.5-4-3.5 4z"
|
|
6011
|
+
d: "M27 22c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm0 18a8 8 0 1 1 0-16 8 8 0 1 1 0 16z"
|
|
4947
6012
|
})));
|
|
4948
6013
|
};
|
|
4949
|
-
var
|
|
6014
|
+
var RadioIcon = SvgRadio;
|
|
4950
6015
|
|
|
4951
6016
|
var _path$5;
|
|
4952
6017
|
function _extends$5() { _extends$5 = 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$5.apply(this, arguments); }
|
|
4953
|
-
var
|
|
6018
|
+
var SvgSelect = function SvgSelect(props) {
|
|
4954
6019
|
return /*#__PURE__*/React__namespace.createElement("svg", _extends$5({
|
|
4955
6020
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4956
6021
|
width: 54,
|
|
4957
6022
|
height: 54,
|
|
4958
6023
|
fill: "currentcolor"
|
|
4959
6024
|
}, props), _path$5 || (_path$5 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4960
|
-
|
|
6025
|
+
fillRule: "evenodd",
|
|
6026
|
+
d: "M45 16a3 3 0 0 1 3 3v16a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V19a3 3 0 0 1 3-3h36zm0 2H9a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h36a1 1 0 0 0 1-1V19a1 1 0 0 0-1-1zm-12 7h9l-4.5 6-4.5-6z"
|
|
4961
6027
|
})));
|
|
4962
6028
|
};
|
|
4963
|
-
var
|
|
6029
|
+
var SelectIcon = SvgSelect;
|
|
4964
6030
|
|
|
4965
|
-
var _path$4;
|
|
6031
|
+
var _path$4, _path2$1;
|
|
4966
6032
|
function _extends$4() { _extends$4 = 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$4.apply(this, arguments); }
|
|
4967
|
-
var
|
|
6033
|
+
var SvgSpacer = function SvgSpacer(props) {
|
|
4968
6034
|
return /*#__PURE__*/React__namespace.createElement("svg", _extends$4({
|
|
4969
6035
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4970
6036
|
width: 54,
|
|
4971
6037
|
height: 54,
|
|
4972
6038
|
fill: "currentcolor"
|
|
4973
6039
|
}, props), _path$4 || (_path$4 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
4974
|
-
|
|
4975
|
-
|
|
6040
|
+
stroke: "currentcolor",
|
|
6041
|
+
strokeLinecap: "square",
|
|
6042
|
+
strokeWidth: 2,
|
|
6043
|
+
d: "M9 23h36M9 31h36"
|
|
6044
|
+
})), _path2$1 || (_path2$1 = /*#__PURE__*/React__namespace.createElement("path", {
|
|
6045
|
+
stroke: "currentcolor",
|
|
6046
|
+
strokeLinecap: "round",
|
|
6047
|
+
strokeLinejoin: "round",
|
|
6048
|
+
strokeWidth: 2,
|
|
6049
|
+
d: "m23 17 4-4 4 4M31 37l-4 4-4-4"
|
|
4976
6050
|
})));
|
|
4977
6051
|
};
|
|
4978
|
-
var
|
|
6052
|
+
var SpacerIcon = SvgSpacer;
|
|
4979
6053
|
|
|
4980
6054
|
var _path$3;
|
|
4981
6055
|
function _extends$3() { _extends$3 = 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$3.apply(this, arguments); }
|
|
@@ -5046,12 +6120,14 @@ const iconsByType = type => {
|
|
|
5046
6120
|
button: ButtonIcon,
|
|
5047
6121
|
checkbox: CheckboxIcon,
|
|
5048
6122
|
checklist: ChecklistIcon,
|
|
5049
|
-
columns:
|
|
6123
|
+
columns: GroupIcon,
|
|
5050
6124
|
datetime: DatetimeIcon,
|
|
6125
|
+
group: GroupIcon,
|
|
5051
6126
|
image: ImageIcon,
|
|
5052
6127
|
number: NumberIcon,
|
|
5053
6128
|
radio: RadioIcon,
|
|
5054
6129
|
select: SelectIcon,
|
|
6130
|
+
spacer: SpacerIcon,
|
|
5055
6131
|
taglist: TaglistIcon,
|
|
5056
6132
|
text: TextIcon,
|
|
5057
6133
|
textfield: TextfieldIcon,
|
|
@@ -5060,7 +6136,7 @@ const iconsByType = type => {
|
|
|
5060
6136
|
}[type];
|
|
5061
6137
|
};
|
|
5062
6138
|
|
|
5063
|
-
const formFields = [Button, Checkbox, Checklist,
|
|
6139
|
+
const formFields = [Button, Checkbox, Checklist, FormComponent$1, Group, Image, Numberfield, Datetime, Radio, Select, Spacer, Taglist, Text, Textfield, Textarea];
|
|
5064
6140
|
|
|
5065
6141
|
class FormFields {
|
|
5066
6142
|
constructor() {
|
|
@@ -5136,9 +6212,12 @@ var renderModule = {
|
|
|
5136
6212
|
};
|
|
5137
6213
|
|
|
5138
6214
|
var core = {
|
|
5139
|
-
__depends__: [
|
|
6215
|
+
__depends__: [renderModule],
|
|
5140
6216
|
eventBus: ['type', EventBus],
|
|
6217
|
+
importer: ['type', Importer],
|
|
6218
|
+
fieldFactory: ['type', FieldFactory],
|
|
5141
6219
|
formFieldRegistry: ['type', FormFieldRegistry],
|
|
6220
|
+
pathRegistry: ['type', PathRegistry],
|
|
5142
6221
|
formLayouter: ['type', FormLayouter],
|
|
5143
6222
|
validator: ['type', Validator]
|
|
5144
6223
|
};
|
|
@@ -5253,9 +6332,9 @@ class Form {
|
|
|
5253
6332
|
this.clear();
|
|
5254
6333
|
const {
|
|
5255
6334
|
schema: importedSchema,
|
|
5256
|
-
data: initializedData,
|
|
5257
6335
|
warnings
|
|
5258
|
-
} = this.get('importer').importSchema(schema
|
|
6336
|
+
} = this.get('importer').importSchema(schema);
|
|
6337
|
+
const initializedData = this._initializeFieldData(clone(data));
|
|
5259
6338
|
this._setState({
|
|
5260
6339
|
data: initializedData,
|
|
5261
6340
|
errors: {},
|
|
@@ -5313,21 +6392,21 @@ class Form {
|
|
|
5313
6392
|
*/
|
|
5314
6393
|
validate() {
|
|
5315
6394
|
const formFieldRegistry = this.get('formFieldRegistry'),
|
|
6395
|
+
pathRegistry = this.get('pathRegistry'),
|
|
5316
6396
|
validator = this.get('validator');
|
|
5317
6397
|
const {
|
|
5318
6398
|
data
|
|
5319
6399
|
} = this._getState();
|
|
5320
6400
|
const errors = formFieldRegistry.getAll().reduce((errors, field) => {
|
|
5321
6401
|
const {
|
|
5322
|
-
disabled
|
|
5323
|
-
_path
|
|
6402
|
+
disabled
|
|
5324
6403
|
} = field;
|
|
5325
6404
|
if (disabled) {
|
|
5326
6405
|
return errors;
|
|
5327
6406
|
}
|
|
5328
|
-
const value = minDash.get(data,
|
|
6407
|
+
const value = minDash.get(data, pathRegistry.getValuePath(field));
|
|
5329
6408
|
const fieldErrors = validator.validateField(field, value);
|
|
5330
|
-
return minDash.set(errors, [
|
|
6409
|
+
return minDash.set(errors, [field.id], fieldErrors.length ? fieldErrors : undefined);
|
|
5331
6410
|
}, /** @type {Errors} */{});
|
|
5332
6411
|
this._setState({
|
|
5333
6412
|
errors
|
|
@@ -5433,16 +6512,14 @@ class Form {
|
|
|
5433
6512
|
value
|
|
5434
6513
|
} = update;
|
|
5435
6514
|
const {
|
|
5436
|
-
_path
|
|
5437
|
-
} = field;
|
|
5438
|
-
let {
|
|
5439
6515
|
data,
|
|
5440
6516
|
errors
|
|
5441
6517
|
} = this._getState();
|
|
5442
|
-
const validator = this.get('validator')
|
|
6518
|
+
const validator = this.get('validator'),
|
|
6519
|
+
pathRegistry = this.get('pathRegistry');
|
|
5443
6520
|
const fieldErrors = validator.validateField(field, value);
|
|
5444
|
-
minDash.set(data,
|
|
5445
|
-
minDash.set(errors, [
|
|
6521
|
+
minDash.set(data, pathRegistry.getValuePath(field), value);
|
|
6522
|
+
minDash.set(errors, [field.id], fieldErrors.length ? fieldErrors : undefined);
|
|
5446
6523
|
this._setState({
|
|
5447
6524
|
data: clone(data),
|
|
5448
6525
|
errors: clone(errors)
|
|
@@ -5471,7 +6548,7 @@ class Form {
|
|
|
5471
6548
|
* @internal
|
|
5472
6549
|
*/
|
|
5473
6550
|
_getModules() {
|
|
5474
|
-
return [ExpressionLanguageModule, MarkdownModule];
|
|
6551
|
+
return [ExpressionLanguageModule, MarkdownModule, ViewerCommandsModule];
|
|
5475
6552
|
}
|
|
5476
6553
|
|
|
5477
6554
|
/**
|
|
@@ -5485,23 +6562,26 @@ class Form {
|
|
|
5485
6562
|
* @internal
|
|
5486
6563
|
*/
|
|
5487
6564
|
_getSubmitData() {
|
|
5488
|
-
const formFieldRegistry = this.get('formFieldRegistry')
|
|
6565
|
+
const formFieldRegistry = this.get('formFieldRegistry'),
|
|
6566
|
+
pathRegistry = this.get('pathRegistry'),
|
|
6567
|
+
formFields = this.get('formFields');
|
|
5489
6568
|
const formData = this._getState().data;
|
|
5490
6569
|
const submitData = formFieldRegistry.getAll().reduce((previous, field) => {
|
|
5491
6570
|
const {
|
|
5492
6571
|
disabled,
|
|
5493
|
-
|
|
6572
|
+
type
|
|
5494
6573
|
} = field;
|
|
6574
|
+
const {
|
|
6575
|
+
config: fieldConfig
|
|
6576
|
+
} = formFields.get(type);
|
|
5495
6577
|
|
|
5496
|
-
// do not submit disabled form fields
|
|
5497
|
-
if (disabled || !
|
|
6578
|
+
// do not submit disabled form fields or routing fields
|
|
6579
|
+
if (disabled || !fieldConfig.keyed) {
|
|
5498
6580
|
return previous;
|
|
5499
6581
|
}
|
|
5500
|
-
const
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
[_path[0]]: value
|
|
5504
|
-
};
|
|
6582
|
+
const valuePath = pathRegistry.getValuePath(field);
|
|
6583
|
+
const value = minDash.get(formData, valuePath);
|
|
6584
|
+
return minDash.set(previous, valuePath, value);
|
|
5505
6585
|
}, {});
|
|
5506
6586
|
const filteredSubmitData = this._applyConditions(submitData, formData);
|
|
5507
6587
|
return filteredSubmitData;
|
|
@@ -5514,9 +6594,46 @@ class Form {
|
|
|
5514
6594
|
const conditionChecker = this.get('conditionChecker');
|
|
5515
6595
|
return conditionChecker.applyConditions(toFilter, data);
|
|
5516
6596
|
}
|
|
6597
|
+
|
|
6598
|
+
/**
|
|
6599
|
+
* @internal
|
|
6600
|
+
*/
|
|
6601
|
+
_initializeFieldData(data) {
|
|
6602
|
+
const formFieldRegistry = this.get('formFieldRegistry'),
|
|
6603
|
+
formFields = this.get('formFields'),
|
|
6604
|
+
pathRegistry = this.get('pathRegistry');
|
|
6605
|
+
return formFieldRegistry.getAll().reduce((initializedData, formField) => {
|
|
6606
|
+
const {
|
|
6607
|
+
defaultValue,
|
|
6608
|
+
type
|
|
6609
|
+
} = formField;
|
|
6610
|
+
|
|
6611
|
+
// try to get value from data
|
|
6612
|
+
// if unavailable - try to get default value from form field
|
|
6613
|
+
// if unavailable - get empty value from form field
|
|
6614
|
+
|
|
6615
|
+
const valuePath = pathRegistry.getValuePath(formField);
|
|
6616
|
+
if (valuePath) {
|
|
6617
|
+
const {
|
|
6618
|
+
config: fieldConfig
|
|
6619
|
+
} = formFields.get(type);
|
|
6620
|
+
let valueData = minDash.get(data, valuePath);
|
|
6621
|
+
if (!minDash.isUndefined(valueData) && fieldConfig.sanitizeValue) {
|
|
6622
|
+
valueData = fieldConfig.sanitizeValue({
|
|
6623
|
+
formField,
|
|
6624
|
+
data,
|
|
6625
|
+
value: valueData
|
|
6626
|
+
});
|
|
6627
|
+
}
|
|
6628
|
+
const initializedFieldValue = !minDash.isUndefined(valueData) ? valueData : !minDash.isUndefined(defaultValue) ? defaultValue : fieldConfig.emptyValue;
|
|
6629
|
+
return minDash.set(initializedData, valuePath, initializedFieldValue);
|
|
6630
|
+
}
|
|
6631
|
+
return initializedData;
|
|
6632
|
+
}, data);
|
|
6633
|
+
}
|
|
5517
6634
|
}
|
|
5518
6635
|
|
|
5519
|
-
const schemaVersion =
|
|
6636
|
+
const schemaVersion = 11;
|
|
5520
6637
|
|
|
5521
6638
|
/**
|
|
5522
6639
|
* @typedef { import('./types').CreateFormOptions } CreateFormOptions
|
|
@@ -5551,10 +6668,11 @@ exports.DATETIME_SUBTYPE_PATH = DATETIME_SUBTYPE_PATH;
|
|
|
5551
6668
|
exports.DATE_DISALLOW_PAST_PATH = DATE_DISALLOW_PAST_PATH;
|
|
5552
6669
|
exports.DATE_LABEL_PATH = DATE_LABEL_PATH;
|
|
5553
6670
|
exports.Datetime = Datetime;
|
|
5554
|
-
exports.Default =
|
|
6671
|
+
exports.Default = FormComponent$1;
|
|
5555
6672
|
exports.ExpressionLanguageModule = ExpressionLanguageModule;
|
|
5556
6673
|
exports.FeelExpressionLanguage = FeelExpressionLanguage;
|
|
5557
6674
|
exports.FeelersTemplating = FeelersTemplating;
|
|
6675
|
+
exports.FieldFactory = FieldFactory;
|
|
5558
6676
|
exports.Form = Form;
|
|
5559
6677
|
exports.FormComponent = FormComponent;
|
|
5560
6678
|
exports.FormContext = FormContext$1;
|
|
@@ -5562,13 +6680,17 @@ exports.FormFieldRegistry = FormFieldRegistry;
|
|
|
5562
6680
|
exports.FormFields = FormFields;
|
|
5563
6681
|
exports.FormLayouter = FormLayouter;
|
|
5564
6682
|
exports.FormRenderContext = FormRenderContext$1;
|
|
6683
|
+
exports.Group = Group;
|
|
5565
6684
|
exports.Image = Image;
|
|
6685
|
+
exports.Importer = Importer;
|
|
5566
6686
|
exports.MINUTES_IN_DAY = MINUTES_IN_DAY;
|
|
5567
6687
|
exports.MarkdownModule = MarkdownModule;
|
|
5568
6688
|
exports.MarkdownRenderer = MarkdownRenderer;
|
|
5569
6689
|
exports.Numberfield = Numberfield;
|
|
6690
|
+
exports.PathRegistry = PathRegistry;
|
|
5570
6691
|
exports.Radio = Radio;
|
|
5571
6692
|
exports.Select = Select;
|
|
6693
|
+
exports.Spacer = Spacer;
|
|
5572
6694
|
exports.TIME_INTERVAL_PATH = TIME_INTERVAL_PATH;
|
|
5573
6695
|
exports.TIME_LABEL_PATH = TIME_LABEL_PATH;
|
|
5574
6696
|
exports.TIME_SERIALISINGFORMAT_LABELS = TIME_SERIALISINGFORMAT_LABELS;
|
|
@@ -5584,11 +6706,12 @@ exports.VALUES_SOURCES_DEFAULTS = VALUES_SOURCES_DEFAULTS;
|
|
|
5584
6706
|
exports.VALUES_SOURCES_LABELS = VALUES_SOURCES_LABELS;
|
|
5585
6707
|
exports.VALUES_SOURCES_PATHS = VALUES_SOURCES_PATHS;
|
|
5586
6708
|
exports.VALUES_SOURCE_DEFAULT = VALUES_SOURCE_DEFAULT;
|
|
6709
|
+
exports.ViewerCommands = ViewerCommands;
|
|
6710
|
+
exports.ViewerCommandsModule = ViewerCommandsModule;
|
|
5587
6711
|
exports.clone = clone;
|
|
5588
6712
|
exports.createForm = createForm;
|
|
5589
6713
|
exports.createFormContainer = createFormContainer;
|
|
5590
6714
|
exports.createInjector = createInjector;
|
|
5591
|
-
exports.findErrors = findErrors;
|
|
5592
6715
|
exports.formFields = formFields;
|
|
5593
6716
|
exports.generateIdForType = generateIdForType;
|
|
5594
6717
|
exports.generateIndexForType = generateIndexForType;
|
|
@@ -5597,7 +6720,7 @@ exports.getValuesSource = getValuesSource;
|
|
|
5597
6720
|
exports.iconsByType = iconsByType;
|
|
5598
6721
|
exports.isRequired = isRequired;
|
|
5599
6722
|
exports.pathParse = pathParse;
|
|
5600
|
-
exports.pathStringify = pathStringify;
|
|
5601
6723
|
exports.pathsEqual = pathsEqual;
|
|
6724
|
+
exports.runRecursively = runRecursively;
|
|
5602
6725
|
exports.schemaVersion = schemaVersion;
|
|
5603
6726
|
//# sourceMappingURL=index.cjs.map
|