@transitrix/diagrams 1.0.1 → 1.2.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/__tests__/validate.test.js +32 -1
- 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 +24 -8
- package/dist/activity-card/__tests__/resolver.test.js +22 -1
- package/dist/activity-card/__tests__/validate.test.js +23 -1
- package/dist/activity-card/resolver.js +28 -20
- package/dist/activity-card/validate.js +22 -11
- package/dist/capability-map/index.d.ts +4 -0
- package/dist/capability-map/index.js +2 -0
- package/dist/capability-map/layout-tree.d.ts +42 -0
- package/dist/capability-map/layout-tree.js +65 -0
- package/dist/capability-map/render-capability-tree.d.ts +15 -0
- package/dist/capability-map/render-capability-tree.js +108 -0
- package/dist/capability-map/types.d.ts +2 -0
- 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/__tests__/validate.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 +24 -13
- 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 +13 -11
- package/dist/fgca/types.js +2 -2
- package/dist/fgca/validate.d.ts +2 -2
- package/dist/fgca/validate.js +34 -23
- 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/index.d.ts +1 -1
- package/dist/theme/index.js +1 -1
- package/dist/theme/themes.js +28 -3
- package/dist/theme/tokens.d.ts +47 -1
- package/dist/theme/tokens.js +31 -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 +30 -16
- 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/__tests__/validate.test.ts +35 -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 +24 -8
- package/src/activity-card/__tests__/resolver.test.ts +24 -1
- package/src/activity-card/__tests__/validate.test.ts +25 -1
- package/src/activity-card/resolver.ts +29 -20
- package/src/activity-card/validate.ts +20 -11
- package/src/capability-map/index.ts +11 -0
- package/src/capability-map/layout-tree.ts +114 -0
- package/src/capability-map/render-capability-tree.ts +131 -0
- package/src/capability-map/types.ts +2 -0
- 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/__tests__/validate.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 +26 -15
- package/src/fgca/preview-layout.ts +5 -5
- package/src/fgca/resolver.ts +3 -1
- package/src/fgca/types.ts +15 -13
- package/src/fgca/validate.ts +32 -21
- 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/index.ts +1 -1
- package/src/theme/themes.ts +29 -2
- package/src/theme/tokens.ts +33 -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 +53 -29
- 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
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
LegendCell,
|
|
14
14
|
ProcessBlueprintFile,
|
|
15
15
|
ProcessBlueprintLayout,
|
|
16
|
+
RowId,
|
|
16
17
|
Stage,
|
|
17
18
|
StageHeaderCell,
|
|
18
19
|
StageTextCell,
|
|
@@ -31,7 +32,7 @@ const ASPECT_LABEL: Record<AspectCategory, string> = {
|
|
|
31
32
|
// (absent = feature disabled) and must stay optional in the resolved type.
|
|
32
33
|
type SizingOptionKeys = Exclude<
|
|
33
34
|
keyof ProcessBlueprintLayoutOptions,
|
|
34
|
-
'complianceLane' | 'complianceInput' | 'visibleAspects'
|
|
35
|
+
'complianceLane' | 'complianceInput' | 'visibleAspects' | 'visibleRows' | 'visibleStages'
|
|
35
36
|
>;
|
|
36
37
|
|
|
37
38
|
/**
|
|
@@ -39,7 +40,7 @@ type SizingOptionKeys = Exclude<
|
|
|
39
40
|
* the opt-in feature fields stay optional (undefined = feature disabled).
|
|
40
41
|
*/
|
|
41
42
|
type ResolvedLayoutOptions = Required<Pick<ProcessBlueprintLayoutOptions, SizingOptionKeys>> &
|
|
42
|
-
Pick<ProcessBlueprintLayoutOptions, 'complianceLane' | 'complianceInput' | 'visibleAspects'>;
|
|
43
|
+
Pick<ProcessBlueprintLayoutOptions, 'complianceLane' | 'complianceInput' | 'visibleAspects' | 'visibleRows' | 'visibleStages'>;
|
|
43
44
|
|
|
44
45
|
const DEFAULTS = {
|
|
45
46
|
legendColumnWidth: 140,
|
|
@@ -48,14 +49,19 @@ const DEFAULTS = {
|
|
|
48
49
|
goalRowHeight: 56,
|
|
49
50
|
resultRowHeight: 56,
|
|
50
51
|
aspectRowMinHeight: 60,
|
|
51
|
-
pillHeight:
|
|
52
|
+
pillHeight: 40,
|
|
52
53
|
pillGap: 4,
|
|
53
54
|
cellPadding: 8,
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
// 17px gives comfortable breathing room between wrapped lines at typical
|
|
56
|
+
// webview font sizes (VS Code uses ~13–14px body, SVG text-secondary ≈ same).
|
|
57
|
+
textLineHeight: 17,
|
|
58
|
+
// 7.5px per char is a conservative estimate that causes wrap to trigger
|
|
59
|
+
// before text visually overflows the cell border.
|
|
60
|
+
textCharWidth: 7.5,
|
|
56
61
|
cellTextPadX: 10,
|
|
57
62
|
cellTextPadY: 10,
|
|
58
|
-
|
|
63
|
+
// No hard truncation: rows grow to fit all wrapped lines.
|
|
64
|
+
maxTextLines: 100,
|
|
59
65
|
} satisfies Required<Pick<ProcessBlueprintLayoutOptions, SizingOptionKeys>>;
|
|
60
66
|
|
|
61
67
|
interface RawPill {
|
|
@@ -369,9 +375,25 @@ export function layoutProcessBlueprint(
|
|
|
369
375
|
const opts = resolveOptions(options);
|
|
370
376
|
|
|
371
377
|
const pb = file.process_blueprint;
|
|
372
|
-
|
|
378
|
+
|
|
379
|
+
// Filter stages by visibleStages if set
|
|
380
|
+
const allStages = Array.isArray(pb?.stages) ? pb.stages : [];
|
|
381
|
+
const stages = opts.visibleStages
|
|
382
|
+
? allStages.filter(s => s?.id != null && opts.visibleStages!.includes(s.id))
|
|
383
|
+
: allStages;
|
|
373
384
|
const stageIndexById = buildStageIndex(stages);
|
|
374
385
|
|
|
386
|
+
// Row visibility from visibleRows
|
|
387
|
+
const visRows = opts.visibleRows;
|
|
388
|
+
const showGoal = !visRows || (visRows as string[]).includes('goal');
|
|
389
|
+
const showResult = !visRows || (visRows as string[]).includes('result');
|
|
390
|
+
const effectiveVisibleAspects: AspectCategory[] | undefined = visRows
|
|
391
|
+
? (ASPECT_CATEGORIES.filter(c => (visRows as string[]).includes(c)) as AspectCategory[])
|
|
392
|
+
: opts.visibleAspects;
|
|
393
|
+
const effectiveComplianceEnabled =
|
|
394
|
+
opts.complianceLane?.enabled === true &&
|
|
395
|
+
(!visRows || (visRows as string[]).includes('compliance'));
|
|
396
|
+
|
|
375
397
|
// Stage headers
|
|
376
398
|
const stageHeaders: StageHeaderCell[] = stages.map((s, i) => ({
|
|
377
399
|
stageIndex: i,
|
|
@@ -398,38 +420,39 @@ export function layoutProcessBlueprint(
|
|
|
398
420
|
const goalLines = stages.map(s => wrap(s?.goal ?? ''));
|
|
399
421
|
const resultLines = stages.map(s => wrap(s?.result ?? ''));
|
|
400
422
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
423
|
+
let cursorY = opts.stageHeaderHeight;
|
|
424
|
+
let goalRowY = 0, goalRowHeight = 0;
|
|
425
|
+
let resultRowY = 0, resultRowHeight = 0;
|
|
426
|
+
const goalCells: StageTextCell[] = [];
|
|
427
|
+
const resultCells: StageTextCell[] = [];
|
|
428
|
+
|
|
429
|
+
if (showGoal) {
|
|
430
|
+
goalRowY = cursorY;
|
|
431
|
+
goalRowHeight = rowHeightFor(goalLines.map(l => l.length), opts.goalRowHeight);
|
|
432
|
+
goalCells.push(...stages.map((s, i) => ({
|
|
433
|
+
stageIndex: i, text: s?.goal ?? '', lines: goalLines[i],
|
|
434
|
+
x: opts.legendColumnWidth + i * opts.stageColumnWidth, y: goalRowY,
|
|
435
|
+
width: opts.stageColumnWidth, height: goalRowHeight,
|
|
436
|
+
})));
|
|
437
|
+
cursorY += goalRowHeight;
|
|
438
|
+
}
|
|
439
|
+
if (showResult) {
|
|
440
|
+
resultRowY = cursorY;
|
|
441
|
+
resultRowHeight = rowHeightFor(resultLines.map(l => l.length), opts.resultRowHeight);
|
|
442
|
+
resultCells.push(...stages.map((s, i) => ({
|
|
443
|
+
stageIndex: i, text: s?.result ?? '', lines: resultLines[i],
|
|
444
|
+
x: opts.legendColumnWidth + i * opts.stageColumnWidth, y: resultRowY,
|
|
445
|
+
width: opts.stageColumnWidth, height: resultRowHeight,
|
|
446
|
+
})));
|
|
447
|
+
cursorY += resultRowHeight;
|
|
448
|
+
}
|
|
449
|
+
const aspectsStartY = cursorY;
|
|
427
450
|
|
|
428
451
|
// Aspect rows: only categories with at least one entry, in fixed order.
|
|
429
|
-
// When
|
|
452
|
+
// When effectiveVisibleAspects is set, skip categories not in the list.
|
|
430
453
|
const aspectCategoriesToRender =
|
|
431
|
-
|
|
432
|
-
? ASPECT_CATEGORIES.filter(c =>
|
|
454
|
+
effectiveVisibleAspects !== undefined
|
|
455
|
+
? ASPECT_CATEGORIES.filter(c => effectiveVisibleAspects.includes(c))
|
|
433
456
|
: ASPECT_CATEGORIES;
|
|
434
457
|
|
|
435
458
|
const aspectRows: AspectRow[] = [];
|
|
@@ -461,6 +484,13 @@ export function layoutProcessBlueprint(
|
|
|
461
484
|
const width =
|
|
462
485
|
(p.endStageIndex - p.startStageIndex + 1) * opts.stageColumnWidth - 2 * opts.cellPadding;
|
|
463
486
|
const y = aspectCursorY + opts.cellPadding + slot[i] * (opts.pillHeight + opts.pillGap);
|
|
487
|
+
const pillMaxChars = Math.max(4, Math.floor((width - 2 * opts.cellPadding) / opts.textCharWidth));
|
|
488
|
+
const nameWrapped = wrapText(p.name, pillMaxChars, 2);
|
|
489
|
+
// Show id as second line only when the name fits on one line; otherwise
|
|
490
|
+
// use both lines for the name so it isn't truncated.
|
|
491
|
+
const lines: string[] = p.id && nameWrapped.length <= 1
|
|
492
|
+
? [...nameWrapped, p.id].slice(0, 2)
|
|
493
|
+
: nameWrapped;
|
|
464
494
|
return {
|
|
465
495
|
category: p.category,
|
|
466
496
|
entryIndex: p.entryIndex,
|
|
@@ -472,6 +502,7 @@ export function layoutProcessBlueprint(
|
|
|
472
502
|
y,
|
|
473
503
|
width,
|
|
474
504
|
height: opts.pillHeight,
|
|
505
|
+
lines,
|
|
475
506
|
};
|
|
476
507
|
});
|
|
477
508
|
|
|
@@ -487,7 +518,7 @@ export function layoutProcessBlueprint(
|
|
|
487
518
|
|
|
488
519
|
// Compliance lane — derived from assertions/requirements, rendered after aspect rows.
|
|
489
520
|
let complianceRow: import('./types.js').ComplianceRow | undefined;
|
|
490
|
-
if (
|
|
521
|
+
if (effectiveComplianceEnabled && opts.complianceInput) {
|
|
491
522
|
complianceRow = deriveComplianceRow(
|
|
492
523
|
stages,
|
|
493
524
|
stageIndexById,
|
|
@@ -502,8 +533,8 @@ export function layoutProcessBlueprint(
|
|
|
502
533
|
|
|
503
534
|
// Legend (left column labels): one entry per row.
|
|
504
535
|
const legend: LegendCell[] = [
|
|
505
|
-
{ kind: 'goal', label: 'Goal', y: goalRowY, height: goalRowHeight },
|
|
506
|
-
{ kind: 'result', label: 'Result', y: resultRowY, height: resultRowHeight },
|
|
536
|
+
...(showGoal ? [{ kind: 'goal' as const, label: 'Goal', y: goalRowY, height: goalRowHeight }] : []),
|
|
537
|
+
...(showResult ? [{ kind: 'result' as const, label: 'Result', y: resultRowY, height: resultRowHeight }] : []),
|
|
507
538
|
...aspectRows.map<LegendCell>(row => ({
|
|
508
539
|
kind: 'aspect',
|
|
509
540
|
category: row.category,
|
|
@@ -511,9 +542,7 @@ export function layoutProcessBlueprint(
|
|
|
511
542
|
y: row.y,
|
|
512
543
|
height: row.height,
|
|
513
544
|
})),
|
|
514
|
-
...(complianceRow
|
|
515
|
-
? [{ kind: 'compliance' as const, label: 'Compliance', y: complianceRow.y, height: complianceRow.height }]
|
|
516
|
-
: []),
|
|
545
|
+
...(complianceRow ? [{ kind: 'compliance' as const, label: 'Compliance', y: complianceRow.y, height: complianceRow.height }] : []),
|
|
517
546
|
];
|
|
518
547
|
|
|
519
548
|
const totalWidth = opts.legendColumnWidth + stages.length * opts.stageColumnWidth;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export type AspectCategory = 'systems' | 'actors' | 'equipment' | 'information_entities';
|
|
2
2
|
|
|
3
|
+
export type RowId = 'goal' | 'result' | 'systems' | 'actors' | 'equipment' | 'information_entities' | 'compliance';
|
|
4
|
+
|
|
3
5
|
// ── Compliance lane types ────────────────────────────────────────────────────
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -191,6 +193,17 @@ export interface ProcessBlueprintLayoutOptions {
|
|
|
191
193
|
* Pass an empty array to suppress all aspect rows.
|
|
192
194
|
*/
|
|
193
195
|
visibleAspects?: AspectCategory[];
|
|
196
|
+
/**
|
|
197
|
+
* Restrict which rows are rendered. When absent, all rows with data are shown.
|
|
198
|
+
* When set, takes precedence over `visibleAspects` for aspect categories and
|
|
199
|
+
* overrides `complianceLane.enabled` for the compliance row.
|
|
200
|
+
*/
|
|
201
|
+
visibleRows?: RowId[];
|
|
202
|
+
/**
|
|
203
|
+
* Restrict which stages (columns) are rendered by their stage ID.
|
|
204
|
+
* When absent, all stages are shown.
|
|
205
|
+
*/
|
|
206
|
+
visibleStages?: string[];
|
|
194
207
|
}
|
|
195
208
|
|
|
196
209
|
import type { LayoutBounds } from '../geometry.js';
|
|
@@ -236,6 +249,8 @@ export interface AspectPill {
|
|
|
236
249
|
y: number;
|
|
237
250
|
width: number;
|
|
238
251
|
height: number;
|
|
252
|
+
/** Word-wrapped lines of `name`, pre-fitted to the pill width by the layout. */
|
|
253
|
+
lines: string[];
|
|
239
254
|
}
|
|
240
255
|
|
|
241
256
|
export interface AspectRow {
|
package/src/scenarios/index.ts
CHANGED
package/src/scenarios/types.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export type ScenarioStatus = 'Draft' | 'Active' | 'Archived';
|
|
2
|
-
export type
|
|
2
|
+
export type DriverRelevance = 'High' | 'Medium' | 'Low';
|
|
3
3
|
|
|
4
|
-
export interface
|
|
4
|
+
export interface DriverView {
|
|
5
5
|
factor_id: string;
|
|
6
|
-
relevance?:
|
|
6
|
+
relevance?: DriverRelevance;
|
|
7
7
|
impact?: string;
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -21,7 +21,7 @@ export interface ScenarioHeader {
|
|
|
21
21
|
status: ScenarioStatus;
|
|
22
22
|
created_at?: string;
|
|
23
23
|
vision?: string;
|
|
24
|
-
factors_view?:
|
|
24
|
+
factors_view?: DriverView[];
|
|
25
25
|
goals?: GoalRef[];
|
|
26
26
|
capabilities?: CapabilityRef[];
|
|
27
27
|
activities?: ActivityRef[];
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { ScenarioStatus,
|
|
1
|
+
import type { ScenarioStatus, DriverRelevance } from './types.js';
|
|
2
2
|
import type { ValidationError, ValidationWarning, ValidationResult } from '../validation-types.js';
|
|
3
3
|
|
|
4
4
|
export type { ValidationError, ValidationWarning, ValidationResult };
|
|
5
5
|
|
|
6
6
|
const VALID_STATUSES = new Set<ScenarioStatus>(['Draft', 'Active', 'Archived']);
|
|
7
|
-
const VALID_RELEVANCE = new Set<
|
|
7
|
+
const VALID_RELEVANCE = new Set<DriverRelevance>(['High', 'Medium', 'Low']);
|
|
8
8
|
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
9
9
|
|
|
10
10
|
interface RefSpec {
|
|
@@ -84,7 +84,7 @@ export function validateScenario(input: unknown): ValidationResult {
|
|
|
84
84
|
if (seen.has(fid)) errors.push({ code: 'SCN-013', message: `Duplicate factor_id: "${fid}"` });
|
|
85
85
|
seen.add(fid);
|
|
86
86
|
}
|
|
87
|
-
if (f['relevance'] !== undefined && !VALID_RELEVANCE.has(f['relevance'] as
|
|
87
|
+
if (f['relevance'] !== undefined && !VALID_RELEVANCE.has(f['relevance'] as DriverRelevance)) {
|
|
88
88
|
errors.push({ code: 'SCN-006', message: `${idx}: relevance "${f['relevance']}" must be one of: High, Medium, Low` });
|
|
89
89
|
}
|
|
90
90
|
}
|
package/src/theme/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export type { AdaptiveTokens } from './tokens.js';
|
|
2
|
-
export { BRAND, FUNCTIONAL, LAYER_COLORS, LEVEL_COLORS, MATURITY_COLORS, STRUCTURAL, TYPOGRAPHY, CSS_VAR, getBaseResetCss } from './tokens.js';
|
|
2
|
+
export { BRAND, FUNCTIONAL, LAYER_COLORS, LEVEL_COLORS, MATURITY_COLORS, TREE_LEVEL_COLORS, TREE_MATURITY_COLORS, STRUCTURAL, TYPOGRAPHY, CSS_VAR, getBaseResetCss } from './tokens.js';
|
|
3
3
|
export type { ThemeId } from './themes.js';
|
|
4
4
|
export { generateWebviewCss, generateSvgEmbedCss } from './themes.js';
|
package/src/theme/themes.ts
CHANGED
|
@@ -2,6 +2,8 @@ import {
|
|
|
2
2
|
LAYER_COLORS,
|
|
3
3
|
LEVEL_COLORS,
|
|
4
4
|
MATURITY_COLORS,
|
|
5
|
+
TREE_LEVEL_COLORS,
|
|
6
|
+
TREE_MATURITY_COLORS,
|
|
5
7
|
STRUCTURAL,
|
|
6
8
|
TYPOGRAPHY,
|
|
7
9
|
CSS_VAR,
|
|
@@ -75,8 +77,21 @@ function diagramVars(variant: 'light' | 'dark' | 'hc'): string {
|
|
|
75
77
|
const sc = STRUCTURAL;
|
|
76
78
|
const lv = LEVEL_COLORS[variant];
|
|
77
79
|
const mat = MATURITY_COLORS[variant];
|
|
80
|
+
const treeLevel = TREE_LEVEL_COLORS;
|
|
81
|
+
const treeMat = TREE_MATURITY_COLORS[variant];
|
|
78
82
|
const levelVars = lv.map((c, i) => `--ts-level-${i}:${c}`).join(';') + ';';
|
|
83
|
+
const treeVars = [
|
|
84
|
+
`${CSS_VAR.treeLevel0}:${treeLevel.band0[variant]}`,
|
|
85
|
+
`${CSS_VAR.treeLevel1}:${treeLevel.band1[variant]}`,
|
|
86
|
+
`${CSS_VAR.treeLevel2}:${treeLevel.band2[variant]}`,
|
|
87
|
+
`${CSS_VAR.treeMaturity1}:${treeMat[0]}`,
|
|
88
|
+
`${CSS_VAR.treeMaturity2}:${treeMat[1]}`,
|
|
89
|
+
`${CSS_VAR.treeMaturity3}:${treeMat[2]}`,
|
|
90
|
+
`${CSS_VAR.treeMaturity4}:${treeMat[3]}`,
|
|
91
|
+
`${CSS_VAR.treeMaturity5}:${treeMat[4]}`,
|
|
92
|
+
].join(';') + ';';
|
|
79
93
|
return [
|
|
94
|
+
`${CSS_VAR.layerDriver}:${lc.driver[variant]}`,
|
|
80
95
|
`${CSS_VAR.layerFactor}:${lc.factor[variant]}`,
|
|
81
96
|
`${CSS_VAR.layerGoal}:${lc.goal[variant]}`,
|
|
82
97
|
`${CSS_VAR.layerChange}:${lc.change[variant]}`,
|
|
@@ -91,7 +106,7 @@ function diagramVars(variant: 'light' | 'dark' | 'hc'): string {
|
|
|
91
106
|
`${CSS_VAR.maturity3}:${mat[2]}`,
|
|
92
107
|
`${CSS_VAR.maturity4}:${mat[3]}`,
|
|
93
108
|
`${CSS_VAR.maturity5}:${mat[4]}`,
|
|
94
|
-
].join(';') + ';' + levelVars;
|
|
109
|
+
].join(';') + ';' + levelVars + treeVars;
|
|
95
110
|
}
|
|
96
111
|
|
|
97
112
|
/** CSS for the webview shell (toolbar, canvas). */
|
|
@@ -131,6 +146,7 @@ function diagramClassCss(): string {
|
|
|
131
146
|
// contract every notation preview honours so the catalogue reads as one
|
|
132
147
|
// visual family.
|
|
133
148
|
return `.diagram-node{stroke:var(${cv.nodeStroke});stroke-width:1;}
|
|
149
|
+
.layer-driver{fill:var(${cv.layerDriver});}
|
|
134
150
|
.layer-factor{fill:var(${cv.layerFactor});}
|
|
135
151
|
.layer-goal{fill:var(${cv.layerGoal});}
|
|
136
152
|
.layer-change{fill:var(${cv.layerChange});}
|
|
@@ -153,7 +169,18 @@ ${levelRules}
|
|
|
153
169
|
.compliance-deadline{fill:var(${cv.statusErrorBg});stroke:var(${cv.statusErrorFg});}
|
|
154
170
|
.compliance-deadline text{fill:var(${cv.statusErrorFg});}
|
|
155
171
|
.compliance-badge{fill:var(${cv.statusErrorFg});}
|
|
156
|
-
.compliance-badge-text{fill:var(${cv.textInverse});font-family:${t.fontFamily};font-size:8px;font-weight:700;}
|
|
172
|
+
.compliance-badge-text{fill:var(${cv.textInverse});font-family:${t.fontFamily};font-size:8px;font-weight:700;}
|
|
173
|
+
.tree-level-0{fill:var(${cv.treeLevel0});}
|
|
174
|
+
.tree-level-1{fill:var(${cv.treeLevel1});}
|
|
175
|
+
.tree-level-2{fill:var(${cv.treeLevel2});}
|
|
176
|
+
.tree-maturity-1{fill:var(${cv.treeMaturity1});}
|
|
177
|
+
.tree-maturity-2{fill:var(${cv.treeMaturity2});}
|
|
178
|
+
.tree-maturity-3{fill:var(${cv.treeMaturity3});}
|
|
179
|
+
.tree-maturity-4{fill:var(${cv.treeMaturity4});}
|
|
180
|
+
.tree-maturity-5{fill:var(${cv.treeMaturity5});}
|
|
181
|
+
.tree-collapse-btn{cursor:pointer;fill:white;stroke:var(${cv.nodeStroke});stroke-width:1.5;}
|
|
182
|
+
.tree-collapse-btn:hover{fill:var(${cv.bgElevated});}
|
|
183
|
+
.tree-collapse-lbl{fill:var(${cv.textSecondary});font-family:${t.fontFamily};font-size:12px;font-weight:700;dominant-baseline:central;pointer-events:none;}`;
|
|
157
184
|
}
|
|
158
185
|
|
|
159
186
|
/**
|
package/src/theme/tokens.ts
CHANGED
|
@@ -13,8 +13,9 @@ export const FUNCTIONAL = {
|
|
|
13
13
|
info: '#1d6fa8',
|
|
14
14
|
} as const;
|
|
15
15
|
|
|
16
|
-
/** Fill colors for FGCA notation columns. */
|
|
16
|
+
/** Fill colors for FGCA/DGCA notation columns. */
|
|
17
17
|
export const LAYER_COLORS = {
|
|
18
|
+
driver: { light: '#fef3c7', dark: '#292108', hc: '#f59e0b' },
|
|
18
19
|
factor: { light: '#fef3c7', dark: '#292108', hc: '#f59e0b' },
|
|
19
20
|
goal: { light: '#e0e7ff', dark: '#1e1b4b', hc: '#818cf8' },
|
|
20
21
|
change: { light: '#dbeafe', dark: '#0c2042', hc: '#60a5fa' },
|
|
@@ -47,6 +48,28 @@ export const MATURITY_COLORS = {
|
|
|
47
48
|
hc: ['#f87171', '#fb923c', '#facc15', '#a3e635', '#4ade80'],
|
|
48
49
|
} as const;
|
|
49
50
|
|
|
51
|
+
/**
|
|
52
|
+
* DSM-matching capability tree node fill colors, grouped by depth band.
|
|
53
|
+
* band0: depth 0–2 (pink)
|
|
54
|
+
* band1: depth 3–4 (yellow)
|
|
55
|
+
* band2: depth 5+ (blue)
|
|
56
|
+
*/
|
|
57
|
+
export const TREE_LEVEL_COLORS = {
|
|
58
|
+
band0: { light: '#fee0e0', dark: '#3d0f0f', hc: '#ff9999' },
|
|
59
|
+
band1: { light: '#ffffcb', dark: '#3a3500', hc: '#ffff88' },
|
|
60
|
+
band2: { light: '#c2f0ff', dark: '#003d4d', hc: '#66ccff' },
|
|
61
|
+
} as const;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* DSM-matching maturity badge fills for the capability tree (L1–L5).
|
|
65
|
+
* Distinct from MATURITY_COLORS which drives the cards / compliance views.
|
|
66
|
+
*/
|
|
67
|
+
export const TREE_MATURITY_COLORS = {
|
|
68
|
+
light: ['#c1c1c1', '#ff3d67', '#ff9a59', '#fdef59', '#83cca3'],
|
|
69
|
+
dark: ['#555555', '#cc1040', '#d06020', '#c8c000', '#4d9970'],
|
|
70
|
+
hc: ['#cccccc', '#ff6699', '#ffbb77', '#ffff44', '#88ddaa'],
|
|
71
|
+
} as const;
|
|
72
|
+
|
|
50
73
|
/**
|
|
51
74
|
* Typography hierarchy. All previews resolve text styling from these roles
|
|
52
75
|
* — never from inline font-* attributes on individual <text> elements.
|
|
@@ -112,6 +135,7 @@ export const CSS_VAR = {
|
|
|
112
135
|
statusInfoFg: '--ts-status-info-fg',
|
|
113
136
|
statusErrorBg: '--ts-status-error-bg',
|
|
114
137
|
statusErrorFg: '--ts-status-error-fg',
|
|
138
|
+
layerDriver: '--ts-layer-driver',
|
|
115
139
|
layerFactor: '--ts-layer-factor',
|
|
116
140
|
layerGoal: '--ts-layer-goal',
|
|
117
141
|
layerChange: '--ts-layer-change',
|
|
@@ -126,6 +150,14 @@ export const CSS_VAR = {
|
|
|
126
150
|
maturity3: '--ts-maturity-3',
|
|
127
151
|
maturity4: '--ts-maturity-4',
|
|
128
152
|
maturity5: '--ts-maturity-5',
|
|
153
|
+
treeLevel0: '--ts-tree-level-0',
|
|
154
|
+
treeLevel1: '--ts-tree-level-1',
|
|
155
|
+
treeLevel2: '--ts-tree-level-2',
|
|
156
|
+
treeMaturity1: '--ts-tree-maturity-1',
|
|
157
|
+
treeMaturity2: '--ts-tree-maturity-2',
|
|
158
|
+
treeMaturity3: '--ts-tree-maturity-3',
|
|
159
|
+
treeMaturity4: '--ts-tree-maturity-4',
|
|
160
|
+
treeMaturity5: '--ts-tree-maturity-5',
|
|
129
161
|
} as const;
|
|
130
162
|
|
|
131
163
|
export function getBaseResetCss(): string {
|
|
@@ -26,6 +26,8 @@ interface Fixture {
|
|
|
26
26
|
// example per notation is enough to prove the dispatch + renderer wiring.
|
|
27
27
|
const FIXTURES: Fixture[] = [
|
|
28
28
|
{ kind: 'goals', file: 'goals/strategy-2026.goals.transitrix.yaml', markup: 'svg' },
|
|
29
|
+
{ kind: 'dgca', file: 'dgca/strategy-2026.dgca.transitrix.yaml', markup: 'svg' },
|
|
30
|
+
{ kind: 'dga', file: 'dga/strategy-2026.dga.transitrix.yaml', markup: 'svg' },
|
|
29
31
|
{ kind: 'fgca', file: 'fgca/strategy-2026.fgca.transitrix.yaml', markup: 'svg' },
|
|
30
32
|
{ kind: 'fga', file: 'fga/strategy-2026.fga.transitrix.yaml', markup: 'svg' },
|
|
31
33
|
{ kind: 'activities', file: 'activities/platform-launch.activities.transitrix.yaml', markup: 'svg' },
|