Fix translation issue with targets

This commit is contained in:
Owen 2025-07-01 21:04:14 -07:00
parent 719d75f8a6
commit 1bcb027e05
No known key found for this signature in database
GPG key ID: 8271FDFFD9E0CCBD

View file

@ -128,7 +128,7 @@ export default function ReverseProxyTargets(props: {
return true; return true;
}, },
{ {
message: t('proxyErrorInvalidHeader') message: t("proxyErrorInvalidHeader")
} }
) )
}); });
@ -146,7 +146,7 @@ export default function ReverseProxyTargets(props: {
return true; return true;
}, },
{ {
message: t('proxyErrorTls') message: t("proxyErrorTls")
} }
) )
}); });
@ -203,10 +203,10 @@ export default function ReverseProxyTargets(props: {
console.error(err); console.error(err);
toast({ toast({
variant: "destructive", variant: "destructive",
title: t('targetErrorFetch'), title: t("targetErrorFetch"),
description: formatAxiosError( description: formatAxiosError(
err, err,
t('targetErrorFetchDescription') t("targetErrorFetchDescription")
) )
}); });
} finally { } finally {
@ -228,10 +228,10 @@ export default function ReverseProxyTargets(props: {
console.error(err); console.error(err);
toast({ toast({
variant: "destructive", variant: "destructive",
title: t('siteErrorFetch'), title: t("siteErrorFetch"),
description: formatAxiosError( description: formatAxiosError(
err, err,
t('siteErrorFetchDescription') t("siteErrorFetchDescription")
) )
}); });
} }
@ -251,8 +251,8 @@ export default function ReverseProxyTargets(props: {
if (isDuplicate) { if (isDuplicate) {
toast({ toast({
variant: "destructive", variant: "destructive",
title: t('targetErrorDuplicate'), title: t("targetErrorDuplicate"),
description: t('targetErrorDuplicateDescription') description: t("targetErrorDuplicateDescription")
}); });
return; return;
} }
@ -261,11 +261,23 @@ export default function ReverseProxyTargets(props: {
// make sure that the target IP is within the site subnet // make sure that the target IP is within the site subnet
const targetIp = data.ip; const targetIp = data.ip;
const subnet = site.subnet; const subnet = site.subnet;
try {
if (!isIPInSubnet(targetIp, subnet)) { if (!isIPInSubnet(targetIp, subnet)) {
toast({ toast({
variant: "destructive", variant: "destructive",
title: t('targetWireGuardErrorInvalidIp'), title: t("targetWireGuardErrorInvalidIp"),
description: t('targetWireGuardErrorInvalidIpDescription') description: t(
"targetWireGuardErrorInvalidIpDescription"
)
});
return;
}
} catch (error) {
console.error(error);
toast({
variant: "destructive",
title: t("targetWireGuardErrorInvalidIp"),
description: t("targetWireGuardErrorInvalidIpDescription")
}); });
return; return;
} }
@ -343,8 +355,8 @@ export default function ReverseProxyTargets(props: {
updateResource({ stickySession: stickySessionData.stickySession }); updateResource({ stickySession: stickySessionData.stickySession });
toast({ toast({
title: t('targetsUpdated'), title: t("targetsUpdated"),
description: t('targetsUpdatedDescription') description: t("targetsUpdatedDescription")
}); });
setTargetsToRemove([]); setTargetsToRemove([]);
@ -353,10 +365,10 @@ export default function ReverseProxyTargets(props: {
console.error(err); console.error(err);
toast({ toast({
variant: "destructive", variant: "destructive",
title: t('targetsErrorUpdate'), title: t("targetsErrorUpdate"),
description: formatAxiosError( description: formatAxiosError(
err, err,
t('targetsErrorUpdateDescription') t("targetsErrorUpdateDescription")
) )
}); });
} finally { } finally {
@ -377,17 +389,17 @@ export default function ReverseProxyTargets(props: {
tlsServerName: data.tlsServerName || null tlsServerName: data.tlsServerName || null
}); });
toast({ toast({
title: t('targetTlsUpdate'), title: t("targetTlsUpdate"),
description: t('targetTlsUpdateDescription') description: t("targetTlsUpdateDescription")
}); });
} catch (err) { } catch (err) {
console.error(err); console.error(err);
toast({ toast({
variant: "destructive", variant: "destructive",
title: t('targetErrorTlsUpdate'), title: t("targetErrorTlsUpdate"),
description: formatAxiosError( description: formatAxiosError(
err, err,
t('targetErrorTlsUpdateDescription') t("targetErrorTlsUpdateDescription")
) )
}); });
} finally { } finally {
@ -406,17 +418,17 @@ export default function ReverseProxyTargets(props: {
setHostHeader: data.setHostHeader || null setHostHeader: data.setHostHeader || null
}); });
toast({ toast({
title: t('proxyUpdated'), title: t("proxyUpdated"),
description: t('proxyUpdatedDescription') description: t("proxyUpdatedDescription")
}); });
} catch (err) { } catch (err) {
console.error(err); console.error(err);
toast({ toast({
variant: "destructive", variant: "destructive",
title: t('proxyErrorUpdate'), title: t("proxyErrorUpdate"),
description: formatAxiosError( description: formatAxiosError(
err, err,
t('proxyErrorUpdateDescription') t("proxyErrorUpdateDescription")
) )
}); });
} finally { } finally {
@ -427,7 +439,7 @@ export default function ReverseProxyTargets(props: {
const columns: ColumnDef<LocalTarget>[] = [ const columns: ColumnDef<LocalTarget>[] = [
{ {
accessorKey: "ip", accessorKey: "ip",
header: t('targetAddr'), header: t("targetAddr"),
cell: ({ row }) => ( cell: ({ row }) => (
<Input <Input
defaultValue={row.original.ip} defaultValue={row.original.ip}
@ -442,7 +454,7 @@ export default function ReverseProxyTargets(props: {
}, },
{ {
accessorKey: "port", accessorKey: "port",
header: t('targetPort'), header: t("targetPort"),
cell: ({ row }) => ( cell: ({ row }) => (
<Input <Input
type="number" type="number"
@ -476,7 +488,7 @@ export default function ReverseProxyTargets(props: {
// }, // },
{ {
accessorKey: "enabled", accessorKey: "enabled",
header: t('enabled'), header: t("enabled"),
cell: ({ row }) => ( cell: ({ row }) => (
<Switch <Switch
defaultChecked={row.original.enabled} defaultChecked={row.original.enabled}
@ -503,7 +515,7 @@ export default function ReverseProxyTargets(props: {
variant="outline" variant="outline"
onClick={() => removeTarget(row.original.targetId)} onClick={() => removeTarget(row.original.targetId)}
> >
{t('delete')} {t("delete")}
</Button> </Button>
</div> </div>
</> </>
@ -514,7 +526,7 @@ export default function ReverseProxyTargets(props: {
if (resource.http) { if (resource.http) {
const methodCol: ColumnDef<LocalTarget> = { const methodCol: ColumnDef<LocalTarget> = {
accessorKey: "method", accessorKey: "method",
header: t('method'), header: t("method"),
cell: ({ row }) => ( cell: ({ row }) => (
<Select <Select
defaultValue={row.original.method ?? ""} defaultValue={row.original.method ?? ""}
@ -561,11 +573,9 @@ export default function ReverseProxyTargets(props: {
<SettingsContainer> <SettingsContainer>
<SettingsSection> <SettingsSection>
<SettingsSectionHeader> <SettingsSectionHeader>
<SettingsSectionTitle> <SettingsSectionTitle>{t("targets")}</SettingsSectionTitle>
{t('targets')}
</SettingsSectionTitle>
<SettingsSectionDescription> <SettingsSectionDescription>
{t('targetsDescription')} {t("targetsDescription")}
</SettingsSectionDescription> </SettingsSectionDescription>
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
@ -587,8 +597,12 @@ export default function ReverseProxyTargets(props: {
<FormControl> <FormControl>
<SwitchInput <SwitchInput
id="sticky-toggle" id="sticky-toggle"
label={t('targetStickySessions')} label={t(
description={t('targetStickySessionsDescription')} "targetStickySessions"
)}
description={t(
"targetStickySessionsDescription"
)}
defaultChecked={ defaultChecked={
field.value field.value
} }
@ -619,7 +633,9 @@ export default function ReverseProxyTargets(props: {
name="method" name="method"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>{t('method')}</FormLabel> <FormLabel>
{t("method")}
</FormLabel>
<FormControl> <FormControl>
<Select <Select
value={ value={
@ -636,7 +652,11 @@ export default function ReverseProxyTargets(props: {
}} }}
> >
<SelectTrigger id="method"> <SelectTrigger id="method">
<SelectValue placeholder={t('methodSelect')} /> <SelectValue
placeholder={t(
"methodSelect"
)}
/>
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="http"> <SelectItem value="http">
@ -662,7 +682,9 @@ export default function ReverseProxyTargets(props: {
name="ip" name="ip"
render={({ field }) => ( render={({ field }) => (
<FormItem className="relative"> <FormItem className="relative">
<FormLabel>{t('targetAddr')}</FormLabel> <FormLabel>
{t("targetAddr")}
</FormLabel>
<FormControl> <FormControl>
<Input id="ip" {...field} /> <Input id="ip" {...field} />
</FormControl> </FormControl>
@ -695,7 +717,9 @@ export default function ReverseProxyTargets(props: {
name="port" name="port"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>{t('targetPort')}</FormLabel> <FormLabel>
{t("targetPort")}
</FormLabel>
<FormControl> <FormControl>
<Input <Input
id="port" id="port"
@ -714,7 +738,7 @@ export default function ReverseProxyTargets(props: {
className="mt-6" className="mt-6"
disabled={!(watchedIp && watchedPort)} disabled={!(watchedIp && watchedPort)}
> >
{t('targetSubmit')} {t("targetSubmit")}
</Button> </Button>
</div> </div>
</form> </form>
@ -758,13 +782,13 @@ export default function ReverseProxyTargets(props: {
colSpan={columns.length} colSpan={columns.length}
className="h-24 text-center" className="h-24 text-center"
> >
{t('targetNoOne')} {t("targetNoOne")}
</TableCell> </TableCell>
</TableRow> </TableRow>
)} )}
</TableBody> </TableBody>
<TableCaption> <TableCaption>
{t('targetNoOneDescription')} {t("targetNoOneDescription")}
</TableCaption> </TableCaption>
</Table> </Table>
</SettingsSectionBody> </SettingsSectionBody>
@ -775,7 +799,7 @@ export default function ReverseProxyTargets(props: {
disabled={targetsLoading} disabled={targetsLoading}
form="targets-settings-form" form="targets-settings-form"
> >
{t('targetsSubmit')} {t("targetsSubmit")}
</Button> </Button>
</SettingsSectionFooter> </SettingsSectionFooter>
</SettingsSection> </SettingsSection>
@ -785,10 +809,10 @@ export default function ReverseProxyTargets(props: {
<SettingsSection> <SettingsSection>
<SettingsSectionHeader> <SettingsSectionHeader>
<SettingsSectionTitle> <SettingsSectionTitle>
{t('targetTlsSettings')} {t("targetTlsSettings")}
</SettingsSectionTitle> </SettingsSectionTitle>
<SettingsSectionDescription> <SettingsSectionDescription>
{t('targetTlsSettingsDescription')} {t("targetTlsSettingsDescription")}
</SettingsSectionDescription> </SettingsSectionDescription>
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
@ -809,7 +833,9 @@ export default function ReverseProxyTargets(props: {
<FormControl> <FormControl>
<SwitchInput <SwitchInput
id="ssl-toggle" id="ssl-toggle"
label={t('proxyEnableSSL')} label={t(
"proxyEnableSSL"
)}
defaultChecked={ defaultChecked={
field.value field.value
} }
@ -838,7 +864,9 @@ export default function ReverseProxyTargets(props: {
className="p-0 flex items-center justify-start gap-2 w-full" className="p-0 flex items-center justify-start gap-2 w-full"
> >
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{t('targetTlsSettingsAdvanced')} {t(
"targetTlsSettingsAdvanced"
)}
</p> </p>
<div> <div>
<ChevronsUpDown className="h-4 w-4" /> <ChevronsUpDown className="h-4 w-4" />
@ -858,7 +886,9 @@ export default function ReverseProxyTargets(props: {
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel> <FormLabel>
{t('targetTlsSni')} {t(
"targetTlsSni"
)}
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input <Input
@ -866,7 +896,9 @@ export default function ReverseProxyTargets(props: {
/> />
</FormControl> </FormControl>
<FormDescription> <FormDescription>
{t('targetTlsSniDescription')} {t(
"targetTlsSniDescription"
)}
</FormDescription> </FormDescription>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -884,17 +916,17 @@ export default function ReverseProxyTargets(props: {
loading={httpsTlsLoading} loading={httpsTlsLoading}
form="tls-settings-form" form="tls-settings-form"
> >
{t('targetTlsSubmit')} {t("targetTlsSubmit")}
</Button> </Button>
</SettingsSectionFooter> </SettingsSectionFooter>
</SettingsSection> </SettingsSection>
<SettingsSection> <SettingsSection>
<SettingsSectionHeader> <SettingsSectionHeader>
<SettingsSectionTitle> <SettingsSectionTitle>
{t('proxyAdditional')} {t("proxyAdditional")}
</SettingsSectionTitle> </SettingsSectionTitle>
<SettingsSectionDescription> <SettingsSectionDescription>
{t('proxyAdditionalDescription')} {t("proxyAdditionalDescription")}
</SettingsSectionDescription> </SettingsSectionDescription>
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
@ -913,13 +945,15 @@ export default function ReverseProxyTargets(props: {
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel> <FormLabel>
{t('proxyCustomHeader')} {t("proxyCustomHeader")}
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input {...field} /> <Input {...field} />
</FormControl> </FormControl>
<FormDescription> <FormDescription>
{t('proxyCustomHeaderDescription')} {t(
"proxyCustomHeaderDescription"
)}
</FormDescription> </FormDescription>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -935,7 +969,7 @@ export default function ReverseProxyTargets(props: {
loading={proxySettingsLoading} loading={proxySettingsLoading}
form="proxy-settings-form" form="proxy-settings-form"
> >
{t('targetTlsSubmit')} {t("targetTlsSubmit")}
</Button> </Button>
</SettingsSectionFooter> </SettingsSectionFooter>
</SettingsSection> </SettingsSection>
@ -950,10 +984,8 @@ function isIPInSubnet(subnet: string, ip: string): boolean {
const [subnetIP, maskBits] = subnet.split("/"); const [subnetIP, maskBits] = subnet.split("/");
const mask = parseInt(maskBits); const mask = parseInt(maskBits);
const t = useTranslations();
if (mask < 0 || mask > 32) { if (mask < 0 || mask > 32) {
throw new Error(t('subnetMaskErrorInvalid')); throw new Error("subnetMaskErrorInvalid");
} }
// Convert IP addresses to binary numbers // Convert IP addresses to binary numbers
@ -970,17 +1002,16 @@ function isIPInSubnet(subnet: string, ip: string): boolean {
function ipToNumber(ip: string): number { function ipToNumber(ip: string): number {
// Validate IP address format // Validate IP address format
const parts = ip.split("."); const parts = ip.split(".");
const t = useTranslations();
if (parts.length !== 4) { if (parts.length !== 4) {
throw new Error(t('ipAddressErrorInvalidFormat')); throw new Error("ipAddressErrorInvalidFormat");
} }
// Convert IP octets to 32-bit number // Convert IP octets to 32-bit number
return parts.reduce((num, octet) => { return parts.reduce((num, octet) => {
const oct = parseInt(octet); const oct = parseInt(octet);
if (isNaN(oct) || oct < 0 || oct > 255) { if (isNaN(oct) || oct < 0 || oct > 255) {
throw new Error(t('ipAddressErrorInvalidOctet')); throw new Error("ipAddressErrorInvalidOctet");
} }
return (num << 8) + oct; return (num << 8) + oct;
}, 0); }, 0);