[FEAT] Cruscotto Studio (frontend): companies.html vista d'insieme + menu

companies.html diventa il cruscotto dello studio consulente: barra KPI (aziende,
compliance media, scadenze in ritardo/in arrivo), griglia aziende (compliance/
rischi/incidenti + badge ritardo, clic = entra nell'azienda) e sezione "Scadenze
generali" aggregata su TUTTE le aziende ordinata per data. Una sola chiamata
api.consultantPortfolio(). Voce menu V3 "Le mie aziende" (icona briefcase) gata a
consultant/super_admin. help.js + i18n (nav.studio + companies.*) aggiornati.
Cache-buster api/topnav-v3/i18n/help ?v=20260729. version 1.25.9.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-07-29 14:49:37 +02:00
co-authored by Claude Opus 4.8
parent 2bd97a6bd8
commit 15010f7dc3
46 changed files with 404 additions and 234 deletions
+12
View File
@@ -23,6 +23,8 @@
// top-level: voce diretta (href) oppure gruppo con mega-menu (cols).
var NAV_GROUPS = [
{ label: 'Dashboard', i18n: 'nav.dashboard', icon: 'layout-dashboard', href: 'dashboard.html' },
// Voce riservata a consulenti/super_admin — gate applicato in loadTopnavV3().
{ label: 'Le mie aziende', i18n: 'nav.studio', icon: 'briefcase', href: 'companies.html', studioOnly: true },
{ label: 'Calendario', i18n: 'nav.calendar', icon: 'calendar', href: 'calendario.html' },
{
label: 'Stakeholders', icon: 'users',
@@ -220,6 +222,16 @@
'</div></nav>' +
'</header>';
// ── Gate voce "Le mie aziende": visibile solo a consulenti / super_admin ──
try {
var role = (typeof api !== 'undefined' && api.getUserRole) ? api.getUserRole() : null;
if (['consultant', 'super_admin'].indexOf(role) === -1) {
var studioLink = host.querySelector('#topnav-bar a[data-nav="companies"]');
var studioItem = studioLink && studioLink.closest('.nav-item');
if (studioItem) studioItem.remove();
}
} catch (e) { /* in caso di errore lasciamo la voce (backend gate comunque presente) */ }
// ── Riuso helper common.js (utente/avatar/ruolo + org-switcher + versione + branding + impersonate) ──
if (typeof _loadUserInfo === 'function') _loadUserInfo();
if (typeof _loadVersionFooter === 'function') _loadVersionFooter();