feat(xugu): expose tablespaces and datafiles in tree
This commit is contained in:
1 parent
afe3b3f3c2
commit
351a8b699b
32 files changed
+811
-4
No files matched your search
@@ -685,6 +685,8 @@ const groupTypes: Set<TreeNodeType> = new Set([
|
||||
"group-types",
|
||||
"group-partitions",
|
||||
"group-extensions",
|
||||
"group-tablespaces",
|
||||
"group-datafiles",
|
||||
]);
|
||||
|
||||
function isGroupLabel(node: TreeNode): boolean {
|
||||
@@ -807,6 +809,35 @@ async function toggle(requestId = beginNavigationRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Xugu tablespace rows and their datafile groups are eagerly materialized
|
||||
// with the tablespace listing; expanding them is a pure local toggle.
|
||||
if (node.type === "tablespace" || node.type === "group-datafiles") {
|
||||
node.isExpanded = !node.isExpanded;
|
||||
emitNodeToggled(node, wasExpanded);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.type === "group-tablespaces") {
|
||||
if (connectionStore.canUseLoadedTreeNodeToggle(node)) {
|
||||
node.isExpanded = !node.isExpanded;
|
||||
if (wasExpanded && shouldReleaseCollapsedTreeNodeChildren()) connectionStore.releaseCollapsedTreeNodeChildren(node.id);
|
||||
emitNodeToggled(node, wasExpanded);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await connectionStore.loadXuguTablespaces(node, { preserveCollapsedChildren: !shouldReleaseCollapsedTreeNodeChildren() });
|
||||
emitNodeToggled(node, wasExpanded);
|
||||
} catch (e: any) {
|
||||
if (!isCurrentNavigationRequest(requestId)) return;
|
||||
if (!wasExpanded) node.isExpanded = false;
|
||||
const errMsg = e?.message || String(e);
|
||||
if (errMsg.includes(CONNECTION_ATTEMPT_CANCELLED_MESSAGE)) return;
|
||||
toast(t("connection.connectFailed", { message: translateBackendError(t, e) }), 5000);
|
||||
openDriverStoreForInstallError(errMsg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isXuguTypeMemberContainer(node, connectionStore.getConfig(node.connectionId || "")?.db_type)) {
|
||||
await connectionStore.loadXuguTypeMembers(node, { preserveCollapsedChildren: !shouldReleaseCollapsedTreeNodeChildren() });
|
||||
emitNodeToggled(node, wasExpanded);
|
||||
|
||||
@@ -240,6 +240,10 @@ function getIconInfo(node: TreeNode): { icon: any; colorClass: string } | null {
|
||||
return { icon: node.isExpanded ? FolderOpen : FolderClosed, colorClass: "text-amber-500" };
|
||||
case "database":
|
||||
return { icon: Database, colorClass: "text-yellow-500" };
|
||||
case "tablespace":
|
||||
return { icon: Database, colorClass: "text-orange-500" };
|
||||
case "datafile":
|
||||
return { icon: FileCode, colorClass: "text-slate-500" };
|
||||
case "linked-server-root":
|
||||
return { icon: Network, colorClass: "text-blue-500" };
|
||||
case "linked-server":
|
||||
@@ -395,6 +399,10 @@ function getIconInfo(node: TreeNode): { icon: any; colorClass: string } | null {
|
||||
return { icon: node.isExpanded ? FolderOpen : FolderClosed, colorClass: "text-green-400" };
|
||||
case "group-extensions":
|
||||
return { icon: Package, colorClass: "text-violet-500" };
|
||||
case "group-tablespaces":
|
||||
return { icon: Database, colorClass: "text-orange-500" };
|
||||
case "group-datafiles":
|
||||
return { icon: node.isExpanded ? FolderOpen : FolderClosed, colorClass: "text-slate-500" };
|
||||
case "extension":
|
||||
return { icon: Package, colorClass: "text-violet-400" };
|
||||
case "load-more":
|
||||
@@ -432,6 +440,7 @@ function displayLabel(node: TreeNode): string {
|
||||
function treeNodeSecondaryValue(node: TreeNode): string | undefined {
|
||||
if (node.type === "type" && node.customTypeKind) return t(`customType.kinds.${node.customTypeKind}`);
|
||||
if (node.type === "type-member") return (node.meta as CustomTypeTreeMemberMeta | undefined)?.displayValue;
|
||||
if (node.type === "datafile") return node.xuguDatafilePath;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
+61
@@ -21,6 +21,9 @@ const connectionStore = {
|
||||
loadObjectGroupChildren: vi.fn(async (node: TreeNode) => {
|
||||
node.isExpanded = true;
|
||||
}),
|
||||
loadXuguTablespaces: vi.fn(async (node: TreeNode) => {
|
||||
node.isExpanded = true;
|
||||
}),
|
||||
};
|
||||
|
||||
const queryStore = {
|
||||
@@ -421,4 +424,62 @@ describe("SidebarTreeRuntimeHost expansion", () => {
|
||||
expect(packageFunctionGroup.isExpanded).toBe(true);
|
||||
expect(packageFunctionGroup.children).toHaveLength(401);
|
||||
});
|
||||
|
||||
it("toggles Xugu tablespace and datafile group nodes locally", async () => {
|
||||
const datafileGroup: TreeNode = {
|
||||
id: "xugu:SHOP_DEMO:tablespace:SYSTEM:datafiles",
|
||||
label: "tree.datafiles",
|
||||
type: "group-datafiles",
|
||||
parentType: "tablespace",
|
||||
parentName: "SYSTEM",
|
||||
connectionId: "xugu",
|
||||
database: "SHOP_DEMO",
|
||||
objectCount: 2,
|
||||
isExpanded: false,
|
||||
children: [
|
||||
{ id: "xugu:SHOP_DEMO:tablespace:SYSTEM:datafile:1", label: "system_01.dbf", type: "datafile", parentType: "tablespace", parentName: "SYSTEM", connectionId: "xugu", database: "SHOP_DEMO", objectName: "system_01.dbf" },
|
||||
{ id: "xugu:SHOP_DEMO:tablespace:SYSTEM:datafile:2", label: "system_02.dbf", type: "datafile", parentType: "tablespace", parentName: "SYSTEM", connectionId: "xugu", database: "SHOP_DEMO", objectName: "system_02.dbf" },
|
||||
],
|
||||
};
|
||||
const tablespaceNode: TreeNode = {
|
||||
id: "xugu:SHOP_DEMO:tablespace:SYSTEM",
|
||||
label: "SYSTEM",
|
||||
type: "tablespace",
|
||||
connectionId: "xugu",
|
||||
database: "SHOP_DEMO",
|
||||
objectName: "SYSTEM",
|
||||
isExpanded: false,
|
||||
children: [datafileGroup],
|
||||
};
|
||||
connectionStore.treeNodes = [tablespaceNode];
|
||||
connectionStore.getConfig.mockReturnValue({ db_type: "xugu" });
|
||||
connectionStore.canUseLoadedTreeNodeToggle.mockReturnValue(false);
|
||||
|
||||
const host = ref<InstanceType<typeof SidebarTreeRuntimeHost> | null>(null);
|
||||
const toggled = vi.fn();
|
||||
const app = createApp(
|
||||
defineComponent({
|
||||
setup: () => () => h(SidebarTreeRuntimeHost, { ref: host, node: tablespaceNode, depth: 0, onNodeToggled: toggled }),
|
||||
}),
|
||||
);
|
||||
mountedApps.push(app);
|
||||
const container = document.createElement("div");
|
||||
document.body.append(container);
|
||||
app.use(i18n);
|
||||
app.mount(container);
|
||||
|
||||
host.value?.toggleNode(tablespaceNode);
|
||||
await nextTick();
|
||||
|
||||
expect(tablespaceNode.isExpanded).toBe(true);
|
||||
expect(connectionStore.loadXuguTablespaces).not.toHaveBeenCalled();
|
||||
expect(toggled).toHaveBeenCalledWith(tablespaceNode, true);
|
||||
|
||||
host.value?.toggleNode(datafileGroup);
|
||||
await nextTick();
|
||||
|
||||
expect(datafileGroup.isExpanded).toBe(true);
|
||||
expect(connectionStore.loadXuguTablespaces).not.toHaveBeenCalled();
|
||||
expect(toggled).toHaveBeenCalledWith(datafileGroup, true);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user