Files
nis2-agile/public/isms.html
T
DevEnv nis2-agileandClaude Opus 4.8 a4150b5389 [FEAT] UI V3 — flotta: chrome top-nav + design system su 32 pagine app
Migrazione UI dal V2 (Bootstrap Italia, sidebar) al V3 (top-nav mega-menu
navy/oro, Inter+Lucide self-host) fedele ai mockup docs/mockup Ui/.
- 32 pagine app convertite (incl. admin/*): head Inter+v3.css, chrome
  topnav-v3, contenuti in card V3, dati REALI preservati (id/data-* intatti),
  i18n/help/FAB reali invariati, nessun CDN esterno.
- v3.css: aggiunti widget condivisi (modal/toast/form/btn-variant/spinner/
  progress/tag/badge) + utility (.btn base, .text-muted, .sr-only) + alias
  variabili V2->token V3, così modali/form/toast di common.js funzionano
  ovunque senza style.css.
- maintenance.html: finestra estesa a ~12:15.
- docs/UI_V3_FLEET_BRIEF.md: ricetta operativa della flotta.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 15:57:35 +02:00

218 lines
17 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Modello Organizzativo SGSI (ISO 27001) · NIS2 Agile</title>
<!-- UI V3: Inter self-host + design system v3.css. Self-host only, nessun CDN esterno. -->
<link rel="stylesheet" href="/vendor/inter/inter.css?v=20260627">
<link rel="stylesheet" href="/css/v3.css?v=20260627">
<style>
/* Stili specifici della pagina SGSI non coperti da v3.css (nessun CDN). */
.text-muted { color: var(--muted); }
.sr-only { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
/* Base .btn usata dai bottoni generati via JS (es. "btn btn-sm btn-outline") */
.btn { display:inline-flex; align-items:center; justify-content:center; gap:7px; font:inherit; font-weight:600; font-size:12.5px; border-radius:8px; padding:8px 13px; border:1px solid transparent; cursor:pointer; line-height:1.4; text-decoration:none; }
.btn .icon, .btn .ic { width:15px; height:15px; }
.isms-intro { background:#EAF1FA; border-left:4px solid var(--c-blue); padding:14px 18px; border-radius:10px; margin-bottom:18px; font-size:.92rem; line-height:1.6; color:var(--ink); }
.isms-steps { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:20px; }
.isms-step { flex:1 1 140px; min-width:120px; padding:11px 12px; border:1.5px solid var(--line); border-radius:11px; background:#fff; cursor:pointer; font-size:.82rem; text-align:center; transition:border-color .12s,background .12s; }
.isms-step:hover { border-color:#9FBEDD; }
.isms-step.active { border-color:var(--c-blue); background:#EAF1FA; font-weight:700; }
.isms-step.done { border-color:var(--c-green); }
.isms-step .num { display:inline-block; width:22px; height:22px; line-height:22px; border-radius:50%; background:#EEF2F7; font-weight:700; margin-bottom:4px; }
.isms-step.done .num { background:var(--c-green); color:#fff; }
.isms-panel { display:none; }
.isms-panel.active { display:block; }
.isms-panel h3 { margin:0 0 12px; font-size:17px; font-weight:800; }
.isms-panel h4 { margin:16px 0 8px; font-size:14px; font-weight:700; }
.isms-disclaimer { font-size:.8rem; color:#92400e; background:#FBF1E2; border:1px solid #fde68a; border-radius:8px; padding:10px 12px; margin:12px 0; }
.raci-row { display:flex; gap:8px; align-items:center; flex-wrap:wrap; padding:8px 0; border-bottom:1px solid var(--line); }
.raci-row input, .raci-row select { padding:8px 10px; border:1px solid var(--line); border-radius:8px; font:inherit; font-size:.85rem; color:var(--ink); }
.soa-std { border:1px solid var(--line); border-radius:11px; margin-bottom:14px; overflow:hidden; }
.soa-std-head { background:#F5F8FC; padding:12px 16px; cursor:pointer; display:flex; justify-content:space-between; align-items:center; }
.soa-std-body { padding:6px 14px 14px; display:none; }
.soa-std.open .soa-std-body { display:block; }
.soa-theme { font-size:.78rem; font-weight:700; text-transform:uppercase; color:var(--muted); margin:14px 0 6px; letter-spacing:.04em; }
.soa-ctrl { padding:12px 0; border-top:1px solid var(--line); }
.soa-ctrl-head { display:flex; gap:10px; align-items:flex-start; justify-content:space-between; flex-wrap:wrap; }
.soa-code { display:inline-block; background:#E7F0FB; color:#1F5FA8; font-weight:700; font-size:.72rem; padding:2px 8px; border-radius:6px; margin-right:6px; }
.soa-derived { background:#E6F4EC; color:#1E7A4E; font-size:.68rem; padding:1px 6px; border-radius:5px; }
.soa-opts { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.soa-opt { min-height:34px; padding:5px 10px; border:1.5px solid var(--line); border-radius:18px; background:#fff; cursor:pointer; font:inherit; font-size:.8rem; font-weight:600; color:var(--ink); }
.soa-opt.sel-implemented,.soa-opt.sel-verified { background:var(--c-green); color:#fff; border-color:var(--c-green); }
.soa-opt.sel-in_progress { background:var(--c-amber); color:#fff; border-color:var(--c-amber); }
.soa-opt.sel-not_started { background:#9ca3af; color:#fff; border-color:#9ca3af; }
.soa-justif { width:100%; margin-top:8px; padding:8px; border:1px solid var(--line); border-radius:8px; font:inherit; font-size:.84rem; min-height:46px; color:var(--ink); }
.isms-field { margin-bottom:14px; }
.isms-field label { display:block; font-weight:600; font-size:.88rem; margin-bottom:4px; }
.isms-field textarea, .isms-field input { width:100%; padding:9px; border:1px solid var(--line); border-radius:8px; font:inherit; font-size:.9rem; color:var(--ink); }
.isms-flags label { display:block; padding:8px 0; font-size:.9rem; }
.ck-item { display:flex; justify-content:space-between; padding:8px 0; border-bottom:1px solid var(--line); font-size:.9rem; }
.ck-yes { color:var(--c-green); font-weight:700; } .ck-no { color:#9ca3af; }
.savehint { font-size:.78rem; color:var(--muted); min-height:16px; }
</style>
<!-- PWA:start -->
<link rel="manifest" href="/manifest.webmanifest">
<meta name="theme-color" content="#0066CC">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
<meta name="application-name" content="NIS2 Agile">
<script src="/js/pwa.js?v=20260614" defer></script>
<!-- PWA:end -->
</head>
<body>
<!-- Chrome V3 (appbar + mega-menu) iniettata da topnav-v3.js in questo host -->
<div id="topnav"></div>
<main class="wrap">
<nav class="crumb" aria-label="breadcrumb">
<i data-lucide="home" class="ic"></i><a href="dashboard.html">Home</a>
<i data-lucide="chevron-right" class="ic"></i><span>SGSI (ISO 27001)</span>
</nav>
<div class="page-head">
<div>
<h1 data-i18n="isms.title">Modello Organizzativo SGSI (ISO 27001)</h1>
<p class="sub">Procedura guidata ISO/IEC 27001:2022 — clausole 4–10 + Statement of Applicability</p>
</div>
<div class="content-header-actions" style="display:flex; align-items:center; gap:12px; flex-wrap:wrap;">
<span class="savehint" id="isms-savehint" role="status" aria-live="polite"></span>
<button class="btn-ghost" id="nis2-isms-btn-export" onclick="ismsExportView()" data-i18n="isms.export">
<i data-lucide="file-text" class="ic"></i>
<span>Esporta SGSI</span>
</button>
</div>
</div>
<section class="card card-pad">
<div class="isms-intro" id="nis2-isms-intro">
<strong data-i18n="isms.intro.title">Costruisci il tuo Sistema di Gestione della Sicurezza delle Informazioni.</strong>
<span data-i18n="isms.intro.body">Procedura guidata ISO/IEC 27001:2022 (clausole 4-10 + Statement of Applicability). Lo Statement of Applicability viene pre-popolato dalle tue risposte alla Gap Analysis NIS2. Attiva le estensioni cloud ISO 27017/27018 dove pertinenti.</span>
</div>
<div class="isms-disclaimer" id="nis2-isms-disclaimer" data-i18n="isms.disclaimer">Strumento di supporto e pre-audit: non costituisce una certificazione ISO 27001 né un parere professionale vincolante. Gli obblighi normativi in Italia derivano da NIS2 / D.Lgs. 138/2024 / Determinazioni ACN; ISO 27001/27017/27018 sono best practice.</div>
<div class="isms-steps" id="isms-steps"></div>
<!-- STEP 1 - Contesto & Ambito (cl.4) -->
<div class="isms-panel" id="panel-0">
<div class="card card-pad">
<h3 data-i18n="isms.s1.title">1. Contesto e Ambito (cl. 4)</h3>
<div class="isms-field"><label for="f-scope" data-i18n="isms.s1.scope">Ambito del SGSI (scope statement)</label><textarea id="f-scope" rows="3" placeholder="Es. Tutti i sistemi e processi a supporto dei servizi ICT erogati dalla sede di..."></textarea></div>
<div class="isms-field"><label for="f-ctx-int" data-i18n="isms.s1.ctx_int">Contesto interno</label><textarea id="f-ctx-int" rows="2"></textarea></div>
<div class="isms-field"><label for="f-ctx-ext" data-i18n="isms.s1.ctx_ext">Contesto esterno</label><textarea id="f-ctx-ext" rows="2"></textarea></div>
<div class="isms-field"><label for="f-parties" data-i18n="isms.s1.parties">Parti interessate (una per riga)</label><textarea id="f-parties" rows="3" placeholder="Clienti&#10;Autorità (ACN/CSIRT)&#10;Fornitori ICT"></textarea></div>
<div class="isms-field"><label for="f-boundaries" data-i18n="isms.s1.boundaries">Confini del SGSI</label><textarea id="f-boundaries" rows="2"></textarea></div>
<div class="isms-field"><label for="f-exclusions" data-i18n="isms.s1.exclusions">Esclusioni motivate</label><textarea id="f-exclusions" rows="2"></textarea></div>
<div class="isms-flags">
<strong data-i18n="isms.s1.cloud">Estensioni cloud (attivano i controlli condizionali nel SoA)</strong>
<label><input type="checkbox" id="f-uses-cloud"> <span data-i18n="isms.s1.uses_cloud">Usiamo servizi cloud pubblici (Microsoft 365, AWS, Google...) → ISO 27017</span></label>
<label><input type="checkbox" id="f-cloud-provider"> <span data-i18n="isms.s1.cloud_provider">Siamo fornitori di servizi cloud → ISO 27017 (lato provider)</span></label>
<label><input type="checkbox" id="f-pii-cloud"> <span data-i18n="isms.s1.pii_cloud">Trattiamo dati personali (PII) in cloud pubblico come responsabili → ISO 27018</span></label>
</div>
<button class="btn-primary" id="nis2-isms-btn-save-step1" onclick="saveStep1()" data-i18n="isms.save_next">Salva e continua</button>
</div>
</div>
<!-- STEP 2 - Leadership (cl.5) -->
<div class="isms-panel" id="panel-1">
<div class="card card-pad">
<h3 data-i18n="isms.s2.title">2. Leadership: ruoli e responsabilità (cl. 5)</h3>
<p class="text-muted" data-i18n="isms.s2.hint">Definisci i ruoli del SGSI con la matrice RACI (Responsible, Accountable, Consulted, Informed).</p>
<div id="roles-list"></div>
<div class="raci-row" style="border-top:2px solid var(--line); margin-top:10px;">
<input id="r-name" placeholder="Ruolo (es. CISO)" aria-label="Ruolo" style="flex:1 1 160px;">
<input id="r-resp" placeholder="Responsabilità" aria-label="Responsabilità" style="flex:2 1 220px;">
<select id="r-raci" aria-label="RACI"><option value="">RACI</option><option>R</option><option>A</option><option>C</option><option>I</option></select>
<button class="btn-primary btn-sm" id="nis2-isms-btn-add-role" onclick="addRole()" data-i18n="isms.s2.add">Aggiungi ruolo</button>
</div>
<button class="btn-ghost" id="nis2-isms-btn-next-step2" style="margin-top:14px;" onclick="goStep(2)" data-i18n="isms.next">Continua</button>
</div>
</div>
<!-- STEP 3 - Risk (cl.6) -->
<div class="isms-panel" id="panel-2">
<div class="card card-pad">
<h3 data-i18n="isms.s3.title">3. Risk: metodologia e obiettivi (cl. 6)</h3>
<div class="isms-field"><label for="f-method" data-i18n="isms.s3.method">Metodologia di risk assessment</label><textarea id="f-method" rows="3" placeholder="Es. ISO 27005 / NIST SP 800-30; scala probabilità×impatto 5×5 (già usata nel modulo Rischi)."></textarea></div>
<div class="isms-field"><label for="f-objectives" data-i18n="isms.s3.objectives">Obiettivi del SGSI (uno per riga)</label><textarea id="f-objectives" rows="3"></textarea></div>
<p class="text-muted" data-i18n="isms.s3.link">Il registro dei rischi vive nel modulo <a href="risks.html">Rischi</a>: questo passo ne dichiara la metodologia.</p>
<button class="btn-primary" id="nis2-isms-btn-save-step3" onclick="saveStep3()" data-i18n="isms.save_next">Salva e continua</button>
</div>
</div>
<!-- STEP 4 - SoA -->
<div class="isms-panel" id="panel-3">
<div class="card card-pad">
<h3 data-i18n="isms.s4.title">4. Statement of Applicability</h3>
<p class="text-muted" data-i18n="isms.s4.hint">I controlli sono pre-popolati dalle risposte NIS2 dove esiste corrispondenza (badge "da NIS2"). Conferma applicabilità, stato e motivazione per ciascuno.</p>
<div style="margin:10px 0;">
<button class="btn-ghost btn-sm" id="nis2-isms-btn-derive-soa" onclick="deriveSoa()" data-i18n="isms.s4.derive">Ri-deriva dal NIS2</button>
<span id="soa-stats" class="text-muted" style="margin-left:12px; font-size:.85rem;"></span>
</div>
<div id="soa-groups"></div>
<button class="btn-ghost" id="nis2-isms-btn-next-step4" style="margin-top:14px;" onclick="goStep(4)" data-i18n="isms.next">Continua</button>
</div>
</div>
<!-- STEP 5 - Documented information (cl.7-8) -->
<div class="isms-panel" id="panel-4">
<div class="card card-pad">
<h3 data-i18n="isms.s5.title">5. Documented Information (cl. 7-8)</h3>
<div class="raci-row" style="border:none;">
<label for="d-type" class="sr-only">Tipo di documento</label>
<select id="d-type" style="flex:1 1 200px;" aria-label="Tipo di documento">
<option value="policy_sgsi">Policy SGSI</option>
<option value="dichiarazione_applicabilita">Dichiarazione di Applicabilità</option>
<option value="politica_controllo_accessi">Politica controllo accessi</option>
<option value="procedura_incident">Procedura gestione incidenti</option>
<option value="procedura_continuita">Procedura continuità operativa</option>
<option value="politica_fornitori">Politica sicurezza fornitori</option>
</select>
<button class="btn-primary btn-sm" onclick="aiGenDoc()" id="btn-aigen" data-i18n="isms.s5.aigen">Genera bozza con AI</button>
</div>
<div class="savehint" id="aigen-hint" role="status" aria-live="polite"></div>
<div id="docs-list" style="margin-top:14px;"></div>
<button class="btn-ghost" id="nis2-isms-btn-next-step5" style="margin-top:14px;" onclick="goStep(5)" data-i18n="isms.next">Continua</button>
</div>
</div>
<!-- STEP 6 - Monitoring & Readiness (cl.9-10) -->
<div class="isms-panel" id="panel-5">
<div class="card card-pad">
<h3 data-i18n="isms.s6.title">6. Monitoraggio e Miglioramento (cl. 9-10)</h3>
<p class="text-muted" data-i18n="isms.s6.hint">Gli audit interni e le non conformità si gestiscono nei moduli esistenti: <a href="reports.html">Audit & Report</a> e NCR/CAPA.</p>
<h4 data-i18n="isms.s6.readiness">Completamento del SGSI</h4>
<div style="text-align:center; margin:14px 0;">
<div style="font-size:2.6rem; font-weight:800; color:var(--c-blue);" id="readiness-pct">0%</div>
</div>
<div id="readiness-checklist"></div>
</div>
</div>
</section>
</main>
<!-- Scripts V3: api.js → common.js (helper+FAB reali) → Lucide self-host →
topnav-v3.js (chrome, ridefinisce loadSidebar) → i18n → help → isms.js.
isms.js si auto-inizializza su DOMContentLoaded (checkAuth/I18n/loadSidebar/Help/render). -->
<script src="/js/api.js?v=20260625d"></script>
<script src="/js/common.js?v=20260627v3"></script>
<script src="/vendor/lucide/lucide.min.js"></script>
<script src="/js/topnav-v3.js?v=20260627"></script>
<script src="/js/i18n.js?v=20260631"></script>
<script src="/js/help.js?v=20260625d"></script>
<script src="/js/isms.js?v=20260627v3"></script>
<script>
// Icone Lucide della chrome + crumb/page-head statici. L'init dati e il wiring
// (renderSteps/loadModel/goStep) restano in isms.js (suo DOMContentLoaded).
document.addEventListener('DOMContentLoaded', function(){
if (window.lucide && lucide.createIcons) { try { lucide.createIcons(); } catch (e) {} }
});
</script>
</body>
</html>