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";
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 { Button } from "@app/components/ui/button";
import {
@@ -24,6 +34,7 @@ import {
ArrowUp10Icon,
ArrowUpRight,
Check,
ChevronDown,
ChevronsUpDownIcon,
MoreHorizontal,
X
@@ -67,6 +78,8 @@ export default function PendingSitesTable({
const [rejectingIds, setRejectingIds] = useState<Set<number>>(new Set());
const [isRejectModalOpen, setIsRejectModalOpen] = useState(false);
const [selectedSite, setSelectedSite] = useState<SiteRow | null>(null);
const [resourcesDialogSite, setResourcesDialogSite] =
useState<SiteRow | null>(null);
const api = createApiClient(useEnvContext());
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",
friendlyName: t("exitNode"),
@@ -491,6 +527,44 @@ export default function PendingSitesTable({
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 && (
<ConfirmDeleteDialog
open={isRejectModalOpen}
+22 -13
View File
@@ -174,8 +174,8 @@ type OverviewRow = {
type OverviewColumnProps = {
title: string;
description: string;
viewAllHref: string;
viewAllLabel: string;
viewAllHref?: string;
viewAllLabel?: string;
emptyLabel: string;
isForbidden: boolean;
isFetching: boolean;
@@ -212,12 +212,14 @@ function OverviewColumn({
{description}
</p>
</div>
<Link
href={viewAllHref}
className="shrink-0 text-muted-foreground text-sm hover:underline"
>
{viewAllLabel}
</Link>
{viewAllHref && viewAllLabel ? (
<Link
href={viewAllHref}
className="shrink-0 text-muted-foreground text-sm hover:underline"
>
{viewAllLabel}
</Link>
) : null}
</div>
</div>
);
@@ -319,6 +321,8 @@ type SiteResourcesOverviewProps = {
initialPrivateForbidden: boolean;
/** When not under `/[orgId]/...` routes, pass org id explicitly (e.g. credenza on sites list). */
orgIdOverride?: string;
/** When false, hides links to the org resources tables filtered by this site. */
showViewAllLinks?: boolean;
};
export default function SiteResourcesOverview({
@@ -327,7 +331,8 @@ export default function SiteResourcesOverview({
initialPrivateData,
initialPublicForbidden,
initialPrivateForbidden,
orgIdOverride
orgIdOverride,
showViewAllLinks = true
}: SiteResourcesOverviewProps) {
const t = useTranslations();
const params = useParams<{ orgId: string }>();
@@ -467,8 +472,10 @@ export default function SiteResourcesOverview({
key="public"
title={t("siteResourcesSectionPublic")}
description={t("siteResourcesSectionPublicDescription")}
viewAllHref={publicViewAllHref}
viewAllLabel={t("siteResourcesViewAllPublic")}
viewAllHref={showViewAllLinks ? publicViewAllHref : undefined}
viewAllLabel={
showViewAllLinks ? t("siteResourcesViewAllPublic") : undefined
}
emptyLabel={t("siteResourcesEmptyPublic")}
isForbidden={publicForbidden}
isFetching={publicQuery.isFetching}
@@ -484,8 +491,10 @@ export default function SiteResourcesOverview({
key="private"
title={t("siteResourcesSectionPrivate")}
description={t("siteResourcesSectionPrivateDescription")}
viewAllHref={privateViewAllHref}
viewAllLabel={t("siteResourcesViewAllPrivate")}
viewAllHref={showViewAllLinks ? privateViewAllHref : undefined}
viewAllLabel={
showViewAllLinks ? t("siteResourcesViewAllPrivate") : undefined
}
emptyLabel={t("siteResourcesEmptyPrivate")}
isForbidden={privateForbidden}
isFetching={privateQuery.isFetching}