Cb 6041 system information (#3245)

* CB-6041 add system information plugin

* CB-6041 api for system information

* CB-6041 api for system information

* CB-6041 api for system information

* CB-6041 simplify system info ui

* CB-6041 remove extra props

* CB-6041 api for internal database information

* CB-6041 remove hint

* CB-6041 add missing field

* CB-6041 use categories for database info

* CB-6041 add categories

* CB-6041 add category to copy info

* CB-6041 code style fix

* CB-6041 fix get property ids

* CB-6041 updates react version to 19

---------

Co-authored-by: Ainur <ainur.iagudin@dbeaver.com>
Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com>
Co-authored-by: Ainur <59531286+yagudin10@users.noreply.github.com>
Co-authored-by: Alexander Skoblikov <aleksandr.skoblikov@dbeaver.com>
Co-authored-by: Serge Rider <serge@jkiss.org>
Co-authored-by: sergeyteleshev <iamsergeyteleshev@gmail.com>
This commit is contained in:
alex
2025-02-12 12:44:07 +01:00
committed by GitHub
co-authored by Ainur Daria Marutkina Ainur Alexander Skoblikov Serge Rider sergeyteleshev
parent f542534fdc
commit 4cdfa5b07f
32 changed files with 661 additions and 26 deletions
@@ -0,0 +1,13 @@
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.osInfo.name=OS
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.memoryAvailable.name=Memory available
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.javaVersion.name=Java version
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.javaParameters.name=JVM parameters
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.productName.name=Product name
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.productVersion.name=Product version
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.workspacePath.name=Workspace path
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.installPath.name=Install path
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.deploymentType.name=Deployment type
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.smDbUrl.name=Security manager database URL
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.smDbDriverName.name=Security manager database driver name
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.smDbProductName.name=Security manager database product name
meta.io.cloudbeaver.model.app.ServletSystemInformationCollector.smDbProductVersion.name=Security manager database product version
@@ -2,5 +2,6 @@ source.. = src/
output.. = target/classes/
bin.includes = .,\
META-INF/,\
OSGI-INF/,\
plugin.xml,\
schema/
@@ -91,6 +91,12 @@ public interface ServletApplication extends DBPApplication {
boolean isLicenseRequired();
/**
* Collector that contains information about system.
*/
@NotNull
ServletSystemInformationCollector getSystemInformationCollector();
default void getStatusInfo(Map<String, Object> infoMap) {
}
@@ -0,0 +1,170 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.cloudbeaver.model.app;
import io.cloudbeaver.auth.NoAuthCredentialsProvider;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.DBPConnectionInformation;
import org.jkiss.dbeaver.model.DBPObject;
import org.jkiss.dbeaver.model.meta.Property;
import org.jkiss.dbeaver.model.meta.PropertyGroup;
import org.jkiss.dbeaver.model.meta.PropertyLength;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.dbeaver.utils.SystemVariablesResolver;
import org.jkiss.utils.StandardConstants;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* Web system information collector.
*/
public class ServletSystemInformationCollector<T extends ServletApplication> implements DBPObject {
private enum DeploymentType {
DEFAULT,
DOCKER,
KUBERNETES
}
@NotNull
protected final T application;
@NotNull
private final String osInfo;
@NotNull
private final String javaVersion;
@NotNull
private final String javaParameters;
@NotNull
private final String productName;
@NotNull
private final String productVersion;
@NotNull
private final String memoryAvailable;
@NotNull
private final String installPath;
private DBPConnectionInformation smDatabaseInfo;
private String workspacePath;
private final DeploymentType deploymentType;
public ServletSystemInformationCollector(@NotNull T application) {
this.application = application;
this.osInfo = System.getProperty(StandardConstants.ENV_OS_NAME) + " " + System.getProperty(
StandardConstants.ENV_OS_VERSION) + " (" + System.getProperty(StandardConstants.ENV_OS_ARCH) + ")";
this.javaVersion = System.getProperty(StandardConstants.ENV_JAVA_VERSION) + " by " + System.getProperty(
StandardConstants.ENV_JAVA_VENDOR) + " (" + System.getProperty(StandardConstants.ENV_JAVA_ARCH) + "bit)";
this.javaParameters = System.getProperty("sun.java.command");
this.productName = GeneralUtils.getProductName();
this.productVersion = GeneralUtils.getProductVersion().toString();
this.installPath = SystemVariablesResolver.getInstallPath();
this.memoryAvailable = "%dMb/%dMb".formatted(
Runtime.getRuntime().totalMemory() / (1024 * 1024),
Runtime.getRuntime().maxMemory() / (1024 * 1024)
);
deploymentType = checkDeploymentType();
}
private DeploymentType checkDeploymentType() {
if (System.getenv("KUBERNETES_SERVICE_HOST") != null) {
return DeploymentType.KUBERNETES;
}
if (isRunningInDocker()) {
return DeploymentType.DOCKER;
}
return DeploymentType.DEFAULT;
}
@NotNull
@Property(order = 1)
public String getProductName() {
return productName;
}
@NotNull
@Property(order = 2)
public String getProductVersion() {
return productVersion;
}
@NotNull
@Property(order = 11)
public String getOsInfo() {
return osInfo;
}
@NotNull
@Property(order = 12)
public String getMemoryAvailable() {
return memoryAvailable;
}
@NotNull
@Property(order = 21, length = PropertyLength.MULTILINE)
public String getJavaVersion() {
return javaVersion;
}
@NotNull
@Property(order = 22, length = PropertyLength.MULTILINE)
public String getJavaParameters() {
return javaParameters;
}
@NotNull
@Property(order = 23)
public String getDeploymentType() {
return deploymentType.name();
}
@NotNull
@PropertyGroup(order = 31, category = "Security manager database", id = "sm")
public DBPConnectionInformation getSmDatabaseInfo() {
return smDatabaseInfo;
}
@Property(order = Integer.MAX_VALUE - 10, length = PropertyLength.MULTILINE)
public String getWorkspacePath() {
return workspacePath;
}
public void setWorkspacePath(String workspacePath) {
this.workspacePath = workspacePath;
}
@NotNull
@Property(order = Integer.MAX_VALUE - 10, length = PropertyLength.MULTILINE)
public String getInstallPath() {
return installPath;
}
/**
* Collects info about internal databases.
*/
public void collectInternalDatabaseUseInformation() throws DBException {
this.smDatabaseInfo = application.getAdminSecurityController(new NoAuthCredentialsProvider())
.getInternalDatabaseInformation();
}
private static boolean isRunningInDocker() {
Path cgroupPath = Path.of("/.dockerenv");
return Files.exists(cgroupPath);
}
}
@@ -43,7 +43,7 @@ public class WebCommonUtils {
PropertyCollector propertyCollector = new PropertyCollector(details, false);
propertyCollector.collectProperties();
return Arrays.stream(propertyCollector.getProperties())
.filter(p -> !(p instanceof ObjectPropertyDescriptor && ((ObjectPropertyDescriptor) p).isHidden()))
.filter(p -> !(p instanceof ObjectPropertyDescriptor objProp && objProp.isHidden()))
.map(p -> new WebPropertyInfo(session, p, propertyCollector)).toArray(WebPropertyInfo[]::new);
}
@@ -23,6 +23,7 @@ import io.cloudbeaver.model.WebServerConfig;
import io.cloudbeaver.model.app.BaseServletApplication;
import io.cloudbeaver.model.app.ServletAuthApplication;
import io.cloudbeaver.model.app.ServletAuthConfiguration;
import io.cloudbeaver.model.app.ServletSystemInformationCollector;
import io.cloudbeaver.model.config.CBAppConfig;
import io.cloudbeaver.model.config.CBServerConfig;
import io.cloudbeaver.model.config.SMControllerConfiguration;
@@ -56,11 +57,8 @@ import org.jkiss.dbeaver.model.websocket.event.WSEventController;
import org.jkiss.dbeaver.model.websocket.event.WSServerConfigurationChangedEvent;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.runtime.ui.DBPPlatformUI;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.dbeaver.utils.SystemVariablesResolver;
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;
import org.jkiss.utils.StandardConstants;
import java.io.File;
import java.io.IOException;
@@ -112,6 +110,7 @@ public abstract class CBApplication<T extends CBServerConfig> extends
private CBSessionManager sessionManager;
private final Map<String, String> initActions = new ConcurrentHashMap<>();
private ServletSystemInformationCollector systemInformationCollector;
private CBJettyServer jettyServer;
@@ -247,15 +246,18 @@ public abstract class CBApplication<T extends CBServerConfig> extends
log.error("Error setting workspace location to " + getWorkspaceDirectory().toAbsolutePath(), e);
return;
}
log.debug(GeneralUtils.getProductName() + " " + GeneralUtils.getProductVersion() + " is starting"); //$NON-NLS-1$
log.debug("\tOS: " + System.getProperty(StandardConstants.ENV_OS_NAME) + " " + System.getProperty(
StandardConstants.ENV_OS_VERSION) + " (" + System.getProperty(StandardConstants.ENV_OS_ARCH) + ")");
log.debug("\tJava version: " + System.getProperty(StandardConstants.ENV_JAVA_VERSION) + " by " + System.getProperty(
StandardConstants.ENV_JAVA_VENDOR) + " (" + System.getProperty(StandardConstants.ENV_JAVA_ARCH) + "bit)");
log.debug("\tInstall path: '" + SystemVariablesResolver.getInstallPath() + "'"); //$NON-NLS-1$ //$NON-NLS-2$
log.debug("\tGlobal workspace: '" + instanceLoc.getURL() + "'"); //$NON-NLS-1$ //$NON-NLS-2$
log.debug("\tMemory available " + (runtime.totalMemory() / (1024 * 1024)) + "Mb/" + (runtime.maxMemory() / (1024 * 1024)) + "Mb");
this.systemInformationCollector = createSystemInformationCollector();
this.systemInformationCollector.setWorkspacePath(instanceLoc.getURL().toString());
log.debug("%s %s is starting".formatted(
systemInformationCollector.getProductName(),
systemInformationCollector.getProductVersion())
); //$NON-NLS-1$
log.debug("\tOS: " + systemInformationCollector.getOsInfo());
log.debug("\tJava version: " + systemInformationCollector.getJavaVersion());
log.debug("\tInstall path: '" + systemInformationCollector.getInstallPath() + "'"); //$NON-NLS-1$ //$NON-NLS-2$
log.debug("\tGlobal workspace: '" + systemInformationCollector.getWorkspacePath() + "'"); //$NON-NLS-1$ //$NON-NLS-2$
log.debug("\tMemory available " + systemInformationCollector.getMemoryAvailable());
DBWorkbench.getPlatform().getApplication();
@@ -321,6 +323,11 @@ public abstract class CBApplication<T extends CBServerConfig> extends
}
grantPermissionsToConnections();
}
try {
this.systemInformationCollector.collectInternalDatabaseUseInformation();
} catch (DBException e) {
log.error("Error collecting system information", e);
}
eventController.scheduleCheckJob();
@@ -331,6 +338,10 @@ public abstract class CBApplication<T extends CBServerConfig> extends
return;
}
protected ServletSystemInformationCollector<?> createSystemInformationCollector() {
return new ServletSystemInformationCollector<>(this);
}
protected void initializeAdditionalConfiguration() {
}
@@ -785,4 +796,10 @@ public abstract class CBApplication<T extends CBServerConfig> extends
public ConnectionController getConnectionController() {
return new ConnectionControllerCE();
}
@NotNull
@Override
public ServletSystemInformationCollector<?> getSystemInformationCollector() {
return systemInformationCollector;
}
}
@@ -570,6 +570,7 @@ input ConnectionConfig {
extend type Query {
# Return server config
serverConfig: ServerConfig!
systemInfo: [ObjectPropertyInfo!]! @since(version: "24.3.5")
# Return product settings
productSettings: ProductSettings! @since(version: "24.0.1")
@@ -41,6 +41,12 @@ public interface DBWServiceCore extends DBWService {
@WebAction(authRequired = false, initializationRequired = false)
WebServerConfig getServerConfig() throws DBWebException;
/**
* Returns information of system.
*/
@WebAction(authRequired = false)
WebPropertyInfo[] getSystemInformationProperties(@NotNull WebSession webSession);
@WebAction(authRequired = false)
WebProductSettings getProductSettings(@NotNull WebSession webSession);
@@ -53,6 +53,7 @@ public class WebServiceBindingCore extends WebServiceBindingBase<DBWServiceCore>
WebAppSessionManager sessionManager = WebAppUtils.getWebApplication().getSessionManager();
model.getQueryType()
.dataFetcher("serverConfig", env -> getService(env).getServerConfig())
.dataFetcher("systemInfo", env -> getService(env).getSystemInformationProperties(getWebSession(env)))
.dataFetcher("productSettings", env -> getService(env).getProductSettings(getWebSession(env)))
.dataFetcher("driverList", env -> getService(env).getDriverList(getWebSession(env), env.getArgument("id")))
@@ -27,10 +27,7 @@ import io.cloudbeaver.server.WebAppUtils;
import io.cloudbeaver.server.WebApplication;
import io.cloudbeaver.service.core.DBWServiceCore;
import io.cloudbeaver.service.security.SMUtils;
import io.cloudbeaver.utils.ServletAppUtils;
import io.cloudbeaver.utils.WebConnectionFolderUtils;
import io.cloudbeaver.utils.WebDataSourceUtils;
import io.cloudbeaver.utils.WebEventUtils;
import io.cloudbeaver.utils.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jkiss.code.NotNull;
@@ -44,18 +41,13 @@ import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
import org.jkiss.dbeaver.model.app.DBPProject;
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.model.exec.DBCConnectException;
import org.jkiss.dbeaver.model.navigator.*;
import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration;
import org.jkiss.dbeaver.model.net.DBWHandlerType;
import org.jkiss.dbeaver.model.net.DBWNetworkHandler;
import org.jkiss.dbeaver.model.net.DBWTunnel;
import org.jkiss.dbeaver.model.net.ssh.SSHSession;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.secret.DBSSecretController;
import org.jkiss.dbeaver.model.secret.DBSSecretValue;
import org.jkiss.dbeaver.model.websocket.WSConstants;
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceConnectEvent;
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceProperty;
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
import org.jkiss.dbeaver.registry.DataSourceProviderRegistry;
@@ -63,8 +55,6 @@ import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor;
import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry;
import org.jkiss.dbeaver.registry.settings.ProductSettingsRegistry;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.runtime.jobs.ConnectionTestJob;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.CommonUtils;
import java.util.*;
@@ -82,6 +72,14 @@ public class WebServiceCore implements DBWServiceCore {
return WebAppUtils.getWebApplication().getWebServerConfig();
}
@Override
public WebPropertyInfo[] getSystemInformationProperties(@NotNull WebSession webSession) {
return WebCommonUtils.getObjectProperties(
webSession,
WebAppUtils.getWebApplication().getSystemInformationCollector()
);
}
@Override
public List<WebDatabaseDriverInfo> getDriverList(@NotNull WebSession webSession, String driverId) {
List<WebDatabaseDriverInfo> result = new ArrayList<>();
@@ -36,6 +36,7 @@ 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.DBPConnectionInformation;
import org.jkiss.dbeaver.model.DBPPage;
import org.jkiss.dbeaver.model.auth.*;
import org.jkiss.dbeaver.model.exec.DBCException;
@@ -3322,4 +3323,10 @@ public class CBEmbeddedSecurityController<T extends ServletAuthApplication>
private String getDefaultUserTeam() {
return application.getAppConfiguration().getDefaultUserTeam();
}
@NotNull
@Override
public DBPConnectionInformation getInternalDatabaseInformation() {
return database.getMetaDataInfo();
}
}
@@ -33,6 +33,7 @@ import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBConstants;
import org.jkiss.dbeaver.model.DBPConnectionInformation;
import org.jkiss.dbeaver.model.auth.AuthInfo;
import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.model.impl.app.ApplicationRegistry;
@@ -86,6 +87,8 @@ public class CBDatabase {
private final ServletApplication application;
private final WebDatabaseConfig databaseConfiguration;
private PoolingDataSource<PoolableConnection> cbDataSource;
private DBPConnectionInformation cbConnectionInformation;
private transient volatile Connection exclusiveConnection;
private String instanceId;
@@ -200,7 +203,16 @@ public class CBDatabase {
try (Connection connection = cbDataSource.getConnection()) {
DatabaseMetaData metaData = connection.getMetaData();
log.debug("\tConnected to " + metaData.getDatabaseProductName() + " " + metaData.getDatabaseProductVersion());
final String dbName = metaData.getDatabaseProductName();
final String dbVersion = metaData.getDatabaseProductVersion();
log.debug("\tConnected to " + dbName + " " + dbVersion);
cbConnectionInformation = new DBPConnectionInformation(
databaseConfiguration.getUrl(),
databaseConfiguration.getDriver(),
dbName,
dbVersion
);
if (dialect instanceof SQLDialectSchemaController && CommonUtils.isNotEmpty(schemaName)) {
var dialectSchemaController = (SQLDialectSchemaController) dialect;
@@ -600,6 +612,14 @@ public class CBDatabase {
|| v2DefaultUrl.equals(databaseConfiguration.getUrl());
}
/**
* Returns internal database metadata.
*/
@NotNull
public DBPConnectionInformation getMetaDataInfo() {
return cbConnectionInformation;
}
protected WebDatabaseConfig getDatabaseConfiguration() {
return databaseConfiguration;
}
@@ -0,0 +1,13 @@
query getSystemInfo {
info: systemInfo {
id
displayName
category
value
length
features
dataType
order
required
}
}
@@ -0,0 +1,17 @@
# dependencies
/node_modules
# testing
/coverage
# production
/lib
# misc
.DS_Store
.env*
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
@@ -0,0 +1,45 @@
{
"name": "@cloudbeaver/plugin-system-information-administration",
"type": "module",
"sideEffects": [
"src/**/*.css",
"src/**/*.scss",
"public/**/*"
],
"version": "0.1.0",
"description": "",
"license": "Apache-2.0",
"exports": {
".": "./dist/index.js"
},
"scripts": {
"build": "tsc -b",
"clean": "rimraf --glob dist",
"lint": "eslint ./src/ --ext .ts,.tsx",
"test": "core-cli-test",
"validate-dependencies": "core-cli-validate-dependencies"
},
"dependencies": {
"@cloudbeaver/core-administration": "workspace:*",
"@cloudbeaver/core-blocks": "workspace:*",
"@cloudbeaver/core-di": "workspace:*",
"@cloudbeaver/core-localization": "workspace:*",
"@cloudbeaver/core-resource": "workspace:*",
"@cloudbeaver/core-root": "workspace:*",
"@cloudbeaver/core-sdk": "workspace:*",
"@cloudbeaver/core-ui": "workspace:*",
"@cloudbeaver/plugin-product-information-administration": "workspace:*",
"mobx": "^6",
"mobx-react-lite": "^4",
"react": "^19",
"react-dom": "^19",
"tslib": "^2"
},
"devDependencies": {
"@cloudbeaver/core-cli": "workspace:*",
"@cloudbeaver/tsconfig": "workspace:*",
"@types/react": "^19",
"typescript": "^5",
"typescript-plugin-css-modules": "^5"
}
}
@@ -0,0 +1,35 @@
/*
* 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 { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { LocalizationService } from '@cloudbeaver/core-localization';
@injectable()
export class LocaleService extends Bootstrap {
constructor(private readonly localizationService: LocalizationService) {
super();
}
override register(): void {
this.localizationService.addProvider(this.provider.bind(this));
}
private async provider(locale: string) {
switch (locale) {
case 'ru':
return (await import('./locales/ru.js')).default;
case 'it':
return (await import('./locales/it.js')).default;
case 'zh':
return (await import('./locales/zh.js')).default;
case 'fr':
return (await import('./locales/fr.js')).default;
default:
return (await import('./locales/en.js')).default;
}
}
}
@@ -0,0 +1,71 @@
/*
* 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 type { AdministrationItemContentProps } from '@cloudbeaver/core-administration';
import {
Button,
ColoredContainer,
Flex,
Fill,
Group,
ObjectPropertyInfoForm,
useClipboard,
useResource,
useTranslate,
useObjectPropertyCategories,
GroupTitle,
Container,
} from '@cloudbeaver/core-blocks';
import type { TabContainerPanelComponent } from '@cloudbeaver/core-ui';
import { SystemInformationResource } from './SystemInformationResource.js';
export const SystemInformation: TabContainerPanelComponent<AdministrationItemContentProps> = observer(function SystemInformation() {
const translate = useTranslate();
const copy = useClipboard();
const systemInformationResource = useResource(SystemInformation, SystemInformationResource, undefined);
const properties = systemInformationResource.data ?? [];
const { categories, isUncategorizedExists } = useObjectPropertyCategories(properties);
function copyToClipboard() {
if (systemInformationResource.data) {
copy(
systemInformationResource.data
.map(property => `${property.category ? property.category + '/' : ''}${property.displayName}: ${property.value}`)
.join('\n'),
true,
);
}
}
return (
<ColoredContainer overflow parent>
<Group gap medium wrap>
{isUncategorizedExists && (
<Container gap>
<ObjectPropertyInfoForm category={null} properties={properties} small fill readOnly />
</Container>
)}
{categories.map(category => (
<Container key={category} gap>
<GroupTitle>{category}</GroupTitle>
<ObjectPropertyInfoForm category={category} properties={properties} small fill readOnly />
</Container>
))}
<Flex>
<Fill />
<Button mod={['unelevated']} onClick={copyToClipboard}>
{translate('ui_copy_to_clipboard')}
</Button>
</Flex>
</Group>
</ColoredContainer>
);
});
@@ -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 { importLazyComponent } from '@cloudbeaver/core-blocks';
import { injectable, Bootstrap } from '@cloudbeaver/core-di';
import { ProductInfoService } from '@cloudbeaver/plugin-product-information-administration';
const SystemInformation = importLazyComponent(() => import('./SystemInformation.js').then(m => m.SystemInformation));
@injectable()
export class SystemInformationBootstrap extends Bootstrap {
constructor(private readonly productInfoService: ProductInfoService) {
super();
}
override register(): void {
this.productInfoService.addSubItem({
key: 'system-information',
name: 'plugin_system_information_administration_tab_title',
panel: () => SystemInformation,
order: 2,
});
}
}
@@ -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.
*/
import { injectable } from '@cloudbeaver/core-di';
import { CachedDataResource } from '@cloudbeaver/core-resource';
import { GraphQLService, type ObjectPropertyInfo } from '@cloudbeaver/core-sdk';
import { SessionPermissionsResource, EAdminPermission } from '@cloudbeaver/core-root';
@injectable()
export class SystemInformationResource extends CachedDataResource<ObjectPropertyInfo[]> {
constructor(
private readonly graphQLService: GraphQLService,
private readonly sessionPermissionsResource: SessionPermissionsResource,
) {
super(() => []);
this.sessionPermissionsResource.require(this, EAdminPermission.admin).outdateResource(this);
}
protected async loader(): Promise<ObjectPropertyInfo[]> {
const { info } = await this.graphQLService.sdk.getSystemInfo();
return info;
}
}
@@ -0,0 +1,11 @@
/*
* 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 { pluginSystemInformationAdministrationManifest } from './manifest.js';
export { pluginSystemInformationAdministrationManifest };
export default pluginSystemInformationAdministrationManifest;
@@ -0,0 +1,8 @@
/*
* 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.
*/
export default [['plugin_system_information_administration_tab_title', 'System Information']];
@@ -0,0 +1,8 @@
/*
* 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.
*/
export default [['plugin_system_information_administration_tab_title', 'System Information']];
@@ -0,0 +1,8 @@
/*
* 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.
*/
export default [['plugin_system_information_administration_tab_title', 'System Information']];
@@ -0,0 +1,8 @@
/*
* 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.
*/
export default [['plugin_system_information_administration_tab_title', 'Информация о системе']];
@@ -0,0 +1,8 @@
/*
* 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.
*/
export default [['plugin_system_information_administration_tab_title', 'System Information']];
@@ -0,0 +1,20 @@
/*
* 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 type { PluginManifest } from '@cloudbeaver/core-di';
export const pluginSystemInformationAdministrationManifest: PluginManifest = {
info: {
name: 'System Information Administration plugin',
},
providers: [
() => import('./LocaleService.js').then(m => m.LocaleService),
() => import('./SystemInformationBootstrap.js').then(m => m.SystemInformationBootstrap),
() => import('./SystemInformationResource.js').then(m => m.SystemInformationResource),
],
};
@@ -0,0 +1,53 @@
{
"extends": "@cloudbeaver/tsconfig/tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"tsBuildInfoFile": "dist/tsconfig.tsbuildinfo",
"composite": true
},
"references": [
{
"path": "../core-administration"
},
{
"path": "../core-blocks"
},
{
"path": "../core-cli"
},
{
"path": "../core-di"
},
{
"path": "../core-localization"
},
{
"path": "../core-resource"
},
{
"path": "../core-root"
},
{
"path": "../core-sdk"
},
{
"path": "../core-ui"
},
{
"path": "../plugin-product-information-administration"
}
],
"include": [
"__custom_mocks__/**/*",
"src/**/*",
"src/**/*.json",
"src/**/*.css",
"src/**/*.scss"
],
"exclude": [
"**/node_modules",
"lib/**/*",
"dist/**/*"
]
}
@@ -27,7 +27,7 @@ export class PluginBootstrap extends Bootstrap {
key: 'version-update',
name: 'plugin_version_update_administration_tab_title',
panel: () => VersionUpdate,
order: 2,
order: 3,
});
this.versionUpdateService.registerGeneralInstruction(() => DockerUpdateInstructions);
@@ -78,6 +78,7 @@
"@cloudbeaver/plugin-sql-editor-screen": "workspace:*",
"@cloudbeaver/plugin-sql-generator": "workspace:*",
"@cloudbeaver/plugin-sso": "workspace:*",
"@cloudbeaver/plugin-system-information-administration": "workspace:*",
"@cloudbeaver/plugin-task-manager": "workspace:*",
"@cloudbeaver/plugin-theme": "workspace:*",
"@cloudbeaver/plugin-tools-panel": "workspace:*",
@@ -72,6 +72,7 @@ import userProfileAdministration from '@cloudbeaver/plugin-user-profile-administ
import { userProfileSettingsPlugin } from '@cloudbeaver/plugin-user-profile-settings';
import version from '@cloudbeaver/plugin-version';
import versionUpdate from '@cloudbeaver/plugin-version-update-administration';
import { pluginSystemInformationAdministrationManifest } from '@cloudbeaver/plugin-system-information-administration';
import { defaultProductManifest } from './manifest.js';
@@ -139,6 +140,7 @@ const PLUGINS: PluginManifest[] = [
holidaysPluginAdministration,
appLogoPlugin,
appLogoPluginAdministration,
pluginSystemInformationAdministrationManifest,
// must be las one to override all
defaultProductManifest,
];
@@ -184,6 +184,9 @@
{
"path": "../plugin-sso"
},
{
"path": "../plugin-system-information-administration"
},
{
"path": "../plugin-task-manager"
},
+27
View File
@@ -4055,6 +4055,32 @@ __metadata:
languageName: unknown
linkType: soft
"@cloudbeaver/plugin-system-information-administration@workspace:*, @cloudbeaver/plugin-system-information-administration@workspace:packages/plugin-system-information-administration":
version: 0.0.0-use.local
resolution: "@cloudbeaver/plugin-system-information-administration@workspace:packages/plugin-system-information-administration"
dependencies:
"@cloudbeaver/core-administration": "workspace:*"
"@cloudbeaver/core-blocks": "workspace:*"
"@cloudbeaver/core-cli": "workspace:*"
"@cloudbeaver/core-di": "workspace:*"
"@cloudbeaver/core-localization": "workspace:*"
"@cloudbeaver/core-resource": "workspace:*"
"@cloudbeaver/core-root": "workspace:*"
"@cloudbeaver/core-sdk": "workspace:*"
"@cloudbeaver/core-ui": "workspace:*"
"@cloudbeaver/plugin-product-information-administration": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
"@types/react": "npm:^19"
mobx: "npm:^6"
mobx-react-lite: "npm:^4"
react: "npm:^19"
react-dom: "npm:^19"
tslib: "npm:^2"
typescript: "npm:^5"
typescript-plugin-css-modules: "npm:^5"
languageName: unknown
linkType: soft
"@cloudbeaver/plugin-task-manager@workspace:*, @cloudbeaver/plugin-task-manager@workspace:packages/plugin-task-manager":
version: 0.0.0-use.local
resolution: "@cloudbeaver/plugin-task-manager@workspace:packages/plugin-task-manager"
@@ -4344,6 +4370,7 @@ __metadata:
"@cloudbeaver/plugin-sql-editor-screen": "workspace:*"
"@cloudbeaver/plugin-sql-generator": "workspace:*"
"@cloudbeaver/plugin-sso": "workspace:*"
"@cloudbeaver/plugin-system-information-administration": "workspace:*"
"@cloudbeaver/plugin-task-manager": "workspace:*"
"@cloudbeaver/plugin-theme": "workspace:*"
"@cloudbeaver/plugin-tools-panel": "workspace:*"