@bpmn-io/form-js-editor 1.4.0 → 1.4.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/dist/index.es.js CHANGED
@@ -1,4 +1,4 @@
1
- import { FormFieldRegistry as FormFieldRegistry$1, iconsByType, Text as Text$1, FormFields, sanitizeImageSource, FormContext, FormRenderContext, FormComponent, Importer, PathRegistry, FormLayouter, FieldFactory, runRecursively, clone, getSchemaVariables, DATETIME_SUBTYPES, DATE_LABEL_PATH, TIME_LABEL_PATH, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES_LABELS, TIME_SERIALISING_FORMAT_PATH, TIME_SERIALISING_FORMATS, TIME_INTERVAL_PATH, TIME_USE24H_PATH, DATE_DISALLOW_PAST_PATH, TIME_SERIALISINGFORMAT_LABELS, getValuesSource, VALUES_SOURCES, VALUES_SOURCES_DEFAULTS, VALUES_SOURCES_PATHS, VALUES_SOURCES_LABELS, FeelExpressionLanguage, createFormContainer, createInjector, MarkdownModule, schemaVersion } from '@bpmn-io/form-js-viewer';
1
+ import { FormFieldRegistry as FormFieldRegistry$1, iconsByType, Text as Text$1, FormFields, sanitizeImageSource, FormContext, FormRenderContext, FormComponent, Importer, PathRegistry, FormLayouter, FieldFactory, runRecursively, clone, VALUES_SOURCES, VALUES_SOURCES_PATHS, getSchemaVariables, DATETIME_SUBTYPES, DATE_LABEL_PATH, TIME_LABEL_PATH, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES_LABELS, TIME_SERIALISING_FORMAT_PATH, TIME_SERIALISING_FORMATS, TIME_INTERVAL_PATH, TIME_USE24H_PATH, DATE_DISALLOW_PAST_PATH, TIME_SERIALISINGFORMAT_LABELS, getValuesSource, VALUES_SOURCES_DEFAULTS, VALUES_SOURCES_LABELS, FeelExpressionLanguage, createFormContainer, createInjector, MarkdownModule, schemaVersion } from '@bpmn-io/form-js-viewer';
2
2
  export { schemaVersion } from '@bpmn-io/form-js-viewer';
3
3
  import Ids from 'ids';
4
4
  import { isArray, isFunction, isNumber, bind, assign, debounce, forEach, get, isObject, uniqueBy, sortBy, find, isString, set as set$1, reduce, isUndefined, without, has } from 'min-dash';
@@ -1970,6 +1970,7 @@ function Element$1(props) {
1970
1970
  const eventBus = useService$1('eventBus'),
1971
1971
  formEditor = useService$1('formEditor'),
1972
1972
  formFieldRegistry = useService$1('formFieldRegistry'),
1973
+ formFields = useService$1('formFields'),
1973
1974
  modeling = useService$1('modeling'),
1974
1975
  selection = useService$1('selection');
1975
1976
  const {
@@ -2055,6 +2056,7 @@ function Element$1(props) {
2055
2056
  field: field
2056
2057
  }), jsx(ContextPad, {
2057
2058
  children: selection.isSelected(field) && field.type !== 'default' ? jsx("button", {
2059
+ title: getRemoveButtonTitle(field, formFields),
2058
2060
  class: "fjs-context-pad-item",
2059
2061
  onClick: onRemove,
2060
2062
  children: jsx(DeleteIcon$1, {})
@@ -2375,6 +2377,13 @@ function findPaletteEntry(type, formFields) {
2375
2377
  function defaultPropertiesPanel(propertiesPanelConfig) {
2376
2378
  return !(propertiesPanelConfig && propertiesPanelConfig.parent);
2377
2379
  }
2380
+ function getRemoveButtonTitle(formField, formFields) {
2381
+ const entry = findPaletteEntry(formField.type, formFields);
2382
+ if (!entry) {
2383
+ return 'Remove form field';
2384
+ }
2385
+ return `Remove ${entry.label}`;
2386
+ }
2378
2387
 
2379
2388
  class Renderer {
2380
2389
  constructor(renderConfig, eventBus, formEditor, injector) {
@@ -4124,12 +4133,61 @@ class ValidateBehavior extends CommandInterceptor {
4124
4133
  }
4125
4134
  ValidateBehavior.$inject = ['eventBus'];
4126
4135
 
4136
+ class ValuesSourceBehavior extends CommandInterceptor {
4137
+ constructor(eventBus) {
4138
+ super(eventBus);
4139
+
4140
+ /**
4141
+ * Cleanup properties on changing the values source.
4142
+ *
4143
+ * 1) Remove other sources, e.g. set `values` => remove `valuesKey` and `valuesExpression`
4144
+ * 2) Remove default values for all other values sources
4145
+ */
4146
+ this.preExecute('formField.edit', function (context) {
4147
+ const {
4148
+ properties
4149
+ } = context;
4150
+ const newProperties = {};
4151
+ if (!isValuesSourceUpdate(properties)) {
4152
+ return;
4153
+ }
4154
+
4155
+ // clean up value sources that are not to going to be set
4156
+ Object.values(VALUES_SOURCES).forEach(source => {
4157
+ const path = VALUES_SOURCES_PATHS[source];
4158
+ if (get(properties, path) == undefined) {
4159
+ newProperties[VALUES_SOURCES_PATHS[source]] = undefined;
4160
+ }
4161
+ });
4162
+
4163
+ // clean up default value
4164
+ if (get(properties, VALUES_SOURCES_PATHS[VALUES_SOURCES.EXPRESSION]) !== undefined || get(properties, VALUES_SOURCES_PATHS[VALUES_SOURCES.INPUT]) !== undefined) {
4165
+ newProperties['defaultValue'] = undefined;
4166
+ }
4167
+ context.properties = {
4168
+ ...properties,
4169
+ ...newProperties
4170
+ };
4171
+ }, true);
4172
+ }
4173
+ }
4174
+ ValuesSourceBehavior.$inject = ['eventBus'];
4175
+
4176
+ // helper ///////////////////
4177
+
4178
+ function isValuesSourceUpdate(properties) {
4179
+ return Object.values(VALUES_SOURCES_PATHS).some(path => {
4180
+ return get(properties, path) !== undefined;
4181
+ });
4182
+ }
4183
+
4127
4184
  var behaviorModule = {
4128
- __init__: ['idBehavior', 'keyBehavior', 'pathBehavior', 'validateBehavior'],
4185
+ __init__: ['idBehavior', 'keyBehavior', 'pathBehavior', 'validateBehavior', 'valuesSourceBehavior'],
4129
4186
  idBehavior: ['type', IdBehavior],
4130
4187
  keyBehavior: ['type', KeyBehavior],
4131
4188
  pathBehavior: ['type', PathBehavior],
4132
- validateBehavior: ['type', ValidateBehavior]
4189
+ validateBehavior: ['type', ValidateBehavior],
4190
+ valuesSourceBehavior: ['type', ValuesSourceBehavior]
4133
4191
  };
4134
4192
 
4135
4193
  /**
@@ -4858,6 +4916,29 @@ FeelIcon$1.defaultProps = {
4858
4916
  fill: "none",
4859
4917
  xmlns: "http://www.w3.org/2000/svg"
4860
4918
  };
4919
+ var HelpIcon = function HelpIcon(props) {
4920
+ return jsxs("svg", {
4921
+ ...props,
4922
+ children: [jsx("path", {
4923
+ d: "M16 2a14 14 0 1 0 14 14A14 14 0 0 0 16 2Zm0 26a12 12 0 1 1 12-12 12 12 0 0 1-12 12Z"
4924
+ }), jsx("circle", {
4925
+ cx: "16",
4926
+ cy: "23.5",
4927
+ r: "1.5"
4928
+ }), jsx("path", {
4929
+ d: "M17 8h-1.5a4.49 4.49 0 0 0-4.5 4.5v.5h2v-.5a2.5 2.5 0 0 1 2.5-2.5H17a2.5 2.5 0 0 1 0 5h-2v4.5h2V17a4.5 4.5 0 0 0 0-9Z"
4930
+ }), jsx("path", {
4931
+ style: {
4932
+ fill: "none"
4933
+ },
4934
+ d: "M0 0h32v32H0z"
4935
+ })]
4936
+ });
4937
+ };
4938
+ HelpIcon.defaultProps = {
4939
+ xmlns: "http://www.w3.org/2000/svg",
4940
+ viewBox: "0 0 32 32"
4941
+ };
4861
4942
  function Header(props) {
4862
4943
  const {
4863
4944
  element,
@@ -5407,6 +5488,7 @@ function Group(props) {
5407
5488
  edited: edited,
5408
5489
  hasErrors: hasErrors
5409
5490
  }), jsx("button", {
5491
+ type: "button",
5410
5492
  title: "Toggle section",
5411
5493
  class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
5412
5494
  children: jsx(ArrowIcon, {
@@ -5587,6 +5669,7 @@ const CodeEditor$1 = forwardRef((props, ref) => {
5587
5669
  ref: inputRef,
5588
5670
  onClick: handleClick
5589
5671
  }), jsx("button", {
5672
+ type: "button",
5590
5673
  title: "Open pop-up editor",
5591
5674
  class: "bio-properties-panel-open-feel-popup",
5592
5675
  onClick: () => onPopupOpen('feelers'),
@@ -5707,6 +5790,7 @@ const CodeEditor = forwardRef((props, ref) => {
5707
5790
  ref: inputRef,
5708
5791
  onClick: handleClick
5709
5792
  }), jsx("button", {
5793
+ type: "button",
5710
5794
  title: "Open pop-up editor",
5711
5795
  class: "bio-properties-panel-open-feel-popup",
5712
5796
  onClick: () => onPopupOpen(),
@@ -5751,6 +5835,7 @@ function FeelIcon(props) {
5751
5835
  }
5752
5836
  };
5753
5837
  return jsx("button", {
5838
+ type: "button",
5754
5839
  class: classnames('bio-properties-panel-feel-icon', active ? 'active' : null, feel === 'required' ? 'required' : 'optional'),
5755
5840
  onClick: handleClick,
5756
5841
  disabled: feel === 'required' || disabled,
@@ -6197,6 +6282,12 @@ function FeelPopupComponent(props) {
6197
6282
  domNode: popupRef.current
6198
6283
  });
6199
6284
  }, []);
6285
+ useEffect(() => {
6286
+ // Set focus on editor when popup is opened
6287
+ if (editorRef.current) {
6288
+ editorRef.current.focus();
6289
+ }
6290
+ }, [editorRef]);
6200
6291
  return jsxs(Popup, {
6201
6292
  container: container,
6202
6293
  className: "bio-properties-panel-feel-popup",
@@ -6215,10 +6306,21 @@ function FeelPopupComponent(props) {
6215
6306
  height: FEEL_POPUP_HEIGHT,
6216
6307
  width: FEEL_POPUP_WIDTH,
6217
6308
  ref: popupRef,
6218
- children: [jsx(Popup.Title, {
6309
+ children: [jsxs(Popup.Title, {
6219
6310
  title: title,
6220
6311
  emit: emit,
6221
- draggable: true
6312
+ draggable: true,
6313
+ children: [type === 'feel' && jsxs("a", {
6314
+ href: "https://docs.camunda.io/docs/components/modeler/feel/what-is-feel/",
6315
+ target: "_blank",
6316
+ class: "bio-properties-panel-feel-popup__title-link",
6317
+ children: ["Learn FEEL expressions", jsx(HelpIcon, {})]
6318
+ }), type === 'feelers' && jsxs("a", {
6319
+ href: "https://docs.camunda.io/docs/components/modeler/forms/configuration/forms-config-templating-syntax/",
6320
+ target: "_blank",
6321
+ class: "bio-properties-panel-feel-popup__title-link",
6322
+ children: ["Learn templating", jsx(HelpIcon, {})]
6323
+ })]
6222
6324
  }), jsx(Popup.Body, {
6223
6325
  children: jsxs("div", {
6224
6326
  onKeyDownCapture: onKeyDownCapture,
@@ -6250,6 +6352,7 @@ function FeelPopupComponent(props) {
6250
6352
  })
6251
6353
  }), jsx(Popup.Footer, {
6252
6354
  children: jsx("button", {
6355
+ type: "button",
6253
6356
  onClick: onClose,
6254
6357
  title: "Close pop-up editor",
6255
6358
  class: "bio-properties-panel-feel-popup__close-btn",
@@ -7491,12 +7594,14 @@ function CollapsibleEntry(props) {
7491
7594
  class: classnames('bio-properties-panel-collapsible-entry-header-title', !label && 'empty'),
7492
7595
  children: label || placeholderLabel
7493
7596
  }), jsx("button", {
7597
+ type: "button",
7494
7598
  title: "Toggle list item",
7495
7599
  class: "bio-properties-panel-arrow bio-properties-panel-collapsible-entry-arrow",
7496
7600
  children: jsx(ArrowIcon, {
7497
7601
  class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
7498
7602
  })
7499
7603
  }), remove ? jsx("button", {
7604
+ type: "button",
7500
7605
  title: "Delete item",
7501
7606
  class: "bio-properties-panel-remove-entry",
7502
7607
  onClick: remove,
@@ -7698,6 +7803,7 @@ function ListGroup(props) {
7698
7803
  }), jsxs("div", {
7699
7804
  class: "bio-properties-panel-group-header-buttons",
7700
7805
  children: [add ? jsxs("button", {
7806
+ type: "button",
7701
7807
  title: "Create new list item",
7702
7808
  class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
7703
7809
  onClick: handleAddClick,
@@ -7710,6 +7816,7 @@ function ListGroup(props) {
7710
7816
  class: classnames('bio-properties-panel-list-badge', hasError ? 'bio-properties-panel-list-badge--error' : ''),
7711
7817
  children: items.length
7712
7818
  }) : null, hasItems ? jsx("button", {
7819
+ type: "button",
7713
7820
  title: "Toggle section",
7714
7821
  class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
7715
7822
  children: jsx(ArrowIcon, {
@@ -10412,11 +10519,7 @@ function ValuesSourceSelect(props) {
10412
10519
  const setValue = value => {
10413
10520
  let newField = field;
10414
10521
  const newProperties = {};
10415
- Object.values(VALUES_SOURCES).forEach(source => {
10416
- // Clear all values source definitions and default the newly selected one
10417
- const newValue = value === source ? VALUES_SOURCES_DEFAULTS[source] : undefined;
10418
- newProperties[VALUES_SOURCES_PATHS[source]] = newValue;
10419
- });
10522
+ newProperties[VALUES_SOURCES_PATHS[value]] = VALUES_SOURCES_DEFAULTS[value];
10420
10523
  newField = editField(field, newProperties);
10421
10524
  return newField;
10422
10525
  };