diff --git a/frontend/src/NetworkConfigManager.jsx b/frontend/src/NetworkConfigManager.jsx index 6d03f4b..ae4889e 100644 --- a/frontend/src/NetworkConfigManager.jsx +++ b/frontend/src/NetworkConfigManager.jsx @@ -671,17 +671,22 @@ function NetworkConfigManager() { code += `# Рекурсивный gateway: ${gw.ip}\n`; code += `# Родительский: ${parentLabel}\n`; + // Формируем gateway: для интерфейсов добавляем имя через %, для gateway - только IP + const gatewayValue = parent.parentType === 'interface' + ? `${parentIp}%${parent.name || parent.interfaceType || 'interface'}` + : parentIp; + // Создаём маршрут к IP рекурсивного gateway через родительский const comment = gw.description ? `${gw.description} -> ${parentIp}` : `Recursive: ${gw.ip} -> ${parentIp}`; - code += `/ip route add dst-address=${gw.ip}/32 gateway=${parentIp} comment="${comment}"\n`; + code += `/ip route add dst-address=${gw.ip}/32 gateway=${gatewayValue} comment="${comment}"\n`; // Если у рекурсивного gateway есть описание с указанием на default route if (gw.description && (gw.description.toLowerCase().includes('default') || gw.description.toLowerCase().includes('0.0.0.0'))) { code += `# Дополнительный default route через рекурсивный gateway\n`; const defaultComment = gw.description ? `${gw.description} (default)` : `Recursive default: ${gw.ip}`; - code += `/ip route add dst-address=0.0.0.0/0 gateway=${parentIp} comment="${defaultComment}"\n`; + code += `/ip route add dst-address=0.0.0.0/0 gateway=${gatewayValue} comment="${defaultComment}"\n`; } code += '\n'; }); @@ -860,7 +865,7 @@ function NetworkConfigManager() { {/* Items */} -
+
{items.map(item => ( type === 'gateway' ? renderGatewayCard(item) : renderInterfaceCard(item, serverId) ))} @@ -917,79 +922,87 @@ function NetworkConfigManager() { ? getParentGateway(gateway.parentGatewayId) : null; + // Определяем тип индикатора + const indicatorType = gateway.type === 'recursive' ? 'EXIT' : 'JUMP'; + const indicatorColor = gateway.type === 'recursive' ? 'red' : 'blue'; + const indicatorIcon = gateway.type === 'recursive' ? IconRouter : IconWorld; + + // Определяем отображаемый IP/домен для зеленого блока + const displayIp = parentGateway + ? (parentGateway.parentType === 'interface' + ? (parentGateway.name || parentGateway.interfaceType || 'interface') + : parentGateway.ip) + : gateway.ip; + return ( -
-
-
-
- - - -
-
- {gateway.ip || '—'} - - {gatewayType.label} - -
-
- {gateway.description || provider || '—'} -
-
-
- -
- - -
-
-
- -
- - {gateway.ip || '—'} - - {gateway.ip && ( - - )} -
- - {displayCountry && ( -
- {countryToFlag(displayCountry)} - {displayCountry} - {gatewayCountry && serverCountry && gatewayCountry !== serverCountry && ( - (сервер: {serverCountry}) +
+
+
+ {/* Индикатор типа */} +
+
+ {indicatorType === 'EXIT' ? ( + + ) : ( + )}
- )} + {indicatorType} +
- {parentGateway && ( -
- - - Родитель: {parentGateway.parentType === 'interface' - ? `Интерфейс ${parentGateway.name || parentGateway.interfaceType || 'interface'} (${parentGateway.remoteIp || '—'})` - : parentGateway.ip - ? `Gateway ${parentGateway.ip}` - : 'Gateway (не указан IP)' - } - + {/* Флаг и название */} +
+ {displayCountry && ( + {countryToFlag(displayCountry)} + )} +
+
{gateway.description || provider || gateway.ip || '—'}
+ {server && ( +
{server.dns || server.ip || gateway.serverId}
+ )} +
+
+ + {/* Теги */} +
+ + {gatewayType.label} + +
+ + {/* Зеленый блок с IP/доменом */} + {displayIp && ( +
+ + {displayIp} +
)} + {/* Кнопки действий */} +
+ + +
@@ -1002,12 +1015,10 @@ function NetworkConfigManager() { const server2 = getServerInfo(iface.serverId2); // Определяем, для какого сервера отображается карточка - // Сравниваем currentServerId с serverId2 используя функцию getServerInfo для надежности const isForServer2 = currentServerId && iface.serverId2 && (() => { const currentServer = getServerInfo(currentServerId); const targetServer2 = getServerInfo(iface.serverId2); if (!currentServer || !targetServer2) return false; - // Сравниваем по id, ip или dns return ( currentServer.id === targetServer2.id || currentServer.ip === targetServer2.ip || @@ -1025,94 +1036,82 @@ function NetworkConfigManager() { : (iface.name || '—'); // IP адреса также зависят от того, для какого сервера отображается - // Для второго сервера localIp и remoteIp меняются местами const displayLocalIp = isForServer2 ? (iface.remoteIp || '—') : (iface.localIp || '—'); const displayRemoteIp = isForServer2 ? (iface.localIp || '—') : (iface.remoteIp || '—'); + // Определяем сервер для отображения + const displayServer = isForServer2 ? server2 : server; + const displayServerName = displayServer?.dns || displayServer?.ip || (isForServer2 ? iface.serverId2 : iface.serverId); + const displayCountry = displayServer?.country || ''; + const interfaceTypeColor = getInterfaceTypeColor(iface.type); + + // Определяем отображаемый IP для зеленого блока (remote IP другого сервера) + const displayIp = displayRemoteIp !== '—' ? displayRemoteIp : displayLocalIp; + return ( -
-
-
-
- - +
+
+
+ {/* Индикатор типа */} +
+
+ +
+ {iface.type} +
+ + {/* Флаг и название */} +
+ {displayCountry && ( + {countryToFlag(displayCountry)} + )} +
+
{interfaceName}
+ {displayServerName && ( +
{displayServerName}
+ )} +
+
+ + {/* Теги */} +
+ + {iface.type} -
-
{interfaceName}
-
- - {iface.type} - -
-
-
-
+ + {/* Зеленый блок с IP/доменом */} + {displayIp && displayIp !== '—' && ( +
+ + {displayIp} + -
- - -
-
+ )} -
-
-
Local IP
-
- {displayLocalIp} - {displayLocalIp && displayLocalIp !== '—' && ( - - )} -
-
-
-
Remote IP
-
- {displayRemoteIp} - {displayRemoteIp && displayRemoteIp !== '—' && ( - - )} -
-
-
- - {/* Серверы */} -
- {server && ( -
- - Сервер 1: - {server.dns || server.ip} - {iface.name && ({iface.name})} -
- )} - {server2 && ( -
- - Сервер 2: - {server2.dns || server2.ip} - {(iface.name2 || iface.name) && ( - ({iface.name2 || iface.name}) - )} -
- )} + {/* Кнопки действий */} +
+ +