mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
dbeaver/cloudbeaver#3495 filter empty folder in global project (#3636)
* dbeaver/cloudbeaver#3495 filter empty folder in global project
* fixes loading nested folder-nodes during connection creation
* Revert "fixes loading nested folder-nodes during connection creation"
This reverts commit 514bb0238b.
* uses more correct solution for preloading folders
* build fix
* cleanup
* fixes deletion of the connections so it removes empty folders
* fix: outdate only one node
---------
Co-authored-by: sergeyteleshev <iamsergeyteleshev@gmail.com>
Co-authored-by: Alexey Potsetsuev <wrouds@gmail.com>
Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com>
This commit is contained in:
co-authored by
sergeyteleshev
Alexey Potsetsuev
Daria Marutkina
parent
ddf94efef0
commit
fea2d78ef2
+29
-6
@@ -17,6 +17,7 @@
|
||||
|
||||
package io.cloudbeaver;
|
||||
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
@@ -37,9 +38,7 @@ import org.jkiss.dbeaver.registry.DataSourceConfigurationManager;
|
||||
import org.jkiss.dbeaver.registry.DataSourcePersistentRegistry;
|
||||
import org.jkiss.dbeaver.registry.DataSourceRegistry;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -48,12 +47,19 @@ import java.util.stream.Collectors;
|
||||
* We need to filter some data sources in case of inaccessibility (not enough permissions).
|
||||
*/
|
||||
public class WebGlobalProjectRegistryProxy implements DBPDataSourceRegistry, DataSourcePersistentRegistry, DBPDataSourceRegistryCache {
|
||||
@NotNull
|
||||
private final WebSession webSession;
|
||||
@NotNull
|
||||
private final DataSourceFilter dataSourceFilter;
|
||||
@NotNull
|
||||
private final DataSourceRegistry<?> dataSourceRegistry;
|
||||
|
||||
public WebGlobalProjectRegistryProxy(@NotNull DataSourceRegistry<?> dataSourceRegistry, @NotNull DataSourceFilter filter) {
|
||||
public WebGlobalProjectRegistryProxy(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull DataSourceRegistry<?> dataSourceRegistry,
|
||||
@NotNull DataSourceFilter filter
|
||||
) {
|
||||
this.webSession = webSession;
|
||||
this.dataSourceRegistry = dataSourceRegistry;
|
||||
this.dataSourceFilter = filter;
|
||||
}
|
||||
@@ -181,13 +187,30 @@ public class WebGlobalProjectRegistryProxy implements DBPDataSourceRegistry, Dat
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends DBPDataSourceFolder> getAllFolders() {
|
||||
return dataSourceRegistry.getAllFolders();
|
||||
if (webSession.hasPermission(DBWConstants.PERMISSION_ADMIN)) {
|
||||
return dataSourceRegistry.getAllFolders();
|
||||
}
|
||||
Set<DBPDataSourceFolder> set = new LinkedHashSet<>();
|
||||
for (DBPDataSourceContainer container : getDataSources()) {
|
||||
DBPDataSourceFolder folder = container.getFolder();
|
||||
while (folder != null) {
|
||||
set.add(folder);
|
||||
folder = folder.getParent();
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(set);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends DBPDataSourceFolder> getRootFolders() {
|
||||
return dataSourceRegistry.getRootFolders();
|
||||
if (webSession.hasPermission(DBWConstants.PERMISSION_ADMIN)) {
|
||||
return dataSourceRegistry.getRootFolders();
|
||||
}
|
||||
return getDataSources().stream()
|
||||
.map(DBPDataSourceContainer::getFolder)
|
||||
.filter(folder -> folder != null && folder.getParent() == null)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
@@ -50,6 +50,7 @@ public class WebSessionGlobalProjectImpl extends WebSessionProjectImpl {
|
||||
@Override
|
||||
protected DBPDataSourceRegistry createDataSourceRegistry() {
|
||||
return new WebGlobalProjectRegistryProxy(
|
||||
webSession,
|
||||
createRegistryWithCredentialsProvider(),
|
||||
this::isDataSourceAccessible
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { action, makeObservable } from 'mobx';
|
||||
import { action, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import { Dependency, injectable } from '@cloudbeaver/core-di';
|
||||
import { ExecutorInterrupter, type IAsyncContextLoader, type IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
@@ -136,65 +136,80 @@ export class ConnectionNavNodeService extends Dependency {
|
||||
}
|
||||
|
||||
private connectionUpdateHandler(key: ResourceKey<IConnectionInfoParams>) {
|
||||
let connectionInfos = this.connectionInfoResource.get(key);
|
||||
const outdatedTrees: string[] = [];
|
||||
const closedConnections: string[] = [];
|
||||
runInAction(() => {
|
||||
let connectionInfos = this.connectionInfoResource.get(key);
|
||||
const outdatedTrees: string[] = [];
|
||||
const closedConnections: string[] = [];
|
||||
|
||||
connectionInfos = Array.isArray(connectionInfos) ? connectionInfos : [connectionInfos];
|
||||
for (const connectionInfo of connectionInfos) {
|
||||
if (!connectionInfo?.nodePath) {
|
||||
return;
|
||||
connectionInfos = Array.isArray(connectionInfos) ? connectionInfos : [connectionInfos];
|
||||
for (const connectionInfo of connectionInfos) {
|
||||
if (!connectionInfo?.nodePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const node = this.navNodeInfoResource.get(connectionInfo.nodePath);
|
||||
const parentId = getConnectionParentId(connectionInfo.projectId, connectionInfo.folder); // new parent
|
||||
|
||||
if (!connectionInfo.connected) {
|
||||
closedConnections.push(connectionInfo.nodePath);
|
||||
outdatedTrees.push(connectionInfo.nodePath);
|
||||
}
|
||||
|
||||
const folderId = node?.parentId; // current parent
|
||||
|
||||
if (folderId && !outdatedTrees.includes(folderId)) {
|
||||
outdatedTrees.push(folderId);
|
||||
}
|
||||
|
||||
if (!outdatedTrees.includes(parentId)) {
|
||||
outdatedTrees.push(parentId);
|
||||
}
|
||||
}
|
||||
|
||||
const node = this.navNodeInfoResource.get(connectionInfo.nodePath);
|
||||
const parentId = getConnectionParentId(connectionInfo.projectId, connectionInfo.folder); // new parent
|
||||
if (closedConnections.length > 0) {
|
||||
const key = resourceKeyList(closedConnections);
|
||||
|
||||
if (!connectionInfo.connected) {
|
||||
closedConnections.push(connectionInfo.nodePath);
|
||||
outdatedTrees.push(connectionInfo.nodePath);
|
||||
if (this.navTreeResource.has(key)) {
|
||||
this.navTreeResource.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
const folderId = node?.parentId; // current parent
|
||||
|
||||
if (folderId && !outdatedTrees.includes(folderId)) {
|
||||
outdatedTrees.push(folderId);
|
||||
if (outdatedTrees.length > 0) {
|
||||
const key = resourceKeyList(outdatedTrees);
|
||||
this.navTreeResource.markOutdated(key);
|
||||
}
|
||||
|
||||
if (!outdatedTrees.includes(parentId)) {
|
||||
outdatedTrees.push(parentId);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedConnections.length > 0) {
|
||||
const key = resourceKeyList(closedConnections);
|
||||
|
||||
if (this.navTreeResource.has(key)) {
|
||||
this.navTreeResource.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (outdatedTrees.length > 0) {
|
||||
const key = resourceKeyList(outdatedTrees);
|
||||
this.navTreeResource.markOutdated(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private connectionRemoveHandler(key: ResourceKeySimple<IConnectionInfoParams>) {
|
||||
ResourceKeyUtils.forEach(key, key => {
|
||||
const connectionInfo = this.connectionInfoResource.get(key);
|
||||
runInAction(() => {
|
||||
ResourceKeyUtils.forEach(key, key => {
|
||||
const connectionInfo = this.connectionInfoResource.get(key);
|
||||
|
||||
if (!connectionInfo) {
|
||||
return;
|
||||
}
|
||||
if (!connectionInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nodePath = connectionInfo.nodePath ?? NodeManagerUtils.connectionIdToConnectionNodeId(key.connectionId);
|
||||
const nodePath = connectionInfo.nodePath ?? NodeManagerUtils.connectionIdToConnectionNodeId(key.connectionId);
|
||||
|
||||
const node = this.navNodeInfoResource.get(nodePath);
|
||||
const folder = node?.parentId ?? getProjectNodeId(key.projectId);
|
||||
const node = this.navNodeInfoResource.get(nodePath);
|
||||
const folder = node?.parentId ?? getProjectNodeId(key.projectId);
|
||||
const parents = this.navNodeInfoResource.getParents(folder);
|
||||
|
||||
if (nodePath) {
|
||||
this.navTreeResource.deleteInNode(folder, [nodePath]);
|
||||
}
|
||||
for (let i = parents.length - 1; i >= 0; i--) {
|
||||
const parent = parents[i]!;
|
||||
const children = this.navTreeResource.get(parent) ?? [];
|
||||
|
||||
if (children.length > 1) {
|
||||
this.navTreeResource.markOutdated(parent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nodePath) {
|
||||
this.navTreeResource.deleteInNode(folder, [nodePath]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -212,7 +227,20 @@ export class ConnectionNavNodeService extends Dependency {
|
||||
await this.navNodeInfoResource.loadNodeParents(parentId);
|
||||
const parents = this.navNodeInfoResource.getParents(parentId);
|
||||
|
||||
this.navTreeResource.markOutdated(parents[parents.length - 1]);
|
||||
// allows to preload missing folders if the did not load
|
||||
for (let i = 0; i < parents.length; i++) {
|
||||
const parent = parents[i]!;
|
||||
const nextParent = parents[i + 1];
|
||||
const children = this.navTreeResource.get(parent) ?? [];
|
||||
const isEmptyRoot = parents.length <= 2 && !children.length; // for case ['', 'g_GlobalConfiguration']
|
||||
const hasNoChildren = nextParent && !children.includes(nextParent);
|
||||
|
||||
if (isEmptyRoot || hasNoChildren) {
|
||||
this.navTreeResource.markOutdated(parent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const preloaded = await this.navTreeResource.preloadNodeParents(parents, parentId);
|
||||
|
||||
if (!preloaded) {
|
||||
|
||||
Reference in New Issue
Block a user