mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-13 08:26:40 +00:00
add archive to org clients and add unarchive
This commit is contained in:
@@ -43,6 +43,7 @@ export type ClientRow = {
|
||||
userEmail: string | null;
|
||||
niceId: string;
|
||||
agent: string | null;
|
||||
archived?: boolean;
|
||||
};
|
||||
|
||||
type ClientTableProps = {
|
||||
@@ -99,6 +100,40 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
||||
});
|
||||
};
|
||||
|
||||
const archiveClient = (clientId: number) => {
|
||||
api.post(`/client/${clientId}/archive`)
|
||||
.catch((e) => {
|
||||
console.error("Error archiving client", e);
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Error archiving client",
|
||||
description: formatAxiosError(e, "Error archiving client")
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
startTransition(() => {
|
||||
router.refresh();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const unarchiveClient = (clientId: number) => {
|
||||
api.post(`/client/${clientId}/unarchive`)
|
||||
.catch((e) => {
|
||||
console.error("Error unarchiving client", e);
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Error unarchiving client",
|
||||
description: formatAxiosError(e, "Error unarchiving client")
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
startTransition(() => {
|
||||
router.refresh();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Check if there are any rows without userIds in the current view's data
|
||||
const hasRowsWithoutUserId = useMemo(() => {
|
||||
return userClients.some((client) => !client.userId);
|
||||
@@ -124,6 +159,19 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
||||
<ArrowUpDown className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const r = row.original;
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<span>{r.name}</span>
|
||||
{r.archived && (
|
||||
<Badge variant="secondary">
|
||||
{t("archived")}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -348,7 +396,7 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
||||
header: () => <span className="p-3"></span>,
|
||||
cell: ({ row }) => {
|
||||
const clientRow = row.original;
|
||||
return !clientRow.userId ? (
|
||||
return (
|
||||
<div className="flex items-center gap-2 justify-end">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
@@ -358,34 +406,40 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{/* <Link */}
|
||||
{/* className="block w-full" */}
|
||||
{/* href={`/${clientRow.orgId}/settings/sites/${clientRow.nice}`} */}
|
||||
{/* > */}
|
||||
{/* <DropdownMenuItem> */}
|
||||
{/* View settings */}
|
||||
{/* </DropdownMenuItem> */}
|
||||
{/* </Link> */}
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
setSelectedClient(clientRow);
|
||||
setIsDeleteModalOpen(true);
|
||||
if (clientRow.archived) {
|
||||
unarchiveClient(clientRow.id);
|
||||
} else {
|
||||
archiveClient(clientRow.id);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span className="text-red-500">Delete</span>
|
||||
<span>{clientRow.archived ? "Unarchive" : "Archive"}</span>
|
||||
</DropdownMenuItem>
|
||||
{!clientRow.userId && (
|
||||
// Machine client - also show delete option
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
setSelectedClient(clientRow);
|
||||
setIsDeleteModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<span className="text-red-500">Delete</span>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Link
|
||||
href={`/${clientRow.orgId}/settings/clients/${clientRow.id}`}
|
||||
>
|
||||
<Button variant={"outline"}>
|
||||
Edit
|
||||
View
|
||||
<ArrowRight className="ml-2 w-4 h-4" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
) : null;
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -394,7 +448,7 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedClient && (
|
||||
{selectedClient && !selectedClient.userId && (
|
||||
<ConfirmDeleteDialog
|
||||
open={isDeleteModalOpen}
|
||||
setOpen={(val) => {
|
||||
@@ -429,6 +483,32 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
|
||||
columnVisibility={defaultUserColumnVisibility}
|
||||
stickyLeftColumn="name"
|
||||
stickyRightColumn="actions"
|
||||
filters={[
|
||||
{
|
||||
id: "status",
|
||||
label: t("status") || "Status",
|
||||
multiSelect: true,
|
||||
displayMode: "calculated",
|
||||
options: [
|
||||
{
|
||||
id: "active",
|
||||
label: t("active") || "Active",
|
||||
value: false
|
||||
},
|
||||
{
|
||||
id: "archived",
|
||||
label: t("archived") || "Archived",
|
||||
value: true
|
||||
}
|
||||
],
|
||||
filterFn: (row: ClientRow, selectedValues: (string | number | boolean)[]) => {
|
||||
if (selectedValues.length === 0) return true;
|
||||
const rowArchived = row.archived || false;
|
||||
return selectedValues.includes(rowArchived);
|
||||
},
|
||||
defaultValues: [false] // Default to showing active clients
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user