From 46d080e70af65cdfcb63a4e9ea239808c0490db2 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Mon, 30 Mar 2026 23:58:05 +0700 Subject: [PATCH] Enhance IP display and server presence in Svelte components - Added `IpServerPresence` component to streamline the display of active and recent servers for IPs, improving code readability and maintainability. - Introduced tooltips for the "Servers" column in tables to provide additional context on active and recent server lists, enhancing user experience. - Updated text descriptions for clarity and consistency across the IP and user pages, ensuring better understanding of the displayed data. --- .../lib/components/ip-server-presence.svelte | 120 ++++++++++++++++++ web/src/routes/ips/+page.svelte | 65 +++++----- web/src/routes/users/[username]/+page.svelte | 43 +++++-- 3 files changed, 182 insertions(+), 46 deletions(-) create mode 100644 web/src/lib/components/ip-server-presence.svelte diff --git a/web/src/lib/components/ip-server-presence.svelte b/web/src/lib/components/ip-server-presence.svelte new file mode 100644 index 0000000..5326229 --- /dev/null +++ b/web/src/lib/components/ip-server-presence.svelte @@ -0,0 +1,120 @@ + + +
+ {#if activeServers.length > 0} +
+
+ Активные + + + + + +

+ Серверы, где этот IP есть в списке активных уникальных адресов на момент снимка + шлюза. +

+
+
+
+
+ {#each activeServers as srv (srv)} + {#if primary_server && srv === primary_server && activeServers.length === 1} + + + + + + +

{soleActiveTip}

+
+
+ {:else} + + {srv} + + {/if} + {/each} +
+
+ {:else} + + {recentOnly.length > 0 ? 'Нет в активных' : '—'} + + {/if} + + {#if recentOnly.length > 0} + {#if activeServers.length > 0} + + {/if} +
+
+ Только недавние + + + + + +

+ Серверы, где IP есть в недавнем списке, но на этом снимке не в активных — например + недавнее подключение с другого шлюза. +

+
+
+
+
+ {#each recentOnly as srv (srv)} + + {srv} + + {/each} +
+
+ {/if} +
diff --git a/web/src/routes/ips/+page.svelte b/web/src/routes/ips/+page.svelte index d29c1d4..62c8d3d 100644 --- a/web/src/routes/ips/+page.svelte +++ b/web/src/routes/ips/+page.svelte @@ -12,10 +12,13 @@ import { Button } from '$lib/components/ui/button/index.js'; import { Badge } from '$lib/components/ui/badge/index.js'; import * as Table from '$lib/components/ui/table/index.js'; + import * as Tooltip from '$lib/components/ui/tooltip/index.js'; + import IpServerPresence from '$lib/components/ip-server-presence.svelte'; import { Skeleton } from '$lib/components/ui/skeleton/index.js'; import { Switch } from '$lib/components/ui/switch/index.js'; import { Label } from '$lib/components/ui/label/index.js'; import RefreshCwIcon from '@lucide/svelte/icons/refresh-cw'; + import InfoIcon from '@lucide/svelte/icons/info'; import AliasFilterSelect from '$lib/components/alias-filter-select.svelte'; import DataQueryState from '$lib/components/fleet/data-query-state.svelte'; import FleetLiveStaleBadge from '$lib/components/fleet/fleet-live-stale-badge.svelte'; @@ -428,7 +431,9 @@

Уникальные IP

-

Снимок active/recent с шлюза; GeoIP из конфига шлюза.

+

+ Снимок активных и недавних списков с шлюза; GeoIP из конфига шлюза. +

@@ -500,7 +505,7 @@ Карта подключений - GeoIP координаты из снимка `unique-ips` + GeoIP координаты из снимка unique-ips
@@ -531,7 +536,24 @@ Пользователь IP Geo - Серверы + +
+ Серверы + + + + + +

+ Активные и недавние — списки на момент снимка шлюза; в ячейке пояснены группы. +

+
+
+
+
@@ -554,37 +576,12 @@ AS{ip.asn} {/if} - - {@const activeServers = (ip.active_on_servers ?? []).filter(Boolean)} - {@const recentServers = (ip.recent_on_servers ?? []).filter(Boolean)} - {@const primaryServer = ip.primary_server ?? null} - {@const recentOnly = recentServers.filter((s) => !activeServers.includes(s))} - - {#if activeServers.length === 0} - - {:else} -
- {#each activeServers as srv (srv)} - - {srv} - - {#if primaryServer && srv === primaryServer} - primary - {/if} - {/each} -
- {/if} - - {#if recentOnly.length > 0} -
- recent - {#each recentOnly as srv (srv)} - - {srv} - - {/each} -
- {/if} + + {/each} diff --git a/web/src/routes/users/[username]/+page.svelte b/web/src/routes/users/[username]/+page.svelte index 3d636e0..9db182d 100644 --- a/web/src/routes/users/[username]/+page.svelte +++ b/web/src/routes/users/[username]/+page.svelte @@ -9,7 +9,10 @@ import { Badge } from '$lib/components/ui/badge/index.js'; import { Button } from '$lib/components/ui/button/index.js'; import * as Table from '$lib/components/ui/table/index.js'; + import * as Tooltip from '$lib/components/ui/tooltip/index.js'; + import IpServerPresence from '$lib/components/ip-server-presence.svelte'; import CopyIcon from '@lucide/svelte/icons/copy'; + import InfoIcon from '@lucide/svelte/icons/info'; import { toast } from 'svelte-sonner'; let loading = $state(true); @@ -187,7 +190,9 @@ IP и подключения - active/recent с серверами и Geo/ASN (если доступно) + + Снимок шлюза: активные и недавние списки по серверам; Geo/ASN при доступности данных. + {#if ipErr} @@ -202,7 +207,25 @@ IP - Серверы + +
+ Серверы + + + + + +

+ Активные и недавние — это списки на момент снимка шлюза; в ячейке коротко + пояснено, что означает каждая группа. +

+
+
+
+
Geo / ASN
@@ -224,16 +247,12 @@ > {ip.ip}
- - active: {((ip.active_on_servers ?? []).filter(Boolean) as string[]).join(', ') || '—'} - {#if (ip.recent_on_servers?.length ?? 0) > 0} -
- recent: {(ip.recent_on_servers ?? []).filter(Boolean).join(', ')} - {/if} - {#if ip.primary_server} -
- primary: {ip.primary_server} - {/if} + +