From 18289b60c873faef61a6550dae5660c6bdbbb627 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 21 Sep 2026 10:27:47 +0800 Subject: [PATCH] fix: some open err --- packages/web-proxy/src/credentials.ts | 14 +++++++++++--- ui/composables/useAiPanel.test.ts | 4 ++-- ui/composables/useAiPanel.ts | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/web-proxy/src/credentials.ts b/packages/web-proxy/src/credentials.ts index 017a6175f..6bfbf0d9f 100644 --- a/packages/web-proxy/src/credentials.ts +++ b/packages/web-proxy/src/credentials.ts @@ -358,7 +358,7 @@ export function buildAutofillScript(selectors, credentials) { successSelector: selectors.success, interactiveSelector: selectors.interactive }; - return `(() => { + return `(async () => { ${selectorLookupScript} ${submitElementScript} let payload = ${JSON.stringify(payload)}; @@ -411,9 +411,17 @@ if (successObserver) { } // The main process decides whether a visible verification area must precede submission. if (payload.interactiveSelector) return true; -internalAction = true; try { - return submitElement(submit); + // Input handlers may schedule a framework render that replaces or enables the + // submit button. Let that update finish, then resolve the current DOM node. + await new Promise(resolve => setTimeout(resolve, 0)); + const currentSubmit = findElement(payload.submitSelector); + if (!(currentSubmit instanceof HTMLElement) || !currentSubmit.isConnected || currentSubmit.disabled) { + throw new Error("登录提交按钮不可用,请检查提交元素配置或页面是否需要验证"); + } + internalAction = true; + if (!submitElement(currentSubmit)) throw new Error("登录表单校验未通过,请检查必填项或验证码配置"); + return true; } finally { internalAction = false; if (!payload.successSelector && !payload.interactiveSelector) cleanup(); diff --git a/ui/composables/useAiPanel.test.ts b/ui/composables/useAiPanel.test.ts index ff561d9c3..fcd69e800 100644 --- a/ui/composables/useAiPanel.test.ts +++ b/ui/composables/useAiPanel.test.ts @@ -47,9 +47,9 @@ describe("AI overlay panel", () => { afterAll(() => vi.unstubAllGlobals()); - it("defaults to open on desktop and remembers visibility across tabs and consumers", () => { + it("defaults to closed on desktop and remembers visibility across tabs and consumers", () => { const panel = useAiPanel(); - expect(useLocalStorage).toHaveBeenCalledWith("jumpserver-client:ai-panel-open", true, { writeDefaults: false }); + expect(useLocalStorage).toHaveBeenCalledWith("jumpserver-client:ai-panel-open", false, { writeDefaults: false }); panel.openAi(); expect(panel.open.value).toBe(true); diff --git a/ui/composables/useAiPanel.ts b/ui/composables/useAiPanel.ts index 067cce903..99793997a 100644 --- a/ui/composables/useAiPanel.ts +++ b/ui/composables/useAiPanel.ts @@ -16,7 +16,7 @@ interface UnifiedAiPanelContext { } const usePanelPreferences = createGlobalState(() => { - const preferredOpen = useLocalStorage("jumpserver-client:ai-panel-open", true, { writeDefaults: false }); + const preferredOpen = useLocalStorage("jumpserver-client:ai-panel-open", false, { writeDefaults: false }); const storedWidth = useLocalStorage("jumpserver-client:ai-panel-width", AI_PANEL_DEFAULT_WIDTH, { writeDefaults: false });