From f32b6f28f5c4b0887c3410b2dda9d40eba4cffc3 Mon Sep 17 00:00:00 2001 From: DevEnv nis2-agile Date: Wed, 17 Jun 2026 12:14:04 +0200 Subject: [PATCH] [FIX] Liste paginate: frontend leggeva result.data (oggetto {items}) come array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Causa "Errore di connessione" su Inventario (e liste analoghe): gli endpoint list usano jsonPaginated → data = {items,total,page,per_page,pages}, ma il frontend faceva `allAssets = result.data || []` e poi .filter/.forEach/.length sull'oggetto → TypeError → catch → messaggio d'errore (e stat a "--"). Allineato il consumo a jsonPaginated (come gia' faceva risks.html): - public/assets.html — Inventario (loadAssets): estrae data.items + per_page=100 - public/incidents.html — lista incidenti (renderIncidentsTable) - public/reports.html — visualizzatore Audit log (loadAuditLogs): data.items + paginazione da data.pages/page (prima usava result.pagination/total_pages inesistenti) - public/admin/organizations.html, public/admin/users.html — liste admin (data.items + paginazione da data: total/per_page/page) Tutti gli estrattori sono difensivi (gestiscono anche un eventuale array bare). Verificato: endpoint reali tornano data={items,...}; nessun consumer rotto restante (listNCRs/listFeedback non usati da pagine; /feedback/mine resta array). Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/OPEN_TICKETS.md | 2 +- public/admin/organizations.html | 3 ++- public/admin/users.html | 3 ++- public/assets.html | 5 +++-- public/incidents.html | 3 ++- public/reports.html | 12 +++++++----- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/docs/OPEN_TICKETS.md b/docs/OPEN_TICKETS.md index 37184cf..d16ec5c 100644 --- a/docs/OPEN_TICKETS.md +++ b/docs/OPEN_TICKETS.md @@ -3,4 +3,4 @@ Nessun ticket aperto. --- -_Ultimo sync: 2026-06-17 09:25:01_ +_Ultimo sync: 2026-06-17 12:10:01_ diff --git a/public/admin/organizations.html b/public/admin/organizations.html index efb710a..01c4bf5 100644 --- a/public/admin/organizations.html +++ b/public/admin/organizations.html @@ -211,7 +211,8 @@ try { const result = await api.request('GET', '/admin/organizations?page=' + page); if (result.success) { - renderOrganizations(result.data || [], result.pagination || {}); + // /admin/organizations risponde paginato: data = {items, total, page, per_page, pages}. + renderOrganizations((result.data && result.data.items) || (Array.isArray(result.data) ? result.data : []), (result.data && !Array.isArray(result.data)) ? result.data : (result.pagination || {})); } else { container.innerHTML = `
diff --git a/public/admin/users.html b/public/admin/users.html index dca48fb..b97570f 100644 --- a/public/admin/users.html +++ b/public/admin/users.html @@ -224,7 +224,8 @@ try { const result = await api.request('GET', '/admin/users?page=' + page); if (result.success) { - renderUsers(result.data || [], result.pagination || {}); + // /admin/users risponde paginato: data = {items, total, page, per_page, pages}. + renderUsers((result.data && result.data.items) || (Array.isArray(result.data) ? result.data : []), (result.data && !Array.isArray(result.data)) ? result.data : (result.pagination || {})); } else { container.innerHTML = `
diff --git a/public/assets.html b/public/assets.html index 5c7b932..be200fc 100644 --- a/public/assets.html +++ b/public/assets.html @@ -451,7 +451,7 @@ const container = document.getElementById('assets-container'); container.innerHTML = '

Caricamento inventario...

'; - const params = {}; + const params = { per_page: 100 }; const type = document.getElementById('filter-type').value; const criticality = document.getElementById('filter-criticality').value; const status = document.getElementById('filter-status').value; @@ -461,7 +461,8 @@ try { const result = await api.listAssets(params); if (result.success) { - allAssets = result.data || []; + // /assets/list risponde paginato: data = {items, total, ...}. Estrai l'array. + allAssets = (result.data && result.data.items) || (Array.isArray(result.data) ? result.data : []); const view = type ? allAssets.filter(a => a.voce_code === type) : allAssets; updateStats(view); renderAssets(view); diff --git a/public/incidents.html b/public/incidents.html index c1a325c..94c76f5 100644 --- a/public/incidents.html +++ b/public/incidents.html @@ -400,7 +400,8 @@ try { const result = await api.listIncidents(params); if (result.success) { - renderIncidentsTable(result.data || []); + // /incidents/list risponde paginato: data = {items, total, ...}. + renderIncidentsTable((result.data && result.data.items) || (Array.isArray(result.data) ? result.data : [])); } else { showNotification(result.message || 'Errore nel caricamento incidenti', 'error'); } diff --git a/public/reports.html b/public/reports.html index 1197c6e..6c9e91d 100644 --- a/public/reports.html +++ b/public/reports.html @@ -903,9 +903,11 @@ try { const result = await api.getAuditLogs({ page: auditPage, per_page: 25 }); if (result.success) { - const logs = result.data || []; - const pagination = result.pagination || {}; - auditTotalPages = pagination.total_pages || 1; + // /audit/logs risponde paginato: data = {items, total, page, per_page, pages}. + const d = result.data || {}; + const logs = Array.isArray(d) ? d : (d.items || []); + const pagination = Array.isArray(d) ? (result.pagination || {}) : d; + auditTotalPages = pagination.pages || pagination.total_pages || 1; renderAuditLogs(logs, pagination); } else { container.innerHTML = '

Errore nel caricamento

' + escapeHtml(result.message || '') + '

'; @@ -968,8 +970,8 @@ html += ''; - // Pagination - const totalPages = pagination.total_pages || 1; + // Pagination (data paginato: 'pages' = numero pagine totali) + const totalPages = pagination.pages || pagination.total_pages || 1; const currentPage = pagination.page || auditPage; html += `