From 08b24cace6237cbf0232f918d4fd07ffe4de3eb8 Mon Sep 17 00:00:00 2001 From: ShadelessFox <35821147+ShadelessFox@users.noreply.github.com> Date: Thu, 28 Jul 2022 09:11:43 -0700 Subject: [PATCH] dbeaver/dbeaver-ee#1734 RM resource properties (#985) Co-authored-by: Serge Rider --- .../rm/local/LocalResourceController.java | 66 ++++++++++--- .../cloudbeaver/model/session/WebSession.java | 4 +- .../utils/WebConnectionFolderUtils.java | 11 ++- .../cloudbeaver/utils/WebDataSourceUtils.java | 6 +- .../schema/service.core.graphqls | 18 ++-- .../schema/service.navigator.graphqls | 13 +-- .../schema/service.sql.graphqls | 23 ++--- .../service/WebServiceBindingBase.java | 7 +- .../service/core/DBWServiceCore.java | 25 ++--- .../service/core/WebServiceBindingCore.java | 40 ++------ .../service/core/impl/WebServiceCore.java | 77 ++++++--------- .../navigator/DBWServiceNavigator.java | 7 ++ .../navigator/WebServiceBindingNavigator.java | 7 ++ .../navigator/impl/WebServiceNavigator.java | 21 ++++- .../service/sql/DBWServiceSQL.java | 6 +- .../service/sql/WebServiceBindingSQL.java | 1 - .../service/sql/impl/WebServiceSQL.java | 9 +- .../auth/local/LocalSessionHandler.java | 6 +- .../CBEmbeddedSecurityController.java | 2 +- .../src/LocalizationService.ts | 2 +- webapp/packages/core-projects/package.json | 2 - .../core-projects/src/ProjectsResource.ts | 35 ++++--- .../core-projects/src/ProjectsService.ts | 52 ---------- webapp/packages/core-projects/src/index.ts | 1 - webapp/packages/core-projects/src/manifest.ts | 2 - .../core-sdk/src/CustomGraphQLClient.ts | 23 ++--- .../src/queries/project/getProjectList.gql | 7 -- ...urceProjectList.gql => getProjectList.gql} | 3 +- webapp/packages/core-sdk/src/sdk.ts | 94 ++++--------------- .../src/ThemeSettingsService.test.ts | 4 +- .../core-theming/src/ThemeSettingsService.ts | 2 +- .../src/NavNodes/ResourceFoldersBootstrap.ts | 16 ++-- .../src/ResourceProjectsResource.ts | 43 --------- .../src/Tree/ResourceManagerTree.tsx | 4 +- .../plugin-resource-manager/src/index.ts | 1 - .../plugin-resource-manager/src/manifest.ts | 2 - .../src/PluginBootstrap.ts | 9 +- 37 files changed, 231 insertions(+), 420 deletions(-) delete mode 100644 webapp/packages/core-projects/src/ProjectsService.ts delete mode 100644 webapp/packages/core-sdk/src/queries/project/getProjectList.gql rename webapp/packages/core-sdk/src/queries/resource-manager/{getResourceProjectList.gql => getProjectList.gql} (57%) delete mode 100644 webapp/packages/plugin-resource-manager/src/ResourceProjectsResource.ts diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java index f45b5f2fdd..9fd6289e1f 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java @@ -21,6 +21,7 @@ import io.cloudbeaver.VirtualProjectImpl; import io.cloudbeaver.model.rm.RMUtils; import io.cloudbeaver.service.sql.WebSQLConstants; import io.cloudbeaver.utils.WebAppUtils; +import org.eclipse.core.runtime.IPath; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; @@ -42,7 +43,10 @@ import org.jkiss.utils.CommonUtils; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.nio.file.*; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; import java.time.OffsetDateTime; import java.time.ZoneId; import java.util.*; @@ -233,11 +237,11 @@ public class LocalResourceController implements RMController { } @Override - public RMProject getProject(@NotNull String projectId, boolean readResources) throws DBException { + public RMProject getProject(@NotNull String projectId, boolean readResources, boolean readProperties) throws DBException { RMProject project = makeProjectFromId(projectId, true); if (readResources) { project.setChildren( - listResources(projectId, null, null, true, false, true) + listResources(projectId, null, null, readProperties, false, true) ); } return project; @@ -312,7 +316,7 @@ public class LocalResourceController implements RMController { if (!folderPath.startsWith(projectPath)) { throw new DBException("Invalid folder path"); } - return readChildResources(folderPath, readProperties, readHistory, recursive); + return readChildResources(projectId, folderPath, readProperties, readHistory, recursive); } catch (NoSuchFileException e) { throw new DBException("Invalid resource folder " + folder); } catch (IOException e) { @@ -321,10 +325,16 @@ public class LocalResourceController implements RMController { } @NotNull - private RMResource[] readChildResources(Path folderPath, boolean readProperties, boolean readHistory, boolean recursive) throws IOException { + private RMResource[] readChildResources( + @NotNull String projectId, + @NotNull Path folderPath, + boolean readProperties, + boolean readHistory, + boolean recursive + ) throws IOException { try (Stream files = Files.list(folderPath)) { return files.filter(path -> !path.getFileName().toString().startsWith(".")) // skip hidden files - .map((Path path) -> makeResourceFromPath(path, readProperties, readHistory, recursive)) + .map((Path path) -> makeResourceFromPath(projectId, path, readProperties, readHistory, recursive)) .filter(Objects::nonNull) .toArray(RMResource[]::new); } @@ -449,6 +459,19 @@ public class LocalResourceController implements RMController { return DEFAULT_CHANGE_ID; } + @NotNull + @Override + public String setResourceProperty( + @NotNull String projectId, + @NotNull String resourcePath, + @NotNull String propertyName, + @Nullable Object propertyValue + ) throws DBException { + validateResourcePath(resourcePath); + getProjectMetadata(projectId).setResourceProperty(resourcePath, propertyName, propertyValue); + return DEFAULT_CHANGE_ID; + } + private void validateResourcePath(String resourcePath) throws DBException { if (resourcePath.startsWith(".")) { throw new DBException("Resource path '" + resourcePath + "' can't start with dot"); @@ -559,14 +582,20 @@ public class LocalResourceController implements RMController { for (var resourceName : relativeResourcePath) { resourcePath = resourcePath.resolve(resourceName); - result.add(makeResourceFromPath(resourcePath, false, false, recursive)); + result.add(makeResourceFromPath(projectId, resourcePath, false, false, recursive)); } return result; } - private RMResource makeResourceFromPath(Path path, boolean readProperties, boolean readHistory, boolean recursive) { - if (path == null || !Files.exists(path)) { + private RMResource makeResourceFromPath( + @NotNull String projectId, + @NotNull Path path, + boolean readProperties, + boolean readHistory, + boolean recursive + ) { + if (Files.notExists(path)) { return null; } RMResource resource = new RMResource(); @@ -594,14 +623,22 @@ public class LocalResourceController implements RMController { )) ); } - } catch (IOException e) { + if (readProperties) { + final BaseProjectImpl project = (BaseProjectImpl) getProjectMetadata(projectId); + final String resourcePath = getProjectRelativePath(projectId, path); + final Map properties = project.getResourceProperties(resourcePath); + + if (properties != null && !properties.isEmpty()) { + resource.setProperties(new LinkedHashMap<>(properties)); + } + } + } catch (Exception e) { log.error(e); } if (recursive && resource.isFolder()) { try { - resource.setChildren( - readChildResources(path, readProperties, readHistory, recursive)); + resource.setChildren(readChildResources(projectId, path, readProperties, readHistory, true)); } catch (IOException e) { log.error(e); } @@ -610,6 +647,11 @@ public class LocalResourceController implements RMController { return resource; } + @NotNull + private String getProjectRelativePath(@NotNull String projectId, @NotNull Path path) throws DBException { + return getProjectPath(projectId).toAbsolutePath().relativize(path).toString().replace('\\', IPath.SEPARATOR); + } + public static Builder builder(SMCredentialsProvider credentialsProvider, SMController smController) { return new Builder(credentialsProvider, smController); } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java index d18a6b3a22..4baf895085 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java @@ -528,13 +528,13 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, } @NotNull - public WebConnectionInfo getWebConnectionInfo(@Nullable String projectId, String connectionID) throws DBWebException { + public WebConnectionInfo getWebConnectionInfo(String connectionID) throws DBWebException { WebConnectionInfo connectionInfo; synchronized (connections) { connectionInfo = connections.get(connectionID); } if (connectionInfo == null) { - DBPDataSourceContainer dataSource = getProjectById(projectId).getDataSourceRegistry().getDataSource(connectionID); + DBPDataSourceContainer dataSource = WebDataSourceUtils.getLocalOrGlobalDataSource(application, this, connectionID); if (dataSource != null) { connectionInfo = new WebConnectionInfo(this, dataSource); synchronized (connections) { diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebConnectionFolderUtils.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebConnectionFolderUtils.java index c95ebd05d3..f35193b67e 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebConnectionFolderUtils.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebConnectionFolderUtils.java @@ -16,21 +16,22 @@ */ package io.cloudbeaver.utils; +import io.cloudbeaver.DBWConstants; import io.cloudbeaver.DBWebException; import io.cloudbeaver.model.WebConnectionFolderInfo; import io.cloudbeaver.model.session.WebSession; -import org.jkiss.code.Nullable; import org.jkiss.dbeaver.model.DBPDataSourceFolder; import org.jkiss.utils.CommonUtils; public class WebConnectionFolderUtils { - public static WebConnectionFolderInfo getFolderInfo( - WebSession session, @Nullable String projectId, String folderPath - ) throws DBWebException { + public static WebConnectionFolderInfo getFolderInfo(WebSession session, String folderPath) throws DBWebException { DBPDataSourceFolder folder = null; if (!CommonUtils.isEmpty(folderPath)) { - folder = session.getProjectById(projectId).getDataSourceRegistry().getFolder(folderPath); + folder = session.getSingletonProject().getDataSourceRegistry().getFolder(folderPath); + if (folder == null && (session.hasPermission(DBWConstants.PERMISSION_ADMIN) || session.getApplication().isConfigurationMode())) { + folder = WebDataSourceUtils.getGlobalDataSourceRegistry().getFolder(folderPath); + } } if (folder != null) { return new WebConnectionFolderInfo(session, folder); diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebDataSourceUtils.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebDataSourceUtils.java index 08e47eaf89..9774394574 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebDataSourceUtils.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebDataSourceUtils.java @@ -60,12 +60,10 @@ public class WebDataSourceUtils { } @Nullable - public static DBPDataSourceContainer getLocalOrGlobalDataSource( - WebApplication application, WebSession webSession, @Nullable String projectId, String connectionId - ) throws DBWebException { + public static DBPDataSourceContainer getLocalOrGlobalDataSource(WebApplication application, WebSession webSession, String connectionId) throws DBWebException { DBPDataSourceContainer dataSource = null; if (!CommonUtils.isEmpty(connectionId)) { - dataSource = webSession.getProjectById(projectId).getDataSourceRegistry().getDataSource(connectionId); + dataSource = webSession.getSingletonProject().getDataSourceRegistry().getDataSource(connectionId); if (dataSource == null && (webSession.hasPermission(DBWConstants.PERMISSION_ADMIN) || application.isConfigurationMode())) { // If called for new connection in admin mode then this connection may absent in session registry yet dataSource = getGlobalDataSourceRegistry().getDataSource(connectionId); diff --git a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls index 73032cdc7e..7b8bb0c995 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls @@ -463,21 +463,21 @@ extend type Query { networkHandlers: [NetworkHandlerDescriptor!]! # List of user connections. - userConnections( projectId: String, id: ID ): [ ConnectionInfo! ]! + userConnections( id: ID ): [ ConnectionInfo! ]! # List of template connections. templateConnections: [ ConnectionInfo! ]! # List of connection folders - connectionFolders( projectId: String, path: ID ): [ ConnectionFolderInfo! ]! + connectionFolders( path: ID ): [ ConnectionFolderInfo! ]! # Return connection state - connectionState( projectId: String, id: ID! ): ConnectionInfo! @deprecated + connectionState( id: ID! ): ConnectionInfo! @deprecated # Return connection info - connectionInfo( projectId: String, id: ID! ): ConnectionInfo! + connectionInfo( id: ID! ): ConnectionInfo! # Return list of accessible user projects - listProjects: [ ProjectInfo! ]! + listProjects: [ ProjectInfo ] readSessionLog(maxEntries: Int, clearEntries: Boolean): [ LogEntry! ]! } @@ -516,19 +516,19 @@ extend type Mutation { copyConnectionFromNode( nodePath: String!, config: ConnectionConfig, projectId: String ): ConnectionInfo! # Test connection configuration. Returns remote server version - testConnection( config: ConnectionConfig!, projectId: String ): ConnectionInfo! + testConnection( config: ConnectionConfig! ): ConnectionInfo! # Test connection configuration. Returns remote server version testNetworkHandler( config: NetworkHandlerConfigInput! ): NetworkEndpointInfo! # Initiate existing connection - initConnection( id: ID!, projectId: String, credentials: Object, networkCredentials: [NetworkHandlerConfigInput!], saveCredentials: Boolean ): ConnectionInfo! + initConnection( id: ID!, credentials: Object, networkCredentials: [NetworkHandlerConfigInput!], saveCredentials: Boolean ): ConnectionInfo! # Disconnect from database - closeConnection( id: ID!, projectId: String ): ConnectionInfo! + closeConnection( id: ID! ): ConnectionInfo! # Changes navigator settings for connection - setConnectionNavigatorSettings( id: ID!, projectId: String, settings: NavigatorSettingsInput!): ConnectionInfo! + setConnectionNavigatorSettings( id: ID!, settings: NavigatorSettingsInput!): ConnectionInfo! #### Generic async functions diff --git a/server/bundles/io.cloudbeaver.server/schema/service.navigator.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.navigator.graphqls index 5750ad0fdf..ce0d24b4d0 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.navigator.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.navigator.graphqls @@ -107,17 +107,18 @@ extend type Query { # Get child nodes navNodeChildren( + projectId: ID, parentPath: ID!, offset: Int, limit: Int, onlyFolders: Boolean): [ NavigatorNodeInfo! ]! # Get child nodes - navNodeParents( nodePath: ID! ): [ NavigatorNodeInfo! ]! + navNodeParents( projectId: ID, nodePath: ID! ): [ NavigatorNodeInfo! ]! - navNodeInfo( nodePath: ID! ): NavigatorNodeInfo! + navNodeInfo( projectId: ID, nodePath: ID! ): NavigatorNodeInfo! - navRefreshNode( nodePath: ID! ): Boolean + navRefreshNode( projectId: ID, nodePath: ID! ): Boolean # contextId currently not using navGetStructContainers( projectId: ID, connectionId: ID!, contextId: ID, catalog: ID ): DatabaseStructContainers! @@ -127,12 +128,12 @@ extend type Query { extend type Mutation { # Rename node and returns new node name - navRenameNode( nodePath: ID!, newName: String! ): String + navRenameNode( projectId: ID, nodePath: ID!, newName: String! ): String # Deletes nodes with specified IDs and returns number of deleted nodes - navDeleteNodes( nodePaths: [ID!]! ): Int + navDeleteNodes( projectId: ID, nodePaths: [ID!]! ): Int # Moves nodes with specified IDs to the connection folder - navMoveNodesToFolder( nodePaths: [ID!]!, folderPath: ID!): Boolean + navMoveNodesToFolder(projectId: ID, nodePaths: [ID!]!, folderPath: ID!): Boolean } \ No newline at end of file diff --git a/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls index c36e1a54de..3c3d66543a 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls @@ -197,13 +197,12 @@ type SQLScriptQuery { extend type Query { - sqlDialectInfo( projectId: ID, connectionId: ID! ): SQLDialectInfo + sqlDialectInfo( connectionId: ID! ): SQLDialectInfo # Lists SQL contexts for a connection (optional) or returns the particular context info - sqlListContexts( projectId: ID, connectionId: ID, contextId: ID ): [ SQLContextInfo ]! + sqlListContexts( connectionId: ID, contextId: ID ): [ SQLContextInfo ]! sqlCompletionProposals( - projectId: ID, connectionId: ID!, contextId: ID!, query: String!, @@ -213,14 +212,12 @@ extend type Query { ): [ SQLCompletionProposal ] sqlFormatQuery( - projectId: ID, connectionId: ID!, contextId: ID!, query: String! ): String! sqlSupportedOperations( - projectId: ID, connectionId: ID!, contextId: ID!, resultsId: ID!, @@ -246,13 +243,11 @@ extend type Query { ): String! sqlParseScript( - projectId: ID, connectionId: ID!, script: String! ): SQLScriptInfo! sqlParseQuery( - projectId: ID, connectionId: ID!, script: String!, position: Int! @@ -260,15 +255,14 @@ extend type Query { } extend type Mutation { - sqlContextCreate( projectId: ID, connectionId: ID!, defaultCatalog: String, defaultSchema: String ): SQLContextInfo! + sqlContextCreate( connectionId: ID!, defaultCatalog: String, defaultSchema: String ): SQLContextInfo! - sqlContextSetDefaults( projectId: ID, connectionId: ID!, contextId: ID!, defaultCatalog: ID, defaultSchema: ID ): Boolean! + sqlContextSetDefaults( connectionId: ID!, contextId: ID!, defaultCatalog: ID, defaultSchema: ID ): Boolean! - sqlContextDestroy( projectId: ID, connectionId: ID!, contextId: ID! ): Boolean! + sqlContextDestroy( connectionId: ID!, contextId: ID! ): Boolean! # Execute SQL and return results asyncSqlExecuteQuery( - projectId: ID, connectionId: ID!, contextId: ID!, sql: String!, @@ -279,7 +273,6 @@ extend type Mutation { # Read data from table asyncReadDataFromContainer( - projectId: ID, connectionId: ID!, contextId: ID!, containerNodePath: ID!, @@ -289,11 +282,10 @@ extend type Mutation { ): AsyncTaskInfo! # Close results (free resources) - sqlResultClose(projectId: ID, connectionId: ID!, contextId: ID!, resultId: ID!): Boolean! + sqlResultClose(connectionId: ID!, contextId: ID!, resultId: ID!): Boolean! # Update multiple cell values updateResultsDataBatch( - projectId: ID, connectionId: ID!, contextId: ID!, resultsId: ID!, @@ -305,7 +297,6 @@ extend type Mutation { # Return SQL script for cell values update updateResultsDataBatchScript( - projectId: ID, connectionId: ID!, contextId: ID!, resultsId: ID!, @@ -317,7 +308,6 @@ extend type Mutation { #Return BLOB name readLobValue( - projectId: ID, connectionId: ID!, contextId: ID!, resultsId: ID!, @@ -330,7 +320,6 @@ extend type Mutation { # Read data from table asyncSqlExplainExecutionPlan( - projectId: ID, connectionId: ID!, contextId: ID!, query: String!, diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceBindingBase.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceBindingBase.java index ff27dd0077..33ad78014b 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceBindingBase.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceBindingBase.java @@ -27,7 +27,6 @@ import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; import io.cloudbeaver.server.graphql.GraphQLEndpoint; import org.jkiss.code.NotNull; -import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.rm.RMProject; @@ -118,7 +117,7 @@ public abstract class WebServiceBindingBase impleme @NotNull protected static WebConnectionInfo getWebConnection(DataFetchingEnvironment env) throws DBWebException { - return getWebConnection(getWebSession(env), getProjectReference(env), env.getArgument("connectionId")); + return getWebConnection(getWebSession(env), env.getArgument("connectionId")); } public static WebSession findWebSession(DataFetchingEnvironment env) { @@ -127,8 +126,8 @@ public abstract class WebServiceBindingBase impleme } @NotNull - public static WebConnectionInfo getWebConnection(WebSession session, String projectId, String connectionId) throws DBWebException { - return session.getWebConnectionInfo(projectId, connectionId); + public static WebConnectionInfo getWebConnection(WebSession session, String connectionId) throws DBWebException { + return session.getWebConnectionInfo(connectionId); } private class ServiceInvocationHandler implements InvocationHandler { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/DBWServiceCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/DBWServiceCore.java index f2ff5d83f9..1994a80d37 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/DBWServiceCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/DBWServiceCore.java @@ -51,12 +51,10 @@ public interface DBWServiceCore extends DBWService { List getNetworkHandlers(@NotNull WebSession webSession); @WebAction(requirePermissions = {}) - List getUserConnections( - @NotNull WebSession webSession, @Nullable String projectId, @Nullable String id) throws DBWebException; + List getUserConnections(@NotNull WebSession webSession, @Nullable String id) throws DBWebException; @WebAction(requirePermissions = {}) - List getConnectionFolders( - @NotNull WebSession webSession, @Nullable String projectId, @Nullable String id) throws DBWebException; + List getConnectionFolders(@NotNull WebSession webSession, @Nullable String id) throws DBWebException; @Deprecated @WebAction @@ -100,12 +98,11 @@ public interface DBWServiceCore extends DBWService { // Connections @WebAction - WebConnectionInfo getConnectionState(WebSession webSession, @Nullable String projectId, String connectionId) throws DBWebException; + WebConnectionInfo getConnectionState(WebSession webSession, String connectionId) throws DBWebException; @WebAction WebConnectionInfo initConnection( @NotNull WebSession webSession, - @Nullable String projectId, @NotNull String connectionId, @NotNull Map authProperties, @Nullable List networkCredentials, @@ -144,8 +141,7 @@ public interface DBWServiceCore extends DBWService { @NotNull WebConnectionConfig config) throws DBWebException; @WebAction - WebConnectionInfo testConnection( - @NotNull WebSession webSession, @Nullable String projectId, @NotNull WebConnectionConfig connectionConfig) throws DBWebException; + WebConnectionInfo testConnection(@NotNull WebSession webSession, @NotNull WebConnectionConfig connectionConfig) throws DBWebException; @WebAction WebNetworkEndpointInfo testNetworkHandler(@NotNull WebSession webSession, @NotNull WebNetworkHandlerConfigInput nhConfig) throws DBWebException; @@ -163,24 +159,19 @@ public interface DBWServiceCore extends DBWService { // Folders @WebAction - WebConnectionFolderInfo createConnectionFolder( - @NotNull WebSession session, @Nullable String projectId, @Nullable String folderPath, @NotNull String newName - ) throws DBWebException; + WebConnectionFolderInfo createConnectionFolder(@NotNull WebSession session, @Nullable String folderPath, @NotNull String newName) throws DBWebException; @WebAction - WebConnectionFolderInfo renameConnectionFolder( - @NotNull WebSession session, @Nullable String projectId, @NotNull String folderPath, @NotNull String newName - ) throws DBWebException; + WebConnectionFolderInfo renameConnectionFolder(@NotNull WebSession session, @NotNull String folderPath, @NotNull String newName) throws DBWebException; @WebAction - boolean deleteConnectionFolder(@NotNull WebSession session, @Nullable String projectId, @NotNull String nodePath) throws DBWebException; + boolean deleteConnectionFolder(@NotNull WebSession session, @NotNull String nodePath) throws DBWebException; /////////////////////////////////////////// // Navigator settings @WebAction - WebConnectionInfo setConnectionNavigatorSettings( - WebSession webSession, @Nullable String projectId, String id, DBNBrowseSettings settings) throws DBWebException; + WebConnectionInfo setConnectionNavigatorSettings(WebSession webSession, String id, DBNBrowseSettings settings) throws DBWebException; /////////////////////////////////////////// // Async tasks diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java index b747b6c4f1..531925bf0a 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java @@ -58,20 +58,16 @@ public class WebServiceBindingCore extends WebServiceBindingBase .dataFetcher("authModels", env -> getService(env).getAuthModels(getWebSession(env))) .dataFetcher("networkHandlers", env -> getService(env).getNetworkHandlers(getWebSession(env))) .dataFetcher("templateDataSources", env -> getService(env).getTemplateDataSources()) - .dataFetcher("userConnections", env -> getService(env).getUserConnections( - getWebSession(env), getProjectReference(env), env.getArgument("id"))) + .dataFetcher("userConnections", env -> getService(env).getUserConnections(getWebSession(env), env.getArgument("id"))) .dataFetcher("templateConnections", env -> getService(env).getTemplateConnections(getWebSession(env))) - .dataFetcher("connectionFolders", env -> getService(env).getConnectionFolders( - getWebSession(env), getProjectReference(env), env.getArgument("path"))) + .dataFetcher("connectionFolders", env -> getService(env).getConnectionFolders(getWebSession(env), env.getArgument("path"))) .dataFetcher("sessionPermissions", env -> getService(env).getSessionPermissions(getWebSession(env))) .dataFetcher("sessionState", env -> getService(env).getSessionState(getWebSession(env))) - .dataFetcher("connectionState", env -> getService(env).getConnectionState( - getWebSession(env), getProjectReference(env), env.getArgument("id"))) - .dataFetcher("connectionInfo", env -> getService(env).getConnectionState( - getWebSession(env), getProjectReference(env), env.getArgument("id"))) + .dataFetcher("connectionState", env -> getService(env).getConnectionState(getWebSession(env), env.getArgument("id"))) + .dataFetcher("connectionInfo", env -> getService(env).getConnectionState(getWebSession(env), env.getArgument("id"))) .dataFetcher("listProjects", env -> getService(env).getProjects(getWebSession(env))) @@ -105,12 +101,9 @@ public class WebServiceBindingCore extends WebServiceBindingBase GraphQLEndpoint.getServletRequest(env), GraphQLEndpoint.getServletResponse(env))) .dataFetcher("changeSessionLanguage", env -> getService(env).changeSessionLanguage(getWebSession(env), env.getArgument("locale"))) - .dataFetcher("createConnection", env -> getService(env).createConnection( - getWebSession(env), getProjectReference(env), getConnectionConfig(env))) - .dataFetcher("updateConnection", env -> getService(env).updateConnection( - getWebSession(env), getProjectReference(env), getConnectionConfig(env))) - .dataFetcher("deleteConnection", env -> getService(env).deleteConnection( - getWebSession(env), getProjectReference(env), env.getArgument("id"))) + .dataFetcher("createConnection", env -> getService(env).createConnection(getWebSession(env), getProjectReference(env), getConnectionConfig(env))) + .dataFetcher("updateConnection", env -> getService(env).updateConnection(getWebSession(env), getProjectReference(env), getConnectionConfig(env))) + .dataFetcher("deleteConnection", env -> getService(env).deleteConnection(getWebSession(env), getProjectReference(env), env.getArgument("id"))) .dataFetcher("createConnectionFromTemplate", env -> getService(env).createConnectionFromTemplate( getWebSession(env), getProjectReference(env), @@ -129,27 +122,17 @@ public class WebServiceBindingCore extends WebServiceBindingBase } return getService(env).initConnection( getWebSession(env), - getProjectReference(env), env.getArgument("id"), env.getArgument("credentials"), nhc, env.getArgument("saveCredentials")); } ) - .dataFetcher("testConnection", env -> getService(env).testConnection( - getWebSession(env), getProjectReference(env), getConnectionConfig(env) - )) - .dataFetcher("testNetworkHandler", env -> getService(env).testNetworkHandler( - getWebSession(env), new WebNetworkHandlerConfigInput(env.getArgument("config")) - )) + .dataFetcher("testConnection", env -> getService(env).testConnection(getWebSession(env), getConnectionConfig(env))) + .dataFetcher("testNetworkHandler", env -> getService(env).testNetworkHandler(getWebSession(env), new WebNetworkHandlerConfigInput(env.getArgument("config")))) .dataFetcher("closeConnection", env -> getService(env).closeConnection(getWebSession(env), getProjectReference(env), env.getArgument("id"))) - .dataFetcher("setConnectionNavigatorSettings", env -> getService(env).setConnectionNavigatorSettings( - getWebSession(env), - getProjectReference(env), - env.getArgument("id"), - WebServiceUtils.parseNavigatorSettings(env.getArgument("settings")) - )) + .dataFetcher("setConnectionNavigatorSettings", env -> getService(env).setConnectionNavigatorSettings(getWebSession(env), env.getArgument("id"), WebServiceUtils.parseNavigatorSettings(env.getArgument("settings")))) .dataFetcher("asyncTaskInfo", env -> getService(env).getAsyncTaskInfo( getWebSession(env), @@ -159,19 +142,16 @@ public class WebServiceBindingCore extends WebServiceBindingBase .dataFetcher("createConnectionFolder", env -> getService(env).createConnectionFolder( getWebSession(env), - getProjectReference(env), env.getArgument("parentFolderPath"), env.getArgument("folderName") )) .dataFetcher("renameConnectionFolder", env -> getService(env).renameConnectionFolder( getWebSession(env), - getProjectReference(env), env.getArgument("folderPath"), env.getArgument("newName") )) .dataFetcher("deleteConnectionFolder", env -> getService(env).deleteConnectionFolder( getWebSession(env), - getProjectReference(env), env.getArgument("folderPath") )) ; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java index cafa5987af..5c656ecb90 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java @@ -100,11 +100,9 @@ public class WebServiceCore implements DBWServiceCore { } @Override - public List getUserConnections( - @NotNull WebSession webSession, @Nullable String projectId, @Nullable String id - ) throws DBWebException { + public List getUserConnections(@NotNull WebSession webSession, @Nullable String id) throws DBWebException { if (id != null) { - WebConnectionInfo connectionInfo = getConnectionState(webSession, projectId, id); + WebConnectionInfo connectionInfo = getConnectionState(webSession, id); if (connectionInfo != null) { return Collections.singletonList(connectionInfo); } @@ -151,14 +149,12 @@ public class WebServiceCore implements DBWServiceCore { } @Override - public List getConnectionFolders( - @NotNull WebSession webSession, @Nullable String projectId, @Nullable String id - ) throws DBWebException { + public List getConnectionFolders(@NotNull WebSession webSession, @Nullable String id) throws DBWebException { if (id != null) { - WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(webSession, projectId, id); + WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(webSession, id); return Collections.singletonList(folderInfo); } - return webSession.getProjectById(projectId).getDataSourceRegistry().getAllFolders().stream() + return webSession.getSingletonProject().getDataSourceRegistry().getAllFolders().stream() .map(f -> new WebConnectionFolderInfo(webSession, f)).collect(Collectors.toList()); } @@ -244,23 +240,20 @@ public class WebServiceCore implements DBWServiceCore { } @Override - public WebConnectionInfo getConnectionState( - WebSession webSession, @Nullable String projectId, String connectionId - ) throws DBWebException { - return webSession.getWebConnectionInfo(projectId, connectionId); + public WebConnectionInfo getConnectionState(WebSession webSession, String connectionId) throws DBWebException { + return webSession.getWebConnectionInfo(connectionId); } @Override public WebConnectionInfo initConnection( @NotNull WebSession webSession, - @Nullable String projectId, @NotNull String connectionId, @NotNull Map authProperties, @Nullable List networkCredentials, @Nullable Boolean saveCredentials) throws DBWebException { - WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(projectId, connectionId); + WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(connectionId); connectionInfo.setSavedCredentials(authProperties, networkCredentials); DBPDataSourceContainer dataSourceContainer = connectionInfo.getDataSourceContainer(); @@ -349,7 +342,7 @@ public class WebServiceCore implements DBWServiceCore { // } DBPDataSourceRegistry sessionRegistry = webSession.getProjectById(projectId).getDataSourceRegistry(); - WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(projectId, config.getConnectionId()); + WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(config.getConnectionId()); DBPDataSourceContainer dataSource = connectionInfo.getDataSourceContainer(); webSession.addInfoMessage("Update connection - " + WebServiceUtils.getConnectionContainerInfo(dataSource)); @@ -378,7 +371,7 @@ public class WebServiceCore implements DBWServiceCore { @Override public boolean deleteConnection( @NotNull WebSession webSession, @Nullable String projectId, @NotNull String connectionId) throws DBWebException { - WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(projectId, connectionId); + WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(connectionId); if (connectionInfo.getDataSourceContainer().getProject() != webSession.getProjectById(projectId)) { throw new DBWebException("Global connection '" + connectionInfo.getName() + "' configuration cannot be deleted"); } @@ -404,9 +397,7 @@ public class WebServiceCore implements DBWServiceCore { DBPDataSourceRegistry projectRegistry = webSession.getProjectById(projectId).getDataSourceRegistry(); DBPDataSourceContainer newDataSource = projectRegistry.createDataSource(dataSourceTemplate); - ((DataSourceDescriptor) newDataSource).setNavigatorSettings( - CBApplication.getInstance().getAppConfiguration().getDefaultNavigatorSettings()); - + ((DataSourceDescriptor) newDataSource).setNavigatorSettings(CBApplication.getInstance().getAppConfiguration().getDefaultNavigatorSettings()); if (!CommonUtils.isEmpty(connectionName)) { newDataSource.setName(connectionName); } @@ -444,8 +435,7 @@ public class WebServiceCore implements DBWServiceCore { DBPDataSourceContainer newDataSource = dataSourceRegistry.createDataSource(dataSourceTemplate); - ((DataSourceDescriptor) newDataSource).setNavigatorSettings( - CBApplication.getInstance().getAppConfiguration().getDefaultNavigatorSettings()); + ((DataSourceDescriptor) newDataSource).setNavigatorSettings(CBApplication.getInstance().getAppConfiguration().getDefaultNavigatorSettings()); // Copy props from config if (!CommonUtils.isEmpty(config.getName())) { @@ -467,17 +457,14 @@ public class WebServiceCore implements DBWServiceCore { } @Override - public WebConnectionInfo testConnection( - @NotNull WebSession webSession, @Nullable String projectId, @NotNull WebConnectionConfig connectionConfig - ) throws DBWebException { + public WebConnectionInfo testConnection(@NotNull WebSession webSession, @NotNull WebConnectionConfig connectionConfig) throws DBWebException { String connectionId = connectionConfig.getConnectionId(); connectionConfig.setSaveCredentials(true); // It is used in createConnectionFromConfig - DBPDataSourceContainer dataSource = WebDataSourceUtils.getLocalOrGlobalDataSource( - CBApplication.getInstance(), webSession, projectId, connectionId); + DBPDataSourceContainer dataSource = WebDataSourceUtils.getLocalOrGlobalDataSource(CBApplication.getInstance(), webSession, connectionId); - DBPDataSourceRegistry sessionRegistry = webSession.getProjectById(projectId).getDataSourceRegistry(); + DBPDataSourceRegistry sessionRegistry = webSession.getSingletonProject().getDataSourceRegistry(); DBPDataSourceContainer testDataSource; if (dataSource != null) { testDataSource = dataSource.createCopy(dataSource.getRegistry()); @@ -561,17 +548,13 @@ public class WebServiceCore implements DBWServiceCore { } @Override - public WebConnectionInfo closeConnection( - @NotNull WebSession webSession, @Nullable String projectId, @NotNull String connectionId - ) throws DBWebException { + public WebConnectionInfo closeConnection(@NotNull WebSession webSession, @Nullable String projectId, @NotNull String connectionId) throws DBWebException { return closeAndDeleteConnection(webSession, projectId, connectionId, false); } @NotNull - private WebConnectionInfo closeAndDeleteConnection( - WebSession webSession, String projectId, String connectionId, boolean forceDelete - ) throws DBWebException { - WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(projectId, connectionId); + private WebConnectionInfo closeAndDeleteConnection(WebSession webSession, String projectId, String connectionId, boolean forceDelete) throws DBWebException { + WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(connectionId); boolean disconnected = false; DBPDataSourceContainer dataSourceContainer = connectionInfo.getDataSourceContainer(); @@ -613,7 +596,6 @@ public class WebServiceCore implements DBWServiceCore { @Override public WebConnectionFolderInfo createConnectionFolder( @NotNull WebSession session, - @Nullable String projectId, @Nullable String parentPath, @NotNull String folderName ) throws DBWebException { @@ -623,9 +605,9 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionFolderInfo parentNode = null; try { if (parentPath != null) { - parentNode = WebConnectionFolderUtils.getFolderInfo(session, projectId, parentPath); + parentNode = WebConnectionFolderUtils.getFolderInfo(session, parentPath); } - DBPDataSourceRegistry sessionRegistry = session.getProjectById(projectId).getDataSourceRegistry(); + DBPDataSourceRegistry sessionRegistry = session.getSingletonProject().getDataSourceRegistry(); DBPDataSourceFolder newFolder = WebServiceUtils.createFolder(parentNode, folderName, sessionRegistry); WebConnectionFolderInfo folderInfo = new WebConnectionFolderInfo(session, newFolder); WebServiceUtils.updateConfigAndRefreshDatabases(session); @@ -639,29 +621,26 @@ public class WebServiceCore implements DBWServiceCore { @Override public WebConnectionFolderInfo renameConnectionFolder( @NotNull WebSession session, - @Nullable String projectId, @NotNull String folderPath, @NotNull String newName ) throws DBWebException { WebConnectionFolderUtils.validateConnectionFolder(newName); - WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(session, projectId, folderPath); + WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(session, folderPath); folderInfo.getDataSourceFolder().setName(newName); WebServiceUtils.updateConfigAndRefreshDatabases(session); return folderInfo; } @Override - public boolean deleteConnectionFolder( - @NotNull WebSession session, @Nullable String projectId, @NotNull String folderPath - ) throws DBWebException { + public boolean deleteConnectionFolder(@NotNull WebSession session, @NotNull String folderPath) throws DBWebException { try { - WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(session, projectId, folderPath); + WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(session, folderPath); DBPDataSourceFolder folder = folderInfo.getDataSourceFolder(); - if (folder.getDataSourceRegistry().getProject() != session.getProjectById(projectId)) { + if (folder.getDataSourceRegistry().getProject() != session.getSingletonProject()) { throw new DBWebException("Global folder '" + folderInfo.getId() + "' cannot be deleted"); } session.addInfoMessage("Delete folder"); - DBPDataSourceRegistry sessionRegistry = session.getProjectById(projectId).getDataSourceRegistry(); + DBPDataSourceRegistry sessionRegistry = session.getSingletonProject().getDataSourceRegistry(); sessionRegistry.removeFolder(folderInfo.getDataSourceFolder(), false); WebServiceUtils.updateConfigAndRefreshDatabases(session); } catch (DBException e) { @@ -671,10 +650,8 @@ public class WebServiceCore implements DBWServiceCore { } @Override - public WebConnectionInfo setConnectionNavigatorSettings( - WebSession webSession, @Nullable String projectId, String id, DBNBrowseSettings settings - ) throws DBWebException { - WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(projectId, id); + public WebConnectionInfo setConnectionNavigatorSettings(WebSession webSession, String id, DBNBrowseSettings settings) throws DBWebException { + WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(id); DataSourceDescriptor dataSourceDescriptor = ((DataSourceDescriptor)connectionInfo.getDataSourceContainer()); dataSourceDescriptor.setNavigatorSettings(settings); dataSourceDescriptor.persistConfiguration(); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/DBWServiceNavigator.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/DBWServiceNavigator.java index 2f58304ff3..df6c570d6c 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/DBWServiceNavigator.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/DBWServiceNavigator.java @@ -34,6 +34,7 @@ public interface DBWServiceNavigator extends DBWService { @WebAction List getNavigatorNodeChildren( @NotNull WebSession session, + @Nullable String projectId, String parentPath, Integer offset, Integer limit, @@ -42,16 +43,19 @@ public interface DBWServiceNavigator extends DBWService { @WebAction List getNavigatorNodeParents( @NotNull WebSession session, + @Nullable String projectId, String nodePath) throws DBWebException; @WebAction WebNavigatorNodeInfo getNavigatorNodeInfo( @NotNull WebSession session, + @Nullable String projectId, @NotNull String nodePath) throws DBWebException; @WebAction boolean refreshNavigatorNode( @NotNull WebSession session, + @Nullable String projectId, @NotNull String nodePath) throws DBWebException; @WebAction @@ -64,17 +68,20 @@ public interface DBWServiceNavigator extends DBWService { @WebAction String renameNode( @NotNull WebSession session, + @Nullable String projectId, @NotNull String nodePath, @NotNull String newName) throws DBWebException; @WebAction int deleteNodes( @NotNull WebSession session, + @Nullable String projectId, @NotNull List nodePaths) throws DBWebException; @WebAction boolean moveNodesToFolder( @NotNull WebSession session, + @Nullable String projectId, @NotNull List nodePaths, @NotNull String folderPath) throws DBWebException; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebServiceBindingNavigator.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebServiceBindingNavigator.java index 78117d0783..97ea9d4a44 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebServiceBindingNavigator.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebServiceBindingNavigator.java @@ -38,6 +38,7 @@ public class WebServiceBindingNavigator extends WebServiceBindingBase getService(env).getNavigatorNodeChildren( getWebSession(env), + getProjectReference(env), env.getArgument("parentPath"), env.getArgument("offset"), env.getArgument("limit"), @@ -45,14 +46,17 @@ public class WebServiceBindingNavigator extends WebServiceBindingBase getService(env).getNavigatorNodeParents( getWebSession(env), + getProjectReference(env), env.getArgument("nodePath") )) .dataFetcher("navNodeInfo", env -> getService(env).getNavigatorNodeInfo( getWebSession(env), + getProjectReference(env), env.getArgument("nodePath") )) .dataFetcher("navRefreshNode", env -> getService(env).refreshNavigatorNode( getWebSession(env), + getProjectReference(env), env.getArgument("nodePath") )) .dataFetcher("navGetStructContainers", env -> getService(env).getStructContainers( @@ -65,15 +69,18 @@ public class WebServiceBindingNavigator extends WebServiceBindingBase getService(env).renameNode( getWebSession(env), + getProjectReference(env), env.getArgument("nodePath"), env.getArgument("newName") )) .dataFetcher("navDeleteNodes", env -> getService(env).deleteNodes( getWebSession(env), + getProjectReference(env), env.getArgument("nodePaths") )) .dataFetcher("navMoveNodesToFolder", env -> getService(env).moveNodesToFolder( getWebSession(env), + getProjectReference(env), env.getArgument("nodePaths"), env.getArgument("folderPath") )); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java index 650819ebdb..9d763e406b 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java @@ -68,6 +68,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { @Override public List getNavigatorNodeChildren( @NotNull WebSession session, + @Nullable String projectId, @NotNull String parentPath, Integer offset, Integer limit, @@ -81,11 +82,11 @@ public class WebServiceNavigator implements DBWServiceNavigator { DBNModel navigatorModel = session.getNavigatorModel(); List applicableDrivers = CBPlatform.getInstance().getApplicableDrivers(); if (isRootPath) { - DBNRoot rootNode = navigatorModel.getRoot(); - nodeChildren = DBNUtils.getNodeChildrenFiltered(monitor, rootNode, true); + DBNProject projectNode = navigatorModel.getRoot().getProjectNode(session.getProjectById(projectId)); + nodeChildren = DBNUtils.getNodeChildrenFiltered(monitor, projectNode.getDatabases(), true); if (SHOW_EXTRA_NODES) { // Inject extra nodes. Disabled because we use different root path for extra nodes - List extraNodes = rootNode.getExtraNodes(); + List extraNodes = projectNode.getExtraNodes(); if (!extraNodes.isEmpty()) { nodeChildren = ArrayUtils.concatArrays(extraNodes.toArray(new DBNNode[0]), nodeChildren); } @@ -146,6 +147,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { @Override public List getNavigatorNodeParents( @NotNull WebSession session, + @Nullable String projectId, String nodePath ) throws DBWebException { try { @@ -172,6 +174,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { @NotNull public WebNavigatorNodeInfo getNavigatorNodeInfo( @NotNull WebSession session, + @Nullable String projectId, @NotNull String nodePath ) throws DBWebException { try { @@ -190,6 +193,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { @Override public boolean refreshNavigatorNode( @NotNull WebSession session, + @Nullable String projectId, @NotNull String nodePath ) throws DBWebException { try { @@ -331,6 +335,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { @Override public String renameNode( @NotNull WebSession session, + @Nullable String projectId, @NotNull String nodePath, @NotNull String newName ) throws DBWebException { @@ -371,6 +376,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { @Override public int deleteNodes( @NotNull WebSession session, + @Nullable String projectId, @NotNull List nodePaths ) throws DBWebException { try { @@ -418,7 +424,9 @@ public class WebServiceNavigator implements DBWServiceNavigator { sessionRegistry.removeFolder(((DBNLocalFolder) ne.getKey()).getFolder(), false); } else if (ne.getKey() instanceof DBNResourceManagerResource) { DBNResourceManagerResource rmResource = ((DBNResourceManagerResource) ne.getKey()); - String projectId = rmResource.getResourceProject().getId(); + if (projectId == null) { + projectId = rmResource.getResourceProject().getId(); + } String resourcePath = rmResource.getResourceFolder(); session.getRmController().deleteResource(projectId, resourcePath, true); } @@ -436,6 +444,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { @Override public boolean moveNodesToFolder( @NotNull WebSession session, + @Nullable String projectId, @NotNull List nodePaths, @NotNull String folderNodePath ) throws DBWebException { @@ -467,7 +476,9 @@ public class WebServiceNavigator implements DBWServiceNavigator { throw new DBWebException("Navigator node '" + folderNodePath + "' is not a resource manager node"); } // Get project id from node - String projectId = rmOldNode.getResourceProject().getId(); + if (projectId == null) { + projectId = rmOldNode.getResourceProject().getId(); + } // Get paths from nodes String newPath = rmOldNode.getResource().getName(); if (folderNode instanceof DBNResourceManagerResource) { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java index 34e935371c..e17438f65c 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java @@ -37,11 +37,7 @@ import java.util.Map; public interface DBWServiceSQL extends DBWService { @WebAction - WebSQLContextInfo[] listContexts( - @NotNull WebSession session, - @Nullable String projectId, - @Nullable String connectionId, - @Nullable String contextId) throws DBWebException; + WebSQLContextInfo[] listContexts(@NotNull WebSession session, @Nullable String connectionId, @Nullable String contextId) throws DBWebException; @WebAction WebSQLDialectInfo getDialectInfo(@NotNull WebConnectionInfo processor) throws DBWebException; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java index b237809063..0e37ee0be7 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java @@ -53,7 +53,6 @@ public class WebServiceBindingSQL extends WebServiceBindingBase i ) .dataFetcher("sqlListContexts", env -> getService(env).listContexts(getWebSession(env), - getProjectReference(env), env.getArgument("connectionId"), env.getArgument("contextId")) ) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java index 542bc9b295..7813cd0e13 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java @@ -71,15 +71,10 @@ public class WebServiceSQL implements DBWServiceSQL { private static final Log log = Log.getLog(WebServiceSQL.class); @Override - public WebSQLContextInfo[] listContexts( - @NotNull WebSession session, - @Nullable String projectId, - @Nullable String connectionId, - @Nullable String contextId - ) throws DBWebException { + public WebSQLContextInfo[] listContexts(@NotNull WebSession session, @Nullable String connectionId, @Nullable String contextId) throws DBWebException { List conToRead = new ArrayList<>(); if (connectionId != null) { - WebConnectionInfo webConnection = WebServiceBindingBase.getWebConnection(session, projectId, connectionId); + WebConnectionInfo webConnection = WebServiceBindingBase.getWebConnection(session, connectionId); conToRead.add(webConnection); } else { conToRead.addAll(session.getConnections()); diff --git a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/local/LocalSessionHandler.java b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/local/LocalSessionHandler.java index 2421214560..bcfc001e5c 100644 --- a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/local/LocalSessionHandler.java +++ b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/local/LocalSessionHandler.java @@ -57,16 +57,16 @@ public class LocalSessionHandler extends AbstractActionSessionHandler { List connectionInfoList = webSession.getConnections(); WebConnectionInfo connectionInfo = null; if (connectionId != null) { - connectionInfo = webSession.getWebConnectionInfo(null, connectionId); + connectionInfo = webSession.getWebConnectionInfo(connectionId); } else if (connectionName != null) { List filteredConnections = connectionInfoList.stream().filter(t -> t.getName().equals(connectionName)).collect(Collectors.toList()); if (filteredConnections.size() == 1) { - connectionInfo = webSession.getWebConnectionInfo(null, filteredConnections.get(0).getId()); + connectionInfo = webSession.getWebConnectionInfo(filteredConnections.get(0).getId()); } } else if (connectionURL != null) { List filteredConnections = connectionInfoList.stream().filter(t -> t.getUrl().equals(connectionURL)).collect(Collectors.toList()); if (filteredConnections.size() == 1) { - connectionInfo = webSession.getWebConnectionInfo(null, filteredConnections.get(0).getId()); + connectionInfo = webSession.getWebConnectionInfo(filteredConnections.get(0).getId()); } } if (connectionInfo == null) { diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/CBEmbeddedSecurityController.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/CBEmbeddedSecurityController.java index c8bfadb81b..2603d661e6 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/CBEmbeddedSecurityController.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/CBEmbeddedSecurityController.java @@ -922,7 +922,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen .filter((cred) -> { AuthPropertyDescriptor property = credProfile.getCredentialParameter(cred.getKey()); - return property != null && property.getEncryption() == AuthPropertyEncryption.none; + return property != null && property.getEncryption() != AuthPropertyEncryption.none; }) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } diff --git a/webapp/packages/core-localization/src/LocalizationService.ts b/webapp/packages/core-localization/src/LocalizationService.ts index 9641210e5f..4fe038cb59 100644 --- a/webapp/packages/core-localization/src/LocalizationService.ts +++ b/webapp/packages/core-localization/src/LocalizationService.ts @@ -43,7 +43,7 @@ export class LocalizationService extends Bootstrap { } get defaultLanguage(): string { - if (this.pluginSettings.isValueDefault('defaultLanguage')) { + if (this.pluginSettings.getValue('defaultLanguage')) { return this.deprecatedPluginSettings.getValue('defaultLanguage'); } diff --git a/webapp/packages/core-projects/package.json b/webapp/packages/core-projects/package.json index 586837dcb6..082a555f0a 100644 --- a/webapp/packages/core-projects/package.json +++ b/webapp/packages/core-projects/package.json @@ -16,8 +16,6 @@ }, "peerDependencies": { "@cloudbeaver/core-di": "~0.1.0", - "@cloudbeaver/core-authentication": "~0.1.0", - "@cloudbeaver/core-sdk": "~0.1.0", "@cloudbeaver/core-root": "~0.1.0", "@cloudbeaver/core-settings": "~0.1.0", "@cloudbeaver/core-utils": "~0.1.0" diff --git a/webapp/packages/core-projects/src/ProjectsResource.ts b/webapp/packages/core-projects/src/ProjectsResource.ts index 767ca16554..c57defb311 100644 --- a/webapp/packages/core-projects/src/ProjectsResource.ts +++ b/webapp/packages/core-projects/src/ProjectsResource.ts @@ -6,41 +6,38 @@ * you may not use this file except in compliance with the License. */ -import { runInAction } from 'mobx'; +import { computed, makeObservable } from 'mobx'; import { UserInfoResource } from '@cloudbeaver/core-authentication'; import { injectable } from '@cloudbeaver/core-di'; -import { GraphQLService, ProjectInfo, CachedMapResource, CachedMapAllKey, ResourceKey, ResourceKeyUtils, resourceKeyList } from '@cloudbeaver/core-sdk'; +import { GraphQLService, CachedDataResource, RmProject } from '@cloudbeaver/core-sdk'; -export type Project = ProjectInfo; +export type Project = Omit; @injectable() -export class ProjectsResource extends CachedMapResource { +export class ProjectsResource extends CachedDataResource { + get userProject(): Project | undefined { + return this.data.filter(project => !project.shared)[0]; + } + constructor( private readonly graphQLService: GraphQLService, private readonly userInfoResource: UserInfoResource, ) { super([]); - this.sync(this.userInfoResource); this.userInfoResource.onUserChange.addPostHandler(() => { - this.clear(); + this.loaded = false; + this.markOutdated(); + }); + + makeObservable(this, { + userProject: computed, }); } - protected async loader(key: ResourceKey): Promise> { - const all = ResourceKeyUtils.includes(key, CachedMapAllKey); - + protected async loader(): Promise { const { projects } = await this.graphQLService.sdk.getProjectList(); - - runInAction(() => { - if (all) { - this.data.clear(); - } - - this.set(resourceKeyList(projects.map(project => project.id)), projects); - }); - - return this.data; + return projects; } } \ No newline at end of file diff --git a/webapp/packages/core-projects/src/ProjectsService.ts b/webapp/packages/core-projects/src/ProjectsService.ts deleted file mode 100644 index c7ca924550..0000000000 --- a/webapp/packages/core-projects/src/ProjectsService.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2022 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ - -import { computed, makeObservable } from 'mobx'; - -import { UserInfoResource } from '@cloudbeaver/core-authentication'; -import { injectable } from '@cloudbeaver/core-di'; - -import { Project, ProjectsResource } from './ProjectsResource'; - -@injectable() -export class ProjectsService { - get activeProject(): Project | undefined { - let project: Project | undefined; - - if (this.activeProjectId) { - project = this.projectsResource.get(this.activeProjectId); - } - - if (!project && this.userInfoResource.data) { - project = this.projectsResource.get(this.userInfoResource.data.userId); - } - - if (!project && this.projectsResource.values.length > 0) { - project = this.projectsResource.values[0]; - } - - return project; - } - - private activeProjectId: string | null; - - constructor( - private readonly projectsResource: ProjectsResource, - private readonly userInfoResource: UserInfoResource - ) { - this.activeProjectId = null; - - makeObservable(this, { - activeProject: computed, - }); - } - - setActiveProject(project: Project): void { - this.activeProjectId = project.id; - } -} \ No newline at end of file diff --git a/webapp/packages/core-projects/src/index.ts b/webapp/packages/core-projects/src/index.ts index e733cd6d45..9b0d44ce39 100644 --- a/webapp/packages/core-projects/src/index.ts +++ b/webapp/packages/core-projects/src/index.ts @@ -1,3 +1,2 @@ export * from './ProjectsResource'; -export * from './ProjectsService'; export { manifest as coreProjectsManifest } from './manifest'; diff --git a/webapp/packages/core-projects/src/manifest.ts b/webapp/packages/core-projects/src/manifest.ts index ee5574c003..fc3c58f809 100644 --- a/webapp/packages/core-projects/src/manifest.ts +++ b/webapp/packages/core-projects/src/manifest.ts @@ -9,7 +9,6 @@ import type { PluginManifest } from '@cloudbeaver/core-di'; import { ProjectsResource } from './ProjectsResource'; -import { ProjectsService } from './ProjectsService'; export const manifest: PluginManifest = { info: { @@ -18,6 +17,5 @@ export const manifest: PluginManifest = { providers: [ ProjectsResource, - ProjectsService, ], }; diff --git a/webapp/packages/core-sdk/src/CustomGraphQLClient.ts b/webapp/packages/core-sdk/src/CustomGraphQLClient.ts index be8b4193f7..1e1bc88d73 100644 --- a/webapp/packages/core-sdk/src/CustomGraphQLClient.ts +++ b/webapp/packages/core-sdk/src/CustomGraphQLClient.ts @@ -6,9 +6,8 @@ * you may not use this file except in compliance with the License. */ -import { GraphQLClient, ClientError, resolveRequestDocument } from 'graphql-request'; -import { parseRequestArgs } from 'graphql-request/dist/parseArgs'; -import type { RequestDocument, RequestOptions, Variables } from 'graphql-request/dist/types'; +import { GraphQLClient, ClientError } from 'graphql-request'; +import type { RequestDocument, Variables } from 'graphql-request/dist/types'; import type * as Dom from 'graphql-request/dist/types.dom'; import { GQLError } from './GQLError'; @@ -28,16 +27,15 @@ export class CustomGraphQLClient extends GraphQLClient { this.interceptors.push(interceptor); } - request(document: RequestDocument, variables?: V, requestHeaders?: Dom.RequestInit['headers']): Promise; - request(options: RequestOptions): Promise; + // @ts-expect-error should be fixed somehow request( - document: RequestDocument | RequestOptions, + document: RequestDocument, variables?: V, requestHeaders?: Dom.RequestInit['headers'] ): Promise { return this.interceptors.reduce( (accumulator, interceptor) => interceptor(accumulator), - this.overrideRequest(document, variables, requestHeaders) + this.overrideRequest(document as string, variables, requestHeaders) ); } @@ -61,20 +59,13 @@ export class CustomGraphQLClient extends GraphQLClient { } } - private async overrideRequest( - documentOrOptions: RequestDocument | RequestOptions, - variables?: V, - requestHeaders?: Dom.RequestInit['headers'] - ): Promise { + private async overrideRequest(query: string, variables?: Variables, requestHeaders?: Dom.RequestInit['headers']): Promise { this.blockRequestsReasonHandler(); try { - const requestOptions = parseRequestArgs(documentOrOptions, variables, requestHeaders); - const { query, operationName } = resolveRequestDocument(requestOptions.document); - const response = await this.rawRequest(query, variables, requestHeaders); // TODO: seems here can be undefined - return response.data; + return response.data as T; } catch (error: any) { if (isClientError(error)) { if (isObjectError(error)) { diff --git a/webapp/packages/core-sdk/src/queries/project/getProjectList.gql b/webapp/packages/core-sdk/src/queries/project/getProjectList.gql deleted file mode 100644 index 11229bfb34..0000000000 --- a/webapp/packages/core-sdk/src/queries/project/getProjectList.gql +++ /dev/null @@ -1,7 +0,0 @@ -query getProjectList { - projects: listProjects { - id, - name, - description, - } -} \ No newline at end of file diff --git a/webapp/packages/core-sdk/src/queries/resource-manager/getResourceProjectList.gql b/webapp/packages/core-sdk/src/queries/resource-manager/getProjectList.gql similarity index 57% rename from webapp/packages/core-sdk/src/queries/resource-manager/getResourceProjectList.gql rename to webapp/packages/core-sdk/src/queries/resource-manager/getProjectList.gql index a45ecc9e84..de56777f92 100644 --- a/webapp/packages/core-sdk/src/queries/resource-manager/getResourceProjectList.gql +++ b/webapp/packages/core-sdk/src/queries/resource-manager/getProjectList.gql @@ -1,8 +1,7 @@ -query getResourceProjectList { +query getProjectList { projects: rmListProjects { id, name, shared, - description, } } \ No newline at end of file diff --git a/webapp/packages/core-sdk/src/sdk.ts b/webapp/packages/core-sdk/src/sdk.ts index 702b861b24..340a3be106 100644 --- a/webapp/packages/core-sdk/src/sdk.ts +++ b/webapp/packages/core-sdk/src/sdk.ts @@ -358,9 +358,7 @@ export interface Mutation { openSession: SessionInfo; readLobValue: Scalars['String']; refreshSessionConnections?: Maybe; - rmCreateProject?: Maybe; rmCreateResource: Scalars['String']; - rmDeleteProject: Scalars['Boolean']; rmDeleteResource?: Maybe; rmMoveResource: Scalars['String']; rmWriteResourceStringContent: Scalars['String']; @@ -446,39 +444,33 @@ export interface MutationCloseConnectionArgs { export interface MutationCopyConnectionFromNodeArgs { config?: InputMaybe; nodePath: Scalars['String']; - projectId?: InputMaybe; } export interface MutationCreateConnectionArgs { config: ConnectionConfig; - projectId?: InputMaybe; } export interface MutationCreateConnectionFolderArgs { folderName: Scalars['String']; parentFolderPath?: InputMaybe; - projectId?: InputMaybe; } export interface MutationCreateConnectionFromTemplateArgs { connectionName?: InputMaybe; - projectId?: InputMaybe; templateId: Scalars['ID']; } export interface MutationDeleteConnectionArgs { id: Scalars['ID']; - projectId?: InputMaybe; } export interface MutationDeleteConnectionFolderArgs { folderPath: Scalars['ID']; - projectId?: InputMaybe; } @@ -492,21 +484,18 @@ export interface MutationInitConnectionArgs { export interface MutationNavDeleteNodesArgs { nodePaths: Array; - projectId?: InputMaybe; } export interface MutationNavMoveNodesToFolderArgs { folderPath: Scalars['ID']; nodePaths: Array; - projectId?: InputMaybe; } export interface MutationNavRenameNodeArgs { newName: Scalars['String']; nodePath: Scalars['ID']; - projectId?: InputMaybe; } @@ -529,12 +518,6 @@ export interface MutationReadLobValueArgs { } -export interface MutationRmCreateProjectArgs { - description?: InputMaybe; - projectName: Scalars['String']; -} - - export interface MutationRmCreateResourceArgs { isFolder: Scalars['Boolean']; projectId: Scalars['String']; @@ -542,11 +525,6 @@ export interface MutationRmCreateResourceArgs { } -export interface MutationRmDeleteProjectArgs { - projectId: Scalars['ID']; -} - - export interface MutationRmDeleteResourceArgs { projectId: Scalars['String']; recursive: Scalars['Boolean']; @@ -620,7 +598,6 @@ export interface MutationTestNetworkHandlerArgs { export interface MutationUpdateConnectionArgs { config: ConnectionConfig; - projectId?: InputMaybe; } @@ -657,7 +634,6 @@ export interface NavigatorNodeInfo { nodeDetails?: Maybe>; nodeType?: Maybe; object?: Maybe; - projectId?: Maybe; } export interface NavigatorSettings { @@ -795,12 +771,6 @@ export interface ProductInfo { version: Scalars['String']; } -export interface ProjectInfo { - description?: Maybe; - id: Scalars['String']; - name: Scalars['String']; -} - export interface Query { activeUser?: Maybe; allConnections: Array; @@ -837,7 +807,6 @@ export interface Query { listAuthProviderConfigurations: Array; listFeatureSets: Array; listPermissions: Array; - listProjects: Array; listRoles: Array; listUserProfileProperties: Array; listUsers: Array; @@ -1057,7 +1026,6 @@ export interface QueryNavGetStructContainersArgs { catalog?: InputMaybe; connectionId: Scalars['ID']; contextId?: InputMaybe; - projectId?: InputMaybe; } @@ -1066,25 +1034,21 @@ export interface QueryNavNodeChildrenArgs { offset?: InputMaybe; onlyFolders?: InputMaybe; parentPath: Scalars['ID']; - projectId?: InputMaybe; } export interface QueryNavNodeInfoArgs { nodePath: Scalars['ID']; - projectId?: InputMaybe; } export interface QueryNavNodeParentsArgs { nodePath: Scalars['ID']; - projectId?: InputMaybe; } export interface QueryNavRefreshNodeArgs { nodePath: Scalars['ID']; - projectId?: InputMaybe; } @@ -1254,8 +1218,6 @@ export interface QueryUserConnectionsArgs { } export interface RmProject { - canEditConnection: Scalars['Boolean']; - canEditResource: Scalars['Boolean']; createTime: Scalars['DateTime']; creator: Scalars['String']; description?: Maybe; @@ -1264,10 +1226,6 @@ export interface RmProject { shared: Scalars['Boolean']; } -export enum RmProjectPermission { - ResourceEdit = 'resource_edit' -} - export interface RmResource { folder: Scalars['Boolean']; length: Scalars['Int']; @@ -2339,11 +2297,6 @@ export type NavRenameNodeMutationVariables = Exact<{ export type NavRenameNodeMutation = { navRenameNode?: string }; -export type GetProjectListQueryVariables = Exact<{ [key: string]: never }>; - - -export type GetProjectListQuery = { projects: Array<{ id: string; name: string; description?: string }> }; - export type CreateResourceMutationVariables = Exact<{ projectId: Scalars['String']; resourcePath: Scalars['String']; @@ -2362,6 +2315,11 @@ export type DeleteResourceMutationVariables = Exact<{ export type DeleteResourceMutation = { rmDeleteResource?: boolean }; +export type GetProjectListQueryVariables = Exact<{ [key: string]: never }>; + + +export type GetProjectListQuery = { projects: Array<{ id: string; name: string; shared: boolean }> }; + export type GetResourceListQueryVariables = Exact<{ projectId: Scalars['String']; folder?: InputMaybe; @@ -2373,11 +2331,6 @@ export type GetResourceListQueryVariables = Exact<{ export type GetResourceListQuery = { resources: Array<{ name: string; folder: boolean; length: number }> }; -export type GetResourceProjectListQueryVariables = Exact<{ [key: string]: never }>; - - -export type GetResourceProjectListQuery = { projects: Array<{ id: string; name: string; shared: boolean; description?: string }> }; - export type MoveResourceMutationVariables = Exact<{ projectId: Scalars['String']; oldPath: Scalars['String']; @@ -3731,15 +3684,6 @@ export const NavRenameNodeDocument = ` navRenameNode(nodePath: $nodePath, newName: $newName) } `; -export const GetProjectListDocument = ` - query getProjectList { - projects: listProjects { - id - name - description - } -} - `; export const CreateResourceDocument = ` mutation createResource($projectId: String!, $resourcePath: String!, $isFolder: Boolean!) { rmCreateResource( @@ -3758,6 +3702,15 @@ export const DeleteResourceDocument = ` ) } `; +export const GetProjectListDocument = ` + query getProjectList { + projects: rmListProjects { + id + name + shared + } +} + `; export const GetResourceListDocument = ` query getResourceList($projectId: String!, $folder: String, $nameMask: String, $readProperties: Boolean, $readHistory: Boolean) { resources: rmListResources( @@ -3773,16 +3726,6 @@ export const GetResourceListDocument = ` } } `; -export const GetResourceProjectListDocument = ` - query getResourceProjectList { - projects: rmListProjects { - id - name - shared - description - } -} - `; export const MoveResourceDocument = ` mutation moveResource($projectId: String!, $oldPath: String!, $newPath: String!) { rmMoveResource( @@ -4286,21 +4229,18 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = navRenameNode(variables: NavRenameNodeMutationVariables, requestHeaders?: Dom.RequestInit['headers']): Promise { return withWrapper(wrappedRequestHeaders => client.request(NavRenameNodeDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), 'navRenameNode', 'mutation'); }, - getProjectList(variables?: GetProjectListQueryVariables, requestHeaders?: Dom.RequestInit['headers']): Promise { - return withWrapper(wrappedRequestHeaders => client.request(GetProjectListDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), 'getProjectList', 'query'); - }, createResource(variables: CreateResourceMutationVariables, requestHeaders?: Dom.RequestInit['headers']): Promise { return withWrapper(wrappedRequestHeaders => client.request(CreateResourceDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), 'createResource', 'mutation'); }, deleteResource(variables: DeleteResourceMutationVariables, requestHeaders?: Dom.RequestInit['headers']): Promise { return withWrapper(wrappedRequestHeaders => client.request(DeleteResourceDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), 'deleteResource', 'mutation'); }, + getProjectList(variables?: GetProjectListQueryVariables, requestHeaders?: Dom.RequestInit['headers']): Promise { + return withWrapper(wrappedRequestHeaders => client.request(GetProjectListDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), 'getProjectList', 'query'); + }, getResourceList(variables: GetResourceListQueryVariables, requestHeaders?: Dom.RequestInit['headers']): Promise { return withWrapper(wrappedRequestHeaders => client.request(GetResourceListDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), 'getResourceList', 'query'); }, - getResourceProjectList(variables?: GetResourceProjectListQueryVariables, requestHeaders?: Dom.RequestInit['headers']): Promise { - return withWrapper(wrappedRequestHeaders => client.request(GetResourceProjectListDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), 'getResourceProjectList', 'query'); - }, moveResource(variables: MoveResourceMutationVariables, requestHeaders?: Dom.RequestInit['headers']): Promise { return withWrapper(wrappedRequestHeaders => client.request(MoveResourceDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), 'moveResource', 'mutation'); }, diff --git a/webapp/packages/core-theming/src/ThemeSettingsService.test.ts b/webapp/packages/core-theming/src/ThemeSettingsService.test.ts index 459a85403f..3cc90236f4 100644 --- a/webapp/packages/core-theming/src/ThemeSettingsService.test.ts +++ b/webapp/packages/core-theming/src/ThemeSettingsService.test.ts @@ -35,7 +35,7 @@ const equalConfigA = { 'core.user': { defaultTheme: testValueA, } as IThemeSettings, - core: { + plugin: { theming: { defaultTheme: testValueA, } as IThemeSettings, @@ -46,7 +46,7 @@ const equalConfigB = { 'core.user': { defaultTheme: testValueB, } as IThemeSettings, - core: { + plugin: { theming: { defaultTheme: testValueB, } as IThemeSettings, diff --git a/webapp/packages/core-theming/src/ThemeSettingsService.ts b/webapp/packages/core-theming/src/ThemeSettingsService.ts index aaa3502808..451dc4887e 100644 --- a/webapp/packages/core-theming/src/ThemeSettingsService.ts +++ b/webapp/packages/core-theming/src/ThemeSettingsService.ts @@ -26,7 +26,7 @@ export class ThemeSettingsService { readonly deprecatedSettings: PluginSettings; constructor(private readonly pluginManagerService: PluginManagerService) { - this.settings = this.pluginManagerService.getCoreSettings('theming', defaultThemeSettings); + this.settings = this.pluginManagerService.getPluginSettings('theming', defaultThemeSettings); this.deprecatedSettings = this.pluginManagerService.getCoreSettings('user', defaultThemeSettings); } } diff --git a/webapp/packages/plugin-resource-manager/src/NavNodes/ResourceFoldersBootstrap.ts b/webapp/packages/plugin-resource-manager/src/NavNodes/ResourceFoldersBootstrap.ts index 11746be06f..644a9aa5ac 100644 --- a/webapp/packages/plugin-resource-manager/src/NavNodes/ResourceFoldersBootstrap.ts +++ b/webapp/packages/plugin-resource-manager/src/NavNodes/ResourceFoldersBootstrap.ts @@ -16,6 +16,7 @@ import { NotificationService } from '@cloudbeaver/core-events'; import type { IExecutionContextProvider } from '@cloudbeaver/core-executor'; import { LocalizationService } from '@cloudbeaver/core-localization'; import { NavTreeResource, NavNodeManagerService, NavNodeInfoResource, type INodeMoveData, navNodeMoveContext, getNodesFromContext, ENodeMoveType, type NavNode } from '@cloudbeaver/core-navigation-tree'; +import { ProjectsResource } from '@cloudbeaver/core-projects'; import { ResourceKey, resourceKeyList, ResourceKeyUtils } from '@cloudbeaver/core-sdk'; import { createPath } from '@cloudbeaver/core-utils'; import { ActionService, MenuService, ACTION_NEW_FOLDER, DATA_CONTEXT_MENU, IAction, IDataContextProvider } from '@cloudbeaver/core-view'; @@ -24,7 +25,6 @@ import { DATA_CONTEXT_ELEMENTS_TREE, MENU_ELEMENTS_TREE_TOOLS, type IElementsTre import { NAV_NODE_TYPE_RM_PROJECT } from '../NAV_NODE_TYPE_RM_PROJECT'; import { NavResourceNodeService } from '../NavResourceNodeService'; import { ResourceManagerResource } from '../ResourceManagerResource'; -import { ResourceProjectsResource } from '../ResourceProjectsResource'; import { RESOURCES_NODE_PATH } from '../RESOURCES_NODE_PATH'; import { NAV_NODE_TYPE_RM_RESOURCE } from './NAV_NODE_TYPE_RM_RESOURCE'; @@ -39,7 +39,7 @@ export class ResourceFoldersBootstrap extends Bootstrap { private readonly navNodeManagerService: NavNodeManagerService, private readonly navResourceNodeService: NavResourceNodeService, private readonly resourceManagerResource: ResourceManagerResource, - private readonly resourceProjectsResource: ResourceProjectsResource, + private readonly projectsResource: ProjectsResource, private readonly commonDialogService: CommonDialogService, private readonly actionService: ActionService, private readonly menuService: MenuService, @@ -70,7 +70,7 @@ export class ResourceFoldersBootstrap extends Bootstrap { return true; } - untracked(async () => await this.resourceProjectsResource.load()); + untracked(async () => await this.projectsResource.load()); return this.getTargetNode(tree) === undefined; }, handler: this.elementsTreeActionHandler.bind(this), @@ -111,10 +111,10 @@ export class ResourceFoldersBootstrap extends Bootstrap { return; } - await this.resourceProjectsResource.load(); - const projectPath = createPath(RESOURCES_NODE_PATH, this.resourceProjectsResource.userProject?.id); + await this.projectsResource.load(); + const projectPath = createPath(RESOURCES_NODE_PATH, this.projectsResource.userProject?.id); - if (!(this.resourceProjectsResource.userProject?.id === data.key.projectId)) { + if (!(this.projectsResource.userProject?.id === data.key.projectId)) { return; } @@ -154,7 +154,7 @@ export class ResourceFoldersBootstrap extends Bootstrap { if (tree === undefined) { return; } - await this.resourceProjectsResource.load(); + await this.projectsResource.load(); switch (action) { case ACTION_NEW_FOLDER: { @@ -245,7 +245,7 @@ export class ResourceFoldersBootstrap extends Bootstrap { targetNode = this.navNodeInfoResource.get(targetFolder); } - const projectPath = createPath(RESOURCES_NODE_PATH, this.resourceProjectsResource.userProject?.id); + const projectPath = createPath(RESOURCES_NODE_PATH, this.projectsResource.userProject?.id); if (!targetNode?.id.startsWith(projectPath)) { targetNode = undefined; } diff --git a/webapp/packages/plugin-resource-manager/src/ResourceProjectsResource.ts b/webapp/packages/plugin-resource-manager/src/ResourceProjectsResource.ts deleted file mode 100644 index 58f8381c0d..0000000000 --- a/webapp/packages/plugin-resource-manager/src/ResourceProjectsResource.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2022 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ - -import { computed, makeObservable } from 'mobx'; - -import { UserInfoResource } from '@cloudbeaver/core-authentication'; -import { injectable } from '@cloudbeaver/core-di'; -import { GraphQLService, CachedDataResource, RmProject } from '@cloudbeaver/core-sdk'; - -export type Project = Omit; - -@injectable() -export class ResourceProjectsResource extends CachedDataResource { - get userProject(): Project | undefined { - return this.data.filter(project => !project.shared)[0]; - } - - constructor( - private readonly graphQLService: GraphQLService, - private readonly userInfoResource: UserInfoResource, - ) { - super([]); - - this.userInfoResource.onUserChange.addPostHandler(() => { - this.loaded = false; - this.markOutdated(); - }); - - makeObservable(this, { - userProject: computed, - }); - } - - protected async loader(): Promise { - const { projects } = await this.graphQLService.sdk.getResourceProjectList(); - return projects; - } -} \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager/src/Tree/ResourceManagerTree.tsx b/webapp/packages/plugin-resource-manager/src/Tree/ResourceManagerTree.tsx index a244bfe1c0..2ad2447688 100644 --- a/webapp/packages/plugin-resource-manager/src/Tree/ResourceManagerTree.tsx +++ b/webapp/packages/plugin-resource-manager/src/Tree/ResourceManagerTree.tsx @@ -12,11 +12,11 @@ import styled, { css } from 'reshadow'; import { Loader, useDataResource } from '@cloudbeaver/core-blocks'; import { useService } from '@cloudbeaver/core-di'; import { useTranslate } from '@cloudbeaver/core-localization'; +import { ProjectsResource } from '@cloudbeaver/core-projects'; import { createPath } from '@cloudbeaver/core-utils'; import { CaptureView } from '@cloudbeaver/core-view'; import { NavigationTreeService, ElementsTree, NavigationNodeControl } from '@cloudbeaver/plugin-navigation-tree'; -import { ResourceProjectsResource } from '../ResourceProjectsResource'; import { RESOURCES_NODE_PATH } from '../RESOURCES_NODE_PATH'; const styles = css` @@ -56,7 +56,7 @@ export const ResourceManagerTree = observer(function ResourceManagerTree() { const translate = useTranslate(); const navTreeService = useService(NavigationTreeService); - const { resource } = useDataResource(ResourceManagerTree, ResourceProjectsResource, undefined); + const { resource } = useDataResource(ResourceManagerTree, ProjectsResource, undefined); return styled(styles)( diff --git a/webapp/packages/plugin-resource-manager/src/index.ts b/webapp/packages/plugin-resource-manager/src/index.ts index a7c53a91ba..ae7b19be16 100644 --- a/webapp/packages/plugin-resource-manager/src/index.ts +++ b/webapp/packages/plugin-resource-manager/src/index.ts @@ -7,5 +7,4 @@ export * from './NavResourceNodeService'; export * from './ResourceManagerResource'; export * from './SaveScriptDialog'; export * from './ResourceManagerService'; -export * from './ResourceProjectsResource'; export * from './RESOURCES_NODE_PATH'; \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager/src/manifest.ts b/webapp/packages/plugin-resource-manager/src/manifest.ts index d5ea903ed0..f61166b5ee 100644 --- a/webapp/packages/plugin-resource-manager/src/manifest.ts +++ b/webapp/packages/plugin-resource-manager/src/manifest.ts @@ -15,7 +15,6 @@ import { PluginBootstrap } from './PluginBootstrap'; import { ResourceManagerResource } from './ResourceManagerResource'; import { ResourceManagerService } from './ResourceManagerService'; import { ResourceManagerSettingsService } from './ResourceManagerSettingsService'; -import { ResourceProjectsResource } from './ResourceProjectsResource'; export const resourceManagerPlugin: PluginManifest = { info: { name: 'Resource manager plugin' }, @@ -27,6 +26,5 @@ export const resourceManagerPlugin: PluginManifest = { ResourceManagerResource, NavResourceNodeService, ResourceFoldersBootstrap, - ResourceProjectsResource, ], }; \ No newline at end of file diff --git a/webapp/packages/plugin-sql-editor-navigation-tab-resource/src/PluginBootstrap.ts b/webapp/packages/plugin-sql-editor-navigation-tab-resource/src/PluginBootstrap.ts index ad452d3422..ac2ebef6c9 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab-resource/src/PluginBootstrap.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab-resource/src/PluginBootstrap.ts @@ -11,11 +11,12 @@ import { CommonDialogService, DialogueStateResult } from '@cloudbeaver/core-dial import { NotificationService } from '@cloudbeaver/core-events'; import type { IExecutionContextProvider } from '@cloudbeaver/core-executor'; import { NavNodeManagerService, NavTreeResource, NavNodeInfoResource, NodeManagerUtils, type INodeNavigationData, NavigationType } from '@cloudbeaver/core-navigation-tree'; +import { ProjectsResource } from '@cloudbeaver/core-projects'; import { DATA_CONTEXT_TAB_ID } from '@cloudbeaver/core-ui'; import { createPath } from '@cloudbeaver/core-utils'; import { ActionService, ACTION_SAVE, DATA_CONTEXT_MENU, MenuService } from '@cloudbeaver/core-view'; import { NavigationTabsService } from '@cloudbeaver/plugin-navigation-tabs'; -import { NavResourceNodeService, RESOURCE_NODE_TYPE, SaveScriptDialog, ResourceManagerService, RESOURCES_NODE_PATH, ResourceProjectsResource } from '@cloudbeaver/plugin-resource-manager'; +import { NavResourceNodeService, RESOURCE_NODE_TYPE, SaveScriptDialog, ResourceManagerService, RESOURCES_NODE_PATH } from '@cloudbeaver/plugin-resource-manager'; import { DATA_CONTEXT_SQL_EDITOR_STATE, getSqlEditorName, SqlDataSourceService, SqlEditorService, SqlEditorSettingsService, SQL_EDITOR_ACTIONS_MENU } from '@cloudbeaver/plugin-sql-editor'; import { isSQLEditorTab, SqlEditorNavigatorService } from '@cloudbeaver/plugin-sql-editor-navigation-tab'; @@ -36,7 +37,7 @@ export class PluginBootstrap extends Bootstrap { private readonly notificationService: NotificationService, private readonly sqlEditorNavigatorService: SqlEditorNavigatorService, private readonly resourceManagerService: ResourceManagerService, - private readonly resourceProjectsResource: ResourceProjectsResource, + private readonly projectsResource: ProjectsResource, private readonly sqlEditorTabResourceService: SqlEditorTabResourceService, private readonly commonDialogService: CommonDialogService, private readonly actionService: ActionService, @@ -85,9 +86,9 @@ export class PluginBootstrap extends Bootstrap { if (result !== DialogueStateResult.Rejected && result !== DialogueStateResult.Resolved) { try { - await this.resourceProjectsResource.load(); + await this.projectsResource.load(); const scriptName = `${result.trim()}.${SCRIPT_EXTENSION}`; - const folder = createPath(RESOURCES_NODE_PATH, this.resourceProjectsResource.userProject?.id); + const folder = createPath(RESOURCES_NODE_PATH, this.projectsResource.userProject?.id); const resourceData = this.navResourceNodeService.getResourceData(folder); if (!resourceData) {