add resources overview column to pending sites table

This commit is contained in:
miloschwartz
2026-07-12 17:53:57 -04:00
parent a8f3f71021
commit ae0be3a4bc
2 changed files with 96 additions and 13 deletions
+74
View File
@@ -1,6 +1,16 @@
"use client"; "use client";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog"; import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import {
Credenza,
CredenzaBody,
CredenzaContent,
CredenzaDescription,
CredenzaFooter,
CredenzaHeader,
CredenzaTitle
} from "@app/components/Credenza";
import SiteResourcesOverview from "@app/components/SiteResourcesOverview";
import { Badge } from "@app/components/ui/badge"; import { Badge } from "@app/components/ui/badge";
import { Button } from "@app/components/ui/button"; import { Button } from "@app/components/ui/button";
import { import {
@@ -24,6 +34,7 @@ import {
ArrowUp10Icon, ArrowUp10Icon,
ArrowUpRight, ArrowUpRight,
Check, Check,
ChevronDown,
ChevronsUpDownIcon, ChevronsUpDownIcon,
MoreHorizontal, MoreHorizontal,
X X
@@ -67,6 +78,8 @@ export default function PendingSitesTable({
const [rejectingIds, setRejectingIds] = useState<Set<number>>(new Set()); const [rejectingIds, setRejectingIds] = useState<Set<number>>(new Set());
const [isRejectModalOpen, setIsRejectModalOpen] = useState(false); const [isRejectModalOpen, setIsRejectModalOpen] = useState(false);
const [selectedSite, setSelectedSite] = useState<SiteRow | null>(null); const [selectedSite, setSelectedSite] = useState<SiteRow | null>(null);
const [resourcesDialogSite, setResourcesDialogSite] =
useState<SiteRow | null>(null);
const api = createApiClient(useEnvContext()); const api = createApiClient(useEnvContext());
const t = useTranslations(); const t = useTranslations();
@@ -342,6 +355,29 @@ export default function PendingSitesTable({
} }
} }
}, },
{
id: "resources",
accessorKey: "resourceCount",
friendlyName: t("resources"),
header: () => <span className="p-3">{t("resources")}</span>,
cell: ({ row }) => {
const siteRow = row.original;
return (
<Button
type="button"
variant="ghost"
size="sm"
onClick={() => setResourcesDialogSite(siteRow)}
className="flex h-8 items-center gap-2 px-0 font-normal"
>
<span className="text-sm tabular-nums">
{siteRow.resourceCount} {t("resources")}
</span>
<ChevronDown className="h-3 w-3 shrink-0" />
</Button>
);
}
},
{ {
accessorKey: "exitNode", accessorKey: "exitNode",
friendlyName: t("exitNode"), friendlyName: t("exitNode"),
@@ -491,6 +527,44 @@ export default function PendingSitesTable({
return ( return (
<> <>
<Credenza
open={Boolean(resourcesDialogSite)}
onOpenChange={(open) => {
if (!open) setResourcesDialogSite(null);
}}
>
<CredenzaContent className="md:max-w-7xl">
<CredenzaHeader>
<CredenzaTitle>{t("siteResourcesTab")}</CredenzaTitle>
<CredenzaDescription>
{t("siteResourcesDialogDescription")}
</CredenzaDescription>
</CredenzaHeader>
<CredenzaBody>
{resourcesDialogSite != null && (
<SiteResourcesOverview
orgIdOverride={orgId}
siteId={resourcesDialogSite.id}
initialPublicData={null}
initialPrivateData={null}
initialPublicForbidden={false}
initialPrivateForbidden={false}
showViewAllLinks={false}
/>
)}
</CredenzaBody>
<CredenzaFooter>
<Button
type="button"
variant="outline"
onClick={() => setResourcesDialogSite(null)}
>
{t("close")}
</Button>
</CredenzaFooter>
</CredenzaContent>
</Credenza>
{selectedSite && ( {selectedSite && (
<ConfirmDeleteDialog <ConfirmDeleteDialog
open={isRejectModalOpen} open={isRejectModalOpen}
+22 -13
View File
@@ -174,8 +174,8 @@ type OverviewRow = {
type OverviewColumnProps = { type OverviewColumnProps = {
title: string; title: string;
description: string; description: string;
viewAllHref: string; viewAllHref?: string;
viewAllLabel: string; viewAllLabel?: string;
emptyLabel: string; emptyLabel: string;
isForbidden: boolean; isForbidden: boolean;
isFetching: boolean; isFetching: boolean;
@@ -212,12 +212,14 @@ function OverviewColumn({
{description} {description}
</p> </p>
</div> </div>
<Link {viewAllHref && viewAllLabel ? (
href={viewAllHref} <Link
className="shrink-0 text-muted-foreground text-sm hover:underline" href={viewAllHref}
> className="shrink-0 text-muted-foreground text-sm hover:underline"
{viewAllLabel} >
</Link> {viewAllLabel}
</Link>
) : null}
</div> </div>
</div> </div>
); );
@@ -319,6 +321,8 @@ type SiteResourcesOverviewProps = {
initialPrivateForbidden: boolean; initialPrivateForbidden: boolean;
/** When not under `/[orgId]/...` routes, pass org id explicitly (e.g. credenza on sites list). */ /** When not under `/[orgId]/...` routes, pass org id explicitly (e.g. credenza on sites list). */
orgIdOverride?: string; orgIdOverride?: string;
/** When false, hides links to the org resources tables filtered by this site. */
showViewAllLinks?: boolean;
}; };
export default function SiteResourcesOverview({ export default function SiteResourcesOverview({
@@ -327,7 +331,8 @@ export default function SiteResourcesOverview({
initialPrivateData, initialPrivateData,
initialPublicForbidden, initialPublicForbidden,
initialPrivateForbidden, initialPrivateForbidden,
orgIdOverride orgIdOverride,
showViewAllLinks = true
}: SiteResourcesOverviewProps) { }: SiteResourcesOverviewProps) {
const t = useTranslations(); const t = useTranslations();
const params = useParams<{ orgId: string }>(); const params = useParams<{ orgId: string }>();
@@ -467,8 +472,10 @@ export default function SiteResourcesOverview({
key="public" key="public"
title={t("siteResourcesSectionPublic")} title={t("siteResourcesSectionPublic")}
description={t("siteResourcesSectionPublicDescription")} description={t("siteResourcesSectionPublicDescription")}
viewAllHref={publicViewAllHref} viewAllHref={showViewAllLinks ? publicViewAllHref : undefined}
viewAllLabel={t("siteResourcesViewAllPublic")} viewAllLabel={
showViewAllLinks ? t("siteResourcesViewAllPublic") : undefined
}
emptyLabel={t("siteResourcesEmptyPublic")} emptyLabel={t("siteResourcesEmptyPublic")}
isForbidden={publicForbidden} isForbidden={publicForbidden}
isFetching={publicQuery.isFetching} isFetching={publicQuery.isFetching}
@@ -484,8 +491,10 @@ export default function SiteResourcesOverview({
key="private" key="private"
title={t("siteResourcesSectionPrivate")} title={t("siteResourcesSectionPrivate")}
description={t("siteResourcesSectionPrivateDescription")} description={t("siteResourcesSectionPrivateDescription")}
viewAllHref={privateViewAllHref} viewAllHref={showViewAllLinks ? privateViewAllHref : undefined}
viewAllLabel={t("siteResourcesViewAllPrivate")} viewAllLabel={
showViewAllLinks ? t("siteResourcesViewAllPrivate") : undefined
}
emptyLabel={t("siteResourcesEmptyPrivate")} emptyLabel={t("siteResourcesEmptyPrivate")}
isForbidden={privateForbidden} isForbidden={privateForbidden}
isFetching={privateQuery.isFetching} isFetching={privateQuery.isFetching}