Add unique IP count by user in the user traffic table
- Introduced a derived state to calculate the count of unique IPs associated with each user, enhancing the data presented in the user traffic table. - Replaced the previous unordered list with a structured table format for better readability and organization of user traffic and IP data. - Updated the user interface to display the number of unique IPs alongside user traffic metrics, improving the overall user experience and data clarity.
This commit is contained in:
@@ -160,6 +160,20 @@
|
|||||||
return set.size;
|
return set.size;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let uniqueIpCountByUser = $derived.by((): Record<string, number> => {
|
||||||
|
const byUser: Record<string, number> = {};
|
||||||
|
for (const row of uniqueIps ?? []) {
|
||||||
|
const username = row.username ?? '';
|
||||||
|
if (!username) continue;
|
||||||
|
const set = new Set<string>();
|
||||||
|
for (const ip of row.ips ?? []) {
|
||||||
|
if (ip.ip) set.add(ip.ip);
|
||||||
|
}
|
||||||
|
byUser[username] = set.size;
|
||||||
|
}
|
||||||
|
return byUser;
|
||||||
|
});
|
||||||
|
|
||||||
let readOnlyNodes = $derived.by(() => {
|
let readOnlyNodes = $derived.by(() => {
|
||||||
let n = 0;
|
let n = 0;
|
||||||
for (const s of fleet?.servers ?? []) {
|
for (const s of fleet?.servers ?? []) {
|
||||||
@@ -459,14 +473,30 @@
|
|||||||
<Card.Title>Топ пользователей по трафику</Card.Title>
|
<Card.Title>Топ пользователей по трафику</Card.Title>
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
<ul class="space-y-1 text-sm">
|
<Table.Root>
|
||||||
{#each summary.top_users.slice(0, 10) as t (t.username)}
|
<Table.Header>
|
||||||
<li class="flex justify-between gap-4">
|
<Table.Row>
|
||||||
<a href="/users/{encodeURIComponent(t.username)}" class="text-primary hover:underline">{t.username}</a>
|
<Table.Head>Пользователь</Table.Head>
|
||||||
<span class="text-muted-foreground tabular-nums">{formatMiB(t.total_megabytes)}</span>
|
<Table.Head class="text-right">Трафик</Table.Head>
|
||||||
</li>
|
<Table.Head class="text-right">Замеченные IP</Table.Head>
|
||||||
{/each}
|
</Table.Row>
|
||||||
</ul>
|
</Table.Header>
|
||||||
|
<Table.Body>
|
||||||
|
{#each summary.top_users.slice(0, 10) as t (t.username)}
|
||||||
|
<Table.Row>
|
||||||
|
<Table.Cell class="font-medium">
|
||||||
|
<a href="/users/{encodeURIComponent(t.username)}" class="text-primary hover:underline">
|
||||||
|
{t.username}
|
||||||
|
</a>
|
||||||
|
</Table.Cell>
|
||||||
|
<Table.Cell class="text-right text-muted-foreground tabular-nums">{formatMiB(t.total_megabytes)}</Table.Cell>
|
||||||
|
<Table.Cell class="text-right text-muted-foreground tabular-nums">
|
||||||
|
{uniqueIpCountByUser[t.username] ?? 0}
|
||||||
|
</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
{/each}
|
||||||
|
</Table.Body>
|
||||||
|
</Table.Root>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card.Root>
|
</Card.Root>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
Reference in New Issue
Block a user