mirror of
https://github.com/fosrl/pangolin.git
synced 2026-05-27 19:22:50 +00:00
dont show site online status for local sites
This commit is contained in:
@@ -152,7 +152,7 @@ export type ResourceWithTargets = {
|
||||
siteId: number;
|
||||
siteName: string;
|
||||
siteNiceId: string;
|
||||
online: boolean;
|
||||
online?: boolean; // undefined for local sites
|
||||
}>;
|
||||
};
|
||||
|
||||
@@ -383,12 +383,8 @@ export async function listResources(
|
||||
.select({ resourceId: targets.resourceId })
|
||||
.from(targets)
|
||||
.innerJoin(sites, eq(targets.siteId, sites.siteId))
|
||||
.where(
|
||||
and(eq(sites.orgId, orgId), eq(sites.siteId, siteId))
|
||||
);
|
||||
conditions.push(
|
||||
inArray(resources.resourceId, resourcesWithSite)
|
||||
);
|
||||
.where(and(eq(sites.orgId, orgId), eq(sites.siteId, siteId)));
|
||||
conditions.push(inArray(resources.resourceId, resourcesWithSite));
|
||||
}
|
||||
|
||||
const baseQuery = queryResourcesBase().where(and(...conditions));
|
||||
@@ -426,7 +422,8 @@ export async function listResources(
|
||||
hcEnabled: targetHealthCheck.hcEnabled,
|
||||
siteName: sites.name,
|
||||
siteNiceId: sites.niceId,
|
||||
siteOnline: sites.online
|
||||
siteOnline: sites.online,
|
||||
siteType: sites.type
|
||||
})
|
||||
.from(targets)
|
||||
.where(inArray(targets.resourceId, resourceIdList))
|
||||
@@ -481,18 +478,19 @@ export async function listResources(
|
||||
siteId: number;
|
||||
siteName: string;
|
||||
siteNiceId: string;
|
||||
online: boolean;
|
||||
online?: boolean;
|
||||
}
|
||||
>();
|
||||
for (const t of raw) {
|
||||
if (typeof t.siteId !== "number" || siteById.has(t.siteId)) {
|
||||
continue;
|
||||
}
|
||||
const isLocal = t.siteType === "local";
|
||||
siteById.set(t.siteId, {
|
||||
siteId: t.siteId,
|
||||
siteName: t.siteName ?? "",
|
||||
siteNiceId: t.siteNiceId ?? "",
|
||||
online: Boolean(t.siteOnline)
|
||||
online: isLocal ? undefined : Boolean(t.siteOnline)
|
||||
});
|
||||
}
|
||||
entry.sites = Array.from(siteById.values());
|
||||
|
||||
@@ -31,7 +31,9 @@ let staleNewtVersion: string | null = null;
|
||||
|
||||
async function getLatestNewtVersion(): Promise<string | null> {
|
||||
try {
|
||||
const cachedVersion = await cache.get<string>("cache:latestNewtVersion");
|
||||
const cachedVersion = await cache.get<string>(
|
||||
"cache:latestNewtVersion"
|
||||
);
|
||||
if (cachedVersion) {
|
||||
return cachedVersion;
|
||||
}
|
||||
@@ -226,7 +228,10 @@ function querySitesBase() {
|
||||
);
|
||||
}
|
||||
|
||||
type SiteWithUpdateAvailable = Awaited<ReturnType<typeof querySitesBase>>[0] & {
|
||||
type SiteRowBase = Awaited<ReturnType<typeof querySitesBase>>[0];
|
||||
|
||||
type SiteWithUpdateAvailable = Omit<SiteRowBase, "online"> & {
|
||||
online?: SiteRowBase["online"]; // undefined for local sites
|
||||
newtUpdateAvailable?: boolean;
|
||||
};
|
||||
|
||||
@@ -338,7 +343,9 @@ export async function listSites(
|
||||
|
||||
// we need to add `as` so that drizzle filters the result as a subquery
|
||||
const countQuery = db.$count(
|
||||
querySitesBase().where(and(...conditions)).as("filtered_sites")
|
||||
querySitesBase()
|
||||
.where(and(...conditions))
|
||||
.as("filtered_sites")
|
||||
);
|
||||
|
||||
const siteListQuery = baseQuery
|
||||
@@ -397,9 +404,13 @@ export async function listSites(
|
||||
);
|
||||
}
|
||||
|
||||
const sitesPayload = sitesWithUpdates.map((site) =>
|
||||
site.type === "local" ? { ...site, online: undefined } : site
|
||||
);
|
||||
|
||||
return response<ListSitesResponse>(res, {
|
||||
data: {
|
||||
sites: sitesWithUpdates,
|
||||
sites: sitesPayload,
|
||||
pagination: {
|
||||
total: totalCount,
|
||||
pageSize,
|
||||
|
||||
@@ -16,10 +16,10 @@ export type ResourceSiteRow = {
|
||||
siteId: number;
|
||||
siteName: string;
|
||||
siteNiceId: string;
|
||||
online: boolean;
|
||||
online?: boolean | null;
|
||||
};
|
||||
|
||||
type AggregateSitesStatus = "allOnline" | "partial" | "allOffline";
|
||||
type AggregateSitesStatus = "allOnline" | "partial" | "allOffline" | "unknown";
|
||||
|
||||
function aggregateSitesStatus(
|
||||
resourceSites: ResourceSiteRow[]
|
||||
@@ -27,8 +27,17 @@ function aggregateSitesStatus(
|
||||
if (resourceSites.length === 0) {
|
||||
return "allOffline";
|
||||
}
|
||||
const onlineCount = resourceSites.filter((rs) => rs.online).length;
|
||||
if (onlineCount === resourceSites.length) return "allOnline";
|
||||
|
||||
const knownStatuses = resourceSites
|
||||
.map((rs) => rs.online)
|
||||
.filter((status): status is boolean => typeof status === "boolean");
|
||||
|
||||
if (knownStatuses.length === 0) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
const onlineCount = knownStatuses.filter(Boolean).length;
|
||||
if (onlineCount === knownStatuses.length) return "allOnline";
|
||||
if (onlineCount > 0) return "partial";
|
||||
return "allOffline";
|
||||
}
|
||||
@@ -40,8 +49,10 @@ function aggregateStatusDotClass(status: AggregateSitesStatus): string {
|
||||
case "partial":
|
||||
return "bg-yellow-500";
|
||||
case "allOffline":
|
||||
default:
|
||||
return "bg-neutral-500";
|
||||
case "unknown":
|
||||
default:
|
||||
return "bg-transparent";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +95,7 @@ export function ResourceSitesStatusCell({
|
||||
<DropdownMenuContent align="start" className="min-w-56">
|
||||
{resourceSites.map((site) => {
|
||||
const isOnline = site.online;
|
||||
const hasKnownStatus = typeof isOnline === "boolean";
|
||||
return (
|
||||
<DropdownMenuItem key={site.siteId} asChild>
|
||||
<Link
|
||||
@@ -94,7 +106,9 @@ export function ResourceSitesStatusCell({
|
||||
<div
|
||||
className={cn(
|
||||
"h-2 w-2 shrink-0 rounded-full",
|
||||
isOnline
|
||||
!hasKnownStatus
|
||||
? "bg-transparent"
|
||||
: isOnline
|
||||
? "bg-green-500"
|
||||
: "bg-neutral-500"
|
||||
)}
|
||||
@@ -106,12 +120,16 @@ export function ResourceSitesStatusCell({
|
||||
<span
|
||||
className={cn(
|
||||
"shrink-0 capitalize",
|
||||
isOnline
|
||||
hasKnownStatus && isOnline
|
||||
? "text-green-600"
|
||||
: "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
{isOnline ? t("online") : t("offline")}
|
||||
{!hasKnownStatus
|
||||
? t("resourcesTableUnknown")
|
||||
: isOnline
|
||||
? t("online")
|
||||
: t("offline")}
|
||||
</span>
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
|
||||
@@ -60,7 +60,7 @@ export type SiteRow = {
|
||||
type: "newt" | "wireguard" | "local";
|
||||
newtVersion?: string;
|
||||
newtUpdateAvailable?: boolean;
|
||||
online: boolean;
|
||||
online?: boolean | null;
|
||||
address?: string;
|
||||
exitNodeName?: string;
|
||||
exitNodeEndpoint?: string;
|
||||
|
||||
@@ -111,11 +111,13 @@ export function MultiSitesSelector({
|
||||
<span className="min-w-0 flex-1 truncate">
|
||||
{site.name}
|
||||
</span>
|
||||
<SiteOnlineStatus
|
||||
type={site.type}
|
||||
online={site.online}
|
||||
t={t}
|
||||
/>
|
||||
{site.online != null && (
|
||||
<SiteOnlineStatus
|
||||
type={site.type}
|
||||
online={site.online}
|
||||
t={t}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</CommandItem>
|
||||
))}
|
||||
|
||||
@@ -124,11 +124,13 @@ export function SitesSelector({
|
||||
<span className="min-w-0 flex-1 truncate">
|
||||
{site.name}
|
||||
</span>
|
||||
<SiteOnlineStatus
|
||||
type={site.type}
|
||||
online={site.online}
|
||||
t={t}
|
||||
/>
|
||||
{site.online != null && (
|
||||
<SiteOnlineStatus
|
||||
type={site.type}
|
||||
online={site.online}
|
||||
t={t}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</CommandItem>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user