add site online indicator to selector

This commit is contained in:
miloschwartz
2026-04-22 14:33:28 -07:00
parent ea4ff75552
commit 4c000c1d49
2 changed files with 56 additions and 4 deletions

View File

@@ -12,7 +12,7 @@ import {
import { Checkbox } from "./ui/checkbox"; import { Checkbox } from "./ui/checkbox";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import { useDebounce } from "use-debounce"; import { useDebounce } from "use-debounce";
import type { Selectedsite } from "./site-selector"; import { SiteOnlineStatus, type Selectedsite } from "./site-selector";
export type MultiSitesSelectorProps = { export type MultiSitesSelectorProps = {
orgId: string; orgId: string;
@@ -107,7 +107,16 @@ export function MultiSitesSelector({
aria-hidden aria-hidden
tabIndex={-1} tabIndex={-1}
/> />
<span className="truncate">{site.name}</span> <div className="min-w-0 flex-1 flex items-center gap-2">
<span className="min-w-0 flex-1 truncate">
{site.name}
</span>
<SiteOnlineStatus
type={site.type}
online={site.online}
t={t}
/>
</div>
</CommandItem> </CommandItem>
))} ))}
</CommandGroup> </CommandGroup>

View File

@@ -18,7 +18,41 @@ import { useDebounce } from "use-debounce";
export type Selectedsite = Pick< export type Selectedsite = Pick<
ListSitesResponse["sites"][number], ListSitesResponse["sites"][number],
"name" | "siteId" | "type" "name" | "siteId" | "type"
>; > & {
/** When omitted, no online/offline indicator is shown. */
online?: ListSitesResponse["sites"][number]["online"];
};
type SiteOnlineStatusProps = {
type: Selectedsite["type"];
online: Selectedsite["online"];
t: (key: "online" | "offline") => string;
};
/** Dot-only indicator matching `SitesTable` colors (newt/wireguard only; nothing for local or missing status). */
export function SiteOnlineStatus({ type, online, t }: SiteOnlineStatusProps) {
if (type !== "newt" && type !== "wireguard") {
return null;
}
if (typeof online !== "boolean") {
return null;
}
return (
<span
className="shrink-0 flex items-center"
role="img"
aria-label={online ? t("online") : t("offline")}
>
<div
className={
online
? "w-2 h-2 bg-green-500 rounded-full"
: "w-2 h-2 bg-neutral-500 rounded-full"
}
/>
</span>
);
}
export type SitesSelectorProps = { export type SitesSelectorProps = {
orgId: string; orgId: string;
@@ -86,7 +120,16 @@ export function SitesSelector({
: "opacity-0" : "opacity-0"
)} )}
/> />
{site.name} <div className="min-w-0 flex-1 flex items-center gap-2">
<span className="min-w-0 flex-1 truncate">
{site.name}
</span>
<SiteOnlineStatus
type={site.type}
online={site.online}
t={t}
/>
</div>
</CommandItem> </CommandItem>
))} ))}
</CommandGroup> </CommandGroup>