From 0bd2a07dd2463f0c788e947100eee0399b7a5228 Mon Sep 17 00:00:00 2001 From: shats Date: Thu, 22 Jan 2026 14:05:52 +0700 Subject: [PATCH] feat(NetworkConfigManager): implement code copying functionality for individual blocks and all generated MikroTik code; update server grouping display for improved clarity --- frontend/src/NetworkConfigManager.jsx | 116 +++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 12 deletions(-) diff --git a/frontend/src/NetworkConfigManager.jsx b/frontend/src/NetworkConfigManager.jsx index d3782f4..6d03f4b 100644 --- a/frontend/src/NetworkConfigManager.jsx +++ b/frontend/src/NetworkConfigManager.jsx @@ -751,6 +751,19 @@ function NetworkConfigManager() { } }; + // === Копирование отдельного блока кода === + const handleCopyBlock = async (code) => { + await handleCopyMikrotikCode(code); + }; + + // === Копирование всего кода === + const handleCopyAllMikrotikCode = async () => { + const fullCode = Array.isArray(generatedMikrotikCode) && generatedMikrotikCode.length > 0 + ? generatedMikrotikCode.map(block => block.code).join('\n\n') + : ''; + await handleCopyMikrotikCode(fullCode); + }; + // === Группировка блоков по серверам === const groupedMikrotikCode = useMemo(() => { if (!Array.isArray(generatedMikrotikCode) || generatedMikrotikCode.length === 0) { @@ -759,7 +772,7 @@ function NetworkConfigManager() { const grouped = {}; generatedMikrotikCode.forEach(block => { - const serverName = block.serverName || '__unknown__'; + const serverName = block.serverName || '__unassigned__'; if (!grouped[serverName]) { grouped[serverName] = { server: block.server, @@ -2042,15 +2055,94 @@ function NetworkConfigManager() { Конфигурация MikroTik RouterOS для рекурсивных маршрутов и IP адресов интерфейсов - {Array.isArray(generatedMikrotikCode) && generatedMikrotikCode.length > 0 ? ( -
- {generatedMikrotikCode.map((block, index) => ( -
-
-                          {block.code}
-                        
-
- ))} + {Object.keys(groupedMikrotikCode).length > 0 ? ( +
+ {Object.entries(groupedMikrotikCode) + .sort(([a], [b]) => a.localeCompare(b)) + .map(([serverName, serverData]) => { + const server = serverData.server; + const isUnassigned = serverName === '__unassigned__'; + + return ( +
+ {/* Заголовок сервера */} +
+
+ {isUnassigned ? ( + <> + + + + Без привязки к серверу + + ) : ( + <> + + + +
+
{serverName}
+ {server && ( +
+ {server.provider && {server.provider}} + {server.provider && server.country && } + {server.country && ( + {countryToFlag(server.country)} {server.country} + )} + {server.ip && server.ip !== serverName && ( + <> + {(server.provider || server.country) && } + {server.ip} + + )} +
+ )} +
+ + )} +
+
+ + {/* Блоки кода для этого сервера */} +
+ {serverData.blocks.map((block, blockIndex) => { + const blockTitle = block.type === 'recursive-routes' + ? 'Рекурсивные маршруты' + : block.type === 'interface-addresses' + ? 'IP адреса интерфейсов' + : 'Конфигурация'; + + return ( +
+ {/* Заголовок блока */} +
+
+ + {blockTitle} +
+ +
+ + {/* Код блока */} +
+
+                                        {block.code}
+                                      
+
+
+ ); + })} +
+
+ ); + })}
) : (
@@ -2075,11 +2167,11 @@ function NetworkConfigManager() {