Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zeebe User Tasks #14

Merged
merged 4 commits into from
Mar 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 196 additions & 0 deletions lib/camunda-cloud/features/modeling/behavior/FormDefinitionBehavior.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@

import inherits from 'inherits';

import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';

import elementHelper from 'bpmn-js-properties-panel/lib/helper/ElementHelper';

import {
getBusinessObject,
is
} from 'bpmn-js/lib/util/ModelUtil';

import {
remove as collectionRemove,
add as collectionAdd
} from 'diagram-js/lib/util/Collections';

import {
createFormDefinition,
createFormId,
createFormKey,
createUserTaskForm,
getFormDefinition,
getUserTaskForm
} from '../../../helper/FormsHelper';


/**
* Zeebe specific form definition behavior.
*/
export default function FormDefinitionBehavior(
eventBus, bpmnFactory) {

CommandInterceptor.call(this, eventBus);

/**
* ensures a zeebe:userTaskForm is cleaned up when user task got removed
*/
this.executed('shape.delete', function(context) {
const {
shape,
oldParent
} = context;

const rootElement = getRootElement(oldParent);

const userTaskForm = getUserTaskForm(shape, rootElement);

const rootExtensionElements = rootElement.get('extensionElements');

if (!is(shape, 'bpmn:UserTask') || !userTaskForm) {
return;
}

collectionRemove(rootExtensionElements.get('values'), userTaskForm);

context.removedUserTaskForm = userTaskForm;
}, true);

this.revert('shape.delete', function(context) {
const {
removedUserTaskForm,
oldParent
} = context;

const rootElement = getRootElement(oldParent);

const rootExtensionElements = rootElement.get('extensionElements');

if (!removedUserTaskForm) {
return;
}

collectionAdd(rootExtensionElements.get('values'), removedUserTaskForm);
}, true);


/**
* create fresh new copied form definition + user task form
*/
this.executed('shape.create', function(context) {
const {
shape,
} = context;

const oldFormDefinition = getFormDefinition(shape);

if (!is(shape, 'bpmn:UserTask') || !oldFormDefinition) {
return;
}

const oldUserTaskForm = getUserTaskForm(shape);

const rootElement = getRootElement(shape);

const businessObject = getBusinessObject(shape);

const extensionElements = businessObject.get('extensionElements');

let rootExtensionElements = rootElement.get('extensionElements');

// (1) ensure extension elements in root
if (!rootExtensionElements) {

rootExtensionElements = elementHelper.createElement(
'bpmn:ExtensionElements',
{ values: [] },
rootElement,
bpmnFactory
);

rootElement.set('extensionElements', rootExtensionElements);
}

// (2) remove existing form definition
context.oldFormDefinition = oldFormDefinition;

collectionRemove(extensionElements.get('values'), oldFormDefinition);

const formId = createFormId();

// (3) create new form definition
const formDefinition = createFormDefinition(
{
formKey: createFormKey(formId)
},
extensionElements,
bpmnFactory
);

collectionAdd(extensionElements.get('values'), formDefinition);

// (4) create new user task form
const userTaskForm = createUserTaskForm(
{
id: formId,
body: oldUserTaskForm ? oldUserTaskForm.get('body') : ''
},
rootExtensionElements,
bpmnFactory
);

collectionAdd(rootExtensionElements.get('values'), userTaskForm);
}, true);

this.revert('shape.create', function(context) {
const {
shape,
oldFormDefinition
} = context;

const businessObject = getBusinessObject(shape);

const extensionElements = businessObject.get('extensionElements');

const formDefinition = getFormDefinition(shape);

const userTaskForm = getUserTaskForm(shape);

const rootElement = getRootElement(shape);

const rootExtensionElements = rootElement.get('extensionElements');

if (!is(shape, 'bpmn:UserTask') || !userTaskForm) {
return;
}

// we need to cover the old form definition to make <redo> possible
collectionRemove(extensionElements.get('values'), formDefinition);
collectionAdd(extensionElements.get('values'), oldFormDefinition);

collectionRemove(rootExtensionElements.get('values'), userTaskForm);
}, true);

}

FormDefinitionBehavior.$inject = [
'eventBus',
'bpmnFactory'
];

inherits(FormDefinitionBehavior, CommandInterceptor);


// helpers //////////////

function getRootElement(element) {
var businessObject = getBusinessObject(element),
parent = businessObject;

while (parent.$parent && !is(parent, 'bpmn:Process')) {
parent = parent.$parent;
}

return parent;
}
7 changes: 5 additions & 2 deletions lib/camunda-cloud/features/modeling/behavior/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import CreateZeebeBoundaryEventBehavior from './CreateZeebeBoundaryEventBehavior';
import CreateZeebeCallActivityBehavior from './CreateZeebeCallActivityBehavior';
import UpdatePropagateAllChildVariablesBehavior from './UpdatePropagateAllChildVariablesBehavior';
import FormDefinitionBehavior from './FormDefinitionBehavior';


export default {
__init__: [
'createZeebeBoundaryEventBehavior',
'createZeebeCallActivityBehavior',
'updatePropagateAllChildVariablesBehavior'
'updatePropagateAllChildVariablesBehavior',
'formDefinitionBehavior'
],
createZeebeBoundaryEventBehavior: [ 'type', CreateZeebeBoundaryEventBehavior ],
createZeebeCallActivityBehavior: [ 'type', CreateZeebeCallActivityBehavior ],
updatePropagateAllChildVariablesBehavior: [ 'type', UpdatePropagateAllChildVariablesBehavior ]
updatePropagateAllChildVariablesBehavior: [ 'type', UpdatePropagateAllChildVariablesBehavior ],
formDefinitionBehavior: [ 'type', FormDefinitionBehavior ]
};
3 changes: 2 additions & 1 deletion lib/camunda-cloud/features/popup-menu/ReplaceOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export const REPLACE_OPTIONS = [
'replace-with-non-interrupting-timer-start',
'replace-with-expanded-pool',
'replace-with-collapsed-pool',
'replace-with-call-activity'
'replace-with-call-activity',
'replace-with-user-task'
];

export const HEADER_OPTIONS = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import errorProps from './parts/ErrorProps';

import callActivityProps from './parts/CallActivityProps';

import formProps from './parts/FormProps';

import { is } from 'bpmn-js/lib/util/ModelUtil';

function getIdOptions(element) {
Expand Down Expand Up @@ -78,6 +80,21 @@ function createGeneralTabGroups(element, bpmnFactory, canvas, translate) {
];
}

function createFormsGroups(element, bpmnFactory, translate) {

const formsGroups = {
id: 'forms-properties',
label: translate('Forms'),
entries: []
};
formProps(formsGroups, element, bpmnFactory, translate);


return [
formsGroups
];
}

function createHeadersGroups(element, bpmnFactory, translate) {

const headersGroup = {
Expand Down Expand Up @@ -144,6 +161,14 @@ export default class ZeebePropertiesProvider extends PropertiesActivator {
element, this._bpmnFactory, this._canvas, this._translate)
};

const formsTab = {
id: 'forms',
label: this._translate('Forms'),
groups: createFormsGroups(
element, this._bpmnFactory, this._translate
)
};

const inputOutputTab = {
id: 'input-output',
label: this._translate('Input/Output'),
Expand All @@ -160,6 +185,7 @@ export default class ZeebePropertiesProvider extends PropertiesActivator {

return [
generalTab,
formsTab,
inputOutputTab,
headersTab
];
Expand Down
14 changes: 14 additions & 0 deletions lib/camunda-cloud/features/properties-provider/parts/FormProps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {
isAny
} from 'bpmn-js/lib/features/modeling/util/ModelingUtil';

import formDefinition from './implementation/FormDefinition';

export default function(group, element, bpmnFactory, translate) {

if (!isAny(element, [ 'bpmn:UserTask' ])) {
return;
}

group.entries = group.entries.concat(formDefinition(element, bpmnFactory, translate));
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import elementHelper from 'bpmn-js-properties-panel/lib/helper/ElementHelper';
import cmdHelper from 'bpmn-js-properties-panel/lib/helper/CmdHelper';

import {
is
} from 'bpmn-js/lib/util/ModelUtil';
isAny
} from 'bpmn-js/lib/features/modeling/util/ModelingUtil';

export default function(group, element, bpmnFactory, translate) {

if (!is(element, 'bpmn:ServiceTask')) {
if (!canHaveHeaders(element)) {
return;
}

Expand Down Expand Up @@ -38,3 +38,13 @@ export default function(group, element, bpmnFactory, translate) {
}

}


// helpers ////////////////

function canHaveHeaders(element) {
return isAny(element, [
'bpmn:ServiceTask',
'bpmn:UserTask'
]);
}
pinussilvestrus marked this conversation as resolved.
Show resolved Hide resolved
Loading