Refactor renamed the component groups to something less obtuse:
Elements -> Groups -> Screens -> Views
This commit is contained in:
parent
ca6de91a96
commit
dd46acba87
2 changed files with 151 additions and 144 deletions
|
|
@ -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",
|
||||
},
|
||||
};
|
||||
93
clients/web/src/components/elements/LogEntry/LogEntry.tsx
Normal file
93
clients/web/src/components/elements/LogEntry/LogEntry.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue