@formicoidea/labre-framework-wardley 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.
- package/dist/actions.d.ts +29 -0
- package/dist/actions.js +61 -38
- package/dist/consts.d.ts +8 -1
- package/dist/consts.js +14 -6
- package/dist/import.d.ts +28 -0
- package/dist/import.js +66 -7
- package/dist/legend.d.ts +20 -2
- package/dist/legend.js +127 -37
- package/dist/morph.d.ts +12 -2
- package/dist/morph.js +25 -9
- package/dist/natures.js +19 -0
- package/dist/node/consts.d.ts +29 -6
- package/dist/node/consts.js +29 -5
- package/dist/presets.d.ts +21 -0
- package/dist/presets.js +21 -0
- package/dist/templates/index.d.ts +9 -0
- package/dist/templates/index.js +35 -17
- package/dist/templates/maps.d.ts +94 -0
- package/dist/templates/maps.js +153 -31
- package/dist/toolbar/config.d.ts +2 -0
- package/dist/toolbar/config.js +46 -7
- package/dist/toolbar/icons.js +16 -15
- package/dist/toolbar/node-config.d.ts +26 -2
- package/dist/toolbar/node-config.js +100 -9
- package/dist/translations.js +80 -1
- package/package.json +2 -2
package/dist/legend.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createGroupCommand } from '@formicoidea/labre-core/gfx/group';
|
|
2
2
|
import { ConnectorElementModel, ConnectorMode, FontFamily, PointStyle, ShapeElementModel, ShapeStyle, StrokeStyle, WardleyNodeElementModel, } from '@formicoidea/labre-core/model';
|
|
3
|
+
import { NOTATION_NEUTRALS } from '@formicoidea/labre-core/shared/consts';
|
|
4
|
+
import { translateKey, } from '@formicoidea/labre-core/shared/services';
|
|
3
5
|
import { Bound } from '@formicoidea/labre-core/global/gfx';
|
|
4
6
|
import { GfxControllerIdentifier } from '@formicoidea/labre-core/std/gfx';
|
|
5
7
|
import { GRADIENT_GREEN, GRADIENT_RED } from './gradient.js';
|
|
@@ -20,37 +22,82 @@ const LEGEND_ORDER = [
|
|
|
20
22
|
'decelerator',
|
|
21
23
|
'area',
|
|
22
24
|
];
|
|
23
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Default (editable) descriptions for each legend row — a `ChromeWording` per
|
|
27
|
+
* row so the seed a legend writes into the document is resolved through the
|
|
28
|
+
* host at BUILD time, like every other text `createWardleyLegend` creates.
|
|
29
|
+
* The fallback is the literal that shipped before these keys existed.
|
|
30
|
+
*/
|
|
24
31
|
const LEGEND_DESC = {
|
|
25
|
-
component:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
component: [
|
|
33
|
+
'com.labre.wardley.legend.desc.component',
|
|
34
|
+
'Need / capability (activity, practice, data…)',
|
|
35
|
+
],
|
|
36
|
+
anchor: [
|
|
37
|
+
'com.labre.wardley.legend.desc.anchor',
|
|
38
|
+
'Stakeholder (customer, user…)',
|
|
39
|
+
],
|
|
40
|
+
market: ['com.labre.wardley.legend.desc.market', 'Market (set of actors)'],
|
|
41
|
+
ecosystem: ['com.labre.wardley.legend.desc.ecosystem', 'Ecosystem'],
|
|
42
|
+
method: [
|
|
43
|
+
'com.labre.wardley.legend.desc.method',
|
|
44
|
+
'Component + method (color = phase)',
|
|
45
|
+
],
|
|
46
|
+
pipeline: [
|
|
47
|
+
'com.labre.wardley.legend.desc.pipeline',
|
|
48
|
+
'Pipeline (possible choices for a capability)',
|
|
49
|
+
],
|
|
50
|
+
link: [
|
|
51
|
+
'com.labre.wardley.legend.desc.link',
|
|
52
|
+
'Need relation (parent → child)',
|
|
53
|
+
],
|
|
54
|
+
arrow: [
|
|
55
|
+
'com.labre.wardley.legend.desc.arrow',
|
|
56
|
+
'Evolution / movement (red = future)',
|
|
57
|
+
],
|
|
58
|
+
inertia: ['com.labre.wardley.legend.desc.inertia', 'Inertia to change'],
|
|
59
|
+
porter: [
|
|
60
|
+
'com.labre.wardley.legend.desc.porter',
|
|
61
|
+
"Porter's forces (external competition: R relative, L survival, E establish)",
|
|
62
|
+
],
|
|
63
|
+
accelerator: [
|
|
64
|
+
'com.labre.wardley.legend.desc.accelerator',
|
|
65
|
+
'Accelerator (speeds evolution up)',
|
|
66
|
+
],
|
|
67
|
+
decelerator: [
|
|
68
|
+
'com.labre.wardley.legend.desc.decelerator',
|
|
69
|
+
'Decelerator (slows evolution down)',
|
|
70
|
+
],
|
|
71
|
+
area: ['com.labre.wardley.legend.desc.area', 'Area (zone of the map)'],
|
|
38
72
|
};
|
|
73
|
+
/** Every {@link LEGEND_DESC} wording, for `translations.ts`'s manifest. */
|
|
74
|
+
export const WARDLEY_LEGEND_DESC_WORDINGS = Object.values(LEGEND_DESC);
|
|
39
75
|
/** Gradient-meaning block, keyed by variant (caption + 2-colour swatch). */
|
|
40
76
|
const LEGEND_GRADIENT = {
|
|
41
77
|
opportunity: {
|
|
42
|
-
caption:
|
|
78
|
+
caption: [
|
|
79
|
+
'com.labre.wardley.legend.gradient.opportunity',
|
|
80
|
+
'Opportunity gradient: differential value (green) vs operational value (red).',
|
|
81
|
+
],
|
|
43
82
|
swatch: [GRADIENT_GREEN, GRADIENT_RED],
|
|
44
83
|
},
|
|
45
84
|
benefit: {
|
|
46
|
-
caption:
|
|
85
|
+
caption: [
|
|
86
|
+
'com.labre.wardley.legend.gradient.benefit',
|
|
87
|
+
'Gradient: investment (red) then benefit (green).',
|
|
88
|
+
],
|
|
47
89
|
swatch: [GRADIENT_RED, GRADIENT_GREEN],
|
|
48
90
|
},
|
|
49
91
|
'evolution-gradient': {
|
|
50
|
-
caption:
|
|
51
|
-
|
|
92
|
+
caption: [
|
|
93
|
+
'com.labre.wardley.legend.gradient.evolution',
|
|
94
|
+
"Gradient representing the growth of Wardley's evolution function.",
|
|
95
|
+
],
|
|
96
|
+
swatch: [NOTATION_NEUTRALS.divider, NOTATION_NEUTRALS.legendBorder],
|
|
52
97
|
},
|
|
53
98
|
};
|
|
99
|
+
/** Every {@link LEGEND_GRADIENT} caption, for `translations.ts`'s manifest. */
|
|
100
|
+
export const WARDLEY_LEGEND_GRADIENT_WORDINGS = Object.values(LEGEND_GRADIENT).map(g => g.caption);
|
|
54
101
|
/* ── Porter's five forces: the panel under the rows ───────────────────── */
|
|
55
102
|
/** The panel's own numbers. Model units, like every other measure here. */
|
|
56
103
|
const PORTER_PANEL = {
|
|
@@ -74,19 +121,50 @@ const PORTER_PANEL = {
|
|
|
74
121
|
captionFs: 13,
|
|
75
122
|
captionH: 21,
|
|
76
123
|
backing: '#e5e7eb',
|
|
77
|
-
backingStroke:
|
|
124
|
+
backingStroke: NOTATION_NEUTRALS.divider,
|
|
78
125
|
};
|
|
79
126
|
/** The four forces the boxes name, north first and then clockwise. */
|
|
80
127
|
const PORTER_FORCES = [
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
128
|
+
[
|
|
129
|
+
'com.labre.wardley.legend.porter.force.new-entrants',
|
|
130
|
+
'Threat of new entrants',
|
|
131
|
+
],
|
|
132
|
+
[
|
|
133
|
+
'com.labre.wardley.legend.porter.force.customers',
|
|
134
|
+
'Bargaining power of customers',
|
|
135
|
+
],
|
|
136
|
+
[
|
|
137
|
+
'com.labre.wardley.legend.porter.force.substitutes',
|
|
138
|
+
'Threat of substitutes',
|
|
139
|
+
],
|
|
140
|
+
[
|
|
141
|
+
'com.labre.wardley.legend.porter.force.suppliers',
|
|
142
|
+
'Bargaining power of suppliers',
|
|
143
|
+
],
|
|
85
144
|
];
|
|
86
|
-
/** What the panel's own glyph reads: the notation, not one force. */
|
|
145
|
+
/** What the panel's own glyph reads: the notation, not one force — untouched, like the Cynefin A/C letters. */
|
|
87
146
|
const PORTER_PANEL_LETTERS = 'R/L/E';
|
|
88
147
|
/** What the letters mean, spelled out under the diagram. */
|
|
89
|
-
const PORTER_CAPTION =
|
|
148
|
+
const PORTER_CAPTION = [
|
|
149
|
+
'com.labre.wardley.legend.porter.caption',
|
|
150
|
+
'R/L/E = Relative competition, or struggLe for survival, or struggle to Establish',
|
|
151
|
+
];
|
|
152
|
+
/** The legend box's own title. */
|
|
153
|
+
export const WARDLEY_LEGEND_TITLE = [
|
|
154
|
+
'com.labre.wardley.legend.title',
|
|
155
|
+
'Legend',
|
|
156
|
+
];
|
|
157
|
+
/** The five-forces panel's own title. */
|
|
158
|
+
export const WARDLEY_LEGEND_PORTER_TITLE = [
|
|
159
|
+
'com.labre.wardley.legend.porter.title',
|
|
160
|
+
"Porter's five forces",
|
|
161
|
+
];
|
|
162
|
+
/** Every {@link PORTER_FORCES} wording, plus the caption, for the manifest. */
|
|
163
|
+
export const WARDLEY_LEGEND_PORTER_WORDINGS = [
|
|
164
|
+
WARDLEY_LEGEND_PORTER_TITLE,
|
|
165
|
+
...PORTER_FORCES,
|
|
166
|
+
PORTER_CAPTION,
|
|
167
|
+
];
|
|
90
168
|
/**
|
|
91
169
|
* How far a porter glyph of the given radius reaches, arrow tips included.
|
|
92
170
|
*
|
|
@@ -144,6 +222,18 @@ export function porterPanelLayout(w) {
|
|
|
144
222
|
caption: [p.pad, captionY, inner, p.captionH],
|
|
145
223
|
};
|
|
146
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* Every wording this file writes onto the canvas, for `translations.ts`'s
|
|
227
|
+
* manifest contribution — the auto-legend's own title, its rows' captions,
|
|
228
|
+
* the gradient blocks and the Porter panel, all as `seed` (written into the
|
|
229
|
+
* document once, at the moment a legend is generated).
|
|
230
|
+
*/
|
|
231
|
+
export const WARDLEY_LEGEND_WORDINGS = [
|
|
232
|
+
WARDLEY_LEGEND_TITLE,
|
|
233
|
+
...WARDLEY_LEGEND_DESC_WORDINGS,
|
|
234
|
+
...WARDLEY_LEGEND_GRADIENT_WORDINGS,
|
|
235
|
+
...WARDLEY_LEGEND_PORTER_WORDINGS,
|
|
236
|
+
];
|
|
147
237
|
/**
|
|
148
238
|
* Build a "Legend" group from real, editable elements (white rect frame +
|
|
149
239
|
* "Legend" text + one row of [real component glyph + description text] per
|
|
@@ -482,8 +572,8 @@ export function createWardleyLegend(std, bg) {
|
|
|
482
572
|
type: 'shape',
|
|
483
573
|
shapeType: 'rect',
|
|
484
574
|
filled: true,
|
|
485
|
-
fillColor:
|
|
486
|
-
strokeColor:
|
|
575
|
+
fillColor: NOTATION_NEUTRALS.cardFill,
|
|
576
|
+
strokeColor: NOTATION_NEUTRALS.legendBorder,
|
|
487
577
|
strokeWidth: 1,
|
|
488
578
|
shapeStyle: ShapeStyle.General,
|
|
489
579
|
roughness: 0,
|
|
@@ -491,13 +581,13 @@ export function createWardleyLegend(std, bg) {
|
|
|
491
581
|
xywh: new Bound(x0, y0, W, H).serialize(),
|
|
492
582
|
}));
|
|
493
583
|
// Title.
|
|
494
|
-
ids.push(text(
|
|
584
|
+
ids.push(text(translateKey(std, ...WARDLEY_LEGEND_TITLE), x0 + PAD, y0 + PAD, W - PAD * 2, TITLE_FS + 6, TITLE_FS));
|
|
495
585
|
// Rows.
|
|
496
586
|
let ry = y0 + PAD + TITLE_H;
|
|
497
587
|
for (const t of rows) {
|
|
498
588
|
const cyRow = ry + ROW_H / 2;
|
|
499
589
|
ids.push(...glyph(t, x0 + PAD + GLYPH_W / 2, cyRow));
|
|
500
|
-
ids.push(text(LEGEND_DESC[t], x0 + PAD + GLYPH_W + GAP, cyRow - (TEXT_FS + 8) / 2, TEXT_W, TEXT_FS + 8, TEXT_FS));
|
|
590
|
+
ids.push(text(translateKey(std, ...LEGEND_DESC[t]), x0 + PAD + GLYPH_W + GAP, cyRow - (TEXT_FS + 8) / 2, TEXT_W, TEXT_FS + 8, TEXT_FS));
|
|
501
591
|
ry += ROW_H;
|
|
502
592
|
}
|
|
503
593
|
// Gradient meaning block: a separator, then [2-colour swatch | caption].
|
|
@@ -507,8 +597,8 @@ export function createWardleyLegend(std, bg) {
|
|
|
507
597
|
type: 'shape',
|
|
508
598
|
shapeType: 'rect',
|
|
509
599
|
filled: true,
|
|
510
|
-
fillColor:
|
|
511
|
-
strokeColor:
|
|
600
|
+
fillColor: NOTATION_NEUTRALS.legendBorder,
|
|
601
|
+
strokeColor: NOTATION_NEUTRALS.legendBorder,
|
|
512
602
|
strokeWidth: 0,
|
|
513
603
|
shapeStyle: ShapeStyle.General,
|
|
514
604
|
roughness: 0,
|
|
@@ -525,7 +615,7 @@ export function createWardleyLegend(std, bg) {
|
|
|
525
615
|
shapeType: 'rect',
|
|
526
616
|
filled: true,
|
|
527
617
|
fillColor: col,
|
|
528
|
-
strokeColor:
|
|
618
|
+
strokeColor: NOTATION_NEUTRALS.legendBorder,
|
|
529
619
|
strokeWidth: 0.5,
|
|
530
620
|
shapeStyle: ShapeStyle.General,
|
|
531
621
|
roughness: 0,
|
|
@@ -533,7 +623,7 @@ export function createWardleyLegend(std, bg) {
|
|
|
533
623
|
xywh: new Bound(sx + i * (sw + sgap), cyRow - sw / 2, sw, sw).serialize(),
|
|
534
624
|
}));
|
|
535
625
|
});
|
|
536
|
-
ids.push(text(grad.caption, x0 + PAD + GLYPH_W + GAP, cyRow - GRAD_ROW_H / 2, TEXT_W, GRAD_ROW_H, TEXT_FS));
|
|
626
|
+
ids.push(text(translateKey(std, ...grad.caption), x0 + PAD + GLYPH_W + GAP, cyRow - GRAD_ROW_H / 2, TEXT_W, GRAD_ROW_H, TEXT_FS));
|
|
537
627
|
}
|
|
538
628
|
// Porter's five forces: the panel the PO's reference draws, under everything
|
|
539
629
|
// else. It is not a row — a row says what a glyph IS, and this says what the
|
|
@@ -559,7 +649,7 @@ export function createWardleyLegend(std, bg) {
|
|
|
559
649
|
xywh: new Bound(px, py, panel.w, panel.h).serialize(),
|
|
560
650
|
}));
|
|
561
651
|
const [tx, ty, tw, th] = panel.title;
|
|
562
|
-
ids.push(text(
|
|
652
|
+
ids.push(text(translateKey(std, ...WARDLEY_LEGEND_PORTER_TITLE), px + tx, py + ty, tw, th, p.titleFs));
|
|
563
653
|
const [cx, cy] = panel.center;
|
|
564
654
|
ids.push(surface.addElement({
|
|
565
655
|
type: 'wardleyNode',
|
|
@@ -592,7 +682,7 @@ export function createWardleyLegend(std, bg) {
|
|
|
592
682
|
type: 'shape',
|
|
593
683
|
shapeType: 'rect',
|
|
594
684
|
filled: true,
|
|
595
|
-
fillColor:
|
|
685
|
+
fillColor: NODE_FILL,
|
|
596
686
|
strokeColor: NODE_STROKE,
|
|
597
687
|
strokeWidth: 1,
|
|
598
688
|
shapeStyle: ShapeStyle.General,
|
|
@@ -600,10 +690,10 @@ export function createWardleyLegend(std, bg) {
|
|
|
600
690
|
radius: 0,
|
|
601
691
|
xywh: new Bound(px + bx, py + by, bw, bh).serialize(),
|
|
602
692
|
}));
|
|
603
|
-
ids.push(text(box.label, px + bx + 4, py + by + 3, bw - 8, bh - 6, p.boxFs, 'center'));
|
|
693
|
+
ids.push(text(translateKey(std, ...box.label), px + bx + 4, py + by + 3, bw - 8, bh - 6, p.boxFs, 'center'));
|
|
604
694
|
}
|
|
605
695
|
const [capX, capY, capW, capH] = panel.caption;
|
|
606
|
-
ids.push(text(PORTER_CAPTION, px + capX, py + capY, capW, capH, p.captionFs, 'center'));
|
|
696
|
+
ids.push(text(translateKey(std, ...PORTER_CAPTION), px + capX, py + capY, capW, capH, p.captionFs, 'center'));
|
|
607
697
|
}
|
|
608
698
|
// 4. Group everything and select it.
|
|
609
699
|
const [, result] = std.command.exec(createGroupCommand, { elements: ids });
|
package/dist/morph.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type MorphSpec } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import { WardleyNodeElementModel } from '@formicoidea/labre-core/model';
|
|
3
|
+
import type { BlockStdScope } from '@formicoidea/labre-core/std';
|
|
3
4
|
import type { GfxPrimitiveElementModel } from '@formicoidea/labre-core/std/gfx';
|
|
4
5
|
/**
|
|
5
6
|
* What a Wardley artefact may BECOME — the declaration behind the "Change type"
|
|
@@ -81,8 +82,17 @@ export declare function wardleyNodeOfComponent(model: GfxPrimitiveElementModel):
|
|
|
81
82
|
*
|
|
82
83
|
* Pure and total over every string: the input is a canvas text element somebody
|
|
83
84
|
* may have typed anything into.
|
|
85
|
+
*
|
|
86
|
+
* `std` is OPTIONAL: "untouched" means equal to the English prompt OR to the
|
|
87
|
+
* host's own resolved wording for `from`'s kind, and the target's prompt is
|
|
88
|
+
* likewise resolved through the host when one is given — mirroring
|
|
89
|
+
* `c4MorphedTypeLine`'s fix for the identical class of gap. With no `std`
|
|
90
|
+
* this behaves exactly as it always has (English only). The morph toolbar's
|
|
91
|
+
* `afterMorph` callback (`MorphSpec`, `packages/affine/blocks/surface`) now
|
|
92
|
+
* hands its callee the inserting editor's `std`, so `rewriteLabel` below
|
|
93
|
+
* passes it straight through.
|
|
84
94
|
*/
|
|
85
|
-
export declare function wardleyMorphedLabel(from: WardleyMorphKind, to: WardleyMorphKind, rawText: string | null | undefined): string | null;
|
|
95
|
+
export declare function wardleyMorphedLabel(from: WardleyMorphKind, to: WardleyMorphKind, rawText: string | null | undefined, std?: BlockStdScope): string | null;
|
|
86
96
|
/**
|
|
87
97
|
* Everything the morph owes a Wardley composite beyond the props patch — the
|
|
88
98
|
* `afterMorph` half of the spec, run inside the generic module's one
|
|
@@ -110,7 +120,7 @@ export declare function wardleyMorphedLabel(from: WardleyMorphKind, to: WardleyM
|
|
|
110
120
|
* LEAVING comes apart before the one it is arriving at is built, so a
|
|
111
121
|
* market → pipeline never has three dots and a handle at once.
|
|
112
122
|
*/
|
|
113
|
-
export declare function wardleyMorphComposite(selected: GfxPrimitiveElementModel, from: WardleyMorphKind, to: WardleyMorphKind): void;
|
|
123
|
+
export declare function wardleyMorphComposite(selected: GfxPrimitiveElementModel, from: WardleyMorphKind, to: WardleyMorphKind, std?: BlockStdScope): void;
|
|
114
124
|
/**
|
|
115
125
|
* Wardley's morph declaration, handed to the generic `morphToolbarConfig`.
|
|
116
126
|
*
|
package/dist/morph.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { morphLabel, } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import { ConnectorElementModel, GroupElementModel, TextElementModel, WardleyNodeElementModel, } from '@formicoidea/labre-core/model';
|
|
3
|
+
import { translateKey } from '@formicoidea/labre-core/shared/services';
|
|
3
4
|
import { wardleyCommandIcons, wardleyCommands } from './commands.js';
|
|
4
|
-
import { wardleyCanonicalBox, wardleyHandleBox, wardleyHandleProps, wardleyMarketDotBoxes, wardleyMarketDotProps, wardleyMarketLinkPairs, wardleyMarketLinkProps, WARDLEY_NODE_LABEL, wardleyMorphClears, wardleyMorphProps, } from './presets.js';
|
|
5
|
+
import { wardleyCanonicalBox, wardleyHandleBox, wardleyHandleProps, wardleyMarketDotBoxes, wardleyMarketDotProps, wardleyMarketLinkPairs, wardleyMarketLinkProps, WARDLEY_NODE_LABEL, wardleyMorphClears, wardleyMorphProps, wardleyNodeLabelKey, } from './presets.js';
|
|
5
6
|
import { WARDLEY_ROLE } from './roles.js';
|
|
6
7
|
/**
|
|
7
8
|
* What a Wardley artefact may BECOME — the declaration behind the "Change type"
|
|
@@ -148,11 +149,26 @@ export function wardleyNodeOfComponent(model) {
|
|
|
148
149
|
*
|
|
149
150
|
* Pure and total over every string: the input is a canvas text element somebody
|
|
150
151
|
* may have typed anything into.
|
|
152
|
+
*
|
|
153
|
+
* `std` is OPTIONAL: "untouched" means equal to the English prompt OR to the
|
|
154
|
+
* host's own resolved wording for `from`'s kind, and the target's prompt is
|
|
155
|
+
* likewise resolved through the host when one is given — mirroring
|
|
156
|
+
* `c4MorphedTypeLine`'s fix for the identical class of gap. With no `std`
|
|
157
|
+
* this behaves exactly as it always has (English only). The morph toolbar's
|
|
158
|
+
* `afterMorph` callback (`MorphSpec`, `packages/affine/blocks/surface`) now
|
|
159
|
+
* hands its callee the inserting editor's `std`, so `rewriteLabel` below
|
|
160
|
+
* passes it straight through.
|
|
151
161
|
*/
|
|
152
|
-
export function wardleyMorphedLabel(from, to, rawText) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
162
|
+
export function wardleyMorphedLabel(from, to, rawText, std) {
|
|
163
|
+
const text = (rawText ?? '').trim();
|
|
164
|
+
const fromPrompt = std
|
|
165
|
+
? translateKey(std, wardleyNodeLabelKey(from), WARDLEY_NODE_LABEL[from])
|
|
166
|
+
: WARDLEY_NODE_LABEL[from];
|
|
167
|
+
if (text !== WARDLEY_NODE_LABEL[from] && text !== fromPrompt)
|
|
168
|
+
return null;
|
|
169
|
+
return std
|
|
170
|
+
? translateKey(std, wardleyNodeLabelKey(to), WARDLEY_NODE_LABEL[to])
|
|
171
|
+
: WARDLEY_NODE_LABEL[to];
|
|
156
172
|
}
|
|
157
173
|
/** The centre of an element, from the box it currently occupies. */
|
|
158
174
|
function centreOf(model) {
|
|
@@ -309,12 +325,12 @@ function removeHandle(group, carrier) {
|
|
|
309
325
|
* inside the caller's `captureSync`, so the rewrite is part of the same single
|
|
310
326
|
* ctrl+z as the kind that made it necessary.
|
|
311
327
|
*/
|
|
312
|
-
function rewriteLabel(group, from, to) {
|
|
328
|
+
function rewriteLabel(group, from, to, std) {
|
|
313
329
|
const label = labelOfComposite(group);
|
|
314
330
|
if (!label || label.isLocked())
|
|
315
331
|
return;
|
|
316
332
|
const text = label.text.toString().trim();
|
|
317
|
-
const next = wardleyMorphedLabel(from, to, text);
|
|
333
|
+
const next = wardleyMorphedLabel(from, to, text, std);
|
|
318
334
|
if (next === null || next === text)
|
|
319
335
|
return;
|
|
320
336
|
label.surface.store.transact(() => {
|
|
@@ -349,7 +365,7 @@ function rewriteLabel(group, from, to) {
|
|
|
349
365
|
* LEAVING comes apart before the one it is arriving at is built, so a
|
|
350
366
|
* market → pipeline never has three dots and a handle at once.
|
|
351
367
|
*/
|
|
352
|
-
export function wardleyMorphComposite(selected, from, to) {
|
|
368
|
+
export function wardleyMorphComposite(selected, from, to, std) {
|
|
353
369
|
if (!(selected instanceof GroupElementModel))
|
|
354
370
|
return;
|
|
355
371
|
const carrier = wardleyNodeOfComponent(selected);
|
|
@@ -367,7 +383,7 @@ export function wardleyMorphComposite(selected, from, to) {
|
|
|
367
383
|
addMarketGlyph(selected, cx, cy);
|
|
368
384
|
if (to === 'pipeline')
|
|
369
385
|
addHandle(selected, carrier, cx, cy);
|
|
370
|
-
rewriteLabel(selected, from, to);
|
|
386
|
+
rewriteLabel(selected, from, to, std);
|
|
371
387
|
}
|
|
372
388
|
/**
|
|
373
389
|
* Wardley's morph declaration, handed to the generic `morphToolbarConfig`.
|
package/dist/natures.js
CHANGED
|
@@ -86,11 +86,14 @@ export const WARDLEY_TAG_DEFS = {
|
|
|
86
86
|
packId: 'wardley-core',
|
|
87
87
|
framework: 'wardley',
|
|
88
88
|
label: 'Wardley',
|
|
89
|
+
labelKey: 'com.labre.wardley.tag-pack.label',
|
|
89
90
|
tags: [
|
|
90
91
|
{
|
|
91
92
|
id: WARDLEY_NATURE_TAG_ID,
|
|
92
93
|
label: 'Nature',
|
|
94
|
+
labelKey: 'com.labre.wardley.tag.nature',
|
|
93
95
|
description: 'What kind of thing this component is: an activity, data, a practice or knowledge.',
|
|
96
|
+
descriptionKey: 'com.labre.wardley.tag.nature.description',
|
|
94
97
|
cardinality: 'single',
|
|
95
98
|
appliesTo: [WARDLEY_ROLE.component],
|
|
96
99
|
// No `order`, on either tag of this pack: an absent order sorts by SEED
|
|
@@ -103,29 +106,39 @@ export const WARDLEY_TAG_DEFS = {
|
|
|
103
106
|
{
|
|
104
107
|
id: WARDLEY_NATURE.activity,
|
|
105
108
|
label: 'Activity',
|
|
109
|
+
labelKey: 'com.labre.wardley.tag.nature.activity',
|
|
106
110
|
description: 'Something that is DONE — a step, a service, a process.',
|
|
111
|
+
descriptionKey: 'com.labre.wardley.tag.nature.activity.description',
|
|
107
112
|
},
|
|
108
113
|
{
|
|
109
114
|
id: WARDLEY_NATURE.data,
|
|
110
115
|
label: 'Data',
|
|
116
|
+
labelKey: 'com.labre.wardley.tag.nature.data',
|
|
111
117
|
description: 'Something that is RECORDED — a dataset, a register.',
|
|
118
|
+
descriptionKey: 'com.labre.wardley.tag.nature.data.description',
|
|
112
119
|
},
|
|
113
120
|
{
|
|
114
121
|
id: WARDLEY_NATURE.practice,
|
|
115
122
|
label: 'Practice',
|
|
123
|
+
labelKey: 'com.labre.wardley.tag.nature.practice',
|
|
116
124
|
description: 'A way of doing — a method, a convention, an operating model.',
|
|
125
|
+
descriptionKey: 'com.labre.wardley.tag.nature.practice.description',
|
|
117
126
|
},
|
|
118
127
|
{
|
|
119
128
|
id: WARDLEY_NATURE.knowledge,
|
|
120
129
|
label: 'Knowledge',
|
|
130
|
+
labelKey: 'com.labre.wardley.tag.nature.knowledge',
|
|
121
131
|
description: 'Something that is KNOWN — a model, a theory, a rule.',
|
|
132
|
+
descriptionKey: 'com.labre.wardley.tag.nature.knowledge.description',
|
|
122
133
|
},
|
|
123
134
|
],
|
|
124
135
|
},
|
|
125
136
|
{
|
|
126
137
|
id: WARDLEY_COMPETITION_TAG_ID,
|
|
127
138
|
label: 'Competition',
|
|
139
|
+
labelKey: 'com.labre.wardley.tag.competition',
|
|
128
140
|
description: "Which of Porter's forces this glyph marks: relative competition, a struggle for survival, or a struggle to establish.",
|
|
141
|
+
descriptionKey: 'com.labre.wardley.tag.competition.description',
|
|
129
142
|
cardinality: 'single',
|
|
130
143
|
appliesTo: [WARDLEY_ROLE.porter],
|
|
131
144
|
values: [
|
|
@@ -135,17 +148,23 @@ export const WARDLEY_TAG_DEFS = {
|
|
|
135
148
|
// shows: a reader picking a value here is choosing what the circle
|
|
136
149
|
// will say, not filling in a form about it.
|
|
137
150
|
label: 'Relative competition (R)',
|
|
151
|
+
labelKey: 'com.labre.wardley.tag.competition.relative',
|
|
138
152
|
description: 'Established players competing against one another on a market that exists.',
|
|
153
|
+
descriptionKey: 'com.labre.wardley.tag.competition.relative.description',
|
|
139
154
|
},
|
|
140
155
|
{
|
|
141
156
|
id: WARDLEY_COMPETITION.struggle,
|
|
142
157
|
label: 'Struggle for survival (L)',
|
|
158
|
+
labelKey: 'com.labre.wardley.tag.competition.struggle',
|
|
143
159
|
description: 'Pressure on a player to stay in a market it is already in.',
|
|
160
|
+
descriptionKey: 'com.labre.wardley.tag.competition.struggle.description',
|
|
144
161
|
},
|
|
145
162
|
{
|
|
146
163
|
id: WARDLEY_COMPETITION.establish,
|
|
147
164
|
label: 'Struggle to establish (E)',
|
|
165
|
+
labelKey: 'com.labre.wardley.tag.competition.establish',
|
|
148
166
|
description: 'Pressure on a newcomer trying to get into a market.',
|
|
167
|
+
descriptionKey: 'com.labre.wardley.tag.competition.establish.description',
|
|
149
168
|
},
|
|
150
169
|
],
|
|
151
170
|
},
|
package/dist/node/consts.d.ts
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
/** Default node diameter (= the map label font size, 18). White fill, thin border. */
|
|
11
11
|
export declare const NODE_SIZE = 18;
|
|
12
|
-
|
|
13
|
-
export declare const
|
|
12
|
+
/** The shared notation scale's card fill and ink — Wardley is its reference. */
|
|
13
|
+
export declare const NODE_FILL: string;
|
|
14
|
+
export declare const NODE_STROKE: string;
|
|
14
15
|
/** Thin border, matching the link / silhouette line weight. */
|
|
15
16
|
export declare const NODE_STROKE_WIDTH = 1;
|
|
16
17
|
/**
|
|
@@ -53,11 +54,33 @@ export declare const PIPELINE_LABEL = "Pipeline";
|
|
|
53
54
|
* to the 1px node border.
|
|
54
55
|
*/
|
|
55
56
|
export declare const LINK_STROKE_WIDTH = 2;
|
|
56
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Wardley red ("future"/evolution) — matches the validated arrow icon.
|
|
59
|
+
*
|
|
60
|
+
* An IDENTITY colour: the legend recognises a stored evolution link by it
|
|
61
|
+
* (`legend.ts`, `el.stroke === WARDLEY_RED`). It stays a literal and must never
|
|
62
|
+
* be derived from `NOTATION_NEUTRALS` or any other scale — a change of value
|
|
63
|
+
* would orphan every link already drawn with it.
|
|
64
|
+
*/
|
|
57
65
|
export declare const WARDLEY_RED = "#d6455d";
|
|
58
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* Dependency link grey.
|
|
68
|
+
*
|
|
69
|
+
* An IDENTITY colour: the legend recognises a stored dependency link by it
|
|
70
|
+
* (`legend.ts`, `el.stroke === LINK_GREY`). It stays a literal and must never
|
|
71
|
+
* be derived from `NOTATION_NEUTRALS` — a change of value would orphan every
|
|
72
|
+
* link already drawn with it.
|
|
73
|
+
*/
|
|
59
74
|
export declare const LINK_GREY = "#666666";
|
|
60
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* Inertia bar color + size.
|
|
77
|
+
*
|
|
78
|
+
* An IDENTITY colour: the legend recognises a stored inertia bar by it
|
|
79
|
+
* (`legend.ts`, `el.fillColor === INERTIA_COLOR`). It happens to equal the
|
|
80
|
+
* scale's ink today, but it stays a literal and must never be derived from
|
|
81
|
+
* `NOTATION_NEUTRALS`: a change of the shared ink would orphan every inertia bar
|
|
82
|
+
* already on a map.
|
|
83
|
+
*/
|
|
61
84
|
export declare const INERTIA_COLOR = "#1f2328";
|
|
62
85
|
export declare const INERTIA_SIZE: {
|
|
63
86
|
w: number;
|
|
@@ -75,7 +98,7 @@ export declare const MARKET_DOT_RING = 8;
|
|
|
75
98
|
export declare const MARKET_DOT_STROKE_WIDTH = 2;
|
|
76
99
|
/** Triangle connectors: thin + dark, no arrows. */
|
|
77
100
|
export declare const MARKET_LINK_WIDTH = 1;
|
|
78
|
-
export declare const MARKET_LINK_COLOR
|
|
101
|
+
export declare const MARKET_LINK_COLOR: string;
|
|
79
102
|
export declare const MARKET_LABEL = "Market";
|
|
80
103
|
/**
|
|
81
104
|
* Ecosystem node: a single connectable circle drawn as a GLYPH — a double border
|
package/dist/node/consts.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NOTATION_NEUTRALS } from '@formicoidea/labre-core/shared/consts';
|
|
1
2
|
/**
|
|
2
3
|
* Visual constants for Wardley nodes (component + anchor) and the connector /
|
|
3
4
|
* inertia presets created from the Wardley menu.
|
|
@@ -9,8 +10,9 @@
|
|
|
9
10
|
*/
|
|
10
11
|
/** Default node diameter (= the map label font size, 18). White fill, thin border. */
|
|
11
12
|
export const NODE_SIZE = 18;
|
|
12
|
-
|
|
13
|
-
export const
|
|
13
|
+
/** The shared notation scale's card fill and ink — Wardley is its reference. */
|
|
14
|
+
export const NODE_FILL = NOTATION_NEUTRALS.cardFill;
|
|
15
|
+
export const NODE_STROKE = NOTATION_NEUTRALS.ink;
|
|
14
16
|
/** Thin border, matching the link / silhouette line weight. */
|
|
15
17
|
export const NODE_STROKE_WIDTH = 1;
|
|
16
18
|
/**
|
|
@@ -50,11 +52,33 @@ export const PIPELINE_LABEL = 'Pipeline';
|
|
|
50
52
|
* to the 1px node border.
|
|
51
53
|
*/
|
|
52
54
|
export const LINK_STROKE_WIDTH = 2;
|
|
53
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* Wardley red ("future"/evolution) — matches the validated arrow icon.
|
|
57
|
+
*
|
|
58
|
+
* An IDENTITY colour: the legend recognises a stored evolution link by it
|
|
59
|
+
* (`legend.ts`, `el.stroke === WARDLEY_RED`). It stays a literal and must never
|
|
60
|
+
* be derived from `NOTATION_NEUTRALS` or any other scale — a change of value
|
|
61
|
+
* would orphan every link already drawn with it.
|
|
62
|
+
*/
|
|
54
63
|
export const WARDLEY_RED = '#d6455d';
|
|
55
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Dependency link grey.
|
|
66
|
+
*
|
|
67
|
+
* An IDENTITY colour: the legend recognises a stored dependency link by it
|
|
68
|
+
* (`legend.ts`, `el.stroke === LINK_GREY`). It stays a literal and must never
|
|
69
|
+
* be derived from `NOTATION_NEUTRALS` — a change of value would orphan every
|
|
70
|
+
* link already drawn with it.
|
|
71
|
+
*/
|
|
56
72
|
export const LINK_GREY = '#666666';
|
|
57
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Inertia bar color + size.
|
|
75
|
+
*
|
|
76
|
+
* An IDENTITY colour: the legend recognises a stored inertia bar by it
|
|
77
|
+
* (`legend.ts`, `el.fillColor === INERTIA_COLOR`). It happens to equal the
|
|
78
|
+
* scale's ink today, but it stays a literal and must never be derived from
|
|
79
|
+
* `NOTATION_NEUTRALS`: a change of the shared ink would orphan every inertia bar
|
|
80
|
+
* already on a map.
|
|
81
|
+
*/
|
|
58
82
|
export const INERTIA_COLOR = '#1f2328';
|
|
59
83
|
export const INERTIA_SIZE = { w: 8, h: 44 };
|
|
60
84
|
/**
|
package/dist/presets.d.ts
CHANGED
|
@@ -72,6 +72,27 @@ export type WardleyLabelledKind = Exclude<WardleyArtefactKind, 'porter' | 'area'
|
|
|
72
72
|
* still carries, and the only string a morph is ever allowed to rewrite.
|
|
73
73
|
*/
|
|
74
74
|
export declare const WARDLEY_NODE_LABEL: Record<WardleyLabelledKind, string>;
|
|
75
|
+
/**
|
|
76
|
+
* The i18n key {@link WARDLEY_NODE_LABEL} is the English default of —
|
|
77
|
+
* resolved at placement (`createWardleyNode` / `createWardleyPipeline` /
|
|
78
|
+
* `createWardleyMarket`), never afterwards. "Pipeline" is the PO's glossary
|
|
79
|
+
* term for Wardley: the French proposal IS the English word.
|
|
80
|
+
*
|
|
81
|
+
* ## The morph's placeholder detection, translated
|
|
82
|
+
*
|
|
83
|
+
* `wardleyMorphedLabel` (`morph.ts`) decides whether to refresh an artefact's
|
|
84
|
+
* name across a morph, and accepts an OPTIONAL `std`: given one, it
|
|
85
|
+
* recognises the stored text as "untouched" whether it reads the English
|
|
86
|
+
* prompt or the host's own resolved wording, and resolves the TARGET kind's
|
|
87
|
+
* prompt through the host too (the same fix `c4MorphedTypeLine` carries,
|
|
88
|
+
* `gfx/c4/src/type-line.ts`). `MorphSpec.afterMorph`
|
|
89
|
+
* (`packages/affine/blocks/surface`) now hands its callee the morph
|
|
90
|
+
* toolbar's own `std`, so `rewriteLabel` passes it straight through: on a
|
|
91
|
+
* host running a French catalogue, morphing an untouched TRANSLATED node
|
|
92
|
+
* rewrites its name to the target kind's own translated prompt, exactly as a
|
|
93
|
+
* standalone playground already rewrote the English one.
|
|
94
|
+
*/
|
|
95
|
+
export declare const wardleyNodeLabelKey: (kind: WardleyLabelledKind) => string;
|
|
75
96
|
/** A box centred on a point — how every Wardley creation site places a node. */
|
|
76
97
|
export declare function wardleyCenteredBox(cx: number, cy: number, w: number, h: number): string;
|
|
77
98
|
/** The canonical box of one kind, centred where the artefact already stands. */
|
package/dist/presets.js
CHANGED
|
@@ -65,6 +65,27 @@ export const WARDLEY_NODE_LABEL = {
|
|
|
65
65
|
accelerator: ACCELERATOR_LABEL,
|
|
66
66
|
decelerator: DECELERATOR_LABEL,
|
|
67
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* The i18n key {@link WARDLEY_NODE_LABEL} is the English default of —
|
|
70
|
+
* resolved at placement (`createWardleyNode` / `createWardleyPipeline` /
|
|
71
|
+
* `createWardleyMarket`), never afterwards. "Pipeline" is the PO's glossary
|
|
72
|
+
* term for Wardley: the French proposal IS the English word.
|
|
73
|
+
*
|
|
74
|
+
* ## The morph's placeholder detection, translated
|
|
75
|
+
*
|
|
76
|
+
* `wardleyMorphedLabel` (`morph.ts`) decides whether to refresh an artefact's
|
|
77
|
+
* name across a morph, and accepts an OPTIONAL `std`: given one, it
|
|
78
|
+
* recognises the stored text as "untouched" whether it reads the English
|
|
79
|
+
* prompt or the host's own resolved wording, and resolves the TARGET kind's
|
|
80
|
+
* prompt through the host too (the same fix `c4MorphedTypeLine` carries,
|
|
81
|
+
* `gfx/c4/src/type-line.ts`). `MorphSpec.afterMorph`
|
|
82
|
+
* (`packages/affine/blocks/surface`) now hands its callee the morph
|
|
83
|
+
* toolbar's own `std`, so `rewriteLabel` passes it straight through: on a
|
|
84
|
+
* host running a French catalogue, morphing an untouched TRANSLATED node
|
|
85
|
+
* rewrites its name to the target kind's own translated prompt, exactly as a
|
|
86
|
+
* standalone playground already rewrote the English one.
|
|
87
|
+
*/
|
|
88
|
+
export const wardleyNodeLabelKey = (kind) => `com.labre.wardley.seed.${kind}`;
|
|
68
89
|
/**
|
|
69
90
|
* The fill a kind is born with. White for every circle that means "a thing on
|
|
70
91
|
* the value chain"; the method's grey is the one that carries meaning — it
|
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
import { type TemplateCategory } from '@formicoidea/labre-core/gfx/template';
|
|
2
|
+
import type { ChromeWording } from '@formicoidea/labre-core/shared/services';
|
|
3
|
+
/**
|
|
4
|
+
* The two hand-drawn palette swatches' own tile names (`Template.nameKey`):
|
|
5
|
+
* neither derives from a command, since `linkTool` / `evolutionArrow`
|
|
6
|
+
* activate a tool rather than draw anything (see `tpl` below and its
|
|
7
|
+
* docstring).
|
|
8
|
+
*/
|
|
9
|
+
export declare const WARDLEY_TEMPLATE_NAME_LINK: ChromeWording;
|
|
10
|
+
export declare const WARDLEY_TEMPLATE_NAME_EVOLUTION_ARROW: ChromeWording;
|
|
2
11
|
export declare const wardleyTemplateCategory: TemplateCategory;
|