feat(ui): Quick-Toggles, Config-Preview, Dashboard-Alerts, Domain-Detail-Health
Quick-Toggle-Switches (kein Modal nötig) für: Backends, Backend-Server, DNS-Zonen, DNS-Records, Domains (active), Firewall-Rules, NAT-Rules, Forward-Proxy ACLs, Routing-Rules. Dashboard: Alert-Banner für komplett ausgefallene Backends (HAProxy-Stats) und Domains im Maintenance-Mode. Domain-Detail: HAProxy-Live-Health-Badge (15s Polling), TLS-Cert ausstellen/erneuern direkt aus dem Detail, Routing-Rules-Panel inline. Config-Preview (Settings): alle 4 Generatoren (haproxy, nftables, squid, unbound) rendern via RenderToString ohne Disk-Write — GET /system/config-preview. ActionButtons: Viewer-Rolle blendet Delete aus (RBAC-Ergänzung). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -38,7 +38,15 @@ interface ServerFormValues {
|
||||
name: string; address: string; port: number
|
||||
weight: number; backup: boolean; active: boolean
|
||||
}
|
||||
interface DomainFull { id: number; name: string; primary_backend_id?: number | null }
|
||||
interface DomainFull {
|
||||
id: number; name: string; active: boolean
|
||||
primary_backend_id?: number | null
|
||||
http_to_https: boolean; hsts_enabled: boolean
|
||||
hsts_max_age: number; hsts_subdomains: boolean; hsts_preload: boolean
|
||||
maintenance_mode: boolean; maintenance_message?: string | null
|
||||
www_redirect: string; rate_limit_rps: number
|
||||
max_body_kb: number; disable_h3: boolean; notes?: string | null
|
||||
}
|
||||
|
||||
async function getBackend(id: number): Promise<Backend | null> {
|
||||
const r = await apiClient.get(`/backends/${id}`)
|
||||
@@ -172,9 +180,9 @@ export default function BackendDetailPage() {
|
||||
<Form.Item label={t('backends.lbAlgo')} name="lb_algorithm" rules={[{ required: true }]}
|
||||
extra={t('backends.lbAlgoHint')}>
|
||||
<Select options={[
|
||||
{ value: 'roundrobin', label: 'roundrobin — gleichmäßige Verteilung' },
|
||||
{ value: 'leastconn', label: 'leastconn — wenigste aktive Verbindungen' },
|
||||
{ value: 'source', label: 'source — sticky per Source-IP-Hash' },
|
||||
{ value: 'roundrobin', label: 'roundrobin' },
|
||||
{ value: 'leastconn', label: 'leastconn' },
|
||||
{ value: 'source', label: 'source' },
|
||||
]} />
|
||||
</Form.Item>
|
||||
<Form.Item label={t('backends.healthCheck')} name="health_check_path"
|
||||
@@ -200,7 +208,7 @@ export default function BackendDetailPage() {
|
||||
options={(domains ?? []).map(d => ({
|
||||
value: d.id,
|
||||
label: d.primary_backend_id && d.primary_backend_id !== backendID
|
||||
? `${d.name} (derzeit: #${d.primary_backend_id})`
|
||||
? `${d.name} (${t('backends.attachedToOther', { id: d.primary_backend_id })})`
|
||||
: d.name,
|
||||
}))}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user