@formicoidea/labre-framework-bpmn 0.23.0 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/consts.d.ts +42 -0
- package/{src/consts.ts → dist/consts.js} +11 -20
- package/dist/descriptor.d.ts +7 -0
- package/{src/descriptor.ts → dist/descriptor.js} +1 -1
- package/dist/effects.d.ts +10 -0
- package/dist/effects.js +7 -0
- package/dist/element-renderer.d.ts +13 -0
- package/dist/element-renderer.js +58 -0
- package/dist/element-view.d.ts +22 -0
- package/dist/element-view.js +103 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/node/node-renderer.d.ts +16 -0
- package/dist/node/node-renderer.js +43 -0
- package/dist/node/node-view.d.ts +17 -0
- package/dist/node/node-view.js +28 -0
- package/dist/templates/index.d.ts +3 -0
- package/dist/templates/index.js +114 -0
- package/dist/toolbar/bpmn-menu.d.ts +27 -0
- package/dist/toolbar/bpmn-menu.js +179 -0
- package/dist/toolbar/bpmn-senior-button.d.ts +16 -0
- package/{src/toolbar/bpmn-senior-button.ts → dist/toolbar/bpmn-senior-button.js} +33 -38
- package/dist/toolbar/config.d.ts +14 -0
- package/dist/toolbar/config.js +55 -0
- package/dist/toolbar/icons.d.ts +16 -0
- package/{src/toolbar/icons.ts → dist/toolbar/icons.js} +8 -14
- package/dist/toolbar/senior-tool.d.ts +2 -0
- package/{src/toolbar/senior-tool.ts → dist/toolbar/senior-tool.js} +5 -5
- package/dist/view.d.ts +7 -0
- package/dist/view.js +34 -0
- package/package.json +15 -6
- package/src/effects.ts +0 -14
- package/src/element-renderer.ts +0 -93
- package/src/element-view.ts +0 -116
- package/src/index.ts +0 -1
- package/src/node/node-renderer.ts +0 -65
- package/src/node/node-view.ts +0 -34
- package/src/templates/index.ts +0 -156
- package/src/toolbar/bpmn-menu.ts +0 -224
- package/src/toolbar/config.ts +0 -74
- package/src/view.ts +0 -37
package/dist/consts.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { BpmnNodeKind } from '@formicoidea/labre-core/model';
|
|
2
|
+
/**
|
|
3
|
+
* Visual constants for the BPMN basics. Style "C" (hybrid): spec-accurate
|
|
4
|
+
* shapes and line weights, with accent colour only on the event rings — the
|
|
5
|
+
* task and gateway stay neutral. All of these are just the creation-time
|
|
6
|
+
* defaults; every value is an editable shape property afterwards.
|
|
7
|
+
*/
|
|
8
|
+
/** Accent stroke for the start event (thin green ring). */
|
|
9
|
+
export declare const EVENT_START = "#43a06b";
|
|
10
|
+
/** Accent stroke for the end event (thick red ring). */
|
|
11
|
+
export declare const EVENT_END = "#cf5648";
|
|
12
|
+
/** Neutral stroke for task / gateway (matches the EDGY base shapes). */
|
|
13
|
+
export declare const NEUTRAL_STROKE = "#262626";
|
|
14
|
+
/** Default fill for events / task / gateway. */
|
|
15
|
+
export declare const NODE_FILL = "#ffffff";
|
|
16
|
+
/** BPMN line weights: thin start ring, thick end ring, regular elsewhere. */
|
|
17
|
+
export declare const START_WIDTH = 2;
|
|
18
|
+
export declare const END_WIDTH = 4;
|
|
19
|
+
export declare const NODE_STROKE_WIDTH = 2;
|
|
20
|
+
/** Task corner radius (absolute px — a lightly rounded rectangle). */
|
|
21
|
+
export declare const TASK_RADIUS = 10;
|
|
22
|
+
/** Inner-text font for the task label. */
|
|
23
|
+
export declare const INNER_FONT_SIZE = 18;
|
|
24
|
+
/** Default node sizes (model units) per kind. */
|
|
25
|
+
export declare const NODE_SIZE: Record<BpmnNodeKind, {
|
|
26
|
+
w: number;
|
|
27
|
+
h: number;
|
|
28
|
+
}>;
|
|
29
|
+
/** Default inner text per kind (only the task carries a label). */
|
|
30
|
+
export declare const NODE_LABEL: Record<BpmnNodeKind, string>;
|
|
31
|
+
/** Pool (background container) defaults. */
|
|
32
|
+
export declare const POOL_BAND_WIDTH = 28;
|
|
33
|
+
export declare const POOL_FRAME_COLOR = "#262626";
|
|
34
|
+
export declare const POOL_BAND_FILL = "#f4f4f5";
|
|
35
|
+
export declare const POOL_FRAME_WIDTH = 1.5;
|
|
36
|
+
export declare const POOL_NAME_FONT_SIZE = 15;
|
|
37
|
+
export declare const POOL_NAME_COLOR = "#262626";
|
|
38
|
+
export declare const POOL_FONT_FAMILY = "Inter, sans-serif";
|
|
39
|
+
/** Sequence-flow connector preset. */
|
|
40
|
+
export declare const SEQUENCE_STROKE = "#262626";
|
|
41
|
+
export declare const SEQUENCE_WIDTH = 2;
|
|
42
|
+
//# sourceMappingURL=consts.d.ts.map
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import type { BpmnNodeKind } from '@formicoidea/labre-core/model';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Visual constants for the BPMN basics. Style "C" (hybrid): spec-accurate
|
|
5
3
|
* shapes and line weights, with accent colour only on the event rings — the
|
|
6
4
|
* task and gateway stay neutral. All of these are just the creation-time
|
|
7
5
|
* defaults; every value is an editable shape property afterwards.
|
|
8
6
|
*/
|
|
9
|
-
|
|
10
7
|
/** Accent stroke for the start event (thin green ring). */
|
|
11
8
|
export const EVENT_START = '#43a06b';
|
|
12
9
|
/** Accent stroke for the end event (thick red ring). */
|
|
@@ -15,34 +12,28 @@ export const EVENT_END = '#cf5648';
|
|
|
15
12
|
export const NEUTRAL_STROKE = '#262626';
|
|
16
13
|
/** Default fill for events / task / gateway. */
|
|
17
14
|
export const NODE_FILL = '#ffffff';
|
|
18
|
-
|
|
19
15
|
/** BPMN line weights: thin start ring, thick end ring, regular elsewhere. */
|
|
20
16
|
export const START_WIDTH = 2;
|
|
21
17
|
export const END_WIDTH = 4;
|
|
22
18
|
export const NODE_STROKE_WIDTH = 2;
|
|
23
|
-
|
|
24
19
|
/** Task corner radius (absolute px — a lightly rounded rectangle). */
|
|
25
20
|
export const TASK_RADIUS = 10;
|
|
26
|
-
|
|
27
21
|
/** Inner-text font for the task label. */
|
|
28
22
|
export const INNER_FONT_SIZE = 18;
|
|
29
|
-
|
|
30
23
|
/** Default node sizes (model units) per kind. */
|
|
31
|
-
export const NODE_SIZE
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
24
|
+
export const NODE_SIZE = {
|
|
25
|
+
startEvent: { w: 56, h: 56 },
|
|
26
|
+
endEvent: { w: 56, h: 56 },
|
|
27
|
+
task: { w: 120, h: 72 },
|
|
28
|
+
gatewayExclusive: { w: 72, h: 72 },
|
|
36
29
|
};
|
|
37
|
-
|
|
38
30
|
/** Default inner text per kind (only the task carries a label). */
|
|
39
|
-
export const NODE_LABEL
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
export const NODE_LABEL = {
|
|
32
|
+
startEvent: '',
|
|
33
|
+
endEvent: '',
|
|
34
|
+
task: 'Task',
|
|
35
|
+
gatewayExclusive: '',
|
|
44
36
|
};
|
|
45
|
-
|
|
46
37
|
/** Pool (background container) defaults. */
|
|
47
38
|
export const POOL_BAND_WIDTH = 28;
|
|
48
39
|
export const POOL_FRAME_COLOR = '#262626';
|
|
@@ -51,7 +42,7 @@ export const POOL_FRAME_WIDTH = 1.5;
|
|
|
51
42
|
export const POOL_NAME_FONT_SIZE = 15;
|
|
52
43
|
export const POOL_NAME_COLOR = '#262626';
|
|
53
44
|
export const POOL_FONT_FAMILY = 'Inter, sans-serif';
|
|
54
|
-
|
|
55
45
|
/** Sequence-flow connector preset. */
|
|
56
46
|
export const SEQUENCE_STROKE = '#262626';
|
|
57
47
|
export const SEQUENCE_WIDTH = 2;
|
|
48
|
+
//# sourceMappingURL=consts.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EdgelessBpmnMenu } from './toolbar/bpmn-menu';
|
|
2
|
+
import { EdgelessBpmnSeniorButton } from './toolbar/bpmn-senior-button';
|
|
3
|
+
export declare function effects(): void;
|
|
4
|
+
declare global {
|
|
5
|
+
interface HTMLElementTagNameMap {
|
|
6
|
+
'edgeless-bpmn-menu': EdgelessBpmnMenu;
|
|
7
|
+
'edgeless-bpmn-senior-button': EdgelessBpmnSeniorButton;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=effects.d.ts.map
|
package/dist/effects.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { EdgelessBpmnMenu } from './toolbar/bpmn-menu';
|
|
2
|
+
import { EdgelessBpmnSeniorButton } from './toolbar/bpmn-senior-button';
|
|
3
|
+
export function effects() {
|
|
4
|
+
customElements.define('edgeless-bpmn-menu', EdgelessBpmnMenu);
|
|
5
|
+
customElements.define('edgeless-bpmn-senior-button', EdgelessBpmnSeniorButton);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=effects.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ElementRenderer } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
import type { BpmnPoolElementModel } from '@formicoidea/labre-core/model';
|
|
3
|
+
/**
|
|
4
|
+
* Canvas renderer for a BPMN pool: a rounded-rect frame with a vertical name
|
|
5
|
+
* band on the left (the participant name is drawn rotated, as in the spec).
|
|
6
|
+
* Drawn directly in element space; the band width and font are fixed so they
|
|
7
|
+
* stay legible at any pool size. Mirrors the other framework backgrounds.
|
|
8
|
+
*/
|
|
9
|
+
export declare const bpmnPool: ElementRenderer<BpmnPoolElementModel>;
|
|
10
|
+
export declare const BpmnPoolRendererExtension: import("@formicoidea/labre-core/store").ExtensionType & {
|
|
11
|
+
identifier: import("@formicoidea/labre-core/global/di").ServiceIdentifier<ElementRenderer<BpmnPoolElementModel>>;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=element-renderer.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ElementRendererExtension, } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
import { POOL_BAND_FILL, POOL_BAND_WIDTH, POOL_FONT_FAMILY, POOL_FRAME_COLOR, POOL_FRAME_WIDTH, POOL_NAME_COLOR, POOL_NAME_FONT_SIZE, } from './consts';
|
|
3
|
+
/** Trace a rounded-rectangle path (no dependency on ctx.roundRect). */
|
|
4
|
+
function roundedRectPath(ctx, x, y, w, h, r) {
|
|
5
|
+
const rr = Math.min(r, w / 2, h / 2);
|
|
6
|
+
ctx.beginPath();
|
|
7
|
+
ctx.moveTo(x + rr, y);
|
|
8
|
+
ctx.lineTo(x + w - rr, y);
|
|
9
|
+
ctx.arcTo(x + w, y, x + w, y + rr, rr);
|
|
10
|
+
ctx.lineTo(x + w, y + h - rr);
|
|
11
|
+
ctx.arcTo(x + w, y + h, x + w - rr, y + h, rr);
|
|
12
|
+
ctx.lineTo(x + rr, y + h);
|
|
13
|
+
ctx.arcTo(x, y + h, x, y + h - rr, rr);
|
|
14
|
+
ctx.lineTo(x, y + rr);
|
|
15
|
+
ctx.arcTo(x, y, x + rr, y, rr);
|
|
16
|
+
ctx.closePath();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Canvas renderer for a BPMN pool: a rounded-rect frame with a vertical name
|
|
20
|
+
* band on the left (the participant name is drawn rotated, as in the spec).
|
|
21
|
+
* Drawn directly in element space; the band width and font are fixed so they
|
|
22
|
+
* stay legible at any pool size. Mirrors the other framework backgrounds.
|
|
23
|
+
*/
|
|
24
|
+
export const bpmnPool = (model, ctx, matrix) => {
|
|
25
|
+
const [, , w, h] = model.deserializedXYWH;
|
|
26
|
+
const cx = w / 2;
|
|
27
|
+
const cy = h / 2;
|
|
28
|
+
ctx.setTransform(matrix.translateSelf(cx, cy).rotateSelf(model.rotate).translateSelf(-cx, -cy));
|
|
29
|
+
const band = Math.min(POOL_BAND_WIDTH, w);
|
|
30
|
+
const inset = POOL_FRAME_WIDTH / 2;
|
|
31
|
+
// Name band (left), filled.
|
|
32
|
+
ctx.fillStyle = POOL_BAND_FILL;
|
|
33
|
+
ctx.fillRect(0, 0, band, h);
|
|
34
|
+
// Frame + band divider.
|
|
35
|
+
ctx.strokeStyle = POOL_FRAME_COLOR;
|
|
36
|
+
ctx.lineWidth = POOL_FRAME_WIDTH;
|
|
37
|
+
ctx.lineJoin = 'round';
|
|
38
|
+
roundedRectPath(ctx, inset, inset, w - POOL_FRAME_WIDTH, h - POOL_FRAME_WIDTH, 6);
|
|
39
|
+
ctx.stroke();
|
|
40
|
+
ctx.beginPath();
|
|
41
|
+
ctx.moveTo(band, 0);
|
|
42
|
+
ctx.lineTo(band, h);
|
|
43
|
+
ctx.stroke();
|
|
44
|
+
// Participant name, rotated to read up the band (skip when empty / too narrow).
|
|
45
|
+
if (model.name && band > 12) {
|
|
46
|
+
ctx.save();
|
|
47
|
+
ctx.translate(band / 2, h / 2);
|
|
48
|
+
ctx.rotate(-Math.PI / 2);
|
|
49
|
+
ctx.fillStyle = POOL_NAME_COLOR;
|
|
50
|
+
ctx.font = `600 ${POOL_NAME_FONT_SIZE}px ${POOL_FONT_FAMILY}`;
|
|
51
|
+
ctx.textAlign = 'center';
|
|
52
|
+
ctx.textBaseline = 'middle';
|
|
53
|
+
ctx.fillText(model.name, 0, 0);
|
|
54
|
+
ctx.restore();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
export const BpmnPoolRendererExtension = ElementRendererExtension('bpmnPool', bpmnPool);
|
|
58
|
+
//# sourceMappingURL=element-renderer.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BpmnPoolElementModel } from '@formicoidea/labre-core/model';
|
|
2
|
+
import { GfxElementModelView } from '@formicoidea/labre-core/std/gfx';
|
|
3
|
+
/**
|
|
4
|
+
* View for a BPMN pool. A double-click edits the participant name in place
|
|
5
|
+
* (single field — the whole pool is the hit target). Mirrors the inline label
|
|
6
|
+
* editor used by the EDGY / Wardley backgrounds.
|
|
7
|
+
*/
|
|
8
|
+
export declare class BpmnPoolView extends GfxElementModelView<BpmnPoolElementModel> {
|
|
9
|
+
static type: string;
|
|
10
|
+
private _nameEditor;
|
|
11
|
+
onCreated(): void;
|
|
12
|
+
onDestroyed(): void;
|
|
13
|
+
private _onDblClick;
|
|
14
|
+
private _openEditor;
|
|
15
|
+
private _closeEditor;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resize gating: the resize handles are hidden unless `model.resizeEnabled` is
|
|
19
|
+
* true (toggled from the toolbar). Moving / selecting stays available.
|
|
20
|
+
*/
|
|
21
|
+
export declare const BpmnPoolInteraction: import("@formicoidea/labre-core/store").ExtensionType;
|
|
22
|
+
//# sourceMappingURL=element-view.d.ts.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { EdgelessCRUDIdentifier } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
import { GfxElementModelView, GfxViewInteractionExtension, } from '@formicoidea/labre-core/std/gfx';
|
|
3
|
+
/**
|
|
4
|
+
* View for a BPMN pool. A double-click edits the participant name in place
|
|
5
|
+
* (single field — the whole pool is the hit target). Mirrors the inline label
|
|
6
|
+
* editor used by the EDGY / Wardley backgrounds.
|
|
7
|
+
*/
|
|
8
|
+
export class BpmnPoolView extends GfxElementModelView {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this._nameEditor = null;
|
|
12
|
+
}
|
|
13
|
+
static { this.type = 'bpmnPool'; }
|
|
14
|
+
onCreated() {
|
|
15
|
+
super.onCreated();
|
|
16
|
+
this.on('dblclick', e => this._onDblClick(e));
|
|
17
|
+
}
|
|
18
|
+
onDestroyed() {
|
|
19
|
+
this._closeEditor();
|
|
20
|
+
super.onDestroyed();
|
|
21
|
+
}
|
|
22
|
+
_onDblClick(e) {
|
|
23
|
+
if (this.model.isLocked())
|
|
24
|
+
return;
|
|
25
|
+
this._openEditor(e);
|
|
26
|
+
}
|
|
27
|
+
_openEditor(e) {
|
|
28
|
+
this._closeEditor();
|
|
29
|
+
const input = document.createElement('input');
|
|
30
|
+
input.value = String(this.model.name ?? '');
|
|
31
|
+
Object.assign(input.style, {
|
|
32
|
+
position: 'fixed',
|
|
33
|
+
left: `${e.raw.clientX}px`,
|
|
34
|
+
top: `${e.raw.clientY}px`,
|
|
35
|
+
transform: 'translate(-50%, -50%)',
|
|
36
|
+
zIndex: '10000',
|
|
37
|
+
minWidth: '140px',
|
|
38
|
+
padding: '3px 8px',
|
|
39
|
+
font: '14px Inter, sans-serif',
|
|
40
|
+
color: 'var(--affine-text-primary-color, #1f2328)',
|
|
41
|
+
background: 'var(--affine-background-overlay-panel-color, #ffffff)',
|
|
42
|
+
border: '1px solid var(--affine-primary-color, #1e96eb)',
|
|
43
|
+
borderRadius: '6px',
|
|
44
|
+
boxShadow: 'var(--affine-shadow-2, 0 2px 8px rgba(0,0,0,0.18))',
|
|
45
|
+
outline: 'none',
|
|
46
|
+
});
|
|
47
|
+
document.body.append(input);
|
|
48
|
+
this._nameEditor = input;
|
|
49
|
+
// Mark "editing" so the global edgeless key handlers (delete, escape, …)
|
|
50
|
+
// don't act on the pool while the user types.
|
|
51
|
+
this.gfx.selection.set({ elements: [this.model.id], editing: true });
|
|
52
|
+
input.focus();
|
|
53
|
+
input.select();
|
|
54
|
+
const commit = () => {
|
|
55
|
+
if (this._nameEditor !== input)
|
|
56
|
+
return;
|
|
57
|
+
const value = input.value;
|
|
58
|
+
this._closeEditor();
|
|
59
|
+
this.gfx.std.store.captureSync();
|
|
60
|
+
this.gfx.std
|
|
61
|
+
.get(EdgelessCRUDIdentifier)
|
|
62
|
+
.updateElement(this.model.id, { name: value });
|
|
63
|
+
};
|
|
64
|
+
input.addEventListener('keydown', ev => {
|
|
65
|
+
ev.stopPropagation();
|
|
66
|
+
if (ev.key === 'Enter') {
|
|
67
|
+
ev.preventDefault();
|
|
68
|
+
commit();
|
|
69
|
+
}
|
|
70
|
+
else if (ev.key === 'Escape') {
|
|
71
|
+
ev.preventDefault();
|
|
72
|
+
this._closeEditor();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
input.addEventListener('blur', commit);
|
|
76
|
+
}
|
|
77
|
+
_closeEditor() {
|
|
78
|
+
if (!this._nameEditor)
|
|
79
|
+
return;
|
|
80
|
+
const input = this._nameEditor;
|
|
81
|
+
this._nameEditor = null;
|
|
82
|
+
input.remove();
|
|
83
|
+
if (this.isConnected) {
|
|
84
|
+
this.gfx.selection.set({ elements: [this.model.id], editing: false });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Resize gating: the resize handles are hidden unless `model.resizeEnabled` is
|
|
90
|
+
* true (toggled from the toolbar). Moving / selecting stays available.
|
|
91
|
+
*/
|
|
92
|
+
export const BpmnPoolInteraction = GfxViewInteractionExtension(BpmnPoolView.type, {
|
|
93
|
+
handleResize({ model }) {
|
|
94
|
+
return {
|
|
95
|
+
beforeResize({ set }) {
|
|
96
|
+
if (!model.resizeEnabled) {
|
|
97
|
+
set({ allowedHandlers: [] });
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=element-view.js.map
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ElementRenderer } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
import { type BpmnNodeElementModel } from '@formicoidea/labre-core/model';
|
|
3
|
+
/**
|
|
4
|
+
* Renderer for a BPMN flow-object node. The shape body (ellipse / rounded rect
|
|
5
|
+
* / diamond) is drawn by REUSING the native shape renderer — so stroke width,
|
|
6
|
+
* colors, inner text and theme behave exactly like a native shape. Only
|
|
7
|
+
* `gatewayExclusive` is decorated: an X drawn on top in the node's (editable)
|
|
8
|
+
* stroke color. Events and task are plain native shapes.
|
|
9
|
+
*
|
|
10
|
+
* Mirrors the EDGY node renderer.
|
|
11
|
+
*/
|
|
12
|
+
export declare const bpmnNode: ElementRenderer<BpmnNodeElementModel>;
|
|
13
|
+
export declare const BpmnNodeRendererExtension: import("@formicoidea/labre-core/store").ExtensionType & {
|
|
14
|
+
identifier: import("@formicoidea/labre-core/global/di").ServiceIdentifier<ElementRenderer<BpmnNodeElementModel>>;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=node-renderer.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ElementRendererExtension, } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
import { shape as shapeRenderer } from '@formicoidea/labre-core/gfx/shape';
|
|
3
|
+
import { DefaultTheme } from '@formicoidea/labre-core/model';
|
|
4
|
+
/**
|
|
5
|
+
* Renderer for a BPMN flow-object node. The shape body (ellipse / rounded rect
|
|
6
|
+
* / diamond) is drawn by REUSING the native shape renderer — so stroke width,
|
|
7
|
+
* colors, inner text and theme behave exactly like a native shape. Only
|
|
8
|
+
* `gatewayExclusive` is decorated: an X drawn on top in the node's (editable)
|
|
9
|
+
* stroke color. Events and task are plain native shapes.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors the EDGY node renderer.
|
|
12
|
+
*/
|
|
13
|
+
export const bpmnNode = (model, ctx, matrix, renderer, rc, bound) => {
|
|
14
|
+
const [, , w, h] = model.deserializedXYWH;
|
|
15
|
+
const cx = w / 2;
|
|
16
|
+
const cy = h / 2;
|
|
17
|
+
// Capture the element-local transform BEFORE the shape renderer mutates the
|
|
18
|
+
// matrix, so the glyph can be drawn in the same space afterwards.
|
|
19
|
+
const glyphMatrix = DOMMatrix.fromMatrix(matrix)
|
|
20
|
+
.translateSelf(cx, cy)
|
|
21
|
+
.rotateSelf(model.rotate)
|
|
22
|
+
.translateSelf(-cx, -cy);
|
|
23
|
+
// Native shape (fill / stroke / inner text / theme handled natively).
|
|
24
|
+
shapeRenderer(model, ctx, matrix, renderer, rc, bound);
|
|
25
|
+
if (model.kind !== 'gatewayExclusive')
|
|
26
|
+
return;
|
|
27
|
+
const color = renderer.getColorValue(model.strokeColor, DefaultTheme.shapeStrokeColor, true);
|
|
28
|
+
// ── Exclusive-gateway X, centred and sized to the diamond ───────────
|
|
29
|
+
const r = Math.min(w, h) * 0.2;
|
|
30
|
+
ctx.setTransform(glyphMatrix);
|
|
31
|
+
ctx.translate(cx, cy);
|
|
32
|
+
ctx.strokeStyle = color;
|
|
33
|
+
ctx.lineWidth = Math.max(2, Math.min(w, h) * 0.06);
|
|
34
|
+
ctx.lineCap = 'round';
|
|
35
|
+
ctx.beginPath();
|
|
36
|
+
ctx.moveTo(-r, -r);
|
|
37
|
+
ctx.lineTo(r, r);
|
|
38
|
+
ctx.moveTo(-r, r);
|
|
39
|
+
ctx.lineTo(r, -r);
|
|
40
|
+
ctx.stroke();
|
|
41
|
+
};
|
|
42
|
+
export const BpmnNodeRendererExtension = ElementRendererExtension('bpmnNode', bpmnNode);
|
|
43
|
+
//# sourceMappingURL=node-renderer.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type BpmnNodeElementModel } from '@formicoidea/labre-core/model';
|
|
2
|
+
import { GfxElementModelView } from '@formicoidea/labre-core/std/gfx';
|
|
3
|
+
/**
|
|
4
|
+
* View for a BPMN flow-object node. Registering it ensures `gfx.view.get(model)`
|
|
5
|
+
* returns a view (required so move / select / connector interactions work).
|
|
6
|
+
*
|
|
7
|
+
* BPMN nodes are native shapes, so we reuse the shape inner-text editor: a
|
|
8
|
+
* double-click mounts the editable text overlay (`mountShapeTextEditor`),
|
|
9
|
+
* exactly like a native shape (used to label the task).
|
|
10
|
+
*
|
|
11
|
+
* Mirrors {@link EdgyNodeView}.
|
|
12
|
+
*/
|
|
13
|
+
export declare class BpmnNodeView extends GfxElementModelView<BpmnNodeElementModel> {
|
|
14
|
+
static type: string;
|
|
15
|
+
onCreated(): void;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=node-view.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { mountShapeTextEditor } from '@formicoidea/labre-core/gfx/shape';
|
|
2
|
+
import { ShapeElementModel, } from '@formicoidea/labre-core/model';
|
|
3
|
+
import { GfxElementModelView } from '@formicoidea/labre-core/std/gfx';
|
|
4
|
+
/**
|
|
5
|
+
* View for a BPMN flow-object node. Registering it ensures `gfx.view.get(model)`
|
|
6
|
+
* returns a view (required so move / select / connector interactions work).
|
|
7
|
+
*
|
|
8
|
+
* BPMN nodes are native shapes, so we reuse the shape inner-text editor: a
|
|
9
|
+
* double-click mounts the editable text overlay (`mountShapeTextEditor`),
|
|
10
|
+
* exactly like a native shape (used to label the task).
|
|
11
|
+
*
|
|
12
|
+
* Mirrors {@link EdgyNodeView}.
|
|
13
|
+
*/
|
|
14
|
+
export class BpmnNodeView extends GfxElementModelView {
|
|
15
|
+
static { this.type = 'bpmnNode'; }
|
|
16
|
+
onCreated() {
|
|
17
|
+
super.onCreated();
|
|
18
|
+
this.on('dblclick', () => {
|
|
19
|
+
const edgeless = this.std.view.getBlock(this.std.store.root.id);
|
|
20
|
+
if (edgeless &&
|
|
21
|
+
!this.model.isLocked() &&
|
|
22
|
+
this.model instanceof ShapeElementModel) {
|
|
23
|
+
mountShapeTextEditor(this.model, edgeless);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=node-view.js.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { makeTemplateSnapshot, surfaceText, } from '@formicoidea/labre-core/gfx/template';
|
|
2
|
+
import { ConnectorMode, FontFamily, PointStyle, ShapeStyle, StrokeStyle, } from '@formicoidea/labre-core/model';
|
|
3
|
+
import { END_WIDTH, EVENT_END, EVENT_START, INNER_FONT_SIZE, NEUTRAL_STROKE, NODE_FILL, NODE_SIZE, NODE_STROKE_WIDTH, SEQUENCE_STROKE, SEQUENCE_WIDTH, START_WIDTH, TASK_RADIUS, } from '../consts';
|
|
4
|
+
/** One BPMN flow-object node, as a surface-element JSON entry. */
|
|
5
|
+
function node(kind, x, y, text) {
|
|
6
|
+
const { w, h } = NODE_SIZE[kind];
|
|
7
|
+
const base = {
|
|
8
|
+
type: 'bpmnNode',
|
|
9
|
+
kind,
|
|
10
|
+
filled: true,
|
|
11
|
+
fillColor: NODE_FILL,
|
|
12
|
+
shapeStyle: ShapeStyle.General,
|
|
13
|
+
roughness: 0,
|
|
14
|
+
xywh: `[${x},${y},${w},${h}]`,
|
|
15
|
+
};
|
|
16
|
+
if (kind === 'startEvent')
|
|
17
|
+
return { ...base, shapeType: 'ellipse', strokeColor: EVENT_START, strokeWidth: START_WIDTH };
|
|
18
|
+
if (kind === 'endEvent')
|
|
19
|
+
return { ...base, shapeType: 'ellipse', strokeColor: EVENT_END, strokeWidth: END_WIDTH };
|
|
20
|
+
if (kind === 'gatewayExclusive')
|
|
21
|
+
return { ...base, shapeType: 'diamond', strokeColor: NEUTRAL_STROKE, strokeWidth: NODE_STROKE_WIDTH };
|
|
22
|
+
return {
|
|
23
|
+
...base,
|
|
24
|
+
shapeType: 'rect',
|
|
25
|
+
radius: TASK_RADIUS,
|
|
26
|
+
strokeColor: NEUTRAL_STROKE,
|
|
27
|
+
strokeWidth: NODE_STROKE_WIDTH,
|
|
28
|
+
text: surfaceText(text ?? 'Task'),
|
|
29
|
+
color: NEUTRAL_STROKE,
|
|
30
|
+
fontFamily: FontFamily.Inter,
|
|
31
|
+
fontSize: INNER_FONT_SIZE,
|
|
32
|
+
textAlign: 'center',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function pool(x, y, w, h, name = 'Pool') {
|
|
36
|
+
return { type: 'bpmnPool', name, xywh: `[${x},${y},${w},${h}]` };
|
|
37
|
+
}
|
|
38
|
+
/** A sequence-flow connector; ids are remapped on insert. */
|
|
39
|
+
function seq(source, target) {
|
|
40
|
+
return {
|
|
41
|
+
type: 'connector',
|
|
42
|
+
mode: ConnectorMode.Orthogonal,
|
|
43
|
+
stroke: SEQUENCE_STROKE,
|
|
44
|
+
strokeWidth: SEQUENCE_WIDTH,
|
|
45
|
+
strokeStyle: StrokeStyle.Solid,
|
|
46
|
+
frontEndpointStyle: PointStyle.None,
|
|
47
|
+
rearEndpointStyle: PointStyle.Triangle,
|
|
48
|
+
source: { id: source, position: [0.5, 0.5] },
|
|
49
|
+
target: { id: target, position: [0.5, 0.5] },
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** A standalone (free) sequence-flow arrow for the prefab card. */
|
|
53
|
+
function freeSeq() {
|
|
54
|
+
return {
|
|
55
|
+
type: 'connector',
|
|
56
|
+
mode: ConnectorMode.Orthogonal,
|
|
57
|
+
stroke: SEQUENCE_STROKE,
|
|
58
|
+
strokeWidth: SEQUENCE_WIDTH,
|
|
59
|
+
strokeStyle: StrokeStyle.Solid,
|
|
60
|
+
frontEndpointStyle: PointStyle.None,
|
|
61
|
+
rearEndpointStyle: PointStyle.Triangle,
|
|
62
|
+
source: { position: [0, 0] },
|
|
63
|
+
target: { position: [140, 0] },
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const single = (el) => ({ a: el });
|
|
67
|
+
const PREVIEW_ATTRS = 'width="100%" height="100%" viewBox="0 0 135 80" xmlns="http://www.w3.org/2000/svg"';
|
|
68
|
+
const previews = {
|
|
69
|
+
process: `<svg ${PREVIEW_ATTRS} fill="none"><circle cx="16" cy="40" r="8" stroke="#43a06b" stroke-width="2"/><rect x="34" y="31" width="26" height="18" rx="3" stroke="#262626" stroke-width="1.6"/><path d="M78 31 L88 40 L78 49 L68 40 Z" stroke="#262626" stroke-width="1.4"/><path d="M73 37 L83 43 M83 37 L73 43" stroke="#262626" stroke-width="1.2"/><circle cx="118" cy="40" r="8" stroke="#cf5648" stroke-width="3"/><path d="M24 40 H34 M60 40 H68 M88 40 H110" stroke="#262626" stroke-width="1.2"/></svg>`,
|
|
70
|
+
startEvent: `<svg ${PREVIEW_ATTRS} fill="none"><circle cx="67" cy="40" r="20" stroke="#43a06b" stroke-width="3"/></svg>`,
|
|
71
|
+
endEvent: `<svg ${PREVIEW_ATTRS} fill="none"><circle cx="67" cy="40" r="20" stroke="#cf5648" stroke-width="5"/></svg>`,
|
|
72
|
+
task: `<svg ${PREVIEW_ATTRS} fill="none"><rect x="34" y="24" width="66" height="32" rx="6" stroke="#262626" stroke-width="2.4"/></svg>`,
|
|
73
|
+
gateway: `<svg ${PREVIEW_ATTRS} fill="none"><path d="M67 16 L92 40 L67 64 L42 40 Z" stroke="#262626" stroke-width="2.4" stroke-linejoin="round"/><path d="M58 31 L76 49 M76 31 L58 49" stroke="#262626" stroke-width="2.2" stroke-linecap="round"/></svg>`,
|
|
74
|
+
sequence: `<svg ${PREVIEW_ATTRS} fill="none"><path d="M24 40 H96" stroke="#262626" stroke-width="2.4" stroke-linecap="round"/><path d="M94 33 L108 40 L94 47 Z" fill="#262626"/></svg>`,
|
|
75
|
+
pool: `<svg ${PREVIEW_ATTRS} fill="none"><rect x="14" y="20" width="107" height="40" rx="3" stroke="#262626" stroke-width="2"/><path d="M30 20 V60" stroke="#262626" stroke-width="1.8"/><rect x="14" y="20" width="16" height="40" fill="#f4f4f5"/><path d="M30 20 V60" stroke="#262626" stroke-width="1.8"/></svg>`,
|
|
76
|
+
};
|
|
77
|
+
/** The lean BPMN basics: a simple worked process + every prefab the menu makes. */
|
|
78
|
+
function bpmnTemplates() {
|
|
79
|
+
const process = {
|
|
80
|
+
pool: pool(0, 0, 640, 200, 'Process'),
|
|
81
|
+
start: node('startEvent', 40, 72),
|
|
82
|
+
task1: node('task', 116, 64, 'Submit request'),
|
|
83
|
+
gw: node('gatewayExclusive', 272, 64),
|
|
84
|
+
task2: node('task', 376, 20, 'Fulfil'),
|
|
85
|
+
task3: node('task', 376, 124, 'Reject'),
|
|
86
|
+
end: node('endEvent', 556, 72),
|
|
87
|
+
c1: seq('start', 'task1'),
|
|
88
|
+
c2: seq('task1', 'gw'),
|
|
89
|
+
c3: seq('gw', 'task2'),
|
|
90
|
+
c4: seq('gw', 'task3'),
|
|
91
|
+
c5: seq('task2', 'end'),
|
|
92
|
+
c6: seq('task3', 'end'),
|
|
93
|
+
};
|
|
94
|
+
const t = (name, preview, elements) => ({
|
|
95
|
+
name,
|
|
96
|
+
type: 'template',
|
|
97
|
+
preview,
|
|
98
|
+
content: makeTemplateSnapshot(elements, name),
|
|
99
|
+
});
|
|
100
|
+
return [
|
|
101
|
+
t('Simple process', previews.process, process),
|
|
102
|
+
t('Start event', previews.startEvent, single(node('startEvent', 0, 0))),
|
|
103
|
+
t('End event', previews.endEvent, single(node('endEvent', 0, 0))),
|
|
104
|
+
t('Task', previews.task, single(node('task', 0, 0))),
|
|
105
|
+
t('Exclusive gateway', previews.gateway, single(node('gatewayExclusive', 0, 0))),
|
|
106
|
+
t('Sequence flow', previews.sequence, single(freeSeq())),
|
|
107
|
+
t('Pool', previews.pool, single(pool(0, 0, 560, 200))),
|
|
108
|
+
];
|
|
109
|
+
}
|
|
110
|
+
export const bpmnTemplateCategory = {
|
|
111
|
+
name: 'BPMN',
|
|
112
|
+
templates: bpmnTemplates(),
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { EmptyTool } from '@formicoidea/labre-core/gfx/pointer';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
declare const EdgelessBpmnMenu_base: typeof LitElement & import("@formicoidea/labre-core/global/utils").Constructor<import("@formicoidea/labre-core/widgets/edgeless-toolbar").EdgelessToolbarToolClass>;
|
|
4
|
+
/**
|
|
5
|
+
* The popover above the toolbar for the BPMN toolbox. Items create the flow
|
|
6
|
+
* objects (native shapes, so they stay editable), the pool background, and arm
|
|
7
|
+
* the native connector tool for sequence flows. Mirrors the EDGY menu.
|
|
8
|
+
*/
|
|
9
|
+
export declare class EdgelessBpmnMenu extends EdgelessBpmnMenu_base {
|
|
10
|
+
static styles: import("lit").CSSResult;
|
|
11
|
+
type: typeof EmptyTool;
|
|
12
|
+
/** Create a flow-object node (native shape) centred on the viewport. */
|
|
13
|
+
private _createNode;
|
|
14
|
+
/** Create a pool (background container) centred on the viewport. */
|
|
15
|
+
private _createPool;
|
|
16
|
+
/**
|
|
17
|
+
* Arm the native connector tool, pre-styled for a BPMN sequence flow:
|
|
18
|
+
* orthogonal, solid, with a filled triangle head. The user then draws from
|
|
19
|
+
* one node to another (endpoints attach to centers).
|
|
20
|
+
*/
|
|
21
|
+
private _activateSequenceFlow;
|
|
22
|
+
private _finish;
|
|
23
|
+
private _track;
|
|
24
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=bpmn-menu.d.ts.map
|