mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-30 02:22:25 +00:00
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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
28
ui/src/ui/controllers/logs.test.ts
Normal file
28
ui/src/ui/controllers/logs.test.ts
Normal 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",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -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") {
|
||||
|
||||
Reference in New Issue
Block a user