99 lines
2.5 KiB
TypeScript
99 lines
2.5 KiB
TypeScript
import clsx from "clsx";
|
|
import {useEffect, useState} from "react";
|
|
import useFlowStore from "../VisProgStores.tsx";
|
|
import {
|
|
warningSummary,
|
|
type WarningSeverity, type EditorWarning
|
|
} from "./EditorWarnings.tsx";
|
|
import styles from "./WarningSidebar.module.css";
|
|
|
|
export function WarningsSidebar() {
|
|
const warnings = useFlowStore.getState().getWarnings();
|
|
|
|
const [severityFilter, setSeverityFilter] = useState<WarningSeverity | 'ALL'>('ALL');
|
|
|
|
useEffect(() => {}, [warnings]);
|
|
const filtered = severityFilter === 'ALL'
|
|
? warnings
|
|
: warnings.filter(w => w.severity === severityFilter);
|
|
|
|
return (
|
|
<aside className={styles.warningsSidebar}>
|
|
<WarningsHeader
|
|
severityFilter={severityFilter}
|
|
onChange={setSeverityFilter}
|
|
/>
|
|
|
|
<WarningsList warnings={filtered} />
|
|
</aside>
|
|
);
|
|
}
|
|
|
|
function WarningsHeader({
|
|
severityFilter,
|
|
onChange,
|
|
}: {
|
|
severityFilter: WarningSeverity | 'ALL';
|
|
onChange: (severity: WarningSeverity | 'ALL') => void;
|
|
}) {
|
|
const summary = warningSummary();
|
|
|
|
return (
|
|
<div className={styles.warningsHeader}>
|
|
<h3>Warnings</h3>
|
|
|
|
<div className={styles.severityTabs}>
|
|
{(['ALL', 'ERROR', 'WARNING', 'INFO'] as const).map(severity => (
|
|
<button
|
|
key={severity}
|
|
className={clsx(styles.severityTab, severityFilter === severity && styles.active)}
|
|
onClick={() => onChange(severity)}
|
|
>
|
|
{severity}
|
|
{severity !== 'ALL' && (
|
|
<span className={styles.count}>
|
|
{summary[severity.toLowerCase() as keyof typeof summary]}
|
|
</span>
|
|
)}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
|
|
|
|
function WarningsList(props: { warnings: EditorWarning[] }) {
|
|
if (props.warnings.length === 0) {
|
|
return (
|
|
<div className={styles.warningsEmpty}>
|
|
No warnings!
|
|
</div>
|
|
)
|
|
}
|
|
return (
|
|
<div className={styles.warningsList}>
|
|
{props.warnings.map((warning) => (
|
|
<WarningListItem warning={warning} />
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function WarningListItem(props: { warning: EditorWarning }) {
|
|
return (
|
|
<div className={clsx(styles.warningItem, styles[`warning-item--${props.warning.severity.toLowerCase()}`],)}>
|
|
<div className={styles.description}>
|
|
{props.warning.description}
|
|
</div>
|
|
|
|
<div className={styles.meta}>
|
|
{props.warning.scope.id}
|
|
{props.warning.scope.handleId && (
|
|
<span className={styles.handle}>@{props.warning.scope.handleId}</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
} |