Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/devel' into CB-5178-redesign-adm…
Browse files Browse the repository at this point in the history
…inistration-menu
  • Loading branch information
Wroud committed Jul 16, 2024
2 parents 8580ac0 + b48684b commit 07761fe
Show file tree
Hide file tree
Showing 164 changed files with 1,530 additions and 1,251 deletions.
19 changes: 4 additions & 15 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,16 @@
}
},
{
"label": "Generate dev proprties for CBCE",
"label": "Generate Eclipse PDE CloudBeaver",
"type": "shell",
"command": "mvn",
"osx": {
"args": [
"package",
"-q",
"exec:java",
"-Dexec.args= -eclipse.version ${eclipse-version} -config ${workspaceFolder}/../idea-workspace-dbeaver/osgi-app.properties -productFile ${workspaceFolder}/server/product/web-server/CloudbeaverServer.product -projectsFolder ${workspaceFolder}/../ -eclipse ${workspaceFolder}/../dbeaver-workspace/dependencies -output ${workspaceFolder}/../dbeaver-workspace/products/CloudbeaverServer.product"
]
"command": "./generate_workspace.sh"
},
"windows": {
"args": [
"package",
"-q",
"exec:java",
"-Dexec.args= -eclipse.version ${eclipse-version} -config ${workspaceFolder}/../cloudbeaver/osgi-app.properties"
]
"command": "./generate_workspace.cmd"
},
"options": {
"cwd": "${workspaceFolder}/../idea-rcp-launch-config-generator"
"cwd": "${workspaceFolder}/../cloudbeaver"
},
"presentation": {
"reveal": "silent",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@
import io.cloudbeaver.utils.CBModelConstants;
import io.cloudbeaver.utils.WebAppUtils;
import io.cloudbeaver.utils.WebCommonUtils;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBConstants;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.DBPDataSourceFolder;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.admin.sessions.DBAServerSessionManager;
import org.jkiss.dbeaver.model.app.DBPProject;
import org.jkiss.dbeaver.model.connection.DBPAuthModelDescriptor;
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
Expand All @@ -40,6 +39,7 @@
import org.jkiss.dbeaver.model.navigator.DBNDataSource;
import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor;
import org.jkiss.dbeaver.model.preferences.DBPPropertySource;
import org.jkiss.dbeaver.model.rm.RMConstants;
import org.jkiss.dbeaver.model.rm.RMProjectPermission;
import org.jkiss.dbeaver.model.runtime.DBRRunnableParametrized;
import org.jkiss.dbeaver.runtime.DBWorkbench;
Expand All @@ -56,6 +56,17 @@ public class WebConnectionInfo {

private static final Log log = Log.getLog(WebConnectionInfo.class);
public static final String SECURED_VALUE = "********";

private static final String FEATURE_HAS_TOOLS = "hasTools";
private static final String FEATURE_CONNECTED = "connected";
private static final String FEATURE_VIRTUAL = "virtual";
private static final String FEATURE_TEMPORARY = "temporary";
private static final String FEATURE_READ_ONLY = "readOnly";
private static final String FEATURE_PROVIDED = "provided";
private static final String FEATURE_MANAGEABLE = "manageable";

private static final String TOOL_SESSION_MANAGER = "sessionManager";

private final WebSession session;
private final DBPDataSourceContainer dataSourceContainer;
private WebServerError connectError;
Expand Down Expand Up @@ -243,22 +254,25 @@ public String[] getFeatures() {
List<String> features = new ArrayList<>();

if (dataSourceContainer.isConnected()) {
features.add("connected");
features.add(FEATURE_CONNECTED);
if (!getTools().isEmpty()) {
features.add(FEATURE_HAS_TOOLS);
}
}
if (dataSourceContainer.isHidden()) {
features.add("virtual");
features.add(FEATURE_VIRTUAL);
}
if (dataSourceContainer.isTemporary()) {
features.add("temporary");
features.add(FEATURE_TEMPORARY);
}
if (dataSourceContainer.isConnectionReadOnly()) {
features.add("readOnly");
features.add(FEATURE_READ_ONLY);
}
if (dataSourceContainer.isProvided()) {
features.add("provided");
features.add(FEATURE_PROVIDED);
}
if (dataSourceContainer.isManageable()) {
features.add("manageable");
features.add(FEATURE_MANAGEABLE);
}

return features.toArray(new String[0]);
Expand Down Expand Up @@ -475,4 +489,18 @@ public List<WebSecretInfo> getSharedSecrets() throws DBException {
.collect(Collectors.toList());
}

@NotNull
@Property
public List<String> getTools() {
if (!session.hasPermission(RMConstants.PERMISSION_DATABASE_DEVELOPER)) {
return List.of();
}
List<String> tools = new ArrayList<>();
// checks inside that datasource is not null in container, and it is adaptable to session manager class
if (DBUtils.getAdapter(DBAServerSessionManager.class, dataSourceContainer) != null) {
tools.add(TOOL_SESSION_MANAGER);
}
return tools;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,8 @@ type ConnectionInfo {

projectId: ID!
requiredAuth: String

tools: [String!]! @since(version: "24.1.3")
}

type ConnectionFolderInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
import com.google.gson.InstanceCreator;
import io.cloudbeaver.model.WebConnectionConfig;
import io.cloudbeaver.model.WebNetworkHandlerConfigInput;
import io.cloudbeaver.model.WebPropertyInfo;
import io.cloudbeaver.model.session.WebActionParameters;
import io.cloudbeaver.model.session.WebSession;
import io.cloudbeaver.registry.WebAuthProviderDescriptor;
import io.cloudbeaver.registry.WebAuthProviderRegistry;
import io.cloudbeaver.server.CBAppConfig;
import io.cloudbeaver.server.CBApplication;
import io.cloudbeaver.server.CBPlatform;
import io.cloudbeaver.service.navigator.WebPropertyFilter;
import io.cloudbeaver.utils.WebAppUtils;
import io.cloudbeaver.utils.WebCommonUtils;
import io.cloudbeaver.utils.WebDataSourceUtils;
Expand All @@ -36,6 +38,7 @@
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBConstants;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.DBPObject;
import org.jkiss.dbeaver.model.access.DBAAuthCredentials;
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
import org.jkiss.dbeaver.model.app.DBPProject;
Expand All @@ -46,6 +49,7 @@
import org.jkiss.dbeaver.model.navigator.DBNModel;
import org.jkiss.dbeaver.model.navigator.DBNProject;
import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration;
import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor;
import org.jkiss.dbeaver.model.rm.RMProjectType;
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings;
Expand All @@ -54,6 +58,7 @@
import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor;
import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry;
import org.jkiss.dbeaver.runtime.properties.PropertyCollector;
import org.jkiss.utils.CommonUtils;

import java.io.InputStream;
Expand Down Expand Up @@ -365,4 +370,35 @@ public static Set<String> getApplicableDriversIds() {
.map(DBPDriver::getId)
.collect(Collectors.toSet());
}

/**
* Returns filtered properties collected from object.
*/
@NotNull
public static WebPropertyInfo[] getObjectFilteredProperties(
@NotNull WebSession session,
@NotNull DBPObject object,
@Nullable WebPropertyFilter filter
) {
PropertyCollector propertyCollector = new PropertyCollector(object, true);
propertyCollector.setLocale(session.getLocale());
propertyCollector.collectProperties();
List<WebPropertyInfo> webProps = new ArrayList<>();
for (DBPPropertyDescriptor prop : propertyCollector.getProperties()) {
if (filter != null && !CommonUtils.isEmpty(filter.getIds()) && !filter.getIds().contains(CommonUtils.toString(prop.getId()))) {
continue;
}
WebPropertyInfo webProperty = new WebPropertyInfo(session, prop, propertyCollector);
if (filter != null) {
if (!CommonUtils.isEmpty(filter.getFeatures()) && !webProperty.hasAnyFeature(filter.getFeatures())) {
continue;
}
if (!CommonUtils.isEmpty(filter.getCategories()) && !filter.getCategories().contains(webProperty.getCategory())) {
continue;
}
}
webProps.add(webProperty);
}
return webProps.toArray(new WebPropertyInfo[0]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,17 @@
*/
package io.cloudbeaver.service.navigator;

import io.cloudbeaver.WebServiceUtils;
import io.cloudbeaver.model.WebPropertyInfo;
import io.cloudbeaver.model.session.WebSession;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.meta.Property;
import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor;
import org.jkiss.dbeaver.model.struct.*;
import org.jkiss.dbeaver.model.struct.rdb.DBSCatalog;
import org.jkiss.dbeaver.model.struct.rdb.DBSSchema;
import org.jkiss.dbeaver.model.struct.rdb.DBSTable;
import org.jkiss.dbeaver.runtime.properties.PropertyCollector;
import org.jkiss.utils.CommonUtils;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -90,26 +88,7 @@ public WebPropertyInfo[] getProperties() {

@Property
public WebPropertyInfo[] filterProperties(@Nullable WebPropertyFilter filter) {
PropertyCollector propertyCollector = new PropertyCollector(object, true);
propertyCollector.setLocale(session.getLocale());
propertyCollector.collectProperties();
List<WebPropertyInfo> webProps = new ArrayList<>();
for (DBPPropertyDescriptor prop : propertyCollector.getProperties()) {
if (filter != null && !CommonUtils.isEmpty(filter.getIds()) && !filter.getIds().contains(CommonUtils.toString(prop.getId()))) {
continue;
}
WebPropertyInfo webProperty = new WebPropertyInfo(session, prop, propertyCollector);
if (filter != null) {
if (!CommonUtils.isEmpty(filter.getFeatures()) && !webProperty.hasAnyFeature(filter.getFeatures())) {
continue;
}
if (!CommonUtils.isEmpty(filter.getCategories()) && !filter.getCategories().contains(webProperty.getCategory())) {
continue;
}
}
webProps.add(webProperty);
}
return webProps.toArray(new WebPropertyInfo[0]);
return WebServiceUtils.getObjectFilteredProperties(session, object, filter);
}

///////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ const equalConfig = {
};

test('Read settings', async () => {
const settings = app.injector.getServiceByClass(AuthSettingsService);
const config = app.injector.getServiceByClass(ServerConfigResource);
const settings = app.serviceProvider.getService(AuthSettingsService);
const config = app.serviceProvider.getService(ServerConfigResource);

server.use(endpoint.query('serverConfig', mockServerConfig(equalConfig)));

Expand Down
21 changes: 21 additions & 0 deletions webapp/packages/core-blocks/src/Table/TableItemGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 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 { observer } from 'mobx-react-lite';
import { useState } from 'react';

import { TableItemGroupContext } from './TableItemGroupContext';

export interface TableItemGroupProps extends React.PropsWithChildren {
expanded?: boolean;
}

export const TableItemGroup = observer<TableItemGroupProps>(function TableItemGroup({ expanded = true, children }) {
const [internalExpanded, setExpanded] = useState(expanded);

return <TableItemGroupContext.Provider value={{ expanded: internalExpanded, setExpanded }}>{children}</TableItemGroupContext.Provider>;
});
29 changes: 29 additions & 0 deletions webapp/packages/core-blocks/src/Table/TableItemGroupContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 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 { observer } from 'mobx-react-lite';
import { useContext } from 'react';

import { TableItemGroupContext } from './TableItemGroupContext';

export interface TableItemGroupContentProps {
children?: React.ReactNode | (() => React.ReactNode);
}

export const TableItemGroupContent = observer<TableItemGroupContentProps>(function TableItemGroupContent({ children }) {
const context = useContext(TableItemGroupContext);

if (!context) {
throw new Error('TableItemGroupContent can be used only inside TableItemGroup');
}

if (!context.expanded) {
return null;
}

return <>{typeof children === 'function' ? children() : children}</>;
});
14 changes: 14 additions & 0 deletions webapp/packages/core-blocks/src/Table/TableItemGroupContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 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 { createContext } from 'react';

export interface ITableItemGroupContext {
expanded: boolean;
setExpanded: (expanded: boolean) => void;
}
export const TableItemGroupContext = createContext<ITableItemGroupContext | undefined>(undefined);
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/

.box {
display: inline-block;
width: 16px;
height: 16px;
align-self: center;
}

.icon {
composes: theme-text-on-surface from global;
width: 100%;
height: 100%;
cursor: pointer;
opacity: 0.5;
transform: rotate(-90deg);
transition: transform 0.15s ease-in-out;

&.expanded {
transform: rotate(0deg);
}
}
Loading

0 comments on commit 07761fe

Please sign in to comment.