mirror of
https://github.com/MeshCore-Beacon/beacon-web.git
synced 2026-10-22 15:23:27 +00:00
Close an inspected observer back to its packet on mobile (#130)
This commit is contained in:
1 parent
609dbc384f
commit
bdf253cbe6
3 files changed
+35
-7
No files matched your search
+10
-5
@@ -274,13 +274,18 @@ function AppInner() {
|
||||
// An observer opens its dashboard; a packet it was inspected from moves into the side drawer beside it.
|
||||
const viewObserver = useCallback((id: string, packet?: { hash: string; observationId?: number }) => {
|
||||
setPanels([]);
|
||||
const next = observerDestination(searchParams, id);
|
||||
const origin = new URLSearchParams(searchParams);
|
||||
if (packet) {
|
||||
next.set("hash", packet.hash); next.set("analyze", "1"); next.delete("path");
|
||||
if (packet.observationId != null) next.set("observation", String(packet.observationId)); else next.delete("observation");
|
||||
origin.set("hash", packet.hash); origin.set("analyze", "1"); origin.delete("path");
|
||||
if (packet.observationId != null) origin.set("observation", String(packet.observationId)); else origin.delete("observation");
|
||||
}
|
||||
if (isMobile) next.delete("analyze");
|
||||
navigate({ search: "?" + next.toString() });
|
||||
const next = observerDestination(origin, id);
|
||||
if (isMobile) {
|
||||
// The dashboard covers the screen on mobile, so its Close steps back to the packet instead.
|
||||
if (packet) navigate({ search: "?" + origin.toString() }, { replace: true });
|
||||
next.delete("analyze");
|
||||
}
|
||||
navigate({ search: "?" + next.toString() }, { state: { inspected: isMobile } });
|
||||
}, [navigate, searchParams, setPanels, isMobile]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { lazy, Suspense, useState, useMemo } from "react";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { useLocation, useNavigate, useSearchParams } from "react-router-dom";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { getBrokers } from "../../api/client";
|
||||
@@ -25,6 +25,8 @@ export function ObserverPage({ wsManager, onAnalyzePacket }: { wsManager: WsMana
|
||||
const { t } = useTranslation();
|
||||
const now = useTick(60_000);
|
||||
const id = params.get("observer");
|
||||
const navigate = useNavigate();
|
||||
const inspected = (useLocation().state as { inspected?: boolean } | null)?.inspected;
|
||||
const [actionTime, setActionTime] = useState(() => Date.now());
|
||||
const hourAt = (time: number) => Math.floor(time / 3_600_000) * 3_600_000;
|
||||
const comparing = params.has("compareWith");
|
||||
@@ -91,7 +93,7 @@ export function ObserverPage({ wsManager, onAnalyzePacket }: { wsManager: WsMana
|
||||
<span className="font-mono text-[13px] font-medium uppercase tracking-wider text-text-dim">{t("observerPage.detail")}</span>
|
||||
<div className="-mr-1 flex items-center gap-0.5">
|
||||
<MinimizeButton collapsed={minimized} onToggle={() => setMinimized(v => !v)} />
|
||||
<CloseButton onClose={() => select(null)} label={t("observerPage.back")} />
|
||||
<CloseButton onClose={() => inspected ? navigate(-1) : select(null)} label={t("observerPage.back")} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={`min-h-0 flex-1 overflow-auto ${minimized ? "hidden md:block" : ""}`}>
|
||||
|
||||
@@ -164,3 +164,24 @@ describe("observer investigation windows", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("observer investigation on mobile", () => {
|
||||
beforeEach(() => vi.stubGlobal("matchMedia", (query: string) => ({ matches: /max-width/.test(query), media: query, addEventListener: () => {}, removeEventListener: () => {}, addListener: () => {}, removeListener: () => {} })));
|
||||
it("closes an inspected observer back to the packet it came from", async () => {
|
||||
render(<App />); click("Route packet"); click("Select report 8"); click("Packet observer");
|
||||
expect(await screen.findByRole("heading", { level: 1 })).toHaveTextContent("Dashboard o1");
|
||||
expect(screen.queryByRole("heading", { name: /^Packet / })).not.toBeInTheDocument();
|
||||
click("Back to observers");
|
||||
await waitFor(() => expect(new URLSearchParams(window.location.search).get("tab")).toBe("Routes"));
|
||||
expect(await screen.findByRole("heading", { name: /^Packet / })).toHaveTextContent("Packet aa");
|
||||
expect(new URLSearchParams(window.location.search).get("observation")).toBe("8");
|
||||
});
|
||||
it("closes a dashboard opened from the list back to the list", async () => {
|
||||
window.history.replaceState({}, "", "/?tab=Observers&observer=o1");
|
||||
render(<App />);
|
||||
await screen.findByRole("heading", { level: 1 });
|
||||
click("Back to observers");
|
||||
await waitFor(() => expect(screen.queryByRole("heading", { level: 1 })).not.toBeInTheDocument());
|
||||
expect(new URLSearchParams(window.location.search).get("tab")).toBe("Observers");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user