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