'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'), eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'), utils = require('../../../../Utils'); var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is; var forEach = require('lodash/forEach'), find = require('lodash/find'), filter = require('lodash/filter'); function getContainedActivities(element) { return getFlowElements(element, 'bpmn:Activity'); } function getContainedBoundaryEvents(element) { return getFlowElements(element, 'bpmn:BoundaryEvent'); } function getFlowElements(element, type) { return utils.filterElementsByType(element.flowElements, type); } function isCompensationEventAttachedToActivity(activity, boundaryEvents) { var activityId = activity.id; var boundaryEvent = find(boundaryEvents, function(boundaryEvent) { var compensateEventDefinition = eventDefinitionHelper.getCompensateEventDefinition(boundaryEvent); var attachedToRef = boundaryEvent.attachedToRef; return compensateEventDefinition && attachedToRef && attachedToRef.id === activityId; }); return !!boundaryEvent; } // subprocess: only when it is not triggeredByEvent // activity: only when it attach a compensation boundary event // callActivity: no limitation function canActivityBeCompensated(activity, boundaryEvents) { return (is(activity, 'bpmn:SubProcess') && !activity.triggeredByEvent) || is(activity, 'bpmn:CallActivity') || isCompensationEventAttachedToActivity(activity, boundaryEvents); } function getActivitiesForCompensation(element) { var boundaryEvents = getContainedBoundaryEvents(element); return filter(getContainedActivities(element), function(activity) { return canActivityBeCompensated(activity, boundaryEvents); }); } function getActivitiesForActivityRef(element) { var bo = getBusinessObject(element); var parent = bo.$parent; var activitiesForActivityRef = getActivitiesForCompensation(parent); // if throwing compensation event is in an event sub process: // get also all activities outside of the event sub process if (is(parent, 'bpmn:SubProcess') && parent.triggeredByEvent) { parent = parent.$parent; if (parent) { activitiesForActivityRef = activitiesForActivityRef.concat(getActivitiesForCompensation(parent)); } } return activitiesForActivityRef; } function createActivityRefOptions(element) { var options = [ { value: '' } ]; var activities = getActivitiesForActivityRef(element); forEach(activities, function(activity) { var activityId = activity.id; var name = (activity.name ? (activity.name + ' ') : '') + '(id=' + activityId + ')'; options.push({ value: activityId, name: name }); }); return options; } module.exports = function(group, element, bpmnFactory, compensateEventDefinition, elementRegistry, translate) { group.entries.push(entryFactory.checkbox({ id: 'wait-for-completion', label: translate('Wait for Completion'), modelProperty: 'waitForCompletion', get: function(element, node) { return { waitForCompletion: compensateEventDefinition.waitForCompletion }; }, set: function(element, values) { values.waitForCompletion = values.waitForCompletion || false; return cmdHelper.updateBusinessObject(element, compensateEventDefinition, values); } })); group.entries.push(entryFactory.selectBox({ id: 'activity-ref', label: translate('Activity Ref'), selectOptions: createActivityRefOptions(element), modelProperty: 'activityRef', get: function(element, node) { var activityRef = compensateEventDefinition.activityRef; activityRef = activityRef && activityRef.id; return { activityRef: activityRef || '' }; }, set: function(element, values) { var activityRef = values.activityRef || undefined; activityRef = activityRef && getBusinessObject(elementRegistry.get(activityRef)); return cmdHelper.updateBusinessObject(element, compensateEventDefinition, { activityRef: activityRef }); } })); };