style: update chat layout and spacing for improved UI consistency

- Adjusted margin and padding for .chat-thread and .content--chat to enhance layout.
- Consolidated CSS selectors for better readability and maintainability.
- Introduced new test for log parsing functionality to ensure accurate message extraction.
This commit is contained in:
Val Alexander
2026-03-13 14:30:43 -05:00
parent 261a40dae1
commit 655a871ab0
6 changed files with 71 additions and 26 deletions

View File

@@ -9,11 +9,15 @@
flex-direction: column;
flex: 1 1 0;
height: 100%;
min-height: 0; /* Allow flex shrinking */
width: 100%;
min-height: 0;
/* Allow flex shrinking */
overflow: hidden;
background: transparent !important;
border: none !important;
box-shadow: none !important;
backdrop-filter: blur(14px) saturate(1.15);
-webkit-backdrop-filter: blur(14px) saturate(1.15);
}
/* Chat header - fixed at top, transparent */
@@ -24,8 +28,8 @@
gap: 12px;
flex-wrap: nowrap;
flex-shrink: 0;
padding-bottom: 12px;
margin-bottom: 12px;
padding-bottom: 0;
margin-bottom: 0;
background: transparent;
}
@@ -49,16 +53,22 @@
/* Chat thread - scrollable middle section, transparent */
.chat-thread {
flex: 1 1 0; /* Grow, shrink, and use 0 base for proper scrolling */
flex: 1 1 0;
/* Grow, shrink, and use 0 base for proper scrolling */
overflow-y: auto;
overflow-x: hidden;
padding: 12px 4px;
margin: 0 -4px;
min-height: 0; /* Allow shrinking for flex scroll behavior */
padding: 0 6px 6px;
margin: 0 0 0 0;
min-height: 0;
/* Allow shrinking for flex scroll behavior */
border-radius: 12px;
background: transparent;
}
.chat-thread-inner> :first-child {
margin-top: 0 !important;
}
/* Focus mode exit button */
.chat-focus-exit {
position: absolute;
@@ -146,7 +156,8 @@
display: flex;
flex-direction: column;
gap: 12px;
margin-top: auto; /* Push to bottom of flex container */
margin-top: auto;
/* Push to bottom of flex container */
padding: 12px 4px 4px;
background: linear-gradient(to bottom, transparent, var(--bg) 20%);
z-index: 10;
@@ -163,7 +174,8 @@
border: 1px solid var(--border);
width: fit-content;
max-width: 100%;
align-self: flex-start; /* Don't stretch in flex column parent */
align-self: flex-start;
/* Don't stretch in flex column parent */
}
.chat-attachment {
@@ -279,7 +291,7 @@
}
/* Hide the "Message" label - keep textarea only */
.chat-compose__field > span {
.chat-compose__field>span {
display: none;
}
@@ -350,7 +362,7 @@
}
}
.agent-chat__input > textarea {
.agent-chat__input>textarea {
width: 100%;
min-height: 40px;
max-height: 150px;
@@ -366,7 +378,7 @@
box-sizing: border-box;
}
.agent-chat__input > textarea::placeholder {
.agent-chat__input>textarea::placeholder {
color: var(--muted);
}
@@ -508,7 +520,7 @@
scrollbar-width: thin;
}
.slash-menu-group + .slash-menu-group {
.slash-menu-group+.slash-menu-group {
margin-top: 4px;
padding-top: 4px;
border-top: 1px solid color-mix(in srgb, var(--border) 50%, transparent);

View File

@@ -2157,7 +2157,7 @@
}
.chat-thread {
margin-top: 16px;
margin-top: 0;
display: flex;
flex-direction: column;
gap: 12px;
@@ -2165,7 +2165,7 @@
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
padding: 16px 12px;
padding: 0 12px 16px;
min-width: 0;
border-radius: 0;
border: none;

View File

@@ -70,7 +70,7 @@
padding-top: 0;
}
.shell--chat-focus .content > * + * {
.shell--chat-focus .content>*+* {
margin-top: 0;
}
@@ -688,11 +688,9 @@
.sidebar--collapsed .nav-item.active,
.sidebar--collapsed .nav-item--active {
background: linear-gradient(
180deg,
background: linear-gradient(180deg,
color-mix(in srgb, #0b2f34 84%, var(--bg-elevated) 16%) 0%,
color-mix(in srgb, #081f25 90%, var(--bg) 10%) 100%
);
color-mix(in srgb, #081f25 90%, var(--bg) 10%) 100%);
border-color: color-mix(in srgb, #1ed2c2 18%, var(--border) 82%);
box-shadow:
inset 0 1px 0 color-mix(in srgb, white 8%, transparent),
@@ -833,7 +831,7 @@
overflow-x: hidden;
}
.content > * + * {
.content>*+* {
margin-top: 20px;
}
@@ -844,12 +842,12 @@
.content--chat {
display: flex;
flex-direction: column;
gap: 24px;
gap: 2px;
overflow: hidden;
padding-bottom: 0;
}
.content--chat > * + * {
.content--chat>*+* {
margin-top: 0;
}
@@ -905,9 +903,10 @@
align-items: center;
justify-content: space-between;
gap: 16px;
padding-bottom: 0;
}
.content--chat .content-header > div:first-child {
.content--chat .content-header>div:first-child {
text-align: left;
}

View File

@@ -323,6 +323,10 @@
gap: 8px;
}
.content--chat {
gap: 2px;
}
.content--chat .content-header > div:first-child,
.content--chat .page-meta,
.content--chat .chat-controls {
@@ -417,8 +421,8 @@
}
.chat-thread {
margin-top: 8px;
padding: 12px 8px;
margin-top: 0;
padding: 0 8px 12px;
}
.chat-msg {

View File

@@ -0,0 +1,28 @@
import { describe, expect, it } from "vitest";
import { parseLogLine } from "./logs.ts";
describe("parseLogLine", () => {
it("prefers the human-readable message field when structured data is stored in slot 1", () => {
const line = JSON.stringify({
0: '{"subsystem":"gateway/ws"}',
1: {
cause: "unauthorized",
authReason: "password_missing",
},
2: "closed before connect conn=abc code=4008 reason=connect failed",
_meta: {
date: "2026-03-13T19:07:12.128Z",
logLevelName: "WARN",
},
time: "2026-03-13T14:07:12.138-05:00",
});
expect(parseLogLine(line)).toEqual(
expect.objectContaining({
level: "warn",
subsystem: "gateway/ws",
message: "closed before connect conn=abc code=4008 reason=connect failed",
}),
);
});
});

View File

@@ -77,6 +77,8 @@ export function parseLogLine(line: string): LogEntry {
let message: string | null = null;
if (typeof obj["1"] === "string") {
message = obj["1"];
} else if (typeof obj["2"] === "string") {
message = obj["2"];
} else if (!contextObj && typeof obj["0"] === "string") {
message = obj["0"];
} else if (typeof obj.message === "string") {