Openstatus www.openstatus.dev

chore: add trigger cron vs api (#1044)

* chore: add trigger cron vs api

* ci: apply automated fixes

* chore: update label and add trigger dict

* ci: apply automated fixes

* fix: tsc error

* ci: apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

authored by

Maximilian Kaske
autofix-ci[bot]
and committed by
GitHub
12db1cd1 4452dbc2

+118 -10
+2
apps/web/src/app/app/[workspaceSlug]/(dashboard)/monitors/[id]/data/_components/data-table-wrapper.tsx
··· 18 18 import { DataTable } from "@/components/data-table/data-table"; 19 19 import { LoadingAnimation } from "@/components/loading-animation"; 20 20 import { ResponseDetailTabs } from "@/components/ping-response-analysis/response-detail-tabs"; 21 + import type { Trigger } from "@/lib/monitor/utils"; 21 22 import { api } from "@/trpc/client"; 22 23 import type { monitorFlyRegionSchema } from "@openstatus/db/src/schema/constants"; 23 24 import type { z } from "zod"; ··· 38 39 cronTimestamp: number | null; 39 40 error: boolean; 40 41 assertions?: string | null; 42 + trigger: Trigger | null; 41 43 }; 42 44 43 45 export function DataTableWrapper({
+1
apps/web/src/app/app/[workspaceSlug]/(dashboard)/monitors/[id]/data/page.tsx
··· 52 52 { id: "statusCode", value: search.statusCode }, 53 53 { id: "region", value: search.regions }, 54 54 { id: "error", value: search.error }, 55 + { id: "trigger", value: search.trigger }, 55 56 ].filter((v) => v.value !== null)} 56 57 pagination={{ 57 58 pageIndex: search.pageIndex,
+2 -1
apps/web/src/app/app/[workspaceSlug]/(dashboard)/monitors/[id]/data/search-params.ts
··· 1 - import { periods } from "@/lib/monitor/utils"; 1 + import { periods, triggers } from "@/lib/monitor/utils"; 2 2 import { flyRegions } from "@openstatus/db/src/schema/constants"; 3 3 import { 4 4 createSearchParamsCache, ··· 18 18 regions: parseAsArrayOf(parseAsStringLiteral(flyRegions)), 19 19 pageSize: parseAsInteger.withDefault(10), 20 20 pageIndex: parseAsInteger.withDefault(0), 21 + trigger: parseAsArrayOf(parseAsStringLiteral(triggers)), 21 22 }; 22 23 export const searchParamsCache = createSearchParamsCache(searchParamsParsers);
+13
apps/web/src/components/data-table/columns.tsx
··· 13 13 } from "@openstatus/ui"; 14 14 import { flyRegionsDict } from "@openstatus/utils"; 15 15 16 + import type { Trigger } from "@/lib/monitor/utils"; 17 + import { TriggerIconWithTooltip } from "../monitor/trigger-icon-with-tooltip"; 16 18 import { DataTableColumnHeader } from "./data-table-column-header"; 17 19 import { DataTableStatusBadge } from "./data-table-status-badge"; 18 20 ··· 102 104 </span> 103 105 </div> 104 106 ); 107 + }, 108 + filterFn: (row, id, value) => { 109 + return value.includes(row.getValue(id)); 110 + }, 111 + }, 112 + { 113 + accessorKey: "trigger", 114 + header: () => null, 115 + cell: ({ row }) => { 116 + const value = row.getValue("trigger") as Trigger; 117 + return <TriggerIconWithTooltip triggerType={value} />; 105 118 }, 106 119 filterFn: (row, id, value) => { 107 120 return value.includes(row.getValue(id));
+1 -1
apps/web/src/components/data-table/data-table-column-header.tsx
··· 27 27 onClick={() => { 28 28 column.toggleSorting(undefined); 29 29 }} 30 - className={className} 30 + className={cn("-ml-3", className)} 31 31 {...props} 32 32 > 33 33 <span>{title}</span>
+26 -8
apps/web/src/components/data-table/data-table-toolbar.tsx
··· 7 7 import { Button } from "@openstatus/ui/src/components/button"; 8 8 import { flyRegionsDict } from "@openstatus/utils"; 9 9 10 + import { Icons } from "@/components/icons"; 10 11 import { codesDict } from "@/data/code-dictionary"; 12 + import { triggerDict } from "@/data/trigger-dictionary"; 11 13 import { DataTableFacetedFilter } from "./data-table-faceted-filter"; 12 14 import { DataTableFacetedInputDropdown } from "./data-table-faceted-input-dropdown"; 13 15 ··· 62 64 ]} 63 65 /> 64 66 )} 65 - <DataTableFacetedInputDropdown 66 - title="Latency" 67 - column={table.getColumn("latency")} 68 - options={[ 69 - { value: "min", label: "Min." }, 70 - { value: "max", label: "Max." }, 71 - ]} 72 - /> 67 + {table.getColumn("latency") && ( 68 + <DataTableFacetedInputDropdown 69 + title="Latency" 70 + column={table.getColumn("latency")} 71 + options={[ 72 + { value: "min", label: "Min." }, 73 + { value: "max", label: "Max." }, 74 + ]} 75 + /> 76 + )} 77 + {table.getColumn("trigger") && ( 78 + <DataTableFacetedFilter 79 + column={table.getColumn("trigger")} 80 + title="Trigger" 81 + options={(["cron", "api"] as const).map((key) => { 82 + const { label, icon, value } = triggerDict[key]; 83 + return { 84 + label, 85 + value, 86 + icon: Icons[icon], 87 + }; 88 + })} 89 + /> 90 + )} 73 91 {isFiltered && ( 74 92 <Button 75 93 variant="ghost"
+2
apps/web/src/components/icons.tsx
··· 34 34 MessageCircle, 35 35 Minus, 36 36 Moon, 37 + Network, 37 38 Newspaper, 38 39 Package, 39 40 PanelTop, ··· 100 101 zap: Zap, 101 102 eye: Eye, 102 103 "eye-off": EyeOff, 104 + network: Network, 103 105 users: Users, 104 106 key: KeyRound, 105 107 "credit-card": CreditCard,
+36
apps/web/src/components/monitor/trigger-icon-with-tooltip.tsx
··· 1 + import type { Trigger } from "@/lib/monitor/utils"; 2 + import { cn } from "@/lib/utils"; 3 + import { 4 + Tooltip, 5 + TooltipContent, 6 + TooltipProvider, 7 + TooltipTrigger, 8 + } from "@openstatus/ui/src/components/tooltip"; 9 + 10 + import { type IconProps, Icons } from "@/components/icons"; 11 + import { triggerDict } from "@/data/trigger-dictionary"; 12 + 13 + interface TriggerIconWithTooltipProps extends IconProps { 14 + triggerType: Trigger; 15 + } 16 + 17 + export function TriggerIconWithTooltip({ 18 + triggerType, 19 + className, 20 + ...props 21 + }: TriggerIconWithTooltipProps) { 22 + const config = triggerDict[triggerType]; 23 + const Icon = Icons[config.icon]; 24 + return ( 25 + <TooltipProvider delayDuration={50}> 26 + <Tooltip> 27 + <TooltipTrigger asChild> 28 + <Icon className={cn("h-4 w-4", className)} {...props} /> 29 + </TooltipTrigger> 30 + <TooltipContent> 31 + <p>{config.label}</p> 32 + </TooltipContent> 33 + </Tooltip> 34 + </TooltipProvider> 35 + ); 36 + }
+27
apps/web/src/data/trigger-dictionary.ts
··· 1 + import type { ValidIcon } from "@/components/icons"; 2 + import type { Trigger } from "@/lib/monitor/utils"; 3 + 4 + export const triggerDict = { 5 + cron: { 6 + value: "cron", 7 + label: "Scheduled", 8 + icon: "clock", 9 + }, 10 + api: { 11 + value: "api", 12 + label: "On-Demand", 13 + icon: "network", 14 + }, 15 + unknown: { 16 + value: "unknown", 17 + label: "Unknown", 18 + icon: "cog", 19 + }, 20 + } satisfies Record< 21 + string, 22 + { 23 + icon: ValidIcon; 24 + label: string; 25 + value: Trigger | "unknown"; 26 + } 27 + >;
+2
apps/web/src/lib/monitor/utils.ts
··· 12 12 export const periods = ["1h", "1d", "3d", "7d", "14d"] as const; // If neeeded (e.g. Pro plans), "7d", "30d" 13 13 export const quantiles = ["p99", "p95", "p90", "p75", "p50"] as const; 14 14 export const intervals = ["1m", "10m", "30m", "1h"] as const; 15 + export const triggers = ["cron", "api"] as const; 15 16 16 17 export type Period = (typeof periods)[number]; 17 18 export type Quantile = (typeof quantiles)[number]; 18 19 export type Interval = (typeof intervals)[number]; 20 + export type Trigger = (typeof triggers)[number]; 19 21 20 22 export function getDateByPeriod(period: Period) { 21 23 switch (period) {
+5
packages/tinybird/src/os-client.ts
··· 239 239 workspaceId: z.string(), 240 240 cronTimestamp: z.number().int().nullable().default(Date.now()), 241 241 assertions: z.string().nullable().optional(), 242 + trigger: z 243 + .enum(["cron", "api"]) 244 + .optional() 245 + .nullable() 246 + .default("cron"), 242 247 }), 243 248 opts: { 244 249 cache: "no-store",
+1
packages/tinybird/src/validation.ts
··· 95 95 region: monitorFlyRegionSchema, 96 96 message: z.string().nullable().optional(), 97 97 assertions: z.string().nullable().optional(), 98 + trigger: z.enum(["cron", "api"]).optional().nullable().default("cron"), 98 99 }); 99 100 100 101 /**