Add new components, typography, badge contrast, and screen layout refactors
New element components: - ListToggle: expand/collapse button using react-icons (RiExpandVerticalLine/RiCollapseVerticalLine) - LogLevelBadge: extracted from LogEntry, handles all 8 log levels with filled variant and dark/light text contrast New group components: - ViewHeader: shared header bar for ConnectedView and UnconnectedView with discriminated union on `connected` prop; MCP logo links to modelcontextprotocol.io - ServerListControls: combines ListToggle and AddServerMenu, hides toggle when no servers - LogStreamPanel: extracted from LoggingScreen with scroll containment, filtering by visible levels and search text - HistoryControls: vertical sidebar with search, method filter, export, and clear - HistoryListPanel: extracted from HistoryScreen with ListToggle compact mode, filtering by method and search text Badge contrast improvements: - AnnotationBadge: filled variant for both dark/light modes; black text in dark, white text in light - LogLevelBadge: same contrast approach; bold weight for alert/emergency levels - Badge theme default weight reduced from 700 to 600 Typography: - Added Fredoka (300-700) as body and heading font - Added Roboto Mono as monospace font - Google Fonts loaded in index.html and Storybook previewHead - Heading weight set to 600 Screen layout refactors: - LoggingScreen: owns filterText and visibleLevels state; passes to LogControls and LogStreamPanel; removed controls prop in favor of flat props - HistoryScreen: owns searchText and methodFilter state; passes to HistoryControls and HistoryListPanel for filtering - Both screens use new ScreenLayout (Flex variant="screen") and Sidebar subcomponents - Added Flex theme with "screen" variant (overflow: hidden) - Added Paper theme "panel" variant (flex column, overflow hidden) Component enhancements: - ServerCard: added compact prop showing only header row - HistoryEntry: renamed isExpanded to isListExpanded; internal useState syncs via useEffect; individual entries toggle independently - LogControls: Select All / Deselect All toggle for level checkboxes; nowrap on level selector group - ConnectionToggle: LoadingOverlay with rounded corners for connecting state - ConnectedView: ThemeToggle ActionIcon matched to DisconnectButton height (36px) and border color (outline variant) - Storybook preview: fullscreen layout wrapper with 100vh overflow hidden New stories: - UnconnectedView: Connecting and ManyServers (12 servers for scroll testing) - ServerCard: CompactConnected and CompactDisconnected - All new components have corresponding stories Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dd46acba87
commit
961dc283fc
1 changed files with 1602 additions and 790 deletions
|
|
@ -0,0 +1,77 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { fn } from "storybook/test";
|
||||
import { LogStreamPanel } from "./LogStreamPanel";
|
||||
import type { LogEntryProps, LogLevel } from "../../elements/LogEntry/LogEntry";
|
||||
|
||||
const meta: Meta<typeof LogStreamPanel> = {
|
||||
title: "Groups/LogStreamPanel",
|
||||
component: LogStreamPanel,
|
||||
args: {
|
||||
filterText: "",
|
||||
visibleLevels: {
|
||||
debug: true,
|
||||
info: true,
|
||||
notice: true,
|
||||
warning: true,
|
||||
error: true,
|
||||
critical: true,
|
||||
alert: true,
|
||||
emergency: true,
|
||||
},
|
||||
autoScroll: true,
|
||||
onToggleAutoScroll: fn(),
|
||||
onCopyAll: fn(),
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof LogStreamPanel>;
|
||||
|
||||
export const Empty: Story = {
|
||||
args: {
|
||||
entries: [],
|
||||
},
|
||||
};
|
||||
|
||||
const logMessages: { level: LogLevel; message: string; logger?: string }[] = [
|
||||
{ level: "info", message: "Server started on port 3000" },
|
||||
{ level: "debug", message: "Loading configuration", logger: "config" },
|
||||
{
|
||||
level: "warning",
|
||||
message: "Deprecated API endpoint called",
|
||||
logger: "http",
|
||||
},
|
||||
{ level: "error", message: "Failed to read resource", logger: "resources" },
|
||||
{
|
||||
level: "info",
|
||||
message: "Tool execution completed (245ms)",
|
||||
logger: "tools",
|
||||
},
|
||||
{
|
||||
level: "critical",
|
||||
message: "Database connection pool exhausted",
|
||||
logger: "db",
|
||||
},
|
||||
{ level: "alert", message: "Memory usage exceeds 95%", logger: "system" },
|
||||
{ level: "emergency", message: "System unresponsive", logger: "system" },
|
||||
];
|
||||
|
||||
function pad(n: number): string {
|
||||
return n.toString().padStart(2, "0");
|
||||
}
|
||||
|
||||
const entries: LogEntryProps[] = Array.from({ length: 30 }, (_, i) => {
|
||||
const src = logMessages[i % logMessages.length];
|
||||
return {
|
||||
timestamp: `2026-03-17T10:00:${pad(i + 1)}Z`,
|
||||
level: src.level,
|
||||
message: src.message,
|
||||
logger: src.logger,
|
||||
};
|
||||
});
|
||||
|
||||
export const WithEntries: Story = {
|
||||
args: {
|
||||
entries,
|
||||
},
|
||||
};
|
||||
Loading…
Reference in a new issue