Properly configure ssl and domain when creating and editing

This commit is contained in:
Owen
2026-08-06 12:20:56 -04:00
parent fb896d6c0f
commit b4d2974e19
5 changed files with 95 additions and 65 deletions
@@ -20,6 +20,7 @@ import {
type SelectedAiProvider type SelectedAiProvider
} from "@app/components/AiProvidersSelector"; } from "@app/components/AiProvidersSelector";
import DomainPicker from "@app/components/DomainPicker"; import DomainPicker from "@app/components/DomainPicker";
import { SwitchInput } from "@app/components/SwitchInput";
import { Button } from "@app/components/ui/button"; import { Button } from "@app/components/ui/button";
import { import {
Form, Form,
@@ -67,7 +68,8 @@ export default function PrivateResourceInferencePage() {
providerIds: z.array(z.number().int().positive()), providerIds: z.array(z.number().int().positive()),
httpConfigSubdomain: z.string().nullish(), httpConfigSubdomain: z.string().nullish(),
httpConfigDomainId: z.string().nullish(), httpConfigDomainId: z.string().nullish(),
httpConfigFullDomain: z.string().nullish() httpConfigFullDomain: z.string().nullish(),
ssl: z.boolean().optional()
}), }),
[] []
); );
@@ -90,7 +92,8 @@ export default function PrivateResourceInferencePage() {
providerIds: [], providerIds: [],
httpConfigSubdomain: siteResource.subdomain ?? null, httpConfigSubdomain: siteResource.subdomain ?? null,
httpConfigDomainId: siteResource.domainId ?? null, httpConfigDomainId: siteResource.domainId ?? null,
httpConfigFullDomain: siteResource.fullDomain ?? null httpConfigFullDomain: siteResource.fullDomain ?? null,
ssl: siteResource.ssl ?? false
} }
}); });
@@ -121,7 +124,8 @@ export default function PrivateResourceInferencePage() {
mode: "inference", mode: "inference",
httpConfigSubdomain: data.httpConfigSubdomain, httpConfigSubdomain: data.httpConfigSubdomain,
httpConfigDomainId: data.httpConfigDomainId, httpConfigDomainId: data.httpConfigDomainId,
httpConfigFullDomain: data.httpConfigFullDomain httpConfigFullDomain: data.httpConfigFullDomain,
ssl: data.ssl
}); });
await api.post(`/site-resource/${siteResource.id}/ai-providers`, { await api.post(`/site-resource/${siteResource.id}/ai-providers`, {
@@ -296,6 +300,33 @@ export default function PrivateResourceInferencePage() {
}} }}
/> />
</SettingsFormCell> </SettingsFormCell>
<SettingsFormCell span="half">
<FormField
control={form.control}
name="ssl"
render={({ field }) => (
<FormItem>
<FormControl>
<SwitchInput
id="private-resource-inference-ssl"
label={t(
"editInternalResourceDialogEnableSsl"
)}
description={t(
"editInternalResourceDialogEnableSslDescription"
)}
checked={
!!field.value
}
onCheckedChange={
field.onChange
}
/>
</FormControl>
</FormItem>
)}
/>
</SettingsFormCell>
</SettingsFormGrid> </SettingsFormGrid>
</form> </form>
</Form> </Form>
@@ -368,56 +368,58 @@ export default function CreatePrivateResourcePage() {
/> />
</SettingsFormCell> </SettingsFormCell>
{mode === "http" && ( {mode === "http" ||
<SettingsFormCell span="full"> (mode === "inference" && (
<FormItem> <SettingsFormCell span="full">
<DomainPicker <FormItem>
orgId={orgId} <DomainPicker
cols={2} orgId={orgId}
hideFreeDomain cols={2}
onDomainChange={(res) => { hideFreeDomain
if (!res) { onDomainChange={(
res
) => {
if (!res) {
form.setValue(
"httpConfigSubdomain",
null
);
form.setValue(
"httpConfigDomainId",
null
);
form.setValue(
"httpConfigFullDomain",
null
);
return;
}
form.setValue( form.setValue(
"httpConfigSubdomain", "httpConfigSubdomain",
null res.subdomain ??
null
); );
form.setValue( form.setValue(
"httpConfigDomainId", "httpConfigDomainId",
null res.domainId
); );
form.setValue( form.setValue(
"httpConfigFullDomain", "httpConfigFullDomain",
null res.fullDomain
); );
return; }}
} />
form.setValue( <FormMessage />
"httpConfigSubdomain", <FormDescription>
res.subdomain ?? {t(
null "resourceDomainDescription"
); )}
form.setValue( </FormDescription>
"httpConfigDomainId", </FormItem>
res.domainId </SettingsFormCell>
); ))}
form.setValue(
"httpConfigFullDomain",
res.fullDomain
);
}}
/>
<FormMessage />
<FormDescription>
{t(
"resourceDomainDescription"
)}
</FormDescription>
</FormItem>
</SettingsFormCell>
)}
{(mode === "host" || {(mode === "host" ||
mode === "inference" ||
(mode === "ssh" && !isNativeSsh)) && ( (mode === "ssh" && !isNativeSsh)) && (
<SettingsFormCell span="half"> <SettingsFormCell span="half">
<PrivateResourceAliasField <PrivateResourceAliasField
@@ -614,7 +616,7 @@ export default function CreatePrivateResourcePage() {
/> />
<SettingsSectionHeader> <SettingsSectionHeader>
<SettingsSectionTitle> <SettingsSectionTitle>
{t("sshServer")} {t("sshSettings")}
</SettingsSectionTitle> </SettingsSectionTitle>
<SettingsSectionDescription> <SettingsSectionDescription>
{t("sshServerDescription")} {t("sshServerDescription")}
+8 -2
View File
@@ -332,7 +332,7 @@ export default function PrivateResourcesTable({
}, },
{ {
accessorKey: "mode", accessorKey: "mode",
friendlyName: t("editInternalResourceDialogMode"), friendlyName: t("type"),
header: () => ( header: () => (
<ColumnFilterButton <ColumnFilterButton
options={[ options={[
@@ -351,6 +351,12 @@ export default function PrivateResourcesTable({
{ {
value: "ssh", value: "ssh",
label: t("editInternalResourceDialogModeSsh") label: t("editInternalResourceDialogModeSsh")
},
{
value: "inference",
label: t(
"editInternalResourceDialogModeInference"
)
} }
]} ]}
selectedValue={searchParams.get("mode") ?? undefined} selectedValue={searchParams.get("mode") ?? undefined}
@@ -359,7 +365,7 @@ export default function PrivateResourcesTable({
} }
searchPlaceholder={t("searchPlaceholder")} searchPlaceholder={t("searchPlaceholder")}
emptyMessage={t("emptySearchOptions")} emptyMessage={t("emptySearchOptions")}
label={t("editInternalResourceDialogMode")} label={t("type")}
className="p-3" className="p-3"
/> />
), ),
+2 -3
View File
@@ -280,7 +280,7 @@ export default function PublicResourcesTable({
}, },
{ {
accessorKey: "protocol", accessorKey: "protocol",
friendlyName: t("protocol"), friendlyName: t("type"),
enableHiding: true, enableHiding: true,
header: () => ( header: () => (
<ColumnFilterButton <ColumnFilterButton
@@ -328,7 +328,7 @@ export default function PublicResourcesTable({
} }
searchPlaceholder={t("searchPlaceholder")} searchPlaceholder={t("searchPlaceholder")}
emptyMessage={t("emptySearchOptions")} emptyMessage={t("emptySearchOptions")}
label={t("protocol")} label={t("type")}
className="p-3" className="p-3"
/> />
), ),
@@ -747,7 +747,6 @@ export default function PublicResourcesTable({
enableColumnVisibility enableColumnVisibility
columnVisibility={{ columnVisibility={{
niceId: false, niceId: false,
protocol: false,
labels: true labels: true
}} }}
stickyLeftColumn="name" stickyLeftColumn="name"
+9 -17
View File
@@ -216,16 +216,17 @@ export function buildCreateSiteResourcePayload(
}) })
}), }),
...(data.mode === "inference" && { ...(data.mode === "inference" && {
alias:
data.alias &&
typeof data.alias === "string" &&
data.alias.trim()
? data.alias
: undefined,
aiProviders: (data.providerIds ?? []).map((providerId) => ({ aiProviders: (data.providerIds ?? []).map((providerId) => ({
providerId, providerId,
modelAccessMode: "catalog" as const modelAccessMode: "catalog" as const
})) })),
ssl: data.ssl ?? false,
domainId: data.httpConfigDomainId
? data.httpConfigDomainId
: undefined,
subdomain: data.httpConfigSubdomain
? data.httpConfigSubdomain
: undefined
}), }),
...((data.mode === "host" || data.mode === "cidr") && { ...((data.mode === "host" || data.mode === "cidr") && {
tcpPortRangeString: data.tcpPortRangeString, tcpPortRangeString: data.tcpPortRangeString,
@@ -306,6 +307,7 @@ export function buildUpdateSiteResourcePayload(
data.alias.trim() data.alias.trim()
? data.alias ? data.alias
: null, : null,
ssl: data.ssl ?? false,
domainId: data.httpConfigDomainId domainId: data.httpConfigDomainId
? data.httpConfigDomainId ? data.httpConfigDomainId
: undefined, : undefined,
@@ -464,16 +466,6 @@ export function createCreateFormSchema(t: TranslateFn) {
path: ["siteIds"] path: ["siteIds"]
}); });
} }
if (data.mode === "inference") {
const trimmedAlias = data.alias?.trim();
if (!trimmedAlias) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: t("aiResourceAliasRequired"),
path: ["alias"]
});
}
}
if ( if (
data.mode !== "ssh" && data.mode !== "ssh" &&
data.mode !== "inference" && data.mode !== "inference" &&