this is some ahh stuff
This commit is contained in:
@@ -160,6 +160,8 @@ export function DevicesPage({ agents, onAfterWake }: Props) {
|
|||||||
const sortedDevices = useMemo(() => {
|
const sortedDevices = useMemo(() => {
|
||||||
const rows = [...devices];
|
const rows = [...devices];
|
||||||
rows.sort((a, b) => {
|
rows.sort((a, b) => {
|
||||||
|
// Pinned always float to top
|
||||||
|
if (a.pinned !== b.pinned) return a.pinned ? -1 : 1;
|
||||||
const dir = sort.dir === "asc" ? 1 : -1;
|
const dir = sort.dir === "asc" ? 1 : -1;
|
||||||
if (sort.key === "presence") {
|
if (sort.key === "presence") {
|
||||||
return dir * (presenceRank(a.presence) - presenceRank(b.presence));
|
return dir * (presenceRank(a.presence) - presenceRank(b.presence));
|
||||||
@@ -361,8 +363,17 @@ function FleetDeviceRow({
|
|||||||
onDetails: () => void;
|
onDetails: () => void;
|
||||||
onCopy: (label: string, value: string) => void;
|
onCopy: (label: string, value: string) => void;
|
||||||
}) {
|
}) {
|
||||||
|
const presenceBorder =
|
||||||
|
device.presence === "online"
|
||||||
|
? "border-l-emerald-500/70"
|
||||||
|
: device.presence === "likely_online"
|
||||||
|
? "border-l-sky-500/60"
|
||||||
|
: device.presence === "offline"
|
||||||
|
? "border-l-muted-foreground/20"
|
||||||
|
: "";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid gap-3 rounded-md border bg-card px-3 py-3 text-sm xl:grid-cols-[minmax(10rem,1.3fr)_8rem_minmax(9rem,1fr)_minmax(10rem,1fr)_minmax(10rem,1fr)_8rem_8rem] xl:items-center xl:gap-2">
|
<div className={`grid gap-3 rounded-md border border-l-[3px] ${presenceBorder} bg-card px-3 py-3 text-sm xl:grid-cols-[minmax(10rem,1.3fr)_8rem_minmax(9rem,1fr)_minmax(10rem,1fr)_minmax(10rem,1fr)_8rem_8rem] xl:items-center xl:gap-2`}>
|
||||||
<button className="min-w-0 text-left" type="button" onClick={onDetails}>
|
<button className="min-w-0 text-left" type="button" onClick={onDetails}>
|
||||||
<div className="truncate font-medium">{device.display_name}</div>
|
<div className="truncate font-medium">{device.display_name}</div>
|
||||||
<div className="mt-1 flex flex-wrap gap-1">
|
<div className="mt-1 flex flex-wrap gap-1">
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ pub(crate) struct AgentRuntimeStatus {
|
|||||||
pub(crate) connected: bool,
|
pub(crate) connected: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug)]
|
||||||
struct FleetAccumulator {
|
struct FleetAccumulator {
|
||||||
device_key: String,
|
device_key: String,
|
||||||
display_name: Option<String>,
|
display_name: Option<String>,
|
||||||
@@ -37,6 +37,26 @@ struct FleetAccumulator {
|
|||||||
routes: BTreeMap<String, FleetWakeRoute>,
|
routes: BTreeMap<String, FleetWakeRoute>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for FleetAccumulator {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
device_key: String::new(),
|
||||||
|
display_name: None,
|
||||||
|
known_device: None,
|
||||||
|
pinned: false,
|
||||||
|
ips: BTreeSet::new(),
|
||||||
|
macs: BTreeSet::new(),
|
||||||
|
hostnames: BTreeSet::new(),
|
||||||
|
sources: BTreeSet::new(),
|
||||||
|
agents: BTreeMap::new(),
|
||||||
|
first_seen_unix: None,
|
||||||
|
last_seen_unix: None,
|
||||||
|
presence: Presence::Offline,
|
||||||
|
routes: BTreeMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn build_fleet_devices(
|
pub(crate) fn build_fleet_devices(
|
||||||
known_devices: Vec<KnownDevice>,
|
known_devices: Vec<KnownDevice>,
|
||||||
agent_devices: Vec<AgentDeviceWithChildren>,
|
agent_devices: Vec<AgentDeviceWithChildren>,
|
||||||
|
|||||||
@@ -7,16 +7,19 @@ use crate::model::{DhcpLease, NeighborEntry, NeighborState};
|
|||||||
use crate::parse::mac;
|
use crate::parse::mac;
|
||||||
|
|
||||||
/// Product-level presence derived from raw neighbor state.
|
/// Product-level presence derived from raw neighbor state.
|
||||||
|
///
|
||||||
|
/// Variant order defines `Ord`: Offline < Unknown < LikelyOnline < Online.
|
||||||
|
/// `std::cmp::max` picks the most-online signal when merging.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug, PartialEq, Eq, Clone, Copy, Hash, Ord, PartialOrd, Serialize, serde::Deserialize, Default,
|
Debug, PartialEq, Eq, Clone, Copy, Hash, Ord, PartialOrd, Serialize, serde::Deserialize, Default,
|
||||||
)]
|
)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum Presence {
|
pub enum Presence {
|
||||||
Online,
|
Offline,
|
||||||
LikelyOnline,
|
|
||||||
#[default]
|
#[default]
|
||||||
Unknown,
|
Unknown,
|
||||||
Offline,
|
LikelyOnline,
|
||||||
|
Online,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Presence {
|
impl Presence {
|
||||||
|
|||||||
Reference in New Issue
Block a user