feat(NetworkConfigManager): implement MikroTik code generation for individual and selected interfaces, enhancing user interaction and flexibility in network configuration
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m37s

This commit is contained in:
2026-01-23 15:59:11 +07:00
parent b7a55e4241
commit f60611e689
+60 -8
View File
@@ -1346,16 +1346,12 @@ function NetworkConfigManager() {
}
};
// === Генерация кода MikroTik для настройки IP адресов интерфейсов ===
const generateMikrotikInterfaceAddresses = async () => {
const interfacesWithBothServers = (config.tunnelInterfaces || []).filter(i =>
i.serverId && i.serverId2 && i.localIp && i.remoteIp
);
if (interfacesWithBothServers.length === 0) {
// === Вспомогательная функция: построение блоков MikroTik для списка интерфейсов ===
const buildMikrotikInterfaceBlocks = async (interfacesWithBothServers) => {
if (!interfacesWithBothServers || interfacesWithBothServers.length === 0) {
return [];
}
// Загружаем пароли для интерфейсов с IPSec
const passwordIds = [...new Set(interfacesWithBothServers
.filter(i => i.ipsecPasswordId && i.ipsecPasswordId.trim() !== '')
@@ -1504,6 +1500,24 @@ function NetworkConfigManager() {
return blocks;
};
// === Генерация кода MikroTik для настройки IP адресов интерфейсов (всех) ===
const generateMikrotikInterfaceAddresses = async () => {
const interfacesWithBothServers = (config.tunnelInterfaces || []).filter(i =>
i.serverId && i.serverId2 && i.localIp && i.remoteIp
);
return buildMikrotikInterfaceBlocks(interfacesWithBothServers);
};
// === Генерация кода MikroTik только для выбранных интерфейсов ===
const generateMikrotikInterfaceAddressesForSelection = async (selectedInterfaces) => {
const interfacesWithBothServers = (selectedInterfaces || []).filter(i =>
i.serverId && i.serverId2 && i.localIp && i.remoteIp
);
return buildMikrotikInterfaceBlocks(interfacesWithBothServers);
};
// === Генерация кода MikroTik для рекурсивных маршрутов ===
const generateMikrotikRecursiveRoutes = async () => {
const recursiveGateways = (config.gateways || []).filter(gw => gw.type === 'recursive');
@@ -1648,6 +1662,30 @@ function NetworkConfigManager() {
}
};
// === Генерация кода MikroTik только для одного интерфейса ===
const handleGenerateMikrotikCodeForInterface = async (iface) => {
if (!iface) {
notify.error('Интерфейс не найден');
return;
}
setLoading(true);
try {
const blocks = await generateMikrotikInterfaceAddressesForSelection([iface]);
if (!blocks || blocks.length === 0) {
notify.error('Нет данных для генерации кода MikroTik для этого интерфейса');
return;
}
setGeneratedMikrotikCode(blocks);
setMikrotikCodeModalOpen(true);
} catch (error) {
console.error('Error generating MikroTik code for interface:', error);
notify.error('Ошибка при генерации кода MikroTik для этого интерфейса');
} finally {
setLoading(false);
}
};
// === Копирование кода MikroTik ===
const handleCopyMikrotikCode = async (codeToCopy) => {
if (!codeToCopy) {
@@ -2160,6 +2198,13 @@ function NetworkConfigManager() {
{/* Правая часть: действия */}
<div className="d-flex align-items-center gap-2 px-3 border-start" style={{ flexShrink: 0 }}>
<button
className="btn btn-outline-primary btn-sm"
onClick={() => handleGenerateMikrotikCodeForInterface(iface)}
>
<IconCode size={16} className="me-1" />
Код
</button>
<button
className="btn btn-outline-secondary btn-sm"
onClick={() => handleEditInterface(iface)}
@@ -2716,6 +2761,13 @@ function NetworkConfigManager() {
</td>
<td className="text-end">
<div className="btn-list gap-1 mb-0 justify-content-end">
<button
className="btn btn-ghost-primary btn-icon btn-sm"
onClick={() => handleGenerateMikrotikCodeForInterface(iface)}
title="Код для MikroTik (только для этого интерфейса)"
>
<IconCode size={16} />
</button>
<button
className="btn btn-ghost-primary btn-icon btn-sm"
onClick={() => handleEditInterface(iface)}