fix(diagnostics): Back from a request's lines returns to the view it came from

Every filter change replaced the history entry, so Back after a request or
job pivot left the console altogether (the 0.90 notes promised otherwise).
A pivot follows a link and is its own entry now; the console reads the
landed entry back on popstate. The other filters still adjust in place.
This commit is contained in:
2026-09-19 04:51:42 +02:00
parent 51e98bfc38
commit 6096dd6927
2 changed files with 58 additions and 2 deletions
+22 -2
View File
@@ -1,4 +1,4 @@
import { useMemo, useRef, useState } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import {
keepPreviousData,
@@ -11,6 +11,7 @@ import { Copy, Radio, Search, X } from "lucide-react";
import { api, type LogFacet, type LogQuery, type ServerLogRow } from "../lib/api";
import { copyText } from "../lib/clipboard";
import { formatDateTime } from "../lib/format";
import { nextNavId, notifyNav, rememberNavPosition } from "../lib/history";
import { LEVEL_GROUPS, type LevelGroup } from "../lib/log";
import {
DEFAULT_LOGS_STATE,
@@ -23,6 +24,7 @@ import {
import { notify } from "../lib/notifications";
import { qk } from "../lib/queryKeys";
import { useDebounced } from "../lib/useDebounced";
import { urlWithParams } from "../lib/urlState";
import { useUrlMirror } from "../lib/useUrlMirror";
import LogLine from "./LogLine";
import NavGrid from "./ui/NavGrid";
@@ -82,6 +84,15 @@ export default function AdminLogs() {
const [open, setOpen] = useState<number | null>(null);
const q = useDebounced(state.q, 300);
useUrlMirror(logsParamUpdates(state));
// Back/Forward lands on another view of the console (a pivot pushed one, below): read it back.
useEffect(() => {
const onPop = () => {
setOpen(null);
setState(logsParamsToState(new URLSearchParams(window.location.search)));
};
window.addEventListener("popstate", onPop);
return () => window.removeEventListener("popstate", onPop);
}, []);
const update = (patch: Partial<LogsUrlState>) => {
setOpen(null);
@@ -184,9 +195,18 @@ export default function AdminLogs() {
return facets.data ? sum(levels.filter((f) => inGroup.includes(f.value))) : undefined;
};
// A pivot follows a link to another view, so it is its own history entry and Back returns to the
// view it was made from. The other filters are adjustments of the view on screen and replace it.
const pivot = (patch: Pick<LogsUrlState, "requestId" | "jobId">) => {
setLive(false);
update({ ...PIVOT_RESET, ...patch });
const next = { ...state, ...PIVOT_RESET, ...patch };
window.history.pushState(
{ ...rememberNavPosition(), sfScroll: nextNavId() },
"",
urlWithParams(logsParamUpdates(next)),
);
notifyNav();
update(next);
};
// "Any", then what the facet counted. The value in use stays offered even at zero — under the