@bpmn-io/form-js-editor 0.7.1 → 0.8.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/assets/form-js-editor.css +26 -214
- package/dist/assets/properties-panel.css +930 -0
- package/dist/index.cjs +3099 -1072
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +3036 -1010
- package/dist/index.es.js.map +1 -1
- package/dist/types/FormEditor.d.ts +6 -4
- package/dist/types/features/palette/PaletteRenderer.d.ts +33 -0
- package/dist/types/{render/components/palette → features/palette/components}/Palette.d.ts +0 -0
- package/dist/types/features/palette/index.d.ts +5 -0
- package/dist/types/render/Renderer.d.ts +1 -1
- package/dist/types/render/components/{palette/icons → icons}/index.d.ts +2 -0
- package/dist/types/render/components/properties-panel/PropertiesPanel.d.ts +1 -1
- package/dist/types/render/components/properties-panel/PropertiesPanelHeaderProvider.d.ts +5 -0
- package/dist/types/render/components/properties-panel/PropertiesPanelPlaceholderProvider.d.ts +8 -0
- package/dist/types/render/components/properties-panel/Util.d.ts +1 -0
- package/dist/types/render/components/properties-panel/entries/ActionEntry.d.ts +9 -1
- package/dist/types/render/components/properties-panel/entries/ColumnsEntry.d.ts +9 -1
- package/dist/types/render/components/properties-panel/entries/CustomValueEntry.d.ts +11 -1
- package/dist/types/render/components/properties-panel/entries/DefaultValueEntry.d.ts +1 -1
- package/dist/types/render/components/properties-panel/entries/DescriptionEntry.d.ts +9 -1
- package/dist/types/render/components/properties-panel/entries/DisabledEntry.d.ts +9 -1
- package/dist/types/render/components/properties-panel/entries/IdEntry.d.ts +9 -1
- package/dist/types/render/components/properties-panel/entries/InputKeyValuesSourceEntry.d.ts +11 -0
- package/dist/types/render/components/properties-panel/entries/KeyEntry.d.ts +9 -1
- package/dist/types/render/components/properties-panel/entries/LabelEntry.d.ts +9 -1
- package/dist/types/render/components/properties-panel/entries/StaticValuesSourceEntry.d.ts +4 -0
- package/dist/types/render/components/properties-panel/entries/TextEntry.d.ts +9 -1
- package/dist/types/render/components/properties-panel/entries/ValueEntry.d.ts +11 -1
- package/dist/types/render/components/properties-panel/entries/ValuesSourceSelectEntry.d.ts +9 -0
- package/dist/types/render/components/properties-panel/entries/ValuesSourceUtil.d.ts +15 -0
- package/dist/types/render/components/properties-panel/entries/index.d.ts +3 -0
- package/dist/types/render/components/properties-panel/groups/CustomValuesGroup.d.ts +22 -1
- package/dist/types/render/components/properties-panel/groups/GeneralGroup.d.ts +5 -1
- package/dist/types/render/components/properties-panel/groups/ValidationGroup.d.ts +14 -1
- package/dist/types/render/components/properties-panel/groups/ValuesGroups.d.ts +1 -0
- package/dist/types/render/components/properties-panel/groups/index.d.ts +1 -1
- package/package.json +5 -4
- package/dist/types/render/components/properties-panel/components/CheckboxInput.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/CheckboxInputEntry.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/CollapsibleEntry.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/Group.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/NumberInput.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/NumberInputEntry.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/Select.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/SelectEntry.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/TextInput.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/TextInputEntry.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/Textarea.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/TextareaEntry.d.ts +0 -1
- package/dist/types/render/components/properties-panel/components/index.d.ts +0 -12
- package/dist/types/render/components/properties-panel/groups/ValuesGroup.d.ts +0 -1
package/dist/index.es.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { FormFieldRegistry as FormFieldRegistry$1, clone, Default, FormContext, FormRenderContext, FormComponent, FormFields, createFormContainer, createInjector, schemaVersion } from '@bpmn-io/form-js-viewer';
|
|
2
2
|
export { schemaVersion } from '@bpmn-io/form-js-viewer';
|
|
3
3
|
import Ids from 'ids';
|
|
4
|
-
import { isArray, isFunction, isNumber, bind, assign, debounce, get, isUndefined,
|
|
5
|
-
import { createContext, render } from 'preact';
|
|
6
|
-
import { useContext,
|
|
4
|
+
import { isArray, isFunction, isNumber, bind, assign, debounce, sortBy, find, get, set, isUndefined, without, has, forEach, isObject, uniqueBy, isString } from 'min-dash';
|
|
5
|
+
import { createContext, createElement, render } from 'preact';
|
|
6
|
+
import { useContext, useState, useEffect, useRef, useCallback, useMemo } from 'preact/hooks';
|
|
7
|
+
import classnames from 'classnames';
|
|
7
8
|
import React from 'preact/compat';
|
|
8
|
-
import {
|
|
9
|
+
import { jsx, jsxs } from 'preact/jsx-runtime';
|
|
10
|
+
import { query, matches, closest, event, domify } from 'min-dom';
|
|
9
11
|
import dragula from 'dragula';
|
|
10
|
-
import { matches, closest, event } from 'min-dom';
|
|
11
12
|
import { mutate } from 'array-move';
|
|
12
13
|
|
|
13
14
|
var FN_REF = '__fn';
|
|
14
|
-
var DEFAULT_PRIORITY$
|
|
15
|
+
var DEFAULT_PRIORITY$3 = 1000;
|
|
15
16
|
var slice = Array.prototype.slice;
|
|
16
17
|
/**
|
|
17
18
|
* A general purpose event bus.
|
|
@@ -127,7 +128,7 @@ EventBus.prototype.on = function (events, priority, callback, that) {
|
|
|
127
128
|
if (isFunction(priority)) {
|
|
128
129
|
that = callback;
|
|
129
130
|
callback = priority;
|
|
130
|
-
priority = DEFAULT_PRIORITY$
|
|
131
|
+
priority = DEFAULT_PRIORITY$3;
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
if (!isNumber(priority)) {
|
|
@@ -169,7 +170,7 @@ EventBus.prototype.once = function (event, priority, callback, that) {
|
|
|
169
170
|
if (isFunction(priority)) {
|
|
170
171
|
that = callback;
|
|
171
172
|
callback = priority;
|
|
172
|
-
priority = DEFAULT_PRIORITY$
|
|
173
|
+
priority = DEFAULT_PRIORITY$3;
|
|
173
174
|
}
|
|
174
175
|
|
|
175
176
|
if (!isNumber(priority)) {
|
|
@@ -765,36 +766,1710 @@ function useService (type, strict) {
|
|
|
765
766
|
return getService(type, strict);
|
|
766
767
|
}
|
|
767
768
|
|
|
768
|
-
|
|
769
|
+
var ArrowIcon = function ArrowIcon(props) {
|
|
770
|
+
return jsx("svg", { ...props,
|
|
771
|
+
children: jsx("path", {
|
|
772
|
+
fillRule: "evenodd",
|
|
773
|
+
d: "m11.657 8-4.95 4.95a1 1 0 0 1-1.414-1.414L8.828 8 5.293 4.464A1 1 0 1 1 6.707 3.05L11.657 8z"
|
|
774
|
+
})
|
|
775
|
+
});
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
ArrowIcon.defaultProps = {
|
|
779
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
780
|
+
width: "16",
|
|
781
|
+
height: "16"
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
var CreateIcon = function CreateIcon(props) {
|
|
785
|
+
return jsx("svg", { ...props,
|
|
786
|
+
children: jsx("path", {
|
|
787
|
+
fillRule: "evenodd",
|
|
788
|
+
d: "M9 13V9h4a1 1 0 0 0 0-2H9V3a1 1 0 1 0-2 0v4H3a1 1 0 1 0 0 2h4v4a1 1 0 0 0 2 0z"
|
|
789
|
+
})
|
|
790
|
+
});
|
|
791
|
+
};
|
|
792
|
+
|
|
793
|
+
CreateIcon.defaultProps = {
|
|
794
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
795
|
+
width: "16",
|
|
796
|
+
height: "16"
|
|
797
|
+
};
|
|
798
|
+
|
|
799
|
+
var DeleteIcon = function DeleteIcon(props) {
|
|
800
|
+
return jsx("svg", { ...props,
|
|
801
|
+
children: jsx("path", {
|
|
802
|
+
fillRule: "evenodd",
|
|
803
|
+
d: "M12 6v7c0 1.1-.4 1.55-1.5 1.55h-5C4.4 14.55 4 14.1 4 13V6h8zm-1.5 1.5h-5v4.3c0 .66.5 1.2 1.111 1.2H9.39c.611 0 1.111-.54 1.111-1.2V7.5zM13 3h-2l-1-1H6L5 3H3v1.5h10V3z"
|
|
804
|
+
})
|
|
805
|
+
});
|
|
806
|
+
};
|
|
807
|
+
|
|
808
|
+
DeleteIcon.defaultProps = {
|
|
809
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
810
|
+
width: "16",
|
|
811
|
+
height: "16"
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
var ExternalLinkIcon = function ExternalLinkIcon(props) {
|
|
815
|
+
return jsx("svg", { ...props,
|
|
816
|
+
children: jsx("path", {
|
|
817
|
+
fillRule: "evenodd",
|
|
818
|
+
clipRule: "evenodd",
|
|
819
|
+
d: "M12.637 12.637v-4.72h1.362v4.721c0 .36-.137.676-.411.95-.275.275-.591.412-.95.412H3.362c-.38 0-.703-.132-.967-.396A1.315 1.315 0 0 1 2 12.638V3.362c0-.38.132-.703.396-.967S2.982 2 3.363 2h4.553v1.363H3.363v9.274h9.274zM14 2H9.28l-.001 1.362h2.408L5.065 9.984l.95.95 6.622-6.622v2.409H14V2z",
|
|
820
|
+
fill: "#818798"
|
|
821
|
+
})
|
|
822
|
+
});
|
|
823
|
+
};
|
|
824
|
+
|
|
825
|
+
ExternalLinkIcon.defaultProps = {
|
|
826
|
+
width: "16",
|
|
827
|
+
height: "16",
|
|
828
|
+
fill: "none",
|
|
829
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
830
|
+
};
|
|
831
|
+
|
|
832
|
+
var FeelRequiredIcon = function FeelRequiredIcon(props) {
|
|
833
|
+
return jsxs("svg", { ...props,
|
|
834
|
+
children: [jsx("path", {
|
|
835
|
+
d: "M5.8 7.06V5.95h4.307v1.11H5.8zm0 3.071v-1.11h4.307v1.11H5.8z",
|
|
836
|
+
fill: "#505562"
|
|
837
|
+
}), jsx("path", {
|
|
838
|
+
fillRule: "evenodd",
|
|
839
|
+
clipRule: "evenodd",
|
|
840
|
+
d: "M8 3.268A4.732 4.732 0 1 0 12.732 8H14a6 6 0 1 1-6-6v1.268z",
|
|
841
|
+
fill: "#505562"
|
|
842
|
+
}), jsx("path", {
|
|
843
|
+
d: "m11.28 6.072-.832-.56 1.016-1.224L10 3.848l.312-.912 1.392.584L11.632 2h1.032l-.072 1.52 1.392-.584.312.912-1.464.44 1.008 1.224-.832.552-.864-1.296-.864 1.304z",
|
|
844
|
+
fill: "#505562"
|
|
845
|
+
})]
|
|
846
|
+
});
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
FeelRequiredIcon.defaultProps = {
|
|
850
|
+
viewBox: "0 0 16 16",
|
|
851
|
+
fill: "none",
|
|
852
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
853
|
+
};
|
|
854
|
+
|
|
855
|
+
var FeelOptionalIcon = function FeelOptionalIcon(props) {
|
|
856
|
+
return jsxs("svg", { ...props,
|
|
857
|
+
children: [jsx("path", {
|
|
858
|
+
d: "M5.845 7.04V5.93h4.307v1.11H5.845zm0 3.07V9h4.307v1.11H5.845z",
|
|
859
|
+
fill: "#505562"
|
|
860
|
+
}), jsx("path", {
|
|
861
|
+
fillRule: "evenodd",
|
|
862
|
+
clipRule: "evenodd",
|
|
863
|
+
d: "M3.286 8a4.714 4.714 0 1 0 9.428 0 4.714 4.714 0 0 0-9.428 0zM8 2a6 6 0 1 0 0 12A6 6 0 0 0 8 2z",
|
|
864
|
+
fill: "#505562"
|
|
865
|
+
})]
|
|
866
|
+
});
|
|
867
|
+
};
|
|
868
|
+
|
|
869
|
+
FeelOptionalIcon.defaultProps = {
|
|
870
|
+
viewBox: "0 0 16 16",
|
|
871
|
+
fill: "none",
|
|
872
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
873
|
+
};
|
|
874
|
+
|
|
875
|
+
function Header(props) {
|
|
876
|
+
const {
|
|
877
|
+
element,
|
|
878
|
+
headerProvider
|
|
879
|
+
} = props;
|
|
880
|
+
const {
|
|
881
|
+
getElementIcon,
|
|
882
|
+
getDocumentationRef,
|
|
883
|
+
getElementLabel,
|
|
884
|
+
getTypeLabel
|
|
885
|
+
} = headerProvider;
|
|
886
|
+
const label = getElementLabel(element);
|
|
887
|
+
const type = getTypeLabel(element);
|
|
888
|
+
const documentationRef = getDocumentationRef && getDocumentationRef(element);
|
|
889
|
+
const ElementIcon = getElementIcon(element);
|
|
890
|
+
return jsxs("div", {
|
|
891
|
+
class: "bio-properties-panel-header",
|
|
892
|
+
children: [jsx("div", {
|
|
893
|
+
class: "bio-properties-panel-header-icon",
|
|
894
|
+
children: ElementIcon && jsx(ElementIcon, {
|
|
895
|
+
width: "32",
|
|
896
|
+
height: "32",
|
|
897
|
+
viewBox: "0 0 32 32"
|
|
898
|
+
})
|
|
899
|
+
}), jsxs("div", {
|
|
900
|
+
class: "bio-properties-panel-header-labels",
|
|
901
|
+
children: [jsx("div", {
|
|
902
|
+
title: type,
|
|
903
|
+
class: "bio-properties-panel-header-type",
|
|
904
|
+
children: type
|
|
905
|
+
}), label ? jsx("div", {
|
|
906
|
+
title: label,
|
|
907
|
+
class: "bio-properties-panel-header-label",
|
|
908
|
+
children: label
|
|
909
|
+
}) : null]
|
|
910
|
+
}), jsx("div", {
|
|
911
|
+
class: "bio-properties-panel-header-actions",
|
|
912
|
+
children: documentationRef ? jsx("a", {
|
|
913
|
+
rel: "noopener",
|
|
914
|
+
class: "bio-properties-panel-header-link",
|
|
915
|
+
href: documentationRef,
|
|
916
|
+
title: "Open documentation",
|
|
917
|
+
target: "_blank",
|
|
918
|
+
children: jsx(ExternalLinkIcon, {})
|
|
919
|
+
}) : null
|
|
920
|
+
})]
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
const DescriptionContext = createContext({
|
|
925
|
+
description: {},
|
|
926
|
+
getDescriptionForId: () => {}
|
|
927
|
+
});
|
|
928
|
+
/**
|
|
929
|
+
* @typedef {Function} <propertiesPanel.showEntry> callback
|
|
930
|
+
*
|
|
931
|
+
* @example
|
|
932
|
+
*
|
|
933
|
+
* useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
|
|
934
|
+
* // ...
|
|
935
|
+
* });
|
|
936
|
+
*
|
|
937
|
+
* @param {Object} context
|
|
938
|
+
* @param {boolean} [context.focus]
|
|
939
|
+
*
|
|
940
|
+
* @returns void
|
|
941
|
+
*/
|
|
942
|
+
|
|
943
|
+
const EventContext = createContext({
|
|
944
|
+
eventBus: null
|
|
945
|
+
});
|
|
946
|
+
const LayoutContext = createContext({
|
|
947
|
+
layout: {},
|
|
948
|
+
setLayout: () => {},
|
|
949
|
+
getLayoutForKey: () => {},
|
|
950
|
+
setLayoutForKey: () => {}
|
|
951
|
+
});
|
|
952
|
+
/**
|
|
953
|
+
* Accesses the global DescriptionContext and returns a description for a given id and element.
|
|
954
|
+
*
|
|
955
|
+
* @example
|
|
956
|
+
* ```jsx
|
|
957
|
+
* function TextField(props) {
|
|
958
|
+
* const description = useDescriptionContext('input1', element);
|
|
959
|
+
* }
|
|
960
|
+
* ```
|
|
961
|
+
*
|
|
962
|
+
* @param {string} id
|
|
963
|
+
* @param {object} element
|
|
964
|
+
*
|
|
965
|
+
* @returns {string}
|
|
966
|
+
*/
|
|
967
|
+
|
|
968
|
+
function useDescriptionContext(id, element) {
|
|
969
|
+
const {
|
|
970
|
+
getDescriptionForId
|
|
971
|
+
} = useContext(DescriptionContext);
|
|
972
|
+
return getDescriptionForId(id, element);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
const DEFAULT_PRIORITY$2 = 1000;
|
|
976
|
+
/**
|
|
977
|
+
* Subscribe to an event.
|
|
978
|
+
*
|
|
979
|
+
* @param {string} event
|
|
980
|
+
* @param {Function} callback
|
|
981
|
+
* @param {number} [priority]
|
|
982
|
+
*
|
|
983
|
+
* @returns {import('preact').Ref}
|
|
984
|
+
*/
|
|
985
|
+
|
|
986
|
+
function useEvent(event, callback, priority = DEFAULT_PRIORITY$2) {
|
|
987
|
+
const {
|
|
988
|
+
eventBus
|
|
989
|
+
} = useContext(EventContext);
|
|
990
|
+
useEffect(() => {
|
|
991
|
+
if (!eventBus) {
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
eventBus.on(event, priority, callback);
|
|
996
|
+
return () => eventBus.off(event, callback);
|
|
997
|
+
}, [callback, event, eventBus, priority]);
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
const HIGH_PRIORITY = 10000;
|
|
1001
|
+
/**
|
|
1002
|
+
* Buffer events and re-fire during passive effect phase.
|
|
1003
|
+
*
|
|
1004
|
+
* @param {string[]} bufferedEvents
|
|
1005
|
+
* @param {Object} [eventBus]
|
|
1006
|
+
*/
|
|
1007
|
+
|
|
1008
|
+
function useEventBuffer(bufferedEvents, eventBus) {
|
|
1009
|
+
const buffer = useRef([]),
|
|
1010
|
+
buffering = useRef(true);
|
|
1011
|
+
|
|
1012
|
+
const createCallback = event => data => {
|
|
1013
|
+
if (buffering.current === true) {
|
|
1014
|
+
buffer.current.unshift([event, data]);
|
|
1015
|
+
}
|
|
1016
|
+
}; // (1) buffer events
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
useEffect(() => {
|
|
1020
|
+
if (!eventBus) {
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
const listeners = bufferedEvents.map(event => {
|
|
1025
|
+
return [event, createCallback(event)];
|
|
1026
|
+
});
|
|
1027
|
+
listeners.forEach(([event, callback]) => {
|
|
1028
|
+
eventBus.on(event, HIGH_PRIORITY, callback);
|
|
1029
|
+
});
|
|
1030
|
+
return () => {
|
|
1031
|
+
listeners.forEach(([event, callback]) => {
|
|
1032
|
+
eventBus.off(event, callback);
|
|
1033
|
+
});
|
|
1034
|
+
};
|
|
1035
|
+
}, [bufferedEvents, eventBus]); // (2) re-fire events
|
|
1036
|
+
|
|
1037
|
+
useEffect(() => {
|
|
1038
|
+
if (!eventBus) {
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
buffering.current = false;
|
|
1043
|
+
|
|
1044
|
+
while (buffer.current.length) {
|
|
1045
|
+
const [event, data] = buffer.current.pop();
|
|
1046
|
+
eventBus.fire(event, data);
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
buffering.current = true;
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Creates a state that persists in the global LayoutContext.
|
|
1054
|
+
*
|
|
1055
|
+
* @example
|
|
1056
|
+
* ```jsx
|
|
1057
|
+
* function Group(props) {
|
|
1058
|
+
* const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
|
|
1059
|
+
* }
|
|
1060
|
+
* ```
|
|
1061
|
+
*
|
|
1062
|
+
* @param {(string|number)[]} path
|
|
1063
|
+
* @param {any} [defaultValue]
|
|
1064
|
+
*
|
|
1065
|
+
* @returns {[ any, Function ]}
|
|
1066
|
+
*/
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
function useLayoutState(path, defaultValue) {
|
|
1070
|
+
const {
|
|
1071
|
+
getLayoutForKey,
|
|
1072
|
+
setLayoutForKey
|
|
1073
|
+
} = useContext(LayoutContext);
|
|
1074
|
+
const layoutForKey = getLayoutForKey(path, defaultValue);
|
|
1075
|
+
const [value, set] = useState(layoutForKey);
|
|
1076
|
+
|
|
1077
|
+
const setState = newValue => {
|
|
1078
|
+
// (1) set component state
|
|
1079
|
+
set(newValue); // (2) set context
|
|
1080
|
+
|
|
1081
|
+
setLayoutForKey(path, newValue);
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
return [value, setState];
|
|
1085
|
+
}
|
|
1086
|
+
/**
|
|
1087
|
+
* @pinussilvestrus: we need to introduce our own hook to persist the previous
|
|
1088
|
+
* state on updates.
|
|
1089
|
+
*
|
|
1090
|
+
* cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
|
|
1091
|
+
*/
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
function usePrevious(value) {
|
|
1095
|
+
const ref = useRef();
|
|
1096
|
+
useEffect(() => {
|
|
1097
|
+
ref.current = value;
|
|
1098
|
+
});
|
|
1099
|
+
return ref.current;
|
|
1100
|
+
}
|
|
1101
|
+
/**
|
|
1102
|
+
* Subscribe to `propertiesPanel.showEntry`.
|
|
1103
|
+
*
|
|
1104
|
+
* @param {Function} show
|
|
1105
|
+
*
|
|
1106
|
+
* @returns {import('preact').Ref}
|
|
1107
|
+
*/
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
function useShowEntryEvent(show) {
|
|
1111
|
+
const {
|
|
1112
|
+
onShow
|
|
1113
|
+
} = useContext(LayoutContext);
|
|
1114
|
+
const ref = useRef();
|
|
1115
|
+
const [focus, setFocus] = useState(false);
|
|
1116
|
+
const onShowEntry = useCallback(event => {
|
|
1117
|
+
if (show(event)) {
|
|
1118
|
+
if (isFunction(onShow)) {
|
|
1119
|
+
onShow();
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
if (event.focus && !focus) {
|
|
1123
|
+
setFocus(true);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}, [show]);
|
|
1127
|
+
useEffect(() => {
|
|
1128
|
+
if (focus && ref.current) {
|
|
1129
|
+
if (isFunction(ref.current.focus)) {
|
|
1130
|
+
ref.current.focus();
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
if (isFunction(ref.current.select)) {
|
|
1134
|
+
ref.current.select();
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
setFocus(false);
|
|
1138
|
+
}
|
|
1139
|
+
}, [focus]);
|
|
1140
|
+
useEvent('propertiesPanel.showEntry', onShowEntry);
|
|
1141
|
+
return ref;
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* Subscribe to `propertiesPanel.showError`. On `propertiesPanel.showError` set
|
|
1145
|
+
* temporary error. Fire `propertiesPanel.showEntry` for temporary error to be
|
|
1146
|
+
* visible. Unset error on `propertiesPanel.updated`.
|
|
1147
|
+
*
|
|
1148
|
+
* @param {Function} show
|
|
1149
|
+
*
|
|
1150
|
+
* @returns {import('preact').Ref}
|
|
1151
|
+
*/
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
function useShowErrorEvent(show) {
|
|
1155
|
+
const {
|
|
1156
|
+
eventBus
|
|
1157
|
+
} = useContext(EventContext);
|
|
1158
|
+
const [temporaryError, setTemporaryError] = useState(null);
|
|
1159
|
+
const onPropertiesPanelUpdated = useCallback(() => setTemporaryError(null), []);
|
|
1160
|
+
useEvent('propertiesPanel.updated', onPropertiesPanelUpdated);
|
|
1161
|
+
const onShowError = useCallback(event => {
|
|
1162
|
+
setTemporaryError(null);
|
|
1163
|
+
|
|
1164
|
+
if (show(event)) {
|
|
1165
|
+
if (eventBus) {
|
|
1166
|
+
eventBus.fire('propertiesPanel.showEntry', event);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
setTemporaryError(event.message);
|
|
1170
|
+
}
|
|
1171
|
+
}, [show]);
|
|
1172
|
+
useEvent('propertiesPanel.showError', onShowError);
|
|
1173
|
+
return temporaryError;
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* @callback setSticky
|
|
1177
|
+
* @param {boolean} value
|
|
1178
|
+
*/
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* Use IntersectionObserver to identify when DOM element is in sticky mode.
|
|
1182
|
+
* If sticky is observered setSticky(true) will be called.
|
|
1183
|
+
* If sticky mode is left, setSticky(false) will be called.
|
|
1184
|
+
*
|
|
1185
|
+
*
|
|
1186
|
+
* @param {Object} ref
|
|
1187
|
+
* @param {string} scrollContainerSelector
|
|
1188
|
+
* @param {setSticky} setSticky
|
|
1189
|
+
*/
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky) {
|
|
1193
|
+
useEffect(() => {
|
|
1194
|
+
// return early if IntersectionObserver is not available
|
|
1195
|
+
if (!IntersectionObserver) {
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
let observer;
|
|
1200
|
+
|
|
1201
|
+
if (ref.current) {
|
|
1202
|
+
const scrollContainer = query(scrollContainerSelector);
|
|
1203
|
+
observer = new IntersectionObserver(entries => {
|
|
1204
|
+
if (entries[0].intersectionRatio < 1) {
|
|
1205
|
+
setSticky(true);
|
|
1206
|
+
} else if (entries[0].intersectionRatio === 1) {
|
|
1207
|
+
setSticky(false);
|
|
1208
|
+
}
|
|
1209
|
+
}, {
|
|
1210
|
+
root: scrollContainer,
|
|
1211
|
+
rootMargin: '0px 0px 999999% 0px',
|
|
1212
|
+
// Use bottom margin to avoid stickyness when scrolling out to bottom
|
|
1213
|
+
threshold: [1]
|
|
1214
|
+
});
|
|
1215
|
+
observer.observe(ref.current);
|
|
1216
|
+
} // Unobserve if unmounted
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
return () => {
|
|
1220
|
+
if (ref.current && observer) {
|
|
1221
|
+
observer.unobserve(ref.current);
|
|
1222
|
+
}
|
|
1223
|
+
};
|
|
1224
|
+
}, [ref]);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
function Group(props) {
|
|
1228
|
+
const {
|
|
1229
|
+
element,
|
|
1230
|
+
entries = [],
|
|
1231
|
+
id,
|
|
1232
|
+
label,
|
|
1233
|
+
shouldOpen = false
|
|
1234
|
+
} = props;
|
|
1235
|
+
const groupRef = useRef(null);
|
|
1236
|
+
const [open, setOpen] = useLayoutState(['groups', id, 'open'], shouldOpen);
|
|
1237
|
+
const onShow = useCallback(() => setOpen(true), [setOpen]);
|
|
1238
|
+
|
|
1239
|
+
const toggleOpen = () => setOpen(!open);
|
|
1240
|
+
|
|
1241
|
+
const [edited, setEdited] = useState(false);
|
|
1242
|
+
const [sticky, setSticky] = useState(false); // set edited state depending on all entries
|
|
1243
|
+
|
|
1244
|
+
useEffect(() => {
|
|
1245
|
+
const hasOneEditedEntry = entries.find(entry => {
|
|
1246
|
+
const {
|
|
1247
|
+
id,
|
|
1248
|
+
isEdited
|
|
1249
|
+
} = entry;
|
|
1250
|
+
const entryNode = query(`[data-entry-id="${id}"]`);
|
|
1251
|
+
|
|
1252
|
+
if (!isFunction(isEdited) || !entryNode) {
|
|
1253
|
+
return false;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
const inputNode = query('.bio-properties-panel-input', entryNode);
|
|
1257
|
+
return isEdited(inputNode);
|
|
1258
|
+
});
|
|
1259
|
+
setEdited(hasOneEditedEntry);
|
|
1260
|
+
}, [entries]); // set css class when group is sticky to top
|
|
1261
|
+
|
|
1262
|
+
useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
|
|
1263
|
+
const propertiesPanelContext = { ...useContext(LayoutContext),
|
|
1264
|
+
onShow
|
|
1265
|
+
};
|
|
1266
|
+
return jsxs("div", {
|
|
1267
|
+
class: "bio-properties-panel-group",
|
|
1268
|
+
"data-group-id": 'group-' + id,
|
|
1269
|
+
ref: groupRef,
|
|
1270
|
+
children: [jsxs("div", {
|
|
1271
|
+
class: classnames('bio-properties-panel-group-header', edited ? '' : 'empty', open ? 'open' : '', sticky && open ? 'sticky' : ''),
|
|
1272
|
+
onClick: toggleOpen,
|
|
1273
|
+
children: [jsx("div", {
|
|
1274
|
+
title: label,
|
|
1275
|
+
class: "bio-properties-panel-group-header-title",
|
|
1276
|
+
children: label
|
|
1277
|
+
}), jsxs("div", {
|
|
1278
|
+
class: "bio-properties-panel-group-header-buttons",
|
|
1279
|
+
children: [edited && jsx(DataMarker, {}), jsx("button", {
|
|
1280
|
+
title: "Toggle section",
|
|
1281
|
+
class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
|
|
1282
|
+
children: jsx(ArrowIcon, {
|
|
1283
|
+
class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
|
|
1284
|
+
})
|
|
1285
|
+
})]
|
|
1286
|
+
})]
|
|
1287
|
+
}), jsx("div", {
|
|
1288
|
+
class: classnames('bio-properties-panel-group-entries', open ? 'open' : ''),
|
|
1289
|
+
children: jsx(LayoutContext.Provider, {
|
|
1290
|
+
value: propertiesPanelContext,
|
|
1291
|
+
children: entries.map(entry => {
|
|
1292
|
+
const {
|
|
1293
|
+
component: Component,
|
|
1294
|
+
id
|
|
1295
|
+
} = entry;
|
|
1296
|
+
return createElement(Component, { ...entry,
|
|
1297
|
+
element: element,
|
|
1298
|
+
key: id
|
|
1299
|
+
});
|
|
1300
|
+
})
|
|
1301
|
+
})
|
|
1302
|
+
})]
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
function DataMarker() {
|
|
1307
|
+
return jsx("div", {
|
|
1308
|
+
title: "Section contains data",
|
|
1309
|
+
class: "bio-properties-panel-dot"
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
/**
|
|
1313
|
+
* @typedef { {
|
|
1314
|
+
* text: (element: object) => string,
|
|
1315
|
+
* icon?: (element: Object) => import('preact').Component
|
|
1316
|
+
* } } PlaceholderDefinition
|
|
1317
|
+
*
|
|
1318
|
+
* @param { PlaceholderDefinition } props
|
|
1319
|
+
*/
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
function Placeholder(props) {
|
|
1323
|
+
const {
|
|
1324
|
+
text,
|
|
1325
|
+
icon: Icon
|
|
1326
|
+
} = props;
|
|
1327
|
+
return jsx("div", {
|
|
1328
|
+
class: "bio-properties-panel open",
|
|
1329
|
+
children: jsxs("section", {
|
|
1330
|
+
class: "bio-properties-panel-placeholder",
|
|
1331
|
+
children: [Icon && jsx(Icon, {
|
|
1332
|
+
class: "bio-properties-panel-placeholder-icon"
|
|
1333
|
+
}), jsx("p", {
|
|
1334
|
+
class: "bio-properties-panel-placeholder-text",
|
|
1335
|
+
children: text
|
|
1336
|
+
})]
|
|
1337
|
+
})
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
const DEFAULT_LAYOUT = {
|
|
1342
|
+
open: true
|
|
1343
|
+
};
|
|
1344
|
+
const DEFAULT_DESCRIPTION = {};
|
|
1345
|
+
const bufferedEvents = ['propertiesPanel.showEntry', 'propertiesPanel.showError'];
|
|
1346
|
+
/**
|
|
1347
|
+
* @typedef { {
|
|
1348
|
+
* component: import('preact').Component,
|
|
1349
|
+
* id: String,
|
|
1350
|
+
* isEdited?: Function
|
|
1351
|
+
* } } EntryDefinition
|
|
1352
|
+
*
|
|
1353
|
+
* @typedef { {
|
|
1354
|
+
* autoFocusEntry: String,
|
|
1355
|
+
* autoOpen?: Boolean,
|
|
1356
|
+
* entries: Array<EntryDefinition>,
|
|
1357
|
+
* id: String,
|
|
1358
|
+
* label: String,
|
|
1359
|
+
* remove: (event: MouseEvent) => void
|
|
1360
|
+
* } } ListItemDefinition
|
|
1361
|
+
*
|
|
1362
|
+
* @typedef { {
|
|
1363
|
+
* add: (event: MouseEvent) => void,
|
|
1364
|
+
* component: import('preact').Component,
|
|
1365
|
+
* element: Object,
|
|
1366
|
+
* id: String,
|
|
1367
|
+
* items: Array<ListItemDefinition>,
|
|
1368
|
+
* label: String,
|
|
1369
|
+
* shouldSort?: Boolean,
|
|
1370
|
+
* shouldOpen?: Boolean
|
|
1371
|
+
* } } ListGroupDefinition
|
|
1372
|
+
*
|
|
1373
|
+
* @typedef { {
|
|
1374
|
+
* component?: import('preact').Component,
|
|
1375
|
+
* entries: Array<EntryDefinition>,
|
|
1376
|
+
* id: String,
|
|
1377
|
+
* label: String,
|
|
1378
|
+
* shouldOpen?: Boolean
|
|
1379
|
+
* } } GroupDefinition
|
|
1380
|
+
*
|
|
1381
|
+
* @typedef { {
|
|
1382
|
+
* [id: String]: GetDescriptionFunction
|
|
1383
|
+
* } } DescriptionConfig
|
|
1384
|
+
*
|
|
1385
|
+
* @callback { {
|
|
1386
|
+
* @param {string} id
|
|
1387
|
+
* @param {Object} element
|
|
1388
|
+
* @returns {string}
|
|
1389
|
+
* } } GetDescriptionFunction
|
|
1390
|
+
*
|
|
1391
|
+
* @typedef { {
|
|
1392
|
+
* getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
|
|
1393
|
+
* getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
|
|
1394
|
+
* } } PlaceholderProvider
|
|
1395
|
+
*
|
|
1396
|
+
*/
|
|
1397
|
+
|
|
1398
|
+
/**
|
|
1399
|
+
* A basic properties panel component. Describes *how* content will be rendered, accepts
|
|
1400
|
+
* data from implementor to describe *what* will be rendered.
|
|
1401
|
+
*
|
|
1402
|
+
* @param {Object} props
|
|
1403
|
+
* @param {Object|Array} props.element
|
|
1404
|
+
* @param {import('./components/Header').HeaderProvider} props.headerProvider
|
|
1405
|
+
* @param {PlaceholderProvider} [props.placeholderProvider]
|
|
1406
|
+
* @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
|
|
1407
|
+
* @param {Object} [props.layoutConfig]
|
|
1408
|
+
* @param {Function} [props.layoutChanged]
|
|
1409
|
+
* @param {DescriptionConfig} [props.descriptionConfig]
|
|
1410
|
+
* @param {Function} [props.descriptionLoaded]
|
|
1411
|
+
* @param {Object} [props.eventBus]
|
|
1412
|
+
*/
|
|
1413
|
+
|
|
1414
|
+
function PropertiesPanel(props) {
|
|
1415
|
+
const {
|
|
1416
|
+
element,
|
|
1417
|
+
headerProvider,
|
|
1418
|
+
placeholderProvider,
|
|
1419
|
+
groups,
|
|
1420
|
+
layoutConfig = {},
|
|
1421
|
+
layoutChanged,
|
|
1422
|
+
descriptionConfig = {},
|
|
1423
|
+
descriptionLoaded,
|
|
1424
|
+
eventBus
|
|
1425
|
+
} = props; // set-up layout context
|
|
1426
|
+
|
|
1427
|
+
const [layout, setLayout] = useState(createLayout(layoutConfig));
|
|
1428
|
+
useEffect(() => {
|
|
1429
|
+
if (typeof layoutChanged === 'function') {
|
|
1430
|
+
layoutChanged(layout);
|
|
1431
|
+
}
|
|
1432
|
+
}, [layout, layoutChanged]);
|
|
1433
|
+
|
|
1434
|
+
const getLayoutForKey = (key, defaultValue) => {
|
|
1435
|
+
return get(layout, key, defaultValue);
|
|
1436
|
+
};
|
|
1437
|
+
|
|
1438
|
+
const setLayoutForKey = (key, config) => {
|
|
1439
|
+
const newLayout = assign({}, layout);
|
|
1440
|
+
set(newLayout, key, config);
|
|
1441
|
+
setLayout(newLayout);
|
|
1442
|
+
};
|
|
1443
|
+
|
|
1444
|
+
const layoutContext = {
|
|
1445
|
+
layout,
|
|
1446
|
+
setLayout,
|
|
1447
|
+
getLayoutForKey,
|
|
1448
|
+
setLayoutForKey
|
|
1449
|
+
}; // set-up description context
|
|
1450
|
+
|
|
1451
|
+
const description = createDescriptionContext(descriptionConfig);
|
|
1452
|
+
|
|
1453
|
+
if (typeof descriptionLoaded === 'function') {
|
|
1454
|
+
descriptionLoaded(description);
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
const getDescriptionForId = (id, element) => {
|
|
1458
|
+
return description[id] && description[id](element);
|
|
1459
|
+
};
|
|
1460
|
+
|
|
1461
|
+
const descriptionContext = {
|
|
1462
|
+
description,
|
|
1463
|
+
getDescriptionForId
|
|
1464
|
+
};
|
|
1465
|
+
useEventBuffer(bufferedEvents, eventBus);
|
|
1466
|
+
const eventContext = {
|
|
1467
|
+
eventBus
|
|
1468
|
+
};
|
|
1469
|
+
const propertiesPanelContext = {
|
|
1470
|
+
element
|
|
1471
|
+
}; // empty state
|
|
1472
|
+
|
|
1473
|
+
if (placeholderProvider && !element) {
|
|
1474
|
+
return jsx(Placeholder, { ...placeholderProvider.getEmpty()
|
|
1475
|
+
});
|
|
1476
|
+
} // multiple state
|
|
1477
|
+
|
|
1478
|
+
|
|
1479
|
+
if (placeholderProvider && isArray(element)) {
|
|
1480
|
+
return jsx(Placeholder, { ...placeholderProvider.getMultiple()
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
return jsx(LayoutContext.Provider, {
|
|
1485
|
+
value: propertiesPanelContext,
|
|
1486
|
+
children: jsx(DescriptionContext.Provider, {
|
|
1487
|
+
value: descriptionContext,
|
|
1488
|
+
children: jsx(LayoutContext.Provider, {
|
|
1489
|
+
value: layoutContext,
|
|
1490
|
+
children: jsx(EventContext.Provider, {
|
|
1491
|
+
value: eventContext,
|
|
1492
|
+
children: jsxs("div", {
|
|
1493
|
+
class: classnames('bio-properties-panel', layout.open ? 'open' : ''),
|
|
1494
|
+
children: [jsx(Header, {
|
|
1495
|
+
element: element,
|
|
1496
|
+
headerProvider: headerProvider
|
|
1497
|
+
}), jsx("div", {
|
|
1498
|
+
class: "bio-properties-panel-scroll-container",
|
|
1499
|
+
children: groups.map(group => {
|
|
1500
|
+
const {
|
|
1501
|
+
component: Component = Group,
|
|
1502
|
+
id
|
|
1503
|
+
} = group;
|
|
1504
|
+
return createElement(Component, { ...group,
|
|
1505
|
+
key: id,
|
|
1506
|
+
element: element
|
|
1507
|
+
});
|
|
1508
|
+
})
|
|
1509
|
+
})]
|
|
1510
|
+
})
|
|
1511
|
+
})
|
|
1512
|
+
})
|
|
1513
|
+
})
|
|
1514
|
+
});
|
|
1515
|
+
} // helpers //////////////////
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
function createLayout(overrides) {
|
|
1519
|
+
return { ...DEFAULT_LAYOUT,
|
|
1520
|
+
...overrides
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
function createDescriptionContext(overrides) {
|
|
1525
|
+
return { ...DEFAULT_DESCRIPTION,
|
|
1526
|
+
...overrides
|
|
1527
|
+
};
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
function CollapsibleEntry(props) {
|
|
1531
|
+
const {
|
|
1532
|
+
element,
|
|
1533
|
+
entries = [],
|
|
1534
|
+
id,
|
|
1535
|
+
label,
|
|
1536
|
+
open: shouldOpen,
|
|
1537
|
+
remove
|
|
1538
|
+
} = props;
|
|
1539
|
+
const [open, setOpen] = useState(shouldOpen);
|
|
1540
|
+
|
|
1541
|
+
const toggleOpen = () => setOpen(!open);
|
|
1542
|
+
|
|
1543
|
+
const {
|
|
1544
|
+
onShow
|
|
1545
|
+
} = useContext(LayoutContext);
|
|
1546
|
+
const propertiesPanelContext = { ...useContext(LayoutContext),
|
|
1547
|
+
onShow: useCallback(() => {
|
|
1548
|
+
setOpen(true);
|
|
1549
|
+
|
|
1550
|
+
if (isFunction(onShow)) {
|
|
1551
|
+
onShow();
|
|
1552
|
+
}
|
|
1553
|
+
}, [onShow, setOpen])
|
|
1554
|
+
}; // todo(pinussilvestrus): translate once we have a translate mechanism for the core
|
|
1555
|
+
|
|
1556
|
+
const placeholderLabel = '<empty>';
|
|
1557
|
+
return jsxs("div", {
|
|
1558
|
+
"data-entry-id": id,
|
|
1559
|
+
class: classnames('bio-properties-panel-collapsible-entry', open ? 'open' : ''),
|
|
1560
|
+
children: [jsxs("div", {
|
|
1561
|
+
class: "bio-properties-panel-collapsible-entry-header",
|
|
1562
|
+
onClick: toggleOpen,
|
|
1563
|
+
children: [jsx("div", {
|
|
1564
|
+
title: label || placeholderLabel,
|
|
1565
|
+
class: classnames('bio-properties-panel-collapsible-entry-header-title', !label && 'empty'),
|
|
1566
|
+
children: label || placeholderLabel
|
|
1567
|
+
}), jsx("button", {
|
|
1568
|
+
title: "Toggle list item",
|
|
1569
|
+
class: "bio-properties-panel-arrow bio-properties-panel-collapsible-entry-arrow",
|
|
1570
|
+
children: jsx(ArrowIcon, {
|
|
1571
|
+
class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
|
|
1572
|
+
})
|
|
1573
|
+
}), remove ? jsx("button", {
|
|
1574
|
+
title: "Delete item",
|
|
1575
|
+
class: "bio-properties-panel-remove-entry",
|
|
1576
|
+
onClick: remove,
|
|
1577
|
+
children: jsx(DeleteIcon, {})
|
|
1578
|
+
}) : null]
|
|
1579
|
+
}), jsx("div", {
|
|
1580
|
+
class: classnames('bio-properties-panel-collapsible-entry-entries', open ? 'open' : ''),
|
|
1581
|
+
children: jsx(LayoutContext.Provider, {
|
|
1582
|
+
value: propertiesPanelContext,
|
|
1583
|
+
children: entries.map(entry => {
|
|
1584
|
+
const {
|
|
1585
|
+
component: Component,
|
|
1586
|
+
id
|
|
1587
|
+
} = entry;
|
|
1588
|
+
return createElement(Component, { ...entry,
|
|
1589
|
+
element: element,
|
|
1590
|
+
key: id
|
|
1591
|
+
});
|
|
1592
|
+
})
|
|
1593
|
+
})
|
|
1594
|
+
})]
|
|
1595
|
+
});
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
function ListItem(props) {
|
|
1599
|
+
const {
|
|
1600
|
+
autoFocusEntry,
|
|
1601
|
+
autoOpen
|
|
1602
|
+
} = props; // focus specified entry on auto open
|
|
1603
|
+
|
|
1604
|
+
useEffect(() => {
|
|
1605
|
+
if (autoOpen && autoFocusEntry) {
|
|
1606
|
+
const entry = query(`[data-entry-id="${autoFocusEntry}"]`);
|
|
1607
|
+
const focusableInput = query('.bio-properties-panel-input', entry);
|
|
1608
|
+
|
|
1609
|
+
if (focusableInput) {
|
|
1610
|
+
if (isFunction(focusableInput.select)) {
|
|
1611
|
+
focusableInput.select();
|
|
1612
|
+
} else if (isFunction(focusableInput.focus)) {
|
|
1613
|
+
focusableInput.focus();
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
}, [autoOpen, autoFocusEntry]);
|
|
1618
|
+
return jsx("div", {
|
|
1619
|
+
class: "bio-properties-panel-list-item",
|
|
1620
|
+
children: jsx(CollapsibleEntry, { ...props,
|
|
1621
|
+
open: autoOpen
|
|
1622
|
+
})
|
|
1623
|
+
});
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
const noop$3 = () => {};
|
|
1627
|
+
/**
|
|
1628
|
+
* @param {import('../PropertiesPanel').ListGroupDefinition} props
|
|
1629
|
+
*/
|
|
1630
|
+
|
|
1631
|
+
|
|
1632
|
+
function ListGroup(props) {
|
|
1633
|
+
const {
|
|
1634
|
+
add,
|
|
1635
|
+
element,
|
|
1636
|
+
id,
|
|
1637
|
+
items,
|
|
1638
|
+
label,
|
|
1639
|
+
shouldOpen = true,
|
|
1640
|
+
shouldSort = true
|
|
1641
|
+
} = props;
|
|
1642
|
+
const groupRef = useRef(null);
|
|
1643
|
+
const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
|
|
1644
|
+
const [sticky, setSticky] = useState(false);
|
|
1645
|
+
const onShow = useCallback(() => setOpen(true), [setOpen]);
|
|
1646
|
+
const [ordering, setOrdering] = useState([]);
|
|
1647
|
+
const [newItemAdded, setNewItemAdded] = useState(false);
|
|
1648
|
+
const prevItems = usePrevious(items);
|
|
1649
|
+
const prevElement = usePrevious(element);
|
|
1650
|
+
const elementChanged = element !== prevElement;
|
|
1651
|
+
const shouldHandleEffects = !elementChanged && (shouldSort || shouldOpen); // reset initial ordering when element changes (before first render)
|
|
1652
|
+
|
|
1653
|
+
if (elementChanged) {
|
|
1654
|
+
setOrdering(createOrdering(shouldSort ? sortItems(items) : items));
|
|
1655
|
+
} // keep ordering in sync to items - and open changes
|
|
1656
|
+
// (0) set initial ordering from given items
|
|
1657
|
+
|
|
1658
|
+
|
|
1659
|
+
useEffect(() => {
|
|
1660
|
+
if (!prevItems || !shouldSort) {
|
|
1661
|
+
setOrdering(createOrdering(items));
|
|
1662
|
+
}
|
|
1663
|
+
}, [items, element]); // (1) items were added
|
|
1664
|
+
|
|
1665
|
+
useEffect(() => {
|
|
1666
|
+
if (shouldHandleEffects && prevItems && items.length > prevItems.length) {
|
|
1667
|
+
let add = [];
|
|
1668
|
+
items.forEach(item => {
|
|
1669
|
+
if (!ordering.includes(item.id)) {
|
|
1670
|
+
add.push(item.id);
|
|
1671
|
+
}
|
|
1672
|
+
});
|
|
1673
|
+
let newOrdering = ordering; // open if not open and configured
|
|
1674
|
+
|
|
1675
|
+
if (!open && shouldOpen) {
|
|
1676
|
+
toggleOpen(); // if I opened and I should sort, then sort items
|
|
1677
|
+
|
|
1678
|
+
if (shouldSort) {
|
|
1679
|
+
newOrdering = createOrdering(sortItems(items));
|
|
1680
|
+
}
|
|
1681
|
+
} // add new items on top or bottom depending on sorting behavior
|
|
1682
|
+
|
|
1683
|
+
|
|
1684
|
+
newOrdering = newOrdering.filter(item => !add.includes(item));
|
|
1685
|
+
|
|
1686
|
+
if (shouldSort) {
|
|
1687
|
+
newOrdering.unshift(...add);
|
|
1688
|
+
} else {
|
|
1689
|
+
newOrdering.push(...add);
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
setOrdering(newOrdering);
|
|
1693
|
+
setNewItemAdded(true);
|
|
1694
|
+
} else {
|
|
1695
|
+
setNewItemAdded(false);
|
|
1696
|
+
}
|
|
1697
|
+
}, [items, open, shouldHandleEffects]); // (2) sort items on open if shouldSort is set
|
|
1698
|
+
|
|
1699
|
+
useEffect(() => {
|
|
1700
|
+
if (shouldSort && open && !newItemAdded) {
|
|
1701
|
+
setOrdering(createOrdering(sortItems(items)));
|
|
1702
|
+
}
|
|
1703
|
+
}, [open, shouldSort]); // (3) items were deleted
|
|
1704
|
+
|
|
1705
|
+
useEffect(() => {
|
|
1706
|
+
if (shouldHandleEffects && prevItems && items.length < prevItems.length) {
|
|
1707
|
+
let keep = [];
|
|
1708
|
+
ordering.forEach(o => {
|
|
1709
|
+
if (getItem(items, o)) {
|
|
1710
|
+
keep.push(o);
|
|
1711
|
+
}
|
|
1712
|
+
});
|
|
1713
|
+
setOrdering(keep);
|
|
1714
|
+
}
|
|
1715
|
+
}, [items, shouldHandleEffects]); // set css class when group is sticky to top
|
|
1716
|
+
|
|
1717
|
+
useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
|
|
1718
|
+
|
|
1719
|
+
const toggleOpen = () => setOpen(!open);
|
|
1720
|
+
|
|
1721
|
+
const hasItems = !!items.length;
|
|
1722
|
+
const propertiesPanelContext = { ...useContext(LayoutContext),
|
|
1723
|
+
onShow
|
|
1724
|
+
};
|
|
1725
|
+
return jsxs("div", {
|
|
1726
|
+
class: "bio-properties-panel-group",
|
|
1727
|
+
"data-group-id": 'group-' + id,
|
|
1728
|
+
ref: groupRef,
|
|
1729
|
+
children: [jsxs("div", {
|
|
1730
|
+
class: classnames('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : '', sticky && open ? 'sticky' : ''),
|
|
1731
|
+
onClick: hasItems ? toggleOpen : noop$3,
|
|
1732
|
+
children: [jsx("div", {
|
|
1733
|
+
title: label,
|
|
1734
|
+
class: "bio-properties-panel-group-header-title",
|
|
1735
|
+
children: label
|
|
1736
|
+
}), jsxs("div", {
|
|
1737
|
+
class: "bio-properties-panel-group-header-buttons",
|
|
1738
|
+
children: [add ? jsxs("button", {
|
|
1739
|
+
title: "Create new list item",
|
|
1740
|
+
class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
|
|
1741
|
+
onClick: add,
|
|
1742
|
+
children: [jsx(CreateIcon, {}), !hasItems ? jsx("span", {
|
|
1743
|
+
class: "bio-properties-panel-add-entry-label",
|
|
1744
|
+
children: "Create"
|
|
1745
|
+
}) : null]
|
|
1746
|
+
}) : null, hasItems ? jsx("div", {
|
|
1747
|
+
title: `List contains ${items.length} item${items.length != 1 ? 's' : ''}`,
|
|
1748
|
+
class: "bio-properties-panel-list-badge",
|
|
1749
|
+
children: items.length
|
|
1750
|
+
}) : null, hasItems ? jsx("button", {
|
|
1751
|
+
title: "Toggle section",
|
|
1752
|
+
class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
|
|
1753
|
+
children: jsx(ArrowIcon, {
|
|
1754
|
+
class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
|
|
1755
|
+
})
|
|
1756
|
+
}) : null]
|
|
1757
|
+
})]
|
|
1758
|
+
}), jsx("div", {
|
|
1759
|
+
class: classnames('bio-properties-panel-list', open && hasItems ? 'open' : ''),
|
|
1760
|
+
children: jsx(LayoutContext.Provider, {
|
|
1761
|
+
value: propertiesPanelContext,
|
|
1762
|
+
children: ordering.map((o, index) => {
|
|
1763
|
+
const item = getItem(items, o);
|
|
1764
|
+
|
|
1765
|
+
if (!item) {
|
|
1766
|
+
return;
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
const {
|
|
1770
|
+
id
|
|
1771
|
+
} = item; // if item was added, open first or last item based on ordering
|
|
1772
|
+
|
|
1773
|
+
const autoOpen = newItemAdded && (shouldSort ? index === 0 : index === ordering.length - 1);
|
|
1774
|
+
return createElement(ListItem, { ...item,
|
|
1775
|
+
autoOpen: autoOpen,
|
|
1776
|
+
element: element,
|
|
1777
|
+
index: index,
|
|
1778
|
+
key: id
|
|
1779
|
+
});
|
|
1780
|
+
})
|
|
1781
|
+
})
|
|
1782
|
+
})]
|
|
1783
|
+
});
|
|
1784
|
+
} // helpers ////////////////////
|
|
1785
|
+
|
|
1786
|
+
/**
|
|
1787
|
+
* Sorts given items alphanumeric by label
|
|
1788
|
+
*/
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
function sortItems(items) {
|
|
1792
|
+
return sortBy(items, i => i.label.toLowerCase());
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
function getItem(items, id) {
|
|
1796
|
+
return find(items, i => i.id === id);
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
function createOrdering(items) {
|
|
1800
|
+
return items.map(i => i.id);
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
function Description$1(props) {
|
|
1804
|
+
const {
|
|
1805
|
+
element,
|
|
1806
|
+
forId,
|
|
1807
|
+
value
|
|
1808
|
+
} = props;
|
|
1809
|
+
const contextDescription = useDescriptionContext(forId, element);
|
|
1810
|
+
const description = value || contextDescription;
|
|
1811
|
+
|
|
1812
|
+
if (description) {
|
|
1813
|
+
return jsx("div", {
|
|
1814
|
+
class: "bio-properties-panel-description",
|
|
1815
|
+
children: description
|
|
1816
|
+
});
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
const noop$2 = () => {};
|
|
1821
|
+
|
|
1822
|
+
function Checkbox(props) {
|
|
1823
|
+
const {
|
|
1824
|
+
id,
|
|
1825
|
+
label,
|
|
1826
|
+
onChange,
|
|
1827
|
+
disabled,
|
|
1828
|
+
value = false,
|
|
1829
|
+
show = noop$2
|
|
1830
|
+
} = props;
|
|
1831
|
+
|
|
1832
|
+
const handleChange = ({
|
|
1833
|
+
target
|
|
1834
|
+
}) => {
|
|
1835
|
+
onChange(target.checked);
|
|
1836
|
+
};
|
|
1837
|
+
|
|
1838
|
+
const ref = useShowEntryEvent(show);
|
|
1839
|
+
return jsxs("div", {
|
|
1840
|
+
class: "bio-properties-panel-checkbox",
|
|
1841
|
+
children: [jsx("input", {
|
|
1842
|
+
ref: ref,
|
|
1843
|
+
id: prefixId$6(id),
|
|
1844
|
+
name: id,
|
|
1845
|
+
type: "checkbox",
|
|
1846
|
+
class: "bio-properties-panel-input",
|
|
1847
|
+
onChange: handleChange,
|
|
1848
|
+
checked: value,
|
|
1849
|
+
disabled: disabled
|
|
1850
|
+
}), jsx("label", {
|
|
1851
|
+
for: prefixId$6(id),
|
|
1852
|
+
class: "bio-properties-panel-label",
|
|
1853
|
+
children: label
|
|
1854
|
+
})]
|
|
1855
|
+
});
|
|
1856
|
+
}
|
|
1857
|
+
/**
|
|
1858
|
+
* @param {Object} props
|
|
1859
|
+
* @param {Object} props.element
|
|
1860
|
+
* @param {String} props.id
|
|
1861
|
+
* @param {String} props.description
|
|
1862
|
+
* @param {String} props.label
|
|
1863
|
+
* @param {Function} props.getValue
|
|
1864
|
+
* @param {Function} props.setValue
|
|
1865
|
+
* @param {boolean} [props.disabled]
|
|
1866
|
+
*/
|
|
1867
|
+
|
|
1868
|
+
|
|
1869
|
+
function CheckboxEntry(props) {
|
|
1870
|
+
const {
|
|
1871
|
+
element,
|
|
1872
|
+
id,
|
|
1873
|
+
description,
|
|
1874
|
+
label,
|
|
1875
|
+
getValue,
|
|
1876
|
+
setValue,
|
|
1877
|
+
disabled,
|
|
1878
|
+
show = noop$2
|
|
1879
|
+
} = props;
|
|
1880
|
+
const value = getValue(element);
|
|
1881
|
+
const error = useShowErrorEvent(show);
|
|
1882
|
+
return jsxs("div", {
|
|
1883
|
+
class: "bio-properties-panel-entry bio-properties-panel-checkbox-entry",
|
|
1884
|
+
"data-entry-id": id,
|
|
1885
|
+
children: [jsx(Checkbox, {
|
|
1886
|
+
disabled: disabled,
|
|
1887
|
+
id: id,
|
|
1888
|
+
label: label,
|
|
1889
|
+
onChange: setValue,
|
|
1890
|
+
show: show,
|
|
1891
|
+
value: value
|
|
1892
|
+
}), error && jsx("div", {
|
|
1893
|
+
class: "bio-properties-panel-error",
|
|
1894
|
+
children: error
|
|
1895
|
+
}), jsx(Description$1, {
|
|
1896
|
+
forId: id,
|
|
1897
|
+
element: element,
|
|
1898
|
+
value: description
|
|
1899
|
+
})]
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
function isEdited$6(node) {
|
|
1904
|
+
return node && !!node.checked;
|
|
1905
|
+
} // helpers /////////////////
|
|
1906
|
+
|
|
1907
|
+
|
|
1908
|
+
function prefixId$6(id) {
|
|
1909
|
+
return `bio-properties-panel-${id}`;
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
function NumberField(props) {
|
|
1913
|
+
const {
|
|
1914
|
+
debounce,
|
|
1915
|
+
disabled,
|
|
1916
|
+
id,
|
|
1917
|
+
label,
|
|
1918
|
+
max,
|
|
1919
|
+
min,
|
|
1920
|
+
onInput,
|
|
1921
|
+
step,
|
|
1922
|
+
value = ''
|
|
1923
|
+
} = props;
|
|
1924
|
+
const handleInput = useMemo(() => {
|
|
1925
|
+
return debounce(event => {
|
|
1926
|
+
const {
|
|
1927
|
+
validity,
|
|
1928
|
+
value
|
|
1929
|
+
} = event.target;
|
|
1930
|
+
|
|
1931
|
+
if (validity.valid) {
|
|
1932
|
+
onInput(value ? parseFloat(value) : undefined);
|
|
1933
|
+
}
|
|
1934
|
+
});
|
|
1935
|
+
}, [onInput, debounce]);
|
|
1936
|
+
return jsxs("div", {
|
|
1937
|
+
class: "bio-properties-panel-numberfield",
|
|
1938
|
+
children: [jsx("label", {
|
|
1939
|
+
for: prefixId$5(id),
|
|
1940
|
+
class: "bio-properties-panel-label",
|
|
1941
|
+
children: label
|
|
1942
|
+
}), jsx("input", {
|
|
1943
|
+
id: prefixId$5(id),
|
|
1944
|
+
type: "number",
|
|
1945
|
+
name: id,
|
|
1946
|
+
spellCheck: "false",
|
|
1947
|
+
autoComplete: "off",
|
|
1948
|
+
disabled: disabled,
|
|
1949
|
+
class: "bio-properties-panel-input",
|
|
1950
|
+
max: max,
|
|
1951
|
+
min: min,
|
|
1952
|
+
onInput: handleInput,
|
|
1953
|
+
step: step,
|
|
1954
|
+
value: value
|
|
1955
|
+
})]
|
|
1956
|
+
});
|
|
1957
|
+
}
|
|
1958
|
+
/**
|
|
1959
|
+
* @param {Object} props
|
|
1960
|
+
* @param {Boolean} props.debounce
|
|
1961
|
+
* @param {String} props.description
|
|
1962
|
+
* @param {Boolean} props.disabled
|
|
1963
|
+
* @param {Object} props.element
|
|
1964
|
+
* @param {Function} props.getValue
|
|
1965
|
+
* @param {String} props.id
|
|
1966
|
+
* @param {String} props.label
|
|
1967
|
+
* @param {String} props.max
|
|
1968
|
+
* @param {String} props.min
|
|
1969
|
+
* @param {Function} props.setValue
|
|
1970
|
+
* @param {String} props.step
|
|
1971
|
+
*/
|
|
1972
|
+
|
|
1973
|
+
|
|
1974
|
+
function NumberFieldEntry(props) {
|
|
1975
|
+
const {
|
|
1976
|
+
debounce,
|
|
1977
|
+
description,
|
|
1978
|
+
disabled,
|
|
1979
|
+
element,
|
|
1980
|
+
getValue,
|
|
1981
|
+
id,
|
|
1982
|
+
label,
|
|
1983
|
+
max,
|
|
1984
|
+
min,
|
|
1985
|
+
setValue,
|
|
1986
|
+
step
|
|
1987
|
+
} = props;
|
|
1988
|
+
const value = getValue(element);
|
|
1989
|
+
return jsxs("div", {
|
|
1990
|
+
class: "bio-properties-panel-entry",
|
|
1991
|
+
"data-entry-id": id,
|
|
1992
|
+
children: [jsx(NumberField, {
|
|
1993
|
+
debounce: debounce,
|
|
1994
|
+
disabled: disabled,
|
|
1995
|
+
id: id,
|
|
1996
|
+
label: label,
|
|
1997
|
+
onInput: setValue,
|
|
1998
|
+
max: max,
|
|
1999
|
+
min: min,
|
|
2000
|
+
step: step,
|
|
2001
|
+
value: value
|
|
2002
|
+
}), jsx(Description$1, {
|
|
2003
|
+
forId: id,
|
|
2004
|
+
element: element,
|
|
2005
|
+
value: description
|
|
2006
|
+
})]
|
|
2007
|
+
});
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
function isEdited$5(node) {
|
|
2011
|
+
return node && !!node.value;
|
|
2012
|
+
} // helpers /////////////////
|
|
2013
|
+
|
|
2014
|
+
|
|
2015
|
+
function prefixId$5(id) {
|
|
2016
|
+
return `bio-properties-panel-${id}`;
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
const noop$1 = () => {};
|
|
2020
|
+
/**
|
|
2021
|
+
* @typedef { { value: string, label: string, disabled: boolean } } Option
|
|
2022
|
+
*/
|
|
2023
|
+
|
|
2024
|
+
/**
|
|
2025
|
+
* Provides basic select input.
|
|
2026
|
+
*
|
|
2027
|
+
* @param {object} props
|
|
2028
|
+
* @param {string} props.id
|
|
2029
|
+
* @param {string[]} props.path
|
|
2030
|
+
* @param {string} props.label
|
|
2031
|
+
* @param {Function} props.onChange
|
|
2032
|
+
* @param {Array<Option>} [props.options]
|
|
2033
|
+
* @param {string} props.value
|
|
2034
|
+
* @param {boolean} [props.disabled]
|
|
2035
|
+
*/
|
|
2036
|
+
|
|
2037
|
+
|
|
2038
|
+
function Select(props) {
|
|
2039
|
+
const {
|
|
2040
|
+
id,
|
|
2041
|
+
label,
|
|
2042
|
+
onChange,
|
|
2043
|
+
options = [],
|
|
2044
|
+
value,
|
|
2045
|
+
disabled,
|
|
2046
|
+
show = noop$1
|
|
2047
|
+
} = props;
|
|
2048
|
+
const ref = useShowEntryEvent(show);
|
|
2049
|
+
|
|
2050
|
+
const handleChange = ({
|
|
2051
|
+
target
|
|
2052
|
+
}) => {
|
|
2053
|
+
onChange(target.value);
|
|
2054
|
+
};
|
|
2055
|
+
|
|
2056
|
+
return jsxs("div", {
|
|
2057
|
+
class: "bio-properties-panel-select",
|
|
2058
|
+
children: [jsx("label", {
|
|
2059
|
+
for: prefixId$4(id),
|
|
2060
|
+
class: "bio-properties-panel-label",
|
|
2061
|
+
children: label
|
|
2062
|
+
}), jsx("select", {
|
|
2063
|
+
ref: ref,
|
|
2064
|
+
id: prefixId$4(id),
|
|
2065
|
+
name: id,
|
|
2066
|
+
class: "bio-properties-panel-input",
|
|
2067
|
+
onInput: handleChange,
|
|
2068
|
+
value: value,
|
|
2069
|
+
disabled: disabled,
|
|
2070
|
+
children: options.map((option, idx) => {
|
|
2071
|
+
return jsx("option", {
|
|
2072
|
+
value: option.value,
|
|
2073
|
+
disabled: option.disabled,
|
|
2074
|
+
children: option.label
|
|
2075
|
+
}, idx);
|
|
2076
|
+
})
|
|
2077
|
+
})]
|
|
2078
|
+
});
|
|
2079
|
+
}
|
|
2080
|
+
/**
|
|
2081
|
+
* @param {object} props
|
|
2082
|
+
* @param {object} props.element
|
|
2083
|
+
* @param {string} props.id
|
|
2084
|
+
* @param {string} [props.description]
|
|
2085
|
+
* @param {string} props.label
|
|
2086
|
+
* @param {Function} props.getValue
|
|
2087
|
+
* @param {Function} props.setValue
|
|
2088
|
+
* @param {Function} props.getOptions
|
|
2089
|
+
* @param {boolean} [props.disabled]
|
|
2090
|
+
*/
|
|
2091
|
+
|
|
2092
|
+
|
|
2093
|
+
function SelectEntry(props) {
|
|
2094
|
+
const {
|
|
2095
|
+
element,
|
|
2096
|
+
id,
|
|
2097
|
+
description,
|
|
2098
|
+
label,
|
|
2099
|
+
getValue,
|
|
2100
|
+
setValue,
|
|
2101
|
+
getOptions,
|
|
2102
|
+
disabled,
|
|
2103
|
+
show = noop$1
|
|
2104
|
+
} = props;
|
|
2105
|
+
const value = getValue(element);
|
|
2106
|
+
const options = getOptions(element);
|
|
2107
|
+
const error = useShowErrorEvent(show);
|
|
2108
|
+
return jsxs("div", {
|
|
2109
|
+
class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
2110
|
+
"data-entry-id": id,
|
|
2111
|
+
children: [jsx(Select, {
|
|
2112
|
+
id: id,
|
|
2113
|
+
label: label,
|
|
2114
|
+
value: value,
|
|
2115
|
+
onChange: setValue,
|
|
2116
|
+
options: options,
|
|
2117
|
+
disabled: disabled,
|
|
2118
|
+
show: show
|
|
2119
|
+
}), error && jsx("div", {
|
|
2120
|
+
class: "bio-properties-panel-error",
|
|
2121
|
+
children: error
|
|
2122
|
+
}), jsx(Description$1, {
|
|
2123
|
+
forId: id,
|
|
2124
|
+
element: element,
|
|
2125
|
+
value: description
|
|
2126
|
+
})]
|
|
2127
|
+
});
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
function isEdited$4(node) {
|
|
2131
|
+
return node && !!node.value;
|
|
2132
|
+
} // helpers /////////////////
|
|
2133
|
+
|
|
2134
|
+
|
|
2135
|
+
function prefixId$4(id) {
|
|
2136
|
+
return `bio-properties-panel-${id}`;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
function FeelIcon(props) {
|
|
2140
|
+
const {
|
|
2141
|
+
label,
|
|
2142
|
+
feel = false
|
|
2143
|
+
} = props;
|
|
2144
|
+
const feelRequiredLabel = ' must be a FEEL expression';
|
|
2145
|
+
const feelOptionalLabel = ' can optionally be a FEEL expression';
|
|
2146
|
+
return jsx("i", {
|
|
2147
|
+
class: "bio-properties-panel-feel-icon",
|
|
2148
|
+
title: label + (feel === 'required' ? feelRequiredLabel : feelOptionalLabel),
|
|
2149
|
+
children: feel === 'required' ? jsx(FeelRequiredIcon, {}) : jsx(FeelOptionalIcon, {})
|
|
2150
|
+
});
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
function TextArea(props) {
|
|
2154
|
+
const {
|
|
2155
|
+
id,
|
|
2156
|
+
label,
|
|
2157
|
+
rows = 2,
|
|
2158
|
+
debounce,
|
|
2159
|
+
feel,
|
|
2160
|
+
onInput,
|
|
2161
|
+
value = '',
|
|
2162
|
+
disabled,
|
|
2163
|
+
monospace
|
|
2164
|
+
} = props;
|
|
2165
|
+
const handleInput = useMemo(() => {
|
|
2166
|
+
return debounce(({
|
|
2167
|
+
target
|
|
2168
|
+
}) => onInput(target.value.length ? target.value : undefined));
|
|
2169
|
+
}, [onInput, debounce]);
|
|
2170
|
+
return jsxs("div", {
|
|
2171
|
+
class: "bio-properties-panel-textarea",
|
|
2172
|
+
children: [jsxs("label", {
|
|
2173
|
+
for: prefixId$2(id),
|
|
2174
|
+
class: "bio-properties-panel-label",
|
|
2175
|
+
children: [label, feel && jsx(FeelIcon, {
|
|
2176
|
+
feel: feel,
|
|
2177
|
+
label: label
|
|
2178
|
+
})]
|
|
2179
|
+
}), jsx("textarea", {
|
|
2180
|
+
id: prefixId$2(id),
|
|
2181
|
+
name: id,
|
|
2182
|
+
spellCheck: "false",
|
|
2183
|
+
class: classnames('bio-properties-panel-input', monospace ? 'bio-properties-panel-input-monospace' : ''),
|
|
2184
|
+
onInput: handleInput,
|
|
2185
|
+
onFocus: props.onFocus,
|
|
2186
|
+
onBlur: props.onBlur,
|
|
2187
|
+
rows: rows,
|
|
2188
|
+
value: value,
|
|
2189
|
+
disabled: disabled
|
|
2190
|
+
})]
|
|
2191
|
+
});
|
|
2192
|
+
}
|
|
2193
|
+
/**
|
|
2194
|
+
* @param {object} props
|
|
2195
|
+
* @param {object} props.element
|
|
2196
|
+
* @param {string} props.id
|
|
2197
|
+
* @param {string} props.description
|
|
2198
|
+
* @param {boolean} props.debounce
|
|
2199
|
+
* @param {string} props.label
|
|
2200
|
+
* @param {Function} props.getValue
|
|
2201
|
+
* @param {Function} props.setValue
|
|
2202
|
+
* @param {number} props.rows
|
|
2203
|
+
* @param {boolean} props.monospace
|
|
2204
|
+
* @param {boolean} [props.disabled]
|
|
2205
|
+
*/
|
|
2206
|
+
|
|
2207
|
+
|
|
2208
|
+
function TextAreaEntry(props) {
|
|
2209
|
+
const {
|
|
2210
|
+
element,
|
|
2211
|
+
id,
|
|
2212
|
+
description,
|
|
2213
|
+
debounce,
|
|
2214
|
+
feel,
|
|
2215
|
+
label,
|
|
2216
|
+
getValue,
|
|
2217
|
+
setValue,
|
|
2218
|
+
rows,
|
|
2219
|
+
monospace,
|
|
2220
|
+
disabled
|
|
2221
|
+
} = props;
|
|
2222
|
+
const value = getValue(element);
|
|
2223
|
+
return jsxs("div", {
|
|
2224
|
+
class: "bio-properties-panel-entry",
|
|
2225
|
+
"data-entry-id": id,
|
|
2226
|
+
children: [jsx(TextArea, {
|
|
2227
|
+
id: id,
|
|
2228
|
+
label: label,
|
|
2229
|
+
value: value,
|
|
2230
|
+
onInput: setValue,
|
|
2231
|
+
rows: rows,
|
|
2232
|
+
debounce: debounce,
|
|
2233
|
+
monospace: monospace,
|
|
2234
|
+
feel: feel,
|
|
2235
|
+
disabled: disabled
|
|
2236
|
+
}), jsx(Description$1, {
|
|
2237
|
+
forId: id,
|
|
2238
|
+
element: element,
|
|
2239
|
+
value: description
|
|
2240
|
+
})]
|
|
2241
|
+
});
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
function isEdited$2(node) {
|
|
2245
|
+
return node && !!node.value;
|
|
2246
|
+
} // helpers /////////////////
|
|
2247
|
+
|
|
2248
|
+
|
|
2249
|
+
function prefixId$2(id) {
|
|
2250
|
+
return `bio-properties-panel-${id}`;
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
const noop = () => {};
|
|
2254
|
+
|
|
2255
|
+
function Textfield(props) {
|
|
2256
|
+
const {
|
|
2257
|
+
debounce,
|
|
2258
|
+
disabled = false,
|
|
2259
|
+
id,
|
|
2260
|
+
label,
|
|
2261
|
+
onInput,
|
|
2262
|
+
feel = false,
|
|
2263
|
+
value = '',
|
|
2264
|
+
show = noop
|
|
2265
|
+
} = props;
|
|
2266
|
+
const ref = useShowEntryEvent(show);
|
|
2267
|
+
const handleInput = useMemo(() => {
|
|
2268
|
+
return debounce(({
|
|
2269
|
+
target
|
|
2270
|
+
}) => onInput(target.value.length ? target.value : undefined));
|
|
2271
|
+
}, [onInput, debounce]);
|
|
2272
|
+
return jsxs("div", {
|
|
2273
|
+
class: "bio-properties-panel-textfield",
|
|
2274
|
+
children: [jsxs("label", {
|
|
2275
|
+
for: prefixId$1(id),
|
|
2276
|
+
class: "bio-properties-panel-label",
|
|
2277
|
+
children: [label, feel && jsx(FeelIcon, {
|
|
2278
|
+
feel: feel,
|
|
2279
|
+
label: label
|
|
2280
|
+
})]
|
|
2281
|
+
}), jsx("input", {
|
|
2282
|
+
ref: ref,
|
|
2283
|
+
id: prefixId$1(id),
|
|
2284
|
+
type: "text",
|
|
2285
|
+
name: id,
|
|
2286
|
+
spellCheck: "false",
|
|
2287
|
+
autoComplete: "off",
|
|
2288
|
+
disabled: disabled,
|
|
2289
|
+
class: "bio-properties-panel-input",
|
|
2290
|
+
onInput: handleInput,
|
|
2291
|
+
onFocus: props.onFocus,
|
|
2292
|
+
onBlur: props.onBlur,
|
|
2293
|
+
value: value || ''
|
|
2294
|
+
})]
|
|
2295
|
+
});
|
|
2296
|
+
}
|
|
2297
|
+
/**
|
|
2298
|
+
* @param {Object} props
|
|
2299
|
+
* @param {Object} props.element
|
|
2300
|
+
* @param {String} props.id
|
|
2301
|
+
* @param {String} props.description
|
|
2302
|
+
* @param {Boolean} props.debounce
|
|
2303
|
+
* @param {Boolean} props.disabled
|
|
2304
|
+
* @param {String} props.label
|
|
2305
|
+
* @param {Function} props.getValue
|
|
2306
|
+
* @param {Function} props.setValue
|
|
2307
|
+
* @param {Function} props.validate
|
|
2308
|
+
*/
|
|
2309
|
+
|
|
2310
|
+
|
|
2311
|
+
function TextfieldEntry(props) {
|
|
2312
|
+
const {
|
|
2313
|
+
element,
|
|
2314
|
+
id,
|
|
2315
|
+
description,
|
|
2316
|
+
debounce,
|
|
2317
|
+
disabled,
|
|
2318
|
+
feel,
|
|
2319
|
+
label,
|
|
2320
|
+
getValue,
|
|
2321
|
+
setValue,
|
|
2322
|
+
validate,
|
|
2323
|
+
show = noop
|
|
2324
|
+
} = props;
|
|
2325
|
+
const [cachedInvalidValue, setCachedInvalidValue] = useState(null);
|
|
2326
|
+
const [validationError, setValidationError] = useState(null);
|
|
2327
|
+
let value = getValue(element);
|
|
2328
|
+
const previousValue = usePrevious(value);
|
|
2329
|
+
useEffect(() => {
|
|
2330
|
+
if (isFunction(validate)) {
|
|
2331
|
+
const newValidationError = validate(value) || null;
|
|
2332
|
+
setValidationError(newValidationError);
|
|
2333
|
+
}
|
|
2334
|
+
}, [value]);
|
|
2335
|
+
|
|
2336
|
+
const onInput = newValue => {
|
|
2337
|
+
let newValidationError = null;
|
|
2338
|
+
|
|
2339
|
+
if (isFunction(validate)) {
|
|
2340
|
+
newValidationError = validate(newValue) || null;
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
if (newValidationError) {
|
|
2344
|
+
setCachedInvalidValue(newValue);
|
|
2345
|
+
} else {
|
|
2346
|
+
setValue(newValue);
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
setValidationError(newValidationError);
|
|
2350
|
+
};
|
|
2351
|
+
|
|
2352
|
+
if (previousValue === value && validationError) {
|
|
2353
|
+
value = cachedInvalidValue;
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
const temporaryError = useShowErrorEvent(show);
|
|
2357
|
+
const error = temporaryError || validationError;
|
|
2358
|
+
return jsxs("div", {
|
|
2359
|
+
class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
2360
|
+
"data-entry-id": id,
|
|
2361
|
+
children: [jsx(Textfield, {
|
|
2362
|
+
debounce: debounce,
|
|
2363
|
+
disabled: disabled,
|
|
2364
|
+
feel: feel,
|
|
2365
|
+
id: id,
|
|
2366
|
+
label: label,
|
|
2367
|
+
onInput: onInput,
|
|
2368
|
+
show: show,
|
|
2369
|
+
value: value
|
|
2370
|
+
}), error && jsx("div", {
|
|
2371
|
+
class: "bio-properties-panel-error",
|
|
2372
|
+
children: error
|
|
2373
|
+
}), jsx(Description$1, {
|
|
2374
|
+
forId: id,
|
|
2375
|
+
element: element,
|
|
2376
|
+
value: description
|
|
2377
|
+
})]
|
|
2378
|
+
});
|
|
2379
|
+
}
|
|
2380
|
+
|
|
2381
|
+
function isEdited$1(node) {
|
|
2382
|
+
return node && !!node.value;
|
|
2383
|
+
} // helpers /////////////////
|
|
2384
|
+
|
|
2385
|
+
|
|
2386
|
+
function prefixId$1(id) {
|
|
2387
|
+
return `bio-properties-panel-${id}`;
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
function arrayAdd$1(array, index, item) {
|
|
2391
|
+
const copy = [...array];
|
|
2392
|
+
copy.splice(index, 0, item);
|
|
2393
|
+
return copy;
|
|
2394
|
+
}
|
|
2395
|
+
function textToLabel(text = '...') {
|
|
2396
|
+
if (text.length > 10) {
|
|
2397
|
+
return `${text.substring(0, 30)}...`;
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
return text;
|
|
2401
|
+
}
|
|
2402
|
+
const INPUTS = ['checkbox', 'checklist', 'number', 'radio', 'select', 'taglist', 'textfield'];
|
|
2403
|
+
const VALUES_INPUTS = ['checklist', 'radio', 'select', 'taglist'];
|
|
2404
|
+
|
|
2405
|
+
function _extends$b() { _extends$b = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$b.apply(this, arguments); }
|
|
769
2406
|
var ButtonIcon = (({
|
|
770
2407
|
styles = {},
|
|
771
2408
|
...props
|
|
772
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
773
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2409
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$b({
|
|
2410
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2411
|
+
width: "54",
|
|
2412
|
+
height: "54"
|
|
2413
|
+
}, props), /*#__PURE__*/React.createElement("path", {
|
|
2414
|
+
fillRule: "evenodd",
|
|
2415
|
+
d: "M45 17a3 3 0 013 3v14a3 3 0 01-3 3H9a3 3 0 01-3-3V20a3 3 0 013-3h36zm-9 8.889H18v2.222h18V25.89z"
|
|
2416
|
+
})));
|
|
2417
|
+
|
|
2418
|
+
function _extends$a() { _extends$a = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$a.apply(this, arguments); }
|
|
2419
|
+
var CheckboxIcon = (({
|
|
2420
|
+
styles = {},
|
|
2421
|
+
...props
|
|
2422
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$a({
|
|
2423
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2424
|
+
width: "54",
|
|
2425
|
+
height: "54"
|
|
2426
|
+
}, props), /*#__PURE__*/React.createElement("path", {
|
|
2427
|
+
d: "M34 18H20a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V20a2 2 0 00-2-2zm-9 14l-5-5 1.41-1.41L25 29.17l7.59-7.59L34 23l-9 9z"
|
|
2428
|
+
})));
|
|
2429
|
+
|
|
2430
|
+
function _extends$9() { _extends$9 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$9.apply(this, arguments); }
|
|
2431
|
+
var ChecklistIcon = (({
|
|
2432
|
+
styles = {},
|
|
2433
|
+
...props
|
|
2434
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$9({
|
|
774
2435
|
width: "54",
|
|
775
|
-
height: "54"
|
|
2436
|
+
height: "54",
|
|
2437
|
+
fill: "none",
|
|
2438
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
776
2439
|
}, props), /*#__PURE__*/React.createElement("path", {
|
|
777
2440
|
fillRule: "evenodd",
|
|
778
|
-
|
|
2441
|
+
clipRule: "evenodd",
|
|
2442
|
+
d: "M19 24h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zm6 18h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zm6-30h-6v6h6V8zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2V8a2 2 0 00-2-2h-6z",
|
|
2443
|
+
fill: "#22242A"
|
|
2444
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
2445
|
+
d: "M26 26a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2zm0 16a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2zm0-32a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2z",
|
|
2446
|
+
fill: "#22242A"
|
|
779
2447
|
})));
|
|
780
2448
|
|
|
781
|
-
function _extends$
|
|
782
|
-
var
|
|
2449
|
+
function _extends$8() { _extends$8 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$8.apply(this, arguments); }
|
|
2450
|
+
var TaglistIcon = (({
|
|
783
2451
|
styles = {},
|
|
784
2452
|
...props
|
|
785
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
786
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2453
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$8({
|
|
787
2454
|
width: "54",
|
|
788
|
-
height: "54"
|
|
2455
|
+
height: "54",
|
|
2456
|
+
fill: "none",
|
|
2457
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
789
2458
|
}, props), /*#__PURE__*/React.createElement("path", {
|
|
790
|
-
|
|
2459
|
+
fillRule: "evenodd",
|
|
2460
|
+
clipRule: "evenodd",
|
|
2461
|
+
d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1z",
|
|
2462
|
+
fill: "#000"
|
|
2463
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
2464
|
+
d: "M11 22a1 1 0 011-1h19a1 1 0 011 1v10a1 1 0 01-1 1H12a1 1 0 01-1-1V22z",
|
|
2465
|
+
fill: "#505562"
|
|
791
2466
|
})));
|
|
792
2467
|
|
|
793
|
-
function _extends$
|
|
2468
|
+
function _extends$7() { _extends$7 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$7.apply(this, arguments); }
|
|
794
2469
|
var FormIcon = (({
|
|
795
2470
|
styles = {},
|
|
796
2471
|
...props
|
|
797
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
2472
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$7({
|
|
798
2473
|
xmlns: "http://www.w3.org/2000/svg",
|
|
799
2474
|
width: "54",
|
|
800
2475
|
height: "54"
|
|
@@ -818,11 +2493,11 @@ var FormIcon = (({
|
|
|
818
2493
|
rx: "1"
|
|
819
2494
|
})));
|
|
820
2495
|
|
|
821
|
-
function _extends$
|
|
2496
|
+
function _extends$6() { _extends$6 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$6.apply(this, arguments); }
|
|
822
2497
|
var ColumnsIcon = (({
|
|
823
2498
|
styles = {},
|
|
824
2499
|
...props
|
|
825
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
2500
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$6({
|
|
826
2501
|
xmlns: "http://www.w3.org/2000/svg",
|
|
827
2502
|
width: "54",
|
|
828
2503
|
height: "54"
|
|
@@ -831,11 +2506,11 @@ var ColumnsIcon = (({
|
|
|
831
2506
|
d: "M8 33v5a1 1 0 001 1h4v2H9a3 3 0 01-3-3v-5h2zm18 6v2H15v-2h11zm13 0v2H28v-2h11zm9-6v5a3 3 0 01-3 3h-4v-2h4a1 1 0 00.993-.883L46 38v-5h2zM8 22v9H6v-9h2zm40 0v9h-2v-9h2zm-35-9v2H9a1 1 0 00-.993.883L8 16v4H6v-4a3 3 0 013-3h4zm32 0a3 3 0 013 3v4h-2v-4a1 1 0 00-.883-.993L45 15h-4v-2h4zm-6 0v2H28v-2h11zm-13 0v2H15v-2h11z"
|
|
832
2507
|
})));
|
|
833
2508
|
|
|
834
|
-
function _extends$
|
|
2509
|
+
function _extends$5() { _extends$5 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$5.apply(this, arguments); }
|
|
835
2510
|
var NumberIcon = (({
|
|
836
2511
|
styles = {},
|
|
837
2512
|
...props
|
|
838
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
2513
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$5({
|
|
839
2514
|
xmlns: "http://www.w3.org/2000/svg",
|
|
840
2515
|
width: "54",
|
|
841
2516
|
height: "54"
|
|
@@ -844,11 +2519,11 @@ var NumberIcon = (({
|
|
|
844
2519
|
d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1zM35 28.444h7l-3.5 4-3.5-4zM35 26h7l-3.5-4-3.5 4z"
|
|
845
2520
|
})));
|
|
846
2521
|
|
|
847
|
-
function _extends$
|
|
2522
|
+
function _extends$4() { _extends$4 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$4.apply(this, arguments); }
|
|
848
2523
|
var RadioIcon = (({
|
|
849
2524
|
styles = {},
|
|
850
2525
|
...props
|
|
851
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
2526
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$4({
|
|
852
2527
|
xmlns: "http://www.w3.org/2000/svg",
|
|
853
2528
|
width: "54",
|
|
854
2529
|
height: "54"
|
|
@@ -856,11 +2531,11 @@ var RadioIcon = (({
|
|
|
856
2531
|
d: "M27 22c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"
|
|
857
2532
|
})));
|
|
858
2533
|
|
|
859
|
-
function _extends$
|
|
2534
|
+
function _extends$3() { _extends$3 = Object.assign || 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); }
|
|
860
2535
|
var SelectIcon = (({
|
|
861
2536
|
styles = {},
|
|
862
2537
|
...props
|
|
863
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
2538
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$3({
|
|
864
2539
|
xmlns: "http://www.w3.org/2000/svg",
|
|
865
2540
|
width: "54",
|
|
866
2541
|
height: "54"
|
|
@@ -869,11 +2544,11 @@ var SelectIcon = (({
|
|
|
869
2544
|
d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1zm-12 7h9l-4.5 6-4.5-6z"
|
|
870
2545
|
})));
|
|
871
2546
|
|
|
872
|
-
function _extends$
|
|
2547
|
+
function _extends$2() { _extends$2 = Object.assign || 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); }
|
|
873
2548
|
var TextIcon = (({
|
|
874
2549
|
styles = {},
|
|
875
2550
|
...props
|
|
876
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
2551
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$2({
|
|
877
2552
|
xmlns: "http://www.w3.org/2000/svg",
|
|
878
2553
|
width: "54",
|
|
879
2554
|
height: "54"
|
|
@@ -881,11 +2556,11 @@ var TextIcon = (({
|
|
|
881
2556
|
d: "M20.58 33.77h-3l-1.18-3.08H11l-1.1 3.08H7l5.27-13.54h2.89zm-5-5.36l-1.86-5-1.83 5zM22 20.23h5.41a15.47 15.47 0 012.4.14 3.42 3.42 0 011.41.55 3.47 3.47 0 011 1.14 3 3 0 01.42 1.58 3.26 3.26 0 01-1.91 2.94 3.63 3.63 0 011.91 1.22 3.28 3.28 0 01.66 2 4 4 0 01-.43 1.8 3.63 3.63 0 01-1.09 1.4 3.89 3.89 0 01-1.83.65q-.69.07-3.3.09H22zm2.73 2.25v3.13h3.8a1.79 1.79 0 001.1-.49 1.41 1.41 0 00.41-1 1.49 1.49 0 00-.35-1 1.54 1.54 0 00-1-.48c-.27 0-1.05-.05-2.34-.05zm0 5.39v3.62h2.57a11.52 11.52 0 001.88-.09 1.65 1.65 0 001-.54 1.6 1.6 0 00.38-1.14 1.75 1.75 0 00-.29-1 1.69 1.69 0 00-.86-.62 9.28 9.28 0 00-2.41-.23zM44.35 28.79l2.65.84a5.94 5.94 0 01-2 3.29A5.74 5.74 0 0141.38 34a5.87 5.87 0 01-4.44-1.84 7.09 7.09 0 01-1.73-5A7.43 7.43 0 0137 21.87 6 6 0 0141.54 20a5.64 5.64 0 014 1.47A5.33 5.33 0 0147 24l-2.7.65a2.8 2.8 0 00-2.86-2.27A3.09 3.09 0 0039 23.42a5.31 5.31 0 00-.93 3.5 5.62 5.62 0 00.93 3.65 3 3 0 002.4 1.09 2.72 2.72 0 001.82-.66 4 4 0 001.13-2.21z"
|
|
882
2557
|
})));
|
|
883
2558
|
|
|
884
|
-
function _extends$
|
|
2559
|
+
function _extends$1() { _extends$1 = Object.assign || 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); }
|
|
885
2560
|
var TextfieldIcon = (({
|
|
886
2561
|
styles = {},
|
|
887
2562
|
...props
|
|
888
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
2563
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$1({
|
|
889
2564
|
xmlns: "http://www.w3.org/2000/svg",
|
|
890
2565
|
width: "54",
|
|
891
2566
|
height: "54"
|
|
@@ -897,755 +2572,438 @@ var TextfieldIcon = (({
|
|
|
897
2572
|
const iconsByType = {
|
|
898
2573
|
button: ButtonIcon,
|
|
899
2574
|
checkbox: CheckboxIcon,
|
|
2575
|
+
checklist: ChecklistIcon,
|
|
900
2576
|
columns: ColumnsIcon,
|
|
901
2577
|
number: NumberIcon,
|
|
902
2578
|
radio: RadioIcon,
|
|
903
2579
|
select: SelectIcon,
|
|
2580
|
+
taglist: TaglistIcon,
|
|
904
2581
|
text: TextIcon,
|
|
905
2582
|
textfield: TextfieldIcon,
|
|
906
2583
|
default: FormIcon
|
|
907
2584
|
};
|
|
908
2585
|
|
|
909
|
-
const
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
}, {
|
|
925
|
-
label: 'Text',
|
|
926
|
-
type: 'text'
|
|
927
|
-
}, {
|
|
928
|
-
label: 'Button',
|
|
929
|
-
type: 'button'
|
|
930
|
-
}];
|
|
931
|
-
function Palette(props) {
|
|
932
|
-
return jsxs("div", {
|
|
933
|
-
class: "fjs-palette",
|
|
934
|
-
children: [jsxs("div", {
|
|
935
|
-
class: "fjs-palette-header",
|
|
936
|
-
title: "Form elements library",
|
|
937
|
-
children: [jsx("span", {
|
|
938
|
-
class: "fjs-hide-compact",
|
|
939
|
-
children: "FORM ELEMENTS "
|
|
940
|
-
}), "LIBRARY"]
|
|
941
|
-
}), jsx("div", {
|
|
942
|
-
class: "fjs-palette-fields fjs-drag-container fjs-no-drop",
|
|
943
|
-
children: types.map(({
|
|
944
|
-
label,
|
|
945
|
-
type
|
|
946
|
-
}) => {
|
|
947
|
-
const Icon = iconsByType[type];
|
|
948
|
-
return jsxs("div", {
|
|
949
|
-
class: "fjs-palette-field fjs-drag-copy fjs-no-drop",
|
|
950
|
-
"data-field-type": type,
|
|
951
|
-
title: `Create a ${label} element`,
|
|
952
|
-
children: [Icon ? jsx(Icon, {
|
|
953
|
-
class: "fjs-palette-field-icon",
|
|
954
|
-
width: "36",
|
|
955
|
-
height: "36",
|
|
956
|
-
viewBox: "0 0 54 54"
|
|
957
|
-
}) : null, jsx("span", {
|
|
958
|
-
class: "fjs-palette-field-text fjs-hide-compact",
|
|
959
|
-
children: label
|
|
960
|
-
})]
|
|
961
|
-
});
|
|
962
|
-
})
|
|
963
|
-
})]
|
|
964
|
-
});
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
function arrayAdd$1(array, index, item) {
|
|
968
|
-
const copy = [...array];
|
|
969
|
-
copy.splice(index, 0, item);
|
|
970
|
-
return copy;
|
|
971
|
-
}
|
|
972
|
-
function arrayRemove$1(array, index) {
|
|
973
|
-
const copy = [...array];
|
|
974
|
-
copy.splice(index, 1);
|
|
975
|
-
return copy;
|
|
976
|
-
}
|
|
977
|
-
function prefixId(id) {
|
|
978
|
-
return `fjs-properties-panel-${id}`;
|
|
979
|
-
}
|
|
980
|
-
function stopPropagation(listener) {
|
|
981
|
-
return event => {
|
|
982
|
-
event.stopPropagation();
|
|
983
|
-
listener(event);
|
|
984
|
-
};
|
|
985
|
-
}
|
|
986
|
-
function textToLabel(text = '...') {
|
|
987
|
-
if (text.length > 10) {
|
|
988
|
-
return `${text.substring(0, 30)}...`;
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
return text;
|
|
992
|
-
}
|
|
993
|
-
const INPUTS = ['checkbox', 'number', 'radio', 'select', 'textfield'];
|
|
994
|
-
|
|
995
|
-
function CheckboxInput(props) {
|
|
996
|
-
const {
|
|
997
|
-
id,
|
|
998
|
-
label,
|
|
999
|
-
onChange,
|
|
1000
|
-
value = false
|
|
1001
|
-
} = props;
|
|
1002
|
-
|
|
1003
|
-
const handleChange = ({
|
|
1004
|
-
target
|
|
1005
|
-
}) => {
|
|
1006
|
-
onChange(target.checked);
|
|
1007
|
-
};
|
|
1008
|
-
|
|
1009
|
-
return jsxs("div", {
|
|
1010
|
-
class: "fjs-properties-panel-checkbox",
|
|
1011
|
-
children: [jsx("label", {
|
|
1012
|
-
for: prefixId(id),
|
|
1013
|
-
class: "fjs-properties-panel-label",
|
|
1014
|
-
children: label
|
|
1015
|
-
}), jsx("input", {
|
|
1016
|
-
id: prefixId(id),
|
|
1017
|
-
type: "checkbox",
|
|
1018
|
-
class: "fjs-properties-panel-input",
|
|
1019
|
-
onChange: handleChange,
|
|
1020
|
-
checked: value
|
|
1021
|
-
})]
|
|
1022
|
-
});
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
function usePrevious(value) {
|
|
1026
|
-
const ref = useRef();
|
|
1027
|
-
useEffect(() => ref.current = value);
|
|
1028
|
-
return ref.current;
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
function useDebounce(fn, dependencies = []) {
|
|
1032
|
-
const debounce = useService('debounce');
|
|
1033
|
-
const callback = useMemo(() => {
|
|
1034
|
-
return debounce(fn);
|
|
1035
|
-
}, dependencies); // cleanup async side-effect if callback #flush is provided.
|
|
1036
|
-
|
|
1037
|
-
useEffect(() => {
|
|
1038
|
-
return () => {
|
|
1039
|
-
typeof callback.flush === 'function' && callback.flush();
|
|
1040
|
-
};
|
|
1041
|
-
}, [callback]);
|
|
1042
|
-
return callback;
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
function NumberInput(props) {
|
|
1046
|
-
const {
|
|
1047
|
-
id,
|
|
1048
|
-
label,
|
|
1049
|
-
max,
|
|
1050
|
-
min,
|
|
1051
|
-
value = '',
|
|
1052
|
-
onInput: _onInput
|
|
1053
|
-
} = props;
|
|
1054
|
-
const onInput = useDebounce(event => {
|
|
2586
|
+
const labelsByType = {
|
|
2587
|
+
button: 'BUTTON',
|
|
2588
|
+
checkbox: 'CHECKBOX',
|
|
2589
|
+
checklist: 'CHECKLIST',
|
|
2590
|
+
columns: 'COLUMNS',
|
|
2591
|
+
default: 'FORM',
|
|
2592
|
+
number: 'NUMBER',
|
|
2593
|
+
radio: 'RADIO',
|
|
2594
|
+
select: 'SELECT',
|
|
2595
|
+
taglist: 'TAGLIST',
|
|
2596
|
+
text: 'TEXT',
|
|
2597
|
+
textfield: 'TEXT FIELD'
|
|
2598
|
+
};
|
|
2599
|
+
const PropertiesPanelHeaderProvider = {
|
|
2600
|
+
getElementLabel: field => {
|
|
1055
2601
|
const {
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
} = event.target;
|
|
2602
|
+
type
|
|
2603
|
+
} = field;
|
|
1059
2604
|
|
|
1060
|
-
if (
|
|
1061
|
-
|
|
2605
|
+
if (type === 'text') {
|
|
2606
|
+
return textToLabel(field.text);
|
|
1062
2607
|
}
|
|
1063
|
-
}, [_onInput]);
|
|
1064
|
-
return jsxs("div", {
|
|
1065
|
-
class: "fjs-properties-panel-number",
|
|
1066
|
-
children: [jsx("label", {
|
|
1067
|
-
for: prefixId(id),
|
|
1068
|
-
class: "fjs-properties-panel-label",
|
|
1069
|
-
children: label
|
|
1070
|
-
}), jsx("input", {
|
|
1071
|
-
id: prefixId(id),
|
|
1072
|
-
type: "number",
|
|
1073
|
-
class: "fjs-properties-panel-input",
|
|
1074
|
-
max: max,
|
|
1075
|
-
min: min,
|
|
1076
|
-
onInput: onInput,
|
|
1077
|
-
value: value
|
|
1078
|
-
})]
|
|
1079
|
-
});
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
function Select(props) {
|
|
1083
|
-
const {
|
|
1084
|
-
id,
|
|
1085
|
-
label,
|
|
1086
|
-
onChange,
|
|
1087
|
-
options,
|
|
1088
|
-
value
|
|
1089
|
-
} = props;
|
|
1090
|
-
|
|
1091
|
-
const handleChange = ({
|
|
1092
|
-
target
|
|
1093
|
-
}) => {
|
|
1094
|
-
onChange(target.value);
|
|
1095
|
-
};
|
|
1096
|
-
|
|
1097
|
-
return jsxs("div", {
|
|
1098
|
-
class: "fjs-properties-panel-select",
|
|
1099
|
-
children: [jsx("label", {
|
|
1100
|
-
for: prefixId(id),
|
|
1101
|
-
class: "fjs-properties-panel-label",
|
|
1102
|
-
children: label
|
|
1103
|
-
}), jsx("select", {
|
|
1104
|
-
id: prefixId(id),
|
|
1105
|
-
class: "fjs-properties-panel-input",
|
|
1106
|
-
onInput: handleChange,
|
|
1107
|
-
children: options.map(option => {
|
|
1108
|
-
return jsx("option", {
|
|
1109
|
-
value: option.value,
|
|
1110
|
-
selected: option.value === value,
|
|
1111
|
-
children: option.label
|
|
1112
|
-
});
|
|
1113
|
-
})
|
|
1114
|
-
})]
|
|
1115
|
-
});
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
function Textarea(props) {
|
|
1119
|
-
const {
|
|
1120
|
-
id,
|
|
1121
|
-
label,
|
|
1122
|
-
rows = 10,
|
|
1123
|
-
value = '',
|
|
1124
|
-
onInput: _onInput
|
|
1125
|
-
} = props;
|
|
1126
|
-
const onInput = useDebounce(event => {
|
|
1127
|
-
const value = event.target.value;
|
|
1128
|
-
|
|
1129
|
-
_onInput(value.length ? value : undefined);
|
|
1130
|
-
}, [_onInput]);
|
|
1131
|
-
return jsxs("div", {
|
|
1132
|
-
class: "fjs-properties-panel-textarea",
|
|
1133
|
-
children: [jsx("label", {
|
|
1134
|
-
for: prefixId(id),
|
|
1135
|
-
class: "fjs-properties-panel-label",
|
|
1136
|
-
children: label
|
|
1137
|
-
}), jsx("textarea", {
|
|
1138
|
-
id: prefixId(id),
|
|
1139
|
-
spellcheck: false,
|
|
1140
|
-
class: "fjs-properties-panel-input",
|
|
1141
|
-
onInput: onInput,
|
|
1142
|
-
rows: rows,
|
|
1143
|
-
value: value
|
|
1144
|
-
})]
|
|
1145
|
-
});
|
|
1146
|
-
}
|
|
1147
2608
|
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
id,
|
|
1151
|
-
label,
|
|
1152
|
-
validate = () => null,
|
|
1153
|
-
onInput: _onInput,
|
|
1154
|
-
value = ''
|
|
1155
|
-
} = props;
|
|
1156
|
-
const prevValue = usePrevious(value);
|
|
1157
|
-
const [cachedValue, setCachedValue] = useState(null);
|
|
1158
|
-
const [error, setError] = useState(null);
|
|
1159
|
-
useEffect(() => setError(validate(value)), [validate, value]);
|
|
1160
|
-
const onInput = useDebounce(event => {
|
|
1161
|
-
const value = event.target.value;
|
|
1162
|
-
const error = validate(value);
|
|
1163
|
-
|
|
1164
|
-
if (error) {
|
|
1165
|
-
setCachedValue(value);
|
|
1166
|
-
} else {
|
|
1167
|
-
_onInput(value.length ? value : undefined);
|
|
2609
|
+
if (type === 'default') {
|
|
2610
|
+
return field.id;
|
|
1168
2611
|
}
|
|
1169
2612
|
|
|
1170
|
-
|
|
1171
|
-
},
|
|
2613
|
+
return field.label;
|
|
2614
|
+
},
|
|
2615
|
+
getElementIcon: field => {
|
|
2616
|
+
const {
|
|
2617
|
+
type
|
|
2618
|
+
} = field;
|
|
2619
|
+
const Icon = iconsByType[type];
|
|
2620
|
+
|
|
2621
|
+
if (Icon) {
|
|
2622
|
+
return () => jsx(Icon, {
|
|
2623
|
+
width: "36",
|
|
2624
|
+
height: "36",
|
|
2625
|
+
viewBox: "0 0 54 54"
|
|
2626
|
+
});
|
|
2627
|
+
}
|
|
2628
|
+
},
|
|
2629
|
+
getTypeLabel: field => {
|
|
2630
|
+
const {
|
|
2631
|
+
type
|
|
2632
|
+
} = field;
|
|
2633
|
+
return labelsByType[type];
|
|
2634
|
+
}
|
|
2635
|
+
};
|
|
1172
2636
|
|
|
1173
|
-
|
|
1174
|
-
|
|
2637
|
+
/**
|
|
2638
|
+
* Provide placeholders for empty and multiple state.
|
|
2639
|
+
*/
|
|
2640
|
+
const PropertiesPanelPlaceholderProvider = {
|
|
2641
|
+
getEmpty: () => {
|
|
2642
|
+
return {
|
|
2643
|
+
text: 'Select a form field to edit its properties.'
|
|
2644
|
+
};
|
|
2645
|
+
},
|
|
2646
|
+
getMultiple: () => {
|
|
2647
|
+
return {
|
|
2648
|
+
text: 'Multiple form fields are selected. Select a single form field to edit its properties.'
|
|
2649
|
+
};
|
|
1175
2650
|
}
|
|
2651
|
+
};
|
|
1176
2652
|
|
|
1177
|
-
|
|
2653
|
+
function ActionEntry(props) {
|
|
2654
|
+
const {
|
|
2655
|
+
editField,
|
|
2656
|
+
field
|
|
2657
|
+
} = props;
|
|
2658
|
+
const {
|
|
2659
|
+
type
|
|
2660
|
+
} = field;
|
|
2661
|
+
const entries = [];
|
|
1178
2662
|
|
|
1179
|
-
if (
|
|
1180
|
-
|
|
2663
|
+
if (type === 'button') {
|
|
2664
|
+
entries.push({
|
|
2665
|
+
id: 'action',
|
|
2666
|
+
component: Action,
|
|
2667
|
+
editField: editField,
|
|
2668
|
+
field: field,
|
|
2669
|
+
isEdited: isEdited$4
|
|
2670
|
+
});
|
|
1181
2671
|
}
|
|
1182
2672
|
|
|
1183
|
-
return
|
|
1184
|
-
class: "fjs-properties-panel-text",
|
|
1185
|
-
children: [jsx("label", {
|
|
1186
|
-
for: prefixId(id),
|
|
1187
|
-
class: "fjs-properties-panel-label",
|
|
1188
|
-
children: label
|
|
1189
|
-
}), jsx("input", {
|
|
1190
|
-
id: prefixId(id),
|
|
1191
|
-
type: "text",
|
|
1192
|
-
spellcheck: false,
|
|
1193
|
-
class: classes.join(' '),
|
|
1194
|
-
onInput: onInput,
|
|
1195
|
-
value: value
|
|
1196
|
-
}), error && jsx("div", {
|
|
1197
|
-
class: "fjs-properties-panel-error",
|
|
1198
|
-
children: error
|
|
1199
|
-
})]
|
|
1200
|
-
});
|
|
2673
|
+
return entries;
|
|
1201
2674
|
}
|
|
1202
2675
|
|
|
1203
|
-
function
|
|
2676
|
+
function Action(props) {
|
|
1204
2677
|
const {
|
|
1205
2678
|
editField,
|
|
1206
2679
|
field,
|
|
1207
|
-
id
|
|
1208
|
-
label,
|
|
1209
|
-
path
|
|
2680
|
+
id
|
|
1210
2681
|
} = props;
|
|
2682
|
+
const path = ['action'];
|
|
1211
2683
|
|
|
1212
|
-
const
|
|
1213
|
-
|
|
1214
|
-
editField(field, path, value);
|
|
1215
|
-
} else {
|
|
1216
|
-
props.onChange(value);
|
|
1217
|
-
}
|
|
2684
|
+
const getValue = () => {
|
|
2685
|
+
return get(field, path, '');
|
|
1218
2686
|
};
|
|
1219
2687
|
|
|
1220
|
-
const
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
2688
|
+
const setValue = value => {
|
|
2689
|
+
return editField(field, path, value);
|
|
2690
|
+
};
|
|
2691
|
+
|
|
2692
|
+
const getOptions = () => [{
|
|
2693
|
+
label: 'Submit',
|
|
2694
|
+
value: 'submit'
|
|
2695
|
+
}, {
|
|
2696
|
+
label: 'Reset',
|
|
2697
|
+
value: 'reset'
|
|
2698
|
+
}];
|
|
2699
|
+
|
|
2700
|
+
return SelectEntry({
|
|
2701
|
+
element: field,
|
|
2702
|
+
getOptions,
|
|
2703
|
+
getValue,
|
|
2704
|
+
id,
|
|
2705
|
+
label: 'Action',
|
|
2706
|
+
setValue
|
|
1229
2707
|
});
|
|
1230
2708
|
}
|
|
1231
2709
|
|
|
1232
|
-
function
|
|
2710
|
+
function ColumnsEntry(props) {
|
|
1233
2711
|
const {
|
|
1234
2712
|
editField,
|
|
1235
|
-
field
|
|
1236
|
-
id,
|
|
1237
|
-
label,
|
|
1238
|
-
max,
|
|
1239
|
-
min,
|
|
1240
|
-
onChange,
|
|
1241
|
-
path
|
|
2713
|
+
field
|
|
1242
2714
|
} = props;
|
|
2715
|
+
const {
|
|
2716
|
+
type
|
|
2717
|
+
} = field;
|
|
2718
|
+
const entries = [];
|
|
1243
2719
|
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
2720
|
+
if (type === 'columns') {
|
|
2721
|
+
entries.push({
|
|
2722
|
+
id: 'columns',
|
|
2723
|
+
component: Columns,
|
|
2724
|
+
editField: editField,
|
|
2725
|
+
field: field,
|
|
2726
|
+
isEdited: isEdited$5
|
|
2727
|
+
});
|
|
2728
|
+
}
|
|
1251
2729
|
|
|
1252
|
-
|
|
1253
|
-
return jsx("div", {
|
|
1254
|
-
class: "fjs-properties-panel-entry",
|
|
1255
|
-
children: jsx(NumberInput, {
|
|
1256
|
-
id: id,
|
|
1257
|
-
label: label,
|
|
1258
|
-
max: max,
|
|
1259
|
-
min: min,
|
|
1260
|
-
onInput: onInput,
|
|
1261
|
-
value: value
|
|
1262
|
-
})
|
|
1263
|
-
});
|
|
2730
|
+
return entries;
|
|
1264
2731
|
}
|
|
1265
2732
|
|
|
1266
|
-
function
|
|
2733
|
+
function Columns(props) {
|
|
1267
2734
|
const {
|
|
1268
2735
|
editField,
|
|
1269
2736
|
field,
|
|
1270
|
-
id
|
|
1271
|
-
description,
|
|
1272
|
-
label,
|
|
1273
|
-
options,
|
|
1274
|
-
path
|
|
2737
|
+
id
|
|
1275
2738
|
} = props;
|
|
2739
|
+
const debounce = useService('debounce');
|
|
2740
|
+
|
|
2741
|
+
const getValue = () => {
|
|
2742
|
+
return field.components.length;
|
|
2743
|
+
};
|
|
2744
|
+
|
|
2745
|
+
const setValue = value => {
|
|
2746
|
+
let components = field.components.slice();
|
|
1276
2747
|
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
2748
|
+
if (value > components.length) {
|
|
2749
|
+
while (value > components.length) {
|
|
2750
|
+
components.push(Default.create({
|
|
2751
|
+
_parent: field.id
|
|
2752
|
+
}));
|
|
2753
|
+
}
|
|
1280
2754
|
} else {
|
|
1281
|
-
|
|
2755
|
+
components = components.slice(0, value);
|
|
1282
2756
|
}
|
|
2757
|
+
|
|
2758
|
+
editField(field, 'components', components);
|
|
1283
2759
|
};
|
|
1284
2760
|
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
options: options,
|
|
1293
|
-
value: value
|
|
1294
|
-
}), description && jsx("div", {
|
|
1295
|
-
class: "fjs-properties-panel-description",
|
|
1296
|
-
children: description
|
|
1297
|
-
})]
|
|
2761
|
+
return NumberFieldEntry({
|
|
2762
|
+
debounce,
|
|
2763
|
+
element: field,
|
|
2764
|
+
getValue,
|
|
2765
|
+
id,
|
|
2766
|
+
label: 'Columns',
|
|
2767
|
+
setValue
|
|
1298
2768
|
});
|
|
1299
2769
|
}
|
|
1300
2770
|
|
|
1301
|
-
function
|
|
2771
|
+
function DescriptionEntry(props) {
|
|
1302
2772
|
const {
|
|
1303
2773
|
editField,
|
|
1304
|
-
field
|
|
1305
|
-
id,
|
|
1306
|
-
description,
|
|
1307
|
-
label,
|
|
1308
|
-
onChange,
|
|
1309
|
-
path
|
|
2774
|
+
field
|
|
1310
2775
|
} = props;
|
|
2776
|
+
const {
|
|
2777
|
+
type
|
|
2778
|
+
} = field;
|
|
2779
|
+
const entries = [];
|
|
1311
2780
|
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
2781
|
+
if (INPUTS.includes(type)) {
|
|
2782
|
+
entries.push({
|
|
2783
|
+
id: 'description',
|
|
2784
|
+
component: Description,
|
|
2785
|
+
editField: editField,
|
|
2786
|
+
field: field,
|
|
2787
|
+
isEdited: isEdited$1
|
|
2788
|
+
});
|
|
2789
|
+
}
|
|
1319
2790
|
|
|
1320
|
-
|
|
1321
|
-
return jsxs("div", {
|
|
1322
|
-
class: "fjs-properties-panel-entry",
|
|
1323
|
-
children: [jsx(Textarea, {
|
|
1324
|
-
id: id,
|
|
1325
|
-
label: label,
|
|
1326
|
-
onInput: onInput,
|
|
1327
|
-
value: value
|
|
1328
|
-
}), description && jsx("div", {
|
|
1329
|
-
class: "fjs-properties-panel-description",
|
|
1330
|
-
children: description
|
|
1331
|
-
})]
|
|
1332
|
-
});
|
|
2791
|
+
return entries;
|
|
1333
2792
|
}
|
|
1334
2793
|
|
|
1335
|
-
function
|
|
2794
|
+
function Description(props) {
|
|
1336
2795
|
const {
|
|
1337
2796
|
editField,
|
|
1338
2797
|
field,
|
|
1339
|
-
id
|
|
1340
|
-
description,
|
|
1341
|
-
label,
|
|
1342
|
-
onChange,
|
|
1343
|
-
path,
|
|
1344
|
-
validate
|
|
2798
|
+
id
|
|
1345
2799
|
} = props;
|
|
2800
|
+
const debounce = useService('debounce');
|
|
2801
|
+
const path = ['description'];
|
|
1346
2802
|
|
|
1347
|
-
const
|
|
1348
|
-
|
|
1349
|
-
editField(field, path, value);
|
|
1350
|
-
} else {
|
|
1351
|
-
onChange(value);
|
|
1352
|
-
}
|
|
2803
|
+
const getValue = () => {
|
|
2804
|
+
return get(field, path, '');
|
|
1353
2805
|
};
|
|
1354
2806
|
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
children: description
|
|
1367
|
-
})]
|
|
2807
|
+
const setValue = value => {
|
|
2808
|
+
return editField(field, path, value);
|
|
2809
|
+
};
|
|
2810
|
+
|
|
2811
|
+
return TextfieldEntry({
|
|
2812
|
+
debounce,
|
|
2813
|
+
element: field,
|
|
2814
|
+
getValue,
|
|
2815
|
+
id,
|
|
2816
|
+
label: 'Field description',
|
|
2817
|
+
setValue
|
|
1368
2818
|
});
|
|
1369
2819
|
}
|
|
1370
2820
|
|
|
1371
|
-
function
|
|
1372
|
-
var CreateIcon = (({
|
|
1373
|
-
styles = {},
|
|
1374
|
-
...props
|
|
1375
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$3({
|
|
1376
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1377
|
-
width: "12",
|
|
1378
|
-
height: "12"
|
|
1379
|
-
}, props), /*#__PURE__*/React.createElement("path", {
|
|
1380
|
-
fillRule: "evenodd",
|
|
1381
|
-
d: "M7 0v5h5v2H7v5H5V7H0V5h5V0h2z"
|
|
1382
|
-
})));
|
|
1383
|
-
|
|
1384
|
-
function _extends$2() { _extends$2 = Object.assign || 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); }
|
|
1385
|
-
var ListArrowIcon = (({
|
|
1386
|
-
styles = {},
|
|
1387
|
-
...props
|
|
1388
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$2({
|
|
1389
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1390
|
-
width: "7",
|
|
1391
|
-
height: "9"
|
|
1392
|
-
}, props), /*#__PURE__*/React.createElement("path", {
|
|
1393
|
-
fillRule: "evenodd",
|
|
1394
|
-
d: "M6.25 4.421L4.836 5.835h-.001L2.007 8.663.593 7.249 3.421 4.42.593 1.593 2.007.178 6.25 4.421z"
|
|
1395
|
-
})));
|
|
1396
|
-
|
|
1397
|
-
function _extends$1() { _extends$1 = Object.assign || 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); }
|
|
1398
|
-
var ListDeleteIcon = (({
|
|
1399
|
-
styles = {},
|
|
1400
|
-
...props
|
|
1401
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$1({
|
|
1402
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1403
|
-
width: "11",
|
|
1404
|
-
height: "14"
|
|
1405
|
-
}, props), /*#__PURE__*/React.createElement("path", {
|
|
1406
|
-
d: "M10 4v8c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V4h9zM8 6H3v4.8c0 .66.5 1.2 1.111 1.2H6.89C7.5 12 8 11.46 8 10.8V6zm3-5H8.5l-1-1h-4l-1 1H0v1.5h11V1z"
|
|
1407
|
-
})));
|
|
1408
|
-
|
|
1409
|
-
function _extends() { _extends = Object.assign || 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); }
|
|
1410
|
-
var SectionArrowIcon = (({
|
|
1411
|
-
styles = {},
|
|
1412
|
-
...props
|
|
1413
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends({
|
|
1414
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1415
|
-
width: "8",
|
|
1416
|
-
height: "12"
|
|
1417
|
-
}, props), /*#__PURE__*/React.createElement("path", {
|
|
1418
|
-
fillRule: "evenodd",
|
|
1419
|
-
d: "M2.007 11.66L.593 10.248l4.242-4.243L.593 1.761 2.007.347l5.657 5.657-5.657 5.657z"
|
|
1420
|
-
})));
|
|
1421
|
-
|
|
1422
|
-
function CollapsibleEntry(props) {
|
|
2821
|
+
function DefaultOptionEntry(props) {
|
|
1423
2822
|
const {
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
removeEntry = () => {}
|
|
2823
|
+
editField,
|
|
2824
|
+
field
|
|
1427
2825
|
} = props;
|
|
1428
|
-
const
|
|
2826
|
+
const {
|
|
2827
|
+
type
|
|
2828
|
+
} = field;
|
|
2829
|
+
const entries = []; // Only make default values available when they are statically defined
|
|
1429
2830
|
|
|
1430
|
-
|
|
2831
|
+
if (!INPUTS.includes(type) || VALUES_INPUTS.includes(type) && !field.values) {
|
|
2832
|
+
return entries;
|
|
2833
|
+
}
|
|
1431
2834
|
|
|
1432
|
-
const
|
|
2835
|
+
const defaultOptions = {
|
|
2836
|
+
editField,
|
|
2837
|
+
field,
|
|
2838
|
+
id: 'defaultValue',
|
|
2839
|
+
label: 'Default value'
|
|
2840
|
+
};
|
|
1433
2841
|
|
|
1434
|
-
if (
|
|
1435
|
-
|
|
2842
|
+
if (type === 'checkbox') {
|
|
2843
|
+
entries.push({ ...defaultOptions,
|
|
2844
|
+
component: DefaultValueCheckbox,
|
|
2845
|
+
isEdited: isEdited$4
|
|
2846
|
+
});
|
|
1436
2847
|
}
|
|
1437
2848
|
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
children: [jsx(ListArrowIcon, {
|
|
1445
|
-
class: collapsed ? 'fjs-arrow-right' : 'fjs-arrow-down'
|
|
1446
|
-
}), jsx("span", {
|
|
1447
|
-
class: "fjs-properties-panel-collapsible-entry-header-label",
|
|
1448
|
-
children: label
|
|
1449
|
-
})]
|
|
1450
|
-
}), jsx("button", {
|
|
1451
|
-
class: "fjs-properties-panel-collapsible-entry-header-remove-entry",
|
|
1452
|
-
onClick: stopPropagation(removeEntry),
|
|
1453
|
-
children: jsx(ListDeleteIcon, {})
|
|
1454
|
-
})]
|
|
1455
|
-
}), collapsed ? null : jsx("div", {
|
|
1456
|
-
class: "fjs-properties-panel-collapsible-entry-entries",
|
|
1457
|
-
children: children
|
|
1458
|
-
})]
|
|
1459
|
-
});
|
|
1460
|
-
}
|
|
2849
|
+
if (type === 'number') {
|
|
2850
|
+
entries.push({ ...defaultOptions,
|
|
2851
|
+
component: DefaultValueNumber,
|
|
2852
|
+
isEdited: isEdited$5
|
|
2853
|
+
});
|
|
2854
|
+
}
|
|
1461
2855
|
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
}
|
|
1468
|
-
const [open, setOpen] = useState(hasEntries);
|
|
2856
|
+
if (type === 'radio' || type === 'select') {
|
|
2857
|
+
entries.push({ ...defaultOptions,
|
|
2858
|
+
component: DefaultValueSingleSelect,
|
|
2859
|
+
isEdited: isEdited$4
|
|
2860
|
+
});
|
|
2861
|
+
} // todo(Skaiir): implement a multiselect equivalent (cf. https://github.com/bpmn-io/form-js/issues/265)
|
|
1469
2862
|
|
|
1470
|
-
const toggleOpen = () => setOpen(!open);
|
|
1471
2863
|
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
2864
|
+
if (type === 'textfield') {
|
|
2865
|
+
entries.push({ ...defaultOptions,
|
|
2866
|
+
component: DefaultValueTextfield,
|
|
2867
|
+
isEdited: isEdited$1
|
|
2868
|
+
});
|
|
2869
|
+
}
|
|
1477
2870
|
|
|
1478
|
-
return
|
|
1479
|
-
class: "fjs-properties-panel-group",
|
|
1480
|
-
children: [jsxs("div", {
|
|
1481
|
-
class: "fjs-properties-panel-group-header",
|
|
1482
|
-
onClick: hasEntries ? toggleOpen : () => {},
|
|
1483
|
-
children: [jsx("span", {
|
|
1484
|
-
class: "fjs-properties-panel-group-header-label",
|
|
1485
|
-
children: label
|
|
1486
|
-
}), jsxs("div", {
|
|
1487
|
-
class: "fjs-properties-panel-group-header-buttons",
|
|
1488
|
-
children: [props.addEntry ? jsx("button", {
|
|
1489
|
-
class: "fjs-properties-panel-group-header-button fjs-properties-panel-group-header-button-add-entry",
|
|
1490
|
-
onClick: addEntry,
|
|
1491
|
-
children: jsx(CreateIcon, {})
|
|
1492
|
-
}) : null, jsx("button", {
|
|
1493
|
-
class: "fjs-properties-panel-group-header-button fjs-properties-panel-group-header-button-toggle-open",
|
|
1494
|
-
children: jsx(SectionArrowIcon, {
|
|
1495
|
-
class: hasEntries && open ? 'fjs-arrow-down' : 'fjs-arrow-right'
|
|
1496
|
-
})
|
|
1497
|
-
})]
|
|
1498
|
-
})]
|
|
1499
|
-
}), hasEntries && open ? jsx("div", {
|
|
1500
|
-
class: "fjs-properties-panel-group-entries",
|
|
1501
|
-
children: children
|
|
1502
|
-
}) : null]
|
|
1503
|
-
});
|
|
2871
|
+
return entries;
|
|
1504
2872
|
}
|
|
1505
2873
|
|
|
1506
|
-
function
|
|
2874
|
+
function DefaultValueCheckbox(props) {
|
|
1507
2875
|
const {
|
|
1508
2876
|
editField,
|
|
1509
|
-
field
|
|
2877
|
+
field,
|
|
2878
|
+
id,
|
|
2879
|
+
label
|
|
1510
2880
|
} = props;
|
|
1511
|
-
const options = [{
|
|
1512
|
-
label: 'Submit',
|
|
1513
|
-
value: 'submit'
|
|
1514
|
-
}, {
|
|
1515
|
-
label: 'Reset',
|
|
1516
|
-
value: 'reset'
|
|
1517
|
-
}];
|
|
1518
|
-
return jsx(SelectEntry, {
|
|
1519
|
-
editField: editField,
|
|
1520
|
-
field: field,
|
|
1521
|
-
id: "action",
|
|
1522
|
-
label: "Action",
|
|
1523
|
-
options: options,
|
|
1524
|
-
path: ['action']
|
|
1525
|
-
});
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
function ColumnsEntry(props) {
|
|
1529
2881
|
const {
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
2882
|
+
defaultValue
|
|
2883
|
+
} = field;
|
|
2884
|
+
const path = ['defaultValue'];
|
|
1533
2885
|
|
|
1534
|
-
const
|
|
1535
|
-
|
|
2886
|
+
const getOptions = () => {
|
|
2887
|
+
return [{
|
|
2888
|
+
label: 'Checked',
|
|
2889
|
+
value: 'true'
|
|
2890
|
+
}, {
|
|
2891
|
+
label: 'Not checked',
|
|
2892
|
+
value: 'false'
|
|
2893
|
+
}];
|
|
2894
|
+
};
|
|
1536
2895
|
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
_parent: field.id
|
|
1541
|
-
}));
|
|
1542
|
-
}
|
|
1543
|
-
} else {
|
|
1544
|
-
components = components.slice(0, value);
|
|
1545
|
-
}
|
|
2896
|
+
const setValue = value => {
|
|
2897
|
+
return editField(field, path, parseStringToBoolean(value));
|
|
2898
|
+
};
|
|
1546
2899
|
|
|
1547
|
-
|
|
2900
|
+
const getValue = () => {
|
|
2901
|
+
return parseBooleanToString(defaultValue);
|
|
1548
2902
|
};
|
|
1549
2903
|
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
value: value,
|
|
1558
|
-
min: "1",
|
|
1559
|
-
max: "3"
|
|
1560
|
-
})
|
|
2904
|
+
return SelectEntry({
|
|
2905
|
+
element: field,
|
|
2906
|
+
getOptions,
|
|
2907
|
+
getValue,
|
|
2908
|
+
id,
|
|
2909
|
+
label,
|
|
2910
|
+
setValue
|
|
1561
2911
|
});
|
|
1562
2912
|
}
|
|
1563
2913
|
|
|
1564
|
-
function
|
|
2914
|
+
function DefaultValueNumber(props) {
|
|
1565
2915
|
const {
|
|
1566
2916
|
editField,
|
|
1567
|
-
field
|
|
2917
|
+
field,
|
|
2918
|
+
id,
|
|
2919
|
+
label
|
|
1568
2920
|
} = props;
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
2921
|
+
const debounce = useService('debounce');
|
|
2922
|
+
const path = ['defaultValue'];
|
|
2923
|
+
|
|
2924
|
+
const getValue = () => {
|
|
2925
|
+
return get(field, path, '');
|
|
2926
|
+
};
|
|
2927
|
+
|
|
2928
|
+
const setValue = value => {
|
|
2929
|
+
return editField(field, path, value);
|
|
2930
|
+
};
|
|
2931
|
+
|
|
2932
|
+
return NumberFieldEntry({
|
|
2933
|
+
debounce,
|
|
2934
|
+
element: field,
|
|
2935
|
+
getValue,
|
|
2936
|
+
id,
|
|
2937
|
+
label,
|
|
2938
|
+
setValue
|
|
1575
2939
|
});
|
|
1576
2940
|
}
|
|
1577
2941
|
|
|
1578
|
-
function
|
|
2942
|
+
function DefaultValueSingleSelect(props) {
|
|
1579
2943
|
const {
|
|
1580
2944
|
editField,
|
|
1581
|
-
field
|
|
2945
|
+
field,
|
|
2946
|
+
id,
|
|
2947
|
+
label
|
|
1582
2948
|
} = props;
|
|
1583
2949
|
const {
|
|
1584
2950
|
defaultValue,
|
|
1585
|
-
type,
|
|
1586
2951
|
values = []
|
|
1587
2952
|
} = field;
|
|
2953
|
+
const path = ['defaultValue'];
|
|
1588
2954
|
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
label: '
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
label: 'Not checked',
|
|
1595
|
-
value: 'false'
|
|
1596
|
-
}];
|
|
2955
|
+
const getOptions = () => {
|
|
2956
|
+
return [{
|
|
2957
|
+
label: '<none>'
|
|
2958
|
+
}, ...values];
|
|
2959
|
+
};
|
|
1597
2960
|
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
2961
|
+
const setValue = value => {
|
|
2962
|
+
return editField(field, path, value.length ? value : undefined);
|
|
2963
|
+
};
|
|
1601
2964
|
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
onChange: onChange,
|
|
1606
|
-
options: options,
|
|
1607
|
-
value: parseBooleanToString(defaultValue)
|
|
1608
|
-
});
|
|
1609
|
-
}
|
|
2965
|
+
const getValue = () => {
|
|
2966
|
+
return defaultValue;
|
|
2967
|
+
};
|
|
1610
2968
|
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
2969
|
+
return SelectEntry({
|
|
2970
|
+
element: field,
|
|
2971
|
+
getOptions,
|
|
2972
|
+
getValue,
|
|
2973
|
+
id,
|
|
2974
|
+
label,
|
|
2975
|
+
setValue
|
|
2976
|
+
});
|
|
2977
|
+
}
|
|
1620
2978
|
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
2979
|
+
function DefaultValueTextfield(props) {
|
|
2980
|
+
const {
|
|
2981
|
+
editField,
|
|
2982
|
+
field,
|
|
2983
|
+
id,
|
|
2984
|
+
label
|
|
2985
|
+
} = props;
|
|
2986
|
+
const debounce = useService('debounce');
|
|
2987
|
+
const path = ['defaultValue'];
|
|
1625
2988
|
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
2989
|
+
const getValue = () => {
|
|
2990
|
+
return get(field, path, '');
|
|
2991
|
+
};
|
|
1629
2992
|
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
2993
|
+
const setValue = value => {
|
|
2994
|
+
return editField(field, path, value);
|
|
2995
|
+
};
|
|
2996
|
+
|
|
2997
|
+
return TextfieldEntry({
|
|
2998
|
+
debounce,
|
|
2999
|
+
element: field,
|
|
3000
|
+
getValue,
|
|
3001
|
+
id,
|
|
3002
|
+
label,
|
|
3003
|
+
setValue
|
|
3004
|
+
});
|
|
3005
|
+
} // helpers /////////////////
|
|
1638
3006
|
|
|
1639
|
-
if (type === 'textfield') {
|
|
1640
|
-
return jsx(TextInputEntry, {
|
|
1641
|
-
editField: editField,
|
|
1642
|
-
field: field,
|
|
1643
|
-
id: "defaultValue",
|
|
1644
|
-
label: "Default Value",
|
|
1645
|
-
path: ['defaultValue']
|
|
1646
|
-
});
|
|
1647
|
-
}
|
|
1648
|
-
}
|
|
1649
3007
|
|
|
1650
3008
|
function parseStringToBoolean(value) {
|
|
1651
3009
|
if (value === 'true') {
|
|
@@ -1668,17 +3026,46 @@ function DisabledEntry(props) {
|
|
|
1668
3026
|
editField,
|
|
1669
3027
|
field
|
|
1670
3028
|
} = props;
|
|
3029
|
+
const {
|
|
3030
|
+
type
|
|
3031
|
+
} = field;
|
|
3032
|
+
const entries = [];
|
|
3033
|
+
|
|
3034
|
+
if (INPUTS.includes(type)) {
|
|
3035
|
+
entries.push({
|
|
3036
|
+
id: 'disabled',
|
|
3037
|
+
component: Disabled,
|
|
3038
|
+
editField: editField,
|
|
3039
|
+
field: field,
|
|
3040
|
+
isEdited: isEdited$6
|
|
3041
|
+
});
|
|
3042
|
+
}
|
|
3043
|
+
|
|
3044
|
+
return entries;
|
|
3045
|
+
}
|
|
3046
|
+
|
|
3047
|
+
function Disabled(props) {
|
|
3048
|
+
const {
|
|
3049
|
+
editField,
|
|
3050
|
+
field,
|
|
3051
|
+
id
|
|
3052
|
+
} = props;
|
|
3053
|
+
const path = ['disabled'];
|
|
3054
|
+
|
|
3055
|
+
const getValue = () => {
|
|
3056
|
+
return get(field, path, '');
|
|
3057
|
+
};
|
|
1671
3058
|
|
|
1672
|
-
const
|
|
1673
|
-
editField(field,
|
|
3059
|
+
const setValue = value => {
|
|
3060
|
+
return editField(field, path, value);
|
|
1674
3061
|
};
|
|
1675
3062
|
|
|
1676
|
-
return
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
3063
|
+
return CheckboxEntry({
|
|
3064
|
+
element: field,
|
|
3065
|
+
getValue,
|
|
3066
|
+
id,
|
|
3067
|
+
label: 'Disabled',
|
|
3068
|
+
setValue
|
|
1682
3069
|
});
|
|
1683
3070
|
}
|
|
1684
3071
|
|
|
@@ -1687,7 +3074,38 @@ function IdEntry(props) {
|
|
|
1687
3074
|
editField,
|
|
1688
3075
|
field
|
|
1689
3076
|
} = props;
|
|
3077
|
+
const entries = [];
|
|
3078
|
+
|
|
3079
|
+
if (field.type === 'default') {
|
|
3080
|
+
entries.push({
|
|
3081
|
+
id: 'id',
|
|
3082
|
+
component: Id,
|
|
3083
|
+
editField: editField,
|
|
3084
|
+
field: field,
|
|
3085
|
+
isEdited: isEdited$1
|
|
3086
|
+
});
|
|
3087
|
+
}
|
|
3088
|
+
|
|
3089
|
+
return entries;
|
|
3090
|
+
}
|
|
3091
|
+
|
|
3092
|
+
function Id(props) {
|
|
3093
|
+
const {
|
|
3094
|
+
editField,
|
|
3095
|
+
field,
|
|
3096
|
+
id
|
|
3097
|
+
} = props;
|
|
1690
3098
|
const formFieldRegistry = useService('formFieldRegistry');
|
|
3099
|
+
const debounce = useService('debounce');
|
|
3100
|
+
const path = ['id'];
|
|
3101
|
+
|
|
3102
|
+
const getValue = () => {
|
|
3103
|
+
return get(field, path, '');
|
|
3104
|
+
};
|
|
3105
|
+
|
|
3106
|
+
const setValue = value => {
|
|
3107
|
+
return editField(field, path, value);
|
|
3108
|
+
};
|
|
1691
3109
|
|
|
1692
3110
|
const validate = value => {
|
|
1693
3111
|
if (isUndefined(value) || !value.length) {
|
|
@@ -1703,16 +3121,18 @@ function IdEntry(props) {
|
|
|
1703
3121
|
return validateId(value) || null;
|
|
1704
3122
|
};
|
|
1705
3123
|
|
|
1706
|
-
return
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
3124
|
+
return TextfieldEntry({
|
|
3125
|
+
debounce,
|
|
3126
|
+
element: field,
|
|
3127
|
+
getValue,
|
|
3128
|
+
id,
|
|
3129
|
+
label: 'ID',
|
|
3130
|
+
setValue,
|
|
3131
|
+
validate
|
|
1713
3132
|
});
|
|
1714
3133
|
} // id structural validation /////////////
|
|
1715
3134
|
|
|
3135
|
+
|
|
1716
3136
|
const SPACE_REGEX = /\s/; // for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar
|
|
1717
3137
|
|
|
1718
3138
|
const QNAME_REGEX = /^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i; // for ID validation as per BPMN Schema (QName - Namespace)
|
|
@@ -1742,7 +3162,41 @@ function KeyEntry(props) {
|
|
|
1742
3162
|
editField,
|
|
1743
3163
|
field
|
|
1744
3164
|
} = props;
|
|
3165
|
+
const {
|
|
3166
|
+
type
|
|
3167
|
+
} = field;
|
|
3168
|
+
const entries = [];
|
|
3169
|
+
|
|
3170
|
+
if (INPUTS.includes(type)) {
|
|
3171
|
+
entries.push({
|
|
3172
|
+
id: 'key',
|
|
3173
|
+
component: Key$1,
|
|
3174
|
+
editField: editField,
|
|
3175
|
+
field: field,
|
|
3176
|
+
isEdited: isEdited$1
|
|
3177
|
+
});
|
|
3178
|
+
}
|
|
3179
|
+
|
|
3180
|
+
return entries;
|
|
3181
|
+
}
|
|
3182
|
+
|
|
3183
|
+
function Key$1(props) {
|
|
3184
|
+
const {
|
|
3185
|
+
editField,
|
|
3186
|
+
field,
|
|
3187
|
+
id
|
|
3188
|
+
} = props;
|
|
1745
3189
|
const formFieldRegistry = useService('formFieldRegistry');
|
|
3190
|
+
const debounce = useService('debounce');
|
|
3191
|
+
const path = ['key'];
|
|
3192
|
+
|
|
3193
|
+
const getValue = () => {
|
|
3194
|
+
return get(field, path, '');
|
|
3195
|
+
};
|
|
3196
|
+
|
|
3197
|
+
const setValue = value => {
|
|
3198
|
+
return editField(field, path, value);
|
|
3199
|
+
};
|
|
1746
3200
|
|
|
1747
3201
|
const validate = value => {
|
|
1748
3202
|
if (isUndefined(value) || !value.length) {
|
|
@@ -1753,134 +3207,306 @@ function KeyEntry(props) {
|
|
|
1753
3207
|
return 'Must not contain spaces.';
|
|
1754
3208
|
}
|
|
1755
3209
|
|
|
1756
|
-
const assigned = formFieldRegistry._keys.assigned(value);
|
|
3210
|
+
const assigned = formFieldRegistry._keys.assigned(value);
|
|
3211
|
+
|
|
3212
|
+
if (assigned && assigned !== field) {
|
|
3213
|
+
return 'Must be unique.';
|
|
3214
|
+
}
|
|
3215
|
+
|
|
3216
|
+
return null;
|
|
3217
|
+
};
|
|
3218
|
+
|
|
3219
|
+
return TextfieldEntry({
|
|
3220
|
+
debounce,
|
|
3221
|
+
description: 'Binds to a form variable',
|
|
3222
|
+
element: field,
|
|
3223
|
+
getValue,
|
|
3224
|
+
id,
|
|
3225
|
+
label: 'Key',
|
|
3226
|
+
setValue,
|
|
3227
|
+
validate
|
|
3228
|
+
});
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3231
|
+
function LabelEntry(props) {
|
|
3232
|
+
const {
|
|
3233
|
+
editField,
|
|
3234
|
+
field
|
|
3235
|
+
} = props;
|
|
3236
|
+
const {
|
|
3237
|
+
type
|
|
3238
|
+
} = field;
|
|
3239
|
+
const entries = [];
|
|
3240
|
+
|
|
3241
|
+
if (INPUTS.includes(type) || type === 'button') {
|
|
3242
|
+
entries.push({
|
|
3243
|
+
id: 'label',
|
|
3244
|
+
component: Label$1,
|
|
3245
|
+
editField: editField,
|
|
3246
|
+
field: field,
|
|
3247
|
+
isEdited: isEdited$1
|
|
3248
|
+
});
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
return entries;
|
|
3252
|
+
}
|
|
3253
|
+
|
|
3254
|
+
function Label$1(props) {
|
|
3255
|
+
const {
|
|
3256
|
+
editField,
|
|
3257
|
+
field,
|
|
3258
|
+
id
|
|
3259
|
+
} = props;
|
|
3260
|
+
const debounce = useService('debounce');
|
|
3261
|
+
const path = ['label'];
|
|
3262
|
+
|
|
3263
|
+
const getValue = () => {
|
|
3264
|
+
return get(field, path, '');
|
|
3265
|
+
};
|
|
3266
|
+
|
|
3267
|
+
const setValue = value => {
|
|
3268
|
+
return editField(field, path, value);
|
|
3269
|
+
};
|
|
3270
|
+
|
|
3271
|
+
return TextfieldEntry({
|
|
3272
|
+
debounce,
|
|
3273
|
+
element: field,
|
|
3274
|
+
getValue,
|
|
3275
|
+
id,
|
|
3276
|
+
label: 'Field label',
|
|
3277
|
+
setValue
|
|
3278
|
+
});
|
|
3279
|
+
}
|
|
3280
|
+
|
|
3281
|
+
function TextEntry(props) {
|
|
3282
|
+
const {
|
|
3283
|
+
editField,
|
|
3284
|
+
field
|
|
3285
|
+
} = props;
|
|
3286
|
+
const {
|
|
3287
|
+
type
|
|
3288
|
+
} = field;
|
|
3289
|
+
const entries = [];
|
|
3290
|
+
|
|
3291
|
+
if (type === 'text') {
|
|
3292
|
+
entries.push({
|
|
3293
|
+
id: 'text',
|
|
3294
|
+
component: Text,
|
|
3295
|
+
editField: editField,
|
|
3296
|
+
field: field,
|
|
3297
|
+
isEdited: isEdited$2
|
|
3298
|
+
});
|
|
3299
|
+
}
|
|
3300
|
+
|
|
3301
|
+
return entries;
|
|
3302
|
+
}
|
|
3303
|
+
|
|
3304
|
+
function Text(props) {
|
|
3305
|
+
const {
|
|
3306
|
+
editField,
|
|
3307
|
+
field,
|
|
3308
|
+
id
|
|
3309
|
+
} = props;
|
|
3310
|
+
const debounce = useService('debounce');
|
|
3311
|
+
const path = ['text'];
|
|
3312
|
+
|
|
3313
|
+
const getValue = () => {
|
|
3314
|
+
return get(field, path, '');
|
|
3315
|
+
};
|
|
3316
|
+
|
|
3317
|
+
const setValue = value => {
|
|
3318
|
+
return editField(field, path, value);
|
|
3319
|
+
};
|
|
3320
|
+
|
|
3321
|
+
return TextAreaEntry({
|
|
3322
|
+
debounce,
|
|
3323
|
+
description: 'Use Markdown or basic HTML to format.',
|
|
3324
|
+
element: field,
|
|
3325
|
+
getValue,
|
|
3326
|
+
id,
|
|
3327
|
+
label: 'Text',
|
|
3328
|
+
rows: 10,
|
|
3329
|
+
setValue
|
|
3330
|
+
});
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3333
|
+
function ValueEntry(props) {
|
|
3334
|
+
const {
|
|
3335
|
+
editField,
|
|
3336
|
+
field,
|
|
3337
|
+
idPrefix,
|
|
3338
|
+
index,
|
|
3339
|
+
validateFactory
|
|
3340
|
+
} = props;
|
|
3341
|
+
const entries = [{
|
|
3342
|
+
component: Label,
|
|
3343
|
+
editField,
|
|
3344
|
+
field,
|
|
3345
|
+
id: idPrefix + '-label',
|
|
3346
|
+
idPrefix,
|
|
3347
|
+
index,
|
|
3348
|
+
validateFactory
|
|
3349
|
+
}, {
|
|
3350
|
+
component: Value$1,
|
|
3351
|
+
editField,
|
|
3352
|
+
field,
|
|
3353
|
+
id: idPrefix + '-value',
|
|
3354
|
+
idPrefix,
|
|
3355
|
+
index,
|
|
3356
|
+
validateFactory
|
|
3357
|
+
}];
|
|
3358
|
+
return entries;
|
|
3359
|
+
}
|
|
3360
|
+
|
|
3361
|
+
function Label(props) {
|
|
3362
|
+
const {
|
|
3363
|
+
editField,
|
|
3364
|
+
field,
|
|
3365
|
+
id,
|
|
3366
|
+
index,
|
|
3367
|
+
validateFactory
|
|
3368
|
+
} = props;
|
|
3369
|
+
const debounce = useService('debounce');
|
|
1757
3370
|
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
3371
|
+
const setValue = value => {
|
|
3372
|
+
const values = get(field, ['values']);
|
|
3373
|
+
return editField(field, 'values', set(values, [index, 'label'], value));
|
|
3374
|
+
};
|
|
1761
3375
|
|
|
1762
|
-
|
|
3376
|
+
const getValue = () => {
|
|
3377
|
+
return get(field, ['values', index, 'label']);
|
|
1763
3378
|
};
|
|
1764
3379
|
|
|
1765
|
-
return
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
validate:
|
|
3380
|
+
return TextfieldEntry({
|
|
3381
|
+
debounce,
|
|
3382
|
+
element: field,
|
|
3383
|
+
getValue,
|
|
3384
|
+
id,
|
|
3385
|
+
label: 'Label',
|
|
3386
|
+
setValue,
|
|
3387
|
+
validate: validateFactory(getValue())
|
|
1773
3388
|
});
|
|
1774
3389
|
}
|
|
1775
3390
|
|
|
1776
|
-
function
|
|
3391
|
+
function Value$1(props) {
|
|
1777
3392
|
const {
|
|
1778
3393
|
editField,
|
|
1779
|
-
field
|
|
3394
|
+
field,
|
|
3395
|
+
id,
|
|
3396
|
+
index,
|
|
3397
|
+
validateFactory
|
|
1780
3398
|
} = props;
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
3399
|
+
const debounce = useService('debounce');
|
|
3400
|
+
|
|
3401
|
+
const setValue = value => {
|
|
3402
|
+
const values = get(field, ['values']);
|
|
3403
|
+
return editField(field, 'values', set(values, [index, 'value'], value));
|
|
3404
|
+
};
|
|
3405
|
+
|
|
3406
|
+
const getValue = () => {
|
|
3407
|
+
return get(field, ['values', index, 'value']);
|
|
3408
|
+
};
|
|
3409
|
+
|
|
3410
|
+
return TextfieldEntry({
|
|
3411
|
+
debounce,
|
|
3412
|
+
element: field,
|
|
3413
|
+
getValue,
|
|
3414
|
+
id,
|
|
3415
|
+
label: 'Value',
|
|
3416
|
+
setValue,
|
|
3417
|
+
validate: validateFactory(getValue())
|
|
1787
3418
|
});
|
|
1788
3419
|
}
|
|
1789
3420
|
|
|
1790
|
-
function
|
|
3421
|
+
function CustomValueEntry(props) {
|
|
1791
3422
|
const {
|
|
1792
3423
|
editField,
|
|
1793
|
-
field
|
|
3424
|
+
field,
|
|
3425
|
+
idPrefix,
|
|
3426
|
+
index,
|
|
3427
|
+
validateFactory
|
|
1794
3428
|
} = props;
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
3429
|
+
const entries = [{
|
|
3430
|
+
component: Key,
|
|
3431
|
+
editField,
|
|
3432
|
+
field,
|
|
3433
|
+
id: idPrefix + '-key',
|
|
3434
|
+
idPrefix,
|
|
3435
|
+
index,
|
|
3436
|
+
validateFactory
|
|
3437
|
+
}, {
|
|
3438
|
+
component: Value,
|
|
3439
|
+
editField,
|
|
3440
|
+
field,
|
|
3441
|
+
id: idPrefix + '-value',
|
|
3442
|
+
idPrefix,
|
|
3443
|
+
index,
|
|
3444
|
+
validateFactory
|
|
3445
|
+
}];
|
|
3446
|
+
return entries;
|
|
1803
3447
|
}
|
|
1804
3448
|
|
|
1805
|
-
function
|
|
3449
|
+
function Key(props) {
|
|
1806
3450
|
const {
|
|
1807
3451
|
editField,
|
|
1808
3452
|
field,
|
|
3453
|
+
id,
|
|
1809
3454
|
index,
|
|
1810
|
-
|
|
3455
|
+
validateFactory
|
|
1811
3456
|
} = props;
|
|
3457
|
+
const debounce = useService('debounce');
|
|
1812
3458
|
|
|
1813
|
-
const
|
|
1814
|
-
|
|
3459
|
+
const setValue = value => {
|
|
3460
|
+
const properties = get(field, ['properties']);
|
|
3461
|
+
const key = Object.keys(properties)[index];
|
|
3462
|
+
return editField(field, 'properties', updateKey(properties, key, value));
|
|
1815
3463
|
};
|
|
1816
3464
|
|
|
1817
3465
|
const getValue = () => {
|
|
1818
|
-
return get(field, ['
|
|
1819
|
-
};
|
|
1820
|
-
|
|
1821
|
-
const onChange = key => {
|
|
1822
|
-
const values = get(field, ['values']);
|
|
1823
|
-
return value => {
|
|
1824
|
-
editField(field, 'values', set(values, [index, key], value));
|
|
1825
|
-
};
|
|
3466
|
+
return Object.keys(get(field, ['properties']))[index];
|
|
1826
3467
|
};
|
|
1827
3468
|
|
|
1828
|
-
return
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
label: "Value",
|
|
1837
|
-
onChange: onChange('value'),
|
|
1838
|
-
value: getValue(),
|
|
1839
|
-
validate: validate(getValue())
|
|
1840
|
-
})]
|
|
3469
|
+
return TextfieldEntry({
|
|
3470
|
+
debounce,
|
|
3471
|
+
element: field,
|
|
3472
|
+
getValue,
|
|
3473
|
+
id,
|
|
3474
|
+
label: 'Key',
|
|
3475
|
+
setValue,
|
|
3476
|
+
validate: validateFactory(getValue())
|
|
1841
3477
|
});
|
|
1842
3478
|
}
|
|
1843
3479
|
|
|
1844
|
-
function
|
|
3480
|
+
function Value(props) {
|
|
1845
3481
|
const {
|
|
1846
3482
|
editField,
|
|
1847
3483
|
field,
|
|
3484
|
+
id,
|
|
1848
3485
|
index,
|
|
1849
|
-
|
|
3486
|
+
validateFactory
|
|
1850
3487
|
} = props;
|
|
3488
|
+
const debounce = useService('debounce');
|
|
1851
3489
|
|
|
1852
|
-
const
|
|
1853
|
-
|
|
3490
|
+
const setValue = value => {
|
|
3491
|
+
const properties = get(field, ['properties']);
|
|
3492
|
+
const key = Object.keys(properties)[index];
|
|
3493
|
+
editField(field, 'properties', updateValue(properties, key, value));
|
|
1854
3494
|
};
|
|
1855
3495
|
|
|
1856
3496
|
const getValue = () => {
|
|
1857
|
-
return get(field, ['properties', getKey()]);
|
|
1858
|
-
};
|
|
1859
|
-
|
|
1860
|
-
const onChange = key => {
|
|
1861
3497
|
const properties = get(field, ['properties']);
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
editField(field, 'properties', updateValue(properties, getKey(), value));
|
|
1865
|
-
} else if (key === 'key') {
|
|
1866
|
-
editField(field, 'properties', updateKey(properties, getKey(), value));
|
|
1867
|
-
}
|
|
1868
|
-
};
|
|
3498
|
+
const key = Object.keys(properties)[index];
|
|
3499
|
+
return get(field, ['properties', key]);
|
|
1869
3500
|
};
|
|
1870
3501
|
|
|
1871
|
-
return
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
id: `value-value-${index}`,
|
|
1880
|
-
label: "Value",
|
|
1881
|
-
onChange: onChange('value'),
|
|
1882
|
-
value: getValue()
|
|
1883
|
-
})]
|
|
3502
|
+
return TextfieldEntry({
|
|
3503
|
+
debounce,
|
|
3504
|
+
element: field,
|
|
3505
|
+
getValue,
|
|
3506
|
+
id,
|
|
3507
|
+
label: 'Value',
|
|
3508
|
+
setValue,
|
|
3509
|
+
validate: validateFactory(getValue())
|
|
1884
3510
|
});
|
|
1885
3511
|
} // helpers //////////
|
|
1886
3512
|
|
|
@@ -1894,6 +3520,7 @@ function CustomValueEntry(props) {
|
|
|
1894
3520
|
* @returns {Object}
|
|
1895
3521
|
*/
|
|
1896
3522
|
|
|
3523
|
+
|
|
1897
3524
|
function updateValue(properties, key, value) {
|
|
1898
3525
|
return { ...properties,
|
|
1899
3526
|
[key]: value
|
|
@@ -1919,79 +3546,225 @@ function updateKey(properties, oldKey, newKey) {
|
|
|
1919
3546
|
}, {});
|
|
1920
3547
|
}
|
|
1921
3548
|
|
|
1922
|
-
|
|
3549
|
+
const VALUES_SOURCES = {
|
|
3550
|
+
STATIC: 'static',
|
|
3551
|
+
INPUT: 'input'
|
|
3552
|
+
};
|
|
3553
|
+
const VALUES_SOURCE_DEFAULT = VALUES_SOURCES.STATIC;
|
|
3554
|
+
const VALUES_SOURCES_LABELS = {
|
|
3555
|
+
[VALUES_SOURCES.STATIC]: 'Static',
|
|
3556
|
+
[VALUES_SOURCES.INPUT]: 'Input data'
|
|
3557
|
+
};
|
|
3558
|
+
const VALUES_SOURCES_PATHS = {
|
|
3559
|
+
[VALUES_SOURCES.STATIC]: ['values'],
|
|
3560
|
+
[VALUES_SOURCES.INPUT]: ['valuesKey']
|
|
3561
|
+
};
|
|
3562
|
+
const VALUES_SOURCES_DEFAULTS = {
|
|
3563
|
+
[VALUES_SOURCES.STATIC]: [],
|
|
3564
|
+
[VALUES_SOURCES.INPUT]: ''
|
|
3565
|
+
}; // helpers ///////////////////
|
|
3566
|
+
|
|
3567
|
+
function getValuesSource(field) {
|
|
3568
|
+
for (const source of Object.values(VALUES_SOURCES)) {
|
|
3569
|
+
if (get(field, VALUES_SOURCES_PATHS[source]) !== undefined) {
|
|
3570
|
+
return source;
|
|
3571
|
+
}
|
|
3572
|
+
}
|
|
3573
|
+
|
|
3574
|
+
return VALUES_SOURCE_DEFAULT;
|
|
3575
|
+
}
|
|
3576
|
+
|
|
3577
|
+
function ValuesSourceSelectEntry(props) {
|
|
1923
3578
|
const {
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
3579
|
+
editField,
|
|
3580
|
+
field,
|
|
3581
|
+
id
|
|
3582
|
+
} = props;
|
|
3583
|
+
return [{
|
|
3584
|
+
id: id + '-select',
|
|
3585
|
+
component: ValuesSourceSelect,
|
|
3586
|
+
isEdited: isEdited$4,
|
|
3587
|
+
editField,
|
|
3588
|
+
field
|
|
3589
|
+
}];
|
|
3590
|
+
}
|
|
1927
3591
|
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
}
|
|
3592
|
+
function ValuesSourceSelect(props) {
|
|
3593
|
+
const {
|
|
3594
|
+
editField,
|
|
3595
|
+
field,
|
|
3596
|
+
id
|
|
3597
|
+
} = props;
|
|
3598
|
+
const getValue = getValuesSource;
|
|
3599
|
+
|
|
3600
|
+
const setValue = value => {
|
|
3601
|
+
let newField = field;
|
|
3602
|
+
Object.values(VALUES_SOURCES).forEach(source => {
|
|
3603
|
+
// Clear all values source definitions and default the newly selected one
|
|
3604
|
+
const newValue = value === source ? VALUES_SOURCES_DEFAULTS[source] : undefined;
|
|
3605
|
+
newField = editField(field, VALUES_SOURCES_PATHS[source], newValue);
|
|
3606
|
+
});
|
|
3607
|
+
return newField;
|
|
3608
|
+
};
|
|
1934
3609
|
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
3610
|
+
const getValuesSourceOptions = () => {
|
|
3611
|
+
return Object.values(VALUES_SOURCES).map(valueSource => ({
|
|
3612
|
+
label: VALUES_SOURCES_LABELS[valueSource],
|
|
3613
|
+
value: valueSource
|
|
1939
3614
|
}));
|
|
1940
|
-
}
|
|
3615
|
+
};
|
|
1941
3616
|
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
3617
|
+
return SelectEntry({
|
|
3618
|
+
label: 'Type',
|
|
3619
|
+
element: field,
|
|
3620
|
+
getOptions: getValuesSourceOptions,
|
|
3621
|
+
getValue,
|
|
3622
|
+
id,
|
|
3623
|
+
setValue
|
|
3624
|
+
});
|
|
3625
|
+
}
|
|
1948
3626
|
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
}
|
|
3627
|
+
function InputKeyValuesSourceEntry(props) {
|
|
3628
|
+
const {
|
|
3629
|
+
editField,
|
|
3630
|
+
field,
|
|
3631
|
+
id
|
|
3632
|
+
} = props;
|
|
3633
|
+
return [{
|
|
3634
|
+
id: id + '-key',
|
|
3635
|
+
component: InputValuesKey,
|
|
3636
|
+
label: 'Input values key',
|
|
3637
|
+
description: 'Define which input property to populate the values from',
|
|
3638
|
+
isEdited: isEdited$1,
|
|
3639
|
+
editField,
|
|
3640
|
+
field
|
|
3641
|
+
}];
|
|
3642
|
+
}
|
|
1955
3643
|
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
3644
|
+
function InputValuesKey(props) {
|
|
3645
|
+
const {
|
|
3646
|
+
editField,
|
|
3647
|
+
field,
|
|
3648
|
+
id,
|
|
3649
|
+
label,
|
|
3650
|
+
description
|
|
3651
|
+
} = props;
|
|
3652
|
+
const debounce = useService('debounce');
|
|
3653
|
+
const path = VALUES_SOURCES_PATHS[VALUES_SOURCES.INPUT];
|
|
1962
3654
|
|
|
1963
|
-
|
|
1964
|
-
entries.push(jsx(ActionEntry, {
|
|
1965
|
-
editField: editField,
|
|
1966
|
-
field: field
|
|
1967
|
-
}));
|
|
1968
|
-
}
|
|
3655
|
+
const getValue = () => get(field, path, '');
|
|
1969
3656
|
|
|
1970
|
-
|
|
1971
|
-
entries.push(jsx(ColumnsEntry, {
|
|
1972
|
-
editField: editField,
|
|
1973
|
-
field: field
|
|
1974
|
-
}));
|
|
1975
|
-
}
|
|
3657
|
+
const setValue = value => editField(field, path, value || '');
|
|
1976
3658
|
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
3659
|
+
return TextfieldEntry({
|
|
3660
|
+
debounce,
|
|
3661
|
+
description,
|
|
3662
|
+
element: field,
|
|
3663
|
+
getValue,
|
|
3664
|
+
id,
|
|
3665
|
+
label,
|
|
3666
|
+
setValue
|
|
3667
|
+
});
|
|
3668
|
+
}
|
|
1983
3669
|
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
}
|
|
3670
|
+
function StaticValuesSourceEntry(props) {
|
|
3671
|
+
const {
|
|
3672
|
+
editField,
|
|
3673
|
+
field,
|
|
3674
|
+
id: idPrefix
|
|
3675
|
+
} = props;
|
|
3676
|
+
const {
|
|
3677
|
+
values
|
|
3678
|
+
} = field;
|
|
3679
|
+
|
|
3680
|
+
const addEntry = e => {
|
|
3681
|
+
e.stopPropagation();
|
|
3682
|
+
const index = values.length + 1;
|
|
3683
|
+
const entry = {
|
|
3684
|
+
label: `Value ${index}`,
|
|
3685
|
+
value: `value${index}`
|
|
3686
|
+
};
|
|
3687
|
+
editField(field, VALUES_SOURCES_PATHS[VALUES_SOURCES.STATIC], arrayAdd$1(values, values.length, entry));
|
|
3688
|
+
};
|
|
3689
|
+
|
|
3690
|
+
const removeEntry = entry => {
|
|
3691
|
+
editField(field, VALUES_SOURCES_PATHS[VALUES_SOURCES.STATIC], without(values, entry));
|
|
3692
|
+
};
|
|
3693
|
+
|
|
3694
|
+
const validateFactory = key => {
|
|
3695
|
+
return value => {
|
|
3696
|
+
if (value === key) {
|
|
3697
|
+
return;
|
|
3698
|
+
}
|
|
1990
3699
|
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
3700
|
+
if (isUndefined(value) || !value.length) {
|
|
3701
|
+
return 'Must not be empty.';
|
|
3702
|
+
}
|
|
3703
|
+
|
|
3704
|
+
const isValueAssigned = values.find(entry => entry.value === value);
|
|
3705
|
+
|
|
3706
|
+
if (isValueAssigned) {
|
|
3707
|
+
return 'Must be unique.';
|
|
3708
|
+
}
|
|
3709
|
+
};
|
|
3710
|
+
};
|
|
3711
|
+
|
|
3712
|
+
const items = values.map((entry, index) => {
|
|
3713
|
+
const id = idPrefix + '-' + index;
|
|
3714
|
+
return {
|
|
3715
|
+
id,
|
|
3716
|
+
label: entry.label,
|
|
3717
|
+
entries: ValueEntry({
|
|
3718
|
+
editField,
|
|
3719
|
+
field,
|
|
3720
|
+
idPrefix: id,
|
|
3721
|
+
index,
|
|
3722
|
+
validateFactory
|
|
3723
|
+
}),
|
|
3724
|
+
autoFocusEntry: id + '-label',
|
|
3725
|
+
remove: () => removeEntry(entry)
|
|
3726
|
+
};
|
|
1994
3727
|
});
|
|
3728
|
+
return {
|
|
3729
|
+
items,
|
|
3730
|
+
add: addEntry
|
|
3731
|
+
};
|
|
3732
|
+
}
|
|
3733
|
+
|
|
3734
|
+
function GeneralGroup(field, editField) {
|
|
3735
|
+
const entries = [...IdEntry({
|
|
3736
|
+
field,
|
|
3737
|
+
editField
|
|
3738
|
+
}), ...LabelEntry({
|
|
3739
|
+
field,
|
|
3740
|
+
editField
|
|
3741
|
+
}), ...DescriptionEntry({
|
|
3742
|
+
field,
|
|
3743
|
+
editField
|
|
3744
|
+
}), ...KeyEntry({
|
|
3745
|
+
field,
|
|
3746
|
+
editField
|
|
3747
|
+
}), ...DefaultOptionEntry({
|
|
3748
|
+
field,
|
|
3749
|
+
editField
|
|
3750
|
+
}), ...ActionEntry({
|
|
3751
|
+
field,
|
|
3752
|
+
editField
|
|
3753
|
+
}), ...ColumnsEntry({
|
|
3754
|
+
field,
|
|
3755
|
+
editField
|
|
3756
|
+
}), ...TextEntry({
|
|
3757
|
+
field,
|
|
3758
|
+
editField
|
|
3759
|
+
}), ...DisabledEntry({
|
|
3760
|
+
field,
|
|
3761
|
+
editField
|
|
3762
|
+
})];
|
|
3763
|
+
return {
|
|
3764
|
+
id: 'general',
|
|
3765
|
+
label: 'General',
|
|
3766
|
+
entries
|
|
3767
|
+
};
|
|
1995
3768
|
}
|
|
1996
3769
|
|
|
1997
3770
|
function ValidationGroup(field, editField) {
|
|
@@ -1999,6 +3772,10 @@ function ValidationGroup(field, editField) {
|
|
|
1999
3772
|
type
|
|
2000
3773
|
} = field;
|
|
2001
3774
|
|
|
3775
|
+
if (!(INPUTS.includes(type) && type !== 'checkbox' && type !== 'checklist' && type !== 'taglist')) {
|
|
3776
|
+
return null;
|
|
3777
|
+
}
|
|
3778
|
+
|
|
2002
3779
|
const onChange = key => {
|
|
2003
3780
|
return value => {
|
|
2004
3781
|
const validate = get(field, ['validate'], {});
|
|
@@ -2006,122 +3783,247 @@ function ValidationGroup(field, editField) {
|
|
|
2006
3783
|
};
|
|
2007
3784
|
};
|
|
2008
3785
|
|
|
2009
|
-
const
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
3786
|
+
const getValue = key => {
|
|
3787
|
+
return () => {
|
|
3788
|
+
return get(field, ['validate', key]);
|
|
3789
|
+
};
|
|
3790
|
+
};
|
|
3791
|
+
|
|
3792
|
+
let entries = [{
|
|
3793
|
+
id: 'required',
|
|
3794
|
+
component: Required,
|
|
3795
|
+
getValue,
|
|
3796
|
+
field,
|
|
3797
|
+
isEdited: isEdited$6,
|
|
3798
|
+
onChange
|
|
3799
|
+
}];
|
|
2015
3800
|
|
|
2016
3801
|
if (type === 'textfield') {
|
|
2017
|
-
entries.push(
|
|
2018
|
-
id:
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
3802
|
+
entries.push({
|
|
3803
|
+
id: 'minLength',
|
|
3804
|
+
component: MinLength,
|
|
3805
|
+
getValue,
|
|
3806
|
+
field,
|
|
3807
|
+
isEdited: isEdited$5,
|
|
3808
|
+
onChange
|
|
3809
|
+
}, {
|
|
3810
|
+
id: 'maxLength',
|
|
3811
|
+
component: MaxLength,
|
|
3812
|
+
getValue,
|
|
3813
|
+
field,
|
|
3814
|
+
isEdited: isEdited$5,
|
|
3815
|
+
onChange
|
|
3816
|
+
}, {
|
|
3817
|
+
id: 'pattern',
|
|
3818
|
+
component: Pattern,
|
|
3819
|
+
getValue,
|
|
3820
|
+
field,
|
|
3821
|
+
isEdited: isEdited$1,
|
|
3822
|
+
onChange
|
|
3823
|
+
});
|
|
2035
3824
|
}
|
|
2036
3825
|
|
|
2037
3826
|
if (type === 'number') {
|
|
2038
|
-
entries.push(
|
|
2039
|
-
id:
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
3827
|
+
entries.push({
|
|
3828
|
+
id: 'min',
|
|
3829
|
+
component: Min,
|
|
3830
|
+
getValue,
|
|
3831
|
+
field,
|
|
3832
|
+
isEdited: isEdited$5,
|
|
3833
|
+
onChange
|
|
3834
|
+
}, {
|
|
3835
|
+
id: 'max',
|
|
3836
|
+
component: Max,
|
|
3837
|
+
getValue,
|
|
3838
|
+
field,
|
|
3839
|
+
isEdited: isEdited$5,
|
|
3840
|
+
onChange
|
|
3841
|
+
});
|
|
2049
3842
|
}
|
|
2050
3843
|
|
|
2051
|
-
return
|
|
2052
|
-
|
|
2053
|
-
|
|
3844
|
+
return {
|
|
3845
|
+
id: 'validation',
|
|
3846
|
+
label: 'Validation',
|
|
3847
|
+
entries
|
|
3848
|
+
};
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3851
|
+
function Required(props) {
|
|
3852
|
+
const {
|
|
3853
|
+
field,
|
|
3854
|
+
getValue,
|
|
3855
|
+
id,
|
|
3856
|
+
onChange
|
|
3857
|
+
} = props;
|
|
3858
|
+
return CheckboxEntry({
|
|
3859
|
+
element: field,
|
|
3860
|
+
getValue: getValue('required'),
|
|
3861
|
+
id,
|
|
3862
|
+
label: 'Required',
|
|
3863
|
+
setValue: onChange('required')
|
|
3864
|
+
});
|
|
3865
|
+
}
|
|
3866
|
+
|
|
3867
|
+
function MinLength(props) {
|
|
3868
|
+
const {
|
|
3869
|
+
field,
|
|
3870
|
+
getValue,
|
|
3871
|
+
id,
|
|
3872
|
+
onChange
|
|
3873
|
+
} = props;
|
|
3874
|
+
const debounce = useService('debounce');
|
|
3875
|
+
return NumberFieldEntry({
|
|
3876
|
+
debounce,
|
|
3877
|
+
element: field,
|
|
3878
|
+
getValue: getValue('minLength'),
|
|
3879
|
+
id,
|
|
3880
|
+
label: 'Minimum length',
|
|
3881
|
+
min: 0,
|
|
3882
|
+
setValue: onChange('minLength')
|
|
3883
|
+
});
|
|
3884
|
+
}
|
|
3885
|
+
|
|
3886
|
+
function MaxLength(props) {
|
|
3887
|
+
const {
|
|
3888
|
+
field,
|
|
3889
|
+
getValue,
|
|
3890
|
+
id,
|
|
3891
|
+
onChange
|
|
3892
|
+
} = props;
|
|
3893
|
+
const debounce = useService('debounce');
|
|
3894
|
+
return NumberFieldEntry({
|
|
3895
|
+
debounce,
|
|
3896
|
+
element: field,
|
|
3897
|
+
getValue: getValue('maxLength'),
|
|
3898
|
+
id,
|
|
3899
|
+
label: 'Maximum length',
|
|
3900
|
+
min: 0,
|
|
3901
|
+
setValue: onChange('maxLength')
|
|
2054
3902
|
});
|
|
2055
3903
|
}
|
|
2056
3904
|
|
|
2057
|
-
function
|
|
3905
|
+
function Pattern(props) {
|
|
2058
3906
|
const {
|
|
3907
|
+
field,
|
|
3908
|
+
getValue,
|
|
2059
3909
|
id,
|
|
2060
|
-
|
|
2061
|
-
} =
|
|
3910
|
+
onChange
|
|
3911
|
+
} = props;
|
|
3912
|
+
const debounce = useService('debounce');
|
|
3913
|
+
return TextfieldEntry({
|
|
3914
|
+
debounce,
|
|
3915
|
+
element: field,
|
|
3916
|
+
getValue: getValue('pattern'),
|
|
3917
|
+
id,
|
|
3918
|
+
label: 'Regular expression pattern',
|
|
3919
|
+
setValue: onChange('pattern')
|
|
3920
|
+
});
|
|
3921
|
+
}
|
|
2062
3922
|
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
3923
|
+
function Min(props) {
|
|
3924
|
+
const {
|
|
3925
|
+
field,
|
|
3926
|
+
getValue,
|
|
3927
|
+
id,
|
|
3928
|
+
onChange
|
|
3929
|
+
} = props;
|
|
3930
|
+
const debounce = useService('debounce');
|
|
3931
|
+
return NumberFieldEntry({
|
|
3932
|
+
debounce,
|
|
3933
|
+
element: field,
|
|
3934
|
+
getValue: getValue('min'),
|
|
3935
|
+
id,
|
|
3936
|
+
label: 'Minimum',
|
|
3937
|
+
min: 0,
|
|
3938
|
+
setValue: onChange('min')
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
2071
3941
|
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
3942
|
+
function Max(props) {
|
|
3943
|
+
const {
|
|
3944
|
+
field,
|
|
3945
|
+
getValue,
|
|
3946
|
+
id,
|
|
3947
|
+
onChange
|
|
3948
|
+
} = props;
|
|
3949
|
+
const debounce = useService('debounce');
|
|
3950
|
+
return NumberFieldEntry({
|
|
3951
|
+
debounce,
|
|
3952
|
+
element: field,
|
|
3953
|
+
getValue: getValue('max'),
|
|
3954
|
+
id,
|
|
3955
|
+
label: 'Maximum',
|
|
3956
|
+
min: 0,
|
|
3957
|
+
setValue: onChange('max')
|
|
3958
|
+
});
|
|
3959
|
+
}
|
|
2077
3960
|
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
3961
|
+
function ValuesGroups(field, editField) {
|
|
3962
|
+
const {
|
|
3963
|
+
type,
|
|
3964
|
+
id: fieldId
|
|
3965
|
+
} = field;
|
|
2081
3966
|
|
|
2082
|
-
|
|
3967
|
+
if (!VALUES_INPUTS.includes(type)) {
|
|
3968
|
+
return [];
|
|
3969
|
+
}
|
|
2083
3970
|
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
};
|
|
3971
|
+
const context = {
|
|
3972
|
+
editField,
|
|
3973
|
+
field
|
|
2088
3974
|
};
|
|
3975
|
+
const valuesSourceId = `${fieldId}-valuesSource`;
|
|
3976
|
+
/**
|
|
3977
|
+
* @type {Array<Group|ListGroup>}
|
|
3978
|
+
*/
|
|
2089
3979
|
|
|
2090
|
-
const
|
|
2091
|
-
|
|
2092
|
-
label:
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
const {
|
|
2097
|
-
label
|
|
2098
|
-
} = value;
|
|
2099
|
-
|
|
2100
|
-
const removeEntry = () => {
|
|
2101
|
-
editField(field, ['values'], arrayRemove$1(values, index));
|
|
2102
|
-
};
|
|
2103
|
-
|
|
2104
|
-
return jsx(CollapsibleEntry, {
|
|
2105
|
-
label: label,
|
|
2106
|
-
removeEntry: removeEntry,
|
|
2107
|
-
children: jsx(ValueEntry, {
|
|
2108
|
-
editField: editField,
|
|
2109
|
-
field: field,
|
|
2110
|
-
index: index,
|
|
2111
|
-
validate: validateFactory
|
|
2112
|
-
})
|
|
2113
|
-
}, `${id}-${index}`);
|
|
3980
|
+
const groups = [{
|
|
3981
|
+
id: valuesSourceId,
|
|
3982
|
+
label: 'Options source',
|
|
3983
|
+
component: Group,
|
|
3984
|
+
entries: ValuesSourceSelectEntry({ ...context,
|
|
3985
|
+
id: valuesSourceId
|
|
2114
3986
|
})
|
|
2115
|
-
}
|
|
3987
|
+
}];
|
|
3988
|
+
const valuesSource = getValuesSource(field);
|
|
3989
|
+
|
|
3990
|
+
if (valuesSource === VALUES_SOURCES.INPUT) {
|
|
3991
|
+
const dynamicValuesId = `${fieldId}-dynamicValues`;
|
|
3992
|
+
groups.push({
|
|
3993
|
+
id: dynamicValuesId,
|
|
3994
|
+
label: 'Dynamic options',
|
|
3995
|
+
component: Group,
|
|
3996
|
+
entries: InputKeyValuesSourceEntry({ ...context,
|
|
3997
|
+
id: dynamicValuesId
|
|
3998
|
+
})
|
|
3999
|
+
});
|
|
4000
|
+
} else if (valuesSource === VALUES_SOURCES.STATIC) {
|
|
4001
|
+
const staticValuesId = `${fieldId}-staticValues`;
|
|
4002
|
+
groups.push({
|
|
4003
|
+
id: staticValuesId,
|
|
4004
|
+
label: 'Static options',
|
|
4005
|
+
component: ListGroup,
|
|
4006
|
+
...StaticValuesSourceEntry({ ...context,
|
|
4007
|
+
id: staticValuesId
|
|
4008
|
+
})
|
|
4009
|
+
});
|
|
4010
|
+
}
|
|
4011
|
+
|
|
4012
|
+
return groups;
|
|
2116
4013
|
}
|
|
2117
4014
|
|
|
2118
4015
|
function CustomValuesGroup(field, editField) {
|
|
2119
4016
|
const {
|
|
2120
|
-
|
|
2121
|
-
|
|
4017
|
+
properties = {},
|
|
4018
|
+
type
|
|
2122
4019
|
} = field;
|
|
2123
4020
|
|
|
2124
|
-
|
|
4021
|
+
if (type === 'default') {
|
|
4022
|
+
return null;
|
|
4023
|
+
}
|
|
4024
|
+
|
|
4025
|
+
const addEntry = event => {
|
|
4026
|
+
event.stopPropagation();
|
|
2125
4027
|
const index = Object.keys(properties).length + 1;
|
|
2126
4028
|
const key = `key${index}`,
|
|
2127
4029
|
value = 'value';
|
|
@@ -2146,28 +4048,35 @@ function CustomValuesGroup(field, editField) {
|
|
|
2146
4048
|
};
|
|
2147
4049
|
};
|
|
2148
4050
|
|
|
2149
|
-
const
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
children: Object.keys(properties).map((key, index) => {
|
|
2155
|
-
const removeEntry = () => {
|
|
2156
|
-
editField(field, ['properties'], removeKey(properties, key));
|
|
2157
|
-
};
|
|
4051
|
+
const items = Object.keys(properties).map((key, index) => {
|
|
4052
|
+
const removeEntry = event => {
|
|
4053
|
+
event.stopPropagation();
|
|
4054
|
+
return editField(field, ['properties'], removeKey(properties, key));
|
|
4055
|
+
};
|
|
2158
4056
|
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
},
|
|
2169
|
-
|
|
4057
|
+
const id = `${field.id}-property-${index}`;
|
|
4058
|
+
return {
|
|
4059
|
+
autoFocusEntry: id + '-key',
|
|
4060
|
+
entries: CustomValueEntry({
|
|
4061
|
+
editField,
|
|
4062
|
+
field,
|
|
4063
|
+
idPrefix: id,
|
|
4064
|
+
index,
|
|
4065
|
+
validateFactory
|
|
4066
|
+
}),
|
|
4067
|
+
id,
|
|
4068
|
+
label: key || '',
|
|
4069
|
+
remove: removeEntry
|
|
4070
|
+
};
|
|
2170
4071
|
});
|
|
4072
|
+
return {
|
|
4073
|
+
add: addEntry,
|
|
4074
|
+
component: ListGroup,
|
|
4075
|
+
id: 'custom-values',
|
|
4076
|
+
items,
|
|
4077
|
+
label: 'Custom properties',
|
|
4078
|
+
shouldSort: false
|
|
4079
|
+
};
|
|
2171
4080
|
} // helpers //////////
|
|
2172
4081
|
|
|
2173
4082
|
/**
|
|
@@ -2193,95 +4102,54 @@ function removeKey(properties, oldKey) {
|
|
|
2193
4102
|
}, {});
|
|
2194
4103
|
}
|
|
2195
4104
|
|
|
2196
|
-
const labelsByType = {
|
|
2197
|
-
button: 'BUTTON',
|
|
2198
|
-
checkbox: 'CHECKBOX',
|
|
2199
|
-
columns: 'COLUMNS',
|
|
2200
|
-
default: 'FORM',
|
|
2201
|
-
number: 'NUMBER',
|
|
2202
|
-
radio: 'RADIO',
|
|
2203
|
-
select: 'SELECT',
|
|
2204
|
-
text: 'TEXT',
|
|
2205
|
-
textfield: 'TEXT FIELD'
|
|
2206
|
-
};
|
|
2207
|
-
|
|
2208
4105
|
function getGroups(field, editField) {
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
} = field;
|
|
2212
|
-
const groups = [GeneralGroup(field, editField)];
|
|
2213
|
-
|
|
2214
|
-
if (type === 'radio' || type === 'select') {
|
|
2215
|
-
groups.push(ValuesGroup(field, editField));
|
|
2216
|
-
}
|
|
2217
|
-
|
|
2218
|
-
if (INPUTS.includes(type) && type !== 'checkbox') {
|
|
2219
|
-
groups.push(ValidationGroup(field, editField));
|
|
4106
|
+
if (!field) {
|
|
4107
|
+
return [];
|
|
2220
4108
|
}
|
|
2221
4109
|
|
|
2222
|
-
|
|
2223
|
-
groups.push(CustomValuesGroup(field, editField));
|
|
2224
|
-
}
|
|
4110
|
+
const groups = [GeneralGroup(field, editField), ...ValuesGroups(field, editField), ValidationGroup(field, editField), CustomValuesGroup(field, editField)]; // contract: if a group returns null, it should not be displayed at all
|
|
2225
4111
|
|
|
2226
|
-
return groups;
|
|
4112
|
+
return groups.filter(group => group !== null);
|
|
2227
4113
|
}
|
|
2228
4114
|
|
|
2229
|
-
function
|
|
4115
|
+
function FormPropertiesPanel(props) {
|
|
2230
4116
|
const {
|
|
2231
4117
|
editField,
|
|
2232
4118
|
field
|
|
2233
4119
|
} = props;
|
|
2234
4120
|
const eventBus = useService('eventBus');
|
|
2235
4121
|
|
|
2236
|
-
if (!field) {
|
|
2237
|
-
return jsx("div", {
|
|
2238
|
-
class: "fjs-properties-panel-placeholder",
|
|
2239
|
-
children: "Select a form field to edit its properties."
|
|
2240
|
-
});
|
|
2241
|
-
}
|
|
2242
|
-
|
|
2243
4122
|
const onFocus = () => eventBus.fire('propertiesPanel.focusin');
|
|
2244
4123
|
|
|
2245
4124
|
const onBlur = () => eventBus.fire('propertiesPanel.focusout');
|
|
2246
4125
|
|
|
2247
|
-
|
|
2248
|
-
type
|
|
2249
|
-
} = field;
|
|
2250
|
-
const Icon = iconsByType[type];
|
|
2251
|
-
const label = labelsByType[type];
|
|
2252
|
-
return jsxs("div", {
|
|
4126
|
+
return jsx("div", {
|
|
2253
4127
|
class: "fjs-properties-panel",
|
|
2254
|
-
"data-field": field.id,
|
|
4128
|
+
"data-field": field && field.id,
|
|
2255
4129
|
onFocusCapture: onFocus,
|
|
2256
4130
|
onBlurCapture: onBlur,
|
|
2257
|
-
children:
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
viewBox: "0 0 54 54"
|
|
2265
|
-
})
|
|
2266
|
-
}), jsxs("div", {
|
|
2267
|
-
children: [jsx("span", {
|
|
2268
|
-
class: "fjs-properties-panel-header-type",
|
|
2269
|
-
children: label
|
|
2270
|
-
}), type === 'text' ? jsx("div", {
|
|
2271
|
-
class: "fjs-properties-panel-header-label",
|
|
2272
|
-
children: textToLabel(field.text)
|
|
2273
|
-
}) : type === 'default' ? jsx("div", {
|
|
2274
|
-
class: "fjs-properties-panel-header-label",
|
|
2275
|
-
children: field.id
|
|
2276
|
-
}) : jsx("div", {
|
|
2277
|
-
class: "fjs-properties-panel-header-label",
|
|
2278
|
-
children: field.label
|
|
2279
|
-
})]
|
|
2280
|
-
})]
|
|
2281
|
-
}), getGroups(field, editField)]
|
|
4131
|
+
children: jsx(PropertiesPanel, {
|
|
4132
|
+
element: field,
|
|
4133
|
+
eventBus: eventBus,
|
|
4134
|
+
groups: getGroups(field, editField),
|
|
4135
|
+
headerProvider: PropertiesPanelHeaderProvider,
|
|
4136
|
+
placeholderProvider: PropertiesPanelPlaceholderProvider
|
|
4137
|
+
})
|
|
2282
4138
|
});
|
|
2283
4139
|
}
|
|
2284
4140
|
|
|
4141
|
+
function _extends() { _extends = Object.assign || 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); }
|
|
4142
|
+
var ListDeleteIcon = (({
|
|
4143
|
+
styles = {},
|
|
4144
|
+
...props
|
|
4145
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends({
|
|
4146
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4147
|
+
width: "11",
|
|
4148
|
+
height: "14"
|
|
4149
|
+
}, props), /*#__PURE__*/React.createElement("path", {
|
|
4150
|
+
d: "M10 4v8c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V4h9zM8 6H3v4.8c0 .66.5 1.2 1.111 1.2H6.89C7.5 12 8 11.46 8 10.8V6zm3-5H8.5l-1-1h-4l-1 1H0v1.5h11V1z"
|
|
4151
|
+
})));
|
|
4152
|
+
|
|
2285
4153
|
function ContextPad(props) {
|
|
2286
4154
|
if (!props.children) {
|
|
2287
4155
|
return null;
|
|
@@ -2396,12 +4264,15 @@ function FormEditor$1(props) {
|
|
|
2396
4264
|
formFieldRegistry = useService('formFieldRegistry'),
|
|
2397
4265
|
injector = useService('injector'),
|
|
2398
4266
|
modeling = useService('modeling'),
|
|
2399
|
-
selection = useService('selection')
|
|
4267
|
+
selection = useService('selection'),
|
|
4268
|
+
palette = useService('palette'),
|
|
4269
|
+
paletteConfig = useService('config.palette');
|
|
2400
4270
|
|
|
2401
4271
|
const {
|
|
2402
4272
|
schema
|
|
2403
4273
|
} = formEditor._getState();
|
|
2404
4274
|
|
|
4275
|
+
const paletteRef = useRef(null);
|
|
2405
4276
|
const [selectedFormField, setSelection] = useState(schema);
|
|
2406
4277
|
useEffect(() => {
|
|
2407
4278
|
function handleSelectionChanged(event) {
|
|
@@ -2485,6 +4356,10 @@ function FormEditor$1(props) {
|
|
|
2485
4356
|
eventBus.off('attach', onAttach);
|
|
2486
4357
|
eventBus.off('detach', onDetach);
|
|
2487
4358
|
};
|
|
4359
|
+
}, []); // fire event after first render to notify interested parties
|
|
4360
|
+
|
|
4361
|
+
useEffect(() => {
|
|
4362
|
+
eventBus.fire('formEditor.rendered');
|
|
2488
4363
|
}, []);
|
|
2489
4364
|
const formRenderContext = {
|
|
2490
4365
|
Children,
|
|
@@ -2519,14 +4394,21 @@ function FormEditor$1(props) {
|
|
|
2519
4394
|
};
|
|
2520
4395
|
const onSubmit = useCallback(() => {}, []);
|
|
2521
4396
|
const onReset = useCallback(() => {}, []);
|
|
2522
|
-
const editField = useCallback((formField, key, value) => modeling.editFormField(formField, key, value), [modeling]);
|
|
4397
|
+
const editField = useCallback((formField, key, value) => modeling.editFormField(formField, key, value), [modeling]); // attach default palette
|
|
4398
|
+
|
|
4399
|
+
const hasDefaultPalette = defaultPalette(paletteConfig);
|
|
4400
|
+
useEffect(() => {
|
|
4401
|
+
if (hasDefaultPalette) {
|
|
4402
|
+
palette.attachTo(paletteRef.current);
|
|
4403
|
+
}
|
|
4404
|
+
}, [palette, paletteRef, hasDefaultPalette]);
|
|
2523
4405
|
return jsxs("div", {
|
|
2524
4406
|
class: "fjs-form-editor",
|
|
2525
4407
|
children: [jsxs(DragAndDropContext.Provider, {
|
|
2526
4408
|
value: dragAndDropContext,
|
|
2527
|
-
children: [jsx("div", {
|
|
2528
|
-
class: "fjs-palette-container",
|
|
2529
|
-
|
|
4409
|
+
children: [hasDefaultPalette && jsx("div", {
|
|
4410
|
+
class: "fjs-editor-palette-container",
|
|
4411
|
+
ref: paletteRef
|
|
2530
4412
|
}), jsx("div", {
|
|
2531
4413
|
class: "fjs-form-container",
|
|
2532
4414
|
children: jsx(FormContext.Provider, {
|
|
@@ -2542,7 +4424,7 @@ function FormEditor$1(props) {
|
|
|
2542
4424
|
}), jsx(CreatePreview, {})]
|
|
2543
4425
|
}), jsx("div", {
|
|
2544
4426
|
class: "fjs-properties-container",
|
|
2545
|
-
children: jsx(
|
|
4427
|
+
children: jsx(FormPropertiesPanel, {
|
|
2546
4428
|
field: selectedFormField,
|
|
2547
4429
|
editField: editField
|
|
2548
4430
|
})
|
|
@@ -2587,6 +4469,11 @@ function CreatePreview(props) {
|
|
|
2587
4469
|
return () => drake.off('cloned', handleCloned);
|
|
2588
4470
|
}, [drake]);
|
|
2589
4471
|
return null;
|
|
4472
|
+
} // helper //////
|
|
4473
|
+
|
|
4474
|
+
|
|
4475
|
+
function defaultPalette(paletteConfig) {
|
|
4476
|
+
return !(paletteConfig && paletteConfig.parent);
|
|
2590
4477
|
}
|
|
2591
4478
|
|
|
2592
4479
|
class Renderer {
|
|
@@ -4643,6 +6530,145 @@ var SelectionModule = {
|
|
|
4643
6530
|
selectionBehavior: ['type', SelectionBehavior]
|
|
4644
6531
|
};
|
|
4645
6532
|
|
|
6533
|
+
const types = [{
|
|
6534
|
+
label: 'Text Field',
|
|
6535
|
+
type: 'textfield'
|
|
6536
|
+
}, {
|
|
6537
|
+
label: 'Number',
|
|
6538
|
+
type: 'number'
|
|
6539
|
+
}, {
|
|
6540
|
+
label: 'Checkbox',
|
|
6541
|
+
type: 'checkbox'
|
|
6542
|
+
}, {
|
|
6543
|
+
label: 'Checklist',
|
|
6544
|
+
type: 'checklist'
|
|
6545
|
+
}, {
|
|
6546
|
+
label: 'Taglist',
|
|
6547
|
+
type: 'taglist'
|
|
6548
|
+
}, {
|
|
6549
|
+
label: 'Radio',
|
|
6550
|
+
type: 'radio'
|
|
6551
|
+
}, {
|
|
6552
|
+
label: 'Select',
|
|
6553
|
+
type: 'select'
|
|
6554
|
+
}, {
|
|
6555
|
+
label: 'Text',
|
|
6556
|
+
type: 'text'
|
|
6557
|
+
}, {
|
|
6558
|
+
label: 'Button',
|
|
6559
|
+
type: 'button'
|
|
6560
|
+
}];
|
|
6561
|
+
function Palette(props) {
|
|
6562
|
+
return jsxs("div", {
|
|
6563
|
+
class: "fjs-palette",
|
|
6564
|
+
children: [jsxs("div", {
|
|
6565
|
+
class: "fjs-palette-header",
|
|
6566
|
+
title: "Form elements library",
|
|
6567
|
+
children: [jsx("span", {
|
|
6568
|
+
class: "fjs-hide-compact",
|
|
6569
|
+
children: "FORM ELEMENTS "
|
|
6570
|
+
}), "LIBRARY"]
|
|
6571
|
+
}), jsx("div", {
|
|
6572
|
+
class: "fjs-palette-fields fjs-drag-container fjs-no-drop",
|
|
6573
|
+
children: types.map(({
|
|
6574
|
+
label,
|
|
6575
|
+
type
|
|
6576
|
+
}) => {
|
|
6577
|
+
const Icon = iconsByType[type];
|
|
6578
|
+
return jsxs("div", {
|
|
6579
|
+
class: "fjs-palette-field fjs-drag-copy fjs-no-drop",
|
|
6580
|
+
"data-field-type": type,
|
|
6581
|
+
title: `Create a ${label} element`,
|
|
6582
|
+
children: [Icon ? jsx(Icon, {
|
|
6583
|
+
class: "fjs-palette-field-icon",
|
|
6584
|
+
width: "36",
|
|
6585
|
+
height: "36",
|
|
6586
|
+
viewBox: "0 0 54 54"
|
|
6587
|
+
}) : null, jsx("span", {
|
|
6588
|
+
class: "fjs-palette-field-text fjs-hide-compact",
|
|
6589
|
+
children: label
|
|
6590
|
+
})]
|
|
6591
|
+
});
|
|
6592
|
+
})
|
|
6593
|
+
})]
|
|
6594
|
+
});
|
|
6595
|
+
}
|
|
6596
|
+
|
|
6597
|
+
class PaletteRenderer {
|
|
6598
|
+
constructor(paletteConfig, eventBus) {
|
|
6599
|
+
const {
|
|
6600
|
+
parent
|
|
6601
|
+
} = paletteConfig || {};
|
|
6602
|
+
this._eventBus = eventBus;
|
|
6603
|
+
this._container = domify('<div class="fjs-palette-container"></div>');
|
|
6604
|
+
|
|
6605
|
+
if (parent) {
|
|
6606
|
+
this.attachTo(parent);
|
|
6607
|
+
}
|
|
6608
|
+
|
|
6609
|
+
this._eventBus.once('formEditor.rendered', 500, () => {
|
|
6610
|
+
this._render();
|
|
6611
|
+
});
|
|
6612
|
+
}
|
|
6613
|
+
/**
|
|
6614
|
+
* Attach the palette to a parent node.
|
|
6615
|
+
*
|
|
6616
|
+
* @param {HTMLElement} container
|
|
6617
|
+
*/
|
|
6618
|
+
|
|
6619
|
+
|
|
6620
|
+
attachTo(container) {
|
|
6621
|
+
if (!container) {
|
|
6622
|
+
throw new Error('container required');
|
|
6623
|
+
}
|
|
6624
|
+
|
|
6625
|
+
if (typeof container === 'string') {
|
|
6626
|
+
container = query(container);
|
|
6627
|
+
} // (1) detach from old parent
|
|
6628
|
+
|
|
6629
|
+
|
|
6630
|
+
this.detach(); // (2) append to parent container
|
|
6631
|
+
|
|
6632
|
+
container.appendChild(this._container); // (3) notify interested parties
|
|
6633
|
+
|
|
6634
|
+
this._eventBus.fire('palette.attach');
|
|
6635
|
+
}
|
|
6636
|
+
/**
|
|
6637
|
+
* Detach the palette from its parent node.
|
|
6638
|
+
*/
|
|
6639
|
+
|
|
6640
|
+
|
|
6641
|
+
detach() {
|
|
6642
|
+
const parentNode = this._container.parentNode;
|
|
6643
|
+
|
|
6644
|
+
if (parentNode) {
|
|
6645
|
+
parentNode.removeChild(this._container);
|
|
6646
|
+
|
|
6647
|
+
this._eventBus.fire('palette.detach');
|
|
6648
|
+
}
|
|
6649
|
+
}
|
|
6650
|
+
|
|
6651
|
+
_render() {
|
|
6652
|
+
render(jsx(Palette, {}), this._container);
|
|
6653
|
+
|
|
6654
|
+
this._eventBus.fire('palette.rendered');
|
|
6655
|
+
}
|
|
6656
|
+
|
|
6657
|
+
_destroy() {
|
|
6658
|
+
if (this._container) {
|
|
6659
|
+
render(null, this._container);
|
|
6660
|
+
|
|
6661
|
+
this._eventBus.fire('palette.destroyed');
|
|
6662
|
+
}
|
|
6663
|
+
}
|
|
6664
|
+
|
|
6665
|
+
}
|
|
6666
|
+
PaletteRenderer.$inject = ['config.palette', 'eventBus'];
|
|
6667
|
+
|
|
6668
|
+
var PaletteModule = {
|
|
6669
|
+
palette: ['type', PaletteRenderer]
|
|
6670
|
+
};
|
|
6671
|
+
|
|
4646
6672
|
const ids = new Ids([32, 36, 1]);
|
|
4647
6673
|
/**
|
|
4648
6674
|
* @typedef { import('./types').Injector } Injector
|
|
@@ -4924,7 +6950,7 @@ class FormEditor {
|
|
|
4924
6950
|
|
|
4925
6951
|
|
|
4926
6952
|
_getModules() {
|
|
4927
|
-
return [ModelingModule, EditorActionsModule, KeyboardModule, SelectionModule];
|
|
6953
|
+
return [ModelingModule, EditorActionsModule, KeyboardModule, SelectionModule, PaletteModule];
|
|
4928
6954
|
}
|
|
4929
6955
|
/**
|
|
4930
6956
|
* @internal
|