remove extra sites query

This commit is contained in:
miloschwartz
2026-04-12 14:58:55 -07:00
parent b5e239d1ad
commit 0cbcc0c29c
6 changed files with 97 additions and 133 deletions

View File

@@ -20,7 +20,7 @@ import {
ArrowDown01Icon,
ArrowUp10Icon,
ArrowUpDown,
ArrowUpRight,
ChevronDown,
ChevronsUpDownIcon,
MoreHorizontal
} from "lucide-react";
@@ -38,16 +38,13 @@ import { ControlledDataTable } from "./ui/controlled-data-table";
import { useNavigationContext } from "@app/hooks/useNavigationContext";
import { useDebouncedCallback } from "use-debounce";
import { ColumnFilterButton } from "./ColumnFilterButton";
import {
Popover,
PopoverContent,
PopoverTrigger
} from "@app/components/ui/popover";
import { cn } from "@app/lib/cn";
export type InternalResourceSiteRow = {
siteId: number;
siteName: string;
siteNiceId: string;
online: boolean;
};
export type InternalResourceRow = {
@@ -113,99 +110,106 @@ function isSafeUrlForLink(href: string): boolean {
}
}
const MAX_SITE_LINKS = 3;
type AggregateSitesStatus = "allOnline" | "partial" | "allOffline";
function ClientResourceSiteLinks({
orgId,
sites
}: {
orgId: string;
sites: InternalResourceSiteRow[];
}) {
if (sites.length === 0) {
return <span>-</span>;
function aggregateSitesStatus(
resourceSites: InternalResourceSiteRow[]
): AggregateSitesStatus {
if (resourceSites.length === 0) {
return "allOffline";
}
const visible = sites.slice(0, MAX_SITE_LINKS);
const overflow = sites.slice(MAX_SITE_LINKS);
return (
<div className="flex flex-wrap items-center gap-1">
{visible.map((site) => (
<Link
key={site.siteId}
href={`/${orgId}/settings/sites/${site.siteNiceId}`}
>
<Button
variant="outline"
size="sm"
className="w-full gap-1"
>
<span className="max-w-[10rem] truncate">
{site.siteName}
</span>
<ArrowUpRight className="h-3 w-3 shrink-0" />
</Button>
</Link>
))}
{overflow.length > 0 ? (
<OverflowSitesPopover orgId={orgId} sites={overflow} />
) : null}
</div>
);
const onlineCount = resourceSites.filter((rs) => rs.online).length;
if (onlineCount === resourceSites.length) return "allOnline";
if (onlineCount > 0) return "partial";
return "allOffline";
}
function OverflowSitesPopover({
function aggregateStatusDotClass(status: AggregateSitesStatus): string {
switch (status) {
case "allOnline":
return "bg-green-500";
case "partial":
return "bg-yellow-500";
case "allOffline":
default:
return "bg-gray-500";
}
}
function ClientResourceSitesStatusCell({
orgId,
sites
resourceSites
}: {
orgId: string;
sites: InternalResourceSiteRow[];
resourceSites: InternalResourceSiteRow[];
}) {
const [open, setOpen] = useState(false);
const t = useTranslations();
if (resourceSites.length === 0) {
return <span>-</span>;
}
const aggregate = aggregateSitesStatus(resourceSites);
const countLabel = t("multiSitesSelectorSitesCount", {
count: resourceSites.length
});
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
type="button"
variant="ghost"
size="sm"
variant="outline"
className="gap-1 px-2 font-normal"
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
className="flex h-8 items-center gap-2 px-0 font-normal"
>
+{sites.length}
<div
className={cn(
"h-2 w-2 shrink-0 rounded-full",
aggregateStatusDotClass(aggregate)
)}
/>
<span className="text-sm tabular-nums">{countLabel}</span>
<ChevronDown className="h-3 w-3 shrink-0" />
</Button>
</PopoverTrigger>
<PopoverContent
align="start"
side="top"
className="w-auto max-w-xs p-2"
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
>
<ul className="flex flex-col gap-1.5 text-sm">
{sites.map((site) => (
<li key={site.siteId}>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="min-w-56">
{resourceSites.map((site) => {
const isOnline = site.online;
return (
<DropdownMenuItem key={site.siteId} asChild>
<Link
href={`/${orgId}/settings/sites/${site.siteNiceId}`}
className="flex cursor-pointer items-center justify-between gap-4"
>
<Button
variant="outline"
size="sm"
className="w-full justify-start gap-1"
>
<div className="flex min-w-0 items-center gap-2">
<div
className={cn(
"h-2 w-2 shrink-0 rounded-full",
isOnline
? "bg-green-500"
: "bg-gray-500"
)}
/>
<span className="truncate">
{site.siteName}
</span>
<ArrowUpRight className="ml-auto h-3 w-3 shrink-0" />
</Button>
</div>
<span
className={cn(
"shrink-0 capitalize",
isOnline
? "text-green-600"
: "text-muted-foreground"
)}
>
{isOnline ? t("online") : t("offline")}
</span>
</Link>
</li>
))}
</ul>
</PopoverContent>
</Popover>
</DropdownMenuItem>
);
})}
</DropdownMenuContent>
</DropdownMenu>
);
}
@@ -243,8 +247,6 @@ export default function ClientResourcesTable({
useState<InternalResourceRow | null>();
const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
const { data: sites = [] } = useQuery(orgQueries.sites({ orgId }));
const [isRefreshing, startTransition] = useTransition();
const refreshData = () => {
@@ -339,9 +341,9 @@ export default function ClientResourcesTable({
cell: ({ row }) => {
const resourceRow = row.original;
return (
<ClientResourceSiteLinks
<ClientResourceSitesStatusCell
orgId={resourceRow.orgId}
sites={resourceRow.sites}
resourceSites={resourceRow.sites}
/>
);
}
@@ -599,7 +601,6 @@ export default function ClientResourcesTable({
setOpen={setIsEditDialogOpen}
resource={editingResource}
orgId={orgId}
sites={sites}
onSuccess={() => {
// Delay refresh to allow modal to close smoothly
setTimeout(() => {
@@ -614,7 +615,6 @@ export default function ClientResourcesTable({
open={isCreateDialogOpen}
setOpen={setIsCreateDialogOpen}
orgId={orgId}
sites={sites}
onSuccess={() => {
// Delay refresh to allow modal to close smoothly
setTimeout(() => {