diff --git a/clients/web/src/App.css b/clients/web/src/App.css
index 4d054964..d8c779d4 100644
--- a/clients/web/src/App.css
+++ b/clients/web/src/App.css
@@ -103,3 +103,15 @@
.inspector-spin {
animation: inspector-spin 1s linear infinite;
}
+
+/* ── Responsive card ────────────────────────────────────── */
+
+.card-responsive {
+ width: 100%;
+}
+
+@media (min-width: 62em) {
+ .card-responsive {
+ width: 50%;
+ }
+}
diff --git a/clients/web/src/components/atoms/InlineError/InlineError.tsx b/clients/web/src/components/atoms/InlineError/InlineError.tsx
index bca095c2..c4be1732 100644
--- a/clients/web/src/components/atoms/InlineError/InlineError.tsx
+++ b/clients/web/src/components/atoms/InlineError/InlineError.tsx
@@ -1,11 +1,11 @@
-import { Alert, Anchor, Group, Spoiler, Stack, Text } from "@mantine/core";
+import { Alert, Button, Collapse, Group, Stack, Text } from "@mantine/core";
+import { useState } from "react";
export interface InlineErrorProps {
message: string;
details?: string;
retryCount?: number;
maxRetries?: number;
- onShowMore?: () => void;
docLink?: string;
}
@@ -16,33 +16,52 @@ export function InlineError({
maxRetries,
docLink,
}: InlineErrorProps) {
- const hasDetails =
- retryCount !== undefined || details !== undefined || docLink !== undefined;
+ const [expanded, setExpanded] = useState(false);
+ const hasExpandable = details !== undefined || docLink !== undefined;
return (
-
- {hasDetails && (
-
- {retryCount !== undefined && (
-
- Retry attempt {retryCount}
- {maxRetries !== undefined && ` of ${maxRetries}`}
+
+
+
+
+
+ {message}
+ {retryCount !== undefined && (
+
+ Retry attempt {retryCount}
+ {maxRetries !== undefined && ` of ${maxRetries}`}
+
+ )}
+
+ {hasExpandable && (
+
)}
- {details && (
-
- {details}
-
- )}
- {docLink && (
-
-
- View Troubleshooting Guide →
-
-
- )}
-
- )}
+
+
+
+ {details && {details}}
+ {docLink && (
+
+ )}
+
+
+
);
}
diff --git a/clients/web/src/components/layouts/HomeLayout/HomeLayout.stories.tsx b/clients/web/src/components/layouts/HomeLayout/HomeLayout.stories.tsx
index fdc28fa3..23d327f4 100644
--- a/clients/web/src/components/layouts/HomeLayout/HomeLayout.stories.tsx
+++ b/clients/web/src/components/layouts/HomeLayout/HomeLayout.stories.tsx
@@ -20,7 +20,6 @@ type Story = StoryObj;
function makeServerCallbacks(): Pick<
ServerCardProps,
| "onToggleConnection"
- | "onCopyCommand"
| "onServerInfo"
| "onSettings"
| "onEdit"
@@ -29,7 +28,6 @@ function makeServerCallbacks(): Pick<
> {
return {
onToggleConnection: fn(),
- onCopyCommand: fn(),
onServerInfo: fn(),
onSettings: fn(),
onEdit: fn(),
diff --git a/clients/web/src/components/molecules/HistoryEntry/HistoryEntry.tsx b/clients/web/src/components/molecules/HistoryEntry/HistoryEntry.tsx
index 634b640b..b7741572 100644
--- a/clients/web/src/components/molecules/HistoryEntry/HistoryEntry.tsx
+++ b/clients/web/src/components/molecules/HistoryEntry/HistoryEntry.tsx
@@ -2,12 +2,12 @@ import {
Badge,
Button,
Card,
- Code,
Collapse,
Group,
Stack,
Text,
} from "@mantine/core";
+import { ContentViewer } from "../../atoms/ContentViewer/ContentViewer";
export interface HistoryChildEntry {
timestamp: string;
@@ -66,12 +66,12 @@ export function HistoryEntry({
)}
-
- {status === "success" ? "OK" : "Error"}
-
{durationMs}ms
+
+ {status === "success" ? "OK" : "Error"}
+
@@ -93,13 +93,21 @@ export function HistoryEntry({
{parameters && (
Parameters:
- {JSON.stringify(parameters, null, 2)}
+
)}
{response && (
Response:
- {JSON.stringify(response, null, 2)}
+
)}
{childEntries && childEntries.length > 0 && (
diff --git a/clients/web/src/components/molecules/ServerCard/ServerCard.stories.tsx b/clients/web/src/components/molecules/ServerCard/ServerCard.stories.tsx
index d42f42c7..5355f092 100644
--- a/clients/web/src/components/molecules/ServerCard/ServerCard.stories.tsx
+++ b/clients/web/src/components/molecules/ServerCard/ServerCard.stories.tsx
@@ -7,7 +7,6 @@ const meta: Meta = {
component: ServerCard,
args: {
onToggleConnection: fn(),
- onCopyCommand: fn(),
onServerInfo: fn(),
onSettings: fn(),
onEdit: fn(),
diff --git a/clients/web/src/components/molecules/ServerCard/ServerCard.tsx b/clients/web/src/components/molecules/ServerCard/ServerCard.tsx
index fcde9295..e3c24fee 100644
--- a/clients/web/src/components/molecules/ServerCard/ServerCard.tsx
+++ b/clients/web/src/components/molecules/ServerCard/ServerCard.tsx
@@ -2,7 +2,6 @@ import {
Badge,
Button,
Card,
- Code,
Group,
Menu,
Stack,
@@ -11,7 +10,7 @@ import {
import { StatusIndicator } from "../../atoms/StatusIndicator/StatusIndicator";
import { TransportBadge } from "../../atoms/TransportBadge/TransportBadge";
import { ConnectionToggle } from "../../atoms/ConnectionToggle/ConnectionToggle";
-import { CopyButton } from "../../atoms/CopyButton/CopyButton";
+import { ContentViewer } from "../../atoms/ContentViewer/ContentViewer";
import { InlineError } from "../../atoms/InlineError/InlineError";
export interface ServerCardProps {
@@ -25,7 +24,6 @@ export interface ServerCardProps {
error?: { message: string; details?: string };
canTestClientFeatures: boolean;
onToggleConnection: (connect: boolean) => void;
- onCopyCommand: () => void;
onServerInfo: () => void;
onSettings: () => void;
onEdit: () => void;
@@ -76,7 +74,7 @@ export function ServerCard({
return (
-
+
{name}
@@ -101,14 +99,7 @@ export function ServerCard({
-
-
-
- {command}
-
-
-
-
+
{error && (
)}
-
-
-
- {canTestClientFeatures && (
-
- )}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ {canTestClientFeatures && (
+
+ )}
+
+
);
diff --git a/clients/web/src/components/organisms/LoggingScreen/LoggingScreen.tsx b/clients/web/src/components/organisms/LoggingScreen/LoggingScreen.tsx
index b77ebb6d..91697b88 100644
--- a/clients/web/src/components/organisms/LoggingScreen/LoggingScreen.tsx
+++ b/clients/web/src/components/organisms/LoggingScreen/LoggingScreen.tsx
@@ -30,15 +30,15 @@ export function LoggingScreen({
onCopyAll,
}: LoggingScreenProps) {
return (
-
+
-
+
-
-
+
+
Log Stream
@@ -52,17 +52,18 @@ export function LoggingScreen({
-
-
- {entries.map((entry, index) => (
-
- ))}
+ {entries.length > 0 ? (
+
+
+ {entries.map((entry, index) => (
+
+ ))}
+
+
+ ) : (
+
+ No log entries
-
- {entries.length === 0 && (
-
- No log entries
-
)}
diff --git a/clients/web/src/components/organisms/ServerListScreen/ServerListScreen.stories.tsx b/clients/web/src/components/organisms/ServerListScreen/ServerListScreen.stories.tsx
index 47705eb0..1d04297a 100644
--- a/clients/web/src/components/organisms/ServerListScreen/ServerListScreen.stories.tsx
+++ b/clients/web/src/components/organisms/ServerListScreen/ServerListScreen.stories.tsx
@@ -19,7 +19,6 @@ type Story = StoryObj;
function makeServerCallbacks(): Pick<
ServerCardProps,
| "onToggleConnection"
- | "onCopyCommand"
| "onServerInfo"
| "onSettings"
| "onEdit"
@@ -32,7 +31,6 @@ function makeServerCallbacks(): Pick<
> {
return {
onToggleConnection: fn(),
- onCopyCommand: fn(),
onServerInfo: fn(),
onSettings: fn(),
onEdit: fn(),
diff --git a/clients/web/src/theme/Card.ts b/clients/web/src/theme/Card.ts
index 46383bb0..014acace 100644
--- a/clients/web/src/theme/Card.ts
+++ b/clients/web/src/theme/Card.ts
@@ -6,4 +6,8 @@ export const ThemeCard = Card.extend({
radius: "md",
withBorder: true,
},
+ classNames: (_theme, props) => {
+ if (props.variant === "responsive") return { root: "card-responsive" };
+ return {};
+ },
});