fix(ui): close provider panels when navigating away from the app page

The add / edit / usage-script panels now only cover the content area, so
the sidebar stays clickable while one is open. Their appId followed
activeApp, so switching apps with the edit panel open saved the Claude
provider into Codex. Close the three panels from selectApp / openPage /
openSettings.
This commit is contained in:
Jason committed 2026-10-03 23:28:59 +08:00
1 parent a39af812e1
commit 20c4ff86c6
2 files changed
+58

No files matched your search

+11
View File
@@ -571,8 +571,17 @@ function App() {
// ─── 导航 ───────────────────────────────────────────────────────────────
// MCP / Skills / 提示词在进行中的操作会锁住导航(卸载面板会丢掉进行中的状态)
// 添加 / 编辑 / 用量脚本面板只盖住内容区,侧栏还能点。离开当前页就把它们关掉:
// 面板的 appId 跟着 activeApp 走,开着切应用会把 A 应用的供应商保存进 B 应用
const closeProviderPanels = () => {
setIsAddOpen(false);
setEditingProvider(null);
setUsageProvider(null);
};
const openSettings = (section: SettingsSection = "general") => {
if (managementBusyRef.current) return;
closeProviderPanels();
if (currentViewRef.current !== "settings") {
settingsReturnViewRef.current = currentViewRef.current;
}
@@ -586,6 +595,7 @@ function App() {
const selectApp = (app: AppId) => {
if (managementBusyRef.current) return;
closeProviderPanels();
setActiveApp(app);
localStorage.setItem(APP_STORAGE_KEY, app);
setCurrentView("providers");
@@ -597,6 +607,7 @@ function App() {
return;
}
if (managementBusyRef.current) return;
closeProviderPanels();
if (page === "prompts" && currentViewRef.current !== "prompts") {
// 提示词页默认选中侧栏里最后选的那个应用
setPromptsApp(
+47
View File
@@ -141,6 +141,11 @@ vi.mock("@/contexts/UpdateContext", () => ({
useUpdate: () => ({ hasUpdate: false, updateInfo: null }),
}));
// 设置页要 ThemeProvider,这里只看导航进去时发生了什么
vi.mock("@/components/settings/SettingsPage", () => ({
SettingsPage: () => <div data-testid="settings-page" />,
}));
vi.mock("@/components/skills/UnifiedSkillsPanel", () => ({
// v7:Skills 的页头(添加 / 检查更新 / 存储与同步)在面板自己里面
default: ({ initialView }: { initialView?: string }) => {
@@ -283,6 +288,48 @@ describe("App integration with MSW", () => {
expect(providerScrollContainer()!.scrollLeft).toBe(0);
}, 10_000);
it("closes provider panels when navigating away from the app page", async () => {
const { default: App } = await import("@/App");
renderApp(App);
await waitFor(() =>
expect(screen.getByTestId("provider-list").textContent).toContain(
"claude-1",
),
);
// 面板只盖住内容区,侧栏还能点:切应用时编辑面板必须关掉,否则 Claude 的
// 供应商会以 appId=codex 保存进 Codex
fireEvent.click(screen.getByText("edit"));
expect(screen.getByTestId("edit-provider-dialog")).toBeInTheDocument();
fireEvent.click(sidebarApp("Codex"));
await waitFor(() =>
expect(screen.getByTestId("provider-list").textContent).toContain(
"codex-1",
),
);
expect(screen.queryByTestId("edit-provider-dialog")).not.toBeInTheDocument();
fireEvent.click(screen.getByText("usage"));
expect(screen.getByTestId("usage-modal")).toBeInTheDocument();
fireEvent.click(sidebarApp("nav.usage"));
await waitFor(() =>
expect(screen.queryByTestId("usage-modal")).not.toBeInTheDocument(),
);
fireEvent.click(sidebarApp("Codex"));
await waitFor(() =>
expect(screen.getByTestId("provider-list").textContent).toContain(
"codex-1",
),
);
fireEvent.click(screen.getByText("create"));
expect(screen.getByTestId("add-provider-dialog")).toBeInTheDocument();
fireEvent.keyDown(window, { key: ",", metaKey: true });
expect(await screen.findByTestId("settings-page")).toBeInTheDocument();
expect(screen.queryByTestId("add-provider-dialog")).not.toBeInTheDocument();
}, 10_000);
it("shows toast when auto sync fails in background", async () => {
const { default: App } = await import("@/App");
renderApp(App);