blob: 14d5b4cac763cec88e69e674fa2291b3fceb00fa [file] [log] [blame]
import { NodeRect } from "./node-rect";
import { nodeIsConnectable, nodeLabel, useStateStore, VolumeNode } from "@/lib/state";
import { useEffect, useMemo } from "react";
import { z } from "zod";
import { DeepPartial, EventType, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form, FormControl, FormField, FormItem, FormMessage } from "./ui/form";
import { Input } from "./ui/input";
import { Handle, Position } from "@xyflow/react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
export function NodeVolume(node: VolumeNode) {
const { id, data, selected } = node;
const isConnectable = useMemo(() => nodeIsConnectable(node, "volume"), [node]);
return (
<NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
<div style={{ padding: "10px 20px" }}>
<div>{nodeLabel(node)}</div>
<div>{data.type && `${data.type}`}</div>
<div>{data.size && `${data.size}`}</div>
<Handle
id="volume"
type={"source"}
position={Position.Top}
isConnectableStart={isConnectable}
isConnectableEnd={isConnectable}
isConnectable={isConnectable}
/>
</div>
</NodeRect>
);
}
const volumeTypes = ["ReadWriteOnce", "ReadOnlyMany", "ReadWriteMany", "ReadWriteOncePod"] as const;
const schema = z.object({
name: z.string().min(1),
type: z.enum(volumeTypes),
size: z.string().min(1).default("1Gi"),
});
export function NodeVolumeDetails({ id, data }: VolumeNode) {
const store = useStateStore();
const form = useForm<z.infer<typeof schema>>({
resolver: zodResolver(schema),
mode: "onChange",
defaultValues: {
name: "",
type: undefined,
size: "",
},
});
useEffect(() => {
const sub = form.watch(
(
value: DeepPartial<z.infer<typeof schema>>,
{ name, type }: { name?: keyof z.infer<typeof schema> | undefined; type?: EventType | undefined },
) => {
if (type !== "change") {
return;
}
console.log({ name, type, value });
store.updateNodeData<"volume">(id, {
label: value.name,
type: value.type,
size: value.size,
});
},
);
return () => sub.unsubscribe();
}, [id, form, store]);
useEffect(() => {
form.reset({
name: data.label,
type: data.type,
size: data.size,
});
}, [form, data]);
return (
<>
<Form {...form}>
<form className="space-y-2">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormControl>
<Input placeholder="name" className="border border-black" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Volume Type" />
</SelectTrigger>
</FormControl>
<SelectContent>
{volumeTypes.map((t) => (
<SelectItem key={t} value={t}>
{t}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="size"
render={({ field }) => (
<FormItem>
<FormControl>
<Input placeholder="size" className="border border-black" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</form>
</Form>
</>
);
}