Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class NavigationTreeContextMenuService {
title: 'app_navigationTree_refreshNode',
onClick: (context) => {
const node = context.data;
this.navNodeManagerService.refresh(node.id);
this.navNodeManagerService.refreshTree(node.id);
},
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ export function useNavigationTree(nodeId: string, parentId: string) {

const isLoaded = children.isLoaded;
const isExpandable = isExpandableFilter(node) && (!isLoaded || children.children!.length > 0);
const isExpandedFiltered = isExpanded
&& (
!node.objectFeatures.includes(EObjectFeature.dataSource)
|| node.objectFeatures.includes(EObjectFeature.dataSourceConnected)
);

const handleDoubleClick = useCallback(
() => navNodeManagerService.navToNode(nodeId, parentId),
Expand All @@ -40,15 +45,16 @@ export function useNavigationTree(nodeId: string, parentId: string) {

const handleExpand = useCallback(
async () => {
if (!isExpanded) {
if (!isExpandedFiltered) {
const state = await navigationTreeService.loadNestedNodes(nodeId);
if (!state) {
switchExpand(false);
return;
}
}
switchExpand(!isExpanded);
switchExpand(!isExpandedFiltered);
},
[isExpanded, nodeId]
[isExpandedFiltered, nodeId]
);

const handleSelect = useCallback(
Expand All @@ -69,10 +75,12 @@ export function useNavigationTree(nodeId: string, parentId: string) {
}, [isExpandable && hasChildren]);

useEffect(() => {
if (isExpanded && !children.isLoaded && !children.isLoading && !!children.children && nodeLoaded) {
navigationTreeService.loadNestedNodes(nodeId);
if (isExpandedFiltered && !children.isLoaded && !children.isLoading && !!children.children && nodeLoaded) {
navigationTreeService
.loadNestedNodes(nodeId)
.then(state => !state && switchExpand(false));
}
}, [isExpanded, children.isLoaded, children.isLoading, children.children, nodeLoaded, nodeId]);
}, [isExpandedFiltered, children.isLoaded, children.isLoading, children.children, nodeLoaded, nodeId]);

// Here we subscribe to selected nodes if current node selected (mobx)
if (isSelected && !navigationTreeService.isNodeSelected(nodeId)) {
Expand All @@ -90,7 +98,7 @@ export function useNavigationTree(nodeId: string, parentId: string) {
node,
nodeType,
icon,
isExpanded,
isExpanded: isExpandedFiltered,
isLoaded,
isLoading: children.isLoading,
isExpandable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ export class ConnectionDialogsService {
title: 'Disconnect',
onClick: (context: IMenuContext<NavNode>) => {
const node = context.data;
const connectionId = NodeManagerUtils.connectionNodeIdToConnectionId(node.id);
this.connectionsManagerService.closeConnectionAsync(connectionId);
this.connectionsManagerService.closeNavNodeConnectionAsync(node.id);
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { computed, observable } from 'mobx';
import { Subject } from 'rxjs';

import { injectable } from '@dbeaver/core/di';
import { NotificationService } from '@dbeaver/core/eventsLog';
import { SessionService } from '@dbeaver/core/root';
import {
ConnectionInfo,
Expand All @@ -21,6 +22,7 @@ import {
} from '@dbeaver/core/sdk';

import { NavNodeManagerService } from '../NodesManager/NavNodeManagerService';
import { NodeManagerUtils } from '../NodesManager/NodeManagerUtils';

export type DBDriver = Pick<
DriverInfo,
Expand Down Expand Up @@ -68,7 +70,8 @@ export class ConnectionsManagerService {
constructor(
private graphQLService: GraphQLService,
private navNodeManagerService: NavNodeManagerService,
private sessionService: SessionService
private sessionService: SessionService,
private notificationService: NotificationService
) {
this.sessionService.onUpdate.subscribe(this.restoreConnections.bind(this));
}
Expand Down Expand Up @@ -126,13 +129,36 @@ export class ConnectionsManagerService {
}
}

async closeNavNodeConnectionAsync(navNodeId: string): Promise<void> {
const node = this.navNodeManagerService.getNode(navNodeId);
if (!node) {
return;
}

try {
const connectionId = NodeManagerUtils.connectionNodeIdToConnectionId(navNodeId);
await this.graphQLService.gql.closeConnection({ id: connectionId });
await this.afterConnectionClose(connectionId);
this.connectionsMap.delete(connectionId);

if (node.objectFeatures.includes('dataSourceTemporary')) {
await this.navNodeManagerService.removeNode(navNodeId);
} else {
await this.navNodeManagerService.refreshNode(navNodeId);
}
await this.navNodeManagerService.removeTree(navNodeId);
} catch (exception) {
this.notificationService.logException(exception, `Can't close connection: ${navNodeId}`);
}
}

async loadObjectContainer(connectionId: string, catalogId?: string): Promise<ObjectContainer[]> {
const data = await this.connectionObjectContainers.load(connectionId, catalogId);
return data.get(connectionId)!;
}

private async afterConnectionClose(id: string) {
await this.navNodeManagerService.remove(id);
await this.navNodeManagerService.removeTree(id);
this.onCloseConnection.next(id);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ export enum EObjectFeature {
'schema' = 'schema',
'catalog' = 'catalog',
'dataSource' = 'dataSource', // connection
'dataSourceTemporary' = 'dataSourceTemporary',
'dataSourceConnected' = 'dataSourceConnected',
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface NavNodeKey {

export interface NavNodeValue {
node: NavNodeInfo;
parentId: string;
parentId?: string;
}

export interface INodeContainerInfo {
Expand Down Expand Up @@ -157,7 +157,7 @@ export class NavNodeManagerService {
});
}

async refresh(navNodeId: string) {
async refreshTree(navNodeId: string) {
await this.graphQLService.gql.navRefreshNode({
nodePath: navNodeId,
});
Expand Down Expand Up @@ -191,6 +191,14 @@ export class NavNodeManagerService {
return this.getTree(navNodeId)!;
}

async removeTree(path = ROOT_NODE_PATH) {
await this.navTree.refresh(true, path, true);
}

async refreshNode(navNodeId: string) {
await this.navNode.refresh(true, { navNodeId: [navNodeId] });
}

getNode(navNodeId: string): NavNode | undefined
getNode(navNodeKey: NavNodeKey): NavNode | undefined
getNode(navNodeKey: NavNodeKey[]): (NavNode | undefined)[]
Expand Down Expand Up @@ -239,6 +247,13 @@ export class NavNodeManagerService {
return this.getNode(nodes);
}

async removeNode(navNodeId = ROOT_NODE_PATH) {
await this.navNode.refresh(true, {
navNodeId: [navNodeId],
remove: true,
});
}

getParent(node: NavNode) {
return this.navNode.data.get(node.parentId);
}
Expand Down Expand Up @@ -283,10 +298,6 @@ export class NavNodeManagerService {
return scanParents(initial, nodeId);
}

async remove(path = ROOT_NODE_PATH) {
await this.navTree.refresh(true, path, true);
}

navigationNavNodeContext = async (
contexts: IContextProvider<INodeNavigationData>,
data: INodeNavigationData
Expand Down Expand Up @@ -369,10 +380,12 @@ export class NavNodeManagerService {
if (data.nodesValue) {
for (const nodeValue of data.nodesValue) {
const itemMetadata = metadata.get(nodeValue.node.id);
const parentId = navNode.get(nodeValue.node.id)?.parentId || nodeValue.parentId || ROOT_NODE_PATH;

navNode.set(nodeValue.node.id, {
...nodeValue.node,
objectFeatures: nodeValue.node.object?.features || [],
parentId: nodeValue.parentId,
parentId,
});
itemMetadata.loaded = true;
}
Expand Down Expand Up @@ -448,12 +461,12 @@ export class NavNodeManagerService {
if (load) {
itemMetadata.loading = true;

const { navNodeChildren } = await this.graphQLService.gql.navNodeChildren({
const { navNodeChildren, navNodeInfo } = await this.graphQLService.gql.navNodeChildren({
parentPath: parentId,
});

await this.navNode.refresh(true, {
nodesValue: navNodeChildren.map(node => ({ node, parentId })),
nodesValue: [{ node: navNodeInfo }, ...navNodeChildren.map(node => ({ node, parentId }))],
});
navTree.set(parentId, navNodeChildren.map(node => node.id));
itemMetadata.loaded = true;
Expand All @@ -480,7 +493,10 @@ export class NavNodeManagerService {
}

const nestedChildren = this.getNestedChildren(childrenToRemove);
await this.navNode.refresh(true, { navNodeId: nestedChildren, remove: true });
await this.navNode.refresh(true, {
navNodeId: nestedChildren.filter(navNodeId => navNodeId !== parentId),
remove: true,
});
for (const navNodeId of nestedChildren) {
navTree.delete(navNodeId);
metadata.delete(navNodeId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,19 @@ query navNodeChildren($parentPath: ID!) {
features
}
}

navNodeInfo(nodePath: $parentPath) {
id
name
hasChildren
nodeType
icon
folder
inline
navigable
features
object {
features
}
}
}
19 changes: 18 additions & 1 deletion webapp/packages/core/src/sdk/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,10 @@ export type NavNodeChildrenQueryVariables = {
export type NavNodeChildrenQuery = { navNodeChildren: Array<(
Pick<NavigatorNodeInfo, 'id' | 'name' | 'hasChildren' | 'nodeType' | 'icon' | 'folder' | 'inline' | 'navigable' | 'features'>
& { object?: Maybe<Pick<DatabaseObjectInfo, 'features'>> }
)>; };
)>; navNodeInfo: (
Pick<NavigatorNodeInfo, 'id' | 'name' | 'hasChildren' | 'nodeType' | 'icon' | 'folder' | 'inline' | 'navigable' | 'features'>
& { object?: Maybe<Pick<DatabaseObjectInfo, 'features'>> }
); };

export type NavNodeInfoQueryVariables = {
nodePath: Scalars['ID'];
Expand Down Expand Up @@ -1308,6 +1311,20 @@ export const NavNodeChildrenDocument = `
features
}
}
navNodeInfo(nodePath: $parentPath) {
id
name
hasChildren
nodeType
icon
folder
inline
navigable
features
object {
features
}
}
}
`;
export const NavNodeInfoDocument = `
Expand Down