Merge branch 'feature-906/smart-host-parsing' of github.com:Pallavikumarimdb/pangolin into Pallavikumarimdb-feature-906/smart-host-parsing

This commit is contained in:
Owen
2025-08-30 15:51:15 -07:00
3 changed files with 207 additions and 152 deletions

View File

@@ -94,6 +94,7 @@ import {
CommandList
} from "@app/components/ui/command";
import { Badge } from "@app/components/ui/badge";
import { parseHostTarget } from "@app/lib/parseHostTarget";
const addTargetSchema = z.object({
ip: z.string().refine(isTargetValid),
@@ -647,13 +648,25 @@ export default function ReverseProxyTargets(props: {
<Input
defaultValue={row.original.ip}
className="min-w-[150px]"
onBlur={(e) =>
onBlur={(e) => {
const parsed = parseHostTarget(e.target.value);
if (parsed) {
updateTarget(row.original.targetId, {
...row.original,
method: parsed.protocol,
ip: parsed.host,
port: parsed.port
});
} else {
updateTarget(row.original.targetId, {
...row.original,
ip: e.target.value
})
});
}
}}
/>
)
},
{
@@ -942,11 +955,22 @@ export default function ReverseProxyTargets(props: {
name="ip"
render={({ field }) => (
<FormItem className="relative">
<FormLabel>
{t("targetAddr")}
</FormLabel>
<FormLabel>{t("targetAddr")}</FormLabel>
<FormControl>
<Input id="ip" {...field} />
<Input
id="ip"
{...field}
onBlur={(e) => {
const parsed = parseHostTarget(e.target.value);
if (parsed) {
addTargetForm.setValue("method", parsed.protocol);
addTargetForm.setValue("ip", parsed.host);
addTargetForm.setValue("port", parsed.port);
} else {
field.onBlur();
}
}}
/>
</FormControl>
<FormMessage />
</FormItem>

View File

@@ -88,6 +88,7 @@ import { ArrayElement } from "@server/types/ArrayElement";
import { isTargetValid } from "@server/lib/validators";
import { ListTargetsResponse } from "@server/routers/target";
import { DockerManager, DockerState } from "@app/lib/docker";
import { parseHostTarget } from "@app/lib/parseHostTarget";
const baseResourceFormSchema = z.object({
name: z.string().min(1).max(255),
@@ -622,12 +623,23 @@ export default function Page() {
<Input
defaultValue={row.original.ip}
className="min-w-[150px]"
onBlur={(e) =>
onBlur={(e) => {
const parsed = parseHostTarget(e.target.value);
if (parsed) {
updateTarget(row.original.targetId, {
...row.original,
ip: e.target.value
})
method: parsed.protocol,
ip: parsed.host,
port: parsed.port ? Number(parsed.port) : undefined,
});
} else {
updateTarget(row.original.targetId, {
...row.original,
ip: e.target.value,
});
}
}}
/>
)
},
@@ -1176,21 +1188,25 @@ export default function Page() {
)}
<FormField
control={
addTargetForm.control
}
control={addTargetForm.control}
name="ip"
render={({ field }) => (
<FormItem className="relative">
<FormLabel>
{t(
"targetAddr"
)}
</FormLabel>
<FormLabel>{t("targetAddr")}</FormLabel>
<FormControl>
<Input
id="ip"
{...field}
onBlur={(e) => {
const parsed = parseHostTarget(e.target.value);
if (parsed) {
addTargetForm.setValue("method", parsed.protocol);
addTargetForm.setValue("ip", parsed.host);
addTargetForm.setValue("port", parsed.port);
} else {
field.onBlur();
}
}}
/>
</FormControl>
<FormMessage />

View File

@@ -0,0 +1,15 @@
export function parseHostTarget(input: string) {
try {
const normalized = input.match(/^https?:\/\//) ? input : `http://${input}`;
const url = new URL(normalized);
const protocol = url.protocol.replace(":", ""); // http | https
const host = url.hostname;
const port = url.port ? parseInt(url.port, 10) : protocol === "https" ? 443 : 80;
return { protocol, host, port };
} catch {
return null;
}
}