camunda-bpmn-js 0.23.1 → 0.24.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.
@@ -12,6 +12,7 @@ import {
12
12
  ZeebeDescriptionProvider
13
13
  } from 'bpmn-js-properties-panel';
14
14
 
15
+ import replaceModule from './features/replace';
15
16
 
16
17
  import { commonModdleExtensions, commonModules } from './util/commonModules';
17
18
 
@@ -44,7 +45,8 @@ Modeler.prototype._camundaCloudModules = [
44
45
  behaviorsModule,
45
46
  rulesModule,
46
47
  zeebePropertiesProviderModule,
47
- cloudElementTemplatesPropertiesProvider
48
+ cloudElementTemplatesPropertiesProvider,
49
+ replaceModule
48
50
  ];
49
51
 
50
52
  Modeler.prototype._modules = [].concat(
@@ -0,0 +1,256 @@
1
+ import {
2
+ isDifferentType
3
+ } from 'bpmn-js/lib/features/popup-menu/util/TypeUtil';
4
+
5
+ import {
6
+ getBusinessObject,
7
+ isAny
8
+ } from 'bpmn-js/lib/util/ModelUtil';
9
+
10
+ import {
11
+ getReplaceOptionGroups
12
+ } from './ReplaceOptionsUtil';
13
+
14
+ /**
15
+ * A replace menu provider that allows to replace elements with
16
+ * element templates.
17
+ */
18
+ export default function ElementTemplatesReplaceProvider(config, popupMenu, translate, elementTemplates) {
19
+
20
+ this._popupMenu = popupMenu;
21
+ this._translate = translate;
22
+ this._elementTemplates = elementTemplates;
23
+
24
+ const enabled = config && config.enabled;
25
+
26
+ if (enabled) {
27
+ this.register();
28
+ }
29
+ }
30
+
31
+ ElementTemplatesReplaceProvider.$inject = [
32
+ 'config.elementTemplatesReplaceProvider',
33
+ 'popupMenu',
34
+ 'translate',
35
+ 'elementTemplates'
36
+ ];
37
+
38
+ /**
39
+ * Register replace menu provider in the popup menu
40
+ */
41
+ ElementTemplatesReplaceProvider.prototype.register = function() {
42
+ this._popupMenu.registerProvider('bpmn-replace', this);
43
+ };
44
+
45
+ /**
46
+ * Adds the element templates to the replace menu.
47
+ * @param {djs.model.Base} element
48
+ *
49
+ * @returns {Object}
50
+ */
51
+ ElementTemplatesReplaceProvider.prototype.getPopupMenuEntries = function(element) {
52
+
53
+ return (entries) => {
54
+
55
+ // convert our entries into something sortable
56
+ let entrySet = Object.entries(entries);
57
+
58
+ if (this._elementTemplates.get(element)) {
59
+
60
+ // add unlink template option
61
+ this._addPlainElementEntry(element, entrySet);
62
+ }
63
+
64
+ // add template entries
65
+ entrySet = [ ...entrySet, ...this.getTemplateEntries(element) ];
66
+
67
+ // convert back to object
68
+ return entrySet.reduce((entries, [ key, value ]) => {
69
+ entries[key] = value;
70
+
71
+ return entries;
72
+ }, {});
73
+ };
74
+ };
75
+
76
+ /**
77
+ * Adds the option to replace with plain element (unlink template).
78
+ *
79
+ * @param {djs.model.Base} element
80
+ * @param {Array<Object>} entries
81
+ */
82
+ ElementTemplatesReplaceProvider.prototype._addPlainElementEntry = function(element, entries) {
83
+
84
+ const replaceOption = this._getPlainEntry(element, entries);
85
+
86
+ if (!replaceOption) {
87
+ return;
88
+ }
89
+
90
+ const [
91
+ insertIndex,
92
+ entry
93
+ ] = replaceOption;
94
+
95
+ // insert unlink entry
96
+ entries.splice(insertIndex, 0, [ entry.id, entry ]);
97
+ };
98
+
99
+ /**
100
+ * Returns the option to replace with plain element and the index where it should be inserted.
101
+ *
102
+ * @param {djs.model.Base} element
103
+ * @param {Array<Object>} entries
104
+ *
105
+ * @returns {Array<Object, number>}
106
+ */
107
+ ElementTemplatesReplaceProvider.prototype._getPlainEntry = function(element, entries) {
108
+
109
+ const {
110
+ options,
111
+ option,
112
+ optionIndex
113
+ } = findReplaceOptions(element) || { };
114
+
115
+ if (!options) {
116
+ return null;
117
+ }
118
+
119
+ const entry = {
120
+ id: 'replace-unlink-element-template',
121
+ action: () => {
122
+ this._elementTemplates.applyTemplate(element, null);
123
+ },
124
+ label: this._translate(option.label),
125
+ className: option.className
126
+ };
127
+
128
+ // insert after previous option, if it exists
129
+ const previousIndex = getOptionIndex(options, optionIndex - 1, entries);
130
+
131
+ if (previousIndex) {
132
+ return [
133
+ previousIndex + 1,
134
+ entry
135
+ ];
136
+ }
137
+
138
+ // insert before next option, if it exists
139
+ const nextIndex = getOptionIndex(options, optionIndex + 1, entries);
140
+
141
+ if (nextIndex) {
142
+ return [
143
+ nextIndex,
144
+ entry
145
+ ];
146
+ }
147
+
148
+ // fallback to insert at start
149
+ return [
150
+ 0,
151
+ entry
152
+ ];
153
+ };
154
+
155
+ /**
156
+ * Get all element templates that can be used to replace the given element.
157
+ *
158
+ * @param {djs.model.Base} element
159
+ *
160
+ * @return {Array<Object>} a list of element templates as menu entries
161
+ */
162
+ ElementTemplatesReplaceProvider.prototype.getTemplateEntries = function(element) {
163
+
164
+ const templates = this._getMatchingTemplates(element);
165
+ return templates.map(template => {
166
+
167
+ const {
168
+ icon = {},
169
+ category,
170
+ } = template;
171
+
172
+ const entryId = `replace.template-${template.id}`;
173
+
174
+ const defaultGroup = {
175
+ id: 'templates',
176
+ name: this._translate('Templates')
177
+ };
178
+
179
+ return [ entryId, {
180
+ name: template.name,
181
+ description: template.description,
182
+ documentationRef: template.documentationRef,
183
+ imageUrl: icon.contents,
184
+ group: category || defaultGroup,
185
+ action: () => {
186
+ this._elementTemplates.applyTemplate(element, template);
187
+ }
188
+ } ];
189
+ });
190
+ };
191
+
192
+ /**
193
+ * Returns the templates that can the element can be replaced with.
194
+ *
195
+ * @param {djs.model.Base} element
196
+ *
197
+ * @return {Array<ElementTemplate>}
198
+ */
199
+ ElementTemplatesReplaceProvider.prototype._getMatchingTemplates = function(element) {
200
+ return this._elementTemplates.getLatest().filter(template => {
201
+ return isAny(element, template.appliesTo) && !isTemplateApplied(element, template);
202
+ });
203
+ };
204
+
205
+
206
+ // helpers ////////////
207
+ export function isTemplateApplied(element, template) {
208
+ const businessObject = getBusinessObject(element);
209
+
210
+ if (businessObject) {
211
+ return businessObject.get('zeebe:modelerTemplate') === template.id;
212
+ }
213
+
214
+ return false;
215
+ }
216
+
217
+ function getOptionIndex(options, index, entries) {
218
+ const option = options[index];
219
+
220
+ if (!option) {
221
+ return false;
222
+ }
223
+
224
+ return entries.findIndex(
225
+ ([ key ]) => key === option.actionName
226
+ );
227
+ }
228
+
229
+ /**
230
+ * @param {ModdleElement} element
231
+ *
232
+ * @return { { options: Array<any>, option: any, optionIndex: number } | null }
233
+ */
234
+ function findReplaceOptions(element) {
235
+
236
+ const isSameType = (element, option) => option.target && !isDifferentType(element)(option);
237
+
238
+ return getReplaceOptionGroups().reduce((result, options) => {
239
+
240
+ if (result) {
241
+ return result;
242
+ }
243
+
244
+ const optionIndex = options.findIndex(option => isSameType(element, option));
245
+
246
+ if (optionIndex === -1) {
247
+ return;
248
+ }
249
+
250
+ return {
251
+ options,
252
+ option: options[optionIndex],
253
+ optionIndex
254
+ };
255
+ }, null);
256
+ }
@@ -0,0 +1,7 @@
1
+ import * as replaceOptions from 'bpmn-js/lib/features/replace/ReplaceOptions';
2
+
3
+ const ALL_OPTIONS = Object.values(replaceOptions);
4
+
5
+ export function getReplaceOptionGroups() {
6
+ return ALL_OPTIONS;
7
+ }
@@ -0,0 +1,6 @@
1
+ import ElementTemplatesReplaceProvider from './ElementTemplatesReplaceProvider';
2
+
3
+ export default {
4
+ __init__: [ 'elementTemplatesProvider' ],
5
+ elementTemplatesProvider: [ 'type', ElementTemplatesReplaceProvider ]
6
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camunda-bpmn-js",
3
- "version": "0.23.1",
3
+ "version": "0.24.1",
4
4
  "description": "Embeddable Camunda modeling distributions based on bpmn-js",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -47,33 +47,36 @@
47
47
  "dependencies": {
48
48
  "@bpmn-io/align-to-origin": "^0.7.0",
49
49
  "@bpmn-io/element-templates-icons-renderer": "^0.3.0",
50
- "bpmn-js": "^10.3.0",
50
+ "bpmn-js": "^11.0.5",
51
51
  "bpmn-js-executable-fix": "^0.2.0",
52
52
  "camunda-bpmn-js-behaviors": "^0.4.0",
53
53
  "camunda-bpmn-moddle": "^7.0.1",
54
- "diagram-js": "^10.0.0",
54
+ "diagram-js": "^11.1.1",
55
55
  "diagram-js-minimap": "^3.0.0",
56
- "diagram-js-origin": "^1.3.4",
56
+ "diagram-js-origin": "^1.4.0",
57
57
  "inherits": "^2.0.4",
58
58
  "min-dash": "^4.0.0",
59
- "zeebe-bpmn-moddle": "^0.16.0"
59
+ "zeebe-bpmn-moddle": "^0.17.0"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@babel/core": "^7.18.13",
63
63
  "@bpmn-io/element-template-chooser": "^0.1.0",
64
- "@bpmn-io/properties-panel": "^0.24.0",
64
+ "@bpmn-io/properties-panel": "^1.0.1",
65
65
  "@rollup/plugin-commonjs": "^23.0.0",
66
66
  "@rollup/plugin-json": "^4.1.0",
67
67
  "@rollup/plugin-node-resolve": "^14.0.0",
68
68
  "babel-loader": "^9.0.0",
69
69
  "babel-plugin-istanbul": "^6.1.1",
70
- "bpmn-js-properties-panel": "^1.11.2",
71
- "chai": "^4.3.6",
70
+ "bpmn-js-connectors-extension": "^0.4.5",
71
+ "bpmn-js-properties-panel": "^1.12.0",
72
+ "chai": "^4.3.7",
72
73
  "cross-env": "^7.0.3",
73
74
  "del-cli": "^5.0.0",
75
+ "downloadjs": "^1.4.7",
74
76
  "eslint": "^8.24.0",
75
77
  "eslint-plugin-bpmn-io": "^0.16.0",
76
78
  "execa": "^5.0.0",
79
+ "file-drops": "^0.5.0",
77
80
  "karma": "^6.4.1",
78
81
  "karma-chai": "^0.1.0",
79
82
  "karma-chrome-launcher": "^3.1.1",
@@ -86,20 +89,20 @@
86
89
  "karma-sinon-chai": "^2.0.2",
87
90
  "karma-webpack": "^5.0.0",
88
91
  "min-dom": "^4.0.3",
89
- "mocha": "^10.0.0",
92
+ "mocha": "^10.1.0",
90
93
  "mocha-test-container-support": "^0.2.0",
91
94
  "npm-run-all": "^4.1.5",
92
- "puppeteer": "^19.0.0",
95
+ "puppeteer": "^19.3.0",
93
96
  "raw-loader": "^4.0.2",
94
97
  "rollup": "^2.38.4",
95
98
  "rollup-plugin-copy": "^3.3.0",
96
99
  "rollup-plugin-terser": "^7.0.2",
97
- "sinon": "^14.0.0",
100
+ "sinon": "^15.0.0",
98
101
  "sinon-chai": "^3.7.0",
99
102
  "webpack": "^5.74.0"
100
103
  },
101
104
  "peerDependencies": {
102
- "bpmn-js-properties-panel": ">= 1.11.1"
105
+ "bpmn-js-properties-panel": ">= 1.11.3"
103
106
  },
104
107
  "files": [
105
108
  "dist",