feat(NetworkConfigManager): enhance IP registry with server information; display unique servers for each IP and improve interface management
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m36s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m36s
This commit is contained in:
@@ -479,12 +479,17 @@ function NetworkConfigManager() {
|
|||||||
|
|
||||||
// Собираем IP из интерфейсов
|
// Собираем IP из интерфейсов
|
||||||
(config.tunnelInterfaces || []).forEach(iface => {
|
(config.tunnelInterfaces || []).forEach(iface => {
|
||||||
|
const server = getServerInfo(iface.serverId);
|
||||||
|
const server2 = getServerInfo(iface.serverId2);
|
||||||
|
|
||||||
if (iface.localIp && iface.localIp.trim()) {
|
if (iface.localIp && iface.localIp.trim()) {
|
||||||
registry.push({
|
registry.push({
|
||||||
ip: iface.localIp.trim(),
|
ip: iface.localIp.trim(),
|
||||||
type: 'localIp',
|
type: 'localIp',
|
||||||
interface: iface,
|
interface: iface,
|
||||||
interfaceName: iface.name || iface.id
|
interfaceName: iface.name || iface.id,
|
||||||
|
server: server,
|
||||||
|
server2: server2
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (iface.remoteIp && iface.remoteIp.trim()) {
|
if (iface.remoteIp && iface.remoteIp.trim()) {
|
||||||
@@ -492,7 +497,9 @@ function NetworkConfigManager() {
|
|||||||
ip: iface.remoteIp.trim(),
|
ip: iface.remoteIp.trim(),
|
||||||
type: 'remoteIp',
|
type: 'remoteIp',
|
||||||
interface: iface,
|
interface: iface,
|
||||||
interfaceName: iface.name || iface.id
|
interfaceName: iface.name || iface.id,
|
||||||
|
server: server,
|
||||||
|
server2: server2
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -509,7 +516,9 @@ function NetworkConfigManager() {
|
|||||||
groupedByIp[item.ip].interfaces.push({
|
groupedByIp[item.ip].interfaces.push({
|
||||||
type: item.type,
|
type: item.type,
|
||||||
interface: item.interface,
|
interface: item.interface,
|
||||||
interfaceName: item.interfaceName
|
interfaceName: item.interfaceName,
|
||||||
|
server: item.server,
|
||||||
|
server2: item.server2
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -518,7 +527,14 @@ function NetworkConfigManager() {
|
|||||||
.map(item => ({
|
.map(item => ({
|
||||||
...item,
|
...item,
|
||||||
usageCount: item.interfaces.length,
|
usageCount: item.interfaces.length,
|
||||||
hasConflict: item.interfaces.length > 1 // Конфликт если IP используется в нескольких интерфейсах
|
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) => {
|
.sort((a, b) => {
|
||||||
// Сначала конфликты, потом по IP
|
// Сначала конфликты, потом по IP
|
||||||
@@ -527,7 +543,7 @@ function NetworkConfigManager() {
|
|||||||
}
|
}
|
||||||
return a.ip.localeCompare(b.ip);
|
return a.ip.localeCompare(b.ip);
|
||||||
});
|
});
|
||||||
}, [config.tunnelInterfaces]);
|
}, [config.tunnelInterfaces, servers]);
|
||||||
|
|
||||||
// === Фильтрация реестра IP ===
|
// === Фильтрация реестра IP ===
|
||||||
const filteredIpRegistry = useMemo(() => {
|
const filteredIpRegistry = useMemo(() => {
|
||||||
@@ -1989,7 +2005,7 @@ function NetworkConfigManager() {
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>IP адрес</th>
|
<th>IP адрес</th>
|
||||||
<th>Использование</th>
|
<th>Сервер</th>
|
||||||
<th>Интерфейсы</th>
|
<th>Интерфейсы</th>
|
||||||
<th className="text-end">Действия</th>
|
<th className="text-end">Действия</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -2008,9 +2024,15 @@ function NetworkConfigManager() {
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span className="badge bg-primary-lt text-primary">
|
<div className="d-flex flex-column gap-1">
|
||||||
{item.usageCount} {item.usageCount === 1 ? 'раз' : 'раза'}
|
{item.servers.map((serverName, sIdx) => (
|
||||||
</span>
|
<div key={sIdx} className="d-flex align-items-center">
|
||||||
|
<IconServer size={14} className="text-muted me-1" />
|
||||||
|
<span>{serverName}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{item.servers.length === 0 && <span className="text-muted">—</span>}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div className="d-flex flex-column gap-1">
|
<div className="d-flex flex-column gap-1">
|
||||||
|
|||||||
Reference in New Issue
Block a user