[FEAT] Supply chain: bottone 'Invia questionario' al fornitore (finding review CISO 🔴C)
Il backend sendQuestionnaire/questionnaire-status esisteva ma la UI non lo esponeva (guida prometteva una funzione non azionabile). Aggiunti: - bottone 'Invia questionario' in lista (azioni) e in dettaglio fornitore - funzione sendSupplierQuestionnaire (chiede email opzionale, mostra il link sq_ generato) - api.js: sendSupplierQuestionnaire + getSupplierQuestionnaireStatus Distinto 'Valuta (interna)' da 'Invia questionario' (link esterno). E2E prod: 201 + link generato. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fffee8e0bc
commit
5ff58aeceb
@ -269,7 +269,9 @@ class NIS2API {
|
||||
importAssets(data) { return this.post('/assets/import', data); } // P2 import CMDB/CSV
|
||||
getControlsMonitoring() { return this.get('/audit/controlsMonitoring'); }
|
||||
getAcnRequirements() { return this.get('/audit/acnRequirements'); } // requisiti ACN per org
|
||||
updateAcnRequirement(id, status, note) { return this.put(`/audit/acnRequirements/${id}`, { status, evidence_note: note }); } // P1 continuous control monitoring (JWT)
|
||||
updateAcnRequirement(id, status, note) { return this.put(`/audit/acnRequirements/${id}`, { status, evidence_note: note }); }
|
||||
sendSupplierQuestionnaire(id, email) { return this.post(`/supply-chain/${id}/send-questionnaire`, email ? { email } : {}); } // self-assessment fornitore (link esterno)
|
||||
getSupplierQuestionnaireStatus(id) { return this.get(`/supply-chain/${id}/questionnaire-status`); } // P1 continuous control monitoring (JWT)
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// Audit
|
||||
|
||||
@ -661,9 +661,12 @@
|
||||
<button class="btn btn-sm btn-ghost" onclick="openEditModal(${s.id})" title="Modifica">
|
||||
<svg viewBox="0 0 20 20" fill="currentColor" width="14" height="14"><path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"/></svg>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-primary" onclick="openAssessmentModal(${s.id})" title="Valuta">
|
||||
<button class="btn btn-sm btn-primary" onclick="openAssessmentModal(${s.id})" title="Valuta (interna)">
|
||||
<svg viewBox="0 0 20 20" fill="currentColor" width="14" height="14"><path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z"/><path fill-rule="evenodd" d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm9.707 5.707a1 1 0 00-1.414-1.414L9 12.586l-1.293-1.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-ghost" onclick="sendSupplierQuestionnaire(${s.id}, '${escapeHtml((s.name||'').replace(/'/g,"\\'"))}')" title="Invia questionario al fornitore">
|
||||
<svg viewBox="0 0 20 20" fill="currentColor" width="14" height="14"><path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z"/><path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>`;
|
||||
@ -1130,6 +1133,29 @@
|
||||
}
|
||||
}
|
||||
|
||||
// ── Invio questionario self-assessment al fornitore (link esterno) ──
|
||||
async function sendSupplierQuestionnaire(supplierId, supplierName) {
|
||||
const def = '';
|
||||
const email = prompt('Invia il questionario di sicurezza a "' + (supplierName || 'fornitore') +
|
||||
'".\nEmail del fornitore (lascia vuoto per usare il contatto in anagrafica):', def);
|
||||
if (email === null) return; // annullato
|
||||
try {
|
||||
const result = await api.sendSupplierQuestionnaire(supplierId, email.trim() || null);
|
||||
if (result.success) {
|
||||
const link = result.data?.link;
|
||||
showNotification('Questionario inviato' + (result.data?.sent_to ? ' a ' + result.data.sent_to : '') + '.', 'success');
|
||||
if (link) {
|
||||
// mostra anche il link generato (utile se l'email non parte / per invio manuale)
|
||||
prompt('Link del questionario (valido 30 giorni) — puoi inoltrarlo manualmente:', link);
|
||||
}
|
||||
} else {
|
||||
showNotification(result.message || 'Errore nell\'invio del questionario.', 'error');
|
||||
}
|
||||
} catch (e) {
|
||||
showNotification('Errore di connessione.', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// ── Init ────────────────────────────────────────────────
|
||||
loadSuppliers();
|
||||
</script>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user