IT Risk Dashboard
Overall Risk Score
0
Open Risks
0
High-Impact Risks
0
Overdue Mitigations
0
Risk Matrix
Open Risks by Category
Risk Register
| ID | Risk Description | Category | Impact | Likelihood | Owner | Status |
|---|
Log a New IT Risk
All Logged Risks
| ID | Description | Status | Action |
|---|
Error: A required library is missing.
'; return; } // --- DATA MANAGEMENT --- let risks = JSON.parse(localStorage.getItem('itr_risks')) || []; const getSampleData = () => [ { id: 'R001', desc: 'Single point of failure in primary datacenter power supply.', category: 'Infrastructure', impact: 'Critical', likelihood: 'Low', owner: 'J. Smith', status: 'Mitigating' }, { id: 'R002', desc: 'Phishing attack targeting finance department credentials.', category: 'Cybersecurity', impact: 'High', likelihood: 'Medium', owner: 'S. Davis', status: 'Open' }, { id: 'R003', desc: 'Key software vendor (CRM) may not be GDPR compliant.', category: 'Compliance', impact: 'High', likelihood: 'Medium', owner: 'E. White', status: 'Open' }, { id: 'R004', desc: 'Outdated server OS no longer receiving security patches.', category: 'Infrastructure', impact: 'High', likelihood: 'High', owner: 'J. Smith', status: 'Mitigating' }, { id: 'R005', desc: 'Insider threat from disgruntled employee.', category: 'Cybersecurity', impact: 'Critical', likelihood: 'Low', owner: 'M. Chen', status: 'Accepted' }, { id: 'R006', desc: 'Lack of disaster recovery plan for customer database.', category: 'Operational', impact: 'High', likelihood: 'Low', owner: 'J. Smith', status: 'Open' }, { id: 'R007', desc: 'Third-party API for shipping quotes is unreliable.', category: 'Operational', impact: 'Medium', likelihood: 'High', owner: 'M. Chen', status: 'Closed' }, ]; if (risks.length === 0) risks = getSampleData(); const saveState = () => localStorage.setItem('itr_risks', JSON.stringify(risks)); // --- CHART INSTANCES & UTILITIES --- let riskMatrixChart, categoryChart; const tabButtons = document.querySelectorAll('.itr-tab-button'); const tabContents = document.querySelectorAll('.itr-tab-content'); const nextBtn = document.getElementById('itr-next-btn'); const prevBtn = document.getElementById('itr-prev-btn'); const IMPACT_MAP = { 'Low': 1, 'Medium': 2, 'High': 3, 'Critical': 4 }; const LIKELIHOOD_MAP = { 'Low': 1, 'Medium': 2, 'High': 3, 'Very High': 4 }; // --- RENDER FUNCTIONS --- const renderAll = () => { try { const openRisks = risks.filter(r => r.status !== 'Closed'); renderKPIs(openRisks); renderRiskMatrix(openRisks); renderCategoryChart(openRisks); renderRiskTable(openRisks); renderManageTable(); updateNavButtons(); } catch(error) { console.error("Dashboard rendering failed:", error); } }; const renderKPIs = (data) => { const riskScores = data.map(r => IMPACT_MAP[r.impact] * LIKELIHOOD_MAP[r.likelihood]); const avgRiskScore = data.length > 0 ? riskScores.reduce((s,v) => s+v, 0) / data.length : 0; document.getElementById('itr-risk-score-kpi').textContent = avgRiskScore.toFixed(1); document.getElementById('itr-open-risks-kpi').textContent = data.length; document.getElementById('itr-high-impact-kpi').textContent = data.filter(r => r.impact === 'High' || r.impact === 'Critical').length; document.getElementById('itr-overdue-kpi').textContent = '2'; // Static for demo }; const renderRiskMatrix = (data) => { const seriesData = Object.keys(LIKELIHOOD_MAP).map(lh => { const counts = Object.keys(IMPACT_MAP).map(im => { return data.filter(r => r.likelihood === lh && r.impact === im).length; }); return { name: lh, data: counts }; }); const options = { chart: { type: 'heatmap', height: 350 }, series: seriesData, xaxis: { categories: Object.keys(IMPACT_MAP), title: { text: 'Impact' } }, yaxis: { title: { text: 'Likelihood' } }, plotOptions: { heatmap: { colorScale: { ranges: [ { from: 0, to: 0, name: 'None', color: '#f0f0f0' }, { from: 1, to: 2, name: 'Low', color: '#27ae60' }, { from: 3, to: 4, name: 'Medium', color: '#f39c12' }, { from: 5, to: 20, name: 'High', color: '#c0392b' } ] } } }, dataLabels: { enabled: true } }; if(riskMatrixChart) riskMatrixChart.destroy(); document.querySelector("#itr-risk-matrix-chart").innerHTML = ''; riskMatrixChart = new ApexCharts(document.querySelector("#itr-risk-matrix-chart"), options); riskMatrixChart.render(); }; const renderCategoryChart = (data) => { const byCategory = data.reduce((acc, r) => { acc[r.category] = (acc[r.category] || 0) + 1; return acc; }, {}); const options = { chart: { type: 'donut', height: 350 }, series: Object.values(byCategory), labels: Object.keys(byCategory), legend: { position: 'bottom' } }; if(categoryChart) categoryChart.destroy(); document.querySelector("#itr-category-chart").innerHTML = ''; categoryChart = new ApexCharts(document.querySelector("#itr-category-chart"), options); categoryChart.render(); }; const renderRiskTable = (data) => { const tbody = document.getElementById('itr-risk-tbody'); tbody.innerHTML = ''; data.sort((a,b) => (IMPACT_MAP[b.impact] * LIKELIHOOD_MAP[b.likelihood]) - (IMPACT_MAP[a.impact] * LIKELIHOOD_MAP[a.likelihood])) .forEach(r => { tbody.innerHTML += `