mirror of
https://github.com/fosrl/pangolin.git
synced 2026-05-30 04:32:53 +00:00
add way to reject a pending site
This commit is contained in:
@@ -3139,5 +3139,6 @@
|
|||||||
"idpUnassociateMenu": "Unassociate",
|
"idpUnassociateMenu": "Unassociate",
|
||||||
"idpDeleteAllOrgsMenu": "Delete",
|
"idpDeleteAllOrgsMenu": "Delete",
|
||||||
"publicIpEndpoint": "Endpoint",
|
"publicIpEndpoint": "Endpoint",
|
||||||
"lastTriggeredAt": "Last Trigger"
|
"lastTriggeredAt": "Last Trigger",
|
||||||
|
"reject": "Reject"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
|
||||||
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,7 +25,8 @@ import {
|
|||||||
ArrowUpRight,
|
ArrowUpRight,
|
||||||
Check,
|
Check,
|
||||||
ChevronsUpDownIcon,
|
ChevronsUpDownIcon,
|
||||||
MoreHorizontal
|
MoreHorizontal,
|
||||||
|
X
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
@@ -62,6 +64,9 @@ export default function PendingSitesTable({
|
|||||||
|
|
||||||
const [isRefreshing, startTransition] = useTransition();
|
const [isRefreshing, startTransition] = useTransition();
|
||||||
const [approvingIds, setApprovingIds] = useState<Set<number>>(new Set());
|
const [approvingIds, setApprovingIds] = useState<Set<number>>(new Set());
|
||||||
|
const [rejectingIds, setRejectingIds] = useState<Set<number>>(new Set());
|
||||||
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
|
const [selectedSite, setSelectedSite] = useState<SiteRow | null>(null);
|
||||||
|
|
||||||
const api = createApiClient(useEnvContext());
|
const api = createApiClient(useEnvContext());
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
@@ -128,6 +133,33 @@ export default function PendingSitesTable({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function rejectSite(siteId: number) {
|
||||||
|
setRejectingIds((prev) => new Set(prev).add(siteId));
|
||||||
|
try {
|
||||||
|
await api.delete(`/site/${siteId}`);
|
||||||
|
toast({
|
||||||
|
title: t("success"),
|
||||||
|
description: t("siteDeleted"),
|
||||||
|
variant: "default"
|
||||||
|
});
|
||||||
|
setIsDeleteModalOpen(false);
|
||||||
|
setSelectedSite(null);
|
||||||
|
router.refresh();
|
||||||
|
} catch (e) {
|
||||||
|
toast({
|
||||||
|
variant: "destructive",
|
||||||
|
title: t("siteErrorDelete"),
|
||||||
|
description: formatAxiosError(e, t("siteErrorDelete"))
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setRejectingIds((prev) => {
|
||||||
|
const next = new Set(prev);
|
||||||
|
next.delete(siteId);
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const columns: ExtendedColumnDef<SiteRow>[] = [
|
const columns: ExtendedColumnDef<SiteRow>[] = [
|
||||||
{
|
{
|
||||||
accessorKey: "name",
|
accessorKey: "name",
|
||||||
@@ -387,6 +419,7 @@ export default function PendingSitesTable({
|
|||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const siteRow = row.original;
|
const siteRow = row.original;
|
||||||
const isApproving = approvingIds.has(siteRow.id);
|
const isApproving = approvingIds.has(siteRow.id);
|
||||||
|
const isRejecting = rejectingIds.has(siteRow.id);
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2 justify-end">
|
<div className="flex items-center gap-2 justify-end">
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
@@ -409,7 +442,18 @@ export default function PendingSitesTable({
|
|||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
disabled={isApproving}
|
disabled={isApproving || isRejecting}
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedSite(siteRow);
|
||||||
|
setIsDeleteModalOpen(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<X className="mr-2 w-4 h-4" />
|
||||||
|
{t("reject")}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
disabled={isApproving || isRejecting}
|
||||||
onClick={() => approveSite(siteRow.id)}
|
onClick={() => approveSite(siteRow.id)}
|
||||||
>
|
>
|
||||||
<Check className="mr-2 w-4 h-4" />
|
<Check className="mr-2 w-4 h-4" />
|
||||||
@@ -446,28 +490,51 @@ export default function PendingSitesTable({
|
|||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ControlledDataTable
|
<>
|
||||||
columns={columns}
|
{selectedSite && (
|
||||||
rows={sites}
|
<ConfirmDeleteDialog
|
||||||
tableId="pending-sites-table"
|
open={isDeleteModalOpen}
|
||||||
searchPlaceholder={t("searchSitesProgress")}
|
setOpen={(val) => {
|
||||||
pagination={pagination}
|
setIsDeleteModalOpen(val);
|
||||||
onPaginationChange={handlePaginationChange}
|
if (!val) {
|
||||||
searchQuery={searchParams.get("query")?.toString()}
|
setSelectedSite(null);
|
||||||
onSearch={handleSearchChange}
|
}
|
||||||
onRefresh={refreshData}
|
}}
|
||||||
isRefreshing={isRefreshing || isFiltering}
|
dialog={
|
||||||
refreshButtonDisabled={!canUseSiteProvisioning}
|
<div className="space-y-2">
|
||||||
rowCount={rowCount}
|
<p>{t("siteQuestionRemove")}</p>
|
||||||
columnVisibility={{
|
<p>{t("siteMessageRemove")}</p>
|
||||||
niceId: false,
|
</div>
|
||||||
nice: false,
|
}
|
||||||
exitNode: false,
|
buttonText={t("siteConfirmDelete")}
|
||||||
address: false
|
onConfirm={async () => rejectSite(selectedSite.id)}
|
||||||
}}
|
string={selectedSite.name}
|
||||||
enableColumnVisibility
|
title={t("siteDelete")}
|
||||||
stickyLeftColumn="name"
|
/>
|
||||||
stickyRightColumn="actions"
|
)}
|
||||||
/>
|
<ControlledDataTable
|
||||||
|
columns={columns}
|
||||||
|
rows={sites}
|
||||||
|
tableId="pending-sites-table"
|
||||||
|
searchPlaceholder={t("searchSitesProgress")}
|
||||||
|
pagination={pagination}
|
||||||
|
onPaginationChange={handlePaginationChange}
|
||||||
|
searchQuery={searchParams.get("query")?.toString()}
|
||||||
|
onSearch={handleSearchChange}
|
||||||
|
onRefresh={refreshData}
|
||||||
|
isRefreshing={isRefreshing || isFiltering}
|
||||||
|
refreshButtonDisabled={!canUseSiteProvisioning}
|
||||||
|
rowCount={rowCount}
|
||||||
|
columnVisibility={{
|
||||||
|
niceId: false,
|
||||||
|
nice: false,
|
||||||
|
exitNode: false,
|
||||||
|
address: false
|
||||||
|
}}
|
||||||
|
enableColumnVisibility
|
||||||
|
stickyLeftColumn="name"
|
||||||
|
stickyRightColumn="actions"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user