blob: a0a1842b89fb14b501dcf467ac2899597777ff81 [file] [log] [blame]
gio8fad76a2025-05-22 14:01:23 +00001import { NodeType, useMode, useNodeMessages } from "@/lib/state";
gio5f2f1002025-03-20 18:38:48 +04002import { Icon } from "./icon";
gio1dc800a2025-04-24 17:15:43 +00003import { useEffect, useState } from "react";
gio5f2f1002025-03-20 18:38:48 +04004
5export type Props = {
giod0026612025-05-08 13:00:36 +00006 id: string;
7 selected?: boolean;
8 children: React.ReactNode;
9 type: NodeType;
gio818da4e2025-05-12 14:45:35 +000010 state?: string | null;
gio5f2f1002025-03-20 18:38:48 +040011};
12
13export function NodeRect(p: Props) {
giod0026612025-05-08 13:00:36 +000014 const { id, selected, children, state } = p;
gio8fad76a2025-05-22 14:01:23 +000015 const mode = useMode();
giod0026612025-05-08 13:00:36 +000016 const messages = useNodeMessages(id);
17 const hasFatal = messages.some((m) => m.type === "FATAL");
18 const hasWarning = messages.some((m) => m.type === "WARNING");
19 const [classes, setClasses] = useState<string[]>([]);
gio8fad76a2025-05-22 14:01:23 +000020 const [stateClasses, setStateClasses] = useState<string[]>([]);
giod0026612025-05-08 13:00:36 +000021 useEffect(() => {
22 const classes = ["px-4", "py-2", "rounded-md", "bg-white"];
giodc2dfcf2025-05-16 09:41:04 +000023 classes.push("border");
24 if (selected) {
25 classes.push("shadow-xl");
26 }
giod0026612025-05-08 13:00:36 +000027 if (hasFatal) {
28 classes.push("border-red-500");
29 } else if (hasWarning) {
30 classes.push("border-yellow-500");
31 } else {
32 classes.push("border-black");
33 }
giod0026612025-05-08 13:00:36 +000034 setClasses(classes);
35 const stateClasses: string[] = [];
36 if (state === "processing") {
37 stateClasses.push("bg-yellow-500");
38 stateClasses.push("animate-pulse");
39 } else if (state === "success") {
40 stateClasses.push("bg-green-500");
41 } else if (state === "failure") {
42 stateClasses.push("bg-red-500");
43 } else {
44 stateClasses.push("bg-black");
45 }
46 setStateClasses(stateClasses);
47 }, [selected, hasFatal, hasWarning, state, setClasses, setStateClasses]);
48 return (
49 <div className={classes.join(" ")}>
gio0b4002c2025-05-11 15:48:51 +000050 <div style={{ position: "absolute", top: "5px", left: "5px" }}>
51 <Icon type={p.type} />
52 </div>
gio8fad76a2025-05-22 14:01:23 +000053 {mode === "deploy" && (
54 <div
55 style={{
56 position: "absolute",
57 top: "5px",
58 right: "5px",
59 borderRadius: "50%",
60 width: "5px",
61 height: "5px",
62 }}
63 className={stateClasses.join(" ")}
64 ></div>
65 )}
giod0026612025-05-08 13:00:36 +000066 {children}
67 </div>
68 );
giof8acc612025-04-26 08:20:55 +040069}