Skip to content

Commit 9ce748e

Browse files
committed
quick range fix
1 parent eec9d4c commit 9ce748e

File tree

4 files changed

+49
-68
lines changed

4 files changed

+49
-68
lines changed

packages/web/app/src/components/ui/date-range-picker.tsx

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useRef, useState } from 'react';
1+
import { useEffect, useMemo, useRef, useState } from 'react';
22
import { endOfDay, endOfToday, formatDate, subMonths } from 'date-fns';
33
import { CalendarDays } from 'lucide-react';
44
import { DateRange, Matcher } from 'react-day-picker';
@@ -122,10 +122,10 @@ export function DateRangePicker(props: DateRangePickerProps): JSX.Element {
122122
? new RegExp(`[0-9]+(${disallowedUnits.join('|')})`)
123123
: null;
124124

125-
let presets = props.presets ?? availablePresets;
125+
let staticPresets = props.presets ?? availablePresets;
126126

127127
if (hasInvalidUnitRegex) {
128-
presets = presets.filter(
128+
staticPresets = staticPresets.filter(
129129
preset =>
130130
!hasInvalidUnitRegex.test(preset.range.from) && !hasInvalidUnitRegex.test(preset.range.to),
131131
);
@@ -153,7 +153,7 @@ export function DateRangePicker(props: DateRangePickerProps): JSX.Element {
153153
!hasInvalidUnitRegex?.test(props.selectedRange.from) &&
154154
!hasInvalidUnitRegex?.test(props.selectedRange.to)
155155
) {
156-
preset = findMatchingPreset(props.selectedRange, presets);
156+
preset = findMatchingPreset(props.selectedRange, staticPresets);
157157

158158
if (preset) {
159159
return preset;
@@ -169,7 +169,7 @@ export function DateRangePicker(props: DateRangePickerProps): JSX.Element {
169169
}
170170
}
171171

172-
return presets.at(0) ?? null;
172+
return staticPresets.at(0) ?? null;
173173
}
174174

175175
const [activePreset, setActivePreset] = useResetState<Preset | null>(getInitialPreset, [
@@ -241,9 +241,9 @@ export function DateRangePicker(props: DateRangePickerProps): JSX.Element {
241241
);
242242
};
243243

244-
const [dynamicPresets, setDynamicPresets] = useState<Preset[]>([]);
245-
useEffect(() => {
244+
const dynamicPresets = useMemo(() => {
246245
const number = parseInt(quickRangeFilter.replace(/\D/g, ''), 10);
246+
247247
const dynamicPresets: Preset[] = [
248248
{
249249
name: `last${number}min`,
@@ -278,7 +278,7 @@ export function DateRangePicker(props: DateRangePickerProps): JSX.Element {
278278
];
279279

280280
const uniqueDynamicPresets = dynamicPresets.filter(
281-
preset => !presets.some(p => p.name === preset.name),
281+
preset => !staticPresets.some(p => p.name === preset.name),
282282
);
283283

284284
const validDynamicPresets = uniqueDynamicPresets.filter(
@@ -288,17 +288,11 @@ export function DateRangePicker(props: DateRangePickerProps): JSX.Element {
288288
);
289289

290290
if (number > 0 && validDynamicPresets.length > 0) {
291-
setDynamicPresets(validDynamicPresets);
291+
return validDynamicPresets;
292292
} else {
293-
setDynamicPresets([]);
293+
return [];
294294
}
295295
}, [quickRangeFilter, validUnits]);
296-
presets = [...presets, ...dynamicPresets].sort((a, b) => {
297-
const aWeight = calculateWeight(a);
298-
const bWeight = calculateWeight(b);
299-
300-
return aWeight - bWeight;
301-
});
302296

303297
return (
304298
<Popover
@@ -448,7 +442,7 @@ export function DateRangePicker(props: DateRangePickerProps): JSX.Element {
448442
preset.label.toLowerCase().includes(quickRangeFilter.toLowerCase().trim()),
449443
)
450444
.map(preset => <PresetButton key={preset.name} preset={preset} />)
451-
: presets
445+
: staticPresets
452446
.filter(preset =>
453447
preset.label.toLowerCase().includes(quickRangeFilter.toLowerCase().trim()),
454448
)

packages/web/app/src/lib/hooks/use-date-range-controller.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,23 @@ import { useRouter } from '@tanstack/react-router';
1616
import { useResetState } from './use-reset-state';
1717

1818
export function useDateRangeController(args: {
19+
/** the data retention aka minimum time range. */
1920
dataRetentionInDays: number;
21+
/** the default preset to pick if no range is provided. */
2022
defaultPreset: Preset;
23+
/** controlled input range */
24+
range?: Preset['range'];
2125
}) {
2226
const router = useRouter();
2327

2428
const [startDate] = useResetState(
2529
() => subDays(new Date(), args.dataRetentionInDays),
2630
[args.dataRetentionInDays],
2731
);
28-
2932
const searchParams = router.latestLocation.search;
30-
// const params = new URLSearchParams(urlParameter);
31-
const fromRaw = (('from' in searchParams && searchParams.from) ?? '') as string;
32-
const toRaw = (('to' in searchParams && searchParams.to) ?? 'now') as string;
33+
const fromRaw =
34+
args.range?.from ?? ((('from' in searchParams && searchParams.from) ?? '') as string);
35+
const toRaw = args.range?.to ?? ((('to' in searchParams && searchParams.to) ?? 'now') as string);
3336

3437
const [selectedPreset] = useResetState(() => {
3538
const preset = availablePresets.find(p => p.range.from === fromRaw && p.range.to === toRaw);

packages/web/app/src/pages/target-traces.tsx

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@ import { z } from 'zod';
1616
import { Page, TargetLayout, useTargetReference } from '@/components/layouts/target';
1717
import { Badge } from '@/components/ui/badge';
1818
import { Button } from '@/components/ui/button';
19-
import { CardDescription } from '@/components/ui/card';
2019
import {
2120
ChartConfig,
2221
ChartContainer,
2322
ChartTooltip,
2423
ChartTooltipContent,
2524
} from '@/components/ui/chart';
26-
import { DateRangePicker, presetLast7Days } from '@/components/ui/date-range-picker';
25+
import { DateRangePicker, Preset, presetLast7Days } from '@/components/ui/date-range-picker';
2726
import { Meta } from '@/components/ui/meta';
2827
import { SubPageLayoutHeader } from '@/components/ui/page-content-layout';
2928
import { QueryError } from '@/components/ui/query-error';
@@ -282,16 +281,15 @@ const TracesList_Trace = graphql(`
282281
`);
283282

284283
const TracesList = memo(function TracesList(
285-
props: SortProps &
286-
PaginationProps & {
287-
traces: FragmentType<typeof TracesList_Trace>[];
288-
onSelectTraceId: (traceId: string) => void;
289-
selectedTraceId: string | null;
290-
isFetching: boolean;
291-
filter: GraphQLSchema.TracesFilterInput;
292-
isFetchingMore: boolean;
293-
fetchMore: null | (() => void);
294-
},
284+
props: SortProps & {
285+
traces: FragmentType<typeof TracesList_Trace>[];
286+
onSelectTraceId: (traceId: string) => void;
287+
selectedTraceId: string | null;
288+
isFetching: boolean;
289+
filter: GraphQLSchema.TracesFilterInput;
290+
isFetchingMore: boolean;
291+
fetchMore: null | (() => void);
292+
},
295293
) {
296294
const router = useRouter();
297295
const data = useFragment(TracesList_Trace, props.traces);
@@ -318,26 +316,6 @@ const TracesList = memo(function TracesList(
318316
[router],
319317
);
320318

321-
const onPaginationChange = useCallback<OnChangeFn<PaginationState>>(
322-
updater => {
323-
const value = typeof updater === 'function' ? updater(props.pagination) : updater;
324-
325-
if (JSON.stringify(value) === JSON.stringify(props.pagination)) {
326-
return;
327-
}
328-
329-
void router.navigate({
330-
search(params) {
331-
return {
332-
...params,
333-
pagination: value,
334-
};
335-
},
336-
});
337-
},
338-
[router],
339-
);
340-
341319
const table = useReactTable({
342320
data,
343321
columns: [
@@ -601,11 +579,9 @@ const TracesList = memo(function TracesList(
601579
getCoreRowModel: getCoreRowModel(),
602580
getPaginationRowModel: getPaginationRowModel(),
603581
getSortedRowModel: getSortedRowModel(),
604-
onPaginationChange,
605582
manualPagination: true,
606583
state: {
607584
sorting: [props.sorting],
608-
pagination: props.pagination,
609585
},
610586
});
611587

@@ -1133,13 +1109,19 @@ const TargetTracesFetchMoreTracesQuery = graphql(`
11331109
}
11341110
`);
11351111

1136-
function TargetTracesPageContent(props: SortProps & PaginationProps & FilterProps) {
1112+
function TargetTracesPageContent(
1113+
props: SortProps &
1114+
FilterProps & {
1115+
range: Preset['range'] | null;
1116+
},
1117+
) {
11371118
const targetRef = useTargetReference();
11381119

11391120
const dateRangeController = useDateRangeController({
11401121
// TODO: ressolve retention from account
11411122
dataRetentionInDays: 365,
11421123
defaultPreset: presetLast7Days,
1124+
range: props.range || undefined,
11431125
});
11441126

11451127
const filter: GraphQLSchema.TracesFilterInput = {
@@ -1162,6 +1144,8 @@ function TargetTracesPageContent(props: SortProps & PaginationProps & FilterProp
11621144
httpUrls: props.filter['http.url'],
11631145
};
11641146

1147+
const paginationSize = 50;
1148+
11651149
const urql = useClient();
11661150
const [query] = useQuery({
11671151
query: TargetTracesPageQuery,
@@ -1172,7 +1156,7 @@ function TargetTracesPageContent(props: SortProps & PaginationProps & FilterProp
11721156
targetSlug: targetRef.targetSlug,
11731157
},
11741158
filter,
1175-
first: props.pagination.pageSize,
1159+
first: paginationSize,
11761160
sort: {
11771161
sort:
11781162
props.sorting.id === 'duration'
@@ -1319,7 +1303,6 @@ function TargetTracesPageContent(props: SortProps & PaginationProps & FilterProp
13191303
</div>
13201304
<TracesList
13211305
sorting={props.sorting}
1322-
pagination={props.pagination}
13231306
traces={traces ?? []}
13241307
onSelectTraceId={setSelectedTraceId}
13251308
selectedTraceId={selectedTraceId}
@@ -1345,7 +1328,7 @@ function TargetTracesPageContent(props: SortProps & PaginationProps & FilterProp
13451328
targetSlug: targetRef.targetSlug,
13461329
},
13471330
filter,
1348-
first: props.pagination.pageSize,
1331+
first: paginationSize,
13491332
sort: {
13501333
sort:
13511334
props.sorting.id === 'duration'
@@ -1394,8 +1377,8 @@ export function TargetTracesPage(
13941377
organizationSlug: string;
13951378
projectSlug: string;
13961379
targetSlug: string;
1380+
range: Preset['range'] | null;
13971381
} & SortProps &
1398-
PaginationProps &
13991382
FilterProps,
14001383
) {
14011384
return (
@@ -1409,8 +1392,8 @@ export function TargetTracesPage(
14091392
>
14101393
<TargetTracesPageContent
14111394
sorting={props.sorting}
1412-
pagination={props.pagination}
14131395
filter={props.filter}
1396+
range={props.range}
14141397
/>
14151398
</TargetLayout>
14161399
</>

packages/web/app/src/router.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { lazy, useCallback, useEffect } from 'react';
1+
import { lazy, useCallback, useEffect, useMemo } from 'react';
22
import { parse as jsUrlParse, stringify as jsUrlStringify } from 'jsurl2';
33
import { Helmet, HelmetProvider } from 'react-helmet-async';
44
import { ToastContainer } from 'react-toastify';
@@ -661,7 +661,8 @@ const targetInsightsRoute = createRoute({
661661
const TargetTracesRouteSearch = z.object({
662662
filter: TargetTracesFilterState.optional(),
663663
sort: TargetTracesSort.shape.optional(),
664-
pagination: TargetTracesPagination.shape.optional(),
664+
from: z.string().optional(),
665+
to: z.string().optional(),
665666
});
666667

667668
const targetTracesRoute = createRoute({
@@ -690,20 +691,20 @@ const targetTracesRoute = createRoute({
690691
id: 'timestamp',
691692
desc: true,
692693
},
693-
pagination = {
694-
pageIndex: 0,
695-
pageSize: 20,
696-
} satisfies PaginationState,
694+
from,
695+
to,
697696
} = targetTracesRoute.useSearch();
698697

698+
const range = useMemo(() => (from && to ? { from, to } : null), [from, to]);
699+
699700
return (
700701
<TargetTracesPage
701702
organizationSlug={organizationSlug}
702703
projectSlug={projectSlug}
703704
targetSlug={targetSlug}
704705
sorting={sort}
705-
pagination={pagination}
706706
filter={filter}
707+
range={range}
707708
/>
708709
);
709710
},

0 commit comments

Comments
 (0)