From 262ca8a1d01052d972c288c4341df46c1e3a5e97 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 16 Sep 2026 09:41:46 -0400 Subject: [PATCH] Add domain validation for inference mode in resource forms --- .../private/[niceId]/ai-gateway/page.tsx | 120 ++++++++------ .../public/[niceId]/general/page.tsx | 154 +++++++++++------- src/lib/privateResourceForm.ts | 7 + 3 files changed, 177 insertions(+), 104 deletions(-) diff --git a/src/app/[orgId]/settings/resources/private/[niceId]/ai-gateway/page.tsx b/src/app/[orgId]/settings/resources/private/[niceId]/ai-gateway/page.tsx index 34830cab5..2edf4f4a3 100644 --- a/src/app/[orgId]/settings/resources/private/[niceId]/ai-gateway/page.tsx +++ b/src/app/[orgId]/settings/resources/private/[niceId]/ai-gateway/page.tsx @@ -76,11 +76,13 @@ export default function PrivateResourceInferencePage() { }) ), httpConfigSubdomain: z.string().nullish(), - httpConfigDomainId: z.string().nullish(), + httpConfigDomainId: z + .string() + .min(1, { message: t("domainRequired") }), httpConfigFullDomain: z.string().nullish(), ssl: z.boolean().optional() }), - [] + [t] ); type FormValues = z.infer; @@ -103,7 +105,7 @@ export default function PrivateResourceInferencePage() { defaultValues: { providers: [], httpConfigSubdomain: siteResource.subdomain ?? null, - httpConfigDomainId: siteResource.domainId ?? null, + httpConfigDomainId: siteResource.domainId ?? "", httpConfigFullDomain: siteResource.fullDomain ?? null, ssl: siteResource.ssl ?? false } @@ -289,50 +291,74 @@ export default function PrivateResourceInferencePage() { - { - if (res === null) { - form.setValue( - "httpConfigSubdomain", - null - ); - form.setValue( - "httpConfigDomainId", - null - ); - form.setValue( - "httpConfigFullDomain", - null - ); - return; - } - form.setValue( - "httpConfigSubdomain", - res.subdomain ?? null - ); - form.setValue( - "httpConfigDomainId", - res.domainId - ); - form.setValue( - "httpConfigFullDomain", - res.fullDomain - ); - }} + ( + + { + if (res === null) { + form.setValue( + "httpConfigSubdomain", + null + ); + form.setValue( + "httpConfigDomainId", + "", + { + shouldValidate: + true + } + ); + form.setValue( + "httpConfigFullDomain", + null + ); + return; + } + form.setValue( + "httpConfigSubdomain", + res.subdomain ?? + null + ); + form.setValue( + "httpConfigDomainId", + res.domainId, + { + shouldValidate: + true + } + ); + form.setValue( + "httpConfigFullDomain", + res.fullDomain + ); + }} + /> + + + )} /> diff --git a/src/app/[orgId]/settings/resources/public/[niceId]/general/page.tsx b/src/app/[orgId]/settings/resources/public/[niceId]/general/page.tsx index 33e54a9b9..8d8537f1f 100644 --- a/src/app/[orgId]/settings/resources/public/[niceId]/general/page.tsx +++ b/src/app/[orgId]/settings/resources/public/[niceId]/general/page.tsx @@ -139,6 +139,22 @@ export default function GeneralForm() { : "Port number should not be set for HTTP resources", path: ["proxyPort"] } + ) + .refine( + (data) => { + if ( + ["http", "ssh", "rdp", "vnc", "inference"].includes( + resource.mode + ) + ) { + return !!data.domainId; + } + return true; + }, + { + message: t("domainRequired"), + path: ["domainId"] + } ); type GeneralFormValues = z.infer; @@ -434,63 +450,87 @@ export default function GeneralForm() { resource.mode ) && ( -
- { - if (res === null) { - form.setValue( - "domainId", - undefined - ); - form.setValue( - "subdomain", - undefined - ); - setResourceFullDomain( - `${resource.ssl ? "https" : "http"}://` - ); - return; - } - form.setValue( - "domainId", - res.domainId - ); - form.setValue( - "subdomain", - res.subdomain ?? - undefined - ); - setResourceFullDomain( - `${resource.ssl ? "https" : "http"}://${toUnicode(res.fullDomain)}` - ); - }} - /> -
+ ( + +
+ { + if ( + res === + null + ) { + form.setValue( + "domainId", + undefined, + { + shouldValidate: + true + } + ); + form.setValue( + "subdomain", + undefined + ); + setResourceFullDomain( + `${resource.ssl ? "https" : "http"}://` + ); + return; + } + form.setValue( + "domainId", + res.domainId, + { + shouldValidate: + true + } + ); + form.setValue( + "subdomain", + res.subdomain ?? + undefined + ); + setResourceFullDomain( + `${resource.ssl ? "https" : "http"}://${toUnicode(res.fullDomain)}` + ); + }} + /> +
+ +
+ )} + />
)} {!["tcp", "udp", "inference"].includes( diff --git a/src/lib/privateResourceForm.ts b/src/lib/privateResourceForm.ts index 669a96363..612cce4d8 100644 --- a/src/lib/privateResourceForm.ts +++ b/src/lib/privateResourceForm.ts @@ -523,6 +523,13 @@ export function createCreateFormSchema(t: TranslateFn) { }); } } + if (data.mode === "inference" && !data.httpConfigDomainId) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: t("domainRequired"), + path: ["httpConfigDomainId"] + }); + } }); }