diff --git a/ui/src/components/StaticIpv4Card.tsx b/ui/src/components/StaticIpv4Card.tsx index e2eaf2c5..c0c5d19c 100644 --- a/ui/src/components/StaticIpv4Card.tsx +++ b/ui/src/components/StaticIpv4Card.tsx @@ -2,31 +2,49 @@ import { LuPlus, LuX } from "react-icons/lu"; import { useFieldArray, useFormContext } from "react-hook-form"; import { useEffect } from "react"; import validator from "validator"; +import { cx } from "cva"; import { GridCard } from "@/components/Card"; import { Button } from "@/components/Button"; import { InputFieldWithLabel } from "@/components/InputField"; import { NetworkSettings } from "@/hooks/stores"; +import { netMaskFromCidr4 } from "@/utils/ip"; export default function StaticIpv4Card() { const formMethods = useFormContext(); - const { register, formState, watch } = formMethods; + const { register, formState, watch, setValue } = formMethods; const { fields, append, remove } = useFieldArray({ name: "ipv4_static.dns" }); - // TODO: set subnet mask if IP address is in CIDR notation - useEffect(() => { if (fields.length === 0) append(""); }, [append, fields.length]); const dns = watch("ipv4_static.dns"); + const ipv4StaticAddress = watch("ipv4_static.address"); + const hideSubnetMask = ipv4StaticAddress?.includes("/"); + useEffect(() => { + const parts = ipv4StaticAddress?.split("/", 2); + if (parts.length !== 2) return; + + const cidrNotation = parseInt(parts[1]); + if (isNaN(cidrNotation) || cidrNotation < 0 || cidrNotation > 32) return; + + const mask = netMaskFromCidr4(cidrNotation); + setValue("ipv4_static.netmask", mask); + }, [ipv4StaticAddress, setValue]); + const validate = (value: string) => { if (!validator.isIP(value)) return "Invalid IP address"; return true; }; + const validateIsIPOrCIDR4 = (value: string) => { + if (!validator.isIP(value, 4) && !validator.isIPRange(value, 4)) return "Invalid IP address or CIDR notation"; + return true; + }; + return (
@@ -35,24 +53,25 @@ export default function StaticIpv4Card() { Static IPv4 Configuration -
+
- + />}
{ + if (settings.ipv4_static?.address?.includes("/")) { + const parts = settings.ipv4_static.address.split("/"); + const cidrNotation = parseInt(parts[1]); + if (isNaN(cidrNotation) || cidrNotation < 0 || cidrNotation > 32) { + return notifications.error("Invalid CIDR notation for IPv4 address"); + } + settings.ipv4_static.netmask = netMaskFromCidr4(cidrNotation); + settings.ipv4_static.address = parts[0]; + } + send("setNetworkSettings", { settings }, async (resp) => { if ("error" in resp) { return notifications.error(