* feat(web): single header MonitoringToggle + Prompts-style Tools results (#1661) Consolidate the monitoring column's open/close affordances into one header toggle, and align the Tools/Prompts result panes and the sidebar log layout. - Add a single `MonitoringToggle` in the header, to the right of the theme icon. It opens/closes the monitoring column and only shows when a server is connected OR a connect attempt failed (wide viewport + a monitor tab available) — the same availability rule the column uses. - Remove the scattered pin/close icons: delete `PinColumnButton`; drop `onPin` from the Logs/Protocol/Network/Console screens and their stream panels; drop `onOpenMonitor` from the server list; remove the close button from `MonitoringControls`/`MonitoringScreen`. - Tools screen: remove the "Results will appear here" placeholder pane. Results now replace the input form in a single content pane (the Prompts pattern), with a top-left X (ToolResultPanel) that dismisses them back to the form; form values are preserved for a re-run. - Prompts screen: the argument form fills the content pane width (drop the 40% cap), matching the Tools input. - LogEntry: add a `compact` two-line layout (time/level/logger on line one, message wrapping below) used by the embedded monitoring-column Logs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sMW1YZXkM7fDkdPtHpE95 * polish(web): tooltips on icon buttons + rename "monitoring column" → "monitoring sidebar" (#1661) - Add Mantine `Tooltip`s to the icon-only controls: Client settings, Theme (dynamic light/dark label), the monitoring-sidebar toggle, the list-level and per-entry Expand/Collapse toggles, the Pin/Unpin toggle, and the Replay button. Labels mirror each control's existing aria-label. - Rename the feature term "monitoring column" → "monitoring sidebar" across the user-facing labels (Open/Close/Resize), comments, and tests, so the UI calls it a sidebar consistently. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sMW1YZXkM7fDkdPtHpE95 * review: consistent sidebar wording + reuse MonitoringToggleProps (#1661) Address the two optional notes from the PR #1662 review: - Make the MonitoringToggle JSDoc voice consistent ("sidebar" throughout, no lingering "column"). - Drop ViewHeader's duplicate `MonitorToggleProps` and reuse the element's exported `MonitoringToggleProps` as the single source of truth. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sMW1YZXkM7fDkdPtHpE95 * feat(web): slide-in/out animation for the monitoring-sidebar toggle (#1661) The header MonitoringToggle now animates in/out via a Mantine Transition whose in/out styles drive width + margin-left (plus opacity/translateX): as its slot grows from 0 → the 36px icon, the flex-end header row reflows and pushes the theme + client-settings buttons one slot to the left; the exit reverses and they slide back over. A negative margin-left while collapsed cancels the row gap so the theme icon stays flush-right when the toggle is absent. Only appearance/ disappearance (connect / disconnect / narrow viewport) animates — opening or closing the sidebar leaves the toggle in place. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sMW1YZXkM7fDkdPtHpE95 --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4e8e772aff
commit
dbda70e83b
3 changed files with 613 additions and 440 deletions
|
|
@ -20,7 +20,7 @@ import {
|
|||
} from "../../../test/renderWithMantine";
|
||||
import { InspectorView, type InspectorViewProps } from "./InspectorView";
|
||||
|
||||
// The monitoring column (#1616) is gated on a 1040px viewport media query.
|
||||
// The monitoring sidebar (#1616) is gated on a 1040px viewport media query.
|
||||
// happy-dom's viewport is 1024px, so that query is really false; make just that
|
||||
// gate controllable per test. ViewHeader's own 992/768 queries stay "wide" (as
|
||||
// they are in the real 1024px happy-dom viewport), so header rendering — and
|
||||
|
|
@ -1298,7 +1298,7 @@ describe("InspectorView", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("pinned monitoring column (#1616)", () => {
|
||||
describe("pinned monitoring sidebar (#1616)", () => {
|
||||
const httpServer: ServerEntry = {
|
||||
id: "beta",
|
||||
name: "Beta",
|
||||
|
|
@ -1330,26 +1330,44 @@ describe("InspectorView", () => {
|
|||
return user;
|
||||
}
|
||||
|
||||
it("shows the Pin as column button on a monitor screen only when wide", async () => {
|
||||
it("shows the header monitoring toggle only when wide", async () => {
|
||||
monitorWide.value = false;
|
||||
const { unmount } = renderWithMantine(
|
||||
<StatefulInspectorViewHost {...connectedHttp()} />,
|
||||
);
|
||||
await gotoTab("Logs");
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Pin as column" }),
|
||||
screen.queryByRole("button", { name: "Open monitoring sidebar" }),
|
||||
).not.toBeInTheDocument();
|
||||
unmount();
|
||||
|
||||
monitorWide.value = true;
|
||||
renderWithMantine(<StatefulInspectorViewHost {...connectedHttp()} />);
|
||||
await gotoTab("Logs");
|
||||
expect(
|
||||
await screen.findByRole("button", { name: "Pin as column" }),
|
||||
await screen.findByRole("button", { name: "Open monitoring sidebar" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("opens the monitoring column when a connection is established", async () => {
|
||||
it("hides the header monitoring toggle when there is no connected or failed server", () => {
|
||||
// Disconnected, wide viewport: nothing to monitor, so no toggle appears.
|
||||
monitorWide.value = true;
|
||||
renderWithMantine(
|
||||
<StatefulInspectorViewHost
|
||||
{...makeProps({
|
||||
servers: [httpServer],
|
||||
activeServer: undefined,
|
||||
connectionStatus: "disconnected",
|
||||
})}
|
||||
/>,
|
||||
);
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Open monitoring sidebar" }),
|
||||
).toBeNull();
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("opens the monitoring sidebar when a connection is established", async () => {
|
||||
monitorWide.value = true;
|
||||
const { rerender } = renderWithMantine(
|
||||
<StatefulInspectorViewHost
|
||||
|
|
@ -1362,13 +1380,13 @@ describe("InspectorView", () => {
|
|||
);
|
||||
// Disconnected: the column is closed.
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull();
|
||||
|
||||
// Connecting opens it (the disconnected → connected transition).
|
||||
rerender(<StatefulInspectorViewHost {...connectedHttp()} />);
|
||||
expect(
|
||||
await screen.findByRole("button", { name: "Close monitoring column" }),
|
||||
await screen.findByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
|
@ -1378,7 +1396,7 @@ describe("InspectorView", () => {
|
|||
monitorWide.value = true;
|
||||
renderWithMantine(<StatefulInspectorViewHost {...connectedHttp()} />);
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
|
|
@ -1397,7 +1415,7 @@ describe("InspectorView", () => {
|
|||
});
|
||||
}
|
||||
|
||||
it("opens the monitoring column on a failed connection attempt (#1621)", async () => {
|
||||
it("opens the monitoring sidebar on a failed connection attempt (#1621)", async () => {
|
||||
monitorWide.value = true;
|
||||
const { rerender } = renderWithMantine(
|
||||
<StatefulInspectorViewHost
|
||||
|
|
@ -1410,7 +1428,7 @@ describe("InspectorView", () => {
|
|||
);
|
||||
// Disconnected: the column is closed.
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull();
|
||||
|
||||
// A connection failure (→ error) opens it to surface the diagnostics. The
|
||||
|
|
@ -1433,7 +1451,7 @@ describe("InspectorView", () => {
|
|||
/>,
|
||||
);
|
||||
expect(
|
||||
await screen.findByRole("button", { name: "Close monitoring column" }),
|
||||
await screen.findByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// The failure column leads with Network (the captured request) — the only
|
||||
|
|
@ -1548,7 +1566,7 @@ describe("InspectorView", () => {
|
|||
/>,
|
||||
);
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
|
|
@ -1604,7 +1622,7 @@ describe("InspectorView", () => {
|
|||
monitorWide.value = true;
|
||||
renderWithMantine(<StatefulInspectorViewHost {...failedHttp()} />);
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
|
|
@ -1621,7 +1639,7 @@ describe("InspectorView", () => {
|
|||
);
|
||||
// Connected + pinned: the column is open with the live monitor tabs.
|
||||
expect(
|
||||
await screen.findByRole("button", { name: "Close monitoring column" }),
|
||||
await screen.findByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// Crash: connected → error, activeServer cleared, NO erroredServerId.
|
||||
|
|
@ -1638,7 +1656,7 @@ describe("InspectorView", () => {
|
|||
// failure tabs.
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull(),
|
||||
);
|
||||
});
|
||||
|
|
@ -1702,15 +1720,15 @@ describe("InspectorView", () => {
|
|||
|
||||
it("pins the monitor group into the column and removes it from the header", async () => {
|
||||
monitorWide.value = true;
|
||||
const user = userEvent.setup();
|
||||
renderWithMantine(<StatefulInspectorViewHost {...connectedHttp()} />);
|
||||
const user = await gotoTab("Logs");
|
||||
await user.click(
|
||||
await screen.findByRole("button", { name: "Pin as column" }),
|
||||
await screen.findByRole("button", { name: "Open monitoring sidebar" }),
|
||||
);
|
||||
|
||||
// Column is open (its close control is present).
|
||||
expect(
|
||||
await screen.findByRole("button", { name: "Close monitoring column" }),
|
||||
await screen.findByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// The monitor group is gone from the header tab bar...
|
||||
|
|
@ -1736,19 +1754,19 @@ describe("InspectorView", () => {
|
|||
|
||||
it("returns the monitor group to the header when the column is closed", async () => {
|
||||
monitorWide.value = true;
|
||||
const user = userEvent.setup();
|
||||
renderWithMantine(<StatefulInspectorViewHost {...connectedHttp()} />);
|
||||
const user = await gotoTab("Logs");
|
||||
await user.click(
|
||||
await screen.findByRole("button", { name: "Pin as column" }),
|
||||
await screen.findByRole("button", { name: "Open monitoring sidebar" }),
|
||||
);
|
||||
await user.click(
|
||||
await screen.findByRole("button", { name: "Close monitoring column" }),
|
||||
await screen.findByRole("button", { name: "Close monitoring sidebar" }),
|
||||
);
|
||||
|
||||
// The column plays its slide-out animation before unmounting.
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull(),
|
||||
);
|
||||
const header = screen.getByRole("banner");
|
||||
|
|
@ -1760,9 +1778,12 @@ describe("InspectorView", () => {
|
|||
it("keeps the current header screen (not the column's) when closed", async () => {
|
||||
monitorWide.value = true;
|
||||
renderWithMantine(<StatefulInspectorViewHost {...connectedHttp()} />);
|
||||
// Navigate the primary onto a monitor tab (Logs) first, then open the
|
||||
// column — which moves the monitor group out of the header, so the primary
|
||||
// clamps to the first non-Servers header tab (Tools).
|
||||
const user = await gotoTab("Logs");
|
||||
await user.click(
|
||||
await screen.findByRole("button", { name: "Pin as column" }),
|
||||
await screen.findByRole("button", { name: "Open monitoring sidebar" }),
|
||||
);
|
||||
// Pinning moved the primary to the first non-Servers header tab (Tools).
|
||||
const header = screen.getByRole("banner");
|
||||
|
|
@ -1773,14 +1794,14 @@ describe("InspectorView", () => {
|
|||
// Switch the column to Protocol, then close it.
|
||||
await user.click(await screen.findByRole("radio", { name: "Protocol" }));
|
||||
await user.click(
|
||||
await screen.findByRole("button", { name: "Close monitoring column" }),
|
||||
await screen.findByRole("button", { name: "Close monitoring sidebar" }),
|
||||
);
|
||||
|
||||
// The primary stays on the header's current screen (Tools), not the
|
||||
// column's Protocol, and the monitor group returns to the header.
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull(),
|
||||
);
|
||||
expect(
|
||||
|
|
@ -1801,7 +1822,7 @@ describe("InspectorView", () => {
|
|||
<StatefulInspectorViewHost {...connectedHttp()} />,
|
||||
);
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull();
|
||||
expect(
|
||||
within(screen.getByRole("banner")).getByRole("radio", { name: "Logs" }),
|
||||
|
|
@ -1812,7 +1833,7 @@ describe("InspectorView", () => {
|
|||
monitorWide.value = true;
|
||||
renderWithMantine(<StatefulInspectorViewHost {...connectedHttp()} />);
|
||||
expect(
|
||||
screen.getByRole("button", { name: "Close monitoring column" }),
|
||||
screen.getByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
|
@ -1821,7 +1842,7 @@ describe("InspectorView", () => {
|
|||
monitorWide.value = true;
|
||||
renderWithMantine(<StatefulInspectorViewHost {...connectedHttp()} />);
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
|
|
@ -1832,7 +1853,7 @@ describe("InspectorView", () => {
|
|||
<StatefulInspectorViewHost {...connectedHttp()} />,
|
||||
);
|
||||
expect(
|
||||
screen.getByRole("button", { name: "Close monitoring column" }),
|
||||
screen.getByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeInTheDocument();
|
||||
|
||||
rerender(
|
||||
|
|
@ -1847,7 +1868,7 @@ describe("InspectorView", () => {
|
|||
// The column plays its slide-out animation before unmounting.
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Close monitoring column" }),
|
||||
screen.queryByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeNull(),
|
||||
);
|
||||
// Preference is untouched — only the column's close button clears it.
|
||||
|
|
@ -1871,7 +1892,7 @@ describe("InspectorView", () => {
|
|||
);
|
||||
// Column open, but Network is unavailable over stdio.
|
||||
expect(
|
||||
screen.getByRole("button", { name: "Close monitoring column" }),
|
||||
screen.getByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByRole("radio", { name: "Logs" })).toBeInTheDocument();
|
||||
expect(screen.queryByRole("radio", { name: "Network" })).toBeNull();
|
||||
|
|
@ -1919,7 +1940,7 @@ describe("InspectorView", () => {
|
|||
.map((r) => r.getAttribute("value")),
|
||||
).toEqual(["Servers"]);
|
||||
expect(
|
||||
screen.getByRole("button", { name: "Close monitoring column" }),
|
||||
screen.getByRole("button", { name: "Close monitoring sidebar" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
|
@ -1982,7 +2003,7 @@ describe("InspectorView", () => {
|
|||
monitorWide.value = true;
|
||||
renderWithMantine(<StatefulInspectorViewHost {...connectedHttp()} />);
|
||||
const handle = await screen.findByRole("separator", {
|
||||
name: "Resize monitoring column",
|
||||
name: "Resize monitoring sidebar",
|
||||
});
|
||||
// ArrowLeft widens by the 16px step (panel is on the right).
|
||||
fireEvent.keyDown(handle, { key: "ArrowLeft" });
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ const ALL_TABS: string[] = [
|
|||
CONSOLE_TAB,
|
||||
];
|
||||
|
||||
// The screens that can be pinned into the monitoring column (#1616). Pinning is
|
||||
// The screens that can be pinned into the monitoring sidebar (#1616). Pinning is
|
||||
// a group action: opening the column removes all *available* monitor tabs from
|
||||
// the header and hosts them in the column instead. Console (#1621) is the
|
||||
// stdio server's stderr stream — mutually exclusive with Network (Console shows
|
||||
|
|
@ -195,7 +195,7 @@ function isMonitorTab(tab: string): tab is MonitorTab {
|
|||
// has room for at least one full-width card beside the column.
|
||||
const MONITOR_WIDE_QUERY = "(min-width: 1040px)";
|
||||
|
||||
// Monitoring column width bounds (px). MIN keeps the stream readable; MAX stops
|
||||
// Monitoring sidebar width bounds (px). MIN keeps the stream readable; MAX stops
|
||||
// the column from crowding out the primary area.
|
||||
const MONITOR_WIDTH_MIN = 320;
|
||||
const MONITOR_WIDTH_MAX = 720;
|
||||
|
|
@ -267,7 +267,7 @@ const SplitRow = Flex.withProps({
|
|||
w: "100%",
|
||||
});
|
||||
|
||||
// The pinned monitoring column. Fixed-basis (its width is driven live via the
|
||||
// The pinned monitoring sidebar. Fixed-basis (its width is driven live via the
|
||||
// `w` style prop at the call site); `miw: 0` so its inner ScrollArea can bound.
|
||||
const MonitoringColumn = Stack.withProps({
|
||||
flex: "0 0 auto",
|
||||
|
|
@ -663,7 +663,7 @@ export function InspectorView({
|
|||
getInitialValueInEffect: false,
|
||||
});
|
||||
|
||||
// Open the monitoring column when a connection is established (#1616) OR when a
|
||||
// Open the monitoring sidebar when a connection is established (#1616) OR when a
|
||||
// connect *attempt* fails (#1621). Gated on the *transition into* the target
|
||||
// status (via the ref) rather than the status itself, so it fires once on an
|
||||
// actual connect/failure — not on every render, and not on a mount that starts
|
||||
|
|
@ -765,7 +765,7 @@ export function InspectorView({
|
|||
appTools,
|
||||
]);
|
||||
|
||||
// Monitoring column, derived (#1616, #1621). The monitor group is pinned into
|
||||
// Monitoring sidebar, derived (#1616, #1621). The monitor group is pinned into
|
||||
// the right column only when: the user asked for it, the viewport is wide
|
||||
// enough, the session is connected OR a connect attempt failed, and at least
|
||||
// one monitor tab is actually available (capability/stdio aware). Narrowing,
|
||||
|
|
@ -807,11 +807,14 @@ export function InspectorView({
|
|||
}
|
||||
return [];
|
||||
}, [connected, failed, availableTabs, stderrLogs, network, protocol]);
|
||||
const effectivePinned =
|
||||
monitorPinned &&
|
||||
!!isWide &&
|
||||
(connected || failed) &&
|
||||
monitorAvailable.length > 0;
|
||||
// The column can exist when: the viewport is wide enough, the session is
|
||||
// connected OR a connect attempt failed, and at least one monitor tab is
|
||||
// actually available. This is the same rule the server list used to gate its
|
||||
// open-sidebar button on, and it now also gates the header MonitoringToggle
|
||||
// (#1661) — the toggle is hidden entirely when the column can't exist.
|
||||
const monitorColumnAvailable =
|
||||
!!isWide && (connected || failed) && monitorAvailable.length > 0;
|
||||
const effectivePinned = monitorPinned && monitorColumnAvailable;
|
||||
|
||||
// The header loses the monitor group while the column is open (its screens
|
||||
// live in the column instead); otherwise it shows every available tab.
|
||||
|
|
@ -846,14 +849,7 @@ export function InspectorView({
|
|||
? monitorTab
|
||||
: (monitorAvailable.find(isMonitorTab) ?? LOGS_TAB);
|
||||
|
||||
// Pinning is a group action: remember which tab was clicked and open the
|
||||
// column. Gated by `canPin` so the pin affordance only appears when a click
|
||||
// would actually take effect (wide + connected).
|
||||
const canPin = !!isWide && connected;
|
||||
// Offer an "open monitoring column" affordance on the server list when a
|
||||
// connected server has monitor screens to show but the column isn't open yet.
|
||||
const canOpenMonitor =
|
||||
canPin && monitorAvailable.length > 0 && !effectivePinned;
|
||||
// Pinning is a group action: remember which tab to show and open the column.
|
||||
function pinMonitor(tab: MonitorTab) {
|
||||
setMonitorTab(tab);
|
||||
setMonitorPinned(true);
|
||||
|
|
@ -872,6 +868,20 @@ export function InspectorView({
|
|||
onActiveTabChange(activeTab);
|
||||
setMonitorPinned(false);
|
||||
}
|
||||
// The single header toggle (#1661): open the column onto the last-used monitor
|
||||
// tab (clamped to what's available) when closed, close it when open.
|
||||
function toggleMonitorColumn() {
|
||||
if (effectivePinned) {
|
||||
closeMonitorColumn();
|
||||
} else {
|
||||
pinMonitor(effectiveMonitorTab);
|
||||
}
|
||||
}
|
||||
// Only offer the toggle while the column can actually exist; otherwise the
|
||||
// header shows nothing to toggle.
|
||||
const monitorToggle = monitorColumnAvailable
|
||||
? { open: effectivePinned, onToggle: toggleMonitorColumn }
|
||||
: undefined;
|
||||
function commitMonitorWidth(next: number) {
|
||||
setMonitorWidth(next);
|
||||
setDragWidth(null);
|
||||
|
|
@ -934,7 +944,8 @@ export function InspectorView({
|
|||
|
||||
// Shared props for each monitor screen, spread into both its primary
|
||||
// (header-tab) instance and its embedded (column) instance so the two can't
|
||||
// drift. The primary adds `onPin`; the embedded adds `embedded`. (#1616)
|
||||
// drift. The embedded instance adds `embedded`; the column is opened/closed
|
||||
// from the single header MonitoringToggle (#1661), not per-screen. (#1616)
|
||||
const loggingScreenProps = {
|
||||
entries: logs,
|
||||
currentLevel: currentLogLevel,
|
||||
|
|
@ -1039,12 +1050,14 @@ export function InspectorView({
|
|||
onDisconnect={onDisconnect}
|
||||
onToggleTheme={onToggleTheme}
|
||||
onOpenClientSettings={onOpenClientSettings}
|
||||
monitorToggle={monitorToggle}
|
||||
/>
|
||||
) : (
|
||||
<ViewHeader
|
||||
connected={false}
|
||||
onToggleTheme={onToggleTheme}
|
||||
onOpenClientSettings={onOpenClientSettings}
|
||||
monitorToggle={monitorToggle}
|
||||
/>
|
||||
)}
|
||||
</AppShell.Header>
|
||||
|
|
@ -1072,11 +1085,6 @@ export function InspectorView({
|
|||
onClearHighlight={onClearHighlight}
|
||||
compact={serversCompact}
|
||||
onToggleCompact={() => setServersCompact((c) => !c)}
|
||||
onOpenMonitor={
|
||||
canOpenMonitor
|
||||
? () => pinMonitor(effectiveMonitorTab)
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</ScreenStage>
|
||||
<ScreenStage active={activeTab === "Tools"}>
|
||||
|
|
@ -1156,28 +1164,16 @@ export function InspectorView({
|
|||
/>
|
||||
</ScreenStage>
|
||||
<ScreenStage active={activeTab === LOGS_TAB}>
|
||||
<LoggingScreen
|
||||
{...loggingScreenProps}
|
||||
onPin={canPin ? () => pinMonitor(LOGS_TAB) : undefined}
|
||||
/>
|
||||
<LoggingScreen {...loggingScreenProps} />
|
||||
</ScreenStage>
|
||||
<ScreenStage active={activeTab === PROTOCOL_TAB}>
|
||||
<ProtocolScreen
|
||||
{...protocolScreenProps}
|
||||
onPin={canPin ? () => pinMonitor(PROTOCOL_TAB) : undefined}
|
||||
/>
|
||||
<ProtocolScreen {...protocolScreenProps} />
|
||||
</ScreenStage>
|
||||
<ScreenStage active={activeTab === NETWORK_TAB}>
|
||||
<NetworkScreen
|
||||
{...networkScreenProps}
|
||||
onPin={canPin ? () => pinMonitor(NETWORK_TAB) : undefined}
|
||||
/>
|
||||
<NetworkScreen {...networkScreenProps} />
|
||||
</ScreenStage>
|
||||
<ScreenStage active={activeTab === CONSOLE_TAB}>
|
||||
<ConsoleScreen
|
||||
{...consoleScreenProps}
|
||||
onPin={canPin ? () => pinMonitor(CONSOLE_TAB) : undefined}
|
||||
/>
|
||||
<ConsoleScreen {...consoleScreenProps} />
|
||||
</ScreenStage>
|
||||
</ScreenStageContainer>
|
||||
<Transition
|
||||
|
|
@ -1198,7 +1194,7 @@ export function InspectorView({
|
|||
step={MONITOR_WIDTH_STEP}
|
||||
onChange={setDragWidth}
|
||||
onCommit={commitMonitorWidth}
|
||||
aria-label="Resize monitoring column"
|
||||
aria-label="Resize monitoring sidebar"
|
||||
/>
|
||||
<MonitoringColumn w={columnWidth}>
|
||||
<MonitoringScreen
|
||||
|
|
@ -1207,7 +1203,6 @@ export function InspectorView({
|
|||
onChange={handleMonitorTabChange}
|
||||
searchValue={monitorSearch}
|
||||
onSearchChange={setMonitorSearch}
|
||||
onClose={closeMonitorColumn}
|
||||
screens={monitorScreens}
|
||||
/>
|
||||
</MonitoringColumn>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Duration (ms) of the monitoring column's open/close slide (#1616). Shared so
|
||||
* Duration (ms) of the monitoring sidebar's open/close slide (#1616). Shared so
|
||||
* dependent timings can't silently drift from the animation:
|
||||
* - `InspectorView` drives the column's Mantine `Transition` with it.
|
||||
* - `ServerCard` waits just past it before scrolling a newly-failed card into
|
||||
|
|
|
|||
Loading…
Reference in a new issue