Skip to content

Commit 92eabe3

Browse files
authored
Auth + Database Report Fix (supabase#36768)
rollback previous files and move auth changes to new files
1 parent 4984392 commit 92eabe3

File tree

5 files changed

+446
-77
lines changed

5 files changed

+446
-77
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* This component acts as a bridge between the data-fetching logic and the
88
* presentational chart component.
99
*/
10-
import ComposedChartHandler from 'components/ui/Charts/ComposedChartHandler'
10+
import LogChartHandler from 'components/ui/Charts/LogChartHandler'
1111
import { useChartData } from 'hooks/useChartData'
1212
import type { UpdateDateRange } from 'pages/project/[ref]/reports/database'
1313
import type { MultiAttribute } from 'components/ui/Charts/ComposedChart.utils'
@@ -43,7 +43,7 @@ const ReportChart = ({
4343
})
4444

4545
return (
46-
<ComposedChartHandler
46+
<LogChartHandler
4747
{...chart}
4848
attributes={
4949
(chartAttributes.length > 0 ? chartAttributes : chart.attributes) as MultiAttribute[]

apps/studio/components/ui/Charts/ComposedChartHandler.tsx

Lines changed: 157 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
/**
2-
* ComposedChartHandler
3-
*
4-
* A presentational component for rendering charts.
5-
* It is responsible only for rendering the chart UI based on the data and loading state passed to it as props.
6-
* All the complex data fetching logic has been moved to the useChartData hook.
7-
*/
8-
import React, { PropsWithChildren, useState, useEffect, useRef } from 'react'
1+
import React, { PropsWithChildren, useState, useMemo, useEffect, useRef } from 'react'
2+
import { useRouter } from 'next/router'
93
import { Loader2 } from 'lucide-react'
104
import { cn, WarningIcon } from 'ui'
115

@@ -17,14 +11,14 @@ import { InfraMonitoringAttribute } from 'data/analytics/infra-monitoring-query'
1711
import { useInfraMonitoringQueries } from 'data/analytics/infra-monitoring-queries'
1812
import { ProjectDailyStatsAttribute } from 'data/analytics/project-daily-stats-query'
1913
import { useProjectDailyStatsQueries } from 'data/analytics/project-daily-stats-queries'
14+
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
2015
import { useChartHighlight } from './useChartHighlight'
21-
import { getMockDataForAttribute } from 'data/reports/auth-charts'
2216

2317
import type { ChartData } from './Charts.types'
2418
import type { UpdateDateRange } from 'pages/project/[ref]/reports/database'
25-
import type { MultiAttribute } from './ComposedChart.utils'
19+
import { MultiAttribute } from './ComposedChart.utils'
2620

27-
interface ComposedChartHandlerProps {
21+
export interface ComposedChartHandlerProps {
2822
id?: string
2923
label: string
3024
attributes: MultiAttribute[]
@@ -46,7 +40,6 @@ interface ComposedChartHandlerProps {
4640
updateDateRange: UpdateDateRange
4741
valuePrecision?: number
4842
isVisible?: boolean
49-
titleTooltip?: string
5043
docsUrl?: string
5144
}
5245

@@ -98,6 +91,9 @@ const LazyChartWrapper = ({ children }: PropsWithChildren) => {
9891
const ComposedChartHandler = ({
9992
label,
10093
attributes,
94+
startDate,
95+
endDate,
96+
interval,
10197
customDateFormat,
10298
children = null,
10399
defaultChartStyle = 'bar',
@@ -113,14 +109,131 @@ const ComposedChartHandler = ({
113109
showTotal,
114110
updateDateRange,
115111
valuePrecision,
116-
titleTooltip,
112+
isVisible = true,
117113
id,
118114
...otherProps
119115
}: PropsWithChildren<ComposedChartHandlerProps>) => {
116+
const router = useRouter()
117+
const { ref } = router.query
118+
119+
const state = useDatabaseSelectorStateSnapshot()
120120
const [chartStyle, setChartStyle] = useState<string>(defaultChartStyle)
121121
const chartHighlight = useChartHighlight()
122122

123-
if (isLoading) {
123+
const databaseIdentifier = state.selectedDatabaseId
124+
125+
// Use the custom hook at the top level of the component
126+
const attributeQueries = useAttributeQueries(
127+
attributes,
128+
ref,
129+
startDate,
130+
endDate,
131+
interval as AnalyticsInterval,
132+
databaseIdentifier,
133+
data,
134+
isVisible
135+
)
136+
137+
// Combine all the data into a single dataset
138+
const combinedData = useMemo(() => {
139+
if (data) return data
140+
141+
const isLoading = attributeQueries.some((query: any) => query.isLoading)
142+
if (isLoading) return undefined
143+
144+
const hasError = attributeQueries.some((query: any) => !query.data)
145+
if (hasError) return undefined
146+
147+
// Get all unique timestamps from all datasets
148+
const timestamps = new Set<string>()
149+
attributeQueries.forEach((query: any) => {
150+
query.data?.data?.forEach((point: any) => {
151+
if (point?.period_start) {
152+
timestamps.add(point.period_start)
153+
}
154+
})
155+
})
156+
157+
const referenceLineQueries = attributeQueries.filter(
158+
(_, index) => attributes[index].provider === 'reference-line'
159+
)
160+
161+
// Combine data points for each timestamp
162+
const combined = Array.from(timestamps)
163+
.sort()
164+
.map((timestamp) => {
165+
const point: any = { timestamp }
166+
167+
// Add regular attributes
168+
attributes.forEach((attr, index) => {
169+
if (!attr) return
170+
171+
// Handle custom value attributes (like disk size)
172+
if (attr.customValue !== undefined) {
173+
point[attr.attribute] = attr.customValue
174+
return
175+
}
176+
177+
// Skip reference line attributes here, we'll add them below
178+
if (attr.provider === 'reference-line') return
179+
180+
const queryData = attributeQueries[index]?.data?.data
181+
const matchingPoint = queryData?.find((p: any) => p.period_start === timestamp)
182+
let value = matchingPoint?.[attr.attribute] ?? 0
183+
184+
// Apply value manipulation if provided
185+
if (attr.manipulateValue && typeof attr.manipulateValue === 'function') {
186+
// Ensure value is a number before manipulation
187+
const numericValue = typeof value === 'number' ? value : Number(value) || 0
188+
value = attr.manipulateValue(numericValue)
189+
}
190+
191+
point[attr.attribute] = value
192+
})
193+
194+
// Add reference line values for each timestamp
195+
referenceLineQueries.forEach((query: any) => {
196+
const attr = query.data.attribute
197+
const value = query.data.total
198+
point[attr] = value
199+
})
200+
201+
return point as DataPoint
202+
})
203+
204+
return combined as DataPoint[]
205+
}, [data, attributeQueries, attributes])
206+
207+
const loading = isLoading || attributeQueries.some((query: any) => query.isLoading)
208+
209+
// Calculate highlighted value based on the first attribute's data
210+
const _highlightedValue = useMemo(() => {
211+
if (highlightedValue !== undefined) return highlightedValue
212+
213+
const firstAttr = attributes[0]
214+
const firstQuery = attributeQueries[0]
215+
const firstData = firstQuery?.data
216+
217+
if (!firstData) return undefined
218+
219+
const shouldHighlightMaxValue =
220+
firstAttr.provider === 'daily-stats' &&
221+
!firstAttr.attribute.includes('ingress') &&
222+
!firstAttr.attribute.includes('egress') &&
223+
'maximum' in firstData
224+
225+
const shouldHighlightTotalGroupedValue = 'totalGrouped' in firstData
226+
227+
return shouldHighlightMaxValue
228+
? firstData.maximum
229+
: firstAttr.provider === 'daily-stats'
230+
? firstData.total
231+
: shouldHighlightTotalGroupedValue
232+
? firstData.totalGrouped?.[firstAttr.attribute as keyof typeof firstData.totalGrouped]
233+
: (firstData.data[firstData.data.length - 1] as any)?.[firstAttr.attribute]
234+
}, [highlightedValue, attributes, attributeQueries])
235+
236+
if (loading) {
124237
return (
125238
<Panel
126239
className={cn(
@@ -137,7 +250,7 @@ const ComposedChartHandler = ({
137250
)
138251
}
139252

140-
if (!data) {
253+
if (!combinedData) {
141254
return (
142255
<div className="flex h-52 w-full flex-col items-center justify-center gap-y-2">
143256
<WarningIcon />
@@ -159,11 +272,11 @@ const ComposedChartHandler = ({
159272
<div className="absolute right-6 z-50 flex justify-between scroll-mt-16">{children}</div>
160273
<ComposedChart
161274
attributes={attributes}
162-
data={data as any}
275+
data={combinedData as DataPoint[]}
163276
format={format}
164277
xAxisKey="period_start"
165278
yAxisKey={attributes[0].attribute}
166-
highlightedValue={highlightedValue}
279+
highlightedValue={_highlightedValue}
167280
title={label}
168281
customDateFormat={customDateFormat}
169282
chartHighlight={chartHighlight}
@@ -176,15 +289,14 @@ const ComposedChartHandler = ({
176289
updateDateRange={updateDateRange}
177290
valuePrecision={valuePrecision}
178291
hideChartType={hideChartType}
179-
titleTooltip={titleTooltip}
180292
{...otherProps}
181293
/>
182294
</Panel.Content>
183295
</Panel>
184296
)
185297
}
186298

187-
export const useAttributeQueries = (
299+
const useAttributeQueries = (
188300
attributes: MultiAttribute[],
189301
ref: string | string[] | undefined,
190302
startDate: string,
@@ -194,15 +306,16 @@ export const useAttributeQueries = (
194306
data: ChartData | undefined,
195307
isVisible: boolean
196308
) => {
197-
const projectRef = typeof ref === 'string' ? ref : Array.isArray(ref) ? ref[0] : ''
198-
199-
const infraAttributes = attributes.filter((attr) => attr.provider === 'infra-monitoring')
200-
const dailyStatsAttributes = attributes.filter((attr) => attr.provider === 'daily-stats')
201-
const mockAttributes = attributes.filter((attr) => attr.provider === 'mock')
202-
const referenceLineAttributes = attributes.filter((attr) => attr.provider === 'reference-line')
309+
const infraAttributes = attributes
310+
.filter((attr) => attr?.provider === 'infra-monitoring')
311+
.map((attr) => attr.attribute as InfraMonitoringAttribute)
312+
const dailyStatsAttributes = attributes
313+
.filter((attr) => attr?.provider === 'daily-stats')
314+
.map((attr) => attr.attribute as ProjectDailyStatsAttribute)
315+
const referenceLines = attributes.filter((attr) => attr?.provider === 'reference-line')
203316

204317
const infraQueries = useInfraMonitoringQueries(
205-
infraAttributes.map((attr) => attr.attribute as InfraMonitoringAttribute),
318+
infraAttributes,
206319
ref,
207320
startDate,
208321
endDate,
@@ -212,7 +325,7 @@ export const useAttributeQueries = (
212325
isVisible
213326
)
214327
const dailyStatsQueries = useProjectDailyStatsQueries(
215-
dailyStatsAttributes.map((attr) => attr.attribute as ProjectDailyStatsAttribute),
328+
dailyStatsAttributes,
216329
ref,
217330
startDate,
218331
endDate,
@@ -222,48 +335,23 @@ export const useAttributeQueries = (
222335
isVisible
223336
)
224337

225-
let infraIdx = 0
226-
let dailyStatsIdx = 0
227-
return attributes
228-
.filter((attr) => attr.provider !== 'logs')
229-
.map((attr) => {
230-
if (attr.provider === 'infra-monitoring') {
231-
return {
232-
...infraQueries[infraIdx++],
233-
data: { ...infraQueries[infraIdx - 1]?.data, provider: 'infra-monitoring' },
234-
}
235-
} else if (attr.provider === 'daily-stats') {
236-
return {
237-
...dailyStatsQueries[dailyStatsIdx++],
238-
data: { ...dailyStatsQueries[dailyStatsIdx - 1]?.data, provider: 'daily-stats' },
239-
}
240-
} else if (attr.provider === 'mock') {
241-
const mockData = getMockDataForAttribute(attr.attribute)
242-
return {
243-
isLoading: false,
244-
data: { ...mockData, provider: 'mock', attribute: attr.attribute },
245-
}
246-
} else if (attr.provider === 'reference-line') {
247-
let value = attr.value || 0
248-
return {
249-
data: {
250-
data: [],
251-
attribute: attr.attribute,
252-
total: value,
253-
maximum: value,
254-
totalGrouped: { [attr.attribute]: value },
255-
provider: 'reference-line',
256-
},
257-
isLoading: false,
258-
isError: false,
259-
}
260-
} else {
261-
return {
262-
isLoading: false,
263-
data: undefined,
264-
}
265-
}
266-
})
338+
const referenceLineQueries = referenceLines.map((line) => {
339+
let value = line.value || 0
340+
341+
return {
342+
data: {
343+
data: [], // Will be populated in combinedData
344+
attribute: line.attribute,
345+
total: value,
346+
maximum: value,
347+
totalGrouped: { [line.attribute]: value },
348+
},
349+
isLoading: false,
350+
isError: false,
351+
}
352+
})
353+
354+
return [...infraQueries, ...dailyStatsQueries, ...referenceLineQueries]
267355
}
268356

269357
export default function LazyComposedChartHandler(props: ComposedChartHandlerProps) {

0 commit comments

Comments
 (0)