@formicoidea/labre-framework-bpmn 0.40.0 → 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,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/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.
@@ -172,28 +244,39 @@ const previews = {
172
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,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.40.0",
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.40.0",
34
+ "@formicoidea/labre-core": "0.41.0",
35
35
  "lit": "^3.2.0"
36
36
  }
37
37
  }