feat: support drag-and-drop .sql files into the app window
This commit is contained in:
parent
922971fdd3
commit
7d2c17559f
|
|
@ -1,5 +1,6 @@
|
|||
import { useI18n } from "vue-i18n";
|
||||
import { uuid } from "@/lib/utils";
|
||||
import { isTauriRuntime } from "@/lib/tauriRuntime";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useQueryStore } from "@/stores/queryStore";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
|
|
@ -15,6 +16,10 @@ function getDbType(path: string): "sqlite" | "duckdb" | null {
|
|||
return null;
|
||||
}
|
||||
|
||||
function isSqlFilePath(path: string): boolean {
|
||||
return /\.sql$/i.test(path);
|
||||
}
|
||||
|
||||
function getDataFileQuery(path: string): Promise<string | undefined> {
|
||||
return api.buildDroppedFilePreviewSql({ path });
|
||||
}
|
||||
|
|
@ -25,60 +30,108 @@ export function useFileDrop() {
|
|||
const queryStore = useQueryStore();
|
||||
const { toast } = useToast();
|
||||
|
||||
async function setupFileDrop() {
|
||||
const { getCurrentWebview } = await import("@tauri-apps/api/webview");
|
||||
const webview = getCurrentWebview();
|
||||
await webview.onDragDropEvent(async (event) => {
|
||||
if (event.payload.type !== "drop") return;
|
||||
for (const path of event.payload.paths) {
|
||||
const name = path.split("/").pop()?.split("\\").pop() || path;
|
||||
async function openDroppedSqlFile(name: string, content: string) {
|
||||
const connectionId = connectionStore.activeConnectionId || connectionStore.connections[0]?.id || "";
|
||||
const connection = connectionId ? connectionStore.getConfig(connectionId) : undefined;
|
||||
const database = connection?.database || "";
|
||||
const tabId = queryStore.createTab(connectionId, database, name, "query");
|
||||
queryStore.updateSql(tabId, content);
|
||||
toast(t("welcome.fileOpened", { name }));
|
||||
}
|
||||
|
||||
const dataQuery = await getDataFileQuery(path);
|
||||
if (dataQuery) {
|
||||
async function setupFileDrop() {
|
||||
if (isTauriRuntime()) {
|
||||
const { getCurrentWebview } = await import("@tauri-apps/api/webview");
|
||||
const webview = getCurrentWebview();
|
||||
await webview.onDragDropEvent(async (event) => {
|
||||
if (event.payload.type !== "drop") return;
|
||||
for (const path of event.payload.paths) {
|
||||
const name = path.split("/").pop()?.split("\\").pop() || path;
|
||||
|
||||
const dataQuery = await getDataFileQuery(path);
|
||||
if (dataQuery) {
|
||||
const config: ConnectionConfig = {
|
||||
id: uuid(),
|
||||
name: `[Preview] ${name}`,
|
||||
db_type: "duckdb",
|
||||
driver_profile: "duckdb",
|
||||
driver_label: "DuckDB",
|
||||
url_params: "",
|
||||
host: ":memory:",
|
||||
port: 0,
|
||||
username: "",
|
||||
password: "",
|
||||
};
|
||||
const connectionId = await api.connectDb(config);
|
||||
connectionStore.addEphemeralConnection({ ...config, id: connectionId });
|
||||
const tabId = queryStore.createTab(connectionId, "", name, "query");
|
||||
queryStore.updateSql(tabId, dataQuery);
|
||||
queryStore.executeCurrentTab();
|
||||
toast(t("welcome.fileOpened", { name }));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isSqlFilePath(path)) {
|
||||
try {
|
||||
const content = await api.readExternalSqlFile(path);
|
||||
await openDroppedSqlFile(name, content);
|
||||
} catch (e: any) {
|
||||
toast(t("toolbar.sqlOpenFailed", { message: e?.message || String(e) }), 5000);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const dbType = getDbType(path);
|
||||
if (!dbType) continue;
|
||||
const config: ConnectionConfig = {
|
||||
id: uuid(),
|
||||
name: `[Preview] ${name}`,
|
||||
db_type: "duckdb",
|
||||
driver_profile: "duckdb",
|
||||
driver_label: "DuckDB",
|
||||
name,
|
||||
db_type: dbType,
|
||||
driver_profile: dbType,
|
||||
driver_label: dbType === "duckdb" ? "DuckDB" : "SQLite",
|
||||
url_params: "",
|
||||
host: ":memory:",
|
||||
host: path,
|
||||
port: 0,
|
||||
username: "",
|
||||
password: "",
|
||||
};
|
||||
const connectionId = await api.connectDb(config);
|
||||
connectionStore.addEphemeralConnection({ ...config, id: connectionId });
|
||||
const tabId = queryStore.createTab(connectionId, "", name, "query");
|
||||
queryStore.updateSql(tabId, dataQuery);
|
||||
queryStore.executeCurrentTab();
|
||||
toast(t("welcome.fileOpened", { name }));
|
||||
continue;
|
||||
try {
|
||||
await connectionStore.addConnection(config);
|
||||
void connectionStore.connect(config);
|
||||
toast(t("welcome.fileOpened", { name }));
|
||||
} catch (e: any) {
|
||||
toast(t("connection.saveFailed", { message: e?.message || String(e) }), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
const dbType = getDbType(path);
|
||||
if (!dbType) continue;
|
||||
const config: ConnectionConfig = {
|
||||
id: uuid(),
|
||||
name,
|
||||
db_type: dbType,
|
||||
driver_profile: dbType,
|
||||
driver_label: dbType === "duckdb" ? "DuckDB" : "SQLite",
|
||||
url_params: "",
|
||||
host: path,
|
||||
port: 0,
|
||||
username: "",
|
||||
password: "",
|
||||
};
|
||||
try {
|
||||
await connectionStore.addConnection(config);
|
||||
void connectionStore.connect(config);
|
||||
toast(t("welcome.fileOpened", { name }));
|
||||
} catch (e: any) {
|
||||
toast(t("connection.saveFailed", { message: e?.message || String(e) }), 5000);
|
||||
});
|
||||
} else {
|
||||
document.addEventListener("drop", (event: DragEvent) => {
|
||||
const files = event.dataTransfer?.files;
|
||||
if (!files || files.length === 0) return;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
if (!isSqlFilePath(file.name)) continue;
|
||||
event.preventDefault();
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
if (typeof reader.result === "string") {
|
||||
void openDroppedSqlFile(file.name, reader.result);
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
document.addEventListener("dragover", (event: DragEvent) => {
|
||||
const files = event.dataTransfer?.files;
|
||||
if (!files || files.length === 0) return;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
if (isSqlFilePath(files[i].name)) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return { setupFileDrop };
|
||||
|
|
|
|||
Loading…
Reference in New Issue