mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-03 21:44:05 +00:00
fix: address Skill Workshop UI check failures
This commit is contained in:
@@ -1061,7 +1061,7 @@ describe("switchChatSession", () => {
|
||||
loadChatHistoryMock.mockResolvedValue(undefined);
|
||||
loadSessionsMock.mockResolvedValue(undefined);
|
||||
|
||||
switchChatSession(state, "agent:main:test-b");
|
||||
void switchChatSession(state, "agent:main:test-b");
|
||||
await Promise.resolve();
|
||||
|
||||
expect(state.chatQueue).toStrictEqual([]);
|
||||
@@ -1133,10 +1133,10 @@ describe("switchChatSession", () => {
|
||||
loadChatHistoryMock.mockResolvedValue(undefined);
|
||||
loadSessionsMock.mockResolvedValue(undefined);
|
||||
|
||||
switchChatSession(state, "agent:main:other");
|
||||
void switchChatSession(state, "agent:main:other");
|
||||
expect(state.chatQueue).toStrictEqual([]);
|
||||
|
||||
switchChatSession(state, "main");
|
||||
void switchChatSession(state, "main");
|
||||
|
||||
expect(state.chatQueue).toEqual([{ id: "queued-1", text: "message B", createdAt: 1 }]);
|
||||
});
|
||||
@@ -1180,7 +1180,7 @@ describe("switchChatSession", () => {
|
||||
loadChatHistoryMock.mockResolvedValue(undefined);
|
||||
loadSessionsMock.mockResolvedValue(undefined);
|
||||
|
||||
switchChatSession(state, "main");
|
||||
void switchChatSession(state, "main");
|
||||
await Promise.resolve();
|
||||
|
||||
expect(
|
||||
|
||||
@@ -282,7 +282,13 @@ function renderCronFilterIcon(hiddenCount: number) {
|
||||
}
|
||||
|
||||
export function renderChatSessionSelect(state: AppViewState) {
|
||||
return renderChatSessionSelectBase(state, switchChatSession, { surface: "desktop" });
|
||||
return renderChatSessionSelectBase(
|
||||
state,
|
||||
(targetState, nextSessionKey) => {
|
||||
void switchChatSession(targetState, nextSessionKey);
|
||||
},
|
||||
{ surface: "desktop" },
|
||||
);
|
||||
}
|
||||
|
||||
function chatAutoScrollLabel(mode: ChatAutoScrollMode) {
|
||||
@@ -586,7 +592,13 @@ export function renderChatMobileToggle(state: AppViewState) {
|
||||
}}
|
||||
>
|
||||
<div class="chat-controls">
|
||||
${renderChatSessionSelectBase(state, switchChatSession, { surface: "mobile" })}
|
||||
${renderChatSessionSelectBase(
|
||||
state,
|
||||
(targetState, nextSessionKey) => {
|
||||
void switchChatSession(targetState, nextSessionKey);
|
||||
},
|
||||
{ surface: "mobile" },
|
||||
)}
|
||||
<div class="chat-controls__thinking">
|
||||
${renderChatAutoScrollToggle(state)}
|
||||
<button
|
||||
@@ -771,7 +783,7 @@ export async function createChatSession(state: AppViewState): Promise<boolean> {
|
||||
|
||||
const preservedDraft = state.chatMessage;
|
||||
const preservedAttachments = state.chatAttachments;
|
||||
switchChatSession(state, nextSessionKey);
|
||||
void switchChatSession(state, nextSessionKey);
|
||||
state.chatMessage = preservedDraft;
|
||||
state.chatAttachments = preservedAttachments;
|
||||
return true;
|
||||
|
||||
@@ -214,7 +214,7 @@ let pendingUpdate: (() => void) | undefined;
|
||||
|
||||
const notifyLazyViewChanged = () => pendingUpdate?.();
|
||||
|
||||
function runUiTask<Args extends unknown[]>(
|
||||
function runUiTask<Args extends readonly unknown[]>(
|
||||
task: (...args: Args) => Promise<unknown>,
|
||||
): (...args: Args) => void {
|
||||
return (...args) => {
|
||||
@@ -423,7 +423,7 @@ function renderSidebarRecentSession(state: AppViewState, row: GatewaySessionRow)
|
||||
}
|
||||
event.preventDefault();
|
||||
if (row.key !== state.sessionKey) {
|
||||
switchChatSession(state, row.key);
|
||||
void switchChatSession(state, row.key);
|
||||
}
|
||||
state.setTab("chat" as import("./navigation.ts").Tab);
|
||||
}}
|
||||
@@ -793,9 +793,9 @@ function applySkillWorkshopReviewState<T extends SkillWorkshopReviewableProposal
|
||||
}));
|
||||
}
|
||||
|
||||
function rememberSkillWorkshopProposalReviewed<T extends SkillWorkshopReviewableProposal>(
|
||||
function rememberSkillWorkshopProposalReviewed(
|
||||
reviewedKeys: string[],
|
||||
proposal: T,
|
||||
proposal: SkillWorkshopReviewableProposal,
|
||||
): string[] {
|
||||
const key = skillWorkshopReviewKey(proposal);
|
||||
if (reviewedKeys.includes(key)) {
|
||||
@@ -2423,12 +2423,17 @@ export function renderApp(state: AppViewState) {
|
||||
<div class="nav-section__items">
|
||||
${group.tabs
|
||||
.filter((tab) => !isChildTab(tab))
|
||||
.flatMap((tab) => [
|
||||
renderTab(state, tab, { collapsed: navCollapsed }),
|
||||
...childTabsOf(tab).map((child) =>
|
||||
renderTab(state, child, { collapsed: navCollapsed, child: true }),
|
||||
),
|
||||
])}
|
||||
.flatMap((tab) => {
|
||||
const renderedTabs = [
|
||||
renderTab(state, tab, { collapsed: navCollapsed }),
|
||||
];
|
||||
for (const child of childTabsOf(tab)) {
|
||||
renderedTabs.push(
|
||||
renderTab(state, child, { collapsed: navCollapsed, child: true }),
|
||||
);
|
||||
}
|
||||
return renderedTabs;
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
@@ -2594,7 +2599,7 @@ export function renderApp(state: AppViewState) {
|
||||
onSettingsChange: (next) => state.applySettings(next),
|
||||
onPasswordChange: (next) => (state.password = next),
|
||||
onSessionKeyChange: (next) => {
|
||||
switchChatSession(state, next);
|
||||
void switchChatSession(state, next);
|
||||
},
|
||||
onToggleGatewayTokenVisibility: () => {
|
||||
state.overviewShowGatewayToken = !state.overviewShowGatewayToken;
|
||||
@@ -2803,7 +2808,7 @@ export function renderApp(state: AppViewState) {
|
||||
}
|
||||
}),
|
||||
onNavigateToChat: (sessionKey) => {
|
||||
switchChatSession(state, sessionKey);
|
||||
void switchChatSession(state, sessionKey);
|
||||
state.setTab("chat" as import("./navigation.ts").Tab);
|
||||
},
|
||||
onAddToWorkboard:
|
||||
@@ -2827,7 +2832,7 @@ export function renderApp(state: AppViewState) {
|
||||
checkpointId,
|
||||
);
|
||||
if (nextKey) {
|
||||
switchChatSession(state, nextKey);
|
||||
void switchChatSession(state, nextKey);
|
||||
state.setTab("chat" as import("./navigation.ts").Tab);
|
||||
}
|
||||
}),
|
||||
@@ -2852,7 +2857,7 @@ export function renderApp(state: AppViewState) {
|
||||
agentsList: state.agentsList,
|
||||
sessions: state.sessionsResult?.sessions ?? [],
|
||||
onOpenSession: (sessionKey) => {
|
||||
switchChatSession(state, sessionKey);
|
||||
void switchChatSession(state, sessionKey);
|
||||
state.setTab("chat" as import("./navigation.ts").Tab);
|
||||
},
|
||||
onRequestUpdate: requestHostUpdate,
|
||||
@@ -2986,7 +2991,7 @@ export function renderApp(state: AppViewState) {
|
||||
await loadCronRuns(state, state.cronRunsJobId);
|
||||
}),
|
||||
onNavigateToChat: (sessionKey) => {
|
||||
switchChatSession(state, sessionKey);
|
||||
void switchChatSession(state, sessionKey);
|
||||
state.setTab("chat" as import("./navigation.ts").Tab);
|
||||
},
|
||||
}),
|
||||
@@ -3384,8 +3389,10 @@ export function renderApp(state: AppViewState) {
|
||||
);
|
||||
const currentIndex = visibleProposals.findIndex((p) => p.key === selectedKey);
|
||||
const goto = (offset: number) => {
|
||||
if (visibleProposals.length === 0) return;
|
||||
const idx = currentIndex < 0 ? 0 : currentIndex;
|
||||
if (visibleProposals.length === 0) {
|
||||
return;
|
||||
}
|
||||
const idx = Math.max(0, currentIndex);
|
||||
const next = (idx + offset + visibleProposals.length) % visibleProposals.length;
|
||||
const proposal = visibleProposals[next];
|
||||
selectSkillWorkshopProposal(state, proposal.key);
|
||||
@@ -3583,7 +3590,7 @@ export function renderApp(state: AppViewState) {
|
||||
renderChat({
|
||||
sessionKey: state.sessionKey,
|
||||
onSessionKeyChange: (next) => {
|
||||
switchChatSession(state, next);
|
||||
void switchChatSession(state, next);
|
||||
},
|
||||
thinkingLevel: state.chatThinkingLevel,
|
||||
showThinking,
|
||||
@@ -3698,14 +3705,14 @@ export function renderApp(state: AppViewState) {
|
||||
currentAgentId: resolvedAgentId ?? "main",
|
||||
fullMessageAgentId: scopedAgentParamsForSession(state, state.sessionKey).agentId,
|
||||
onAgentChange: (agentId: string) => {
|
||||
switchChatSession(state, buildAgentMainSessionKey({ agentId }));
|
||||
void switchChatSession(state, buildAgentMainSessionKey({ agentId }));
|
||||
},
|
||||
onNavigateToAgent: () => {
|
||||
state.agentsSelectedId = resolvedAgentId;
|
||||
state.setTab("agents" as import("./navigation.ts").Tab);
|
||||
},
|
||||
onSessionSelect: (key: string) => {
|
||||
switchChatSession(state, key);
|
||||
void switchChatSession(state, key);
|
||||
},
|
||||
showNewMessages: state.chatNewMessagesBelow && !state.chatManualRefreshInFlight,
|
||||
onScrollToBottom: () => state.scrollToBottom(),
|
||||
@@ -3821,7 +3828,7 @@ export function renderApp(state: AppViewState) {
|
||||
onRefresh: refreshDreaming,
|
||||
onSelectAgent: (agentId: string) => {
|
||||
state.selectedAgentId = agentId;
|
||||
switchChatSession(state, resolvePreferredSessionForAgent(state, agentId));
|
||||
void switchChatSession(state, resolvePreferredSessionForAgent(state, agentId));
|
||||
void loadDreamingStatus(state);
|
||||
void loadDreamDiary(state);
|
||||
},
|
||||
|
||||
@@ -106,7 +106,10 @@ vi.mock("../tool-display.ts", () => ({
|
||||
icon: "zap",
|
||||
detail:
|
||||
args && typeof args === "object" && ("detail" in args || "action" in args)
|
||||
? String((args as { detail?: unknown; action?: unknown }).detail ?? args.action)
|
||||
? String(
|
||||
(args as { detail?: unknown; action?: unknown }).detail ??
|
||||
(args as { action?: unknown }).action,
|
||||
)
|
||||
: undefined,
|
||||
}),
|
||||
}));
|
||||
|
||||
@@ -467,13 +467,13 @@ export class OpenClawFilePreviewModal extends LitElement {
|
||||
}
|
||||
|
||||
private filterFiles(): FilePreviewModalFile[] {
|
||||
const query = this.query.trim().toLowerCase();
|
||||
if (!query) {
|
||||
const normalizedQuery = this.query.trim().toLowerCase();
|
||||
if (!normalizedQuery) {
|
||||
return this.files;
|
||||
}
|
||||
return this.files.filter((file) => {
|
||||
const haystack = `${file.path}\n${file.contents}`.toLowerCase();
|
||||
return haystack.includes(query);
|
||||
return haystack.includes(normalizedQuery);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -492,12 +492,12 @@ export class OpenClawFilePreviewModal extends LitElement {
|
||||
}
|
||||
|
||||
private handleQueryInput = (event: Event) => {
|
||||
const query = (event.target as HTMLInputElement).value ?? "";
|
||||
const nextQuery = (event.target as HTMLInputElement).value ?? "";
|
||||
this.dispatchEvent(
|
||||
new CustomEvent<string>("file-preview-query-change", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: query,
|
||||
detail: nextQuery,
|
||||
}),
|
||||
);
|
||||
};
|
||||
@@ -518,9 +518,7 @@ export class OpenClawFilePreviewModal extends LitElement {
|
||||
return;
|
||||
case "ArrowUp":
|
||||
this.moveSelection(-1, event);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export type ControlUiPublicAsset =
|
||||
|
||||
type WindowWithControlUiBasePath = Window &
|
||||
typeof globalThis & {
|
||||
__OPENCLAW_CONTROL_UI_BASE_PATH__?: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export function controlUiPublicAssetPath(
|
||||
@@ -40,7 +40,7 @@ function readConfiguredBasePath(): string | null {
|
||||
if (typeof window === "undefined") {
|
||||
return null;
|
||||
}
|
||||
const value = (window as WindowWithControlUiBasePath).__OPENCLAW_CONTROL_UI_BASE_PATH__;
|
||||
const value = (window as WindowWithControlUiBasePath)["__OPENCLAW_CONTROL_UI_BASE_PATH__"];
|
||||
return typeof value === "string" ? value : null;
|
||||
}
|
||||
|
||||
|
||||
@@ -2091,7 +2091,7 @@ describe("chat session controls", () => {
|
||||
]),
|
||||
);
|
||||
|
||||
switchChatSession(state, "agent:ops:main");
|
||||
void switchChatSession(state, "agent:ops:main");
|
||||
expect(state.chatSessionPickerResult).toBeNull();
|
||||
expect(state.chatSessionPickerAppliedQuery).toBe("");
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ describe("renderQuickSettings", () => {
|
||||
);
|
||||
|
||||
expect(container.querySelector(".qs-assistant-avatar")?.getAttribute("src")).toBe(
|
||||
"apple-touch-icon.png",
|
||||
"/apple-touch-icon.png",
|
||||
);
|
||||
expect(expectAssistantAvatarSource(container)).toEqual({
|
||||
label: "IDENTITY.md",
|
||||
|
||||
@@ -566,6 +566,11 @@ function resolveBoardEmptyState(props: SkillWorkshopProps): {
|
||||
body: "Skill Workshop proposals will appear here when your agent drafts them.",
|
||||
};
|
||||
}
|
||||
return {
|
||||
icon: "search",
|
||||
title: "No proposals here",
|
||||
body: "Skill Workshop proposals will appear here when your agent drafts them.",
|
||||
};
|
||||
}
|
||||
|
||||
function renderEmptyStateIcon(icon: SkillWorkshopEmptyIcon) {
|
||||
@@ -614,6 +619,7 @@ function renderEmptyStateIcon(icon: SkillWorkshopEmptyIcon) {
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
return nothing;
|
||||
}
|
||||
|
||||
function renderWorkshopEmptyState(props: SkillWorkshopProps) {
|
||||
|
||||
Reference in New Issue
Block a user