mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-01 10:11:27 +02:00
Add basic page to configure the alias
This commit is contained in:
@@ -2256,6 +2256,7 @@
|
||||
"requireDeviceApproval": "Require Device Approvals",
|
||||
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.",
|
||||
"sshSettings": "SSH Settings",
|
||||
"inferenceSettings": "Inference Settings",
|
||||
"sshAccess": "SSH Access",
|
||||
"rdpSettings": "RDP Settings",
|
||||
"vncSettings": "VNC Settings",
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
SettingsContainer,
|
||||
SettingsFormCell,
|
||||
SettingsFormGrid,
|
||||
SettingsSection,
|
||||
SettingsSectionBody,
|
||||
SettingsSectionDescription,
|
||||
SettingsSectionFooter,
|
||||
SettingsSectionForm,
|
||||
SettingsSectionHeader,
|
||||
SettingsSectionTitle
|
||||
} from "@app/components/Settings";
|
||||
import { Button } from "@app/components/ui/button";
|
||||
import { Form } from "@app/components/ui/form";
|
||||
import { createInferenceFormSchema } from "@app/lib/privateResourceForm";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useActionState, useMemo, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
import { PrivateResourceSitesField } from "@app/components/PrivateResourceSitesField";
|
||||
import { PrivateResourceInferenceDestinationFields } from "@app/components/PrivateResourceDestinationFields";
|
||||
import { PrivateResourcePortRanges } from "@app/components/PrivateResourcePortRanges";
|
||||
import { useSaveSiteResource } from "@app/hooks/useSaveSiteResource";
|
||||
import {
|
||||
asAnyControl,
|
||||
asAnySetValue,
|
||||
asAnyWatch
|
||||
} from "@app/lib/formControlUtils";
|
||||
import { buildSelectedSitesForResource } from "@app/lib/privateResourceUtils";
|
||||
|
||||
export default function PrivateResourceInferencePage() {
|
||||
const t = useTranslations();
|
||||
const { save, siteResource } = useSaveSiteResource();
|
||||
const [selectedSites, setSelectedSites] = useState(() =>
|
||||
buildSelectedSitesForResource(siteResource)
|
||||
);
|
||||
|
||||
const formSchema = useMemo(() => createInferenceFormSchema(t), [t]);
|
||||
type FormValues = z.infer<typeof formSchema>;
|
||||
|
||||
const form = useForm<FormValues>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
mode: "inference",
|
||||
alias: siteResource.alias ?? null
|
||||
}
|
||||
});
|
||||
|
||||
const [, formAction, saveLoading] = useActionState(async () => {
|
||||
const isValid = await form.trigger();
|
||||
if (!isValid) return;
|
||||
|
||||
const data = form.getValues();
|
||||
await save({
|
||||
mode: "inference",
|
||||
alias: data.alias
|
||||
});
|
||||
}, null);
|
||||
|
||||
return (
|
||||
<SettingsContainer>
|
||||
<SettingsSection>
|
||||
<SettingsSectionHeader>
|
||||
<SettingsSectionTitle>
|
||||
{t("hostSettings")}
|
||||
</SettingsSectionTitle>
|
||||
<SettingsSectionDescription>
|
||||
{t("editInternalResourceDialogDestinationDescription")}
|
||||
</SettingsSectionDescription>
|
||||
</SettingsSectionHeader>
|
||||
|
||||
<SettingsSectionBody>
|
||||
<SettingsSectionForm variant="half">
|
||||
<Form {...form}>
|
||||
<form
|
||||
action={formAction}
|
||||
id="private-resource-host-form"
|
||||
>
|
||||
<SettingsFormGrid>
|
||||
<SettingsFormCell span="full">
|
||||
<PrivateResourceInferenceDestinationFields
|
||||
control={asAnyControl(form.control)}
|
||||
watch={asAnyWatch(form.watch)}
|
||||
/>
|
||||
</SettingsFormCell>
|
||||
</SettingsFormGrid>
|
||||
</form>
|
||||
</Form>
|
||||
</SettingsSectionForm>
|
||||
</SettingsSectionBody>
|
||||
|
||||
<SettingsSectionFooter>
|
||||
<Button
|
||||
type="submit"
|
||||
form="private-resource-host-form"
|
||||
loading={saveLoading}
|
||||
>
|
||||
{t("saveSettings")}
|
||||
</Button>
|
||||
</SettingsSectionFooter>
|
||||
</SettingsSection>
|
||||
</SettingsContainer>
|
||||
);
|
||||
}
|
||||
@@ -52,7 +52,8 @@ export default async function PrivateResourceLayout(
|
||||
| "hostSettings"
|
||||
| "cidrSettings"
|
||||
| "httpSettings"
|
||||
| "sshSettings";
|
||||
| "sshSettings"
|
||||
| "inferenceSettings";
|
||||
|
||||
const navItems = [
|
||||
{
|
||||
|
||||
@@ -76,6 +76,37 @@ type PrivateResourceHostDestinationFieldsProps = {
|
||||
hideAlias?: boolean;
|
||||
};
|
||||
|
||||
type PrivateResourceInferenceDestinationFieldsProps = {
|
||||
control: Control<any>;
|
||||
watch: UseFormWatch<any>;
|
||||
labelPrefix?: "create" | "edit";
|
||||
hideAlias?: boolean;
|
||||
};
|
||||
|
||||
export function PrivateResourceInferenceDestinationFields({
|
||||
control,
|
||||
watch,
|
||||
labelPrefix = "edit"
|
||||
}: PrivateResourceInferenceDestinationFieldsProps) {
|
||||
const t = useTranslations();
|
||||
const destinationLabelKey =
|
||||
labelPrefix === "create"
|
||||
? "createInternalResourceDialogDestination"
|
||||
: "editInternalResourceDialogDestination";
|
||||
|
||||
return (
|
||||
<SettingsFormGrid>
|
||||
<SettingsFormCell span="half">
|
||||
<PrivateResourceAliasField
|
||||
control={control}
|
||||
watch={watch}
|
||||
labelPrefix={labelPrefix}
|
||||
/>
|
||||
</SettingsFormCell>
|
||||
</SettingsFormGrid>
|
||||
);
|
||||
}
|
||||
|
||||
export function PrivateResourceHostDestinationFields({
|
||||
control,
|
||||
watch,
|
||||
|
||||
@@ -485,6 +485,7 @@ function destinationRefine(
|
||||
const isNativeSsh = data.mode === "ssh" && data.authDaemonMode === "native";
|
||||
const trimmedDestination = data.destination?.trim();
|
||||
if (
|
||||
data.mode !== "inference" &&
|
||||
!isNativeSsh &&
|
||||
(!trimmedDestination || trimmedDestination.length < 1)
|
||||
) {
|
||||
@@ -555,6 +556,15 @@ export function createHostFormSchema(t: TranslateFn) {
|
||||
.superRefine((data, ctx) => destinationRefine(data, ctx, t));
|
||||
}
|
||||
|
||||
export function createInferenceFormSchema(t: TranslateFn) {
|
||||
return z
|
||||
.object({
|
||||
mode: z.literal("inference"),
|
||||
alias: z.string().nullish()
|
||||
})
|
||||
.superRefine((data, ctx) => destinationRefine(data, ctx, t));
|
||||
}
|
||||
|
||||
export function createCidrFormSchema(t: TranslateFn) {
|
||||
return z
|
||||
.object({
|
||||
|
||||
Reference in New Issue
Block a user