Files
next-tjwater-frontend/src/features/workbench/components/scada-alert-atmosphere.tsx
T

42 lines
2.6 KiB
TypeScript

import { createPortal } from "react-dom";
import { ArrowUpRight, TriangleAlert, X } from "lucide-react";
import { Button } from "@/shared/ui/button";
import type { ScadaAlertAtmosphereState } from "../hooks/use-scada-alert-notices";
import type { WorkbenchAlert } from "../types";
export type ScadaAlertIntensity = "soft" | "standard" | "strong";
/** Event-lifetime viewport warning with an independently dismissible visual layer. */
export function ScadaAlertAtmosphere({ atmosphere, onDismiss, onOpen, intensity = "standard" }: {
atmosphere: ScadaAlertAtmosphereState | null;
onDismiss: (id: string) => void;
onOpen: (alert: WorkbenchAlert) => void;
intensity?: ScadaAlertIntensity;
}) {
if (!atmosphere) return null;
const alert = atmosphere.alert;
return createPortal(
<div className="scada-alert-atmosphere status-tone-danger"
data-testid="scada-alert-atmosphere" data-alert-id={atmosphere.id} data-preview={atmosphere.preview} data-intensity={intensity}>
<div className="scada-alert-atmosphere-frame" aria-hidden="true" />
<div className="scada-alert-atmosphere-light" aria-hidden="true" />
<div role="status" aria-live="polite" className="scada-alert-atmosphere-notice glass-transient items-center gap-3 rounded-xl border p-3 text-foreground">
<span className="grid size-9 shrink-0 place-items-center rounded-lg bg-[var(--status-soft)] text-[var(--status-foreground)]">
<TriangleAlert size={19} aria-hidden="true" />
</span>
<div className="min-w-0 flex-1 space-y-0.5">
<p className="text-[13px] leading-5 font-semibold">{atmosphere.preview ? "爆管告警效果预览"
: (atmosphere.count ?? 1) > 1 ? `${atmosphere.count} 起爆管风险事件处理中` : "爆管风险调查中"}</p>
<p className="text-[11px] leading-4 text-[var(--ink-muted)]">{atmosphere.preview ? "持续预览 · 可在 Dev 面板模拟结束" : "持续至事件处理结束"}</p>
</div>
{alert?.conditionId ? <Button type="button" size="sm" variant="ghost" className="scada-alert-atmosphere-action h-9 shrink-0 gap-1 px-2 text-xs"
onClick={() => onOpen(alert)}>
查看调查<ArrowUpRight size={14} aria-hidden="true" />
</Button> : null}
<Button type="button" size="sm" variant="outline" className="scada-alert-atmosphere-close h-9 shrink-0 gap-1.5 px-2.5 text-xs" aria-label="关闭告警灯效" title="关闭当前视觉警告"
onClick={() => onDismiss(atmosphere.id)}><X size={14} aria-hidden="true" />关闭灯效</Button>
</div>
</div>, document.body
);
}