From ee357ed59ab8681843fe47df3a8b80094490ade6 Mon Sep 17 00:00:00 2001 From: shats Date: Mon, 16 Feb 2026 23:40:33 +0700 Subject: [PATCH] feat(SettingsModal): enhance server selection for ping services with autocomplete input and load server list from API --- frontend/src/components/SettingsModal.jsx | 50 +++++++++++++++-------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/frontend/src/components/SettingsModal.jsx b/frontend/src/components/SettingsModal.jsx index bfac072..bbba756 100644 --- a/frontend/src/components/SettingsModal.jsx +++ b/frontend/src/components/SettingsModal.jsx @@ -1,8 +1,9 @@ import FormField from './FormField'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, useMemo } from 'react'; import api from '../lib/api.js'; import { IconSettings, IconDeviceFloppy } from '@tabler/icons-react'; import ErrorAlert from './ErrorAlert'; +import ServerAutocompleteInput from './ServerAutocompleteInput.jsx'; /** * SettingsModal - модальное окно настроек интерфейса @@ -25,17 +26,27 @@ export default function SettingsModal({ open, onClose }) { const [pingServicesSource, setPingServicesSource] = useState('web'); const [pingServicesServerId, setPingServicesServerId] = useState(''); const [pingServicesGatewayIp, setPingServicesGatewayIp] = useState(''); + const [serversList, setServersList] = useState([]); + + const routerServersForPing = useMemo(() => { + return (serversList || []).filter( + (s) => s && (String(s.type || '').toLowerCase() === 'jumphost' || String(s.type || '').toLowerCase() === 'home') + ); + }, [serversList]); useEffect(() => { if (!open) return; setError(''); setSuccess(''); setLoading(true); - + (async () => { try { - const res = await api.get('/ui-settings'); - const data = res?.data || {}; + const [settingsRes, serversRes] = await Promise.all([ + api.get('/ui-settings'), + api.get('/servers').catch(() => ({ data: [] })), + ]); + const data = settingsRes?.data || {}; setRawSettings(data); setDohServer(String(data?.dohServer || '')); setWsUrl(String(data?.wsUpdateUrl || '')); @@ -47,8 +58,9 @@ export default function SettingsModal({ open, onClose }) { setPingServicesSource(String(data?.pingServicesSource || 'web').toLowerCase() === 'router' ? 'router' : 'web'); setPingServicesServerId(String(data?.pingServicesServerId || '').trim()); setPingServicesGatewayIp(String(data?.pingServicesGatewayIp || '').trim()); - const e = res?.headers?.etag || res?.headers?.ETag || ''; + const e = settingsRes?.headers?.etag || settingsRes?.headers?.ETag || ''; setEtag(e ? String(e) : ''); + setServersList(Array.isArray(serversRes?.data) ? serversRes.data : []); } catch (e) { setError('Не удалось загрузить настройки'); } finally { @@ -256,26 +268,30 @@ export default function SettingsModal({ open, onClose }) { {pingServicesSource === 'router' && (
- + +
+ setPingServicesServerId(String(v || '').trim())} + servers={routerServersForPing} + placeholder="Выберите роутер (jumphost или входной)" + className="form-control form-control-sm" + maxSuggestions={10} + /> +
+
+ Выбор роутера с MikroTik API для пинга с главной. Пусто — первый jumphost из списка. +