[FEAT] Visura auto-fill, adesione volontaria, modulo NCR/CAPA
1. Fix auto-fill visura: mapping corretto suggested_sector e employees_range, indicatori visivi verdi sui campi auto-compilati, fatturato sempre manuale 2. Adesione volontaria: colonna voluntary_compliance, checkbox in onboarding step 5 quando not_applicable, toggle in settings, reset su ri-classificazione 3. Modulo NCR/CAPA: NonConformityController con 10 endpoint API, tabelle non_conformities + capa_actions, generazione NCR dai gap assessment, predisposizione integrazione SistemiG.agile (webhook + sync) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+44
-4
@@ -79,6 +79,11 @@
|
||||
color: var(--gray-600);
|
||||
border: 1px solid var(--gray-300);
|
||||
}
|
||||
.entity-badge.voluntary {
|
||||
background: var(--primary-bg);
|
||||
color: var(--primary);
|
||||
border: 1px solid var(--primary-light);
|
||||
}
|
||||
.plan-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -573,10 +578,14 @@
|
||||
|
||||
function renderEntityClassification(org) {
|
||||
const type = org.entity_type || 'not_applicable';
|
||||
const label = entityTypeLabels[type] || 'Non Applicabile';
|
||||
const isVoluntary = org.voluntary_compliance == 1 && type === 'not_applicable';
|
||||
const displayLabel = isVoluntary ? 'Adesione Volontaria' : (entityTypeLabels[type] || 'Non Applicabile');
|
||||
const badgeClass = isVoluntary ? 'voluntary' : type;
|
||||
|
||||
let description = '';
|
||||
if (type === 'essential') {
|
||||
if (isVoluntary) {
|
||||
description = 'L\'organizzazione ha scelto di aderire <strong>volontariamente</strong> ai requisiti della Direttiva NIS2, pur non rientrando nell\'ambito di applicazione obbligatorio. Le misure di sicurezza sono adottate su base volontaria.';
|
||||
} else if (type === 'essential') {
|
||||
description = 'L\'organizzazione rientra tra le entita\' <strong>Essenziali</strong> ai sensi della Direttiva NIS2. Soggetta a supervisione proattiva con sanzioni fino a EUR 10M o 2% del fatturato globale.';
|
||||
} else if (type === 'important') {
|
||||
description = 'L\'organizzazione rientra tra le entita\' <strong>Importanti</strong> ai sensi della Direttiva NIS2. Soggetta a supervisione reattiva con sanzioni fino a EUR 7M o 1,4% del fatturato globale.';
|
||||
@@ -584,15 +593,46 @@
|
||||
description = 'In base ai parametri attuali, l\'organizzazione <strong>non rientra</strong> nell\'ambito di applicazione della Direttiva NIS2. Si consiglia comunque di adottare le best practice di cybersecurity.';
|
||||
}
|
||||
|
||||
// Voluntary toggle (only visible for not_applicable entities)
|
||||
const voluntaryToggle = type === 'not_applicable' ? `
|
||||
<div style="margin-top:16px; padding:16px; background:var(--gray-50); border-radius:var(--border-radius); border:1px solid var(--gray-200);">
|
||||
<label style="display:flex; align-items:center; gap:10px; cursor:pointer;">
|
||||
<input type="checkbox" id="org-voluntary" ${isVoluntary ? 'checked' : ''}
|
||||
onchange="toggleVoluntaryCompliance(this.checked)"
|
||||
style="accent-color:var(--primary); width:18px; height:18px; flex-shrink:0;">
|
||||
<span style="font-size:0.875rem; font-weight:600; color:var(--gray-700);">Adesione Volontaria alla NIS2</span>
|
||||
</label>
|
||||
<p style="font-size:0.75rem; color:var(--gray-500); margin-top:6px; margin-left:28px;">
|
||||
Aderisci volontariamente ai requisiti NIS2 anche se non obbligato dalla normativa.
|
||||
</p>
|
||||
</div>` : '';
|
||||
|
||||
document.getElementById('entity-classification').innerHTML = `
|
||||
<div class="entity-badge ${type}">
|
||||
<div class="entity-badge ${badgeClass}">
|
||||
<svg viewBox="0 0 20 20" fill="currentColor" width="20" height="20"><path fill-rule="evenodd" d="M10 1.944A11.954 11.954 0 012.166 5C2.056 5.649 2 6.319 2 7c0 5.225 3.34 9.67 8 11.317C14.66 16.67 18 12.225 18 7c0-.682-.057-1.35-.166-2.001A11.954 11.954 0 0110 1.944zM11 14a1 1 0 11-2 0 1 1 0 012 0zm0-7a1 1 0 10-2 0v3a1 1 0 102 0V7z" clip-rule="evenodd"/></svg>
|
||||
Entita' ${label}
|
||||
Entita': ${displayLabel}
|
||||
</div>
|
||||
<p style="font-size:0.8125rem; color:var(--gray-600); line-height:1.6; max-width:640px;">${description}</p>
|
||||
${voluntaryToggle}
|
||||
`;
|
||||
}
|
||||
|
||||
async function toggleVoluntaryCompliance(checked) {
|
||||
if (!currentOrg) return;
|
||||
try {
|
||||
const result = await api.updateOrganization(currentOrg.id, { voluntary_compliance: checked ? 1 : 0 });
|
||||
if (result.success) {
|
||||
currentOrg.voluntary_compliance = checked ? 1 : 0;
|
||||
renderEntityClassification(currentOrg);
|
||||
showNotification(checked ? 'Adesione volontaria attivata.' : 'Adesione volontaria disattivata.', 'success');
|
||||
} else {
|
||||
showNotification(result.message || 'Errore.', 'error');
|
||||
}
|
||||
} catch (e) {
|
||||
showNotification('Errore di connessione.', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
function renderSubscriptionPlan(org) {
|
||||
const plan = org.subscription_plan || 'free';
|
||||
const planLabels = { free: 'Free', professional: 'Professional', enterprise: 'Enterprise' };
|
||||
|
||||
Reference in New Issue
Block a user