diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 45a5df9779..1e681b674b 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -20,7 +20,7 @@ import { MarkerIdentifier, StyleDefault, StyleIdentifier } from '../StyleUtils'; import Shape from '../../../model/bpmn/shape/Shape'; import Edge from '../../../model/bpmn/edge/Edge'; import Bounds from '../../../model/bpmn/Bounds'; -import { +import ShapeBpmnElement, { ShapeBpmnActivity, ShapeBpmnBoundaryEvent, ShapeBpmnCallActivity, @@ -174,9 +174,11 @@ export default class StyleConfigurator { private configureLaneStyle(): void { const style = this.cloneDefaultVertexStyle(); style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_SWIMLANE; + + // TODO Remove when the bounds of the lane label is implemented style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE; style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER; - style[mxConstants.STYLE_HORIZONTAL] = false; + style[mxConstants.STYLE_SWIMLANE_LINE] = 0; // hide the line between the title region and the content area // TODO manage lane text area rendering. there is no Label neither the size available (we have only attribute name="Text of the Label") @@ -305,7 +307,7 @@ export default class StyleConfigurator { if (markers.length > 0) { styleValues.set(StyleIdentifier.BPMN_STYLE_MARKERS, markers.join(',')); } - } else if (bpmnElement.kind === ShapeBpmnElementKind.POOL) { + } else if (ShapeUtil.isPoolOrLane((bpmnElement as ShapeBpmnElement).kind)) { // mxConstants.STYLE_HORIZONTAL is for the label // In BPMN, isHorizontal is for the Pool styleValues.set(mxConstants.STYLE_HORIZONTAL, bpmnCell.isHorizontal ? '0' : '1'); diff --git a/test/e2e/__image_snapshots__/bpmn-rendering-test-ts-no-visual-regression-pools-02-vertical-1-snap.png b/test/e2e/__image_snapshots__/bpmn-rendering-test-ts-no-visual-regression-pools-02-vertical-1-snap.png index 4e3beede16..3b34ac57d2 100644 Binary files a/test/e2e/__image_snapshots__/bpmn-rendering-test-ts-no-visual-regression-pools-02-vertical-1-snap.png and b/test/e2e/__image_snapshots__/bpmn-rendering-test-ts-no-visual-regression-pools-02-vertical-1-snap.png differ diff --git a/test/e2e/mxGraph.model.test.ts b/test/e2e/mxGraph.model.test.ts index 9ebd95588a..088127c50a 100644 --- a/test/e2e/mxGraph.model.test.ts +++ b/test/e2e/mxGraph.model.test.ts @@ -39,6 +39,7 @@ export interface ExpectedShapeModelElement { styleShape?: string; markers?: ShapeBpmnMarkerKind[]; isInstantiating?: boolean; + isHorizontal?: boolean; } export interface ExpectedEventModelElement extends ExpectedShapeModelElement { @@ -206,11 +207,13 @@ describe('mxGraph model', () => { } function expectModelContainsPool(cellId: string, modelElement: ExpectedShapeModelElement): void { - expectModelContainsShape(cellId, { ...modelElement, kind: ShapeBpmnElementKind.POOL, styleShape: mxConstants.SHAPE_SWIMLANE }); + const mxCell = expectModelContainsShape(cellId, { ...modelElement, kind: ShapeBpmnElementKind.POOL, styleShape: mxConstants.SHAPE_SWIMLANE }); + expect(mxCell.style).toContain(`${mxConstants.STYLE_HORIZONTAL}=${modelElement.isHorizontal ? '0' : '1'}`); } function expectModelContainsLane(cellId: string, modelElement: ExpectedShapeModelElement): void { - expectModelContainsShape(cellId, { ...modelElement, kind: ShapeBpmnElementKind.LANE, styleShape: mxConstants.SHAPE_SWIMLANE }); + const mxCell = expectModelContainsShape(cellId, { ...modelElement, kind: ShapeBpmnElementKind.LANE, styleShape: mxConstants.SHAPE_SWIMLANE }); + expect(mxCell.style).toContain(`${mxConstants.STYLE_HORIZONTAL}=${modelElement.isHorizontal ? '0' : '1'}`); } it('bpmn elements should be available in the mxGraph model', async () => { @@ -228,7 +231,7 @@ describe('mxGraph model', () => { }; // pool - const minimalPoolModelElement: ExpectedShapeModelElement = { kind: null }; + const minimalPoolModelElement: ExpectedShapeModelElement = { kind: null, isHorizontal: true }; expectModelContainsPool('participant_1_id', { ...minimalPoolModelElement, label: 'Pool 1' }); expectModelContainsPool('participant_2_id', minimalPoolModelElement); expectModelContainsPool('participant_3_id', { ...minimalPoolModelElement, label: 'Black Box Process' }); @@ -946,4 +949,19 @@ describe('mxGraph model', () => { ]; expectModelContainsCellWithGeometry('MessageFlow_1', undefined, messageFlowMxGeometry); }); + + it('vertical pool, with vertical lanes & sub-lanes', async () => { + bpmnVisualization.load(readFileSync('../fixtures/bpmn/model-vertical-pool-lanes-sub_lanes.bpmn')); + + // pool + const minimalPoolModelElement: ExpectedShapeModelElement = { kind: null, isHorizontal: false }; + expectModelContainsPool('Participant_Vertical_With_Lanes', { ...minimalPoolModelElement, label: 'Vertical Pool With Lanes' }); + + // lane + expectModelContainsLane('Lane_Vertical_3', { ...minimalPoolModelElement }); + expectModelContainsLane('Lane_Vertical_1', { ...minimalPoolModelElement, label: 'Lane' }); + expectModelContainsLane('Lane_Vertical_With_Sub_Lane', { ...minimalPoolModelElement, label: 'Lane with Sub-Lanes' }); + expectModelContainsLane('SubLane_Vertical_1', { ...minimalPoolModelElement, label: 'Sub-Lane 1', parentId: 'Lane_Vertical_With_Sub_Lane' }); + expectModelContainsLane('SubLane_Vertical_2', { ...minimalPoolModelElement, label: 'Sub-Lane 2', parentId: 'Lane_Vertical_With_Sub_Lane' }); + }); }); diff --git a/test/fixtures/bpmn/model-vertical-pool-lanes-sub_lanes.bpmn b/test/fixtures/bpmn/model-vertical-pool-lanes-sub_lanes.bpmn new file mode 100644 index 0000000000..e8216263a1 --- /dev/null +++ b/test/fixtures/bpmn/model-vertical-pool-lanes-sub_lanes.bpmn @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/unit/component/mxgraph/config/StyleConfigurator.test.ts b/test/unit/component/mxgraph/config/StyleConfigurator.test.ts index 537bcff73b..85c79c1027 100644 --- a/test/unit/component/mxgraph/config/StyleConfigurator.test.ts +++ b/test/unit/component/mxgraph/config/StyleConfigurator.test.ts @@ -333,6 +333,16 @@ describe('mxgraph renderer', () => { }); }); + describe('compute style - lane', () => { + it.each([ + ['vertical', false, '1'], + ['horizontal', true, '0'], + ])('%s lane', (title, isHorizontal: boolean, expected: string) => { + const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.LANE), undefined, isHorizontal); + expect(computeStyle(shape)).toEqual(`lane;horizontal=${expected}`); + }); + }); + describe.each([ [ShapeBpmnElementKind.CALL_ACTIVITY], [ShapeBpmnElementKind.SUB_PROCESS],