[UX+SEC] Eccellenza pre-audit: idle timeout, loading states, i18n, UX polish
- common.js: idle session timeout 30min con avviso countdown 5min prima del logout - common.js: checkAuth() attiva automaticamente il monitor di inattività - api.js: messaggi errore connessione usano i18n (IT/EN) tramite I18n.t() - risks.html: saveRisk() e aiSuggest() con setButtonLoading durante salvataggio - risks.html: deleteRisk() ricarica la matrice se si è in matrix view - incidents.html: createIncident() con setButtonLoading durante registrazione - policies.html: savePolicy() e saveAIGeneratedPolicy() con setButtonLoading - policies.html: banner AI-draft con pulsante X per dismissione Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
a56401f5a9
commit
59fad22c0e
+11
-1
@@ -307,7 +307,7 @@
|
||||
<button class="active" onclick="switchView('table')">Tabella</button>
|
||||
<button onclick="switchView('matrix')">Matrice</button>
|
||||
</div>
|
||||
<button class="btn btn-secondary" onclick="aiSuggest()">
|
||||
<button class="btn btn-secondary" id="btn-ai-suggest" onclick="aiSuggest()">
|
||||
<svg viewBox="0 0 20 20" fill="currentColor" width="18" height="18"><path d="M5 2a1 1 0 011 1v1h1a1 1 0 010 2H6v1a1 1 0 01-2 0V6H3a1 1 0 010-2h1V3a1 1 0 011-1zm0 10a1 1 0 011 1v1h1a1 1 0 110 2H6v1a1 1 0 11-2 0v-1H3a1 1 0 110-2h1v-1a1 1 0 011-1zm7-10a1 1 0 01.967.744L14.146 7.2 17.5 8.512a1 1 0 010 1.836l-3.354 1.311-1.18 4.456a1 1 0 01-1.932 0L9.854 11.66 6.5 10.348a1 1 0 010-1.836l3.354-1.311 1.18-4.456A1 1 0 0112 2z"/></svg>
|
||||
AI Suggerisci
|
||||
</button>
|
||||
@@ -955,6 +955,7 @@
|
||||
}
|
||||
|
||||
async function saveRisk(riskId) {
|
||||
const btn = document.querySelector('#modal-overlay .btn-primary');
|
||||
const data = {
|
||||
title: document.getElementById('risk-title').value.trim(),
|
||||
description: document.getElementById('risk-description').value.trim(),
|
||||
@@ -974,6 +975,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
setButtonLoading(btn, true);
|
||||
try {
|
||||
let result;
|
||||
if (riskId) {
|
||||
@@ -991,9 +993,11 @@
|
||||
viewRiskDetail(riskId || result.data.id);
|
||||
}
|
||||
} else {
|
||||
setButtonLoading(btn, false);
|
||||
showNotification(result.message || 'Errore nel salvataggio', 'error');
|
||||
}
|
||||
} catch (e) {
|
||||
setButtonLoading(btn, false);
|
||||
showNotification('Errore di connessione', 'error');
|
||||
}
|
||||
}
|
||||
@@ -1018,8 +1022,10 @@
|
||||
if (result.success) {
|
||||
closeModal();
|
||||
showNotification('Rischio eliminato', 'success');
|
||||
const wasMatrix = currentView === 'matrix';
|
||||
backToList();
|
||||
loadRisks();
|
||||
if (wasMatrix) loadMatrix();
|
||||
} else {
|
||||
showNotification(result.message || 'Errore nella eliminazione', 'error');
|
||||
}
|
||||
@@ -1097,6 +1103,8 @@
|
||||
|
||||
// ── AI Suggest ───────────────────────────────────────────────
|
||||
async function aiSuggest() {
|
||||
const btn = document.getElementById('btn-ai-suggest');
|
||||
setButtonLoading(btn, true);
|
||||
showNotification('Generazione suggerimenti AI in corso...', 'info');
|
||||
try {
|
||||
const result = await api.aiSuggestRisks();
|
||||
@@ -1131,6 +1139,8 @@
|
||||
}
|
||||
} catch (e) {
|
||||
showNotification('Errore di connessione al servizio AI', 'error');
|
||||
} finally {
|
||||
setButtonLoading(btn, false);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user