diff --git a/src/components/resource-policy/EditPolicyRulesSectionForm.tsx b/src/components/resource-policy/EditPolicyRulesSectionForm.tsx index 13a344525..15669272b 100644 --- a/src/components/resource-policy/EditPolicyRulesSectionForm.tsx +++ b/src/components/resource-policy/EditPolicyRulesSectionForm.tsx @@ -61,6 +61,11 @@ import { import { MAJOR_ASNS } from "@server/db/asns"; import { COUNTRIES } from "@server/db/countries"; +import { + REGIONS, + getRegionNameById, + isValidRegionId +} from "@server/db/regions"; import { isValidCIDR, isValidIP, @@ -210,6 +215,8 @@ export function EditPolicyRulesSectionForm({ const [openAddRuleCountrySelect, setOpenAddRuleCountrySelect] = useState(false); const [openAddRuleAsnSelect, setOpenAddRuleAsnSelect] = useState(false); + const [openAddRuleRegionSelect, setOpenAddRuleRegionSelect] = + useState(false); const addRuleForm = useForm({ resolver: zodResolver(addRuleSchema), @@ -235,7 +242,8 @@ export function EditPolicyRulesSectionForm({ IP: "IP", CIDR: t("ipAddressRange"), COUNTRY: t("country"), - ASN: "ASN" + ASN: "ASN", + REGION: t("region") }), [t] ); @@ -309,6 +317,14 @@ export function EditPolicyRulesSectionForm({ }); return; } + if (data.match === "REGION" && !isValidRegionId(data.value)) { + toast({ + variant: "destructive", + title: t("rulesErrorInvalidRegion"), + description: t("rulesErrorInvalidRegionDescription") || "" + }); + return; + } let priority = data.priority; if (priority === undefined) { @@ -378,6 +394,8 @@ export function EditPolicyRulesSectionForm({ return t("rulesMatchCountry"); case "ASN": return "Enter an Autonomous System Number (e.g., AS15169 or 15169)"; + case "REGION": + return t("rulesMatchRegion"); } }, [t] @@ -476,7 +494,13 @@ export function EditPolicyRulesSectionForm({ defaultValue={row.original.match} disabled={readonly || row.original.fromPolicy} onValueChange={( - value: "CIDR" | "IP" | "PATH" | "COUNTRY" | "ASN" + value: + | "CIDR" + | "IP" + | "PATH" + | "COUNTRY" + | "ASN" + | "REGION" ) => updateRule(row.original.ruleId, { match: value, @@ -485,7 +509,9 @@ export function EditPolicyRulesSectionForm({ ? "US" : value === "ASN" ? "AS15169" - : row.original.value + : value === "REGION" + ? "021" + : row.original.value }) } > @@ -505,6 +531,11 @@ export function EditPolicyRulesSectionForm({ {RuleMatch.COUNTRY} )} + {isMaxmindAvailable && ( + + {RuleMatch.REGION} + + )} {isMaxmindAsnAvailable && ( {RuleMatch.ASN} @@ -666,6 +697,111 @@ export function EditPolicyRulesSectionForm({ + ) : row.original.match === "REGION" ? ( + + + + + + + + + + {t("noRegionFound")} + + {REGIONS.map((continent) => ( + + + updateRule( + row.original.ruleId, + { + value: continent.id + } + ) + } + > + + {t(continent.name)} ( + {continent.id}) + + {continent.includes.map( + (subregion) => ( + + updateRule( + row.original + .ruleId, + { + value: subregion.id + } + ) + } + > + + {t(subregion.name)}{" "} + ({subregion.id}) + + ) + )} + + ))} + + + + ) : ( )} + {isMaxmindAvailable && ( + + { + RuleMatch.REGION + } + + )} {isMaxmindAsnAvailable && ( {RuleMatch.ASN} @@ -1240,6 +1383,160 @@ export function EditPolicyRulesSectionForm({ + ) : addRuleForm.watch( + "match" + ) === "REGION" ? ( + + + + + + + + + + {t( + "noRegionFound" + )} + + {REGIONS.map( + ( + continent + ) => ( + + { + field.onChange( + continent.id + ); + setOpenAddRuleRegionSelect( + false + ); + }} + > + + {t( + continent.name + )}{" "} + ( + { + continent.id + } + ) + + {continent.includes.map( + ( + subregion + ) => ( + { + field.onChange( + subregion.id + ); + setOpenAddRuleRegionSelect( + false + ); + }} + > + + {t( + subregion.name + )}{" "} + ( + { + subregion.id + } + ) + + ) + )} + + ) + )} + + + + ) : (