feat(mongo): add GridFS manager for MongoDB

* feat(mongo): browse GridFS buckets and files

Refs #2342

* feat(mongo): add GridFS manager for MongoDB

* chore(i18n): autofill new translations

---------

Co-authored-by: dbx-i18n-bot <github-actions[bot]@users.noreply.github.com>
Co-authored-by: t8y2 <1156263951@qq.com>
This commit is contained in:
authored and GitHub committed 2026-07-03 18:34:00 +08:00
1 parent a8abb1c478
commit f826cb5d38
35 files changed
+1959 -39

No files matched your search

+25 -9
View File
@@ -1868,18 +1868,32 @@ export const useConnectionStore = defineStore("connection", () => {
node.isLoading = true;
try {
const collections = await api.mongoListCollections(connectionId, database);
const names = collections.map((c) => c.name);
setChildren(
node,
sortSidebarNames(names).map((col) => ({
id: `${nodeId}:${col}`,
label: col,
type: "mongo-collection" as const,
const bucketNames = new Set(collections.filter((c) => c.kind === "bucket" && c.bucketName).map((c) => c.bucketName as string));
const hiddenCollectionNames = new Set([...bucketNames].flatMap((bucketName) => [`${bucketName}.files`, `${bucketName}.chunks`]));
const collectionNames = collections
.filter((c) => c.kind !== "bucket")
.map((c) => c.name)
.filter((name) => !hiddenCollectionNames.has(name));
const collectionChildren = sortSidebarNames(collectionNames).map((col) => ({
id: `${nodeId}:${col}`,
label: col,
type: "mongo-collection" as const,
connectionId,
database,
isExpanded: false,
}));
const children = [
{
id: `${nodeId}:__gridfs`,
label: i18n.global.t("tree.gridfs"),
type: "mongo-gridfs" as const,
connectionId,
database,
isExpanded: false,
})),
);
},
...collectionChildren,
];
setChildren(node, children);
node.isExpanded = true;
} catch (e) {
recordMetadataLoadError(connectionId, e);
@@ -2649,6 +2663,8 @@ export const useConnectionStore = defineStore("connection", () => {
await loadMongoCollections(node.connectionId, node.database);
} else if (node.type === "mongo-collection" && node.connectionId && node.database) {
await loadTableGroups(node.connectionId, node.database, node.label, node.schema, node.id);
} else if (node.type === "mongo-gridfs") {
node.isExpanded = true;
} else if (node.type === "database" && node.connectionId && hasTreeNodeDatabaseContext(node)) {
const config = getConfig(node.connectionId);
const effectiveDbType = effectiveDatabaseTypeForConnection(config);
+54
View File
@@ -691,6 +691,58 @@ export const useQueryStore = defineStore("query", () => {
return id;
}
function openMongoBucket(connectionId: string, database: string, bucketName: string) {
const title = `${database}.${bucketName}`;
const existing = tabs.value.find((tab) => tab.mode === "mongo-bucket" && tab.connectionId === connectionId && tab.database === database && tab.mongoBucket?.bucketName === bucketName);
if (existing) {
activeTabId.value = existing.id;
return existing.id;
}
const id = uuid();
const tab: QueryTab = {
id,
title,
connectionId,
database,
sql: bucketName,
isExecuting: false,
isCancelling: false,
isExplaining: false,
mode: "mongo-bucket",
mongoBucket: {
bucketName,
},
};
tabs.value.push(tab);
activeTabId.value = id;
return id;
}
function openMongoGridFs(connectionId: string, database: string) {
const existing = tabs.value.find((tab) => tab.mode === "mongo-gridfs" && tab.connectionId === connectionId && tab.database === database);
if (existing) {
activeTabId.value = existing.id;
return existing.id;
}
const id = uuid();
const tab: QueryTab = {
id,
title: "GridFS",
connectionId,
database,
sql: "",
isExecuting: false,
isCancelling: false,
isExplaining: false,
mode: "mongo-gridfs",
};
tabs.value.push(tab);
activeTabId.value = id;
return id;
}
function openMqAdmin(connectionId: string, target?: { tenant?: string; initialTab?: QueryTab["mqInitialTab"] }) {
const existing = tabs.value.find((tab) => tab.mode === "mq" && tab.connectionId === connectionId);
if (existing) {
@@ -2778,6 +2830,8 @@ export const useQueryStore = defineStore("query", () => {
rollbackTransaction,
renameTab,
openObjectBrowser,
openMongoGridFs,
openMongoBucket,
openUserAdmin,
openMqAdmin,
openNacosAdmin,