@formicoidea/labre-framework-bpmn 0.39.3 → 0.41.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.
@@ -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/0016`.
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;
@@ -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
- import { MESSAGE_STROKE, MESSAGE_WIDTH, NODE_SIZE, SEQUENCE_STROKE, SEQUENCE_WIDTH, } from '../consts.js';
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/0016`.
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.
@@ -134,66 +206,77 @@ const A = 'width="100%" height="100%" viewBox="0 0 135 80" xmlns="http://www.w3.
134
206
  /** An event: the ring weight says start or end, the glyph says what triggers it. */
135
207
  const eventPreview = (stroke, width, glyph = '') => `<svg ${A} fill="none"><circle cx="67" cy="40" r="20" stroke="${stroke}" stroke-width="${width}"/>${glyph}</svg>`;
136
208
  /** An activity: one rounded rectangle, and a marker tells the kinds apart. */
137
- const taskPreview = (glyph = '', width = 2.4) => `<svg ${A} fill="none"><rect x="34" y="24" width="66" height="32" rx="6" stroke="#262626" stroke-width="${width}"/>${glyph}</svg>`;
209
+ const taskPreview = (glyph = '', width = 2.4) => `<svg ${A} fill="none"><rect x="34" y="24" width="66" height="32" rx="6" stroke="${NEUTRAL_STROKE}" stroke-width="${width}"/>${glyph}</svg>`;
138
210
  /** A gateway: one diamond, one marker each. */
139
- const gatewayPreview = (marker) => `<svg ${A} fill="none"><path d="M67 16 L92 40 L67 64 L42 40 Z" stroke="#262626" stroke-width="2.4" stroke-linejoin="round"/><path d="${marker}" stroke="#262626" stroke-width="2.2" stroke-linecap="round"/></svg>`;
140
- const ENVELOPE = '<rect x="59" y="35" width="16" height="11" stroke="#262626" stroke-width="1.4"/><path d="M59 35 L67 42 L75 35" stroke="#262626" stroke-width="1.4" stroke-linejoin="round"/>';
141
- const CLOCK = '<circle cx="67" cy="40" r="9" stroke="#262626" stroke-width="1.4"/><path d="M67 40 V33 M67 40 L72 43" stroke="#262626" stroke-width="1.4" stroke-linecap="round"/>';
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>`;
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"/>`;
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
214
  /** 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="#262626" stroke-width="1.4"/><path d="M67 47 V53 M64 50 H70" stroke="#262626" stroke-width="1.4" stroke-linecap="round"/>';
215
+ 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
216
  const previews = {
145
- process: `<svg ${A} 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>`,
146
- startEvent: eventPreview('#43a06b', 3),
147
- startEventMessage: eventPreview('#43a06b', 3, ENVELOPE),
148
- startEventTimer: eventPreview('#43a06b', 3, CLOCK),
149
- endEvent: eventPreview('#cf5648', 5),
150
- endEventMessage: eventPreview('#cf5648', 5, ENVELOPE),
151
- endEventTerminate: eventPreview('#cf5648', 5, '<circle cx="67" cy="40" r="8" fill="#262626"/>'),
217
+ 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>`,
218
+ startEvent: eventPreview(EVENT_START, 3),
219
+ startEventMessage: eventPreview(EVENT_START, 3, ENVELOPE),
220
+ startEventTimer: eventPreview(EVENT_START, 3, CLOCK),
221
+ endEvent: eventPreview(EVENT_END, 5),
222
+ endEventMessage: eventPreview(EVENT_END, 5, ENVELOPE),
223
+ endEventTerminate: eventPreview(EVENT_END, 5, `<circle cx="67" cy="40" r="8" fill="${NEUTRAL_STROKE}"/>`),
152
224
  task: taskPreview(),
153
- taskUser: taskPreview('<circle cx="41" cy="31" r="2.6" stroke="#262626" stroke-width="1.2"/><path d="M37.4 38 a3.6 3.6 0 0 1 7.2 0" stroke="#262626" stroke-width="1.2"/>'),
154
- taskService: taskPreview('<circle cx="41" cy="32" r="3.4" stroke="#262626" stroke-width="1.2"/><circle cx="41" cy="32" r="1" fill="#262626"/><path d="M41 27.4 V29 M41 35 V36.6 M36.4 32 H38 M44 32 H45.6" stroke="#262626" stroke-width="1.2" stroke-linecap="round"/>'),
225
+ 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"/>`),
226
+ 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
227
  subProcess: taskPreview(COLLAPSED),
156
228
  // The thick border IS the distinction: this box stands for a process defined
157
229
  // elsewhere (`presets.ts`, `CALL_ACTIVITY_WIDTH`).
158
230
  callActivity: taskPreview(COLLAPSED, 4.5),
159
231
  gateway: gatewayPreview('M58 31 L76 49 M76 31 L58 49'),
160
232
  gatewayParallel: gatewayPreview('M67 30 V50 M57 40 H77'),
161
- dataObject: `<svg ${A} fill="none"><path d="M52 14 H76 L88 26 V66 H52 Z" stroke="#262626" stroke-width="2.2" stroke-linejoin="round"/><path d="M76 14 V26 H88" stroke="#262626" stroke-width="1.8" stroke-linejoin="round"/></svg>`,
162
- dataStore: `<svg ${A} fill="none"><path d="M48 22 V58 C48 62 56 65 67 65 C78 65 86 62 86 58 V22" stroke="#262626" stroke-width="2.2" stroke-linejoin="round"/><ellipse cx="67" cy="22" rx="19" ry="6" stroke="#262626" stroke-width="2.2"/></svg>`,
163
- textAnnotation: `<svg ${A} fill="none"><path d="M46 16 H36 V64 H46" stroke="#262626" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/><path d="M54 28 H100 M54 40 H100 M54 52 H86" stroke="#262626" stroke-width="1.8" stroke-linecap="round"/></svg>`,
164
- group: `<svg ${A} fill="none"><rect x="18" y="12" width="99" height="56" rx="10" stroke="#8e8d91" stroke-width="2.2" stroke-dasharray="7 5"/></svg>`,
165
- sequence: `<svg ${A} 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>`,
166
- pool: `<svg ${A} 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>`,
233
+ 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>`,
234
+ dataStore: `<svg ${A} fill="none"><path d="M48 22 V58 C48 62 56 65 67 65 C78 65 86 62 86 58 V22" stroke="${NEUTRAL_STROKE}" stroke-width="2.2" stroke-linejoin="round"/><ellipse cx="67" cy="22" rx="19" ry="6" stroke="${NEUTRAL_STROKE}" stroke-width="2.2"/></svg>`,
235
+ textAnnotation: `<svg ${A} fill="none"><path d="M46 16 H36 V64 H46" stroke="${NEUTRAL_STROKE}" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/><path d="M54 28 H100 M54 40 H100 M54 52 H86" stroke="${NEUTRAL_STROKE}" stroke-width="1.8" stroke-linecap="round"/></svg>`,
236
+ group: `<svg ${A} fill="none"><rect x="18" y="12" width="99" height="56" rx="10" stroke="${GROUP_STROKE}" stroke-width="2.2" stroke-dasharray="7 5"/></svg>`,
237
+ sequence: `<svg ${A} fill="none"><path d="M24 40 H96" stroke="${SEQUENCE_STROKE}" stroke-width="2.4" stroke-linecap="round"/><path d="M94 33 L108 40 L94 47 Z" fill="${SEQUENCE_STROKE}"/></svg>`,
238
+ pool: `<svg ${A} fill="none"><rect x="14" y="20" width="107" height="40" rx="3" stroke="${POOL_FRAME_COLOR}" stroke-width="2"/><path d="M30 20 V60" stroke="${POOL_FRAME_COLOR}" stroke-width="1.8"/><rect x="14" y="20" width="16" height="40" fill="${POOL_BAND_FILL}"/><path d="M30 20 V60" stroke="${POOL_FRAME_COLOR}" stroke-width="1.8"/></svg>`,
167
239
  // Two participants stacked, and the dashed line between them is the whole
168
240
  // point of the card: a message flow is the one arrow that crosses a pool.
169
241
  // Its source terminator is a FILLED disc, matching what `renderCircle`
170
242
  // actually paints rather than the hollow ring the norm asks for — a preview
171
243
  // has one job, which is to look like what lands on the board.
172
- messageExchange: `<svg ${A} fill="none"><rect x="14" y="8" width="107" height="27" rx="3" stroke="#262626" stroke-width="1.6"/><rect x="14" y="8" width="11" height="27" fill="#f4f4f5"/><path d="M25 8 V35" stroke="#262626" stroke-width="1.4"/><rect x="14" y="45" width="107" height="27" rx="3" stroke="#262626" stroke-width="1.6"/><rect x="14" y="45" width="11" height="27" fill="#f4f4f5"/><path d="M25 45 V72" stroke="#262626" stroke-width="1.4"/><circle cx="33" cy="21.5" r="4.5" stroke="#43a06b" stroke-width="1.6"/><rect x="46" y="14" width="26" height="15" rx="3" stroke="#262626" stroke-width="1.6"/><circle cx="88" cy="21.5" r="4.5" stroke="#cf5648" stroke-width="2.6"/><rect x="46" y="51" width="26" height="15" rx="3" stroke="#262626" stroke-width="1.6"/><path d="M41 21.5 H46 M72 21.5 H83" stroke="#262626" stroke-width="1.4"/><circle cx="59" cy="31.5" r="2.2" fill="#262626"/><path d="M59 34 V48" stroke="#262626" stroke-width="1.4" stroke-dasharray="3 2.4"/><path d="M56 46 L59 50 L62 46" stroke="#262626" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
244
+ 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
245
  };
174
246
  /* ── The two worked scenes ────────────────────────────────────────────────── */
175
- /** A hand-composed card — what is left once the artefacts are derived. */
176
- const scene = (name, preview, elements) => ({
247
+ /**
248
+ * A hand-composed card — what is left once the artefacts are derived.
249
+ *
250
+ * `build` takes the OPTIONAL inserting editor: called with none, at module
251
+ * load, for the English `content`; called again with the real `std` as
252
+ * {@link Template.localize}, so the two builds read the very same layout and
253
+ * differ only in the words a seed resolves to (`docs/adr/0016`).
254
+ */
255
+ const scene = (name, preview, build, nameKey) => ({
177
256
  name,
178
257
  type: 'template',
179
258
  preview,
180
- content: makeTemplateSnapshot(elements, name),
259
+ nameKey,
260
+ content: makeTemplateSnapshot(build(), name),
261
+ localize: std => makeTemplateSnapshot(build(std), name),
181
262
  });
182
- const process = {
183
- pool: pool(0, 0, 640, 200, 'Process'),
184
- start: node('startEvent', 40, 72),
185
- task1: node('task', 116, 64, 'Submit request'),
186
- gw: node('gatewayExclusive', 272, 64),
187
- task2: node('task', 376, 20, 'Fulfil'),
188
- task3: node('task', 376, 124, 'Reject'),
189
- end: node('endEvent', 556, 72),
190
- c1: seq('start', 'task1'),
191
- c2: seq('task1', 'gw'),
192
- c3: seq('gw', 'task2'),
193
- c4: seq('gw', 'task3'),
194
- c5: seq('task2', 'end'),
195
- c6: seq('task3', 'end'),
196
- };
263
+ function process(std) {
264
+ return {
265
+ pool: pool(0, 0, 640, 200, seedText(std, SIMPLE_PROCESS_SEED.poolName)),
266
+ start: node('startEvent', 40, 72),
267
+ task1: node('task', 116, 64, seedText(std, SIMPLE_PROCESS_SEED.submitRequest)),
268
+ gw: node('gatewayExclusive', 272, 64),
269
+ task2: node('task', 376, 20, seedText(std, SIMPLE_PROCESS_SEED.fulfil)),
270
+ task3: node('task', 376, 124, seedText(std, SIMPLE_PROCESS_SEED.reject)),
271
+ end: node('endEvent', 556, 72),
272
+ c1: seq('start', 'task1'),
273
+ c2: seq('task1', 'gw'),
274
+ c3: seq('gw', 'task2'),
275
+ c4: seq('gw', 'task3'),
276
+ c5: seq('task2', 'end'),
277
+ c6: seq('task3', 'end'),
278
+ };
279
+ }
197
280
  /**
198
281
  * Two participants, and the one arrow that is allowed to cross between them.
199
282
  *
@@ -216,30 +299,34 @@ const process = {
216
299
  * until this slice ran the rules over the shipped cards. The customer's process
217
300
  * now closes where it should: order placed, then done.
218
301
  */
219
- const messageExchange = {
220
- customer: pool(0, 0, 640, 200, 'Customer'),
221
- supplier: pool(0, 240, 640, 200, 'Supplier'),
222
- start: node('startEvent', 40, 72),
223
- ask: node('taskUser', 140, 64, 'Place order'),
224
- done: node('endEvent', 320, 72),
225
- answer: node('taskService', 140, 304, 'Confirm order'),
226
- // Inside the first participant: what happens, and in what order.
227
- inside: seq('start', 'ask'),
228
- closes: seq('ask', 'done'),
229
- // Across the two: who told whom.
230
- across: msg('ask', 'answer'),
231
- };
302
+ function messageExchange(std) {
303
+ return {
304
+ customer: pool(0, 0, 640, 200, seedText(std, MESSAGE_EXCHANGE_SEED.customer)),
305
+ supplier: pool(0, 240, 640, 200, seedText(std, MESSAGE_EXCHANGE_SEED.supplier)),
306
+ start: node('startEvent', 40, 72),
307
+ ask: node('taskUser', 140, 64, seedText(std, MESSAGE_EXCHANGE_SEED.placeOrder)),
308
+ done: node('endEvent', 320, 72),
309
+ answer: node('taskService', 140, 304, seedText(std, MESSAGE_EXCHANGE_SEED.confirmOrder)),
310
+ // Inside the first participant: what happens, and in what order.
311
+ inside: seq('start', 'ask'),
312
+ closes: seq('ask', 'done'),
313
+ // Across the two: who told whom.
314
+ across: msg('ask', 'answer'),
315
+ };
316
+ }
232
317
  export const bpmnTemplateCategory = {
233
318
  name: 'BPMN',
319
+ // Reuses the senior button's own key — see `TemplateCategory.nameKey`.
320
+ nameKey: 'com.labre.framework.bpmn',
234
321
  templates: [
235
- scene('Simple process', previews.process, process),
236
- scene('Message exchange', previews.messageExchange, messageExchange),
322
+ scene('Simple process', previews.process, process, BPMN_TEMPLATE_NAME_SIMPLE_PROCESS[0]),
323
+ scene('Message exchange', previews.messageExchange, messageExchange, BPMN_TEMPLATE_NAME_MESSAGE_EXCHANGE[0]),
237
324
  /* ── The core: a drawable process, from the first click ─────────────── */
238
325
  templateFromCommand(byId('bpmn.addStartEvent'), previews.startEvent),
239
326
  templateFromCommand(byId('bpmn.addEndEvent'), previews.endEvent),
240
327
  templateFromCommand(byId('bpmn.addTask'), previews.task),
241
328
  templateFromCommand(byId('bpmn.addExclusiveGateway'), previews.gateway),
242
- scene('Sequence flow', previews.sequence, { a: freeSeq() }),
329
+ scene('Sequence flow', previews.sequence, () => ({ a: freeSeq() }), BPMN_TEMPLATE_NAME_SEQUENCE_FLOW[0]),
243
330
  templateFromCommand(byId('bpmn.addPool'), previews.pool),
244
331
  /* ── Activities ─────────────────────────────────────────────────────── */
245
332
  templateFromCommand(byId('bpmn.addUserTask'), previews.taskUser),
@@ -1,11 +1,12 @@
1
1
  import { svg } from 'lit';
2
+ import { NEUTRAL_STROKE, NODE_FILL, POOL_CARD_FILL, POOL_FRAME_COLOR, } from '../consts.js';
2
3
  /** Colored BPMN glyph for the main toolbar button: a pool (green name band) with
3
4
  * a single activity inside. */
4
5
  export const bpmnToolbarIcon = svg `<svg width="100%" height="100%" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
5
- <rect x="4" y="13" width="48" height="30" rx="3" fill="#ffffff" stroke="#262626" stroke-width="2.2"/>
6
+ <rect x="4" y="13" width="48" height="30" rx="3" fill="${POOL_CARD_FILL}" stroke="${POOL_FRAME_COLOR}" stroke-width="2.2"/>
6
7
  <path d="M6 14 h5 v28 h-5 z" fill="#43a06b"/>
7
- <line x1="11" y1="13" x2="11" y2="43" stroke="#262626" stroke-width="1.8"/>
8
- <rect x="20" y="20" width="24" height="16" rx="3.5" fill="#ffffff" stroke="#262626" stroke-width="2.2"/>
8
+ <line x1="11" y1="13" x2="11" y2="43" stroke="${POOL_FRAME_COLOR}" stroke-width="1.8"/>
9
+ <rect x="20" y="20" width="24" height="16" rx="3.5" fill="${NODE_FILL}" stroke="${NEUTRAL_STROKE}" stroke-width="2.2"/>
9
10
  </svg>`;
10
11
  /** Export BPMN XML — a document with an arrow leaving it. */
11
12
  export const bpmnExportXmlIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -1,11 +1,13 @@
1
1
  import { collectTranslationKeys, commandCategoryTranslationEntries, commandTranslationEntries, mergeTranslationEntries, } from '@formicoidea/labre-core/std';
2
2
  import { bpmnCommands } from './commands.js';
3
- import { NODE_LABEL, nodeLabelKey } from './consts.js';
4
- import { BPMN_IMPORT_REMARKS } from './import.js';
3
+ import { LANE_NAME_FALLBACK, LANE_NAME_KEY, NODE_LABEL, nodeLabelKey, POOL_NAME_FALLBACK, POOL_NAME_KEY, } from './consts.js';
4
+ import { BPMN_EXPORT_WARNING_KEYS } from './export.js';
5
+ import { BPMN_IMPORT_ERRORS, BPMN_IMPORT_REMARKS, BPMN_QUARANTINE_REASON, BPMN_QUARANTINE_REASON_KEY, } from './import.js';
5
6
  import { BPMN_PROFILES } from './profiles.js';
6
7
  import { BPMN_READINGS } from './reading.js';
7
8
  import { BPMN_ROLES } from './roles.js';
8
9
  import { BPMN_RULES } from './rules.js';
10
+ import { BPMN_TEMPLATE_NAME_MESSAGE_EXCHANGE, BPMN_TEMPLATE_NAME_SEQUENCE_FLOW, BPMN_TEMPLATE_NAME_SIMPLE_PROCESS, MESSAGE_EXCHANGE_SEED, SIMPLE_PROCESS_SEED, } from './templates/index.js';
9
11
  /**
10
12
  * The captions a placed artefact is seeded with, and the fixed-wording remarks
11
13
  * an import can produce — the two families of BPMN prose that live in tables
@@ -28,6 +30,66 @@ const importRemarkEntries = () => Object.values(BPMN_IMPORT_REMARKS).map(([key,
28
30
  fallback: english,
29
31
  source: 'chrome',
30
32
  }));
33
+ /**
34
+ * The reader's own refusals ({@link BPMN_IMPORT_ERRORS}) — thrown via
35
+ * `InterchangeImportError`, chrome like the remarks above for the same
36
+ * reason: re-rendered by the catch site every time, never written into a
37
+ * document.
38
+ */
39
+ const importErrorEntries = () => Object.values(BPMN_IMPORT_ERRORS).map(([key, english]) => ({
40
+ key,
41
+ fallback: english,
42
+ source: 'chrome',
43
+ }));
44
+ /**
45
+ * {@link BPMN_QUARANTINE_REASON}'s own four keys — a report note about
46
+ * material the import kept but will never write back (D5), fixed wording like
47
+ * the three remarks above and for the same reason: nothing in any of the four
48
+ * sentences names anything out of the file.
49
+ */
50
+ const quarantineReasonEntries = () => Object.keys(BPMN_QUARANTINE_REASON).map(reason => ({
51
+ key: BPMN_QUARANTINE_REASON_KEY[reason],
52
+ fallback: BPMN_QUARANTINE_REASON[reason],
53
+ source: 'chrome',
54
+ }));
55
+ /**
56
+ * The nine export-warning keys ({@link BPMN_EXPORT_WARNING_KEYS}) — a report
57
+ * built from the board rather than written into it, so `chrome` like the
58
+ * import remarks above and not `seed`.
59
+ */
60
+ const exportWarningEntries = () => BPMN_EXPORT_WARNING_KEYS.map(([key, fallback]) => ({
61
+ key,
62
+ fallback,
63
+ source: 'chrome',
64
+ }));
65
+ /**
66
+ * The pool's own default name and a fresh lane's, resolved at placement
67
+ * exactly like {@link seedEntries} — the fallback IS `POOL_NAME_FALLBACK` /
68
+ * `LANE_NAME_FALLBACK`, never restated.
69
+ */
70
+ const furnitureSeedEntries = () => [
71
+ { key: POOL_NAME_KEY, fallback: POOL_NAME_FALLBACK, source: 'seed' },
72
+ { key: LANE_NAME_KEY, fallback: LANE_NAME_FALLBACK, source: 'seed' },
73
+ ];
74
+ /**
75
+ * The seeds the two worked-example scenes write — derived from the very
76
+ * tables `templates/index.ts` reads at placement, so the words a host is
77
+ * offered are the words the card would insert.
78
+ */
79
+ const exampleSeedEntries = () => [
80
+ ...Object.values(SIMPLE_PROCESS_SEED),
81
+ ...Object.values(MESSAGE_EXCHANGE_SEED),
82
+ ].map(({ key, fallback }) => ({ key, fallback, source: 'seed' }));
83
+ /**
84
+ * The three hand-composed cards' own tile names — chrome, not seeds: a
85
+ * `Template.nameKey`, re-resolved every time the panel opens, never written
86
+ * into a document. See `templates/index.ts`.
87
+ */
88
+ const templateNameEntries = () => [
89
+ BPMN_TEMPLATE_NAME_SIMPLE_PROCESS,
90
+ BPMN_TEMPLATE_NAME_MESSAGE_EXCHANGE,
91
+ BPMN_TEMPLATE_NAME_SEQUENCE_FLOW,
92
+ ].map(([key, fallback]) => ({ key, fallback, source: 'chrome' }));
31
93
  /**
32
94
  * THIS framework's contribution to the translation-key manifest — every
33
95
  * `com.labre.*` key BPMN can hand to `TranslationProvider.t`, derived from the
@@ -48,7 +110,7 @@ export const bpmnTranslationEntries = mergeTranslationEntries(commandTranslation
48
110
  // registry names no framework category in the bundled distribution, so a
49
111
  // host that composed core's manifest alone drew translated entries under
50
112
  // English headers (#183).
51
- commandCategoryTranslationEntries(bpmnCommands), collectTranslationKeys('role', BPMN_ROLES), collectTranslationKeys('rule', BPMN_RULES), collectTranslationKeys('profile', BPMN_PROFILES), seedEntries(), importRemarkEntries(),
113
+ commandCategoryTranslationEntries(bpmnCommands), collectTranslationKeys('role', BPMN_ROLES), collectTranslationKeys('rule', BPMN_RULES), collectTranslationKeys('profile', BPMN_PROFILES), seedEntries(), furnitureSeedEntries(), exampleSeedEntries(), templateNameEntries(), importRemarkEntries(), importErrorEntries(), quarantineReasonEntries(), exportWarningEntries(),
52
114
  // LAST, and the order is load-bearing: a reading profile carries the
53
115
  // framework's own `roles`, so walking it reaches every role key the `role`
54
116
  // line above already named. `mergeTranslationEntries` keeps the FIRST
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@formicoidea/labre-framework-bpmn",
3
3
  "description": "Labre bpmn framework for @formicoidea/labre-core.",
4
- "version": "0.39.3",
4
+ "version": "0.41.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "author": "lajola",
@@ -31,7 +31,7 @@
31
31
  "dist"
32
32
  ],
33
33
  "dependencies": {
34
- "@formicoidea/labre-core": "0.39.3",
34
+ "@formicoidea/labre-core": "0.41.0",
35
35
  "lit": "^3.2.0"
36
36
  }
37
37
  }