fix(ms-ai-architect): playground v1.13.1 — visuelle bugs i v1.13.0
10 visuelle bugs identifisert av maintainer i nettleser etter v1.13.0
shipped. Patch-pakke som adresserer mismatch mellom playground-rendrere
og DS-konvensjoner som v1.13.0 ikke fanget opp.
- B7: classify "Forpliktelser" indent — lokal .report-meta CSS-reset
(DL grid max-content+1fr, h4 uppercase+bold, ul padding-left space-5)
for konsistent venstre-justering uavhengig av nestelse.
- B8a: requirement-expand handler missing — renderRequirements markup
hadde data-action="requirement-expand" på hver expansion__head, men
ingen ACTIONS-handler var registrert. R-01..R-09-radene i AI Act-krav
var derfor ikke klikkbare. Fix: register ACTIONS['requirement-expand'].
- B8b: expansion title-main + title-sub kjørte sammen — DS' spans var
inline. Lokal display:block så de stables vertikalt.
- B10: kanban-card tegnknekking — DS' word-break:break-all knekker midt
i ord. Lokal override med break-word.
- B11: DPIA matrix-bobler ikke responderer — v1.13.0 click-handler
matchet kun mot første-kolonne i Trusler-tabellen. DPIA-fixturer har
full-tekst label i matrix_cells men T-001-id i threats-tabellen, så
ingen match. Utvid til (Pass 1) exact first-cell + (Pass 2) substring-
match mot enhver celle med 40-tegn-prefiks-toleranse.
- B12, B13, B15: defensive layout for top-risks/suppressed-panel/
phase-detail/aiact-timeline — eksplisitt display:block; clear:both;
width:100% mot grid-leak fra small-multiples/kanban-board/mat-ladder.
- B14: Migrate "skal vel være tabell" — phases-summary-tabell over
phase-detail-seksjonene (Fase, Varighet, Milepæler-count, Suksesskriterier-
count, Status). Samme tabell speilet i renderPoc for konsistens.
Verifisering:
- 23/23 smoke-test PASS (B7-B15 + 5 v1.13.0-regresjoner)
- 271/271 playground E2E PASS
- 219 plugin-validering PASS
- 42 KB-update PASS
Versjon: v1.13.0 -> v1.13.1 (plugin.json, README badge, README
version-history, CHANGELOG, ROADMAP, TODO, plugin CLAUDE.md
playground-header, root README plugin-list, root CLAUDE.md plugin-list).
Berører kun lokal CSS i <style>-blokk, ACTIONS-handler-registrering,
click-handler-utvidelse, og to renderer-funksjoner. Ingen modifisering
av playground/vendor/. Vendored DS' .kanban-card__name { word-break:
break-all } står — overstyres lokalt.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
121c5cc677
commit
9f806469f3
7 changed files with 149 additions and 15 deletions
|
|
@ -191,6 +191,47 @@
|
|||
.matrix__bubble { cursor: pointer; transition: transform var(--duration-fast) var(--ease-default); }
|
||||
.matrix__bubble:hover { transform: scale(1.15); }
|
||||
.matrix__bubble:focus-visible { outline: 2px solid var(--color-primary-500); outline-offset: 2px; }
|
||||
|
||||
/* v1.13.1 fix (B7): .report-meta er ikke definert i vendored DS — vi bruker
|
||||
<section class="report-meta"> som outer-wrapper i flere rendrere. Browser-
|
||||
defaults for <dl><dd><ul> gir uforutsigbare indents (Forpliktelser-bullet-
|
||||
liste i renderAiActPyramid, expansion__body-dl i renderRequirements).
|
||||
Lokal reset gir konsistent venstre-justering uavhengig av nestelse. */
|
||||
.report-meta { display: block; margin-block: var(--space-4); }
|
||||
.report-meta > h4 { margin: 0 0 var(--space-2); font-size: var(--font-size-md); font-weight: var(--font-weight-semibold); color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.04em; }
|
||||
.report-meta dl { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-1) var(--space-3); margin: 0; }
|
||||
.report-meta dt { font-weight: var(--font-weight-semibold); color: var(--color-text-secondary); }
|
||||
.report-meta dd { margin: 0; color: var(--color-text-primary); }
|
||||
.report-meta > ul { padding-left: var(--space-5); margin: 0; }
|
||||
.report-meta > ul > li { margin-bottom: var(--space-1); color: var(--color-text-primary); }
|
||||
|
||||
/* v1.13.1 fix (B8b): .expansion__title-main og __title-sub er <span>'ene som
|
||||
DS lar flyte inline. Resultat: "dokumentertKilde: Art. 9" uten linjebrytning.
|
||||
Tving block-display så de stables vertikalt med riktig spacing. */
|
||||
.expansion__title-main, .expansion__title-sub { display: block; }
|
||||
|
||||
/* v1.13.1 fix (B10): DS' .kanban-card__name har word-break:break-all som knekker
|
||||
midt i ord ("Tekn isk dokumen tasjon"). Erstatt med break-word så ordskjøt
|
||||
respekteres. Override krever spesifisitet pga. cascade-orden. */
|
||||
.kanban-card .kanban-card__name { word-break: break-word; }
|
||||
|
||||
/* 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. */
|
||||
.top-risks,
|
||||
.suppressed-panel,
|
||||
.phase-detail,
|
||||
.aiact-timeline,
|
||||
.small-multiples + .top-risks,
|
||||
.kanban-board + .report-meta,
|
||||
.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); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -4104,6 +4145,23 @@
|
|||
'<span class="cycle-ribbon__msg">' + escapeHtml(cur.name) + '</span>' +
|
||||
'</div>';
|
||||
}
|
||||
// v1.13.1 fix (B14): brukeren etterspurte tabell-visning. Legg til en
|
||||
// phases-summary-tabell over phase-detail-seksjonene som gir oversikt
|
||||
// (Fase, Varighet, Milepæler-count, Suksess-count, Status).
|
||||
const phasesSummaryRows = phases.map(function (p, i) {
|
||||
const state = stepStateFor(p, i);
|
||||
const stateLabel = state === 'completed' ? 'Ferdig' : state === 'current' ? 'Pågår' : 'Planlagt';
|
||||
return '<tr>' +
|
||||
'<td>' + escapeHtml(p.name) + '</td>' +
|
||||
'<td>' + escapeHtml(String(p.duration_weeks || '—')) + ' uker</td>' +
|
||||
'<td>' + ((p.milestones || []).length) + '</td>' +
|
||||
'<td>' + ((p.success_criteria || []).length) + '</td>' +
|
||||
'<td>' + escapeHtml(stateLabel) + '</td>' +
|
||||
'</tr>';
|
||||
}).join('');
|
||||
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) {
|
||||
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('');
|
||||
|
|
@ -4119,7 +4177,7 @@
|
|||
const risksHtml = risksRows
|
||||
? '<table class="report-table"><thead><tr><th>Risiko</th><th>Sannsynlighet</th><th>Konsekvens</th><th>Tiltak</th></tr></thead><tbody>' + risksRows + '</tbody></table>'
|
||||
: '';
|
||||
const body = ribbonHtml + ladderHtml + detailsHtml + risksHtml;
|
||||
const body = ribbonHtml + ladderHtml + phasesSummaryHtml + detailsHtml + risksHtml;
|
||||
slot.innerHTML = renderPageShell({
|
||||
eyebrow: 'MIGRASJON',
|
||||
title: data.title || 'Migrasjonsplan',
|
||||
|
|
@ -4281,6 +4339,23 @@
|
|||
'</div>';
|
||||
}).join('');
|
||||
const ladderHtml = '<div class="mat-ladder">' + stepsHtml + '</div>';
|
||||
// v1.13.1 fix (B15): phases-summary-tabell over phase-detail-seksjonene
|
||||
// gir struktur og forhindrer at faseinfo flyter horisontalt mot risiko-
|
||||
// tabellen i renderPoc. Samme mønster som renderMigrate.
|
||||
const phasesSummaryRows = phases.map(function (p, i) {
|
||||
const state = stepStateFor(p, i);
|
||||
const stateLabel = state === 'completed' ? 'Ferdig' : state === 'current' ? 'Pågår' : 'Planlagt';
|
||||
return '<tr>' +
|
||||
'<td>' + escapeHtml(p.name) + '</td>' +
|
||||
'<td>' + escapeHtml(String(p.duration_weeks || '—')) + ' uker</td>' +
|
||||
'<td>' + ((p.milestones || []).length) + '</td>' +
|
||||
'<td>' + ((p.success_criteria || []).length) + '</td>' +
|
||||
'<td>' + escapeHtml(stateLabel) + '</td>' +
|
||||
'</tr>';
|
||||
}).join('');
|
||||
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) {
|
||||
|
|
@ -4307,7 +4382,7 @@
|
|||
const risksHtml = risksRows
|
||||
? '<table class="report-table"><thead><tr><th>Risiko</th><th>Sannsynlighet</th><th>Konsekvens</th><th>Tiltak</th></tr></thead><tbody>' + risksRows + '</tbody></table>'
|
||||
: '';
|
||||
const body = ladderHtml + detailsHtml + risksHtml;
|
||||
const body = ladderHtml + phasesSummaryHtml + detailsHtml + risksHtml;
|
||||
// B1 verdict-pille: data.pocVerdict styrer (go/go-with-conditions/block).
|
||||
// R15: hvis ikke satt, fall tilbake til risk-baserte heuristikk.
|
||||
let verdict = data.verdict || data.pocVerdict;
|
||||
|
|
@ -5283,28 +5358,54 @@
|
|||
|
||||
// v1.13.0 fix (B3): matrix-bobler klikkbare. Klikk scroller til tilsvarende
|
||||
// rad i Trusler-tabellen og fremhever den kort. Bruker data-threat-id som
|
||||
// anker (matchet mot første kolonne i tabellen). Speilet fra llm-security
|
||||
// v7.6.1 commit f9b555a.
|
||||
// anker. Speilet fra llm-security v7.6.1 commit f9b555a.
|
||||
//
|
||||
// v1.13.1 fix (B11): DPIA-fixturer har full-tekst label i matrix_cells men
|
||||
// T-001..T-005-id i threats-tabellen. Matchet kun mot første-kolonne ga
|
||||
// klikk uten effekt. Utvid match-strategi: prøv first-cell exact, så
|
||||
// any-cell substring-match (fuzzy). Også legg til normalisering for å
|
||||
// håndtere truncation (escapeHtml + slice).
|
||||
document.addEventListener('click', function (ev) {
|
||||
const bubble = ev.target.closest('.matrix__bubble[data-threat-id]');
|
||||
if (!bubble) return;
|
||||
const threatId = bubble.getAttribute('data-threat-id');
|
||||
if (!threatId) return;
|
||||
const norm = function (s) { return String(s || '').trim().toLowerCase(); };
|
||||
const target = norm(threatId);
|
||||
const targetHead = target.slice(0, 40);
|
||||
const tables = document.querySelectorAll('table.report-table');
|
||||
// Pass 1: exact match på første-kolonne (T-001-mønster).
|
||||
for (let t = 0; t < tables.length; t++) {
|
||||
const rows = tables[t].querySelectorAll('tbody tr');
|
||||
for (let r = 0; r < rows.length; r++) {
|
||||
const firstCell = rows[r].querySelector('td');
|
||||
if (firstCell && firstCell.textContent.trim() === threatId) {
|
||||
rows[r].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
const orig = rows[r].style.background;
|
||||
rows[r].style.background = 'var(--color-primary-100, var(--color-bg-soft))';
|
||||
rows[r].style.transition = 'background var(--duration-base) var(--ease-default)';
|
||||
setTimeout(function () { rows[r].style.background = orig; }, 1600);
|
||||
if (firstCell && norm(firstCell.textContent) === target) {
|
||||
highlightRow(rows[r]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Pass 2: substring-match mot enhver celle i raden (label-baserte data-id).
|
||||
for (let t = 0; t < tables.length; t++) {
|
||||
const rows = tables[t].querySelectorAll('tbody tr');
|
||||
for (let r = 0; r < rows.length; r++) {
|
||||
const cells = rows[r].querySelectorAll('td');
|
||||
for (let c = 0; c < cells.length; c++) {
|
||||
const cellText = norm(cells[c].textContent);
|
||||
if (cellText && (cellText.indexOf(targetHead) !== -1 || target.indexOf(cellText.slice(0, 40)) !== -1)) {
|
||||
highlightRow(rows[r]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function highlightRow(row) {
|
||||
row.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
const orig = row.style.background;
|
||||
row.style.background = 'var(--color-primary-100, var(--color-bg-soft))';
|
||||
row.style.transition = 'background var(--duration-base) var(--ease-default)';
|
||||
setTimeout(function () { row.style.background = orig; }, 1600);
|
||||
}
|
||||
});
|
||||
|
||||
ACTIONS['onboarding-toggle-group'] = function (ev, el) {
|
||||
|
|
@ -5314,6 +5415,17 @@
|
|||
exp.setAttribute('aria-expanded', open ? 'false' : 'true');
|
||||
};
|
||||
|
||||
// v1.13.1 fix (B8a): renderRequirements bruker data-action="requirement-expand"
|
||||
// på hver expansion__head-knapp, men handleren var aldri registrert. Klikk
|
||||
// gjorde derfor ingenting på R-01..R-09-radene i AI Act-krav-rapporten.
|
||||
// Samme toggle-mønster som onboarding/catalog.
|
||||
ACTIONS['requirement-expand'] = function (ev, el) {
|
||||
const exp = el.closest('.expansion');
|
||||
if (!exp) return;
|
||||
const open = exp.getAttribute('aria-expanded') === 'true';
|
||||
exp.setAttribute('aria-expanded', open ? 'false' : 'true');
|
||||
};
|
||||
|
||||
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