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;
|
||||
});
|
||||
|
||||
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 n = 0;
|
||||
for (const s of fleet?.servers ?? []) {
|
||||
@@ -459,14 +473,30 @@
|
||||
<Card.Title>Топ пользователей по трафику</Card.Title>
|
||||
</Card.Header>
|
||||
<Card.Content>
|
||||
<ul class="space-y-1 text-sm">
|
||||
{#each summary.top_users.slice(0, 10) as t (t.username)}
|
||||
<li class="flex justify-between gap-4">
|
||||
<a href="/users/{encodeURIComponent(t.username)}" class="text-primary hover:underline">{t.username}</a>
|
||||
<span class="text-muted-foreground tabular-nums">{formatMiB(t.total_megabytes)}</span>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.Head>Пользователь</Table.Head>
|
||||
<Table.Head class="text-right">Трафик</Table.Head>
|
||||
<Table.Head class="text-right">Замеченные IP</Table.Head>
|
||||
</Table.Row>
|
||||
</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.Root>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user