import { Button, Checkbox, Input, Modal, Select } from "react-daisyui"; import { useAssignNode, useClusterLayout, useClusterStatus } from "../hooks"; import { Controller, useForm, useWatch } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { AssignNodeSchema, assignNodeSchema, capacityUnits, calculateCapacity, parseCapacity, } from "../schema"; import { toast } from "sonner"; import { useQueryClient } from "@tanstack/react-query"; import { useEffect, useMemo } from "react"; import { assignNodeDialog } from "../stores"; import FormControl from "@/components/ui/form-control"; import Select2 from "@/components/ui/select"; const defaultValues: AssignNodeSchema = { nodeId: "", zone: "", capacity: 1, capacityUnit: "GB", isGateway: false, tags: [], }; const AssignNodeDialog = () => { const { isOpen, data } = assignNodeDialog.use(); const { data: cluster } = useClusterStatus(); const { data: layout } = useClusterLayout(); const queryClient = useQueryClient(); const form = useForm({ resolver: zodResolver(assignNodeSchema), defaultValues, }); const isGateway = useWatch({ control: form.control, name: "isGateway" }); const assignNode = useAssignNode({ onSuccess() { form.reset(); toast.success("Node staged for assignment!"); queryClient.invalidateQueries({ queryKey: ["status"] }); queryClient.invalidateQueries({ queryKey: ["layout"] }); assignNodeDialog.close(); }, onError(err) { toast.error(err?.message || "Unknown error"); }, }); useEffect(() => { if (data) { const isGateway = data.capacity === null; const cap = parseCapacity(data.capacity); form.reset({ ...defaultValues, ...data, capacity: cap.value, capacityUnit: cap.unit, isGateway, }); } }, [data]); const zoneList = useMemo(() => { const list = cluster?.nodes .flatMap((i) => { const role = layout?.roles.find((role) => role.id === i.id); const staged = layout?.stagedRoleChanges.find( (role) => role.id === i.id ); return staged?.zone || role?.zone || i.role?.zone; }) .filter(Boolean); return [...new Set(list)].map((zone) => ({ label: zone, value: zone, })); }, [cluster, layout]); const tagsList = useMemo(() => { const list = cluster?.nodes .flatMap((i) => { const role = layout?.roles.find((role) => role.id === i.id); const staged = layout?.stagedRoleChanges.find( (role) => role.id === i.id ); return staged?.tags || role?.tags || i.role?.tags; }) .filter(Boolean); return [...new Set(list)].map((tag) => ({ label: tag, value: tag, })); }, [cluster, layout]); const onSubmit = form.handleSubmit((values) => { const capacity = !values.isGateway ? calculateCapacity(values.capacity, values.capacityUnit) : null; const data = { id: values.nodeId, zone: values.zone, capacity, tags: values.tags, }; assignNode.mutate(data); }); return (
{ e.preventDefault(); onSubmit(e); }} > Assign Node
( field.onChange(value)} /> )} />
{!isGateway && (
} /> ( )} />
)} ( ({ label: value, value, })) : null } options={tagsList} onChange={(values) => { if (Array.isArray(values)) { field.onChange(values.map((value) => value.value)); } }} /> )} />
); }; export default AssignNodeDialog;