mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-01 10:11:27 +02:00
add first seen and last seen columns to user devices table
This commit is contained in:
@@ -67,12 +67,12 @@ const listUserDevicesSchema = z.strictObject({
|
||||
}),
|
||||
query: z.string().optional(),
|
||||
sort_by: z
|
||||
.enum(["megabytesIn", "megabytesOut"])
|
||||
.enum(["megabytesIn", "megabytesOut", "firstSeen", "lastSeen"])
|
||||
.optional()
|
||||
.catch(undefined)
|
||||
.openapi({
|
||||
type: "string",
|
||||
enum: ["megabytesIn", "megabytesOut"],
|
||||
enum: ["megabytesIn", "megabytesOut", "firstSeen", "lastSeen"],
|
||||
description: "Field to sort by"
|
||||
}),
|
||||
order: z
|
||||
@@ -183,7 +183,9 @@ function queryUserDevicesBase() {
|
||||
fingerprintArch: currentFingerprint.arch,
|
||||
fingerprintSerialNumber: currentFingerprint.serialNumber,
|
||||
fingerprintUsername: currentFingerprint.username,
|
||||
fingerprintHostname: currentFingerprint.hostname
|
||||
fingerprintHostname: currentFingerprint.hostname,
|
||||
firstSeen: currentFingerprint.firstSeen,
|
||||
lastSeen: currentFingerprint.lastSeen
|
||||
})
|
||||
.from(clients)
|
||||
.leftJoin(orgs, eq(clients.orgId, orgs.orgId))
|
||||
@@ -389,14 +391,23 @@ export async function listUserDevices(
|
||||
|
||||
const countQuery = db.$count(baseQuery.as("filtered_clients"));
|
||||
|
||||
const sortColumn =
|
||||
sort_by === "firstSeen"
|
||||
? currentFingerprint.firstSeen
|
||||
: sort_by === "lastSeen"
|
||||
? currentFingerprint.lastSeen
|
||||
: sort_by
|
||||
? clients[sort_by]
|
||||
: undefined;
|
||||
|
||||
const listDevicesQuery = baseQuery
|
||||
.limit(pageSize)
|
||||
.offset(pageSize * (page - 1))
|
||||
.orderBy(
|
||||
sort_by
|
||||
sortColumn
|
||||
? order === "asc"
|
||||
? asc(clients[sort_by])
|
||||
: desc(clients[sort_by])
|
||||
? asc(sortColumn)
|
||||
: desc(sortColumn)
|
||||
: asc(clients.clientId)
|
||||
);
|
||||
|
||||
|
||||
@@ -104,7 +104,9 @@ export default async function ClientsPage(props: ClientsPageProps) {
|
||||
archived: Boolean(client.archived),
|
||||
blocked: Boolean(client.blocked),
|
||||
approvalState: client.approvalState,
|
||||
fingerprint
|
||||
fingerprint,
|
||||
firstSeen: client.firstSeen ?? null,
|
||||
lastSeen: client.lastSeen ?? null
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -77,6 +77,8 @@ export type ClientRow = {
|
||||
username: string | null;
|
||||
hostname: string | null;
|
||||
} | null;
|
||||
firstSeen: number | null;
|
||||
lastSeen: number | null;
|
||||
};
|
||||
|
||||
type ClientTableProps = {
|
||||
@@ -112,7 +114,9 @@ export default function UserDevicesTable({
|
||||
|
||||
const defaultUserColumnVisibility = {
|
||||
subnet: false,
|
||||
niceId: false
|
||||
niceId: false,
|
||||
firstSeen: false,
|
||||
lastSeen: false
|
||||
};
|
||||
|
||||
const refreshData = () => {
|
||||
@@ -621,6 +625,68 @@ export default function UserDevicesTable({
|
||||
accessorKey: "subnet",
|
||||
friendlyName: t("address"),
|
||||
header: () => <span className="px-3">{t("address")}</span>
|
||||
},
|
||||
{
|
||||
accessorKey: "firstSeen",
|
||||
friendlyName: t("firstSeen"),
|
||||
header: () => {
|
||||
const firstSeenOrder = getSortDirection(
|
||||
"firstSeen",
|
||||
searchParams
|
||||
);
|
||||
|
||||
const Icon =
|
||||
firstSeenOrder === "asc"
|
||||
? ArrowDown01Icon
|
||||
: firstSeenOrder === "desc"
|
||||
? ArrowUp10Icon
|
||||
: ChevronsUpDownIcon;
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => toggleSort("firstSeen")}
|
||||
>
|
||||
{t("firstSeen")}
|
||||
<Icon className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const firstSeen = row.original.firstSeen;
|
||||
if (!firstSeen) return "-";
|
||||
return new Date(firstSeen * 1000).toLocaleString();
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "lastSeen",
|
||||
friendlyName: t("lastSeen"),
|
||||
header: () => {
|
||||
const lastSeenOrder = getSortDirection(
|
||||
"lastSeen",
|
||||
searchParams
|
||||
);
|
||||
|
||||
const Icon =
|
||||
lastSeenOrder === "asc"
|
||||
? ArrowDown01Icon
|
||||
: lastSeenOrder === "desc"
|
||||
? ArrowUp10Icon
|
||||
: ChevronsUpDownIcon;
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => toggleSort("lastSeen")}
|
||||
>
|
||||
{t("lastSeen")}
|
||||
<Icon className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const lastSeen = row.original.lastSeen;
|
||||
if (!lastSeen) return "-";
|
||||
return new Date(lastSeen * 1000).toLocaleString();
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user