@bpmn-io/form-js-editor 1.12.0 → 1.13.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.cjs CHANGED
@@ -1202,7 +1202,37 @@ EditorExpressionField.config = {
1202
1202
  escapeGridRender: false
1203
1203
  };
1204
1204
 
1205
- const editorFormFields = [EditorIFrame, EditorText, EditorHtml, EditorTable, EditorExpressionField];
1205
+ function EditorDocumentPreview(props) {
1206
+ const {
1207
+ field,
1208
+ domId
1209
+ } = props;
1210
+ const {
1211
+ label
1212
+ } = field;
1213
+ const Icon = formJsViewer.iconsByType(field.type);
1214
+ return jsxRuntime.jsxs("div", {
1215
+ class: editorFormFieldClasses(field.type),
1216
+ children: [jsxRuntime.jsx(formJsViewer.Label, {
1217
+ id: domId,
1218
+ label: label
1219
+ }), jsxRuntime.jsx("div", {
1220
+ class: "fjs-documentPreview-placeholder",
1221
+ id: domId,
1222
+ children: jsxRuntime.jsxs("p", {
1223
+ class: "fjs-documentPreview-placeholder-text",
1224
+ children: [jsxRuntime.jsx(Icon, {
1225
+ width: "32",
1226
+ height: "24",
1227
+ viewBox: "0 0 56 56"
1228
+ }), "Document preview"]
1229
+ })
1230
+ })]
1231
+ });
1232
+ }
1233
+ EditorDocumentPreview.config = formJsViewer.DocumentPreview.config;
1234
+
1235
+ const editorFormFields = [EditorIFrame, EditorText, EditorHtml, EditorTable, EditorExpressionField, EditorDocumentPreview];
1206
1236
 
1207
1237
  class EditorFormFields extends formJsViewer.FormFields {
1208
1238
  constructor() {
@@ -9499,7 +9529,7 @@ function isProhibitedPath(path) {
9499
9529
  const prohibitedSegments = ['__proto__', 'prototype', 'constructor'];
9500
9530
  return path.split('.').some(segment => prohibitedSegments.includes(segment));
9501
9531
  }
9502
- const LABELED_NON_INPUTS = ['button', 'group', 'dynamiclist', 'iframe', 'table'];
9532
+ const LABELED_NON_INPUTS = ['button', 'group', 'dynamiclist', 'iframe', 'table', 'documentPreview'];
9503
9533
  const INPUTS = ['checkbox', 'checklist', 'datetime', 'number', 'radio', 'select', 'taglist', 'textfield', 'textarea', 'filepicker'];
9504
9534
  const OPTIONS_INPUTS = ['checklist', 'radio', 'select', 'taglist'];
9505
9535
  function hasEntryConfigured(formFieldDefinition, entryId) {
@@ -10346,7 +10376,7 @@ function LabelEntry(props) {
10346
10376
  return field.type === 'datetime' && (field.subtype === formJsViewer.DATETIME_SUBTYPES.TIME || field.subtype === formJsViewer.DATETIME_SUBTYPES.DATETIME);
10347
10377
  }
10348
10378
  });
10349
- const isSimplyLabled = field => {
10379
+ const isSimplyLabeled = field => {
10350
10380
  return [...INPUTS.filter(input => input !== 'datetime'), ...LABELED_NON_INPUTS].includes(field.type);
10351
10381
  };
10352
10382
  entries.push({
@@ -10355,7 +10385,7 @@ function LabelEntry(props) {
10355
10385
  editField,
10356
10386
  field,
10357
10387
  isEdited: isEdited$6,
10358
- isDefaultVisible: isSimplyLabled
10388
+ isDefaultVisible: isSimplyLabeled
10359
10389
  });
10360
10390
  return entries;
10361
10391
  }
@@ -10459,6 +10489,7 @@ function getLabelText(type) {
10459
10489
  case 'table':
10460
10490
  return 'Table label';
10461
10491
  case 'iframe':
10492
+ case 'documentPreview':
10462
10493
  return 'Title';
10463
10494
  default:
10464
10495
  return 'Field label';
@@ -10515,7 +10546,7 @@ function Height(props) {
10515
10546
  id,
10516
10547
  getValue,
10517
10548
  setValue,
10518
- validate: validate$7
10549
+ validate: validate$a
10519
10550
  });
10520
10551
  }
10521
10552
 
@@ -10525,7 +10556,7 @@ function Height(props) {
10525
10556
  * @param {number|void} value
10526
10557
  * @returns {string|null}
10527
10558
  */
10528
- const validate$7 = value => {
10559
+ const validate$a = value => {
10529
10560
  if (typeof value !== 'number') {
10530
10561
  return 'A number is required.';
10531
10562
  }
@@ -10590,7 +10621,7 @@ function Url(props) {
10590
10621
  setValue,
10591
10622
  singleLine: true,
10592
10623
  tooltip: getTooltip$1(),
10593
- validate: validate$6,
10624
+ validate: validate$9,
10594
10625
  variables
10595
10626
  });
10596
10627
  }
@@ -10617,7 +10648,7 @@ function getTooltip$1() {
10617
10648
  * @param {string|void} value
10618
10649
  * @returns {string|null}
10619
10650
  */
10620
- const validate$6 = value => {
10651
+ const validate$9 = value => {
10621
10652
  if (!value || value.startsWith('=')) {
10622
10653
  return;
10623
10654
  }
@@ -10708,7 +10739,7 @@ function Text(props) {
10708
10739
  };
10709
10740
  return FeelTemplatingEntry({
10710
10741
  debounce,
10711
- description: description$2,
10742
+ description: description$4,
10712
10743
  element: field,
10713
10744
  getValue,
10714
10745
  id,
@@ -10718,7 +10749,7 @@ function Text(props) {
10718
10749
  variables
10719
10750
  });
10720
10751
  }
10721
- const description$2 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
10752
+ const description$4 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
10722
10753
  children: ["Supports markdown and templating.", ' ', jsxRuntime.jsx("a", {
10723
10754
  href: "https://docs.camunda.io/docs/components/modeler/forms/form-element-library/forms-element-library-text/",
10724
10755
  target: "_blank",
@@ -10760,13 +10791,13 @@ function Content(props) {
10760
10791
  };
10761
10792
  return FeelTemplatingEntry({
10762
10793
  debounce,
10763
- description: description$1,
10794
+ description: description$3,
10764
10795
  element: field,
10765
10796
  getValue,
10766
10797
  id,
10767
10798
  label: 'Content',
10768
10799
  hostLanguage: 'html',
10769
- validate: validate$5,
10800
+ validate: validate$8,
10770
10801
  setValue,
10771
10802
  variables
10772
10803
  });
@@ -10774,7 +10805,7 @@ function Content(props) {
10774
10805
 
10775
10806
  // helpers //////////
10776
10807
 
10777
- const description$1 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
10808
+ const description$3 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
10778
10809
  children: ["Supports HTML, styling, and templating. Styles are automatically scoped to the HTML component.", ' ', jsxRuntime.jsx("a", {
10779
10810
  href: "https://docs.camunda.io/docs/components/modeler/forms/form-element-library/forms-element-library-html/",
10780
10811
  target: "_blank",
@@ -10786,7 +10817,7 @@ const description$1 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
10786
10817
  * @param {string|void} value
10787
10818
  * @returns {string|null}
10788
10819
  */
10789
- const validate$5 = value => {
10820
+ const validate$8 = value => {
10790
10821
  // allow empty state
10791
10822
  if (typeof value !== 'string' || value === '') {
10792
10823
  return null;
@@ -11625,7 +11656,7 @@ function InputValuesKey(props) {
11625
11656
  id,
11626
11657
  label: 'Input values key',
11627
11658
  setValue,
11628
- validate: validate$4
11659
+ validate: validate$7
11629
11660
  });
11630
11661
  }
11631
11662
 
@@ -11635,7 +11666,7 @@ function InputValuesKey(props) {
11635
11666
  * @param {string|void} value
11636
11667
  * @returns {string|null}
11637
11668
  */
11638
- const validate$4 = value => {
11669
+ const validate$7 = value => {
11639
11670
  if (typeof value !== 'string' || value.length === 0) {
11640
11671
  return 'Must not be empty.';
11641
11672
  }
@@ -12078,7 +12109,7 @@ function Source(props) {
12078
12109
  setValue,
12079
12110
  singleLine: true,
12080
12111
  variables,
12081
- validate: validate$3
12112
+ validate: validate$6
12082
12113
  });
12083
12114
  }
12084
12115
 
@@ -12088,7 +12119,7 @@ function Source(props) {
12088
12119
  * @param {string|void} value
12089
12120
  * @returns {string|null}
12090
12121
  */
12091
- const validate$3 = value => {
12122
+ const validate$6 = value => {
12092
12123
  if (!minDash.isString(value) || value.length === 0) {
12093
12124
  return 'Must not be empty.';
12094
12125
  }
@@ -12192,7 +12223,7 @@ function RowCount(props) {
12192
12223
  id,
12193
12224
  getValue,
12194
12225
  setValue,
12195
- validate: validate$2
12226
+ validate: validate$5
12196
12227
  });
12197
12228
  }
12198
12229
 
@@ -12202,7 +12233,7 @@ function RowCount(props) {
12202
12233
  * @param {string|void} value
12203
12234
  * @returns {string|null}
12204
12235
  */
12205
- const validate$2 = value => {
12236
+ const validate$5 = value => {
12206
12237
  if (minDash.isNil(value)) {
12207
12238
  return null;
12208
12239
  }
@@ -12376,7 +12407,7 @@ function ColumnsExpression(props) {
12376
12407
  setValue,
12377
12408
  singleLine: true,
12378
12409
  variables,
12379
- validate: validate$1
12410
+ validate: validate$4
12380
12411
  });
12381
12412
  }
12382
12413
 
@@ -12386,7 +12417,7 @@ function ColumnsExpression(props) {
12386
12417
  * @param {string|void} value
12387
12418
  * @returns {string|null}
12388
12419
  */
12389
- const validate$1 = value => {
12420
+ const validate$4 = value => {
12390
12421
  if (!minDash.isString(value) || value.length === 0 || value === '=') {
12391
12422
  return 'Must not be empty.';
12392
12423
  }
@@ -12484,7 +12515,7 @@ function Key(props) {
12484
12515
  id,
12485
12516
  label: 'Key',
12486
12517
  setValue,
12487
- validate
12518
+ validate: validate$3
12488
12519
  });
12489
12520
  }
12490
12521
 
@@ -12494,7 +12525,7 @@ function Key(props) {
12494
12525
  * @param {string|void} value
12495
12526
  * @returns {string|null}
12496
12527
  */
12497
- function validate(value) {
12528
+ function validate$3(value) {
12498
12529
  if (!minDash.isString(value) || value.length === 0) {
12499
12530
  return 'Must not be empty.';
12500
12531
  }
@@ -12632,13 +12663,13 @@ function Accept(props) {
12632
12663
  singleLine: true,
12633
12664
  setValue,
12634
12665
  variables,
12635
- description
12666
+ description: description$2
12636
12667
  });
12637
12668
  }
12638
12669
 
12639
12670
  // helpers //////////
12640
12671
 
12641
- const description = jsxRuntime.jsxs(jsxRuntime.Fragment, {
12672
+ const description$2 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
12642
12673
  children: ["A comma-separated list of", ' ', jsxRuntime.jsx("a", {
12643
12674
  href: "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers",
12644
12675
  target: "_blank",
@@ -12692,6 +12723,236 @@ function Multiple(props) {
12692
12723
  });
12693
12724
  }
12694
12725
 
12726
+ function DocumentsDataSourceEntry(props) {
12727
+ const {
12728
+ editField,
12729
+ field
12730
+ } = props;
12731
+ const entries = [];
12732
+ entries.push({
12733
+ id: 'dataSource',
12734
+ component: DocumentsDataSource,
12735
+ editField: editField,
12736
+ field: field,
12737
+ isEdited: isEdited$6,
12738
+ isDefaultVisible: field => field.type === 'documentPreview'
12739
+ });
12740
+ return entries;
12741
+ }
12742
+ function DocumentsDataSource(props) {
12743
+ const {
12744
+ editField,
12745
+ field,
12746
+ id
12747
+ } = props;
12748
+ const debounce = useService('debounce');
12749
+ const variables = useVariables().map(name => ({
12750
+ name
12751
+ }));
12752
+ const path = ['dataSource'];
12753
+ const getValue = () => {
12754
+ return minDash.get(field, path, '');
12755
+ };
12756
+ const setValue = value => {
12757
+ return editField(field, path, value);
12758
+ };
12759
+ const schema = `[
12760
+ {
12761
+ "documentId": "u123",
12762
+ "metadata": {
12763
+ "fileName": "Document.pdf",
12764
+ "contentType": "application/pdf"
12765
+ }
12766
+ }
12767
+ ]`;
12768
+ const tooltip = jsxRuntime.jsxs("div", {
12769
+ children: [jsxRuntime.jsx("p", {
12770
+ children: "A source is a JSON object containing metadata for a document or an array of documents."
12771
+ }), jsxRuntime.jsx("p", {
12772
+ children: "Each entry must include a document ID, name, and MIME type."
12773
+ }), jsxRuntime.jsx("p", {
12774
+ children: "Additional details are optional. The expected format is as follows:"
12775
+ }), jsxRuntime.jsx("pre", {
12776
+ children: jsxRuntime.jsx("code", {
12777
+ children: schema
12778
+ })
12779
+ })]
12780
+ });
12781
+ return FeelTemplatingEntry({
12782
+ debounce,
12783
+ element: field,
12784
+ getValue,
12785
+ id,
12786
+ label: 'Document reference',
12787
+ feel: 'required',
12788
+ singleLine: true,
12789
+ setValue,
12790
+ variables,
12791
+ tooltip,
12792
+ validate: validate$2
12793
+ });
12794
+ }
12795
+
12796
+ // helpers //////////
12797
+
12798
+ /**
12799
+ * @param {string|undefined} value
12800
+ * @returns {string|null}
12801
+ */
12802
+ const validate$2 = value => {
12803
+ if (typeof value !== 'string' || value.length === 0) {
12804
+ return 'The document data source is required.';
12805
+ }
12806
+ };
12807
+
12808
+ function EndpointKeyEntry(props) {
12809
+ const {
12810
+ editField,
12811
+ field
12812
+ } = props;
12813
+ const entries = [];
12814
+ entries.push({
12815
+ id: 'endpointKey',
12816
+ component: EndpointKey,
12817
+ editField: editField,
12818
+ field: field,
12819
+ isEdited: isEdited$6,
12820
+ isDefaultVisible: field => field.type === 'documentPreview'
12821
+ });
12822
+ return entries;
12823
+ }
12824
+ function EndpointKey(props) {
12825
+ const {
12826
+ editField,
12827
+ field,
12828
+ id
12829
+ } = props;
12830
+ const debounce = useService('debounce');
12831
+ const variables = useVariables().map(name => ({
12832
+ name
12833
+ }));
12834
+ const path = ['endpointKey'];
12835
+ const getValue = () => {
12836
+ return minDash.get(field, path, '');
12837
+ };
12838
+ const setValue = value => {
12839
+ return editField(field, path, value);
12840
+ };
12841
+ const tooltip = jsxRuntime.jsxs("div", {
12842
+ children: [jsxRuntime.jsx("p", {
12843
+ children: "Enter a context key that generates a string with the API endpoint to download a document."
12844
+ }), jsxRuntime.jsxs("p", {
12845
+ children: ["The string must contain ", jsxRuntime.jsx("code", {
12846
+ children: '{ documentId }'
12847
+ }), ", which will be replaced with the document ID from the document's reference."]
12848
+ }), jsxRuntime.jsx("p", {
12849
+ children: "If you're using the Camunda Tasklist, this variable is automatically added to the context for you."
12850
+ }), jsxRuntime.jsxs("p", {
12851
+ children: ["For more details, see the", ' ', jsxRuntime.jsx("a", {
12852
+ href: "https://docs.camunda.io/docs/next/components/modeler/forms/form-element-library/forms-element-library-document-preview/",
12853
+ rel: "noopener noreferrer",
12854
+ target: "_blank",
12855
+ children: "Camunda documentation"
12856
+ })]
12857
+ })]
12858
+ });
12859
+ return FeelTemplatingEntry({
12860
+ debounce,
12861
+ element: field,
12862
+ getValue,
12863
+ id,
12864
+ label: 'Document URL',
12865
+ feel: 'required',
12866
+ singleLine: true,
12867
+ setValue,
12868
+ variables,
12869
+ description: description$1,
12870
+ tooltip,
12871
+ validate: validate$1
12872
+ });
12873
+ }
12874
+
12875
+ // helpers //////////
12876
+
12877
+ /**
12878
+ * @param {string|undefined} value
12879
+ * @returns {string|null}
12880
+ */
12881
+ const validate$1 = value => {
12882
+ if (typeof value !== 'string' || value.length === 0) {
12883
+ return 'The document reference is required.';
12884
+ }
12885
+ };
12886
+ const description$1 = jsxRuntime.jsx(jsxRuntime.Fragment, {
12887
+ children: "Define an API URL for downloading a document"
12888
+ });
12889
+
12890
+ function MaxHeightEntry(props) {
12891
+ const {
12892
+ editField,
12893
+ field
12894
+ } = props;
12895
+ const entries = [];
12896
+ entries.push({
12897
+ id: 'maxHeight',
12898
+ component: MaxHeight,
12899
+ editField: editField,
12900
+ field: field,
12901
+ isEdited: isEdited$7,
12902
+ isDefaultVisible: field => field.type === 'documentPreview'
12903
+ });
12904
+ return entries;
12905
+ }
12906
+ function MaxHeight(props) {
12907
+ const {
12908
+ editField,
12909
+ field,
12910
+ id
12911
+ } = props;
12912
+ const debounce = useService('debounce');
12913
+ const path = ['maxHeight'];
12914
+ const getValue = () => {
12915
+ return minDash.get(field, path, '');
12916
+ };
12917
+ const setValue = value => {
12918
+ return editField(field, path, value);
12919
+ };
12920
+ return NumberFieldEntry({
12921
+ debounce,
12922
+ label: 'Max height of preview container',
12923
+ element: field,
12924
+ id,
12925
+ getValue,
12926
+ setValue,
12927
+ validate,
12928
+ description
12929
+ });
12930
+ }
12931
+
12932
+ // helpers //////////
12933
+
12934
+ /**
12935
+ * @param {string|number|undefined} value
12936
+ * @returns {string|null}
12937
+ */
12938
+ const validate = value => {
12939
+ if (value === undefined || value === '') {
12940
+ return null;
12941
+ }
12942
+ if (typeof value === 'string') {
12943
+ return 'Value must be a number.';
12944
+ }
12945
+ if (!Number.isInteger(value)) {
12946
+ return 'Should be an integer.';
12947
+ }
12948
+ if (value < 1) {
12949
+ return 'Should be greater than zero.';
12950
+ }
12951
+ };
12952
+ const description = jsxRuntime.jsx(jsxRuntime.Fragment, {
12953
+ children: "Documents with height that exceeds the defined value will be vertically scrollable"
12954
+ });
12955
+
12695
12956
  function GeneralGroup(field, editField, getService) {
12696
12957
  const entries = [...IdEntry({
12697
12958
  field,
@@ -12779,6 +13040,9 @@ function GeneralGroup(field, editField, getService) {
12779
13040
  }), ...RowCountEntry({
12780
13041
  field,
12781
13042
  editField
13043
+ }), ...DocumentsDataSourceEntry({
13044
+ field,
13045
+ editField
12782
13046
  })];
12783
13047
  if (entries.length === 0) {
12784
13048
  return null;
@@ -13236,6 +13500,9 @@ function AppearanceGroup(field, editField, getService) {
13236
13500
  }), ...LayouterAppearanceEntry({
13237
13501
  field,
13238
13502
  editField
13503
+ }), ...MaxHeightEntry({
13504
+ field,
13505
+ editField
13239
13506
  })];
13240
13507
  if (!entries.length) {
13241
13508
  return null;
@@ -13404,6 +13671,21 @@ const TOOLTIP_TEXT = `"List of items" defines a constant, predefined set of form
13404
13671
  "Expression" defines options that are populated from a FEEL expression.
13405
13672
  `;
13406
13673
 
13674
+ function DownloadSettings(field, editField) {
13675
+ const entries = [...EndpointKeyEntry({
13676
+ field,
13677
+ editField
13678
+ })];
13679
+ if (!entries.length) {
13680
+ return null;
13681
+ }
13682
+ return {
13683
+ id: 'downloadSettings',
13684
+ label: 'Download settings',
13685
+ entries
13686
+ };
13687
+ }
13688
+
13407
13689
  class PropertiesProvider {
13408
13690
  constructor(propertiesPanel, injector) {
13409
13691
  this._injector = injector;
@@ -13439,7 +13721,7 @@ class PropertiesProvider {
13439
13721
  return groups;
13440
13722
  }
13441
13723
  const getService = (type, strict = true) => this._injector.get(type, strict);
13442
- groups = [...groups, GeneralGroup(field, editField, getService), ...OptionsGroups(field, editField, getService), ...TableHeaderGroups(field, editField), SecurityAttributesGroup(field, editField), ConditionGroup(field, editField), LayoutGroup(field, editField), AppearanceGroup(field, editField), SerializationGroup(field, editField), ConstraintsGroup(field, editField), ValidationGroup(field, editField), CustomPropertiesGroup(field, editField)].filter(group => group != null);
13724
+ groups = [...groups, GeneralGroup(field, editField, getService), DownloadSettings(field, editField), ...OptionsGroups(field, editField, getService), ...TableHeaderGroups(field, editField), SecurityAttributesGroup(field, editField), ConditionGroup(field, editField), LayoutGroup(field, editField), AppearanceGroup(field, editField), SerializationGroup(field, editField), ConstraintsGroup(field, editField), ValidationGroup(field, editField), CustomPropertiesGroup(field, editField)].filter(group => group != null);
13443
13725
  this._filterVisibleEntries(groups, field, getService);
13444
13726
 
13445
13727
  // contract: if a group has no entries or items, it should not be displayed at all