fix(i18n): RemoteTargets S3/SFTP-Labels + NTP-Interface-Labels vollständig lokalisieren

RemoteTargets: alle 20+ hardkodierten Form-Labels und deutschen Hilfetexte
(S3: Endpoint/Region/Bucket/AccessKey/SecretKey/PathPrefix/HTTPS;
 SFTP: Host/Port/Username/Password/PrivateKey/RemoteDir/HostKeyFp)
sind jetzt in t()-Aufrufen mit remotes.s3.*/remotes.sftp.*-Keys.

NTP: Listen-Address-Dropdown-Labels (alle IPv4/IPv6-Interfaces, Loopback)
verwenden jetzt dns.settings.allIPv4/allIPv6/loopback (identisch zu DNS-Settings).
NTP-Pool-Adresse-Placeholder → t('ntp.pool.addressPlaceholder').

en/de: alle neuen Keys ergänzt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-24 12:52:13 +02:00
parent f6852256b1
commit 49e3e39ea6
8 changed files with 91 additions and 33 deletions

View File

@@ -250,12 +250,12 @@ export default function RemoteTargetsTab() {
<Form form={form} layout="vertical"
onFinish={(v) => edit ? update.mutate({ id: edit.id, v }) : create.mutate(v)}>
<Form.Item label={t('remotes.col.name')} name="name" rules={[{ required: true }]}>
<Input placeholder="MinIO offsite / Hetzner Storage Box" />
<Input placeholder={t('remotes.namePlaceholder')} />
</Form.Item>
<Form.Item label={t('remotes.col.kind')} name="kind" rules={[{ required: true }]}>
<Select options={[
{ value: 's3', label: 'S3 (AWS / MinIO / R2 / B2 / Hetzner Object)' },
{ value: 'sftp', label: 'SFTP (SSH)' },
{ value: 's3', label: t('remotes.kindS3') },
{ value: 'sftp', label: t('remotes.kindSftp') },
]} />
</Form.Item>
<Form.Item label={t('remotes.col.target')} name="target_url" rules={[{ required: true }]}
@@ -265,27 +265,27 @@ export default function RemoteTargetsTab() {
{kind === 's3' && (
<>
<Form.Item label="Endpoint" name="endpoint" rules={[{ required: true }]}
extra="s3.amazonaws.com / minio.example.com:9000 / fsn1.your-objectstorage.com">
<Form.Item label={t('remotes.s3.endpoint')} name="endpoint" rules={[{ required: true }]}
extra={t('remotes.s3.endpointExtra')}>
<Input />
</Form.Item>
<Form.Item label="Region" name="region">
<Input placeholder="eu-central-1 / auto (R2)" />
<Form.Item label={t('remotes.s3.region')} name="region">
<Input placeholder={t('remotes.s3.regionPlaceholder')} />
</Form.Item>
<Form.Item label="Bucket" name="bucket" rules={[{ required: true }]}>
<Form.Item label={t('remotes.s3.bucket')} name="bucket" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item label="Access Key" name="access_key" rules={[{ required: true }]}>
<Form.Item label={t('remotes.s3.accessKey')} name="access_key" rules={[{ required: true }]}>
<Input autoComplete="off" />
</Form.Item>
<Form.Item label="Secret Key" name="secret_key" rules={[{ required: !edit }]}>
<Form.Item label={t('remotes.s3.secretKey')} name="secret_key" rules={[{ required: !edit }]}>
<Input.Password autoComplete="new-password" />
</Form.Item>
<Form.Item label="Path Prefix" name="path_prefix"
extra="z.B. edgeguard/utm-1 — wird vor jedem Filename gesetzt">
<Form.Item label={t('remotes.s3.pathPrefix')} name="path_prefix"
extra={t('remotes.s3.pathPrefixExtra')}>
<Input />
</Form.Item>
<Form.Item label="HTTPS (use_ssl)" name="use_ssl" valuePropName="checked">
<Form.Item label={t('remotes.s3.useSsl')} name="use_ssl" valuePropName="checked">
<Switch />
</Form.Item>
</>
@@ -293,29 +293,29 @@ export default function RemoteTargetsTab() {
{kind === 'sftp' && (
<>
<Form.Item label="Host" name="host" rules={[{ required: true }]}>
<Form.Item label={t('remotes.sftp.host')} name="host" rules={[{ required: true }]}>
<Input placeholder="backup.example.com" />
</Form.Item>
<Form.Item label="Port" name="port" rules={[{ required: true }]}>
<Form.Item label={t('remotes.sftp.port')} name="port" rules={[{ required: true }]}>
<InputNumber min={1} max={65535} style={{ width: '100%' }} />
</Form.Item>
<Form.Item label="Username" name="username" rules={[{ required: true }]}>
<Form.Item label={t('remotes.sftp.username')} name="username" rules={[{ required: true }]}>
<Input autoComplete="off" />
</Form.Item>
<Form.Item label="Password" name="password"
extra="Entweder Password ODER Private-Key.">
<Form.Item label={t('remotes.sftp.password')} name="password"
extra={t('remotes.sftp.passwordExtra')}>
<Input.Password autoComplete="new-password" />
</Form.Item>
<Form.Item label="Private Key (OpenSSH, base64)" name="private_key">
<Form.Item label={t('remotes.sftp.privateKey')} name="private_key">
<Input.TextArea rows={3} autoComplete="off"
placeholder="base64-encoded OpenSSH private key" />
placeholder={t('remotes.sftp.privateKeyPlaceholder')} />
</Form.Item>
<Form.Item label="Remote Dir" name="remote_dir" rules={[{ required: true }]}
extra="z.B. /backups/edgeguard">
<Form.Item label={t('remotes.sftp.remoteDir')} name="remote_dir" rules={[{ required: true }]}
extra={t('remotes.sftp.remoteDirExtra')}>
<Input />
</Form.Item>
<Form.Item label="Host-Key-Fingerprint" name="host_key_fingerprint"
extra="optional, SHA256:... — wenn leer wird TOFU verwendet (unsicher gegen MitM)">
<Form.Item label={t('remotes.sftp.hostKeyFp')} name="host_key_fingerprint"
extra={t('remotes.sftp.hostKeyFpExtra')}>
<Input placeholder="SHA256:abc123..." />
</Form.Item>
</>

View File

@@ -303,7 +303,7 @@ function PoolsTab() {
</Form.Item>
<Form.Item label={t('ntp.pool.address')} name="address" rules={[{ required: true }]}
extra={t('ntp.pool.addressExtra')}>
<Input placeholder="0.de.pool.ntp.org oder 10.0.0.10" />
<Input placeholder={t('ntp.pool.addressPlaceholder')} />
</Form.Item>
<Space>
<Form.Item label={t('ntp.pool.iburst')} name="iburst" valuePropName="checked">
@@ -341,10 +341,10 @@ function SettingsTab() {
const [form] = Form.useForm<SettingsForm>()
const ipOptions: { value: string; label: string }[] = [
{ value: '0.0.0.0', label: '0.0.0.0 — alle IPv4-Interfaces' },
{ value: '::', label: ':: — alle IPv6-Interfaces' },
{ value: '127.0.0.1', label: '127.0.0.1 — Loopback IPv4' },
{ value: '::1', label: '::1 — Loopback IPv6' },
{ value: '0.0.0.0', label: `0.0.0.0 — ${t('dns.settings.allIPv4')}` },
{ value: '::', label: `:: — ${t('dns.settings.allIPv6')}` },
{ value: '127.0.0.1', label: `127.0.0.1 — ${t('dns.settings.loopback')} IPv4` },
{ value: '::1', label: `::1 — ${t('dns.settings.loopback')} IPv6` },
]
for (const i of sys ?? []) {
if (i.ifname === 'lo') continue