fix(i18n): hardkodierte Strings in DNS/RoutingRules/Settings/Backends bereinigen

- DNS Settings: Loopback/allIPv4/allIPv6 Interface-Labels in t() überführt
- RoutingRules: UP/DOWN-Tags + fehlende onError-Handler in create/update
- Settings: t-Variable-Shadowing in top_tables-Map behoben (t → tbl)
- Backends: 'Live'-Spaltenheader → t('backends.server.live')
- common.up/down + dns.settings.allIPv4/allIPv6/loopback in en+de ergänzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-24 12:30:43 +02:00
parent e04bddd574
commit 519522b8ee
10 changed files with 30 additions and 16 deletions

View File

@@ -1 +1 @@
1.1.80 1.1.81

View File

@@ -60,7 +60,7 @@ import (
usersvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/users" usersvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/users"
) )
var version = "1.1.80" var version = "1.1.81"
func main() { func main() {
addr := os.Getenv("EDGEGUARD_API_ADDR") addr := os.Getenv("EDGEGUARD_API_ADDR")

View File

@@ -11,7 +11,7 @@ import (
"git.netcell-it.de/projekte/edgeguard-native/internal/services/setup" "git.netcell-it.de/projekte/edgeguard-native/internal/services/setup"
) )
var version = "1.1.80" var version = "1.1.81"
const usage = `edgeguard-ctl — EdgeGuard CLI const usage = `edgeguard-ctl — EdgeGuard CLI

View File

@@ -35,7 +35,7 @@ import (
"git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts" "git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts"
) )
var version = "1.1.80" var version = "1.1.81"
const ( const (
// renewTickInterval — how often we re-evaluate expiring certs. // renewTickInterval — how often we re-evaluate expiring certs.

View File

@@ -367,7 +367,8 @@
"backup": "Backup", "backup": "Backup",
"backupHint": "Backup-Server werden nur angesprochen, wenn alle primären Server (non-backup) down sind.", "backupHint": "Backup-Server werden nur angesprochen, wenn alle primären Server (non-backup) down sind.",
"empty": "Noch keine Server im Pool. „Server hinzufügen\" startet damit.", "empty": "Noch keine Server im Pool. „Server hinzufügen\" startet damit.",
"deleteConfirm": "Server {{name}} wirklich löschen?" "deleteConfirm": "Server {{name}} wirklich löschen?",
"live": "Live"
} }
}, },
"routing": { "routing": {
@@ -868,7 +869,10 @@
"dnssec": "DNSSEC validieren", "dnssec": "DNSSEC validieren",
"qnameMin": "QName-Minimisation (privacy)", "qnameMin": "QName-Minimisation (privacy)",
"cacheMin": "Cache min-TTL", "cacheMin": "Cache min-TTL",
"cacheMax": "Cache max-TTL" "cacheMax": "Cache max-TTL",
"allIPv4": "alle IPv4-Interfaces",
"allIPv6": "alle IPv6-Interfaces",
"loopback": "Loopback"
} }
}, },
"fwd": { "fwd": {
@@ -934,6 +938,8 @@
"copied": "Kopiert", "copied": "Kopiert",
"close": "Schließen", "close": "Schließen",
"refresh": "Aktualisieren", "refresh": "Aktualisieren",
"up": "UP",
"down": "DOWN",
"relTime": { "relTime": {
"Xs": "vor {{n}}s", "Xs": "vor {{n}}s",
"Xm": "vor {{n}}m", "Xm": "vor {{n}}m",

View File

@@ -367,7 +367,8 @@
"backup": "Backup", "backup": "Backup",
"backupHint": "Backup servers receive traffic only when every primary (non-backup) server is down.", "backupHint": "Backup servers receive traffic only when every primary (non-backup) server is down.",
"empty": "No servers in the pool yet. Click “Add server” to get started.", "empty": "No servers in the pool yet. Click “Add server” to get started.",
"deleteConfirm": "Really delete server {{name}}?" "deleteConfirm": "Really delete server {{name}}?",
"live": "Live"
} }
}, },
"routing": { "routing": {
@@ -868,7 +869,10 @@
"dnssec": "DNSSEC validation", "dnssec": "DNSSEC validation",
"qnameMin": "QName minimisation (privacy)", "qnameMin": "QName minimisation (privacy)",
"cacheMin": "Cache min-TTL", "cacheMin": "Cache min-TTL",
"cacheMax": "Cache max-TTL" "cacheMax": "Cache max-TTL",
"allIPv4": "all IPv4 interfaces",
"allIPv6": "all IPv6 interfaces",
"loopback": "Loopback"
} }
}, },
"fwd": { "fwd": {
@@ -934,6 +938,8 @@
"copied": "Copied", "copied": "Copied",
"close": "Close", "close": "Close",
"refresh": "Refresh", "refresh": "Refresh",
"up": "UP",
"down": "DOWN",
"relTime": { "relTime": {
"Xs": "{{n}}s ago", "Xs": "{{n}}s ago",
"Xm": "{{n}}m ago", "Xm": "{{n}}m ago",

View File

@@ -309,7 +309,7 @@ function ServerPanel({ backendID, haproxyStats }: { backendID: number; haproxySt
), ),
}, },
{ {
title: 'Live', key: 'live', width: 160, title: t('backends.server.live'), key: 'live', width: 160,
render: (_, r) => { render: (_, r) => {
const stat = haproxyStats.find( const stat = haproxyStats.find(
s => s.backend === `eg_backend_${backendID}` && s.server === r.name s => s.backend === `eg_backend_${backendID}` && s.server === r.name

View File

@@ -442,10 +442,10 @@ function SettingsTab() {
// Mode "tags" damit der Operator notfalls auch eine IP eintippen kann // Mode "tags" damit der Operator notfalls auch eine IP eintippen kann
// die der Kernel noch nicht meldet (z.B. eine geplante VIP). // die der Kernel noch nicht meldet (z.B. eine geplante VIP).
const ipOptions: { value: string; label: string }[] = [] const ipOptions: { value: string; label: string }[] = []
ipOptions.push({ value: '0.0.0.0', label: '0.0.0.0 — alle IPv4-Interfaces' }) ipOptions.push({ value: '0.0.0.0', label: `0.0.0.0 — ${t('dns.settings.allIPv4')}` })
ipOptions.push({ value: '::', label: ':: — alle IPv6-Interfaces' }) ipOptions.push({ value: '::', label: `:: — ${t('dns.settings.allIPv6')}` })
ipOptions.push({ value: '127.0.0.1', label: '127.0.0.1 — Loopback IPv4' }) ipOptions.push({ value: '127.0.0.1', label: `127.0.0.1 — ${t('dns.settings.loopback')} IPv4` })
ipOptions.push({ value: '::1', label: '::1 — Loopback IPv6' }) ipOptions.push({ value: '::1', label: `::1 — ${t('dns.settings.loopback')} IPv6` })
for (const i of sys ?? []) { for (const i of sys ?? []) {
if (i.ifname === 'lo') continue if (i.ifname === 'lo') continue
for (const a of i.addr_info ?? []) { for (const a of i.addr_info ?? []) {

View File

@@ -106,6 +106,7 @@ export default function RoutingRulesPage() {
form.resetFields() form.resetFields()
void qc.invalidateQueries({ queryKey: ['routing-rules'] }) void qc.invalidateQueries({ queryKey: ['routing-rules'] })
}, },
onError: (e: Error) => message.error(e.message),
}) })
const update = useMutation({ const update = useMutation({
mutationFn: async ({ id, v }: { id: number; v: RuleFormValues }) => { mutationFn: async ({ id, v }: { id: number; v: RuleFormValues }) => {
@@ -117,6 +118,7 @@ export default function RoutingRulesPage() {
form.resetFields() form.resetFields()
void qc.invalidateQueries({ queryKey: ['routing-rules'] }) void qc.invalidateQueries({ queryKey: ['routing-rules'] })
}, },
onError: (e: Error) => message.error(e.message),
}) })
const del = useMutation({ const del = useMutation({
mutationFn: async (id: number) => { await apiClient.delete(`/routing-rules/${id}`) }, mutationFn: async (id: number) => { await apiClient.delete(`/routing-rules/${id}`) },
@@ -144,7 +146,7 @@ export default function RoutingRulesPage() {
<span>{backendLabel(id)}</span> <span>{backendLabel(id)}</span>
{h && ( {h && (
<Tooltip title={tip}> <Tooltip title={tip}>
<Tag color={h.up ? 'green' : 'red'} style={{ margin: 0 }}>{h.up ? 'UP' : 'DOWN'}</Tag> <Tag color={h.up ? 'green' : 'red'} style={{ margin: 0 }}>{h.up ? t('common.up') : t('common.down')}</Tag>
</Tooltip> </Tooltip>
)} )}
</Space> </Space>

View File

@@ -326,8 +326,8 @@ export default function SettingsPage() {
{dbSize.top_tables.length > 0 && ( {dbSize.top_tables.length > 0 && (
<Typography.Text type="secondary" style={{ fontSize: 11 }}> <Typography.Text type="secondary" style={{ fontSize: 11 }}>
{t('settings.dbSizeTop')}:{' '} {t('settings.dbSizeTop')}:{' '}
{dbSize.top_tables.slice(0, 3).map(t => {dbSize.top_tables.slice(0, 3).map(tbl =>
`${t.name} (${t.human_size})` `${tbl.name} (${tbl.human_size})`
).join(', ')} ).join(', ')}
</Typography.Text> </Typography.Text>
)} )}