From 6e7b62b58e0765cdc1f0c6ff0dfb7542d6e5a957 Mon Sep 17 00:00:00 2001 From: lxk955 <164191365+lxk955@users.noreply.github.com> Date: Mon, 19 Oct 2026 02:52:33 +0800 Subject: [PATCH] fix(sql-file): toast completion and close dialog on success --- .../SqlFileExecutionDialog.retry.spec.ts | 50 +++++++++++++++++++ .../sql-file/SqlFileExecutionDialog.vue | 25 +++++++++- apps/desktop/src/i18n/locales/az.ts | 2 + apps/desktop/src/i18n/locales/en.ts | 2 + apps/desktop/src/i18n/locales/es.ts | 2 + apps/desktop/src/i18n/locales/id.ts | 2 + apps/desktop/src/i18n/locales/it.ts | 2 + apps/desktop/src/i18n/locales/ja.ts | 2 + apps/desktop/src/i18n/locales/ko.ts | 2 + apps/desktop/src/i18n/locales/pt-BR.ts | 2 + apps/desktop/src/i18n/locales/ru.ts | 2 + apps/desktop/src/i18n/locales/th.ts | 2 + apps/desktop/src/i18n/locales/tr.ts | 2 + apps/desktop/src/i18n/locales/zh-CN.ts | 2 + apps/desktop/src/i18n/locales/zh-TW.ts | 2 + 15 files changed, 99 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/components/sql-file/SqlFileExecutionDialog.retry.spec.ts b/apps/desktop/src/components/sql-file/SqlFileExecutionDialog.retry.spec.ts index 017fd2ce2b..1b1135888c 100644 --- a/apps/desktop/src/components/sql-file/SqlFileExecutionDialog.retry.spec.ts +++ b/apps/desktop/src/components/sql-file/SqlFileExecutionDialog.retry.spec.ts @@ -1167,3 +1167,53 @@ describe("SqlFileExecutionDialog target preservation (#4844)", () => { await vi.waitFor(() => expect(mocks.executeSqlFiles).toHaveBeenCalledWith(expect.objectContaining({ connectionId: "mysql-1", database: "chosen_db" }), ["/tmp/brand_new.sql"])); }); }); + +describe("SqlFileExecutionDialog completion prompt and close (#12608)", () => { + it("toasts success and closes dialog upon successful completion", async () => { + const onOpenChange = vi.fn(); + await mountReadyDialog(onOpenChange); + + mocks.executeSqlFiles.mockImplementationOnce(async (request) => { + mocks.progressHandler?.(progress(request.executionId, "done", { statementIndex: 1, successCount: 1, failureCount: 0 })); + }); + + findButton("sqlFile.execute").click(); + + await vi.waitFor(() => expect(mocks.toast).toHaveBeenCalledWith("sqlFile.executeSuccess", 3000)); + expect(onOpenChange).toHaveBeenCalledWith(false); + }); + + it("toasts warning and keeps dialog open when execution has statement failures", async () => { + const onOpenChange = vi.fn(); + await mountReadyDialog(onOpenChange); + + mocks.executeSqlFiles.mockImplementationOnce(async (request) => { + mocks.progressHandler?.(progress(request.executionId, "done", { statementIndex: 2, successCount: 1, failureCount: 1 })); + }); + + findButton("sqlFile.execute").click(); + + await vi.waitFor(() => expect(mocks.toast).toHaveBeenCalledWith("sqlFile.completedWithErrors", 5000)); + expect(onOpenChange).not.toHaveBeenCalled(); + }); + + it("toasts success and closes dialog upon manual transaction commit", async () => { + const onOpenChange = vi.fn(); + await mountReadyDialog(onOpenChange); + const label = Array.from(root!.querySelectorAll("label")).find((item) => item.textContent?.includes("toolbar.manualTransaction")); + label!.querySelector('input[type="checkbox"]')!.click(); + await nextTick(); + + mocks.executeSqlFiles.mockImplementationOnce(async (request: { executionId: string }) => { + mocks.progressHandler?.(progress(request.executionId, "done", { statementIndex: 1, successCount: 1, failureCount: 0 })); + }); + findButton("sqlFile.execute").click(); + + await vi.waitFor(() => expect(findButton("toolbar.commit").disabled).toBe(false)); + expect(onOpenChange).not.toHaveBeenCalled(); + + findButton("toolbar.commit").click(); + await vi.waitFor(() => expect(mocks.toast).toHaveBeenCalledWith("sqlFile.executeSuccess", 3000)); + expect(onOpenChange).toHaveBeenCalledWith(false); + }); +}); diff --git a/apps/desktop/src/components/sql-file/SqlFileExecutionDialog.vue b/apps/desktop/src/components/sql-file/SqlFileExecutionDialog.vue index 87e77705de..0c54528c90 100644 --- a/apps/desktop/src/components/sql-file/SqlFileExecutionDialog.vue +++ b/apps/desktop/src/components/sql-file/SqlFileExecutionDialog.vue @@ -252,6 +252,15 @@ async function finishTransaction(commit: boolean) { if (progress.value) updateSqlFileTask(executionId.value, { ...progress.value, status: terminalStatus.value }); } await refreshTargetAfterImport(sqlFileExecutionTarget()); + if (committed && !outcomeUnknown) { + const failureCount = progress.value?.failureCount ?? 0; + if (failureCount > 0) { + toast(t("sqlFile.completedWithErrors", { succeeded: progress.value?.successCount ?? 0, failed: failureCount }), 5000); + } else { + toast(t("sqlFile.executeSuccess"), 3000); + open.value = false; + } + } return true; } catch (error: any) { toast(error?.message || String(error), 5000); @@ -751,6 +760,7 @@ async function startExecution() { const taskLabel = previews.value.length === 1 ? previews.value[0]!.fileName : `${previews.value[0]!.fileName} (+${previews.value.length - 1})`; activeExecutionTask.value = addSqlFileTask(batchId, taskLabel, filePathDisplay.value); let completedSuccessfully = false; + let terminal: SqlFileProgress | null = null; try { await store.ensureConnected(connectionId.value); @@ -848,7 +858,8 @@ async function startExecution() { }, executionPaths, ); - const terminal = await terminalProgress; + terminal = await terminalProgress; + progress.value = terminal; if (terminal.status === "error") { throw new Error(terminal.error || "SQL file execution failed"); } @@ -873,7 +884,17 @@ async function startExecution() { } } } - if (!txnSessionId.value) await refreshTargetAfterImport(target); + if (!txnSessionId.value) { + await refreshTargetAfterImport(target); + const finalProgress = terminal ?? progress.value; + const failureCount = finalProgress?.failureCount ?? 0; + if (failureCount > 0) { + toast(t("sqlFile.completedWithErrors", { succeeded: finalProgress?.successCount ?? 0, failed: failureCount }), 5000); + } else { + toast(t("sqlFile.executeSuccess"), 3000); + open.value = false; + } + } } } catch (e: any) { terminalStatus.value = cancelRequested.value ? "cancelled" : "error"; diff --git a/apps/desktop/src/i18n/locales/az.ts b/apps/desktop/src/i18n/locales/az.ts index eea4f47dbf..8721797500 100644 --- a/apps/desktop/src/i18n/locales/az.ts +++ b/apps/desktop/src/i18n/locales/az.ts @@ -6827,6 +6827,8 @@ export default withEnglishFallback({ fileProgress: "Fayl {current} / {total}", fileColumn: "Fayl", totalFiles: "{count} fayl", + executeSuccess: "SQL faylı uğurla icra edildi", + completedWithErrors: "İcra tamamlandı: {succeeded} uğurlu, {failed} uğursuz", }, sqlFileTree: { folderNameInvalid: "Yol deyil, tək qovluq adı daxil edin.", diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index fab163babd..dccf46e782 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -8186,6 +8186,8 @@ export default { }, fileColumn: "File", totalFiles: "{count} files", + executeSuccess: "SQL file executed successfully", + completedWithErrors: "Execution completed: {succeeded} succeeded, {failed} failed", }, sqlFileTree: { folderNameInvalid: "Enter a single folder name, not a path.", diff --git a/apps/desktop/src/i18n/locales/es.ts b/apps/desktop/src/i18n/locales/es.ts index bfaf9a37d8..d8ca930869 100644 --- a/apps/desktop/src/i18n/locales/es.ts +++ b/apps/desktop/src/i18n/locales/es.ts @@ -7400,6 +7400,8 @@ export default withEnglishFallback({ }, fileColumn: "Archivo", totalFiles: "{count} archivos", + executeSuccess: "Archivo SQL ejecutado con éxito", + completedWithErrors: "Ejecución completada: {succeeded} correctos, {failed} fallidos", }, diff: { progress: { diff --git a/apps/desktop/src/i18n/locales/id.ts b/apps/desktop/src/i18n/locales/id.ts index 47d55b3fa6..34be656981 100644 --- a/apps/desktop/src/i18n/locales/id.ts +++ b/apps/desktop/src/i18n/locales/id.ts @@ -7526,6 +7526,8 @@ export default withEnglishFallback({ }, fileColumn: "File", totalFiles: "{count} file", + executeSuccess: "File SQL berhasil dijalankan", + completedWithErrors: "Eksekusi selesai: {succeeded} berhasil, {failed} gagal", }, sqlFileTree: { folderNameInvalid: "Masukkan satu nama folder, bukan jalur.", diff --git a/apps/desktop/src/i18n/locales/it.ts b/apps/desktop/src/i18n/locales/it.ts index 41685e0eea..0d7a7e7beb 100644 --- a/apps/desktop/src/i18n/locales/it.ts +++ b/apps/desktop/src/i18n/locales/it.ts @@ -7184,6 +7184,8 @@ export default withEnglishFallback({ fileProgress: "File {current} di {total}", fileColumn: "File", totalFiles: "{count} file", + executeSuccess: "File SQL eseguito con successo", + completedWithErrors: "Esecuzione completata: {succeeded} riusciti, {failed} non riusciti", }, diff: { progress: { diff --git a/apps/desktop/src/i18n/locales/ja.ts b/apps/desktop/src/i18n/locales/ja.ts index 74dd8c5be9..5af5024cb6 100644 --- a/apps/desktop/src/i18n/locales/ja.ts +++ b/apps/desktop/src/i18n/locales/ja.ts @@ -7212,6 +7212,8 @@ export default withEnglishFallback({ fileProgress: "ファイル {current}/{total}", fileColumn: "ファイル", totalFiles: "{count} ファイル", + executeSuccess: "SQLファイルを実行しました", + completedWithErrors: "実行が完了しました: 成功 {succeeded} 件、失敗 {failed} 件", }, diff: { progress: { diff --git a/apps/desktop/src/i18n/locales/ko.ts b/apps/desktop/src/i18n/locales/ko.ts index bcf61cd90b..6cd115a764 100644 --- a/apps/desktop/src/i18n/locales/ko.ts +++ b/apps/desktop/src/i18n/locales/ko.ts @@ -6987,6 +6987,8 @@ export default withEnglishFallback({ fileProgress: "파일 {current}/{total}", fileColumn: "파일", totalFiles: "{count}개 파일", + executeSuccess: "SQL 파일을 실행했습니다", + completedWithErrors: "실행 완료: 성공 {succeeded}개, 실패 {failed}개", }, sqlFileTree: { folderNameInvalid: "경로가 아닌 폴더 이름 하나를 입력하세요.", diff --git a/apps/desktop/src/i18n/locales/pt-BR.ts b/apps/desktop/src/i18n/locales/pt-BR.ts index d99ee86f75..d69b6fe7c9 100644 --- a/apps/desktop/src/i18n/locales/pt-BR.ts +++ b/apps/desktop/src/i18n/locales/pt-BR.ts @@ -7183,6 +7183,8 @@ export default withEnglishFallback({ fileProgress: "Arquivo {current} de {total}", fileColumn: "Arquivo", totalFiles: "{count} arquivos", + executeSuccess: "Arquivo SQL executado com sucesso", + completedWithErrors: "Execução concluída: {succeeded} com sucesso, {failed} com falha", }, diff: { progress: { diff --git a/apps/desktop/src/i18n/locales/ru.ts b/apps/desktop/src/i18n/locales/ru.ts index 666e84ed49..f2b1f905c7 100644 --- a/apps/desktop/src/i18n/locales/ru.ts +++ b/apps/desktop/src/i18n/locales/ru.ts @@ -8433,6 +8433,8 @@ export default withEnglishFallback({ }, fileColumn: "Файл", totalFiles: "{count} файлов", + executeSuccess: "SQL-файл успешно выполнен", + completedWithErrors: "Выполнение завершено: успешно {succeeded}, с ошибкой {failed}", }, sqlFileTree: { folderNameInvalid: "Введите одно имя папки, а не путь.", diff --git a/apps/desktop/src/i18n/locales/th.ts b/apps/desktop/src/i18n/locales/th.ts index a41b1b46ea..4663d41ecf 100644 --- a/apps/desktop/src/i18n/locales/th.ts +++ b/apps/desktop/src/i18n/locales/th.ts @@ -8842,6 +8842,8 @@ export default withEnglishFallback({ }, fileColumn: "ไฟล์", totalFiles: "ไฟล์ {count} ไฟล์", + executeSuccess: "เรียกใช้ไฟล์ SQL สำเร็จแล้ว", + completedWithErrors: "การเรียกใช้เสร็จสิ้น: สำเร็จ {succeeded}, ล้มเหลว {failed}", }, sqlFileTree: { locateActiveFile: "ค้นหาตำแหน่งไฟล์ปัจจุบัน", diff --git a/apps/desktop/src/i18n/locales/tr.ts b/apps/desktop/src/i18n/locales/tr.ts index 195ea54731..99943daf03 100644 --- a/apps/desktop/src/i18n/locales/tr.ts +++ b/apps/desktop/src/i18n/locales/tr.ts @@ -6708,6 +6708,8 @@ export default withEnglishFallback({ fileProgress: "Dosya {current} / {total}", fileColumn: "Dosya", totalFiles: "{count} dosya", + executeSuccess: "SQL dosyası başarıyla çalıştırıldı", + completedWithErrors: "Çalıştırma tamamlandı: {succeeded} başarılı, {failed} başarısız", }, sqlFileTree: { folderNameInvalid: "Yol yerine tek bir klasör adı girin.", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index d53a50b266..8071a66cc5 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -8168,6 +8168,8 @@ export default withEnglishFallback({ }, fileColumn: "文件", totalFiles: "{count} 个文件", + executeSuccess: "SQL 文件执行成功", + completedWithErrors: "执行完成:成功 {succeeded} 条,失败 {failed} 条", }, sqlFileTree: { folderNameInvalid: "请输入单个文件夹名称,不能包含路径。", diff --git a/apps/desktop/src/i18n/locales/zh-TW.ts b/apps/desktop/src/i18n/locales/zh-TW.ts index 8fb934b66f..8463c967b0 100644 --- a/apps/desktop/src/i18n/locales/zh-TW.ts +++ b/apps/desktop/src/i18n/locales/zh-TW.ts @@ -6531,6 +6531,8 @@ export default withEnglishFallback({ }, fileColumn: "檔案", totalFiles: "{count} 個檔案", + executeSuccess: "SQL 檔案執行成功", + completedWithErrors: "執行完成:成功 {succeeded} 條,失敗 {failed} 條", runInBackground: "背景執行", }, diff: {