Skip to content

Commit 866185d

Browse files
fix(studio): observability reports refresh time (supabase#40876)
* fix: realtime report refresh * feat: add createRefreshHandler hook * feat: add new refresh for storage * feat: add new refresh for postgrest * feat: add new refresh for edge functions * fix: rename postgrest to data api * feat: add db auth and api overview refresh * fix: db refresh handler for time * chore: change from or to nullish where required * chore: db refresh func becomes flatmap * chore: memoize helper function for report refresh * chore: remove unused lines from realtime * fix: be a bit more verbose apparently * chore: remove unused imports
1 parent dbb5c1b commit 866185d

File tree

9 files changed

+165
-63
lines changed

9 files changed

+165
-63
lines changed

apps/studio/components/interfaces/Reports/ReportFilterBar.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,13 @@ const ReportFilterBar = ({
171171

172172
const [selectedRange, setSelectedRange] = useState<DatePickerValue>(getInitialDatePickerValue())
173173

174+
// Sync selectedRange when initialDatePickerValue changes
175+
useEffect(() => {
176+
if (initialDatePickerValue) {
177+
setSelectedRange(initialDatePickerValue)
178+
}
179+
}, [initialDatePickerValue])
180+
174181
return (
175182
<div className={cn('flex items-center justify-between', className)}>
176183
<div className="flex flex-row justify-start items-center flex-wrap gap-2">

apps/studio/hooks/misc/useReportDateRange.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,3 +272,26 @@ export const useReportDateRange = (
272272
handleDatePickerChange,
273273
}
274274
}
275+
276+
export function useRefreshHandler(
277+
datePickerValue: DatePickerValue,
278+
datePickerHelpers: ReportsDatetimeHelper[],
279+
handleDatePickerChange: (value: DatePickerValue) => boolean | void,
280+
refresh: () => void | Promise<void>
281+
): () => void | Promise<void> {
282+
return useCallback(async () => {
283+
if (datePickerValue.isHelper && datePickerValue.text) {
284+
const selectedHelper = datePickerHelpers.find((h) => h.text === datePickerValue.text)
285+
if (selectedHelper) {
286+
handleDatePickerChange({
287+
from: selectedHelper.calcFrom(),
288+
to: selectedHelper.calcTo(),
289+
isHelper: true,
290+
text: selectedHelper.text,
291+
})
292+
}
293+
}
294+
295+
await refresh()
296+
}, [datePickerValue, datePickerHelpers, handleDatePickerChange, refresh])
297+
}

apps/studio/pages/project/[ref]/observability/api-overview.tsx

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import DefaultLayout from 'components/layouts/DefaultLayout'
1717
import ObservabilityLayout from 'components/layouts/ObservabilityLayout/ObservabilityLayout'
1818
import { useApiReport } from 'data/reports/api-report-query'
1919
import { useReportDateRange } from 'hooks/misc/useReportDateRange'
20+
import { useCallback } from 'react'
2021
import type { NextPageWithLayout } from 'types'
2122

2223
export const ApiReport: NextPageWithLayout = () => {
@@ -42,15 +43,51 @@ export const ApiReport: NextPageWithLayout = () => {
4243
setShowUpgradePrompt,
4344
} = useReportDateRange(REPORT_DATERANGE_HELPER_LABELS.LAST_60_MINUTES)
4445

45-
const handleDatepickerChange = (vals: DatePickerValue) => {
46-
const promptShown = handleDatePickerChangeFromHook(vals)
47-
if (!promptShown) {
46+
const handleDatepickerChange = useCallback(
47+
(vals: DatePickerValue) => {
48+
const promptShown = handleDatePickerChangeFromHook(vals)
49+
if (!promptShown) {
50+
mergeParams({
51+
iso_timestamp_start: vals.from ?? '',
52+
iso_timestamp_end: vals.to ?? '',
53+
})
54+
}
55+
},
56+
[handleDatePickerChangeFromHook, mergeParams]
57+
)
58+
59+
const handleDatepickerChangeForRefresh = useCallback(
60+
(vals: DatePickerValue) => {
61+
handleDatePickerChangeFromHook(vals)
4862
mergeParams({
49-
iso_timestamp_start: vals.from || '',
50-
iso_timestamp_end: vals.to || '',
63+
iso_timestamp_start: vals.from ?? '',
64+
iso_timestamp_end: vals.to ?? '',
5165
})
66+
handleDatepickerChange(vals)
67+
},
68+
[handleDatePickerChangeFromHook, mergeParams, handleDatepickerChange]
69+
)
70+
71+
const refreshWithParams = useCallback(async () => {
72+
await new Promise((resolve) => setTimeout(resolve, 0))
73+
refresh()
74+
}, [refresh])
75+
76+
const onRefreshReport = useCallback(async () => {
77+
if (datePickerValue.isHelper && datePickerValue.text) {
78+
const selectedHelper = datePickerHelpers.find((h) => h.text === datePickerValue.text)
79+
if (selectedHelper) {
80+
handleDatepickerChangeForRefresh({
81+
from: selectedHelper.calcFrom(),
82+
to: selectedHelper.calcTo(),
83+
isHelper: true,
84+
text: selectedHelper.text,
85+
})
86+
}
5287
}
53-
}
88+
89+
await refreshWithParams()
90+
}, [datePickerValue, datePickerHelpers, handleDatepickerChangeForRefresh, refreshWithParams])
5491

5592
return (
5693
<ReportPadding>
@@ -64,7 +101,7 @@ export const ApiReport: NextPageWithLayout = () => {
64101
datepickerFrom={params.totalRequests.iso_timestamp_start}
65102
datepickerTo={params.totalRequests.iso_timestamp_end}
66103
onAddFilter={addFilter}
67-
onRefresh={refresh}
104+
onRefresh={onRefreshReport}
68105
isLoading={isLoading}
69106
filters={filters}
70107
datepickerHelpers={datePickerHelpers}

apps/studio/pages/project/[ref]/observability/auth.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import {
3434
createLatencyReportConfig,
3535
createUsageReportConfig,
3636
} from 'data/reports/v2/auth.config'
37-
import { useReportDateRange } from 'hooks/misc/useReportDateRange'
37+
import { useReportDateRange, useRefreshHandler } from 'hooks/misc/useReportDateRange'
3838
import { useRouter } from 'next/router'
3939
import { parseAsJson, useQueryState } from 'nuqs'
4040
import type { NextPageWithLayout } from 'types'
@@ -155,14 +155,18 @@ const AuthUsage = () => {
155155
filters: {},
156156
})
157157

158-
const onRefreshReport = async () => {
159-
if (!selectedDateRange) return
160-
161-
setIsRefreshing(true)
158+
const onRefreshReport = useRefreshHandler(
159+
datePickerValue,
160+
datePickerHelpers,
161+
handleDatePickerChange,
162+
async () => {
163+
if (!selectedDateRange) return
162164

163-
refetch()
164-
setTimeout(() => setIsRefreshing(false), 1000)
165-
}
165+
setIsRefreshing(true)
166+
refetch()
167+
setTimeout(() => setIsRefreshing(false), 1000)
168+
}
169+
)
166170

167171
const router = useRouter()
168172

apps/studio/pages/project/[ref]/observability/database.tsx

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import { getReportAttributesV2 } from 'data/reports/database-charts'
3737
import { useDatabaseReport } from 'data/reports/database-report-query'
3838
import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query'
3939
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
40-
import { useReportDateRange } from 'hooks/misc/useReportDateRange'
40+
import { useReportDateRange, useRefreshHandler } from 'hooks/misc/useReportDateRange'
4141
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
4242
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
4343
import { DOCS_URL } from 'lib/constants'
@@ -140,38 +140,45 @@ const DatabaseUsage = () => {
140140
},
141141
})
142142

143-
const onRefreshReport = async () => {
144-
if (!selectedDateRange) return
143+
const onRefreshReport = useRefreshHandler(
144+
datePickerValue,
145+
datePickerHelpers,
146+
handleDatePickerChange,
147+
async () => {
148+
if (!selectedDateRange) return
149+
150+
setIsRefreshing(true)
151+
refresh()
152+
const { period_start, period_end, interval } = selectedDateRange
145153

146-
setIsRefreshing(true)
147-
refresh()
148-
const { period_start, period_end, interval } = selectedDateRange
149-
REPORT_ATTRIBUTES.forEach((chart: any) => {
150-
chart.attributes.forEach((attr: any) => {
154+
REPORT_ATTRIBUTES.flatMap((chart) => chart.attributes || [])
155+
.filter((attr): attr is MultiAttribute => attr !== false)
156+
.forEach((attr) => {
157+
queryClient.invalidateQueries({
158+
queryKey: analyticsKeys.infraMonitoring(ref, {
159+
attribute: attr.attribute,
160+
startDate: period_start.date,
161+
endDate: period_end.date,
162+
interval,
163+
databaseIdentifier: state.selectedDatabaseId,
164+
}),
165+
})
166+
})
167+
168+
if (isReplicaSelected) {
151169
queryClient.invalidateQueries({
152170
queryKey: analyticsKeys.infraMonitoring(ref, {
153-
attribute: attr.attribute,
171+
attribute: 'physical_replication_lag_physical_replica_lag_seconds',
154172
startDate: period_start.date,
155173
endDate: period_end.date,
156174
interval,
157175
databaseIdentifier: state.selectedDatabaseId,
158176
}),
159177
})
160-
})
161-
})
162-
if (isReplicaSelected) {
163-
queryClient.invalidateQueries({
164-
queryKey: analyticsKeys.infraMonitoring(ref, {
165-
attribute: 'physical_replication_lag_physical_replica_lag_seconds',
166-
startDate: period_start.date,
167-
endDate: period_end.date,
168-
interval,
169-
databaseIdentifier: state.selectedDatabaseId,
170-
}),
171-
})
178+
}
179+
setTimeout(() => setIsRefreshing(false), 1000)
172180
}
173-
setTimeout(() => setIsRefreshing(false), 1000)
174-
}
181+
)
175182

176183
const stateSyncedFromUrlRef = useRef(false)
177184
useEffect(() => {

apps/studio/pages/project/[ref]/observability/edge-functions.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { edgeFunctionReports } from 'data/reports/v2/edge-functions.config'
2727

2828
import { REPORT_DATERANGE_HELPER_LABELS } from 'components/interfaces/Reports/Reports.constants'
2929
import UpgradePrompt from 'components/interfaces/Settings/Logs/UpgradePrompt'
30-
import { useReportDateRange } from 'hooks/misc/useReportDateRange'
30+
import { useReportDateRange, useRefreshHandler } from 'hooks/misc/useReportDateRange'
3131

3232
import { EDGE_FUNCTION_REGIONS } from 'components/interfaces/Reports/Reports.constants'
3333
import { ReportSettings } from 'components/ui/Charts/ReportSettings'
@@ -117,13 +117,18 @@ const EdgeFunctionsUsage = () => {
117117
executionTimeFilter,
118118
])
119119

120-
const onRefreshReport = async () => {
121-
if (!selectedDateRange) return
120+
const onRefreshReport = useRefreshHandler(
121+
datePickerValue,
122+
datePickerHelpers,
123+
handleDatePickerChange,
124+
async () => {
125+
if (!selectedDateRange) return
122126

123-
setIsRefreshing(true)
124-
queryClient.invalidateQueries({ queryKey: ['projects', ref, 'report-v2'] })
125-
setTimeout(() => setIsRefreshing(false), 1000)
126-
}
127+
setIsRefreshing(true)
128+
queryClient.invalidateQueries({ queryKey: ['projects', ref, 'report-v2'] })
129+
setTimeout(() => setIsRefreshing(false), 1000)
130+
}
131+
)
127132

128133
return (
129134
<>

apps/studio/pages/project/[ref]/observability/postgrest.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import UpgradePrompt from 'components/interfaces/Settings/Logs/UpgradePrompt'
1515
import DefaultLayout from 'components/layouts/DefaultLayout'
1616
import ObservabilityLayout from 'components/layouts/ObservabilityLayout/ObservabilityLayout'
1717
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
18-
import { useReportDateRange } from 'hooks/misc/useReportDateRange'
18+
import { useReportDateRange, useRefreshHandler } from 'hooks/misc/useReportDateRange'
1919
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
2020

2121
import ReportFilterBar from 'components/interfaces/Reports/ReportFilterBar'
@@ -95,9 +95,16 @@ const PostgrestReport = () => {
9595
handleDatePickerChangeFromHook(values)
9696
}
9797

98+
const onRefreshReport = useRefreshHandler(
99+
datePickerValue,
100+
datePickerHelpers,
101+
handleDatePickerChange,
102+
refetch
103+
)
104+
98105
return (
99106
<>
100-
<ReportHeader showDatabaseSelector={false} title="PostgREST" />
107+
<ReportHeader showDatabaseSelector={false} title="Data API" />
101108
<ReportStickyNav
102109
content={
103110
<div className="flex flex-col gap-2">
@@ -108,7 +115,7 @@ const PostgrestReport = () => {
108115
icon={<RefreshCw className={isRefetching ? 'animate-spin' : ''} />}
109116
className="w-7"
110117
tooltip={{ content: { side: 'bottom', text: 'Refresh report' } }}
111-
onClick={() => refetch()}
118+
onClick={onRefreshReport}
112119
/>
113120
<LogsDatePicker
114121
onSubmit={handleDatePickerChange}

apps/studio/pages/project/[ref]/observability/realtime.tsx

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
1717
import { REPORT_DATERANGE_HELPER_LABELS } from 'components/interfaces/Reports/Reports.constants'
1818
import ReportStickyNav from 'components/interfaces/Reports/ReportStickyNav'
1919
import UpgradePrompt from 'components/interfaces/Settings/Logs/UpgradePrompt'
20-
import { useReportDateRange } from 'hooks/misc/useReportDateRange'
20+
import { useRefreshHandler, useReportDateRange } from 'hooks/misc/useReportDateRange'
2121

2222
import { SharedAPIReport } from 'components/interfaces/Reports/SharedAPIReport/SharedAPIReport'
2323
import { useSharedAPIReport } from 'components/interfaces/Reports/SharedAPIReport/SharedAPIReport.constants'
@@ -86,16 +86,22 @@ const RealtimeUsage = () => {
8686
})
8787
}, [ref, selectedDateRange, state.selectedDatabaseId])
8888

89-
const onRefreshReport = async () => {
90-
if (!selectedDateRange) return
89+
const onRefreshReport = useRefreshHandler(
90+
datePickerValue,
91+
datePickerHelpers,
92+
handleDatePickerChange,
93+
async () => {
94+
if (!selectedDateRange) return
9195

92-
setIsRefreshing(true)
93-
queryClient.invalidateQueries({
94-
queryKey: ['projects', ref, 'report-v2', { queryGroup: 'realtime' }],
95-
})
96-
refetch()
97-
setTimeout(() => setIsRefreshing(false), 1000)
98-
}
96+
setIsRefreshing(true)
97+
98+
queryClient.invalidateQueries({
99+
queryKey: ['projects', ref, 'report-v2', { queryGroup: 'realtime' }],
100+
})
101+
refetch()
102+
setTimeout(() => setIsRefreshing(false), 1000)
103+
}
104+
)
99105

100106
const urlStateHasSyncedRef = useRef(false)
101107
useEffect(() => {

apps/studio/pages/project/[ref]/observability/storage.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import DefaultLayout from 'components/layouts/DefaultLayout'
2727
import ObservabilityLayout from 'components/layouts/ObservabilityLayout/ObservabilityLayout'
2828
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
2929
import { useStorageReport } from 'data/reports/storage-report-query'
30-
import { useReportDateRange } from 'hooks/misc/useReportDateRange'
30+
import { useReportDateRange, useRefreshHandler } from 'hooks/misc/useReportDateRange'
3131
import { DOCS_URL } from 'lib/constants'
3232
import type { NextPageWithLayout } from 'types'
3333

@@ -58,14 +58,20 @@ export const StorageReport: NextPageWithLayout = () => {
5858
const handleDatepickerChange = (vals: DatePickerValue) => {
5959
const promptShown = handleDatePickerChangeFromHook(vals)
6060
if (!promptShown) {
61-
// Update query params for the report
6261
mergeParams({
63-
iso_timestamp_start: vals.from || '',
64-
iso_timestamp_end: vals.to || '',
62+
iso_timestamp_start: vals.from ?? '',
63+
iso_timestamp_end: vals.to ?? '',
6564
})
6665
}
6766
}
6867

68+
const onRefreshReport = useRefreshHandler(
69+
datePickerValue,
70+
datePickerHelpers,
71+
handleDatepickerChange,
72+
refresh
73+
)
74+
6975
return (
7076
<ReportPadding>
7177
<ReportHeader title="Storage" showDatabaseSelector={false} />
@@ -79,7 +85,7 @@ export const StorageReport: NextPageWithLayout = () => {
7985
icon={<RefreshCw className={report.isLoading ? 'animate-spin' : ''} />}
8086
className="w-7"
8187
tooltip={{ content: { side: 'bottom', text: 'Refresh report' } }}
82-
onClick={() => report.refresh()}
88+
onClick={onRefreshReport}
8389
/>
8490
<LogsDatePicker
8591
onSubmit={handleDatepickerChange}

0 commit comments

Comments
 (0)