reduce dupplicate code in reports date ranges

This commit is contained in:
Jordi Enric committed 2025-06-18 12:20:03 +02:00
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">
+37 -7
View File
@@ -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,
+7 -18
View File
@@ -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">