Refactor renamed the component groups to something less obtuse:

Elements -> Groups -> Screens -> Views
This commit is contained in:
cliffhall 2026-03-28 12:58:47 -04:00
commit dd46acba87
2 changed files with 151 additions and 144 deletions

View file

@ -0,0 +1,83 @@
import type { Meta, StoryObj } from "@storybook/react-vite";
import { LogEntry } from "./LogEntry";
const meta: Meta<typeof LogEntry> = {
title: "Elements/LogEntry",
component: LogEntry,
};
export default meta;
type Story = StoryObj<typeof LogEntry>;
export const Debug: Story = {
args: {
timestamp: "2026-03-17T10:00:00Z",
level: "debug",
message: "Initializing connection pool",
},
};
export const Info: Story = {
args: {
timestamp: "2026-03-17T10:00:01Z",
level: "info",
message: "Server started on port 3000",
},
};
export const Notice: Story = {
args: {
timestamp: "2026-03-17T10:00:02Z",
level: "notice",
message: "Configuration reloaded successfully",
},
};
export const Warning: Story = {
args: {
timestamp: "2026-03-17T10:00:03Z",
level: "warning",
message: "Memory usage above 80%",
},
};
export const Error: Story = {
args: {
timestamp: "2026-03-17T10:00:04Z",
level: "error",
message: "Failed to connect to database",
},
};
export const Critical: Story = {
args: {
timestamp: "2026-03-17T10:00:05Z",
level: "critical",
message: "Disk space critically low",
},
};
export const Alert: Story = {
args: {
timestamp: "2026-03-17T10:00:06Z",
level: "alert",
message: "Service degradation detected",
},
};
export const Emergency: Story = {
args: {
timestamp: "2026-03-17T10:00:07Z",
level: "emergency",
message: "System is unusable",
},
};
export const WithLogger: Story = {
args: {
timestamp: "2026-03-17T10:00:08Z",
level: "info",
message: "Tool execution completed",
logger: "mcp-server",
},
};

View file

@ -0,0 +1,93 @@
import { Badge, Group, Text } from "@mantine/core";
export type LogLevel =
| "debug"
| "info"
| "notice"
| "warning"
| "error"
| "critical"
| "alert"
| "emergency";
export interface LogEntryProps {
timestamp: string;
level: LogLevel;
message: string;
logger?: string;
}
const levelBadgeColor: Record<LogLevel, string> = {
debug: "gray",
info: "blue",
notice: "teal",
warning: "yellow",
error: "red",
critical: "red",
alert: "red",
emergency: "red",
};
const levelBadgeVariant: Record<LogLevel, string> = {
debug: "light",
info: "light",
notice: "light",
warning: "light",
error: "light",
critical: "filled",
alert: "filled",
emergency: "filled",
};
const levelMessageColor: Record<LogLevel, string | undefined> = {
debug: "dimmed",
info: "blue",
notice: undefined,
warning: "yellow",
error: "red",
critical: "red",
alert: "red",
emergency: "red",
};
function isBoldLevel(level: LogLevel): boolean {
return level === "alert" || level === "emergency";
}
function getBoldWeight(level: LogLevel): number | undefined {
return isBoldLevel(level) ? 700 : undefined;
}
function formatLogger(logger: string): string {
return `[${logger}]`;
}
const TimestampText = Text.withProps({
size: "sm",
ff: "monospace",
c: "dimmed",
});
const LoggerText = Text.withProps({
size: "xs",
c: "dimmed",
});
export function LogEntry({ timestamp, level, message, logger }: LogEntryProps) {
return (
<Group gap="sm" wrap="nowrap">
<TimestampText>{timestamp}</TimestampText>
<Badge
color={levelBadgeColor[level]}
variant={levelBadgeVariant[level]}
fw={getBoldWeight(level)}
>
{level}
</Badge>
{logger && <LoggerText>{formatLogger(logger)}</LoggerText>}
<Text size="sm" c={levelMessageColor[level]}>
{message}
</Text>
</Group>
);
}