[FIX] ARIA chat: indicatore 'sta scrivendo' + input multi-riga (Shift+Invio)

Risolve #418/#420 (ARIA sembrava non rispondere / serviva riaprire il pannello):
l'attesa della risposta /api/ai/ask (RAG+Claude, alcuni secondi) non mostrava
alcun indicatore -> ora compare 'ARIA sta scrivendo...' con input disabilitato
(anti doppio-invio). Indicatore rispetta prefers-reduced-motion (AGID/WCAG).

Risolve #425: il campo di scrittura era <input> a riga singola -> ora <textarea>
con Invio=invia, Shift+Invio=a capo, auto-crescita e aria-label.

common.js e' statico (no PHP/USR2): bump cache-buster ?v=20260623 su 39 pagine
(public + admin) + version.json 1.24.6.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-06-23 18:13:38 +02:00
co-authored by Claude Opus 4.8
parent 4e2e56ec0b
commit bd1e95542c
41 changed files with 92 additions and 46 deletions
+1 -1
View File
@@ -71,7 +71,7 @@
<!-- Stessa logica della app: api.js + common.js (helper) + common-bi.js (override BI) --> <!-- Stessa logica della app: api.js + common.js (helper) + common-bi.js (override BI) -->
<script src="js/api.js?v=20260631"></script> <script src="js/api.js?v=20260631"></script>
<script src="js/common.js?v=20260631"></script> <script src="js/common.js?v=20260623"></script>
<script src="js/common-bi.js?v=20260631"></script> <script src="js/common-bi.js?v=20260631"></script>
<script> <script>
// Renderizza la sidebar BI (loadSidebar è stato ridefinito da common-bi.js) // Renderizza la sidebar BI (loadSidebar è stato ridefinito da common-bi.js)
+1 -1
View File
@@ -318,7 +318,7 @@
</div> </div>
<script src="/js/api.js?v=20260620"></script> <script src="/js/api.js?v=20260620"></script>
<script src="/js/common.js?v=20260620"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -148,7 +148,7 @@
</div> </div>
<script src="../js/api.js?v=20260620"></script> <script src="../js/api.js?v=20260620"></script>
<script src="../js/common.js?v=20260620"></script> <script src="../js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -170,7 +170,7 @@
</div> </div>
<script src="../js/api.js?v=20260620"></script> <script src="../js/api.js?v=20260620"></script>
<script src="../js/common.js?v=20260620"></script> <script src="../js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -1091,7 +1091,7 @@
</div> </div>
<script src="js/api.js?v=20260631"></script> <script src="js/api.js?v=20260631"></script>
<script src="js/common.js?v=20260631"></script> <script src="js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="js/i18n.js?v=20260631"></script> <script src="js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -155,7 +155,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -362,7 +362,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -152,7 +152,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -350,7 +350,7 @@
</div> </div>
<script src="js/api.js?v=20260631"></script> <script src="js/api.js?v=20260631"></script>
<script src="js/common.js?v=20260631"></script> <script src="js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle + override sidebar BI (common-bi.js dopo common.js: ridefinisce solo loadSidebar) --> <!-- Bootstrap Italia bundle + override sidebar BI (common-bi.js dopo common.js: ridefinisce solo loadSidebar) -->
<script src="vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script>if (window.bootstrap && bootstrap.loadFonts) { bootstrap.loadFonts('vendor/bootstrap-italia/dist/fonts'); }</script> <script>if (window.bootstrap && bootstrap.loadFonts) { bootstrap.loadFonts('vendor/bootstrap-italia/dist/fonts'); }</script>
+1 -1
View File
@@ -184,7 +184,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -137,7 +137,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -383,7 +383,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -144,7 +144,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -1143,7 +1143,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (accordion) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (accordion) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI. --> common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI. -->
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
+1 -1
View File
@@ -352,7 +352,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -912,7 +912,7 @@ curl -H <span class="str">"X-API-Key: nis2_TUA_CHIAVE"</span> \
</main> </main>
<script src="js/common.js?v=20260631"></script> <script src="js/common.js?v=20260623"></script>
<script src="js/i18n.js?v=20260631"></script> <script src="js/i18n.js?v=20260631"></script>
<script> <script>
function showTab(id) { function showTab(id) {
+1 -1
View File
@@ -140,7 +140,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -185,7 +185,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+52 -6
View File
@@ -996,8 +996,24 @@ function switchLang(lang) {
var STORAGE_KEY = 'nis2_ai_chat'; var STORAGE_KEY = 'nis2_ai_chat';
var history = []; var history = [];
var pending = false; // ARIA sta elaborando una risposta (mostra indicatore "sta scrivendo")
try { history = JSON.parse(sessionStorage.getItem(STORAGE_KEY) || '[]'); } catch (e) {} try { history = JSON.parse(sessionStorage.getItem(STORAGE_KEY) || '[]'); } catch (e) {}
// Stile una-tantum per l'indicatore "ARIA sta scrivendo…" (puntini animati,
// rispetta prefers-reduced-motion per accessibilita AGID/WCAG).
if (!document.getElementById('nis2-aria-style')) {
var ariaStyle = document.createElement('style');
ariaStyle.id = 'nis2-aria-style';
ariaStyle.textContent =
'@keyframes nis2AriaBlink{0%,80%,100%{opacity:.2}40%{opacity:1}}'
+ '.nis2-aria-dot{display:inline-block;width:6px;height:6px;margin:0 1px;'
+ 'border-radius:50%;background:#7C3AED;animation:nis2AriaBlink 1.2s infinite both}'
+ '.nis2-aria-dot:nth-child(2){animation-delay:.2s}'
+ '.nis2-aria-dot:nth-child(3){animation-delay:.4s}'
+ '@media (prefers-reduced-motion:reduce){.nis2-aria-dot{animation:none;opacity:.6}}';
document.head.appendChild(ariaStyle);
}
function escHtml(s) { function escHtml(s) {
return String(s).replace(/[&<>"']/g, function (c) { return String(s).replace(/[&<>"']/g, function (c) {
return ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'})[c]; return ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'})[c];
@@ -1043,31 +1059,60 @@ function switchLang(lang) {
+ (list || '<div style="color:#9ca3af;font-size:13px;text-align:center;' + (list || '<div style="color:#9ca3af;font-size:13px;text-align:center;'
+ 'margin-top:24px">Ciao! Chiedimi qualcosa su NIS2: misure di ' + 'margin-top:24px">Ciao! Chiedimi qualcosa su NIS2: misure di '
+ 'sicurezza, audit, fornitori, incident response…</div>') + 'sicurezza, audit, fornitori, incident response…</div>')
+ (pending
? '<div id="ai-chat-typing" aria-live="polite" '
+ 'style="margin-bottom:10px;display:flex;justify-content:flex-start">'
+ '<div style="padding:8px 12px;border-radius:14px;font-size:13px;'
+ 'background:#f3f4f6;color:#6b7280">ARIA sta scrivendo '
+ '<span class="nis2-aria-dot"></span><span class="nis2-aria-dot"></span>'
+ '<span class="nis2-aria-dot"></span></div></div>'
: '')
+ '</div>' + '</div>'
+ '<form id="ai-chat-form" style="display:flex;gap:6px;padding:10px;' + '<form id="ai-chat-form" style="display:flex;gap:6px;padding:10px;'
+ 'border-top:1px solid #e5e7eb;background:#fff">' + 'border-top:1px solid #e5e7eb;background:#fff;align-items:flex-end">'
+ '<input id="ai-chat-input" type="text" placeholder="Scrivi…" ' + '<textarea id="ai-chat-input" rows="1" '
+ 'autocomplete="off" style="flex:1;padding:10px 12px;border:1px solid ' + 'placeholder="Scrivi… (Invio per inviare, Shift+Invio per andare a capo)" '
+ '#d1d5db;border-radius:10px;font-size:14px;font-family:inherit">' + 'aria-label="Scrivi un messaggio ad ARIA" autocomplete="off"'
+ '<button type="submit" style="padding:10px 14px;border:none;' + (pending ? ' disabled' : '')
+ ' style="flex:1;padding:10px 12px;border:1px solid #d1d5db;border-radius:10px;'
+ 'font-size:14px;font-family:inherit;resize:none;max-height:120px;'
+ 'overflow-y:auto;line-height:1.4"></textarea>'
+ '<button type="submit"' + (pending ? ' disabled' : '')
+ ' style="padding:10px 14px;border:none;'
+ 'border-radius:10px;background:linear-gradient(135deg,#7C3AED,#3B82F6);' + 'border-radius:10px;background:linear-gradient(135deg,#7C3AED,#3B82F6);'
+ 'color:#fff;font-weight:600;cursor:pointer">' + 'color:#fff;font-weight:600;cursor:' + (pending ? 'not-allowed' : 'pointer')
+ ';opacity:' + (pending ? '.6' : '1') + '">'
+ '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>' + '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>'
+ '</button>' + '</button>'
+ '</form>'; + '</form>';
document.getElementById('ai-chat-close').onclick = closePanel; document.getElementById('ai-chat-close').onclick = closePanel;
document.getElementById('ai-chat-form').onsubmit = onSubmit; document.getElementById('ai-chat-form').onsubmit = onSubmit;
var inputEl = document.getElementById('ai-chat-input');
if (inputEl) {
// Invio = invia · Shift+Invio = vai a capo (textarea multi-riga)
inputEl.addEventListener('keydown', function (e) {
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); onSubmit(e); }
});
// Auto-crescita altezza della textarea fino a max-height
inputEl.addEventListener('input', function () {
inputEl.style.height = 'auto';
inputEl.style.height = Math.min(inputEl.scrollHeight, 120) + 'px';
});
if (!pending) inputEl.focus();
}
var msgs = document.getElementById('ai-chat-msgs'); var msgs = document.getElementById('ai-chat-msgs');
msgs.scrollTop = msgs.scrollHeight; msgs.scrollTop = msgs.scrollHeight;
} }
async function onSubmit(ev) { async function onSubmit(ev) {
ev.preventDefault(); ev.preventDefault();
if (pending) return; // evita invii doppi mentre ARIA elabora
var input = document.getElementById('ai-chat-input'); var input = document.getElementById('ai-chat-input');
var text = (input.value || '').trim(); var text = (input.value || '').trim();
if (!text) return; if (!text) return;
history.push({ role: 'user', content: text }); history.push({ role: 'user', content: text });
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(history)); sessionStorage.setItem(STORAGE_KEY, JSON.stringify(history));
pending = true;
render(); render();
try { try {
// AI nativa NIS2 (RAG con KB Multi-Livello già attivo) // AI nativa NIS2 (RAG con KB Multi-Livello già attivo)
@@ -1094,6 +1139,7 @@ function switchLang(lang) {
content: '⚠️ ARIA non risponde in questo momento. Riprova tra poco.' content: '⚠️ ARIA non risponde in questo momento. Riprova tra poco.'
}); });
} }
pending = false;
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(history)); sessionStorage.setItem(STORAGE_KEY, JSON.stringify(history));
render(); render();
} }
+1 -1
View File
@@ -151,7 +151,7 @@
</div> </div>
<!-- Stessa logica JS della pagina live (parita' funzionale assoluta, zero backend). --> <!-- Stessa logica JS della pagina live (parita' funzionale assoluta, zero backend). -->
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI. --> common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI. -->
+1 -1
View File
@@ -95,7 +95,7 @@
<!-- Stessa logica della login attuale: ZERO modifiche backend --> <!-- Stessa logica della login attuale: ZERO modifiche backend -->
<script src="js/api.js?v=20260631"></script> <script src="js/api.js?v=20260631"></script>
<script src="js/common.js?v=20260631"></script> <script src="js/common.js?v=20260623"></script>
<script> <script>
if (api.isAuthenticated()) { window.location.href = 'dashboard.html'; } if (api.isAuthenticated()) { window.location.href = 'dashboard.html'; }
+1 -1
View File
@@ -127,7 +127,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -168,7 +168,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -426,6 +426,6 @@ curl https://nis2.agile.software/api/services/status</pre>
</div> </div>
</div> </div>
<script src="js/common.js?v=20260631"></script> <script src="js/common.js?v=20260623"></script>
</body> </body>
</html> </html>
+1 -1
View File
@@ -113,7 +113,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -495,7 +495,7 @@
<!-- Stessa logica della onboarding.html: ZERO modifiche backend --> <!-- Stessa logica della onboarding.html: ZERO modifiche backend -->
<script src="js/api.js?v=20260631"></script> <script src="js/api.js?v=20260631"></script>
<script src="js/common.js?v=20260631"></script> <script src="js/common.js?v=20260623"></script>
<script> <script>
// ── Auth check ────────────────────────────────────────────────── // ── Auth check ──────────────────────────────────────────────────
if (!checkAuth()) throw new Error('Not authenticated'); if (!checkAuth()) throw new Error('Not authenticated');
+1 -1
View File
@@ -139,7 +139,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -334,7 +334,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -132,7 +132,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -269,7 +269,7 @@
<!-- Stessa logica della register.html: ZERO modifiche backend --> <!-- Stessa logica della register.html: ZERO modifiche backend -->
<script src="js/api.js?v=20260631"></script> <script src="js/api.js?v=20260631"></script>
<script src="js/common.js?v=20260631"></script> <script src="js/common.js?v=20260623"></script>
<script> <script>
if (api.isAuthenticated()) { window.location.href = 'dashboard.html'; } if (api.isAuthenticated()) { window.location.href = 'dashboard.html'; }
+1 -1
View File
@@ -444,7 +444,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -142,7 +142,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -495,7 +495,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -689,7 +689,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -195,7 +195,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -192,7 +192,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="/js/i18n.js?v=20260631"></script> <script src="/js/i18n.js?v=20260631"></script>
+1 -1
View File
@@ -478,7 +478,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -293,7 +293,7 @@
</div> </div>
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -1 +1 @@
{"version": "1.24.5", "build": "2026-06-21-v1.24.5", "date": "2026-06-21", "changelog": "Internazionalizzazione EN del modulo Fornitori: il Portale Fornitori esterno (supplier-portal.html) e' ora bilingue IT/EN con meccanismo self-contained (dizionario inline + toggle lingua, ~79 stringhe) preservando il flusso OTP/token; la pagina interna Supply Chain (supply-chain.html) ha l'i18n estesa (data-i18n + I18n.t, +82 chiavi sp.* in i18n.js, ora 120 totali). Le domande dei questionari restano nei dati (non tradotte)."} {"version": "1.24.6", "build": "2026-06-23-v1.24.6", "date": "2026-06-23", "changelog": "Assistente AI ARIA (chat): aggiunto l'indicatore \"ARIA sta scrivendo...\" durante l'elaborazione (con campo input disabilitato anti-doppio-invio) cosi' l'utente vede che la risposta e' in arrivo e non pensa che sia bloccata; il campo di scrittura e' ora multi-riga (Invio per inviare, Shift+Invio per andare a capo). Risolti ticket #418/#420 (sembrava non rispondere / serviva riaprire) e #425 (Shift+Invio). Indicatore conforme a prefers-reduced-motion (AGID/WCAG)."}
+1 -1
View File
@@ -208,7 +208,7 @@
<!-- Report Detail Modal handled by common.js showModal --> <!-- Report Detail Modal handled by common.js showModal -->
<script src="/js/api.js?v=20260631"></script> <script src="/js/api.js?v=20260631"></script>
<script src="/js/common.js?v=20260631"></script> <script src="/js/common.js?v=20260623"></script>
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js). <!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI, common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
riusando tutti gli helper di common.js (zero backend). --> riusando tutti gli helper di common.js (zero backend). -->
+1 -1
View File
@@ -322,7 +322,7 @@
</div> </div>
<script src="js/api.js?v=20260631"></script> <script src="js/api.js?v=20260631"></script>
<script src="js/common.js?v=20260631"></script> <script src="js/common.js?v=20260623"></script>
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script> <script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
<script src="/js/common-bi.js?v=20260631"></script> <script src="/js/common-bi.js?v=20260631"></script>
<script src="js/i18n.js?v=20260631"></script> <script src="js/i18n.js?v=20260631"></script>