formatting
This commit is contained in:
parent
0471443716
commit
4b28a69856
111 changed files with 2438 additions and 1874 deletions
35
.github/workflows/main.yml
vendored
Normal file
35
.github/workflows/main.yml
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
name: Run install, format, lint, build, and test on every push or pull request
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '20.x'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Check formatting
|
||||
run: npm run format:check
|
||||
|
||||
- name: Run linter
|
||||
run: npm run lint
|
||||
|
||||
- name: Run type check
|
||||
run: npm run typecheck
|
||||
|
||||
- name: Run Build
|
||||
run: npm run build
|
||||
|
||||
- name: Run tests
|
||||
run: npm run test
|
||||
21
clients/web/package-lock.json
generated
21
clients/web/package-lock.json
generated
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"name": "web",
|
||||
"name": "@modelcontextprotocol/inspector-web",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "web",
|
||||
"name": "@modelcontextprotocol/inspector-web",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.14.0",
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
"eslint-plugin-storybook": "^10.2.19",
|
||||
"globals": "^17.4.0",
|
||||
"playwright": "^1.58.2",
|
||||
"prettier": "^3.8.1",
|
||||
"storybook": "^10.2.19",
|
||||
"typescript": "~5.9.3",
|
||||
"typescript-eslint": "^8.56.1",
|
||||
|
|
@ -5009,6 +5010,22 @@
|
|||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz",
|
||||
"integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-format": {
|
||||
"version": "27.5.1",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
"dev": "vite",
|
||||
"build": "tsc -b && vite build",
|
||||
"lint": "eslint .",
|
||||
"format": "prettier --write src",
|
||||
"format:check": "prettier --check src",
|
||||
"preview": "vite preview",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"build-storybook": "storybook build"
|
||||
|
|
@ -32,6 +34,7 @@
|
|||
"globals": "^17.4.0",
|
||||
"typescript": "~5.9.3",
|
||||
"typescript-eslint": "^8.56.1",
|
||||
"prettier": "^3.8.1",
|
||||
"vite": "^8.0.0",
|
||||
"storybook": "^10.2.19",
|
||||
"@storybook/react-vite": "^10.2.19",
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
}
|
||||
|
||||
/* Dark mode overrides — tokens that need adjustment in dark scheme */
|
||||
[data-mantine-color-scheme='dark'] {
|
||||
[data-mantine-color-scheme="dark"] {
|
||||
--inspector-surface-code: var(--mantine-color-dark-6);
|
||||
--inspector-border-subtle: var(--mantine-color-dark-4);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,15 +7,15 @@ import {
|
|||
useComputedColorScheme,
|
||||
ActionIcon,
|
||||
Group,
|
||||
} from '@mantine/core'
|
||||
} from "@mantine/core";
|
||||
|
||||
function App() {
|
||||
const { setColorScheme } = useMantineColorScheme()
|
||||
const computedColorScheme = useComputedColorScheme('light')
|
||||
const { setColorScheme } = useMantineColorScheme();
|
||||
const computedColorScheme = useComputedColorScheme("light");
|
||||
|
||||
const toggleColorScheme = () => {
|
||||
setColorScheme(computedColorScheme === 'dark' ? 'light' : 'dark')
|
||||
}
|
||||
setColorScheme(computedColorScheme === "dark" ? "light" : "dark");
|
||||
};
|
||||
|
||||
return (
|
||||
<Container size="sm" py="xl">
|
||||
|
|
@ -28,7 +28,7 @@ function App() {
|
|||
size="lg"
|
||||
aria-label="Toggle color scheme"
|
||||
>
|
||||
{computedColorScheme === 'dark' ? '\u2600' : '\u263E'}
|
||||
{computedColorScheme === "dark" ? "\u2600" : "\u263E"}
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
<Text c="var(--inspector-text-secondary)">
|
||||
|
|
@ -36,7 +36,7 @@ function App() {
|
|||
</Text>
|
||||
</Stack>
|
||||
</Container>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default App
|
||||
export default App;
|
||||
|
|
|
|||
|
|
@ -1,52 +1,52 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite'
|
||||
import { AnnotationBadge } from './AnnotationBadge'
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { AnnotationBadge } from "./AnnotationBadge";
|
||||
|
||||
const meta: Meta<typeof AnnotationBadge> = {
|
||||
title: 'Atoms/AnnotationBadge',
|
||||
title: "Atoms/AnnotationBadge",
|
||||
component: AnnotationBadge,
|
||||
}
|
||||
};
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof AnnotationBadge>
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof AnnotationBadge>;
|
||||
|
||||
export const Audience: Story = {
|
||||
args: {
|
||||
label: 'user',
|
||||
variant: 'audience',
|
||||
label: "user",
|
||||
variant: "audience",
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const ReadOnly: Story = {
|
||||
args: {
|
||||
label: 'read-only',
|
||||
variant: 'readOnly',
|
||||
label: "read-only",
|
||||
variant: "readOnly",
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const Destructive: Story = {
|
||||
args: {
|
||||
label: 'destructive',
|
||||
variant: 'destructive',
|
||||
label: "destructive",
|
||||
variant: "destructive",
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const LongRun: Story = {
|
||||
args: {
|
||||
label: 'long-run',
|
||||
variant: 'longRun',
|
||||
label: "long-run",
|
||||
variant: "longRun",
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const PriorityHigh: Story = {
|
||||
args: {
|
||||
label: 'priority: high',
|
||||
variant: 'priority',
|
||||
label: "priority: high",
|
||||
variant: "priority",
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
label: 'custom',
|
||||
variant: 'default',
|
||||
label: "custom",
|
||||
variant: "default",
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,27 +1,39 @@
|
|||
import { Badge } from '@mantine/core'
|
||||
import { Badge } from "@mantine/core";
|
||||
|
||||
export type AnnotationVariant = 'audience' | 'readOnly' | 'destructive' | 'longRun' | 'priority' | 'default'
|
||||
export type AnnotationVariant =
|
||||
| "audience"
|
||||
| "readOnly"
|
||||
| "destructive"
|
||||
| "longRun"
|
||||
| "priority"
|
||||
| "default";
|
||||
|
||||
export interface AnnotationBadgeProps {
|
||||
label: string
|
||||
variant?: AnnotationVariant
|
||||
label: string;
|
||||
variant?: AnnotationVariant;
|
||||
}
|
||||
|
||||
const variantMap: Record<AnnotationVariant, { color: string; variant: string }> = {
|
||||
audience: { color: 'gray', variant: 'outline' },
|
||||
readOnly: { color: 'dark', variant: 'filled' },
|
||||
destructive: { color: 'red', variant: 'outline' },
|
||||
longRun: { color: 'yellow', variant: 'outline' },
|
||||
priority: { color: 'orange', variant: 'light' },
|
||||
default: { color: 'gray', variant: 'light' },
|
||||
}
|
||||
const variantMap: Record<
|
||||
AnnotationVariant,
|
||||
{ color: string; variant: string }
|
||||
> = {
|
||||
audience: { color: "gray", variant: "outline" },
|
||||
readOnly: { color: "dark", variant: "filled" },
|
||||
destructive: { color: "red", variant: "outline" },
|
||||
longRun: { color: "yellow", variant: "outline" },
|
||||
priority: { color: "orange", variant: "light" },
|
||||
default: { color: "gray", variant: "light" },
|
||||
};
|
||||
|
||||
export function AnnotationBadge({ label, variant = 'default' }: AnnotationBadgeProps) {
|
||||
const { color, variant: badgeVariant } = variantMap[variant]
|
||||
export function AnnotationBadge({
|
||||
label,
|
||||
variant = "default",
|
||||
}: AnnotationBadgeProps) {
|
||||
const { color, variant: badgeVariant } = variantMap[variant];
|
||||
|
||||
return (
|
||||
<Badge color={color} variant={badgeVariant}>
|
||||
{label}
|
||||
</Badge>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { CapabilityItem } from './CapabilityItem';
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { CapabilityItem } from "./CapabilityItem";
|
||||
|
||||
const meta: Meta<typeof CapabilityItem> = {
|
||||
title: 'Atoms/CapabilityItem',
|
||||
title: "Atoms/CapabilityItem",
|
||||
component: CapabilityItem,
|
||||
};
|
||||
|
||||
|
|
@ -11,14 +11,14 @@ type Story = StoryObj<typeof CapabilityItem>;
|
|||
|
||||
export const Supported: Story = {
|
||||
args: {
|
||||
name: 'Tools',
|
||||
name: "Tools",
|
||||
supported: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const SupportedWithCount: Story = {
|
||||
args: {
|
||||
name: 'Tools',
|
||||
name: "Tools",
|
||||
supported: true,
|
||||
count: 4,
|
||||
},
|
||||
|
|
@ -26,7 +26,7 @@ export const SupportedWithCount: Story = {
|
|||
|
||||
export const NotSupported: Story = {
|
||||
args: {
|
||||
name: 'Completions',
|
||||
name: "Completions",
|
||||
supported: false,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Group, Text } from '@mantine/core';
|
||||
import { Group, Text } from "@mantine/core";
|
||||
|
||||
export interface CapabilityItemProps {
|
||||
name: string;
|
||||
|
|
@ -6,12 +6,18 @@ export interface CapabilityItemProps {
|
|||
count?: number;
|
||||
}
|
||||
|
||||
export function CapabilityItem({ name, supported, count }: CapabilityItemProps) {
|
||||
export function CapabilityItem({
|
||||
name,
|
||||
supported,
|
||||
count,
|
||||
}: CapabilityItemProps) {
|
||||
const label = count != null ? `${name} (${count})` : name;
|
||||
|
||||
return (
|
||||
<Group gap="xs">
|
||||
<Text c={supported ? 'green' : 'red'}>{supported ? '\u2713' : '\u2717'}</Text>
|
||||
<Text c={supported ? "green" : "red"}>
|
||||
{supported ? "\u2713" : "\u2717"}
|
||||
</Text>
|
||||
<Text>{label}</Text>
|
||||
</Group>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { fn } from 'storybook/test';
|
||||
import { ConnectionToggle } from './ConnectionToggle';
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { fn } from "storybook/test";
|
||||
import { ConnectionToggle } from "./ConnectionToggle";
|
||||
|
||||
const meta: Meta<typeof ConnectionToggle> = {
|
||||
title: 'Atoms/ConnectionToggle',
|
||||
title: "Atoms/ConnectionToggle",
|
||||
component: ConnectionToggle,
|
||||
args: {
|
||||
onChange: fn(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Switch } from '@mantine/core';
|
||||
import { Switch } from "@mantine/core";
|
||||
|
||||
export interface ConnectionToggleProps {
|
||||
checked: boolean;
|
||||
|
|
@ -7,7 +7,12 @@ export interface ConnectionToggleProps {
|
|||
onChange: (checked: boolean) => void;
|
||||
}
|
||||
|
||||
export function ConnectionToggle({ checked, loading, disabled, onChange }: ConnectionToggleProps) {
|
||||
export function ConnectionToggle({
|
||||
checked,
|
||||
loading,
|
||||
disabled,
|
||||
onChange,
|
||||
}: ConnectionToggleProps) {
|
||||
return (
|
||||
<Switch
|
||||
size="lg"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { fn } from 'storybook/test';
|
||||
import { ContentViewer } from './ContentViewer';
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { fn } from "storybook/test";
|
||||
import { ContentViewer } from "./ContentViewer";
|
||||
|
||||
const meta: Meta<typeof ContentViewer> = {
|
||||
title: 'Atoms/ContentViewer',
|
||||
title: "Atoms/ContentViewer",
|
||||
component: ContentViewer,
|
||||
};
|
||||
|
||||
|
|
@ -12,56 +12,57 @@ type Story = StoryObj<typeof ContentViewer>;
|
|||
|
||||
export const PlainText: Story = {
|
||||
args: {
|
||||
type: 'text',
|
||||
content: 'Hello, world!\nThis is plain text.',
|
||||
type: "text",
|
||||
content: "Hello, world!\nThis is plain text.",
|
||||
},
|
||||
};
|
||||
|
||||
export const JsonContent: Story = {
|
||||
args: {
|
||||
type: 'json',
|
||||
content: '{"name":"my-app","version":"1.0.0","description":"Sample configuration file"}',
|
||||
type: "json",
|
||||
content:
|
||||
'{"name":"my-app","version":"1.0.0","description":"Sample configuration file"}',
|
||||
},
|
||||
};
|
||||
|
||||
export const ImagePreview: Story = {
|
||||
args: {
|
||||
type: 'image',
|
||||
type: "image",
|
||||
content:
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
|
||||
mimeType: 'image/png',
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
|
||||
mimeType: "image/png",
|
||||
},
|
||||
};
|
||||
|
||||
export const LongContent: Story = {
|
||||
args: {
|
||||
type: 'json',
|
||||
type: "json",
|
||||
content: JSON.stringify({
|
||||
name: 'my-app',
|
||||
version: '2.5.0',
|
||||
description: 'A comprehensive application configuration',
|
||||
author: 'Inspector Team',
|
||||
license: 'MIT',
|
||||
repository: 'https://github.com/example/my-app',
|
||||
name: "my-app",
|
||||
version: "2.5.0",
|
||||
description: "A comprehensive application configuration",
|
||||
author: "Inspector Team",
|
||||
license: "MIT",
|
||||
repository: "https://github.com/example/my-app",
|
||||
dependencies: {
|
||||
react: '^18.0.0',
|
||||
typescript: '^5.0.0',
|
||||
mantine: '^7.0.0',
|
||||
react: "^18.0.0",
|
||||
typescript: "^5.0.0",
|
||||
mantine: "^7.0.0",
|
||||
},
|
||||
devDependencies: {
|
||||
vitest: '^1.0.0',
|
||||
storybook: '^8.0.0',
|
||||
eslint: '^9.0.0',
|
||||
vitest: "^1.0.0",
|
||||
storybook: "^8.0.0",
|
||||
eslint: "^9.0.0",
|
||||
},
|
||||
scripts: {
|
||||
dev: 'vite',
|
||||
build: 'tsc && vite build',
|
||||
test: 'vitest',
|
||||
lint: 'eslint .',
|
||||
dev: "vite",
|
||||
build: "tsc && vite build",
|
||||
test: "vitest",
|
||||
lint: "eslint .",
|
||||
},
|
||||
settings: {
|
||||
theme: 'dark',
|
||||
language: 'en',
|
||||
theme: "dark",
|
||||
language: "en",
|
||||
notifications: true,
|
||||
maxRetries: 3,
|
||||
},
|
||||
|
|
@ -71,8 +72,8 @@ export const LongContent: Story = {
|
|||
|
||||
export const WithCopyButton: Story = {
|
||||
args: {
|
||||
type: 'text',
|
||||
content: 'Hello, world!\nThis text can be copied.',
|
||||
type: "text",
|
||||
content: "Hello, world!\nThis text can be copied.",
|
||||
onCopy: fn(),
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Button, Code, Image, Stack } from '@mantine/core';
|
||||
import { Button, Code, Image, Stack } from "@mantine/core";
|
||||
|
||||
export interface ContentViewerProps {
|
||||
type: 'text' | 'json' | 'image' | 'audio';
|
||||
type: "text" | "json" | "image" | "audio";
|
||||
content: string;
|
||||
mimeType?: string;
|
||||
onCopy?: () => void;
|
||||
|
|
@ -15,22 +15,27 @@ function formatJson(content: string): string {
|
|||
}
|
||||
}
|
||||
|
||||
export function ContentViewer({ type, content, mimeType, onCopy }: ContentViewerProps) {
|
||||
export function ContentViewer({
|
||||
type,
|
||||
content,
|
||||
mimeType,
|
||||
onCopy,
|
||||
}: ContentViewerProps) {
|
||||
return (
|
||||
<Stack gap="xs">
|
||||
{type === 'json' && <Code block>{formatJson(content)}</Code>}
|
||||
{type === 'text' && <Code block>{content}</Code>}
|
||||
{type === 'image' && (
|
||||
{type === "json" && <Code block>{formatJson(content)}</Code>}
|
||||
{type === "text" && <Code block>{content}</Code>}
|
||||
{type === "image" && (
|
||||
<Image
|
||||
src={`data:${mimeType || 'image/png'};base64,${content}`}
|
||||
src={`data:${mimeType || "image/png"};base64,${content}`}
|
||||
alt="Content preview"
|
||||
maw={400}
|
||||
radius="md"
|
||||
/>
|
||||
)}
|
||||
{type === 'audio' && (
|
||||
{type === "audio" && (
|
||||
<audio controls>
|
||||
<source src={`data:${mimeType || 'audio/wav'};base64,${content}`} />
|
||||
<source src={`data:${mimeType || "audio/wav"};base64,${content}`} />
|
||||
</audio>
|
||||
)}
|
||||
{onCopy && (
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { CopyButton } from './CopyButton';
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { CopyButton } from "./CopyButton";
|
||||
|
||||
const meta: Meta<typeof CopyButton> = {
|
||||
title: 'Atoms/CopyButton',
|
||||
title: "Atoms/CopyButton",
|
||||
component: CopyButton,
|
||||
};
|
||||
|
||||
|
|
@ -11,13 +11,13 @@ type Story = StoryObj<typeof CopyButton>;
|
|||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
value: 'Hello, world!',
|
||||
value: "Hello, world!",
|
||||
},
|
||||
};
|
||||
|
||||
export const LongValue: Story = {
|
||||
args: {
|
||||
value:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.',
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import { ActionIcon, CopyButton as MantineCopyButton, Tooltip } from '@mantine/core';
|
||||
import {
|
||||
ActionIcon,
|
||||
CopyButton as MantineCopyButton,
|
||||
Tooltip,
|
||||
} from "@mantine/core";
|
||||
|
||||
export interface CopyButtonProps {
|
||||
value: string;
|
||||
|
|
@ -8,9 +12,13 @@ export function CopyButton({ value }: CopyButtonProps) {
|
|||
return (
|
||||
<MantineCopyButton value={value}>
|
||||
{({ copied, copy }) => (
|
||||
<Tooltip label={copied ? 'Copied' : 'Copy'}>
|
||||
<ActionIcon variant="subtle" color={copied ? 'green' : 'gray'} onClick={copy}>
|
||||
{copied ? '\u2713' : '\u2398'}
|
||||
<Tooltip label={copied ? "Copied" : "Copy"}>
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
color={copied ? "green" : "gray"}
|
||||
onClick={copy}
|
||||
>
|
||||
{copied ? "\u2713" : "\u2398"}
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { InlineError } from './InlineError';
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { InlineError } from "./InlineError";
|
||||
|
||||
const meta: Meta<typeof InlineError> = {
|
||||
title: 'Atoms/InlineError',
|
||||
title: "Atoms/InlineError",
|
||||
component: InlineError,
|
||||
};
|
||||
|
||||
|
|
@ -11,13 +11,13 @@ type Story = StoryObj<typeof InlineError>;
|
|||
|
||||
export const ShortError: Story = {
|
||||
args: {
|
||||
message: 'Connection timeout after 20s',
|
||||
message: "Connection timeout after 20s",
|
||||
},
|
||||
};
|
||||
|
||||
export const WithRetryCount: Story = {
|
||||
args: {
|
||||
message: 'Connection failed',
|
||||
message: "Connection failed",
|
||||
retryCount: 3,
|
||||
maxRetries: 5,
|
||||
},
|
||||
|
|
@ -25,26 +25,26 @@ export const WithRetryCount: Story = {
|
|||
|
||||
export const WithDetails: Story = {
|
||||
args: {
|
||||
message: 'Connection refused',
|
||||
message: "Connection refused",
|
||||
details:
|
||||
'Error: ECONNREFUSED 127.0.0.1:3000\n at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)',
|
||||
"Error: ECONNREFUSED 127.0.0.1:3000\n at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)",
|
||||
},
|
||||
};
|
||||
|
||||
export const WithDocLink: Story = {
|
||||
args: {
|
||||
message: 'Connection failed',
|
||||
docLink: 'https://example.com/troubleshooting',
|
||||
message: "Connection failed",
|
||||
docLink: "https://example.com/troubleshooting",
|
||||
},
|
||||
};
|
||||
|
||||
export const FullError: Story = {
|
||||
args: {
|
||||
message: 'Connection refused',
|
||||
message: "Connection refused",
|
||||
details:
|
||||
'Error: ECONNREFUSED 127.0.0.1:3000\n at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)',
|
||||
"Error: ECONNREFUSED 127.0.0.1:3000\n at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)",
|
||||
retryCount: 3,
|
||||
maxRetries: 5,
|
||||
docLink: 'https://example.com/troubleshooting',
|
||||
docLink: "https://example.com/troubleshooting",
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Alert, Anchor, Group, Spoiler, Stack, Text } from '@mantine/core';
|
||||
import { Alert, Anchor, Group, Spoiler, Stack, Text } from "@mantine/core";
|
||||
|
||||
export interface InlineErrorProps {
|
||||
message: string;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { fn } from 'storybook/test';
|
||||
import { ListChangedIndicator } from './ListChangedIndicator';
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { fn } from "storybook/test";
|
||||
import { ListChangedIndicator } from "./ListChangedIndicator";
|
||||
|
||||
const meta: Meta<typeof ListChangedIndicator> = {
|
||||
title: 'Atoms/ListChangedIndicator',
|
||||
title: "Atoms/ListChangedIndicator",
|
||||
component: ListChangedIndicator,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Button, Flex, Group, Text } from '@mantine/core';
|
||||
import { Button, Flex, Group, Text } from "@mantine/core";
|
||||
|
||||
export interface ListChangedIndicatorProps {
|
||||
visible: boolean;
|
||||
|
|
@ -8,17 +8,22 @@ export interface ListChangedIndicatorProps {
|
|||
const Dot = Flex.withProps({
|
||||
w: 8,
|
||||
h: 8,
|
||||
style: { borderRadius: '50%' },
|
||||
bg: 'var(--inspector-status-connecting)',
|
||||
style: { borderRadius: "50%" },
|
||||
bg: "var(--inspector-status-connecting)",
|
||||
});
|
||||
|
||||
export function ListChangedIndicator({ visible, onRefresh }: ListChangedIndicatorProps) {
|
||||
export function ListChangedIndicator({
|
||||
visible,
|
||||
onRefresh,
|
||||
}: ListChangedIndicatorProps) {
|
||||
if (!visible) return null;
|
||||
|
||||
return (
|
||||
<Group gap="xs">
|
||||
<Dot />
|
||||
<Text size="sm" c="dimmed">List updated</Text>
|
||||
<Text size="sm" c="dimmed">
|
||||
List updated
|
||||
</Text>
|
||||
<Button size="xs" variant="light" onClick={onRefresh}>
|
||||
↻ Refresh
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { LogEntry } from './LogEntry';
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { LogEntry } from "./LogEntry";
|
||||
|
||||
const meta: Meta<typeof LogEntry> = {
|
||||
title: 'Atoms/LogEntry',
|
||||
title: "Atoms/LogEntry",
|
||||
component: LogEntry,
|
||||
};
|
||||
|
||||
|
|
@ -11,73 +11,73 @@ type Story = StoryObj<typeof LogEntry>;
|
|||
|
||||
export const Debug: Story = {
|
||||
args: {
|
||||
timestamp: '2026-03-17T10:00:00Z',
|
||||
level: 'debug',
|
||||
message: 'Initializing connection pool',
|
||||
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',
|
||||
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',
|
||||
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%',
|
||||
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',
|
||||
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',
|
||||
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',
|
||||
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',
|
||||
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',
|
||||
timestamp: "2026-03-17T10:00:08Z",
|
||||
level: "info",
|
||||
message: "Tool execution completed",
|
||||
logger: "mcp-server",
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue