diff --git a/ui/src/app/app-host.test.ts b/ui/src/app/app-host.test.ts index 6e6d31af9714..f50a80504366 100644 --- a/ui/src/app/app-host.test.ts +++ b/ui/src/app/app-host.test.ts @@ -11,7 +11,6 @@ import { } from "../components/command-palette-contract.ts"; import { BROWSER_PANEL_TOGGLE_EVENT, - CUSTODIAN_PANEL_TOGGLE_EVENT, TERMINAL_PANEL_TOGGLE_EVENT, UI_COMMAND_EVENT, } from "../components/panel-toggle-contract.ts"; @@ -87,9 +86,7 @@ type TestOptionalCustomElement = { type ShellLazySurfaceState = ShellKeyboardState & { browserPanelElement: TestOptionalCustomElement; commandPaletteElement: TestOptionalCustomElement; - custodianPanelElement: TestOptionalCustomElement; handleDeferredBrowserToggle: (event: Event) => void; - handleDeferredCustodianToggle: (event: Event) => void; handleDeferredTerminalToggle: (event: Event) => void; terminalPanelElement: TestOptionalCustomElement; }; @@ -869,14 +866,11 @@ describe("OpenClaw shell keyboard shortcuts", () => { it("delivers first panel toggles after their lazy modules load", async () => { const terminalElement = createLazyElementSpec("terminal panel"); const browserElement = createLazyElementSpec("browser panel"); - const custodianElement = createLazyElementSpec("custodian panel"); const terminalToggle = vi.fn(); const browserToggle = vi.fn(); - const custodianToggle = vi.fn(); const shell = document.createElement("openclaw-app-shell") as unknown as ShellLazySurfaceState; shell.terminalPanelElement = terminalElement; shell.browserPanelElement = browserElement; - shell.custodianPanelElement = custodianElement; shell.runtime = { context: { gateway: { @@ -904,9 +898,6 @@ describe("OpenClaw shell keyboard shortcuts", () => { if (selector === browserElement.tagName) { return { handleToggleRequest: browserToggle }; } - if (selector === custodianElement.tagName) { - return { handleToggleRequest: custodianToggle }; - } return null; }, }); @@ -914,16 +905,13 @@ describe("OpenClaw shell keyboard shortcuts", () => { detail: { dock: "right", open: true }, }); const browserEvent = new CustomEvent(BROWSER_PANEL_TOGGLE_EVENT); - const custodianEvent = new CustomEvent(CUSTODIAN_PANEL_TOGGLE_EVENT); shell.handleDeferredTerminalToggle(terminalEvent); shell.handleDeferredBrowserToggle(browserEvent); - shell.handleDeferredCustodianToggle(custodianEvent); await vi.waitFor(() => { expect(terminalToggle).toHaveBeenCalledWith(terminalEvent); expect(browserToggle).toHaveBeenCalledWith(browserEvent); - expect(custodianToggle).toHaveBeenCalledWith(custodianEvent); }); }); diff --git a/ui/src/app/app-host.ts b/ui/src/app/app-host.ts index c6da27c0b722..5cb3e026eac7 100644 --- a/ui/src/app/app-host.ts +++ b/ui/src/app/app-host.ts @@ -477,8 +477,6 @@ class OpenClawShell this.shellChrome.handleDeferredTerminalToggle(event); readonly handleDeferredBrowserToggle = (event: Event) => this.shellChrome.handleDeferredBrowserToggle(event); - readonly handleDeferredCustodianToggle = (event: Event) => - this.shellChrome.handleDeferredCustodianToggle(event); readonly handleCommandPaletteSlashCommand = (command: string) => this.shellChrome.handleCommandPaletteSlashCommand(command); diff --git a/ui/src/app/app-shell-chrome.ts b/ui/src/app/app-shell-chrome.ts index d8980a7a553c..6b695c4a825b 100644 --- a/ui/src/app/app-shell-chrome.ts +++ b/ui/src/app/app-shell-chrome.ts @@ -12,7 +12,6 @@ import { import type { OpenClawModalDialog } from "../components/modal-dialog.ts"; import { BROWSER_PANEL_TOGGLE_EVENT, - CUSTODIAN_PANEL_TOGGLE_EVENT, DESKTOP_PANEL_TOGGLE_EVENT, isTerminalPanelShortcut, TERMINAL_PANEL_TOGGLE_EVENT, @@ -72,7 +71,6 @@ export interface ShellChromeHost extends HTMLElement { readonly terminalPanelElement: OptionalCustomElement; readonly browserPanelElement: OptionalCustomElement; readonly desktopPanelElement: OptionalCustomElement; - readonly custodianPanelElement: OptionalCustomElement; readonly execApprovalElement: OptionalCustomElement; readonly commandPalette: CommandPaletteElement | undefined; readonly approvalOverlay: (HTMLElement & { show(): void }) | undefined; @@ -117,7 +115,6 @@ export class ShellChromeOwner { window.addEventListener(TERMINAL_PANEL_TOGGLE_EVENT, this.handleDeferredTerminalToggle); window.addEventListener(BROWSER_PANEL_TOGGLE_EVENT, this.handleDeferredBrowserToggle); window.addEventListener(DESKTOP_PANEL_TOGGLE_EVENT, this.handleDeferredDesktopToggle); - window.addEventListener(CUSTODIAN_PANEL_TOGGLE_EVENT, this.handleDeferredCustodianToggle); } disconnect(): void { @@ -138,7 +135,6 @@ export class ShellChromeOwner { window.removeEventListener(TERMINAL_PANEL_TOGGLE_EVENT, this.handleDeferredTerminalToggle); window.removeEventListener(BROWSER_PANEL_TOGGLE_EVENT, this.handleDeferredBrowserToggle); window.removeEventListener(DESKTOP_PANEL_TOGGLE_EVENT, this.handleDeferredDesktopToggle); - window.removeEventListener(CUSTODIAN_PANEL_TOGGLE_EVENT, this.handleDeferredCustodianToggle); } toggleNavigationSurface(trigger?: HTMLElement): void { @@ -513,17 +509,6 @@ export class ShellChromeOwner { this.deliverPanelEventAfterLoad(host.desktopPanelElement, event); }; - readonly handleDeferredCustodianToggle = (event: Event): void => { - const host = this.host; - if (isOptionalElementDefined(host.custodianPanelElement)) { - return; - } - const snapshot = host.context?.gateway?.snapshot; - if (snapshot && isGatewayMethodAdvertised(snapshot, "openclaw.chat") === true) { - this.deliverPanelEventAfterLoad(host.custodianPanelElement, event); - } - }; - readonly handleCommandPaletteSlashCommand = (command: string): void => { const host = this.host; const chatHandler = host.commandPaletteTarget?.owner.isConnected diff --git a/ui/src/components/custodian/custodian-panel.test.ts b/ui/src/components/custodian/custodian-panel.test.ts index 1c13100e91be..e350f7249c9a 100644 --- a/ui/src/components/custodian/custodian-panel.test.ts +++ b/ui/src/components/custodian/custodian-panel.test.ts @@ -5,7 +5,6 @@ import { createContext } from "../../pages/custodian/custodian-page.test-harness import { CustodianSessionStore } from "../../pages/custodian/custodian-session-store.ts"; import { createApplicationContextProvider } from "../../test-helpers/application-context.ts"; import { createStorageMock } from "../../test-helpers/storage.ts"; -import { CUSTODIAN_PANEL_TOGGLE_EVENT } from "../panel-toggle-contract.ts"; import "./custodian-panel.ts"; type TestCustodianPanel = HTMLElement & { @@ -88,17 +87,23 @@ describe("custodian panel", () => { expect(panel.custodianPanelOpen).toBe(true); }); - it("suppresses the dock on the full page and ignores explicit toggles there", async () => { - const { panel } = await mountPanel(); + it("hides and restores the dock across full-page suppression", async () => { + const { panel, store } = await mountPanel(); + store.messages = [ + { id: 1, role: "user", text: "Check this system", at: 1, question: null, step: null }, + ]; - window.dispatchEvent(new CustomEvent(CUSTODIAN_PANEL_TOGGLE_EVENT, { detail: { open: true } })); + panel.suppressed = false; + panel.minimizeRequestId = 1; + await panel.updateComplete; + expect(panel.custodianPanelOpen).toBe(true); + + panel.suppressed = true; await panel.updateComplete; expect(panel.custodianPanelOpen).toBe(false); panel.suppressed = false; await panel.updateComplete; - window.dispatchEvent(new CustomEvent(CUSTODIAN_PANEL_TOGGLE_EVENT, { detail: { open: true } })); - await panel.updateComplete; expect(panel.custodianPanelOpen).toBe(true); panel.suppressed = true; @@ -155,8 +160,11 @@ describe("custodian panel", () => { it("updates the panel mascot mood with shared sending state", async () => { const { panel, store } = await mountPanel(); + store.messages = [ + { id: 1, role: "user", text: "Check this system", at: 1, question: null, step: null }, + ]; panel.suppressed = false; - window.dispatchEvent(new CustomEvent(CUSTODIAN_PANEL_TOGGLE_EVENT, { detail: { open: true } })); + panel.minimizeRequestId = 1; await panel.updateComplete; store.sending = true; diff --git a/ui/src/components/custodian/custodian-panel.ts b/ui/src/components/custodian/custodian-panel.ts index 96349f84ec27..02076252c335 100644 --- a/ui/src/components/custodian/custodian-panel.ts +++ b/ui/src/components/custodian/custodian-panel.ts @@ -10,10 +10,6 @@ import { import { DockLayoutController } from "../dock-layout-controller.ts"; import { createDockPanelLayout, type DockPanelSide } from "../dock-panel-layout.ts"; import { icons } from "../icons.ts"; -import { - CUSTODIAN_PANEL_TOGGLE_EVENT, - type CustodianPanelToggleDetail, -} from "../panel-toggle-contract.ts"; import "../../pages/custodian/custodian-surface.ts"; import "../../styles/custodian-panel.css"; @@ -40,7 +36,6 @@ export class OpenClawCustodianPanel extends OpenClawLightDomElement { reservationPrefix: "custodian", isAvailable: () => this.available, }); - private readonly onToggleRequest = (event: Event) => this.handleToggleRequest(event); private handledMinimizeRequestId = 0; private subscribedStore: CustodianSessionStore | null = null; private storeCleanup: (() => void) | null = null; @@ -48,12 +43,10 @@ export class OpenClawCustodianPanel extends OpenClawLightDomElement { override connectedCallback(): void { super.connectedCallback(); this.subscribeToStore(); - window.addEventListener(CUSTODIAN_PANEL_TOGGLE_EVENT, this.onToggleRequest); this.dockLayout.setSuppressed(this.suppressed); } override disconnectedCallback(): void { - window.removeEventListener(CUSTODIAN_PANEL_TOGGLE_EVENT, this.onToggleRequest); this.storeCleanup?.(); this.storeCleanup = null; this.subscribedStore = null; @@ -94,39 +87,6 @@ export class OpenClawCustodianPanel extends OpenClawLightDomElement { this.storeCleanup = this.store.subscribe(() => this.requestUpdate()); } - toggle(): void { - if (!this.available || this.suppressed) { - return; - } - if (this.dockLayout.open) { - this.dockLayout.setOpen(false); - } else { - this.dockLayout.setOpen(true); - } - } - - handleToggleRequest(event: Event): void { - const detail = - event instanceof CustomEvent && typeof event.detail === "object" && event.detail !== null - ? (event.detail as CustodianPanelToggleDetail) - : null; - if (detail?.dock === "right" || detail?.dock === "bottom") { - this.dockLayout.setDock(detail.dock, false); - } - if (detail?.open === false) { - this.dockLayout.setOpen(false); - return; - } - if (detail?.open === true) { - if (!this.available || this.suppressed) { - return; - } - this.dockLayout.setOpen(true); - return; - } - this.toggle(); - } - private setDock(dock: CustodianDock): void { this.dockLayout.setDock(dock); } diff --git a/ui/src/components/panel-toggle-contract.ts b/ui/src/components/panel-toggle-contract.ts index c1e22ee7c86a..7196f7e80639 100644 --- a/ui/src/components/panel-toggle-contract.ts +++ b/ui/src/components/panel-toggle-contract.ts @@ -3,7 +3,6 @@ import type { UiCommandParams } from "@openclaw/gateway-protocol"; export const TERMINAL_PANEL_TOGGLE_EVENT = "openclaw:terminal-toggle"; export const BROWSER_PANEL_TOGGLE_EVENT = "openclaw:browser-toggle"; export const DESKTOP_PANEL_TOGGLE_EVENT = "openclaw:desktop-toggle"; -export const CUSTODIAN_PANEL_TOGGLE_EVENT = "openclaw:custodian-toggle"; export const UI_COMMAND_EVENT = "openclaw:ui-command"; export type UiCommandDetail = UiCommandParams; @@ -31,11 +30,6 @@ export type DesktopPanelToggleDetail = { environmentId?: string; }; -export type CustodianPanelToggleDetail = { - dock?: "bottom" | "right"; - open?: boolean; -}; - export type PanelToggleElement = HTMLElement & { handleToggleRequest: (event: Event) => void; }; diff --git a/ui/src/i18n/locales/en.ts b/ui/src/i18n/locales/en.ts index 64a786302f75..d9c987c29673 100644 --- a/ui/src/i18n/locales/en.ts +++ b/ui/src/i18n/locales/en.ts @@ -2358,7 +2358,6 @@ export const en: TranslationMap = { unsupportedGateway: "Update the Gateway to continue setup with OpenClaw.", panel: { title: "OpenClaw", - toggle: "Ask OpenClaw", close: "Close Ask OpenClaw", resize: "Resize Ask OpenClaw", dockBottom: "Dock Ask OpenClaw at bottom",