feat: Обновить серверную часть для улучшения обработки запросов и добавления новых метрик; интегрировать поддержку WebSocket URL в менеджеры ASNs, Domains и IPRanges, а также обновить интерфейс настроек для ввода WebSocket URL
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m58s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m58s
This commit is contained in:
@@ -9,6 +9,7 @@ export default function SettingsModal({ open, onClose }) {
|
||||
const [success, setSuccess] = useState('')
|
||||
const [etag, setEtag] = useState('')
|
||||
const [dohServer, setDohServer] = useState('')
|
||||
const [wsUrl, setWsUrl] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return
|
||||
@@ -20,6 +21,7 @@ export default function SettingsModal({ open, onClose }) {
|
||||
const res = await api.get('/ui-settings')
|
||||
const data = res?.data || {}
|
||||
setDohServer(String(data?.dohServer || ''))
|
||||
setWsUrl(String(data?.wsUpdateUrl || ''))
|
||||
const e = res?.headers?.etag || res?.headers?.ETag || ''
|
||||
setEtag(e ? String(e) : '')
|
||||
// фокус на первом поле
|
||||
@@ -42,13 +44,22 @@ export default function SettingsModal({ open, onClose }) {
|
||||
} catch { return false }
|
||||
}
|
||||
|
||||
const validateWs = (value) => {
|
||||
if (!value) return true // допускаем пустое значение
|
||||
try {
|
||||
const u = new URL(String(value))
|
||||
return u.protocol === 'ws:' || u.protocol === 'wss:'
|
||||
} catch { return false }
|
||||
}
|
||||
|
||||
const onSave = async () => {
|
||||
setError('')
|
||||
setSuccess('')
|
||||
if (!validateDoh(dohServer)) { setError('Укажите корректный HTTPS URL для DoH'); return }
|
||||
if (!validateWs(wsUrl)) { setError('Укажите корректный WebSocket URL (ws:// или wss://)'); return }
|
||||
setSaving(true)
|
||||
try {
|
||||
const payload = { settings: { dohServer: String(dohServer || '').trim() }, etag }
|
||||
const payload = { settings: { dohServer: String(dohServer || '').trim(), wsUpdateUrl: String(wsUrl || '').trim() }, etag }
|
||||
const res = await api.post('/ui-settings', payload)
|
||||
const meta = res?.data || {}
|
||||
setSuccess('Настройки сохранены')
|
||||
@@ -91,6 +102,22 @@ export default function SettingsModal({ open, onClose }) {
|
||||
<button type="button" className="btn-close" onClick={() => setSuccess('')}></button>
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-3">
|
||||
<label className="form-label">WebSocket URL (BGP Live)</label>
|
||||
<input
|
||||
type="text"
|
||||
className={`form-control${wsUrl && !validateWs(wsUrl) ? ' is-invalid' : ''}`}
|
||||
placeholder="ws://host:port/ws/update_bgp?api_key=..."
|
||||
value={wsUrl}
|
||||
onChange={(e) => setWsUrl(e.target.value)}
|
||||
disabled={loading || saving}
|
||||
/>
|
||||
<div className="form-hint">URL для Live-обновления BGP (ws:// или wss://). Можно оставить пустым.</div>
|
||||
{wsUrl && !validateWs(wsUrl) && (
|
||||
<div className="invalid-feedback">Укажите корректный WebSocket URL</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label">DoH сервер</label>
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user