import React, { useState, useMemo } from 'react'; const RANDOM_EVENTS = [ { event_type: "Texas Deep Freeze (Uri Pattern)", severity: "CRITICAL", description: "Unprecedented multi-day freezing temperatures causing severe grid strain and widespread generation failure.", demand_impact_pct: 25.4, grid_region: "PJM-South" }, { event_type: "Summer Heatwave (Derecho)", severity: "HIGH", description: "Prolonged 100F+ temperatures across the midwest causing massive A/C load and transmission line sagging.", demand_impact_pct: 18.2, grid_region: "PJM-West" }, { event_type: "Shoulder Month Cold Snap", severity: "MEDIUM", description: "Unexpected cold front during typical shoulder months causing unforecasted heating demand.", demand_impact_pct: 8.5, grid_region: "PJM-East" }, { event_type: "Major Transmission Outage", severity: "HIGH", description: "Failure of critical 500kV interconnect causing localized demand spikes and rerouting.", demand_impact_pct: 12.0, grid_region: "PJM-West" }, { event_type: "Industrial Shutdown", severity: "LOW", description: "Planned maintenance of major manufacturing hubs causing sudden drop in base load.", demand_impact_pct: -5.5, grid_region: "PJM-East" } ]; const SEVERITY_LEVELS = ['ALL', 'CRITICAL', 'HIGH', 'MEDIUM', 'LOW']; const SEVERITY_COLORS = { CRITICAL: 'var(--accent-rose)', HIGH: '#f97316', MEDIUM: 'var(--accent-amber)', LOW: 'var(--accent-emerald)', }; export function EventsDatabase({ events, onAddEvent, onBack }) { const [form, setForm] = useState({ event_type: '', severity: 'MEDIUM', description: '', demand_impact_pct: 0, grid_region: 'PJM-West' }); const [msg, setMsg] = useState(''); const [loading, setLoading] = useState(false); const [activeFilter, setActiveFilter] = useState('ALL'); const [searchText, setSearchText] = useState(''); // Count events per severity const severityCounts = useMemo(() => { const counts = { ALL: events.length, CRITICAL: 0, HIGH: 0, MEDIUM: 0, LOW: 0 }; events.forEach(ev => { const sev = (ev.severity || '').toUpperCase(); if (counts[sev] !== undefined) counts[sev]++; }); return counts; }, [events]); // Filter events const filteredEvents = useMemo(() => { let filtered = events; // Severity filter if (activeFilter !== 'ALL') { filtered = filtered.filter(ev => (ev.severity || '').toUpperCase() === activeFilter); } // Text search if (searchText.trim()) { const query = searchText.toLowerCase(); filtered = filtered.filter(ev => (ev.event_type || '').toLowerCase().includes(query) || (ev.description || '').toLowerCase().includes(query) || (ev.grid_region || '').toLowerCase().includes(query) ); } return filtered; }, [events, activeFilter, searchText]); function autofill() { const random = RANDOM_EVENTS[Math.floor(Math.random() * RANDOM_EVENTS.length)]; setForm(random); setMsg('Autofilled random scenario.'); } async function submit(e) { e.preventDefault(); if (!form.event_type || !form.description) return; setLoading(true); setMsg(''); try { const res = await onAddEvent(form); setMsg(res.message || 'Event embedded and added to Vector DB successfully.'); setForm({ event_type: '', severity: 'MEDIUM', description: '', demand_impact_pct: 0, grid_region: 'PJM-West' }); } catch (err) { setMsg('Failed: ' + err.message); } setLoading(false); } return (

Historical Event Database

Manage the ChromaDB vector store used by the Retrieval-Augmented Generation (RAG) node.

Inject Custom Scenario (Optional)

Embed new historical or hypothetical grid events into the database. The RAG agent will query these events if future anomalies match their pattern.

setForm({ ...form, event_type: e.target.value })} required />
setForm({ ...form, demand_impact_pct: parseFloat(e.target.value) || 0 })} />