feat(ms-ai-architect): renderer A.2 requirements adopt page-header + scenario-cards + E7
- renderRequirements wrapped med renderPageShell (eyebrow KRAV, verdict via requirements-list) - scenario-card-grid: gruppert pa source_article, status fra dominant (met/partial/missing) - expansion-card per krav (E7): severity-dot + title + chev, body med dl - data-action requirement-expand wired for klikk-toggle (handler kommer i Sesjon 6)
This commit is contained in:
parent
2e8cb9ed93
commit
5f461bfe20
1 changed files with 53 additions and 17 deletions
|
|
@ -3040,6 +3040,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderRequirements(data, slot) {
|
function renderRequirements(data, slot) {
|
||||||
|
const items = data.items || [];
|
||||||
const sevForStatus = function (status) {
|
const sevForStatus = function (status) {
|
||||||
const s = (status || '').toLowerCase();
|
const s = (status || '').toLowerCase();
|
||||||
if (s === 'met') return 'low';
|
if (s === 'met') return 'low';
|
||||||
|
|
@ -3047,23 +3048,58 @@
|
||||||
if (s === 'missing') return 'critical';
|
if (s === 'missing') return 'critical';
|
||||||
return 'info';
|
return 'info';
|
||||||
};
|
};
|
||||||
const items = (data.items || []).map(function (it, idx) {
|
const dominantStatus = function (group) {
|
||||||
return '<li class="findings__item" data-status="' + escapeAttr(it.status || '') + '">' +
|
if (group.some(function (it) { return /missing/i.test(it.status); })) return 'missing';
|
||||||
'<span class="findings__item-severity-dot" data-severity="' + escapeAttr(sevForStatus(it.status)) + '"></span>' +
|
if (group.some(function (it) { return /partial/i.test(it.status); })) return 'partial';
|
||||||
'<span class="findings__item-id">R-' + String(idx + 1).padStart(2, '0') + '</span>' +
|
return 'met';
|
||||||
'<span class="findings__item-title">' + escapeHtml(it.requirement) + '</span>' +
|
};
|
||||||
'<span class="findings__item-meta">Kilde: ' + escapeHtml(it.source_article || '—') + ' · Status: ' + escapeHtml(it.status || '—') + '</span>' +
|
|
||||||
'</li>';
|
// Group by source_article (Art. X) for scenario-card-grid.
|
||||||
}).join('');
|
const groups = {};
|
||||||
slot.innerHTML =
|
items.forEach(function (it) {
|
||||||
'<div class="findings">' +
|
const key = it.source_article || 'Andre';
|
||||||
'<div class="findings__list">' +
|
if (!groups[key]) groups[key] = [];
|
||||||
'<div class="findings__group">' +
|
groups[key].push(it);
|
||||||
'<div class="findings__group-header"><span>Krav</span><span>' + (data.items || []).length + '</span></div>' +
|
});
|
||||||
'<ul class="findings__items">' + items + '</ul>' +
|
const groupKeys = Object.keys(groups).sort();
|
||||||
'</div>' +
|
const cardsHtml = groupKeys.length ? '<div class="scenario-card-grid">' + groupKeys.map(function (k) {
|
||||||
'</div>' +
|
const group = groups[k];
|
||||||
'</div>';
|
const status = dominantStatus(group);
|
||||||
|
return '<div class="scenario-card" data-status="' + escapeAttr(status) + '">' +
|
||||||
|
'<div class="scenario-card__head">' +
|
||||||
|
'<span class="scenario-card__source">' + escapeHtml(k) + '</span>' +
|
||||||
|
'<span class="scenario-card__count">' + group.length + ' krav</span>' +
|
||||||
|
'</div>' +
|
||||||
|
'<p class="scenario-card__title">' + escapeHtml(group[0].requirement) + (group.length > 1 ? ' (+' + (group.length - 1) + ')' : '') + '</p>' +
|
||||||
|
'</div>';
|
||||||
|
}).join('') + '</div>' : '';
|
||||||
|
|
||||||
|
const expansionsHtml = items.length ? items.map(function (it, idx) {
|
||||||
|
const sev = sevForStatus(it.status);
|
||||||
|
return '<div class="expansion" aria-expanded="false">' +
|
||||||
|
'<button type="button" class="expansion__head" data-action="requirement-expand" data-idx="' + idx + '">' +
|
||||||
|
'<span class="findings__item-severity-dot" data-severity="' + escapeAttr(sev) + '"></span>' +
|
||||||
|
'<span class="expansion__title">' +
|
||||||
|
'<span class="expansion__title-main">R-' + String(idx + 1).padStart(2, '0') + ' — ' + escapeHtml(it.requirement) + '</span>' +
|
||||||
|
'<span class="expansion__title-sub">Kilde: ' + escapeHtml(it.source_article || '—') + ' · Status: ' + escapeHtml(it.status || '—') + '</span>' +
|
||||||
|
'</span>' +
|
||||||
|
'<span class="expansion__chev" aria-hidden="true">▾</span>' +
|
||||||
|
'</button>' +
|
||||||
|
'<div class="expansion__body"><div class="expansion__body-inner"><div>' +
|
||||||
|
'<dl><dt>Kilde</dt><dd>' + escapeHtml(it.source_article || '—') + '</dd>' +
|
||||||
|
'<dt>Status</dt><dd>' + escapeHtml(it.status || '—') + '</dd></dl>' +
|
||||||
|
'</div></div></div>' +
|
||||||
|
'</div>';
|
||||||
|
}).join('') : '';
|
||||||
|
|
||||||
|
const body = cardsHtml + (expansionsHtml ? '<div class="findings">' + expansionsHtml + '</div>' : '');
|
||||||
|
slot.innerHTML = renderPageShell({
|
||||||
|
eyebrow: 'KRAV',
|
||||||
|
title: data.title || 'AI Act-krav per risiko og rolle',
|
||||||
|
lede: data.lede || 'Konkrete forpliktelser gruppert etter Art-paragraf med detaljer per krav.',
|
||||||
|
verdict: data.verdict || inferVerdict(data, 'requirements-list'),
|
||||||
|
keyStats: data.keyStats || inferKeyStats(data, 'requirements-list')
|
||||||
|
}, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderTransparency(data, slot) {
|
function renderTransparency(data, slot) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue