feat(web): monitoring column search, close-to-fullscreen, and open/close animation (#1616)
- Add a search box to MonitoringControls (right of the tabs). It's a single shared search kept across column tab switches, filtering whichever screen is shown. Embedded panels apply this text but still ignore the sidebar-only filters (levels/categories/directions/method), which have no control there. - Close button now uses the "collapse sidebar" icon (TbLayoutSidebarRightCollapse), the mirror of the pin button's expand icon. - Closing the column carries its selection to the primary view: the screen the user was watching becomes the active header tab (rather than snapping back to the pre-pin selection). - Animate the column open/close: the handle + column slide in from the right and fade (reversing on close) via a Mantine Transition. - HistoryListPanel: drop the redundant "History (N)" header when there are no pinned requests (lone unpinned section renders headerless). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9b76272ad1
commit
c5e064ff71
3 changed files with 448 additions and 169 deletions
|
|
@ -127,8 +127,25 @@ describe("HistoryScreen", () => {
|
|||
expect(screen.queryByPlaceholderText("Search...")).toBeNull();
|
||||
});
|
||||
|
||||
it("shows the full stream when embedded, ignoring the live filter", () => {
|
||||
// A search that matches nothing would empty the full-size screen...
|
||||
it("applies the search text but ignores the method filter when embedded", () => {
|
||||
renderWithMantine(
|
||||
<HistoryScreen
|
||||
{...baseProps}
|
||||
ui={{
|
||||
...EMPTY_HISTORY_UI,
|
||||
// Method filter would exclude the tools/list entries on the full-size
|
||||
// screen...
|
||||
methodFilter: "resources/list",
|
||||
// ...but the column search matches them.
|
||||
search: "tools",
|
||||
}}
|
||||
embedded
|
||||
/>,
|
||||
);
|
||||
expect(screen.queryByText("No request history")).toBeNull();
|
||||
});
|
||||
|
||||
it("hides entries not matching the column search when embedded", () => {
|
||||
renderWithMantine(
|
||||
<HistoryScreen
|
||||
{...baseProps}
|
||||
|
|
@ -136,7 +153,6 @@ describe("HistoryScreen", () => {
|
|||
embedded
|
||||
/>,
|
||||
);
|
||||
// ...but the embedded column shows the full stream (not the empty state).
|
||||
expect(screen.queryByText("No request history")).toBeNull();
|
||||
expect(screen.getByText("No request history")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -147,14 +147,38 @@ describe("LoggingScreen", () => {
|
|||
expect(screen.queryByRole("button", { name: "Set" })).toBeNull();
|
||||
});
|
||||
|
||||
it("shows the full stream when embedded, ignoring the live filter", () => {
|
||||
it("applies the search text but ignores the level filter when embedded", () => {
|
||||
const entries = [
|
||||
{
|
||||
receivedAt: new Date(),
|
||||
params: { level: "info" as const, data: "hello" },
|
||||
},
|
||||
];
|
||||
renderWithMantine(
|
||||
<LoggingScreen
|
||||
{...baseProps}
|
||||
entries={entries}
|
||||
ui={{
|
||||
...EMPTY_LOGS_UI,
|
||||
// The level filter would hide this entry on the full-size screen...
|
||||
visibleLevels: { ...EMPTY_LOGS_UI.visibleLevels, info: false },
|
||||
// ...but the column search matches it.
|
||||
filterText: "hello",
|
||||
}}
|
||||
embedded
|
||||
/>,
|
||||
);
|
||||
// Search matches + level filter is ignored → the entry shows.
|
||||
expect(screen.getByText("hello")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("hides entries not matching the column search when embedded", () => {
|
||||
const entries = [
|
||||
{
|
||||
receivedAt: new Date(),
|
||||
params: { level: "info" as const, data: "hello" },
|
||||
},
|
||||
];
|
||||
// A filter that would hide the entry on the full-size screen...
|
||||
renderWithMantine(
|
||||
<LoggingScreen
|
||||
{...baseProps}
|
||||
|
|
@ -163,7 +187,6 @@ describe("LoggingScreen", () => {
|
|||
embedded
|
||||
/>,
|
||||
);
|
||||
// ...is ignored in the embedded, sidebar-less column.
|
||||
expect(screen.getByText("hello")).toBeInTheDocument();
|
||||
expect(screen.queryByText("hello")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -180,8 +180,25 @@ describe("NetworkScreen", () => {
|
|||
expect(screen.getByRole("button", { name: "Export" })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows the full stream when embedded, ignoring the live filter", () => {
|
||||
// A filter that matches nothing would empty the full-size screen...
|
||||
it("applies the search text but ignores the category filter when embedded", () => {
|
||||
renderWithMantine(
|
||||
<NetworkScreen
|
||||
{...baseProps}
|
||||
ui={{
|
||||
...EMPTY_NETWORK_UI,
|
||||
// Category filter would hide the transport entry on the full-size
|
||||
// screen...
|
||||
visibleCategories: { auth: true, transport: false },
|
||||
// ...but the column search matches it.
|
||||
filterText: "example.com",
|
||||
}}
|
||||
embedded
|
||||
/>,
|
||||
);
|
||||
expect(screen.queryByText("No network requests")).toBeNull();
|
||||
});
|
||||
|
||||
it("hides entries not matching the column search when embedded", () => {
|
||||
renderWithMantine(
|
||||
<NetworkScreen
|
||||
{...baseProps}
|
||||
|
|
@ -189,7 +206,6 @@ describe("NetworkScreen", () => {
|
|||
embedded
|
||||
/>,
|
||||
);
|
||||
// ...but the embedded column shows the full stream (not the empty state).
|
||||
expect(screen.queryByText("No network requests")).toBeNull();
|
||||
expect(screen.getByText("No network requests")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue