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 (
Manage the ChromaDB vector store used by the Retrieval-Augmented Generation (RAG) node.
Embed new historical or hypothetical grid events into the database. The RAG agent will query these events if future anomalies match their pattern.
{ev.description}