[FEAT] Inventario: ordinamento lista per colonna (#442)
Click su un'intestazione (Nome/Tipo/Categoria/Criticita/Rilevanza NIS2/Owner/Stato) ordina l'inventario; secondo click inverte (freccia ▲/▼, aria-sort). Criticita e Rilevanza ordinano per valore reale, non alfabetico. Client-side sull'inventario gia' caricato (no paginazione su assets), si combina coi filtri, accessibile da tastiera. Help aggiornato + cache-buster help.js. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
87fc5bf959
commit
ab3e88299e
@@ -1095,7 +1095,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="js/i18n.js?v=20260631"></script>
|
<script src="js/i18n.js?v=20260631"></script>
|
||||||
<script src="js/help.js?v=20260625b"></script>
|
<script src="js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
loadSidebar();
|
loadSidebar();
|
||||||
|
|||||||
@@ -167,7 +167,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth check ───────────────────────────────────────────
|
// ── Auth check ───────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
|
|||||||
+61
-12
@@ -105,6 +105,13 @@
|
|||||||
.data-table tr:last-child td { border-bottom: none; }
|
.data-table tr:last-child td { border-bottom: none; }
|
||||||
.data-table tbody tr { cursor: pointer; transition: background var(--transition-fast); }
|
.data-table tbody tr { cursor: pointer; transition: background var(--transition-fast); }
|
||||||
.data-table tbody tr:hover td { background: var(--gray-50); }
|
.data-table tbody tr:hover td { background: var(--gray-50); }
|
||||||
|
/* ── Intestazioni ordinabili (click per ordinare la lista) ── */
|
||||||
|
.data-table th.sortable-th { cursor: pointer; user-select: none; white-space: nowrap; transition: background var(--transition-fast), color var(--transition-fast); }
|
||||||
|
.data-table th.sortable-th:hover { background: var(--gray-100); color: var(--gray-700); }
|
||||||
|
.data-table th.sortable-th:focus-visible { outline: 2px solid var(--primary, #0066CC); outline-offset: -2px; }
|
||||||
|
.data-table th.sortable-th.sorted { color: var(--gray-700); }
|
||||||
|
.data-table th.sortable-th .sort-ind { font-size: 0.7rem; opacity: 0.35; margin-left: 3px; }
|
||||||
|
.data-table th.sortable-th .sort-ind.active { opacity: 1; color: var(--primary, #0066CC); }
|
||||||
|
|
||||||
/* ── Criticality Badges ─────────────────────────────────── */
|
/* ── Criticality Badges ─────────────────────────────────── */
|
||||||
.criticality-badge {
|
.criticality-badge {
|
||||||
@@ -376,7 +383,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth & Init ─────────────────────────────────────────
|
// ── Auth & Init ─────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
@@ -535,8 +542,57 @@
|
|||||||
).join('');
|
).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Ordinamento colonne (client-side, sull'inventario gia' caricato) ──
|
||||||
|
// L'inventario e' caricato per intero lato client (nessuna paginazione),
|
||||||
|
// quindi l'ordinamento sull'array e' completo e non parziale.
|
||||||
|
let lastView = [];
|
||||||
|
let sortState = { key: null, dir: 1 }; // dir: 1 = crescente, -1 = decrescente
|
||||||
|
const ASSET_COLUMNS = [
|
||||||
|
{ key: 'name', label: 'Nome', type: 'text', val: a => (a.name || '') },
|
||||||
|
{ key: 'type', label: 'Tipo', type: 'text', val: a => assetTipo(a) },
|
||||||
|
{ key: 'category', label: 'Categoria', type: 'text', val: a => (a.category || '') },
|
||||||
|
{ key: 'criticality', label: "Criticita'", type: 'num', val: a => ({ low: 1, medium: 2, high: 3, critical: 4 }[a.criticality || 'medium'] || 0) },
|
||||||
|
{ key: 'relevance', label: 'Rilevanza NIS2', type: 'num', val: a => (a.relevance_score == null ? -1 : Number(a.relevance_score)) },
|
||||||
|
{ key: 'owner', label: 'Owner', type: 'text', val: a => (a.owner_name || '') },
|
||||||
|
{ key: 'status', label: 'Stato', type: 'text', val: a => (a.status || '') }
|
||||||
|
];
|
||||||
|
|
||||||
|
function sortableTh(c) {
|
||||||
|
const active = sortState.key === c.key;
|
||||||
|
const ariaSort = active ? (sortState.dir === 1 ? 'ascending' : 'descending') : 'none';
|
||||||
|
const ind = active ? (sortState.dir === 1 ? '▲' : '▼') : '⇅';
|
||||||
|
const indClass = active ? 'sort-ind active' : 'sort-ind';
|
||||||
|
return `<th class="sortable-th${active ? ' sorted' : ''}" role="button" tabindex="0" aria-sort="${ariaSort}" `
|
||||||
|
+ `title="Ordina per ${escapeHtml(c.label)}" onclick="sortBy('${c.key}')" `
|
||||||
|
+ `onkeydown="if(event.key==='Enter'||event.key===' '){event.preventDefault();sortBy('${c.key}');}">`
|
||||||
|
+ `${escapeHtml(c.label)} <span class="${indClass}" aria-hidden="true">${ind}</span></th>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortAssetsView(assets) {
|
||||||
|
if (!sortState.key) return assets;
|
||||||
|
const col = ASSET_COLUMNS.find(c => c.key === sortState.key);
|
||||||
|
if (!col) return assets;
|
||||||
|
const copy = assets.slice();
|
||||||
|
copy.sort((a, b) => {
|
||||||
|
const va = col.val(a), vb = col.val(b);
|
||||||
|
let cmp;
|
||||||
|
if (col.type === 'num') cmp = (Number(va) - Number(vb));
|
||||||
|
else cmp = String(va).localeCompare(String(vb), 'it', { numeric: true, sensitivity: 'base' });
|
||||||
|
if (cmp === 0) return 0;
|
||||||
|
return cmp * sortState.dir;
|
||||||
|
});
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortBy(key) {
|
||||||
|
if (sortState.key === key) sortState.dir *= -1;
|
||||||
|
else { sortState.key = key; sortState.dir = 1; }
|
||||||
|
renderAssets(lastView);
|
||||||
|
}
|
||||||
|
|
||||||
function renderAssets(assets) {
|
function renderAssets(assets) {
|
||||||
const container = document.getElementById('assets-container');
|
const container = document.getElementById('assets-container');
|
||||||
|
lastView = assets || [];
|
||||||
|
|
||||||
if (!assets || assets.length === 0) {
|
if (!assets || assets.length === 0) {
|
||||||
container.innerHTML = `
|
container.innerHTML = `
|
||||||
@@ -548,23 +604,16 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sortedAssets = sortAssetsView(assets);
|
||||||
|
|
||||||
let html = `
|
let html = `
|
||||||
<table class="data-table">
|
<table class="data-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>${ASSET_COLUMNS.map(sortableTh).join('')}<th>Azioni</th></tr>
|
||||||
<th>Nome</th>
|
|
||||||
<th>Tipo</th>
|
|
||||||
<th>Categoria</th>
|
|
||||||
<th>Criticita'</th>
|
|
||||||
<th>Rilevanza NIS2</th>
|
|
||||||
<th>Owner</th>
|
|
||||||
<th>Stato</th>
|
|
||||||
<th>Azioni</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>`;
|
<tbody>`;
|
||||||
|
|
||||||
assets.forEach(asset => {
|
sortedAssets.forEach(asset => {
|
||||||
const crit = asset.criticality || 'medium';
|
const crit = asset.criticality || 'medium';
|
||||||
const st = asset.status || 'active';
|
const st = asset.status || 'active';
|
||||||
html += `
|
html += `
|
||||||
|
|||||||
@@ -156,7 +156,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -356,7 +356,7 @@
|
|||||||
<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>
|
||||||
<script src="js/common-bi.js?v=20260624f"></script>
|
<script src="js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="js/i18n.js?v=20260631"></script>
|
<script src="js/i18n.js?v=20260631"></script>
|
||||||
<script src="js/help.js?v=20260625b"></script>
|
<script src="js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
|
|
||||||
|
|||||||
@@ -188,7 +188,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script src="/js/competenze.js?v=20260617"></script>
|
<script src="/js/competenze.js?v=20260617"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -141,7 +141,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
/* Controlli periodici (control monitoring §9.1/A.8.16): controlli ricorrenti + esecuzioni (evidenza) + NC/AC. */
|
/* Controlli periodici (control monitoring §9.1/A.8.16): controlli ricorrenti + esecuzioni (evidenza) + NC/AC. */
|
||||||
|
|||||||
@@ -156,7 +156,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth check ───────────────────────────────────────────
|
// ── Auth check ───────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
|
|||||||
+1
-1
@@ -1154,7 +1154,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// La guida è accessibile anche da non autenticati (utile per onboarding)
|
// La guida è accessibile anche da non autenticati (utile per onboarding)
|
||||||
// ma se sei loggato carichi sidebar + i18n normalmente. Stessa logica
|
// ma se sei loggato carichi sidebar + i18n normalmente. Stessa logica
|
||||||
|
|||||||
@@ -364,7 +364,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth & Init ──────────────────────────────────────────────
|
// ── Auth & Init ──────────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
/*
|
/*
|
||||||
|
|||||||
+1
-1
@@ -197,7 +197,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script src="/js/isms.js?v=20260620b"></script>
|
<script src="/js/isms.js?v=20260620b"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -960,6 +960,15 @@ const HelpSystem = (function () {
|
|||||||
'Il file usa le colonne riconosciute dall\'import; re-importandolo lo <strong>scoring di rilevanza NIS2</strong> viene ricalcolato e i beni con lo stesso <code>external_ref</code> vengono aggiornati (nessun duplicato).',
|
'Il file usa le colonne riconosciute dall\'import; re-importandolo lo <strong>scoring di rilevanza NIS2</strong> viene ricalcolato e i beni con lo stesso <code>external_ref</code> vengono aggiornati (nessun duplicato).',
|
||||||
'Utile per backup, migrazioni e modifiche massive in foglio di calcolo (il file è in UTF-8, apribile direttamente in Excel).'
|
'Utile per backup, migrazioni e modifiche massive in foglio di calcolo (il file è in UTF-8, apribile direttamente in Excel).'
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: 'Ordinare la lista per colonna',
|
||||||
|
items: [
|
||||||
|
'Fai <strong>click su un\'intestazione di colonna</strong> (Nome, Tipo, Categoria, Criticità, Rilevanza NIS2, Owner, Stato) per ordinare l\'inventario in base a quella colonna.',
|
||||||
|
'Un secondo click sulla stessa colonna <strong>inverte l\'ordine</strong> (crescente ⇄ decrescente); la freccia ▲/▼ indica la direzione attiva.',
|
||||||
|
'Criticità e Rilevanza NIS2 si ordinano per <strong>valore reale</strong> (es. Critico prima di Basso, punteggio alto prima di basso), non in ordine alfabetico.',
|
||||||
|
'L\'ordinamento agisce su <strong>tutto l\'inventario caricato</strong> e si combina con i filtri Tipo/Criticità/Stato. È accessibile anche da tastiera (Tab fino all\'intestazione, poi Invio o Spazio).'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
references: [
|
references: [
|
||||||
|
|||||||
+1
-1
@@ -163,7 +163,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script src="/js/kb.js"></script>
|
<script src="/js/kb.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Gate auth + chrome come le altre pagine -bi.
|
// Gate auth + chrome come le altre pagine -bi.
|
||||||
|
|||||||
@@ -131,7 +131,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -172,7 +172,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
loadSidebar();
|
loadSidebar();
|
||||||
|
|||||||
@@ -143,7 +143,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script src="/js/organigramma.js?v=20260617"></script>
|
<script src="/js/organigramma.js?v=20260617"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -346,7 +346,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth & Init ─────────────────────────────────────────
|
// ── Auth & Init ─────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
|
|||||||
+1
-1
@@ -136,7 +136,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script src="/js/raci.js?v=20260619"></script>
|
<script src="/js/raci.js?v=20260619"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+1
-1
@@ -456,7 +456,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth & Init ─────────────────────────────────────────
|
// ── Auth & Init ─────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
|
|||||||
@@ -146,7 +146,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
/*
|
/*
|
||||||
|
|||||||
+1
-1
@@ -507,7 +507,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth & Init ──────────────────────────────────────────────
|
// ── Auth & Init ──────────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
|
|||||||
@@ -701,7 +701,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth check ───────────────────────────────────────────
|
// ── Auth check ───────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
|
|||||||
@@ -199,7 +199,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -196,7 +196,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -490,7 +490,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260621sp"></script>
|
<script src="/js/i18n.js?v=20260621sp"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth & Init ─────────────────────────────────────────
|
// ── Auth & Init ─────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
|
|||||||
@@ -305,7 +305,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth & Init ─────────────────────────────────────────
|
// ── Auth & Init ─────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version": "1.24.14", "build": "2026-06-25-v1.24.14", "date": "2026-06-25", "changelog": "Inventario beni — Aggiunto il pulsante 'Esporta': scarica l'intero inventario in CSV con le stesse colonne dell'importazione, cosi puoi salvarne una copia, modificarlo in foglio di calcolo e re-importarlo senza riformattare nulla (re-import: scoring NIS2 ricalcolato, deduplica per external_ref). Il parser di importazione ora gestisce le virgolette CSV, cosi nomi con virgola si re-importano correttamente. Risolve ticket #441."}
|
{"version": "1.24.15", "build": "2026-06-25-v1.24.15", "date": "2026-06-25", "changelog": "Inventario beni — Ora puoi ORDINARE la lista facendo click su un'intestazione di colonna (Nome, Tipo, Categoria, Criticita, Rilevanza NIS2, Owner, Stato). Un secondo click inverte l'ordine (freccia ▲/▼). Criticita e Rilevanza NIS2 si ordinano per valore reale (Critico prima di Basso, punteggio alto prima di basso), non in ordine alfabetico. L'ordinamento si combina con i filtri ed e usabile da tastiera. Risolve ticket #442."}
|
||||||
|
|||||||
@@ -220,7 +220,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260625b"></script>
|
<script src="/js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
loadSidebar();
|
loadSidebar();
|
||||||
|
|||||||
@@ -326,7 +326,7 @@
|
|||||||
<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=20260624f"></script>
|
<script src="/js/common-bi.js?v=20260624f"></script>
|
||||||
<script src="js/i18n.js?v=20260631"></script>
|
<script src="js/i18n.js?v=20260631"></script>
|
||||||
<script src="js/help.js?v=20260625b"></script>
|
<script src="js/help.js?v=20260625c"></script>
|
||||||
<script>
|
<script>
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
loadSidebar();
|
loadSidebar();
|
||||||
|
|||||||
Reference in New Issue
Block a user