From 51999d485c996762d6ed60dfbcdca2f4631d4dc8 Mon Sep 17 00:00:00 2001 From: shats Date: Thu, 22 Jan 2026 17:33:31 +0700 Subject: [PATCH] refactor(NetworkConfigManager): streamline IP registry processing; enhance conflict detection and improve interface display with clearer server information --- frontend/src/NetworkConfigManager.jsx | 116 +++++++++++--------------- 1 file changed, 47 insertions(+), 69 deletions(-) diff --git a/frontend/src/NetworkConfigManager.jsx b/frontend/src/NetworkConfigManager.jsx index 1035280..2205d94 100644 --- a/frontend/src/NetworkConfigManager.jsx +++ b/frontend/src/NetworkConfigManager.jsx @@ -477,72 +477,55 @@ function NetworkConfigManager() { const ipRegistry = useMemo(() => { const registry = []; - // Собираем IP из интерфейсов + // Собираем IP из интерфейсов - каждая запись это отдельное использование IP (config.tunnelInterfaces || []).forEach(iface => { - const server = getServerInfo(iface.serverId); - const server2 = getServerInfo(iface.serverId2); - if (iface.localIp && iface.localIp.trim()) { + const server = getServerInfo(iface.serverId); registry.push({ ip: iface.localIp.trim(), type: 'localIp', interface: iface, interfaceName: iface.name || iface.id, - server: server, - server2: server2 + server: server, // localIp привязан к serverId + serverName: server?.dns || server?.ip || iface.serverId || '—' }); } if (iface.remoteIp && iface.remoteIp.trim()) { + const server2 = getServerInfo(iface.serverId2); registry.push({ ip: iface.remoteIp.trim(), type: 'remoteIp', interface: iface, interfaceName: iface.name || iface.id, - server: server, - server2: server2 + server: server2, // remoteIp привязан к serverId2 + serverName: server2?.dns || server2?.ip || iface.serverId2 || '—' }); } }); - // Группируем по IP адресам - const groupedByIp = {}; + // Проверяем конфликты (один IP используется в нескольких интерфейсах) + const ipUsageMap = {}; registry.forEach(item => { - if (!groupedByIp[item.ip]) { - groupedByIp[item.ip] = { - ip: item.ip, - interfaces: [] - }; + if (!ipUsageMap[item.ip]) { + ipUsageMap[item.ip] = []; } - groupedByIp[item.ip].interfaces.push({ - type: item.type, - interface: item.interface, - interfaceName: item.interfaceName, - server: item.server, - server2: item.server2 - }); + ipUsageMap[item.ip].push(item); }); - // Преобразуем в массив и сортируем - return Object.values(groupedByIp) - .map(item => ({ - ...item, - usageCount: item.interfaces.length, - hasConflict: item.interfaces.length > 1, // Конфликт если IP используется в нескольких интерфейсах - // Собираем уникальные серверы для этого IP - servers: [...new Set( - item.interfaces.flatMap(i => [ - i.server?.dns || i.server?.ip || i.interface.serverId, - i.server2?.dns || i.server2?.ip || i.interface.serverId2 - ].filter(Boolean)) - )] - })) - .sort((a, b) => { - // Сначала конфликты, потом по IP - if (a.hasConflict !== b.hasConflict) { - return a.hasConflict ? -1 : 1; - } + // Добавляем флаг конфликта + return registry.map(item => ({ + ...item, + hasConflict: ipUsageMap[item.ip].length > 1 + })).sort((a, b) => { + // Сначала конфликты, потом по IP, потом по типу + if (a.hasConflict !== b.hasConflict) { + return a.hasConflict ? -1 : 1; + } + if (a.ip !== b.ip) { return a.ip.localeCompare(b.ip); - }); + } + return a.type.localeCompare(b.type); + }); }, [config.tunnelInterfaces, servers]); // === Фильтрация реестра IP === @@ -551,7 +534,8 @@ function NetworkConfigManager() { const term = ipRegistrySearch.toLowerCase(); return ipRegistry.filter(item => item.ip.toLowerCase().includes(term) || - item.interfaces.some(i => i.interfaceName.toLowerCase().includes(term)) + item.interfaceName.toLowerCase().includes(term) || + item.serverName.toLowerCase().includes(term) ); }, [ipRegistry, ipRegistrySearch]); @@ -2005,14 +1989,15 @@ function NetworkConfigManager() { IP адрес + Тип Сервер - Интерфейсы + Интерфейс Действия {filteredIpRegistry.map((item, idx) => ( - +
{item.ip} @@ -2024,33 +2009,26 @@ function NetworkConfigManager() {
-
- {item.servers.map((serverName, sIdx) => ( -
- - {serverName} -
- ))} - {item.servers.length === 0 && } + + {item.type === 'localIp' ? 'Local' : 'Remote'} + + + +
+ + {item.serverName}
-
- {item.interfaces.map((usage, uIdx) => ( -
- - {usage.type === 'localIp' ? 'Local' : 'Remote'} - - {usage.interfaceName} - -
- ))} +
+ {item.interfaceName} +