@bpmn-io/form-js-editor 1.2.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/dist/assets/form-js-editor-base.css +50 -11
- package/dist/assets/form-js-editor.css +289 -10
- package/dist/assets/properties-panel.css +245 -1
- package/dist/index.cjs +2320 -1640
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +2320 -1641
- package/dist/index.es.js.map +1 -1
- package/dist/types/FormEditor.d.ts +1 -0
- package/dist/types/core/index.d.ts +7 -5
- package/dist/types/features/dragging/Dragging.d.ts +3 -1
- package/dist/types/features/modeling/Modeling.d.ts +4 -0
- package/dist/types/features/modeling/behavior/KeyBehavior.d.ts +1 -1
- package/dist/types/features/modeling/behavior/PathBehavior.d.ts +8 -0
- package/dist/types/features/modeling/behavior/index.d.ts +2 -0
- package/dist/types/features/modeling/cmd/MoveFormFieldHandler.d.ts +3 -1
- package/dist/types/features/modeling/cmd/UpdateKeyClaimHandler.d.ts +3 -3
- package/dist/types/features/modeling/cmd/UpdatePathClaimHandler.d.ts +14 -0
- package/dist/types/features/modeling/cmd/Util.d.ts +1 -0
- package/dist/types/features/modeling/index.d.ts +1 -0
- package/dist/types/features/properties-panel/Util.d.ts +1 -0
- package/dist/types/features/properties-panel/entries/GroupEntries.d.ts +10 -0
- package/dist/types/features/properties-panel/entries/PathEntry.d.ts +9 -0
- package/dist/types/features/properties-panel/entries/index.d.ts +2 -0
- package/dist/types/render/components/Util.d.ts +1 -2
- package/package.json +4 -4
- package/dist/types/core/FieldFactory.d.ts +0 -18
- package/dist/types/import/Importer.d.ts +0 -53
- package/dist/types/import/index.d.ts +0 -5
package/dist/index.cjs
CHANGED
|
@@ -13,6 +13,8 @@ var minDom = require('min-dom');
|
|
|
13
13
|
var arrayMove = require('array-move');
|
|
14
14
|
var feelers = require('feelers');
|
|
15
15
|
var FeelEditor = require('@bpmn-io/feel-editor');
|
|
16
|
+
var view = require('@codemirror/view');
|
|
17
|
+
var focusTrap = require('focus-trap');
|
|
16
18
|
var Big = require('big.js');
|
|
17
19
|
|
|
18
20
|
function _interopNamespaceDefault(e) {
|
|
@@ -33,6 +35,7 @@ function _interopNamespaceDefault(e) {
|
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
38
|
+
var focusTrap__namespace = /*#__PURE__*/_interopNamespaceDefault(focusTrap);
|
|
36
39
|
|
|
37
40
|
var FN_REF = '__fn';
|
|
38
41
|
var DEFAULT_PRIORITY$2 = 1000;
|
|
@@ -549,73 +552,6 @@ function DebounceFactory(config = true) {
|
|
|
549
552
|
}
|
|
550
553
|
DebounceFactory.$inject = ['config.debounce'];
|
|
551
554
|
|
|
552
|
-
class FieldFactory {
|
|
553
|
-
/**
|
|
554
|
-
* @constructor
|
|
555
|
-
*
|
|
556
|
-
* @param { import('./FormFieldRegistry').default } formFieldRegistry
|
|
557
|
-
* @param { import('@bpmn-io/form-js-viewer').FormFields } formFields
|
|
558
|
-
*/
|
|
559
|
-
constructor(formFieldRegistry, formFields) {
|
|
560
|
-
this._formFieldRegistry = formFieldRegistry;
|
|
561
|
-
this._formFields = formFields;
|
|
562
|
-
}
|
|
563
|
-
create(attrs, applyDefaults = true) {
|
|
564
|
-
const {
|
|
565
|
-
id,
|
|
566
|
-
key,
|
|
567
|
-
type
|
|
568
|
-
} = attrs;
|
|
569
|
-
const fieldDefinition = this._formFields.get(type);
|
|
570
|
-
if (!fieldDefinition) {
|
|
571
|
-
throw new Error(`form field of type <${type}> not supported`);
|
|
572
|
-
}
|
|
573
|
-
const {
|
|
574
|
-
config
|
|
575
|
-
} = fieldDefinition;
|
|
576
|
-
if (id && this._formFieldRegistry._ids.assigned(id)) {
|
|
577
|
-
throw new Error(`ID <${id}> already assigned`);
|
|
578
|
-
}
|
|
579
|
-
if (key && this._formFieldRegistry._keys.assigned(key)) {
|
|
580
|
-
throw new Error(`key <${key}> already assigned`);
|
|
581
|
-
}
|
|
582
|
-
const labelAttrs = applyDefaults && config.label ? {
|
|
583
|
-
label: config.label
|
|
584
|
-
} : {};
|
|
585
|
-
const field = config.create({
|
|
586
|
-
...labelAttrs,
|
|
587
|
-
...attrs
|
|
588
|
-
});
|
|
589
|
-
this._ensureId(field);
|
|
590
|
-
if (config.keyed) {
|
|
591
|
-
this._ensureKey(field, applyDefaults);
|
|
592
|
-
}
|
|
593
|
-
return field;
|
|
594
|
-
}
|
|
595
|
-
_ensureId(field) {
|
|
596
|
-
if (field.id) {
|
|
597
|
-
this._formFieldRegistry._ids.claim(field.id, field);
|
|
598
|
-
return;
|
|
599
|
-
}
|
|
600
|
-
let prefix = 'Field';
|
|
601
|
-
if (field.type === 'default') {
|
|
602
|
-
prefix = 'Form';
|
|
603
|
-
}
|
|
604
|
-
field.id = this._formFieldRegistry._ids.nextPrefixed(`${prefix}_`, field);
|
|
605
|
-
}
|
|
606
|
-
_ensureKey(field, applyDefaults) {
|
|
607
|
-
if (field.key) {
|
|
608
|
-
this._formFieldRegistry._keys.claim(field.key, field);
|
|
609
|
-
return;
|
|
610
|
-
}
|
|
611
|
-
if (applyDefaults) {
|
|
612
|
-
let prefix = 'field';
|
|
613
|
-
field.key = this._formFieldRegistry._keys.nextPrefixed(`${prefix}_`, field);
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
FieldFactory.$inject = ['formFieldRegistry', 'formFields'];
|
|
618
|
-
|
|
619
555
|
class FormFieldRegistry extends formJsViewer.FormFieldRegistry {
|
|
620
556
|
/**
|
|
621
557
|
* Updates a form fields id.
|
|
@@ -728,111 +664,7 @@ function calculateMaxColumnsWithAuto(autoCols) {
|
|
|
728
664
|
return MAX_COLUMNS_PER_ROW - autoCols * 2;
|
|
729
665
|
}
|
|
730
666
|
|
|
731
|
-
|
|
732
|
-
/**
|
|
733
|
-
* @constructor
|
|
734
|
-
* @param { import('../core/FormFieldRegistry').default } formFieldRegistry
|
|
735
|
-
* @param { import('../core/FieldFactory').default } fieldFactory
|
|
736
|
-
* @param { import('../core/FormLayouter').default } formLayouter
|
|
737
|
-
*/
|
|
738
|
-
constructor(formFieldRegistry, fieldFactory, formLayouter) {
|
|
739
|
-
this._formFieldRegistry = formFieldRegistry;
|
|
740
|
-
this._fieldFactory = fieldFactory;
|
|
741
|
-
this._formLayouter = formLayouter;
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
/**
|
|
745
|
-
* Import schema creating rows, fields, attaching additional
|
|
746
|
-
* information to each field and adding fields to the
|
|
747
|
-
* field registry.
|
|
748
|
-
*
|
|
749
|
-
* Additional information attached:
|
|
750
|
-
*
|
|
751
|
-
* * `id` (unless present)
|
|
752
|
-
* * `_parent`
|
|
753
|
-
* * `_path`
|
|
754
|
-
*
|
|
755
|
-
* @param {any} schema
|
|
756
|
-
*
|
|
757
|
-
* @typedef {{ warnings: Error[], schema: any }} ImportResult
|
|
758
|
-
* @returns {ImportResult}
|
|
759
|
-
*/
|
|
760
|
-
importSchema(schema) {
|
|
761
|
-
// TODO: Add warnings
|
|
762
|
-
const warnings = [];
|
|
763
|
-
try {
|
|
764
|
-
const importedSchema = this.importFormField(formJsViewer.clone(schema));
|
|
765
|
-
this._formLayouter.calculateLayout(formJsViewer.clone(importedSchema));
|
|
766
|
-
return {
|
|
767
|
-
schema: importedSchema,
|
|
768
|
-
warnings
|
|
769
|
-
};
|
|
770
|
-
} catch (err) {
|
|
771
|
-
err.warnings = warnings;
|
|
772
|
-
throw err;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
/**
|
|
777
|
-
* @param {{[x: string]: any}} fieldAttrs
|
|
778
|
-
* @param {String} [parentId]
|
|
779
|
-
* @param {number} [index]
|
|
780
|
-
*
|
|
781
|
-
* @return {any} field
|
|
782
|
-
*/
|
|
783
|
-
importFormField(fieldAttrs, parentId, index) {
|
|
784
|
-
const {
|
|
785
|
-
components,
|
|
786
|
-
id,
|
|
787
|
-
key
|
|
788
|
-
} = fieldAttrs;
|
|
789
|
-
let parent, path;
|
|
790
|
-
if (parentId) {
|
|
791
|
-
parent = this._formFieldRegistry.get(parentId);
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
// validate <id> uniqueness
|
|
795
|
-
if (id && this._formFieldRegistry._ids.assigned(id)) {
|
|
796
|
-
throw new Error(`form field with id <${id}> already exists`);
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// validate <key> uniqueness
|
|
800
|
-
if (key && this._formFieldRegistry._keys.assigned(key)) {
|
|
801
|
-
throw new Error(`form field with key <${key}> already exists`);
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
// set form field path
|
|
805
|
-
path = parent ? [...parent._path, 'components', index] : [];
|
|
806
|
-
const field = this._fieldFactory.create({
|
|
807
|
-
...fieldAttrs,
|
|
808
|
-
_path: path,
|
|
809
|
-
_parent: parent && parent.id
|
|
810
|
-
}, false);
|
|
811
|
-
this._formFieldRegistry.add(field);
|
|
812
|
-
if (components) {
|
|
813
|
-
field.components = this.importFormFields(components, field.id);
|
|
814
|
-
}
|
|
815
|
-
return field;
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
/**
|
|
819
|
-
* @param {Array<any>} components
|
|
820
|
-
* @param {string} parentId
|
|
821
|
-
*
|
|
822
|
-
* @return {Array<any>} imported components
|
|
823
|
-
*/
|
|
824
|
-
importFormFields(components, parentId) {
|
|
825
|
-
return components.map((component, index) => {
|
|
826
|
-
return this.importFormField(component, parentId, index);
|
|
827
|
-
});
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
Importer.$inject = ['formFieldRegistry', 'fieldFactory', 'formLayouter'];
|
|
831
|
-
|
|
832
|
-
var importModule = {
|
|
833
|
-
importer: ['type', Importer]
|
|
834
|
-
};
|
|
835
|
-
|
|
667
|
+
const emptyImage = createEmptyImage();
|
|
836
668
|
function editorFormFieldClasses(type, {
|
|
837
669
|
disabled = false
|
|
838
670
|
} = {}) {
|
|
@@ -857,11 +689,10 @@ function editorFormFieldClasses(type, {
|
|
|
857
689
|
* domElement.addEventListener('dragstart', dragger(dragMove));
|
|
858
690
|
*
|
|
859
691
|
* @param {Function} fn
|
|
860
|
-
* @param {Element} dragPreview
|
|
861
692
|
*
|
|
862
693
|
* @return {Function} drag start callback function
|
|
863
694
|
*/
|
|
864
|
-
function createDragger(fn
|
|
695
|
+
function createDragger$1(fn) {
|
|
865
696
|
let self;
|
|
866
697
|
let startX, startY;
|
|
867
698
|
|
|
@@ -871,9 +702,9 @@ function createDragger(fn, dragPreview) {
|
|
|
871
702
|
startX = event.clientX;
|
|
872
703
|
startY = event.clientY;
|
|
873
704
|
|
|
874
|
-
// (1)
|
|
705
|
+
// (1) hide drag preview image
|
|
875
706
|
if (event.dataTransfer) {
|
|
876
|
-
event.dataTransfer.setDragImage(
|
|
707
|
+
event.dataTransfer.setDragImage(emptyImage, 0, 0);
|
|
877
708
|
}
|
|
878
709
|
|
|
879
710
|
// (2) setup drag listeners
|
|
@@ -881,7 +712,7 @@ function createDragger(fn, dragPreview) {
|
|
|
881
712
|
// attach drag + cleanup event
|
|
882
713
|
document.addEventListener('dragover', onDrag);
|
|
883
714
|
document.addEventListener('dragend', onEnd);
|
|
884
|
-
document.addEventListener('drop', preventDefault);
|
|
715
|
+
document.addEventListener('drop', preventDefault$1);
|
|
885
716
|
}
|
|
886
717
|
function onDrag(event) {
|
|
887
718
|
const delta = {
|
|
@@ -895,7 +726,7 @@ function createDragger(fn, dragPreview) {
|
|
|
895
726
|
function onEnd() {
|
|
896
727
|
document.removeEventListener('dragover', onDrag);
|
|
897
728
|
document.removeEventListener('dragend', onEnd);
|
|
898
|
-
document.removeEventListener('drop', preventDefault);
|
|
729
|
+
document.removeEventListener('drop', preventDefault$1);
|
|
899
730
|
}
|
|
900
731
|
return onDragStart;
|
|
901
732
|
}
|
|
@@ -924,10 +755,15 @@ function throttle(fn) {
|
|
|
924
755
|
});
|
|
925
756
|
};
|
|
926
757
|
}
|
|
927
|
-
function preventDefault(event) {
|
|
758
|
+
function preventDefault$1(event) {
|
|
928
759
|
event.preventDefault();
|
|
929
760
|
event.stopPropagation();
|
|
930
761
|
}
|
|
762
|
+
function createEmptyImage() {
|
|
763
|
+
const img = new Image();
|
|
764
|
+
img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
|
765
|
+
return img;
|
|
766
|
+
}
|
|
931
767
|
|
|
932
768
|
const DragAndDropContext = preact.createContext({
|
|
933
769
|
drake: null
|
|
@@ -1585,13 +1421,15 @@ class Dragging {
|
|
|
1585
1421
|
* @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
|
|
1586
1422
|
* @param { import('../../core/EventBus').default } eventBus
|
|
1587
1423
|
* @param { import('../modeling/Modeling').default } modeling
|
|
1424
|
+
* @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
|
|
1588
1425
|
*/
|
|
1589
|
-
constructor(formFieldRegistry, formLayouter, formLayoutValidator, eventBus, modeling) {
|
|
1426
|
+
constructor(formFieldRegistry, formLayouter, formLayoutValidator, eventBus, modeling, pathRegistry) {
|
|
1590
1427
|
this._formFieldRegistry = formFieldRegistry;
|
|
1591
1428
|
this._formLayouter = formLayouter;
|
|
1592
1429
|
this._formLayoutValidator = formLayoutValidator;
|
|
1593
1430
|
this._eventBus = eventBus;
|
|
1594
1431
|
this._modeling = modeling;
|
|
1432
|
+
this._pathRegistry = pathRegistry;
|
|
1595
1433
|
}
|
|
1596
1434
|
|
|
1597
1435
|
/**
|
|
@@ -1625,11 +1463,50 @@ class Dragging {
|
|
|
1625
1463
|
const targetRow = this._formLayouter.getRow(target.dataset.rowId);
|
|
1626
1464
|
let columns;
|
|
1627
1465
|
let formField;
|
|
1466
|
+
let targetParentId;
|
|
1628
1467
|
if (formFieldNode) {
|
|
1629
1468
|
formField = this._formFieldRegistry.get(formFieldNode.dataset.id);
|
|
1630
1469
|
columns = (formField.layout || {}).columns;
|
|
1470
|
+
|
|
1471
|
+
// (1) check for row constraints
|
|
1472
|
+
if (isRow(target)) {
|
|
1473
|
+
targetParentId = getFormParent(target).dataset.id;
|
|
1474
|
+
const rowError = this._formLayoutValidator.validateField(formField, columns, targetRow);
|
|
1475
|
+
if (rowError) {
|
|
1476
|
+
return rowError;
|
|
1477
|
+
}
|
|
1478
|
+
} else {
|
|
1479
|
+
targetParentId = target.dataset.id;
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
// (2) check target is a valid parent
|
|
1483
|
+
if (!targetParentId) {
|
|
1484
|
+
return 'Drop is not a valid target';
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
// (3) check for path collisions
|
|
1488
|
+
const targetParentFormField = this._formFieldRegistry.get(targetParentId);
|
|
1489
|
+
const currentParentFormField = this._formFieldRegistry.get(formField._parent);
|
|
1490
|
+
if (targetParentFormField !== currentParentFormField) {
|
|
1491
|
+
const targetParentPath = this._pathRegistry.getValuePath(targetParentFormField);
|
|
1492
|
+
const currentParentPath = this._pathRegistry.getValuePath(currentParentFormField);
|
|
1493
|
+
if (targetParentPath.join('.') !== currentParentPath.join('.')) {
|
|
1494
|
+
const isDropAllowedByPathRegistry = this._pathRegistry.executeRecursivelyOnFields(formField, ({
|
|
1495
|
+
field,
|
|
1496
|
+
isClosed
|
|
1497
|
+
}) => {
|
|
1498
|
+
const options = {
|
|
1499
|
+
cutoffNode: currentParentFormField.id
|
|
1500
|
+
};
|
|
1501
|
+
const fieldPath = this._pathRegistry.getValuePath(field, options);
|
|
1502
|
+
return this._pathRegistry.canClaimPath([...targetParentPath, ...fieldPath], isClosed);
|
|
1503
|
+
});
|
|
1504
|
+
if (!isDropAllowedByPathRegistry) {
|
|
1505
|
+
return 'Drop not allowed by path registry';
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1631
1509
|
}
|
|
1632
|
-
return this._formLayoutValidator.validateField(formField, columns, targetRow);
|
|
1633
1510
|
}
|
|
1634
1511
|
moveField(element, source, targetRow, targetFormField, targetIndex) {
|
|
1635
1512
|
const formFieldNode = element.querySelector('.fjs-element');
|
|
@@ -1647,6 +1524,7 @@ class Dragging {
|
|
|
1647
1524
|
};
|
|
1648
1525
|
attrs = {
|
|
1649
1526
|
...attrs,
|
|
1527
|
+
_parent: targetFormField.id,
|
|
1650
1528
|
layout: {
|
|
1651
1529
|
row: targetRow ? targetRow.id : this._formLayouter.nextRowId(),
|
|
1652
1530
|
// enable auto columns
|
|
@@ -1680,14 +1558,13 @@ class Dragging {
|
|
|
1680
1558
|
|
|
1681
1559
|
// (2.1) dropped in existing row
|
|
1682
1560
|
if (isRow(target)) {
|
|
1683
|
-
unsetDropNotAllowed(target);
|
|
1684
1561
|
targetRow = this._formLayouter.getRow(target.dataset.rowId);
|
|
1562
|
+
}
|
|
1685
1563
|
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
}
|
|
1564
|
+
// (2.2) validate whether drop is allowed
|
|
1565
|
+
const validationError = this.validateDrop(el, target);
|
|
1566
|
+
if (validationError) {
|
|
1567
|
+
return drake.cancel(true);
|
|
1691
1568
|
}
|
|
1692
1569
|
drake.remove();
|
|
1693
1570
|
|
|
@@ -1735,13 +1612,11 @@ class Dragging {
|
|
|
1735
1612
|
return !target.classList.contains(DROP_CONTAINER_HORIZONTAL_CLS);
|
|
1736
1613
|
}
|
|
1737
1614
|
|
|
1738
|
-
// validate field drop
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
setDropNotAllowed(target);
|
|
1744
|
-
}
|
|
1615
|
+
// validate field drop
|
|
1616
|
+
const validationError = this.validateDrop(el, target);
|
|
1617
|
+
if (validationError) {
|
|
1618
|
+
// set error feedback to row
|
|
1619
|
+
setDropNotAllowed(target);
|
|
1745
1620
|
}
|
|
1746
1621
|
return !target.classList.contains(DRAG_NO_DROP_CLS);
|
|
1747
1622
|
},
|
|
@@ -1812,7 +1687,7 @@ class Dragging {
|
|
|
1812
1687
|
this._eventBus.fire(event, context);
|
|
1813
1688
|
}
|
|
1814
1689
|
}
|
|
1815
|
-
Dragging.$inject = ['formFieldRegistry', 'formLayouter', 'formLayoutValidator', 'eventBus', 'modeling'];
|
|
1690
|
+
Dragging.$inject = ['formFieldRegistry', 'formLayouter', 'formLayoutValidator', 'eventBus', 'modeling', 'pathRegistry'];
|
|
1816
1691
|
|
|
1817
1692
|
// helper //////////
|
|
1818
1693
|
|
|
@@ -1870,7 +1745,6 @@ function FieldDragPreview(props) {
|
|
|
1870
1745
|
|
|
1871
1746
|
const COLUMNS_REGEX = /^cds--col(-lg)?/;
|
|
1872
1747
|
const ELEMENT_RESIZING_CLS = 'fjs-element-resizing';
|
|
1873
|
-
const RESIZE_DRAG_PREVIEW_CLS = 'fjs-resize-drag-preview';
|
|
1874
1748
|
const GRID_OFFSET_PX = 16;
|
|
1875
1749
|
function FieldResizer(props) {
|
|
1876
1750
|
const {
|
|
@@ -1909,17 +1783,8 @@ function FieldResizer(props) {
|
|
|
1909
1783
|
const target = getElementNode(field);
|
|
1910
1784
|
const parent = getParent(target);
|
|
1911
1785
|
|
|
1912
|
-
// create a blank element to use as drag preview
|
|
1913
|
-
// ensure it was only created once
|
|
1914
|
-
let blankPreview = getDragPreviewImage(parent);
|
|
1915
|
-
if (!blankPreview) {
|
|
1916
|
-
blankPreview = document.createElement('div');
|
|
1917
|
-
blankPreview.classList.add(RESIZE_DRAG_PREVIEW_CLS);
|
|
1918
|
-
parent.appendChild(blankPreview);
|
|
1919
|
-
}
|
|
1920
|
-
|
|
1921
1786
|
// initialize drag handler
|
|
1922
|
-
const onDragStart = createDragger(onResize
|
|
1787
|
+
const onDragStart = createDragger$1(onResize);
|
|
1923
1788
|
onDragStart(event);
|
|
1924
1789
|
|
|
1925
1790
|
// mitigate auto columns on the grid that
|
|
@@ -1942,10 +1807,6 @@ function FieldResizer(props) {
|
|
|
1942
1807
|
const target = getElementNode(field);
|
|
1943
1808
|
unsetResizing(target, position);
|
|
1944
1809
|
context.current.newColumns = null;
|
|
1945
|
-
|
|
1946
|
-
// remove blank preview
|
|
1947
|
-
const blankPreview = getDragPreviewImage(getParent(target));
|
|
1948
|
-
blankPreview.remove();
|
|
1949
1810
|
};
|
|
1950
1811
|
if (field.type === 'default') {
|
|
1951
1812
|
return null;
|
|
@@ -1988,9 +1849,6 @@ function getColumnNode(node) {
|
|
|
1988
1849
|
function getElementNode(field) {
|
|
1989
1850
|
return minDom.query('.fjs-element[data-id="' + field.id + '"]');
|
|
1990
1851
|
}
|
|
1991
|
-
function getDragPreviewImage(node) {
|
|
1992
|
-
return minDom.query('.fjs-resize-drag-preview', node);
|
|
1993
|
-
}
|
|
1994
1852
|
function setResizing(node, position) {
|
|
1995
1853
|
minDom.classes(node).add(ELEMENT_RESIZING_CLS + '-' + position);
|
|
1996
1854
|
}
|
|
@@ -2007,7 +1865,10 @@ function ContextPad(props) {
|
|
|
2007
1865
|
children: props.children
|
|
2008
1866
|
});
|
|
2009
1867
|
}
|
|
2010
|
-
function Empty(
|
|
1868
|
+
function Empty() {
|
|
1869
|
+
return null;
|
|
1870
|
+
}
|
|
1871
|
+
function EmptyRoot(props) {
|
|
2011
1872
|
return jsxRuntime.jsx("div", {
|
|
2012
1873
|
class: "fjs-empty-editor",
|
|
2013
1874
|
children: jsxRuntime.jsxs("div", {
|
|
@@ -2028,12 +1889,17 @@ function Element$1(props) {
|
|
|
2028
1889
|
formFieldRegistry = useService$1('formFieldRegistry'),
|
|
2029
1890
|
modeling = useService$1('modeling'),
|
|
2030
1891
|
selection = useService$1('selection');
|
|
1892
|
+
const {
|
|
1893
|
+
hoveredId,
|
|
1894
|
+
setHoveredId
|
|
1895
|
+
} = hooks.useContext(formJsViewer.FormRenderContext);
|
|
2031
1896
|
const {
|
|
2032
1897
|
field
|
|
2033
1898
|
} = props;
|
|
2034
1899
|
const {
|
|
2035
1900
|
id,
|
|
2036
|
-
type
|
|
1901
|
+
type,
|
|
1902
|
+
showOutline
|
|
2037
1903
|
} = field;
|
|
2038
1904
|
const ref = hooks.useRef();
|
|
2039
1905
|
function scrollIntoView({
|
|
@@ -2071,6 +1937,12 @@ function Element$1(props) {
|
|
|
2071
1937
|
if (selection.isSelected(field)) {
|
|
2072
1938
|
classes.push('fjs-editor-selected');
|
|
2073
1939
|
}
|
|
1940
|
+
if (showOutline) {
|
|
1941
|
+
classes.push('fjs-outlined');
|
|
1942
|
+
}
|
|
1943
|
+
if (hoveredId === field.id) {
|
|
1944
|
+
classes.push('fjs-editor-hovered');
|
|
1945
|
+
}
|
|
2074
1946
|
const onRemove = event => {
|
|
2075
1947
|
event.stopPropagation();
|
|
2076
1948
|
const parentField = formFieldRegistry.get(field._parent);
|
|
@@ -2090,6 +1962,11 @@ function Element$1(props) {
|
|
|
2090
1962
|
tabIndex: type === 'default' ? -1 : 0,
|
|
2091
1963
|
onClick: onClick,
|
|
2092
1964
|
onKeyPress: onKeyPress,
|
|
1965
|
+
onMouseOver: e => {
|
|
1966
|
+
// @ts-ignore
|
|
1967
|
+
setHoveredId(field.id);
|
|
1968
|
+
e.stopPropagation();
|
|
1969
|
+
},
|
|
2093
1970
|
ref: ref,
|
|
2094
1971
|
children: [jsxRuntime.jsx(DebugColumns, {
|
|
2095
1972
|
field: field
|
|
@@ -2259,14 +2136,18 @@ function FormEditor$1(props) {
|
|
|
2259
2136
|
hooks.useEffect(() => {
|
|
2260
2137
|
eventBus.fire('formEditor.rendered');
|
|
2261
2138
|
}, []);
|
|
2262
|
-
const
|
|
2139
|
+
const [hoveredId, setHoveredId] = hooks.useState(null);
|
|
2140
|
+
const formRenderContext = hooks.useMemo(() => ({
|
|
2263
2141
|
Children,
|
|
2264
2142
|
Column,
|
|
2265
2143
|
Element: Element$1,
|
|
2266
2144
|
Empty,
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2145
|
+
EmptyRoot,
|
|
2146
|
+
Row,
|
|
2147
|
+
hoveredId,
|
|
2148
|
+
setHoveredId
|
|
2149
|
+
}), [hoveredId]);
|
|
2150
|
+
const formContext = hooks.useMemo(() => ({
|
|
2270
2151
|
getService(type, strict = true) {
|
|
2271
2152
|
// TODO(philippfromme): clean up
|
|
2272
2153
|
if (type === 'form') {
|
|
@@ -2287,7 +2168,7 @@ function FormEditor$1(props) {
|
|
|
2287
2168
|
return injector.get(type, strict);
|
|
2288
2169
|
},
|
|
2289
2170
|
formId: formEditor._id
|
|
2290
|
-
};
|
|
2171
|
+
}), [ariaLabel, formEditor, injector, schema]);
|
|
2291
2172
|
const onSubmit = hooks.useCallback(() => {}, []);
|
|
2292
2173
|
const onReset = hooks.useCallback(() => {}, []);
|
|
2293
2174
|
|
|
@@ -2313,6 +2194,7 @@ function FormEditor$1(props) {
|
|
|
2313
2194
|
children: jsxRuntime.jsx(formJsViewer.FormContext.Provider, {
|
|
2314
2195
|
value: formContext,
|
|
2315
2196
|
children: jsxRuntime.jsx(formJsViewer.FormRenderContext.Provider, {
|
|
2197
|
+
// @ts-ignore
|
|
2316
2198
|
value: formRenderContext,
|
|
2317
2199
|
children: jsxRuntime.jsx(formJsViewer.FormComponent, {
|
|
2318
2200
|
onSubmit: onSubmit,
|
|
@@ -2450,13 +2332,15 @@ var renderModule = {
|
|
|
2450
2332
|
};
|
|
2451
2333
|
|
|
2452
2334
|
var core = {
|
|
2453
|
-
__depends__: [
|
|
2335
|
+
__depends__: [renderModule],
|
|
2454
2336
|
debounce: ['factory', DebounceFactory],
|
|
2455
2337
|
eventBus: ['type', EventBus],
|
|
2338
|
+
importer: ['type', formJsViewer.Importer],
|
|
2456
2339
|
formFieldRegistry: ['type', FormFieldRegistry],
|
|
2340
|
+
pathRegistry: ['type', formJsViewer.PathRegistry],
|
|
2457
2341
|
formLayouter: ['type', formJsViewer.FormLayouter],
|
|
2458
2342
|
formLayoutValidator: ['type', FormLayoutValidator],
|
|
2459
|
-
fieldFactory: ['type', FieldFactory]
|
|
2343
|
+
fieldFactory: ['type', formJsViewer.FieldFactory]
|
|
2460
2344
|
};
|
|
2461
2345
|
|
|
2462
2346
|
/**
|
|
@@ -3162,9 +3046,16 @@ function arrayRemove(array, index) {
|
|
|
3162
3046
|
}
|
|
3163
3047
|
function updatePath(formFieldRegistry, formField, index) {
|
|
3164
3048
|
const parent = formFieldRegistry.get(formField._parent);
|
|
3165
|
-
formField
|
|
3049
|
+
refreshPathsRecursively(formField, [...parent._path, 'components', index]);
|
|
3166
3050
|
return formField;
|
|
3167
3051
|
}
|
|
3052
|
+
function refreshPathsRecursively(formField, path) {
|
|
3053
|
+
formField._path = path;
|
|
3054
|
+
const components = formField.components || [];
|
|
3055
|
+
components.forEach((component, index) => {
|
|
3056
|
+
refreshPathsRecursively(component, [...path, 'components', index]);
|
|
3057
|
+
});
|
|
3058
|
+
}
|
|
3168
3059
|
function updateRow(formField, rowId) {
|
|
3169
3060
|
formField.layout = {
|
|
3170
3061
|
...(formField.layout || {}),
|
|
@@ -3198,7 +3089,7 @@ class AddFormFieldHandler {
|
|
|
3198
3089
|
// (1) Add new form field
|
|
3199
3090
|
arrayAdd$1(minDash.get(schema, targetPath), targetIndex, formField);
|
|
3200
3091
|
|
|
3201
|
-
// (2) Update paths of new form field and its siblings
|
|
3092
|
+
// (2) Update internal paths of new form field and its siblings (and their children)
|
|
3202
3093
|
minDash.get(schema, targetPath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
3203
3094
|
|
|
3204
3095
|
// (3) Add new form field to form field registry
|
|
@@ -3223,7 +3114,7 @@ class AddFormFieldHandler {
|
|
|
3223
3114
|
// (1) Remove new form field
|
|
3224
3115
|
arrayRemove(minDash.get(schema, targetPath), targetIndex);
|
|
3225
3116
|
|
|
3226
|
-
// (2) Update paths of new form field and its siblings
|
|
3117
|
+
// (2) Update internal paths of new form field and its siblings (and their children)
|
|
3227
3118
|
minDash.get(schema, targetPath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
3228
3119
|
|
|
3229
3120
|
// (3) Remove new form field from form field registry
|
|
@@ -3308,10 +3199,12 @@ class MoveFormFieldHandler {
|
|
|
3308
3199
|
* @constructor
|
|
3309
3200
|
* @param { import('../../../FormEditor').default } formEditor
|
|
3310
3201
|
* @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
|
|
3202
|
+
* @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
|
|
3311
3203
|
*/
|
|
3312
|
-
constructor(formEditor, formFieldRegistry) {
|
|
3204
|
+
constructor(formEditor, formFieldRegistry, pathRegistry) {
|
|
3313
3205
|
this._formEditor = formEditor;
|
|
3314
3206
|
this._formFieldRegistry = formFieldRegistry;
|
|
3207
|
+
this._pathRegistry = pathRegistry;
|
|
3315
3208
|
}
|
|
3316
3209
|
execute(context) {
|
|
3317
3210
|
this.moveFormField(context);
|
|
@@ -3364,27 +3257,42 @@ class MoveFormFieldHandler {
|
|
|
3364
3257
|
// (2) Move form field
|
|
3365
3258
|
arrayMove.mutate(minDash.get(schema, sourcePath), sourceIndex, targetIndex);
|
|
3366
3259
|
|
|
3367
|
-
// (3) Update paths of new form field and its siblings
|
|
3260
|
+
// (3) Update internal paths of new form field and its siblings (and their children)
|
|
3368
3261
|
minDash.get(schema, sourcePath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
3369
3262
|
} else {
|
|
3370
3263
|
const formField = minDash.get(schema, [...sourcePath, sourceIndex]);
|
|
3264
|
+
|
|
3265
|
+
// (1) Deregister form field (and children) from path registry
|
|
3266
|
+
this._pathRegistry.executeRecursivelyOnFields(formField, ({
|
|
3267
|
+
field
|
|
3268
|
+
}) => {
|
|
3269
|
+
this._pathRegistry.unclaimPath(this._pathRegistry.getValuePath(field));
|
|
3270
|
+
});
|
|
3371
3271
|
formField._parent = targetFormField.id;
|
|
3372
3272
|
|
|
3373
|
-
// (
|
|
3273
|
+
// (2) Remove form field
|
|
3374
3274
|
arrayRemove(minDash.get(schema, sourcePath), sourceIndex);
|
|
3375
3275
|
|
|
3376
|
-
// (
|
|
3276
|
+
// (3) Update internal paths of siblings (and their children)
|
|
3377
3277
|
minDash.get(schema, sourcePath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
3378
3278
|
const targetPath = [...targetFormField._path, 'components'];
|
|
3379
3279
|
|
|
3380
|
-
// (
|
|
3280
|
+
// (4) Add to row
|
|
3381
3281
|
updateRow(formField, targetRow ? targetRow.id : null);
|
|
3382
3282
|
|
|
3383
|
-
// (
|
|
3283
|
+
// (5) Add form field
|
|
3384
3284
|
arrayAdd$1(minDash.get(schema, targetPath), targetIndex, formField);
|
|
3385
3285
|
|
|
3386
|
-
// (
|
|
3286
|
+
// (6) Update internal paths of siblings (and their children)
|
|
3387
3287
|
minDash.get(schema, targetPath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
3288
|
+
|
|
3289
|
+
// (7) Reregister form field (and children) from path registry
|
|
3290
|
+
this._pathRegistry.executeRecursivelyOnFields(formField, ({
|
|
3291
|
+
field,
|
|
3292
|
+
isClosed
|
|
3293
|
+
}) => {
|
|
3294
|
+
this._pathRegistry.claimPath(this._pathRegistry.getValuePath(field), isClosed);
|
|
3295
|
+
});
|
|
3388
3296
|
}
|
|
3389
3297
|
|
|
3390
3298
|
// TODO: Create updater/change support that automatically updates paths and schema on command execution
|
|
@@ -3393,7 +3301,7 @@ class MoveFormFieldHandler {
|
|
|
3393
3301
|
});
|
|
3394
3302
|
}
|
|
3395
3303
|
}
|
|
3396
|
-
MoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
|
|
3304
|
+
MoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry', 'pathRegistry'];
|
|
3397
3305
|
|
|
3398
3306
|
class RemoveFormFieldHandler {
|
|
3399
3307
|
/**
|
|
@@ -3419,11 +3327,11 @@ class RemoveFormFieldHandler {
|
|
|
3419
3327
|
// (1) Remove form field
|
|
3420
3328
|
arrayRemove(minDash.get(schema, sourcePath), sourceIndex);
|
|
3421
3329
|
|
|
3422
|
-
// (2) Update paths of its siblings
|
|
3330
|
+
// (2) Update internal paths of its siblings (and their children)
|
|
3423
3331
|
minDash.get(schema, sourcePath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
3424
3332
|
|
|
3425
|
-
// (3) Remove form field from form field registry
|
|
3426
|
-
this._formFieldRegistry.remove(formField);
|
|
3333
|
+
// (3) Remove form field and children from form field registry
|
|
3334
|
+
formJsViewer.runRecursively(formField, formField => this._formFieldRegistry.remove(formField));
|
|
3427
3335
|
|
|
3428
3336
|
// TODO: Create updater/change support that automatically updates paths and schema on command execution
|
|
3429
3337
|
this._formEditor._setState({
|
|
@@ -3444,11 +3352,11 @@ class RemoveFormFieldHandler {
|
|
|
3444
3352
|
// (1) Add form field
|
|
3445
3353
|
arrayAdd$1(minDash.get(schema, sourcePath), sourceIndex, formField);
|
|
3446
3354
|
|
|
3447
|
-
// (2) Update paths of its siblings
|
|
3355
|
+
// (2) Update internal paths of its siblings (and their children)
|
|
3448
3356
|
minDash.get(schema, sourcePath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
3449
3357
|
|
|
3450
|
-
// (3) Add form field to form field registry
|
|
3451
|
-
this._formFieldRegistry.add(formField);
|
|
3358
|
+
// (3) Add form field and children to form field registry
|
|
3359
|
+
formJsViewer.runRecursively(formField, formField => this._formFieldRegistry.add(formField));
|
|
3452
3360
|
|
|
3453
3361
|
// TODO: Create updater/change support that automatically updates paths and schema on command execution
|
|
3454
3362
|
this._formEditor._setState({
|
|
@@ -3496,10 +3404,10 @@ UpdateIdClaimHandler.$inject = ['formFieldRegistry'];
|
|
|
3496
3404
|
class UpdateKeyClaimHandler {
|
|
3497
3405
|
/**
|
|
3498
3406
|
* @constructor
|
|
3499
|
-
* @param { import('
|
|
3407
|
+
* @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
|
|
3500
3408
|
*/
|
|
3501
|
-
constructor(
|
|
3502
|
-
this.
|
|
3409
|
+
constructor(pathRegistry) {
|
|
3410
|
+
this._pathRegistry = pathRegistry;
|
|
3503
3411
|
}
|
|
3504
3412
|
execute(context) {
|
|
3505
3413
|
const {
|
|
@@ -3507,26 +3415,106 @@ class UpdateKeyClaimHandler {
|
|
|
3507
3415
|
formField,
|
|
3508
3416
|
key
|
|
3509
3417
|
} = context;
|
|
3418
|
+
const options = {
|
|
3419
|
+
replacements: {
|
|
3420
|
+
[formField.id]: key
|
|
3421
|
+
}
|
|
3422
|
+
};
|
|
3423
|
+
const valuePath = this._pathRegistry.getValuePath(formField, options);
|
|
3510
3424
|
if (claiming) {
|
|
3511
|
-
this.
|
|
3425
|
+
this._pathRegistry.claimPath(valuePath, true);
|
|
3512
3426
|
} else {
|
|
3513
|
-
this.
|
|
3427
|
+
this._pathRegistry.unclaimPath(valuePath);
|
|
3514
3428
|
}
|
|
3429
|
+
|
|
3430
|
+
// cache path for revert
|
|
3431
|
+
context.valuePath = valuePath;
|
|
3515
3432
|
}
|
|
3516
3433
|
revert(context) {
|
|
3434
|
+
const {
|
|
3435
|
+
claiming,
|
|
3436
|
+
valuePath
|
|
3437
|
+
} = context;
|
|
3438
|
+
if (claiming) {
|
|
3439
|
+
this._pathRegistry.unclaimPath(valuePath);
|
|
3440
|
+
} else {
|
|
3441
|
+
this._pathRegistry.claimPath(valuePath, true);
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3445
|
+
UpdateKeyClaimHandler.$inject = ['pathRegistry'];
|
|
3446
|
+
|
|
3447
|
+
class UpdatePathClaimHandler {
|
|
3448
|
+
/**
|
|
3449
|
+
* @constructor
|
|
3450
|
+
* @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
|
|
3451
|
+
*/
|
|
3452
|
+
constructor(pathRegistry) {
|
|
3453
|
+
this._pathRegistry = pathRegistry;
|
|
3454
|
+
}
|
|
3455
|
+
execute(context) {
|
|
3517
3456
|
const {
|
|
3518
3457
|
claiming,
|
|
3519
3458
|
formField,
|
|
3520
|
-
|
|
3459
|
+
path
|
|
3460
|
+
} = context;
|
|
3461
|
+
const options = {
|
|
3462
|
+
replacements: {
|
|
3463
|
+
[formField.id]: path
|
|
3464
|
+
}
|
|
3465
|
+
};
|
|
3466
|
+
const valuePaths = [];
|
|
3467
|
+
if (claiming) {
|
|
3468
|
+
this._pathRegistry.executeRecursivelyOnFields(formField, ({
|
|
3469
|
+
field,
|
|
3470
|
+
isClosed
|
|
3471
|
+
}) => {
|
|
3472
|
+
const valuePath = this._pathRegistry.getValuePath(field, options);
|
|
3473
|
+
valuePaths.push({
|
|
3474
|
+
valuePath,
|
|
3475
|
+
isClosed
|
|
3476
|
+
});
|
|
3477
|
+
this._pathRegistry.claimPath(valuePath, isClosed);
|
|
3478
|
+
});
|
|
3479
|
+
} else {
|
|
3480
|
+
this._pathRegistry.executeRecursivelyOnFields(formField, ({
|
|
3481
|
+
field,
|
|
3482
|
+
isClosed
|
|
3483
|
+
}) => {
|
|
3484
|
+
const valuePath = this._pathRegistry.getValuePath(field, options);
|
|
3485
|
+
valuePaths.push({
|
|
3486
|
+
valuePath,
|
|
3487
|
+
isClosed
|
|
3488
|
+
});
|
|
3489
|
+
this._pathRegistry.unclaimPath(valuePath);
|
|
3490
|
+
});
|
|
3491
|
+
}
|
|
3492
|
+
|
|
3493
|
+
// cache path info for revert
|
|
3494
|
+
context.valuePaths = valuePaths;
|
|
3495
|
+
}
|
|
3496
|
+
revert(context) {
|
|
3497
|
+
const {
|
|
3498
|
+
claiming,
|
|
3499
|
+
valuePaths
|
|
3521
3500
|
} = context;
|
|
3522
3501
|
if (claiming) {
|
|
3523
|
-
|
|
3502
|
+
valuePaths.forEach(({
|
|
3503
|
+
valuePath
|
|
3504
|
+
}) => {
|
|
3505
|
+
this._pathRegistry.unclaimPath(valuePath);
|
|
3506
|
+
});
|
|
3524
3507
|
} else {
|
|
3525
|
-
|
|
3508
|
+
valuePaths.forEach(({
|
|
3509
|
+
valuePath,
|
|
3510
|
+
isClosed
|
|
3511
|
+
}) => {
|
|
3512
|
+
this._pathRegistry.claimPath(valuePath, isClosed);
|
|
3513
|
+
});
|
|
3526
3514
|
}
|
|
3527
3515
|
}
|
|
3528
3516
|
}
|
|
3529
|
-
|
|
3517
|
+
UpdatePathClaimHandler.$inject = ['pathRegistry'];
|
|
3530
3518
|
|
|
3531
3519
|
class Modeling {
|
|
3532
3520
|
constructor(commandStack, eventBus, formEditor, formFieldRegistry, fieldFactory) {
|
|
@@ -3550,7 +3538,8 @@ class Modeling {
|
|
|
3550
3538
|
'formField.move': MoveFormFieldHandler,
|
|
3551
3539
|
'formField.remove': RemoveFormFieldHandler,
|
|
3552
3540
|
'id.updateClaim': UpdateIdClaimHandler,
|
|
3553
|
-
'key.updateClaim': UpdateKeyClaimHandler
|
|
3541
|
+
'key.updateClaim': UpdateKeyClaimHandler,
|
|
3542
|
+
'path.updateClaim': UpdatePathClaimHandler
|
|
3554
3543
|
};
|
|
3555
3544
|
}
|
|
3556
3545
|
addFormField(attrs, targetFormField, targetIndex) {
|
|
@@ -3627,6 +3616,22 @@ class Modeling {
|
|
|
3627
3616
|
};
|
|
3628
3617
|
this._commandStack.execute('key.updateClaim', context);
|
|
3629
3618
|
}
|
|
3619
|
+
claimPath(formField, path) {
|
|
3620
|
+
const context = {
|
|
3621
|
+
formField,
|
|
3622
|
+
path,
|
|
3623
|
+
claiming: true
|
|
3624
|
+
};
|
|
3625
|
+
this._commandStack.execute('path.updateClaim', context);
|
|
3626
|
+
}
|
|
3627
|
+
unclaimPath(formField, path) {
|
|
3628
|
+
const context = {
|
|
3629
|
+
formField,
|
|
3630
|
+
path,
|
|
3631
|
+
claiming: false
|
|
3632
|
+
};
|
|
3633
|
+
this._commandStack.execute('path.updateClaim', context);
|
|
3634
|
+
}
|
|
3630
3635
|
}
|
|
3631
3636
|
Modeling.$inject = ['commandStack', 'eventBus', 'formEditor', 'formFieldRegistry', 'fieldFactory'];
|
|
3632
3637
|
|
|
@@ -3899,8 +3904,6 @@ FormLayoutUpdater.$inject = ['eventBus', 'formLayouter', 'modeling', 'formEditor
|
|
|
3899
3904
|
class IdBehavior extends CommandInterceptor {
|
|
3900
3905
|
constructor(eventBus, modeling) {
|
|
3901
3906
|
super(eventBus);
|
|
3902
|
-
|
|
3903
|
-
// @ts-ignore-next-line
|
|
3904
3907
|
this.preExecute('formField.remove', function (context) {
|
|
3905
3908
|
const {
|
|
3906
3909
|
formField
|
|
@@ -3910,8 +3913,6 @@ class IdBehavior extends CommandInterceptor {
|
|
|
3910
3913
|
} = formField;
|
|
3911
3914
|
modeling.unclaimId(formField, id);
|
|
3912
3915
|
}, true);
|
|
3913
|
-
|
|
3914
|
-
// @ts-ignore-next-line
|
|
3915
3916
|
this.preExecute('formField.edit', function (context) {
|
|
3916
3917
|
const {
|
|
3917
3918
|
formField,
|
|
@@ -3927,36 +3928,82 @@ class IdBehavior extends CommandInterceptor {
|
|
|
3927
3928
|
IdBehavior.$inject = ['eventBus', 'modeling'];
|
|
3928
3929
|
|
|
3929
3930
|
class KeyBehavior extends CommandInterceptor {
|
|
3930
|
-
constructor(eventBus, modeling) {
|
|
3931
|
+
constructor(eventBus, modeling, formFields) {
|
|
3931
3932
|
super(eventBus);
|
|
3932
|
-
|
|
3933
|
-
// @ts-ignore-next-line
|
|
3934
3933
|
this.preExecute('formField.remove', function (context) {
|
|
3935
3934
|
const {
|
|
3936
3935
|
formField
|
|
3937
3936
|
} = context;
|
|
3938
3937
|
const {
|
|
3939
|
-
key
|
|
3938
|
+
key,
|
|
3939
|
+
type
|
|
3940
3940
|
} = formField;
|
|
3941
|
-
|
|
3941
|
+
const {
|
|
3942
|
+
config
|
|
3943
|
+
} = formFields.get(type);
|
|
3944
|
+
if (config.keyed) {
|
|
3942
3945
|
modeling.unclaimKey(formField, key);
|
|
3943
3946
|
}
|
|
3944
3947
|
}, true);
|
|
3945
|
-
|
|
3946
|
-
// @ts-ignore-next-line
|
|
3947
3948
|
this.preExecute('formField.edit', function (context) {
|
|
3948
3949
|
const {
|
|
3949
3950
|
formField,
|
|
3950
3951
|
properties
|
|
3951
3952
|
} = context;
|
|
3952
|
-
|
|
3953
|
-
|
|
3953
|
+
const {
|
|
3954
|
+
key,
|
|
3955
|
+
type
|
|
3956
|
+
} = formField;
|
|
3957
|
+
const {
|
|
3958
|
+
config
|
|
3959
|
+
} = formFields.get(type);
|
|
3960
|
+
if (config.keyed && 'key' in properties) {
|
|
3961
|
+
modeling.unclaimKey(formField, key);
|
|
3954
3962
|
modeling.claimKey(formField, properties.key);
|
|
3955
3963
|
}
|
|
3956
3964
|
}, true);
|
|
3957
3965
|
}
|
|
3958
3966
|
}
|
|
3959
|
-
KeyBehavior.$inject = ['eventBus', 'modeling'];
|
|
3967
|
+
KeyBehavior.$inject = ['eventBus', 'modeling', 'formFields'];
|
|
3968
|
+
|
|
3969
|
+
class PathBehavior extends CommandInterceptor {
|
|
3970
|
+
constructor(eventBus, modeling, formFields) {
|
|
3971
|
+
super(eventBus);
|
|
3972
|
+
this.preExecute('formField.remove', function (context) {
|
|
3973
|
+
const {
|
|
3974
|
+
formField
|
|
3975
|
+
} = context;
|
|
3976
|
+
const {
|
|
3977
|
+
path,
|
|
3978
|
+
type
|
|
3979
|
+
} = formField;
|
|
3980
|
+
const {
|
|
3981
|
+
config
|
|
3982
|
+
} = formFields.get(type);
|
|
3983
|
+
if (config.pathed) {
|
|
3984
|
+
modeling.unclaimPath(formField, path);
|
|
3985
|
+
}
|
|
3986
|
+
}, true);
|
|
3987
|
+
this.preExecute('formField.edit', function (context) {
|
|
3988
|
+
const {
|
|
3989
|
+
formField,
|
|
3990
|
+
properties
|
|
3991
|
+
} = context;
|
|
3992
|
+
const {
|
|
3993
|
+
path,
|
|
3994
|
+
type
|
|
3995
|
+
} = formField;
|
|
3996
|
+
const {
|
|
3997
|
+
config
|
|
3998
|
+
} = formFields.get(type);
|
|
3999
|
+
if (config.pathed && 'path' in properties) {
|
|
4000
|
+
modeling.unclaimPath(formField, path);
|
|
4001
|
+
modeling.claimPath(formField, properties.path);
|
|
4002
|
+
}
|
|
4003
|
+
}, true);
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
PathBehavior.$inject = ['eventBus', 'modeling', 'formFields'];
|
|
3960
4007
|
|
|
3961
4008
|
class ValidateBehavior extends CommandInterceptor {
|
|
3962
4009
|
constructor(eventBus) {
|
|
@@ -3965,7 +4012,6 @@ class ValidateBehavior extends CommandInterceptor {
|
|
|
3965
4012
|
/**
|
|
3966
4013
|
* Remove custom validation if <validationType> is about to be added.
|
|
3967
4014
|
*/
|
|
3968
|
-
// @ts-ignore-next-line
|
|
3969
4015
|
this.preExecute('formField.edit', function (context) {
|
|
3970
4016
|
const {
|
|
3971
4017
|
properties
|
|
@@ -3988,9 +4034,10 @@ class ValidateBehavior extends CommandInterceptor {
|
|
|
3988
4034
|
ValidateBehavior.$inject = ['eventBus'];
|
|
3989
4035
|
|
|
3990
4036
|
var behaviorModule = {
|
|
3991
|
-
__init__: ['idBehavior', 'keyBehavior', 'validateBehavior'],
|
|
4037
|
+
__init__: ['idBehavior', 'keyBehavior', 'pathBehavior', 'validateBehavior'],
|
|
3992
4038
|
idBehavior: ['type', IdBehavior],
|
|
3993
4039
|
keyBehavior: ['type', KeyBehavior],
|
|
4040
|
+
pathBehavior: ['type', PathBehavior],
|
|
3994
4041
|
validateBehavior: ['type', ValidateBehavior]
|
|
3995
4042
|
};
|
|
3996
4043
|
|
|
@@ -4661,6 +4708,33 @@ DeleteIcon.defaultProps = {
|
|
|
4661
4708
|
width: "16",
|
|
4662
4709
|
height: "16"
|
|
4663
4710
|
};
|
|
4711
|
+
var DragIcon = function DragIcon(props) {
|
|
4712
|
+
return jsxRuntime.jsxs("svg", {
|
|
4713
|
+
...props,
|
|
4714
|
+
children: [jsxRuntime.jsx("path", {
|
|
4715
|
+
fill: "#fff",
|
|
4716
|
+
style: {
|
|
4717
|
+
mixBlendMode: "multiply"
|
|
4718
|
+
},
|
|
4719
|
+
d: "M0 0h16v16H0z"
|
|
4720
|
+
}), jsxRuntime.jsx("path", {
|
|
4721
|
+
fill: "#fff",
|
|
4722
|
+
style: {
|
|
4723
|
+
mixBlendMode: "multiply"
|
|
4724
|
+
},
|
|
4725
|
+
d: "M0 0h16v16H0z"
|
|
4726
|
+
}), jsxRuntime.jsx("path", {
|
|
4727
|
+
d: "M7 3H5v2h2V3zm4 0H9v2h2V3zM7 7H5v2h2V7zm4 0H9v2h2V7zm-4 4H5v2h2v-2zm4 0H9v2h2v-2z",
|
|
4728
|
+
fill: "#161616"
|
|
4729
|
+
})]
|
|
4730
|
+
});
|
|
4731
|
+
};
|
|
4732
|
+
DragIcon.defaultProps = {
|
|
4733
|
+
width: "16",
|
|
4734
|
+
height: "16",
|
|
4735
|
+
fill: "none",
|
|
4736
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
4737
|
+
};
|
|
4664
4738
|
var ExternalLinkIcon = function ExternalLinkIcon(props) {
|
|
4665
4739
|
return jsxRuntime.jsx("svg", {
|
|
4666
4740
|
...props,
|
|
@@ -4668,7 +4742,7 @@ var ExternalLinkIcon = function ExternalLinkIcon(props) {
|
|
|
4668
4742
|
fillRule: "evenodd",
|
|
4669
4743
|
clipRule: "evenodd",
|
|
4670
4744
|
d: "M12.637 12.637v-4.72h1.362v4.721c0 .36-.137.676-.411.95-.275.275-.591.412-.95.412H3.362c-.38 0-.703-.132-.967-.396A1.315 1.315 0 0 1 2 12.638V3.362c0-.38.132-.703.396-.967S2.982 2 3.363 2h4.553v1.363H3.363v9.274h9.274ZM14 2H9.28l-.001 1.362h2.408L5.065 9.984l.95.95 6.622-6.622v2.409H14V2Z",
|
|
4671
|
-
fill: "
|
|
4745
|
+
fill: "currentcolor"
|
|
4672
4746
|
})
|
|
4673
4747
|
});
|
|
4674
4748
|
};
|
|
@@ -4811,7 +4885,7 @@ function TooltipWrapper(props) {
|
|
|
4811
4885
|
return jsxRuntime.jsx(Tooltip, {
|
|
4812
4886
|
...props,
|
|
4813
4887
|
value: value,
|
|
4814
|
-
forId: prefixId$
|
|
4888
|
+
forId: prefixId$9(forId)
|
|
4815
4889
|
});
|
|
4816
4890
|
}
|
|
4817
4891
|
function Tooltip(props) {
|
|
@@ -4929,7 +5003,7 @@ function getTooltipPosition(refElement) {
|
|
|
4929
5003
|
function isHovered(element) {
|
|
4930
5004
|
return element.matches(':hover');
|
|
4931
5005
|
}
|
|
4932
|
-
function prefixId$
|
|
5006
|
+
function prefixId$9(id) {
|
|
4933
5007
|
return `bio-properties-panel-${id}`;
|
|
4934
5008
|
}
|
|
4935
5009
|
|
|
@@ -5302,638 +5376,739 @@ function Placeholder(props) {
|
|
|
5302
5376
|
})
|
|
5303
5377
|
});
|
|
5304
5378
|
}
|
|
5305
|
-
|
|
5306
|
-
const
|
|
5307
|
-
|
|
5379
|
+
function Description$1(props) {
|
|
5380
|
+
const {
|
|
5381
|
+
element,
|
|
5382
|
+
forId,
|
|
5383
|
+
value
|
|
5384
|
+
} = props;
|
|
5385
|
+
const contextDescription = useDescriptionContext(forId, element);
|
|
5386
|
+
const description = value || contextDescription;
|
|
5387
|
+
if (description) {
|
|
5388
|
+
return jsxRuntime.jsx("div", {
|
|
5389
|
+
class: "bio-properties-panel-description",
|
|
5390
|
+
children: description
|
|
5391
|
+
});
|
|
5392
|
+
}
|
|
5393
|
+
}
|
|
5394
|
+
const noop$6 = () => {};
|
|
5308
5395
|
|
|
5309
5396
|
/**
|
|
5310
|
-
*
|
|
5311
|
-
*
|
|
5312
|
-
* id: String,
|
|
5313
|
-
* isEdited?: Function
|
|
5314
|
-
* } } EntryDefinition
|
|
5315
|
-
*
|
|
5316
|
-
* @typedef { {
|
|
5317
|
-
* autoFocusEntry: String,
|
|
5318
|
-
* autoOpen?: Boolean,
|
|
5319
|
-
* entries: Array<EntryDefinition>,
|
|
5320
|
-
* id: String,
|
|
5321
|
-
* label: String,
|
|
5322
|
-
* remove: (event: MouseEvent) => void
|
|
5323
|
-
* } } ListItemDefinition
|
|
5324
|
-
*
|
|
5325
|
-
* @typedef { {
|
|
5326
|
-
* add: (event: MouseEvent) => void,
|
|
5327
|
-
* component: import('preact').Component,
|
|
5328
|
-
* element: Object,
|
|
5329
|
-
* id: String,
|
|
5330
|
-
* items: Array<ListItemDefinition>,
|
|
5331
|
-
* label: String,
|
|
5332
|
-
* shouldSort?: Boolean,
|
|
5333
|
-
* shouldOpen?: Boolean
|
|
5334
|
-
* } } ListGroupDefinition
|
|
5335
|
-
*
|
|
5336
|
-
* @typedef { {
|
|
5337
|
-
* component?: import('preact').Component,
|
|
5338
|
-
* entries: Array<EntryDefinition>,
|
|
5339
|
-
* id: String,
|
|
5340
|
-
* label: String,
|
|
5341
|
-
* shouldOpen?: Boolean
|
|
5342
|
-
* } } GroupDefinition
|
|
5343
|
-
*
|
|
5344
|
-
* @typedef { {
|
|
5345
|
-
* [id: String]: GetDescriptionFunction
|
|
5346
|
-
* } } DescriptionConfig
|
|
5347
|
-
*
|
|
5348
|
-
* @typedef { {
|
|
5349
|
-
* [id: String]: GetTooltipFunction
|
|
5350
|
-
* } } TooltipConfig
|
|
5351
|
-
*
|
|
5352
|
-
* @callback { {
|
|
5353
|
-
* @param {string} id
|
|
5354
|
-
* @param {Object} element
|
|
5355
|
-
* @returns {string}
|
|
5356
|
-
* } } GetDescriptionFunction
|
|
5357
|
-
*
|
|
5358
|
-
* @callback { {
|
|
5359
|
-
* @param {string} id
|
|
5360
|
-
* @param {Object} element
|
|
5361
|
-
* @returns {string}
|
|
5362
|
-
* } } GetTooltipFunction
|
|
5363
|
-
*
|
|
5364
|
-
* @typedef { {
|
|
5365
|
-
* getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
|
|
5366
|
-
* getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
|
|
5367
|
-
* } } PlaceholderProvider
|
|
5368
|
-
*
|
|
5369
|
-
*/
|
|
5370
|
-
|
|
5371
|
-
/**
|
|
5372
|
-
* A basic properties panel component. Describes *how* content will be rendered, accepts
|
|
5373
|
-
* data from implementor to describe *what* will be rendered.
|
|
5374
|
-
*
|
|
5375
|
-
* @param {Object} props
|
|
5376
|
-
* @param {Object|Array} props.element
|
|
5377
|
-
* @param {import('./components/Header').HeaderProvider} props.headerProvider
|
|
5378
|
-
* @param {PlaceholderProvider} [props.placeholderProvider]
|
|
5379
|
-
* @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
|
|
5380
|
-
* @param {Object} [props.layoutConfig]
|
|
5381
|
-
* @param {Function} [props.layoutChanged]
|
|
5382
|
-
* @param {DescriptionConfig} [props.descriptionConfig]
|
|
5383
|
-
* @param {Function} [props.descriptionLoaded]
|
|
5384
|
-
* @param {TooltipConfig} [props.tooltipConfig]
|
|
5385
|
-
* @param {Function} [props.tooltipLoaded]
|
|
5386
|
-
* @param {Object} [props.eventBus]
|
|
5397
|
+
* Buffer `.focus()` calls while the editor is not initialized.
|
|
5398
|
+
* Set Focus inside when the editor is ready.
|
|
5387
5399
|
*/
|
|
5388
|
-
function
|
|
5400
|
+
const useBufferedFocus$1 = function (editor, ref) {
|
|
5401
|
+
const [buffer, setBuffer] = hooks.useState(undefined);
|
|
5402
|
+
ref.current = hooks.useMemo(() => ({
|
|
5403
|
+
focus: offset => {
|
|
5404
|
+
if (editor) {
|
|
5405
|
+
editor.focus(offset);
|
|
5406
|
+
} else {
|
|
5407
|
+
if (typeof offset === 'undefined') {
|
|
5408
|
+
offset = Infinity;
|
|
5409
|
+
}
|
|
5410
|
+
setBuffer(offset);
|
|
5411
|
+
}
|
|
5412
|
+
}
|
|
5413
|
+
}), [editor]);
|
|
5414
|
+
hooks.useEffect(() => {
|
|
5415
|
+
if (typeof buffer !== 'undefined' && editor) {
|
|
5416
|
+
editor.focus(buffer);
|
|
5417
|
+
setBuffer(false);
|
|
5418
|
+
}
|
|
5419
|
+
}, [editor, buffer]);
|
|
5420
|
+
};
|
|
5421
|
+
const CodeEditor$1 = React.forwardRef((props, ref) => {
|
|
5389
5422
|
const {
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5423
|
+
onInput,
|
|
5424
|
+
disabled,
|
|
5425
|
+
tooltipContainer,
|
|
5426
|
+
enableGutters,
|
|
5427
|
+
value,
|
|
5428
|
+
onLint = noop$6,
|
|
5429
|
+
onPopupOpen = noop$6,
|
|
5430
|
+
popupOpen,
|
|
5431
|
+
contentAttributes = {},
|
|
5432
|
+
hostLanguage = null,
|
|
5433
|
+
singleLine = false
|
|
5401
5434
|
} = props;
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
const [
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
}, [layoutConfig]);
|
|
5435
|
+
const inputRef = hooks.useRef();
|
|
5436
|
+
const [editor, setEditor] = hooks.useState();
|
|
5437
|
+
const [localValue, setLocalValue] = hooks.useState(value || '');
|
|
5438
|
+
useBufferedFocus$1(editor, ref);
|
|
5439
|
+
const handleInput = useStaticCallback(newValue => {
|
|
5440
|
+
onInput(newValue);
|
|
5441
|
+
setLocalValue(newValue);
|
|
5442
|
+
});
|
|
5411
5443
|
hooks.useEffect(() => {
|
|
5412
|
-
|
|
5413
|
-
|
|
5444
|
+
let editor;
|
|
5445
|
+
editor = new feelers.FeelersEditor({
|
|
5446
|
+
container: inputRef.current,
|
|
5447
|
+
onChange: handleInput,
|
|
5448
|
+
value: localValue,
|
|
5449
|
+
onLint,
|
|
5450
|
+
contentAttributes,
|
|
5451
|
+
tooltipContainer,
|
|
5452
|
+
enableGutters,
|
|
5453
|
+
hostLanguage,
|
|
5454
|
+
singleLine
|
|
5455
|
+
});
|
|
5456
|
+
setEditor(editor);
|
|
5457
|
+
return () => {
|
|
5458
|
+
onLint([]);
|
|
5459
|
+
inputRef.current.innerHTML = '';
|
|
5460
|
+
setEditor(null);
|
|
5461
|
+
};
|
|
5462
|
+
}, []);
|
|
5463
|
+
hooks.useEffect(() => {
|
|
5464
|
+
if (!editor) {
|
|
5465
|
+
return;
|
|
5414
5466
|
}
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
};
|
|
5424
|
-
const layoutContext = {
|
|
5425
|
-
layout,
|
|
5426
|
-
setLayout,
|
|
5427
|
-
getLayoutForKey,
|
|
5428
|
-
setLayoutForKey
|
|
5467
|
+
if (value === localValue) {
|
|
5468
|
+
return;
|
|
5469
|
+
}
|
|
5470
|
+
editor.setValue(value);
|
|
5471
|
+
setLocalValue(value);
|
|
5472
|
+
}, [value]);
|
|
5473
|
+
const handleClick = () => {
|
|
5474
|
+
ref.current.focus();
|
|
5429
5475
|
};
|
|
5476
|
+
return jsxRuntime.jsxs("div", {
|
|
5477
|
+
class: classnames('bio-properties-panel-feelers-editor-container', popupOpen ? 'popupOpen' : null),
|
|
5478
|
+
children: [jsxRuntime.jsx("div", {
|
|
5479
|
+
class: "bio-properties-panel-feelers-editor__open-popup-placeholder",
|
|
5480
|
+
children: "Opened in editor"
|
|
5481
|
+
}), jsxRuntime.jsx("div", {
|
|
5482
|
+
name: props.name,
|
|
5483
|
+
class: classnames('bio-properties-panel-feelers-editor bio-properties-panel-input', localValue ? 'edited' : null, disabled ? 'disabled' : null),
|
|
5484
|
+
ref: inputRef,
|
|
5485
|
+
onClick: handleClick
|
|
5486
|
+
}), jsxRuntime.jsx("button", {
|
|
5487
|
+
title: "Open pop-up editor",
|
|
5488
|
+
class: "bio-properties-panel-open-feel-popup",
|
|
5489
|
+
onClick: () => onPopupOpen('feelers'),
|
|
5490
|
+
children: jsxRuntime.jsx(ExternalLinkIcon, {})
|
|
5491
|
+
})]
|
|
5492
|
+
});
|
|
5493
|
+
});
|
|
5494
|
+
const noop$5 = () => {};
|
|
5430
5495
|
|
|
5431
|
-
|
|
5432
|
-
|
|
5496
|
+
/**
|
|
5497
|
+
* Buffer `.focus()` calls while the editor is not initialized.
|
|
5498
|
+
* Set Focus inside when the editor is ready.
|
|
5499
|
+
*/
|
|
5500
|
+
const useBufferedFocus = function (editor, ref) {
|
|
5501
|
+
const [buffer, setBuffer] = hooks.useState(undefined);
|
|
5502
|
+
ref.current = hooks.useMemo(() => ({
|
|
5503
|
+
focus: offset => {
|
|
5504
|
+
if (editor) {
|
|
5505
|
+
editor.focus(offset);
|
|
5506
|
+
} else {
|
|
5507
|
+
if (typeof offset === 'undefined') {
|
|
5508
|
+
offset = Infinity;
|
|
5509
|
+
}
|
|
5510
|
+
setBuffer(offset);
|
|
5511
|
+
}
|
|
5512
|
+
}
|
|
5513
|
+
}), [editor]);
|
|
5433
5514
|
hooks.useEffect(() => {
|
|
5434
|
-
if (typeof
|
|
5435
|
-
|
|
5515
|
+
if (typeof buffer !== 'undefined' && editor) {
|
|
5516
|
+
editor.focus(buffer);
|
|
5517
|
+
setBuffer(false);
|
|
5436
5518
|
}
|
|
5437
|
-
}, [
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5519
|
+
}, [editor, buffer]);
|
|
5520
|
+
};
|
|
5521
|
+
const CodeEditor = React.forwardRef((props, ref) => {
|
|
5522
|
+
const {
|
|
5523
|
+
enableGutters,
|
|
5524
|
+
value,
|
|
5525
|
+
onInput,
|
|
5526
|
+
onFeelToggle = noop$5,
|
|
5527
|
+
onLint = noop$5,
|
|
5528
|
+
onPopupOpen = noop$5,
|
|
5529
|
+
popupOpen,
|
|
5530
|
+
disabled,
|
|
5531
|
+
tooltipContainer,
|
|
5532
|
+
variables
|
|
5533
|
+
} = props;
|
|
5534
|
+
const inputRef = hooks.useRef();
|
|
5535
|
+
const [editor, setEditor] = hooks.useState();
|
|
5536
|
+
const [localValue, setLocalValue] = hooks.useState(value || '');
|
|
5537
|
+
useBufferedFocus(editor, ref);
|
|
5538
|
+
const handleInput = useStaticCallback(newValue => {
|
|
5539
|
+
onInput(newValue);
|
|
5540
|
+
setLocalValue(newValue);
|
|
5541
|
+
});
|
|
5542
|
+
hooks.useEffect(() => {
|
|
5543
|
+
let editor;
|
|
5445
5544
|
|
|
5446
|
-
|
|
5447
|
-
|
|
5545
|
+
/* Trigger FEEL toggle when
|
|
5546
|
+
*
|
|
5547
|
+
* - `backspace` is pressed
|
|
5548
|
+
* - AND the cursor is at the beginning of the input
|
|
5549
|
+
*/
|
|
5550
|
+
const onKeyDown = e => {
|
|
5551
|
+
if (e.key !== 'Backspace' || !editor) {
|
|
5552
|
+
return;
|
|
5553
|
+
}
|
|
5554
|
+
const selection = editor.getSelection();
|
|
5555
|
+
const range = selection.ranges[selection.mainIndex];
|
|
5556
|
+
if (range.from === 0 && range.to === 0) {
|
|
5557
|
+
onFeelToggle();
|
|
5558
|
+
}
|
|
5559
|
+
};
|
|
5560
|
+
editor = new FeelEditor({
|
|
5561
|
+
container: inputRef.current,
|
|
5562
|
+
onChange: handleInput,
|
|
5563
|
+
onKeyDown: onKeyDown,
|
|
5564
|
+
onLint: onLint,
|
|
5565
|
+
tooltipContainer: tooltipContainer,
|
|
5566
|
+
value: localValue,
|
|
5567
|
+
variables: variables,
|
|
5568
|
+
extensions: [...(enableGutters ? [view.lineNumbers()] : [])]
|
|
5569
|
+
});
|
|
5570
|
+
setEditor(editor);
|
|
5571
|
+
return () => {
|
|
5572
|
+
onLint([]);
|
|
5573
|
+
inputRef.current.innerHTML = '';
|
|
5574
|
+
setEditor(null);
|
|
5575
|
+
};
|
|
5576
|
+
}, []);
|
|
5448
5577
|
hooks.useEffect(() => {
|
|
5449
|
-
if (
|
|
5450
|
-
|
|
5578
|
+
if (!editor) {
|
|
5579
|
+
return;
|
|
5451
5580
|
}
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
}
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
errors
|
|
5467
|
-
};
|
|
5468
|
-
const eventContext = {
|
|
5469
|
-
eventBus
|
|
5470
|
-
};
|
|
5471
|
-
const propertiesPanelContext = {
|
|
5472
|
-
element
|
|
5581
|
+
if (value === localValue) {
|
|
5582
|
+
return;
|
|
5583
|
+
}
|
|
5584
|
+
editor.setValue(value);
|
|
5585
|
+
setLocalValue(value);
|
|
5586
|
+
}, [value]);
|
|
5587
|
+
hooks.useEffect(() => {
|
|
5588
|
+
if (!editor) {
|
|
5589
|
+
return;
|
|
5590
|
+
}
|
|
5591
|
+
editor.setVariables(variables);
|
|
5592
|
+
}, [variables]);
|
|
5593
|
+
const handleClick = () => {
|
|
5594
|
+
ref.current.focus();
|
|
5473
5595
|
};
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
})
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5596
|
+
return jsxRuntime.jsxs("div", {
|
|
5597
|
+
class: classnames('bio-properties-panel-feel-editor-container', disabled ? 'disabled' : null, popupOpen ? 'popupOpen' : null),
|
|
5598
|
+
children: [jsxRuntime.jsx("div", {
|
|
5599
|
+
class: "bio-properties-panel-feel-editor__open-popup-placeholder",
|
|
5600
|
+
children: "Opened in editor"
|
|
5601
|
+
}), jsxRuntime.jsx("div", {
|
|
5602
|
+
name: props.name,
|
|
5603
|
+
class: classnames('bio-properties-panel-input', localValue ? 'edited' : null),
|
|
5604
|
+
ref: inputRef,
|
|
5605
|
+
onClick: handleClick
|
|
5606
|
+
}), jsxRuntime.jsx("button", {
|
|
5607
|
+
title: "Open pop-up editor",
|
|
5608
|
+
class: "bio-properties-panel-open-feel-popup",
|
|
5609
|
+
onClick: () => onPopupOpen(),
|
|
5610
|
+
children: jsxRuntime.jsx(ExternalLinkIcon, {})
|
|
5611
|
+
})]
|
|
5612
|
+
});
|
|
5613
|
+
});
|
|
5614
|
+
function FeelIndicator(props) {
|
|
5615
|
+
const {
|
|
5616
|
+
active
|
|
5617
|
+
} = props;
|
|
5618
|
+
if (!active) {
|
|
5619
|
+
return null;
|
|
5487
5620
|
}
|
|
5488
|
-
return jsxRuntime.jsx(
|
|
5489
|
-
|
|
5490
|
-
children:
|
|
5491
|
-
value: errorsContext,
|
|
5492
|
-
children: jsxRuntime.jsx(DescriptionContext.Provider, {
|
|
5493
|
-
value: descriptionContext,
|
|
5494
|
-
children: jsxRuntime.jsx(TooltipContext.Provider, {
|
|
5495
|
-
value: tooltipContext,
|
|
5496
|
-
children: jsxRuntime.jsx(LayoutContext.Provider, {
|
|
5497
|
-
value: layoutContext,
|
|
5498
|
-
children: jsxRuntime.jsx(EventContext.Provider, {
|
|
5499
|
-
value: eventContext,
|
|
5500
|
-
children: jsxRuntime.jsxs("div", {
|
|
5501
|
-
class: "bio-properties-panel",
|
|
5502
|
-
children: [jsxRuntime.jsx(Header, {
|
|
5503
|
-
element: element,
|
|
5504
|
-
headerProvider: headerProvider
|
|
5505
|
-
}), jsxRuntime.jsx("div", {
|
|
5506
|
-
class: "bio-properties-panel-scroll-container",
|
|
5507
|
-
children: groups.map(group => {
|
|
5508
|
-
const {
|
|
5509
|
-
component: Component = Group,
|
|
5510
|
-
id
|
|
5511
|
-
} = group;
|
|
5512
|
-
return preact.createElement(Component, {
|
|
5513
|
-
...group,
|
|
5514
|
-
key: id,
|
|
5515
|
-
element: element
|
|
5516
|
-
});
|
|
5517
|
-
})
|
|
5518
|
-
})]
|
|
5519
|
-
})
|
|
5520
|
-
})
|
|
5521
|
-
})
|
|
5522
|
-
})
|
|
5523
|
-
})
|
|
5524
|
-
})
|
|
5621
|
+
return jsxRuntime.jsx("span", {
|
|
5622
|
+
class: "bio-properties-panel-feel-indicator",
|
|
5623
|
+
children: "="
|
|
5525
5624
|
});
|
|
5526
5625
|
}
|
|
5626
|
+
const noop$4 = () => {};
|
|
5527
5627
|
|
|
5528
|
-
|
|
5628
|
+
/**
|
|
5629
|
+
* @param {Object} props
|
|
5630
|
+
* @param {Object} props.label
|
|
5631
|
+
* @param {String} props.feel
|
|
5632
|
+
*/
|
|
5633
|
+
function FeelIcon(props) {
|
|
5634
|
+
const {
|
|
5635
|
+
feel = false,
|
|
5636
|
+
active,
|
|
5637
|
+
disabled = false,
|
|
5638
|
+
onClick = noop$4
|
|
5639
|
+
} = props;
|
|
5640
|
+
const feelRequiredLabel = 'FEEL expression is mandatory';
|
|
5641
|
+
const feelOptionalLabel = `Click to ${active ? 'remove' : 'set a'} dynamic value with FEEL expression`;
|
|
5642
|
+
const handleClick = e => {
|
|
5643
|
+
onClick(e);
|
|
5529
5644
|
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5645
|
+
// when pointer event was created from keyboard, keep focus on button
|
|
5646
|
+
if (!e.pointerType) {
|
|
5647
|
+
e.stopPropagation();
|
|
5648
|
+
}
|
|
5534
5649
|
};
|
|
5650
|
+
return jsxRuntime.jsx("button", {
|
|
5651
|
+
class: classnames('bio-properties-panel-feel-icon', active ? 'active' : null, feel === 'required' ? 'required' : 'optional'),
|
|
5652
|
+
onClick: handleClick,
|
|
5653
|
+
disabled: feel === 'required' || disabled,
|
|
5654
|
+
title: feel === 'required' ? feelRequiredLabel : feelOptionalLabel,
|
|
5655
|
+
children: jsxRuntime.jsx(FeelIcon$1, {})
|
|
5656
|
+
});
|
|
5535
5657
|
}
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5658
|
+
const FeelPopupContext = preact.createContext({
|
|
5659
|
+
open: () => {},
|
|
5660
|
+
close: () => {},
|
|
5661
|
+
source: null
|
|
5662
|
+
});
|
|
5663
|
+
|
|
5664
|
+
/**
|
|
5665
|
+
* Add a dragger that calls back the passed function with
|
|
5666
|
+
* { event, delta } on drag.
|
|
5667
|
+
*
|
|
5668
|
+
* @example
|
|
5669
|
+
*
|
|
5670
|
+
* function dragMove(event, delta) {
|
|
5671
|
+
* // we are dragging (!!)
|
|
5672
|
+
* }
|
|
5673
|
+
*
|
|
5674
|
+
* domElement.addEventListener('dragstart', dragger(dragMove));
|
|
5675
|
+
*
|
|
5676
|
+
* @param {Function} fn
|
|
5677
|
+
* @param {Element} [dragPreview]
|
|
5678
|
+
*
|
|
5679
|
+
* @return {Function} drag start callback function
|
|
5680
|
+
*/
|
|
5681
|
+
function createDragger(fn, dragPreview) {
|
|
5682
|
+
let self;
|
|
5683
|
+
let startX, startY;
|
|
5684
|
+
|
|
5685
|
+
/** drag start */
|
|
5686
|
+
function onDragStart(event) {
|
|
5687
|
+
self = this;
|
|
5688
|
+
startX = event.clientX;
|
|
5689
|
+
startY = event.clientY;
|
|
5690
|
+
|
|
5691
|
+
// (1) prevent preview image
|
|
5692
|
+
if (event.dataTransfer) {
|
|
5693
|
+
event.dataTransfer.setDragImage(dragPreview || emptyCanvas(), 0, 0);
|
|
5694
|
+
}
|
|
5695
|
+
|
|
5696
|
+
// (2) setup drag listeners
|
|
5697
|
+
|
|
5698
|
+
// attach drag + cleanup event
|
|
5699
|
+
document.addEventListener('dragover', onDrag);
|
|
5700
|
+
document.addEventListener('dragend', onEnd);
|
|
5701
|
+
document.addEventListener('drop', preventDefault);
|
|
5702
|
+
}
|
|
5703
|
+
function onDrag(event) {
|
|
5704
|
+
const delta = {
|
|
5705
|
+
x: event.clientX - startX,
|
|
5706
|
+
y: event.clientY - startY
|
|
5707
|
+
};
|
|
5708
|
+
|
|
5709
|
+
// call provided fn with event, delta
|
|
5710
|
+
return fn.call(self, event, delta);
|
|
5711
|
+
}
|
|
5712
|
+
function onEnd() {
|
|
5713
|
+
document.removeEventListener('dragover', onDrag);
|
|
5714
|
+
document.removeEventListener('dragend', onEnd);
|
|
5715
|
+
document.removeEventListener('drop', preventDefault);
|
|
5716
|
+
}
|
|
5717
|
+
return onDragStart;
|
|
5541
5718
|
}
|
|
5542
|
-
function
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
...overrides
|
|
5546
|
-
};
|
|
5719
|
+
function preventDefault(event) {
|
|
5720
|
+
event.preventDefault();
|
|
5721
|
+
event.stopPropagation();
|
|
5547
5722
|
}
|
|
5548
|
-
|
|
5549
|
-
|
|
5723
|
+
function emptyCanvas() {
|
|
5724
|
+
return minDom.domify('<canvas width="0" height="0" />');
|
|
5725
|
+
}
|
|
5726
|
+
const noop$3 = () => {};
|
|
5550
5727
|
|
|
5551
5728
|
/**
|
|
5552
|
-
*
|
|
5729
|
+
* A generic popup component.
|
|
5553
5730
|
*
|
|
5554
|
-
* @param {
|
|
5555
|
-
* @param {
|
|
5731
|
+
* @param {Object} props
|
|
5732
|
+
* @param {HTMLElement} [props.container]
|
|
5733
|
+
* @param {string} [props.className]
|
|
5734
|
+
* @param {{x: number, y: number}} [props.position]
|
|
5735
|
+
* @param {number} [props.width]
|
|
5736
|
+
* @param {number} [props.height]
|
|
5737
|
+
* @param {Function} props.onClose
|
|
5738
|
+
* @param {Function} [props.onPostActivate]
|
|
5739
|
+
* @param {Function} [props.onPostDeactivate]
|
|
5740
|
+
* @param {boolean} [props.returnFocus]
|
|
5741
|
+
* @param {string} props.title
|
|
5556
5742
|
*/
|
|
5557
|
-
function
|
|
5558
|
-
const
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5743
|
+
function Popup(props) {
|
|
5744
|
+
const {
|
|
5745
|
+
container,
|
|
5746
|
+
className,
|
|
5747
|
+
position,
|
|
5748
|
+
width,
|
|
5749
|
+
height,
|
|
5750
|
+
onClose,
|
|
5751
|
+
onPostActivate = noop$3,
|
|
5752
|
+
onPostDeactivate = noop$3,
|
|
5753
|
+
returnFocus = true,
|
|
5754
|
+
title
|
|
5755
|
+
} = props;
|
|
5756
|
+
const focusTrapRef = hooks.useRef(null);
|
|
5757
|
+
const popupRef = hooks.useRef(null);
|
|
5758
|
+
const handleKeyPress = event => {
|
|
5759
|
+
if (event.key === 'Escape') {
|
|
5760
|
+
onClose();
|
|
5564
5761
|
}
|
|
5565
|
-
}
|
|
5762
|
+
};
|
|
5763
|
+
|
|
5764
|
+
// re-activate focus trap on focus
|
|
5765
|
+
const handleFocus = () => {
|
|
5766
|
+
if (focusTrapRef.current) {
|
|
5767
|
+
focusTrapRef.current.activate();
|
|
5768
|
+
}
|
|
5769
|
+
};
|
|
5770
|
+
let style = {};
|
|
5771
|
+
if (position) {
|
|
5772
|
+
style = {
|
|
5773
|
+
...style,
|
|
5774
|
+
top: position.top + 'px',
|
|
5775
|
+
left: position.left + 'px'
|
|
5776
|
+
};
|
|
5777
|
+
}
|
|
5778
|
+
if (width) {
|
|
5779
|
+
style.width = width + 'px';
|
|
5780
|
+
}
|
|
5781
|
+
if (height) {
|
|
5782
|
+
style.height = height + 'px';
|
|
5783
|
+
}
|
|
5784
|
+
hooks.useEffect(() => {
|
|
5785
|
+
if (popupRef.current) {
|
|
5786
|
+
popupRef.current.addEventListener('keydown', handleKeyPress);
|
|
5787
|
+
}
|
|
5788
|
+
return () => {
|
|
5789
|
+
popupRef.current.removeEventListener('keydown', handleKeyPress);
|
|
5790
|
+
};
|
|
5791
|
+
}, [popupRef]);
|
|
5792
|
+
hooks.useEffect(() => {
|
|
5793
|
+
if (popupRef.current) {
|
|
5794
|
+
popupRef.current.addEventListener('focusin', handleFocus);
|
|
5795
|
+
}
|
|
5796
|
+
return () => {
|
|
5797
|
+
popupRef.current.removeEventListener('focusin', handleFocus);
|
|
5798
|
+
};
|
|
5799
|
+
}, [popupRef]);
|
|
5800
|
+
hooks.useEffect(() => {
|
|
5801
|
+
if (popupRef.current) {
|
|
5802
|
+
focusTrapRef.current = focusTrap__namespace.createFocusTrap(popupRef.current, {
|
|
5803
|
+
clickOutsideDeactivates: true,
|
|
5804
|
+
fallbackFocus: popupRef.current,
|
|
5805
|
+
onPostActivate,
|
|
5806
|
+
onPostDeactivate,
|
|
5807
|
+
returnFocusOnDeactivate: returnFocus
|
|
5808
|
+
});
|
|
5809
|
+
focusTrapRef.current.activate();
|
|
5810
|
+
}
|
|
5811
|
+
return () => focusTrapRef.current && focusTrapRef.current.deactivate();
|
|
5812
|
+
}, [popupRef]);
|
|
5813
|
+
return React.createPortal(jsxRuntime.jsx("div", {
|
|
5814
|
+
"aria-label": title,
|
|
5815
|
+
tabIndex: -1,
|
|
5816
|
+
ref: popupRef,
|
|
5817
|
+
role: "dialog",
|
|
5818
|
+
class: classnames('bio-properties-panel-popup', className),
|
|
5819
|
+
style: style,
|
|
5820
|
+
children: props.children
|
|
5821
|
+
}), container || document.body);
|
|
5566
5822
|
}
|
|
5567
|
-
|
|
5823
|
+
Popup.Title = Title;
|
|
5824
|
+
Popup.Body = Body;
|
|
5825
|
+
Popup.Footer = Footer;
|
|
5826
|
+
function Title(props) {
|
|
5568
5827
|
const {
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
remove
|
|
5828
|
+
children,
|
|
5829
|
+
className,
|
|
5830
|
+
draggable,
|
|
5831
|
+
title,
|
|
5832
|
+
...rest
|
|
5575
5833
|
} = props;
|
|
5576
|
-
const [open, setOpen] = hooks.useState(shouldOpen);
|
|
5577
|
-
const toggleOpen = () => setOpen(!open);
|
|
5578
|
-
const {
|
|
5579
|
-
onShow
|
|
5580
|
-
} = hooks.useContext(LayoutContext);
|
|
5581
|
-
const propertiesPanelContext = {
|
|
5582
|
-
...hooks.useContext(LayoutContext),
|
|
5583
|
-
onShow: hooks.useCallback(() => {
|
|
5584
|
-
setOpen(true);
|
|
5585
|
-
if (minDash.isFunction(onShow)) {
|
|
5586
|
-
onShow();
|
|
5587
|
-
}
|
|
5588
|
-
}, [onShow, setOpen])
|
|
5589
|
-
};
|
|
5590
5834
|
|
|
5591
|
-
//
|
|
5592
|
-
|
|
5835
|
+
// we can't use state as we need to
|
|
5836
|
+
// manipulate this inside dragging events
|
|
5837
|
+
const context = hooks.useRef({
|
|
5838
|
+
startPosition: null,
|
|
5839
|
+
newPosition: null
|
|
5840
|
+
});
|
|
5841
|
+
const dragPreviewRef = hooks.useRef();
|
|
5842
|
+
const titleRef = hooks.useRef();
|
|
5843
|
+
const onMove = minDash.throttle((_, delta) => {
|
|
5844
|
+
const {
|
|
5845
|
+
x: dx,
|
|
5846
|
+
y: dy
|
|
5847
|
+
} = delta;
|
|
5848
|
+
const newPosition = {
|
|
5849
|
+
x: context.current.startPosition.x + dx,
|
|
5850
|
+
y: context.current.startPosition.y + dy
|
|
5851
|
+
};
|
|
5852
|
+
const popupParent = getPopupParent(titleRef.current);
|
|
5853
|
+
popupParent.style.top = newPosition.y + 'px';
|
|
5854
|
+
popupParent.style.left = newPosition.x + 'px';
|
|
5855
|
+
});
|
|
5856
|
+
const onMoveStart = event => {
|
|
5857
|
+
// initialize drag handler
|
|
5858
|
+
const onDragStart = createDragger(onMove, dragPreviewRef.current);
|
|
5859
|
+
onDragStart(event);
|
|
5860
|
+
const popupParent = getPopupParent(titleRef.current);
|
|
5861
|
+
const bounds = popupParent.getBoundingClientRect();
|
|
5862
|
+
context.current.startPosition = {
|
|
5863
|
+
x: bounds.left,
|
|
5864
|
+
y: bounds.top
|
|
5865
|
+
};
|
|
5866
|
+
};
|
|
5867
|
+
const onMoveEnd = () => {
|
|
5868
|
+
context.current.newPosition = null;
|
|
5869
|
+
};
|
|
5593
5870
|
return jsxRuntime.jsxs("div", {
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5871
|
+
class: classnames('bio-properties-panel-popup__header', draggable && 'draggable', className),
|
|
5872
|
+
ref: titleRef,
|
|
5873
|
+
draggable: draggable,
|
|
5874
|
+
onDragStart: onMoveStart,
|
|
5875
|
+
onDragEnd: onMoveEnd,
|
|
5876
|
+
...rest,
|
|
5877
|
+
children: [draggable && jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
5599
5878
|
children: [jsxRuntime.jsx("div", {
|
|
5600
|
-
|
|
5601
|
-
class:
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
children: jsxRuntime.jsx(ArrowIcon, {
|
|
5607
|
-
class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
|
|
5608
|
-
})
|
|
5609
|
-
}), remove ? jsxRuntime.jsx("button", {
|
|
5610
|
-
title: "Delete item",
|
|
5611
|
-
class: "bio-properties-panel-remove-entry",
|
|
5612
|
-
onClick: remove,
|
|
5613
|
-
children: jsxRuntime.jsx(DeleteIcon, {})
|
|
5614
|
-
}) : null]
|
|
5879
|
+
ref: dragPreviewRef,
|
|
5880
|
+
class: "bio-properties-panel-popup__drag-preview"
|
|
5881
|
+
}), jsxRuntime.jsx("div", {
|
|
5882
|
+
class: "bio-properties-panel-popup__drag-handle",
|
|
5883
|
+
children: jsxRuntime.jsx(DragIcon, {})
|
|
5884
|
+
})]
|
|
5615
5885
|
}), jsxRuntime.jsx("div", {
|
|
5616
|
-
class:
|
|
5617
|
-
children:
|
|
5618
|
-
|
|
5619
|
-
children: entries.map(entry => {
|
|
5620
|
-
const {
|
|
5621
|
-
component: Component,
|
|
5622
|
-
id
|
|
5623
|
-
} = entry;
|
|
5624
|
-
return preact.createElement(Component, {
|
|
5625
|
-
...entry,
|
|
5626
|
-
element: element,
|
|
5627
|
-
key: id
|
|
5628
|
-
});
|
|
5629
|
-
})
|
|
5630
|
-
})
|
|
5631
|
-
})]
|
|
5886
|
+
class: "bio-properties-panel-popup__title",
|
|
5887
|
+
children: title
|
|
5888
|
+
}), children]
|
|
5632
5889
|
});
|
|
5633
5890
|
}
|
|
5634
|
-
function
|
|
5891
|
+
function Body(props) {
|
|
5635
5892
|
const {
|
|
5636
|
-
|
|
5637
|
-
|
|
5893
|
+
children,
|
|
5894
|
+
className,
|
|
5895
|
+
...rest
|
|
5638
5896
|
} = props;
|
|
5639
|
-
|
|
5640
|
-
// focus specified entry on auto open
|
|
5641
|
-
hooks.useEffect(() => {
|
|
5642
|
-
if (autoOpen && autoFocusEntry) {
|
|
5643
|
-
const entry = minDom.query(`[data-entry-id="${autoFocusEntry}"]`);
|
|
5644
|
-
const focusableInput = minDom.query('.bio-properties-panel-input', entry);
|
|
5645
|
-
if (focusableInput) {
|
|
5646
|
-
if (minDash.isFunction(focusableInput.select)) {
|
|
5647
|
-
focusableInput.select();
|
|
5648
|
-
} else if (minDash.isFunction(focusableInput.focus)) {
|
|
5649
|
-
focusableInput.focus();
|
|
5650
|
-
}
|
|
5651
|
-
}
|
|
5652
|
-
}
|
|
5653
|
-
}, [autoOpen, autoFocusEntry]);
|
|
5654
5897
|
return jsxRuntime.jsx("div", {
|
|
5655
|
-
class:
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
open: autoOpen
|
|
5659
|
-
})
|
|
5898
|
+
class: classnames('bio-properties-panel-popup__body', className),
|
|
5899
|
+
...rest,
|
|
5900
|
+
children: children
|
|
5660
5901
|
});
|
|
5661
5902
|
}
|
|
5662
|
-
|
|
5903
|
+
function Footer(props) {
|
|
5904
|
+
const {
|
|
5905
|
+
children,
|
|
5906
|
+
className,
|
|
5907
|
+
...rest
|
|
5908
|
+
} = props;
|
|
5909
|
+
return jsxRuntime.jsx("div", {
|
|
5910
|
+
class: classnames('bio-properties-panel-popup__footer', className),
|
|
5911
|
+
...rest,
|
|
5912
|
+
children: props.children
|
|
5913
|
+
});
|
|
5914
|
+
}
|
|
5915
|
+
|
|
5916
|
+
// helpers //////////////////////
|
|
5917
|
+
|
|
5918
|
+
function getPopupParent(node) {
|
|
5919
|
+
return node.closest('.bio-properties-panel-popup');
|
|
5920
|
+
}
|
|
5921
|
+
const FEEL_POPUP_WIDTH = 700;
|
|
5922
|
+
const FEEL_POPUP_HEIGHT = 250;
|
|
5663
5923
|
|
|
5664
5924
|
/**
|
|
5665
|
-
*
|
|
5925
|
+
* FEEL popup component, built as a singleton.
|
|
5666
5926
|
*/
|
|
5667
|
-
function
|
|
5927
|
+
function FEELPopupRoot(props) {
|
|
5668
5928
|
const {
|
|
5669
|
-
|
|
5670
|
-
element,
|
|
5671
|
-
id,
|
|
5672
|
-
items,
|
|
5673
|
-
label,
|
|
5674
|
-
shouldOpen = true,
|
|
5675
|
-
shouldSort = true
|
|
5929
|
+
element
|
|
5676
5930
|
} = props;
|
|
5677
|
-
const groupRef = hooks.useRef(null);
|
|
5678
|
-
const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
|
|
5679
|
-
const [sticky, setSticky] = hooks.useState(false);
|
|
5680
|
-
const onShow = hooks.useCallback(() => setOpen(true), [setOpen]);
|
|
5681
|
-
const [ordering, setOrdering] = hooks.useState([]);
|
|
5682
|
-
const [newItemAdded, setNewItemAdded] = hooks.useState(false);
|
|
5683
|
-
|
|
5684
|
-
// Flag to mark that add button was clicked in the last render cycle
|
|
5685
|
-
const [addTriggered, setAddTriggered] = hooks.useState(false);
|
|
5686
|
-
const prevItems = usePrevious(items);
|
|
5687
5931
|
const prevElement = usePrevious(element);
|
|
5688
|
-
const
|
|
5689
|
-
const
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5932
|
+
const [popupConfig, setPopupConfig] = hooks.useState({});
|
|
5933
|
+
const [open, setOpen] = hooks.useState(false);
|
|
5934
|
+
const [source, setSource] = hooks.useState(null);
|
|
5935
|
+
const [sourceElement, setSourceElement] = hooks.useState(null);
|
|
5936
|
+
const handleOpen = (key, config, _sourceElement) => {
|
|
5937
|
+
setSource(key);
|
|
5938
|
+
setPopupConfig(config);
|
|
5939
|
+
setOpen(true);
|
|
5940
|
+
setSourceElement(_sourceElement);
|
|
5941
|
+
};
|
|
5942
|
+
const handleClose = () => {
|
|
5943
|
+
setOpen(false);
|
|
5944
|
+
setSource(null);
|
|
5945
|
+
};
|
|
5946
|
+
const feelPopupContext = {
|
|
5947
|
+
open: handleOpen,
|
|
5948
|
+
close: handleClose,
|
|
5949
|
+
source
|
|
5950
|
+
};
|
|
5951
|
+
|
|
5952
|
+
// close popup on element change, cf. https://github.com/bpmn-io/properties-panel/issues/270
|
|
5706
5953
|
hooks.useEffect(() => {
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
if (shouldHandleEffects && prevItems && items.length > prevItems.length) {
|
|
5710
|
-
let add = [];
|
|
5711
|
-
items.forEach(item => {
|
|
5712
|
-
if (!ordering.includes(item.id)) {
|
|
5713
|
-
add.push(item.id);
|
|
5714
|
-
}
|
|
5715
|
-
});
|
|
5716
|
-
let newOrdering = ordering;
|
|
5717
|
-
|
|
5718
|
-
// open if not open, configured and triggered by add button
|
|
5719
|
-
//
|
|
5720
|
-
// TODO(marstamm): remove once we refactor layout handling for listGroups.
|
|
5721
|
-
// Ideally, opening should be handled as part of the `add` callback and
|
|
5722
|
-
// not be a concern for the ListGroup component.
|
|
5723
|
-
if (addTriggered && !open && shouldOpen) {
|
|
5724
|
-
toggleOpen();
|
|
5725
|
-
}
|
|
5726
|
-
|
|
5727
|
-
// filter when not open and configured
|
|
5728
|
-
if (!open && shouldSort) {
|
|
5729
|
-
newOrdering = createOrdering(sortItems(items));
|
|
5730
|
-
}
|
|
5731
|
-
|
|
5732
|
-
// add new items on top or bottom depending on sorting behavior
|
|
5733
|
-
newOrdering = newOrdering.filter(item => !add.includes(item));
|
|
5734
|
-
if (shouldSort) {
|
|
5735
|
-
newOrdering.unshift(...add);
|
|
5736
|
-
} else {
|
|
5737
|
-
newOrdering.push(...add);
|
|
5738
|
-
}
|
|
5739
|
-
setOrdering(newOrdering);
|
|
5740
|
-
setNewItemAdded(addTriggered);
|
|
5741
|
-
} else {
|
|
5742
|
-
setNewItemAdded(false);
|
|
5954
|
+
if (element && element !== prevElement) {
|
|
5955
|
+
handleClose();
|
|
5743
5956
|
}
|
|
5744
|
-
}, [
|
|
5745
|
-
|
|
5746
|
-
|
|
5957
|
+
}, [element]);
|
|
5958
|
+
return jsxRuntime.jsxs(FeelPopupContext.Provider, {
|
|
5959
|
+
value: feelPopupContext,
|
|
5960
|
+
children: [open && jsxRuntime.jsx(FeelPopupComponent, {
|
|
5961
|
+
onClose: handleClose,
|
|
5962
|
+
sourceElement: sourceElement,
|
|
5963
|
+
...popupConfig
|
|
5964
|
+
}), props.children]
|
|
5965
|
+
});
|
|
5966
|
+
}
|
|
5967
|
+
function FeelPopupComponent(props) {
|
|
5968
|
+
const {
|
|
5969
|
+
id,
|
|
5970
|
+
hostLanguage,
|
|
5971
|
+
onInput,
|
|
5972
|
+
onClose,
|
|
5973
|
+
position,
|
|
5974
|
+
singleLine,
|
|
5975
|
+
sourceElement,
|
|
5976
|
+
title,
|
|
5977
|
+
tooltipContainer,
|
|
5978
|
+
type,
|
|
5979
|
+
value,
|
|
5980
|
+
variables
|
|
5981
|
+
} = props;
|
|
5982
|
+
const editorRef = hooks.useRef();
|
|
5983
|
+
const handleSetReturnFocus = () => {
|
|
5984
|
+
sourceElement && sourceElement.focus();
|
|
5985
|
+
};
|
|
5747
5986
|
hooks.useEffect(() => {
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5987
|
+
const editor = editorRef.current;
|
|
5988
|
+
if (editor) {
|
|
5989
|
+
editor.focus();
|
|
5990
|
+
}
|
|
5991
|
+
}, [editorRef, id]);
|
|
5992
|
+
return jsxRuntime.jsxs(Popup, {
|
|
5993
|
+
className: "bio-properties-panel-feel-popup",
|
|
5994
|
+
position: position,
|
|
5995
|
+
title: title,
|
|
5996
|
+
onClose: onClose
|
|
5997
|
+
|
|
5998
|
+
// handle focus manually on deactivate
|
|
5999
|
+
,
|
|
6000
|
+
|
|
6001
|
+
returnFocus: false,
|
|
6002
|
+
onPostDeactivate: handleSetReturnFocus,
|
|
6003
|
+
height: FEEL_POPUP_HEIGHT,
|
|
6004
|
+
width: FEEL_POPUP_WIDTH,
|
|
6005
|
+
children: [jsxRuntime.jsx(Popup.Title, {
|
|
6006
|
+
title: title,
|
|
6007
|
+
draggable: true
|
|
6008
|
+
}), jsxRuntime.jsx(Popup.Body, {
|
|
6009
|
+
children: jsxRuntime.jsxs("div", {
|
|
6010
|
+
class: "bio-properties-panel-feel-popup__body",
|
|
6011
|
+
children: [type === 'feel' && jsxRuntime.jsx(CodeEditor, {
|
|
6012
|
+
enableGutters: true,
|
|
6013
|
+
id: prefixId$8(id),
|
|
6014
|
+
name: id,
|
|
6015
|
+
onInput: onInput,
|
|
6016
|
+
value: value,
|
|
6017
|
+
variables: variables,
|
|
6018
|
+
ref: editorRef,
|
|
6019
|
+
tooltipContainer: tooltipContainer
|
|
6020
|
+
}), type === 'feelers' && jsxRuntime.jsx(CodeEditor$1, {
|
|
6021
|
+
id: prefixId$8(id),
|
|
6022
|
+
contentAttributes: {
|
|
6023
|
+
'aria-label': title
|
|
6024
|
+
},
|
|
6025
|
+
enableGutters: true,
|
|
6026
|
+
hostLanguage: hostLanguage,
|
|
6027
|
+
name: id,
|
|
6028
|
+
onInput: onInput,
|
|
6029
|
+
value: value,
|
|
6030
|
+
ref: editorRef,
|
|
6031
|
+
singleLine: singleLine,
|
|
6032
|
+
tooltipContainer: tooltipContainer
|
|
6033
|
+
})]
|
|
6034
|
+
})
|
|
6035
|
+
}), jsxRuntime.jsx(Popup.Footer, {
|
|
6036
|
+
children: jsxRuntime.jsx("button", {
|
|
6037
|
+
onClick: onClose,
|
|
6038
|
+
title: "Close pop-up editor",
|
|
6039
|
+
class: "bio-properties-panel-feel-popup__close-btn",
|
|
6040
|
+
children: "Close"
|
|
6041
|
+
})
|
|
6042
|
+
})]
|
|
6043
|
+
});
|
|
6044
|
+
}
|
|
5752
6045
|
|
|
5753
|
-
|
|
5754
|
-
hooks.useEffect(() => {
|
|
5755
|
-
if (shouldHandleEffects && prevItems && items.length < prevItems.length) {
|
|
5756
|
-
let keep = [];
|
|
5757
|
-
ordering.forEach(o => {
|
|
5758
|
-
if (getItem(items, o)) {
|
|
5759
|
-
keep.push(o);
|
|
5760
|
-
}
|
|
5761
|
-
});
|
|
5762
|
-
setOrdering(keep);
|
|
5763
|
-
}
|
|
5764
|
-
}, [items, shouldHandleEffects]);
|
|
6046
|
+
// helpers /////////////////
|
|
5765
6047
|
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
const
|
|
5771
|
-
|
|
5772
|
-
|
|
6048
|
+
function prefixId$8(id) {
|
|
6049
|
+
return `bio-properties-panel-${id}`;
|
|
6050
|
+
}
|
|
6051
|
+
function ToggleSwitch(props) {
|
|
6052
|
+
const {
|
|
6053
|
+
id,
|
|
6054
|
+
label,
|
|
6055
|
+
onInput,
|
|
6056
|
+
value,
|
|
6057
|
+
switcherLabel,
|
|
6058
|
+
inline,
|
|
6059
|
+
onFocus,
|
|
6060
|
+
onBlur,
|
|
6061
|
+
inputRef,
|
|
6062
|
+
tooltip
|
|
6063
|
+
} = props;
|
|
6064
|
+
const [localValue, setLocalValue] = hooks.useState(value);
|
|
6065
|
+
const handleInputCallback = async () => {
|
|
6066
|
+
onInput(!value);
|
|
5773
6067
|
};
|
|
5774
|
-
const
|
|
5775
|
-
|
|
5776
|
-
|
|
6068
|
+
const handleInput = e => {
|
|
6069
|
+
handleInputCallback();
|
|
6070
|
+
setLocalValue(e.target.value);
|
|
5777
6071
|
};
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
if (allErrors[item.id]) {
|
|
5781
|
-
return true;
|
|
5782
|
-
}
|
|
5783
|
-
if (!item.entries) {
|
|
6072
|
+
hooks.useEffect(() => {
|
|
6073
|
+
if (value === localValue) {
|
|
5784
6074
|
return;
|
|
5785
6075
|
}
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
return item.entries.some(entry => allErrors[entry.id]);
|
|
5789
|
-
});
|
|
6076
|
+
setLocalValue(value);
|
|
6077
|
+
}, [value]);
|
|
5790
6078
|
return jsxRuntime.jsxs("div", {
|
|
5791
|
-
class:
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
children: [jsxRuntime.
|
|
5795
|
-
class: classnames('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : '', sticky && open ? 'sticky' : ''),
|
|
5796
|
-
onClick: hasItems ? toggleOpen : noop$3,
|
|
5797
|
-
children: [jsxRuntime.jsx("div", {
|
|
5798
|
-
title: label,
|
|
5799
|
-
class: "bio-properties-panel-group-header-title",
|
|
5800
|
-
children: jsxRuntime.jsx(TooltipWrapper, {
|
|
5801
|
-
value: props.tooltip,
|
|
5802
|
-
forId: 'group-' + id,
|
|
5803
|
-
element: element,
|
|
5804
|
-
parent: groupRef,
|
|
5805
|
-
children: label
|
|
5806
|
-
})
|
|
5807
|
-
}), jsxRuntime.jsxs("div", {
|
|
5808
|
-
class: "bio-properties-panel-group-header-buttons",
|
|
5809
|
-
children: [add ? jsxRuntime.jsxs("button", {
|
|
5810
|
-
title: "Create new list item",
|
|
5811
|
-
class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
|
|
5812
|
-
onClick: handleAddClick,
|
|
5813
|
-
children: [jsxRuntime.jsx(CreateIcon, {}), !hasItems ? jsxRuntime.jsx("span", {
|
|
5814
|
-
class: "bio-properties-panel-add-entry-label",
|
|
5815
|
-
children: "Create"
|
|
5816
|
-
}) : null]
|
|
5817
|
-
}) : null, hasItems ? jsxRuntime.jsx("div", {
|
|
5818
|
-
title: `List contains ${items.length} item${items.length != 1 ? 's' : ''}`,
|
|
5819
|
-
class: classnames('bio-properties-panel-list-badge', hasError ? 'bio-properties-panel-list-badge--error' : ''),
|
|
5820
|
-
children: items.length
|
|
5821
|
-
}) : null, hasItems ? jsxRuntime.jsx("button", {
|
|
5822
|
-
title: "Toggle section",
|
|
5823
|
-
class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
|
|
5824
|
-
children: jsxRuntime.jsx(ArrowIcon, {
|
|
5825
|
-
class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
|
|
5826
|
-
})
|
|
5827
|
-
}) : null]
|
|
5828
|
-
})]
|
|
5829
|
-
}), jsxRuntime.jsx("div", {
|
|
5830
|
-
class: classnames('bio-properties-panel-list', open && hasItems ? 'open' : ''),
|
|
5831
|
-
children: jsxRuntime.jsx(LayoutContext.Provider, {
|
|
5832
|
-
value: propertiesPanelContext,
|
|
5833
|
-
children: ordering.map((o, index) => {
|
|
5834
|
-
const item = getItem(items, o);
|
|
5835
|
-
if (!item) {
|
|
5836
|
-
return;
|
|
5837
|
-
}
|
|
5838
|
-
const {
|
|
5839
|
-
id
|
|
5840
|
-
} = item;
|
|
5841
|
-
|
|
5842
|
-
// if item was added, open it
|
|
5843
|
-
// Existing items will not be affected as autoOpen is only applied on first render
|
|
5844
|
-
const autoOpen = newItemAdded;
|
|
5845
|
-
return preact.createElement(ListItem, {
|
|
5846
|
-
...item,
|
|
5847
|
-
autoOpen: autoOpen,
|
|
5848
|
-
element: element,
|
|
5849
|
-
index: index,
|
|
5850
|
-
key: id
|
|
5851
|
-
});
|
|
5852
|
-
})
|
|
5853
|
-
})
|
|
5854
|
-
})]
|
|
5855
|
-
});
|
|
5856
|
-
}
|
|
5857
|
-
|
|
5858
|
-
// helpers ////////////////////
|
|
5859
|
-
|
|
5860
|
-
/**
|
|
5861
|
-
* Sorts given items alphanumeric by label
|
|
5862
|
-
*/
|
|
5863
|
-
function sortItems(items) {
|
|
5864
|
-
return minDash.sortBy(items, i => i.label.toLowerCase());
|
|
5865
|
-
}
|
|
5866
|
-
function getItem(items, id) {
|
|
5867
|
-
return minDash.find(items, i => i.id === id);
|
|
5868
|
-
}
|
|
5869
|
-
function createOrdering(items) {
|
|
5870
|
-
return items.map(i => i.id);
|
|
5871
|
-
}
|
|
5872
|
-
function Description$1(props) {
|
|
5873
|
-
const {
|
|
5874
|
-
element,
|
|
5875
|
-
forId,
|
|
5876
|
-
value
|
|
5877
|
-
} = props;
|
|
5878
|
-
const contextDescription = useDescriptionContext(forId, element);
|
|
5879
|
-
const description = value || contextDescription;
|
|
5880
|
-
if (description) {
|
|
5881
|
-
return jsxRuntime.jsx("div", {
|
|
5882
|
-
class: "bio-properties-panel-description",
|
|
5883
|
-
children: description
|
|
5884
|
-
});
|
|
5885
|
-
}
|
|
5886
|
-
}
|
|
5887
|
-
function Checkbox(props) {
|
|
5888
|
-
const {
|
|
5889
|
-
id,
|
|
5890
|
-
label,
|
|
5891
|
-
onChange,
|
|
5892
|
-
disabled,
|
|
5893
|
-
value = false,
|
|
5894
|
-
onFocus,
|
|
5895
|
-
onBlur,
|
|
5896
|
-
tooltip
|
|
5897
|
-
} = props;
|
|
5898
|
-
const [localValue, setLocalValue] = hooks.useState(value);
|
|
5899
|
-
const handleChangeCallback = ({
|
|
5900
|
-
target
|
|
5901
|
-
}) => {
|
|
5902
|
-
onChange(target.checked);
|
|
5903
|
-
};
|
|
5904
|
-
const handleChange = e => {
|
|
5905
|
-
handleChangeCallback(e);
|
|
5906
|
-
setLocalValue(e.target.value);
|
|
5907
|
-
};
|
|
5908
|
-
hooks.useEffect(() => {
|
|
5909
|
-
if (value === localValue) {
|
|
5910
|
-
return;
|
|
5911
|
-
}
|
|
5912
|
-
setLocalValue(value);
|
|
5913
|
-
}, [value]);
|
|
5914
|
-
const ref = useShowEntryEvent(id);
|
|
5915
|
-
return jsxRuntime.jsxs("div", {
|
|
5916
|
-
class: "bio-properties-panel-checkbox",
|
|
5917
|
-
children: [jsxRuntime.jsx("input", {
|
|
5918
|
-
ref: ref,
|
|
5919
|
-
id: prefixId$7(id),
|
|
5920
|
-
name: id,
|
|
5921
|
-
onFocus: onFocus,
|
|
5922
|
-
onBlur: onBlur,
|
|
5923
|
-
type: "checkbox",
|
|
5924
|
-
class: "bio-properties-panel-input",
|
|
5925
|
-
onChange: handleChange,
|
|
5926
|
-
checked: localValue,
|
|
5927
|
-
disabled: disabled
|
|
5928
|
-
}), jsxRuntime.jsx("label", {
|
|
5929
|
-
for: prefixId$7(id),
|
|
6079
|
+
class: classnames('bio-properties-panel-toggle-switch', {
|
|
6080
|
+
inline
|
|
6081
|
+
}),
|
|
6082
|
+
children: [jsxRuntime.jsx("label", {
|
|
5930
6083
|
class: "bio-properties-panel-label",
|
|
6084
|
+
for: prefixId$7(id),
|
|
5931
6085
|
children: jsxRuntime.jsx(TooltipWrapper, {
|
|
5932
6086
|
value: tooltip,
|
|
5933
6087
|
forId: id,
|
|
5934
6088
|
element: props.element,
|
|
5935
6089
|
children: label
|
|
5936
6090
|
})
|
|
6091
|
+
}), jsxRuntime.jsxs("div", {
|
|
6092
|
+
class: "bio-properties-panel-field-wrapper",
|
|
6093
|
+
children: [jsxRuntime.jsxs("label", {
|
|
6094
|
+
class: "bio-properties-panel-toggle-switch__switcher",
|
|
6095
|
+
children: [jsxRuntime.jsx("input", {
|
|
6096
|
+
ref: inputRef,
|
|
6097
|
+
id: prefixId$7(id),
|
|
6098
|
+
class: "bio-properties-panel-input",
|
|
6099
|
+
type: "checkbox",
|
|
6100
|
+
onFocus: onFocus,
|
|
6101
|
+
onBlur: onBlur,
|
|
6102
|
+
name: id,
|
|
6103
|
+
onInput: handleInput,
|
|
6104
|
+
checked: !!localValue
|
|
6105
|
+
}), jsxRuntime.jsx("span", {
|
|
6106
|
+
class: "bio-properties-panel-toggle-switch__slider"
|
|
6107
|
+
})]
|
|
6108
|
+
}), switcherLabel && jsxRuntime.jsx("p", {
|
|
6109
|
+
class: "bio-properties-panel-toggle-switch__label",
|
|
6110
|
+
children: switcherLabel
|
|
6111
|
+
})]
|
|
5937
6112
|
})]
|
|
5938
6113
|
});
|
|
5939
6114
|
}
|
|
@@ -5944,44 +6119,43 @@ function Checkbox(props) {
|
|
|
5944
6119
|
* @param {String} props.id
|
|
5945
6120
|
* @param {String} props.description
|
|
5946
6121
|
* @param {String} props.label
|
|
6122
|
+
* @param {String} props.switcherLabel
|
|
6123
|
+
* @param {Boolean} props.inline
|
|
5947
6124
|
* @param {Function} props.getValue
|
|
5948
6125
|
* @param {Function} props.setValue
|
|
5949
6126
|
* @param {Function} props.onFocus
|
|
5950
6127
|
* @param {Function} props.onBlur
|
|
5951
6128
|
* @param {string|import('preact').Component} props.tooltip
|
|
5952
|
-
* @param {boolean} [props.disabled]
|
|
5953
6129
|
*/
|
|
5954
|
-
function
|
|
6130
|
+
function ToggleSwitchEntry(props) {
|
|
5955
6131
|
const {
|
|
5956
6132
|
element,
|
|
5957
6133
|
id,
|
|
5958
6134
|
description,
|
|
5959
6135
|
label,
|
|
6136
|
+
switcherLabel,
|
|
6137
|
+
inline,
|
|
5960
6138
|
getValue,
|
|
5961
6139
|
setValue,
|
|
5962
|
-
disabled,
|
|
5963
6140
|
onFocus,
|
|
5964
6141
|
onBlur,
|
|
5965
6142
|
tooltip
|
|
5966
6143
|
} = props;
|
|
5967
6144
|
const value = getValue(element);
|
|
5968
|
-
const error = useError(id);
|
|
5969
6145
|
return jsxRuntime.jsxs("div", {
|
|
5970
|
-
class: "bio-properties-panel-entry bio-properties-panel-
|
|
6146
|
+
class: "bio-properties-panel-entry bio-properties-panel-toggle-switch-entry",
|
|
5971
6147
|
"data-entry-id": id,
|
|
5972
|
-
children: [jsxRuntime.jsx(
|
|
5973
|
-
disabled: disabled,
|
|
6148
|
+
children: [jsxRuntime.jsx(ToggleSwitch, {
|
|
5974
6149
|
id: id,
|
|
5975
6150
|
label: label,
|
|
5976
|
-
|
|
6151
|
+
value: value,
|
|
6152
|
+
onInput: setValue,
|
|
5977
6153
|
onFocus: onFocus,
|
|
5978
6154
|
onBlur: onBlur,
|
|
5979
|
-
|
|
6155
|
+
switcherLabel: switcherLabel,
|
|
6156
|
+
inline: inline,
|
|
5980
6157
|
tooltip: tooltip,
|
|
5981
6158
|
element: element
|
|
5982
|
-
}, element), error && jsxRuntime.jsx("div", {
|
|
5983
|
-
class: "bio-properties-panel-error",
|
|
5984
|
-
children: error
|
|
5985
6159
|
}), jsxRuntime.jsx(Description$1, {
|
|
5986
6160
|
forId: id,
|
|
5987
6161
|
element: element,
|
|
@@ -5998,254 +6172,38 @@ function isEdited$8(node) {
|
|
|
5998
6172
|
function prefixId$7(id) {
|
|
5999
6173
|
return `bio-properties-panel-${id}`;
|
|
6000
6174
|
}
|
|
6001
|
-
|
|
6002
|
-
const [buffer, setBuffer] = hooks.useState(undefined);
|
|
6003
|
-
ref.current = hooks.useMemo(() => ({
|
|
6004
|
-
focus: offset => {
|
|
6005
|
-
if (editor) {
|
|
6006
|
-
editor.focus(offset);
|
|
6007
|
-
} else {
|
|
6008
|
-
if (typeof offset === 'undefined') {
|
|
6009
|
-
offset = Infinity;
|
|
6010
|
-
}
|
|
6011
|
-
setBuffer(offset);
|
|
6012
|
-
}
|
|
6013
|
-
}
|
|
6014
|
-
}), [editor]);
|
|
6015
|
-
hooks.useEffect(() => {
|
|
6016
|
-
if (typeof buffer !== 'undefined' && editor) {
|
|
6017
|
-
editor.focus(buffer);
|
|
6018
|
-
setBuffer(false);
|
|
6019
|
-
}
|
|
6020
|
-
}, [editor, buffer]);
|
|
6021
|
-
};
|
|
6022
|
-
const CodeEditor$1 = React.forwardRef((props, ref) => {
|
|
6175
|
+
function NumberField(props) {
|
|
6023
6176
|
const {
|
|
6024
|
-
|
|
6177
|
+
debounce,
|
|
6025
6178
|
disabled,
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6179
|
+
displayLabel = true,
|
|
6180
|
+
id,
|
|
6181
|
+
inputRef,
|
|
6182
|
+
label,
|
|
6183
|
+
max,
|
|
6184
|
+
min,
|
|
6185
|
+
onInput,
|
|
6186
|
+
step,
|
|
6187
|
+
value = '',
|
|
6188
|
+
onFocus,
|
|
6189
|
+
onBlur
|
|
6033
6190
|
} = props;
|
|
6034
|
-
const
|
|
6035
|
-
const
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
editor = new feelers.FeelersEditor({
|
|
6045
|
-
container: inputRef.current,
|
|
6046
|
-
onChange: handleInput,
|
|
6047
|
-
value: localValue,
|
|
6048
|
-
onLint,
|
|
6049
|
-
contentAttributes,
|
|
6050
|
-
tooltipContainer,
|
|
6051
|
-
enableGutters,
|
|
6052
|
-
hostLanguage,
|
|
6053
|
-
singleLine
|
|
6191
|
+
const [localValue, setLocalValue] = hooks.useState(value);
|
|
6192
|
+
const handleInputCallback = hooks.useMemo(() => {
|
|
6193
|
+
return debounce(event => {
|
|
6194
|
+
const {
|
|
6195
|
+
validity,
|
|
6196
|
+
value
|
|
6197
|
+
} = event.target;
|
|
6198
|
+
if (validity.valid) {
|
|
6199
|
+
onInput(value ? parseFloat(value) : undefined);
|
|
6200
|
+
}
|
|
6054
6201
|
});
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
};
|
|
6061
|
-
}, []);
|
|
6062
|
-
hooks.useEffect(() => {
|
|
6063
|
-
if (!editor) {
|
|
6064
|
-
return;
|
|
6065
|
-
}
|
|
6066
|
-
if (value === localValue) {
|
|
6067
|
-
return;
|
|
6068
|
-
}
|
|
6069
|
-
editor.setValue(value);
|
|
6070
|
-
setLocalValue(value);
|
|
6071
|
-
}, [value]);
|
|
6072
|
-
const handleClick = () => {
|
|
6073
|
-
ref.current.focus();
|
|
6074
|
-
};
|
|
6075
|
-
return jsxRuntime.jsx("div", {
|
|
6076
|
-
name: props.name,
|
|
6077
|
-
class: classnames('bio-properties-panel-feelers-editor bio-properties-panel-input', localValue ? 'edited' : null, disabled ? 'disabled' : null),
|
|
6078
|
-
ref: inputRef,
|
|
6079
|
-
onClick: handleClick
|
|
6080
|
-
});
|
|
6081
|
-
});
|
|
6082
|
-
const useBufferedFocus = function (editor, ref) {
|
|
6083
|
-
const [buffer, setBuffer] = hooks.useState(undefined);
|
|
6084
|
-
ref.current = hooks.useMemo(() => ({
|
|
6085
|
-
focus: offset => {
|
|
6086
|
-
if (editor) {
|
|
6087
|
-
editor.focus(offset);
|
|
6088
|
-
} else {
|
|
6089
|
-
if (typeof offset === 'undefined') {
|
|
6090
|
-
offset = Infinity;
|
|
6091
|
-
}
|
|
6092
|
-
setBuffer(offset);
|
|
6093
|
-
}
|
|
6094
|
-
}
|
|
6095
|
-
}), [editor]);
|
|
6096
|
-
hooks.useEffect(() => {
|
|
6097
|
-
if (typeof buffer !== 'undefined' && editor) {
|
|
6098
|
-
editor.focus(buffer);
|
|
6099
|
-
setBuffer(false);
|
|
6100
|
-
}
|
|
6101
|
-
}, [editor, buffer]);
|
|
6102
|
-
};
|
|
6103
|
-
const CodeEditor = React.forwardRef((props, ref) => {
|
|
6104
|
-
const {
|
|
6105
|
-
value,
|
|
6106
|
-
onInput,
|
|
6107
|
-
onFeelToggle,
|
|
6108
|
-
onLint = () => {},
|
|
6109
|
-
disabled,
|
|
6110
|
-
tooltipContainer,
|
|
6111
|
-
variables
|
|
6112
|
-
} = props;
|
|
6113
|
-
const inputRef = hooks.useRef();
|
|
6114
|
-
const [editor, setEditor] = hooks.useState();
|
|
6115
|
-
const [localValue, setLocalValue] = hooks.useState(value || '');
|
|
6116
|
-
useBufferedFocus(editor, ref);
|
|
6117
|
-
const handleInput = useStaticCallback(newValue => {
|
|
6118
|
-
onInput(newValue);
|
|
6119
|
-
setLocalValue(newValue);
|
|
6120
|
-
});
|
|
6121
|
-
hooks.useEffect(() => {
|
|
6122
|
-
let editor;
|
|
6123
|
-
|
|
6124
|
-
/* Trigger FEEL toggle when
|
|
6125
|
-
*
|
|
6126
|
-
* - `backspace` is pressed
|
|
6127
|
-
* - AND the cursor is at the beginning of the input
|
|
6128
|
-
*/
|
|
6129
|
-
const onKeyDown = e => {
|
|
6130
|
-
if (e.key !== 'Backspace' || !editor) {
|
|
6131
|
-
return;
|
|
6132
|
-
}
|
|
6133
|
-
const selection = editor.getSelection();
|
|
6134
|
-
const range = selection.ranges[selection.mainIndex];
|
|
6135
|
-
if (range.from === 0 && range.to === 0) {
|
|
6136
|
-
onFeelToggle();
|
|
6137
|
-
}
|
|
6138
|
-
};
|
|
6139
|
-
editor = new FeelEditor({
|
|
6140
|
-
container: inputRef.current,
|
|
6141
|
-
onChange: handleInput,
|
|
6142
|
-
onKeyDown: onKeyDown,
|
|
6143
|
-
onLint: onLint,
|
|
6144
|
-
tooltipContainer: tooltipContainer,
|
|
6145
|
-
value: localValue,
|
|
6146
|
-
variables: variables
|
|
6147
|
-
});
|
|
6148
|
-
setEditor(editor);
|
|
6149
|
-
return () => {
|
|
6150
|
-
onLint([]);
|
|
6151
|
-
inputRef.current.innerHTML = '';
|
|
6152
|
-
setEditor(null);
|
|
6153
|
-
};
|
|
6154
|
-
}, []);
|
|
6155
|
-
hooks.useEffect(() => {
|
|
6156
|
-
if (!editor) {
|
|
6157
|
-
return;
|
|
6158
|
-
}
|
|
6159
|
-
if (value === localValue) {
|
|
6160
|
-
return;
|
|
6161
|
-
}
|
|
6162
|
-
editor.setValue(value);
|
|
6163
|
-
setLocalValue(value);
|
|
6164
|
-
}, [value]);
|
|
6165
|
-
hooks.useEffect(() => {
|
|
6166
|
-
if (!editor) {
|
|
6167
|
-
return;
|
|
6168
|
-
}
|
|
6169
|
-
editor.setVariables(variables);
|
|
6170
|
-
}, [variables]);
|
|
6171
|
-
const handleClick = () => {
|
|
6172
|
-
ref.current.focus();
|
|
6173
|
-
};
|
|
6174
|
-
return jsxRuntime.jsx("div", {
|
|
6175
|
-
class: classnames('bio-properties-panel-feel-editor-container', disabled ? 'disabled' : null),
|
|
6176
|
-
children: jsxRuntime.jsx("div", {
|
|
6177
|
-
name: props.name,
|
|
6178
|
-
class: classnames('bio-properties-panel-input', localValue ? 'edited' : null),
|
|
6179
|
-
ref: inputRef,
|
|
6180
|
-
onClick: handleClick
|
|
6181
|
-
})
|
|
6182
|
-
});
|
|
6183
|
-
});
|
|
6184
|
-
function FeelIndicator(props) {
|
|
6185
|
-
const {
|
|
6186
|
-
active
|
|
6187
|
-
} = props;
|
|
6188
|
-
if (!active) {
|
|
6189
|
-
return null;
|
|
6190
|
-
}
|
|
6191
|
-
return jsxRuntime.jsx("span", {
|
|
6192
|
-
class: "bio-properties-panel-feel-indicator",
|
|
6193
|
-
children: "="
|
|
6194
|
-
});
|
|
6195
|
-
}
|
|
6196
|
-
const noop$2 = () => {};
|
|
6197
|
-
|
|
6198
|
-
/**
|
|
6199
|
-
* @param {Object} props
|
|
6200
|
-
* @param {Object} props.label
|
|
6201
|
-
* @param {String} props.feel
|
|
6202
|
-
*/
|
|
6203
|
-
function FeelIcon(props) {
|
|
6204
|
-
const {
|
|
6205
|
-
feel = false,
|
|
6206
|
-
active,
|
|
6207
|
-
disabled = false,
|
|
6208
|
-
onClick = noop$2
|
|
6209
|
-
} = props;
|
|
6210
|
-
const feelRequiredLabel = 'FEEL expression is mandatory';
|
|
6211
|
-
const feelOptionalLabel = `Click to ${active ? 'remove' : 'set a'} dynamic value with FEEL expression`;
|
|
6212
|
-
const handleClick = e => {
|
|
6213
|
-
onClick(e);
|
|
6214
|
-
|
|
6215
|
-
// when pointer event was created from keyboard, keep focus on button
|
|
6216
|
-
if (!e.pointerType) {
|
|
6217
|
-
e.stopPropagation();
|
|
6218
|
-
}
|
|
6219
|
-
};
|
|
6220
|
-
return jsxRuntime.jsx("button", {
|
|
6221
|
-
class: classnames('bio-properties-panel-feel-icon', active ? 'active' : null, feel === 'required' ? 'required' : 'optional'),
|
|
6222
|
-
onClick: handleClick,
|
|
6223
|
-
disabled: feel === 'required' || disabled,
|
|
6224
|
-
title: feel === 'required' ? feelRequiredLabel : feelOptionalLabel,
|
|
6225
|
-
children: jsxRuntime.jsx(FeelIcon$1, {})
|
|
6226
|
-
});
|
|
6227
|
-
}
|
|
6228
|
-
function ToggleSwitch(props) {
|
|
6229
|
-
const {
|
|
6230
|
-
id,
|
|
6231
|
-
label,
|
|
6232
|
-
onInput,
|
|
6233
|
-
value,
|
|
6234
|
-
switcherLabel,
|
|
6235
|
-
inline,
|
|
6236
|
-
onFocus,
|
|
6237
|
-
onBlur,
|
|
6238
|
-
inputRef,
|
|
6239
|
-
tooltip
|
|
6240
|
-
} = props;
|
|
6241
|
-
const [localValue, setLocalValue] = hooks.useState(value);
|
|
6242
|
-
const handleInputCallback = async () => {
|
|
6243
|
-
onInput(!value);
|
|
6244
|
-
};
|
|
6245
|
-
const handleInput = e => {
|
|
6246
|
-
handleInputCallback();
|
|
6247
|
-
setLocalValue(e.target.value);
|
|
6248
|
-
};
|
|
6202
|
+
}, [onInput, debounce]);
|
|
6203
|
+
const handleInput = e => {
|
|
6204
|
+
handleInputCallback(e);
|
|
6205
|
+
setLocalValue(e.target.value);
|
|
6206
|
+
};
|
|
6249
6207
|
hooks.useEffect(() => {
|
|
6250
6208
|
if (value === localValue) {
|
|
6251
6209
|
return;
|
|
@@ -6253,199 +6211,64 @@ function ToggleSwitch(props) {
|
|
|
6253
6211
|
setLocalValue(value);
|
|
6254
6212
|
}, [value]);
|
|
6255
6213
|
return jsxRuntime.jsxs("div", {
|
|
6256
|
-
class:
|
|
6257
|
-
|
|
6258
|
-
}),
|
|
6259
|
-
children: [jsxRuntime.jsx("label", {
|
|
6260
|
-
class: "bio-properties-panel-label",
|
|
6214
|
+
class: "bio-properties-panel-numberfield",
|
|
6215
|
+
children: [displayLabel && jsxRuntime.jsx("label", {
|
|
6261
6216
|
for: prefixId$6(id),
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
onInput: handleInput,
|
|
6281
|
-
checked: !!localValue
|
|
6282
|
-
}), jsxRuntime.jsx("span", {
|
|
6283
|
-
class: "bio-properties-panel-toggle-switch__slider"
|
|
6284
|
-
})]
|
|
6285
|
-
}), switcherLabel && jsxRuntime.jsx("p", {
|
|
6286
|
-
class: "bio-properties-panel-toggle-switch__label",
|
|
6287
|
-
children: switcherLabel
|
|
6288
|
-
})]
|
|
6217
|
+
class: "bio-properties-panel-label",
|
|
6218
|
+
children: label
|
|
6219
|
+
}), jsxRuntime.jsx("input", {
|
|
6220
|
+
id: prefixId$6(id),
|
|
6221
|
+
ref: inputRef,
|
|
6222
|
+
type: "number",
|
|
6223
|
+
name: id,
|
|
6224
|
+
spellCheck: "false",
|
|
6225
|
+
autoComplete: "off",
|
|
6226
|
+
disabled: disabled,
|
|
6227
|
+
class: "bio-properties-panel-input",
|
|
6228
|
+
max: max,
|
|
6229
|
+
min: min,
|
|
6230
|
+
onInput: handleInput,
|
|
6231
|
+
onFocus: onFocus,
|
|
6232
|
+
onBlur: onBlur,
|
|
6233
|
+
step: step,
|
|
6234
|
+
value: localValue
|
|
6289
6235
|
})]
|
|
6290
6236
|
});
|
|
6291
6237
|
}
|
|
6292
6238
|
|
|
6293
6239
|
/**
|
|
6294
6240
|
* @param {Object} props
|
|
6241
|
+
* @param {Boolean} props.debounce
|
|
6242
|
+
* @param {String} props.description
|
|
6243
|
+
* @param {Boolean} props.disabled
|
|
6295
6244
|
* @param {Object} props.element
|
|
6245
|
+
* @param {Function} props.getValue
|
|
6296
6246
|
* @param {String} props.id
|
|
6297
|
-
* @param {String} props.description
|
|
6298
6247
|
* @param {String} props.label
|
|
6299
|
-
* @param {String} props.
|
|
6300
|
-
* @param {
|
|
6301
|
-
* @param {Function} props.getValue
|
|
6248
|
+
* @param {String} props.max
|
|
6249
|
+
* @param {String} props.min
|
|
6302
6250
|
* @param {Function} props.setValue
|
|
6303
6251
|
* @param {Function} props.onFocus
|
|
6304
6252
|
* @param {Function} props.onBlur
|
|
6305
|
-
* @param {
|
|
6253
|
+
* @param {String} props.step
|
|
6254
|
+
* @param {Function} props.validate
|
|
6306
6255
|
*/
|
|
6307
|
-
function
|
|
6256
|
+
function NumberFieldEntry(props) {
|
|
6308
6257
|
const {
|
|
6258
|
+
debounce,
|
|
6259
|
+
description,
|
|
6260
|
+
disabled,
|
|
6309
6261
|
element,
|
|
6262
|
+
getValue,
|
|
6310
6263
|
id,
|
|
6311
|
-
description,
|
|
6312
6264
|
label,
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
getValue,
|
|
6265
|
+
max,
|
|
6266
|
+
min,
|
|
6316
6267
|
setValue,
|
|
6268
|
+
step,
|
|
6317
6269
|
onFocus,
|
|
6318
6270
|
onBlur,
|
|
6319
|
-
|
|
6320
|
-
} = props;
|
|
6321
|
-
const value = getValue(element);
|
|
6322
|
-
return jsxRuntime.jsxs("div", {
|
|
6323
|
-
class: "bio-properties-panel-entry bio-properties-panel-toggle-switch-entry",
|
|
6324
|
-
"data-entry-id": id,
|
|
6325
|
-
children: [jsxRuntime.jsx(ToggleSwitch, {
|
|
6326
|
-
id: id,
|
|
6327
|
-
label: label,
|
|
6328
|
-
value: value,
|
|
6329
|
-
onInput: setValue,
|
|
6330
|
-
onFocus: onFocus,
|
|
6331
|
-
onBlur: onBlur,
|
|
6332
|
-
switcherLabel: switcherLabel,
|
|
6333
|
-
inline: inline,
|
|
6334
|
-
tooltip: tooltip,
|
|
6335
|
-
element: element
|
|
6336
|
-
}), jsxRuntime.jsx(Description$1, {
|
|
6337
|
-
forId: id,
|
|
6338
|
-
element: element,
|
|
6339
|
-
value: description
|
|
6340
|
-
})]
|
|
6341
|
-
});
|
|
6342
|
-
}
|
|
6343
|
-
function isEdited$7(node) {
|
|
6344
|
-
return node && !!node.checked;
|
|
6345
|
-
}
|
|
6346
|
-
|
|
6347
|
-
// helpers /////////////////
|
|
6348
|
-
|
|
6349
|
-
function prefixId$6(id) {
|
|
6350
|
-
return `bio-properties-panel-${id}`;
|
|
6351
|
-
}
|
|
6352
|
-
function NumberField(props) {
|
|
6353
|
-
const {
|
|
6354
|
-
debounce,
|
|
6355
|
-
disabled,
|
|
6356
|
-
displayLabel = true,
|
|
6357
|
-
id,
|
|
6358
|
-
inputRef,
|
|
6359
|
-
label,
|
|
6360
|
-
max,
|
|
6361
|
-
min,
|
|
6362
|
-
onInput,
|
|
6363
|
-
step,
|
|
6364
|
-
value = '',
|
|
6365
|
-
onFocus,
|
|
6366
|
-
onBlur
|
|
6367
|
-
} = props;
|
|
6368
|
-
const [localValue, setLocalValue] = hooks.useState(value);
|
|
6369
|
-
const handleInputCallback = hooks.useMemo(() => {
|
|
6370
|
-
return debounce(event => {
|
|
6371
|
-
const {
|
|
6372
|
-
validity,
|
|
6373
|
-
value
|
|
6374
|
-
} = event.target;
|
|
6375
|
-
if (validity.valid) {
|
|
6376
|
-
onInput(value ? parseFloat(value) : undefined);
|
|
6377
|
-
}
|
|
6378
|
-
});
|
|
6379
|
-
}, [onInput, debounce]);
|
|
6380
|
-
const handleInput = e => {
|
|
6381
|
-
handleInputCallback(e);
|
|
6382
|
-
setLocalValue(e.target.value);
|
|
6383
|
-
};
|
|
6384
|
-
hooks.useEffect(() => {
|
|
6385
|
-
if (value === localValue) {
|
|
6386
|
-
return;
|
|
6387
|
-
}
|
|
6388
|
-
setLocalValue(value);
|
|
6389
|
-
}, [value]);
|
|
6390
|
-
return jsxRuntime.jsxs("div", {
|
|
6391
|
-
class: "bio-properties-panel-numberfield",
|
|
6392
|
-
children: [displayLabel && jsxRuntime.jsx("label", {
|
|
6393
|
-
for: prefixId$5(id),
|
|
6394
|
-
class: "bio-properties-panel-label",
|
|
6395
|
-
children: label
|
|
6396
|
-
}), jsxRuntime.jsx("input", {
|
|
6397
|
-
id: prefixId$5(id),
|
|
6398
|
-
ref: inputRef,
|
|
6399
|
-
type: "number",
|
|
6400
|
-
name: id,
|
|
6401
|
-
spellCheck: "false",
|
|
6402
|
-
autoComplete: "off",
|
|
6403
|
-
disabled: disabled,
|
|
6404
|
-
class: "bio-properties-panel-input",
|
|
6405
|
-
max: max,
|
|
6406
|
-
min: min,
|
|
6407
|
-
onInput: handleInput,
|
|
6408
|
-
onFocus: onFocus,
|
|
6409
|
-
onBlur: onBlur,
|
|
6410
|
-
step: step,
|
|
6411
|
-
value: localValue
|
|
6412
|
-
})]
|
|
6413
|
-
});
|
|
6414
|
-
}
|
|
6415
|
-
|
|
6416
|
-
/**
|
|
6417
|
-
* @param {Object} props
|
|
6418
|
-
* @param {Boolean} props.debounce
|
|
6419
|
-
* @param {String} props.description
|
|
6420
|
-
* @param {Boolean} props.disabled
|
|
6421
|
-
* @param {Object} props.element
|
|
6422
|
-
* @param {Function} props.getValue
|
|
6423
|
-
* @param {String} props.id
|
|
6424
|
-
* @param {String} props.label
|
|
6425
|
-
* @param {String} props.max
|
|
6426
|
-
* @param {String} props.min
|
|
6427
|
-
* @param {Function} props.setValue
|
|
6428
|
-
* @param {Function} props.onFocus
|
|
6429
|
-
* @param {Function} props.onBlur
|
|
6430
|
-
* @param {String} props.step
|
|
6431
|
-
* @param {Function} props.validate
|
|
6432
|
-
*/
|
|
6433
|
-
function NumberFieldEntry(props) {
|
|
6434
|
-
const {
|
|
6435
|
-
debounce,
|
|
6436
|
-
description,
|
|
6437
|
-
disabled,
|
|
6438
|
-
element,
|
|
6439
|
-
getValue,
|
|
6440
|
-
id,
|
|
6441
|
-
label,
|
|
6442
|
-
max,
|
|
6443
|
-
min,
|
|
6444
|
-
setValue,
|
|
6445
|
-
step,
|
|
6446
|
-
onFocus,
|
|
6447
|
-
onBlur,
|
|
6448
|
-
validate
|
|
6271
|
+
validate
|
|
6449
6272
|
} = props;
|
|
6450
6273
|
const globalError = useError(id);
|
|
6451
6274
|
const [localError, setLocalError] = hooks.useState(null);
|
|
@@ -6490,27 +6313,30 @@ function NumberFieldEntry(props) {
|
|
|
6490
6313
|
})]
|
|
6491
6314
|
});
|
|
6492
6315
|
}
|
|
6493
|
-
function isEdited$
|
|
6316
|
+
function isEdited$7(node) {
|
|
6494
6317
|
return node && !!node.value;
|
|
6495
6318
|
}
|
|
6496
6319
|
|
|
6497
6320
|
// helpers /////////////////
|
|
6498
6321
|
|
|
6499
|
-
function prefixId$
|
|
6322
|
+
function prefixId$6(id) {
|
|
6500
6323
|
return `bio-properties-panel-${id}`;
|
|
6501
6324
|
}
|
|
6502
|
-
const noop$
|
|
6325
|
+
const noop$2 = () => {};
|
|
6503
6326
|
function FeelTextfield(props) {
|
|
6504
6327
|
const {
|
|
6505
6328
|
debounce,
|
|
6506
6329
|
id,
|
|
6330
|
+
element,
|
|
6507
6331
|
label,
|
|
6332
|
+
hostLanguage,
|
|
6508
6333
|
onInput,
|
|
6509
6334
|
onError,
|
|
6510
6335
|
feel,
|
|
6511
6336
|
value = '',
|
|
6512
6337
|
disabled = false,
|
|
6513
6338
|
variables,
|
|
6339
|
+
singleLine,
|
|
6514
6340
|
tooltipContainer,
|
|
6515
6341
|
OptionalComponent = OptionalFeelInput,
|
|
6516
6342
|
tooltip
|
|
@@ -6521,6 +6347,11 @@ function FeelTextfield(props) {
|
|
|
6521
6347
|
const feelActive = minDash.isString(localValue) && localValue.startsWith('=') || feel === 'required';
|
|
6522
6348
|
const feelOnlyValue = minDash.isString(localValue) && localValue.startsWith('=') ? localValue.substring(1) : localValue;
|
|
6523
6349
|
const [focus, _setFocus] = hooks.useState(undefined);
|
|
6350
|
+
const {
|
|
6351
|
+
open: openPopup,
|
|
6352
|
+
source: popupSource
|
|
6353
|
+
} = hooks.useContext(FeelPopupContext);
|
|
6354
|
+
const popuOpen = popupSource === id;
|
|
6524
6355
|
const setFocus = (offset = 0) => {
|
|
6525
6356
|
const hasFocus = containerRef.current.contains(document.activeElement);
|
|
6526
6357
|
|
|
@@ -6573,6 +6404,21 @@ function FeelTextfield(props) {
|
|
|
6573
6404
|
const message = `${error.source}: ${error.message}`;
|
|
6574
6405
|
onError(message);
|
|
6575
6406
|
});
|
|
6407
|
+
const handlePopupOpen = (type = 'feel') => {
|
|
6408
|
+
const popupOptions = {
|
|
6409
|
+
id,
|
|
6410
|
+
hostLanguage,
|
|
6411
|
+
onInput: handleLocalInput,
|
|
6412
|
+
position: calculatePopupPosition(containerRef.current),
|
|
6413
|
+
singleLine,
|
|
6414
|
+
title: getPopupTitle(element, label),
|
|
6415
|
+
tooltipContainer,
|
|
6416
|
+
type,
|
|
6417
|
+
value: feelOnlyValue,
|
|
6418
|
+
variables
|
|
6419
|
+
};
|
|
6420
|
+
openPopup(id, popupOptions, editorRef.current);
|
|
6421
|
+
};
|
|
6576
6422
|
hooks.useEffect(() => {
|
|
6577
6423
|
if (typeof focus !== 'undefined') {
|
|
6578
6424
|
editorRef.current.focus(focus);
|
|
@@ -6601,7 +6447,7 @@ function FeelTextfield(props) {
|
|
|
6601
6447
|
event.clipboardData.setData('application/FEEL', event.clipboardData.getData('text'));
|
|
6602
6448
|
};
|
|
6603
6449
|
const pasteHandler = event => {
|
|
6604
|
-
if (feelActive) {
|
|
6450
|
+
if (feelActive || popuOpen) {
|
|
6605
6451
|
return;
|
|
6606
6452
|
}
|
|
6607
6453
|
const data = event.clipboardData.getData('application/FEEL');
|
|
@@ -6626,7 +6472,7 @@ function FeelTextfield(props) {
|
|
|
6626
6472
|
'feel-active': feelActive
|
|
6627
6473
|
}),
|
|
6628
6474
|
children: [jsxRuntime.jsxs("label", {
|
|
6629
|
-
for: prefixId$
|
|
6475
|
+
for: prefixId$5(id),
|
|
6630
6476
|
class: "bio-properties-panel-label",
|
|
6631
6477
|
onClick: () => setFocus(),
|
|
6632
6478
|
children: [jsxRuntime.jsx(TooltipWrapper, {
|
|
@@ -6648,28 +6494,33 @@ function FeelTextfield(props) {
|
|
|
6648
6494
|
disabled: feel !== 'optional' || disabled,
|
|
6649
6495
|
onClick: handleFeelToggle
|
|
6650
6496
|
}), feelActive ? jsxRuntime.jsx(CodeEditor, {
|
|
6651
|
-
id: prefixId$
|
|
6497
|
+
id: prefixId$5(id),
|
|
6652
6498
|
name: id,
|
|
6653
6499
|
onInput: handleLocalInput,
|
|
6654
6500
|
disabled: disabled,
|
|
6501
|
+
popupOpen: popuOpen,
|
|
6655
6502
|
onFeelToggle: () => {
|
|
6656
6503
|
handleFeelToggle();
|
|
6657
6504
|
setFocus(true);
|
|
6658
6505
|
},
|
|
6659
6506
|
onLint: handleLint,
|
|
6507
|
+
onPopupOpen: handlePopupOpen,
|
|
6660
6508
|
value: feelOnlyValue,
|
|
6661
6509
|
variables: variables,
|
|
6662
6510
|
ref: editorRef,
|
|
6663
6511
|
tooltipContainer: tooltipContainer
|
|
6664
6512
|
}) : jsxRuntime.jsx(OptionalComponent, {
|
|
6665
6513
|
...props,
|
|
6514
|
+
popupOpen: popuOpen,
|
|
6666
6515
|
onInput: handleLocalInput,
|
|
6667
6516
|
contentAttributes: {
|
|
6668
|
-
'id': prefixId$
|
|
6517
|
+
'id': prefixId$5(id),
|
|
6669
6518
|
'aria-label': label
|
|
6670
6519
|
},
|
|
6671
6520
|
value: localValue,
|
|
6672
|
-
ref: editorRef
|
|
6521
|
+
ref: editorRef,
|
|
6522
|
+
onPopupOpen: handlePopupOpen,
|
|
6523
|
+
containerRef: containerRef
|
|
6673
6524
|
})]
|
|
6674
6525
|
})]
|
|
6675
6526
|
});
|
|
@@ -6703,7 +6554,7 @@ const OptionalFeelInput = React.forwardRef((props, ref) => {
|
|
|
6703
6554
|
}
|
|
6704
6555
|
};
|
|
6705
6556
|
return jsxRuntime.jsx("input", {
|
|
6706
|
-
id: prefixId$
|
|
6557
|
+
id: prefixId$5(id),
|
|
6707
6558
|
type: "text",
|
|
6708
6559
|
ref: inputRef,
|
|
6709
6560
|
name: id,
|
|
@@ -6730,309 +6581,995 @@ const OptionalFeelNumberField = React.forwardRef((props, ref) => {
|
|
|
6730
6581
|
onFocus,
|
|
6731
6582
|
onBlur
|
|
6732
6583
|
} = props;
|
|
6733
|
-
const inputRef = hooks.useRef();
|
|
6584
|
+
const inputRef = hooks.useRef();
|
|
6585
|
+
|
|
6586
|
+
// To be consistent with the FEEL editor, set focus at start of input
|
|
6587
|
+
// this ensures clean editing experience when switching with the keyboard
|
|
6588
|
+
ref.current = {
|
|
6589
|
+
focus: position => {
|
|
6590
|
+
const input = inputRef.current;
|
|
6591
|
+
if (!input) {
|
|
6592
|
+
return;
|
|
6593
|
+
}
|
|
6594
|
+
input.focus();
|
|
6595
|
+
if (typeof position === 'number' && position !== Infinity) {
|
|
6596
|
+
if (position > value.length) {
|
|
6597
|
+
position = value.length;
|
|
6598
|
+
}
|
|
6599
|
+
input.setSelectionRange(position, position);
|
|
6600
|
+
}
|
|
6601
|
+
}
|
|
6602
|
+
};
|
|
6603
|
+
return jsxRuntime.jsx(NumberField, {
|
|
6604
|
+
id: id,
|
|
6605
|
+
debounce: debounce,
|
|
6606
|
+
disabled: disabled,
|
|
6607
|
+
displayLabel: false,
|
|
6608
|
+
inputRef: inputRef,
|
|
6609
|
+
max: max,
|
|
6610
|
+
min: min,
|
|
6611
|
+
onInput: onInput,
|
|
6612
|
+
step: step,
|
|
6613
|
+
value: value,
|
|
6614
|
+
onFocus: onFocus,
|
|
6615
|
+
onBlur: onBlur
|
|
6616
|
+
});
|
|
6617
|
+
});
|
|
6618
|
+
React.forwardRef((props, ref) => {
|
|
6619
|
+
const {
|
|
6620
|
+
id,
|
|
6621
|
+
disabled,
|
|
6622
|
+
onInput,
|
|
6623
|
+
value,
|
|
6624
|
+
onFocus,
|
|
6625
|
+
onBlur
|
|
6626
|
+
} = props;
|
|
6627
|
+
const inputRef = hooks.useRef();
|
|
6628
|
+
|
|
6629
|
+
// To be consistent with the FEEL editor, set focus at start of input
|
|
6630
|
+
// this ensures clean editing experience when switching with the keyboard
|
|
6631
|
+
ref.current = {
|
|
6632
|
+
focus: () => {
|
|
6633
|
+
const input = inputRef.current;
|
|
6634
|
+
if (!input) {
|
|
6635
|
+
return;
|
|
6636
|
+
}
|
|
6637
|
+
input.focus();
|
|
6638
|
+
input.setSelectionRange(0, 0);
|
|
6639
|
+
}
|
|
6640
|
+
};
|
|
6641
|
+
return jsxRuntime.jsx("textarea", {
|
|
6642
|
+
id: prefixId$5(id),
|
|
6643
|
+
type: "text",
|
|
6644
|
+
ref: inputRef,
|
|
6645
|
+
name: id,
|
|
6646
|
+
spellCheck: "false",
|
|
6647
|
+
autoComplete: "off",
|
|
6648
|
+
disabled: disabled,
|
|
6649
|
+
class: "bio-properties-panel-input",
|
|
6650
|
+
onInput: e => onInput(e.target.value),
|
|
6651
|
+
onFocus: onFocus,
|
|
6652
|
+
onBlur: onBlur,
|
|
6653
|
+
value: value || '',
|
|
6654
|
+
"data-gramm": "false"
|
|
6655
|
+
});
|
|
6656
|
+
});
|
|
6657
|
+
const OptionalFeelToggleSwitch = React.forwardRef((props, ref) => {
|
|
6658
|
+
const {
|
|
6659
|
+
id,
|
|
6660
|
+
onInput,
|
|
6661
|
+
value,
|
|
6662
|
+
onFocus,
|
|
6663
|
+
onBlur,
|
|
6664
|
+
switcherLabel
|
|
6665
|
+
} = props;
|
|
6666
|
+
const inputRef = hooks.useRef();
|
|
6667
|
+
|
|
6668
|
+
// To be consistent with the FEEL editor, set focus at start of input
|
|
6669
|
+
// this ensures clean editing experience when switching with the keyboard
|
|
6670
|
+
ref.current = {
|
|
6671
|
+
focus: () => {
|
|
6672
|
+
const input = inputRef.current;
|
|
6673
|
+
if (!input) {
|
|
6674
|
+
return;
|
|
6675
|
+
}
|
|
6676
|
+
input.focus();
|
|
6677
|
+
}
|
|
6678
|
+
};
|
|
6679
|
+
return jsxRuntime.jsx(ToggleSwitch, {
|
|
6680
|
+
id: id,
|
|
6681
|
+
value: value,
|
|
6682
|
+
inputRef: inputRef,
|
|
6683
|
+
onInput: onInput,
|
|
6684
|
+
onFocus: onFocus,
|
|
6685
|
+
onBlur: onBlur,
|
|
6686
|
+
switcherLabel: switcherLabel
|
|
6687
|
+
});
|
|
6688
|
+
});
|
|
6689
|
+
React.forwardRef((props, ref) => {
|
|
6690
|
+
const {
|
|
6691
|
+
id,
|
|
6692
|
+
disabled,
|
|
6693
|
+
onInput,
|
|
6694
|
+
value,
|
|
6695
|
+
onFocus,
|
|
6696
|
+
onBlur
|
|
6697
|
+
} = props;
|
|
6698
|
+
const inputRef = hooks.useRef();
|
|
6699
|
+
const handleChange = ({
|
|
6700
|
+
target
|
|
6701
|
+
}) => {
|
|
6702
|
+
onInput(target.checked);
|
|
6703
|
+
};
|
|
6704
|
+
|
|
6705
|
+
// To be consistent with the FEEL editor, set focus at start of input
|
|
6706
|
+
// this ensures clean editing experience when switching with the keyboard
|
|
6707
|
+
ref.current = {
|
|
6708
|
+
focus: () => {
|
|
6709
|
+
const input = inputRef.current;
|
|
6710
|
+
if (!input) {
|
|
6711
|
+
return;
|
|
6712
|
+
}
|
|
6713
|
+
input.focus();
|
|
6714
|
+
}
|
|
6715
|
+
};
|
|
6716
|
+
return jsxRuntime.jsx("input", {
|
|
6717
|
+
ref: inputRef,
|
|
6718
|
+
id: prefixId$5(id),
|
|
6719
|
+
name: id,
|
|
6720
|
+
onFocus: onFocus,
|
|
6721
|
+
onBlur: onBlur,
|
|
6722
|
+
type: "checkbox",
|
|
6723
|
+
class: "bio-properties-panel-input",
|
|
6724
|
+
onChange: handleChange,
|
|
6725
|
+
checked: value,
|
|
6726
|
+
disabled: disabled
|
|
6727
|
+
});
|
|
6728
|
+
});
|
|
6729
|
+
|
|
6730
|
+
/**
|
|
6731
|
+
* @param {Object} props
|
|
6732
|
+
* @param {Object} props.element
|
|
6733
|
+
* @param {String} props.id
|
|
6734
|
+
* @param {String} props.description
|
|
6735
|
+
* @param {Boolean} props.debounce
|
|
6736
|
+
* @param {Boolean} props.disabled
|
|
6737
|
+
* @param {Boolean} props.feel
|
|
6738
|
+
* @param {String} props.label
|
|
6739
|
+
* @param {Function} props.getValue
|
|
6740
|
+
* @param {Function} props.setValue
|
|
6741
|
+
* @param {Function} props.tooltipContainer
|
|
6742
|
+
* @param {Function} props.validate
|
|
6743
|
+
* @param {Function} props.show
|
|
6744
|
+
* @param {Function} props.example
|
|
6745
|
+
* @param {Function} props.variables
|
|
6746
|
+
* @param {Function} props.onFocus
|
|
6747
|
+
* @param {Function} props.onBlur
|
|
6748
|
+
* @param {string|import('preact').Component} props.tooltip
|
|
6749
|
+
*/
|
|
6750
|
+
function FeelEntry(props) {
|
|
6751
|
+
const {
|
|
6752
|
+
element,
|
|
6753
|
+
id,
|
|
6754
|
+
description,
|
|
6755
|
+
debounce,
|
|
6756
|
+
disabled,
|
|
6757
|
+
feel,
|
|
6758
|
+
label,
|
|
6759
|
+
getValue,
|
|
6760
|
+
setValue,
|
|
6761
|
+
tooltipContainer,
|
|
6762
|
+
hostLanguage,
|
|
6763
|
+
singleLine,
|
|
6764
|
+
validate,
|
|
6765
|
+
show = noop$2,
|
|
6766
|
+
example,
|
|
6767
|
+
variables,
|
|
6768
|
+
onFocus,
|
|
6769
|
+
onBlur,
|
|
6770
|
+
tooltip
|
|
6771
|
+
} = props;
|
|
6772
|
+
const [validationError, setValidationError] = hooks.useState(null);
|
|
6773
|
+
const [localError, setLocalError] = hooks.useState(null);
|
|
6774
|
+
let value = getValue(element);
|
|
6775
|
+
hooks.useEffect(() => {
|
|
6776
|
+
if (minDash.isFunction(validate)) {
|
|
6777
|
+
const newValidationError = validate(value) || null;
|
|
6778
|
+
setValidationError(newValidationError);
|
|
6779
|
+
}
|
|
6780
|
+
}, [value]);
|
|
6781
|
+
const onInput = useStaticCallback(newValue => {
|
|
6782
|
+
let newValidationError = null;
|
|
6783
|
+
if (minDash.isFunction(validate)) {
|
|
6784
|
+
newValidationError = validate(newValue) || null;
|
|
6785
|
+
}
|
|
6786
|
+
|
|
6787
|
+
// don't create multiple commandStack entries for the same value
|
|
6788
|
+
if (newValue !== value) {
|
|
6789
|
+
setValue(newValue, newValidationError);
|
|
6790
|
+
}
|
|
6791
|
+
setValidationError(newValidationError);
|
|
6792
|
+
});
|
|
6793
|
+
const onError = hooks.useCallback(err => {
|
|
6794
|
+
setLocalError(err);
|
|
6795
|
+
}, []);
|
|
6796
|
+
const temporaryError = useError(id);
|
|
6797
|
+
const error = localError || temporaryError || validationError;
|
|
6798
|
+
return jsxRuntime.jsxs("div", {
|
|
6799
|
+
class: classnames(props.class, 'bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
6800
|
+
"data-entry-id": id,
|
|
6801
|
+
children: [preact.createElement(FeelTextfield, {
|
|
6802
|
+
...props,
|
|
6803
|
+
debounce: debounce,
|
|
6804
|
+
disabled: disabled,
|
|
6805
|
+
feel: feel,
|
|
6806
|
+
id: id,
|
|
6807
|
+
key: element,
|
|
6808
|
+
label: label,
|
|
6809
|
+
onInput: onInput,
|
|
6810
|
+
onError: onError,
|
|
6811
|
+
onFocus: onFocus,
|
|
6812
|
+
onBlur: onBlur,
|
|
6813
|
+
example: example,
|
|
6814
|
+
hostLanguage: hostLanguage,
|
|
6815
|
+
singleLine: singleLine,
|
|
6816
|
+
show: show,
|
|
6817
|
+
value: value,
|
|
6818
|
+
variables: variables,
|
|
6819
|
+
tooltipContainer: tooltipContainer,
|
|
6820
|
+
OptionalComponent: props.OptionalComponent,
|
|
6821
|
+
tooltip: tooltip
|
|
6822
|
+
}), error && jsxRuntime.jsx("div", {
|
|
6823
|
+
class: "bio-properties-panel-error",
|
|
6824
|
+
children: error
|
|
6825
|
+
}), jsxRuntime.jsx(Description$1, {
|
|
6826
|
+
forId: id,
|
|
6827
|
+
element: element,
|
|
6828
|
+
value: description
|
|
6829
|
+
})]
|
|
6830
|
+
});
|
|
6831
|
+
}
|
|
6832
|
+
|
|
6833
|
+
/**
|
|
6834
|
+
* @param {Object} props
|
|
6835
|
+
* @param {Object} props.element
|
|
6836
|
+
* @param {String} props.id
|
|
6837
|
+
* @param {String} props.description
|
|
6838
|
+
* @param {Boolean} props.debounce
|
|
6839
|
+
* @param {Boolean} props.disabled
|
|
6840
|
+
* @param {String} props.max
|
|
6841
|
+
* @param {String} props.min
|
|
6842
|
+
* @param {String} props.step
|
|
6843
|
+
* @param {Boolean} props.feel
|
|
6844
|
+
* @param {String} props.label
|
|
6845
|
+
* @param {Function} props.getValue
|
|
6846
|
+
* @param {Function} props.setValue
|
|
6847
|
+
* @param {Function} props.tooltipContainer
|
|
6848
|
+
* @param {Function} props.validate
|
|
6849
|
+
* @param {Function} props.show
|
|
6850
|
+
* @param {Function} props.example
|
|
6851
|
+
* @param {Function} props.variables
|
|
6852
|
+
* @param {Function} props.onFocus
|
|
6853
|
+
* @param {Function} props.onBlur
|
|
6854
|
+
*/
|
|
6855
|
+
function FeelNumberEntry(props) {
|
|
6856
|
+
return jsxRuntime.jsx(FeelEntry, {
|
|
6857
|
+
class: "bio-properties-panel-feel-number",
|
|
6858
|
+
OptionalComponent: OptionalFeelNumberField,
|
|
6859
|
+
...props
|
|
6860
|
+
});
|
|
6861
|
+
}
|
|
6862
|
+
|
|
6863
|
+
/**
|
|
6864
|
+
* @param {Object} props
|
|
6865
|
+
* @param {Object} props.element
|
|
6866
|
+
* @param {String} props.id
|
|
6867
|
+
* @param {String} props.description
|
|
6868
|
+
* @param {Boolean} props.debounce
|
|
6869
|
+
* @param {Boolean} props.disabled
|
|
6870
|
+
* @param {Boolean} props.feel
|
|
6871
|
+
* @param {String} props.label
|
|
6872
|
+
* @param {Function} props.getValue
|
|
6873
|
+
* @param {Function} props.setValue
|
|
6874
|
+
* @param {Function} props.tooltipContainer
|
|
6875
|
+
* @param {Function} props.validate
|
|
6876
|
+
* @param {Function} props.show
|
|
6877
|
+
* @param {Function} props.example
|
|
6878
|
+
* @param {Function} props.variables
|
|
6879
|
+
* @param {Function} props.onFocus
|
|
6880
|
+
* @param {Function} props.onBlur
|
|
6881
|
+
*/
|
|
6882
|
+
function FeelToggleSwitchEntry(props) {
|
|
6883
|
+
return jsxRuntime.jsx(FeelEntry, {
|
|
6884
|
+
class: "bio-properties-panel-feel-toggle-switch",
|
|
6885
|
+
OptionalComponent: OptionalFeelToggleSwitch,
|
|
6886
|
+
...props
|
|
6887
|
+
});
|
|
6888
|
+
}
|
|
6889
|
+
|
|
6890
|
+
/**
|
|
6891
|
+
* @param {Object} props
|
|
6892
|
+
* @param {Object} props.element
|
|
6893
|
+
* @param {String} props.id
|
|
6894
|
+
* @param {String} props.description
|
|
6895
|
+
* @param {String} props.hostLanguage
|
|
6896
|
+
* @param {Boolean} props.singleLine
|
|
6897
|
+
* @param {Boolean} props.debounce
|
|
6898
|
+
* @param {Boolean} props.disabled
|
|
6899
|
+
* @param {Boolean} props.feel
|
|
6900
|
+
* @param {String} props.label
|
|
6901
|
+
* @param {Function} props.getValue
|
|
6902
|
+
* @param {Function} props.setValue
|
|
6903
|
+
* @param {Function} props.tooltipContainer
|
|
6904
|
+
* @param {Function} props.validate
|
|
6905
|
+
* @param {Function} props.show
|
|
6906
|
+
* @param {Function} props.example
|
|
6907
|
+
* @param {Function} props.variables
|
|
6908
|
+
* @param {Function} props.onFocus
|
|
6909
|
+
* @param {Function} props.onBlur
|
|
6910
|
+
*/
|
|
6911
|
+
function FeelTemplatingEntry(props) {
|
|
6912
|
+
return jsxRuntime.jsx(FeelEntry, {
|
|
6913
|
+
class: "bio-properties-panel-feel-templating",
|
|
6914
|
+
OptionalComponent: CodeEditor$1,
|
|
6915
|
+
...props
|
|
6916
|
+
});
|
|
6917
|
+
}
|
|
6918
|
+
function isEdited$6(node) {
|
|
6919
|
+
if (!node) {
|
|
6920
|
+
return false;
|
|
6921
|
+
}
|
|
6922
|
+
if (node.type === 'checkbox') {
|
|
6923
|
+
return !!node.checked || node.classList.contains('edited');
|
|
6924
|
+
}
|
|
6925
|
+
return !!node.value || node.classList.contains('edited');
|
|
6926
|
+
}
|
|
6927
|
+
|
|
6928
|
+
// helpers /////////////////
|
|
6929
|
+
|
|
6930
|
+
function prefixId$5(id) {
|
|
6931
|
+
return `bio-properties-panel-${id}`;
|
|
6932
|
+
}
|
|
6933
|
+
function calculatePopupPosition(element) {
|
|
6934
|
+
const {
|
|
6935
|
+
top,
|
|
6936
|
+
left
|
|
6937
|
+
} = element.getBoundingClientRect();
|
|
6938
|
+
return {
|
|
6939
|
+
left: left - FEEL_POPUP_WIDTH - 20,
|
|
6940
|
+
top: top
|
|
6941
|
+
};
|
|
6942
|
+
}
|
|
6943
|
+
|
|
6944
|
+
// todo(pinussilvestrus): make this configurable in the future
|
|
6945
|
+
function getPopupTitle(element, label) {
|
|
6946
|
+
let popupTitle;
|
|
6947
|
+
if (element && element.type) {
|
|
6948
|
+
popupTitle = `${element.type} / `;
|
|
6949
|
+
}
|
|
6950
|
+
return `${popupTitle}${label}`;
|
|
6951
|
+
}
|
|
6952
|
+
const DEFAULT_LAYOUT = {};
|
|
6953
|
+
const DEFAULT_DESCRIPTION = {};
|
|
6954
|
+
const DEFAULT_TOOLTIP = {};
|
|
6955
|
+
|
|
6956
|
+
/**
|
|
6957
|
+
* @typedef { {
|
|
6958
|
+
* component: import('preact').Component,
|
|
6959
|
+
* id: String,
|
|
6960
|
+
* isEdited?: Function
|
|
6961
|
+
* } } EntryDefinition
|
|
6962
|
+
*
|
|
6963
|
+
* @typedef { {
|
|
6964
|
+
* autoFocusEntry: String,
|
|
6965
|
+
* autoOpen?: Boolean,
|
|
6966
|
+
* entries: Array<EntryDefinition>,
|
|
6967
|
+
* id: String,
|
|
6968
|
+
* label: String,
|
|
6969
|
+
* remove: (event: MouseEvent) => void
|
|
6970
|
+
* } } ListItemDefinition
|
|
6971
|
+
*
|
|
6972
|
+
* @typedef { {
|
|
6973
|
+
* add: (event: MouseEvent) => void,
|
|
6974
|
+
* component: import('preact').Component,
|
|
6975
|
+
* element: Object,
|
|
6976
|
+
* id: String,
|
|
6977
|
+
* items: Array<ListItemDefinition>,
|
|
6978
|
+
* label: String,
|
|
6979
|
+
* shouldSort?: Boolean,
|
|
6980
|
+
* shouldOpen?: Boolean
|
|
6981
|
+
* } } ListGroupDefinition
|
|
6982
|
+
*
|
|
6983
|
+
* @typedef { {
|
|
6984
|
+
* component?: import('preact').Component,
|
|
6985
|
+
* entries: Array<EntryDefinition>,
|
|
6986
|
+
* id: String,
|
|
6987
|
+
* label: String,
|
|
6988
|
+
* shouldOpen?: Boolean
|
|
6989
|
+
* } } GroupDefinition
|
|
6990
|
+
*
|
|
6991
|
+
* @typedef { {
|
|
6992
|
+
* [id: String]: GetDescriptionFunction
|
|
6993
|
+
* } } DescriptionConfig
|
|
6994
|
+
*
|
|
6995
|
+
* @typedef { {
|
|
6996
|
+
* [id: String]: GetTooltipFunction
|
|
6997
|
+
* } } TooltipConfig
|
|
6998
|
+
*
|
|
6999
|
+
* @callback { {
|
|
7000
|
+
* @param {string} id
|
|
7001
|
+
* @param {Object} element
|
|
7002
|
+
* @returns {string}
|
|
7003
|
+
* } } GetDescriptionFunction
|
|
7004
|
+
*
|
|
7005
|
+
* @callback { {
|
|
7006
|
+
* @param {string} id
|
|
7007
|
+
* @param {Object} element
|
|
7008
|
+
* @returns {string}
|
|
7009
|
+
* } } GetTooltipFunction
|
|
7010
|
+
*
|
|
7011
|
+
* @typedef { {
|
|
7012
|
+
* getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
|
|
7013
|
+
* getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
|
|
7014
|
+
* } } PlaceholderProvider
|
|
7015
|
+
*
|
|
7016
|
+
*/
|
|
7017
|
+
|
|
7018
|
+
/**
|
|
7019
|
+
* A basic properties panel component. Describes *how* content will be rendered, accepts
|
|
7020
|
+
* data from implementor to describe *what* will be rendered.
|
|
7021
|
+
*
|
|
7022
|
+
* @param {Object} props
|
|
7023
|
+
* @param {Object|Array} props.element
|
|
7024
|
+
* @param {import('./components/Header').HeaderProvider} props.headerProvider
|
|
7025
|
+
* @param {PlaceholderProvider} [props.placeholderProvider]
|
|
7026
|
+
* @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
|
|
7027
|
+
* @param {Object} [props.layoutConfig]
|
|
7028
|
+
* @param {Function} [props.layoutChanged]
|
|
7029
|
+
* @param {DescriptionConfig} [props.descriptionConfig]
|
|
7030
|
+
* @param {Function} [props.descriptionLoaded]
|
|
7031
|
+
* @param {TooltipConfig} [props.tooltipConfig]
|
|
7032
|
+
* @param {Function} [props.tooltipLoaded]
|
|
7033
|
+
* @param {Object} [props.eventBus]
|
|
7034
|
+
*/
|
|
7035
|
+
function PropertiesPanel(props) {
|
|
7036
|
+
const {
|
|
7037
|
+
element,
|
|
7038
|
+
headerProvider,
|
|
7039
|
+
placeholderProvider,
|
|
7040
|
+
groups,
|
|
7041
|
+
layoutConfig,
|
|
7042
|
+
layoutChanged,
|
|
7043
|
+
descriptionConfig,
|
|
7044
|
+
descriptionLoaded,
|
|
7045
|
+
tooltipConfig,
|
|
7046
|
+
tooltipLoaded,
|
|
7047
|
+
eventBus
|
|
7048
|
+
} = props;
|
|
7049
|
+
|
|
7050
|
+
// set-up layout context
|
|
7051
|
+
const [layout, setLayout] = hooks.useState(createLayout(layoutConfig));
|
|
7052
|
+
|
|
7053
|
+
// react to external changes in the layout config
|
|
7054
|
+
useUpdateLayoutEffect(() => {
|
|
7055
|
+
const newLayout = createLayout(layoutConfig);
|
|
7056
|
+
setLayout(newLayout);
|
|
7057
|
+
}, [layoutConfig]);
|
|
7058
|
+
hooks.useEffect(() => {
|
|
7059
|
+
if (typeof layoutChanged === 'function') {
|
|
7060
|
+
layoutChanged(layout);
|
|
7061
|
+
}
|
|
7062
|
+
}, [layout, layoutChanged]);
|
|
7063
|
+
const getLayoutForKey = (key, defaultValue) => {
|
|
7064
|
+
return minDash.get(layout, key, defaultValue);
|
|
7065
|
+
};
|
|
7066
|
+
const setLayoutForKey = (key, config) => {
|
|
7067
|
+
const newLayout = minDash.assign({}, layout);
|
|
7068
|
+
minDash.set(newLayout, key, config);
|
|
7069
|
+
setLayout(newLayout);
|
|
7070
|
+
};
|
|
7071
|
+
const layoutContext = {
|
|
7072
|
+
layout,
|
|
7073
|
+
setLayout,
|
|
7074
|
+
getLayoutForKey,
|
|
7075
|
+
setLayoutForKey
|
|
7076
|
+
};
|
|
7077
|
+
|
|
7078
|
+
// set-up description context
|
|
7079
|
+
const description = hooks.useMemo(() => createDescriptionContext(descriptionConfig), [descriptionConfig]);
|
|
7080
|
+
hooks.useEffect(() => {
|
|
7081
|
+
if (typeof descriptionLoaded === 'function') {
|
|
7082
|
+
descriptionLoaded(description);
|
|
7083
|
+
}
|
|
7084
|
+
}, [description, descriptionLoaded]);
|
|
7085
|
+
const getDescriptionForId = (id, element) => {
|
|
7086
|
+
return description[id] && description[id](element);
|
|
7087
|
+
};
|
|
7088
|
+
const descriptionContext = {
|
|
7089
|
+
description,
|
|
7090
|
+
getDescriptionForId
|
|
7091
|
+
};
|
|
7092
|
+
|
|
7093
|
+
// set-up tooltip context
|
|
7094
|
+
const tooltip = hooks.useMemo(() => createTooltipContext(tooltipConfig), [tooltipConfig]);
|
|
7095
|
+
hooks.useEffect(() => {
|
|
7096
|
+
if (typeof tooltipLoaded === 'function') {
|
|
7097
|
+
tooltipLoaded(tooltip);
|
|
7098
|
+
}
|
|
7099
|
+
}, [tooltip, tooltipLoaded]);
|
|
7100
|
+
const getTooltipForId = (id, element) => {
|
|
7101
|
+
return tooltip[id] && tooltip[id](element);
|
|
7102
|
+
};
|
|
7103
|
+
const tooltipContext = {
|
|
7104
|
+
tooltip,
|
|
7105
|
+
getTooltipForId
|
|
7106
|
+
};
|
|
7107
|
+
const [errors, setErrors] = hooks.useState({});
|
|
7108
|
+
const onSetErrors = ({
|
|
7109
|
+
errors
|
|
7110
|
+
}) => setErrors(errors);
|
|
7111
|
+
useEvent('propertiesPanel.setErrors', onSetErrors, eventBus);
|
|
7112
|
+
const errorsContext = {
|
|
7113
|
+
errors
|
|
7114
|
+
};
|
|
7115
|
+
const eventContext = {
|
|
7116
|
+
eventBus
|
|
7117
|
+
};
|
|
7118
|
+
const propertiesPanelContext = {
|
|
7119
|
+
element
|
|
7120
|
+
};
|
|
7121
|
+
|
|
7122
|
+
// empty state
|
|
7123
|
+
if (placeholderProvider && !element) {
|
|
7124
|
+
return jsxRuntime.jsx(Placeholder, {
|
|
7125
|
+
...placeholderProvider.getEmpty()
|
|
7126
|
+
});
|
|
7127
|
+
}
|
|
7128
|
+
|
|
7129
|
+
// multiple state
|
|
7130
|
+
if (placeholderProvider && minDash.isArray(element)) {
|
|
7131
|
+
return jsxRuntime.jsx(Placeholder, {
|
|
7132
|
+
...placeholderProvider.getMultiple()
|
|
7133
|
+
});
|
|
7134
|
+
}
|
|
7135
|
+
return jsxRuntime.jsx(LayoutContext.Provider, {
|
|
7136
|
+
value: propertiesPanelContext,
|
|
7137
|
+
children: jsxRuntime.jsx(ErrorsContext.Provider, {
|
|
7138
|
+
value: errorsContext,
|
|
7139
|
+
children: jsxRuntime.jsx(DescriptionContext.Provider, {
|
|
7140
|
+
value: descriptionContext,
|
|
7141
|
+
children: jsxRuntime.jsx(TooltipContext.Provider, {
|
|
7142
|
+
value: tooltipContext,
|
|
7143
|
+
children: jsxRuntime.jsx(LayoutContext.Provider, {
|
|
7144
|
+
value: layoutContext,
|
|
7145
|
+
children: jsxRuntime.jsx(EventContext.Provider, {
|
|
7146
|
+
value: eventContext,
|
|
7147
|
+
children: jsxRuntime.jsx(FEELPopupRoot, {
|
|
7148
|
+
element: element,
|
|
7149
|
+
children: jsxRuntime.jsxs("div", {
|
|
7150
|
+
class: "bio-properties-panel",
|
|
7151
|
+
children: [jsxRuntime.jsx(Header, {
|
|
7152
|
+
element: element,
|
|
7153
|
+
headerProvider: headerProvider
|
|
7154
|
+
}), jsxRuntime.jsx("div", {
|
|
7155
|
+
class: "bio-properties-panel-scroll-container",
|
|
7156
|
+
children: groups.map(group => {
|
|
7157
|
+
const {
|
|
7158
|
+
component: Component = Group,
|
|
7159
|
+
id
|
|
7160
|
+
} = group;
|
|
7161
|
+
return preact.createElement(Component, {
|
|
7162
|
+
...group,
|
|
7163
|
+
key: id,
|
|
7164
|
+
element: element
|
|
7165
|
+
});
|
|
7166
|
+
})
|
|
7167
|
+
})]
|
|
7168
|
+
})
|
|
7169
|
+
})
|
|
7170
|
+
})
|
|
7171
|
+
})
|
|
7172
|
+
})
|
|
7173
|
+
})
|
|
7174
|
+
})
|
|
7175
|
+
});
|
|
7176
|
+
}
|
|
7177
|
+
|
|
7178
|
+
// helpers //////////////////
|
|
7179
|
+
|
|
7180
|
+
function createLayout(overrides = {}, defaults = DEFAULT_LAYOUT) {
|
|
7181
|
+
return {
|
|
7182
|
+
...defaults,
|
|
7183
|
+
...overrides
|
|
7184
|
+
};
|
|
7185
|
+
}
|
|
7186
|
+
function createDescriptionContext(overrides = {}) {
|
|
7187
|
+
return {
|
|
7188
|
+
...DEFAULT_DESCRIPTION,
|
|
7189
|
+
...overrides
|
|
7190
|
+
};
|
|
7191
|
+
}
|
|
7192
|
+
function createTooltipContext(overrides = {}) {
|
|
7193
|
+
return {
|
|
7194
|
+
...DEFAULT_TOOLTIP,
|
|
7195
|
+
...overrides
|
|
7196
|
+
};
|
|
7197
|
+
}
|
|
7198
|
+
|
|
7199
|
+
// hooks //////////////////
|
|
7200
|
+
|
|
7201
|
+
/**
|
|
7202
|
+
* This hook behaves like useLayoutEffect, but does not trigger on the first render.
|
|
7203
|
+
*
|
|
7204
|
+
* @param {Function} effect
|
|
7205
|
+
* @param {Array} deps
|
|
7206
|
+
*/
|
|
7207
|
+
function useUpdateLayoutEffect(effect, deps) {
|
|
7208
|
+
const isMounted = hooks.useRef(false);
|
|
7209
|
+
hooks.useLayoutEffect(() => {
|
|
7210
|
+
if (isMounted.current) {
|
|
7211
|
+
return effect();
|
|
7212
|
+
} else {
|
|
7213
|
+
isMounted.current = true;
|
|
7214
|
+
}
|
|
7215
|
+
}, deps);
|
|
7216
|
+
}
|
|
7217
|
+
function CollapsibleEntry(props) {
|
|
7218
|
+
const {
|
|
7219
|
+
element,
|
|
7220
|
+
entries = [],
|
|
7221
|
+
id,
|
|
7222
|
+
label,
|
|
7223
|
+
open: shouldOpen,
|
|
7224
|
+
remove
|
|
7225
|
+
} = props;
|
|
7226
|
+
const [open, setOpen] = hooks.useState(shouldOpen);
|
|
7227
|
+
const toggleOpen = () => setOpen(!open);
|
|
7228
|
+
const {
|
|
7229
|
+
onShow
|
|
7230
|
+
} = hooks.useContext(LayoutContext);
|
|
7231
|
+
const propertiesPanelContext = {
|
|
7232
|
+
...hooks.useContext(LayoutContext),
|
|
7233
|
+
onShow: hooks.useCallback(() => {
|
|
7234
|
+
setOpen(true);
|
|
7235
|
+
if (minDash.isFunction(onShow)) {
|
|
7236
|
+
onShow();
|
|
7237
|
+
}
|
|
7238
|
+
}, [onShow, setOpen])
|
|
7239
|
+
};
|
|
7240
|
+
|
|
7241
|
+
// todo(pinussilvestrus): translate once we have a translate mechanism for the core
|
|
7242
|
+
const placeholderLabel = '<empty>';
|
|
7243
|
+
return jsxRuntime.jsxs("div", {
|
|
7244
|
+
"data-entry-id": id,
|
|
7245
|
+
class: classnames('bio-properties-panel-collapsible-entry', open ? 'open' : ''),
|
|
7246
|
+
children: [jsxRuntime.jsxs("div", {
|
|
7247
|
+
class: "bio-properties-panel-collapsible-entry-header",
|
|
7248
|
+
onClick: toggleOpen,
|
|
7249
|
+
children: [jsxRuntime.jsx("div", {
|
|
7250
|
+
title: label || placeholderLabel,
|
|
7251
|
+
class: classnames('bio-properties-panel-collapsible-entry-header-title', !label && 'empty'),
|
|
7252
|
+
children: label || placeholderLabel
|
|
7253
|
+
}), jsxRuntime.jsx("button", {
|
|
7254
|
+
title: "Toggle list item",
|
|
7255
|
+
class: "bio-properties-panel-arrow bio-properties-panel-collapsible-entry-arrow",
|
|
7256
|
+
children: jsxRuntime.jsx(ArrowIcon, {
|
|
7257
|
+
class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
|
|
7258
|
+
})
|
|
7259
|
+
}), remove ? jsxRuntime.jsx("button", {
|
|
7260
|
+
title: "Delete item",
|
|
7261
|
+
class: "bio-properties-panel-remove-entry",
|
|
7262
|
+
onClick: remove,
|
|
7263
|
+
children: jsxRuntime.jsx(DeleteIcon, {})
|
|
7264
|
+
}) : null]
|
|
7265
|
+
}), jsxRuntime.jsx("div", {
|
|
7266
|
+
class: classnames('bio-properties-panel-collapsible-entry-entries', open ? 'open' : ''),
|
|
7267
|
+
children: jsxRuntime.jsx(LayoutContext.Provider, {
|
|
7268
|
+
value: propertiesPanelContext,
|
|
7269
|
+
children: entries.map(entry => {
|
|
7270
|
+
const {
|
|
7271
|
+
component: Component,
|
|
7272
|
+
id
|
|
7273
|
+
} = entry;
|
|
7274
|
+
return preact.createElement(Component, {
|
|
7275
|
+
...entry,
|
|
7276
|
+
element: element,
|
|
7277
|
+
key: id
|
|
7278
|
+
});
|
|
7279
|
+
})
|
|
7280
|
+
})
|
|
7281
|
+
})]
|
|
7282
|
+
});
|
|
7283
|
+
}
|
|
7284
|
+
function ListItem(props) {
|
|
7285
|
+
const {
|
|
7286
|
+
autoFocusEntry,
|
|
7287
|
+
autoOpen
|
|
7288
|
+
} = props;
|
|
6734
7289
|
|
|
6735
|
-
//
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
const
|
|
6740
|
-
if (
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
if (position > value.length) {
|
|
6746
|
-
position = value.length;
|
|
7290
|
+
// focus specified entry on auto open
|
|
7291
|
+
hooks.useEffect(() => {
|
|
7292
|
+
if (autoOpen && autoFocusEntry) {
|
|
7293
|
+
const entry = minDom.query(`[data-entry-id="${autoFocusEntry}"]`);
|
|
7294
|
+
const focusableInput = minDom.query('.bio-properties-panel-input', entry);
|
|
7295
|
+
if (focusableInput) {
|
|
7296
|
+
if (minDash.isFunction(focusableInput.select)) {
|
|
7297
|
+
focusableInput.select();
|
|
7298
|
+
} else if (minDash.isFunction(focusableInput.focus)) {
|
|
7299
|
+
focusableInput.focus();
|
|
6747
7300
|
}
|
|
6748
|
-
input.setSelectionRange(position, position);
|
|
6749
7301
|
}
|
|
6750
7302
|
}
|
|
6751
|
-
};
|
|
6752
|
-
return jsxRuntime.jsx(
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
max: max,
|
|
6759
|
-
min: min,
|
|
6760
|
-
onInput: onInput,
|
|
6761
|
-
step: step,
|
|
6762
|
-
value: value,
|
|
6763
|
-
onFocus: onFocus,
|
|
6764
|
-
onBlur: onBlur
|
|
7303
|
+
}, [autoOpen, autoFocusEntry]);
|
|
7304
|
+
return jsxRuntime.jsx("div", {
|
|
7305
|
+
class: "bio-properties-panel-list-item",
|
|
7306
|
+
children: jsxRuntime.jsx(CollapsibleEntry, {
|
|
7307
|
+
...props,
|
|
7308
|
+
open: autoOpen
|
|
7309
|
+
})
|
|
6765
7310
|
});
|
|
6766
|
-
}
|
|
6767
|
-
|
|
7311
|
+
}
|
|
7312
|
+
const noop$1 = () => {};
|
|
7313
|
+
|
|
7314
|
+
/**
|
|
7315
|
+
* @param {import('../PropertiesPanel').ListGroupDefinition} props
|
|
7316
|
+
*/
|
|
7317
|
+
function ListGroup(props) {
|
|
6768
7318
|
const {
|
|
7319
|
+
add,
|
|
7320
|
+
element,
|
|
6769
7321
|
id,
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
onBlur
|
|
7322
|
+
items,
|
|
7323
|
+
label,
|
|
7324
|
+
shouldOpen = true,
|
|
7325
|
+
shouldSort = true
|
|
6775
7326
|
} = props;
|
|
6776
|
-
const
|
|
7327
|
+
const groupRef = hooks.useRef(null);
|
|
7328
|
+
const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
|
|
7329
|
+
const [sticky, setSticky] = hooks.useState(false);
|
|
7330
|
+
const onShow = hooks.useCallback(() => setOpen(true), [setOpen]);
|
|
7331
|
+
const [ordering, setOrdering] = hooks.useState([]);
|
|
7332
|
+
const [newItemAdded, setNewItemAdded] = hooks.useState(false);
|
|
6777
7333
|
|
|
6778
|
-
//
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
7334
|
+
// Flag to mark that add button was clicked in the last render cycle
|
|
7335
|
+
const [addTriggered, setAddTriggered] = hooks.useState(false);
|
|
7336
|
+
const prevItems = usePrevious(items);
|
|
7337
|
+
const prevElement = usePrevious(element);
|
|
7338
|
+
const elementChanged = element !== prevElement;
|
|
7339
|
+
const shouldHandleEffects = !elementChanged && (shouldSort || shouldOpen);
|
|
7340
|
+
|
|
7341
|
+
// reset initial ordering when element changes (before first render)
|
|
7342
|
+
if (elementChanged) {
|
|
7343
|
+
setOrdering(createOrdering(shouldSort ? sortItems(items) : items));
|
|
7344
|
+
}
|
|
7345
|
+
|
|
7346
|
+
// keep ordering in sync to items - and open changes
|
|
7347
|
+
|
|
7348
|
+
// (0) set initial ordering from given items
|
|
7349
|
+
hooks.useEffect(() => {
|
|
7350
|
+
if (!prevItems || !shouldSort) {
|
|
7351
|
+
setOrdering(createOrdering(items));
|
|
7352
|
+
}
|
|
7353
|
+
}, [items, element]);
|
|
7354
|
+
|
|
7355
|
+
// (1) items were added
|
|
7356
|
+
hooks.useEffect(() => {
|
|
7357
|
+
// reset addTriggered flag
|
|
7358
|
+
setAddTriggered(false);
|
|
7359
|
+
if (shouldHandleEffects && prevItems && items.length > prevItems.length) {
|
|
7360
|
+
let add = [];
|
|
7361
|
+
items.forEach(item => {
|
|
7362
|
+
if (!ordering.includes(item.id)) {
|
|
7363
|
+
add.push(item.id);
|
|
7364
|
+
}
|
|
7365
|
+
});
|
|
7366
|
+
let newOrdering = ordering;
|
|
7367
|
+
|
|
7368
|
+
// open if not open, configured and triggered by add button
|
|
7369
|
+
//
|
|
7370
|
+
// TODO(marstamm): remove once we refactor layout handling for listGroups.
|
|
7371
|
+
// Ideally, opening should be handled as part of the `add` callback and
|
|
7372
|
+
// not be a concern for the ListGroup component.
|
|
7373
|
+
if (addTriggered && !open && shouldOpen) {
|
|
7374
|
+
toggleOpen();
|
|
6785
7375
|
}
|
|
6786
|
-
|
|
6787
|
-
|
|
7376
|
+
|
|
7377
|
+
// filter when not open and configured
|
|
7378
|
+
if (!open && shouldSort) {
|
|
7379
|
+
newOrdering = createOrdering(sortItems(items));
|
|
7380
|
+
}
|
|
7381
|
+
|
|
7382
|
+
// add new items on top or bottom depending on sorting behavior
|
|
7383
|
+
newOrdering = newOrdering.filter(item => !add.includes(item));
|
|
7384
|
+
if (shouldSort) {
|
|
7385
|
+
newOrdering.unshift(...add);
|
|
7386
|
+
} else {
|
|
7387
|
+
newOrdering.push(...add);
|
|
7388
|
+
}
|
|
7389
|
+
setOrdering(newOrdering);
|
|
7390
|
+
setNewItemAdded(addTriggered);
|
|
7391
|
+
} else {
|
|
7392
|
+
setNewItemAdded(false);
|
|
7393
|
+
}
|
|
7394
|
+
}, [items, open, shouldHandleEffects, addTriggered]);
|
|
7395
|
+
|
|
7396
|
+
// (2) sort items on open if shouldSort is set
|
|
7397
|
+
hooks.useEffect(() => {
|
|
7398
|
+
if (shouldSort && open && !newItemAdded) {
|
|
7399
|
+
setOrdering(createOrdering(sortItems(items)));
|
|
7400
|
+
}
|
|
7401
|
+
}, [open, shouldSort]);
|
|
7402
|
+
|
|
7403
|
+
// (3) items were deleted
|
|
7404
|
+
hooks.useEffect(() => {
|
|
7405
|
+
if (shouldHandleEffects && prevItems && items.length < prevItems.length) {
|
|
7406
|
+
let keep = [];
|
|
7407
|
+
ordering.forEach(o => {
|
|
7408
|
+
if (getItem(items, o)) {
|
|
7409
|
+
keep.push(o);
|
|
7410
|
+
}
|
|
7411
|
+
});
|
|
7412
|
+
setOrdering(keep);
|
|
6788
7413
|
}
|
|
7414
|
+
}, [items, shouldHandleEffects]);
|
|
7415
|
+
|
|
7416
|
+
// set css class when group is sticky to top
|
|
7417
|
+
useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
|
|
7418
|
+
const toggleOpen = () => setOpen(!open);
|
|
7419
|
+
const hasItems = !!items.length;
|
|
7420
|
+
const propertiesPanelContext = {
|
|
7421
|
+
...hooks.useContext(LayoutContext),
|
|
7422
|
+
onShow
|
|
6789
7423
|
};
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
7424
|
+
const handleAddClick = e => {
|
|
7425
|
+
setAddTriggered(true);
|
|
7426
|
+
add(e);
|
|
7427
|
+
};
|
|
7428
|
+
const allErrors = useErrors();
|
|
7429
|
+
const hasError = items.some(item => {
|
|
7430
|
+
if (allErrors[item.id]) {
|
|
7431
|
+
return true;
|
|
7432
|
+
}
|
|
7433
|
+
if (!item.entries) {
|
|
7434
|
+
return;
|
|
7435
|
+
}
|
|
7436
|
+
|
|
7437
|
+
// also check if the error is nested, e.g. for name-value entries
|
|
7438
|
+
return item.entries.some(entry => allErrors[entry.id]);
|
|
6804
7439
|
});
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
7440
|
+
return jsxRuntime.jsxs("div", {
|
|
7441
|
+
class: "bio-properties-panel-group",
|
|
7442
|
+
"data-group-id": 'group-' + id,
|
|
7443
|
+
ref: groupRef,
|
|
7444
|
+
children: [jsxRuntime.jsxs("div", {
|
|
7445
|
+
class: classnames('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : '', sticky && open ? 'sticky' : ''),
|
|
7446
|
+
onClick: hasItems ? toggleOpen : noop$1,
|
|
7447
|
+
children: [jsxRuntime.jsx("div", {
|
|
7448
|
+
title: label,
|
|
7449
|
+
class: "bio-properties-panel-group-header-title",
|
|
7450
|
+
children: jsxRuntime.jsx(TooltipWrapper, {
|
|
7451
|
+
value: props.tooltip,
|
|
7452
|
+
forId: 'group-' + id,
|
|
7453
|
+
element: element,
|
|
7454
|
+
parent: groupRef,
|
|
7455
|
+
children: label
|
|
7456
|
+
})
|
|
7457
|
+
}), jsxRuntime.jsxs("div", {
|
|
7458
|
+
class: "bio-properties-panel-group-header-buttons",
|
|
7459
|
+
children: [add ? jsxRuntime.jsxs("button", {
|
|
7460
|
+
title: "Create new list item",
|
|
7461
|
+
class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
|
|
7462
|
+
onClick: handleAddClick,
|
|
7463
|
+
children: [jsxRuntime.jsx(CreateIcon, {}), !hasItems ? jsxRuntime.jsx("span", {
|
|
7464
|
+
class: "bio-properties-panel-add-entry-label",
|
|
7465
|
+
children: "Create"
|
|
7466
|
+
}) : null]
|
|
7467
|
+
}) : null, hasItems ? jsxRuntime.jsx("div", {
|
|
7468
|
+
title: `List contains ${items.length} item${items.length != 1 ? 's' : ''}`,
|
|
7469
|
+
class: classnames('bio-properties-panel-list-badge', hasError ? 'bio-properties-panel-list-badge--error' : ''),
|
|
7470
|
+
children: items.length
|
|
7471
|
+
}) : null, hasItems ? jsxRuntime.jsx("button", {
|
|
7472
|
+
title: "Toggle section",
|
|
7473
|
+
class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
|
|
7474
|
+
children: jsxRuntime.jsx(ArrowIcon, {
|
|
7475
|
+
class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
|
|
7476
|
+
})
|
|
7477
|
+
}) : null]
|
|
7478
|
+
})]
|
|
7479
|
+
}), jsxRuntime.jsx("div", {
|
|
7480
|
+
class: classnames('bio-properties-panel-list', open && hasItems ? 'open' : ''),
|
|
7481
|
+
children: jsxRuntime.jsx(LayoutContext.Provider, {
|
|
7482
|
+
value: propertiesPanelContext,
|
|
7483
|
+
children: ordering.map((o, index) => {
|
|
7484
|
+
const item = getItem(items, o);
|
|
7485
|
+
if (!item) {
|
|
7486
|
+
return;
|
|
7487
|
+
}
|
|
7488
|
+
const {
|
|
7489
|
+
id
|
|
7490
|
+
} = item;
|
|
6816
7491
|
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
value: value,
|
|
6831
|
-
inputRef: inputRef,
|
|
6832
|
-
onInput: onInput,
|
|
6833
|
-
onFocus: onFocus,
|
|
6834
|
-
onBlur: onBlur,
|
|
6835
|
-
switcherLabel: switcherLabel
|
|
7492
|
+
// if item was added, open it
|
|
7493
|
+
// Existing items will not be affected as autoOpen is only applied on first render
|
|
7494
|
+
const autoOpen = newItemAdded;
|
|
7495
|
+
return preact.createElement(ListItem, {
|
|
7496
|
+
...item,
|
|
7497
|
+
autoOpen: autoOpen,
|
|
7498
|
+
element: element,
|
|
7499
|
+
index: index,
|
|
7500
|
+
key: id
|
|
7501
|
+
});
|
|
7502
|
+
})
|
|
7503
|
+
})
|
|
7504
|
+
})]
|
|
6836
7505
|
});
|
|
6837
|
-
}
|
|
6838
|
-
React.forwardRef((props, ref) => {
|
|
6839
|
-
const {
|
|
6840
|
-
id,
|
|
6841
|
-
disabled,
|
|
6842
|
-
onInput,
|
|
6843
|
-
value,
|
|
6844
|
-
onFocus,
|
|
6845
|
-
onBlur
|
|
6846
|
-
} = props;
|
|
6847
|
-
const inputRef = hooks.useRef();
|
|
6848
|
-
const handleChange = ({
|
|
6849
|
-
target
|
|
6850
|
-
}) => {
|
|
6851
|
-
onInput(target.checked);
|
|
6852
|
-
};
|
|
7506
|
+
}
|
|
6853
7507
|
|
|
6854
|
-
|
|
6855
|
-
// this ensures clean editing experience when switching with the keyboard
|
|
6856
|
-
ref.current = {
|
|
6857
|
-
focus: () => {
|
|
6858
|
-
const input = inputRef.current;
|
|
6859
|
-
if (!input) {
|
|
6860
|
-
return;
|
|
6861
|
-
}
|
|
6862
|
-
input.focus();
|
|
6863
|
-
}
|
|
6864
|
-
};
|
|
6865
|
-
return jsxRuntime.jsx("input", {
|
|
6866
|
-
ref: inputRef,
|
|
6867
|
-
id: prefixId$4(id),
|
|
6868
|
-
name: id,
|
|
6869
|
-
onFocus: onFocus,
|
|
6870
|
-
onBlur: onBlur,
|
|
6871
|
-
type: "checkbox",
|
|
6872
|
-
class: "bio-properties-panel-input",
|
|
6873
|
-
onChange: handleChange,
|
|
6874
|
-
checked: value,
|
|
6875
|
-
disabled: disabled
|
|
6876
|
-
});
|
|
6877
|
-
});
|
|
7508
|
+
// helpers ////////////////////
|
|
6878
7509
|
|
|
6879
7510
|
/**
|
|
6880
|
-
*
|
|
6881
|
-
* @param {Object} props.element
|
|
6882
|
-
* @param {String} props.id
|
|
6883
|
-
* @param {String} props.description
|
|
6884
|
-
* @param {Boolean} props.debounce
|
|
6885
|
-
* @param {Boolean} props.disabled
|
|
6886
|
-
* @param {Boolean} props.feel
|
|
6887
|
-
* @param {String} props.label
|
|
6888
|
-
* @param {Function} props.getValue
|
|
6889
|
-
* @param {Function} props.setValue
|
|
6890
|
-
* @param {Function} props.tooltipContainer
|
|
6891
|
-
* @param {Function} props.validate
|
|
6892
|
-
* @param {Function} props.show
|
|
6893
|
-
* @param {Function} props.example
|
|
6894
|
-
* @param {Function} props.variables
|
|
6895
|
-
* @param {Function} props.onFocus
|
|
6896
|
-
* @param {Function} props.onBlur
|
|
6897
|
-
* @param {string|import('preact').Component} props.tooltip
|
|
7511
|
+
* Sorts given items alphanumeric by label
|
|
6898
7512
|
*/
|
|
6899
|
-
function
|
|
7513
|
+
function sortItems(items) {
|
|
7514
|
+
return minDash.sortBy(items, i => i.label.toLowerCase());
|
|
7515
|
+
}
|
|
7516
|
+
function getItem(items, id) {
|
|
7517
|
+
return minDash.find(items, i => i.id === id);
|
|
7518
|
+
}
|
|
7519
|
+
function createOrdering(items) {
|
|
7520
|
+
return items.map(i => i.id);
|
|
7521
|
+
}
|
|
7522
|
+
function Checkbox(props) {
|
|
6900
7523
|
const {
|
|
6901
|
-
element,
|
|
6902
7524
|
id,
|
|
6903
|
-
description,
|
|
6904
|
-
debounce,
|
|
6905
|
-
disabled,
|
|
6906
|
-
feel,
|
|
6907
7525
|
label,
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
hostLanguage,
|
|
6912
|
-
singleLine,
|
|
6913
|
-
validate,
|
|
6914
|
-
show = noop$1,
|
|
6915
|
-
example,
|
|
6916
|
-
variables,
|
|
7526
|
+
onChange,
|
|
7527
|
+
disabled,
|
|
7528
|
+
value = false,
|
|
6917
7529
|
onFocus,
|
|
6918
7530
|
onBlur,
|
|
6919
7531
|
tooltip
|
|
6920
7532
|
} = props;
|
|
6921
|
-
const [
|
|
6922
|
-
const
|
|
6923
|
-
|
|
7533
|
+
const [localValue, setLocalValue] = hooks.useState(value);
|
|
7534
|
+
const handleChangeCallback = ({
|
|
7535
|
+
target
|
|
7536
|
+
}) => {
|
|
7537
|
+
onChange(target.checked);
|
|
7538
|
+
};
|
|
7539
|
+
const handleChange = e => {
|
|
7540
|
+
handleChangeCallback(e);
|
|
7541
|
+
setLocalValue(e.target.value);
|
|
7542
|
+
};
|
|
6924
7543
|
hooks.useEffect(() => {
|
|
6925
|
-
if (
|
|
6926
|
-
|
|
6927
|
-
setValidationError(newValidationError);
|
|
7544
|
+
if (value === localValue) {
|
|
7545
|
+
return;
|
|
6928
7546
|
}
|
|
7547
|
+
setLocalValue(value);
|
|
6929
7548
|
}, [value]);
|
|
6930
|
-
const
|
|
6931
|
-
let newValidationError = null;
|
|
6932
|
-
if (minDash.isFunction(validate)) {
|
|
6933
|
-
newValidationError = validate(newValue) || null;
|
|
6934
|
-
}
|
|
6935
|
-
|
|
6936
|
-
// don't create multiple commandStack entries for the same value
|
|
6937
|
-
if (newValue !== value) {
|
|
6938
|
-
setValue(newValue, newValidationError);
|
|
6939
|
-
}
|
|
6940
|
-
setValidationError(newValidationError);
|
|
6941
|
-
});
|
|
6942
|
-
const onError = hooks.useCallback(err => {
|
|
6943
|
-
setLocalError(err);
|
|
6944
|
-
}, []);
|
|
6945
|
-
const temporaryError = useError(id);
|
|
6946
|
-
const error = localError || temporaryError || validationError;
|
|
7549
|
+
const ref = useShowEntryEvent(id);
|
|
6947
7550
|
return jsxRuntime.jsxs("div", {
|
|
6948
|
-
class:
|
|
6949
|
-
"
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
disabled: disabled,
|
|
6954
|
-
feel: feel,
|
|
6955
|
-
id: id,
|
|
6956
|
-
key: element,
|
|
6957
|
-
label: label,
|
|
6958
|
-
onInput: onInput,
|
|
6959
|
-
onError: onError,
|
|
7551
|
+
class: "bio-properties-panel-checkbox",
|
|
7552
|
+
children: [jsxRuntime.jsx("input", {
|
|
7553
|
+
ref: ref,
|
|
7554
|
+
id: prefixId$4(id),
|
|
7555
|
+
name: id,
|
|
6960
7556
|
onFocus: onFocus,
|
|
6961
7557
|
onBlur: onBlur,
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
value: description
|
|
6978
|
-
})]
|
|
6979
|
-
});
|
|
6980
|
-
}
|
|
6981
|
-
|
|
6982
|
-
/**
|
|
6983
|
-
* @param {Object} props
|
|
6984
|
-
* @param {Object} props.element
|
|
6985
|
-
* @param {String} props.id
|
|
6986
|
-
* @param {String} props.description
|
|
6987
|
-
* @param {Boolean} props.debounce
|
|
6988
|
-
* @param {Boolean} props.disabled
|
|
6989
|
-
* @param {String} props.max
|
|
6990
|
-
* @param {String} props.min
|
|
6991
|
-
* @param {String} props.step
|
|
6992
|
-
* @param {Boolean} props.feel
|
|
6993
|
-
* @param {String} props.label
|
|
6994
|
-
* @param {Function} props.getValue
|
|
6995
|
-
* @param {Function} props.setValue
|
|
6996
|
-
* @param {Function} props.tooltipContainer
|
|
6997
|
-
* @param {Function} props.validate
|
|
6998
|
-
* @param {Function} props.show
|
|
6999
|
-
* @param {Function} props.example
|
|
7000
|
-
* @param {Function} props.variables
|
|
7001
|
-
* @param {Function} props.onFocus
|
|
7002
|
-
* @param {Function} props.onBlur
|
|
7003
|
-
*/
|
|
7004
|
-
function FeelNumberEntry(props) {
|
|
7005
|
-
return jsxRuntime.jsx(FeelEntry, {
|
|
7006
|
-
class: "bio-properties-panel-feel-number",
|
|
7007
|
-
OptionalComponent: OptionalFeelNumberField,
|
|
7008
|
-
...props
|
|
7009
|
-
});
|
|
7010
|
-
}
|
|
7011
|
-
|
|
7012
|
-
/**
|
|
7013
|
-
* @param {Object} props
|
|
7014
|
-
* @param {Object} props.element
|
|
7015
|
-
* @param {String} props.id
|
|
7016
|
-
* @param {String} props.description
|
|
7017
|
-
* @param {Boolean} props.debounce
|
|
7018
|
-
* @param {Boolean} props.disabled
|
|
7019
|
-
* @param {Boolean} props.feel
|
|
7020
|
-
* @param {String} props.label
|
|
7021
|
-
* @param {Function} props.getValue
|
|
7022
|
-
* @param {Function} props.setValue
|
|
7023
|
-
* @param {Function} props.tooltipContainer
|
|
7024
|
-
* @param {Function} props.validate
|
|
7025
|
-
* @param {Function} props.show
|
|
7026
|
-
* @param {Function} props.example
|
|
7027
|
-
* @param {Function} props.variables
|
|
7028
|
-
* @param {Function} props.onFocus
|
|
7029
|
-
* @param {Function} props.onBlur
|
|
7030
|
-
*/
|
|
7031
|
-
function FeelToggleSwitchEntry(props) {
|
|
7032
|
-
return jsxRuntime.jsx(FeelEntry, {
|
|
7033
|
-
class: "bio-properties-panel-feel-toggle-switch",
|
|
7034
|
-
OptionalComponent: OptionalFeelToggleSwitch,
|
|
7035
|
-
...props
|
|
7558
|
+
type: "checkbox",
|
|
7559
|
+
class: "bio-properties-panel-input",
|
|
7560
|
+
onChange: handleChange,
|
|
7561
|
+
checked: localValue,
|
|
7562
|
+
disabled: disabled
|
|
7563
|
+
}), jsxRuntime.jsx("label", {
|
|
7564
|
+
for: prefixId$4(id),
|
|
7565
|
+
class: "bio-properties-panel-label",
|
|
7566
|
+
children: jsxRuntime.jsx(TooltipWrapper, {
|
|
7567
|
+
value: tooltip,
|
|
7568
|
+
forId: id,
|
|
7569
|
+
element: props.element,
|
|
7570
|
+
children: label
|
|
7571
|
+
})
|
|
7572
|
+
})]
|
|
7036
7573
|
});
|
|
7037
7574
|
}
|
|
7038
7575
|
|
|
@@ -7041,37 +7578,54 @@ function FeelToggleSwitchEntry(props) {
|
|
|
7041
7578
|
* @param {Object} props.element
|
|
7042
7579
|
* @param {String} props.id
|
|
7043
7580
|
* @param {String} props.description
|
|
7044
|
-
* @param {String} props.hostLanguage
|
|
7045
|
-
* @param {Boolean} props.singleLine
|
|
7046
|
-
* @param {Boolean} props.debounce
|
|
7047
|
-
* @param {Boolean} props.disabled
|
|
7048
|
-
* @param {Boolean} props.feel
|
|
7049
7581
|
* @param {String} props.label
|
|
7050
7582
|
* @param {Function} props.getValue
|
|
7051
7583
|
* @param {Function} props.setValue
|
|
7052
|
-
* @param {Function} props.tooltipContainer
|
|
7053
|
-
* @param {Function} props.validate
|
|
7054
|
-
* @param {Function} props.show
|
|
7055
|
-
* @param {Function} props.example
|
|
7056
|
-
* @param {Function} props.variables
|
|
7057
7584
|
* @param {Function} props.onFocus
|
|
7058
7585
|
* @param {Function} props.onBlur
|
|
7586
|
+
* @param {string|import('preact').Component} props.tooltip
|
|
7587
|
+
* @param {boolean} [props.disabled]
|
|
7059
7588
|
*/
|
|
7060
|
-
function
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7589
|
+
function CheckboxEntry(props) {
|
|
7590
|
+
const {
|
|
7591
|
+
element,
|
|
7592
|
+
id,
|
|
7593
|
+
description,
|
|
7594
|
+
label,
|
|
7595
|
+
getValue,
|
|
7596
|
+
setValue,
|
|
7597
|
+
disabled,
|
|
7598
|
+
onFocus,
|
|
7599
|
+
onBlur,
|
|
7600
|
+
tooltip
|
|
7601
|
+
} = props;
|
|
7602
|
+
const value = getValue(element);
|
|
7603
|
+
const error = useError(id);
|
|
7604
|
+
return jsxRuntime.jsxs("div", {
|
|
7605
|
+
class: "bio-properties-panel-entry bio-properties-panel-checkbox-entry",
|
|
7606
|
+
"data-entry-id": id,
|
|
7607
|
+
children: [jsxRuntime.jsx(Checkbox, {
|
|
7608
|
+
disabled: disabled,
|
|
7609
|
+
id: id,
|
|
7610
|
+
label: label,
|
|
7611
|
+
onChange: setValue,
|
|
7612
|
+
onFocus: onFocus,
|
|
7613
|
+
onBlur: onBlur,
|
|
7614
|
+
value: value,
|
|
7615
|
+
tooltip: tooltip,
|
|
7616
|
+
element: element
|
|
7617
|
+
}, element), error && jsxRuntime.jsx("div", {
|
|
7618
|
+
class: "bio-properties-panel-error",
|
|
7619
|
+
children: error
|
|
7620
|
+
}), jsxRuntime.jsx(Description$1, {
|
|
7621
|
+
forId: id,
|
|
7622
|
+
element: element,
|
|
7623
|
+
value: description
|
|
7624
|
+
})]
|
|
7065
7625
|
});
|
|
7066
7626
|
}
|
|
7067
7627
|
function isEdited$5(node) {
|
|
7068
|
-
|
|
7069
|
-
return false;
|
|
7070
|
-
}
|
|
7071
|
-
if (node.type === 'checkbox') {
|
|
7072
|
-
return !!node.checked || node.classList.contains('edited');
|
|
7073
|
-
}
|
|
7074
|
-
return !!node.value || node.classList.contains('edited');
|
|
7628
|
+
return node && !!node.checked;
|
|
7075
7629
|
}
|
|
7076
7630
|
|
|
7077
7631
|
// helpers /////////////////
|
|
@@ -7567,6 +8121,9 @@ function textToLabel(text) {
|
|
|
7567
8121
|
}
|
|
7568
8122
|
return null;
|
|
7569
8123
|
}
|
|
8124
|
+
function isValidDotPath(path) {
|
|
8125
|
+
return /^\w+(\.\w+)*$/.test(path);
|
|
8126
|
+
}
|
|
7570
8127
|
const INPUTS = ['checkbox', 'checklist', 'datetime', 'number', 'radio', 'select', 'taglist', 'textfield', 'textarea'];
|
|
7571
8128
|
const VALUES_INPUTS = ['checklist', 'radio', 'select', 'taglist'];
|
|
7572
8129
|
|
|
@@ -7577,6 +8134,7 @@ const labelsByType = {
|
|
|
7577
8134
|
columns: 'COLUMNS',
|
|
7578
8135
|
default: 'FORM',
|
|
7579
8136
|
datetime: 'DATETIME',
|
|
8137
|
+
group: 'GROUP',
|
|
7580
8138
|
image: 'IMAGE VIEW',
|
|
7581
8139
|
number: 'NUMBER',
|
|
7582
8140
|
radio: 'RADIO',
|
|
@@ -7592,6 +8150,9 @@ const PropertiesPanelHeaderProvider = {
|
|
|
7592
8150
|
const {
|
|
7593
8151
|
type
|
|
7594
8152
|
} = field;
|
|
8153
|
+
if (type === 'spacer') {
|
|
8154
|
+
return '';
|
|
8155
|
+
}
|
|
7595
8156
|
if (type === 'text') {
|
|
7596
8157
|
return textToLabel(field.text);
|
|
7597
8158
|
}
|
|
@@ -7723,7 +8284,7 @@ function AltTextEntry(props) {
|
|
|
7723
8284
|
component: AltText,
|
|
7724
8285
|
editField: editField,
|
|
7725
8286
|
field: field,
|
|
7726
|
-
isEdited: isEdited$
|
|
8287
|
+
isEdited: isEdited$6
|
|
7727
8288
|
});
|
|
7728
8289
|
}
|
|
7729
8290
|
return entries;
|
|
@@ -7846,7 +8407,7 @@ function DescriptionEntry(props) {
|
|
|
7846
8407
|
component: Description,
|
|
7847
8408
|
editField: editField,
|
|
7848
8409
|
field: field,
|
|
7849
|
-
isEdited: isEdited$
|
|
8410
|
+
isEdited: isEdited$6
|
|
7850
8411
|
});
|
|
7851
8412
|
}
|
|
7852
8413
|
return entries;
|
|
@@ -8133,7 +8694,7 @@ function DisabledEntry(props) {
|
|
|
8133
8694
|
component: Disabled,
|
|
8134
8695
|
editField: editField,
|
|
8135
8696
|
field: field,
|
|
8136
|
-
isEdited: isEdited$
|
|
8697
|
+
isEdited: isEdited$8
|
|
8137
8698
|
});
|
|
8138
8699
|
}
|
|
8139
8700
|
return entries;
|
|
@@ -8268,7 +8829,7 @@ function Key$1(props) {
|
|
|
8268
8829
|
field,
|
|
8269
8830
|
id
|
|
8270
8831
|
} = props;
|
|
8271
|
-
const
|
|
8832
|
+
const pathRegistry = useService('pathRegistry');
|
|
8272
8833
|
const debounce = useService('debounce');
|
|
8273
8834
|
const path = ['key'];
|
|
8274
8835
|
const getValue = () => {
|
|
@@ -8281,17 +8842,32 @@ function Key$1(props) {
|
|
|
8281
8842
|
return editField(field, path, value);
|
|
8282
8843
|
};
|
|
8283
8844
|
const validate = value => {
|
|
8845
|
+
if (value === field.key) {
|
|
8846
|
+
return null;
|
|
8847
|
+
}
|
|
8284
8848
|
if (minDash.isUndefined(value) || !value.length) {
|
|
8285
8849
|
return 'Must not be empty.';
|
|
8286
8850
|
}
|
|
8287
|
-
if (
|
|
8288
|
-
return 'Must
|
|
8851
|
+
if (value && !isValidDotPath(value)) {
|
|
8852
|
+
return 'Must be a variable or a dot separated path.';
|
|
8289
8853
|
}
|
|
8290
|
-
const
|
|
8291
|
-
if (
|
|
8292
|
-
return 'Must
|
|
8854
|
+
const hasIntegerPathSegment = value.split('.').some(segment => /^\d+$/.test(segment));
|
|
8855
|
+
if (hasIntegerPathSegment) {
|
|
8856
|
+
return 'Must not contain numerical path segments.';
|
|
8293
8857
|
}
|
|
8294
|
-
|
|
8858
|
+
const replacements = {
|
|
8859
|
+
[field.id]: value.split('.')
|
|
8860
|
+
};
|
|
8861
|
+
const oldPath = pathRegistry.getValuePath(field);
|
|
8862
|
+
const newPath = pathRegistry.getValuePath(field, {
|
|
8863
|
+
replacements
|
|
8864
|
+
});
|
|
8865
|
+
|
|
8866
|
+
// unclaim temporarily to avoid self-conflicts
|
|
8867
|
+
pathRegistry.unclaimPath(oldPath);
|
|
8868
|
+
const canClaim = pathRegistry.canClaimPath(newPath, true);
|
|
8869
|
+
pathRegistry.claimPath(oldPath, true);
|
|
8870
|
+
return canClaim ? null : 'Must not conflict with other key/path assignments.';
|
|
8295
8871
|
};
|
|
8296
8872
|
return TextfieldEntry({
|
|
8297
8873
|
debounce,
|
|
@@ -8306,6 +8882,147 @@ function Key$1(props) {
|
|
|
8306
8882
|
});
|
|
8307
8883
|
}
|
|
8308
8884
|
|
|
8885
|
+
function PathEntry(props) {
|
|
8886
|
+
const {
|
|
8887
|
+
editField,
|
|
8888
|
+
field
|
|
8889
|
+
} = props;
|
|
8890
|
+
const {
|
|
8891
|
+
type
|
|
8892
|
+
} = field;
|
|
8893
|
+
const entries = [];
|
|
8894
|
+
if (type === 'group') {
|
|
8895
|
+
entries.push({
|
|
8896
|
+
id: 'path',
|
|
8897
|
+
component: Path,
|
|
8898
|
+
editField: editField,
|
|
8899
|
+
field: field,
|
|
8900
|
+
isEdited: isEdited
|
|
8901
|
+
});
|
|
8902
|
+
}
|
|
8903
|
+
return entries;
|
|
8904
|
+
}
|
|
8905
|
+
function Path(props) {
|
|
8906
|
+
const {
|
|
8907
|
+
editField,
|
|
8908
|
+
field,
|
|
8909
|
+
id
|
|
8910
|
+
} = props;
|
|
8911
|
+
const debounce = useService('debounce');
|
|
8912
|
+
const pathRegistry = useService('pathRegistry');
|
|
8913
|
+
const path = ['path'];
|
|
8914
|
+
const getValue = () => {
|
|
8915
|
+
return minDash.get(field, path, '');
|
|
8916
|
+
};
|
|
8917
|
+
const setValue = (value, error) => {
|
|
8918
|
+
if (error) {
|
|
8919
|
+
return;
|
|
8920
|
+
}
|
|
8921
|
+
return editField(field, path, value);
|
|
8922
|
+
};
|
|
8923
|
+
const validate = value => {
|
|
8924
|
+
if (!value || value === field.path) {
|
|
8925
|
+
return null;
|
|
8926
|
+
}
|
|
8927
|
+
if (value && !isValidDotPath(value)) {
|
|
8928
|
+
return 'Must be empty, a variable or a dot separated path';
|
|
8929
|
+
}
|
|
8930
|
+
const hasIntegerPathSegment = value && value.split('.').some(segment => /^\d+$/.test(segment));
|
|
8931
|
+
if (hasIntegerPathSegment) {
|
|
8932
|
+
return 'Must not contain numerical path segments.';
|
|
8933
|
+
}
|
|
8934
|
+
const options = value && {
|
|
8935
|
+
replacements: {
|
|
8936
|
+
[field.id]: [value]
|
|
8937
|
+
}
|
|
8938
|
+
} || {};
|
|
8939
|
+
const canClaim = pathRegistry.executeRecursivelyOnFields(field, ({
|
|
8940
|
+
field,
|
|
8941
|
+
isClosed
|
|
8942
|
+
}) => {
|
|
8943
|
+
const path = pathRegistry.getValuePath(field, options);
|
|
8944
|
+
return pathRegistry.canClaimPath(path, isClosed);
|
|
8945
|
+
});
|
|
8946
|
+
if (!canClaim) {
|
|
8947
|
+
return 'Must not cause two binding paths to colide';
|
|
8948
|
+
}
|
|
8949
|
+
};
|
|
8950
|
+
return TextfieldEntry({
|
|
8951
|
+
debounce,
|
|
8952
|
+
description: 'Where the child variables of this component are pathed to.',
|
|
8953
|
+
element: field,
|
|
8954
|
+
getValue,
|
|
8955
|
+
id,
|
|
8956
|
+
label: 'Path',
|
|
8957
|
+
tooltip: 'Routes the children of this component into a form variable, may be left empty to route at the root level.',
|
|
8958
|
+
setValue,
|
|
8959
|
+
validate
|
|
8960
|
+
});
|
|
8961
|
+
}
|
|
8962
|
+
|
|
8963
|
+
function simpleBoolEntryFactory(options) {
|
|
8964
|
+
const {
|
|
8965
|
+
id,
|
|
8966
|
+
label,
|
|
8967
|
+
description,
|
|
8968
|
+
path,
|
|
8969
|
+
props
|
|
8970
|
+
} = options;
|
|
8971
|
+
const {
|
|
8972
|
+
editField,
|
|
8973
|
+
field
|
|
8974
|
+
} = props;
|
|
8975
|
+
return {
|
|
8976
|
+
id,
|
|
8977
|
+
label,
|
|
8978
|
+
path,
|
|
8979
|
+
field,
|
|
8980
|
+
editField,
|
|
8981
|
+
description,
|
|
8982
|
+
component: SimpleBoolComponent,
|
|
8983
|
+
isEdited: isEdited$5
|
|
8984
|
+
};
|
|
8985
|
+
}
|
|
8986
|
+
const SimpleBoolComponent = props => {
|
|
8987
|
+
const {
|
|
8988
|
+
id,
|
|
8989
|
+
label,
|
|
8990
|
+
path,
|
|
8991
|
+
field,
|
|
8992
|
+
editField,
|
|
8993
|
+
description
|
|
8994
|
+
} = props;
|
|
8995
|
+
const getValue = () => minDash.get(field, path, '');
|
|
8996
|
+
const setValue = value => editField(field, path, value || false);
|
|
8997
|
+
return CheckboxEntry({
|
|
8998
|
+
element: field,
|
|
8999
|
+
getValue,
|
|
9000
|
+
id,
|
|
9001
|
+
label,
|
|
9002
|
+
setValue,
|
|
9003
|
+
description
|
|
9004
|
+
});
|
|
9005
|
+
};
|
|
9006
|
+
|
|
9007
|
+
function GroupEntries(props) {
|
|
9008
|
+
const {
|
|
9009
|
+
field
|
|
9010
|
+
} = props;
|
|
9011
|
+
const {
|
|
9012
|
+
type
|
|
9013
|
+
} = field;
|
|
9014
|
+
if (type !== 'group') {
|
|
9015
|
+
return [];
|
|
9016
|
+
}
|
|
9017
|
+
const entries = [simpleBoolEntryFactory({
|
|
9018
|
+
id: 'showOutline',
|
|
9019
|
+
path: ['showOutline'],
|
|
9020
|
+
label: 'Show outline',
|
|
9021
|
+
props
|
|
9022
|
+
})];
|
|
9023
|
+
return entries;
|
|
9024
|
+
}
|
|
9025
|
+
|
|
8309
9026
|
function LabelEntry(props) {
|
|
8310
9027
|
const {
|
|
8311
9028
|
field,
|
|
@@ -8323,7 +9040,7 @@ function LabelEntry(props) {
|
|
|
8323
9040
|
component: DateLabel,
|
|
8324
9041
|
editField,
|
|
8325
9042
|
field,
|
|
8326
|
-
isEdited: isEdited$
|
|
9043
|
+
isEdited: isEdited$6
|
|
8327
9044
|
});
|
|
8328
9045
|
}
|
|
8329
9046
|
if (subtype === formJsViewer.DATETIME_SUBTYPES.TIME || subtype === formJsViewer.DATETIME_SUBTYPES.DATETIME) {
|
|
@@ -8332,16 +9049,16 @@ function LabelEntry(props) {
|
|
|
8332
9049
|
component: TimeLabel,
|
|
8333
9050
|
editField,
|
|
8334
9051
|
field,
|
|
8335
|
-
isEdited: isEdited$
|
|
9052
|
+
isEdited: isEdited$6
|
|
8336
9053
|
});
|
|
8337
9054
|
}
|
|
8338
|
-
} else if (INPUTS.includes(type) || type === 'button') {
|
|
9055
|
+
} else if (INPUTS.includes(type) || type === 'button' || type === 'group') {
|
|
8339
9056
|
entries.push({
|
|
8340
9057
|
id: 'label',
|
|
8341
9058
|
component: Label$1,
|
|
8342
9059
|
editField,
|
|
8343
9060
|
field,
|
|
8344
|
-
isEdited: isEdited$
|
|
9061
|
+
isEdited: isEdited$6
|
|
8345
9062
|
});
|
|
8346
9063
|
}
|
|
8347
9064
|
return entries;
|
|
@@ -8363,12 +9080,13 @@ function Label$1(props) {
|
|
|
8363
9080
|
const setValue = value => {
|
|
8364
9081
|
return editField(field, path, value || '');
|
|
8365
9082
|
};
|
|
9083
|
+
const label = field.type === 'group' ? 'Group label' : 'Field label';
|
|
8366
9084
|
return FeelTemplatingEntry({
|
|
8367
9085
|
debounce,
|
|
8368
9086
|
element: field,
|
|
8369
9087
|
getValue,
|
|
8370
9088
|
id,
|
|
8371
|
-
label
|
|
9089
|
+
label,
|
|
8372
9090
|
singleLine: true,
|
|
8373
9091
|
setValue,
|
|
8374
9092
|
variables
|
|
@@ -8446,7 +9164,7 @@ function SourceEntry(props) {
|
|
|
8446
9164
|
component: Source,
|
|
8447
9165
|
editField: editField,
|
|
8448
9166
|
field: field,
|
|
8449
|
-
isEdited: isEdited$
|
|
9167
|
+
isEdited: isEdited$6
|
|
8450
9168
|
});
|
|
8451
9169
|
}
|
|
8452
9170
|
return entries;
|
|
@@ -8503,7 +9221,7 @@ function TextEntry(props) {
|
|
|
8503
9221
|
component: Text,
|
|
8504
9222
|
editField: editField,
|
|
8505
9223
|
field: field,
|
|
8506
|
-
isEdited: isEdited$
|
|
9224
|
+
isEdited: isEdited$6
|
|
8507
9225
|
}];
|
|
8508
9226
|
|
|
8509
9227
|
// todo: skipped to make the release without too much risk
|
|
@@ -8572,7 +9290,7 @@ function SpacerEntry(props) {
|
|
|
8572
9290
|
entries.push({
|
|
8573
9291
|
id: id + '-height',
|
|
8574
9292
|
component: SpacerHeight,
|
|
8575
|
-
isEdited: isEdited$
|
|
9293
|
+
isEdited: isEdited$7,
|
|
8576
9294
|
editField,
|
|
8577
9295
|
field
|
|
8578
9296
|
});
|
|
@@ -8623,7 +9341,7 @@ function NumberEntries(props) {
|
|
|
8623
9341
|
entries.push({
|
|
8624
9342
|
id: id + '-decimalDigits',
|
|
8625
9343
|
component: NumberDecimalDigits,
|
|
8626
|
-
isEdited: isEdited$
|
|
9344
|
+
isEdited: isEdited$7,
|
|
8627
9345
|
editField,
|
|
8628
9346
|
field
|
|
8629
9347
|
});
|
|
@@ -8727,7 +9445,7 @@ function NumberSerializationEntry(props) {
|
|
|
8727
9445
|
entries.push({
|
|
8728
9446
|
id: 'serialize-to-string',
|
|
8729
9447
|
component: SerializeToString,
|
|
8730
|
-
isEdited: isEdited$
|
|
9448
|
+
isEdited: isEdited$5,
|
|
8731
9449
|
editField,
|
|
8732
9450
|
field
|
|
8733
9451
|
});
|
|
@@ -8786,7 +9504,7 @@ function DateTimeEntry(props) {
|
|
|
8786
9504
|
entries.push({
|
|
8787
9505
|
id: 'use24h',
|
|
8788
9506
|
component: Use24h,
|
|
8789
|
-
isEdited: isEdited$
|
|
9507
|
+
isEdited: isEdited$5,
|
|
8790
9508
|
editField,
|
|
8791
9509
|
field
|
|
8792
9510
|
});
|
|
@@ -8899,7 +9617,7 @@ function DateTimeConstraintsEntry(props) {
|
|
|
8899
9617
|
entries.push({
|
|
8900
9618
|
id: id + '-disallowPassedDates',
|
|
8901
9619
|
component: DisallowPassedDates,
|
|
8902
|
-
isEdited: isEdited$
|
|
9620
|
+
isEdited: isEdited$5,
|
|
8903
9621
|
editField,
|
|
8904
9622
|
field
|
|
8905
9623
|
});
|
|
@@ -9000,50 +9718,6 @@ function TimeFormatSelect(props) {
|
|
|
9000
9718
|
});
|
|
9001
9719
|
}
|
|
9002
9720
|
|
|
9003
|
-
function simpleBoolEntryFactory(options) {
|
|
9004
|
-
const {
|
|
9005
|
-
id,
|
|
9006
|
-
label,
|
|
9007
|
-
description,
|
|
9008
|
-
path,
|
|
9009
|
-
props
|
|
9010
|
-
} = options;
|
|
9011
|
-
const {
|
|
9012
|
-
editField,
|
|
9013
|
-
field
|
|
9014
|
-
} = props;
|
|
9015
|
-
return {
|
|
9016
|
-
id,
|
|
9017
|
-
label,
|
|
9018
|
-
path,
|
|
9019
|
-
field,
|
|
9020
|
-
editField,
|
|
9021
|
-
description,
|
|
9022
|
-
component: SimpleBoolComponent,
|
|
9023
|
-
isEdited: isEdited$8
|
|
9024
|
-
};
|
|
9025
|
-
}
|
|
9026
|
-
const SimpleBoolComponent = props => {
|
|
9027
|
-
const {
|
|
9028
|
-
id,
|
|
9029
|
-
label,
|
|
9030
|
-
path,
|
|
9031
|
-
field,
|
|
9032
|
-
editField,
|
|
9033
|
-
description
|
|
9034
|
-
} = props;
|
|
9035
|
-
const getValue = () => minDash.get(field, path, '');
|
|
9036
|
-
const setValue = value => editField(field, path, value);
|
|
9037
|
-
return CheckboxEntry({
|
|
9038
|
-
element: field,
|
|
9039
|
-
getValue,
|
|
9040
|
-
id,
|
|
9041
|
-
label,
|
|
9042
|
-
setValue,
|
|
9043
|
-
description
|
|
9044
|
-
});
|
|
9045
|
-
};
|
|
9046
|
-
|
|
9047
9721
|
function SelectEntries(props) {
|
|
9048
9722
|
const {
|
|
9049
9723
|
field
|
|
@@ -9525,7 +10199,7 @@ function AdornerEntry(props) {
|
|
|
9525
10199
|
entries.push({
|
|
9526
10200
|
id: 'prefix-adorner',
|
|
9527
10201
|
component: PrefixAdorner,
|
|
9528
|
-
isEdited: isEdited$
|
|
10202
|
+
isEdited: isEdited$6,
|
|
9529
10203
|
editField,
|
|
9530
10204
|
field,
|
|
9531
10205
|
onChange,
|
|
@@ -9534,7 +10208,7 @@ function AdornerEntry(props) {
|
|
|
9534
10208
|
entries.push({
|
|
9535
10209
|
id: 'suffix-adorner',
|
|
9536
10210
|
component: SuffixAdorner,
|
|
9537
|
-
isEdited: isEdited$
|
|
10211
|
+
isEdited: isEdited$6,
|
|
9538
10212
|
editField,
|
|
9539
10213
|
field,
|
|
9540
10214
|
onChange,
|
|
@@ -9604,7 +10278,7 @@ function ReadonlyEntry(props) {
|
|
|
9604
10278
|
component: Readonly,
|
|
9605
10279
|
editField: editField,
|
|
9606
10280
|
field: field,
|
|
9607
|
-
isEdited: isEdited$
|
|
10281
|
+
isEdited: isEdited$6
|
|
9608
10282
|
});
|
|
9609
10283
|
}
|
|
9610
10284
|
return entries;
|
|
@@ -9649,7 +10323,7 @@ function ConditionEntry(props) {
|
|
|
9649
10323
|
component: Condition,
|
|
9650
10324
|
editField: editField,
|
|
9651
10325
|
field: field,
|
|
9652
|
-
isEdited: isEdited$
|
|
10326
|
+
isEdited: isEdited$6
|
|
9653
10327
|
}];
|
|
9654
10328
|
}
|
|
9655
10329
|
function Condition(props) {
|
|
@@ -9697,7 +10371,7 @@ function ValuesExpressionEntry(props) {
|
|
|
9697
10371
|
id: id + '-expression',
|
|
9698
10372
|
component: ValuesExpression,
|
|
9699
10373
|
label: 'Values expression',
|
|
9700
|
-
isEdited: isEdited$
|
|
10374
|
+
isEdited: isEdited$6,
|
|
9701
10375
|
editField,
|
|
9702
10376
|
field
|
|
9703
10377
|
}];
|
|
@@ -9749,6 +10423,12 @@ function GeneralGroup(field, editField, getService) {
|
|
|
9749
10423
|
}), ...KeyEntry({
|
|
9750
10424
|
field,
|
|
9751
10425
|
editField
|
|
10426
|
+
}), ...PathEntry({
|
|
10427
|
+
field,
|
|
10428
|
+
editField
|
|
10429
|
+
}), ...GroupEntries({
|
|
10430
|
+
field,
|
|
10431
|
+
editField
|
|
9752
10432
|
}), ...DefaultOptionEntry({
|
|
9753
10433
|
field,
|
|
9754
10434
|
editField
|
|
@@ -9863,7 +10543,7 @@ function ValidationGroup(field, editField) {
|
|
|
9863
10543
|
component: Required,
|
|
9864
10544
|
getValue,
|
|
9865
10545
|
field,
|
|
9866
|
-
isEdited: isEdited$
|
|
10546
|
+
isEdited: isEdited$5,
|
|
9867
10547
|
onChange
|
|
9868
10548
|
}];
|
|
9869
10549
|
if (type === 'textfield') {
|
|
@@ -9883,14 +10563,14 @@ function ValidationGroup(field, editField) {
|
|
|
9883
10563
|
component: MinLength,
|
|
9884
10564
|
getValue,
|
|
9885
10565
|
field,
|
|
9886
|
-
isEdited: isEdited$
|
|
10566
|
+
isEdited: isEdited$6,
|
|
9887
10567
|
onChange
|
|
9888
10568
|
}, {
|
|
9889
10569
|
id: 'maxLength',
|
|
9890
10570
|
component: MaxLength,
|
|
9891
10571
|
getValue,
|
|
9892
10572
|
field,
|
|
9893
|
-
isEdited: isEdited$
|
|
10573
|
+
isEdited: isEdited$6,
|
|
9894
10574
|
onChange
|
|
9895
10575
|
});
|
|
9896
10576
|
}
|
|
@@ -9910,14 +10590,14 @@ function ValidationGroup(field, editField) {
|
|
|
9910
10590
|
component: Min,
|
|
9911
10591
|
getValue,
|
|
9912
10592
|
field,
|
|
9913
|
-
isEdited: isEdited$
|
|
10593
|
+
isEdited: isEdited$6,
|
|
9914
10594
|
onChange
|
|
9915
10595
|
}, {
|
|
9916
10596
|
id: 'max',
|
|
9917
10597
|
component: Max,
|
|
9918
10598
|
getValue,
|
|
9919
10599
|
field,
|
|
9920
|
-
isEdited: isEdited$
|
|
10600
|
+
isEdited: isEdited$6,
|
|
9921
10601
|
onChange
|
|
9922
10602
|
});
|
|
9923
10603
|
}
|