Skip to content

Commit cb3e5e8

Browse files
committed
feat: support zeebe:userTask
* deps: update to `[email protected]` * feat: support `zeebe:userTask` Related to camunda/camunda-modeler#4087 * feat: make `externalReference` FEEL-optional * deps: update to `[email protected]` * test: remove redundant tests * chore: update label
1 parent 87a7421 commit cb3e5e8

12 files changed

+764
-301
lines changed

package-lock.json

Lines changed: 26 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
"bpmn-js": "^17.0.0",
7575
"bpmn-js-create-append-anything": "^0.5.0",
7676
"bpmn-moddle": "^8.1.0",
77-
"camunda-bpmn-js-behaviors": "^1.2.2",
77+
"camunda-bpmn-js-behaviors": "^1.3.0",
7878
"camunda-bpmn-moddle": "^7.0.1",
7979
"chai": "^4.4.1",
8080
"cross-env": "^7.0.3",
@@ -105,7 +105,7 @@
105105
"sinon": "^17.0.1",
106106
"sinon-chai": "^3.7.0",
107107
"webpack": "^5.89.0",
108-
"zeebe-bpmn-moddle": "^1.0.0"
108+
"zeebe-bpmn-moddle": "^1.1.0"
109109
},
110110
"peerDependencies": {
111111
"@bpmn-io/properties-panel": ">= 3.7",

src/provider/zeebe/ZeebePropertiesProvider.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ import {
2121
TargetProps,
2222
TaskDefinitionProps,
2323
TaskScheduleProps,
24-
TimerProps
24+
TimerProps,
25+
UserTaskImplementationProps
2526
} from './properties';
2627

2728
import { ExtensionPropertiesProps } from '../shared/ExtensionPropertiesProps';
@@ -39,6 +40,7 @@ const ZEEBE_GROUPS = [
3940
CalledDecisionGroup,
4041
ScriptImplementationGroup,
4142
ScriptGroup,
43+
UserTaskImplementationGroup,
4244
TaskDefinitionGroup,
4345
AssignmentDefinitionGroup,
4446
FormGroup,
@@ -255,6 +257,19 @@ function ScriptImplementationGroup(element) {
255257
return group.entries.length ? group : null;
256258
}
257259

260+
function UserTaskImplementationGroup(element) {
261+
const group = {
262+
id: 'userTaskImplementation',
263+
label: 'Implementation',
264+
entries: [
265+
...UserTaskImplementationProps({ element })
266+
],
267+
component: Group
268+
};
269+
270+
return group.entries.length ? group : null;
271+
}
272+
258273
function AssignmentDefinitionGroup(element) {
259274
const group = {
260275
id: 'assignmentDefinition',

src/provider/zeebe/properties/FormProps.js

Lines changed: 95 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import {
1212
SelectEntry,
1313
TextFieldEntry,
1414
TextAreaEntry,
15-
isSelectEntryEdited,
15+
isFeelEntryEdited,
1616
isTextFieldEntryEdited,
1717
isTextAreaEntryEdited
1818
} from '@bpmn-io/properties-panel';
1919

20+
import { FeelEntryWithVariableContext } from '../../../entries/FeelEntryWithContext';
21+
2022
import { createElement } from '../../../utils/ElementUtil';
2123

2224
import { useService } from '../../../hooks';
@@ -28,9 +30,12 @@ import {
2830
getFormType,
2931
getRootElement,
3032
getUserTaskForm,
33+
isZeebeUserTask,
3134
userTaskFormIdToFormKey
3235
} from '../utils/FormUtil';
3336

37+
const NONE_VALUE = 'none';
38+
3439

3540
export function FormProps(props) {
3641
const { element } = props;
@@ -42,7 +47,7 @@ export function FormProps(props) {
4247
const entries = [ {
4348
id: 'formType',
4449
component: FormType,
45-
isEdited: isSelectEntryEdited
50+
isEdited: node => node.value !== NONE_VALUE
4651
} ];
4752

4853
const formType = getFormType(element);
@@ -62,9 +67,15 @@ export function FormProps(props) {
6267
} else if (formType === FORM_TYPES.CUSTOM_FORM) {
6368
entries.push({
6469
id: 'customFormKey',
65-
component: CustomFormKey,
70+
component: CustomForm,
6671
isEdited: isTextFieldEntryEdited
6772
});
73+
} else if (formType === FORM_TYPES.EXTERNAL_REFERENCE) {
74+
entries.push({
75+
id: 'externalReference',
76+
component: ExternalReference,
77+
isEdited: isFeelEntryEdited
78+
});
6879
}
6980

7081
return entries;
@@ -78,28 +89,15 @@ function FormType(props) {
7889
translate = useService('translate');
7990

8091
const getValue = () => {
81-
return getFormType(element) || '';
92+
return getFormType(element) || NONE_VALUE;
8293
};
8394

8495
const setValue = (value) => {
85-
if (value === FORM_TYPES.CAMUNDA_FORM_EMBEDDED) {
86-
setUserTaskForm(injector, element, '');
87-
} else if (value === FORM_TYPES.CAMUNDA_FORM_LINKED) {
88-
setFormId(injector, element, '');
89-
} else if (value === FORM_TYPES.CUSTOM_FORM) {
90-
setCustomFormKey(injector, element, '');
91-
} else {
92-
removeFormDefinition(injector, element);
93-
}
96+
setFormType(injector, element, value);
9497
};
9598

9699
const getOptions = () => {
97-
return [
98-
{ value: '', label: translate('<none>') },
99-
{ value: FORM_TYPES.CAMUNDA_FORM_LINKED, label: translate('Camunda Form (linked)') },
100-
{ value: FORM_TYPES.CAMUNDA_FORM_EMBEDDED, label: translate('Camunda Form (embedded)') },
101-
{ value: FORM_TYPES.CUSTOM_FORM, label: translate('Custom form key') }
102-
];
100+
return getFormTypeOptions(translate, element);
103101
};
104102

105103
return SelectEntry({
@@ -112,6 +110,37 @@ function FormType(props) {
112110
});
113111
}
114112

113+
function setFormType(injector, element, value) {
114+
if (value === FORM_TYPES.CAMUNDA_FORM_EMBEDDED) {
115+
setUserTaskForm(injector, element, '');
116+
} else if (value === FORM_TYPES.CAMUNDA_FORM_LINKED) {
117+
setFormId(injector, element, '');
118+
} else if (value === FORM_TYPES.CUSTOM_FORM) {
119+
setCustomFormKey(injector, element, '');
120+
} else if (value === FORM_TYPES.EXTERNAL_REFERENCE) {
121+
setExternalReference(injector, element, '');
122+
} else {
123+
removeFormDefinition(injector, element);
124+
}
125+
}
126+
127+
function getFormTypeOptions(translate, element) {
128+
if (isZeebeUserTask(element)) {
129+
return [
130+
{ value: NONE_VALUE, label: translate('<none>') },
131+
{ value: FORM_TYPES.CAMUNDA_FORM_LINKED, label: translate('Camunda Form') },
132+
{ value: FORM_TYPES.EXTERNAL_REFERENCE, label: translate('External form reference') }
133+
];
134+
}
135+
136+
return [
137+
{ value: NONE_VALUE, label: translate('<none>') },
138+
{ value: FORM_TYPES.CAMUNDA_FORM_LINKED, label: translate('Camunda Form (linked)') },
139+
{ value: FORM_TYPES.CAMUNDA_FORM_EMBEDDED, label: translate('Camunda Form (embedded)') },
140+
{ value: FORM_TYPES.CUSTOM_FORM, label: translate('Custom form key') }
141+
];
142+
}
143+
115144

116145
function FormConfiguration(props) {
117146
const { element } = props;
@@ -165,16 +194,16 @@ function FormId(props) {
165194
});
166195
}
167196

168-
169-
function CustomFormKey(props) {
197+
function CustomForm(props) {
170198
const { element } = props;
171199

172200
const debounce = useService('debounceInput'),
173201
injector = useService('injector'),
174202
translate = useService('translate');
175203

176204
const getValue = () => {
177-
return getFormDefinition(element).get('formKey');
205+
const formDefinition = getFormDefinition(element);
206+
return formDefinition.get('formKey');
178207
};
179208

180209
const setValue = (value) => {
@@ -184,7 +213,34 @@ function CustomFormKey(props) {
184213
return TextFieldEntry({
185214
element,
186215
id: 'customFormKey',
187-
label: translate('Form key'),
216+
label: translate('Custom form key'),
217+
getValue,
218+
setValue,
219+
debounce
220+
});
221+
}
222+
223+
function ExternalReference(props) {
224+
const { element } = props;
225+
226+
const debounce = useService('debounceInput'),
227+
injector = useService('injector'),
228+
translate = useService('translate');
229+
230+
const getValue = () => {
231+
const formDefinition = getFormDefinition(element);
232+
return formDefinition.get('externalReference');
233+
};
234+
235+
const setValue = (value) => {
236+
setExternalReference(injector, element, isUndefined(value) ? '' : value);
237+
};
238+
239+
return FeelEntryWithVariableContext({
240+
element,
241+
id: 'externalReference',
242+
label: translate('External form reference'),
243+
feel: 'optional',
188244
getValue,
189245
setValue,
190246
debounce
@@ -370,6 +426,22 @@ function setCustomFormKey(injector, element, formKey) {
370426
]);
371427
}
372428

429+
function setExternalReference(injector, element, externalReference) {
430+
let {
431+
commands,
432+
formDefinition
433+
} = getOrCreateFormDefintition(injector, element);
434+
435+
const commandStack = injector.get('commandStack');
436+
437+
commandStack.execute('properties-panel.multi-command-executor', [
438+
...commands,
439+
createUpdateModdlePropertiesCommand(element, formDefinition, {
440+
externalReference
441+
})
442+
]);
443+
}
444+
373445
function setUserTaskForm(injector, element, body) {
374446
let {
375447
commands,

0 commit comments

Comments
 (0)