diff --git a/apps/canvas/front/src/components/node-volume.tsx b/apps/canvas/front/src/components/node-volume.tsx
index cb42241..14d5b4c 100644
--- a/apps/canvas/front/src/components/node-volume.tsx
+++ b/apps/canvas/front/src/components/node-volume.tsx
@@ -1,126 +1,134 @@
-import { NodeRect } from './node-rect';
-import { nodeIsConnectable, nodeLabel, useStateStore, VolumeNode } from '@/lib/state';
-import { useEffect, useMemo } from 'react';
+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 { 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 { 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"),
+	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>
-    </>);
-}
\ No newline at end of file
+	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>
+		</>
+	);
+}
