@bpmn-io/form-js-editor 1.8.7 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -22
- package/dist/assets/form-js-editor.css +25 -0
- package/dist/assets/properties-panel.css +25 -0
- package/dist/index.cjs +179 -185
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +180 -186
- package/dist/index.es.js.map +1 -1
- package/dist/types/features/properties-panel/PropertiesPanelHeaderProvider.d.ts +6 -5
- package/dist/types/features/properties-panel/entries/StaticColumnsSourceEntry.d.ts +0 -1
- package/dist/types/features/properties-panel/entries/StaticOptionsSourceEntry.d.ts +0 -1
- package/dist/types/features/properties-panel/groups/CustomPropertiesGroup.d.ts +0 -1
- package/package.json +4 -4
package/dist/index.es.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Ids from 'ids';
|
|
2
2
|
import { FormFieldRegistry as FormFieldRegistry$1, iconsByType, Label as Label$3, IFrame, Text as Text$1, Html, Table, ExpressionField, FormFields, sanitizeImageSource, getAncestryList, FormContext, FormRenderContext, FormComponent, getScrollContainer, Importer, PathRegistry, FormLayouter, FieldFactory, FeelExpressionLanguage, OPTIONS_SOURCES, OPTIONS_SOURCES_PATHS, clone, runRecursively, getSchemaVariables, DATETIME_SUBTYPES, DATE_LABEL_PATH, TIME_LABEL_PATH, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES_LABELS, TIME_SERIALISING_FORMAT_PATH, TIME_SERIALISING_FORMATS, TIME_INTERVAL_PATH, TIME_USE24H_PATH, DATE_DISALLOW_PAST_PATH, TIME_SERIALISINGFORMAT_LABELS, getOptionsSource, OPTIONS_SOURCES_DEFAULTS, OPTIONS_SOURCES_LABELS, SECURITY_ATTRIBUTES_DEFINITIONS, createFormContainer, createInjector, MarkdownRendererModule, schemaVersion } from '@bpmn-io/form-js-viewer';
|
|
3
3
|
export { schemaVersion } from '@bpmn-io/form-js-viewer';
|
|
4
|
-
import { isArray, isFunction, isNumber, bind, assign, debounce, forEach, isString, uniqueBy, isObject, get, isDefined,
|
|
4
|
+
import { isArray, isFunction, isNumber, bind, assign, debounce, forEach, isString, uniqueBy, isObject, get, isDefined, set as set$1, reduce, without, isNil, has } from 'min-dash';
|
|
5
5
|
import classnames from 'classnames';
|
|
6
6
|
import { jsxs, jsx, Fragment as Fragment$1 } from 'preact/jsx-runtime';
|
|
7
7
|
import { useContext, useRef, useEffect, useMemo, useState, useCallback, useLayoutEffect } from 'preact/hooks';
|
|
@@ -5373,6 +5373,21 @@ PopupIcon.defaultProps = {
|
|
|
5373
5373
|
height: "16",
|
|
5374
5374
|
viewBox: "0 0 32 32"
|
|
5375
5375
|
};
|
|
5376
|
+
var CloseIcon = function CloseIcon(props) {
|
|
5377
|
+
return jsx("svg", {
|
|
5378
|
+
...props,
|
|
5379
|
+
children: jsx("path", {
|
|
5380
|
+
fillRule: "evenodd",
|
|
5381
|
+
d: "m12 4.7-.7-.7L8 7.3 4.7 4l-.7.7L7.3 8 4 11.3l.7.7L8 8.7l3.3 3.3.7-.7L8.7 8 12 4.7Z",
|
|
5382
|
+
fill: "currentColor"
|
|
5383
|
+
})
|
|
5384
|
+
});
|
|
5385
|
+
};
|
|
5386
|
+
CloseIcon.defaultProps = {
|
|
5387
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5388
|
+
width: "16",
|
|
5389
|
+
height: "16"
|
|
5390
|
+
};
|
|
5376
5391
|
function Header(props) {
|
|
5377
5392
|
const {
|
|
5378
5393
|
element,
|
|
@@ -6073,7 +6088,8 @@ const CodeEditor$1 = forwardRef((props, ref) => {
|
|
|
6073
6088
|
tooltipContainer,
|
|
6074
6089
|
enableGutters,
|
|
6075
6090
|
hostLanguage,
|
|
6076
|
-
singleLine
|
|
6091
|
+
singleLine,
|
|
6092
|
+
lineWrap: true
|
|
6077
6093
|
});
|
|
6078
6094
|
setEditor(editor);
|
|
6079
6095
|
return () => {
|
|
@@ -6110,7 +6126,7 @@ const CodeEditor$1 = forwardRef((props, ref) => {
|
|
|
6110
6126
|
title: "Open pop-up editor",
|
|
6111
6127
|
class: "bio-properties-panel-open-feel-popup",
|
|
6112
6128
|
onClick: () => onPopupOpen('feelers'),
|
|
6113
|
-
children: jsx(
|
|
6129
|
+
children: jsx(PopupIcon, {})
|
|
6114
6130
|
})]
|
|
6115
6131
|
});
|
|
6116
6132
|
});
|
|
@@ -6150,6 +6166,7 @@ const CodeEditor = forwardRef((props, ref) => {
|
|
|
6150
6166
|
onFeelToggle = noop$5,
|
|
6151
6167
|
onLint = noop$5,
|
|
6152
6168
|
onPopupOpen = noop$5,
|
|
6169
|
+
placeholder,
|
|
6153
6170
|
popupOpen,
|
|
6154
6171
|
disabled,
|
|
6155
6172
|
tooltipContainer,
|
|
@@ -6186,6 +6203,7 @@ const CodeEditor = forwardRef((props, ref) => {
|
|
|
6186
6203
|
onChange: handleInput,
|
|
6187
6204
|
onKeyDown: onKeyDown,
|
|
6188
6205
|
onLint: onLint,
|
|
6206
|
+
placeholder: placeholder,
|
|
6189
6207
|
tooltipContainer: tooltipContainer,
|
|
6190
6208
|
value: localValue,
|
|
6191
6209
|
variables: variables,
|
|
@@ -6215,6 +6233,12 @@ const CodeEditor = forwardRef((props, ref) => {
|
|
|
6215
6233
|
}
|
|
6216
6234
|
editor.setVariables(variables);
|
|
6217
6235
|
}, [variables]);
|
|
6236
|
+
useEffect(() => {
|
|
6237
|
+
if (!editor) {
|
|
6238
|
+
return;
|
|
6239
|
+
}
|
|
6240
|
+
editor.setPlaceholder(placeholder);
|
|
6241
|
+
}, [placeholder]);
|
|
6218
6242
|
const handleClick = () => {
|
|
6219
6243
|
ref.current.focus();
|
|
6220
6244
|
};
|
|
@@ -6467,6 +6491,9 @@ function Title(props) {
|
|
|
6467
6491
|
draggable,
|
|
6468
6492
|
emit = () => {},
|
|
6469
6493
|
title,
|
|
6494
|
+
showCloseButton = false,
|
|
6495
|
+
closeButtonTooltip = 'Close popup',
|
|
6496
|
+
onClose,
|
|
6470
6497
|
...rest
|
|
6471
6498
|
} = props;
|
|
6472
6499
|
|
|
@@ -6537,7 +6564,12 @@ function Title(props) {
|
|
|
6537
6564
|
}), jsx("div", {
|
|
6538
6565
|
class: "bio-properties-panel-popup__title",
|
|
6539
6566
|
children: title
|
|
6540
|
-
}), children
|
|
6567
|
+
}), children, showCloseButton && jsx("button", {
|
|
6568
|
+
title: closeButtonTooltip,
|
|
6569
|
+
class: "bio-properties-panel-popup__close",
|
|
6570
|
+
onClick: onClose,
|
|
6571
|
+
children: jsx(CloseIcon, {})
|
|
6572
|
+
})]
|
|
6541
6573
|
});
|
|
6542
6574
|
}
|
|
6543
6575
|
function Body(props) {
|
|
@@ -6755,6 +6787,9 @@ function FeelPopupComponent(props) {
|
|
|
6755
6787
|
children: [jsxs(Popup.Title, {
|
|
6756
6788
|
title: title,
|
|
6757
6789
|
emit: emit,
|
|
6790
|
+
showCloseButton: true,
|
|
6791
|
+
closeButtonTooltip: "Save and close",
|
|
6792
|
+
onClose: onClose,
|
|
6758
6793
|
draggable: true,
|
|
6759
6794
|
children: [type === 'feel' && jsxs("a", {
|
|
6760
6795
|
href: "https://docs.camunda.io/docs/components/modeler/feel/what-is-feel/",
|
|
@@ -6796,14 +6831,6 @@ function FeelPopupComponent(props) {
|
|
|
6796
6831
|
tooltipContainer: tooltipContainer
|
|
6797
6832
|
})]
|
|
6798
6833
|
})
|
|
6799
|
-
}), jsx(Popup.Footer, {
|
|
6800
|
-
children: jsx("button", {
|
|
6801
|
-
type: "button",
|
|
6802
|
-
onClick: () => onClose(),
|
|
6803
|
-
title: "Close pop-up editor",
|
|
6804
|
-
class: "bio-properties-panel-feel-popup__close-btn",
|
|
6805
|
-
children: "Close"
|
|
6806
|
-
})
|
|
6807
6834
|
})]
|
|
6808
6835
|
});
|
|
6809
6836
|
}
|
|
@@ -7113,6 +7140,7 @@ function FeelTextfieldComponent(props) {
|
|
|
7113
7140
|
hostLanguage,
|
|
7114
7141
|
onInput,
|
|
7115
7142
|
onError,
|
|
7143
|
+
placeholder,
|
|
7116
7144
|
feel,
|
|
7117
7145
|
value = '',
|
|
7118
7146
|
disabled = false,
|
|
@@ -7287,6 +7315,7 @@ function FeelTextfieldComponent(props) {
|
|
|
7287
7315
|
},
|
|
7288
7316
|
onLint: handleLint,
|
|
7289
7317
|
onPopupOpen: handlePopupOpen,
|
|
7318
|
+
placeholder: placeholder,
|
|
7290
7319
|
value: feelOnlyValue,
|
|
7291
7320
|
variables: variables,
|
|
7292
7321
|
ref: editorRef,
|
|
@@ -7315,7 +7344,8 @@ const OptionalFeelInput = forwardRef((props, ref) => {
|
|
|
7315
7344
|
onInput,
|
|
7316
7345
|
value,
|
|
7317
7346
|
onFocus,
|
|
7318
|
-
onBlur
|
|
7347
|
+
onBlur,
|
|
7348
|
+
placeholder
|
|
7319
7349
|
} = props;
|
|
7320
7350
|
const inputRef = useRef();
|
|
7321
7351
|
|
|
@@ -7348,6 +7378,7 @@ const OptionalFeelInput = forwardRef((props, ref) => {
|
|
|
7348
7378
|
onInput: e => onInput(e.target.value),
|
|
7349
7379
|
onFocus: onFocus,
|
|
7350
7380
|
onBlur: onBlur,
|
|
7381
|
+
placeholder: placeholder,
|
|
7351
7382
|
value: value || ''
|
|
7352
7383
|
});
|
|
7353
7384
|
});
|
|
@@ -7405,7 +7436,8 @@ forwardRef((props, ref) => {
|
|
|
7405
7436
|
onInput,
|
|
7406
7437
|
value,
|
|
7407
7438
|
onFocus,
|
|
7408
|
-
onBlur
|
|
7439
|
+
onBlur,
|
|
7440
|
+
placeholder
|
|
7409
7441
|
} = props;
|
|
7410
7442
|
const inputRef = useRef();
|
|
7411
7443
|
|
|
@@ -7433,6 +7465,7 @@ forwardRef((props, ref) => {
|
|
|
7433
7465
|
onInput: e => onInput(e.target.value),
|
|
7434
7466
|
onFocus: onFocus,
|
|
7435
7467
|
onBlur: onBlur,
|
|
7468
|
+
placeholder: placeholder,
|
|
7436
7469
|
value: value || '',
|
|
7437
7470
|
"data-gramm": "false"
|
|
7438
7471
|
});
|
|
@@ -7528,6 +7561,7 @@ forwardRef((props, ref) => {
|
|
|
7528
7561
|
* @param {Function} props.variables
|
|
7529
7562
|
* @param {Function} props.onFocus
|
|
7530
7563
|
* @param {Function} props.onBlur
|
|
7564
|
+
* @param {string} [props.placeholder]
|
|
7531
7565
|
* @param {string|import('preact').Component} props.tooltip
|
|
7532
7566
|
*/
|
|
7533
7567
|
function FeelEntry(props) {
|
|
@@ -7550,6 +7584,7 @@ function FeelEntry(props) {
|
|
|
7550
7584
|
variables,
|
|
7551
7585
|
onFocus,
|
|
7552
7586
|
onBlur,
|
|
7587
|
+
placeholder,
|
|
7553
7588
|
tooltip
|
|
7554
7589
|
} = props;
|
|
7555
7590
|
const [validationError, setValidationError] = useState(null);
|
|
@@ -7593,6 +7628,7 @@ function FeelEntry(props) {
|
|
|
7593
7628
|
onError: onError,
|
|
7594
7629
|
onFocus: onFocus,
|
|
7595
7630
|
onBlur: onBlur,
|
|
7631
|
+
placeholder: placeholder,
|
|
7596
7632
|
example: example,
|
|
7597
7633
|
hostLanguage: hostLanguage,
|
|
7598
7634
|
singleLine: singleLine,
|
|
@@ -7780,7 +7816,6 @@ const DEFAULT_TOOLTIP = {};
|
|
|
7780
7816
|
* id: String,
|
|
7781
7817
|
* items: Array<ListItemDefinition>,
|
|
7782
7818
|
* label: String,
|
|
7783
|
-
* shouldSort?: Boolean,
|
|
7784
7819
|
* shouldOpen?: Boolean
|
|
7785
7820
|
* } } ListGroupDefinition
|
|
7786
7821
|
*
|
|
@@ -8108,6 +8143,7 @@ function ListItem(props) {
|
|
|
8108
8143
|
} else if (isFunction(focusableInput.focus)) {
|
|
8109
8144
|
focusableInput.focus();
|
|
8110
8145
|
}
|
|
8146
|
+
focusableInput.scrollIntoView();
|
|
8111
8147
|
}
|
|
8112
8148
|
}
|
|
8113
8149
|
}, [autoOpen, autoFocusEntry]);
|
|
@@ -8131,97 +8167,61 @@ function ListGroup(props) {
|
|
|
8131
8167
|
id,
|
|
8132
8168
|
items,
|
|
8133
8169
|
label,
|
|
8134
|
-
shouldOpen = true
|
|
8135
|
-
shouldSort = true
|
|
8170
|
+
shouldOpen = true
|
|
8136
8171
|
} = props;
|
|
8172
|
+
useEffect(() => {
|
|
8173
|
+
if (props.shouldSort != undefined) {
|
|
8174
|
+
console.warn('the property \'shouldSort\' is no longer supported');
|
|
8175
|
+
}
|
|
8176
|
+
}, [props.shouldSort]);
|
|
8137
8177
|
const groupRef = useRef(null);
|
|
8138
8178
|
const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
|
|
8139
8179
|
const [sticky, setSticky] = useState(false);
|
|
8140
8180
|
const onShow = useCallback(() => setOpen(true), [setOpen]);
|
|
8141
|
-
const [
|
|
8142
|
-
const [
|
|
8181
|
+
const [localItems, setLocalItems] = useState([]);
|
|
8182
|
+
const [newlyAddedItemIds, setNewlyAddedItemIds] = useState([]);
|
|
8143
8183
|
|
|
8144
8184
|
// Flag to mark that add button was clicked in the last render cycle
|
|
8145
8185
|
const [addTriggered, setAddTriggered] = useState(false);
|
|
8146
|
-
const prevItems = usePrevious(items);
|
|
8147
8186
|
const prevElement = usePrevious(element);
|
|
8148
8187
|
const elementChanged = element !== prevElement;
|
|
8149
|
-
const shouldHandleEffects = !elementChanged &&
|
|
8150
|
-
|
|
8151
|
-
//
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
//
|
|
8157
|
-
|
|
8158
|
-
// (0) set initial ordering from given items
|
|
8188
|
+
const shouldHandleEffects = !elementChanged && shouldOpen;
|
|
8189
|
+
|
|
8190
|
+
// (0) delay setting items
|
|
8191
|
+
//
|
|
8192
|
+
// We need to this to align the render cycles of items
|
|
8193
|
+
// with the detection of newly added items.
|
|
8194
|
+
// This is important, because the autoOpen property can
|
|
8195
|
+
// only set per list item on its very first render.
|
|
8159
8196
|
useEffect(() => {
|
|
8160
|
-
|
|
8161
|
-
|
|
8162
|
-
}
|
|
8163
|
-
}, [items, element]);
|
|
8197
|
+
setLocalItems(items);
|
|
8198
|
+
}, [items]);
|
|
8164
8199
|
|
|
8165
|
-
// (1) items were added
|
|
8200
|
+
// (1) handle auto opening when items were added
|
|
8166
8201
|
useEffect(() => {
|
|
8167
8202
|
// reset addTriggered flag
|
|
8168
8203
|
setAddTriggered(false);
|
|
8169
|
-
if (shouldHandleEffects &&
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8204
|
+
if (shouldHandleEffects && localItems) {
|
|
8205
|
+
if (addTriggered) {
|
|
8206
|
+
const previousItemIds = localItems.map(item => item.id);
|
|
8207
|
+
const currentItemsIds = items.map(item => item.id);
|
|
8208
|
+
const newItemIds = currentItemsIds.filter(itemId => !previousItemIds.includes(itemId));
|
|
8209
|
+
|
|
8210
|
+
// open if not open, configured and triggered by add button
|
|
8211
|
+
//
|
|
8212
|
+
// TODO(marstamm): remove once we refactor layout handling for listGroups.
|
|
8213
|
+
// Ideally, opening should be handled as part of the `add` callback and
|
|
8214
|
+
// not be a concern for the ListGroup component.
|
|
8215
|
+
if (!open && shouldOpen && newItemIds.length > 0) {
|
|
8216
|
+
toggleOpen();
|
|
8174
8217
|
}
|
|
8175
|
-
|
|
8176
|
-
let newOrdering = ordering;
|
|
8177
|
-
|
|
8178
|
-
// open if not open, configured and triggered by add button
|
|
8179
|
-
//
|
|
8180
|
-
// TODO(marstamm): remove once we refactor layout handling for listGroups.
|
|
8181
|
-
// Ideally, opening should be handled as part of the `add` callback and
|
|
8182
|
-
// not be a concern for the ListGroup component.
|
|
8183
|
-
if (addTriggered && !open && shouldOpen) {
|
|
8184
|
-
toggleOpen();
|
|
8185
|
-
}
|
|
8186
|
-
|
|
8187
|
-
// filter when not open and configured
|
|
8188
|
-
if (!open && shouldSort) {
|
|
8189
|
-
newOrdering = createOrdering(sortItems(items));
|
|
8190
|
-
}
|
|
8191
|
-
|
|
8192
|
-
// add new items on top or bottom depending on sorting behavior
|
|
8193
|
-
newOrdering = newOrdering.filter(item => !add.includes(item));
|
|
8194
|
-
if (shouldSort) {
|
|
8195
|
-
newOrdering.unshift(...add);
|
|
8218
|
+
setNewlyAddedItemIds(newItemIds);
|
|
8196
8219
|
} else {
|
|
8197
|
-
|
|
8220
|
+
// ignore newly added items that do not result from a triggered add
|
|
8221
|
+
setNewlyAddedItemIds([]);
|
|
8198
8222
|
}
|
|
8199
|
-
setOrdering(newOrdering);
|
|
8200
|
-
setNewItemAdded(addTriggered);
|
|
8201
|
-
} else {
|
|
8202
|
-
setNewItemAdded(false);
|
|
8203
|
-
}
|
|
8204
|
-
}, [items, open, shouldHandleEffects, addTriggered]);
|
|
8205
|
-
|
|
8206
|
-
// (2) sort items on open if shouldSort is set
|
|
8207
|
-
useEffect(() => {
|
|
8208
|
-
if (shouldSort && open && !newItemAdded) {
|
|
8209
|
-
setOrdering(createOrdering(sortItems(items)));
|
|
8210
|
-
}
|
|
8211
|
-
}, [open, shouldSort]);
|
|
8212
|
-
|
|
8213
|
-
// (3) items were deleted
|
|
8214
|
-
useEffect(() => {
|
|
8215
|
-
if (shouldHandleEffects && prevItems && items.length < prevItems.length) {
|
|
8216
|
-
let keep = [];
|
|
8217
|
-
ordering.forEach(o => {
|
|
8218
|
-
if (getItem(items, o)) {
|
|
8219
|
-
keep.push(o);
|
|
8220
|
-
}
|
|
8221
|
-
});
|
|
8222
|
-
setOrdering(keep);
|
|
8223
8223
|
}
|
|
8224
|
-
}, [items, shouldHandleEffects]);
|
|
8224
|
+
}, [items, open, shouldHandleEffects, addTriggered, localItems]);
|
|
8225
8225
|
|
|
8226
8226
|
// set css class when group is sticky to top
|
|
8227
8227
|
useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
|
|
@@ -8293,8 +8293,7 @@ function ListGroup(props) {
|
|
|
8293
8293
|
class: classnames('bio-properties-panel-list', open && hasItems ? 'open' : ''),
|
|
8294
8294
|
children: jsx(LayoutContext.Provider, {
|
|
8295
8295
|
value: propertiesPanelContext,
|
|
8296
|
-
children:
|
|
8297
|
-
const item = getItem(items, o);
|
|
8296
|
+
children: localItems.map((item, index) => {
|
|
8298
8297
|
if (!item) {
|
|
8299
8298
|
return;
|
|
8300
8299
|
}
|
|
@@ -8304,7 +8303,7 @@ function ListGroup(props) {
|
|
|
8304
8303
|
|
|
8305
8304
|
// if item was added, open it
|
|
8306
8305
|
// Existing items will not be affected as autoOpen is only applied on first render
|
|
8307
|
-
const autoOpen =
|
|
8306
|
+
const autoOpen = newlyAddedItemIds.includes(item.id);
|
|
8308
8307
|
return createElement(ListItem, {
|
|
8309
8308
|
...item,
|
|
8310
8309
|
autoOpen: autoOpen,
|
|
@@ -8317,21 +8316,6 @@ function ListGroup(props) {
|
|
|
8317
8316
|
})]
|
|
8318
8317
|
});
|
|
8319
8318
|
}
|
|
8320
|
-
|
|
8321
|
-
// helpers ////////////////////
|
|
8322
|
-
|
|
8323
|
-
/**
|
|
8324
|
-
* Sorts given items alphanumeric by label
|
|
8325
|
-
*/
|
|
8326
|
-
function sortItems(items) {
|
|
8327
|
-
return sortBy(items, i => i.label.toLowerCase());
|
|
8328
|
-
}
|
|
8329
|
-
function getItem(items, id) {
|
|
8330
|
-
return find(items, i => i.id === id);
|
|
8331
|
-
}
|
|
8332
|
-
function createOrdering(items) {
|
|
8333
|
-
return items.map(i => i.id);
|
|
8334
|
-
}
|
|
8335
8319
|
function Checkbox(props) {
|
|
8336
8320
|
const {
|
|
8337
8321
|
id,
|
|
@@ -8618,6 +8602,7 @@ function TextArea(props) {
|
|
|
8618
8602
|
onFocus,
|
|
8619
8603
|
onBlur,
|
|
8620
8604
|
autoResize,
|
|
8605
|
+
placeholder,
|
|
8621
8606
|
rows = autoResize ? 1 : 2,
|
|
8622
8607
|
tooltip
|
|
8623
8608
|
} = props;
|
|
@@ -8660,6 +8645,7 @@ function TextArea(props) {
|
|
|
8660
8645
|
onInput: handleInput,
|
|
8661
8646
|
onFocus: onFocus,
|
|
8662
8647
|
onBlur: onBlur,
|
|
8648
|
+
placeholder: placeholder,
|
|
8663
8649
|
rows: rows,
|
|
8664
8650
|
value: localValue,
|
|
8665
8651
|
disabled: disabled,
|
|
@@ -8699,6 +8685,7 @@ function TextAreaEntry(props) {
|
|
|
8699
8685
|
validate,
|
|
8700
8686
|
onFocus,
|
|
8701
8687
|
onBlur,
|
|
8688
|
+
placeholder,
|
|
8702
8689
|
autoResize,
|
|
8703
8690
|
tooltip
|
|
8704
8691
|
} = props;
|
|
@@ -8734,6 +8721,7 @@ function TextAreaEntry(props) {
|
|
|
8734
8721
|
debounce: debounce,
|
|
8735
8722
|
monospace: monospace,
|
|
8736
8723
|
disabled: disabled,
|
|
8724
|
+
placeholder: placeholder,
|
|
8737
8725
|
autoResize: autoResize,
|
|
8738
8726
|
tooltip: tooltip,
|
|
8739
8727
|
element: element
|
|
@@ -8765,6 +8753,7 @@ function Textfield(props) {
|
|
|
8765
8753
|
onInput,
|
|
8766
8754
|
onFocus,
|
|
8767
8755
|
onBlur,
|
|
8756
|
+
placeholder,
|
|
8768
8757
|
value = '',
|
|
8769
8758
|
tooltip
|
|
8770
8759
|
} = props;
|
|
@@ -8806,6 +8795,7 @@ function Textfield(props) {
|
|
|
8806
8795
|
onInput: handleInput,
|
|
8807
8796
|
onFocus: onFocus,
|
|
8808
8797
|
onBlur: onBlur,
|
|
8798
|
+
placeholder: placeholder,
|
|
8809
8799
|
value: localValue
|
|
8810
8800
|
})]
|
|
8811
8801
|
});
|
|
@@ -8839,6 +8829,7 @@ function TextfieldEntry(props) {
|
|
|
8839
8829
|
validate,
|
|
8840
8830
|
onFocus,
|
|
8841
8831
|
onBlur,
|
|
8832
|
+
placeholder,
|
|
8842
8833
|
tooltip
|
|
8843
8834
|
} = props;
|
|
8844
8835
|
const globalError = useError(id);
|
|
@@ -8870,6 +8861,7 @@ function TextfieldEntry(props) {
|
|
|
8870
8861
|
onInput: onInput,
|
|
8871
8862
|
onFocus: onFocus,
|
|
8872
8863
|
onBlur: onBlur,
|
|
8864
|
+
placeholder: placeholder,
|
|
8873
8865
|
value: value,
|
|
8874
8866
|
tooltip: tooltip,
|
|
8875
8867
|
element: element
|
|
@@ -9018,83 +9010,64 @@ function hasIntegerPathSegment(path) {
|
|
|
9018
9010
|
return path.split('.').some(segment => /^\d+$/.test(segment));
|
|
9019
9011
|
}
|
|
9020
9012
|
|
|
9021
|
-
|
|
9013
|
+
const headerlessTypes = ['spacer', 'separator', 'expression', 'html'];
|
|
9014
|
+
function getPropertiesPanelHeaderProvider(options = {}) {
|
|
9022
9015
|
const {
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9016
|
+
getDocumentationRef,
|
|
9017
|
+
formFields
|
|
9018
|
+
} = options;
|
|
9019
|
+
return {
|
|
9020
|
+
getElementLabel: field => {
|
|
9021
|
+
const {
|
|
9022
|
+
type
|
|
9023
|
+
} = field;
|
|
9024
|
+
if (headerlessTypes.includes(type)) {
|
|
9025
|
+
return '';
|
|
9026
|
+
}
|
|
9027
|
+
if (type === 'text') {
|
|
9028
|
+
return textToLabel(field.text);
|
|
9029
|
+
}
|
|
9030
|
+
if (type === 'image') {
|
|
9031
|
+
return field.alt;
|
|
9032
|
+
}
|
|
9033
|
+
if (type === 'default') {
|
|
9034
|
+
return field.id;
|
|
9035
|
+
}
|
|
9036
|
+
return field.label;
|
|
9037
|
+
},
|
|
9038
|
+
getElementIcon: field => {
|
|
9039
|
+
const {
|
|
9040
|
+
type
|
|
9041
|
+
} = field;
|
|
9042
|
+
const fieldDefinition = formFields.get(type).config;
|
|
9043
|
+
const Icon = fieldDefinition.icon || iconsByType(type);
|
|
9044
|
+
if (Icon) {
|
|
9045
|
+
return () => jsx(Icon, {
|
|
9046
|
+
width: "36",
|
|
9047
|
+
height: "36",
|
|
9048
|
+
viewBox: "0 0 54 54"
|
|
9049
|
+
});
|
|
9050
|
+
} else if (fieldDefinition.iconUrl) {
|
|
9051
|
+
return getPaletteIcon({
|
|
9052
|
+
iconUrl: fieldDefinition.iconUrl,
|
|
9053
|
+
label: fieldDefinition.label
|
|
9054
|
+
});
|
|
9055
|
+
}
|
|
9056
|
+
},
|
|
9057
|
+
getTypeLabel: field => {
|
|
9058
|
+
const {
|
|
9059
|
+
type
|
|
9060
|
+
} = field;
|
|
9061
|
+
if (type === 'default') {
|
|
9062
|
+
return 'Form';
|
|
9063
|
+
}
|
|
9064
|
+
const fieldDefinition = formFields.get(type).config;
|
|
9065
|
+
return fieldDefinition.label || type;
|
|
9066
|
+
},
|
|
9067
|
+
getDocumentationRef
|
|
9068
|
+
};
|
|
9037
9069
|
}
|
|
9038
9070
|
|
|
9039
|
-
const headerlessTypes = ['spacer', 'separator', 'expression', 'html'];
|
|
9040
|
-
const PropertiesPanelHeaderProvider = {
|
|
9041
|
-
getElementLabel: field => {
|
|
9042
|
-
const {
|
|
9043
|
-
type
|
|
9044
|
-
} = field;
|
|
9045
|
-
if (headerlessTypes.includes(type)) {
|
|
9046
|
-
return '';
|
|
9047
|
-
}
|
|
9048
|
-
if (type === 'text') {
|
|
9049
|
-
return textToLabel(field.text);
|
|
9050
|
-
}
|
|
9051
|
-
if (type === 'image') {
|
|
9052
|
-
return field.alt;
|
|
9053
|
-
}
|
|
9054
|
-
if (type === 'default') {
|
|
9055
|
-
return field.id;
|
|
9056
|
-
}
|
|
9057
|
-
return field.label;
|
|
9058
|
-
},
|
|
9059
|
-
getElementIcon: field => {
|
|
9060
|
-
const {
|
|
9061
|
-
type
|
|
9062
|
-
} = field;
|
|
9063
|
-
|
|
9064
|
-
// @Note: We know that we are inside the properties panel context,
|
|
9065
|
-
// so we can savely use the hook here.
|
|
9066
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
9067
|
-
const fieldDefinition = useService('formFields').get(type).config;
|
|
9068
|
-
const Icon = fieldDefinition.icon || iconsByType(type);
|
|
9069
|
-
if (Icon) {
|
|
9070
|
-
return () => jsx(Icon, {
|
|
9071
|
-
width: "36",
|
|
9072
|
-
height: "36",
|
|
9073
|
-
viewBox: "0 0 54 54"
|
|
9074
|
-
});
|
|
9075
|
-
} else if (fieldDefinition.iconUrl) {
|
|
9076
|
-
return getPaletteIcon({
|
|
9077
|
-
iconUrl: fieldDefinition.iconUrl,
|
|
9078
|
-
label: fieldDefinition.label
|
|
9079
|
-
});
|
|
9080
|
-
}
|
|
9081
|
-
},
|
|
9082
|
-
getTypeLabel: field => {
|
|
9083
|
-
const {
|
|
9084
|
-
type
|
|
9085
|
-
} = field;
|
|
9086
|
-
if (type === 'default') {
|
|
9087
|
-
return 'Form';
|
|
9088
|
-
}
|
|
9089
|
-
|
|
9090
|
-
// @Note: We know that we are inside the properties panel context,
|
|
9091
|
-
// so we can savely use the hook here.
|
|
9092
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
9093
|
-
const fieldDefinition = useService('formFields').get(type).config;
|
|
9094
|
-
return fieldDefinition.label || type;
|
|
9095
|
-
}
|
|
9096
|
-
};
|
|
9097
|
-
|
|
9098
9071
|
/**
|
|
9099
9072
|
* Provide placeholders for empty and multiple state.
|
|
9100
9073
|
*/
|
|
@@ -9111,6 +9084,7 @@ const PropertiesPanelPlaceholderProvider = {
|
|
|
9111
9084
|
}
|
|
9112
9085
|
};
|
|
9113
9086
|
|
|
9087
|
+
const EMPTY = {};
|
|
9114
9088
|
function PropertiesPanel(props) {
|
|
9115
9089
|
const {
|
|
9116
9090
|
eventBus,
|
|
@@ -9120,7 +9094,7 @@ function PropertiesPanel(props) {
|
|
|
9120
9094
|
const formEditor = injector.get('formEditor');
|
|
9121
9095
|
const modeling = injector.get('modeling');
|
|
9122
9096
|
const selectionModule = injector.get('selection');
|
|
9123
|
-
const propertiesPanelConfig = injector.get('config.propertiesPanel') ||
|
|
9097
|
+
const propertiesPanelConfig = injector.get('config.propertiesPanel') || EMPTY;
|
|
9124
9098
|
const {
|
|
9125
9099
|
feelPopupContainer
|
|
9126
9100
|
} = propertiesPanelConfig;
|
|
@@ -9174,6 +9148,11 @@ function PropertiesPanel(props) {
|
|
|
9174
9148
|
return updater(groups);
|
|
9175
9149
|
}, []);
|
|
9176
9150
|
}, [providers, selectedFormField, editField]);
|
|
9151
|
+
const formFields = getService('formFields');
|
|
9152
|
+
const PropertiesPanelHeaderProvider = useMemo(() => getPropertiesPanelHeaderProvider({
|
|
9153
|
+
getDocumentationRef: propertiesPanelConfig.getDocumentationRef,
|
|
9154
|
+
formFields
|
|
9155
|
+
}), [formFields, propertiesPanelConfig]);
|
|
9177
9156
|
return jsx("div", {
|
|
9178
9157
|
class: "fjs-properties-panel",
|
|
9179
9158
|
"data-field": selectedFormField && selectedFormField.id,
|
|
@@ -9347,6 +9326,24 @@ function Action(props) {
|
|
|
9347
9326
|
});
|
|
9348
9327
|
}
|
|
9349
9328
|
|
|
9329
|
+
function useService(type, strict) {
|
|
9330
|
+
const {
|
|
9331
|
+
getService
|
|
9332
|
+
} = useContext(FormPropertiesPanelContext);
|
|
9333
|
+
return getService(type, strict);
|
|
9334
|
+
}
|
|
9335
|
+
|
|
9336
|
+
/**
|
|
9337
|
+
* Retrieve list of variables from the form schema.
|
|
9338
|
+
*
|
|
9339
|
+
* @returns { string[] } list of variables used in form schema
|
|
9340
|
+
*/
|
|
9341
|
+
function useVariables() {
|
|
9342
|
+
const form = useService('formEditor');
|
|
9343
|
+
const schema = form.getSchema();
|
|
9344
|
+
return getSchemaVariables(schema);
|
|
9345
|
+
}
|
|
9346
|
+
|
|
9350
9347
|
function AltTextEntry(props) {
|
|
9351
9348
|
const {
|
|
9352
9349
|
editField,
|
|
@@ -11633,8 +11630,7 @@ function StaticOptionsSourceEntry(props) {
|
|
|
11633
11630
|
});
|
|
11634
11631
|
return {
|
|
11635
11632
|
items,
|
|
11636
|
-
add: addEntry
|
|
11637
|
-
shouldSort: false
|
|
11633
|
+
add: addEntry
|
|
11638
11634
|
};
|
|
11639
11635
|
}
|
|
11640
11636
|
|
|
@@ -12478,8 +12474,7 @@ function StaticColumnsSourceEntry(props) {
|
|
|
12478
12474
|
});
|
|
12479
12475
|
return {
|
|
12480
12476
|
items,
|
|
12481
|
-
add: addEntry
|
|
12482
|
-
shouldSort: false
|
|
12477
|
+
add: addEntry
|
|
12483
12478
|
};
|
|
12484
12479
|
}
|
|
12485
12480
|
|
|
@@ -12981,8 +12976,7 @@ function CustomPropertiesGroup(field, editField) {
|
|
|
12981
12976
|
id: 'custom-values',
|
|
12982
12977
|
items,
|
|
12983
12978
|
label: 'Custom properties',
|
|
12984
|
-
tooltip: 'Add properties directly to the form schema, useful to configure functionality in custom-built task applications and form renderers.'
|
|
12985
|
-
shouldSort: false
|
|
12979
|
+
tooltip: 'Add properties directly to the form schema, useful to configure functionality in custom-built task applications and form renderers.'
|
|
12986
12980
|
};
|
|
12987
12981
|
}
|
|
12988
12982
|
|