@formicoidea/labre-framework-bpmn 0.40.0 → 0.42.0
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/LICENSE +384 -0
- package/dist/actions.d.ts +7 -7
- package/dist/actions.js +49 -38
- package/dist/commands.js +201 -39
- package/dist/consts.d.ts +54 -2
- package/dist/consts.js +58 -2
- package/dist/export.d.ts +30 -1
- package/dist/export.js +119 -66
- package/dist/import.d.ts +65 -13
- package/dist/import.js +205 -68
- package/dist/interchange.d.ts +34 -0
- package/dist/interchange.js +112 -8
- package/dist/node/node-renderer.js +22 -32
- package/dist/presets.js +4 -3
- package/dist/templates/index.d.ts +55 -0
- package/dist/templates/index.js +126 -38
- package/dist/toolbar/bpmn-senior-button.d.ts +2 -0
- package/dist/toolbar/bpmn-senior-button.js +6 -2
- package/dist/toolbar/config.d.ts +22 -11
- package/dist/toolbar/config.js +39 -39
- package/dist/toolbar/icons.d.ts +9 -2
- package/dist/toolbar/icons.js +9 -6
- package/dist/toolbar/palette.d.ts +23 -0
- package/dist/toolbar/palette.js +65 -0
- package/dist/translations.js +76 -3
- package/dist/view.js +18 -14
- package/package.json +2 -2
|
@@ -12,7 +12,6 @@ import { DefaultTheme, } from '@formicoidea/labre-core/model';
|
|
|
12
12
|
*
|
|
13
13
|
* - events — envelope (message), clock (timer), solid disc (terminate);
|
|
14
14
|
* - tasks — a person (user) or a gear (service) in the top-left corner;
|
|
15
|
-
* - activity — the `+` box at the bottom edge (sub-process, call activity);
|
|
16
15
|
* - gateway — the X (exclusive) or the `+` (parallel);
|
|
17
16
|
* - data — folded page, cylinder, open bracket.
|
|
18
17
|
*
|
|
@@ -34,6 +33,13 @@ import { DefaultTheme, } from '@formicoidea/labre-core/model';
|
|
|
34
33
|
* two and the one that is legible zoomed out.
|
|
35
34
|
* - The **timer** has no hour ticks and the **data store** no shelf lines: at
|
|
36
35
|
* the sizes this canvas draws them, both read as noise around the shape.
|
|
36
|
+
* - The **collapsed `[+]`** of the sub-process and the call activity is not
|
|
37
|
+
* drawn at all. In bpmn.io that boxed plus is a BUTTON — it unfolds the
|
|
38
|
+
* process the box stands for. Labre has no such gesture: a process defined
|
|
39
|
+
* elsewhere is a linked document, which carries a symbol of its own. Drawn
|
|
40
|
+
* here the marker would promise an action nothing performs, so the two kinds
|
|
41
|
+
* are bare and the call activity is told apart by its thick border, a
|
|
42
|
+
* creation-time preset (`CALL_ACTIVITY_WIDTH` in `consts.ts`).
|
|
37
43
|
*
|
|
38
44
|
* Mirrors the EDGY node renderer.
|
|
39
45
|
*/
|
|
@@ -41,13 +47,19 @@ import { DefaultTheme, } from '@formicoidea/labre-core/model';
|
|
|
41
47
|
* The artefacts BPMN draws BARE — a plain native shape with nothing on it.
|
|
42
48
|
* Everything else in the union is decorated here.
|
|
43
49
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
50
|
+
* Three of them are here because the notation puts no marker on them at all.
|
|
51
|
+
* The other three are here for reasons of their own:
|
|
52
|
+
*
|
|
53
|
+
* - `group` has a distinctive look — a dashed, rounded, unfilled rectangle —
|
|
54
|
+
* and it is bare because that look is expressible as a native shape's own
|
|
55
|
+
* properties (`strokeStyle: dash`, `radius`, `filled: false`). Drawing it by
|
|
56
|
+
* hand would have meant re-implementing dashes the shape renderer already
|
|
57
|
+
* does, and losing the editability that comes free with them.
|
|
58
|
+
* - `subProcess` and `callActivity` do carry a marker in the notation — the
|
|
59
|
+
* collapsed `[+]` — and Labre drops it on purpose, because here it opens
|
|
60
|
+
* nothing (see the note on simplifications above). What tells the call
|
|
61
|
+
* activity from the sub-process is its thick border, a creation-time preset
|
|
62
|
+
* rather than anything drawn here.
|
|
51
63
|
*
|
|
52
64
|
* Written as the short list rather than the long one, so that the glyph kinds
|
|
53
65
|
* are DERIVED from the model's union instead of restated beside it: a kind
|
|
@@ -61,6 +73,8 @@ const UNDECORATED_KINDS = {
|
|
|
61
73
|
startEvent: true,
|
|
62
74
|
endEvent: true,
|
|
63
75
|
task: true,
|
|
76
|
+
subProcess: true,
|
|
77
|
+
callActivity: true,
|
|
64
78
|
group: true,
|
|
65
79
|
};
|
|
66
80
|
const isUndecorated = (kind) => Object.hasOwn(UNDECORATED_KINDS, kind);
|
|
@@ -204,30 +218,6 @@ export const bpmnNode = (model, ctx, matrix, renderer, rc, bound) => {
|
|
|
204
218
|
ctx.stroke();
|
|
205
219
|
return;
|
|
206
220
|
}
|
|
207
|
-
if (kind === 'subProcess' || kind === 'callActivity') {
|
|
208
|
-
// The collapsed marker: a small boxed `+` on the bottom edge, saying
|
|
209
|
-
// "there is a whole process folded up in here". The call activity carries
|
|
210
|
-
// the SAME marker — what tells the two apart is its thick border, which is
|
|
211
|
-
// a creation-time preset rather than anything drawn here.
|
|
212
|
-
const side = unit * 0.2;
|
|
213
|
-
const bx = cx;
|
|
214
|
-
const by = h - unit * 0.1 - side / 2;
|
|
215
|
-
const half = side / 2;
|
|
216
|
-
const arm = side * 0.3;
|
|
217
|
-
ctx.lineWidth = Math.max(1, unit * 0.028);
|
|
218
|
-
ctx.beginPath();
|
|
219
|
-
ctx.moveTo(bx - half, by - half);
|
|
220
|
-
ctx.lineTo(bx + half, by - half);
|
|
221
|
-
ctx.lineTo(bx + half, by + half);
|
|
222
|
-
ctx.lineTo(bx - half, by + half);
|
|
223
|
-
ctx.lineTo(bx - half, by - half);
|
|
224
|
-
ctx.moveTo(bx - arm, by);
|
|
225
|
-
ctx.lineTo(bx + arm, by);
|
|
226
|
-
ctx.moveTo(bx, by - arm);
|
|
227
|
-
ctx.lineTo(bx, by + arm);
|
|
228
|
-
ctx.stroke();
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
221
|
// ── Data and artifacts: the glyph IS the body ────────────────────────
|
|
232
222
|
// The native rect under these three is unfilled and unstroked, so both the
|
|
233
223
|
// fill and the outline are drawn here — off the model's own colours, which
|
package/dist/presets.js
CHANGED
|
@@ -29,9 +29,10 @@ export const NODE_PRESETS = {
|
|
|
29
29
|
stroke: EVENT_END,
|
|
30
30
|
width: END_WIDTH,
|
|
31
31
|
},
|
|
32
|
-
// Activities: the same rounded rectangle, and a marker tells
|
|
33
|
-
//
|
|
34
|
-
//
|
|
32
|
+
// Activities: the same rounded rectangle, and a corner marker tells the two
|
|
33
|
+
// typed tasks apart. The sub-process wears nothing (its collapsed `+` opens
|
|
34
|
+
// nothing here, so it is not drawn) and the call activity's thick border IS
|
|
35
|
+
// its distinction.
|
|
35
36
|
task: {
|
|
36
37
|
shapeType: 'rect',
|
|
37
38
|
stroke: NEUTRAL_STROKE,
|
|
@@ -1,2 +1,57 @@
|
|
|
1
1
|
import { type TemplateCategory } from '@formicoidea/labre-core/gfx/template';
|
|
2
|
+
import { type ChromeWording } from '@formicoidea/labre-core/shared/services';
|
|
3
|
+
/**
|
|
4
|
+
* The seeds the two worked scenes write — declared once so the scene builder
|
|
5
|
+
* and the manifest ({@link ../translations.ts}) read the very same fallback,
|
|
6
|
+
* never a restated literal. `com.labre.bpmn.example.<scene>.<slug>`, per
|
|
7
|
+
* `docs/adr/0023`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SIMPLE_PROCESS_SEED: {
|
|
10
|
+
readonly poolName: {
|
|
11
|
+
readonly key: "com.labre.bpmn.example.simple-process.pool-name";
|
|
12
|
+
readonly fallback: "Process";
|
|
13
|
+
};
|
|
14
|
+
readonly submitRequest: {
|
|
15
|
+
readonly key: "com.labre.bpmn.example.simple-process.submit-request";
|
|
16
|
+
readonly fallback: "Submit request";
|
|
17
|
+
};
|
|
18
|
+
readonly fulfil: {
|
|
19
|
+
readonly key: "com.labre.bpmn.example.simple-process.fulfil";
|
|
20
|
+
readonly fallback: "Fulfil";
|
|
21
|
+
};
|
|
22
|
+
readonly reject: {
|
|
23
|
+
readonly key: "com.labre.bpmn.example.simple-process.reject";
|
|
24
|
+
readonly fallback: "Reject";
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* The two worked scenes' and the free-standing "Sequence flow" swatch's own
|
|
29
|
+
* tile names — a `nameKey` per hand-composed card, since none of the three
|
|
30
|
+
* derives from a command (`Template.nameKey`; `resolveTemplateName` checks it
|
|
31
|
+
* BEFORE `commandId`). `com.labre.bpmn.template.<slug>`, distinct from the
|
|
32
|
+
* `com.labre.bpmn.example.<scene>.*` seeds the two scenes WRITE — a tile name
|
|
33
|
+
* is chrome (re-rendered every time the panel opens), a seed is content
|
|
34
|
+
* (translated once, at insertion).
|
|
35
|
+
*/
|
|
36
|
+
export declare const BPMN_TEMPLATE_NAME_SIMPLE_PROCESS: ChromeWording;
|
|
37
|
+
export declare const BPMN_TEMPLATE_NAME_MESSAGE_EXCHANGE: ChromeWording;
|
|
38
|
+
export declare const BPMN_TEMPLATE_NAME_SEQUENCE_FLOW: ChromeWording;
|
|
39
|
+
export declare const MESSAGE_EXCHANGE_SEED: {
|
|
40
|
+
readonly customer: {
|
|
41
|
+
readonly key: "com.labre.bpmn.example.message-exchange.customer";
|
|
42
|
+
readonly fallback: "Customer";
|
|
43
|
+
};
|
|
44
|
+
readonly supplier: {
|
|
45
|
+
readonly key: "com.labre.bpmn.example.message-exchange.supplier";
|
|
46
|
+
readonly fallback: "Supplier";
|
|
47
|
+
};
|
|
48
|
+
readonly placeOrder: {
|
|
49
|
+
readonly key: "com.labre.bpmn.example.message-exchange.place-order";
|
|
50
|
+
readonly fallback: "Place order";
|
|
51
|
+
};
|
|
52
|
+
readonly confirmOrder: {
|
|
53
|
+
readonly key: "com.labre.bpmn.example.message-exchange.confirm-order";
|
|
54
|
+
readonly fallback: "Confirm order";
|
|
55
|
+
};
|
|
56
|
+
};
|
|
2
57
|
export declare const bpmnTemplateCategory: TemplateCategory;
|
package/dist/templates/index.js
CHANGED
|
@@ -1,9 +1,81 @@
|
|
|
1
1
|
import { makeTemplateSnapshot, surfaceText, templateFromCommand, } from '@formicoidea/labre-core/gfx/template';
|
|
2
2
|
import { ConnectorMode, PointStyle, StrokeStyle, } from '@formicoidea/labre-core/model';
|
|
3
|
+
import { translateKey, } from '@formicoidea/labre-core/shared/services';
|
|
3
4
|
import { bpmnCommands } from '../commands.js';
|
|
4
5
|
import { EVENT_END, EVENT_START, GROUP_STROKE, MESSAGE_STROKE, MESSAGE_WIDTH, NEUTRAL_STROKE, NODE_SIZE, POOL_BAND_FILL, POOL_FRAME_COLOR, SEQUENCE_STROKE, SEQUENCE_WIDTH, } from '../consts.js';
|
|
5
6
|
import { bpmnNodeProps, bpmnPoolProps } from '../presets.js';
|
|
6
7
|
import { BPMN_ROLE } from '../roles.js';
|
|
8
|
+
/**
|
|
9
|
+
* The seeds the two worked scenes write — declared once so the scene builder
|
|
10
|
+
* and the manifest ({@link ../translations.ts}) read the very same fallback,
|
|
11
|
+
* never a restated literal. `com.labre.bpmn.example.<scene>.<slug>`, per
|
|
12
|
+
* `docs/adr/0023`.
|
|
13
|
+
*/
|
|
14
|
+
export const SIMPLE_PROCESS_SEED = {
|
|
15
|
+
poolName: {
|
|
16
|
+
key: 'com.labre.bpmn.example.simple-process.pool-name',
|
|
17
|
+
fallback: 'Process',
|
|
18
|
+
},
|
|
19
|
+
submitRequest: {
|
|
20
|
+
key: 'com.labre.bpmn.example.simple-process.submit-request',
|
|
21
|
+
fallback: 'Submit request',
|
|
22
|
+
},
|
|
23
|
+
fulfil: {
|
|
24
|
+
key: 'com.labre.bpmn.example.simple-process.fulfil',
|
|
25
|
+
fallback: 'Fulfil',
|
|
26
|
+
},
|
|
27
|
+
reject: {
|
|
28
|
+
key: 'com.labre.bpmn.example.simple-process.reject',
|
|
29
|
+
fallback: 'Reject',
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The two worked scenes' and the free-standing "Sequence flow" swatch's own
|
|
34
|
+
* tile names — a `nameKey` per hand-composed card, since none of the three
|
|
35
|
+
* derives from a command (`Template.nameKey`; `resolveTemplateName` checks it
|
|
36
|
+
* BEFORE `commandId`). `com.labre.bpmn.template.<slug>`, distinct from the
|
|
37
|
+
* `com.labre.bpmn.example.<scene>.*` seeds the two scenes WRITE — a tile name
|
|
38
|
+
* is chrome (re-rendered every time the panel opens), a seed is content
|
|
39
|
+
* (translated once, at insertion).
|
|
40
|
+
*/
|
|
41
|
+
export const BPMN_TEMPLATE_NAME_SIMPLE_PROCESS = [
|
|
42
|
+
'com.labre.bpmn.template.simple-process',
|
|
43
|
+
'Simple process',
|
|
44
|
+
];
|
|
45
|
+
export const BPMN_TEMPLATE_NAME_MESSAGE_EXCHANGE = [
|
|
46
|
+
'com.labre.bpmn.template.message-exchange',
|
|
47
|
+
'Message exchange',
|
|
48
|
+
];
|
|
49
|
+
export const BPMN_TEMPLATE_NAME_SEQUENCE_FLOW = [
|
|
50
|
+
'com.labre.bpmn.template.sequence-flow',
|
|
51
|
+
'Sequence flow',
|
|
52
|
+
];
|
|
53
|
+
export const MESSAGE_EXCHANGE_SEED = {
|
|
54
|
+
customer: {
|
|
55
|
+
key: 'com.labre.bpmn.example.message-exchange.customer',
|
|
56
|
+
fallback: 'Customer',
|
|
57
|
+
},
|
|
58
|
+
supplier: {
|
|
59
|
+
key: 'com.labre.bpmn.example.message-exchange.supplier',
|
|
60
|
+
fallback: 'Supplier',
|
|
61
|
+
},
|
|
62
|
+
placeOrder: {
|
|
63
|
+
key: 'com.labre.bpmn.example.message-exchange.place-order',
|
|
64
|
+
fallback: 'Place order',
|
|
65
|
+
},
|
|
66
|
+
confirmOrder: {
|
|
67
|
+
key: 'com.labre.bpmn.example.message-exchange.confirm-order',
|
|
68
|
+
fallback: 'Confirm order',
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* One seed's resolved text — the host's catalogue when `std` is a real
|
|
73
|
+
* inserting editor, the English fallback when building the module's own
|
|
74
|
+
* `content` (no editor exists yet at that point).
|
|
75
|
+
*/
|
|
76
|
+
function seedText(std, def) {
|
|
77
|
+
return std ? translateKey(std, def.key, def.fallback) : def.fallback;
|
|
78
|
+
}
|
|
7
79
|
/**
|
|
8
80
|
* The BPMN palette — DERIVED from the toolbox, one template per artefact
|
|
9
81
|
* command.
|
|
@@ -139,8 +211,6 @@ const taskPreview = (glyph = '', width = 2.4) => `<svg ${A} fill="none"><rect x=
|
|
|
139
211
|
const gatewayPreview = (marker) => `<svg ${A} fill="none"><path d="M67 16 L92 40 L67 64 L42 40 Z" stroke="${NEUTRAL_STROKE}" stroke-width="2.4" stroke-linejoin="round"/><path d="${marker}" stroke="${NEUTRAL_STROKE}" stroke-width="2.2" stroke-linecap="round"/></svg>`;
|
|
140
212
|
const ENVELOPE = `<rect x="59" y="35" width="16" height="11" stroke="${NEUTRAL_STROKE}" stroke-width="1.4"/><path d="M59 35 L67 42 L75 35" stroke="${NEUTRAL_STROKE}" stroke-width="1.4" stroke-linejoin="round"/>`;
|
|
141
213
|
const CLOCK = `<circle cx="67" cy="40" r="9" stroke="${NEUTRAL_STROKE}" stroke-width="1.4"/><path d="M67 40 V33 M67 40 L72 43" stroke="${NEUTRAL_STROKE}" stroke-width="1.4" stroke-linecap="round"/>`;
|
|
142
|
-
/** The collapsed `[+]`, on the activity's bottom edge — sub-process and call alike. */
|
|
143
|
-
const COLLAPSED = `<rect x="61" y="44" width="12" height="12" stroke="${NEUTRAL_STROKE}" stroke-width="1.4"/><path d="M67 47 V53 M64 50 H70" stroke="${NEUTRAL_STROKE}" stroke-width="1.4" stroke-linecap="round"/>`;
|
|
144
214
|
const previews = {
|
|
145
215
|
process: `<svg ${A} fill="none"><circle cx="16" cy="40" r="8" stroke="${EVENT_START}" stroke-width="2"/><rect x="34" y="31" width="26" height="18" rx="3" stroke="${NEUTRAL_STROKE}" stroke-width="1.6"/><path d="M78 31 L88 40 L78 49 L68 40 Z" stroke="${NEUTRAL_STROKE}" stroke-width="1.4"/><path d="M73 37 L83 43 M83 37 L73 43" stroke="${NEUTRAL_STROKE}" stroke-width="1.2"/><circle cx="118" cy="40" r="8" stroke="${EVENT_END}" stroke-width="3"/><path d="M24 40 H34 M60 40 H68 M88 40 H110" stroke="${SEQUENCE_STROKE}" stroke-width="1.2"/></svg>`,
|
|
146
216
|
startEvent: eventPreview(EVENT_START, 3),
|
|
@@ -152,10 +222,13 @@ const previews = {
|
|
|
152
222
|
task: taskPreview(),
|
|
153
223
|
taskUser: taskPreview(`<circle cx="41" cy="31" r="2.6" stroke="${NEUTRAL_STROKE}" stroke-width="1.2"/><path d="M37.4 38 a3.6 3.6 0 0 1 7.2 0" stroke="${NEUTRAL_STROKE}" stroke-width="1.2"/>`),
|
|
154
224
|
taskService: taskPreview(`<circle cx="41" cy="32" r="3.4" stroke="${NEUTRAL_STROKE}" stroke-width="1.2"/><circle cx="41" cy="32" r="1" fill="${NEUTRAL_STROKE}"/><path d="M41 27.4 V29 M41 35 V36.6 M36.4 32 H38 M44 32 H45.6" stroke="${NEUTRAL_STROKE}" stroke-width="1.2" stroke-linecap="round"/>`),
|
|
155
|
-
|
|
225
|
+
// Neither carries the notation's collapsed `[+]`: it opens nothing in Labre
|
|
226
|
+
// and the board does not paint it, so a card that did would be advertising a
|
|
227
|
+
// drawing the command never makes.
|
|
228
|
+
subProcess: taskPreview(),
|
|
156
229
|
// The thick border IS the distinction: this box stands for a process defined
|
|
157
230
|
// elsewhere (`presets.ts`, `CALL_ACTIVITY_WIDTH`).
|
|
158
|
-
callActivity: taskPreview(
|
|
231
|
+
callActivity: taskPreview('', 4.5),
|
|
159
232
|
gateway: gatewayPreview('M58 31 L76 49 M76 31 L58 49'),
|
|
160
233
|
gatewayParallel: gatewayPreview('M67 30 V50 M57 40 H77'),
|
|
161
234
|
dataObject: `<svg ${A} fill="none"><path d="M52 14 H76 L88 26 V66 H52 Z" stroke="${NEUTRAL_STROKE}" stroke-width="2.2" stroke-linejoin="round"/><path d="M76 14 V26 H88" stroke="${NEUTRAL_STROKE}" stroke-width="1.8" stroke-linejoin="round"/></svg>`,
|
|
@@ -172,28 +245,39 @@ const previews = {
|
|
|
172
245
|
messageExchange: `<svg ${A} fill="none"><rect x="14" y="8" width="107" height="27" rx="3" stroke="${POOL_FRAME_COLOR}" stroke-width="1.6"/><rect x="14" y="8" width="11" height="27" fill="${POOL_BAND_FILL}"/><path d="M25 8 V35" stroke="${POOL_FRAME_COLOR}" stroke-width="1.4"/><rect x="14" y="45" width="107" height="27" rx="3" stroke="${POOL_FRAME_COLOR}" stroke-width="1.6"/><rect x="14" y="45" width="11" height="27" fill="${POOL_BAND_FILL}"/><path d="M25 45 V72" stroke="${POOL_FRAME_COLOR}" stroke-width="1.4"/><circle cx="33" cy="21.5" r="4.5" stroke="${EVENT_START}" stroke-width="1.6"/><rect x="46" y="14" width="26" height="15" rx="3" stroke="${NEUTRAL_STROKE}" stroke-width="1.6"/><circle cx="88" cy="21.5" r="4.5" stroke="${EVENT_END}" stroke-width="2.6"/><rect x="46" y="51" width="26" height="15" rx="3" stroke="${NEUTRAL_STROKE}" stroke-width="1.6"/><path d="M41 21.5 H46 M72 21.5 H83" stroke="${SEQUENCE_STROKE}" stroke-width="1.4"/><circle cx="59" cy="31.5" r="2.2" fill="${MESSAGE_STROKE}"/><path d="M59 34 V48" stroke="${MESSAGE_STROKE}" stroke-width="1.4" stroke-dasharray="3 2.4"/><path d="M56 46 L59 50 L62 46" stroke="${MESSAGE_STROKE}" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
|
|
173
246
|
};
|
|
174
247
|
/* ── The two worked scenes ────────────────────────────────────────────────── */
|
|
175
|
-
/**
|
|
176
|
-
|
|
248
|
+
/**
|
|
249
|
+
* A hand-composed card — what is left once the artefacts are derived.
|
|
250
|
+
*
|
|
251
|
+
* `build` takes the OPTIONAL inserting editor: called with none, at module
|
|
252
|
+
* load, for the English `content`; called again with the real `std` as
|
|
253
|
+
* {@link Template.localize}, so the two builds read the very same layout and
|
|
254
|
+
* differ only in the words a seed resolves to (`docs/adr/0023`).
|
|
255
|
+
*/
|
|
256
|
+
const scene = (name, preview, build, nameKey) => ({
|
|
177
257
|
name,
|
|
178
258
|
type: 'template',
|
|
179
259
|
preview,
|
|
180
|
-
|
|
260
|
+
nameKey,
|
|
261
|
+
content: makeTemplateSnapshot(build(), name),
|
|
262
|
+
localize: std => makeTemplateSnapshot(build(std), name),
|
|
181
263
|
});
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
264
|
+
function process(std) {
|
|
265
|
+
return {
|
|
266
|
+
pool: pool(0, 0, 640, 200, seedText(std, SIMPLE_PROCESS_SEED.poolName)),
|
|
267
|
+
start: node('startEvent', 40, 72),
|
|
268
|
+
task1: node('task', 116, 64, seedText(std, SIMPLE_PROCESS_SEED.submitRequest)),
|
|
269
|
+
gw: node('gatewayExclusive', 272, 64),
|
|
270
|
+
task2: node('task', 376, 20, seedText(std, SIMPLE_PROCESS_SEED.fulfil)),
|
|
271
|
+
task3: node('task', 376, 124, seedText(std, SIMPLE_PROCESS_SEED.reject)),
|
|
272
|
+
end: node('endEvent', 556, 72),
|
|
273
|
+
c1: seq('start', 'task1'),
|
|
274
|
+
c2: seq('task1', 'gw'),
|
|
275
|
+
c3: seq('gw', 'task2'),
|
|
276
|
+
c4: seq('gw', 'task3'),
|
|
277
|
+
c5: seq('task2', 'end'),
|
|
278
|
+
c6: seq('task3', 'end'),
|
|
279
|
+
};
|
|
280
|
+
}
|
|
197
281
|
/**
|
|
198
282
|
* Two participants, and the one arrow that is allowed to cross between them.
|
|
199
283
|
*
|
|
@@ -216,30 +300,34 @@ const process = {
|
|
|
216
300
|
* until this slice ran the rules over the shipped cards. The customer's process
|
|
217
301
|
* now closes where it should: order placed, then done.
|
|
218
302
|
*/
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
303
|
+
function messageExchange(std) {
|
|
304
|
+
return {
|
|
305
|
+
customer: pool(0, 0, 640, 200, seedText(std, MESSAGE_EXCHANGE_SEED.customer)),
|
|
306
|
+
supplier: pool(0, 240, 640, 200, seedText(std, MESSAGE_EXCHANGE_SEED.supplier)),
|
|
307
|
+
start: node('startEvent', 40, 72),
|
|
308
|
+
ask: node('taskUser', 140, 64, seedText(std, MESSAGE_EXCHANGE_SEED.placeOrder)),
|
|
309
|
+
done: node('endEvent', 320, 72),
|
|
310
|
+
answer: node('taskService', 140, 304, seedText(std, MESSAGE_EXCHANGE_SEED.confirmOrder)),
|
|
311
|
+
// Inside the first participant: what happens, and in what order.
|
|
312
|
+
inside: seq('start', 'ask'),
|
|
313
|
+
closes: seq('ask', 'done'),
|
|
314
|
+
// Across the two: who told whom.
|
|
315
|
+
across: msg('ask', 'answer'),
|
|
316
|
+
};
|
|
317
|
+
}
|
|
232
318
|
export const bpmnTemplateCategory = {
|
|
233
319
|
name: 'BPMN',
|
|
320
|
+
// Reuses the senior button's own key — see `TemplateCategory.nameKey`.
|
|
321
|
+
nameKey: 'com.labre.framework.bpmn',
|
|
234
322
|
templates: [
|
|
235
|
-
scene('Simple process', previews.process, process),
|
|
236
|
-
scene('Message exchange', previews.messageExchange, messageExchange),
|
|
323
|
+
scene('Simple process', previews.process, process, BPMN_TEMPLATE_NAME_SIMPLE_PROCESS[0]),
|
|
324
|
+
scene('Message exchange', previews.messageExchange, messageExchange, BPMN_TEMPLATE_NAME_MESSAGE_EXCHANGE[0]),
|
|
237
325
|
/* ── The core: a drawable process, from the first click ─────────────── */
|
|
238
326
|
templateFromCommand(byId('bpmn.addStartEvent'), previews.startEvent),
|
|
239
327
|
templateFromCommand(byId('bpmn.addEndEvent'), previews.endEvent),
|
|
240
328
|
templateFromCommand(byId('bpmn.addTask'), previews.task),
|
|
241
329
|
templateFromCommand(byId('bpmn.addExclusiveGateway'), previews.gateway),
|
|
242
|
-
scene('Sequence flow', previews.sequence, { a: freeSeq() }),
|
|
330
|
+
scene('Sequence flow', previews.sequence, () => ({ a: freeSeq() }), BPMN_TEMPLATE_NAME_SEQUENCE_FLOW[0]),
|
|
243
331
|
templateFromCommand(byId('bpmn.addPool'), previews.pool),
|
|
244
332
|
/* ── Activities ─────────────────────────────────────────────────────── */
|
|
245
333
|
templateFromCommand(byId('bpmn.addUserTask'), previews.taskUser),
|
|
@@ -10,6 +10,8 @@ export declare class EdgelessBpmnSeniorButton extends EdgelessBpmnSeniorButton_b
|
|
|
10
10
|
enableActiveBackground: boolean;
|
|
11
11
|
type: typeof EmptyTool;
|
|
12
12
|
private _toggleMenu;
|
|
13
|
+
/** Lit while one of THIS framework's artefacts is armed. See the Wardley one. */
|
|
14
|
+
private get _armed();
|
|
13
15
|
render(): import("lit-html").TemplateResult<1>;
|
|
14
16
|
}
|
|
15
17
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DefaultTool } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import { EmptyTool } from '@formicoidea/labre-core/gfx/pointer';
|
|
3
3
|
import { translateKey } from '@formicoidea/labre-core/shared/services';
|
|
4
|
-
import { EdgelessToolbarToolMixin } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
|
|
4
|
+
import { armedArtefact, EdgelessToolbarToolMixin, } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
|
|
5
5
|
import { SignalWatcher } from '@formicoidea/labre-core/global/lit';
|
|
6
6
|
import { css, html, LitElement } from 'lit';
|
|
7
7
|
import { bpmnToolbarIcon } from './icons.js';
|
|
@@ -72,6 +72,10 @@ export class EdgelessBpmnSeniorButton extends EdgelessToolbarToolMixin(SignalWat
|
|
|
72
72
|
const menu = this.createPopper('edgeless-bpmn-menu', this);
|
|
73
73
|
menu.element.edgeless = this.edgeless;
|
|
74
74
|
}
|
|
75
|
+
/** Lit while one of THIS framework's artefacts is armed. See the Wardley one. */
|
|
76
|
+
get _armed() {
|
|
77
|
+
return armedArtefact(this.gfx)?.owner === 'bpmn';
|
|
78
|
+
}
|
|
75
79
|
render() {
|
|
76
80
|
return html `<edgeless-toolbar-button
|
|
77
81
|
class="bpmn-button"
|
|
@@ -79,7 +83,7 @@ export class EdgelessBpmnSeniorButton extends EdgelessToolbarToolMixin(SignalWat
|
|
|
79
83
|
? ''
|
|
80
84
|
: translateKey(this.edgeless.std, 'com.labre.framework.bpmn', 'BPMN')}
|
|
81
85
|
.tooltipOffset=${4}
|
|
82
|
-
.active=${!!this.popper}
|
|
86
|
+
.active=${!!this.popper || this._armed}
|
|
83
87
|
@click=${this._toggleMenu}
|
|
84
88
|
>
|
|
85
89
|
<div class="bpmn-root">
|
package/dist/toolbar/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type ChromeWording, type ToolbarContext, type ToolbarModuleConfig } from '@formicoidea/labre-core/shared/services';
|
|
2
2
|
import { type TemplateResult } from 'lit';
|
|
3
3
|
export declare const bpmnPoolToolbarConfig: {
|
|
4
4
|
readonly actions: [{
|
|
@@ -24,16 +24,27 @@ export declare const bpmnPoolToolbarConfig: {
|
|
|
24
24
|
tooltip: string;
|
|
25
25
|
run: (runCtx: ToolbarContext) => void;
|
|
26
26
|
};
|
|
27
|
-
},
|
|
28
|
-
id: string;
|
|
29
|
-
placement: ActionPlacement;
|
|
30
|
-
when: (ctx: ToolbarContext) => boolean;
|
|
31
|
-
generate: (ctx: ToolbarContext) => {
|
|
32
|
-
icon: TemplateResult;
|
|
33
|
-
label: string;
|
|
34
|
-
run: (runCtx: ToolbarContext) => void;
|
|
35
|
-
};
|
|
36
|
-
}];
|
|
27
|
+
}, import("@formicoidea/labre-core/shared/services").ToolbarActionGenerator];
|
|
37
28
|
readonly when: (ctx: ToolbarContext) => boolean;
|
|
38
29
|
};
|
|
39
30
|
export declare const bpmnPoolToolbarExtension: import("@formicoidea/labre-core/store/index.js").ExtensionType;
|
|
31
|
+
/**
|
|
32
|
+
* The pool's FLAG-GATED row: the legend and the validation dropdown, in one
|
|
33
|
+
* module because a flavour may carry exactly one (a second on the same key
|
|
34
|
+
* throws `DuplicateServiceDefinitionError` before the editor finishes setting
|
|
35
|
+
* up — the same merge C4's board makes for the same reason).
|
|
36
|
+
*
|
|
37
|
+
* `c.legend` and not `b.legend`: the toolbar sorts lexicographically by id
|
|
38
|
+
* after partitioning by placement, and `'b.add-lane' < 'b.legend' <
|
|
39
|
+
* 'b.remove-lane'` would wedge the button between the two lane gestures. `c.`
|
|
40
|
+
* puts it where it belongs — resize · add lane · remove lane · **Legend** ·
|
|
41
|
+
* Validation, with Export XML in the "⋮".
|
|
42
|
+
*
|
|
43
|
+
* Gated, because GENERATING a legend is tooling (ADR 0026, amending 0009). What
|
|
44
|
+
* the gesture already wrote is document content and keeps painting with the
|
|
45
|
+
* flag off: the box is plain shapes and text plus `bpmnNode`s the always-on
|
|
46
|
+
* renderer paints, and the pool keeps its resize handle and its lanes either
|
|
47
|
+
* way.
|
|
48
|
+
*/
|
|
49
|
+
export declare const bpmnPoolToolingToolbarConfig: ToolbarModuleConfig;
|
|
50
|
+
export declare const bpmnPoolToolingToolbarExtension: import("@formicoidea/labre-core/store/index.js").ExtensionType;
|
package/dist/toolbar/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EdgelessCRUDIdentifier } from '@formicoidea/labre-core/blocks/surface';
|
|
1
|
+
import { EdgelessCRUDIdentifier, legendToolbarAction, validationToolbarConfig, } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import { BpmnPoolElementModel } from '@formicoidea/labre-core/model';
|
|
3
|
-
import {
|
|
3
|
+
import { BOARD_RESIZE_TOGGLE, commandMoreAction, ToolbarModuleExtension, translateKey, } from '@formicoidea/labre-core/shared/services';
|
|
4
4
|
import { BlockFlavourIdentifier, getRegisteredCommands, runCommand, } from '@formicoidea/labre-core/std';
|
|
5
5
|
import { html } from 'lit';
|
|
6
6
|
import { bpmnExportXmlIcon, bpmnLaneAddIcon, bpmnLaneRemoveIcon, } from './icons.js';
|
|
@@ -84,43 +84,6 @@ function commandAction(id, commandId, labelKey, labelFallback, icon) {
|
|
|
84
84
|
},
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
|
-
/**
|
|
88
|
-
* The same thing, for the "⋮" menu instead of the row.
|
|
89
|
-
*
|
|
90
|
-
* Two differences, and the widget imposes both: a menu line is drawn from
|
|
91
|
-
* `label` (a tooltip on a line that is already words would be a second copy of
|
|
92
|
-
* them), and `placement: ActionPlacement.More` is what partitions it out of the
|
|
93
|
-
* row in the first place — `renderToolbar` splits on exactly that flag, and the
|
|
94
|
-
* entries it collects come from every module contributing to the element,
|
|
95
|
-
* so a framework can add to the "⋮" without owning it.
|
|
96
|
-
*/
|
|
97
|
-
function commandMoreAction(id, commandId, labelKey, labelFallback, icon) {
|
|
98
|
-
return {
|
|
99
|
-
id,
|
|
100
|
-
placement: ActionPlacement.More,
|
|
101
|
-
when: (ctx) => {
|
|
102
|
-
const command = findCommand(ctx, commandId);
|
|
103
|
-
return command !== undefined && (command.when?.(ctx.std) ?? true);
|
|
104
|
-
},
|
|
105
|
-
generate: (ctx) => ({
|
|
106
|
-
icon,
|
|
107
|
-
label: translateKey(ctx.std, labelKey, labelFallback),
|
|
108
|
-
run: (runCtx) => {
|
|
109
|
-
const command = findCommand(runCtx, commandId);
|
|
110
|
-
if (!command)
|
|
111
|
-
return;
|
|
112
|
-
// The same `source` the row's own entries report: the "⋮" is a
|
|
113
|
-
// degradation of the row, not a surface of its own, and the
|
|
114
|
-
// `ElementCreationSource` union deliberately names places rather than
|
|
115
|
-
// widths (`docs/adr/0008`).
|
|
116
|
-
runCommand(runCtx.std, command, {
|
|
117
|
-
surface: 'contextual-toolbar',
|
|
118
|
-
source: 'toolbar:general',
|
|
119
|
-
});
|
|
120
|
-
},
|
|
121
|
-
}),
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
87
|
const findCommand = (ctx, id) => getRegisteredCommands(ctx.std).find(candidate => candidate.id === id);
|
|
125
88
|
export const bpmnPoolToolbarConfig = {
|
|
126
89
|
actions: [
|
|
@@ -141,3 +104,40 @@ export const bpmnPoolToolbarExtension = ToolbarModuleExtension({
|
|
|
141
104
|
id: BlockFlavourIdentifier('affine:surface:bpmnPool'),
|
|
142
105
|
config: bpmnPoolToolbarConfig,
|
|
143
106
|
});
|
|
107
|
+
/**
|
|
108
|
+
* The pool's FLAG-GATED row: the legend and the validation dropdown, in one
|
|
109
|
+
* module because a flavour may carry exactly one (a second on the same key
|
|
110
|
+
* throws `DuplicateServiceDefinitionError` before the editor finishes setting
|
|
111
|
+
* up — the same merge C4's board makes for the same reason).
|
|
112
|
+
*
|
|
113
|
+
* `c.legend` and not `b.legend`: the toolbar sorts lexicographically by id
|
|
114
|
+
* after partitioning by placement, and `'b.add-lane' < 'b.legend' <
|
|
115
|
+
* 'b.remove-lane'` would wedge the button between the two lane gestures. `c.`
|
|
116
|
+
* puts it where it belongs — resize · add lane · remove lane · **Legend** ·
|
|
117
|
+
* Validation, with Export XML in the "⋮".
|
|
118
|
+
*
|
|
119
|
+
* Gated, because GENERATING a legend is tooling (ADR 0026, amending 0009). What
|
|
120
|
+
* the gesture already wrote is document content and keeps painting with the
|
|
121
|
+
* flag off: the box is plain shapes and text plus `bpmnNode`s the always-on
|
|
122
|
+
* renderer paints, and the pool keeps its resize handle and its lanes either
|
|
123
|
+
* way.
|
|
124
|
+
*/
|
|
125
|
+
export const bpmnPoolToolingToolbarConfig = {
|
|
126
|
+
actions: [
|
|
127
|
+
legendToolbarAction({
|
|
128
|
+
id: 'c.legend',
|
|
129
|
+
Model: BpmnPoolElementModel,
|
|
130
|
+
owner: 'bpmn',
|
|
131
|
+
framework: 'bpmn',
|
|
132
|
+
}),
|
|
133
|
+
// The generic dropdown, not a BPMN variant of it: the config names no
|
|
134
|
+
// framework — it reads the registered rules and profiles — so this is the
|
|
135
|
+
// very same object wardley, c4 and the context map register.
|
|
136
|
+
...validationToolbarConfig.actions,
|
|
137
|
+
],
|
|
138
|
+
when: bpmnPoolToolbarConfig.when,
|
|
139
|
+
};
|
|
140
|
+
export const bpmnPoolToolingToolbarExtension = ToolbarModuleExtension({
|
|
141
|
+
id: BlockFlavourIdentifier('custom:affine:surface:bpmnPool'),
|
|
142
|
+
config: bpmnPoolToolingToolbarConfig,
|
|
143
|
+
});
|
package/dist/toolbar/icons.d.ts
CHANGED
|
@@ -38,9 +38,16 @@ export declare const bpmnTaskIcon: import("lit-html").TemplateResult<2>;
|
|
|
38
38
|
export declare const bpmnTaskUserIcon: import("lit-html").TemplateResult<2>;
|
|
39
39
|
/** Service task — the rectangle with a gear in its top-left corner. */
|
|
40
40
|
export declare const bpmnTaskServiceIcon: import("lit-html").TemplateResult<2>;
|
|
41
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* Sub-process — the plain rectangle, like the task it is drawn as.
|
|
43
|
+
*
|
|
44
|
+
* The notation puts a collapsed [+] on its bottom edge and the canvas does not
|
|
45
|
+
* paint one (see `node/node-renderer.ts`): that box is a button everywhere else
|
|
46
|
+
* and opens nothing here. A palette glyph says what lands on the board, so it
|
|
47
|
+
* has none either, and the menu label is what tells this entry from the task.
|
|
48
|
+
*/
|
|
42
49
|
export declare const bpmnSubProcessIcon: import("lit-html").TemplateResult<2>;
|
|
43
|
-
/** Call activity — the same
|
|
50
|
+
/** Call activity — the same bare rectangle, on the notation's THICKEST border. */
|
|
44
51
|
export declare const bpmnCallActivityIcon: import("lit-html").TemplateResult<2>;
|
|
45
52
|
/** Exclusive gateway — diamond with an X. */
|
|
46
53
|
export declare const bpmnGatewayIcon: import("lit-html").TemplateResult<2>;
|
package/dist/toolbar/icons.js
CHANGED
|
@@ -87,17 +87,20 @@ export const bpmnTaskServiceIcon = svg `<svg width="24" height="24" viewBox="0 0
|
|
|
87
87
|
<circle cx="7.6" cy="11" r="0.5" stroke="currentColor" stroke-width="0.8"/>
|
|
88
88
|
<path d="M7.6 8.9 V9.3 M7.6 12.7 V13.1 M5.5 11 H5.9 M9.3 11 H9.7 M6.1 9.5 L6.4 9.8 M8.8 12.2 L9.1 12.5 M9.1 9.5 L8.8 9.8 M6.4 12.2 L6.1 12.5" stroke="currentColor" stroke-width="1" stroke-linecap="round"/>
|
|
89
89
|
</svg>`;
|
|
90
|
-
/**
|
|
90
|
+
/**
|
|
91
|
+
* Sub-process — the plain rectangle, like the task it is drawn as.
|
|
92
|
+
*
|
|
93
|
+
* The notation puts a collapsed [+] on its bottom edge and the canvas does not
|
|
94
|
+
* paint one (see `node/node-renderer.ts`): that box is a button everywhere else
|
|
95
|
+
* and opens nothing here. A palette glyph says what lands on the board, so it
|
|
96
|
+
* has none either, and the menu label is what tells this entry from the task.
|
|
97
|
+
*/
|
|
91
98
|
export const bpmnSubProcessIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
92
99
|
<rect x="3.5" y="6.5" width="17" height="11" rx="2.5" stroke="currentColor" stroke-width="1.6"/>
|
|
93
|
-
<rect x="9.6" y="12.6" width="4.8" height="4.8" stroke="currentColor" stroke-width="1.1"/>
|
|
94
|
-
<path d="M12 13.8 V16.2 M10.8 15 H13.2" stroke="currentColor" stroke-width="1.1" stroke-linecap="round"/>
|
|
95
100
|
</svg>`;
|
|
96
|
-
/** Call activity — the same
|
|
101
|
+
/** Call activity — the same bare rectangle, on the notation's THICKEST border. */
|
|
97
102
|
export const bpmnCallActivityIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
98
103
|
<rect x="4" y="7" width="16" height="10" rx="2.5" stroke="currentColor" stroke-width="3"/>
|
|
99
|
-
<rect x="9.6" y="12.2" width="4.8" height="4.8" stroke="currentColor" stroke-width="1.1"/>
|
|
100
|
-
<path d="M12 13.4 V15.8 M10.8 14.6 H13.2" stroke="currentColor" stroke-width="1.1" stroke-linecap="round"/>
|
|
101
104
|
</svg>`;
|
|
102
105
|
/** Exclusive gateway — diamond with an X. */
|
|
103
106
|
export const bpmnGatewayIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { FrameworkPalette, NamedPalette } from '@formicoidea/labre-core/components/color-picker';
|
|
2
|
+
import type { ChromeWording } from '@formicoidea/labre-core/shared/services';
|
|
3
|
+
/**
|
|
4
|
+
* The two BPMN swatches' own names, resolved by `resolvePaletteLabel`
|
|
5
|
+
* (`@labre/affine-components/color-picker`) through each swatch's own
|
|
6
|
+
* {@link NamedPalette.labelWording} — the mechanism `WARDLEY_PALETTE_WORDINGS`
|
|
7
|
+
* established, reused here without either package naming the other.
|
|
8
|
+
*
|
|
9
|
+
* Exported so `../translations.ts` can list them under source `chrome`: a
|
|
10
|
+
* swatch's name is toolbar chrome, never seeded into a document.
|
|
11
|
+
*/
|
|
12
|
+
export declare const BPMN_PALETTE_WORDING_START: ChromeWording;
|
|
13
|
+
export declare const BPMN_PALETTE_WORDING_END: ChromeWording;
|
|
14
|
+
export declare const BPMN_PALETTE_WORDINGS: readonly ChromeWording[];
|
|
15
|
+
/** The two notation hues, then the neutrals every drawing needs. */
|
|
16
|
+
export declare const BPMN_PALETTE_LIST: NamedPalette[];
|
|
17
|
+
/**
|
|
18
|
+
* BPMN's page of the colour pickers' carousel (`docs/adr/0027`). Registered
|
|
19
|
+
* from the FLAG-GATED view extension, because offering hues is TOOLING: a
|
|
20
|
+
* process drawn while the flag was on keeps every colour it was painted with
|
|
21
|
+
* when the flag goes off (`docs/adr/0009`).
|
|
22
|
+
*/
|
|
23
|
+
export declare const BPMN_FRAMEWORK_PALETTE: FrameworkPalette;
|