Skip to content

Commit 5ca54e7

Browse files
committed
Time filtering fixes
1 parent 2d7b440 commit 5ca54e7

File tree

2 files changed

+41
-6
lines changed
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query

2 files changed

+41
-6
lines changed

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ import { requireUser } from "~/services/session.server";
6969
import parse from "parse-duration";
7070
import { SimpleTooltip } from "~/components/primitives/Tooltip";
7171

72+
/** Convert a Date or ISO string to ISO string format */
73+
function toISOString(value: Date | string): string {
74+
if (typeof value === "string") {
75+
return value;
76+
}
77+
return value.toISOString();
78+
}
79+
7280
async function hasQueryAccess(
7381
userId: string,
7482
isAdmin: boolean,
@@ -295,6 +303,13 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
295303
source: "DASHBOARD",
296304
userId: user.id,
297305
skip: user.isImpersonating,
306+
timeFilter: {
307+
// Save the effective period used for the query (timeFilters() handles defaults)
308+
// Only save period if no custom from/to range was specified
309+
period: timeFilter.from || timeFilter.to ? undefined : timeFilter.period,
310+
from: timeFilter.from,
311+
to: timeFilter.to,
312+
},
298313
},
299314
});
300315

@@ -344,6 +359,7 @@ interface QueryEditorFormHandle {
344359
setQuery: (query: string) => void;
345360
setScope: (scope: QueryScope) => void;
346361
getQuery: () => string;
362+
setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => void;
347363
}
348364

349365
/** Self-contained query editor with form - isolates query state from parent */
@@ -352,20 +368,21 @@ const QueryEditorForm = forwardRef<
352368
{
353369
defaultQuery: string;
354370
defaultScope: QueryScope;
371+
defaultTimeFilter?: { period?: string; from?: string; to?: string };
355372
history: QueryHistoryItem[];
356373
fetcher: ReturnType<typeof useTypedFetcher<typeof action>>;
357374
isAdmin: boolean;
358375
}
359-
>(function QueryEditorForm({ defaultQuery, defaultScope, history, fetcher, isAdmin }, ref) {
376+
>(function QueryEditorForm({ defaultQuery, defaultScope, defaultTimeFilter, history, fetcher, isAdmin }, ref) {
360377
const isLoading = fetcher.state === "submitting" || fetcher.state === "loading";
361378
const [query, setQuery] = useState(defaultQuery);
362379
const [scope, setScope] = useState<QueryScope>(defaultScope);
363380
const formRef = useRef<HTMLFormElement>(null);
364381

365-
// Get time filter values from URL search params
366-
const [period, setPeriod] = useState<string | undefined>();
367-
const [from, setFrom] = useState<string | undefined>();
368-
const [to, setTo] = useState<string | undefined>();
382+
// Get time filter values - initialize from props (which may come from history)
383+
const [period, setPeriod] = useState<string | undefined>(defaultTimeFilter?.period);
384+
const [from, setFrom] = useState<string | undefined>(defaultTimeFilter?.from);
385+
const [to, setTo] = useState<string | undefined>(defaultTimeFilter?.to);
369386

370387
// Check if the query contains triggered_at in a WHERE clause
371388
// This disables the time filter UI since the user is filtering in their query
@@ -378,13 +395,23 @@ const QueryEditorForm = forwardRef<
378395
setQuery,
379396
setScope,
380397
getQuery: () => query,
398+
setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => {
399+
setPeriod(filter.period);
400+
setFrom(filter.from);
401+
setTo(filter.to);
402+
},
381403
}),
382404
[query]
383405
);
384406

385407
const handleHistorySelected = useCallback((item: QueryHistoryItem) => {
386408
setQuery(item.query);
387409
setScope(item.scope);
410+
// Apply time filter from history item
411+
// Note: filterFrom/filterTo might be Date objects or ISO strings depending on serialization
412+
setPeriod(item.filterPeriod ?? undefined);
413+
setFrom(item.filterFrom ? toISOString(item.filterFrom) : undefined);
414+
setTo(item.filterTo ? toISOString(item.filterTo) : undefined);
388415
}, []);
389416

390417
return (
@@ -488,6 +515,14 @@ export default function Page() {
488515
// Use most recent history item if available, otherwise fall back to defaults
489516
const initialQuery = history.length > 0 ? history[0].query : defaultQuery;
490517
const initialScope: QueryScope = history.length > 0 ? history[0].scope : "environment";
518+
const initialTimeFilter = history.length > 0
519+
? {
520+
period: history[0].filterPeriod ?? undefined,
521+
// Note: filterFrom/filterTo might be Date objects or ISO strings depending on serialization
522+
from: history[0].filterFrom ? toISOString(history[0].filterFrom) : undefined,
523+
to: history[0].filterTo ? toISOString(history[0].filterTo) : undefined,
524+
}
525+
: undefined;
491526

492527
const editorRef = useRef<QueryEditorFormHandle>(null);
493528
const [prettyFormatting, setPrettyFormatting] = useState(true);
@@ -552,6 +587,7 @@ export default function Page() {
552587
ref={editorRef}
553588
defaultQuery={initialQuery}
554589
defaultScope={initialScope}
590+
defaultTimeFilter={initialTimeFilter}
555591
history={history}
556592
fetcher={fetcher}
557593
isAdmin={isAdmin}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,3 @@ export function formatBytes(bytes: number): string {
3030
);
3131
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
3232
}
33-

0 commit comments

Comments
 (0)