@formicoidea/labre-framework-bpmn 0.42.0 → 0.45.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.
@@ -0,0 +1,88 @@
1
+ import { paletteColorAction, shapeToolbarConfig, } from '@formicoidea/labre-core/gfx/shape';
2
+ import { BpmnNodeElementModel } from '@formicoidea/labre-core/model';
3
+ import { ToolbarModuleExtension, } from '@formicoidea/labre-core/shared/services';
4
+ import { BlockFlavourIdentifier } from '@formicoidea/labre-core/std';
5
+ import { bpmnLabelMode } from '../consts.js';
6
+ import { BPMN_PALETTE_LIST } from './palette.js';
7
+ /**
8
+ * The shape toolbar's actions a BPMN node keeps.
9
+ *
10
+ * A BPMN node IS a `ShapeElementModel`, so the shape actions (which target
11
+ * `getSurfaceModelsByType(ShapeElementModel)`) operate on it directly — but
12
+ * `renderToolbar` merges by flavour KEY, so none of them reach a node until a
13
+ * module is registered on `affine:surface:bpmnNode`. This is that module, and
14
+ * it keeps what Edgy keeps (the reference the PO cited):
15
+ *
16
+ * - `d.style` — the scribbled / general line style;
17
+ * - `f.text` — "Add text", narrowed below to inscribed kinds;
18
+ * - `f2.text-fit` and every `g.text-*` — they already hide themselves on a
19
+ * node with no inner text, which is every external kind drawn since R38.
20
+ *
21
+ * Dropped: `c.switch-type` (the KIND decides the native shape — a diamond is a
22
+ * gateway because it is a gateway; turning it into an ellipse would paint a
23
+ * start event's outline with a gateway's marker; "Change type" is the morph
24
+ * module's job) and `f1.edit-vertices` (no BPMN symbol is a free polygon).
25
+ */
26
+ const KEEP_FROM_SHAPE = (id) => id === 'd.style' ||
27
+ id === 'f.text' ||
28
+ id === 'f2.text-fit' ||
29
+ id.startsWith('g.text-');
30
+ /**
31
+ * Every selected BPMN node wears its name INSIDE the shape.
32
+ *
33
+ * An event, a gateway or a data shape names itself with a grouped `bpmn:label`
34
+ * text under the symbol (R38), so "Add text" on one would write a second,
35
+ * inner name the notation never draws there. The gesture exists for the
36
+ * inscribed kinds only — the same gate `bpmnNodeEditsInnerText` puts on the
37
+ * double-click, minus the legacy exception: a legacy event's inner text is
38
+ * already there, and "Add text" only ever shows on a node with none.
39
+ */
40
+ export function bpmnSelectionIsInscribed(ctx) {
41
+ const models = ctx.getSurfaceModelsByType(BpmnNodeElementModel);
42
+ return (models.length > 0 &&
43
+ models.every(model => bpmnLabelMode(model.kind) === 'inscribed'));
44
+ }
45
+ /** Narrow a shape action's own `when` with {@link bpmnSelectionIsInscribed}. */
46
+ function inscribedOnly(action) {
47
+ const when = action.when;
48
+ return {
49
+ ...action,
50
+ when: (ctx) => bpmnSelectionIsInscribed(ctx) &&
51
+ (typeof when === 'function' ? when(ctx) : when !== false),
52
+ };
53
+ }
54
+ /**
55
+ * Fill, stroke colour, stroke width and stroke style — the picker Edgy and
56
+ * Wardley use, seeded with BPMN's two notation hues and the neutrals.
57
+ * `paletteColorAction` and the shape's own `e.color` expose the same four
58
+ * controls (both render `edgeless-shape-color-picker`, which carries the
59
+ * width / style panel); the palette one is taken because it is Edgy's.
60
+ *
61
+ * On the glyph-bodied kinds (`dataObject`, `dataStore`, `textAnnotation`) the
62
+ * native shape is born with `strokeStyle: None` and the renderer's glyph draws
63
+ * the silhouette from `strokeColor` / `fillColor`. Picking a visible stroke
64
+ * style there makes the native rectangle paint its outline around the glyph —
65
+ * an honest result of the author's pick, so it is left to the author rather
66
+ * than filtered out here.
67
+ */
68
+ const bpmnColorAction = paletteColorAction('e.color', BPMN_PALETTE_LIST);
69
+ export const bpmnNodeToolbarConfig = {
70
+ actions: [
71
+ ...shapeToolbarConfig.actions
72
+ .filter(action => KEEP_FROM_SHAPE(action.id))
73
+ .map(action => (action.id === 'f.text' ? inscribedOnly(action) : action)),
74
+ bpmnColorAction,
75
+ ],
76
+ when: shapeToolbarConfig.when,
77
+ };
78
+ /**
79
+ * The base shape features on a selected BPMN node, on the BARE flavour key.
80
+ * Registered from the ALWAYS-ON view extension: recolouring or re-typesetting
81
+ * a stored element is editing content, not tooling (`docs/adr/0009`). The
82
+ * "Change type" morph, which IS tooling, takes an owner-suffixed key beside
83
+ * it (`view.ts`).
84
+ */
85
+ export const bpmnNodeToolbarExtension = ToolbarModuleExtension({
86
+ id: BlockFlavourIdentifier('affine:surface:bpmnNode'),
87
+ config: bpmnNodeToolbarConfig,
88
+ });
@@ -1 +1 @@
1
- export declare const bpmnSeniorTool: import("@formicoidea/labre-core/store").ExtensionType;
1
+ export declare const bpmnSeniorTool: import("@formicoidea/labre-core/_pkgs/store").ExtensionType;
package/dist/view.js CHANGED
@@ -2,14 +2,14 @@ import { FrameworkBackgroundInteractionExtension, InterchangeExtension, morphToo
2
2
  import { FrameworkPaletteExtension } from '@formicoidea/labre-core/components/color-picker';
3
3
  import { ViewExtensionProvider, } from '@formicoidea/labre-core/ext-loader';
4
4
  import { TemplateCategoryExtension } from '@formicoidea/labre-core/gfx/template';
5
- import { ToolbarModuleExtension } from '@formicoidea/labre-core/shared/services';
5
+ import { ToolbarModuleExtension, toolbarModuleKey, } from '@formicoidea/labre-core/shared/services';
6
6
  import { BlockFlavourIdentifier, CommandExtension } from '@formicoidea/labre-core/std';
7
7
  import { RoleVocabularyExtension } from '@formicoidea/labre-core/std/gfx';
8
8
  import { BPMN_POOL_BACKGROUND } from './background.js';
9
9
  import { bpmnCommandIcons, bpmnCommands } from './commands.js';
10
10
  import { effects } from './effects.js';
11
11
  import { BPMN_INTERCHANGE } from './interchange.js';
12
- import { BPMN_MORPH_SPEC } from './morph.js';
12
+ import { BPMN_GROUP_MORPH_SPEC, BPMN_MORPH_SPEC } from './morph.js';
13
13
  import { BPMN_PROFILES } from './profiles.js';
14
14
  import { BPMN_READINGS } from './reading.js';
15
15
  import { BPMN_ROLES } from './roles.js';
@@ -20,6 +20,7 @@ import { BpmnPoolView } from './element-view.js';
20
20
  import { BpmnNodeRendererExtension } from './node/node-renderer.js';
21
21
  import { BpmnNodeView } from './node/node-view.js';
22
22
  import { bpmnPoolToolbarExtension, bpmnPoolToolingToolbarExtension, } from './toolbar/config.js';
23
+ import { bpmnNodeToolbarExtension } from './toolbar/node-config.js';
23
24
  import { BPMN_FRAMEWORK_PALETTE } from './toolbar/palette.js';
24
25
  import { bpmnSeniorTool } from './toolbar/senior-tool.js';
25
26
  /**
@@ -51,6 +52,11 @@ export class BpmnRenderViewExtension extends ViewExtensionProvider {
51
52
  // otherwise, and the toolbar toggle is what writes it.
52
53
  context.register(FrameworkBackgroundInteractionExtension(BPMN_POOL_BACKGROUND));
53
54
  context.register(bpmnPoolToolbarExtension);
55
+ // The base shape features on a selected NODE — colours, stroke, text
56
+ // style — on the BARE `affine:surface:bpmnNode` key, like Wardley's and
57
+ // EDGY's node modules. Always on: recolouring a stored element is editing
58
+ // content, not tooling (`docs/adr/0009`).
59
+ context.register(bpmnNodeToolbarExtension);
54
60
  }
55
61
  }
56
62
  }
@@ -94,25 +100,41 @@ export class BpmnViewExtension extends ViewExtensionProvider {
94
100
  // The "Change type" dropdown on a selected NODE's contextual toolbar —
95
101
  // the generic module, parameterized by BPMN's own families table.
96
102
  //
97
- // `affine:surface:bpmnNode` is a FREE slot, and class inheritance has
98
- // nothing to do with it: `renderToolbar` merges by flavour KEY — the
99
- // element's own, its `custom:` twin and the `affine:surface:*` wildcards
100
- // — so `shapeToolbarExtension`, which binds `affine:surface:shape`, never
103
+ // ## Why the key carries an owner
104
+ //
105
+ // `renderToolbar` merges by flavour KEY — the element's own, its
106
+ // `custom:` twin and the `affine:surface:*` wildcards — so
107
+ // `shapeToolbarExtension`, which binds `affine:surface:shape`, never
101
108
  // reaches a bpmn node however much of `ShapeElementModel` the class
102
- // inherits. Nothing claimed this key before, so the registration is purely
103
- // additive: it joins the wildcard entries (tags, validation) that a node
104
- // already gets, and a second module claiming the same key would throw
105
- // `DuplicateServiceDefinitionError` before the editor finished setting up.
109
+ // inherits. The bare `affine:surface:bpmnNode` key is now taken by the
110
+ // always-on `bpmnNodeToolbarExtension` (the shape's base features), and
111
+ // a second module on it would throw `DuplicateServiceDefinitionError`
112
+ // at setup. `toolbarModuleKey` lifts that ceiling: the morph is the
113
+ // DISTINCT variant `affine:surface:bpmnNode#bpmn-morph`, and the
114
+ // registry hands it to the same row.
106
115
  //
107
- // Registered HERE, in the flag-gated half, because a morph is TOOLING: a
108
- // node drawn while the flag was on keeps its kind, its role, its glyph
109
- // and its place in every rule when the flag goes off — it just stops
110
- // being something the toolbar offers to say more precisely
111
- // (`docs/adr/0009`).
116
+ // ## Why here
117
+ //
118
+ // In the flag-gated half, because a morph is TOOLING: a node drawn while
119
+ // the flag was on keeps its kind, its role, its glyph and its place in
120
+ // every rule when the flag goes off — it just stops being something the
121
+ // toolbar offers to say more precisely (`docs/adr/0009`).
112
122
  context.register(ToolbarModuleExtension({
113
- id: BlockFlavourIdentifier('affine:surface:bpmnNode'),
123
+ id: BlockFlavourIdentifier(toolbarModuleKey('affine:surface:bpmnNode', 'bpmn-morph')),
114
124
  config: morphToolbarConfig(BPMN_MORPH_SPEC),
115
125
  }));
126
+ // The same dropdown on the GROUP row. An event, a gateway or a data
127
+ // shape is born as a native group of the symbol and its gravitating
128
+ // label (R38), and a click selects the group — so, exactly as Wardley,
129
+ // C4 and UML do for their composites, the morph is also registered on
130
+ // `custom:affine:surface:group` under an owner, and
131
+ // `BPMN_GROUP_MORPH_SPEC` resolves the node inside (refusing any group
132
+ // that is not one BPMN external-label artefact). Flag-gated for the
133
+ // same reason as the node row.
134
+ context.register(ToolbarModuleExtension({
135
+ id: BlockFlavourIdentifier(toolbarModuleKey('custom:affine:surface:group', 'bpmn-morph')),
136
+ config: morphToolbarConfig(BPMN_GROUP_MORPH_SPEC),
137
+ }));
116
138
  // The reversed reading (MF3): what the process says about an artefact, on
117
139
  // demand. Four profiles because BPMN has four parent-less node families
118
140
  // (`reading.ts` says why the notation refuses a common root). The CLICK
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.42.0",
4
+ "version": "0.45.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.42.0",
34
+ "@formicoidea/labre-core": "0.45.0",
35
35
  "lit": "^3.2.0"
36
36
  }
37
37
  }