Openstatus www.openstatus.dev

fix: private locations (#1460)

* fix: private locations regions select

* refactor: private location token

authored by

Maximilian Kaske and committed by
GitHub
ae29e8b3 a68337f6

+26 -34
+4 -9
apps/dashboard/src/app/(dashboard)/monitors/[id]/logs/client.tsx
··· 43 43 setSearchParams, 44 44 ] = useQueryStates(searchParamsParsers); 45 45 const { data: workspace } = useQuery(trpc.workspace.get.queryOptions()); 46 - const { data: privateLocations } = useQuery( 47 - trpc.privateLocation.list.queryOptions(), 48 - ); 49 46 const { data: monitor } = useQuery( 50 47 trpc.monitor.get.queryOptions({ id: Number.parseInt(id) }), 51 48 ); ··· 79 76 ); 80 77 81 78 const columns = useMemo( 82 - () => getColumns(privateLocations ?? []), 83 - [privateLocations], 79 + () => getColumns(monitor?.privateLocations ?? []), 80 + [monitor?.privateLocations], 84 81 ); 85 82 86 83 if (!workspace || !monitor) return null; ··· 106 103 <DropdownTrigger /> 107 104 <CommandRegion 108 105 regions={monitor.regions} 109 - privateLocations={privateLocations?.filter((location) => 110 - location.monitors.some((m) => m.id === Number(id)), 111 - )} 106 + privateLocations={monitor?.privateLocations} 112 107 /> 113 108 <ButtonReset /> 114 109 </div> ··· 145 140 )} 146 141 <Sheet 147 142 data={_log?.data?.length ? _log.data[0] : null} 148 - privateLocations={privateLocations} 143 + privateLocations={monitor?.privateLocations ?? []} 149 144 onClose={() => 150 145 setTimeout(() => setSearchParams({ selected: null }), 300) 151 146 }
+12 -15
apps/dashboard/src/app/(dashboard)/monitors/[id]/overview/client.tsx
··· 22 22 import { PopoverQuantile } from "@/components/popovers/popover-quantile"; 23 23 import { PopoverResolution } from "@/components/popovers/popover-resolution"; 24 24 import { DataTable } from "@/components/ui/data-table/data-table"; 25 + import { DataTablePagination } from "@/components/ui/data-table/data-table-pagination"; 25 26 import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; 26 27 import { mapRegionMetrics } from "@/data/metrics.client"; 27 28 import type { RegionMetric } from "@/data/region-metrics"; ··· 43 44 const { data: monitor } = useQuery( 44 45 trpc.monitor.get.queryOptions({ id: Number.parseInt(id) }), 45 46 ); 46 - const { data: privateLocations } = useQuery( 47 - trpc.privateLocation.list.queryOptions(), 48 - ); 49 - 50 47 const selectedRegions = regions ?? undefined; 51 48 52 49 const regionTimelineQuery = { ··· 72 69 ? monitor?.regions ?? [] 73 70 : [ 74 71 ...monitorRegions, 75 - ...(privateLocations?.map((location) => location.id.toString()) ?? 76 - []), 72 + ...(monitor?.privateLocations?.map((location) => 73 + location.id.toString(), 74 + ) ?? []), 77 75 ], 78 76 percentile, 79 77 ); 80 - }, [regionTimeline, monitor, percentile, isLoading, privateLocations]); 78 + }, [regionTimeline, monitor, percentile, isLoading]); 81 79 82 80 const regionColumns = useMemo( 83 - () => getRegionColumns(privateLocations ?? []), 84 - [privateLocations], 81 + () => getRegionColumns(monitor?.privateLocations ?? []), 82 + [monitor?.privateLocations], 85 83 ); 86 84 87 85 if (!monitor) return null; ··· 106 104 <DropdownPeriod /> including{" "} 107 105 <CommandRegion 108 106 regions={monitor.regions} 109 - privateLocations={privateLocations} 107 + privateLocations={monitor.privateLocations} 110 108 /> 111 109 </div> 112 110 <div> ··· 200 198 <DataTable 201 199 data={regionMetrics} 202 200 columns={regionColumns} 203 - defaultPagination={{ 204 - pageIndex: 0, 205 - pageSize: regionMetrics.length, 206 - }} 201 + paginationComponent={({ table }) => ( 202 + <DataTablePagination table={table} /> 203 + )} 207 204 /> 208 205 </TabsContent> 209 206 <TabsContent value="chart"> 210 207 <ChartLineRegions 211 208 className="mt-3" 212 209 regions={regionMetrics.map((region) => region.region)} 213 - privateLocations={privateLocations} 210 + privateLocations={monitor?.privateLocations ?? []} 214 211 data={regionMetrics.reduce( 215 212 (acc, region) => { 216 213 region.trend.forEach((t) => {
+1
apps/dashboard/src/app/(dashboard)/private-locations/nav-actions.tsx
··· 47 47 await createPrivateLocationMutation.mutateAsync({ 48 48 name: values.name, 49 49 monitors: values.monitors, 50 + token: values.token, 50 51 }); 51 52 }} 52 53 >
+1 -1
apps/dashboard/src/components/data-table/private-locations/data-table-row-actions.tsx
··· 59 59 <FormSheetPrivateLocation 60 60 defaultValues={{ 61 61 name: props.row.original.name, 62 - key: props.row.original.token.toString(), 62 + token: props.row.original.token.toString(), 63 63 monitors: props.row.original.monitors.map((m) => m.id), 64 64 }} 65 65 monitors={monitors ?? []}
+6 -6
apps/dashboard/src/components/forms/private-location/form.tsx
··· 39 39 40 40 const schema = z.object({ 41 41 name: z.string().min(1, "Name is required"), 42 - key: z.string(), 42 + token: z.string(), 43 43 monitors: z.array(z.number()), 44 44 }); 45 45 ··· 60 60 resolver: zodResolver(schema), 61 61 defaultValues: defaultValues ?? { 62 62 name: "", 63 - key: crypto.randomUUID(), 63 + token: crypto.randomUUID(), 64 64 monitors: [], 65 65 }, 66 66 }); ··· 116 116 <FormCardContent> 117 117 <FormField 118 118 control={form.control} 119 - name="key" 119 + name="token" 120 120 disabled 121 121 render={({ field }) => ( 122 122 <FormItem> 123 - <FormLabel>Key</FormLabel> 123 + <FormLabel>Token</FormLabel> 124 124 <FormControl> 125 125 <InputGroup> 126 126 <InputGroupInput 127 - placeholder="Private Location Key" 127 + placeholder="Private Location Token" 128 128 readOnly 129 129 value={field.value} 130 130 /> ··· 135 135 size="icon-xs" 136 136 onClick={() => { 137 137 copy(field.value, { 138 - successMessage: "Key copied to clipboard", 138 + successMessage: "Token copied to clipboard", 139 139 }); 140 140 }} 141 141 >
+2 -3
packages/api/src/router/privateLocation.ts
··· 32 32 z.object({ 33 33 name: z.string(), 34 34 monitors: z.array(z.number()), 35 + token: z.string(), 35 36 }), 36 37 ) 37 38 .mutation(async (opts) => { 38 - const token = crypto.randomUUID(); 39 - 40 39 return await opts.ctx.db.transaction(async (tx) => { 41 40 const _privateLocation = await tx 42 41 .insert(privateLocation) 43 42 .values({ 44 43 name: opts.input.name, 45 - token, 44 + token: opts.input.token, 46 45 workspaceId: opts.ctx.workspace.id, 47 46 }) 48 47 .returning()