8c7affc933
Fixed import paths for 43 components moved into features/ directories. Key fixes: - api/, types/, hooks/, state/, utils/ imports need ../../../ from features/*/ - components/ imports need ../../ from features/*/ - Cross-feature imports use relative paths (e.g., ../tool/tools-bottom-sheet) - app-shell.tsx updated to import from features/ subdirectories Frontend typecheck now passes except for one pre-existing error: xterm-addon-webgl missing type declarations. Quality gates: ruff passed on backend, py_compile passed on all backend files.
78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
import { useEffect, useRef, useState } from "react";
|
|
import { useEventContext } from "../../../state/events";
|
|
import {
|
|
handleEventToast,
|
|
mapEventToCategory,
|
|
mapEventToSeverity,
|
|
} from "../../toast-rules";
|
|
import { getUserConfig } from "../../../api/settings";
|
|
import type { UserConfig } from "../../../api/settings";
|
|
|
|
interface ToastConfig {
|
|
notification_toast_level: string;
|
|
notification_mute_categories: string[];
|
|
}
|
|
|
|
export function EventToastBridge(): JSX.Element | null {
|
|
const { events } = useEventContext();
|
|
const processedRef = useRef<Set<string>>(new Set());
|
|
const [config, setConfig] = useState<ToastConfig | null>(null);
|
|
|
|
useEffect(() => {
|
|
getUserConfig()
|
|
.then((c) => {
|
|
setConfig({
|
|
notification_toast_level: c.notification_toast_level ?? "all",
|
|
notification_mute_categories: c.notification_mute_categories ?? [],
|
|
});
|
|
})
|
|
.catch(() => {
|
|
setConfig({
|
|
notification_toast_level: "all",
|
|
notification_mute_categories: [],
|
|
});
|
|
});
|
|
|
|
const handler = (e: Event) => {
|
|
const detail = (e as CustomEvent<Partial<UserConfig>>).detail;
|
|
if (detail) {
|
|
setConfig((prev) => ({
|
|
notification_toast_level:
|
|
detail.notification_toast_level ??
|
|
prev?.notification_toast_level ??
|
|
"all",
|
|
notification_mute_categories:
|
|
detail.notification_mute_categories ??
|
|
prev?.notification_mute_categories ??
|
|
[],
|
|
}));
|
|
}
|
|
};
|
|
|
|
window.addEventListener("userconfig:updated", handler);
|
|
return () => window.removeEventListener("userconfig:updated", handler);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!config) return;
|
|
|
|
for (const event of events) {
|
|
const key = `${event.correlation_id}:${event.timestamp}`;
|
|
if (processedRef.current.has(key)) continue;
|
|
processedRef.current.add(key);
|
|
|
|
const category = mapEventToCategory(event);
|
|
const severity = mapEventToSeverity(event);
|
|
|
|
if (config.notification_toast_level === "none") continue;
|
|
if (config.notification_toast_level === "errors" && severity !== "error")
|
|
continue;
|
|
if (config.notification_mute_categories.includes(category)) continue;
|
|
|
|
handleEventToast(event);
|
|
}
|
|
}, [events, config]);
|
|
|
|
return null;
|
|
}
|