Openstatus
www.openstatus.dev
1"use client";
2
3import type { ColumnDef } from "@tanstack/react-table";
4import { format } from "date-fns";
5import type * as z from "zod";
6
7import { regionDict } from "@openstatus/regions";
8
9import type { Trigger } from "@/lib/monitor/utils";
10import type { monitorRegionSchema } from "@openstatus/db/src/schema/constants";
11import { TriggerIconWithTooltip } from "../monitor/trigger-icon-with-tooltip";
12import { DataTableColumnHeader } from "./data-table-column-header";
13import { DataTableStatusBadge } from "./data-table-status-badge";
14
15export type Check = {
16 type: "http" | "tcp";
17 monitorId: string;
18 latency: number;
19 region: z.infer<typeof monitorRegionSchema>;
20 statusCode?: number | null;
21 timestamp: number;
22 workspaceId: string;
23 cronTimestamp: number | null;
24 error: boolean;
25 trigger: Trigger | null;
26};
27
28export const columns: ColumnDef<Check>[] = [
29 {
30 accessorKey: "error",
31 header: () => null,
32 cell: ({ row }) => {
33 if (row.original.error)
34 return <div className="h-2.5 w-2.5 rounded-full bg-rose-500" />;
35 return <div className="h-2.5 w-2.5 rounded-full bg-green-500" />;
36 },
37 filterFn: (row, id, value) => value.includes(row.getValue(id)),
38 },
39 {
40 accessorKey: "cronTimestamp",
41 header: ({ column }) => (
42 <DataTableColumnHeader column={column} title="Date" />
43 ),
44 cell: ({ row }) => {
45 return (
46 <div>
47 {format(new Date(row.getValue("cronTimestamp")), "LLL dd, y HH:mm")}
48 </div>
49 );
50 },
51 },
52 {
53 accessorKey: "statusCode",
54 header: ({ column }) => (
55 <DataTableColumnHeader column={column} title="Status" />
56 ),
57 cell: ({ row }) => {
58 const statusCode = row.getValue("statusCode") as
59 | number
60 | null
61 | undefined;
62
63 if (statusCode) {
64 return <DataTableStatusBadge {...{ statusCode }} />;
65 }
66
67 return <div className="text-muted-foreground">N/A</div>;
68 },
69 filterFn: (row, id, value) => {
70 // get the first digit of the status code
71 return value.includes(Number(String(row.getValue(id)).charAt(0)));
72 },
73 },
74 {
75 accessorKey: "latency",
76 header: ({ column }) => (
77 <DataTableColumnHeader column={column} title="Latency (ms)" />
78 ),
79 filterFn: (row, id, value) => {
80 const { select, input } = value || {};
81 if (select === "min" && input)
82 return Number.parseInt(row.getValue(id)) > Number.parseInt(input);
83 if (select === "max" && input)
84 return Number.parseInt(row.getValue(id)) < Number.parseInt(input);
85 return true;
86 },
87 },
88 {
89 accessorKey: "region",
90 header: ({ column }) => (
91 <DataTableColumnHeader column={column} title="Region" />
92 ),
93 cell: ({ row }) => {
94 return (
95 <div>
96 <span className="font-mono">{String(row.getValue("region"))} </span>
97 <span className="text-muted-foreground text-xs">
98 {regionDict[row.original.region]?.location}
99 </span>
100 </div>
101 );
102 },
103 filterFn: (row, id, value) => {
104 return value.includes(row.getValue(id));
105 },
106 },
107 {
108 accessorKey: "trigger",
109 header: () => null,
110 cell: ({ row }) => {
111 const value = row.getValue("trigger") as Trigger;
112 return <TriggerIconWithTooltip triggerType={value} />;
113 },
114 filterFn: (row, id, value) => {
115 return value.includes(row.getValue(id));
116 },
117 },
118];