@transitrix/diagrams 1.0.1 → 1.1.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/activities/cpm.js +11 -2
- package/dist/activities/gantt.js +6 -3
- package/dist/activities/types.d.ts +1 -0
- package/dist/activities/validate.js +3 -3
- package/dist/activity-card/__tests__/resolver.test.js +22 -1
- package/dist/activity-card/resolver.js +11 -5
- package/dist/compliance/__tests__/impact.test.js +198 -0
- package/dist/compliance/html.js +1 -7
- package/dist/compliance/impact.d.ts +24 -1
- package/dist/compliance/impact.js +97 -21
- package/dist/factor/__tests__/validate.test.js +3 -3
- package/dist/factor/types.d.ts +1 -1
- package/dist/factor/validate.js +2 -2
- package/dist/fgca/__tests__/chain-table.test.js +2 -2
- package/dist/fgca/__tests__/layout.test.js +11 -11
- package/dist/fgca/__tests__/preview-layout.test.js +7 -7
- package/dist/fgca/__tests__/resolver.test.js +2 -2
- package/dist/fgca/chain-table.d.ts +1 -1
- package/dist/fgca/chain-table.js +4 -4
- package/dist/fgca/index.d.ts +2 -2
- package/dist/fgca/index.js +1 -1
- package/dist/fgca/layout.d.ts +2 -2
- package/dist/fgca/layout.js +9 -9
- package/dist/fgca/nodeTypes.d.ts +1 -1
- package/dist/fgca/nodeTypes.js +2 -2
- package/dist/fgca/nodes/FGCAFactorNode.d.ts +3 -3
- package/dist/fgca/nodes/FGCAFactorNode.js +5 -5
- package/dist/fgca/parse-canonical.js +15 -10
- package/dist/fgca/preview-layout.d.ts +1 -1
- package/dist/fgca/preview-layout.js +4 -4
- package/dist/fgca/resolver.js +3 -1
- package/dist/fgca/types.d.ts +11 -11
- package/dist/fgca/types.js +2 -2
- package/dist/fgca/validate.d.ts +2 -2
- package/dist/fgca/validate.js +17 -14
- package/dist/process-blueprint/index.d.ts +1 -1
- package/dist/process-blueprint/layout.js +64 -37
- package/dist/process-blueprint/types.d.ts +14 -0
- package/dist/scenarios/index.d.ts +1 -1
- package/dist/scenarios/types.d.ts +4 -4
- package/dist/theme/themes.js +2 -0
- package/dist/theme/tokens.d.ts +7 -1
- package/dist/theme/tokens.js +3 -1
- package/dist/webview/__tests__/entry-notations.test.js +2 -0
- package/dist/webview/__tests__/render-process.test.d.ts +1 -0
- package/dist/webview/__tests__/render-process.test.js +463 -0
- package/dist/webview/__tests__/render-util.test.d.ts +1 -0
- package/dist/webview/__tests__/render-util.test.js +54 -0
- package/dist/webview/entry.d.ts +1 -1
- package/dist/webview/entry.js +9 -5
- package/dist/webview/render-activities.d.ts +21 -1
- package/dist/webview/render-activities.js +91 -56
- package/dist/webview/render-activity-card.d.ts +11 -1
- package/dist/webview/render-activity-card.js +11 -2
- package/dist/webview/render-blocks.d.ts +24 -1
- package/dist/webview/render-blocks.js +58 -24
- package/dist/webview/render-fgca.d.ts +27 -0
- package/dist/webview/render-fgca.js +29 -15
- package/dist/webview/render-goals.d.ts +26 -1
- package/dist/webview/render-goals.js +30 -20
- package/dist/webview/render-process-blueprint.d.ts +11 -1
- package/dist/webview/render-process-blueprint.js +118 -53
- package/dist/webview/render-process.d.ts +95 -0
- package/dist/webview/render-process.js +392 -0
- package/dist/webview/render-scenarios.js +2 -2
- package/dist/webview/render-util.d.ts +19 -6
- package/dist/webview/render-util.js +23 -15
- package/package.json +15 -1
- package/src/activities/cpm.ts +14 -2
- package/src/activities/gantt.ts +6 -5
- package/src/activities/types.ts +1 -0
- package/src/activities/validate.ts +3 -3
- package/src/activity-card/__tests__/resolver.test.ts +24 -1
- package/src/activity-card/resolver.ts +12 -5
- package/src/compliance/__tests__/impact.test.ts +219 -0
- package/src/compliance/html.ts +1 -8
- package/src/compliance/impact.ts +141 -23
- package/src/factor/__tests__/validate.test.ts +3 -3
- package/src/factor/types.ts +1 -1
- package/src/factor/validate.ts +2 -2
- package/src/fgca/__tests__/chain-table.test.ts +2 -2
- package/src/fgca/__tests__/layout.test.ts +13 -13
- package/src/fgca/__tests__/preview-layout.test.ts +7 -7
- package/src/fgca/__tests__/resolver.test.ts +2 -2
- package/src/fgca/chain-table.ts +5 -5
- package/src/fgca/index.ts +3 -3
- package/src/fgca/layout.ts +11 -11
- package/src/fgca/nodeTypes.ts +3 -3
- package/src/fgca/nodes/FGCAFactorNode.tsx +6 -6
- package/src/fgca/parse-canonical.ts +17 -12
- package/src/fgca/preview-layout.ts +5 -5
- package/src/fgca/resolver.ts +3 -1
- package/src/fgca/types.ts +13 -13
- package/src/fgca/validate.ts +17 -14
- package/src/process-blueprint/index.ts +1 -0
- package/src/process-blueprint/layout.ts +71 -42
- package/src/process-blueprint/types.ts +15 -0
- package/src/scenarios/index.ts +2 -2
- package/src/scenarios/types.ts +4 -4
- package/src/scenarios/validate.ts +3 -3
- package/src/theme/themes.ts +2 -0
- package/src/theme/tokens.ts +3 -1
- package/src/webview/__tests__/entry-notations.test.ts +2 -0
- package/src/webview/__tests__/render-process.test.ts +538 -0
- package/src/webview/__tests__/render-util.test.ts +66 -0
- package/src/webview/entry.ts +11 -5
- package/src/webview/render-activities.ts +107 -67
- package/src/webview/render-activity-card.ts +11 -2
- package/src/webview/render-blocks.ts +78 -28
- package/src/webview/render-fgca.ts +52 -28
- package/src/webview/render-goals.ts +45 -23
- package/src/webview/render-process-blueprint.ts +156 -82
- package/src/webview/render-process.ts +507 -0
- package/src/webview/render-scenarios.ts +3 -3
- package/src/webview/render-util.ts +27 -14
package/dist/fgca/validate.js
CHANGED
|
@@ -9,10 +9,13 @@ export function validateFGCADoc(input) {
|
|
|
9
9
|
errors.push({ code: 'MISSING_NOTATION', message: 'notation field is required' });
|
|
10
10
|
return { valid: false, errors, warnings };
|
|
11
11
|
}
|
|
12
|
-
if (raw.notation !== 'fgca') {
|
|
13
|
-
errors.push({ code: 'WRONG_NOTATION', message: `notation must be "fgca", got "${String(raw.notation)}"` });
|
|
12
|
+
if (raw.notation !== 'fgca' && raw.notation !== 'dgca') {
|
|
13
|
+
errors.push({ code: 'WRONG_NOTATION', message: `notation must be "dgca" (or legacy "fgca"), got "${String(raw.notation)}"` });
|
|
14
14
|
return { valid: false, errors, warnings };
|
|
15
15
|
}
|
|
16
|
+
if (raw.notation === 'fgca') {
|
|
17
|
+
warnings.push({ code: 'DEPRECATED_NOTATION', message: 'notation "fgca" is deprecated — rename to "dgca"' });
|
|
18
|
+
}
|
|
16
19
|
if (!Array.isArray(raw.factors))
|
|
17
20
|
errors.push({ code: 'SCHEMA_INVALID', message: 'factors must be an array', path: 'factors' });
|
|
18
21
|
if (!Array.isArray(raw.goals))
|
|
@@ -29,7 +32,7 @@ export function validateFGCADoc(input) {
|
|
|
29
32
|
for (const el of arr) {
|
|
30
33
|
if (el && typeof el === 'object') {
|
|
31
34
|
const id = el.id;
|
|
32
|
-
if (typeof id === 'number')
|
|
35
|
+
if (typeof id === 'number' || typeof id === 'string')
|
|
33
36
|
out.add(id);
|
|
34
37
|
}
|
|
35
38
|
}
|
|
@@ -45,8 +48,8 @@ export function validateFGCADoc(input) {
|
|
|
45
48
|
continue;
|
|
46
49
|
}
|
|
47
50
|
const factor = f;
|
|
48
|
-
if (typeof factor.id !== 'number')
|
|
49
|
-
errors.push({ code: 'SCHEMA_INVALID', message: 'factor id must be a number', path: `factors[${i}]` });
|
|
51
|
+
if (typeof factor.id !== 'number' && typeof factor.id !== 'string')
|
|
52
|
+
errors.push({ code: 'SCHEMA_INVALID', message: 'factor id must be a number or string', path: `factors[${i}]` });
|
|
50
53
|
if (typeof factor.name !== 'string' || !factor.name.trim())
|
|
51
54
|
errors.push({ code: 'EMPTY_NAME', message: `Factor ${String(factor.id)} has empty name`, path: `factors[${i}]` });
|
|
52
55
|
}
|
|
@@ -57,8 +60,8 @@ export function validateFGCADoc(input) {
|
|
|
57
60
|
continue;
|
|
58
61
|
}
|
|
59
62
|
const goal = g;
|
|
60
|
-
if (typeof goal.id !== 'number')
|
|
61
|
-
errors.push({ code: 'SCHEMA_INVALID', message: 'goal id must be a number', path: `goals[${i}]` });
|
|
63
|
+
if (typeof goal.id !== 'number' && typeof goal.id !== 'string')
|
|
64
|
+
errors.push({ code: 'SCHEMA_INVALID', message: 'goal id must be a number or string', path: `goals[${i}]` });
|
|
62
65
|
if (typeof goal.name !== 'string' || !goal.name.trim())
|
|
63
66
|
errors.push({ code: 'EMPTY_NAME', message: `Goal ${String(goal.id)} has empty name`, path: `goals[${i}]` });
|
|
64
67
|
const factorRefs = Array.isArray(goal.factor) ? goal.factor : [];
|
|
@@ -66,7 +69,7 @@ export function validateFGCADoc(input) {
|
|
|
66
69
|
if (!fr || typeof fr !== 'object')
|
|
67
70
|
continue;
|
|
68
71
|
const fid = fr.id;
|
|
69
|
-
if (typeof fid === 'number' && !factorIds.has(fid)) {
|
|
72
|
+
if ((typeof fid === 'number' || typeof fid === 'string') && !factorIds.has(fid)) {
|
|
70
73
|
warnings.push({ code: 'BROKEN_REF', message: `Goal ${String(goal.id)} references missing factor ${fid}`, path: `goals[${i}].factor` });
|
|
71
74
|
}
|
|
72
75
|
}
|
|
@@ -78,16 +81,16 @@ export function validateFGCADoc(input) {
|
|
|
78
81
|
continue;
|
|
79
82
|
}
|
|
80
83
|
const change = c;
|
|
81
|
-
if (typeof change.id !== 'number')
|
|
82
|
-
errors.push({ code: 'SCHEMA_INVALID', message: 'change id must be a number', path: `changes[${i}]` });
|
|
84
|
+
if (typeof change.id !== 'number' && typeof change.id !== 'string')
|
|
85
|
+
errors.push({ code: 'SCHEMA_INVALID', message: 'change id must be a number or string', path: `changes[${i}]` });
|
|
83
86
|
if (typeof change.name !== 'string' || !change.name.trim())
|
|
84
87
|
errors.push({ code: 'EMPTY_NAME', message: `Change ${String(change.id)} has empty name`, path: `changes[${i}]` });
|
|
85
|
-
if (typeof change.goal_id === 'number' && !goalIds.has(change.goal_id)) {
|
|
88
|
+
if ((typeof change.goal_id === 'number' || typeof change.goal_id === 'string') && !goalIds.has(change.goal_id)) {
|
|
86
89
|
warnings.push({ code: 'BROKEN_REF', message: `Change ${String(change.id)} references missing goal ${change.goal_id}`, path: `changes[${i}].goal_id` });
|
|
87
90
|
}
|
|
88
91
|
const aids = Array.isArray(change.activity_ids) ? change.activity_ids : [];
|
|
89
92
|
for (const aid of aids) {
|
|
90
|
-
if (typeof aid === 'number' && !activityIds.has(aid)) {
|
|
93
|
+
if ((typeof aid === 'number' || typeof aid === 'string') && !activityIds.has(aid)) {
|
|
91
94
|
warnings.push({ code: 'BROKEN_REF', message: `Change ${String(change.id)} references missing activity ${aid}`, path: `changes[${i}].activity_ids` });
|
|
92
95
|
}
|
|
93
96
|
}
|
|
@@ -99,8 +102,8 @@ export function validateFGCADoc(input) {
|
|
|
99
102
|
continue;
|
|
100
103
|
}
|
|
101
104
|
const activity = a;
|
|
102
|
-
if (typeof activity.id !== 'number')
|
|
103
|
-
errors.push({ code: 'SCHEMA_INVALID', message: 'activity id must be a number', path: `activities[${i}]` });
|
|
105
|
+
if (typeof activity.id !== 'number' && typeof activity.id !== 'string')
|
|
106
|
+
errors.push({ code: 'SCHEMA_INVALID', message: 'activity id must be a number or string', path: `activities[${i}]` });
|
|
104
107
|
if (typeof activity.name !== 'string' || !activity.name.trim())
|
|
105
108
|
errors.push({ code: 'EMPTY_NAME', message: `Activity ${String(activity.id)} has empty name`, path: `activities[${i}]` });
|
|
106
109
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { AspectCategory, Stage, AspectEntry, LaneConfig, ProcessBlueprintHeader, ProcessBlueprintFile, ProcessBlueprintLayoutOptions, LegendCell, StageHeaderCell, StageTextCell, AspectPill, AspectRow, ProcessBlueprintLayout, ComplianceDecoration, ComplianceChip, ComplianceRow, ComplianceLaneConfig, ComplianceLaneAssertion, ComplianceLaneRequirement, ComplianceLaneInput, } from './types.js';
|
|
1
|
+
export type { AspectCategory, RowId, Stage, AspectEntry, LaneConfig, ProcessBlueprintHeader, ProcessBlueprintFile, ProcessBlueprintLayoutOptions, LegendCell, StageHeaderCell, StageTextCell, AspectPill, AspectRow, ProcessBlueprintLayout, ComplianceDecoration, ComplianceChip, ComplianceRow, ComplianceLaneConfig, ComplianceLaneAssertion, ComplianceLaneRequirement, ComplianceLaneInput, } from './types.js';
|
|
2
2
|
export { validateProcessBlueprint } from './validate.js';
|
|
3
3
|
export type { ValidationError as ProcessBlueprintValidationError, ValidationWarning as ProcessBlueprintValidationWarning, ValidationResult as ProcessBlueprintValidationResult, } from './validate.js';
|
|
4
4
|
export { layoutProcessBlueprint } from './layout.js';
|
|
@@ -12,14 +12,19 @@ const DEFAULTS = {
|
|
|
12
12
|
goalRowHeight: 56,
|
|
13
13
|
resultRowHeight: 56,
|
|
14
14
|
aspectRowMinHeight: 60,
|
|
15
|
-
pillHeight:
|
|
15
|
+
pillHeight: 40,
|
|
16
16
|
pillGap: 4,
|
|
17
17
|
cellPadding: 8,
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
// 17px gives comfortable breathing room between wrapped lines at typical
|
|
19
|
+
// webview font sizes (VS Code uses ~13–14px body, SVG text-secondary ≈ same).
|
|
20
|
+
textLineHeight: 17,
|
|
21
|
+
// 7.5px per char is a conservative estimate that causes wrap to trigger
|
|
22
|
+
// before text visually overflows the cell border.
|
|
23
|
+
textCharWidth: 7.5,
|
|
20
24
|
cellTextPadX: 10,
|
|
21
25
|
cellTextPadY: 10,
|
|
22
|
-
|
|
26
|
+
// No hard truncation: rows grow to fit all wrapped lines.
|
|
27
|
+
maxTextLines: 100,
|
|
23
28
|
};
|
|
24
29
|
function resolveOptions(options) {
|
|
25
30
|
return { ...DEFAULTS, ...(options ?? {}) };
|
|
@@ -285,8 +290,21 @@ function deriveComplianceRow(stages, stageIndexById, input, opts, yStart) {
|
|
|
285
290
|
export function layoutProcessBlueprint(file, options) {
|
|
286
291
|
const opts = resolveOptions(options);
|
|
287
292
|
const pb = file.process_blueprint;
|
|
288
|
-
|
|
293
|
+
// Filter stages by visibleStages if set
|
|
294
|
+
const allStages = Array.isArray(pb?.stages) ? pb.stages : [];
|
|
295
|
+
const stages = opts.visibleStages
|
|
296
|
+
? allStages.filter(s => s?.id != null && opts.visibleStages.includes(s.id))
|
|
297
|
+
: allStages;
|
|
289
298
|
const stageIndexById = buildStageIndex(stages);
|
|
299
|
+
// Row visibility from visibleRows
|
|
300
|
+
const visRows = opts.visibleRows;
|
|
301
|
+
const showGoal = !visRows || visRows.includes('goal');
|
|
302
|
+
const showResult = !visRows || visRows.includes('result');
|
|
303
|
+
const effectiveVisibleAspects = visRows
|
|
304
|
+
? ASPECT_CATEGORIES.filter(c => visRows.includes(c))
|
|
305
|
+
: opts.visibleAspects;
|
|
306
|
+
const effectiveComplianceEnabled = opts.complianceLane?.enabled === true &&
|
|
307
|
+
(!visRows || visRows.includes('compliance'));
|
|
290
308
|
// Stage headers
|
|
291
309
|
const stageHeaders = stages.map((s, i) => ({
|
|
292
310
|
stageIndex: i,
|
|
@@ -307,33 +325,36 @@ export function layoutProcessBlueprint(file, options) {
|
|
|
307
325
|
};
|
|
308
326
|
const goalLines = stages.map(s => wrap(s?.goal ?? ''));
|
|
309
327
|
const resultLines = stages.map(s => wrap(s?.result ?? ''));
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
328
|
+
let cursorY = opts.stageHeaderHeight;
|
|
329
|
+
let goalRowY = 0, goalRowHeight = 0;
|
|
330
|
+
let resultRowY = 0, resultRowHeight = 0;
|
|
331
|
+
const goalCells = [];
|
|
332
|
+
const resultCells = [];
|
|
333
|
+
if (showGoal) {
|
|
334
|
+
goalRowY = cursorY;
|
|
335
|
+
goalRowHeight = rowHeightFor(goalLines.map(l => l.length), opts.goalRowHeight);
|
|
336
|
+
goalCells.push(...stages.map((s, i) => ({
|
|
337
|
+
stageIndex: i, text: s?.goal ?? '', lines: goalLines[i],
|
|
338
|
+
x: opts.legendColumnWidth + i * opts.stageColumnWidth, y: goalRowY,
|
|
339
|
+
width: opts.stageColumnWidth, height: goalRowHeight,
|
|
340
|
+
})));
|
|
341
|
+
cursorY += goalRowHeight;
|
|
342
|
+
}
|
|
343
|
+
if (showResult) {
|
|
344
|
+
resultRowY = cursorY;
|
|
345
|
+
resultRowHeight = rowHeightFor(resultLines.map(l => l.length), opts.resultRowHeight);
|
|
346
|
+
resultCells.push(...stages.map((s, i) => ({
|
|
347
|
+
stageIndex: i, text: s?.result ?? '', lines: resultLines[i],
|
|
348
|
+
x: opts.legendColumnWidth + i * opts.stageColumnWidth, y: resultRowY,
|
|
349
|
+
width: opts.stageColumnWidth, height: resultRowHeight,
|
|
350
|
+
})));
|
|
351
|
+
cursorY += resultRowHeight;
|
|
352
|
+
}
|
|
353
|
+
const aspectsStartY = cursorY;
|
|
333
354
|
// Aspect rows: only categories with at least one entry, in fixed order.
|
|
334
|
-
// When
|
|
335
|
-
const aspectCategoriesToRender =
|
|
336
|
-
? ASPECT_CATEGORIES.filter(c =>
|
|
355
|
+
// When effectiveVisibleAspects is set, skip categories not in the list.
|
|
356
|
+
const aspectCategoriesToRender = effectiveVisibleAspects !== undefined
|
|
357
|
+
? ASPECT_CATEGORIES.filter(c => effectiveVisibleAspects.includes(c))
|
|
337
358
|
: ASPECT_CATEGORIES;
|
|
338
359
|
const aspectRows = [];
|
|
339
360
|
let aspectCursorY = aspectsStartY;
|
|
@@ -358,6 +379,13 @@ export function layoutProcessBlueprint(file, options) {
|
|
|
358
379
|
const x = opts.legendColumnWidth + p.startStageIndex * opts.stageColumnWidth + opts.cellPadding;
|
|
359
380
|
const width = (p.endStageIndex - p.startStageIndex + 1) * opts.stageColumnWidth - 2 * opts.cellPadding;
|
|
360
381
|
const y = aspectCursorY + opts.cellPadding + slot[i] * (opts.pillHeight + opts.pillGap);
|
|
382
|
+
const pillMaxChars = Math.max(4, Math.floor((width - 2 * opts.cellPadding) / opts.textCharWidth));
|
|
383
|
+
const nameWrapped = wrapText(p.name, pillMaxChars, 2);
|
|
384
|
+
// Show id as second line only when the name fits on one line; otherwise
|
|
385
|
+
// use both lines for the name so it isn't truncated.
|
|
386
|
+
const lines = p.id && nameWrapped.length <= 1
|
|
387
|
+
? [...nameWrapped, p.id].slice(0, 2)
|
|
388
|
+
: nameWrapped;
|
|
361
389
|
return {
|
|
362
390
|
category: p.category,
|
|
363
391
|
entryIndex: p.entryIndex,
|
|
@@ -369,6 +397,7 @@ export function layoutProcessBlueprint(file, options) {
|
|
|
369
397
|
y,
|
|
370
398
|
width,
|
|
371
399
|
height: opts.pillHeight,
|
|
400
|
+
lines,
|
|
372
401
|
};
|
|
373
402
|
});
|
|
374
403
|
aspectRows.push({
|
|
@@ -381,7 +410,7 @@ export function layoutProcessBlueprint(file, options) {
|
|
|
381
410
|
}
|
|
382
411
|
// Compliance lane — derived from assertions/requirements, rendered after aspect rows.
|
|
383
412
|
let complianceRow;
|
|
384
|
-
if (
|
|
413
|
+
if (effectiveComplianceEnabled && opts.complianceInput) {
|
|
385
414
|
complianceRow = deriveComplianceRow(stages, stageIndexById, opts.complianceInput, opts, aspectCursorY);
|
|
386
415
|
if (complianceRow) {
|
|
387
416
|
aspectCursorY += complianceRow.height;
|
|
@@ -389,8 +418,8 @@ export function layoutProcessBlueprint(file, options) {
|
|
|
389
418
|
}
|
|
390
419
|
// Legend (left column labels): one entry per row.
|
|
391
420
|
const legend = [
|
|
392
|
-
{ kind: 'goal', label: 'Goal', y: goalRowY, height: goalRowHeight },
|
|
393
|
-
{ kind: 'result', label: 'Result', y: resultRowY, height: resultRowHeight },
|
|
421
|
+
...(showGoal ? [{ kind: 'goal', label: 'Goal', y: goalRowY, height: goalRowHeight }] : []),
|
|
422
|
+
...(showResult ? [{ kind: 'result', label: 'Result', y: resultRowY, height: resultRowHeight }] : []),
|
|
394
423
|
...aspectRows.map(row => ({
|
|
395
424
|
kind: 'aspect',
|
|
396
425
|
category: row.category,
|
|
@@ -398,9 +427,7 @@ export function layoutProcessBlueprint(file, options) {
|
|
|
398
427
|
y: row.y,
|
|
399
428
|
height: row.height,
|
|
400
429
|
})),
|
|
401
|
-
...(complianceRow
|
|
402
|
-
? [{ kind: 'compliance', label: 'Compliance', y: complianceRow.y, height: complianceRow.height }]
|
|
403
|
-
: []),
|
|
430
|
+
...(complianceRow ? [{ kind: 'compliance', label: 'Compliance', y: complianceRow.y, height: complianceRow.height }] : []),
|
|
404
431
|
];
|
|
405
432
|
const totalWidth = opts.legendColumnWidth + stages.length * opts.stageColumnWidth;
|
|
406
433
|
const totalHeight = aspectCursorY;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type AspectCategory = 'systems' | 'actors' | 'equipment' | 'information_entities';
|
|
2
|
+
export type RowId = 'goal' | 'result' | 'systems' | 'actors' | 'equipment' | 'information_entities' | 'compliance';
|
|
2
3
|
/**
|
|
3
4
|
* One of the three orthogonal decoration signals that can appear on a compliance
|
|
4
5
|
* law chip (ADR 2026-06-09-compliance-impact-as-blueprint-lane §3):
|
|
@@ -176,6 +177,17 @@ export interface ProcessBlueprintLayoutOptions {
|
|
|
176
177
|
* Pass an empty array to suppress all aspect rows.
|
|
177
178
|
*/
|
|
178
179
|
visibleAspects?: AspectCategory[];
|
|
180
|
+
/**
|
|
181
|
+
* Restrict which rows are rendered. When absent, all rows with data are shown.
|
|
182
|
+
* When set, takes precedence over `visibleAspects` for aspect categories and
|
|
183
|
+
* overrides `complianceLane.enabled` for the compliance row.
|
|
184
|
+
*/
|
|
185
|
+
visibleRows?: RowId[];
|
|
186
|
+
/**
|
|
187
|
+
* Restrict which stages (columns) are rendered by their stage ID.
|
|
188
|
+
* When absent, all stages are shown.
|
|
189
|
+
*/
|
|
190
|
+
visibleStages?: string[];
|
|
179
191
|
}
|
|
180
192
|
import type { LayoutBounds } from '../geometry.js';
|
|
181
193
|
export type { LayoutBounds };
|
|
@@ -216,6 +228,8 @@ export interface AspectPill {
|
|
|
216
228
|
y: number;
|
|
217
229
|
width: number;
|
|
218
230
|
height: number;
|
|
231
|
+
/** Word-wrapped lines of `name`, pre-fitted to the pill width by the layout. */
|
|
232
|
+
lines: string[];
|
|
219
233
|
}
|
|
220
234
|
export interface AspectRow {
|
|
221
235
|
category: AspectCategory;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { ScenarioStatus,
|
|
1
|
+
export type { ScenarioStatus, DriverRelevance, DriverView, GoalRef, CapabilityRef, ActivityRef, ProductRef, ProcessRef, ApplicationRef, ScenarioHeader, ScenarioFile, } from './types.js';
|
|
2
2
|
export { validateScenario } from './validate.js';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export type ScenarioStatus = 'Draft' | 'Active' | 'Archived';
|
|
2
|
-
export type
|
|
3
|
-
export interface
|
|
2
|
+
export type DriverRelevance = 'High' | 'Medium' | 'Low';
|
|
3
|
+
export interface DriverView {
|
|
4
4
|
factor_id: string;
|
|
5
|
-
relevance?:
|
|
5
|
+
relevance?: DriverRelevance;
|
|
6
6
|
impact?: string;
|
|
7
7
|
}
|
|
8
8
|
export interface GoalRef {
|
|
@@ -30,7 +30,7 @@ export interface ScenarioHeader {
|
|
|
30
30
|
status: ScenarioStatus;
|
|
31
31
|
created_at?: string;
|
|
32
32
|
vision?: string;
|
|
33
|
-
factors_view?:
|
|
33
|
+
factors_view?: DriverView[];
|
|
34
34
|
goals?: GoalRef[];
|
|
35
35
|
capabilities?: CapabilityRef[];
|
|
36
36
|
activities?: ActivityRef[];
|
package/dist/theme/themes.js
CHANGED
|
@@ -62,6 +62,7 @@ function diagramVars(variant) {
|
|
|
62
62
|
const mat = MATURITY_COLORS[variant];
|
|
63
63
|
const levelVars = lv.map((c, i) => `--ts-level-${i}:${c}`).join(';') + ';';
|
|
64
64
|
return [
|
|
65
|
+
`${CSS_VAR.layerDriver}:${lc.driver[variant]}`,
|
|
65
66
|
`${CSS_VAR.layerFactor}:${lc.factor[variant]}`,
|
|
66
67
|
`${CSS_VAR.layerGoal}:${lc.goal[variant]}`,
|
|
67
68
|
`${CSS_VAR.layerChange}:${lc.change[variant]}`,
|
|
@@ -112,6 +113,7 @@ function diagramClassCss() {
|
|
|
112
113
|
// contract every notation preview honours so the catalogue reads as one
|
|
113
114
|
// visual family.
|
|
114
115
|
return `.diagram-node{stroke:var(${cv.nodeStroke});stroke-width:1;}
|
|
116
|
+
.layer-driver{fill:var(${cv.layerDriver});}
|
|
115
117
|
.layer-factor{fill:var(${cv.layerFactor});}
|
|
116
118
|
.layer-goal{fill:var(${cv.layerGoal});}
|
|
117
119
|
.layer-change{fill:var(${cv.layerChange});}
|
package/dist/theme/tokens.d.ts
CHANGED
|
@@ -11,8 +11,13 @@ export declare const FUNCTIONAL: {
|
|
|
11
11
|
readonly error: "#b91c1c";
|
|
12
12
|
readonly info: "#1d6fa8";
|
|
13
13
|
};
|
|
14
|
-
/** Fill colors for FGCA notation columns. */
|
|
14
|
+
/** Fill colors for FGCA/DGCA notation columns. */
|
|
15
15
|
export declare const LAYER_COLORS: {
|
|
16
|
+
readonly driver: {
|
|
17
|
+
readonly light: "#fef3c7";
|
|
18
|
+
readonly dark: "#292108";
|
|
19
|
+
readonly hc: "#f59e0b";
|
|
20
|
+
};
|
|
16
21
|
readonly factor: {
|
|
17
22
|
readonly light: "#fef3c7";
|
|
18
23
|
readonly dark: "#292108";
|
|
@@ -140,6 +145,7 @@ export declare const CSS_VAR: {
|
|
|
140
145
|
readonly statusInfoFg: "--ts-status-info-fg";
|
|
141
146
|
readonly statusErrorBg: "--ts-status-error-bg";
|
|
142
147
|
readonly statusErrorFg: "--ts-status-error-fg";
|
|
148
|
+
readonly layerDriver: "--ts-layer-driver";
|
|
143
149
|
readonly layerFactor: "--ts-layer-factor";
|
|
144
150
|
readonly layerGoal: "--ts-layer-goal";
|
|
145
151
|
readonly layerChange: "--ts-layer-change";
|
package/dist/theme/tokens.js
CHANGED
|
@@ -11,8 +11,9 @@ export const FUNCTIONAL = {
|
|
|
11
11
|
error: '#b91c1c',
|
|
12
12
|
info: '#1d6fa8',
|
|
13
13
|
};
|
|
14
|
-
/** Fill colors for FGCA notation columns. */
|
|
14
|
+
/** Fill colors for FGCA/DGCA notation columns. */
|
|
15
15
|
export const LAYER_COLORS = {
|
|
16
|
+
driver: { light: '#fef3c7', dark: '#292108', hc: '#f59e0b' },
|
|
16
17
|
factor: { light: '#fef3c7', dark: '#292108', hc: '#f59e0b' },
|
|
17
18
|
goal: { light: '#e0e7ff', dark: '#1e1b4b', hc: '#818cf8' },
|
|
18
19
|
change: { light: '#dbeafe', dark: '#0c2042', hc: '#60a5fa' },
|
|
@@ -85,6 +86,7 @@ export const CSS_VAR = {
|
|
|
85
86
|
statusInfoFg: '--ts-status-info-fg',
|
|
86
87
|
statusErrorBg: '--ts-status-error-bg',
|
|
87
88
|
statusErrorFg: '--ts-status-error-fg',
|
|
89
|
+
layerDriver: '--ts-layer-driver',
|
|
88
90
|
layerFactor: '--ts-layer-factor',
|
|
89
91
|
layerGoal: '--ts-layer-goal',
|
|
90
92
|
layerChange: '--ts-layer-change',
|
|
@@ -15,6 +15,8 @@ const EXAMPLES = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../
|
|
|
15
15
|
// example per notation is enough to prove the dispatch + renderer wiring.
|
|
16
16
|
const FIXTURES = [
|
|
17
17
|
{ kind: 'goals', file: 'goals/strategy-2026.goals.transitrix.yaml', markup: 'svg' },
|
|
18
|
+
{ kind: 'dgca', file: 'dgca/strategy-2026.dgca.transitrix.yaml', markup: 'svg' },
|
|
19
|
+
{ kind: 'dga', file: 'dga/strategy-2026.dga.transitrix.yaml', markup: 'svg' },
|
|
18
20
|
{ kind: 'fgca', file: 'fgca/strategy-2026.fgca.transitrix.yaml', markup: 'svg' },
|
|
19
21
|
{ kind: 'fga', file: 'fga/strategy-2026.fga.transitrix.yaml', markup: 'svg' },
|
|
20
22
|
{ kind: 'activities', file: 'activities/platform-launch.activities.transitrix.yaml', markup: 'svg' },
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|