feat(mongodb): add Compass-style collection import/export
This commit is contained in:
1 parent
bf4874906c
commit
8ff56b4837
47 files changed
+5626
-52
No files matched your search
@@ -391,21 +391,22 @@ watch(
|
||||
{ flush: "post" },
|
||||
);
|
||||
|
||||
const { copyStructureAs, copyStructureDocText, copyStructurePreview, exportData, exportDataXlsx, exportStructure, saveStructurePreview, selectTextareaContent } = useSidebarTreeExportRuntime({
|
||||
const { copyStructureAs, copyStructureDocText, copyStructurePreview, exportData, exportDataXlsx, exportMongoCollection, exportStructure, saveStructurePreview, selectTextareaContent } = useSidebarTreeExportRuntime({
|
||||
activeNode,
|
||||
connectionStore,
|
||||
settingsStore,
|
||||
acceptedSelectionIds: () => acceptedSelectionIds,
|
||||
});
|
||||
|
||||
const { openAllDatabasesExport, openDataCompare, openDatabaseExport, openDatabaseSearch, openDiagram, openDocs, openFieldLineage, openScheduledBackups, openSchemaDiff, openSchemaDiffForRoutine, openSqlFileExecution, openStructureEditor, openTableImport, openTransfer } = useSidebarTreeToolRuntime({
|
||||
activeNode,
|
||||
connectionStore,
|
||||
queryStore,
|
||||
settingsStore,
|
||||
tableChildObjectName: tableChildDropObjectName,
|
||||
acceptedSelectionIds: () => acceptedSelectionIds,
|
||||
});
|
||||
const { openAllDatabasesExport, openDataCompare, openDatabaseExport, openDatabaseSearch, openDiagram, openDocs, openFieldLineage, openMongoImport, openScheduledBackups, openSchemaDiff, openSchemaDiffForRoutine, openSqlFileExecution, openStructureEditor, openTableImport, openTransfer } =
|
||||
useSidebarTreeToolRuntime({
|
||||
activeNode,
|
||||
connectionStore,
|
||||
queryStore,
|
||||
settingsStore,
|
||||
tableChildObjectName: tableChildDropObjectName,
|
||||
acceptedSelectionIds: () => acceptedSelectionIds,
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
"rename-started": [];
|
||||
@@ -5932,6 +5933,15 @@ function buildSpecialSidebarMenu(context: SidebarMenuFactoryContext): boolean {
|
||||
if (canCloneMongoCollection.value) {
|
||||
items.push({ label: t("contextMenu.cloneCollection"), action: openCloneMongoCollectionDialog, icon: CopyPlus });
|
||||
}
|
||||
items.push({ label: t("contextMenu.importData"), action: openMongoImport, icon: Download });
|
||||
items.push({
|
||||
label: t("contextMenu.exportData"),
|
||||
icon: Upload,
|
||||
children: [
|
||||
{ label: "CSV", action: () => void exportMongoCollection("csv") },
|
||||
{ label: "NDJSON", action: () => void exportMongoCollection("ndjson") },
|
||||
],
|
||||
});
|
||||
if (canDropMongoCollection.value) {
|
||||
items.push({ label: "", separator: true });
|
||||
items.push({ label: t("contextMenu.dropCollection"), action: dropMongoCollection, icon: Trash2, shortcut: shortcutDelete, variant: "destructive" as const });
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const here = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
function read(relativePath: string) {
|
||||
return readFileSync(resolve(here, relativePath), "utf8");
|
||||
}
|
||||
|
||||
describe("mongo collection import/export UI", () => {
|
||||
it("adds table-style import/export to the original mongo-collection menu", () => {
|
||||
const menu = read("../SidebarTreeRuntimeHost.vue");
|
||||
const start = menu.indexOf('if (node.type === "mongo-collection") {\n items.push({ label: t("contextMenu.copyName")');
|
||||
expect(start).toBeGreaterThan(-1);
|
||||
const end = menu.indexOf("return true;", start);
|
||||
const block = menu.slice(start, end);
|
||||
expect(block).toContain('t("contextMenu.viewData")');
|
||||
expect(block).toContain('t("contextMenu.cloneCollection")');
|
||||
expect(block.indexOf('t("contextMenu.cloneCollection")')).toBeLessThan(block.indexOf('t("contextMenu.importData")'));
|
||||
expect(block).toContain("openMongoImport");
|
||||
expect(block).toContain('t("contextMenu.exportData")');
|
||||
expect(block).toContain('exportMongoCollection("csv")');
|
||||
expect(block).toContain('exportMongoCollection("ndjson")');
|
||||
expect(block).not.toContain("openMongoExport");
|
||||
});
|
||||
|
||||
it("opens import through AppDialogs like table import, without an export setup dialog", () => {
|
||||
const dialogs = read("../../layout/AppDialogs.vue");
|
||||
expect(dialogs).toContain("MongoImportDialog");
|
||||
expect(dialogs).not.toContain("MongoExportDialog");
|
||||
expect(dialogs).toContain("dialogs.showMongoImportDialog.value");
|
||||
|
||||
const sources = read("../../../composables/useDialogSources.ts");
|
||||
expect(sources).toContain("connectionStore.mongoImportSource");
|
||||
expect(sources).not.toContain("connectionStore.mongoExportSource");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user