@bpmn-io/form-js-editor 0.12.1 → 0.13.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/README.md +0 -3
- package/dist/assets/form-js-editor-base.css +486 -0
- package/dist/assets/form-js-editor.css +1162 -60
- package/dist/index.cjs +1258 -529
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +1260 -531
- package/dist/index.es.js.map +1 -1
- package/dist/types/FormEditor.d.ts +9 -0
- package/dist/types/core/FormFieldRegistry.d.ts +1 -1
- package/dist/types/core/FormLayoutValidator.d.ts +16 -0
- package/dist/types/core/FormLayouter.d.ts +1 -0
- package/dist/types/core/index.d.ts +8 -4
- package/dist/types/features/dragging/Dragging.d.ts +60 -0
- package/dist/types/features/dragging/index.d.ts +6 -0
- package/dist/types/features/editor-actions/index.d.ts +1 -1
- package/dist/types/features/expression-language/index.d.ts +8 -0
- package/dist/types/features/keyboard/index.d.ts +1 -1
- package/dist/types/features/modeling/FormLayoutUpdater.d.ts +13 -0
- package/dist/types/features/modeling/Modeling.d.ts +7 -7
- package/dist/types/features/modeling/behavior/index.d.ts +3 -3
- package/dist/types/features/modeling/cmd/Util.d.ts +1 -0
- package/dist/types/features/modeling/index.d.ts +3 -1
- package/dist/types/features/palette/index.d.ts +1 -1
- package/dist/types/features/properties-panel/entries/ColumnsEntry.d.ts +2 -1
- package/dist/types/features/properties-panel/entries/DefaultValueEntry.d.ts +1 -0
- package/dist/types/features/properties-panel/entries/InputKeyValuesSourceEntry.d.ts +1 -1
- package/dist/types/features/properties-panel/entries/SelectEntries.d.ts +1 -0
- package/dist/types/features/properties-panel/entries/factories/simpleBoolEntryFactory.d.ts +1 -0
- package/dist/types/features/properties-panel/groups/GeneralGroup.d.ts +1 -1
- package/dist/types/features/properties-panel/groups/LayoutGroup.d.ts +11 -0
- package/dist/types/features/properties-panel/groups/index.d.ts +1 -0
- package/dist/types/features/properties-panel/index.d.ts +1 -1
- package/dist/types/features/selection/index.d.ts +2 -2
- package/dist/types/import/Importer.d.ts +4 -2
- package/dist/types/import/index.d.ts +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/render/EditorFormFields.d.ts +1 -1
- package/dist/types/render/components/FieldDragPreview.d.ts +1 -0
- package/dist/types/render/components/editor-form-fields/EditorText.d.ts +1 -1
- package/dist/types/render/components/editor-form-fields/index.d.ts +1 -1
- package/dist/types/render/components/icons/index.d.ts +1 -1
- package/dist/types/render/hooks/index.d.ts +3 -0
- package/dist/types/render/hooks/useDebounce.d.ts +1 -0
- package/dist/types/render/hooks/usePrevious.d.ts +1 -0
- package/dist/types/render/index.d.ts +2 -2
- package/package.json +10 -8
- package/dist/assets/dragula.css +0 -22
- package/dist/assets/properties-panel.css +0 -1016
package/dist/index.es.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { FormFieldRegistry as FormFieldRegistry$1, clone, iconsByType,
|
|
1
|
+
import { FormFieldRegistry as FormFieldRegistry$1, clone, iconsByType, Text as Text$1, FormFields, formFields, FormContext, FormRenderContext, FormComponent, FormLayouter, getSchemaVariables, DATETIME_SUBTYPES, DATE_LABEL_PATH, TIME_LABEL_PATH, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES_LABELS, TIME_SERIALISING_FORMAT_PATH, TIME_SERIALISING_FORMATS, TIME_INTERVAL_PATH, TIME_USE24H_PATH, DATE_DISALLOW_PAST_PATH, TIME_SERIALISINGFORMAT_LABELS, getValuesSource, VALUES_SOURCES, VALUES_SOURCES_DEFAULTS, VALUES_SOURCES_PATHS, VALUES_SOURCES_LABELS, FeelExpressionLanguage, FeelersTemplating, createFormContainer, createInjector, MarkdownModule, schemaVersion } from '@bpmn-io/form-js-viewer';
|
|
2
2
|
export { schemaVersion } from '@bpmn-io/form-js-viewer';
|
|
3
3
|
import Ids from 'ids';
|
|
4
4
|
import { isArray, isFunction, isNumber, bind, assign, debounce, forEach, get, isObject, uniqueBy, sortBy, find, set as set$1, isUndefined, without, has, isString } from 'min-dash';
|
|
5
5
|
import classnames from 'classnames';
|
|
6
|
-
import { jsx, jsxs } from 'preact/jsx-runtime';
|
|
7
|
-
import { createContext, render, createElement } from 'preact';
|
|
6
|
+
import { jsx, jsxs, Fragment } from 'preact/jsx-runtime';
|
|
8
7
|
import { useContext, useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect } from 'preact/hooks';
|
|
9
|
-
import
|
|
8
|
+
import { createContext, render, createElement } from 'preact';
|
|
10
9
|
import React, { forwardRef } from 'preact/compat';
|
|
10
|
+
import dragula from 'dragula';
|
|
11
11
|
import { classes, closest, event, matches, domify, query } from 'min-dom';
|
|
12
12
|
import { mutate } from 'array-move';
|
|
13
|
+
import { FeelersEditor } from 'feelers';
|
|
13
14
|
import FeelEditor from '@bpmn-io/feel-editor';
|
|
14
15
|
import Big from 'big.js';
|
|
15
16
|
|
|
@@ -569,19 +570,78 @@ class FormFieldRegistry extends FormFieldRegistry$1 {
|
|
|
569
570
|
}
|
|
570
571
|
}
|
|
571
572
|
|
|
573
|
+
class FormLayoutValidator {
|
|
574
|
+
/**
|
|
575
|
+
* @constructor
|
|
576
|
+
*
|
|
577
|
+
* @param { import('./FormLayouter').default } formLayouter
|
|
578
|
+
* @param { import('./FormFieldRegistry').default } formFieldRegistry
|
|
579
|
+
*/
|
|
580
|
+
constructor(formLayouter, formFieldRegistry) {
|
|
581
|
+
this._formLayouter = formLayouter;
|
|
582
|
+
this._formFieldRegistry = formFieldRegistry;
|
|
583
|
+
}
|
|
584
|
+
validateField(field = {}, columns, row) {
|
|
585
|
+
// allow empty (auto columns)
|
|
586
|
+
if (columns) {
|
|
587
|
+
// allow minimum 2 cols
|
|
588
|
+
if (columns < 2) {
|
|
589
|
+
return 'Minimum 2 columns are allowed';
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// allow maximum 16 cols
|
|
593
|
+
if (columns > 16) {
|
|
594
|
+
return 'Maximum 16 columns are allowed';
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
if (!row) {
|
|
598
|
+
row = this._formLayouter.getRowForField(field);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// calculate columns with and without updated field
|
|
602
|
+
let sumColumns = parseInt(columns) || 0;
|
|
603
|
+
let sumFields = 1;
|
|
604
|
+
let sumAutoCols = columns ? 0 : 1;
|
|
605
|
+
row.components.forEach(id => {
|
|
606
|
+
if (field.id === id) {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
const component = this._formFieldRegistry.get(id);
|
|
610
|
+
const cols = (component.layout || {}).columns;
|
|
611
|
+
if (!cols) {
|
|
612
|
+
sumAutoCols++;
|
|
613
|
+
}
|
|
614
|
+
sumColumns += parseInt(cols) || 0;
|
|
615
|
+
sumFields++;
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
// do not allow overflows
|
|
619
|
+
if (sumColumns > 16 || sumColumns === 16 && sumAutoCols > 0 || columns === 16 && sumFields > 1) {
|
|
620
|
+
return 'New value exceeds the maximum of 16 columns per row';
|
|
621
|
+
}
|
|
622
|
+
if (sumFields > 4) {
|
|
623
|
+
return 'Maximum 4 fields per row are allowed';
|
|
624
|
+
}
|
|
625
|
+
return null;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
FormLayoutValidator.$inject = ['formLayouter', 'formFieldRegistry'];
|
|
629
|
+
|
|
572
630
|
class Importer {
|
|
573
631
|
/**
|
|
574
632
|
* @constructor
|
|
575
633
|
* @param { import('../core/FormFieldRegistry').default } formFieldRegistry
|
|
576
634
|
* @param { import('../core/FieldFactory').default } fieldFactory
|
|
635
|
+
* @param { import('../core/FormLayouter').default } formLayouter
|
|
577
636
|
*/
|
|
578
|
-
constructor(formFieldRegistry, fieldFactory) {
|
|
637
|
+
constructor(formFieldRegistry, fieldFactory, formLayouter) {
|
|
579
638
|
this._formFieldRegistry = formFieldRegistry;
|
|
580
639
|
this._fieldFactory = fieldFactory;
|
|
640
|
+
this._formLayouter = formLayouter;
|
|
581
641
|
}
|
|
582
642
|
|
|
583
643
|
/**
|
|
584
|
-
* Import schema creating fields, attaching additional
|
|
644
|
+
* Import schema creating rows, fields, attaching additional
|
|
585
645
|
* information to each field and adding fields to the
|
|
586
646
|
* field registry.
|
|
587
647
|
*
|
|
@@ -601,6 +661,7 @@ class Importer {
|
|
|
601
661
|
const warnings = [];
|
|
602
662
|
try {
|
|
603
663
|
const importedSchema = this.importFormField(clone(schema));
|
|
664
|
+
this._formLayouter.calculateLayout(clone(importedSchema));
|
|
604
665
|
return {
|
|
605
666
|
schema: importedSchema,
|
|
606
667
|
warnings
|
|
@@ -665,7 +726,7 @@ class Importer {
|
|
|
665
726
|
});
|
|
666
727
|
}
|
|
667
728
|
}
|
|
668
|
-
Importer.$inject = ['formFieldRegistry', 'fieldFactory'];
|
|
729
|
+
Importer.$inject = ['formFieldRegistry', 'fieldFactory', 'formLayouter'];
|
|
669
730
|
|
|
670
731
|
var importModule = {
|
|
671
732
|
importer: ['type', Importer]
|
|
@@ -682,11 +743,35 @@ function editorFormFieldClasses(type, {
|
|
|
682
743
|
});
|
|
683
744
|
}
|
|
684
745
|
|
|
685
|
-
|
|
746
|
+
const DragAndDropContext = createContext({
|
|
747
|
+
drake: null
|
|
748
|
+
});
|
|
749
|
+
var DragAndDropContext$1 = DragAndDropContext;
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* @param {string} type
|
|
753
|
+
* @param {boolean} [strict]
|
|
754
|
+
*
|
|
755
|
+
* @returns {any}
|
|
756
|
+
*/
|
|
757
|
+
function getService$1(type, strict) {}
|
|
758
|
+
const FormEditorContext = createContext({
|
|
759
|
+
getService: getService$1
|
|
760
|
+
});
|
|
761
|
+
var FormEditorContext$1 = FormEditorContext;
|
|
762
|
+
|
|
763
|
+
function useService$1 (type, strict) {
|
|
764
|
+
const {
|
|
765
|
+
getService
|
|
766
|
+
} = useContext(FormEditorContext$1);
|
|
767
|
+
return getService(type, strict);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
function _extends$3() { _extends$3 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3.apply(this, arguments); }
|
|
686
771
|
var CloseIcon = (({
|
|
687
772
|
styles = {},
|
|
688
773
|
...props
|
|
689
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
774
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$3({
|
|
690
775
|
width: "16",
|
|
691
776
|
height: "16",
|
|
692
777
|
fill: "currentColor",
|
|
@@ -697,6 +782,23 @@ var CloseIcon = (({
|
|
|
697
782
|
d: "M12 4.7l-.7-.7L8 7.3 4.7 4l-.7.7L7.3 8 4 11.3l.7.7L8 8.7l3.3 3.3.7-.7L8.7 8 12 4.7z"
|
|
698
783
|
})));
|
|
699
784
|
|
|
785
|
+
function _extends$2() { _extends$2 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$2.apply(this, arguments); }
|
|
786
|
+
var DraggableIcon = (({
|
|
787
|
+
styles = {},
|
|
788
|
+
...props
|
|
789
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$2({
|
|
790
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
791
|
+
width: "16",
|
|
792
|
+
height: "16",
|
|
793
|
+
fill: "currentcolor",
|
|
794
|
+
viewBox: "0 0 32 32"
|
|
795
|
+
}, props), /*#__PURE__*/React.createElement("path", {
|
|
796
|
+
d: "M10 6h4v4h-4zm8 0h4v4h-4zm-8 8h4v4h-4zm8 0h4v4h-4zm-8 8h4v4h-4zm8 0h4v4h-4z"
|
|
797
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
798
|
+
d: "M0 0h32v32H0z",
|
|
799
|
+
fill: "none"
|
|
800
|
+
})));
|
|
801
|
+
|
|
700
802
|
function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
|
|
701
803
|
var SearchIcon = (({
|
|
702
804
|
styles = {},
|
|
@@ -717,6 +819,8 @@ function EditorText(props) {
|
|
|
717
819
|
text = ''
|
|
718
820
|
} = props.field;
|
|
719
821
|
const Icon = iconsByType('text');
|
|
822
|
+
const templating = useService$1('templating');
|
|
823
|
+
const expressionLanguage = useService$1('expressionLanguage');
|
|
720
824
|
if (!text) {
|
|
721
825
|
return jsx("div", {
|
|
722
826
|
class: editorFormFieldClasses(type),
|
|
@@ -728,7 +832,7 @@ function EditorText(props) {
|
|
|
728
832
|
})
|
|
729
833
|
});
|
|
730
834
|
}
|
|
731
|
-
if (isExpression(text)) {
|
|
835
|
+
if (expressionLanguage.isExpression(text)) {
|
|
732
836
|
return jsx("div", {
|
|
733
837
|
class: editorFormFieldClasses(type),
|
|
734
838
|
children: jsxs("div", {
|
|
@@ -739,6 +843,17 @@ function EditorText(props) {
|
|
|
739
843
|
})
|
|
740
844
|
});
|
|
741
845
|
}
|
|
846
|
+
if (templating.isTemplate(text)) {
|
|
847
|
+
return jsx("div", {
|
|
848
|
+
class: editorFormFieldClasses(type),
|
|
849
|
+
children: jsxs("div", {
|
|
850
|
+
class: "fjs-form-field-placeholder",
|
|
851
|
+
children: [jsx(Icon, {
|
|
852
|
+
viewBox: "0 0 54 54"
|
|
853
|
+
}), "Text view is templated"]
|
|
854
|
+
})
|
|
855
|
+
});
|
|
856
|
+
}
|
|
742
857
|
return jsx(Text$1, {
|
|
743
858
|
...props,
|
|
744
859
|
disableLinks: true
|
|
@@ -759,30 +874,6 @@ class EditorFormFields extends FormFields {
|
|
|
759
874
|
}
|
|
760
875
|
}
|
|
761
876
|
|
|
762
|
-
const DragAndDropContext = createContext({
|
|
763
|
-
drake: null
|
|
764
|
-
});
|
|
765
|
-
var DragAndDropContext$1 = DragAndDropContext;
|
|
766
|
-
|
|
767
|
-
/**
|
|
768
|
-
* @param {string} type
|
|
769
|
-
* @param {boolean} [strict]
|
|
770
|
-
*
|
|
771
|
-
* @returns {any}
|
|
772
|
-
*/
|
|
773
|
-
function getService$1(type, strict) {}
|
|
774
|
-
const FormEditorContext = createContext({
|
|
775
|
-
getService: getService$1
|
|
776
|
-
});
|
|
777
|
-
var FormEditorContext$1 = FormEditorContext;
|
|
778
|
-
|
|
779
|
-
function useService$1 (type, strict) {
|
|
780
|
-
const {
|
|
781
|
-
getService
|
|
782
|
-
} = useContext(FormEditorContext$1);
|
|
783
|
-
return getService(type, strict);
|
|
784
|
-
}
|
|
785
|
-
|
|
786
877
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
787
878
|
var ListDeleteIcon = (({
|
|
788
879
|
styles = {},
|
|
@@ -886,7 +977,7 @@ function Palette(props) {
|
|
|
886
977
|
return jsxs("div", {
|
|
887
978
|
class: "fjs-palette-field fjs-drag-copy fjs-no-drop",
|
|
888
979
|
"data-field-type": type,
|
|
889
|
-
title: `Create
|
|
980
|
+
title: `Create ${getIndefiniteArticle(type)} ${label} element`,
|
|
890
981
|
children: [Icon ? jsx(Icon, {
|
|
891
982
|
class: "fjs-palette-field-icon",
|
|
892
983
|
width: "36",
|
|
@@ -925,6 +1016,12 @@ function groupEntries(entries) {
|
|
|
925
1016
|
});
|
|
926
1017
|
return groups.filter(g => g.entries.length);
|
|
927
1018
|
}
|
|
1019
|
+
function getIndefiniteArticle(type) {
|
|
1020
|
+
if (['image'].includes(type)) {
|
|
1021
|
+
return 'an';
|
|
1022
|
+
}
|
|
1023
|
+
return 'a';
|
|
1024
|
+
}
|
|
928
1025
|
|
|
929
1026
|
const CURSOR_CLS_PATTERN = /^fjs-cursor-.*$/;
|
|
930
1027
|
function set(mode) {
|
|
@@ -938,6 +1035,307 @@ function unset() {
|
|
|
938
1035
|
set(null);
|
|
939
1036
|
}
|
|
940
1037
|
|
|
1038
|
+
const DRAG_CONTAINER_CLS = 'fjs-drag-container';
|
|
1039
|
+
const DROP_CONTAINER_VERTICAL_CLS = 'fjs-drop-container-vertical';
|
|
1040
|
+
const DROP_CONTAINER_HORIZONTAL_CLS = 'fjs-drop-container-horizontal';
|
|
1041
|
+
const DRAG_MOVE_CLS = 'fjs-drag-move';
|
|
1042
|
+
const DRAG_ROW_MOVE_CLS = 'fjs-drag-row-move';
|
|
1043
|
+
const DRAG_COPY_CLS = 'fjs-drag-copy';
|
|
1044
|
+
const DRAG_NO_DROP_CLS = 'fjs-no-drop';
|
|
1045
|
+
const DRAG_NO_MOVE_CLS = 'fjs-no-move';
|
|
1046
|
+
const ERROR_DROP_CLS = 'fjs-error-drop';
|
|
1047
|
+
|
|
1048
|
+
/**
|
|
1049
|
+
* @typedef { { id: String, components: Array<any> } } FormRow
|
|
1050
|
+
*/
|
|
1051
|
+
|
|
1052
|
+
class Dragging {
|
|
1053
|
+
/**
|
|
1054
|
+
* @constructor
|
|
1055
|
+
*
|
|
1056
|
+
* @param { import('../../core/FormFieldRegistry').default } formFieldRegistry
|
|
1057
|
+
* @param { import('../../core/FormLayouter').default } formLayouter
|
|
1058
|
+
* @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
|
|
1059
|
+
* @param { import('../../core/EventBus').default } eventBus
|
|
1060
|
+
* @param { import('../modeling/Modeling').default } modeling
|
|
1061
|
+
*/
|
|
1062
|
+
constructor(formFieldRegistry, formLayouter, formLayoutValidator, eventBus, modeling) {
|
|
1063
|
+
this._formFieldRegistry = formFieldRegistry;
|
|
1064
|
+
this._formLayouter = formLayouter;
|
|
1065
|
+
this._formLayoutValidator = formLayoutValidator;
|
|
1066
|
+
this._eventBus = eventBus;
|
|
1067
|
+
this._modeling = modeling;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
/**
|
|
1071
|
+
* Calculcates position in form schema given the dropped place.
|
|
1072
|
+
*
|
|
1073
|
+
* @param { FormRow } targetRow
|
|
1074
|
+
* @param { any } targetFormField
|
|
1075
|
+
* @param { HTMLElement } sibling
|
|
1076
|
+
* @returns { number }
|
|
1077
|
+
*/
|
|
1078
|
+
getTargetIndex(targetRow, targetFormField, sibling) {
|
|
1079
|
+
/** @type HTMLElement */
|
|
1080
|
+
const siblingFormFieldNode = sibling && sibling.querySelector('.fjs-element');
|
|
1081
|
+
const siblingFormField = siblingFormFieldNode && this._formFieldRegistry.get(siblingFormFieldNode.dataset.id);
|
|
1082
|
+
|
|
1083
|
+
// (1) dropped before existing field => place before
|
|
1084
|
+
if (siblingFormField) {
|
|
1085
|
+
return getFormFieldIndex$1(targetFormField, siblingFormField);
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
// (2) dropped in row => place at the end of row (after last field in row)
|
|
1089
|
+
if (targetRow) {
|
|
1090
|
+
return getFormFieldIndex$1(targetFormField, this._formFieldRegistry.get(targetRow.components[targetRow.components.length - 1])) + 1;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
// (3) dropped as last item
|
|
1094
|
+
return targetFormField.components.length;
|
|
1095
|
+
}
|
|
1096
|
+
validateDrop(element, target) {
|
|
1097
|
+
const formFieldNode = element.querySelector('.fjs-element');
|
|
1098
|
+
const targetRow = this._formLayouter.getRow(target.dataset.rowId);
|
|
1099
|
+
let columns;
|
|
1100
|
+
let formField;
|
|
1101
|
+
if (formFieldNode) {
|
|
1102
|
+
formField = this._formFieldRegistry.get(formFieldNode.dataset.id);
|
|
1103
|
+
columns = (formField.layout || {}).columns;
|
|
1104
|
+
}
|
|
1105
|
+
return this._formLayoutValidator.validateField(formField, columns, targetRow);
|
|
1106
|
+
}
|
|
1107
|
+
moveField(element, source, targetRow, targetFormField, targetIndex) {
|
|
1108
|
+
const formFieldNode = element.querySelector('.fjs-element');
|
|
1109
|
+
const formField = this._formFieldRegistry.get(formFieldNode.dataset.id);
|
|
1110
|
+
const sourceParent = getFormParent(source);
|
|
1111
|
+
const sourceFormField = this._formFieldRegistry.get(sourceParent.dataset.id);
|
|
1112
|
+
const sourceIndex = getFormFieldIndex$1(sourceFormField, formField);
|
|
1113
|
+
const sourceRow = this._formLayouter.getRowForField(formField);
|
|
1114
|
+
this._modeling.moveFormField(formField, sourceFormField, targetFormField, sourceIndex, targetIndex, sourceRow, targetRow);
|
|
1115
|
+
}
|
|
1116
|
+
createNewField(element, targetRow, targetFormField, targetIndex) {
|
|
1117
|
+
const type = element.dataset.fieldType;
|
|
1118
|
+
let attrs = {
|
|
1119
|
+
type
|
|
1120
|
+
};
|
|
1121
|
+
attrs = {
|
|
1122
|
+
...attrs,
|
|
1123
|
+
layout: {
|
|
1124
|
+
row: targetRow ? targetRow.id : this._formLayouter.nextRowId(),
|
|
1125
|
+
// enable auto columns
|
|
1126
|
+
columns: null
|
|
1127
|
+
}
|
|
1128
|
+
};
|
|
1129
|
+
this._modeling.addFormField(attrs, targetFormField, targetIndex);
|
|
1130
|
+
}
|
|
1131
|
+
handleRowDrop(el, target, source, sibling) {
|
|
1132
|
+
const targetFormField = this._formFieldRegistry.get(target.dataset.id);
|
|
1133
|
+
const rowNode = el.querySelector('.fjs-layout-row');
|
|
1134
|
+
const row = this._formLayouter.getRow(rowNode.dataset.rowId);
|
|
1135
|
+
|
|
1136
|
+
// move each field in the row before first field of sibling row
|
|
1137
|
+
row.components.forEach((id, index) => {
|
|
1138
|
+
const formField = this._formFieldRegistry.get(id);
|
|
1139
|
+
const sourceParent = getFormParent(source);
|
|
1140
|
+
const sourceFormField = this._formFieldRegistry.get(sourceParent.dataset.id);
|
|
1141
|
+
const siblingRowNode = sibling && sibling.querySelector('.fjs-layout-row');
|
|
1142
|
+
const siblingRow = siblingRowNode && this._formLayouter.getRow(siblingRowNode.dataset.rowId);
|
|
1143
|
+
const siblingFormField = sibling && this._formFieldRegistry.get(siblingRow.components[0]);
|
|
1144
|
+
const sourceIndex = getFormFieldIndex$1(sourceFormField, formField);
|
|
1145
|
+
const targetIndex = (siblingRowNode ? getFormFieldIndex$1(targetFormField, siblingFormField) : targetFormField.components.length) + index;
|
|
1146
|
+
this._modeling.moveFormField(formField, sourceFormField, targetFormField, sourceIndex, targetIndex, row, row);
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
1149
|
+
handleElementDrop(el, target, source, sibling, drake) {
|
|
1150
|
+
// (1) detect drop target
|
|
1151
|
+
const targetFormField = this._formFieldRegistry.get(getFormParent(target).dataset.id);
|
|
1152
|
+
let targetRow;
|
|
1153
|
+
|
|
1154
|
+
// (2.1) dropped in existing row
|
|
1155
|
+
if (isRow(target)) {
|
|
1156
|
+
unsetDropNotAllowed(target);
|
|
1157
|
+
targetRow = this._formLayouter.getRow(target.dataset.rowId);
|
|
1158
|
+
|
|
1159
|
+
// validate whether drop is allowed
|
|
1160
|
+
const validationError = this.validateDrop(el, target);
|
|
1161
|
+
if (validationError) {
|
|
1162
|
+
return drake.cancel(true);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
drake.remove();
|
|
1166
|
+
|
|
1167
|
+
// (3) detect position to drop field in schema order
|
|
1168
|
+
const targetIndex = this.getTargetIndex(targetRow, targetFormField, sibling);
|
|
1169
|
+
|
|
1170
|
+
// (4) create new field or move existing
|
|
1171
|
+
if (isPalette(source)) {
|
|
1172
|
+
this.createNewField(el, targetRow, targetFormField, targetIndex);
|
|
1173
|
+
} else {
|
|
1174
|
+
this.moveField(el, source, targetRow, targetFormField, targetIndex);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
/**
|
|
1179
|
+
* @param { { container: Array<string>, direction: string, mirrorContainer: string } } options
|
|
1180
|
+
*/
|
|
1181
|
+
createDragulaInstance(options) {
|
|
1182
|
+
const {
|
|
1183
|
+
container,
|
|
1184
|
+
direction,
|
|
1185
|
+
mirrorContainer
|
|
1186
|
+
} = options || {};
|
|
1187
|
+
const dragulaInstance = dragula({
|
|
1188
|
+
direction,
|
|
1189
|
+
mirrorContainer,
|
|
1190
|
+
isContainer(el) {
|
|
1191
|
+
return container.some(cls => el.classList.contains(cls));
|
|
1192
|
+
},
|
|
1193
|
+
moves(el, source, handle) {
|
|
1194
|
+
return !handle.classList.contains(DRAG_NO_MOVE_CLS) && (el.classList.contains(DRAG_MOVE_CLS) || el.classList.contains(DRAG_COPY_CLS) || el.classList.contains(DRAG_ROW_MOVE_CLS));
|
|
1195
|
+
},
|
|
1196
|
+
copy(el) {
|
|
1197
|
+
return el.classList.contains(DRAG_COPY_CLS);
|
|
1198
|
+
},
|
|
1199
|
+
accepts: (el, target) => {
|
|
1200
|
+
unsetDropNotAllowed(target);
|
|
1201
|
+
|
|
1202
|
+
// allow dropping rows only between rows
|
|
1203
|
+
if (el.classList.contains(DRAG_ROW_MOVE_CLS)) {
|
|
1204
|
+
return !target.classList.contains(DROP_CONTAINER_HORIZONTAL_CLS);
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
// validate field drop in row
|
|
1208
|
+
if (isRow(target)) {
|
|
1209
|
+
const validationError = this.validateDrop(el, target);
|
|
1210
|
+
if (validationError) {
|
|
1211
|
+
// set error feedback to row
|
|
1212
|
+
setDropNotAllowed(target);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
return !target.classList.contains(DRAG_NO_DROP_CLS);
|
|
1216
|
+
},
|
|
1217
|
+
slideFactorX: 10,
|
|
1218
|
+
slideFactorY: 5
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1221
|
+
// bind life cycle events
|
|
1222
|
+
dragulaInstance.on('drag', (element, source) => {
|
|
1223
|
+
this.emit('drag.start', {
|
|
1224
|
+
element,
|
|
1225
|
+
source
|
|
1226
|
+
});
|
|
1227
|
+
});
|
|
1228
|
+
dragulaInstance.on('dragend', element => {
|
|
1229
|
+
this.emit('drag.end', {
|
|
1230
|
+
element
|
|
1231
|
+
});
|
|
1232
|
+
});
|
|
1233
|
+
dragulaInstance.on('drop', (element, target, source, sibling) => {
|
|
1234
|
+
this.emit('drag.drop', {
|
|
1235
|
+
element,
|
|
1236
|
+
target,
|
|
1237
|
+
source,
|
|
1238
|
+
sibling
|
|
1239
|
+
});
|
|
1240
|
+
});
|
|
1241
|
+
dragulaInstance.on('over', (element, container, source) => {
|
|
1242
|
+
this.emit('drag.hover', {
|
|
1243
|
+
element,
|
|
1244
|
+
container,
|
|
1245
|
+
source
|
|
1246
|
+
});
|
|
1247
|
+
});
|
|
1248
|
+
dragulaInstance.on('out', (element, container, source) => {
|
|
1249
|
+
this.emit('drag.out', {
|
|
1250
|
+
element,
|
|
1251
|
+
container,
|
|
1252
|
+
source
|
|
1253
|
+
});
|
|
1254
|
+
});
|
|
1255
|
+
dragulaInstance.on('cancel', (element, container, source) => {
|
|
1256
|
+
this.emit('drag.cancel', {
|
|
1257
|
+
element,
|
|
1258
|
+
container,
|
|
1259
|
+
source
|
|
1260
|
+
});
|
|
1261
|
+
});
|
|
1262
|
+
dragulaInstance.on('drop', (el, target, source, sibling) => {
|
|
1263
|
+
if (!target) {
|
|
1264
|
+
dragulaInstance.remove();
|
|
1265
|
+
return;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
// (1) handle row drop
|
|
1269
|
+
if (isDragRow(el)) {
|
|
1270
|
+
this.handleRowDrop(el, target, source, sibling);
|
|
1271
|
+
} else {
|
|
1272
|
+
// (2) handle form field drop
|
|
1273
|
+
this.handleElementDrop(el, target, source, sibling, dragulaInstance);
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
1276
|
+
this.emit('dragula.created', dragulaInstance);
|
|
1277
|
+
return dragulaInstance;
|
|
1278
|
+
}
|
|
1279
|
+
emit(event, context) {
|
|
1280
|
+
this._eventBus.fire(event, context);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
Dragging.$inject = ['formFieldRegistry', 'formLayouter', 'formLayoutValidator', 'eventBus', 'modeling'];
|
|
1284
|
+
|
|
1285
|
+
// helper //////////
|
|
1286
|
+
|
|
1287
|
+
function getFormFieldIndex$1(parent, formField) {
|
|
1288
|
+
let fieldFormIndex = parent.components.length;
|
|
1289
|
+
parent.components.forEach(({
|
|
1290
|
+
id
|
|
1291
|
+
}, index) => {
|
|
1292
|
+
if (id === formField.id) {
|
|
1293
|
+
fieldFormIndex = index;
|
|
1294
|
+
}
|
|
1295
|
+
});
|
|
1296
|
+
return fieldFormIndex;
|
|
1297
|
+
}
|
|
1298
|
+
function isRow(node) {
|
|
1299
|
+
return node.classList.contains('fjs-layout-row');
|
|
1300
|
+
}
|
|
1301
|
+
function isDragRow(node) {
|
|
1302
|
+
return node.classList.contains(DRAG_ROW_MOVE_CLS);
|
|
1303
|
+
}
|
|
1304
|
+
function isPalette(node) {
|
|
1305
|
+
return node.classList.contains('fjs-palette-fields');
|
|
1306
|
+
}
|
|
1307
|
+
function getFormParent(node) {
|
|
1308
|
+
return node.closest('.fjs-element');
|
|
1309
|
+
}
|
|
1310
|
+
function setDropNotAllowed(node) {
|
|
1311
|
+
node.classList.add(ERROR_DROP_CLS);
|
|
1312
|
+
set('not-allowed');
|
|
1313
|
+
}
|
|
1314
|
+
function unsetDropNotAllowed(node) {
|
|
1315
|
+
node.classList.remove(ERROR_DROP_CLS);
|
|
1316
|
+
set('grabbing');
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
function FieldDragPreview(props) {
|
|
1320
|
+
const {
|
|
1321
|
+
class: className,
|
|
1322
|
+
Icon,
|
|
1323
|
+
label
|
|
1324
|
+
} = props;
|
|
1325
|
+
return jsxs("div", {
|
|
1326
|
+
class: classnames('fjs-field-preview', className),
|
|
1327
|
+
children: [jsx(Icon, {
|
|
1328
|
+
class: "fjs-field-preview-icon",
|
|
1329
|
+
width: "36",
|
|
1330
|
+
height: "36",
|
|
1331
|
+
viewBox: "0 0 54 54"
|
|
1332
|
+
}), jsx("span", {
|
|
1333
|
+
class: "fjs-field-preview-text",
|
|
1334
|
+
children: label
|
|
1335
|
+
})]
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1338
|
+
|
|
941
1339
|
function ContextPad(props) {
|
|
942
1340
|
if (!props.children) {
|
|
943
1341
|
return null;
|
|
@@ -984,7 +1382,7 @@ function Element(props) {
|
|
|
984
1382
|
event.stopPropagation();
|
|
985
1383
|
selection.toggle(field);
|
|
986
1384
|
}
|
|
987
|
-
const classes = [
|
|
1385
|
+
const classes = [];
|
|
988
1386
|
if (props.class) {
|
|
989
1387
|
classes.push(...props.class.split(' '));
|
|
990
1388
|
}
|
|
@@ -1003,7 +1401,9 @@ function Element(props) {
|
|
|
1003
1401
|
"data-field-type": type,
|
|
1004
1402
|
onClick: onClick,
|
|
1005
1403
|
ref: ref,
|
|
1006
|
-
children: [jsx(
|
|
1404
|
+
children: [jsx(DebugColumns, {
|
|
1405
|
+
field: field
|
|
1406
|
+
}), jsx(ContextPad, {
|
|
1007
1407
|
children: selection.isSelected(field) && field.type !== 'default' ? jsx("button", {
|
|
1008
1408
|
class: "fjs-context-pad-item",
|
|
1009
1409
|
onClick: onRemove,
|
|
@@ -1012,6 +1412,20 @@ function Element(props) {
|
|
|
1012
1412
|
}), props.children]
|
|
1013
1413
|
});
|
|
1014
1414
|
}
|
|
1415
|
+
function DebugColumns(props) {
|
|
1416
|
+
const {
|
|
1417
|
+
field
|
|
1418
|
+
} = props;
|
|
1419
|
+
const debugColumnsConfig = useService$1('config.debugColumns');
|
|
1420
|
+
if (!debugColumnsConfig || field.type == 'default') {
|
|
1421
|
+
return null;
|
|
1422
|
+
}
|
|
1423
|
+
return jsx("div", {
|
|
1424
|
+
style: "width: fit-content; padding: 2px 6px; height: 16px; background: var(--color-blue-205-100-95); display: flex; justify-content: center; align-items: center; position: absolute; bottom: -2px; z-index: 2; font-size: 10px; right: 3px;",
|
|
1425
|
+
class: "fjs-debug-columns",
|
|
1426
|
+
children: (field.layout || {}).columns || 'auto'
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1015
1429
|
function Children(props) {
|
|
1016
1430
|
const {
|
|
1017
1431
|
field
|
|
@@ -1019,7 +1433,7 @@ function Children(props) {
|
|
|
1019
1433
|
const {
|
|
1020
1434
|
id
|
|
1021
1435
|
} = field;
|
|
1022
|
-
const classes = ['fjs-children',
|
|
1436
|
+
const classes = ['fjs-children', DROP_CONTAINER_VERTICAL_CLS];
|
|
1023
1437
|
if (props.class) {
|
|
1024
1438
|
classes.push(...props.class.split(' '));
|
|
1025
1439
|
}
|
|
@@ -1029,12 +1443,51 @@ function Children(props) {
|
|
|
1029
1443
|
children: props.children
|
|
1030
1444
|
});
|
|
1031
1445
|
}
|
|
1446
|
+
function Row(props) {
|
|
1447
|
+
const {
|
|
1448
|
+
row
|
|
1449
|
+
} = props;
|
|
1450
|
+
const {
|
|
1451
|
+
id
|
|
1452
|
+
} = row;
|
|
1453
|
+
const classes = [DROP_CONTAINER_HORIZONTAL_CLS];
|
|
1454
|
+
if (props.class) {
|
|
1455
|
+
classes.push(...props.class.split(' '));
|
|
1456
|
+
}
|
|
1457
|
+
return jsxs("div", {
|
|
1458
|
+
class: classnames(DRAG_ROW_MOVE_CLS),
|
|
1459
|
+
children: [jsx("span", {
|
|
1460
|
+
class: "fjs-row-dragger",
|
|
1461
|
+
children: jsx(DraggableIcon, {})
|
|
1462
|
+
}), jsx("div", {
|
|
1463
|
+
class: classes.join(' '),
|
|
1464
|
+
"data-row-id": id,
|
|
1465
|
+
children: props.children
|
|
1466
|
+
})]
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1469
|
+
function Column(props) {
|
|
1470
|
+
const {
|
|
1471
|
+
field
|
|
1472
|
+
} = props;
|
|
1473
|
+
const classes = [DRAG_MOVE_CLS];
|
|
1474
|
+
if (field.type === 'default') {
|
|
1475
|
+
return props.children;
|
|
1476
|
+
}
|
|
1477
|
+
if (props.class) {
|
|
1478
|
+
classes.push(...props.class.split(' '));
|
|
1479
|
+
}
|
|
1480
|
+
return jsx("div", {
|
|
1481
|
+
"data-field-type": field.type,
|
|
1482
|
+
class: classes.join(' '),
|
|
1483
|
+
children: props.children
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1032
1486
|
function FormEditor$1(props) {
|
|
1033
|
-
const
|
|
1487
|
+
const dragging = useService$1('dragging'),
|
|
1488
|
+
eventBus = useService$1('eventBus'),
|
|
1034
1489
|
formEditor = useService$1('formEditor'),
|
|
1035
|
-
formFieldRegistry = useService$1('formFieldRegistry'),
|
|
1036
1490
|
injector = useService$1('injector'),
|
|
1037
|
-
modeling = useService$1('modeling'),
|
|
1038
1491
|
selection = useService$1('selection'),
|
|
1039
1492
|
palette = useService$1('palette'),
|
|
1040
1493
|
paletteConfig = useService$1('config.palette'),
|
|
@@ -1043,6 +1496,7 @@ function FormEditor$1(props) {
|
|
|
1043
1496
|
const {
|
|
1044
1497
|
schema
|
|
1045
1498
|
} = formEditor._getState();
|
|
1499
|
+
const formContainerRef = useRef(null);
|
|
1046
1500
|
const paletteRef = useRef(null);
|
|
1047
1501
|
const propertiesPanelRef = useRef(null);
|
|
1048
1502
|
const [, setSelection] = useState(schema);
|
|
@@ -1061,98 +1515,12 @@ function FormEditor$1(props) {
|
|
|
1061
1515
|
drake
|
|
1062
1516
|
};
|
|
1063
1517
|
useEffect(() => {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
return el.classList.contains('fjs-drag-container');
|
|
1071
|
-
},
|
|
1072
|
-
copy(el) {
|
|
1073
|
-
return el.classList.contains('fjs-drag-copy');
|
|
1074
|
-
},
|
|
1075
|
-
accepts(el, target) {
|
|
1076
|
-
return !target.classList.contains('fjs-no-drop');
|
|
1077
|
-
},
|
|
1078
|
-
slideFactorX: 10,
|
|
1079
|
-
slideFactorY: 5
|
|
1080
|
-
});
|
|
1081
|
-
|
|
1082
|
-
// bind life cycle events
|
|
1083
|
-
dragulaInstance.on('drag', (element, source) => {
|
|
1084
|
-
handleDragEvent('drag.start', {
|
|
1085
|
-
element,
|
|
1086
|
-
source
|
|
1087
|
-
});
|
|
1088
|
-
});
|
|
1089
|
-
dragulaInstance.on('dragend', element => {
|
|
1090
|
-
handleDragEvent('drag.end', {
|
|
1091
|
-
element
|
|
1092
|
-
});
|
|
1093
|
-
});
|
|
1094
|
-
dragulaInstance.on('drop', (element, target, source, sibling) => {
|
|
1095
|
-
handleDragEvent('drag.drop', {
|
|
1096
|
-
element,
|
|
1097
|
-
target,
|
|
1098
|
-
source,
|
|
1099
|
-
sibling
|
|
1100
|
-
});
|
|
1101
|
-
});
|
|
1102
|
-
dragulaInstance.on('over', (element, container, source) => {
|
|
1103
|
-
handleDragEvent('drag.hover', {
|
|
1104
|
-
element,
|
|
1105
|
-
container,
|
|
1106
|
-
source
|
|
1107
|
-
});
|
|
1108
|
-
});
|
|
1109
|
-
dragulaInstance.on('out', (element, container, source) => {
|
|
1110
|
-
handleDragEvent('drag.out', {
|
|
1111
|
-
element,
|
|
1112
|
-
container,
|
|
1113
|
-
source
|
|
1114
|
-
});
|
|
1115
|
-
});
|
|
1116
|
-
dragulaInstance.on('cancel', (element, container, source) => {
|
|
1117
|
-
handleDragEvent('drag.cancel', {
|
|
1118
|
-
element,
|
|
1119
|
-
container,
|
|
1120
|
-
source
|
|
1121
|
-
});
|
|
1122
|
-
});
|
|
1123
|
-
|
|
1124
|
-
// set custom styling
|
|
1125
|
-
dragulaInstance.on('drag', () => {
|
|
1126
|
-
set('grabbing');
|
|
1127
|
-
});
|
|
1128
|
-
dragulaInstance.on('dragend', () => {
|
|
1129
|
-
unset();
|
|
1130
|
-
});
|
|
1131
|
-
dragulaInstance.on('drop', (el, target, source, sibling) => {
|
|
1132
|
-
dragulaInstance.remove();
|
|
1133
|
-
if (!target) {
|
|
1134
|
-
return;
|
|
1135
|
-
}
|
|
1136
|
-
const targetFormField = formFieldRegistry.get(target.dataset.id);
|
|
1137
|
-
const siblingFormField = sibling && formFieldRegistry.get(sibling.dataset.id),
|
|
1138
|
-
targetIndex = siblingFormField ? getFormFieldIndex(targetFormField, siblingFormField) : targetFormField.components.length;
|
|
1139
|
-
if (source.classList.contains('fjs-palette-fields')) {
|
|
1140
|
-
const type = el.dataset.fieldType;
|
|
1141
|
-
modeling.addFormField({
|
|
1142
|
-
type
|
|
1143
|
-
}, targetFormField, targetIndex);
|
|
1144
|
-
} else {
|
|
1145
|
-
const formField = formFieldRegistry.get(el.dataset.id),
|
|
1146
|
-
sourceFormField = formFieldRegistry.get(source.dataset.id),
|
|
1147
|
-
sourceIndex = getFormFieldIndex(sourceFormField, formField);
|
|
1148
|
-
modeling.moveFormField(formField, sourceFormField, targetFormField, sourceIndex, targetIndex);
|
|
1149
|
-
}
|
|
1150
|
-
});
|
|
1151
|
-
eventBus.fire('dragula.created');
|
|
1152
|
-
setDrake(dragulaInstance);
|
|
1153
|
-
return dragulaInstance;
|
|
1154
|
-
};
|
|
1155
|
-
let dragulaInstance = createDragulaInstance();
|
|
1518
|
+
let dragulaInstance = dragging.createDragulaInstance({
|
|
1519
|
+
container: [DRAG_CONTAINER_CLS, DROP_CONTAINER_VERTICAL_CLS, DROP_CONTAINER_HORIZONTAL_CLS],
|
|
1520
|
+
direction: 'vertical',
|
|
1521
|
+
mirrorContainer: formContainerRef.current
|
|
1522
|
+
});
|
|
1523
|
+
setDrake(dragulaInstance);
|
|
1156
1524
|
const onDetach = () => {
|
|
1157
1525
|
if (dragulaInstance) {
|
|
1158
1526
|
dragulaInstance.destroy();
|
|
@@ -1161,14 +1529,34 @@ function FormEditor$1(props) {
|
|
|
1161
1529
|
};
|
|
1162
1530
|
const onAttach = () => {
|
|
1163
1531
|
onDetach();
|
|
1164
|
-
dragulaInstance = createDragulaInstance(
|
|
1532
|
+
dragulaInstance = dragging.createDragulaInstance({
|
|
1533
|
+
container: [DRAG_CONTAINER_CLS, DROP_CONTAINER_VERTICAL_CLS, DROP_CONTAINER_HORIZONTAL_CLS],
|
|
1534
|
+
direction: 'vertical',
|
|
1535
|
+
mirrorContainer: formContainerRef.current
|
|
1536
|
+
});
|
|
1537
|
+
setDrake(dragulaInstance);
|
|
1538
|
+
};
|
|
1539
|
+
const onCreate = drake => {
|
|
1540
|
+
setDrake(drake);
|
|
1541
|
+
};
|
|
1542
|
+
const onDragStart = () => {
|
|
1543
|
+
set('grabbing');
|
|
1544
|
+
};
|
|
1545
|
+
const onDragEnd = () => {
|
|
1546
|
+
unset();
|
|
1165
1547
|
};
|
|
1166
1548
|
eventBus.on('attach', onAttach);
|
|
1167
1549
|
eventBus.on('detach', onDetach);
|
|
1550
|
+
eventBus.on('dragula.created', onCreate);
|
|
1551
|
+
eventBus.on('drag.start', onDragStart);
|
|
1552
|
+
eventBus.on('drag.end', onDragEnd);
|
|
1168
1553
|
return () => {
|
|
1169
1554
|
onDetach();
|
|
1170
1555
|
eventBus.off('attach', onAttach);
|
|
1171
1556
|
eventBus.off('detach', onDetach);
|
|
1557
|
+
eventBus.off('dragula.created', onCreate);
|
|
1558
|
+
eventBus.off('drag.start', onDragStart);
|
|
1559
|
+
eventBus.off('drag.end', onDragEnd);
|
|
1172
1560
|
};
|
|
1173
1561
|
}, []);
|
|
1174
1562
|
|
|
@@ -1178,8 +1566,10 @@ function FormEditor$1(props) {
|
|
|
1178
1566
|
}, []);
|
|
1179
1567
|
const formRenderContext = {
|
|
1180
1568
|
Children,
|
|
1569
|
+
Column,
|
|
1181
1570
|
Element,
|
|
1182
|
-
Empty
|
|
1571
|
+
Empty,
|
|
1572
|
+
Row
|
|
1183
1573
|
};
|
|
1184
1574
|
const formContext = {
|
|
1185
1575
|
getService(type, strict = true) {
|
|
@@ -1228,6 +1618,7 @@ function FormEditor$1(props) {
|
|
|
1228
1618
|
class: "fjs-editor-palette-container",
|
|
1229
1619
|
ref: paletteRef
|
|
1230
1620
|
}), jsx("div", {
|
|
1621
|
+
ref: formContainerRef,
|
|
1231
1622
|
class: "fjs-form-container",
|
|
1232
1623
|
children: jsx(FormContext.Provider, {
|
|
1233
1624
|
value: formContext,
|
|
@@ -1263,29 +1654,39 @@ function CreatePreview(props) {
|
|
|
1263
1654
|
} = useContext(DragAndDropContext$1);
|
|
1264
1655
|
function handleCloned(clone, original, type) {
|
|
1265
1656
|
const fieldType = clone.dataset.fieldType;
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
label
|
|
1269
|
-
} = findPaletteEntry(fieldType);
|
|
1657
|
+
|
|
1658
|
+
// (1) field preview
|
|
1270
1659
|
if (fieldType) {
|
|
1660
|
+
const {
|
|
1661
|
+
label
|
|
1662
|
+
} = findPaletteEntry(fieldType);
|
|
1663
|
+
const Icon = iconsByType(fieldType);
|
|
1271
1664
|
clone.innerHTML = '';
|
|
1272
1665
|
clone.class = 'gu-mirror';
|
|
1666
|
+
clone.classList.add('fjs-field-preview-container');
|
|
1273
1667
|
if (original.classList.contains('fjs-palette-field')) {
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
children: [jsx(Icon, {
|
|
1277
|
-
class: "fjs-palette-field-icon",
|
|
1278
|
-
width: "36",
|
|
1279
|
-
height: "36",
|
|
1280
|
-
viewBox: "0 0 54 54"
|
|
1281
|
-
}), jsx("span", {
|
|
1282
|
-
class: "fjs-palette-field-text",
|
|
1283
|
-
children: label
|
|
1284
|
-
})]
|
|
1285
|
-
}), clone);
|
|
1286
|
-
} else {
|
|
1287
|
-
render(jsx(Icon, {}), clone);
|
|
1668
|
+
// default to auto columns when creating from palette
|
|
1669
|
+
clone.classList.add('cds--col');
|
|
1288
1670
|
}
|
|
1671
|
+
|
|
1672
|
+
// todo(pinussilvestrus): dragula, how to mitigate cursor position
|
|
1673
|
+
// https://github.com/bevacqua/dragula/issues/285
|
|
1674
|
+
render(jsx(FieldDragPreview, {
|
|
1675
|
+
label: label,
|
|
1676
|
+
Icon: Icon
|
|
1677
|
+
}), clone);
|
|
1678
|
+
} else {
|
|
1679
|
+
// (2) row preview
|
|
1680
|
+
|
|
1681
|
+
// remove elements from copy (context pad, row dragger, ...)
|
|
1682
|
+
['fjs-context-pad', 'fjs-row-dragger', 'fjs-debug-columns'].forEach(cls => {
|
|
1683
|
+
const cloneNode = clone.querySelectorAll('.' + cls);
|
|
1684
|
+
cloneNode.length && cloneNode.forEach(e => e.remove());
|
|
1685
|
+
});
|
|
1686
|
+
|
|
1687
|
+
// mirror grid
|
|
1688
|
+
clone.classList.add('cds--grid');
|
|
1689
|
+
clone.classList.add('cds--grid--condensed');
|
|
1289
1690
|
}
|
|
1290
1691
|
}
|
|
1291
1692
|
useEffect(() => {
|
|
@@ -1358,10 +1759,12 @@ var renderModule = {
|
|
|
1358
1759
|
|
|
1359
1760
|
var core = {
|
|
1360
1761
|
__depends__: [importModule, renderModule],
|
|
1762
|
+
debounce: ['factory', DebounceFactory],
|
|
1361
1763
|
eventBus: ['type', EventBus],
|
|
1362
1764
|
formFieldRegistry: ['type', FormFieldRegistry],
|
|
1363
|
-
|
|
1364
|
-
|
|
1765
|
+
formLayouter: ['type', FormLayouter],
|
|
1766
|
+
formLayoutValidator: ['type', FormLayoutValidator],
|
|
1767
|
+
fieldFactory: ['type', FieldFactory]
|
|
1365
1768
|
};
|
|
1366
1769
|
|
|
1367
1770
|
var NOT_REGISTERED_ERROR = 'is not a registered action',
|
|
@@ -1639,6 +2042,11 @@ var EditorActionsModule = {
|
|
|
1639
2042
|
editorActions: ['type', FormEditorActions]
|
|
1640
2043
|
};
|
|
1641
2044
|
|
|
2045
|
+
var DraggingModule = {
|
|
2046
|
+
__init__: ['dragging'],
|
|
2047
|
+
dragging: ['type', Dragging]
|
|
2048
|
+
};
|
|
2049
|
+
|
|
1642
2050
|
var KEYS_COPY = ['c', 'C', 'KeyC'];
|
|
1643
2051
|
var KEYS_PASTE = ['v', 'V', 'KeyV'];
|
|
1644
2052
|
var KEYS_REDO$1 = ['y', 'Y', 'KeyY'];
|
|
@@ -2051,6 +2459,13 @@ function updatePath(formFieldRegistry, formField, index) {
|
|
|
2051
2459
|
formField._path = [...parent._path, 'components', index];
|
|
2052
2460
|
return formField;
|
|
2053
2461
|
}
|
|
2462
|
+
function updateRow(formField, rowId) {
|
|
2463
|
+
formField.layout = {
|
|
2464
|
+
...(formField.layout || {}),
|
|
2465
|
+
row: rowId
|
|
2466
|
+
};
|
|
2467
|
+
return formField;
|
|
2468
|
+
}
|
|
2054
2469
|
|
|
2055
2470
|
class AddFormFieldHandler {
|
|
2056
2471
|
/**
|
|
@@ -2200,13 +2615,17 @@ class MoveFormFieldHandler {
|
|
|
2200
2615
|
sourceFormField,
|
|
2201
2616
|
targetFormField,
|
|
2202
2617
|
sourceIndex,
|
|
2203
|
-
targetIndex
|
|
2618
|
+
targetIndex,
|
|
2619
|
+
sourceRow,
|
|
2620
|
+
targetRow
|
|
2204
2621
|
} = context;
|
|
2205
2622
|
this.moveFormField({
|
|
2206
2623
|
sourceFormField: targetFormField,
|
|
2207
2624
|
targetFormField: sourceFormField,
|
|
2208
2625
|
sourceIndex: targetIndex,
|
|
2209
|
-
targetIndex: sourceIndex
|
|
2626
|
+
targetIndex: sourceIndex,
|
|
2627
|
+
sourceRow: targetRow,
|
|
2628
|
+
targetRow: sourceRow
|
|
2210
2629
|
}, true);
|
|
2211
2630
|
}
|
|
2212
2631
|
moveFormField(context, revert) {
|
|
@@ -2214,7 +2633,8 @@ class MoveFormFieldHandler {
|
|
|
2214
2633
|
sourceFormField,
|
|
2215
2634
|
targetFormField,
|
|
2216
2635
|
sourceIndex,
|
|
2217
|
-
targetIndex
|
|
2636
|
+
targetIndex,
|
|
2637
|
+
targetRow
|
|
2218
2638
|
} = context;
|
|
2219
2639
|
let {
|
|
2220
2640
|
schema
|
|
@@ -2230,11 +2650,15 @@ class MoveFormFieldHandler {
|
|
|
2230
2650
|
targetIndex--;
|
|
2231
2651
|
}
|
|
2232
2652
|
}
|
|
2653
|
+
const formField = get(schema, [...sourcePath, sourceIndex]);
|
|
2654
|
+
|
|
2655
|
+
// (1) Add to row
|
|
2656
|
+
updateRow(formField, targetRow ? targetRow.id : null);
|
|
2233
2657
|
|
|
2234
|
-
// (
|
|
2658
|
+
// (2) Move form field
|
|
2235
2659
|
mutate(get(schema, sourcePath), sourceIndex, targetIndex);
|
|
2236
2660
|
|
|
2237
|
-
// (
|
|
2661
|
+
// (3) Update paths of new form field and its siblings
|
|
2238
2662
|
get(schema, sourcePath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
2239
2663
|
} else {
|
|
2240
2664
|
const formField = get(schema, [...sourcePath, sourceIndex]);
|
|
@@ -2247,10 +2671,13 @@ class MoveFormFieldHandler {
|
|
|
2247
2671
|
get(schema, sourcePath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
2248
2672
|
const targetPath = [...targetFormField._path, 'components'];
|
|
2249
2673
|
|
|
2250
|
-
// (3) Add
|
|
2674
|
+
// (3) Add to row
|
|
2675
|
+
updateRow(formField, targetRow ? targetRow.id : null);
|
|
2676
|
+
|
|
2677
|
+
// (4) Add form field
|
|
2251
2678
|
arrayAdd$1(get(schema, targetPath), targetIndex, formField);
|
|
2252
2679
|
|
|
2253
|
-
// (
|
|
2680
|
+
// (5) Update paths of siblings
|
|
2254
2681
|
get(schema, targetPath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
2255
2682
|
}
|
|
2256
2683
|
|
|
@@ -2442,13 +2869,15 @@ class Modeling {
|
|
|
2442
2869
|
};
|
|
2443
2870
|
this._commandStack.execute('formField.edit', context);
|
|
2444
2871
|
}
|
|
2445
|
-
moveFormField(formField, sourceFormField, targetFormField, sourceIndex, targetIndex) {
|
|
2872
|
+
moveFormField(formField, sourceFormField, targetFormField, sourceIndex, targetIndex, sourceRow, targetRow) {
|
|
2446
2873
|
const context = {
|
|
2447
2874
|
formField,
|
|
2448
2875
|
sourceFormField,
|
|
2449
2876
|
targetFormField,
|
|
2450
2877
|
sourceIndex,
|
|
2451
|
-
targetIndex
|
|
2878
|
+
targetIndex,
|
|
2879
|
+
sourceRow,
|
|
2880
|
+
targetRow
|
|
2452
2881
|
};
|
|
2453
2882
|
this._commandStack.execute('formField.move', context);
|
|
2454
2883
|
}
|
|
@@ -2607,6 +3036,44 @@ forEach(hooks, function (hook) {
|
|
|
2607
3036
|
};
|
|
2608
3037
|
});
|
|
2609
3038
|
|
|
3039
|
+
class FormLayoutUpdater extends CommandInterceptor {
|
|
3040
|
+
constructor(eventBus, formLayouter, modeling, formEditor) {
|
|
3041
|
+
super(eventBus);
|
|
3042
|
+
this._eventBus = eventBus;
|
|
3043
|
+
this._formLayouter = formLayouter;
|
|
3044
|
+
this._modeling = modeling;
|
|
3045
|
+
this._formEditor = formEditor;
|
|
3046
|
+
|
|
3047
|
+
// @ts-ignore
|
|
3048
|
+
this.preExecute(['formField.add', 'formField.remove', 'formField.move', 'id.updateClaim'], event => this.updateRowIds(event));
|
|
3049
|
+
|
|
3050
|
+
// we need that as the state got updates
|
|
3051
|
+
// on the next tick (not in post execute)
|
|
3052
|
+
eventBus.on('changed', context => {
|
|
3053
|
+
const {
|
|
3054
|
+
schema
|
|
3055
|
+
} = context;
|
|
3056
|
+
this.updateLayout(schema);
|
|
3057
|
+
});
|
|
3058
|
+
}
|
|
3059
|
+
updateLayout(schema) {
|
|
3060
|
+
this._formLayouter.clear();
|
|
3061
|
+
this._formLayouter.calculateLayout(clone(schema));
|
|
3062
|
+
}
|
|
3063
|
+
updateRowIds(event) {
|
|
3064
|
+
const {
|
|
3065
|
+
schema
|
|
3066
|
+
} = this._formEditor._getState();
|
|
3067
|
+
|
|
3068
|
+
// make sure rows are persisted in schema (e.g. for migration case)
|
|
3069
|
+
schema.components.forEach(formField => {
|
|
3070
|
+
const row = this._formLayouter.getRowForField(formField);
|
|
3071
|
+
updateRow(formField, row.id);
|
|
3072
|
+
});
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3075
|
+
FormLayoutUpdater.$inject = ['eventBus', 'formLayouter', 'modeling', 'formEditor'];
|
|
3076
|
+
|
|
2610
3077
|
class IdBehavior extends CommandInterceptor {
|
|
2611
3078
|
constructor(eventBus, modeling) {
|
|
2612
3079
|
super(eventBus);
|
|
@@ -3128,7 +3595,8 @@ var commandModule = {
|
|
|
3128
3595
|
|
|
3129
3596
|
var ModelingModule = {
|
|
3130
3597
|
__depends__: [behaviorModule, commandModule],
|
|
3131
|
-
__init__: ['modeling'],
|
|
3598
|
+
__init__: ['formLayoutUpdater', 'modeling'],
|
|
3599
|
+
formLayoutUpdater: ['type', FormLayoutUpdater],
|
|
3132
3600
|
modeling: ['type', Modeling]
|
|
3133
3601
|
};
|
|
3134
3602
|
|
|
@@ -3424,19 +3892,19 @@ const ErrorsContext = createContext({
|
|
|
3424
3892
|
errors: {}
|
|
3425
3893
|
});
|
|
3426
3894
|
|
|
3427
|
-
/**
|
|
3428
|
-
* @typedef {Function} <propertiesPanel.showEntry> callback
|
|
3429
|
-
*
|
|
3430
|
-
* @example
|
|
3431
|
-
*
|
|
3432
|
-
* useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
|
|
3433
|
-
* // ...
|
|
3434
|
-
* });
|
|
3435
|
-
*
|
|
3436
|
-
* @param {Object} context
|
|
3437
|
-
* @param {boolean} [context.focus]
|
|
3438
|
-
*
|
|
3439
|
-
* @returns void
|
|
3895
|
+
/**
|
|
3896
|
+
* @typedef {Function} <propertiesPanel.showEntry> callback
|
|
3897
|
+
*
|
|
3898
|
+
* @example
|
|
3899
|
+
*
|
|
3900
|
+
* useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
|
|
3901
|
+
* // ...
|
|
3902
|
+
* });
|
|
3903
|
+
*
|
|
3904
|
+
* @param {Object} context
|
|
3905
|
+
* @param {boolean} [context.focus]
|
|
3906
|
+
*
|
|
3907
|
+
* @returns void
|
|
3440
3908
|
*/
|
|
3441
3909
|
const EventContext = createContext({
|
|
3442
3910
|
eventBus: null
|
|
@@ -3448,20 +3916,20 @@ const LayoutContext = createContext({
|
|
|
3448
3916
|
setLayoutForKey: () => {}
|
|
3449
3917
|
});
|
|
3450
3918
|
|
|
3451
|
-
/**
|
|
3452
|
-
* Accesses the global DescriptionContext and returns a description for a given id and element.
|
|
3453
|
-
*
|
|
3454
|
-
* @example
|
|
3455
|
-
* ```jsx
|
|
3456
|
-
* function TextField(props) {
|
|
3457
|
-
* const description = useDescriptionContext('input1', element);
|
|
3458
|
-
* }
|
|
3459
|
-
* ```
|
|
3460
|
-
*
|
|
3461
|
-
* @param {string} id
|
|
3462
|
-
* @param {object} element
|
|
3463
|
-
*
|
|
3464
|
-
* @returns {string}
|
|
3919
|
+
/**
|
|
3920
|
+
* Accesses the global DescriptionContext and returns a description for a given id and element.
|
|
3921
|
+
*
|
|
3922
|
+
* @example
|
|
3923
|
+
* ```jsx
|
|
3924
|
+
* function TextField(props) {
|
|
3925
|
+
* const description = useDescriptionContext('input1', element);
|
|
3926
|
+
* }
|
|
3927
|
+
* ```
|
|
3928
|
+
*
|
|
3929
|
+
* @param {string} id
|
|
3930
|
+
* @param {object} element
|
|
3931
|
+
*
|
|
3932
|
+
* @returns {string}
|
|
3465
3933
|
*/
|
|
3466
3934
|
function useDescriptionContext(id, element) {
|
|
3467
3935
|
const {
|
|
@@ -3476,11 +3944,11 @@ function useError(id) {
|
|
|
3476
3944
|
return errors[id];
|
|
3477
3945
|
}
|
|
3478
3946
|
|
|
3479
|
-
/**
|
|
3480
|
-
* Subscribe to an event immediately. Update subscription after inputs changed.
|
|
3481
|
-
*
|
|
3482
|
-
* @param {string} event
|
|
3483
|
-
* @param {Function} callback
|
|
3947
|
+
/**
|
|
3948
|
+
* Subscribe to an event immediately. Update subscription after inputs changed.
|
|
3949
|
+
*
|
|
3950
|
+
* @param {string} event
|
|
3951
|
+
* @param {Function} callback
|
|
3484
3952
|
*/
|
|
3485
3953
|
function useEvent(event, callback, eventBus) {
|
|
3486
3954
|
const eventContext = useContext(EventContext);
|
|
@@ -3510,20 +3978,20 @@ function useEvent(event, callback, eventBus) {
|
|
|
3510
3978
|
}, [callback, event, eventBus]);
|
|
3511
3979
|
}
|
|
3512
3980
|
|
|
3513
|
-
/**
|
|
3514
|
-
* Creates a state that persists in the global LayoutContext.
|
|
3515
|
-
*
|
|
3516
|
-
* @example
|
|
3517
|
-
* ```jsx
|
|
3518
|
-
* function Group(props) {
|
|
3519
|
-
* const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
|
|
3520
|
-
* }
|
|
3521
|
-
* ```
|
|
3522
|
-
*
|
|
3523
|
-
* @param {(string|number)[]} path
|
|
3524
|
-
* @param {any} [defaultValue]
|
|
3525
|
-
*
|
|
3526
|
-
* @returns {[ any, Function ]}
|
|
3981
|
+
/**
|
|
3982
|
+
* Creates a state that persists in the global LayoutContext.
|
|
3983
|
+
*
|
|
3984
|
+
* @example
|
|
3985
|
+
* ```jsx
|
|
3986
|
+
* function Group(props) {
|
|
3987
|
+
* const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
|
|
3988
|
+
* }
|
|
3989
|
+
* ```
|
|
3990
|
+
*
|
|
3991
|
+
* @param {(string|number)[]} path
|
|
3992
|
+
* @param {any} [defaultValue]
|
|
3993
|
+
*
|
|
3994
|
+
* @returns {[ any, Function ]}
|
|
3527
3995
|
*/
|
|
3528
3996
|
function useLayoutState(path, defaultValue) {
|
|
3529
3997
|
const {
|
|
@@ -3531,22 +3999,17 @@ function useLayoutState(path, defaultValue) {
|
|
|
3531
3999
|
setLayoutForKey
|
|
3532
4000
|
} = useContext(LayoutContext);
|
|
3533
4001
|
const layoutForKey = getLayoutForKey(path, defaultValue);
|
|
3534
|
-
const
|
|
3535
|
-
const setState = newValue => {
|
|
3536
|
-
// (1) set component state
|
|
3537
|
-
set(newValue);
|
|
3538
|
-
|
|
3539
|
-
// (2) set context
|
|
4002
|
+
const setState = useCallback(newValue => {
|
|
3540
4003
|
setLayoutForKey(path, newValue);
|
|
3541
|
-
};
|
|
3542
|
-
return [
|
|
4004
|
+
}, [setLayoutForKey]);
|
|
4005
|
+
return [layoutForKey, setState];
|
|
3543
4006
|
}
|
|
3544
4007
|
|
|
3545
|
-
/**
|
|
3546
|
-
* @pinussilvestrus: we need to introduce our own hook to persist the previous
|
|
3547
|
-
* state on updates.
|
|
3548
|
-
*
|
|
3549
|
-
* cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
|
|
4008
|
+
/**
|
|
4009
|
+
* @pinussilvestrus: we need to introduce our own hook to persist the previous
|
|
4010
|
+
* state on updates.
|
|
4011
|
+
*
|
|
4012
|
+
* cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
|
|
3550
4013
|
*/
|
|
3551
4014
|
|
|
3552
4015
|
function usePrevious(value) {
|
|
@@ -3557,12 +4020,12 @@ function usePrevious(value) {
|
|
|
3557
4020
|
return ref.current;
|
|
3558
4021
|
}
|
|
3559
4022
|
|
|
3560
|
-
/**
|
|
3561
|
-
* Subscribe to `propertiesPanel.showEntry`.
|
|
3562
|
-
*
|
|
3563
|
-
* @param {string} id
|
|
3564
|
-
*
|
|
3565
|
-
* @returns {import('preact').Ref}
|
|
4023
|
+
/**
|
|
4024
|
+
* Subscribe to `propertiesPanel.showEntry`.
|
|
4025
|
+
*
|
|
4026
|
+
* @param {string} id
|
|
4027
|
+
*
|
|
4028
|
+
* @returns {import('preact').Ref}
|
|
3566
4029
|
*/
|
|
3567
4030
|
function useShowEntryEvent(id) {
|
|
3568
4031
|
const {
|
|
@@ -3593,20 +4056,20 @@ function useShowEntryEvent(id) {
|
|
|
3593
4056
|
return ref;
|
|
3594
4057
|
}
|
|
3595
4058
|
|
|
3596
|
-
/**
|
|
3597
|
-
* @callback setSticky
|
|
3598
|
-
* @param {boolean} value
|
|
4059
|
+
/**
|
|
4060
|
+
* @callback setSticky
|
|
4061
|
+
* @param {boolean} value
|
|
3599
4062
|
*/
|
|
3600
4063
|
|
|
3601
|
-
/**
|
|
3602
|
-
* Use IntersectionObserver to identify when DOM element is in sticky mode.
|
|
3603
|
-
* If sticky is observered setSticky(true) will be called.
|
|
3604
|
-
* If sticky mode is left, setSticky(false) will be called.
|
|
3605
|
-
*
|
|
3606
|
-
*
|
|
3607
|
-
* @param {Object} ref
|
|
3608
|
-
* @param {string} scrollContainerSelector
|
|
3609
|
-
* @param {setSticky} setSticky
|
|
4064
|
+
/**
|
|
4065
|
+
* Use IntersectionObserver to identify when DOM element is in sticky mode.
|
|
4066
|
+
* If sticky is observered setSticky(true) will be called.
|
|
4067
|
+
* If sticky mode is left, setSticky(false) will be called.
|
|
4068
|
+
*
|
|
4069
|
+
*
|
|
4070
|
+
* @param {Object} ref
|
|
4071
|
+
* @param {string} scrollContainerSelector
|
|
4072
|
+
* @param {setSticky} setSticky
|
|
3610
4073
|
*/
|
|
3611
4074
|
function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky) {
|
|
3612
4075
|
useEffect(() => {
|
|
@@ -3645,19 +4108,19 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
|
|
|
3645
4108
|
}, [ref, scrollContainerSelector, setSticky]);
|
|
3646
4109
|
}
|
|
3647
4110
|
|
|
3648
|
-
/**
|
|
3649
|
-
* Creates a static function reference with changing body.
|
|
3650
|
-
* This is necessary when external libraries require a callback function
|
|
3651
|
-
* that has references to state variables.
|
|
3652
|
-
*
|
|
3653
|
-
* Usage:
|
|
3654
|
-
* const callback = useStaticCallback((val) => {val === currentState});
|
|
3655
|
-
*
|
|
3656
|
-
* The `callback` reference is static and can be safely used in external
|
|
3657
|
-
* libraries or as a prop that does not cause rerendering of children.
|
|
3658
|
-
*
|
|
3659
|
-
* @param {Function} callback function with changing reference
|
|
3660
|
-
* @returns {Function} static function reference
|
|
4111
|
+
/**
|
|
4112
|
+
* Creates a static function reference with changing body.
|
|
4113
|
+
* This is necessary when external libraries require a callback function
|
|
4114
|
+
* that has references to state variables.
|
|
4115
|
+
*
|
|
4116
|
+
* Usage:
|
|
4117
|
+
* const callback = useStaticCallback((val) => {val === currentState});
|
|
4118
|
+
*
|
|
4119
|
+
* The `callback` reference is static and can be safely used in external
|
|
4120
|
+
* libraries or as a prop that does not cause rerendering of children.
|
|
4121
|
+
*
|
|
4122
|
+
* @param {Function} callback function with changing reference
|
|
4123
|
+
* @returns {Function} static function reference
|
|
3661
4124
|
*/
|
|
3662
4125
|
function useStaticCallback(callback) {
|
|
3663
4126
|
const callbackRef = useRef(callback);
|
|
@@ -3749,13 +4212,13 @@ function DataMarker() {
|
|
|
3749
4212
|
});
|
|
3750
4213
|
}
|
|
3751
4214
|
|
|
3752
|
-
/**
|
|
3753
|
-
* @typedef { {
|
|
3754
|
-
* text: (element: object) => string,
|
|
3755
|
-
* icon?: (element: Object) => import('preact').Component
|
|
3756
|
-
* } } PlaceholderDefinition
|
|
3757
|
-
*
|
|
3758
|
-
* @param { PlaceholderDefinition } props
|
|
4215
|
+
/**
|
|
4216
|
+
* @typedef { {
|
|
4217
|
+
* text: (element: object) => string,
|
|
4218
|
+
* icon?: (element: Object) => import('preact').Component
|
|
4219
|
+
* } } PlaceholderDefinition
|
|
4220
|
+
*
|
|
4221
|
+
* @param { PlaceholderDefinition } props
|
|
3759
4222
|
*/
|
|
3760
4223
|
function Placeholder(props) {
|
|
3761
4224
|
const {
|
|
@@ -3780,72 +4243,72 @@ const DEFAULT_LAYOUT = {
|
|
|
3780
4243
|
};
|
|
3781
4244
|
const DEFAULT_DESCRIPTION = {};
|
|
3782
4245
|
|
|
3783
|
-
/**
|
|
3784
|
-
* @typedef { {
|
|
3785
|
-
* component: import('preact').Component,
|
|
3786
|
-
* id: String,
|
|
3787
|
-
* isEdited?: Function
|
|
3788
|
-
* } } EntryDefinition
|
|
3789
|
-
*
|
|
3790
|
-
* @typedef { {
|
|
3791
|
-
* autoFocusEntry: String,
|
|
3792
|
-
* autoOpen?: Boolean,
|
|
3793
|
-
* entries: Array<EntryDefinition>,
|
|
3794
|
-
* id: String,
|
|
3795
|
-
* label: String,
|
|
3796
|
-
* remove: (event: MouseEvent) => void
|
|
3797
|
-
* } } ListItemDefinition
|
|
3798
|
-
*
|
|
3799
|
-
* @typedef { {
|
|
3800
|
-
* add: (event: MouseEvent) => void,
|
|
3801
|
-
* component: import('preact').Component,
|
|
3802
|
-
* element: Object,
|
|
3803
|
-
* id: String,
|
|
3804
|
-
* items: Array<ListItemDefinition>,
|
|
3805
|
-
* label: String,
|
|
3806
|
-
* shouldSort?: Boolean,
|
|
3807
|
-
* shouldOpen?: Boolean
|
|
3808
|
-
* } } ListGroupDefinition
|
|
3809
|
-
*
|
|
3810
|
-
* @typedef { {
|
|
3811
|
-
* component?: import('preact').Component,
|
|
3812
|
-
* entries: Array<EntryDefinition>,
|
|
3813
|
-
* id: String,
|
|
3814
|
-
* label: String,
|
|
3815
|
-
* shouldOpen?: Boolean
|
|
3816
|
-
* } } GroupDefinition
|
|
3817
|
-
*
|
|
3818
|
-
* @typedef { {
|
|
3819
|
-
* [id: String]: GetDescriptionFunction
|
|
3820
|
-
* } } DescriptionConfig
|
|
3821
|
-
*
|
|
3822
|
-
* @callback { {
|
|
3823
|
-
* @param {string} id
|
|
3824
|
-
* @param {Object} element
|
|
3825
|
-
* @returns {string}
|
|
3826
|
-
* } } GetDescriptionFunction
|
|
3827
|
-
*
|
|
3828
|
-
* @typedef { {
|
|
3829
|
-
* getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
|
|
3830
|
-
* getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
|
|
3831
|
-
* } } PlaceholderProvider
|
|
3832
|
-
*
|
|
4246
|
+
/**
|
|
4247
|
+
* @typedef { {
|
|
4248
|
+
* component: import('preact').Component,
|
|
4249
|
+
* id: String,
|
|
4250
|
+
* isEdited?: Function
|
|
4251
|
+
* } } EntryDefinition
|
|
4252
|
+
*
|
|
4253
|
+
* @typedef { {
|
|
4254
|
+
* autoFocusEntry: String,
|
|
4255
|
+
* autoOpen?: Boolean,
|
|
4256
|
+
* entries: Array<EntryDefinition>,
|
|
4257
|
+
* id: String,
|
|
4258
|
+
* label: String,
|
|
4259
|
+
* remove: (event: MouseEvent) => void
|
|
4260
|
+
* } } ListItemDefinition
|
|
4261
|
+
*
|
|
4262
|
+
* @typedef { {
|
|
4263
|
+
* add: (event: MouseEvent) => void,
|
|
4264
|
+
* component: import('preact').Component,
|
|
4265
|
+
* element: Object,
|
|
4266
|
+
* id: String,
|
|
4267
|
+
* items: Array<ListItemDefinition>,
|
|
4268
|
+
* label: String,
|
|
4269
|
+
* shouldSort?: Boolean,
|
|
4270
|
+
* shouldOpen?: Boolean
|
|
4271
|
+
* } } ListGroupDefinition
|
|
4272
|
+
*
|
|
4273
|
+
* @typedef { {
|
|
4274
|
+
* component?: import('preact').Component,
|
|
4275
|
+
* entries: Array<EntryDefinition>,
|
|
4276
|
+
* id: String,
|
|
4277
|
+
* label: String,
|
|
4278
|
+
* shouldOpen?: Boolean
|
|
4279
|
+
* } } GroupDefinition
|
|
4280
|
+
*
|
|
4281
|
+
* @typedef { {
|
|
4282
|
+
* [id: String]: GetDescriptionFunction
|
|
4283
|
+
* } } DescriptionConfig
|
|
4284
|
+
*
|
|
4285
|
+
* @callback { {
|
|
4286
|
+
* @param {string} id
|
|
4287
|
+
* @param {Object} element
|
|
4288
|
+
* @returns {string}
|
|
4289
|
+
* } } GetDescriptionFunction
|
|
4290
|
+
*
|
|
4291
|
+
* @typedef { {
|
|
4292
|
+
* getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
|
|
4293
|
+
* getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
|
|
4294
|
+
* } } PlaceholderProvider
|
|
4295
|
+
*
|
|
3833
4296
|
*/
|
|
3834
4297
|
|
|
3835
|
-
/**
|
|
3836
|
-
* A basic properties panel component. Describes *how* content will be rendered, accepts
|
|
3837
|
-
* data from implementor to describe *what* will be rendered.
|
|
3838
|
-
*
|
|
3839
|
-
* @param {Object} props
|
|
3840
|
-
* @param {Object|Array} props.element
|
|
3841
|
-
* @param {import('./components/Header').HeaderProvider} props.headerProvider
|
|
3842
|
-
* @param {PlaceholderProvider} [props.placeholderProvider]
|
|
3843
|
-
* @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
|
|
3844
|
-
* @param {Object} [props.layoutConfig]
|
|
3845
|
-
* @param {Function} [props.layoutChanged]
|
|
3846
|
-
* @param {DescriptionConfig} [props.descriptionConfig]
|
|
3847
|
-
* @param {Function} [props.descriptionLoaded]
|
|
3848
|
-
* @param {Object} [props.eventBus]
|
|
4298
|
+
/**
|
|
4299
|
+
* A basic properties panel component. Describes *how* content will be rendered, accepts
|
|
4300
|
+
* data from implementor to describe *what* will be rendered.
|
|
4301
|
+
*
|
|
4302
|
+
* @param {Object} props
|
|
4303
|
+
* @param {Object|Array} props.element
|
|
4304
|
+
* @param {import('./components/Header').HeaderProvider} props.headerProvider
|
|
4305
|
+
* @param {PlaceholderProvider} [props.placeholderProvider]
|
|
4306
|
+
* @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
|
|
4307
|
+
* @param {Object} [props.layoutConfig]
|
|
4308
|
+
* @param {Function} [props.layoutChanged]
|
|
4309
|
+
* @param {DescriptionConfig} [props.descriptionConfig]
|
|
4310
|
+
* @param {Function} [props.descriptionLoaded]
|
|
4311
|
+
* @param {Object} [props.eventBus]
|
|
3849
4312
|
*/
|
|
3850
4313
|
function PropertiesPanel(props) {
|
|
3851
4314
|
const {
|
|
@@ -3853,15 +4316,21 @@ function PropertiesPanel(props) {
|
|
|
3853
4316
|
headerProvider,
|
|
3854
4317
|
placeholderProvider,
|
|
3855
4318
|
groups,
|
|
3856
|
-
layoutConfig
|
|
4319
|
+
layoutConfig,
|
|
3857
4320
|
layoutChanged,
|
|
3858
|
-
descriptionConfig
|
|
4321
|
+
descriptionConfig,
|
|
3859
4322
|
descriptionLoaded,
|
|
3860
4323
|
eventBus
|
|
3861
4324
|
} = props;
|
|
3862
4325
|
|
|
3863
4326
|
// set-up layout context
|
|
3864
4327
|
const [layout, setLayout] = useState(createLayout(layoutConfig));
|
|
4328
|
+
|
|
4329
|
+
// react to external changes in the layout config
|
|
4330
|
+
useUpdateEffect(() => {
|
|
4331
|
+
const newLayout = createLayout(layoutConfig);
|
|
4332
|
+
setLayout(newLayout);
|
|
4333
|
+
}, [layoutConfig]);
|
|
3865
4334
|
useEffect(() => {
|
|
3866
4335
|
if (typeof layoutChanged === 'function') {
|
|
3867
4336
|
layoutChanged(layout);
|
|
@@ -3883,10 +4352,12 @@ function PropertiesPanel(props) {
|
|
|
3883
4352
|
};
|
|
3884
4353
|
|
|
3885
4354
|
// set-up description context
|
|
3886
|
-
const description = createDescriptionContext(descriptionConfig);
|
|
3887
|
-
|
|
3888
|
-
descriptionLoaded
|
|
3889
|
-
|
|
4355
|
+
const description = useMemo(() => createDescriptionContext(descriptionConfig), [descriptionConfig]);
|
|
4356
|
+
useEffect(() => {
|
|
4357
|
+
if (typeof descriptionLoaded === 'function') {
|
|
4358
|
+
descriptionLoaded(description);
|
|
4359
|
+
}
|
|
4360
|
+
}, [description, descriptionLoaded]);
|
|
3890
4361
|
const getDescriptionForId = (id, element) => {
|
|
3891
4362
|
return description[id] && description[id](element);
|
|
3892
4363
|
};
|
|
@@ -3961,18 +4432,37 @@ function PropertiesPanel(props) {
|
|
|
3961
4432
|
|
|
3962
4433
|
// helpers //////////////////
|
|
3963
4434
|
|
|
3964
|
-
function createLayout(overrides) {
|
|
4435
|
+
function createLayout(overrides = {}, defaults = DEFAULT_LAYOUT) {
|
|
3965
4436
|
return {
|
|
3966
|
-
...
|
|
4437
|
+
...defaults,
|
|
3967
4438
|
...overrides
|
|
3968
4439
|
};
|
|
3969
4440
|
}
|
|
3970
|
-
function createDescriptionContext(overrides) {
|
|
4441
|
+
function createDescriptionContext(overrides = {}) {
|
|
3971
4442
|
return {
|
|
3972
4443
|
...DEFAULT_DESCRIPTION,
|
|
3973
4444
|
...overrides
|
|
3974
4445
|
};
|
|
3975
4446
|
}
|
|
4447
|
+
|
|
4448
|
+
// hooks //////////////////
|
|
4449
|
+
|
|
4450
|
+
/**
|
|
4451
|
+
* This hook behaves like useEffect, but does not trigger on the first render.
|
|
4452
|
+
*
|
|
4453
|
+
* @param {Function} effect
|
|
4454
|
+
* @param {Array} deps
|
|
4455
|
+
*/
|
|
4456
|
+
function useUpdateEffect(effect, deps) {
|
|
4457
|
+
const isMounted = useRef(false);
|
|
4458
|
+
useEffect(() => {
|
|
4459
|
+
if (isMounted.current) {
|
|
4460
|
+
return effect();
|
|
4461
|
+
} else {
|
|
4462
|
+
isMounted.current = true;
|
|
4463
|
+
}
|
|
4464
|
+
}, deps);
|
|
4465
|
+
}
|
|
3976
4466
|
function CollapsibleEntry(props) {
|
|
3977
4467
|
const {
|
|
3978
4468
|
element,
|
|
@@ -4068,10 +4558,10 @@ function ListItem(props) {
|
|
|
4068
4558
|
})
|
|
4069
4559
|
});
|
|
4070
4560
|
}
|
|
4071
|
-
const noop$
|
|
4561
|
+
const noop$3 = () => {};
|
|
4072
4562
|
|
|
4073
|
-
/**
|
|
4074
|
-
* @param {import('../PropertiesPanel').ListGroupDefinition} props
|
|
4563
|
+
/**
|
|
4564
|
+
* @param {import('../PropertiesPanel').ListGroupDefinition} props
|
|
4075
4565
|
*/
|
|
4076
4566
|
function ListGroup(props) {
|
|
4077
4567
|
const {
|
|
@@ -4089,6 +4579,9 @@ function ListGroup(props) {
|
|
|
4089
4579
|
const onShow = useCallback(() => setOpen(true), [setOpen]);
|
|
4090
4580
|
const [ordering, setOrdering] = useState([]);
|
|
4091
4581
|
const [newItemAdded, setNewItemAdded] = useState(false);
|
|
4582
|
+
|
|
4583
|
+
// Flag to mark that add button was clicked in the last render cycle
|
|
4584
|
+
const [addTriggered, setAddTriggered] = useState(false);
|
|
4092
4585
|
const prevItems = usePrevious(items);
|
|
4093
4586
|
const prevElement = usePrevious(element);
|
|
4094
4587
|
const elementChanged = element !== prevElement;
|
|
@@ -4110,6 +4603,8 @@ function ListGroup(props) {
|
|
|
4110
4603
|
|
|
4111
4604
|
// (1) items were added
|
|
4112
4605
|
useEffect(() => {
|
|
4606
|
+
// reset addTriggered flag
|
|
4607
|
+
setAddTriggered(false);
|
|
4113
4608
|
if (shouldHandleEffects && prevItems && items.length > prevItems.length) {
|
|
4114
4609
|
let add = [];
|
|
4115
4610
|
items.forEach(item => {
|
|
@@ -4119,14 +4614,18 @@ function ListGroup(props) {
|
|
|
4119
4614
|
});
|
|
4120
4615
|
let newOrdering = ordering;
|
|
4121
4616
|
|
|
4122
|
-
// open if not open and
|
|
4123
|
-
|
|
4617
|
+
// open if not open, configured and triggered by add button
|
|
4618
|
+
//
|
|
4619
|
+
// TODO(marstamm): remove once we refactor layout handling for listGroups.
|
|
4620
|
+
// Ideally, opening should be handled as part of the `add` callback and
|
|
4621
|
+
// not be a concern for the ListGroup component.
|
|
4622
|
+
if (addTriggered && !open && shouldOpen) {
|
|
4124
4623
|
toggleOpen();
|
|
4624
|
+
}
|
|
4125
4625
|
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
}
|
|
4626
|
+
// filter when not open and configured
|
|
4627
|
+
if (!open && shouldSort) {
|
|
4628
|
+
newOrdering = createOrdering(sortItems(items));
|
|
4130
4629
|
}
|
|
4131
4630
|
|
|
4132
4631
|
// add new items on top or bottom depending on sorting behavior
|
|
@@ -4137,11 +4636,11 @@ function ListGroup(props) {
|
|
|
4137
4636
|
newOrdering.push(...add);
|
|
4138
4637
|
}
|
|
4139
4638
|
setOrdering(newOrdering);
|
|
4140
|
-
setNewItemAdded(
|
|
4639
|
+
setNewItemAdded(addTriggered);
|
|
4141
4640
|
} else {
|
|
4142
4641
|
setNewItemAdded(false);
|
|
4143
4642
|
}
|
|
4144
|
-
}, [items, open, shouldHandleEffects]);
|
|
4643
|
+
}, [items, open, shouldHandleEffects, addTriggered]);
|
|
4145
4644
|
|
|
4146
4645
|
// (2) sort items on open if shouldSort is set
|
|
4147
4646
|
useEffect(() => {
|
|
@@ -4171,13 +4670,17 @@ function ListGroup(props) {
|
|
|
4171
4670
|
...useContext(LayoutContext),
|
|
4172
4671
|
onShow
|
|
4173
4672
|
};
|
|
4673
|
+
const handleAddClick = e => {
|
|
4674
|
+
setAddTriggered(true);
|
|
4675
|
+
add(e);
|
|
4676
|
+
};
|
|
4174
4677
|
return jsxs("div", {
|
|
4175
4678
|
class: "bio-properties-panel-group",
|
|
4176
4679
|
"data-group-id": 'group-' + id,
|
|
4177
4680
|
ref: groupRef,
|
|
4178
4681
|
children: [jsxs("div", {
|
|
4179
4682
|
class: classnames('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : '', sticky && open ? 'sticky' : ''),
|
|
4180
|
-
onClick: hasItems ? toggleOpen : noop$
|
|
4683
|
+
onClick: hasItems ? toggleOpen : noop$3,
|
|
4181
4684
|
children: [jsx("div", {
|
|
4182
4685
|
title: label,
|
|
4183
4686
|
class: "bio-properties-panel-group-header-title",
|
|
@@ -4187,7 +4690,7 @@ function ListGroup(props) {
|
|
|
4187
4690
|
children: [add ? jsxs("button", {
|
|
4188
4691
|
title: "Create new list item",
|
|
4189
4692
|
class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
|
|
4190
|
-
onClick:
|
|
4693
|
+
onClick: handleAddClick,
|
|
4191
4694
|
children: [jsx(CreateIcon, {}), !hasItems ? jsx("span", {
|
|
4192
4695
|
class: "bio-properties-panel-add-entry-label",
|
|
4193
4696
|
children: "Create"
|
|
@@ -4217,8 +4720,9 @@ function ListGroup(props) {
|
|
|
4217
4720
|
id
|
|
4218
4721
|
} = item;
|
|
4219
4722
|
|
|
4220
|
-
// if item was added, open
|
|
4221
|
-
|
|
4723
|
+
// if item was added, open it
|
|
4724
|
+
// Existing items will not be affected as autoOpen is only applied on first render
|
|
4725
|
+
const autoOpen = newItemAdded;
|
|
4222
4726
|
return createElement(ListItem, {
|
|
4223
4727
|
...item,
|
|
4224
4728
|
autoOpen: autoOpen,
|
|
@@ -4234,8 +4738,8 @@ function ListGroup(props) {
|
|
|
4234
4738
|
|
|
4235
4739
|
// helpers ////////////////////
|
|
4236
4740
|
|
|
4237
|
-
/**
|
|
4238
|
-
* Sorts given items alphanumeric by label
|
|
4741
|
+
/**
|
|
4742
|
+
* Sorts given items alphanumeric by label
|
|
4239
4743
|
*/
|
|
4240
4744
|
function sortItems(items) {
|
|
4241
4745
|
return sortBy(items, i => i.label.toLowerCase());
|
|
@@ -4309,17 +4813,17 @@ function Checkbox(props) {
|
|
|
4309
4813
|
});
|
|
4310
4814
|
}
|
|
4311
4815
|
|
|
4312
|
-
/**
|
|
4313
|
-
* @param {Object} props
|
|
4314
|
-
* @param {Object} props.element
|
|
4315
|
-
* @param {String} props.id
|
|
4316
|
-
* @param {String} props.description
|
|
4317
|
-
* @param {String} props.label
|
|
4318
|
-
* @param {Function} props.getValue
|
|
4319
|
-
* @param {Function} props.setValue
|
|
4320
|
-
* @param {Function} props.onFocus
|
|
4321
|
-
* @param {Function} props.onBlur
|
|
4322
|
-
* @param {boolean} [props.disabled]
|
|
4816
|
+
/**
|
|
4817
|
+
* @param {Object} props
|
|
4818
|
+
* @param {Object} props.element
|
|
4819
|
+
* @param {String} props.id
|
|
4820
|
+
* @param {String} props.description
|
|
4821
|
+
* @param {String} props.label
|
|
4822
|
+
* @param {Function} props.getValue
|
|
4823
|
+
* @param {Function} props.setValue
|
|
4824
|
+
* @param {Function} props.onFocus
|
|
4825
|
+
* @param {Function} props.onBlur
|
|
4826
|
+
* @param {boolean} [props.disabled]
|
|
4323
4827
|
*/
|
|
4324
4828
|
function CheckboxEntry(props) {
|
|
4325
4829
|
const {
|
|
@@ -4356,7 +4860,7 @@ function CheckboxEntry(props) {
|
|
|
4356
4860
|
})]
|
|
4357
4861
|
});
|
|
4358
4862
|
}
|
|
4359
|
-
function isEdited$
|
|
4863
|
+
function isEdited$8(node) {
|
|
4360
4864
|
return node && !!node.checked;
|
|
4361
4865
|
}
|
|
4362
4866
|
|
|
@@ -4365,6 +4869,87 @@ function isEdited$7(node) {
|
|
|
4365
4869
|
function prefixId$7(id) {
|
|
4366
4870
|
return `bio-properties-panel-${id}`;
|
|
4367
4871
|
}
|
|
4872
|
+
const useBufferedFocus$1 = function (editor, ref) {
|
|
4873
|
+
const [buffer, setBuffer] = useState(undefined);
|
|
4874
|
+
ref.current = useMemo(() => ({
|
|
4875
|
+
focus: offset => {
|
|
4876
|
+
if (editor) {
|
|
4877
|
+
editor.focus(offset);
|
|
4878
|
+
} else {
|
|
4879
|
+
if (typeof offset === 'undefined') {
|
|
4880
|
+
offset = Infinity;
|
|
4881
|
+
}
|
|
4882
|
+
setBuffer(offset);
|
|
4883
|
+
}
|
|
4884
|
+
}
|
|
4885
|
+
}), [editor]);
|
|
4886
|
+
useEffect(() => {
|
|
4887
|
+
if (typeof buffer !== 'undefined' && editor) {
|
|
4888
|
+
editor.focus(buffer);
|
|
4889
|
+
setBuffer(false);
|
|
4890
|
+
}
|
|
4891
|
+
}, [editor, buffer]);
|
|
4892
|
+
};
|
|
4893
|
+
const CodeEditor$1 = forwardRef((props, ref) => {
|
|
4894
|
+
const {
|
|
4895
|
+
onInput,
|
|
4896
|
+
disabled,
|
|
4897
|
+
tooltipContainer,
|
|
4898
|
+
enableGutters,
|
|
4899
|
+
value,
|
|
4900
|
+
onLint = () => {},
|
|
4901
|
+
contentAttributes = {},
|
|
4902
|
+
hostLanguage = null,
|
|
4903
|
+
singleLine = false
|
|
4904
|
+
} = props;
|
|
4905
|
+
const inputRef = useRef();
|
|
4906
|
+
const [editor, setEditor] = useState();
|
|
4907
|
+
const [localValue, setLocalValue] = useState(value || '');
|
|
4908
|
+
useBufferedFocus$1(editor, ref);
|
|
4909
|
+
const handleInput = useStaticCallback(newValue => {
|
|
4910
|
+
onInput(newValue);
|
|
4911
|
+
setLocalValue(newValue);
|
|
4912
|
+
});
|
|
4913
|
+
useEffect(() => {
|
|
4914
|
+
let editor;
|
|
4915
|
+
editor = new FeelersEditor({
|
|
4916
|
+
container: inputRef.current,
|
|
4917
|
+
onChange: handleInput,
|
|
4918
|
+
value: localValue,
|
|
4919
|
+
onLint,
|
|
4920
|
+
contentAttributes,
|
|
4921
|
+
tooltipContainer,
|
|
4922
|
+
enableGutters,
|
|
4923
|
+
hostLanguage,
|
|
4924
|
+
singleLine
|
|
4925
|
+
});
|
|
4926
|
+
setEditor(editor);
|
|
4927
|
+
return () => {
|
|
4928
|
+
onLint([]);
|
|
4929
|
+
inputRef.current.innerHTML = '';
|
|
4930
|
+
setEditor(null);
|
|
4931
|
+
};
|
|
4932
|
+
}, []);
|
|
4933
|
+
useEffect(() => {
|
|
4934
|
+
if (!editor) {
|
|
4935
|
+
return;
|
|
4936
|
+
}
|
|
4937
|
+
if (value === localValue) {
|
|
4938
|
+
return;
|
|
4939
|
+
}
|
|
4940
|
+
editor.setValue(value);
|
|
4941
|
+
setLocalValue(value);
|
|
4942
|
+
}, [value]);
|
|
4943
|
+
const handleClick = () => {
|
|
4944
|
+
ref.current.focus();
|
|
4945
|
+
};
|
|
4946
|
+
return jsx("div", {
|
|
4947
|
+
name: props.name,
|
|
4948
|
+
class: classnames('bio-properties-panel-feelers-editor bio-properties-panel-input', localValue ? 'edited' : null, disabled ? 'disabled' : null),
|
|
4949
|
+
ref: inputRef,
|
|
4950
|
+
onClick: handleClick
|
|
4951
|
+
});
|
|
4952
|
+
});
|
|
4368
4953
|
const useBufferedFocus = function (editor, ref) {
|
|
4369
4954
|
const [buffer, setBuffer] = useState(undefined);
|
|
4370
4955
|
ref.current = useMemo(() => ({
|
|
@@ -4407,10 +4992,10 @@ const CodeEditor = forwardRef((props, ref) => {
|
|
|
4407
4992
|
useEffect(() => {
|
|
4408
4993
|
let editor;
|
|
4409
4994
|
|
|
4410
|
-
/* Trigger FEEL toggle when
|
|
4411
|
-
*
|
|
4412
|
-
* - `backspace` is pressed
|
|
4413
|
-
* - AND the cursor is at the beginning of the input
|
|
4995
|
+
/* Trigger FEEL toggle when
|
|
4996
|
+
*
|
|
4997
|
+
* - `backspace` is pressed
|
|
4998
|
+
* - AND the cursor is at the beginning of the input
|
|
4414
4999
|
*/
|
|
4415
5000
|
const onKeyDown = e => {
|
|
4416
5001
|
if (e.key !== 'Backspace' || !editor) {
|
|
@@ -4479,12 +5064,12 @@ function FeelIndicator(props) {
|
|
|
4479
5064
|
children: "="
|
|
4480
5065
|
});
|
|
4481
5066
|
}
|
|
4482
|
-
const noop$
|
|
5067
|
+
const noop$2 = () => {};
|
|
4483
5068
|
|
|
4484
|
-
/**
|
|
4485
|
-
* @param {Object} props
|
|
4486
|
-
* @param {Object} props.label
|
|
4487
|
-
* @param {String} props.feel
|
|
5069
|
+
/**
|
|
5070
|
+
* @param {Object} props
|
|
5071
|
+
* @param {Object} props.label
|
|
5072
|
+
* @param {String} props.feel
|
|
4488
5073
|
*/
|
|
4489
5074
|
function FeelIcon(props) {
|
|
4490
5075
|
const {
|
|
@@ -4492,7 +5077,7 @@ function FeelIcon(props) {
|
|
|
4492
5077
|
feel = false,
|
|
4493
5078
|
active,
|
|
4494
5079
|
disabled = false,
|
|
4495
|
-
onClick = noop$
|
|
5080
|
+
onClick = noop$2
|
|
4496
5081
|
} = props;
|
|
4497
5082
|
const feelRequiredLabel = ' must be a FEEL expression';
|
|
4498
5083
|
const feelOptionalLabel = ' can optionally be a FEEL expression';
|
|
@@ -4512,7 +5097,7 @@ function FeelIcon(props) {
|
|
|
4512
5097
|
children: feel === 'required' ? jsx(FeelRequiredIcon, {}) : jsx(FeelOptionalIcon, {})
|
|
4513
5098
|
});
|
|
4514
5099
|
}
|
|
4515
|
-
const noop = () => {};
|
|
5100
|
+
const noop$1 = () => {};
|
|
4516
5101
|
function FeelTextfield(props) {
|
|
4517
5102
|
const {
|
|
4518
5103
|
debounce,
|
|
@@ -4669,6 +5254,9 @@ function FeelTextfield(props) {
|
|
|
4669
5254
|
}) : jsx(OptionalComponent, {
|
|
4670
5255
|
...props,
|
|
4671
5256
|
onInput: handleLocalInput,
|
|
5257
|
+
contentAttributes: {
|
|
5258
|
+
'id': prefixId$6(id)
|
|
5259
|
+
},
|
|
4672
5260
|
value: localValue,
|
|
4673
5261
|
ref: editorRef
|
|
4674
5262
|
})]
|
|
@@ -4718,7 +5306,7 @@ const OptionalFeelInput = forwardRef((props, ref) => {
|
|
|
4718
5306
|
value: value || ''
|
|
4719
5307
|
});
|
|
4720
5308
|
});
|
|
4721
|
-
|
|
5309
|
+
forwardRef((props, ref) => {
|
|
4722
5310
|
const {
|
|
4723
5311
|
id,
|
|
4724
5312
|
disabled,
|
|
@@ -4758,17 +5346,24 @@ const OptionalFeelTextArea = forwardRef((props, ref) => {
|
|
|
4758
5346
|
});
|
|
4759
5347
|
});
|
|
4760
5348
|
|
|
4761
|
-
/**
|
|
4762
|
-
* @param {Object} props
|
|
4763
|
-
* @param {Object} props.element
|
|
4764
|
-
* @param {String} props.id
|
|
4765
|
-
* @param {String} props.description
|
|
4766
|
-
* @param {Boolean} props.debounce
|
|
4767
|
-
* @param {Boolean} props.disabled
|
|
4768
|
-
* @param {
|
|
4769
|
-
* @param {
|
|
4770
|
-
* @param {Function} props.
|
|
4771
|
-
* @param {Function} props.
|
|
5349
|
+
/**
|
|
5350
|
+
* @param {Object} props
|
|
5351
|
+
* @param {Object} props.element
|
|
5352
|
+
* @param {String} props.id
|
|
5353
|
+
* @param {String} props.description
|
|
5354
|
+
* @param {Boolean} props.debounce
|
|
5355
|
+
* @param {Boolean} props.disabled
|
|
5356
|
+
* @param {Boolean} props.feel
|
|
5357
|
+
* @param {String} props.label
|
|
5358
|
+
* @param {Function} props.getValue
|
|
5359
|
+
* @param {Function} props.setValue
|
|
5360
|
+
* @param {Function} props.tooltipContainer
|
|
5361
|
+
* @param {Function} props.validate
|
|
5362
|
+
* @param {Function} props.show
|
|
5363
|
+
* @param {Function} props.example
|
|
5364
|
+
* @param {Function} props.variables
|
|
5365
|
+
* @param {Function} props.onFocus
|
|
5366
|
+
* @param {Function} props.onBlur
|
|
4772
5367
|
*/
|
|
4773
5368
|
function FeelEntry(props) {
|
|
4774
5369
|
const {
|
|
@@ -4782,8 +5377,10 @@ function FeelEntry(props) {
|
|
|
4782
5377
|
getValue,
|
|
4783
5378
|
setValue,
|
|
4784
5379
|
tooltipContainer,
|
|
5380
|
+
hostLanguage,
|
|
5381
|
+
singleLine,
|
|
4785
5382
|
validate,
|
|
4786
|
-
show = noop,
|
|
5383
|
+
show = noop$1,
|
|
4787
5384
|
example,
|
|
4788
5385
|
variables,
|
|
4789
5386
|
onFocus,
|
|
@@ -4837,6 +5434,8 @@ function FeelEntry(props) {
|
|
|
4837
5434
|
onFocus: onFocus,
|
|
4838
5435
|
onBlur: onBlur,
|
|
4839
5436
|
example: example,
|
|
5437
|
+
hostLanguage: hostLanguage,
|
|
5438
|
+
singleLine: singleLine,
|
|
4840
5439
|
show: show,
|
|
4841
5440
|
value: value,
|
|
4842
5441
|
variables: variables,
|
|
@@ -4853,28 +5452,35 @@ function FeelEntry(props) {
|
|
|
4853
5452
|
});
|
|
4854
5453
|
}
|
|
4855
5454
|
|
|
4856
|
-
/**
|
|
4857
|
-
* @param {Object} props
|
|
4858
|
-
* @param {Object} props.element
|
|
4859
|
-
* @param {String} props.id
|
|
4860
|
-
* @param {String} props.description
|
|
4861
|
-
* @param {
|
|
4862
|
-
* @param {Boolean} props.
|
|
4863
|
-
* @param {
|
|
4864
|
-
* @param {
|
|
4865
|
-
* @param {
|
|
4866
|
-
* @param {
|
|
4867
|
-
* @param {Function} props.
|
|
4868
|
-
* @param {Function} props.
|
|
5455
|
+
/**
|
|
5456
|
+
* @param {Object} props
|
|
5457
|
+
* @param {Object} props.element
|
|
5458
|
+
* @param {String} props.id
|
|
5459
|
+
* @param {String} props.description
|
|
5460
|
+
* @param {String} props.hostLanguage
|
|
5461
|
+
* @param {Boolean} props.singleLine
|
|
5462
|
+
* @param {Boolean} props.debounce
|
|
5463
|
+
* @param {Boolean} props.disabled
|
|
5464
|
+
* @param {Boolean} props.feel
|
|
5465
|
+
* @param {String} props.label
|
|
5466
|
+
* @param {Function} props.getValue
|
|
5467
|
+
* @param {Function} props.setValue
|
|
5468
|
+
* @param {Function} props.tooltipContainer
|
|
5469
|
+
* @param {Function} props.validate
|
|
5470
|
+
* @param {Function} props.show
|
|
5471
|
+
* @param {Function} props.example
|
|
5472
|
+
* @param {Function} props.variables
|
|
5473
|
+
* @param {Function} props.onFocus
|
|
5474
|
+
* @param {Function} props.onBlur
|
|
4869
5475
|
*/
|
|
4870
|
-
function
|
|
5476
|
+
function FeelTemplatingEntry(props) {
|
|
4871
5477
|
return jsx(FeelEntry, {
|
|
4872
|
-
class: "bio-properties-panel-feel-
|
|
4873
|
-
OptionalComponent:
|
|
5478
|
+
class: "bio-properties-panel-feel-templating",
|
|
5479
|
+
OptionalComponent: CodeEditor$1,
|
|
4874
5480
|
...props
|
|
4875
5481
|
});
|
|
4876
5482
|
}
|
|
4877
|
-
function isEdited$
|
|
5483
|
+
function isEdited$7(node) {
|
|
4878
5484
|
return node && (!!node.value || node.classList.contains('edited'));
|
|
4879
5485
|
}
|
|
4880
5486
|
|
|
@@ -4944,22 +5550,22 @@ function NumberField(props) {
|
|
|
4944
5550
|
});
|
|
4945
5551
|
}
|
|
4946
5552
|
|
|
4947
|
-
/**
|
|
4948
|
-
* @param {Object} props
|
|
4949
|
-
* @param {Boolean} props.debounce
|
|
4950
|
-
* @param {String} props.description
|
|
4951
|
-
* @param {Boolean} props.disabled
|
|
4952
|
-
* @param {Object} props.element
|
|
4953
|
-
* @param {Function} props.getValue
|
|
4954
|
-
* @param {String} props.id
|
|
4955
|
-
* @param {String} props.label
|
|
4956
|
-
* @param {String} props.max
|
|
4957
|
-
* @param {String} props.min
|
|
4958
|
-
* @param {Function} props.setValue
|
|
4959
|
-
* @param {Function} props.onFocus
|
|
4960
|
-
* @param {Function} props.onBlur
|
|
4961
|
-
* @param {String} props.step
|
|
4962
|
-
* @param {Function} props.validate
|
|
5553
|
+
/**
|
|
5554
|
+
* @param {Object} props
|
|
5555
|
+
* @param {Boolean} props.debounce
|
|
5556
|
+
* @param {String} props.description
|
|
5557
|
+
* @param {Boolean} props.disabled
|
|
5558
|
+
* @param {Object} props.element
|
|
5559
|
+
* @param {Function} props.getValue
|
|
5560
|
+
* @param {String} props.id
|
|
5561
|
+
* @param {String} props.label
|
|
5562
|
+
* @param {String} props.max
|
|
5563
|
+
* @param {String} props.min
|
|
5564
|
+
* @param {Function} props.setValue
|
|
5565
|
+
* @param {Function} props.onFocus
|
|
5566
|
+
* @param {Function} props.onBlur
|
|
5567
|
+
* @param {String} props.step
|
|
5568
|
+
* @param {Function} props.validate
|
|
4963
5569
|
*/
|
|
4964
5570
|
function NumberFieldEntry(props) {
|
|
4965
5571
|
const {
|
|
@@ -5084,6 +5690,16 @@ function Select(props) {
|
|
|
5084
5690
|
value: localValue,
|
|
5085
5691
|
disabled: disabled,
|
|
5086
5692
|
children: options.map((option, idx) => {
|
|
5693
|
+
if (option.children) {
|
|
5694
|
+
return jsx("optgroup", {
|
|
5695
|
+
label: option.label,
|
|
5696
|
+
children: option.children.map((child, idx) => jsx("option", {
|
|
5697
|
+
value: child.value,
|
|
5698
|
+
disabled: child.disabled,
|
|
5699
|
+
children: child.label
|
|
5700
|
+
}, idx))
|
|
5701
|
+
}, idx);
|
|
5702
|
+
}
|
|
5087
5703
|
return jsx("option", {
|
|
5088
5704
|
value: option.value,
|
|
5089
5705
|
disabled: option.disabled,
|
|
@@ -5094,18 +5710,19 @@ function Select(props) {
|
|
|
5094
5710
|
});
|
|
5095
5711
|
}
|
|
5096
5712
|
|
|
5097
|
-
/**
|
|
5098
|
-
* @param {object} props
|
|
5099
|
-
* @param {object} props.element
|
|
5100
|
-
* @param {string} props.id
|
|
5101
|
-
* @param {string} [props.description]
|
|
5102
|
-
* @param {string} props.label
|
|
5103
|
-
* @param {Function} props.getValue
|
|
5104
|
-
* @param {Function} props.setValue
|
|
5105
|
-
* @param {Function} props.onFocus
|
|
5106
|
-
* @param {Function} props.onBlur
|
|
5107
|
-
* @param {Function} props.getOptions
|
|
5108
|
-
* @param {boolean} [props.disabled]
|
|
5713
|
+
/**
|
|
5714
|
+
* @param {object} props
|
|
5715
|
+
* @param {object} props.element
|
|
5716
|
+
* @param {string} props.id
|
|
5717
|
+
* @param {string} [props.description]
|
|
5718
|
+
* @param {string} props.label
|
|
5719
|
+
* @param {Function} props.getValue
|
|
5720
|
+
* @param {Function} props.setValue
|
|
5721
|
+
* @param {Function} props.onFocus
|
|
5722
|
+
* @param {Function} props.onBlur
|
|
5723
|
+
* @param {Function} props.getOptions
|
|
5724
|
+
* @param {boolean} [props.disabled]
|
|
5725
|
+
* @param {Function} [props.validate]
|
|
5109
5726
|
*/
|
|
5110
5727
|
function SelectEntry(props) {
|
|
5111
5728
|
const {
|
|
@@ -5118,11 +5735,37 @@ function SelectEntry(props) {
|
|
|
5118
5735
|
getOptions,
|
|
5119
5736
|
disabled,
|
|
5120
5737
|
onFocus,
|
|
5121
|
-
onBlur
|
|
5738
|
+
onBlur,
|
|
5739
|
+
validate
|
|
5122
5740
|
} = props;
|
|
5123
|
-
const value = getValue(element);
|
|
5124
5741
|
const options = getOptions(element);
|
|
5125
|
-
const
|
|
5742
|
+
const [cachedInvalidValue, setCachedInvalidValue] = useState(null);
|
|
5743
|
+
const globalError = useError(id);
|
|
5744
|
+
const [localError, setLocalError] = useState(null);
|
|
5745
|
+
let value = getValue(element);
|
|
5746
|
+
const previousValue = usePrevious(value);
|
|
5747
|
+
useEffect(() => {
|
|
5748
|
+
if (isFunction(validate)) {
|
|
5749
|
+
const newValidationError = validate(value) || null;
|
|
5750
|
+
setLocalError(newValidationError);
|
|
5751
|
+
}
|
|
5752
|
+
}, [value]);
|
|
5753
|
+
const onChange = newValue => {
|
|
5754
|
+
let newValidationError = null;
|
|
5755
|
+
if (isFunction(validate)) {
|
|
5756
|
+
newValidationError = validate(newValue) || null;
|
|
5757
|
+
}
|
|
5758
|
+
if (newValidationError) {
|
|
5759
|
+
setCachedInvalidValue(newValue);
|
|
5760
|
+
} else {
|
|
5761
|
+
setValue(newValue);
|
|
5762
|
+
}
|
|
5763
|
+
setLocalError(newValidationError);
|
|
5764
|
+
};
|
|
5765
|
+
if (previousValue === value && localError) {
|
|
5766
|
+
value = cachedInvalidValue;
|
|
5767
|
+
}
|
|
5768
|
+
const error = globalError || localError;
|
|
5126
5769
|
return jsxs("div", {
|
|
5127
5770
|
class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
5128
5771
|
"data-entry-id": id,
|
|
@@ -5130,7 +5773,7 @@ function SelectEntry(props) {
|
|
|
5130
5773
|
id: id,
|
|
5131
5774
|
label: label,
|
|
5132
5775
|
value: value,
|
|
5133
|
-
onChange:
|
|
5776
|
+
onChange: onChange,
|
|
5134
5777
|
onFocus: onFocus,
|
|
5135
5778
|
onBlur: onBlur,
|
|
5136
5779
|
options: options,
|
|
@@ -5154,18 +5797,26 @@ function isEdited$4(node) {
|
|
|
5154
5797
|
function prefixId$4(id) {
|
|
5155
5798
|
return `bio-properties-panel-${id}`;
|
|
5156
5799
|
}
|
|
5800
|
+
function resizeToContents(element) {
|
|
5801
|
+
element.style.height = 'auto';
|
|
5802
|
+
|
|
5803
|
+
// a 2px pixel offset is required to prevent scrollbar from
|
|
5804
|
+
// appearing on OS with a full length scroll bar (Windows/Linux)
|
|
5805
|
+
element.style.height = `${element.scrollHeight + 2}px`;
|
|
5806
|
+
}
|
|
5157
5807
|
function TextArea(props) {
|
|
5158
5808
|
const {
|
|
5159
5809
|
id,
|
|
5160
5810
|
label,
|
|
5161
|
-
rows = 2,
|
|
5162
5811
|
debounce,
|
|
5163
5812
|
onInput,
|
|
5164
5813
|
value = '',
|
|
5165
5814
|
disabled,
|
|
5166
5815
|
monospace,
|
|
5167
5816
|
onFocus,
|
|
5168
|
-
onBlur
|
|
5817
|
+
onBlur,
|
|
5818
|
+
autoResize,
|
|
5819
|
+
rows = autoResize ? 1 : 2
|
|
5169
5820
|
} = props;
|
|
5170
5821
|
const [localValue, setLocalValue] = useState(value);
|
|
5171
5822
|
const ref = useShowEntryEvent(id);
|
|
@@ -5176,8 +5827,12 @@ function TextArea(props) {
|
|
|
5176
5827
|
}, [onInput, debounce]);
|
|
5177
5828
|
const handleInput = e => {
|
|
5178
5829
|
handleInputCallback(e);
|
|
5830
|
+
autoResize && resizeToContents(e.target);
|
|
5179
5831
|
setLocalValue(e.target.value);
|
|
5180
5832
|
};
|
|
5833
|
+
useLayoutEffect(() => {
|
|
5834
|
+
autoResize && resizeToContents(ref.current);
|
|
5835
|
+
}, []);
|
|
5181
5836
|
useEffect(() => {
|
|
5182
5837
|
if (value === localValue) {
|
|
5183
5838
|
return;
|
|
@@ -5195,7 +5850,7 @@ function TextArea(props) {
|
|
|
5195
5850
|
id: prefixId$2(id),
|
|
5196
5851
|
name: id,
|
|
5197
5852
|
spellCheck: "false",
|
|
5198
|
-
class: classnames('bio-properties-panel-input', monospace ? 'bio-properties-panel-input-monospace' : ''),
|
|
5853
|
+
class: classnames('bio-properties-panel-input', monospace ? 'bio-properties-panel-input-monospace' : '', autoResize ? 'auto-resize' : ''),
|
|
5199
5854
|
onInput: handleInput,
|
|
5200
5855
|
onFocus: onFocus,
|
|
5201
5856
|
onBlur: onBlur,
|
|
@@ -5207,20 +5862,20 @@ function TextArea(props) {
|
|
|
5207
5862
|
});
|
|
5208
5863
|
}
|
|
5209
5864
|
|
|
5210
|
-
/**
|
|
5211
|
-
* @param {object} props
|
|
5212
|
-
* @param {object} props.element
|
|
5213
|
-
* @param {string} props.id
|
|
5214
|
-
* @param {string} props.description
|
|
5215
|
-
* @param {boolean} props.debounce
|
|
5216
|
-
* @param {string} props.label
|
|
5217
|
-
* @param {Function} props.getValue
|
|
5218
|
-
* @param {Function} props.setValue
|
|
5219
|
-
* @param {Function} props.onFocus
|
|
5220
|
-
* @param {Function} props.onBlur
|
|
5221
|
-
* @param {number} props.rows
|
|
5222
|
-
* @param {boolean} props.monospace
|
|
5223
|
-
* @param {boolean} [props.disabled]
|
|
5865
|
+
/**
|
|
5866
|
+
* @param {object} props
|
|
5867
|
+
* @param {object} props.element
|
|
5868
|
+
* @param {string} props.id
|
|
5869
|
+
* @param {string} props.description
|
|
5870
|
+
* @param {boolean} props.debounce
|
|
5871
|
+
* @param {string} props.label
|
|
5872
|
+
* @param {Function} props.getValue
|
|
5873
|
+
* @param {Function} props.setValue
|
|
5874
|
+
* @param {Function} props.onFocus
|
|
5875
|
+
* @param {Function} props.onBlur
|
|
5876
|
+
* @param {number} props.rows
|
|
5877
|
+
* @param {boolean} props.monospace
|
|
5878
|
+
* @param {boolean} [props.disabled]
|
|
5224
5879
|
*/
|
|
5225
5880
|
function TextAreaEntry(props) {
|
|
5226
5881
|
const {
|
|
@@ -5235,7 +5890,8 @@ function TextAreaEntry(props) {
|
|
|
5235
5890
|
monospace,
|
|
5236
5891
|
disabled,
|
|
5237
5892
|
onFocus,
|
|
5238
|
-
onBlur
|
|
5893
|
+
onBlur,
|
|
5894
|
+
autoResize
|
|
5239
5895
|
} = props;
|
|
5240
5896
|
const value = getValue(element);
|
|
5241
5897
|
const error = useError(id);
|
|
@@ -5252,7 +5908,8 @@ function TextAreaEntry(props) {
|
|
|
5252
5908
|
rows: rows,
|
|
5253
5909
|
debounce: debounce,
|
|
5254
5910
|
monospace: monospace,
|
|
5255
|
-
disabled: disabled
|
|
5911
|
+
disabled: disabled,
|
|
5912
|
+
autoResize: autoResize
|
|
5256
5913
|
}, element), error && jsx("div", {
|
|
5257
5914
|
class: "bio-properties-panel-error",
|
|
5258
5915
|
children: error
|
|
@@ -5323,19 +5980,19 @@ function Textfield(props) {
|
|
|
5323
5980
|
});
|
|
5324
5981
|
}
|
|
5325
5982
|
|
|
5326
|
-
/**
|
|
5327
|
-
* @param {Object} props
|
|
5328
|
-
* @param {Object} props.element
|
|
5329
|
-
* @param {String} props.id
|
|
5330
|
-
* @param {String} props.description
|
|
5331
|
-
* @param {Boolean} props.debounce
|
|
5332
|
-
* @param {Boolean} props.disabled
|
|
5333
|
-
* @param {String} props.label
|
|
5334
|
-
* @param {Function} props.getValue
|
|
5335
|
-
* @param {Function} props.setValue
|
|
5336
|
-
* @param {Function} props.onFocus
|
|
5337
|
-
* @param {Function} props.onBlur
|
|
5338
|
-
* @param {Function} props.validate
|
|
5983
|
+
/**
|
|
5984
|
+
* @param {Object} props
|
|
5985
|
+
* @param {Object} props.element
|
|
5986
|
+
* @param {String} props.id
|
|
5987
|
+
* @param {String} props.description
|
|
5988
|
+
* @param {Boolean} props.debounce
|
|
5989
|
+
* @param {Boolean} props.disabled
|
|
5990
|
+
* @param {String} props.label
|
|
5991
|
+
* @param {Function} props.getValue
|
|
5992
|
+
* @param {Function} props.setValue
|
|
5993
|
+
* @param {Function} props.onFocus
|
|
5994
|
+
* @param {Function} props.onBlur
|
|
5995
|
+
* @param {Function} props.validate
|
|
5339
5996
|
*/
|
|
5340
5997
|
function TextfieldEntry(props) {
|
|
5341
5998
|
const {
|
|
@@ -5602,7 +6259,7 @@ function AltTextEntry(props) {
|
|
|
5602
6259
|
component: AltText,
|
|
5603
6260
|
editField: editField,
|
|
5604
6261
|
field: field,
|
|
5605
|
-
isEdited: isEdited$
|
|
6262
|
+
isEdited: isEdited$7
|
|
5606
6263
|
});
|
|
5607
6264
|
}
|
|
5608
6265
|
return entries;
|
|
@@ -5636,59 +6293,70 @@ function AltText(props) {
|
|
|
5636
6293
|
});
|
|
5637
6294
|
}
|
|
5638
6295
|
|
|
6296
|
+
const AUTO_OPTION_VALUE = '';
|
|
5639
6297
|
function ColumnsEntry(props) {
|
|
5640
6298
|
const {
|
|
5641
6299
|
editField,
|
|
5642
6300
|
field
|
|
5643
6301
|
} = props;
|
|
5644
|
-
const {
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
component: Columns,
|
|
5652
|
-
editField: editField,
|
|
5653
|
-
field: field,
|
|
5654
|
-
isEdited: isEdited$5
|
|
5655
|
-
});
|
|
5656
|
-
}
|
|
6302
|
+
const entries = [{
|
|
6303
|
+
id: 'columns',
|
|
6304
|
+
component: Columns,
|
|
6305
|
+
field,
|
|
6306
|
+
editField,
|
|
6307
|
+
isEdited: isEdited$4
|
|
6308
|
+
}];
|
|
5657
6309
|
return entries;
|
|
5658
6310
|
}
|
|
5659
6311
|
function Columns(props) {
|
|
5660
6312
|
const {
|
|
5661
|
-
editField,
|
|
5662
6313
|
field,
|
|
6314
|
+
editField,
|
|
5663
6315
|
id
|
|
5664
6316
|
} = props;
|
|
5665
6317
|
const debounce = useService('debounce');
|
|
5666
|
-
const
|
|
5667
|
-
|
|
6318
|
+
const formLayoutValidator = useService('formLayoutValidator');
|
|
6319
|
+
const validate = value => {
|
|
6320
|
+
return formLayoutValidator.validateField(field, value ? parseInt(value) : null);
|
|
5668
6321
|
};
|
|
5669
6322
|
const setValue = value => {
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
components.push(Default.create({
|
|
5674
|
-
_parent: field.id
|
|
5675
|
-
}));
|
|
5676
|
-
}
|
|
5677
|
-
} else {
|
|
5678
|
-
components = components.slice(0, value);
|
|
5679
|
-
}
|
|
5680
|
-
editField(field, 'components', components);
|
|
6323
|
+
const layout = get(field, ['layout'], {});
|
|
6324
|
+
const newValue = value ? parseInt(value) : null;
|
|
6325
|
+
editField(field, ['layout'], set$1(layout, ['columns'], newValue));
|
|
5681
6326
|
};
|
|
5682
|
-
|
|
6327
|
+
const getValue = () => {
|
|
6328
|
+
return get(field, ['layout', 'columns']);
|
|
6329
|
+
};
|
|
6330
|
+
const getOptions = () => {
|
|
6331
|
+
return [{
|
|
6332
|
+
label: 'Auto',
|
|
6333
|
+
value: AUTO_OPTION_VALUE
|
|
6334
|
+
},
|
|
6335
|
+
// todo(pinussilvestrus): make options dependant on field type
|
|
6336
|
+
// cf. https://github.com/bpmn-io/form-js/issues/575
|
|
6337
|
+
...[2, 4, 6, 8, 10, 12, 14, 16].map(asOption)];
|
|
6338
|
+
};
|
|
6339
|
+
return SelectEntry({
|
|
5683
6340
|
debounce,
|
|
5684
6341
|
element: field,
|
|
5685
|
-
getValue,
|
|
5686
6342
|
id,
|
|
5687
6343
|
label: 'Columns',
|
|
5688
|
-
|
|
6344
|
+
getOptions,
|
|
6345
|
+
getValue,
|
|
6346
|
+
setValue,
|
|
6347
|
+
validate
|
|
5689
6348
|
});
|
|
5690
6349
|
}
|
|
5691
6350
|
|
|
6351
|
+
// helper /////////
|
|
6352
|
+
|
|
6353
|
+
function asOption(number) {
|
|
6354
|
+
return {
|
|
6355
|
+
value: number,
|
|
6356
|
+
label: number.toString()
|
|
6357
|
+
};
|
|
6358
|
+
}
|
|
6359
|
+
|
|
5692
6360
|
function DescriptionEntry(props) {
|
|
5693
6361
|
const {
|
|
5694
6362
|
editField,
|
|
@@ -5733,6 +6401,7 @@ function Description(props) {
|
|
|
5733
6401
|
});
|
|
5734
6402
|
}
|
|
5735
6403
|
|
|
6404
|
+
const EMPTY_OPTION = null;
|
|
5736
6405
|
function DefaultOptionEntry(props) {
|
|
5737
6406
|
const {
|
|
5738
6407
|
editField,
|
|
@@ -5878,13 +6547,14 @@ function DefaultValueSingleSelect(props) {
|
|
|
5878
6547
|
label
|
|
5879
6548
|
} = props;
|
|
5880
6549
|
const {
|
|
5881
|
-
defaultValue,
|
|
6550
|
+
defaultValue = EMPTY_OPTION,
|
|
5882
6551
|
values = []
|
|
5883
6552
|
} = field;
|
|
5884
6553
|
const path = ['defaultValue'];
|
|
5885
6554
|
const getOptions = () => {
|
|
5886
6555
|
return [{
|
|
5887
|
-
label: '<none>'
|
|
6556
|
+
label: '<none>',
|
|
6557
|
+
value: EMPTY_OPTION
|
|
5888
6558
|
}, ...values];
|
|
5889
6559
|
};
|
|
5890
6560
|
const setValue = value => {
|
|
@@ -5981,7 +6651,7 @@ function DisabledEntry(props) {
|
|
|
5981
6651
|
component: Disabled,
|
|
5982
6652
|
editField: editField,
|
|
5983
6653
|
field: field,
|
|
5984
|
-
isEdited: isEdited$
|
|
6654
|
+
isEdited: isEdited$8
|
|
5985
6655
|
});
|
|
5986
6656
|
}
|
|
5987
6657
|
return entries;
|
|
@@ -6191,6 +6861,7 @@ function simpleBoolEntryFactory(options) {
|
|
|
6191
6861
|
const {
|
|
6192
6862
|
id,
|
|
6193
6863
|
label,
|
|
6864
|
+
description,
|
|
6194
6865
|
path,
|
|
6195
6866
|
props
|
|
6196
6867
|
} = options;
|
|
@@ -6204,8 +6875,9 @@ function simpleBoolEntryFactory(options) {
|
|
|
6204
6875
|
path,
|
|
6205
6876
|
field,
|
|
6206
6877
|
editField,
|
|
6878
|
+
description,
|
|
6207
6879
|
component: SimpleBoolComponent,
|
|
6208
|
-
isEdited: isEdited$
|
|
6880
|
+
isEdited: isEdited$8
|
|
6209
6881
|
};
|
|
6210
6882
|
}
|
|
6211
6883
|
const SimpleBoolComponent = props => {
|
|
@@ -6214,7 +6886,8 @@ const SimpleBoolComponent = props => {
|
|
|
6214
6886
|
label,
|
|
6215
6887
|
path,
|
|
6216
6888
|
field,
|
|
6217
|
-
editField
|
|
6889
|
+
editField,
|
|
6890
|
+
description
|
|
6218
6891
|
} = props;
|
|
6219
6892
|
const getValue = () => get(field, path, '');
|
|
6220
6893
|
const setValue = value => editField(field, path, value);
|
|
@@ -6223,7 +6896,8 @@ const SimpleBoolComponent = props => {
|
|
|
6223
6896
|
getValue,
|
|
6224
6897
|
id,
|
|
6225
6898
|
label,
|
|
6226
|
-
setValue
|
|
6899
|
+
setValue,
|
|
6900
|
+
description
|
|
6227
6901
|
});
|
|
6228
6902
|
};
|
|
6229
6903
|
|
|
@@ -6279,7 +6953,7 @@ function SourceEntry(props) {
|
|
|
6279
6953
|
component: Source,
|
|
6280
6954
|
editField: editField,
|
|
6281
6955
|
field: field,
|
|
6282
|
-
isEdited: isEdited$
|
|
6956
|
+
isEdited: isEdited$7
|
|
6283
6957
|
});
|
|
6284
6958
|
}
|
|
6285
6959
|
return entries;
|
|
@@ -6317,21 +6991,38 @@ function Source(props) {
|
|
|
6317
6991
|
function TextEntry(props) {
|
|
6318
6992
|
const {
|
|
6319
6993
|
editField,
|
|
6994
|
+
/* getService, */
|
|
6320
6995
|
field
|
|
6321
6996
|
} = props;
|
|
6322
6997
|
const {
|
|
6323
6998
|
type
|
|
6324
6999
|
} = field;
|
|
7000
|
+
|
|
7001
|
+
// const templating = getService('templating');
|
|
7002
|
+
|
|
6325
7003
|
if (type !== 'text') {
|
|
6326
7004
|
return [];
|
|
6327
7005
|
}
|
|
6328
|
-
|
|
7006
|
+
const entries = [{
|
|
6329
7007
|
id: 'text',
|
|
6330
7008
|
component: Text,
|
|
6331
7009
|
editField: editField,
|
|
6332
7010
|
field: field,
|
|
6333
|
-
isEdited: isEdited$
|
|
7011
|
+
isEdited: isEdited$7
|
|
6334
7012
|
}];
|
|
7013
|
+
|
|
7014
|
+
// todo: skipped to make the release without too much risk
|
|
7015
|
+
// if (templating.isTemplate(field.text)) {
|
|
7016
|
+
// entries.push(simpleBoolEntryFactory({
|
|
7017
|
+
// id: 'strict',
|
|
7018
|
+
// path: [ 'strict' ],
|
|
7019
|
+
// label: 'Strict templating',
|
|
7020
|
+
// description: 'Enforces types to be correct',
|
|
7021
|
+
// props
|
|
7022
|
+
// }));
|
|
7023
|
+
// }
|
|
7024
|
+
|
|
7025
|
+
return entries;
|
|
6335
7026
|
}
|
|
6336
7027
|
function Text(props) {
|
|
6337
7028
|
const {
|
|
@@ -6350,15 +7041,21 @@ function Text(props) {
|
|
|
6350
7041
|
const setValue = value => {
|
|
6351
7042
|
return editField(field, path, value);
|
|
6352
7043
|
};
|
|
6353
|
-
|
|
7044
|
+
const description = useMemo(() => jsxs(Fragment, {
|
|
7045
|
+
children: ["Supports markdown and templating. ", jsx("a", {
|
|
7046
|
+
href: "https://docs.camunda.io/docs/components/modeler/forms/form-element-library/forms-element-library-text/",
|
|
7047
|
+
target: "_blank",
|
|
7048
|
+
children: "Learn more"
|
|
7049
|
+
})]
|
|
7050
|
+
}), []);
|
|
7051
|
+
return FeelTemplatingEntry({
|
|
6354
7052
|
debounce,
|
|
6355
|
-
description
|
|
7053
|
+
description,
|
|
6356
7054
|
element: field,
|
|
6357
|
-
feel: 'optional',
|
|
6358
7055
|
getValue,
|
|
6359
7056
|
id,
|
|
6360
7057
|
label: 'Text',
|
|
6361
|
-
|
|
7058
|
+
hostLanguage: 'markdown',
|
|
6362
7059
|
setValue,
|
|
6363
7060
|
variables
|
|
6364
7061
|
});
|
|
@@ -6474,7 +7171,7 @@ function NumberSerializationEntry(props) {
|
|
|
6474
7171
|
entries.push({
|
|
6475
7172
|
id: 'serialize-to-string',
|
|
6476
7173
|
component: SerializeToString,
|
|
6477
|
-
isEdited: isEdited$
|
|
7174
|
+
isEdited: isEdited$8,
|
|
6478
7175
|
editField,
|
|
6479
7176
|
field
|
|
6480
7177
|
});
|
|
@@ -6533,7 +7230,7 @@ function DateTimeEntry(props) {
|
|
|
6533
7230
|
entries.push({
|
|
6534
7231
|
id: 'use24h',
|
|
6535
7232
|
component: Use24h,
|
|
6536
|
-
isEdited: isEdited$
|
|
7233
|
+
isEdited: isEdited$8,
|
|
6537
7234
|
editField,
|
|
6538
7235
|
field
|
|
6539
7236
|
});
|
|
@@ -6646,7 +7343,7 @@ function DateTimeConstraintsEntry(props) {
|
|
|
6646
7343
|
entries.push({
|
|
6647
7344
|
id: id + '-disallowPassedDates',
|
|
6648
7345
|
component: DisallowPassedDates,
|
|
6649
|
-
isEdited: isEdited$
|
|
7346
|
+
isEdited: isEdited$8,
|
|
6650
7347
|
editField,
|
|
6651
7348
|
field
|
|
6652
7349
|
});
|
|
@@ -7021,11 +7718,19 @@ function InputKeyValuesSourceEntry(props) {
|
|
|
7021
7718
|
field,
|
|
7022
7719
|
id
|
|
7023
7720
|
} = props;
|
|
7721
|
+
const schema = '[\n {\n "label": "dollar",\n "value": "$"\n }\n]';
|
|
7722
|
+
const description = jsxs("div", {
|
|
7723
|
+
children: ["Define which input property to populate the values from.", jsx("br", {}), jsx("br", {}), "The input property may be an array of simple values or alternatively follow this schema:", jsx("pre", {
|
|
7724
|
+
children: jsx("code", {
|
|
7725
|
+
children: schema
|
|
7726
|
+
})
|
|
7727
|
+
})]
|
|
7728
|
+
});
|
|
7024
7729
|
return [{
|
|
7025
7730
|
id: id + '-key',
|
|
7026
7731
|
component: InputValuesKey,
|
|
7027
7732
|
label: 'Input values key',
|
|
7028
|
-
description
|
|
7733
|
+
description,
|
|
7029
7734
|
isEdited: isEdited$1,
|
|
7030
7735
|
editField,
|
|
7031
7736
|
field
|
|
@@ -7220,7 +7925,7 @@ function ConditionEntry(props) {
|
|
|
7220
7925
|
component: Condition,
|
|
7221
7926
|
editField: editField,
|
|
7222
7927
|
field: field,
|
|
7223
|
-
isEdited: isEdited$
|
|
7928
|
+
isEdited: isEdited$7
|
|
7224
7929
|
}];
|
|
7225
7930
|
}
|
|
7226
7931
|
function Condition(props) {
|
|
@@ -7258,7 +7963,7 @@ function Condition(props) {
|
|
|
7258
7963
|
});
|
|
7259
7964
|
}
|
|
7260
7965
|
|
|
7261
|
-
function GeneralGroup(field, editField) {
|
|
7966
|
+
function GeneralGroup(field, editField, getService) {
|
|
7262
7967
|
const entries = [...IdEntry({
|
|
7263
7968
|
field,
|
|
7264
7969
|
editField
|
|
@@ -7277,15 +7982,13 @@ function GeneralGroup(field, editField) {
|
|
|
7277
7982
|
}), ...ActionEntry({
|
|
7278
7983
|
field,
|
|
7279
7984
|
editField
|
|
7280
|
-
}), ...ColumnsEntry({
|
|
7281
|
-
field,
|
|
7282
|
-
editField
|
|
7283
7985
|
}), ...DateTimeEntry({
|
|
7284
7986
|
field,
|
|
7285
7987
|
editField
|
|
7286
7988
|
}), ...TextEntry({
|
|
7287
7989
|
field,
|
|
7288
|
-
editField
|
|
7990
|
+
editField,
|
|
7991
|
+
getService
|
|
7289
7992
|
}), ...NumberEntries({
|
|
7290
7993
|
field,
|
|
7291
7994
|
editField
|
|
@@ -7381,7 +8084,7 @@ function ValidationGroup(field, editField) {
|
|
|
7381
8084
|
component: Required,
|
|
7382
8085
|
getValue,
|
|
7383
8086
|
field,
|
|
7384
|
-
isEdited: isEdited$
|
|
8087
|
+
isEdited: isEdited$8,
|
|
7385
8088
|
onChange
|
|
7386
8089
|
}];
|
|
7387
8090
|
if (type === 'textfield') {
|
|
@@ -7723,6 +8426,27 @@ function AppearanceGroup(field, editField) {
|
|
|
7723
8426
|
};
|
|
7724
8427
|
}
|
|
7725
8428
|
|
|
8429
|
+
function LayoutGroup(field, editField) {
|
|
8430
|
+
const {
|
|
8431
|
+
type
|
|
8432
|
+
} = field;
|
|
8433
|
+
if (type === 'default') {
|
|
8434
|
+
return null;
|
|
8435
|
+
}
|
|
8436
|
+
const entries = [...ColumnsEntry({
|
|
8437
|
+
field,
|
|
8438
|
+
editField
|
|
8439
|
+
})];
|
|
8440
|
+
if (entries.length === 0) {
|
|
8441
|
+
return null;
|
|
8442
|
+
}
|
|
8443
|
+
return {
|
|
8444
|
+
id: 'layout',
|
|
8445
|
+
label: 'Layout',
|
|
8446
|
+
entries
|
|
8447
|
+
};
|
|
8448
|
+
}
|
|
8449
|
+
|
|
7726
8450
|
function ConditionGroup(field, editField) {
|
|
7727
8451
|
const {
|
|
7728
8452
|
type
|
|
@@ -7741,11 +8465,11 @@ function ConditionGroup(field, editField) {
|
|
|
7741
8465
|
};
|
|
7742
8466
|
}
|
|
7743
8467
|
|
|
7744
|
-
function getGroups(field, editField) {
|
|
8468
|
+
function getGroups(field, editField, getService) {
|
|
7745
8469
|
if (!field) {
|
|
7746
8470
|
return [];
|
|
7747
8471
|
}
|
|
7748
|
-
const groups = [GeneralGroup(field, editField), ConditionGroup(field, editField), AppearanceGroup(field, editField), SerializationGroup(field, editField), ...ValuesGroups(field, editField), ConstraintsGroup(field, editField), ValidationGroup(field, editField), CustomValuesGroup(field, editField)];
|
|
8472
|
+
const groups = [GeneralGroup(field, editField, getService), ConditionGroup(field, editField), LayoutGroup(field, editField), AppearanceGroup(field, editField), SerializationGroup(field, editField), ...ValuesGroups(field, editField), ConstraintsGroup(field, editField), ValidationGroup(field, editField), CustomValuesGroup(field, editField)];
|
|
7749
8473
|
|
|
7750
8474
|
// contract: if a group returns null, it should not be displayed at all
|
|
7751
8475
|
return groups.filter(group => group !== null);
|
|
@@ -7798,10 +8522,9 @@ function FormPropertiesPanel(props) {
|
|
|
7798
8522
|
};
|
|
7799
8523
|
}, []);
|
|
7800
8524
|
const selectedFormField = state.selectedFormField;
|
|
8525
|
+
const getService = (type, strict = true) => injector.get(type, strict);
|
|
7801
8526
|
const propertiesPanelContext = {
|
|
7802
|
-
getService
|
|
7803
|
-
return injector.get(type, strict);
|
|
7804
|
-
}
|
|
8527
|
+
getService
|
|
7805
8528
|
};
|
|
7806
8529
|
const onFocus = () => eventBus.fire('propertiesPanel.focusin');
|
|
7807
8530
|
const onBlur = () => eventBus.fire('propertiesPanel.focusout');
|
|
@@ -7816,7 +8539,7 @@ function FormPropertiesPanel(props) {
|
|
|
7816
8539
|
children: jsx(PropertiesPanel, {
|
|
7817
8540
|
element: selectedFormField,
|
|
7818
8541
|
eventBus: eventBus,
|
|
7819
|
-
groups: getGroups(selectedFormField, editField),
|
|
8542
|
+
groups: getGroups(selectedFormField, editField, getService),
|
|
7820
8543
|
headerProvider: PropertiesPanelHeaderProvider,
|
|
7821
8544
|
placeholderProvider: PropertiesPanelPlaceholderProvider
|
|
7822
8545
|
})
|
|
@@ -7894,6 +8617,12 @@ var PropertiesPanelModule = {
|
|
|
7894
8617
|
propertiesPanel: ['type', PropertiesPanelRenderer]
|
|
7895
8618
|
};
|
|
7896
8619
|
|
|
8620
|
+
var ExpressionLanguageModule = {
|
|
8621
|
+
__init__: ['expressionLanguage', 'templating'],
|
|
8622
|
+
expressionLanguage: ['type', FeelExpressionLanguage],
|
|
8623
|
+
templating: ['type', FeelersTemplating]
|
|
8624
|
+
};
|
|
8625
|
+
|
|
7897
8626
|
const ids = new Ids([32, 36, 1]);
|
|
7898
8627
|
|
|
7899
8628
|
/**
|
|
@@ -8146,7 +8875,7 @@ class FormEditor {
|
|
|
8146
8875
|
* @internal
|
|
8147
8876
|
*/
|
|
8148
8877
|
_getModules() {
|
|
8149
|
-
return [ModelingModule, EditorActionsModule, KeyboardModule, SelectionModule, PaletteModule, PropertiesPanelModule];
|
|
8878
|
+
return [ModelingModule, EditorActionsModule, DraggingModule, KeyboardModule, SelectionModule, PaletteModule, ExpressionLanguageModule, MarkdownModule, PropertiesPanelModule];
|
|
8150
8879
|
}
|
|
8151
8880
|
|
|
8152
8881
|
/**
|