Skip to content

Commit

Permalink
impl, refactoring, typos
Browse files Browse the repository at this point in the history
Issue #212
  • Loading branch information
rsoika committed Mar 11, 2023
1 parent 03334f1 commit 7b83fd4
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 88 deletions.
77 changes: 15 additions & 62 deletions open-bpmn.glsp-client/open-bpmn-glsp/src/bpmn-element-views.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,24 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import {
ActionDispatcher,
getElements,
filter,
findParentByFeature,
getSubType,
Hoverable,
IViewArgs,
RenderingContext,
SelectAction,
setAttr,SShapeElement,
SModelRoot,
hasArguments,
Hoverable,Selectable,IViewArgs,SPort,SNode,
TYPES,
findParentByFeature, ShapeView, svg
Selectable, setAttr,
ShapeView, SNode, SPort,
SShapeElement,
svg
} from '@eclipse-glsp/client';
import { SelectionListener } from '@eclipse-glsp/client/lib/features/select/selection-service';
import { Icon,
isContainerNode,
isBPMNLabelNode,
isEventNode,
isGatewayNode,
isTaskNode,
isBoundaryEvent
} from '@open-bpmn/open-bpmn-model';
import { inject, injectable } from 'inversify';
import {
Icon,
isContainerNode,
isEventNode,
isGatewayNode,
isTaskNode
} from '@open-bpmn/open-bpmn-model';
import { injectable } from 'inversify';
import { VNode } from 'snabbdom';

/****************************************************************************
Expand Down Expand Up @@ -322,45 +317,3 @@ export class TextAnnotationNodeView extends ShapeView {
</g>;
}
}

/**
* This selectionListener selects additional associated BundaryEvents and BPMNLabels.
* This allows to move both independent Nodes (TaskNode and BoundaryEvent, GNode and GLabel)
*/
@injectable()
export class BPMNLabelNodeSelectionListener implements SelectionListener {
@inject(TYPES.IActionDispatcher)
protected actionDispatcher: ActionDispatcher;

selectionChanged(root: Readonly<SModelRoot>, selectedElements: string[]): void {
const additionalSelection: string[]=[''];
// We are intersted in Tasks with BoundaryEvents ...
const selectedTaskNodes = getElements(root.index, selectedElements, isTaskNode);
// - first get a list of all selected TaskIDs
const taskIds = selectedTaskNodes.map(task => task.id);
// - next iterate over all BoundaryEvents
const boundaryEvents=filter(root.index,isBoundaryEvent);
if (selectedTaskNodes.length > 0) {
// do we have a boundaryEvent that matches this taskID?
boundaryEvents.forEach( b => {
if (hasArguments(b)) {
const taskRef=b.args.attachedToRef+'';
if (taskIds.includes(taskRef)) {
additionalSelection.push(b.id);
}
}
});
}
// ... and we are intersted in BPMNLabelNodes
const eventNodes = getElements(root.index, selectedElements, isBPMNLabelNode);
if (eventNodes.length > 0) {
// find the associated BPMNLabels
const eventLabelIds = eventNodes.map(node => node.id + '_bpmnlabel');
eventLabelIds.forEach( l => {
additionalSelection.push(l);
});
}
// finally dispatch the additional elementIDs...
this.actionDispatcher.dispatch(SelectAction.create({ selectedElementsIDs: additionalSelection }));
}
}
114 changes: 114 additions & 0 deletions open-bpmn.glsp-client/open-bpmn-glsp/src/bpmn-select-listeners.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/********************************************************************************
* Copyright (c) 2022 Imixs Software Solutions GmbH and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import {
ActionDispatcher, filter, getElements, hasArguments, SelectAction,
SModelRoot, TYPES
} from '@eclipse-glsp/client';
import { SelectionListener } from '@eclipse-glsp/client/lib/features/select/selection-service';
import {
isBoundaryEvent, isBPMNLabelNode, isLaneNode, isPoolNode, isTaskNode
} from '@open-bpmn/open-bpmn-model';
import { inject, injectable } from 'inversify';

/****************************************************************************
* This module provides BPMN select listeners for custom behavior.
*
****************************************************************************/

/**
* This selectionListener selects additional associated BoundaryEvents and BPMNLabels.
* This allows to move both independent Nodes (TaskNode and BoundaryEvent, GNode and GLabel)
*/
@injectable()
export class BPMNLabelNodeSelectionListener implements SelectionListener {
@inject(TYPES.IActionDispatcher)
protected actionDispatcher: ActionDispatcher;

selectionChanged(root: Readonly<SModelRoot>, selectedElements: string[]): void {
const additionalSelection: string[]=[''];
// We are interested in Tasks with BoundaryEvents ...
const selectedTaskNodes = getElements(root.index, selectedElements, isTaskNode);
// - first get a list of all selected TaskIDs
const taskIds = selectedTaskNodes.map(task => task.id);
// - next iterate over all BoundaryEvents
const boundaryEvents=filter(root.index,isBoundaryEvent);
if (selectedTaskNodes.length > 0) {
// do we have a boundaryEvent that matches this taskID?
boundaryEvents.forEach( b => {
if (hasArguments(b)) {
const taskRef=b.args.attachedToRef+'';
if (taskIds.includes(taskRef)) {
additionalSelection.push(b.id);
}
}
});
}
// ... and we are interested in BPMNLabelNodes
const eventNodes = getElements(root.index, selectedElements, isBPMNLabelNode);
if (eventNodes.length > 0) {
// find the associated BPMNLabels
const eventLabelIds = eventNodes.map(node => node.id + '_bpmnlabel');
eventLabelIds.forEach( l => {
additionalSelection.push(l);
});
}
// finally dispatch the additional elementIDs...
this.actionDispatcher.dispatch(SelectAction.create({ selectedElementsIDs: additionalSelection }));
}
}

/**
* This selectionListener reacts on multiple selection. In case the selection list contains
* a Pool or a Lane, these elements are removed from the selection. This is to support
* multi-node selections within a Pool with the Marquee Tool.
* As a consequence it is not possible to select
*/
@injectable()
export class BPMNMultiNodeSelectionListener implements SelectionListener {
@inject(TYPES.IActionDispatcher)
protected actionDispatcher: ActionDispatcher;

selectionChanged(root: Readonly<SModelRoot>, selectedElements: string[]): void {
// react only if more than one element is selected
if (selectedElements.length<2) {
return;
}
const containerIDs: string[]=[];
// We are interested in Pools and Lanes ...
const selectedPools = getElements(root.index, selectedElements, isPoolNode);
const selectedLanes = getElements(root.index, selectedElements, isLaneNode);
// collect pools...
selectedPools.forEach( elementNode => {
containerIDs.push(elementNode.id);
});
// collect lanes...
selectedLanes.forEach( elementNode => {
containerIDs.push(elementNode.id);
});
// if the size of the selected containers is equals the size of selectionElements
// this means we only have containers selected and can skip this method
if (selectedElements.length===containerIDs.length) {
return;
}
// filter current selection...
selectedElements = selectedElements.filter(function (element: string) {
return !containerIDs.includes(element);
});

// finally dispatch the updated selected and unselected IDs...
this.actionDispatcher.dispatch(SelectAction.create({ selectedElementsIDs: selectedElements, deselectedElementsIDs: containerIDs }));
}
}
11 changes: 7 additions & 4 deletions open-bpmn.glsp-client/open-bpmn-glsp/src/di.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ import {
createDiagramContainer,
DeleteElementContextMenuItemProvider,
DiamondNodeView,
editLabelFeature,
ForeignObjectView, LogLevel, moveFeature, overrideViewerOptions, RectangularNodeView, RevealNamedElementActionProvider,
editLabelFeature, ForeignObjectView, LogLevel, moveFeature, overrideViewerOptions,
RectangularNodeView, RevealNamedElementActionProvider,
RoundedCornerNodeView, SCompartment,
SCompartmentView, selectFeature, SLabel, SLabelView, TYPES
} from '@eclipse-glsp/client';
// import { DefaultTypes } from '@eclipse-glsp/protocol';
import {
BPMNEdge,
DataObjectNode,
Expand All @@ -39,13 +38,16 @@ import { Container, ContainerModule } from 'inversify';
import 'sprotty/css/edit-label.css';
import '../css/diagram.css';
import {
BPMNLabelNodeSelectionListener, ContainerHeaderView, DataObjectNodeView, IconView, MessageNodeView,
ContainerHeaderView, DataObjectNodeView, IconView, MessageNodeView,
TextAnnotationNodeView
} from './bpmn-element-views';
import {
BPMNElementSnapper, DrawHelperLinesCommand, HelperLineListener, HelperLineView, RemoveHelperLinesCommand
} from './bpmn-helperlines';
import { BPMNEdgeView } from './bpmn-routing-views';
import {
BPMNLabelNodeSelectionListener, BPMNMultiNodeSelectionListener
} from './bpmn-select-listeners';

import bpmnPropertyModule from '@open-bpmn/open-bpmn-properties';

Expand All @@ -61,6 +63,7 @@ const bpmnDiagramModule = new ContainerModule((bind, unbind, isBound, rebind) =>

// bind new SelectionListener for BPMNLabels and BoundaryEvents
bind(TYPES.SelectionListener).to(BPMNLabelNodeSelectionListener);
bind(TYPES.SelectionListener).to(BPMNMultiNodeSelectionListener);

// bpmn helper lines
bind(TYPES.MouseListener).to(HelperLineListener);
Expand Down
24 changes: 8 additions & 16 deletions open-bpmn.glsp-client/open-bpmn-model/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,22 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import {
boundsFeature,
connectableFeature,
CircularNode,DiamondNode,
deletableFeature,
EditableLabel,
fadeFeature,
hoverFeedbackFeature,
isEditableLabel,
Args, Bounds, boundsFeature, CircularNode, connectableFeature, deletableFeature, DiamondNode, Dimension, EditableLabel,
fadeFeature, ForeignObjectElement, hoverFeedbackFeature, isBoundsAware, isEditableLabel,
layoutableChildFeature,
LayoutContainer,
layoutContainerFeature,
moveFeature,
Nameable,
nameFeature,
popupFeature,
RectangularNode,
SChildElement,
RectangularNode, SArgumentable, SChildElement,
SEdge,
selectFeature,
SModelElement,
SShapeElement,
WithEditableLabel,
withEditLabelFeature,
ForeignObjectElement,SArgumentable,Args,Bounds,isBoundsAware,Dimension
withEditLabelFeature
} from '@eclipse-glsp/client';

export interface BPMNFlowElement {
Expand Down Expand Up @@ -148,7 +140,7 @@ export class TextAnnotationNode extends RectangularNode implements BPMNFlowEleme
}

/*
* This class provides a new Node displaying a multiline textblock.
* This class provides a new Node displaying a multiline text block.
* The node also allows editing the text.
* We are using this model object for BPMN TextAnnotations.
*
Expand Down Expand Up @@ -197,7 +189,7 @@ export class MultiLineTextNode extends ForeignObjectElement implements SArgument
}

/*
* Helper Methods to determind if a ModelElement is of a specific type
* Helper Methods to determine if a ModelElement is of a specific type
* The methods return the corresponding node
*/
export function isTaskNode(element: SModelElement): element is TaskNode {
Expand Down Expand Up @@ -225,7 +217,7 @@ export function isGatewayNode(element: SModelElement): element is GatewayNode {
}

/*
* Indicates that the ModelElement has a independed BPNNLabel
* Indicates that the ModelElement has a independent BPMNLabel
*/
export function isBPMNLabelNode(element: SModelElement): element is SModelElement {
return (element instanceof EventNode || element instanceof GatewayNode || element instanceof DataObjectNode
Expand All @@ -244,7 +236,7 @@ export function isBPMNNode(element: SModelElement): element is TaskNode | EventN
}

/*
* Returns ture if the BPMN Node Elmeent is a BoundaryEvent
* Returns true if the BPMN Node Element is a BoundaryEvent
*/
export function isBoundaryEvent(element: SModelElement): element is EventNode {
return element instanceof EventNode && element.type === 'boundaryEvent';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export class BPMNPropertyPanel extends AbstractUIExtension implements SelectionL
*/
selectionChanged(root: Readonly<SModelRoot>, selectedElements: string[]): void {
// return if the property panel is not yet visible
if (!this.bodyDiv) {
if (!this.bodyDiv || !selectedElements || selectedElements.length===0) {
return;
}

Expand Down Expand Up @@ -289,7 +289,7 @@ export class BPMNPropertyPanel extends AbstractUIExtension implements SelectionL

// init the react container only once....
if (!this.panelContainer) {
this.panelContainer = createRoot(this.bodyDiv); // createRoot(container!) if you use TypeScript
this.panelContainer = createRoot(this.bodyDiv);
}
// BPMN Node selected, collect JSONForms schemata....
let bpmnPropertiesData;
Expand Down Expand Up @@ -331,12 +331,10 @@ export class BPMNPropertyPanel extends AbstractUIExtension implements SelectionL
} else {
// no single element selected!
this.selectedElementId = '';
if (this.bodyDiv) {
if (this.bodyDiv && this.panelContainer) {
this.headerTitle.textContent = 'BPMN Properties';
// multi selection - we can not show a property panel
if (this.bodyDiv) {
this.panelContainer.render(<React.Fragment>Please select a single element </React.Fragment>);
}
this.panelContainer.render(<React.Fragment>Please select a single element </React.Fragment>);
}
}
}
Expand Down

0 comments on commit 7b83fd4

Please sign in to comment.