fix(settings): Bestätigungsdialog vor Service-Restart + status-dot CSS (v1.1.138)
- Popconfirm vor jedem Restart-Button — kein versehentlicher Neustart mehr - status-dot inline styles → .status-dot.online/.offline CSS-Klassen Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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.137"
|
var version = "1.1.138"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
addr := os.Getenv("EDGEGUARD_API_ADDR")
|
addr := os.Getenv("EDGEGUARD_API_ADDR")
|
||||||
|
|||||||
@@ -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.137"
|
var version = "1.1.138"
|
||||||
|
|
||||||
const usage = `edgeguard-ctl — EdgeGuard CLI
|
const usage = `edgeguard-ctl — EdgeGuard CLI
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,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.137"
|
var version = "1.1.138"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// renewTickInterval — how often we re-evaluate expiring certs.
|
// renewTickInterval — how often we re-evaluate expiring certs.
|
||||||
|
|||||||
@@ -567,6 +567,9 @@
|
|||||||
"backupNowFailed": "Backup-Trigger fehlgeschlagen",
|
"backupNowFailed": "Backup-Trigger fehlgeschlagen",
|
||||||
"serviceRestartCardTitle": "Dienste neu starten",
|
"serviceRestartCardTitle": "Dienste neu starten",
|
||||||
"serviceRestartBtn": "Restart",
|
"serviceRestartBtn": "Restart",
|
||||||
|
"serviceRestartConfirmTitle": "{{service}} neu starten?",
|
||||||
|
"serviceRestartConfirmDesc": "Der Dienst ist während des Neustarts kurz nicht erreichbar.",
|
||||||
|
"serviceRestartConfirmOk": "Ja, neu starten",
|
||||||
"serviceRestartOk": "{{service}} wurde neu gestartet.",
|
"serviceRestartOk": "{{service}} wurde neu gestartet.",
|
||||||
"serviceRestartFailed": "Neustart von {{service}} fehlgeschlagen",
|
"serviceRestartFailed": "Neustart von {{service}} fehlgeschlagen",
|
||||||
"serviceRestartHint": "Startet den Dienst via systemctl restart. edgeguard-api und PostgreSQL sind bewusst ausgeschlossen.",
|
"serviceRestartHint": "Startet den Dienst via systemctl restart. edgeguard-api und PostgreSQL sind bewusst ausgeschlossen.",
|
||||||
|
|||||||
@@ -565,6 +565,9 @@
|
|||||||
"backupNowBtn": "Backup now",
|
"backupNowBtn": "Backup now",
|
||||||
"serviceRestartCardTitle": "Restart services",
|
"serviceRestartCardTitle": "Restart services",
|
||||||
"serviceRestartBtn": "Restart",
|
"serviceRestartBtn": "Restart",
|
||||||
|
"serviceRestartConfirmTitle": "Restart {{service}}?",
|
||||||
|
"serviceRestartConfirmDesc": "The service will be briefly unavailable while restarting.",
|
||||||
|
"serviceRestartConfirmOk": "Yes, restart",
|
||||||
"serviceRestartOk": "{{service}} restarted successfully.",
|
"serviceRestartOk": "{{service}} restarted successfully.",
|
||||||
"serviceRestartFailed": "Restart of {{service}} failed",
|
"serviceRestartFailed": "Restart of {{service}} failed",
|
||||||
"serviceRestartHint": "Restarts the service via systemctl restart. edgeguard-api and PostgreSQL are intentionally excluded.",
|
"serviceRestartHint": "Restarts the service via systemctl restart. edgeguard-api and PostgreSQL are intentionally excluded.",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Alert, Button, Card, Descriptions, Form, Input, InputNumber, Select, Space, Spin, Switch, Tooltip, Typography, message } from 'antd'
|
import { Alert, Button, Card, Descriptions, Form, Input, InputNumber, Popconfirm, Select, Space, Spin, Switch, Tooltip, Typography, message } from 'antd'
|
||||||
import { CloudDownloadOutlined, CloudSyncOutlined, CodeOutlined, CopyOutlined, DatabaseOutlined, DownloadOutlined, ExclamationCircleOutlined, FileSearchOutlined, GlobalOutlined, LockOutlined, MailOutlined, ReloadOutlined, SettingOutlined, StopOutlined, ToolOutlined } from '@ant-design/icons'
|
import { CloudDownloadOutlined, CloudSyncOutlined, CodeOutlined, CopyOutlined, DatabaseOutlined, DownloadOutlined, ExclamationCircleOutlined, FileSearchOutlined, GlobalOutlined, LockOutlined, MailOutlined, ReloadOutlined, SettingOutlined, StopOutlined, ToolOutlined } from '@ant-design/icons'
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
@@ -407,13 +407,7 @@ export default function SettingsPage() {
|
|||||||
return (
|
return (
|
||||||
<Space key={svc} style={{ width: '100%', justifyContent: 'space-between' }}>
|
<Space key={svc} style={{ width: '100%', justifyContent: 'space-between' }}>
|
||||||
<Space size={6}>
|
<Space size={6}>
|
||||||
<span
|
<span className={`status-dot ${status?.active ? 'online' : 'offline'}`} />
|
||||||
style={{
|
|
||||||
display: 'inline-block', width: 8, height: 8, borderRadius: '50%',
|
|
||||||
background: status?.active ? '#22c55e' : '#ef4444',
|
|
||||||
flexShrink: 0,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Typography.Text style={{ fontFamily: 'monospace', fontSize: 13 }}>{svc}</Typography.Text>
|
<Typography.Text style={{ fontFamily: 'monospace', fontSize: 13 }}>{svc}</Typography.Text>
|
||||||
{status && (
|
{status && (
|
||||||
<Typography.Text type="secondary" style={{ fontSize: 11 }}>
|
<Typography.Text type="secondary" style={{ fontSize: 11 }}>
|
||||||
@@ -422,15 +416,23 @@ export default function SettingsPage() {
|
|||||||
)}
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
<Tooltip title={isViewer ? t('auth.viewerBadge') : undefined}>
|
<Tooltip title={isViewer ? t('auth.viewerBadge') : undefined}>
|
||||||
<Button
|
<Popconfirm
|
||||||
size="small"
|
title={t('settings.serviceRestartConfirmTitle', { service: svc })}
|
||||||
icon={<ReloadOutlined />}
|
description={t('settings.serviceRestartConfirmDesc')}
|
||||||
loading={restartingService === svc}
|
okText={t('settings.serviceRestartConfirmOk')}
|
||||||
|
cancelText={t('common.cancel')}
|
||||||
disabled={isViewer}
|
disabled={isViewer}
|
||||||
onClick={() => serviceRestart.mutate(svc)}
|
onConfirm={() => serviceRestart.mutate(svc)}
|
||||||
>
|
>
|
||||||
{t('settings.serviceRestartBtn')}
|
<Button
|
||||||
</Button>
|
size="small"
|
||||||
|
icon={<ReloadOutlined />}
|
||||||
|
loading={restartingService === svc}
|
||||||
|
disabled={isViewer}
|
||||||
|
>
|
||||||
|
{t('settings.serviceRestartBtn')}
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Space>
|
</Space>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user