mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
fix(ui): keep the archive Undo working after leaving the Sessions page (#123749)
The archive toast outlives the Sessions page (toast host is app-shell level), but its Undo action was gated on the page's request scope, which dies the moment the operator navigates away — clicking Undo within the 6s window then silently did nothing. Run the un-archive through the shared sessions mutations store directly (it already fails closed on connection replacement and publishes errors), mirroring the always-mounted sidebar undo sibling.
This commit is contained in:
committed by
GitHub
parent
b9cf0bb96f
commit
3292ff146c
@@ -131,6 +131,40 @@ describe("sessions page lifecycle", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps the archive Undo working after navigating off the Sessions page", async () => {
|
||||
const key = "agent:main:navigated";
|
||||
const patch = vi.fn(async () => ({
|
||||
ok: true as const,
|
||||
path: "",
|
||||
key,
|
||||
entry: { sessionId: key },
|
||||
}));
|
||||
const sessions = createSessions({ patch });
|
||||
const mutableGateway = createGateway({} as GatewayBrowserClient);
|
||||
mutableGateway.emit({ sessionKey: key });
|
||||
const page = await createPage(createContext(mutableGateway.gateway, sessions));
|
||||
const toast = document.createElement("openclaw-toast-host");
|
||||
document.body.append(toast);
|
||||
await toast.updateComplete;
|
||||
|
||||
await page.archiveSessionWithUndo({
|
||||
key,
|
||||
sessionId: "session-nav",
|
||||
pinned: false,
|
||||
} as GatewaySessionRow);
|
||||
await toast.updateComplete;
|
||||
// The toast host outlives the page; navigation unmounts the page element.
|
||||
page.remove();
|
||||
toast.querySelector<HTMLButtonElement>(".app-toast__action")?.click();
|
||||
await vi.waitFor(() => expect(patch).toHaveBeenCalledTimes(2));
|
||||
expect(patch).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
key,
|
||||
{ archived: false },
|
||||
{ agentId: undefined, expectedSessionId: "session-nav" },
|
||||
);
|
||||
});
|
||||
|
||||
it("submits one trimmed bounded transcript search and adopts its status", async () => {
|
||||
const response = deferred<SessionsSearchResult>();
|
||||
const request = vi.fn(() => response.promise);
|
||||
|
||||
@@ -1193,21 +1193,20 @@ class SessionsPage extends OpenClawLightDomElement {
|
||||
if (result !== "completed" || !this.isRequestScopeCurrent(scope)) {
|
||||
return;
|
||||
}
|
||||
// Undo is captured before showing the toast: the toast host outlives this
|
||||
// page, so the action must run against the shared mutations store (which
|
||||
// fails closed on connection replacement) rather than page scope — a
|
||||
// page-scope check would silently no-op after navigating away.
|
||||
const agentId = this.sessionAgentId(row.key, scope.context);
|
||||
showToast({
|
||||
message: t("sessionsView.sessionArchived"),
|
||||
actionLabel: t("common.undo"),
|
||||
onAction: () => {
|
||||
void (async () => {
|
||||
if (!this.isRequestScopeCurrent(scope)) {
|
||||
return;
|
||||
}
|
||||
await this.patchSession(
|
||||
row.key,
|
||||
{ archived: false, ...(row.pinned === true ? { pinned: true } : {}) },
|
||||
scope,
|
||||
row.sessionId,
|
||||
);
|
||||
})();
|
||||
void scope.sessions.patch(
|
||||
row.key,
|
||||
{ archived: false, ...(row.pinned === true ? { pinned: true } : {}) },
|
||||
{ agentId, expectedSessionId: row.sessionId },
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user