Refactor active IP-server data handling in user traffic table
- Updated the data structure to store multiple servers associated with each user, enhancing the representation of active connections. - Improved the logic for generating active IP-server rows, utilizing a map for better performance and organization. - Modified the UI to display a list of servers for each user, improving clarity and usability in the user traffic table.
This commit is contained in:
+46
-30
@@ -213,17 +213,19 @@
|
|||||||
username: string;
|
username: string;
|
||||||
ip: string;
|
ip: string;
|
||||||
country_code: string | null | undefined;
|
country_code: string | null | undefined;
|
||||||
server: string;
|
servers: string[];
|
||||||
activeLabel: string;
|
activeLabel: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
let activeIpServerRows = $derived.by((): ActiveIpServerRow[] => {
|
let activeIpServerRows = $derived.by((): ActiveIpServerRow[] => {
|
||||||
const out: ActiveIpServerRow[] = [];
|
const map = new Map<
|
||||||
const seen = new Set<string>();
|
string,
|
||||||
|
{ row: Omit<ActiveIpServerRow, 'servers'>; serversSet: Set<string> }
|
||||||
|
>();
|
||||||
const maxUniqueIpRows = 80;
|
const maxUniqueIpRows = 80;
|
||||||
const maxOutRows = 2000;
|
const maxOutRows = 2000;
|
||||||
|
|
||||||
for (const ur of uniqueIps?.slice(0, maxUniqueIpRows) ?? []) {
|
outer: for (const ur of uniqueIps?.slice(0, maxUniqueIpRows) ?? []) {
|
||||||
const username = ur.username ?? '';
|
const username = ur.username ?? '';
|
||||||
if (!username) continue;
|
if (!username) continue;
|
||||||
|
|
||||||
@@ -231,32 +233,41 @@
|
|||||||
const ip = ipa.ip ?? '';
|
const ip = ipa.ip ?? '';
|
||||||
if (!ip) continue;
|
if (!ip) continue;
|
||||||
|
|
||||||
const servers = ipa.active_on_servers ?? [];
|
const servers = (ipa.active_on_servers ?? []).filter(Boolean);
|
||||||
if (servers.length === 0) continue;
|
if (servers.length === 0) continue;
|
||||||
|
|
||||||
|
const key = `${username}|${ip}`;
|
||||||
|
let item = map.get(key);
|
||||||
|
if (!item) {
|
||||||
|
if (map.size >= maxOutRows) break outer;
|
||||||
|
item = {
|
||||||
|
row: {
|
||||||
|
username,
|
||||||
|
ip,
|
||||||
|
country_code: ipa.country_code,
|
||||||
|
activeLabel: chipLabel(ipa)
|
||||||
|
},
|
||||||
|
serversSet: new Set<string>()
|
||||||
|
};
|
||||||
|
map.set(key, item);
|
||||||
|
}
|
||||||
|
|
||||||
for (const server of servers) {
|
for (const server of servers) {
|
||||||
if (!server) continue;
|
if (!server) continue;
|
||||||
const key = `${username}|${ip}|${server}`;
|
item.serversSet.add(server);
|
||||||
if (seen.has(key)) continue;
|
|
||||||
seen.add(key);
|
|
||||||
|
|
||||||
out.push({
|
|
||||||
username,
|
|
||||||
ip,
|
|
||||||
country_code: ipa.country_code,
|
|
||||||
server,
|
|
||||||
activeLabel: chipLabel(ipa)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (out.length >= maxOutRows) return out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out.sort(
|
const out: ActiveIpServerRow[] = [];
|
||||||
(a, b) =>
|
for (const { row, serversSet } of map.values()) {
|
||||||
a.ip.localeCompare(b.ip) || a.server.localeCompare(b.server) || a.username.localeCompare(b.username)
|
out.push({
|
||||||
);
|
...row,
|
||||||
|
servers: [...serversSet].sort((a, b) => a.localeCompare(b))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
out.sort((a, b) => a.ip.localeCompare(b.ip) || a.username.localeCompare(b.username));
|
||||||
return out;
|
return out;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -443,7 +454,7 @@
|
|||||||
<Table.Row>
|
<Table.Row>
|
||||||
<Table.Head>IP со страной</Table.Head>
|
<Table.Head>IP со страной</Table.Head>
|
||||||
<Table.Head>Клиент</Table.Head>
|
<Table.Head>Клиент</Table.Head>
|
||||||
<Table.Head>Сервер</Table.Head>
|
<Table.Head>Серверы</Table.Head>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
</Table.Header>
|
</Table.Header>
|
||||||
<Table.Body>
|
<Table.Body>
|
||||||
@@ -454,7 +465,7 @@
|
|||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
{:else}
|
{:else}
|
||||||
{#each activeIpServerRows as r (r.username + '|' + r.ip + '|' + r.server)}
|
{#each activeIpServerRows as r (r.username + '|' + r.ip)}
|
||||||
<Table.Row>
|
<Table.Row>
|
||||||
<Table.Cell class="font-mono text-sm">
|
<Table.Cell class="font-mono text-sm">
|
||||||
{r.activeLabel}
|
{r.activeLabel}
|
||||||
@@ -468,12 +479,17 @@
|
|||||||
</a>
|
</a>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>
|
<Table.Cell>
|
||||||
<a
|
{#each r.servers as srv, idx (srv)}
|
||||||
href="/servers/{encodeURIComponent(r.server)}"
|
<a
|
||||||
class="text-primary hover:underline"
|
href="/servers/{encodeURIComponent(srv)}"
|
||||||
>
|
class="text-primary hover:underline"
|
||||||
{r.server}
|
>
|
||||||
</a>
|
{srv}
|
||||||
|
</a>
|
||||||
|
{#if idx < r.servers.length - 1}
|
||||||
|
<span class="text-muted-foreground">, </span>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
Reference in New Issue
Block a user