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>
94 lines
5.9 KiB
Markdown
94 lines
5.9 KiB
Markdown
# UI V3 — BRIEF OPERATIVO FLOTTA (FASE 1)
|
||
|
||
Migri pagine NIS2 dal V2 (Bootstrap Italia, sidebar) al **V3** (top-nav navy/oro, Inter, Lucide).
|
||
La **FASE 0 è già fatta e in prod**: `public/css/v3.css`, `public/js/topnav-v3.js`, `public/vendor/inter/`,
|
||
`public/vendor/lucide/lucide.min.js`, e la **pilota `public/dashboard.html` + `public/js/dashboard.js`**.
|
||
**Replica quel pattern.** Il sito è in MANUTENZIONE: testa SEMPRE con `?mnt=efc088d042032889b64b887d2e562ec8`.
|
||
|
||
## REGOLE D'ORO (vincolanti)
|
||
- **NON usare git** (no add/commit/push). **Solo scrivere file.** Il commit lo fa l'orchestratore.
|
||
- **NON toccare**: `public/css/v3.css`, `public/js/topnav-v3.js`, `public/js/common.js`, `public/js/api.js`,
|
||
`public/js/i18n.js`, `public/js/help.js`, qualunque `.php`, DB, migrazioni. Sono condivisi/già pronti.
|
||
- **NON toccare** `/var/www/nis2-agile/.maintenance` né `/tmp/agent-working.lock`.
|
||
- **Modifichi SOLO le pagine assegnate** (e, se serve, il loro `<pagina>.js` dedicato — non condiviso).
|
||
- **Dati REALI** via `api.js` (quelli che la pagina già usa). Zero numeri finti dei mockup.
|
||
Se un dato non esiste nel backend → placeholder "—"/empty, **non inventarlo**.
|
||
- **Self-host only**: nessun `googleapis.com`, `gstatic.com`, `unpkg.com`, CDN Bootstrap Italia.
|
||
- Mantieni: `checkAuth`, i18n IT/EN (`data-i18n`), help "?", **trittico FAB reale** (lo monta `common.js`).
|
||
- A11y/AGID: `focus-visible`, contrasto, touch ≥44px, `aria-label`, zoom non bloccato, responsive ≤900/≤560.
|
||
|
||
## RICETTA PER PAGINA — "reskin a rischio minimo"
|
||
L'obiettivo è cambiare **chrome + look**, **senza rompere il wiring**: **preserva ogni `id`/`data-*`
|
||
che il `<pagina>.js` legge** (non rinominarli). Cambi guscio e classi, non la logica.
|
||
|
||
### 1) `<head>` — sostituisci il caricamento CSS/font con (vedi `dashboard.html` righe 3–23):
|
||
```html
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||
<title>NomePagina · NIS2 Agile</title>
|
||
<link rel="stylesheet" href="/vendor/inter/inter.css?v=20260627">
|
||
<link rel="stylesheet" href="/css/v3.css?v=20260627">
|
||
<!-- mantieni il blocco PWA: manifest, theme-color #0066CC, icone, pwa.js (copia da dashboard.html) -->
|
||
```
|
||
**Rimuovi**: bundle Bootstrap Italia (CSS/JS), `/css/style.css`, Google Fonts, unpkg.
|
||
Se la pagina ha un `<style>` inline con regole essenziali non coperte da `v3.css`, puoi **tenerne una
|
||
versione minima** (nessun CDN), ma preferisci le classi di `v3.css`.
|
||
|
||
### 2) `<body>` — struttura V3:
|
||
```html
|
||
<div id="topnav"></div> <!-- host chrome: lo riempie topnav-v3.js -->
|
||
<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>NomePagina</span>
|
||
</nav>
|
||
<div class="page-head">
|
||
<div><h1 data-i18n="...">Titolo</h1><p class="sub">sottotitolo breve</p></div>
|
||
<!-- eventuali bottoni pagina: <button class="btn-primary">…</button> -->
|
||
</div>
|
||
<!-- CONTENUTO: avvolgi i blocchi in <section class="card card-pad">… ; preserva gli id dinamici -->
|
||
</main>
|
||
```
|
||
Mappa i componenti vecchi → classi `v3.css`: contenitori → `.card`/`.card-pad`; KPI → `.stat`
|
||
(`.green/.amber/.blue/.red`, `.ibox`,`.val`,`.lbl`,`.bar`); bottoni → `.btn-primary`/`.btn-ghost`;
|
||
stati → `.badge-t` (varianti colore); intestazioni sezione → `.sec-head`; griglie → `.grid3`/`.split2`.
|
||
Tabelle/liste: tienile dentro una `.card`; usa stili tabella di `v3.css` se presenti, altrimenti markup sobrio.
|
||
Stati **loading/empty/error**: usa `.v3-loading`/`.v3-empty`/`.v3-error` (come la dashboard) dove la pagina carica dati.
|
||
|
||
### 3) Scripts in fondo (ordine ESATTO come `dashboard.html` righe 112–140):
|
||
```html
|
||
<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/NOMEPAGINA.js?v=20260627"></script>
|
||
<script>
|
||
if (!checkAuth()) throw new Error('Not authenticated');
|
||
loadSidebar(); // = loadTopnavV3()
|
||
if (typeof I18n !== 'undefined') I18n.init();
|
||
if (typeof HelpSystem !== 'undefined') HelpSystem.init();
|
||
if (window.lucide && lucide.createIcons) { try { lucide.createIcons(); } catch(e){} }
|
||
/* poi l'init reale della pagina, es: if (typeof initPagina==='function') initPagina(); */
|
||
</script>
|
||
```
|
||
**Rimuovi** `common-bi.js` e il bundle Bootstrap Italia JS. Se il vecchio init chiamava `loadSidebar()`
|
||
funziona identico (topnav-v3.js ridefinisce `window.loadSidebar`). Mantieni l'init dati della pagina.
|
||
|
||
### 4) Pagine con MOCKUP (massima fedeltà)
|
||
- `assessment.html` → segui `docs/mockup Ui/assessment.html` (pattern pagina-modulo/GAP).
|
||
- `calendario.html` → segui `docs/mockup Ui/calendario.html` (app full-page: `.cal-app/.cal-main/.cal-side/.mv-grid/.view-switch/.legend`).
|
||
Le altre pagine: applica lo stile dashboard/card in modo **coerente** (non esiste un mockup dedicato).
|
||
|
||
## VALIDAZIONE (obbligatoria prima di riportare "fatto")
|
||
- `node --check public/js/<ogni-js-toccato>.js` → deve passare.
|
||
- HTTP: `curl -s -o /dev/null -w "%{http_code}\n" "https://nis2.agile.software/<pagina>?mnt=efc088d042032889b64b887d2e562ec8"` → **200**.
|
||
- HTML servito non deve contenere `googleapis|gstatic|unpkg|bootstrap-italia` (CDN):
|
||
`curl -s "https://nis2.agile.software/<pagina>?mnt=efc088d042032889b64b887d2e562ec8" | grep -Eo 'googleapis|gstatic|unpkg|cdn[^"]*bootstrap' | sort -u` → vuoto.
|
||
|
||
## REPORT FINALE
|
||
Elenca: pagine convertite (✓), eventuali `<pagina>.js` adattati e perché, gap/placeholder usati (dato mockup
|
||
inesistente nel backend), componenti `v3.css` che mancavano (NON aggiungerli tu — **segnalali**), e qualsiasi
|
||
pagina che NON sei riuscito a convertire fedelmente (spiega, non improvvisare).
|