mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:40:44 +00:00
feat(ui): add mobile cron session filter
Add the existing desktop cron-session visibility toggle to the mobile chat settings dropdown, reusing the shared session filtering state and cron filter icon path. Also add focused browser render coverage for the mobile dropdown so the cron filter button, hidden-count title, active/pressed state, and click behavior are covered. Validated: - pnpm exec oxfmt --check --threads=1 ui/src/ui/app-render.helpers.browser.test.ts - pnpm test ui/src/ui/app-render.helpers.browser.test.ts ui/src/ui/app-render.helpers.node.test.ts - pnpm lint --threads=8 Thanks @luzhidong.
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
import { render } from "lit";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { t } from "../i18n/index.ts";
|
||||
import { renderChatControls } from "./app-render.helpers.ts";
|
||||
import { renderChatControls, renderChatMobileToggle } from "./app-render.helpers.ts";
|
||||
import type { AppViewState } from "./app-view-state.ts";
|
||||
import type { SessionsListResult } from "./types.ts";
|
||||
|
||||
type SessionRow = SessionsListResult["sessions"][number];
|
||||
|
||||
function row(overrides: Partial<SessionRow> & { key: string }): SessionRow {
|
||||
return { kind: "direct", updatedAt: 0, ...overrides };
|
||||
}
|
||||
|
||||
function createState(overrides: Partial<AppViewState> = {}) {
|
||||
return {
|
||||
@@ -66,4 +73,35 @@ describe("chat header controls (browser)", () => {
|
||||
expect(button.getAttribute("aria-label")).toBe(button.getAttribute("data-tooltip"));
|
||||
}
|
||||
});
|
||||
|
||||
it("renders the cron session filter in the mobile dropdown controls", async () => {
|
||||
const state = createState({
|
||||
sessionsResult: {
|
||||
ts: 0,
|
||||
path: "",
|
||||
count: 2,
|
||||
defaults: { modelProvider: "openai", model: "gpt-5", contextTokens: null },
|
||||
sessions: [row({ key: "main" }), row({ key: "agent:main:cron:daily-briefing" })],
|
||||
},
|
||||
});
|
||||
const container = document.createElement("div");
|
||||
render(renderChatMobileToggle(state), container);
|
||||
await Promise.resolve();
|
||||
|
||||
const buttons = Array.from(
|
||||
container.querySelectorAll<HTMLButtonElement>(".chat-controls__thinking .btn--icon"),
|
||||
);
|
||||
|
||||
expect(buttons).toHaveLength(4);
|
||||
const cronButton = buttons.at(-1);
|
||||
expect(cronButton?.classList.contains("active")).toBe(true);
|
||||
expect(cronButton?.getAttribute("aria-pressed")).toBe("true");
|
||||
expect(cronButton?.getAttribute("title")).toBe(
|
||||
t("chat.showCronSessionsHidden", { count: "1" }),
|
||||
);
|
||||
|
||||
cronButton?.click();
|
||||
|
||||
expect(state.sessionsHideCron).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -386,6 +386,10 @@ export function renderChatMobileToggle(state: AppViewState) {
|
||||
const showThinking = state.onboarding ? false : state.settings.chatShowThinking;
|
||||
const showToolCalls = state.onboarding ? true : state.settings.chatShowToolCalls;
|
||||
const focusActive = state.onboarding ? true : state.settings.chatFocusMode;
|
||||
const hideCron = state.sessionsHideCron ?? true;
|
||||
const hiddenCronCount = hideCron
|
||||
? countHiddenCronSessions(state.sessionKey, state.sessionsResult)
|
||||
: 0;
|
||||
const toolCallsIcon = html`
|
||||
<svg
|
||||
width="18"
|
||||
@@ -543,6 +547,22 @@ export function renderChatMobileToggle(state: AppViewState) {
|
||||
>
|
||||
${focusIcon}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn--sm btn--icon ${hideCron ? "active" : ""}"
|
||||
@click=${() => {
|
||||
state.sessionsHideCron = !hideCron;
|
||||
}}
|
||||
aria-pressed=${hideCron}
|
||||
title=${
|
||||
hideCron
|
||||
? hiddenCronCount > 0
|
||||
? t("chat.showCronSessionsHidden", { count: String(hiddenCronCount) })
|
||||
: t("chat.showCronSessions")
|
||||
: t("chat.hideCronSessions")
|
||||
}
|
||||
>
|
||||
${renderCronFilterIcon(hiddenCronCount)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user