inspector/clients/web/src/components/molecules/ToolDetailPanel/ToolDetailPanel.tsx
cliffhall 39ef184b53 feat: Add Mantine theme, 12 atom components, and 25 molecule components with Storybook stories
- Mantine theme with component extensions (Badge, Card, Paper, Button, etc.)
- CSS custom properties for design tokens (--inspector-* vars)
- Dark/light mode support with auto detection
- 12 atoms: StatusIndicator, AnnotationBadge, CapabilityItem, LogEntry,
  ProgressDisplay, ContentViewer, ListChangedIndicator, CopyButton,
  ConnectionToggle, TransportBadge, InlineError, MessageBubble
- 25 molecules: ServerCard, AddServerMenu, SchemaForm, ToolListItem,
  ToolDetailPanel, ResultPanel, ResourceListItem, ResourcePreviewPanel,
  ResourceTemplateInput, PromptArgumentsForm, PromptMessagesDisplay,
  LogControls, TaskCard, HistoryEntry, ServerInfoContent, ServerSettingsForm,
  RootsTable, SamplingRequestPanel, ElicitationFormPanel, ElicitationUrlPanel,
  InlineSamplingRequest, InlineElicitationRequest, PendingClientRequests,
  ImportServerJsonPanel, ExperimentalFeaturesPanel
- Exclude storybook-static from version control
- Exclude .stories.tsx from app tsconfig (Storybook-only modules)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:23:56 -04:00

102 lines
2.7 KiB
TypeScript

import { Button, Divider, Group, Stack, Text, Title } from '@mantine/core'
import { AnnotationBadge } from '../../atoms/AnnotationBadge/AnnotationBadge'
import { ProgressDisplay } from '../../atoms/ProgressDisplay/ProgressDisplay'
import { SchemaForm } from '../SchemaForm/SchemaForm'
import type { JsonSchema } from '../SchemaForm/SchemaForm'
export interface ToolAnnotations {
audience?: string
readOnly?: boolean
destructive?: boolean
longRunning?: boolean
hints?: string
}
export interface ToolDetailPanelProps {
name: string
description?: string
annotations?: ToolAnnotations
schema: JsonSchema
formValues: Record<string, unknown>
isExecuting: boolean
progress?: { percent: number; description?: string }
onFormChange: (values: Record<string, unknown>) => void
onExecute: () => void
onCancel: () => void
}
export function ToolDetailPanel({
name,
description,
annotations,
schema,
formValues,
isExecuting,
progress,
onFormChange,
onExecute,
onCancel,
}: ToolDetailPanelProps) {
const hasAnnotations =
annotations &&
(annotations.audience ||
annotations.readOnly ||
annotations.destructive ||
annotations.longRunning ||
annotations.hints)
return (
<Stack gap="md">
<Title order={4}>Tool: {name}</Title>
{description && (
<Text size="sm" c="dimmed">
{description}
</Text>
)}
{hasAnnotations && (
<>
<Text size="sm">Annotations:</Text>
<Group gap="xs">
{annotations.audience && (
<AnnotationBadge label={annotations.audience} variant="audience" />
)}
{annotations.readOnly && <AnnotationBadge label="read-only" variant="readOnly" />}
{annotations.destructive && (
<AnnotationBadge label="destructive" variant="destructive" />
)}
{annotations.longRunning && <AnnotationBadge label="long-run" variant="longRun" />}
{annotations.hints && (
<Text size="xs" c="dimmed" fs="italic">
{annotations.hints}
</Text>
)}
</Group>
</>
)}
<Divider />
<SchemaForm
schema={schema}
values={formValues}
onChange={onFormChange}
disabled={isExecuting}
/>
{progress && <ProgressDisplay progress={progress.percent} description={progress.description} />}
<Group>
<Button fullWidth onClick={onExecute} disabled={isExecuting} loading={isExecuting}>
Execute Tool
</Button>
{isExecuting && (
<Button variant="light" color="red" onClick={onCancel}>
Cancel
</Button>
)}
</Group>
</Stack>
)
}