@bpmn-io/form-js-playground 0.13.1 → 0.14.1
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.
|
@@ -49251,15 +49251,163 @@
|
|
|
49251
49251
|
return value;
|
|
49252
49252
|
}
|
|
49253
49253
|
|
|
49254
|
+
const getFlavouredFeelVariableNames = (feelString, feelFlavour, options = {}) => {
|
|
49255
|
+
const {
|
|
49256
|
+
depth = 0,
|
|
49257
|
+
specialDepthAccessors = {}
|
|
49258
|
+
} = options;
|
|
49259
|
+
if (!['expression', 'unaryTest'].includes(feelFlavour)) return [];
|
|
49260
|
+
const tree = feelFlavour === 'expression' ? parseExpressions$1(feelString) : parseUnaryTests$1(feelString);
|
|
49261
|
+
const simpleExpressionTree = _buildSimpleFeelStructureTree(tree, feelString);
|
|
49262
|
+
return function _unfoldVariables(node) {
|
|
49263
|
+
if (node.name === 'PathExpression') {
|
|
49264
|
+
if (Object.keys(specialDepthAccessors).length === 0) {
|
|
49265
|
+
return depth === 0 ? [_getVariableNameAtPathIndex(node, 0)] : [];
|
|
49266
|
+
}
|
|
49267
|
+
|
|
49268
|
+
// if using special depth accessors, use a more complex extraction
|
|
49269
|
+
return Array.from(_smartExtractVariableNames(node, depth, specialDepthAccessors));
|
|
49270
|
+
}
|
|
49271
|
+
if (depth === 0 && node.name === 'VariableName') return [node.variableName];
|
|
49272
|
+
|
|
49273
|
+
// for any other kind of node, traverse its children and flatten the result
|
|
49274
|
+
if (node.children) {
|
|
49275
|
+
return node.children.reduce((acc, child) => {
|
|
49276
|
+
return acc.concat(_unfoldVariables(child));
|
|
49277
|
+
}, []);
|
|
49278
|
+
}
|
|
49279
|
+
return [];
|
|
49280
|
+
}(simpleExpressionTree);
|
|
49281
|
+
};
|
|
49282
|
+
|
|
49283
|
+
/**
|
|
49284
|
+
* Get the variable name at the specified index in a given path expression.
|
|
49285
|
+
*
|
|
49286
|
+
* @param {Object} root - The root node of the path expression tree.
|
|
49287
|
+
* @param {number} index - The index of the variable name to retrieve.
|
|
49288
|
+
* @returns {string|null} The variable name at the specified index or null if index is out of bounds.
|
|
49289
|
+
*/
|
|
49290
|
+
const _getVariableNameAtPathIndex = (root, index) => {
|
|
49291
|
+
const accessors = _deconstructPathExpression(root);
|
|
49292
|
+
return accessors[index] || null;
|
|
49293
|
+
};
|
|
49294
|
+
|
|
49295
|
+
/**
|
|
49296
|
+
* Extracts the variables which are required of the external context for a given path expression.
|
|
49297
|
+
* This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
|
|
49298
|
+
*
|
|
49299
|
+
* @param {Object} node - The root node of the path expression tree.
|
|
49300
|
+
* @param {number} initialDepth - The depth at which the root node is located in the outer context.
|
|
49301
|
+
* @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
|
|
49302
|
+
* @returns {Set} - A set containing the extracted variable names.
|
|
49303
|
+
*/
|
|
49304
|
+
const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) => {
|
|
49305
|
+
// depth info represents the previous (initialised as null) and current depth of the current accessor in the path expression
|
|
49306
|
+
// we track multiple of these to account for the fact that a path expression may be ambiguous due to special keywords
|
|
49307
|
+
let accessorDepthInfos = [{
|
|
49308
|
+
previous: null,
|
|
49309
|
+
current: initialDepth - 1
|
|
49310
|
+
}];
|
|
49311
|
+
const extractedVariables = new Set();
|
|
49312
|
+
const nodeAccessors = _deconstructPathExpression(node);
|
|
49313
|
+
for (let i = 0; i < nodeAccessors.length; i++) {
|
|
49314
|
+
const currentAccessor = nodeAccessors[i];
|
|
49315
|
+
if (currentAccessor in specialDepthAccessors) {
|
|
49316
|
+
const depthOffsets = specialDepthAccessors[currentAccessor];
|
|
49317
|
+
|
|
49318
|
+
// if the current accessor is a special keyword, we need to expand the current depth info set
|
|
49319
|
+
// this is done to account for the ambiguity of keywords like parent, which may be used to access
|
|
49320
|
+
// the parent of the current node, or a child variable of the same name
|
|
49321
|
+
accessorDepthInfos = depthOffsets.reduce((accumulator, offset) => {
|
|
49322
|
+
return [...accumulator, ...accessorDepthInfos.map(depthInfo => ({
|
|
49323
|
+
previous: depthInfo.current,
|
|
49324
|
+
current: depthInfo.current + offset
|
|
49325
|
+
}))];
|
|
49326
|
+
}, []).filter(depthInfo => depthInfo.current >= -1); // discard all depth infos which are out of bounds
|
|
49327
|
+
} else {
|
|
49328
|
+
// if the current accessor is not a special keyword, we know it's simply accessing a child
|
|
49329
|
+
// hence we are now one level deeper in the tree and simply increment
|
|
49330
|
+
accessorDepthInfos = accessorDepthInfos.map(depthInfo => ({
|
|
49331
|
+
previous: depthInfo.current,
|
|
49332
|
+
current: depthInfo.current + 1
|
|
49333
|
+
}));
|
|
49334
|
+
}
|
|
49335
|
+
|
|
49336
|
+
// finally, we check if for the current accessor, there is a scenario where:
|
|
49337
|
+
// previous it was at depth -1 (i.e. the root context), and is now at depth 0 (i.e. a variable)
|
|
49338
|
+
// these are the variables we need to request, so we add them to the set
|
|
49339
|
+
if (accessorDepthInfos.some(depthInfo => depthInfo.previous === -1 && depthInfo.current === 0)) {
|
|
49340
|
+
extractedVariables.add(currentAccessor);
|
|
49341
|
+
}
|
|
49342
|
+
}
|
|
49343
|
+
|
|
49344
|
+
// we return a set to avoid duplicates
|
|
49345
|
+
return new Set(extractedVariables);
|
|
49346
|
+
};
|
|
49347
|
+
|
|
49348
|
+
/**
|
|
49349
|
+
* Deconstructs a path expression tree into an array of components.
|
|
49350
|
+
*
|
|
49351
|
+
* @param {Object} root - The root node of the path expression tree.
|
|
49352
|
+
* @returns {Array<string>} An array of components in the path expression, in the correct order.
|
|
49353
|
+
*/
|
|
49354
|
+
const _deconstructPathExpression = root => {
|
|
49355
|
+
let node = root;
|
|
49356
|
+
let parts = [];
|
|
49357
|
+
|
|
49358
|
+
// Traverse the tree and collect path components
|
|
49359
|
+
while (node.name === 'PathExpression') {
|
|
49360
|
+
parts.push(node.children[1].variableName);
|
|
49361
|
+
node = node.children[0];
|
|
49362
|
+
}
|
|
49363
|
+
|
|
49364
|
+
// Add the last component to the array
|
|
49365
|
+
parts.push(node.variableName);
|
|
49366
|
+
|
|
49367
|
+
// Reverse and return the array to get the correct order
|
|
49368
|
+
return parts.reverse();
|
|
49369
|
+
};
|
|
49370
|
+
|
|
49371
|
+
/**
|
|
49372
|
+
* Builds a simplified feel structure tree from the given parse tree and feel string.
|
|
49373
|
+
* The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
|
|
49374
|
+
*
|
|
49375
|
+
* @param {Object} parseTree - The parse tree generated by a parser.
|
|
49376
|
+
* @param {string} feelString - The feel string used for parsing.
|
|
49377
|
+
* @returns {Object} The simplified feel structure tree.
|
|
49378
|
+
*/
|
|
49379
|
+
const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
|
|
49380
|
+
const stack = [{
|
|
49381
|
+
children: []
|
|
49382
|
+
}];
|
|
49383
|
+
parseTree.iterate({
|
|
49384
|
+
enter: node => {
|
|
49385
|
+
const nodeRepresentation = {
|
|
49386
|
+
name: node.type.name,
|
|
49387
|
+
children: []
|
|
49388
|
+
};
|
|
49389
|
+
if (node.type.name === 'VariableName') {
|
|
49390
|
+
nodeRepresentation.variableName = feelString.slice(node.from, node.to);
|
|
49391
|
+
}
|
|
49392
|
+
stack.push(nodeRepresentation);
|
|
49393
|
+
},
|
|
49394
|
+
leave: () => {
|
|
49395
|
+
const result = stack.pop();
|
|
49396
|
+
const parent = stack[stack.length - 1];
|
|
49397
|
+
parent.children.push(result);
|
|
49398
|
+
}
|
|
49399
|
+
});
|
|
49400
|
+
return stack[0].children[0];
|
|
49401
|
+
};
|
|
49254
49402
|
class FeelExpressionLanguage {
|
|
49255
49403
|
constructor(eventBus) {
|
|
49256
49404
|
this._eventBus = eventBus;
|
|
49257
49405
|
}
|
|
49258
49406
|
|
|
49259
49407
|
/**
|
|
49260
|
-
* Determines if the given
|
|
49408
|
+
* Determines if the given value is a FEEL expression.
|
|
49261
49409
|
*
|
|
49262
|
-
* @param {
|
|
49410
|
+
* @param {any} value
|
|
49263
49411
|
* @returns {boolean}
|
|
49264
49412
|
*
|
|
49265
49413
|
*/
|
|
@@ -49283,12 +49431,10 @@
|
|
|
49283
49431
|
if (!this.isExpression(expression)) {
|
|
49284
49432
|
return [];
|
|
49285
49433
|
}
|
|
49286
|
-
if (
|
|
49287
|
-
|
|
49288
|
-
} else if (type === 'expression') {
|
|
49289
|
-
return this._getExpressionVariableNames(expression);
|
|
49434
|
+
if (!['unaryTest', 'expression'].includes(type)) {
|
|
49435
|
+
throw new Error('Unknown expression type: ' + type);
|
|
49290
49436
|
}
|
|
49291
|
-
|
|
49437
|
+
return getFlavouredFeelVariableNames(expression, type);
|
|
49292
49438
|
}
|
|
49293
49439
|
|
|
49294
49440
|
/**
|
|
@@ -49316,36 +49462,51 @@
|
|
|
49316
49462
|
return null;
|
|
49317
49463
|
}
|
|
49318
49464
|
}
|
|
49319
|
-
_getExpressionVariableNames(expression) {
|
|
49320
|
-
const tree = parseExpressions$1(expression);
|
|
49321
|
-
const cursor = tree.cursor();
|
|
49322
|
-
const variables = new Set();
|
|
49323
|
-
do {
|
|
49324
|
-
const node = cursor.node;
|
|
49325
|
-
if (node.type.name === 'VariableName') {
|
|
49326
|
-
variables.add(expression.slice(node.from, node.to));
|
|
49327
|
-
}
|
|
49328
|
-
} while (cursor.next());
|
|
49329
|
-
return Array.from(variables);
|
|
49330
|
-
}
|
|
49331
|
-
_getUnaryVariableNames(unaryTest) {
|
|
49332
|
-
const tree = parseUnaryTests$1(unaryTest);
|
|
49333
|
-
const cursor = tree.cursor();
|
|
49334
|
-
const variables = new Set();
|
|
49335
|
-
do {
|
|
49336
|
-
const node = cursor.node;
|
|
49337
|
-
if (node.type.name === 'VariableName') {
|
|
49338
|
-
variables.add(unaryTest.slice(node.from, node.to));
|
|
49339
|
-
}
|
|
49340
|
-
} while (cursor.next());
|
|
49341
|
-
return Array.from(variables);
|
|
49342
|
-
}
|
|
49343
49465
|
}
|
|
49344
49466
|
FeelExpressionLanguage.$inject = ['eventBus'];
|
|
49345
49467
|
class FeelersTemplating {
|
|
49346
49468
|
constructor() {}
|
|
49469
|
+
|
|
49470
|
+
/**
|
|
49471
|
+
* Determines if the given value is a feelers template.
|
|
49472
|
+
*
|
|
49473
|
+
* @param {any} value
|
|
49474
|
+
* @returns {boolean}
|
|
49475
|
+
*
|
|
49476
|
+
*/
|
|
49347
49477
|
isTemplate(value) {
|
|
49348
|
-
return isString$4(value) && (value.startsWith('=') || /{{/.test(value));
|
|
49478
|
+
return isString$4(value) && (value.startsWith('=') || /{{.*?}}/.test(value));
|
|
49479
|
+
}
|
|
49480
|
+
|
|
49481
|
+
/**
|
|
49482
|
+
* Retrieve variable names from a given feelers template.
|
|
49483
|
+
*
|
|
49484
|
+
* @param {string} template
|
|
49485
|
+
*
|
|
49486
|
+
* @returns {string[]}
|
|
49487
|
+
*/
|
|
49488
|
+
getVariableNames(template) {
|
|
49489
|
+
if (!this.isTemplate(template)) {
|
|
49490
|
+
return [];
|
|
49491
|
+
}
|
|
49492
|
+
const expressions = this._extractExpressionsWithDepth(template);
|
|
49493
|
+
|
|
49494
|
+
// defines special accessors, and the change(s) in depth they could imply (e.g. parent can be used to access the parent context (depth - 1) or a child variable named parent (depth + 1)
|
|
49495
|
+
const specialDepthAccessors = {
|
|
49496
|
+
parent: [-1, 1],
|
|
49497
|
+
_parent_: [-1],
|
|
49498
|
+
this: [0, 1],
|
|
49499
|
+
_this_: [0]
|
|
49500
|
+
};
|
|
49501
|
+
return expressions.reduce((variables, {
|
|
49502
|
+
expression,
|
|
49503
|
+
depth
|
|
49504
|
+
}) => {
|
|
49505
|
+
return variables.concat(getFlavouredFeelVariableNames(expression, 'expression', {
|
|
49506
|
+
depth,
|
|
49507
|
+
specialDepthAccessors
|
|
49508
|
+
}));
|
|
49509
|
+
}, []);
|
|
49349
49510
|
}
|
|
49350
49511
|
|
|
49351
49512
|
/**
|
|
@@ -49372,6 +49533,50 @@
|
|
|
49372
49533
|
buildDebugString
|
|
49373
49534
|
});
|
|
49374
49535
|
}
|
|
49536
|
+
|
|
49537
|
+
/**
|
|
49538
|
+
* @typedef {Object} ExpressionWithDepth
|
|
49539
|
+
* @property {number} depth - The depth of the expression in the syntax tree.
|
|
49540
|
+
* @property {string} expression - The extracted expression
|
|
49541
|
+
*/
|
|
49542
|
+
|
|
49543
|
+
/**
|
|
49544
|
+
* Extracts all feel expressions in the template along with their depth in the syntax tree.
|
|
49545
|
+
* The depth is incremented for child expressions of loops to account for context drilling.
|
|
49546
|
+
* @name extractExpressionsWithDepth
|
|
49547
|
+
* @param {string} template - A feelers template string.
|
|
49548
|
+
* @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
|
|
49549
|
+
*
|
|
49550
|
+
* @example
|
|
49551
|
+
* const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
|
|
49552
|
+
* const extractedExpressions = _extractExpressionsWithDepth(template);
|
|
49553
|
+
*/
|
|
49554
|
+
_extractExpressionsWithDepth(template) {
|
|
49555
|
+
// build simplified feelers syntax tree
|
|
49556
|
+
const parseTree = parser$1.parse(template);
|
|
49557
|
+
const tree = buildSimpleTree(parseTree, template);
|
|
49558
|
+
return function _traverse(n, depth = 0) {
|
|
49559
|
+
if (['Feel', 'FeelBlock'].includes(n.name)) {
|
|
49560
|
+
return [{
|
|
49561
|
+
depth,
|
|
49562
|
+
expression: n.content
|
|
49563
|
+
}];
|
|
49564
|
+
}
|
|
49565
|
+
if (n.name === 'LoopSpanner') {
|
|
49566
|
+
const loopExpression = n.children[0].content;
|
|
49567
|
+
const childResults = n.children.slice(1).reduce((acc, child) => {
|
|
49568
|
+
return acc.concat(_traverse(child, depth + 1));
|
|
49569
|
+
}, []);
|
|
49570
|
+
return [{
|
|
49571
|
+
depth,
|
|
49572
|
+
expression: loopExpression
|
|
49573
|
+
}, ...childResults];
|
|
49574
|
+
}
|
|
49575
|
+
return n.children.reduce((acc, child) => {
|
|
49576
|
+
return acc.concat(_traverse(child, depth));
|
|
49577
|
+
}, []);
|
|
49578
|
+
}(tree);
|
|
49579
|
+
}
|
|
49375
49580
|
}
|
|
49376
49581
|
FeelersTemplating.$inject = [];
|
|
49377
49582
|
|
|
@@ -49992,8 +50197,13 @@
|
|
|
49992
50197
|
if (validate.pattern && value && !new RegExp(validate.pattern).test(value)) {
|
|
49993
50198
|
errors = [...errors, `Field must match pattern ${validate.pattern}.`];
|
|
49994
50199
|
}
|
|
49995
|
-
if (validate.required
|
|
49996
|
-
|
|
50200
|
+
if (validate.required) {
|
|
50201
|
+
const isUncheckedCheckbox = type === 'checkbox' && value === false;
|
|
50202
|
+
const isUnsetValue = isNil$1(value) || value === '';
|
|
50203
|
+
const isEmptyMultiselect = Array.isArray(value) && value.length === 0;
|
|
50204
|
+
if (isUncheckedCheckbox || isUnsetValue || isEmptyMultiselect) {
|
|
50205
|
+
errors = [...errors, 'Field is required.'];
|
|
50206
|
+
}
|
|
49997
50207
|
}
|
|
49998
50208
|
if ('min' in validate && (value || value === 0) && value < validate.min) {
|
|
49999
50209
|
errors = [...errors, `Field must have minimum value of ${validate.min}.`];
|
|
@@ -50292,6 +50502,7 @@
|
|
|
50292
50502
|
return container;
|
|
50293
50503
|
}
|
|
50294
50504
|
const EXPRESSION_PROPERTIES = ['alt', 'source', 'text'];
|
|
50505
|
+
const TEMPLATE_PROPERTIES = ['text'];
|
|
50295
50506
|
function findErrors(errors, path) {
|
|
50296
50507
|
return errors[pathStringify(path)];
|
|
50297
50508
|
}
|
|
@@ -50331,7 +50542,7 @@
|
|
|
50331
50542
|
*
|
|
50332
50543
|
* @return {string[]}
|
|
50333
50544
|
*/
|
|
50334
|
-
function getSchemaVariables(schema, expressionLanguage = new FeelExpressionLanguage(null)) {
|
|
50545
|
+
function getSchemaVariables(schema, expressionLanguage = new FeelExpressionLanguage(null), templating = new FeelersTemplating()) {
|
|
50335
50546
|
if (!schema.components) {
|
|
50336
50547
|
return [];
|
|
50337
50548
|
}
|
|
@@ -50366,6 +50577,13 @@
|
|
|
50366
50577
|
variables = [...variables, ...expressionVariables];
|
|
50367
50578
|
}
|
|
50368
50579
|
});
|
|
50580
|
+
TEMPLATE_PROPERTIES.forEach(prop => {
|
|
50581
|
+
const property = component[prop];
|
|
50582
|
+
if (property && !expressionLanguage.isExpression(property) && templating.isTemplate(property)) {
|
|
50583
|
+
const templateVariables = templating.getVariableNames(property);
|
|
50584
|
+
variables = [...variables, ...templateVariables];
|
|
50585
|
+
}
|
|
50586
|
+
});
|
|
50369
50587
|
return variables;
|
|
50370
50588
|
}, []);
|
|
50371
50589
|
|
|
@@ -50671,8 +50889,12 @@
|
|
|
50671
50889
|
const {
|
|
50672
50890
|
description,
|
|
50673
50891
|
id,
|
|
50674
|
-
label
|
|
50892
|
+
label,
|
|
50893
|
+
validate = {}
|
|
50675
50894
|
} = field;
|
|
50895
|
+
const {
|
|
50896
|
+
required
|
|
50897
|
+
} = validate;
|
|
50676
50898
|
const onChange = ({
|
|
50677
50899
|
target
|
|
50678
50900
|
}) => {
|
|
@@ -50694,7 +50916,7 @@
|
|
|
50694
50916
|
children: [e$1(Label$1, {
|
|
50695
50917
|
id: prefixId(id, formId),
|
|
50696
50918
|
label: label,
|
|
50697
|
-
required:
|
|
50919
|
+
required: required,
|
|
50698
50920
|
children: e$1("input", {
|
|
50699
50921
|
checked: value,
|
|
50700
50922
|
class: "fjs-input",
|
|
@@ -51057,8 +51279,12 @@
|
|
|
51057
51279
|
const {
|
|
51058
51280
|
description,
|
|
51059
51281
|
id,
|
|
51060
|
-
label
|
|
51282
|
+
label,
|
|
51283
|
+
validate = {}
|
|
51061
51284
|
} = field;
|
|
51285
|
+
const {
|
|
51286
|
+
required
|
|
51287
|
+
} = validate;
|
|
51062
51288
|
const toggleCheckbox = v => {
|
|
51063
51289
|
let newValue = [...value];
|
|
51064
51290
|
if (!newValue.includes(v)) {
|
|
@@ -51084,7 +51310,8 @@
|
|
|
51084
51310
|
disabled
|
|
51085
51311
|
})),
|
|
51086
51312
|
children: [e$1(Label$1, {
|
|
51087
|
-
label: label
|
|
51313
|
+
label: label,
|
|
51314
|
+
required: required
|
|
51088
51315
|
}), loadState == LOAD_STATES.LOADED && options.map((v, index) => {
|
|
51089
51316
|
return e$1(Label$1, {
|
|
51090
51317
|
id: prefixId(`${id}-${index}`, formId),
|
|
@@ -52964,6 +53191,12 @@
|
|
|
52964
53191
|
errors,
|
|
52965
53192
|
disabled
|
|
52966
53193
|
}),
|
|
53194
|
+
onKeyDown: event => {
|
|
53195
|
+
if (event.key === 'Enter') {
|
|
53196
|
+
event.preventDefault();
|
|
53197
|
+
event.stopPropagation();
|
|
53198
|
+
}
|
|
53199
|
+
},
|
|
52967
53200
|
children: [e$1(Label$1, {
|
|
52968
53201
|
id: prefixId(id, formId),
|
|
52969
53202
|
label: label,
|
|
@@ -53011,8 +53244,12 @@
|
|
|
53011
53244
|
const {
|
|
53012
53245
|
description,
|
|
53013
53246
|
id,
|
|
53014
|
-
label
|
|
53247
|
+
label,
|
|
53248
|
+
validate = {}
|
|
53015
53249
|
} = field;
|
|
53250
|
+
const {
|
|
53251
|
+
required
|
|
53252
|
+
} = validate;
|
|
53016
53253
|
const {
|
|
53017
53254
|
formId
|
|
53018
53255
|
} = F$1(FormContext$1);
|
|
@@ -53109,8 +53346,15 @@
|
|
|
53109
53346
|
errors,
|
|
53110
53347
|
disabled
|
|
53111
53348
|
}),
|
|
53349
|
+
onKeyDown: event => {
|
|
53350
|
+
if (event.key === 'Enter') {
|
|
53351
|
+
event.stopPropagation();
|
|
53352
|
+
event.preventDefault();
|
|
53353
|
+
}
|
|
53354
|
+
},
|
|
53112
53355
|
children: [e$1(Label$1, {
|
|
53113
53356
|
label: label,
|
|
53357
|
+
required: required,
|
|
53114
53358
|
id: prefixId(`${id}-search`, formId)
|
|
53115
53359
|
}), e$1("div", {
|
|
53116
53360
|
class: classNames('fjs-taglist', {
|
|
@@ -65103,7 +65347,7 @@
|
|
|
65103
65347
|
id,
|
|
65104
65348
|
label: 'Label',
|
|
65105
65349
|
setValue,
|
|
65106
|
-
validate: validateFactory(getValue())
|
|
65350
|
+
validate: validateFactory(getValue(), entry => entry.label)
|
|
65107
65351
|
});
|
|
65108
65352
|
}
|
|
65109
65353
|
function Value$1(props) {
|
|
@@ -65129,7 +65373,7 @@
|
|
|
65129
65373
|
id,
|
|
65130
65374
|
label: 'Value',
|
|
65131
65375
|
setValue,
|
|
65132
|
-
validate: validateFactory(getValue())
|
|
65376
|
+
validate: validateFactory(getValue(), entry => entry.value)
|
|
65133
65377
|
});
|
|
65134
65378
|
}
|
|
65135
65379
|
function CustomValueEntry(props) {
|
|
@@ -65367,13 +65611,13 @@
|
|
|
65367
65611
|
const addEntry = e => {
|
|
65368
65612
|
e.stopPropagation();
|
|
65369
65613
|
const index = values.length + 1;
|
|
65370
|
-
const entry = getIndexedEntry(index);
|
|
65614
|
+
const entry = getIndexedEntry(index, values);
|
|
65371
65615
|
editField(field, VALUES_SOURCES_PATHS[VALUES_SOURCES.STATIC], arrayAdd(values, values.length, entry));
|
|
65372
65616
|
};
|
|
65373
65617
|
const removeEntry = entry => {
|
|
65374
65618
|
editField(field, VALUES_SOURCES_PATHS[VALUES_SOURCES.STATIC], without(values, entry));
|
|
65375
65619
|
};
|
|
65376
|
-
const validateFactory = key => {
|
|
65620
|
+
const validateFactory = (key, getValue) => {
|
|
65377
65621
|
return value => {
|
|
65378
65622
|
if (value === key) {
|
|
65379
65623
|
return;
|
|
@@ -65381,7 +65625,7 @@
|
|
|
65381
65625
|
if (isUndefined(value) || !value.length) {
|
|
65382
65626
|
return 'Must not be empty.';
|
|
65383
65627
|
}
|
|
65384
|
-
const isValueAssigned = values.find(entry => entry
|
|
65628
|
+
const isValueAssigned = values.find(entry => getValue(entry) === value);
|
|
65385
65629
|
if (isValueAssigned) {
|
|
65386
65630
|
return 'Must be unique.';
|
|
65387
65631
|
}
|
|
@@ -65412,17 +65656,23 @@
|
|
|
65412
65656
|
|
|
65413
65657
|
// helper
|
|
65414
65658
|
|
|
65415
|
-
function getIndexedEntry(index) {
|
|
65659
|
+
function getIndexedEntry(index, values) {
|
|
65416
65660
|
const entry = {
|
|
65417
65661
|
label: 'Value',
|
|
65418
65662
|
value: 'value'
|
|
65419
65663
|
};
|
|
65664
|
+
while (labelOrValueIsAlreadyAssignedForIndex(index, values)) {
|
|
65665
|
+
index++;
|
|
65666
|
+
}
|
|
65420
65667
|
if (index > 1) {
|
|
65421
65668
|
entry.label += ` ${index}`;
|
|
65422
65669
|
entry.value += `${index}`;
|
|
65423
65670
|
}
|
|
65424
65671
|
return entry;
|
|
65425
65672
|
}
|
|
65673
|
+
function labelOrValueIsAlreadyAssignedForIndex(index, values) {
|
|
65674
|
+
return values.some(existingEntry => existingEntry.label === `Value ${index}` || existingEntry.value === `value${index}`);
|
|
65675
|
+
}
|
|
65426
65676
|
function AdornerEntry(props) {
|
|
65427
65677
|
const {
|
|
65428
65678
|
editField,
|
|
@@ -65645,7 +65895,7 @@
|
|
|
65645
65895
|
} = field;
|
|
65646
65896
|
const validate = get(field, ['validate'], {});
|
|
65647
65897
|
const isCustomValidation = [undefined, VALIDATION_TYPE_OPTIONS.custom.value].includes(validate.validationType);
|
|
65648
|
-
if (!
|
|
65898
|
+
if (!INPUTS.includes(type)) {
|
|
65649
65899
|
return null;
|
|
65650
65900
|
}
|
|
65651
65901
|
const onChange = key => {
|
|
@@ -65915,12 +66165,13 @@
|
|
|
65915
66165
|
}
|
|
65916
66166
|
const addEntry = event => {
|
|
65917
66167
|
event.stopPropagation();
|
|
65918
|
-
|
|
65919
|
-
|
|
65920
|
-
|
|
66168
|
+
let index = Object.keys(properties).length + 1;
|
|
66169
|
+
while (`key${index}` in properties) {
|
|
66170
|
+
index++;
|
|
66171
|
+
}
|
|
65921
66172
|
editField(field, ['properties'], {
|
|
65922
66173
|
...properties,
|
|
65923
|
-
[key]: value
|
|
66174
|
+
[`key${index}`]: 'value'
|
|
65924
66175
|
});
|
|
65925
66176
|
};
|
|
65926
66177
|
const validateFactory = key => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bpmn-io/form-js-playground",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "A form-js playground",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"url": "https://github.com/bpmn-io"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@bpmn-io/form-js-editor": "^0.
|
|
48
|
-
"@bpmn-io/form-js-viewer": "^0.
|
|
47
|
+
"@bpmn-io/form-js-editor": "^0.14.1",
|
|
48
|
+
"@bpmn-io/form-js-viewer": "^0.14.1",
|
|
49
49
|
"@codemirror/autocomplete": "^6.3.4",
|
|
50
50
|
"@codemirror/commands": "^6.1.2",
|
|
51
51
|
"@codemirror/lang-json": "^6.0.0",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"rollup-plugin-css-only": "^4.0.0",
|
|
71
71
|
"style-loader": "^3.3.0"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "a9ad771bc8f87d2fc428bd5bd1429b96bb03fe7a"
|
|
74
74
|
}
|