mirror of
https://github.com/supabase/supabase.git
synced 2026-10-14 21:59:16 +03:00
reduce dupplicate code in reports date ranges
This commit is contained in:
1 parent
4150bbe2cc
commit
65185cd499
8 files changed
+68
-131
No files matched your search
@@ -22,22 +22,26 @@ import { TestCollectionDialog } from './TestCollectionDialog'
|
||||
|
||||
const INTERVALS: DatetimeHelper[] = [
|
||||
{
|
||||
id: 'last-hour',
|
||||
text: 'Last hour',
|
||||
calcFrom: () => dayjs().subtract(1, 'hour').toISOString(),
|
||||
calcTo: () => dayjs().toISOString(),
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
id: 'last-12-hours',
|
||||
text: 'Last 12 hours',
|
||||
calcFrom: () => dayjs().subtract(12, 'hour').toISOString(),
|
||||
calcTo: () => dayjs().toISOString(),
|
||||
},
|
||||
{
|
||||
id: 'last-day',
|
||||
text: 'Last day',
|
||||
calcFrom: () => dayjs().subtract(1, 'day').toISOString(),
|
||||
calcTo: () => dayjs().toISOString(),
|
||||
},
|
||||
{
|
||||
id: 'last-7-days',
|
||||
text: 'Last 7 days',
|
||||
calcFrom: () => dayjs().subtract(7, 'day').toISOString(),
|
||||
calcTo: () => dayjs().toISOString(),
|
||||
@@ -202,22 +206,7 @@ order by timestamp desc limit ${filters.limit} offset ${filters.offset}
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
/> */}
|
||||
<LogsDatePicker
|
||||
helpers={INTERVALS}
|
||||
value={{
|
||||
from: filters.interval.from(),
|
||||
to: filters.interval.to(),
|
||||
}}
|
||||
onSubmit={(e) =>
|
||||
setFilters({
|
||||
...filters,
|
||||
interval: {
|
||||
to: () => e.to || '',
|
||||
from: () => e.from || '',
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
<LogsDatePicker helpers={INTERVALS} />
|
||||
</form>
|
||||
<div className="flex items-center gap-2">
|
||||
<Tooltip>
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
Select,
|
||||
cn,
|
||||
} from 'ui'
|
||||
import { DatePickerValue, LogsDatePicker } from '../Settings/Logs/Logs.DatePickers'
|
||||
import { LogsDatePicker } from '../Settings/Logs/Logs.DatePickers'
|
||||
import { REPORTS_DATEPICKER_HELPERS } from './Reports.constants'
|
||||
import type { ReportFilterItem } from './Reports.types'
|
||||
|
||||
@@ -30,9 +30,6 @@ interface ReportFilterBarProps {
|
||||
onAddFilter: (filter: ReportFilterItem) => void
|
||||
onRemoveFilters: (filters: ReportFilterItem[]) => void
|
||||
onRefresh: () => void
|
||||
onDatepickerChange: ComponentProps<typeof LogsDatePicker>['onSubmit']
|
||||
datepickerTo?: string
|
||||
datepickerFrom?: string
|
||||
datepickerHelpers: typeof REPORTS_DATEPICKER_HELPERS
|
||||
}
|
||||
|
||||
@@ -83,7 +80,6 @@ const ReportFilterBar = ({
|
||||
filters,
|
||||
isLoading = false,
|
||||
onAddFilter,
|
||||
onDatepickerChange,
|
||||
onRemoveFilters,
|
||||
onRefresh,
|
||||
datepickerHelpers,
|
||||
@@ -117,11 +113,6 @@ const ReportFilterBar = ({
|
||||
})
|
||||
}
|
||||
|
||||
const handleDatepickerChange = (vals: DatePickerValue) => {
|
||||
onDatepickerChange(vals)
|
||||
setSelectedRange(vals)
|
||||
}
|
||||
|
||||
const handleProductFilterChange = async (
|
||||
nextProductFilter: null | (typeof PRODUCT_FILTERS)[number]
|
||||
) => {
|
||||
@@ -144,14 +135,6 @@ const ReportFilterBar = ({
|
||||
setCurrentProductFilter(nextProductFilter)
|
||||
}
|
||||
|
||||
const defaultHelper = datepickerHelpers[0]
|
||||
const [selectedRange, setSelectedRange] = useState<DatePickerValue>({
|
||||
to: defaultHelper.calcTo(),
|
||||
from: defaultHelper.calcFrom(),
|
||||
isHelper: true,
|
||||
text: defaultHelper.text,
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-row justify-start items-center flex-wrap gap-2">
|
||||
@@ -163,11 +146,7 @@ const ReportFilterBar = ({
|
||||
tooltip={{ content: { side: 'bottom', text: 'Refresh report' } }}
|
||||
onClick={() => onRefresh()}
|
||||
/>
|
||||
<LogsDatePicker
|
||||
onSubmit={handleDatepickerChange}
|
||||
value={selectedRange}
|
||||
helpers={datepickerHelpers}
|
||||
/>
|
||||
<LogsDatePicker helpers={datepickerHelpers} />
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
|
||||
@@ -65,8 +65,6 @@ const PreviewFilterPanel = ({
|
||||
table,
|
||||
onSelectedDatabaseChange,
|
||||
className,
|
||||
selectedDatePickerValue,
|
||||
setSelectedDatePickerValue,
|
||||
}: PreviewFilterPanelProps) => {
|
||||
const router = useRouter()
|
||||
const { ref } = useParams()
|
||||
@@ -181,14 +179,7 @@ const PreviewFilterPanel = ({
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<LogsDatePicker
|
||||
helpers={PREVIEWER_DATEPICKER_HELPERS}
|
||||
onSubmit={(vals) => {
|
||||
onSearch('datepicker-change', { to: vals.to, from: vals.from })
|
||||
setSelectedDatePickerValue(vals)
|
||||
}}
|
||||
value={selectedDatePickerValue}
|
||||
/>
|
||||
<LogsDatePicker helpers={PREVIEWER_DATEPICKER_HELPERS} />
|
||||
|
||||
{FILTER_OPTIONS[table] !== undefined && (
|
||||
<div className="flex items-center">
|
||||
|
||||
@@ -8,11 +8,13 @@ import { queriesFactory } from 'components/interfaces/Reports/Reports.utils'
|
||||
import type { LogsEndpointParams } from 'components/interfaces/Settings/Logs/Logs.types'
|
||||
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
|
||||
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
|
||||
import { useLogsUrlState } from 'hooks/analytics/useLogsUrlState'
|
||||
|
||||
export const useApiReport = () => {
|
||||
const { project } = useProjectContext()
|
||||
const { ref: projectRef } = useParams()
|
||||
const state = useDatabaseSelectorStateSnapshot()
|
||||
const { timestampStart, timestampEnd } = useLogsUrlState()
|
||||
|
||||
const identifier = state.selectedDatabaseId
|
||||
const [filters, setFilters] = useState<ReportFilterItem[]>([])
|
||||
@@ -121,13 +123,41 @@ export const useApiReport = () => {
|
||||
networkTraffic: networkTraffic.logData,
|
||||
},
|
||||
params: {
|
||||
totalRequests: totalRequests.params,
|
||||
errorCounts: errorCounts.params,
|
||||
responseSpeed: responseSpeed.params,
|
||||
topRoutes: topRoutes.params,
|
||||
topErrorRoutes: topErrorRoutes.params,
|
||||
topSlowRoutes: topSlowRoutes.params,
|
||||
networkTraffic: networkTraffic.params,
|
||||
totalRequests: {
|
||||
...totalRequests.params,
|
||||
iso_timestamp_start: timestampStart,
|
||||
iso_timestamp_end: timestampEnd,
|
||||
},
|
||||
errorCounts: {
|
||||
...errorCounts.params,
|
||||
iso_timestamp_start: timestampStart,
|
||||
iso_timestamp_end: timestampEnd,
|
||||
},
|
||||
responseSpeed: {
|
||||
...responseSpeed.params,
|
||||
iso_timestamp_start: timestampStart,
|
||||
iso_timestamp_end: timestampEnd,
|
||||
},
|
||||
topRoutes: {
|
||||
...topRoutes.params,
|
||||
iso_timestamp_start: timestampStart,
|
||||
iso_timestamp_end: timestampEnd,
|
||||
},
|
||||
topErrorRoutes: {
|
||||
...topErrorRoutes.params,
|
||||
iso_timestamp_start: timestampStart,
|
||||
iso_timestamp_end: timestampEnd,
|
||||
},
|
||||
topSlowRoutes: {
|
||||
...topSlowRoutes.params,
|
||||
iso_timestamp_start: timestampStart,
|
||||
iso_timestamp_end: timestampEnd,
|
||||
},
|
||||
networkTraffic: {
|
||||
...networkTraffic.params,
|
||||
iso_timestamp_start: timestampStart,
|
||||
iso_timestamp_end: timestampEnd,
|
||||
},
|
||||
},
|
||||
error: {
|
||||
totalRequest: totalRequests.error,
|
||||
|
||||
@@ -4,9 +4,11 @@ import { useParams } from 'common'
|
||||
import { PRESET_CONFIG } from 'components/interfaces/Reports/Reports.constants'
|
||||
import { queriesFactory } from 'components/interfaces/Reports/Reports.utils'
|
||||
import type { LogsEndpointParams } from 'components/interfaces/Settings/Logs/Logs.types'
|
||||
import { useLogsUrlState } from 'hooks/analytics/useLogsUrlState'
|
||||
|
||||
export const useStorageReport = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const { timestampStart, timestampEnd } = useLogsUrlState()
|
||||
|
||||
const queryHooks = queriesFactory<keyof typeof PRESET_CONFIG.storage.queries>(
|
||||
PRESET_CONFIG.storage.queries,
|
||||
@@ -43,8 +45,16 @@ export const useStorageReport = () => {
|
||||
topCacheMisses: topCacheMisses.logData,
|
||||
},
|
||||
params: {
|
||||
cacheHitRate: cacheHitRate.params,
|
||||
topCacheMisses: topCacheMisses.params,
|
||||
cacheHitRate: {
|
||||
...cacheHitRate.params,
|
||||
iso_timestamp_start: timestampStart,
|
||||
iso_timestamp_end: timestampEnd,
|
||||
},
|
||||
topCacheMisses: {
|
||||
...topCacheMisses.params,
|
||||
iso_timestamp_start: timestampStart,
|
||||
iso_timestamp_end: timestampEnd,
|
||||
},
|
||||
},
|
||||
mergeParams: handleSetParams,
|
||||
isLoading,
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
checkForWithClause,
|
||||
} from 'components/interfaces/Settings/Logs/Logs.utils'
|
||||
import { get } from 'data/fetchers'
|
||||
import { useLogsUrlState } from 'hooks/analytics/useLogsUrlState'
|
||||
|
||||
export interface LogsQueryHook {
|
||||
params: LogsEndpointParams
|
||||
@@ -34,16 +35,13 @@ const useLogsQuery = (
|
||||
initialParams: Partial<LogsEndpointParams> = {},
|
||||
enabled = true
|
||||
): LogsQueryHook => {
|
||||
const { timestampStart, timestampEnd } = useLogsUrlState()
|
||||
const defaultHelper = getDefaultHelper(EXPLORER_DATEPICKER_HELPERS)
|
||||
const [params, setParams] = useState<LogsEndpointParams>({
|
||||
sql: initialParams?.sql || '',
|
||||
project: projectRef,
|
||||
iso_timestamp_start: initialParams.iso_timestamp_start
|
||||
? initialParams.iso_timestamp_start
|
||||
: defaultHelper.calcFrom(),
|
||||
iso_timestamp_end: initialParams.iso_timestamp_end
|
||||
? initialParams.iso_timestamp_end
|
||||
: defaultHelper.calcTo(),
|
||||
iso_timestamp_start: timestampStart || initialParams.iso_timestamp_start || '',
|
||||
iso_timestamp_end: timestampEnd || initialParams.iso_timestamp_end || '',
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
@@ -52,19 +50,10 @@ const useLogsQuery = (
|
||||
...initialParams,
|
||||
project: projectRef,
|
||||
sql: initialParams?.sql ?? prev.sql,
|
||||
iso_timestamp_start: initialParams.iso_timestamp_start
|
||||
? initialParams.iso_timestamp_start
|
||||
: defaultHelper.calcFrom(),
|
||||
iso_timestamp_end: initialParams.iso_timestamp_end
|
||||
? initialParams.iso_timestamp_end
|
||||
: defaultHelper.calcTo(),
|
||||
iso_timestamp_start: timestampStart || initialParams.iso_timestamp_start || '',
|
||||
iso_timestamp_end: timestampEnd || initialParams.iso_timestamp_end || '',
|
||||
}))
|
||||
}, [
|
||||
projectRef,
|
||||
initialParams.sql,
|
||||
initialParams.iso_timestamp_start,
|
||||
initialParams.iso_timestamp_end,
|
||||
])
|
||||
}, [projectRef, initialParams.sql, timestampStart, timestampEnd])
|
||||
|
||||
const _enabled = enabled && typeof projectRef !== 'undefined' && Boolean(params.sql)
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
TopApiRoutesRenderer,
|
||||
TotalRequestsChartRenderer,
|
||||
} from 'components/interfaces/Reports/renderers/ApiRenderers'
|
||||
import type { DatePickerToFrom } from 'components/interfaces/Settings/Logs/Logs.types'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import ReportsLayout from 'components/layouts/ReportsLayout/ReportsLayout'
|
||||
import ShimmerLine from 'components/ui/ShimmerLine'
|
||||
@@ -22,36 +21,16 @@ export const ApiReport: NextPageWithLayout = () => {
|
||||
const report = useApiReport()
|
||||
const organization = useSelectedOrganization()
|
||||
|
||||
const {
|
||||
data,
|
||||
error,
|
||||
filters,
|
||||
isLoading,
|
||||
params,
|
||||
mergeParams,
|
||||
removeFilters,
|
||||
addFilter,
|
||||
refresh,
|
||||
} = report
|
||||
const { data, error, filters, isLoading, params, removeFilters, addFilter, refresh } = report
|
||||
|
||||
const plan = organization?.plan
|
||||
|
||||
const handleDatepickerChange = ({ from, to }: DatePickerToFrom) => {
|
||||
mergeParams({
|
||||
iso_timestamp_start: from || '',
|
||||
iso_timestamp_end: to || '',
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<ReportPadding>
|
||||
<ReportHeader title="API" />
|
||||
<div className="w-full flex flex-col gap-1">
|
||||
<ReportFilterBar
|
||||
onRemoveFilters={removeFilters}
|
||||
onDatepickerChange={handleDatepickerChange}
|
||||
datepickerFrom={params.totalRequests.iso_timestamp_start}
|
||||
datepickerTo={params.totalRequests.iso_timestamp_end}
|
||||
onAddFilter={addFilter}
|
||||
onRefresh={refresh}
|
||||
isLoading={isLoading}
|
||||
|
||||
@@ -1,20 +1,12 @@
|
||||
import { useState } from 'react'
|
||||
|
||||
import ReportHeader from 'components/interfaces/Reports/ReportHeader'
|
||||
import ReportPadding from 'components/interfaces/Reports/ReportPadding'
|
||||
import ReportWidget from 'components/interfaces/Reports/ReportWidget'
|
||||
import {
|
||||
createFilteredDatePickerHelpers,
|
||||
REPORTS_DATEPICKER_HELPERS,
|
||||
} from 'components/interfaces/Reports/Reports.constants'
|
||||
import { createFilteredDatePickerHelpers } from 'components/interfaces/Reports/Reports.constants'
|
||||
import {
|
||||
CacheHitRateChartRenderer,
|
||||
TopCacheMissesRenderer,
|
||||
} from 'components/interfaces/Reports/renderers/StorageRenderers'
|
||||
import {
|
||||
DatePickerValue,
|
||||
LogsDatePicker,
|
||||
} from 'components/interfaces/Settings/Logs/Logs.DatePickers'
|
||||
import { LogsDatePicker } from 'components/interfaces/Settings/Logs/Logs.DatePickers'
|
||||
import ReportsLayout from 'components/layouts/ReportsLayout/ReportsLayout'
|
||||
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
|
||||
import ShimmerLine from 'components/ui/ShimmerLine'
|
||||
@@ -32,26 +24,8 @@ export const StorageReport: NextPageWithLayout = () => {
|
||||
|
||||
const plan = organization?.plan
|
||||
|
||||
const defaultHelper =
|
||||
REPORTS_DATEPICKER_HELPERS.find((h) => h.default) || REPORTS_DATEPICKER_HELPERS[0]
|
||||
|
||||
const [selectedRange, setSelectedRange] = useState<DatePickerValue>({
|
||||
to: defaultHelper.calcTo(),
|
||||
from: defaultHelper.calcFrom(),
|
||||
isHelper: true,
|
||||
text: defaultHelper.text,
|
||||
})
|
||||
|
||||
const datepickerHelpers = createFilteredDatePickerHelpers(plan?.id || 'free')
|
||||
|
||||
const handleDatepickerChange = (vals: DatePickerValue) => {
|
||||
report.mergeParams({
|
||||
iso_timestamp_start: vals.from || '',
|
||||
iso_timestamp_end: vals.to || '',
|
||||
})
|
||||
setSelectedRange(vals)
|
||||
}
|
||||
|
||||
return (
|
||||
<ReportPadding>
|
||||
<ReportHeader title="Storage" />
|
||||
@@ -66,11 +40,7 @@ export const StorageReport: NextPageWithLayout = () => {
|
||||
onClick={() => refresh()}
|
||||
/>
|
||||
|
||||
<LogsDatePicker
|
||||
onSubmit={handleDatepickerChange}
|
||||
value={selectedRange}
|
||||
helpers={datepickerHelpers}
|
||||
/>
|
||||
<LogsDatePicker helpers={datepickerHelpers} />
|
||||
</div>
|
||||
|
||||
<div className="h-2 w-full">
|
||||
|
||||
Reference in new issue
Block a user