Endpoints table improvements / sort
This commit is contained in:
@@ -1,57 +0,0 @@
|
|||||||
# lda rambling
|
|
||||||
|
|
||||||
currently the collection of fleetwakeroutes doesnt make much sense.
|
|
||||||
|
|
||||||
it goes deep. Read code, then this again.
|
|
||||||
|
|
||||||
## big fleet shows everything.
|
|
||||||
|
|
||||||
all the IPs, offline or not. I at least want to hide the offline/unknown IPs into a drawer somewhere. its too cluttered.
|
|
||||||
|
|
||||||
i do need offline IPs, because, a failed / dhcp-rotated IP may be of use. but what use? copying only. You cant even send shit to it, its FAILED.
|
|
||||||
|
|
||||||
so not all the IPs should be immediately invisible.
|
|
||||||
|
|
||||||
## big fleet DOESNT show everything
|
|
||||||
|
|
||||||
yea showing all the offline IP but only ONE online ip per mac for wake routes.
|
|
||||||
|
|
||||||
BRING This BACK. i need ALL the routes. Color coded (already has that with disabled wake button)
|
|
||||||
|
|
||||||
## big collect collects everything
|
|
||||||
|
|
||||||
at wakey, collection makes no sense; a device saves all IPs without saying which of them is not real.
|
|
||||||
|
|
||||||
oh you do have to search again for the observations because they are unknown ahh hints,
|
|
||||||
|
|
||||||
## logics are misleading
|
|
||||||
|
|
||||||
also IPs without macs are unknown, (should be OFFLINE? ips without macs? what do you think it is)
|
|
||||||
while macs without ips are offline (pulled straight from the Big Mac Name cache)
|
|
||||||
|
|
||||||
what is this ahh logic
|
|
||||||
|
|
||||||
## struct names are misleading
|
|
||||||
|
|
||||||
Big Device over here, collected (fresh AND old) From the router ITSELF. Is BY MAC.
|
|
||||||
|
|
||||||
but the Device struct was designed to take multiple MACs, Why. This is very misleading.
|
|
||||||
|
|
||||||
The migration was from Observations, which is a string fest, to Device, which
|
|
||||||
|
|
||||||
1. give up the very cool observations based design, which fundamentally is just tracking identifing pairs of (ip, mac, maybe hostname)
|
|
||||||
2. doesnt solve the confusing ahh mac-keyed Devices. Why is the deviceid optional? What!
|
|
||||||
|
|
||||||
## big code needs a rewrite
|
|
||||||
|
|
||||||
i think we need to have a very clear model. And such model is ALREADY PRESENT! fleet wake route MIGHT be the coolest thing ever, solves everything.
|
|
||||||
|
|
||||||
Should type instead of free string construction. For example. alot of the keys are currently freehanded. You need a struct with Display or ToString or a dedicated method.
|
|
||||||
hopefully those keys can have a helper contructor. HOPEFULLY NOONE PULLS INFO OUT OF THE STRING BY SLICING IT.
|
|
||||||
|
|
||||||
If you want to keep just device.macs, device.ips, you can, we need to collect the Wake routes! which goes deep,
|
|
||||||
|
|
||||||
but is reasonable, because there are two sources that give us identifiers, neighbors and observations. We flatten this to device, at the router its keyed by mac or failed ip.
|
|
||||||
At the fleet idfk, i dont control that part of the code; its all AI.
|
|
||||||
|
|
||||||
So, if we can collect wake targets directly from device. Saves a whole plane of problems. suddenly wakey-cc is like 6 million times slimmer, because this is a wakey or wakey-core problem.
|
|
||||||
@@ -34,6 +34,7 @@ import {
|
|||||||
agentLabel,
|
agentLabel,
|
||||||
formatSeen,
|
formatSeen,
|
||||||
identifiersFor,
|
identifiersFor,
|
||||||
|
presenceRank,
|
||||||
routeLabel,
|
routeLabel,
|
||||||
} from "@/pages/fleet/utils";
|
} from "@/pages/fleet/utils";
|
||||||
|
|
||||||
@@ -189,7 +190,7 @@ export function FleetDeviceDetailsDialog({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
<DialogContent className="max-h-[92vh] overflow-auto sm:max-w-3xl">
|
<DialogContent className="max-h-[92vh] overflow-auto sm:max-w-4xl">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<div className="flex min-w-0 items-start justify-between gap-3 pr-8">
|
<div className="flex min-w-0 items-start justify-between gap-3 pr-8">
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
@@ -237,14 +238,26 @@ export function FleetDeviceDetailsDialog({
|
|||||||
<Badge variant="outline">{device.endpoints.length}</Badge>
|
<Badge variant="outline">{device.endpoints.length}</Badge>
|
||||||
</div>
|
</div>
|
||||||
{device.endpoints.length ? (
|
{device.endpoints.length ? (
|
||||||
<div className="divide-y overflow-hidden rounded-md border">
|
<div className="grid gap-1.5">
|
||||||
{device.endpoints.map((endpoint, index) => (
|
<div className="hidden grid-cols-[minmax(0,1.3fr)_minmax(0,1fr)_8rem_2rem] items-center gap-2 px-3 py-1.5 text-xs font-medium text-muted-foreground sm:grid">
|
||||||
<EndpointRow
|
<span>Source</span>
|
||||||
key={`${endpoint.agent_id}:${endpoint.source}:${endpoint.mac ?? ""}:${endpoint.ip ?? ""}:${index}`}
|
<span>Target</span>
|
||||||
endpoint={endpoint}
|
<span className="text-right">Last seen</span>
|
||||||
onCopy={onCopy}
|
<span />
|
||||||
/>
|
</div>
|
||||||
))}
|
{[...device.endpoints]
|
||||||
|
.sort((a, b) => {
|
||||||
|
const p = presenceRank(b.presence) - presenceRank(a.presence);
|
||||||
|
if (p !== 0) return p;
|
||||||
|
return (b.last_seen_unix ?? 0) - (a.last_seen_unix ?? 0);
|
||||||
|
})
|
||||||
|
.map((endpoint, index) => (
|
||||||
|
<EndpointRow
|
||||||
|
key={`${endpoint.agent_id}:${endpoint.source}:${endpoint.mac ?? ""}:${endpoint.ip ?? ""}:${index}`}
|
||||||
|
endpoint={endpoint}
|
||||||
|
onCopy={onCopy}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<p className="rounded-md border bg-muted/30 p-3 text-sm text-muted-foreground">
|
<p className="rounded-md border bg-muted/30 p-3 text-sm text-muted-foreground">
|
||||||
@@ -557,7 +570,7 @@ function EndpointRow({
|
|||||||
.join(" / ");
|
.join(" / ");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid gap-2 p-3 text-sm sm:grid-cols-[minmax(0,1.35fr)_minmax(0,1fr)_auto] sm:items-center">
|
<div className="grid gap-3 rounded-md border bg-card px-3 py-2.5 text-sm sm:grid-cols-[minmax(0,1.3fr)_minmax(0,1fr)_8rem_2rem] sm:items-center sm:gap-2">
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<div className="flex min-w-0 flex-wrap items-center gap-1.5">
|
<div className="flex min-w-0 flex-wrap items-center gap-1.5">
|
||||||
<PresenceBadge presence={endpoint.presence} />
|
<PresenceBadge presence={endpoint.presence} />
|
||||||
@@ -570,14 +583,14 @@ function EndpointRow({
|
|||||||
</div>
|
</div>
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<p className="truncate font-mono text-xs">{target || "-"}</p>
|
<p className="truncate font-mono text-xs">{target || "-"}</p>
|
||||||
<p className="truncate text-xs text-muted-foreground">
|
<p className="mt-0.5 truncate text-xs text-muted-foreground">
|
||||||
{location || "No interface or hostname"}
|
{location || "No interface or hostname"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between gap-2 sm:justify-end">
|
<span className="whitespace-nowrap text-right text-xs text-muted-foreground">
|
||||||
<span className="text-xs text-muted-foreground">
|
{formatSeen(endpoint.last_seen_unix)}
|
||||||
{formatSeen(endpoint.last_seen_unix)}
|
</span>
|
||||||
</span>
|
<div className="flex justify-end">
|
||||||
{target && (
|
{target && (
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|||||||
Reference in New Issue
Block a user