HOMEOPERATIONSTHREE CONSOLE SOC MODEL — KB
dashboard-soc-live-three-consoles.html · Sim + API
KNOWLEDGE BASE // OPERATIONS // SOC REAL-TIME TRIAGE
SOC Real-Time Triage Console
Complete reference for using, configuring, and integrating the live SOC operations dashboard. Covers all three consoles, the action system, the API data layer, and the full build guide in a single document.
OPERATIONS SOC / NOC SIM + API READY USER GUIDE CONFIG GUIDE
FILE
dashboard-soc-live-three-consoles.html
DATA MODE
Simulated → Live API
API ENDPOINT
/api/msp/soc-dashboard
CONSOLES
3 (Operations · Triage · Automation)
REFRESH
Auto · 30s interval
01
WHAT THIS TOOL DOES

The SOC Real-Time Triage Console is a real-time MSP operations dashboard that surfaces the health of every managed platform, all active security incidents, and the full ticket queue in a single browser-based interface. It is designed for NOC/SOC engineers who need to monitor across multiple clients and platforms simultaneously without switching between vendor portals.

The dashboard auto-refreshes every 30 seconds. When a live API endpoint is reachable it augments simulated data with real values. When the API is unreachable it falls back to a realistic simulation seamlessly — the indicator in the top rail shows which mode is active.

GLOBAL LAYER
TOP RAIL — LIVE STATS BAR
Critical · Warnings · Incidents · Tickets · At Risk · Env Score — clickable; each opens the Detail Pane filtered to that category
CONSOLE 01
GLOBAL OPERATIONS
Platform health grid · KPI strip · Client overview · Ticket summary · Environment score gauge · API status · 7-day alert chart
CONSOLE 02
REAL-TIME TRIAGE
Critical alert stream · Incident feed · Category mini-counts · Ticket list with SLA coloring
CONSOLE 03
AUTOMATION & RESPONSE
Active incident context · Security actions · Network actions · Ticket actions · Automation scripts · 24h alert chart
SINGLE HTML FILE The entire dashboard — all three consoles, all charts, all actions, the detail pane, and the modal — is contained in one self-hosted HTML file. No framework, no build step, no backend server required. Chart.js is loaded from CDN.
02
ARCHITECTURE & DATA FLOW

The dashboard has two operating modes that coexist at runtime. On every refresh cycle fetchData() attempts to call the live API. If the call succeeds the response is merged into the simulated payload. If it fails the simulation runs entirely on its own. The UI is identical in both modes.

30s TICK
Auto refresh
🌐
fetchData()
GET /api/msp/soc-dashboard
buildPayload()
Simulate or merge
📊
renderAll()
All 3 consoles update
SIMULATION ENGINE

When the API is unavailable, buildPayload() generates a full realistic dataset on each refresh using randomized values seeded from four static arrays: PLATS (9 monitored platforms), CLIENTS (10 managed clients), APOOL (12 alert archetypes), and TICKET_DATA (7 ticket records). Each refresh produces new health scores, incident assignments, and alert combinations — making the dashboard appear live even without a backend.

KEY FUNCTIONS
fetchData()
Async. Calls /api/msp/soc-dashboard with an 8-second timeout. On success merges the API response into the simulated payload via Object.assign(). On failure returns pure simulation. Updates the API / SIM badge in the rail.
buildPayload()
Generates the full data object from static arrays with randomized health states. Returns platforms, clients, incidents, tickets, aggregate counts, chart data, and system health percentages.
renderAll(d)
Calls renderRail, renderC1, renderC2, renderC3, renderTicker, and updateSwitcherBadges in sequence. All five consoles and the ticker update in a single pass.
switchConsole(n)
Shows the selected console div, updates switcher tab styling, and triggers chart re-renders for the newly visible console (charts must be re-initialized when their canvas becomes visible).
runAction(title, steps)
Opens the action modal and sequentially executes a steps array — each step has a label, icon, and duration. Steps animate from waiting → running → done. In simulation mode all steps succeed.
openPane(key)
Opens the slide-in detail pane filtered to a specific category: critical, warnings, incidents, tickets, clients, or kpi. Renders filtered incident cards or platform cards depending on the key.
an(el, to)
Number animation helper. Animates the text content of a DOM element from its current value to the target over ~500ms using easeOutCubic interpolation. Used for all stat values in the rail and KPI strips.
MODEAPI STATUSBADGEDATA SOURCETICKET DATA
SimulationDown or unreachable◌ SIMbuildPayload() — randomized each refreshStatic TICKET_DATA array
Live (merged)API returns 200● APIbuildPayload() + Object.assign(json)From API if provided, else TICKET_DATA
03
TOP RAIL & GLOBAL STATS

The rail runs across the very top of the page and is always visible regardless of which console is active. It shows six live KPI values that update on every refresh cycle. Each value is clickable and opens the detail pane filtered to that category.

CRITICAL (red)
Sum of critAlerts across all nine monitored platforms. Clicking opens the detail pane showing only CRIT incidents.
WARNINGS (orange)
Sum of warnAlerts across all platforms. Clicking opens the pane filtered to WARN incidents.
INCIDENTS (blue)
Count of critical-severity active incidents in the current data payload (max 10). Clicking opens all active incidents in the detail pane.
TICKETS (cyan)
Total open ticket count from TICKET_DATA (or API). Clicking opens the full ticket list in the detail pane.
AT RISK (orange)
Count of clients whose health risk is red or yellow. Clicking opens the client list in the detail pane.
ENV SCORE
Average health score across all nine platforms (0–100). Green above 80, orange 60–79, red below 60. This is the single headline number for overall environment health.
API / SIM BADGE The ● API / ◌ SIM badge in the top-right of the rail shows whether the live API call succeeded on the last refresh. Green means real data was returned. Grey means the dashboard is running on simulation only. This is informational — both modes produce a fully functional dashboard.
04
CONSOLE 1 — GLOBAL OPERATIONS

Console 1 is the command overview. It gives a single-screen picture of every managed platform, all clients, the full ticket queue, and system-wide health metrics. Load this console during morning standups or any time leadership asks for an environment status summary.

PLATFORM HEALTH GRID

A nine-cell grid across the top of Console 1, one cell per monitored platform. Each cell shows the platform icon, name, operational status, critical alert count, and API latency. A color stripe at the top of each cell indicates health: green for Operational, orange for Degraded, red for Critical. Clicking any platform cell opens the detail pane with that platform's full status.

ALWAYS AT LEAST ONE CRITICAL The simulation engine guarantees at least one platform in Critical state on every refresh cycle. This is intentional — it keeps the dashboard realistic and ensures engineers stay alert. When wired to a live API, real status from the platform replaces this forced critical.
KPI STRIP

Seven KPI tiles below the platform grid: Malware alerts, Firewall criticals, Network down, Backup failures, Open tickets, Clients at risk, and SLA compliance percentage. Each tile shows a directional flag (▲ if above 5, — if zero). Clicking any tile opens the detail pane in kpi mode.

CLIENT OVERVIEW PANEL

All ten managed clients listed with sector, device count, alert count, health score, and a colored dot (red/yellow/green risk indicator). Clicking a client row opens its full detail in the pane including per-platform scores, patch compliance, and backup failure count.

TICKET SUMMARY & QUEUE

Open ticket count and closed-today count at the top, SLA compliance percentage (green above 95%, orange 85–94%, red below 85%), followed by the full ticket list. Each ticket row shows priority badge (P1 P2 P3 P4), subject, client, assignee, SLA status, and age. Clicking a ticket row opens its detail in the pane.

ENVIRONMENT SCORE & HEALTH BARS

A semicircular gauge in the right column shows the overall ENV score. Below it, four health bars (Security, Network, Backup, Endpoints) show the breakdown. The gauge animates on each refresh with a 1.2-second stroke transition. Color rules: green ≥85%, orange 70–84%, red below 70%.

API STATUS PANEL & 7-DAY CHART

The API status panel lists all nine platforms with their current latency in milliseconds and a color-coded status badge. The 7-day chart below shows a stacked bar chart of Critical (red), Warning (orange), and Informational (blue) alert volumes per day for the rolling week.

05
CONSOLE 2 — REAL-TIME TRIAGE

Console 2 is the active triage view. It surfaces every incoming alert and incident in real time and is the primary view for on-call engineers during an active incident. When an incident escalates from warning to critical, engineers switch to Console 2 to assess and then jump to Console 3 to respond.

CRITICAL ALERT STREAM

The left column shows a scrolling stream of active critical alerts, each with a severity badge, title, source (tool and device), timestamp, and client name. New alerts on the current refresh cycle are marked with a NEW badge. Clicking any alert item loads that incident into Console 3's context panel.

CATEGORY MINI-COUNTS

Four animated counters at the top of the left column: Malware (SentinelOne criticals), Firewall (FortiGate criticals), Network (Auvik criticals), and Backup failures. These match the values shown in Console 1's KPI strip and animate via the an() helper on every refresh.

INCIDENT FEED

The center column shows the active incident feed — up to 10 incidents combining live-injected events from the session (LIVE array) and the simulated pool. Each incident card shows severity, ID, title, detail text, device, platform, client, and timestamp. Clicking an incident card switches to Console 3 with that incident pre-loaded as context.

TICKET QUEUE

The right column shows the same ticket queue as Console 1 — all open tickets sorted by priority with SLA status coloring. P1 tickets with SLA breach are highlighted red. Use this column to cross-reference whether a P1 ticket already exists for an active incident before creating a duplicate.

06
CONSOLE 3 — AUTOMATION & RESPONSE

Console 3 is the response console. It keeps the full incident context visible on the left while exposing every available action on the right — security actions, network actions, ticket actions, and automation scripts. Engineers drive the full incident response lifecycle without leaving this view.

INCIDENT CONTEXT PANEL

The left column shows the currently active incident: severity badge, incident ID, timestamp, title, detail text, and a fields grid showing Client, Device, Platform, Ticket link (or Unlinked), Status, and Assigned engineer. Below this is the incident selector list showing up to 8 active incidents — clicking any one loads it into the context panel without leaving Console 3.

When switching from Console 2 by clicking an incident card, Console 3 pre-loads that incident automatically and calls switchConsole(3).

SECURITY ACTIONS
🔒
Isolate Endpoint
→ SentinelOne · 4-step workflow
Kill Process
→ SentinelOne · 3-step workflow
🔍
Run EDR Scan
→ Huntress · Full scan + report
🔑
Reset Credentials
→ Azure AD · Token invalidation
🛡
Block IP / Domain
→ FortiGate · Push block rule
📸
Memory Snapshot
→ SentinelOne · Hash verified
DANGER ACTIONS Actions marked with a red border (Isolate Endpoint, Kill Process, Block IP/Domain) are destructive and cannot be automatically undone. In simulation mode they complete successfully without affecting any real system. When wired to live APIs, confirm the target device and IP before executing.
NETWORK ACTIONS
Restart Device
→ Ninja RMM · Remote reboot
🔌
Disable Switch Port
→ Auvik · Port shutdown
📋
Pull Device Logs
→ Ninja RMM · Agent fetch
🔄
Bounce VPN Tunnel
→ FortiGate · Flush + re-establish
🌐
Network Topology
→ Auvik · Discovery refresh
📡
Test Connectivity
→ Ninja RMM · Ping + traceroute
TICKET ACTIONS

Six one-click ticket operations scoped to the currently active incident: Create P1 Ticket (full ConnectWise workflow), Assign to Engineer, Escalate Incident, Clear Alert, Send Client Update, and Close Ticket. These appear in a compact action-row layout with colored Run buttons matching their severity implication.

AUTOMATION SCRIPTS

Six pre-built scripts that run multi-step automated workflows: Remediation Script, Force Patch Cycle, Malware Cleanup, Emergency Backup, Bulk Password Reset, and Generate SOC Report. Each script displays its target systems and a ▶ Run button. All scripts use the same runAction() modal system as the action buttons above.

24-HOUR ALERT CHART

A stacked bar chart at the bottom of Console 3 showing critical (red) and warning (orange) alert volumes by hour over the last 24 hours. Rendered with Chart.js. The chart re-renders each time Console 3 becomes active to ensure it draws correctly after being hidden.

07
DETAIL PANE

The detail pane is a 440px slide-in panel that opens from the right side of the screen. It is triggered by clicking any stat value in the top rail, any platform cell, any client row, or any ticket row. It overlays all three consoles and can be closed by clicking outside it or pressing the close button.

openPane('critical')
Shows all incidents with CRIT severity as expanded cards. Each card has a "Load into Console 3" action.
openPane('warnings')
Shows all incidents with WARN severity.
openPane('incidents')
Shows all active incidents regardless of severity.
openPane('tickets')
Shows all open tickets as detailed cards with full fields.
openPane('clients')
Shows all managed clients with their health scores, alert counts, patch compliance, and backup status.
openPane('kpi')
Shows a KPI breakdown summary card.
08
RUN ACTION MODAL

Every action button and script in Console 3 uses the same animated modal system. When an action is triggered, a full-screen overlay appears with the action title, a list of steps, a progress bar, and step-by-step status indicators.

  • 1
    Action is triggeredby clicking a button or script. The modal opens immediately with all steps in "waiting" state.
  • 2
    Steps execute sequentially.Each step transitions waiting → running (with animated label) → ✓ done. The progress bar advances proportionally.
  • 3
    On completionthe progress bar fills to 100%, a green "✓ Completed successfully." message appears, and the Close button becomes available.

Step durations are defined in each action's steps array (e.g. {id:'a', icon:'🔒', label:'Apply isolation', dur:1300}). In simulation mode all steps always succeed. When wired to real APIs, individual step failures can be surfaced by adding error handling inside the next() closure in runAction().

ADDING NEW ACTIONS To add a new action to Console 3, add an entry to the relevant secActs, netActs, or scripts array inside renderC3(). Define icon, lbl, sub, and a fn string calling runAction("Title", [steps]). The modal handles the rest automatically.
09
ALERT TICKER

A slim 20px ticker bar runs below the console switcher. It continuously scrolls all active incidents from left to right, color-coded by severity: red for critical, orange for warning, green for informational. Each item shows the timestamp, incident title, and client name.

The ticker content is duplicated in the DOM so the scroll animation loops seamlessly. Hovering over the ticker pauses it — useful for reading a specific entry without switching consoles. The ticker updates on every refresh cycle via renderTicker(d).

10
MONITORED PLATFORMS

The dashboard monitors nine platforms across six categories. Each platform appears in the Console 1 health grid and the API status panel, and is the source of specific alert types in Consoles 2 and 3.

🖥
Ninja RMM
Endpoints
🌐
Auvik
Network
🛡
FortiGate
Firewall
SentinelOne
Security / EDR
🔍
Huntress
Threat Detection
💾
Backup
Data Protection
🎫
ConnectWise
Service Desk / PSA
📧
Email Security
Email
Azure / M365
Cloud / Identity

In simulation mode, platform health states are randomly drawn from the pool: ok · ok · ok · ok · warn · warn · crit · deg. At least one platform is always forced to Critical to ensure realistic triage conditions.

11
ALL ACTIONS REFERENCE
ACTIONCATEGORYTARGET PLATFORMSTEPSDESTRUCTIVE
Isolate EndpointSecuritySentinelOneLocate → Isolate → Snapshot → ConfirmYes
Kill ProcessSecuritySentinelOneFind → Terminate → VerifyYes
Run EDR ScanSecurityHuntressInit → Scan → Analyze → ReportNo
Reset CredentialsSecurityAzure ADAuth → Invalidate tokens → NotifyPartial
Block IP / DomainSecurityFortiGateConnect → Push rule → VerifyYes
Memory SnapshotSecuritySentinelOneCapture → Upload → Hash verifyNo
Restart DeviceNetworkNinja RMMHeartbeat → Stop services → Reboot → AwaitPartial
Disable Switch PortNetworkAuvikConnect → Disable → VerifyYes
Pull Device LogsNetworkNinja RMMConnect → Fetch → IndexNo
Bounce VPN TunnelNetworkFortiGateConnect → Flush → Re-establish → ConfirmPartial
Network TopologyNetworkAuvikTrigger discovery → Map → UpdateNo
Test ConnectivityNetworkNinja RMMPing sweep → Trace route → ReportNo
Create P1 TicketTicketConnectWiseFetch client → Populate → Submit → NotifyNo
Remediation ScriptScriptNinja RMM (all)Load → Validate → Deploy → CompletePartial
Force Patch CycleScriptNinja RMM (unpatched)Find unpatched → Queue → Push → VerifyNo
Malware CleanupScriptSentinelOneEnumerate → Remove → Harden policyPartial
Emergency BackupScriptBackup SystemsInit job → Upload → Verify integrityNo
Bulk Password ResetScriptAzure ADAuth → Enumerate → Reset all → NotifyPartial
Generate SOC ReportScriptAll platformsGather data → Security summary → Render PDF → SendNo
12
SEVERITY & PRIORITY REFERENCE
LEVELLABELCOLORTYPICAL SOURCES
CRITCriticalRedMalware detected, ransomware indicator, DC unreachable, VPN down, RAID degraded
WARNWarningOrangeBackup job failed, high CPU, switch port offline, firewall rule spike, patch compliance low, auth anomaly
INFOInformationalBlueSSL cert expiring, scheduled maintenance, policy updates
TICKET PRIORITYSLA — RESPONSESLA — RESOLVEEXAMPLE
P115 minutes4 hoursVPN down, malware isolation, DC unreachable
P21 hour8 hoursServer disk full, firewall policy mismatch
P34 hours24 hoursPrinter offline, email quarantine review
P4Next business day72 hoursNew user onboarding, routine requests

SLA status coloring in the ticket queue: breach = SLA already missed (red), warn = SLA at risk within 30 minutes (orange), ok = within SLA (green).

CONFIGURATION GUIDE
C1
PREREQUISITES

The dashboard runs in simulation mode with zero prerequisites — open the HTML file in any modern browser and it works immediately. Connecting a live API or wiring real platform actions requires the following.

Web Host or SharePoint
The file must be served over HTTP/HTTPS for the API calls to work. Opening from a local C:\ path works for simulation only — browser security policies block cross-origin fetch from file:// origins. Any static host, IIS, SharePoint document library, or CDN works.
API Backend (Optional)
A REST endpoint at /api/msp/soc-dashboard returning a JSON object. The file sends a GET with header X-Console: three-console-soc. The response is merged into the simulation using Object.assign() — you only need to return the fields you want to override, not the full payload.
Platform API Credentials
Each action that will be wired to a live system needs credentials for that platform's API: SentinelOne API token, Huntress API key, FortiGate admin credentials, Auvik API key, Ninja RMM OAuth token, Azure AD app registration (client ID + secret), ConnectWise REST API member credentials.
Text or Code Editor
VS Code or any plain-text editor to modify the static data arrays and action step functions. Do not use Word or any rich-text editor — it will corrupt the file.
WORKS IMMEDIATELY IN SIMULATION Every feature of the dashboard — all three consoles, all actions, the detail pane, the modal, the charts, and the ticker — is fully functional in simulation mode with no configuration. Start there to validate the deployment and train engineers before connecting live APIs.
C2
API INTEGRATION

The dashboard calls one endpoint on every refresh cycle. You control how much real data it injects by deciding which fields your API returns. Everything you don't return stays simulated.

ENDPOINT SPEC
REQUEST
GET /api/msp/soc-dashboard Headers: Content-Type: application/json X-Console: three-console-soc Timeout: 8000ms
RESPONSE — MINIMUM VIABLE (override only what you have)
{ "plats": [ // array of 9 platform objects { "id": "ninja", // matches PLATS[i].id "status": "ok", // ok | warn | crit | deg "score": 97, "critAlerts": 0, "warnAlerts": 2, "latency": 88, // ms "uptime": 99.97 } ], "openTix": 84, "closedToday": 23, "slaCompl": 94, "tickets": [ // optional — overrides TICKET_DATA {"p":"p1","subject":"...","client":"...","sla":"breach","age":"2h","assignee":"..."} ] }
PLATFORM IDs — EXACT MATCH REQUIRED

The platform array in the API response is matched to the static PLATS array by the id field. Use these exact IDs or the merge will not apply: ninja · auvik · forti · s1 · huntress · backup · cw · email · azure

CHANGE THE ENDPOINT URL

If your API lives at a different path, find fetchData() in the script and update the fetch URL. The path must be relative to the host serving the HTML file to avoid CORS issues.

LOCATION IN SCRIPT
async function fetchData(){ try{ var resp = await fetch('/api/msp/soc-dashboard',{ // ← change this method: 'GET', headers:{ 'Content-Type':'application/json', 'X-Console':'three-console-soc' }, signal: AbortSignal.timeout(8000) }); ... }
C3
CONFIGURE DATA ARRAYS

Four static arrays at the top of the script control the simulation engine. Update these to reflect your actual MSP environment — even in simulation mode the dashboard will then show your real clients, tools, and incident patterns.

PLATS — PLATFORM REGISTRY

Nine objects. Each needs id (API match key), name (display name), icon (emoji), and cat (category label). Add or remove platforms by editing this array — the platform grid, API status panel, and KPI strip all render from it automatically.

STRUCTURE
var PLATS = [ {id:'ninja', name:'Ninja RMM', icon:'🖥', cat:'Endpoints'}, {id:'s1', name:'SentinelOne', icon:'⚔', cat:'Security'}, // ... 7 more ];
KPI STRIP USES HARDCODED PLATFORM IDs The Malware KPI tile references id: 's1' (SentinelOne) and the Firewall tile references id: 'forti'. If you rename those platforms, update the matching plats.find(function(p){return p.id==='s1';}) references inside renderC1() and renderC2().
CLIENTS — MANAGED CLIENT ROSTER

Ten objects. Each needs name, sector, and devices. Replace with your actual client list. The simulation randomly assigns health risk states on each refresh. The detail pane pulls directly from this array when opening client detail cards.

STRUCTURE
var CLIENTS = [ {name:'Acme Manufacturing', sector:'Mfg', devices:87}, {name:'Cortex Financial', sector:'Finance', devices:112}, // ... 8 more ];
APOOL — ALERT ARCHETYPES

Twelve alert templates drawn from randomly on each refresh to generate the active incident feed. Each object defines title, sub (source description), sev (crit/warn/info), icon, detail (full explanation), device, and platform. Customize these to reflect the actual alert types your environment generates most frequently.

TICKET_DATA — STATIC TICKET QUEUE

Seven ticket objects used as the baseline ticket queue. In production, replace this with live data from your PSA via the API. Each object needs p (priority: p1–p4), subject, client, sla (ok/warn/breach), age, and assignee. This array is only used when the API does not return a tickets field.

C4
WIRE LIVE ACTIONS

All Console 3 actions currently execute as pure simulation — they animate through steps and display success but make no real API calls. Wiring a live action means replacing the simulated step durations with actual API calls inside the runAction() flow.

APPROACH: REPLACE DURATIONS WITH REAL CALLS

The cleanest approach is to add a call property to each step and extend runAction() to execute it when present. This keeps the modal animation intact and only replaces the timing simulation with real async calls.

EXTENDED STEP FORMAT
{ id: 'b', icon: '🔒', label: 'Apply isolation', dur: 1300, // fallback if call not present call: async () => { // live API call const r = await fetch('/api/sentinelone/isolate', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_TOKEN', 'Content-Type': 'application/json' }, body: JSON.stringify({ deviceId: DATA.incidents[ACTIVE_INC_IDX].device }) }); if(!r.ok) throw new Error('Isolation failed: ' + r.status); } }
CREDENTIAL SECURITY Do not hardcode API tokens directly in the HTML file if it is served publicly. Use a backend proxy endpoint on the same host that holds the credentials server-side. The dashboard calls your proxy; your proxy calls the platform API. The HTML file never sees the token.
RECOMMENDED WIRING ORDER
  • 1
    Start with read-only actions.Pull Device Logs, Run EDR Scan, Test Connectivity, and Generate SOC Report are safe to wire first — they cannot cause disruption and let you validate the API integration pattern before touching destructive actions.
  • 2
    Wire ticket creation next.Create P1 Ticket in ConnectWise is the highest-value action for most MSPs and has no security risk. Wire it to your PSA API and test against a sandbox board before going to production.
  • 3
    Wire destructive actions last.Isolate Endpoint, Kill Process, and Block IP affect live systems. Wire these after the read-only and ticket actions are validated. Add a confirmation prompt step before the destructive API call.
C5
DEPLOY & HOST

The dashboard is a single HTML file with one CDN dependency (Chart.js). It can be hosted anywhere that serves static files over HTTPS.

SharePoint Document Library
Upload the HTML file to a document library on your SharePoint site. Click the file to open it in the browser. The simulation runs fully. API calls to relative paths (e.g. /api/...) will not work from SharePoint unless you route them through an Azure Function proxy on the same domain.
IIS / Web Server
Copy the file to your web root. If you are also hosting the API on the same IIS instance, relative API paths resolve naturally and no CORS configuration is needed.
Azure Static Web Apps
Drop the file in the app root. Add Azure Functions in the /api/ folder for the backend. Azure Static Web Apps automatically routes /api/* calls to the Functions without CORS headers.
Local File (Simulation Only)
Open the file directly from disk (file://). All simulation features work. API fetch calls will be blocked by browser security policy — this is expected and the dashboard degrades gracefully to simulation mode.
CORS NOTE If your API endpoint lives on a different origin than the file host, you must configure CORS on the API to allow the origin serving the HTML file. Alternatively, route all API calls through a proxy on the same origin as the HTML file. Never use Access-Control-Allow-Origin: * on an endpoint that handles platform credentials.
FULL-SCREEN MODE The dashboard is designed for full-screen browser display on a dedicated NOC monitor. Open the file, press F11 for full-screen, then F5 to start the auto-refresh cycle. The fixed 100vh layout with overflow:hidden is intentional — it prevents the page from scrolling so the three-console layout fills the screen edge to edge at all times.
C6
VERIFY & TROUBLESHOOT

Run through this checklist after deploying to a new environment or after connecting a live API for the first time.

  • Dashboard loads and auto-populates. All three console tabs appear. The rail stats animate from — to real numbers within 2 seconds of page load.
  • Console switcher works. Clicking Console 1, 2, and 3 tabs switches the view. The active tab gets an accent underline. The badges (e.g. "2 crit") update on each switch.
  • Charts render on Console 1 and 3. If a chart appears blank after switching to a console, it means the canvas was not visible when Chart.js tried to draw it. Check that renderC3Charts() is being called inside switchConsole(3).
  • Detail pane opens from rail stats. Click each stat value in the rail. The pane should slide in from the right showing the correct filtered content. Clicking outside the pane closes it.
  • Run Action modal completes. Trigger any action in Console 3. The modal should open, step through all stages, show ✓ Completed, and offer a Close button. If a step hangs, check for a thrown error in the browser console.
  • Incident context loads on Console 3. Click an incident in Console 2. Confirm Console 3 becomes active and shows the correct incident in the context panel. Click multiple incidents in the selector list and confirm the context panel updates each time.
  • API badge shows ● API when live endpoint is available. If you have an API connected and the badge still shows ◌ SIM, open the browser console (F12) and check for the fetch error. Common causes: wrong path, CORS blocked, or 4xx/5xx response from the server.
  • Auto-refresh cycle is running. Watch the rail stats for 30 seconds. The numbers should animate to new values on each cycle. If they freeze, check that the setInterval in the init block is not being cleared by an error.
TROUBLESHOOTING QUICK REFERENCE
SYMPTOMLIKELY CAUSEFIX
Rail stats show — and never updaterenderAll() threw before completingOpen F12 Console. Find the JS error and fix the affected render function. Common cause: a .find() on PLATS returning undefined.
Charts blank on Console 1 or 3Canvas not visible when Chart.js initializedConfirm render7d() and renderC3Charts() are called after the console div becomes visible. Wrap in a setTimeout(..., 80).
Badge stays ◌ SIM with a live APIAPI returning non-200, wrong path, or CORS blockedCheck F12 Network tab for the failing request. Verify the path matches your API host. Add CORS headers if cross-origin.
Detail pane doesn't close on outside clickdimov overlay not covering the full viewportCheck that #dimov has position:fixed; inset:0; and that its click handler calls closePane().
Action modal hangs on a stepUnhandled promise rejection in a live API callWrap each call() in try/catch and update the step status to an error state before calling return.
Incident context doesn't load on Console 3DATA is null when loadIncidentContext() is calledThe first fetchData() call may not have completed. Add a guard: if(!DATA) return; at the top of loadIncidentContext().
Dashboard scrolls on the monitorBrowser zoom level not at 100%Press Ctrl+0 to reset zoom. The layout uses height:100vh; overflow:hidden — it only fills the screen at 100% zoom on a 1080p or higher display.