blob: da3cb35ead915ed267a42ddf0b3ad0dd1c1f1e84 [file] [log] [blame]
gio69148322025-06-19 23:16:12 +04001import { 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";
gio69148322025-06-19 23:16:12 +04004import { AppNode } from "config";
gio5f2f1002025-03-20 18:38:48 +04005
6export type Props = {
giod0026612025-05-08 13:00:36 +00007 id: string;
8 selected?: boolean;
9 children: React.ReactNode;
gio69148322025-06-19 23:16:12 +040010 node: AppNode;
gio818da4e2025-05-12 14:45:35 +000011 state?: string | null;
gio5f2f1002025-03-20 18:38:48 +040012};
13
14export function NodeRect(p: Props) {
giod0026612025-05-08 13:00:36 +000015 const { id, selected, children, state } = p;
gio8fad76a2025-05-22 14:01:23 +000016 const mode = useMode();
giod0026612025-05-08 13:00:36 +000017 const messages = useNodeMessages(id);
18 const hasFatal = messages.some((m) => m.type === "FATAL");
19 const hasWarning = messages.some((m) => m.type === "WARNING");
20 const [classes, setClasses] = useState<string[]>([]);
gio8fad76a2025-05-22 14:01:23 +000021 const [stateClasses, setStateClasses] = useState<string[]>([]);
giod0026612025-05-08 13:00:36 +000022 useEffect(() => {
23 const classes = ["px-4", "py-2", "rounded-md", "bg-white"];
giodc2dfcf2025-05-16 09:41:04 +000024 classes.push("border");
25 if (selected) {
26 classes.push("shadow-xl");
27 }
giod0026612025-05-08 13:00:36 +000028 if (hasFatal) {
29 classes.push("border-red-500");
30 } else if (hasWarning) {
31 classes.push("border-yellow-500");
32 } else {
33 classes.push("border-black");
34 }
giod0026612025-05-08 13:00:36 +000035 setClasses(classes);
36 const stateClasses: string[] = [];
37 if (state === "processing") {
38 stateClasses.push("bg-yellow-500");
39 stateClasses.push("animate-pulse");
40 } else if (state === "success") {
41 stateClasses.push("bg-green-500");
42 } else if (state === "failure") {
43 stateClasses.push("bg-red-500");
44 } else {
45 stateClasses.push("bg-black");
46 }
47 setStateClasses(stateClasses);
48 }, [selected, hasFatal, hasWarning, state, setClasses, setStateClasses]);
49 return (
50 <div className={classes.join(" ")}>
gio0b4002c2025-05-11 15:48:51 +000051 <div style={{ position: "absolute", top: "5px", left: "5px" }}>
gio69148322025-06-19 23:16:12 +040052 <Icon node={p.node} />
gio0b4002c2025-05-11 15:48:51 +000053 </div>
gio8fad76a2025-05-22 14:01:23 +000054 {mode === "deploy" && (
55 <div
56 style={{
57 position: "absolute",
58 top: "5px",
59 right: "5px",
60 borderRadius: "50%",
61 width: "5px",
62 height: "5px",
63 }}
64 className={stateClasses.join(" ")}
65 ></div>
66 )}
giod0026612025-05-08 13:00:36 +000067 {children}
68 </div>
69 );
giof8acc612025-04-26 08:20:55 +040070}