diff --git a/ui/src/components/logs/logs-entry-list.tsx b/ui/src/components/logs/logs-entry-list.tsx
index 58049b9f..f8fe46dc 100644
--- a/ui/src/components/logs/logs-entry-list.tsx
+++ b/ui/src/components/logs/logs-entry-list.tsx
@@ -24,10 +24,13 @@ export interface LogsEntryListProps {
density?: RowDensity;
}
-// Leading 16px slot reserves space for the trace-expand chevron so that
-// trace rows and standalone leaf rows align under the same column edges.
+// Column layout shared by the header and every row variant:
+// chevron(16) · time(88) · level(64) · stage(72) · module(140) · message(flex) · latency(72) · request(112)
+// The dedicated `stage` column is rendered as an empty span on rows that
+// have no stage hint so column edges align across leaf, trace head, and
+// trace child rows alike.
const COLS_TEMPLATE =
- 'grid grid-cols-[16px_88px_64px_140px_minmax(0,1fr)_72px_112px] items-center gap-3 px-3';
+ 'grid grid-cols-[16px_88px_64px_72px_140px_minmax(0,1fr)_72px_112px] items-center gap-3 px-3';
export function LogsEntryList({
entries,
@@ -149,6 +152,7 @@ export function LogsEntryList({
Time
Level
+ Stage
Module
Message
diff --git a/ui/src/components/logs/logs-row.tsx b/ui/src/components/logs/logs-row.tsx
index 8875484a..c6675c39 100644
--- a/ui/src/components/logs/logs-row.tsx
+++ b/ui/src/components/logs/logs-row.tsx
@@ -59,6 +59,10 @@ function LogsRowImpl({
const handleSelect = () => onSelect(entry.id);
const handleKey = (e: KeyboardEvent) => {
+ // Ignore keys that bubbled from a nested interactive element (e.g. the
+ // copy-requestId button). Without this guard, pressing Enter on the
+ // copy button would also select the row and shift the detail panel.
+ if (e.target !== e.currentTarget) return;
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handleSelect();
@@ -106,6 +110,10 @@ function LogsRowImpl({
+ {/* Always reserve the stage column so leaf, trace head, and trace
+ child rows all align under the same column edges in the header
+ grid template. Children with `stageHint` show a chip; rows
+ without one render an empty span at the same width. */}
{stageHint ? (
{stageHint}
- ) : null}
+ ) : (
+
+ )}