blob: cb422419c7ad1d9916776ed3407ca9f1db42ceff [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>
</>);
}