GroupBehavior.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. import inherits from 'inherits';
  2. import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
  3. import {
  4. add as collectionAdd,
  5. remove as collectionRemove
  6. } from 'diagram-js/lib/util/Collections';
  7. import {
  8. getBusinessObject,
  9. is
  10. } from '../../../util/ModelUtil';
  11. import {
  12. createCategoryValue
  13. } from './util/CategoryUtil';
  14. var HIGH_PRIORITY = 2000;
  15. /**
  16. * BPMN specific Group behavior
  17. */
  18. export default function GroupBehavior(
  19. bpmnFactory,
  20. canvas,
  21. elementRegistry,
  22. eventBus,
  23. injector,
  24. moddleCopy
  25. ) {
  26. injector.invoke(CommandInterceptor, this);
  27. /**
  28. * Gets process definitions
  29. *
  30. * @return {ModdleElement} definitions
  31. */
  32. function getDefinitions() {
  33. var rootElement = canvas.getRootElement(),
  34. businessObject = getBusinessObject(rootElement);
  35. return businessObject.$parent;
  36. }
  37. /**
  38. * Removes a referenced category value for a given group shape
  39. *
  40. * @param {djs.model.Shape} shape
  41. */
  42. function removeReferencedCategoryValue(shape) {
  43. var businessObject = getBusinessObject(shape),
  44. categoryValue = businessObject.categoryValueRef;
  45. if (!categoryValue) {
  46. return;
  47. }
  48. var category = categoryValue.$parent;
  49. if (!categoryValue) {
  50. return;
  51. }
  52. collectionRemove(category.categoryValue, categoryValue);
  53. // cleanup category if it is empty
  54. if (category && !category.categoryValue.length) {
  55. removeCategory(category);
  56. }
  57. }
  58. /**
  59. * Removes a given category from the definitions
  60. *
  61. * @param {ModdleElement} category
  62. */
  63. function removeCategory(category) {
  64. var definitions = getDefinitions();
  65. collectionRemove(definitions.get('rootElements'), category);
  66. }
  67. /**
  68. * Returns all group element in the current registry
  69. *
  70. * @return {Array<djs.model.shape>} a list of group shapes
  71. */
  72. function getGroupElements() {
  73. return elementRegistry.filter(function(e) {
  74. return is(e, 'bpmn:Group');
  75. });
  76. }
  77. /**
  78. * Returns true if given categoryValue is referenced in one of the given elements
  79. *
  80. * @param {Array<djs.model.shape>} elements
  81. * @param {ModdleElement} categoryValue
  82. * @return {boolean}
  83. */
  84. function isReferenced(elements, categoryValue) {
  85. return elements.some(function(e) {
  86. var businessObject = getBusinessObject(e);
  87. return businessObject.categoryValueRef
  88. && businessObject.categoryValueRef === categoryValue;
  89. });
  90. }
  91. /**
  92. * remove referenced category + value when group was deleted
  93. */
  94. this.executed('shape.delete', function(event) {
  95. var context = event.context,
  96. shape = context.shape;
  97. if (is(shape, 'bpmn:Group')) {
  98. var businessObject = getBusinessObject(shape),
  99. categoryValueRef = businessObject.categoryValueRef,
  100. groupElements = getGroupElements();
  101. if (!isReferenced(groupElements, categoryValueRef)) {
  102. removeReferencedCategoryValue(shape);
  103. }
  104. }
  105. });
  106. /**
  107. * re-attach removed category
  108. */
  109. this.reverted('shape.delete', function(event) {
  110. var context = event.context,
  111. shape = context.shape;
  112. if (is(shape, 'bpmn:Group')) {
  113. var businessObject = getBusinessObject(shape),
  114. categoryValueRef = businessObject.categoryValueRef,
  115. definitions = getDefinitions(),
  116. category = categoryValueRef ? categoryValueRef.$parent : null;
  117. collectionAdd(category.get('categoryValue'), categoryValueRef);
  118. collectionAdd(definitions.get('rootElements'), category);
  119. }
  120. });
  121. /**
  122. * create new category + value when group was created
  123. */
  124. this.execute('shape.create', function(event) {
  125. var context = event.context,
  126. shape = context.shape,
  127. businessObject = getBusinessObject(shape);
  128. if (is(businessObject, 'bpmn:Group') && !businessObject.categoryValueRef) {
  129. var definitions = getDefinitions(),
  130. categoryValue = createCategoryValue(definitions, bpmnFactory);
  131. // link the reference to the Group
  132. businessObject.categoryValueRef = categoryValue;
  133. }
  134. });
  135. this.revert('shape.create', function(event) {
  136. var context = event.context,
  137. shape = context.shape;
  138. if (is(shape, 'bpmn:Group')) {
  139. removeReferencedCategoryValue(shape);
  140. delete getBusinessObject(shape).categoryValueRef;
  141. }
  142. });
  143. // copy bpmn:CategoryValue when copying element
  144. eventBus.on('moddleCopy.canCopyProperty', HIGH_PRIORITY, function(context) {
  145. var property = context.property,
  146. categoryValue;
  147. if (is(property, 'bpmn:CategoryValue')) {
  148. categoryValue = createCategoryValue(getDefinitions(), bpmnFactory);
  149. // return copy of category
  150. return moddleCopy.copyElement(property, categoryValue);
  151. }
  152. });
  153. }
  154. GroupBehavior.$inject = [
  155. 'bpmnFactory',
  156. 'canvas',
  157. 'elementRegistry',
  158. 'eventBus',
  159. 'injector',
  160. 'moddleCopy'
  161. ];
  162. inherits(GroupBehavior, CommandInterceptor);