refactor(ms-ai-architect): playground v1.14.0 sesjon 5 — phase-rapporter til expansion-list
- renderMigrate: <section class="phase-detail"> per fase erstattet med
<div class="expansion">-list (DS-supplement). Default-collapsed, klikkbar
header (Fase N: navn + duration), body = milepaeler + suksesskriterier.
Behold cycle-ribbon + mat-ladder + phases-summary-tabell + risks-tabell.
- renderPoc: speil renderMigrate. Traffic-light flyttet inn i expansion-body
(ul.traffic-list per fase med status fra fasens stepState).
- renderSummary: KEY_STATS_CONFIG['verdict'] patchet — parseTable returnerer
rader med header-baserte nokler (Metric/Verdi/Mal) ikke canonical
{label,value,unit}. Ny logikk bruker metrics_headers + heuristikk-match for
label/value/unit-kolonner, med fallback til canonical felt.
Backward-kompatibelt.
- renderAdr: verifisert PASS — ingen endring (.adr-meta + critique-cards
rendrer pent uten ekstra arbeid).
- ACTIONS['phase-expand']: ny handler registrert som alias for
requirement-expand (samme toggle-monster, eget action-navn for senere
divergens).
- Lokal CSS: hele .phase-detail-blokken (~10 linjer) slettet. Defensive-
kommentar oppsummert til 5-linjers historie-notat.
- Style-blokk effektive linjer: 147 (var 178 etter sesjon 4).
Smoke-tester:
- validate-plugin.sh: 219 PASS
- run-e2e.sh --playground: 272 PASS (202 statisk + 70 parser)
- test-playground-migrations.sh: 7 PASS
Refs V1.14.0-AUDIT.local.md sub-batch D.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
5c5c7b40a9
commit
30ddeb2d9f
1 changed files with 67 additions and 35 deletions
|
|
@ -205,22 +205,11 @@
|
|||
- .expansion__title-main/sub (display: block)
|
||||
- .matrix__bubble (cursor + hover + focus) */
|
||||
|
||||
/* v1.13.1 fix (B12, B13, B15): defensive block-layout for sibling-rapport-
|
||||
seksjoner som kan ha overflow-issues mot foregående grid-elementer
|
||||
(.small-multiples, .kanban-board, .mat-ladder). Sikrer eksplisitt
|
||||
block-flow + clear så de ikke leker grid-celler eller flyter.
|
||||
v1.14.0 sesjon 3: .top-risks fjernet (ligger nå i .card med riktig DS block-flow).
|
||||
v1.14.0 sesjon 4: .aiact-timeline + .kanban-board + .report-meta + .suppressed-panel
|
||||
fjernet (kanban-board → aiact-timeline-section / details.suppressed-panel stacker
|
||||
naturlig som block-level <section>/<details>; .report-meta-mønsteret er borte). */
|
||||
.phase-detail,
|
||||
.mat-ladder + .phase-detail,
|
||||
.phase-detail + .phase-detail { display: block; clear: both; width: 100%; }
|
||||
.phase-detail { margin-top: var(--space-5); }
|
||||
.phase-detail h3 { margin-bottom: var(--space-3); }
|
||||
.phase-detail h4 { margin: var(--space-3) 0 var(--space-2); font-size: var(--font-size-sm); color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.04em; }
|
||||
.phase-detail ul { padding-left: var(--space-5); margin: 0 0 var(--space-2); }
|
||||
.phase-detail ul li { margin-bottom: var(--space-1); }
|
||||
/* v1.14.0 sesjon 5: .phase-detail-CSS slettet — renderMigrate + renderPoc
|
||||
bruker nå <div class="expansion">-list (DS-supplement) i stedet for det
|
||||
lokale .phase-detail-mønsteret. v1.13.1-defensive layout-overrides for
|
||||
.top-risks (sesjon 3), .aiact-timeline + .report-meta + .suppressed-panel
|
||||
(sesjon 4) og .phase-detail (sesjon 5) er nå alle ute. */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -4199,15 +4188,29 @@
|
|||
const phasesSummaryHtml = phasesSummaryRows
|
||||
? '<table class="report-table"><thead><tr><th>Fase</th><th>Varighet</th><th>Milepæler</th><th>Suksesskriterier</th><th>Status</th></tr></thead><tbody>' + phasesSummaryRows + '</tbody></table>'
|
||||
: '';
|
||||
const detailsHtml = phases.map(function (p) {
|
||||
// v1.14.0 sesjon 5: phase-detail (lokal CSS-mønster) erstattet med
|
||||
// <div class="expansion">-list (DS-supplement). Default-collapsed, klikkbar
|
||||
// header = fase-navn + varighet, body = milepæler + suksesskriterier.
|
||||
// phase-expand-handler er registrert i ACTIONS som alias for samme
|
||||
// toggle-mønster som requirement-expand.
|
||||
const detailsHtml = phases.length ? '<div class="stack-sm">' + phases.map(function (p, idx) {
|
||||
const ms = (p.milestones || []).map(function (m) { return '<li>' + escapeHtml(m) + '</li>'; }).join('');
|
||||
const sc = (p.success_criteria || []).map(function (s) { return '<li>' + escapeHtml(s) + '</li>'; }).join('');
|
||||
return '<section class="phase-detail">' +
|
||||
'<h3>' + escapeHtml(p.name) + ' <small>(' + (p.duration_weeks || '?') + ' uker)</small></h3>' +
|
||||
(ms ? '<h4>Milepæler</h4><ul>' + ms + '</ul>' : '') +
|
||||
(sc ? '<h4>Suksesskriterier</h4><ul>' + sc + '</ul>' : '') +
|
||||
'</section>';
|
||||
}).join('');
|
||||
const innerBody = (ms ? '<h4>Milepæler</h4><ul>' + ms + '</ul>' : '') +
|
||||
(sc ? '<h4>Suksesskriterier</h4><ul>' + sc + '</ul>' : '');
|
||||
return '<div class="expansion" aria-expanded="false">' +
|
||||
'<button type="button" class="expansion__head" data-action="phase-expand" data-idx="' + idx + '">' +
|
||||
'<span class="expansion__title">' +
|
||||
'<span class="expansion__title-main">Fase ' + (idx + 1) + ': ' + escapeHtml(p.name || '—') + '</span>' +
|
||||
'<span class="expansion__title-sub">' + escapeHtml(String(p.duration_weeks || '—')) + ' uker</span>' +
|
||||
'</span>' +
|
||||
'<span class="expansion__chev" aria-hidden="true">▾</span>' +
|
||||
'</button>' +
|
||||
'<div class="expansion__body"><div class="expansion__body-inner"><div>' +
|
||||
innerBody +
|
||||
'</div></div></div>' +
|
||||
'</div>';
|
||||
}).join('') + '</div>' : '';
|
||||
const risksRows = (data.risks || []).map(function (r) {
|
||||
return '<tr><td>' + escapeHtml(r.risk || '') + '</td><td>' + escapeHtml(r.probability || '') + '</td><td>' + escapeHtml(r.consequence || '') + '</td><td>' + escapeHtml(r.mitigation || '') + '</td></tr>';
|
||||
}).join('');
|
||||
|
|
@ -4393,9 +4396,11 @@
|
|||
const phasesSummaryHtml = phasesSummaryRows
|
||||
? '<table class="report-table"><thead><tr><th>Fase</th><th>Varighet</th><th>Milepæler</th><th>Suksesskriterier</th><th>Status</th></tr></thead><tbody>' + phasesSummaryRows + '</tbody></table>'
|
||||
: '';
|
||||
// B5 traffic-light per success-kriterie. R15: uten eksplisitt status,
|
||||
// bruk fasens state — done=go, active=warning, future=neutral.
|
||||
const detailsHtml = phases.map(function (p, i) {
|
||||
// v1.14.0 sesjon 5: phase-detail erstattet med expansion-list (samme
|
||||
// mønster som renderMigrate). Traffic-light per success-kriterie beholdes
|
||||
// inne i expansion-body. R15: uten eksplisitt status, bruk fasens state —
|
||||
// done=green, active=yellow, future=gray.
|
||||
const detailsHtml = phases.length ? '<div class="stack-sm">' + phases.map(function (p, i) {
|
||||
const state = stepStateFor(p, i);
|
||||
const tlStatus = state === 'completed' ? 'green' : state === 'current' ? 'yellow' : 'gray';
|
||||
const ms = (p.milestones || []).map(function (m) { return '<li>' + escapeHtml(m) + '</li>'; }).join('');
|
||||
|
|
@ -4407,12 +4412,21 @@
|
|||
'</span>' +
|
||||
'</li>';
|
||||
}).join('');
|
||||
return '<section class="phase-detail">' +
|
||||
'<h3>' + escapeHtml(p.name) + ' <small>(' + (p.duration_weeks || '?') + ' uker)</small></h3>' +
|
||||
(ms ? '<h4>Milepæler</h4><ul>' + ms + '</ul>' : '') +
|
||||
(sc ? '<h4>Suksesskriterier</h4><ul class="traffic-list">' + sc + '</ul>' : '') +
|
||||
'</section>';
|
||||
}).join('');
|
||||
const innerBody = (ms ? '<h4>Milepæler</h4><ul>' + ms + '</ul>' : '') +
|
||||
(sc ? '<h4>Suksesskriterier</h4><ul class="traffic-list">' + sc + '</ul>' : '');
|
||||
return '<div class="expansion" aria-expanded="false">' +
|
||||
'<button type="button" class="expansion__head" data-action="phase-expand" data-idx="' + i + '">' +
|
||||
'<span class="expansion__title">' +
|
||||
'<span class="expansion__title-main">Fase ' + (i + 1) + ': ' + escapeHtml(p.name || '—') + '</span>' +
|
||||
'<span class="expansion__title-sub">' + escapeHtml(String(p.duration_weeks || '—')) + ' uker</span>' +
|
||||
'</span>' +
|
||||
'<span class="expansion__chev" aria-hidden="true">▾</span>' +
|
||||
'</button>' +
|
||||
'<div class="expansion__body"><div class="expansion__body-inner"><div>' +
|
||||
innerBody +
|
||||
'</div></div></div>' +
|
||||
'</div>';
|
||||
}).join('') + '</div>' : '';
|
||||
const risksRows = (data.risks || []).map(function (r) {
|
||||
return '<tr><td>' + escapeHtml(r.risk || '') + '</td><td>' + escapeHtml(r.probability || '') + '</td><td>' + escapeHtml(r.consequence || '') + '</td><td>' + escapeHtml(r.mitigation || '') + '</td></tr>';
|
||||
}).join('');
|
||||
|
|
@ -4736,11 +4750,24 @@
|
|||
},
|
||||
'verdict': function (d) {
|
||||
const km = d.key_metrics || [];
|
||||
if (!km.length) return [];
|
||||
// v1.14.0 sesjon 5: parseTable produserer rader med header-baserte nøkler
|
||||
// (f.eks. Metric/Verdi/Mål) — ikke canonical {label,value,unit}. Bruk
|
||||
// metrics_headers + heuristikk for å mappe til key-stat-form, med
|
||||
// fallback til canonical-felt hvis fixturen er normalisert.
|
||||
const headers = d.metrics_headers || Object.keys(km[0] || {});
|
||||
const findKey = function (re) { return headers.find(function (h) { return re.test(h); }); };
|
||||
const labelKey = findKey(/^(label|name|metric|metrikk|navn)$/i) || headers[0] || 'label';
|
||||
const valueKey = findKey(/^(value|verdi|score)$/i) || headers[1] || 'value';
|
||||
const unitKey = findKey(/^(unit|enhet|hint|m[åa]l|target)$/i);
|
||||
return km.slice(0, 4).map(function (m) {
|
||||
const labelRaw = m[labelKey] != null ? m[labelKey] : (m.label || m.name || '');
|
||||
const valueRaw = m[valueKey] != null && m[valueKey] !== '' ? m[valueKey] : (m.value != null ? m.value : '—');
|
||||
const hintRaw = unitKey ? m[unitKey] : m.unit;
|
||||
return {
|
||||
label: String(m.label || m.name || '').toUpperCase(),
|
||||
value: m.value != null ? m.value : '—',
|
||||
hint: m.unit || undefined
|
||||
label: String(labelRaw || '').toUpperCase(),
|
||||
value: valueRaw,
|
||||
hint: hintRaw || undefined
|
||||
};
|
||||
});
|
||||
},
|
||||
|
|
@ -5463,6 +5490,11 @@
|
|||
exp.setAttribute('aria-expanded', open ? 'false' : 'true');
|
||||
};
|
||||
|
||||
// v1.14.0 sesjon 5: phase-expand alias — renderMigrate + renderPoc bruker
|
||||
// samme expansion-toggle-mønster som requirement-expand, men med eget action-
|
||||
// navn for å gjøre intent eksplisitt og åpne for senere divergens.
|
||||
ACTIONS['phase-expand'] = ACTIONS['requirement-expand'];
|
||||
|
||||
ACTIONS['onboarding-goto-group'] = function (ev, el) {
|
||||
const groupId = el.dataset.group;
|
||||
const root = getSurfaceEl('onboarding');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue