feat(diagnostics): walk the log lines from the keyboard; name the console "Server log"

Both log viewers put their lines in a NavGrid: j/k (and the arrows) step
from line to line, and Enter opens one exactly as a click does (the line's
button is its `data-nav-open`). A focused line is named by its code and
message.

The console's nav entry is "Szervernapló" / "Server log", its page title:
"Diagnosztika" was already the Settings tab that holds the user's own log,
and two places with one name read as one place.
This commit is contained in:
2026-09-19 02:02:45 +02:00
parent 8cfab498cf
commit 142593083f
6 changed files with 77 additions and 49 deletions
+24 -20
View File
@@ -24,13 +24,14 @@ import { qk } from "../lib/queryKeys";
import { useDebounced } from "../lib/useDebounced";
import { useUrlMirror } from "../lib/useUrlMirror";
import LogLine from "./LogLine";
import NavGrid from "./ui/NavGrid";
import { Button } from "./ui/Button";
import FilterChipGroup from "./ui/FilterChipGroup";
import FilterSelect from "./ui/FilterSelect";
import { Section } from "./ui/form";
import { LoadingState, StateMessage } from "./ui/QueryState";
// Admin → Diagnosztika: the server's stored log (`log_events`, E22.6). One list, newest first; a line
// Admin → Szervernapló: the server's stored log (`log_events`, E22.6). One list, newest first; a line
// opens in place to its full record, and its request id / job id narrow the list to that request or
// job. Filters live in the URL, so a filtered view is a link. "Élő" re-reads the newest page every
// few seconds while the tab is visible — the newest page only: live is watching the top, so paging
@@ -287,25 +288,28 @@ export default function AdminLogs() {
{t("adminLogs.empty")}
</p>
) : (
rows.map((row) => (
<LogLine
key={row.id}
ts={row.ts}
level={row.level}
event={row.event ?? "—"}
msg={row.msg}
title={new Date(row.ts).toLocaleString()}
open={open === row.id}
onToggle={() => setOpen(open === row.id ? null : row.id)}
>
<RowDetail
row={row}
account={row.user_id === null ? null : accountLabel(String(row.user_id))}
onRequest={(requestId) => pivot({ requestId, jobId: null })}
onJob={(jobId) => pivot({ requestId: null, jobId })}
/>
</LogLine>
))
<NavGrid>
{rows.map((row, index) => (
<LogLine
navIndex={index}
key={row.id}
ts={row.ts}
level={row.level}
event={row.event ?? "—"}
msg={row.msg}
title={new Date(row.ts).toLocaleString()}
open={open === row.id}
onToggle={() => setOpen(open === row.id ? null : row.id)}
>
<RowDetail
row={row}
account={row.user_id === null ? null : accountLabel(String(row.user_id))}
onRequest={(requestId) => pivot({ requestId, jobId: null })}
onJob={(jobId) => pivot({ requestId: null, jobId })}
/>
</LogLine>
))}
</NavGrid>
)}
</div>