[FEAT] Inventario Rilevanza NIS2: significato opzioni combo + dettaglio punteggio per criterio (ticket #431, #432)

- AssetScoringService::GRID: aggiunto campo 'desc' a tutte le 35 opzioni dei 6 criteri (significato operativo, additivo)
- assets.html: ogni combo mostra il significato dell'opzione selezionata + nuovo box 'Dettaglio punteggio per criterio' (live, anche alla riapertura di una valutazione salvata)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-06-23 22:43:43 +02:00
co-authored by Claude Opus 4.8
parent ea5966eaee
commit cf23be9c77
3 changed files with 60 additions and 40 deletions
+25 -5
View File
@@ -634,16 +634,18 @@
const sel = (pv != null) ? (typeof pv === 'object' ? (pv.value || '') : pv) : '';
let opts = `<option value="">— seleziona —</option>`;
for (const [ov, od] of Object.entries(def.options)) {
opts += `<option value="${ov}" data-pts="${od.points}" ${ov === sel ? 'selected' : ''}>${od.label} (${od.points})</option>`;
opts += `<option value="${ov}" data-pts="${od.points}" data-lbl="${escapeHtml(od.label)}" data-desc="${escapeHtml(od.desc || '')}" ${ov === sel ? 'selected' : ''}>${od.label} (${od.points})</option>`;
}
body += `<div class="form-group" style="margin-bottom:0.75rem;">
<label class="form-label" style="font-weight:600;">${def.label} <span style="color:var(--gray-400);font-weight:400;">(max ${def.max})</span></label>
<div style="font-size:0.78rem;color:var(--gray-500);margin-bottom:4px;">${def.help}</div>
<select class="form-select score-criterion" data-key="${key}" onchange="updateScorePreview()" aria-label="${def.label}">${opts}</select>
<select class="form-select score-criterion" data-key="${key}" data-crit-label="${escapeHtml(def.label)}" data-max="${def.max}" onchange="updateScorePreview()" aria-label="${def.label}">${opts}</select>
<div class="score-meaning" id="meaning-${key}" style="font-size:0.78rem;color:var(--gray-600);margin-top:4px;min-height:1.1em;font-style:italic;"></div>
</div>`;
}
body += `<div id="score-preview" style="margin-top:1rem;padding:0.9rem;border-radius:10px;background:var(--gray-50);font-weight:600;text-align:center;">
Totale: <span id="score-total">0</span>/100 — <span id="score-class">—</span></div>`;
Totale: <span id="score-total">0</span>/100 — <span id="score-class">—</span></div>
<div id="score-breakdown" style="margin-top:0.6rem;font-size:0.8rem;color:var(--gray-700);"></div>`;
showModal(`Valuta Rilevanza NIS2 — ${escapeHtml(a.name)}`, body, {
size: 'lg',
@@ -658,9 +660,23 @@
function updateScorePreview() {
let total = 0, complete = true;
let rows = '';
document.querySelectorAll('.score-criterion').forEach(s => {
if (!s.value) { complete = false; return; }
total += parseInt(s.selectedOptions[0].dataset.pts || '0', 10);
const meaningEl = document.getElementById('meaning-' + s.dataset.key);
if (!s.value) {
complete = false;
if (meaningEl) meaningEl.textContent = '';
return;
}
const opt = s.selectedOptions[0];
const pts = parseInt(opt.dataset.pts || '0', 10);
total += pts;
// #432: mostra il significato dell'opzione selezionata sotto la combo
if (meaningEl) meaningEl.textContent = opt.dataset.desc || '';
// #431: dettaglio per criterio del punteggio raggiunto
rows += `<div style="display:flex;justify-content:space-between;gap:0.5rem;padding:3px 0;border-bottom:1px solid var(--gray-100);">
<span>${escapeHtml(s.dataset.critLabel)}: ${escapeHtml(opt.dataset.lbl || '')}</span>
<span style="font-weight:600;white-space:nowrap;">${pts}/${s.dataset.max}</span></div>`;
});
let cls = total >= 80 ? 'critico' : total >= 60 ? 'alto' : total >= 40 ? 'medio' : total >= 20 ? 'basso' : 'trascurabile';
const color = relevanceClassColors[cls];
@@ -668,6 +684,10 @@
const clsEl = document.getElementById('score-class');
clsEl.textContent = complete ? `${cls.charAt(0).toUpperCase() + cls.slice(1)}${total >= 40 ? ' — Rilevante NIS2 ✓' : ''}` : '(completa tutti i criteri)';
clsEl.style.color = complete ? color : 'var(--gray-400)';
const bdEl = document.getElementById('score-breakdown');
if (bdEl) bdEl.innerHTML = rows
? `<div style="font-weight:600;margin-bottom:4px;">Dettaglio punteggio per criterio</div>${rows}`
: '';
}
async function submitScoring(id) {
+1 -1
View File
@@ -1 +1 @@
{"version": "1.24.9", "build": "2026-06-23-v1.24.9", "date": "2026-06-23", "changelog": "Assistente ARIA — Ora ARIA conosce la barra laterale REALE dell'app e, quando ti spiega dove cliccare, usa i nomi esatti delle voci di menu (es. «sezione Operativo > Inventario») senza piu' inventare moduli o «fasi» inesistenti. Inoltre riceve la pagina da cui stai scrivendo, cosi' da darti indicazioni piu' pertinenti al punto in cui ti trovi. Risolto ticket #424."}
{"version": "1.24.10", "build": "2026-06-23-v1.24.10", "date": "2026-06-23", "changelog": "Valuta Rilevanza NIS2 (Inventario) — Ogni voce delle tendine ora mostra anche il suo SIGNIFICATO: scegliendo un'opzione compare sotto la combo una breve spiegazione di cosa indica (es. cosa vuol dire «Critico» per la Criticita Operativa). In piu' la finestra mostra il «Dettaglio punteggio per criterio»: vedi quanti punti hai ottenuto da ciascuna voce e come si compone il totale, anche riaprendo una valutazione gia' salvata. Risolti ticket #431 e #432."}