From caa566aa8fa451c1b0841ae00b4e922b5993ce64 Mon Sep 17 00:00:00 2001 From: shats Date: Thu, 12 Feb 2026 23:43:44 +0700 Subject: [PATCH] feat(MikrotikTools): implement gateway selection feature with enhanced UI for improved user experience and server-specific filtering --- frontend/src/MikrotikTools.jsx | 278 +++++++++++++++++---------------- 1 file changed, 145 insertions(+), 133 deletions(-) diff --git a/frontend/src/MikrotikTools.jsx b/frontend/src/MikrotikTools.jsx index 55f063d..60f7b8d 100644 --- a/frontend/src/MikrotikTools.jsx +++ b/frontend/src/MikrotikTools.jsx @@ -199,6 +199,16 @@ function MikrotikTools() { [jumphostServers, serverId] ); + const gatewaysForServer = useMemo(() => { + if (!serverId || !gateways.length) return []; + const ids = currentServer + ? new Set( + [serverId, currentServer.id, currentServer.ip, currentServer.dns].filter(Boolean).map(String) + ) + : new Set([String(serverId)]); + return gateways.filter((g) => g && g.ip && ids.has(String(g.serverId))); + }, [serverId, currentServer, gateways]); + const currentServerLabel = currentServer?.dns || currentServer?.ip || makeServerId(currentServer || {}) || 'Не выбран'; @@ -304,58 +314,143 @@ function MikrotikTools() { - {/* Горизонтальная панель: режим (Traceroute/Ping) + основное действие — по образцу Tabler "page-header" с btn-list */} -
-
-
-
-
    -
  • - -
  • -
  • - -
  • -
+ {/* Шлюз и параметры проверки — только когда выбран сервер, в том же стиле что и блок серверов */} + {serverId && ( + <> + {/* Выбор gateway в стиле карточек серверов */} +
+
+

Шлюз (gateway)

+
+ {gatewaysForServer.length > 0 + ? 'Выберите шлюз для привязки проверки (опционально). Можно искать по IP или интерфейсу ниже.' + : 'Нет настроенных шлюзов для этого сервера. Проверка пойдёт без привязки к gateway.'} +
-
-
- - +
+ {loading && !networkConfig ? ( +
Загрузка сетевых настроек…
+ ) : ( + <> + {gatewaysForServer.length > 0 && ( +
+ {gatewaysForServer .map((g) => { + const isSelected = gatewayRef === g.ip || gatewayRef === g.id; + const flag = g.country ? countryToFlag(g.country) : ''; + const subtitle = [g.country, g.provider].filter(Boolean).join(' · '); + return ( +
+
{ + const next = isSelected ? '' : (g.ip || g.id); + setGatewayRef(next); + if (!next) { + setGatewayMeta(null); + } else { + setGatewayMeta({ ip: g.ip, gateway: g }); + if (!target && g.ip) setTarget(g.ip); + } + }} + > +
+ + {flag || (g.ip ? g.ip.slice(0, 2) : '?')} + +
+
+ {g.ip || '—'} +
+ {(g.description || g.ip) && ( +
+ {g.description || g.ip} +
+ )} +
+ {subtitle || '—'} +
+
+
+
+
+ ); + })} +
+ )} + +
+ Текущий gateway:  + {gatewayRef || gatewayMeta?.ip || 'не выбран'} +
+ + )} +
+
+ + {/* Режим и кнопки запуска */} +
+
+
+
+
    +
  • + +
  • +
  • + +
  • +
+
+
+
+ + +
+
-
-
+ + )} {/* Параметры проверки + результаты */}
@@ -367,93 +462,10 @@ function MikrotikTools() {
{loading && !networkConfig ? (
Загрузка сетевых настроек…
+ ) : !serverId ? ( +
Выберите сервер выше — шлюз и параметры появятся там.
) : ( <> - -
- - {/* Карточки gateways выбранного сервера */} - {serverId && gateways.length > 0 && ( -
-
- {gateways - .filter((g) => { - if (!g || !g.ip) return false; - if (!serverId) return false; - if (!currentServer) return g.serverId === serverId; - const serverIds = new Set([ - serverId, - currentServer.id, - currentServer.ip, - currentServer.dns, - ].filter(Boolean).map(String)); - return serverIds.has(String(g.serverId)); - }) - .map((g) => { - const isSelected = gatewayRef === g.ip || gatewayRef === g.id; - const flag = g.country ? countryToFlag(g.country) : ''; - // В подзаголовке показываем страну/провайдера, чтобы не дублировать description - const subtitle = [g.country, g.provider].filter(Boolean).join(' · '); - return ( - // Показываем карточки одной колонкой (по одной в ряд), чтобы текст был читаемым -
-
{ - const next = isSelected ? '' : (g.ip || g.id); - setGatewayRef(next); - if (!next) { - setGatewayMeta(null); - } else { - setGatewayMeta({ ip: g.ip, gateway: g }); - if (!target && g.ip) setTarget(g.ip); - } - }} - > -
- - {flag || (g.ip ? g.ip.split('.').slice(-1)[0] : '?')} - -
-
- {g.ip || '—'} -
- {g.description && ( -
- {g.description} -
- )} - {subtitle && ( -
- {subtitle} -
- )} -
-
-
-
- ); - })} -
-
- )} - {/* Расширенный выбор по IP/интерфейсу */} - -
- Можно выбрать gateway карточкой выше или через поиск по IP/интерфейсу. -
-
-