import {useReactFlow, useStoreApi} from "@xyflow/react"; import clsx from "clsx"; import {useEffect, useState} from "react"; import useFlowStore from "../VisProgStores.tsx"; import { warningSummary, type WarningSeverity, type EditorWarning, globalWarning } from "./EditorWarnings.tsx"; import styles from "./WarningSidebar.module.css"; export function WarningsSidebar() { const warnings = useFlowStore.getState().getWarnings(); const [severityFilter, setSeverityFilter] = useState('ALL'); useEffect(() => {}, [warnings]); const filtered = severityFilter === 'ALL' ? warnings : warnings.filter(w => w.severity === severityFilter); return ( ); } function WarningsHeader({ severityFilter, onChange, }: { severityFilter: WarningSeverity | 'ALL'; onChange: (severity: WarningSeverity | 'ALL') => void; }) { const summary = warningSummary(); return (

Warnings

{(['ALL', 'ERROR', 'WARNING', 'INFO'] as const).map(severity => ( ))}
); } function WarningsList(props: { warnings: EditorWarning[] }) { const splitWarnings = { global: props.warnings.filter(w => w.scope.id === globalWarning), other: props.warnings.filter(w => w.scope.id !== globalWarning), } if (props.warnings.length === 0) { return (
No warnings!
) } if (splitWarnings.global.length === 0) { return (
global:
No global warnings!
other:
{splitWarnings.other.map((warning) => ( ))}
); } return (
global:
{splitWarnings.global.map((warning) => ( ))}
other:
{splitWarnings.other.map((warning) => ( ))}
); } function WarningListItem(props: { warning: EditorWarning }) { const jumpToNode = useJumpToNode(); return (
jumpToNode(props.warning.scope.id)} >
{props.warning.description}
{props.warning.scope.id} {props.warning.scope.handleId && ( @{props.warning.scope.handleId} )}
); } function useJumpToNode() { const { getNode, setCenter } = useReactFlow(); const { addSelectedNodes } = useStoreApi().getState(); return (nodeId: string) => { // user can't jump to global warning, so prevent further logic from running if (nodeId === globalWarning) return; const node = getNode(nodeId); if (!node) return; const { position, width = 0, height = 0} = node; // move to node setCenter( position!.x + width / 2, position!.y + height / 2, { zoom: 2, duration: 300 } ).then(() => { // select the node addSelectedNodes([nodeId]); }); }; }