diff --git a/apps/desktop/src/components/layout/SqlLibraryPanel.vue b/apps/desktop/src/components/layout/SqlLibraryPanel.vue index 22efbae43f..f63a128d24 100644 --- a/apps/desktop/src/components/layout/SqlLibraryPanel.vue +++ b/apps/desktop/src/components/layout/SqlLibraryPanel.vue @@ -313,8 +313,13 @@ async function openSqlStorageDirectory() { return; } + const syncDir = settingsStore.desktopSettings.saved_sql_sync_dir?.trim(); + if (!syncDir) { + toast(t("sqlLibrary.noSyncDirectory"), 3000); + return; + } try { - await api.openSavedSqlStorageDir(settingsStore.desktopSettings.saved_sql_sync_dir || undefined); + await api.openSavedSqlStorageDir(syncDir); } catch (e: any) { toast(t("sqlLibrary.openDirectoryFailed", { message: e?.message || String(e) }), 5000); } diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index 3241b335e4..3cf66e4b41 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -122,6 +122,7 @@ export default { syncDirectoryDisabled: "SQL local sync disabled", syncDirectoryFailed: "Failed to set sync directory: {message}", openDirectoryFailed: "Failed to open directory: {message}", + noSyncDirectory: "Please set a local sync directory first", exported: "Exported", exportFailed: "Export failed: {message}", importFailed: "Import failed: {message}", diff --git a/apps/desktop/src/i18n/locales/es.ts b/apps/desktop/src/i18n/locales/es.ts index 740fd4f1d5..bc8395d8c7 100644 --- a/apps/desktop/src/i18n/locales/es.ts +++ b/apps/desktop/src/i18n/locales/es.ts @@ -122,6 +122,7 @@ export default { syncDirectoryDisabled: "Sincronización local de SQL desactivada", syncDirectoryFailed: "Error al definir el directorio de sincronización: {message}", openDirectoryFailed: "Error al abrir el directorio: {message}", + noSyncDirectory: "Primero defina un directorio de sincronización local", exported: "Exportado", exportFailed: "Error al exportar: {message}", importFailed: "Error al importar: {message}", diff --git a/apps/desktop/src/i18n/locales/it.ts b/apps/desktop/src/i18n/locales/it.ts index 37598a8dd8..e41abdb60b 100644 --- a/apps/desktop/src/i18n/locales/it.ts +++ b/apps/desktop/src/i18n/locales/it.ts @@ -122,6 +122,7 @@ export default { syncDirectoryDisabled: "Sincronizzazione locale SQL disattivata", syncDirectoryFailed: "Impossibile impostare la directory di sincronizzazione: {message}", openDirectoryFailed: "Impossibile aprire la directory: {message}", + noSyncDirectory: "Imposta prima una directory di sincronizzazione locale", exported: "Esportato", exportFailed: "Esportazione non riuscita: {message}", importFailed: "Importazione non riuscita: {message}", diff --git a/apps/desktop/src/i18n/locales/pt-BR.ts b/apps/desktop/src/i18n/locales/pt-BR.ts index decdc791a3..a1c9259b7b 100644 --- a/apps/desktop/src/i18n/locales/pt-BR.ts +++ b/apps/desktop/src/i18n/locales/pt-BR.ts @@ -122,6 +122,7 @@ export default { syncDirectoryDisabled: "Sincronização local de SQL desativada", syncDirectoryFailed: "Falha ao definir diretório de sincronização: {message}", openDirectoryFailed: "Falha ao abrir diretório: {message}", + noSyncDirectory: "Defina um diretório de sincronização local primeiro", exported: "Exportado", exportFailed: "Falha na exportação: {message}", importFailed: "Falha na importação: {message}", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index f6c7c69f18..9594198089 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -121,6 +121,7 @@ export default { syncDirectoryDisabled: "SQL 本地同步已关闭", syncDirectoryFailed: "设置同步目录失败:{message}", openDirectoryFailed: "打开目录失败:{message}", + noSyncDirectory: "请先设置本地同步目录", exported: "导出完成", exportedCount: "已导入 {count} 个 SQL 文件", exportFailed: "导出失败:{message}", diff --git a/apps/desktop/src/i18n/locales/zh-TW.ts b/apps/desktop/src/i18n/locales/zh-TW.ts index ff6e4f3b53..2a764c33f3 100644 --- a/apps/desktop/src/i18n/locales/zh-TW.ts +++ b/apps/desktop/src/i18n/locales/zh-TW.ts @@ -121,6 +121,7 @@ export default { syncDirectoryDisabled: "SQL 本機同步已關閉", syncDirectoryFailed: "設定同步目錄失敗:{message}", openDirectoryFailed: "開啟目錄失敗:{message}", + noSyncDirectory: "請先設定本機同步目錄", exported: "匯出完成", exportFailed: "匯出失敗:{message}", importFailed: "匯入失敗:{message}", diff --git a/src-tauri/src/commands/saved_sql.rs b/src-tauri/src/commands/saved_sql.rs index f0725596a0..a90a2afb96 100644 --- a/src-tauri/src/commands/saved_sql.rs +++ b/src-tauri/src/commands/saved_sql.rs @@ -95,12 +95,13 @@ pub async fn sync_saved_sql_directory(request: SavedSqlSyncRequest) -> Result<() } fn sync_saved_sql_directory_blocking(target_dir: &Path, entries: &[SavedSqlSyncEntry]) -> Result<(), String> { - std::fs::create_dir_all(target_dir).map_err(|e| e.to_string())?; - remove_previous_sync_files(target_dir)?; + let sync_root = target_dir.join("dbx-sql-library"); + std::fs::create_dir_all(&sync_root).map_err(|e| e.to_string())?; + remove_previous_sync_files(&sync_root)?; let mut written_files = Vec::new(); for entry in entries { - let mut file_dir = target_dir.to_path_buf(); + let mut file_dir = sync_root.to_path_buf(); if let Some(folder_name) = entry.folder_name.as_deref().map(str::trim).filter(|name| !name.is_empty()) { file_dir.push(sanitize_file_segment(folder_name)); } @@ -109,14 +110,14 @@ fn sync_saved_sql_directory_blocking(target_dir: &Path, entries: &[SavedSqlSyncE let file_name = ensure_sql_extension(&sanitize_file_segment(&entry.file_name)); let file_path = unique_file_path(&file_dir, &file_name); std::fs::write(&file_path, &entry.sql).map_err(|e| e.to_string())?; - if let Ok(relative) = file_path.strip_prefix(target_dir) { + if let Ok(relative) = file_path.strip_prefix(&sync_root) { written_files.push(relative.to_string_lossy().replace('\\', "/")); } } let manifest = SavedSqlSyncManifest { files: written_files }; let manifest_json = serde_json::to_string_pretty(&manifest).map_err(|e| e.to_string())?; - std::fs::write(target_dir.join(SYNC_MANIFEST_FILE), manifest_json).map_err(|e| e.to_string())?; + std::fs::write(sync_root.join(SYNC_MANIFEST_FILE), manifest_json).map_err(|e| e.to_string())?; Ok(()) }