diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionInfo.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionInfo.java index b77f5e3291a..963339b8c1a 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionInfo.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionInfo.java @@ -287,6 +287,12 @@ public DBNBrowseSettings getNavigatorSettings() { return dataSourceContainer.getNavigatorSettings(); } + @Property + @NotNull + public DBNBrowseSettings getDefaultNavigatorSettings() { + return dataSourceContainer.getNavigatorSettings().getOriginalSettings(); + } + @Property @NotNull public List getSupportedDataFormats() { diff --git a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls index 86db10b4f88..f09fac54ff1 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls @@ -548,7 +548,11 @@ type ConnectionInfo { "Supported features (provided etc)" features: [ String! ]! + "Navigator settings for the connection (with user settings applied)" navigatorSettings: NavigatorSettings! + "Default navigator settings for the connection (without user settings applied)" + defaultNavigatorSettings: NavigatorSettings! + supportedDataFormats: [ ResultDataFormat! ]! configurationType: DriverConfigurationType @@ -595,7 +599,7 @@ type NavigatorSettings { hideFolders: Boolean! hideSchemas: Boolean! hideVirtualModel: Boolean! - + "Shows whether these settings are user-specific or global" userSettings: Boolean! @since(version: "25.3.2") } @@ -837,10 +841,10 @@ extend type Mutation { "Disconnect from the database" closeConnection( id: ID!, projectId: ID ): ConnectionInfo! - "Change navigator settings for connection. It can change default settings or user settings depending on userSettings property." + "Change navigator settings for connection. It can change default settings or user settings depending on 'default' parameter." setConnectionNavigatorSettings( id: ID!, projectId: ID, settings: NavigatorSettingsInput!): ConnectionInfo! "Sets to default navigator settings for connection. Resets all user navigator settings for this connection." - clearConnectionNavigatorSettings(projectId: ID!, id: ID! ): ConnectionInfo! @since(version: "25.3.2") + clearConnectionNavigatorSettings(projectId: ID!, id: ID!): ConnectionInfo! @since(version: "25.3.2") #### Generic async functions 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 b5ff5c892a9..bfc3be1d17f 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 @@ -150,8 +150,9 @@ public void bindWiring(DBWBindingContext model) throws DBWebException { getWebSession(env), getProjectReference(env), getArgumentVal(env, "id"), - WebServiceUtils.parseNavigatorSettings(getArgument(env, "settings")) - )) + WebServiceUtils.parseNavigatorSettings(getArgument(env, "settings")) + ) + ) .dataFetcher( "clearConnectionNavigatorSettings", env -> getService(env).clearConnectionNavigatorSettings( getWebSession(env), 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 79126fb6f3a..ada2a84760a 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 @@ -726,10 +726,12 @@ public WebConnectionInfo setConnectionNavigatorSettings( @NotNull String id, @NotNull DataSourceNavigatorSettings settings ) throws DBWebException { - WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, id); + WebSessionProjectImpl project = webSession.getProjectById(projectId); + WebConnectionInfo connectionInfo = project != null ? project.getWebConnectionInfo(id) : + WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, id); DataSourceDescriptor dataSourceDescriptor = ((DataSourceDescriptor) connectionInfo.getDataSourceContainer()); try { - if (settings.isUserSettings()) { + if (project != null && !project.isPrivateProject() && settings.isUserSettings()) { DataSourceNavigatorSettingsUtils.updateCustomNavigatorSettings(dataSourceDescriptor, settings); } else { // If user has no permissions to save it will cause error diff --git a/webapp/packages/core-connections/src/ConnectionInfoResource.ts b/webapp/packages/core-connections/src/ConnectionInfoResource.ts index d693ee82f1d..5233a023173 100644 --- a/webapp/packages/core-connections/src/ConnectionInfoResource.ts +++ b/webapp/packages/core-connections/src/ConnectionInfoResource.ts @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2025 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -26,13 +26,7 @@ import { resourceKeyListAliasFactory, ResourceKeyUtils, } from '@cloudbeaver/core-resource'; -import { - DataSynchronizationService, - type NavigatorViewSettings, - ServerEventId, - SessionDataResource, - WorkspaceConfigEventHandler, -} from '@cloudbeaver/core-root'; +import { DataSynchronizationService, ServerEventId, SessionDataResource, WorkspaceConfigEventHandler } from '@cloudbeaver/core-root'; import { type AdminConnectionGrantInfo, type AdminConnectionSearchInfo, @@ -40,7 +34,6 @@ import { type GetUserConnectionsQueryVariables, GraphQLService, type InitConnectionMutationVariables, - type NavigatorSettingsInput, type TestConnectionMutation, } from '@cloudbeaver/core-sdk'; import { schemaValidationError } from '@cloudbeaver/core-utils'; @@ -64,16 +57,6 @@ export const ConnectionInfoProjectKey = resourceKeyListAliasFactory('@connection export const ConnectionInfoActiveProjectKey = resourceKeyListAlias('@connection-info/projects-active'); -export const DEFAULT_NAVIGATOR_VIEW_SETTINGS: NavigatorSettingsInput = { - showOnlyEntities: false, - hideFolders: false, - hideVirtualModel: false, - hideSchemas: false, - mergeEntities: false, - showSystemObjects: false, - showUtilityObjects: false, -}; - export interface IConnectionInfoMetadata extends ICachedResourceMetadata { connecting?: boolean; } @@ -432,20 +415,6 @@ export class ConnectionInfoResource extends CachedMapResource { - const connectionNavigatorViewSettings = this.get(key)?.navigatorSettings || DEFAULT_NAVIGATOR_VIEW_SETTINGS; - const { connection } = await this.graphQLService.sdk.setConnectionNavigatorSettings({ - connectionId: key.connectionId, - projectId: key.projectId, - settings: { ...connectionNavigatorViewSettings, ...settings }, - }); - - this.set(createConnectionParam(connection), connection); - this.onDataOutdated.execute(key); - - return this.get(key)!; - } - async update(key: IConnectionInfoParams, config: ConnectionConfig): Promise { await this.performUpdate(key, [], async () => { const { connection } = await this.graphQLService.sdk.updateConnection({ diff --git a/webapp/packages/core-localization/src/locales/en.ts b/webapp/packages/core-localization/src/locales/en.ts index 024f360c9dc..1c19ece1516 100644 --- a/webapp/packages/core-localization/src/locales/en.ts +++ b/webapp/packages/core-localization/src/locales/en.ts @@ -147,6 +147,7 @@ export default [ ['ui_field_is_required', 'Please fill in this field'], ['ui_delete_confirmation_message', 'You are about to delete "{arg:item}". Are you sure?'], ['ui_not_selected', 'Not selected'], + ['ui_reset', 'Reset'], ['root_permission_denied', "You don't have permissions"], ['root_permission_no_permission', "You don't have permission for this action"], diff --git a/webapp/packages/core-localization/src/locales/fr.ts b/webapp/packages/core-localization/src/locales/fr.ts index 7570cfd7c14..4f8064a9c80 100644 --- a/webapp/packages/core-localization/src/locales/fr.ts +++ b/webapp/packages/core-localization/src/locales/fr.ts @@ -141,6 +141,7 @@ export default [ ['ui_field_is_required', 'Please fill in this field'], ['ui_delete_confirmation_message', 'You are about to delete "{arg:item}". Are you sure?'], ['ui_not_selected', 'Not selected'], + ['ui_reset', 'Reset'], ['root_permission_denied', "Vous n'avez pas les permissions"], ['root_permission_no_permission', "Vous n'avez pas la permission pour cette action"], diff --git a/webapp/packages/core-localization/src/locales/it.ts b/webapp/packages/core-localization/src/locales/it.ts index 742eb80a6d2..f8524bfa005 100644 --- a/webapp/packages/core-localization/src/locales/it.ts +++ b/webapp/packages/core-localization/src/locales/it.ts @@ -137,6 +137,7 @@ export default [ ['ui_field_is_required', 'Please fill in this field'], ['ui_delete_confirmation_message', 'You are about to delete "{arg:item}". Are you sure?'], ['ui_not_selected', 'Not selected'], + ['ui_reset', 'Reset'], ['root_permission_denied', 'Non hai i permessi'], ['app_root_session_expire_warning_title', 'La sessione sta per scadere'], diff --git a/webapp/packages/core-localization/src/locales/ru.ts b/webapp/packages/core-localization/src/locales/ru.ts index 9211ec89070..15b80379748 100644 --- a/webapp/packages/core-localization/src/locales/ru.ts +++ b/webapp/packages/core-localization/src/locales/ru.ts @@ -143,6 +143,7 @@ export default [ ['ui_field_is_required', 'Заполните это поле'], ['ui_delete_confirmation_message', 'Вы собираетесь удалить "{arg:item}". Вы уверены?'], ['ui_not_selected', 'Не выбрано'], + ['ui_reset', 'Сбросить'], ['root_permission_denied', 'Отказано в доступе'], ['root_permission_no_permission', 'У вас нет разрешения на это действие'], diff --git a/webapp/packages/core-localization/src/locales/vi.ts b/webapp/packages/core-localization/src/locales/vi.ts index 5190c9561fa..c787fc7b6f3 100644 --- a/webapp/packages/core-localization/src/locales/vi.ts +++ b/webapp/packages/core-localization/src/locales/vi.ts @@ -147,6 +147,7 @@ export default [ ['ui_field_is_required', 'Please fill in this field'], ['ui_delete_confirmation_message', 'You are about to delete "{arg:item}". Are you sure?'], ['ui_not_selected', 'Not selected'], + ['ui_reset', 'Reset'], ['root_permission_denied', 'Bạn không có quyền'], ['root_permission_no_permission', 'Bạn không có quyền thực hiện hành động này'], diff --git a/webapp/packages/core-localization/src/locales/zh.ts b/webapp/packages/core-localization/src/locales/zh.ts index b03a407797a..fb27a966170 100644 --- a/webapp/packages/core-localization/src/locales/zh.ts +++ b/webapp/packages/core-localization/src/locales/zh.ts @@ -143,6 +143,7 @@ export default [ ['ui_field_is_required', 'Please fill in this field'], ['ui_delete_confirmation_message', 'You are about to delete "{arg:item}". Are you sure?'], ['ui_not_selected', 'Not selected'], + ['ui_reset', 'Reset'], ['root_permission_denied', '您没有权限'], ['root_permission_no_permission', '您没有权限执行此操作'], diff --git a/webapp/packages/core-root/src/ConnectionNavigatorViewSettings.ts b/webapp/packages/core-root/src/ConnectionNavigatorViewSettings.ts index 1a76dedc885..bb0fccdc73f 100644 --- a/webapp/packages/core-root/src/ConnectionNavigatorViewSettings.ts +++ b/webapp/packages/core-root/src/ConnectionNavigatorViewSettings.ts @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -8,7 +8,17 @@ import type { NavigatorSettingsInput } from '@cloudbeaver/core-sdk'; export type NavigatorView = 'simple' | 'advanced'; -export type NavigatorViewSettings = Partial; +export type NavigatorViewSettings = Omit & { showSystemObjects?: boolean }; + +export const DEFAULT_NAVIGATOR_VIEW_SETTINGS: NavigatorSettingsInput = { + showOnlyEntities: false, + hideFolders: false, + hideVirtualModel: false, + hideSchemas: false, + mergeEntities: false, + showSystemObjects: false, + showUtilityObjects: false, +}; export const CONNECTION_NAVIGATOR_VIEW_SETTINGS: Record = { simple: { diff --git a/webapp/packages/core-sdk/src/queries/connections/clearConnectionNavigatorSettings.gql b/webapp/packages/core-sdk/src/queries/connections/clearConnectionNavigatorSettings.gql new file mode 100644 index 00000000000..afbfdbb6189 --- /dev/null +++ b/webapp/packages/core-sdk/src/queries/connections/clearConnectionNavigatorSettings.gql @@ -0,0 +1,5 @@ +mutation clearConnectionNavigatorSettings($id: ID!, $projectId: ID!) { + connection: clearConnectionNavigatorSettings(id: $id, projectId: $projectId) { + ...DatabaseConnectionNavigatorViewSettings + } +} diff --git a/webapp/packages/core-sdk/src/queries/connections/getUserConnectionsNavigatorViewSettings.gql b/webapp/packages/core-sdk/src/queries/connections/getUserConnectionsNavigatorViewSettings.gql new file mode 100644 index 00000000000..8086118165c --- /dev/null +++ b/webapp/packages/core-sdk/src/queries/connections/getUserConnectionsNavigatorViewSettings.gql @@ -0,0 +1,5 @@ +query getUserConnectionsNavigatorViewSettings($projectId: ID, $connectionId: ID, $projectIds: [ID!]) { + connections: userConnections(projectId: $projectId, id: $connectionId, projectIds: $projectIds) { + ...DatabaseConnectionNavigatorViewSettings + } +} diff --git a/webapp/packages/core-sdk/src/queries/connections/setConnectionNavigatorSettings.gql b/webapp/packages/core-sdk/src/queries/connections/setConnectionNavigatorSettings.gql index c08644d2ab3..fd7c0a869f5 100644 --- a/webapp/packages/core-sdk/src/queries/connections/setConnectionNavigatorSettings.gql +++ b/webapp/packages/core-sdk/src/queries/connections/setConnectionNavigatorSettings.gql @@ -1,5 +1,5 @@ mutation setConnectionNavigatorSettings($projectId: ID!, $connectionId: ID!, $settings: NavigatorSettingsInput!) { connection: setConnectionNavigatorSettings(projectId: $projectId, id: $connectionId, settings: $settings) { - ...DatabaseConnection + ...DatabaseConnectionNavigatorViewSettings } } diff --git a/webapp/packages/core-sdk/src/queries/fragments/AllNavigatorSettings.gql b/webapp/packages/core-sdk/src/queries/fragments/AllNavigatorSettings.gql index 1f430eaa577..2a43f1ab784 100644 --- a/webapp/packages/core-sdk/src/queries/fragments/AllNavigatorSettings.gql +++ b/webapp/packages/core-sdk/src/queries/fragments/AllNavigatorSettings.gql @@ -6,4 +6,6 @@ fragment AllNavigatorSettings on NavigatorSettings { hideFolders hideSchemas hideVirtualModel -} \ No newline at end of file + + userSettings +} diff --git a/webapp/packages/core-sdk/src/queries/fragments/DatabaseConnection.gql b/webapp/packages/core-sdk/src/queries/fragments/DatabaseConnection.gql index c4e671c0563..8a05f70f7d7 100644 --- a/webapp/packages/core-sdk/src/queries/fragments/DatabaseConnection.gql +++ b/webapp/packages/core-sdk/src/queries/fragments/DatabaseConnection.gql @@ -10,9 +10,6 @@ fragment DatabaseConnection on ConnectionInfo { nodePath features supportedDataFormats - navigatorSettings { - ...AllNavigatorSettings - } canViewSettings canEdit canDelete diff --git a/webapp/packages/core-sdk/src/queries/fragments/DatabaseConnectionNavigatorViewSettings.gql b/webapp/packages/core-sdk/src/queries/fragments/DatabaseConnectionNavigatorViewSettings.gql new file mode 100644 index 00000000000..976059e2a4f --- /dev/null +++ b/webapp/packages/core-sdk/src/queries/fragments/DatabaseConnectionNavigatorViewSettings.gql @@ -0,0 +1,10 @@ +fragment DatabaseConnectionNavigatorViewSettings on ConnectionInfo { + id + projectId + navigatorSettings { + ...AllNavigatorSettings + } + defaultNavigatorSettings { + ...AllNavigatorSettings + } +} diff --git a/webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/ServerConfigurationFormPart.ts b/webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/ServerConfigurationFormPart.ts index f16b23de7ce..213b770edfc 100644 --- a/webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/ServerConfigurationFormPart.ts +++ b/webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/ServerConfigurationFormPart.ts @@ -7,10 +7,15 @@ */ import { AdministrationScreenService } from '@cloudbeaver/core-administration'; import { ADMIN_USERNAME_MIN_LENGTH, AUTH_PROVIDER_LOCAL_ID, AuthProvidersResource, PasswordPolicyService } from '@cloudbeaver/core-authentication'; -import { DEFAULT_NAVIGATOR_VIEW_SETTINGS } from '@cloudbeaver/core-connections'; import { ExecutorInterrupter, type IExecutionContextProvider } from '@cloudbeaver/core-executor'; import { CachedMapAllKey } from '@cloudbeaver/core-resource'; -import { DefaultNavigatorSettingsResource, PasswordPolicyResource, ProductInfoResource, ServerConfigResource } from '@cloudbeaver/core-root'; +import { + DefaultNavigatorSettingsResource, + PasswordPolicyResource, + ProductInfoResource, + ServerConfigResource, + DEFAULT_NAVIGATOR_VIEW_SETTINGS, +} from '@cloudbeaver/core-root'; import { FormPart, formValidationContext, type IFormState } from '@cloudbeaver/core-ui'; import { isIp, isObjectsEqual, isValuesEqual } from '@cloudbeaver/core-utils'; import { LocalizationService } from '@cloudbeaver/core-localization'; diff --git a/webapp/packages/plugin-connection-view/.gitignore b/webapp/packages/plugin-connection-view/.gitignore new file mode 100644 index 00000000000..fd03da61a36 --- /dev/null +++ b/webapp/packages/plugin-connection-view/.gitignore @@ -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* \ No newline at end of file diff --git a/webapp/packages/plugin-connection-view/package.json b/webapp/packages/plugin-connection-view/package.json new file mode 100644 index 00000000000..23ae96e4de5 --- /dev/null +++ b/webapp/packages/plugin-connection-view/package.json @@ -0,0 +1,55 @@ +{ + "name": "@cloudbeaver/plugin-connection-view", + "type": "module", + "sideEffects": [ + "./lib/module.js", + "./lib/index.js", + "src/**/*.css", + "src/**/*.scss", + "public/**/*" + ], + "version": "0.1.0", + "description": "", + "license": "Apache-2.0", + "exports": { + ".": "./lib/index.js", + "./module": "./lib/module.js" + }, + "scripts": { + "build": "tsc -b", + "clean": "rimraf --glob lib", + "lint": "eslint ./src/ --ext .ts,.tsx", + "validate-dependencies": "core-cli-validate-dependencies" + }, + "dependencies": { + "@cloudbeaver/core-blocks": "workspace:*", + "@cloudbeaver/core-connections": "workspace:*", + "@cloudbeaver/core-data-context": "workspace:*", + "@cloudbeaver/core-di": "workspace:*", + "@cloudbeaver/core-events": "workspace:*", + "@cloudbeaver/core-localization": "workspace:*", + "@cloudbeaver/core-navigation-tree": "workspace:*", + "@cloudbeaver/core-projects": "workspace:*", + "@cloudbeaver/core-resource": "workspace:*", + "@cloudbeaver/core-root": "workspace:*", + "@cloudbeaver/core-sdk": "workspace:*", + "@cloudbeaver/core-ui": "workspace:*", + "@cloudbeaver/core-utils": "workspace:*", + "@cloudbeaver/core-view": "workspace:*", + "@cloudbeaver/plugin-connections": "workspace:*", + "@dbeaver/js-helpers": "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", + "rimraf": "^6", + "typescript": "^5", + "typescript-plugin-css-modules": "^5" + } +} diff --git a/webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_VIEW_ADVANCED.ts b/webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_ADVANCED.ts similarity index 74% rename from webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_VIEW_ADVANCED.ts rename to webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_ADVANCED.ts index bb06bd3b19d..9106023b140 100644 --- a/webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_VIEW_ADVANCED.ts +++ b/webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_ADVANCED.ts @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -8,6 +8,6 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_CONNECTION_VIEW_ADVANCED = createAction('connection-view-advanced', { - label: 'app_navigationTree_connection_view_option_advanced', + label: 'plugin_connection_view_option_advanced', type: 'select', }); diff --git a/webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_RESET.ts b/webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_RESET.ts new file mode 100644 index 00000000000..ab4c1b19686 --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_RESET.ts @@ -0,0 +1,14 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 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 { createAction } from '@cloudbeaver/core-view'; + +export const ACTION_CONNECTION_VIEW_RESET = createAction('connection-view-reset', { + label: 'ui_reset', + tooltip: 'plugin_connection_view_option_reset_description', +}); diff --git a/webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_VIEW_SIMPLE.ts b/webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_SIMPLE.ts similarity index 74% rename from webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_VIEW_SIMPLE.ts rename to webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_SIMPLE.ts index e3778facb31..f8c2d228fe3 100644 --- a/webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_VIEW_SIMPLE.ts +++ b/webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_SIMPLE.ts @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -8,6 +8,6 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_CONNECTION_VIEW_SIMPLE = createAction('connection-view-simple', { - label: 'app_navigationTree_connection_view_option_simple', + label: 'plugin_connection_view_option_simple', type: 'select', }); diff --git a/webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS.ts b/webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS.ts similarity index 74% rename from webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS.ts rename to webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS.ts index bd314236275..088458a386b 100644 --- a/webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS.ts +++ b/webapp/packages/plugin-connection-view/src/Actions/ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS.ts @@ -1,13 +1,14 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others + * Copyright (C) 2020-2026 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 { createAction } from '@cloudbeaver/core-view'; export const ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS = createAction('connection-view-system-objects', { - label: 'app_navigationTree_connection_view_option_showSystemObjects', + label: 'plugin_connection_view_option_show_system_objects', type: 'checkbox', }); diff --git a/webapp/packages/plugin-connection-view/src/ConnectionViewForm.tsx b/webapp/packages/plugin-connection-view/src/ConnectionViewForm.tsx new file mode 100644 index 00000000000..b8dbe15ea5f --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/ConnectionViewForm.tsx @@ -0,0 +1,44 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 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 { Container, FieldCheckbox, Group, GroupTitle, useAutoLoad, useTranslate } from '@cloudbeaver/core-blocks'; +import { CONNECTION_NAVIGATOR_VIEW_SETTINGS, isNavigatorViewSettingsEqual } from '@cloudbeaver/core-root'; +import { getConnectionFormOptionsPart, type ConnectionFormContainerProps } from '@cloudbeaver/plugin-connections'; + +import { getConnectionViewPart } from './getConnectionViewPart.js'; + +export const ConnectionViewForm = observer(function ConnectionViewForm({ formState }) { + const translate = useTranslate(); + const optionsFormPart = getConnectionFormOptionsPart(formState); + const viewFormPart = getConnectionViewPart(formState); + + useAutoLoad(ConnectionViewForm, [optionsFormPart, viewFormPart]); + + const isSimple = isNavigatorViewSettingsEqual(viewFormPart.state, CONNECTION_NAVIGATOR_VIEW_SETTINGS.simple); + + function changeView() { + const view = isSimple ? CONNECTION_NAVIGATOR_VIEW_SETTINGS.advanced : CONNECTION_NAVIGATOR_VIEW_SETTINGS.simple; + viewFormPart.state = { ...viewFormPart.state, ...view }; + } + + return ( + + {translate('plugin_connection_view')} + + + {translate('plugin_connection_view_option_simple')} + + + {translate('plugin_connection_view_option_show_system_objects')} + + + + ); +}); diff --git a/webapp/packages/plugin-connection-view/src/ConnectionViewPart.ts b/webapp/packages/plugin-connection-view/src/ConnectionViewPart.ts new file mode 100644 index 00000000000..622be3bb190 --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/ConnectionViewPart.ts @@ -0,0 +1,60 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 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 NavigatorViewSettings, DEFAULT_NAVIGATOR_VIEW_SETTINGS } from '@cloudbeaver/core-root'; +import { FormPart, type IFormState } from '@cloudbeaver/core-ui'; +import type { ConnectionFormOptionsPart, IConnectionFormState } from '@cloudbeaver/plugin-connections'; + +import type { ConnectionViewService } from './ConnectionViewService.js'; +import type { ConnectionViewResource } from './ConnectionViewResource.js'; + +export type ConnectionViewPartState = Required>; + +function defaultStateGetter(): ConnectionViewPartState { + return { ...DEFAULT_NAVIGATOR_VIEW_SETTINGS }; +} + +export class ConnectionViewPart extends FormPart { + constructor( + formState: IFormState, + private readonly optionsPart: ConnectionFormOptionsPart, + private readonly connectionViewService: ConnectionViewService, + private readonly connectionViewResource: ConnectionViewResource, + ) { + super(formState, defaultStateGetter()); + } + + override isOutdated(): boolean { + if (!this.optionsPart.connectionKey) { + return false; + } + + return this.connectionViewResource.isOutdated(this.optionsPart.connectionKey); + } + + protected override async loader(): Promise { + if (!this.optionsPart.connectionKey) { + this.setInitialState(defaultStateGetter()); + return; + } + + const settings = await this.connectionViewResource.load(this.optionsPart.connectionKey); + this.setInitialState({ ...settings.defaultNavigatorSettings }); + } + + protected override async saveChanges(data: IFormState): Promise { + if (!this.optionsPart.connectionKey) { + return; + } + + await this.connectionViewService.changeConnectionView(this.optionsPart.connectionKey, { + ...this.state, + userSettings: false, + }); + } +} diff --git a/webapp/packages/plugin-connection-view/src/ConnectionViewPluginBootstrap.ts b/webapp/packages/plugin-connection-view/src/ConnectionViewPluginBootstrap.ts new file mode 100644 index 00000000000..bc6ffd81dbf --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/ConnectionViewPluginBootstrap.ts @@ -0,0 +1,169 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 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 { DATA_CONTEXT_CONNECTION, type IConnectionInfoParams } from '@cloudbeaver/core-connections'; +import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { importLazyComponent } from '@cloudbeaver/core-blocks'; +import { ActionService, MenuSeparatorItem, MenuService } from '@cloudbeaver/core-view'; +import { DATA_CONTEXT_NAV_NODE, EObjectFeature } from '@cloudbeaver/core-navigation-tree'; +import { + CONNECTION_NAVIGATOR_VIEW_SETTINGS, + EAdminPermission, + isNavigatorViewSettingsEqual, + PermissionsService, + type NavigatorViewSettings, +} from '@cloudbeaver/core-root'; +import { getCachedMapResourceLoaderState } from '@cloudbeaver/core-resource'; +import { ProjectInfoResource } from '@cloudbeaver/core-projects'; +import { ConnectionFormService, PluginConnectionsSettingsService } from '@cloudbeaver/plugin-connections'; + +import { ACTION_CONNECTION_VIEW_SIMPLE } from './Actions/ACTION_CONNECTION_VIEW_SIMPLE.js'; +import { ACTION_CONNECTION_VIEW_ADVANCED } from './Actions/ACTION_CONNECTION_VIEW_ADVANCED.js'; +import { ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS } from './Actions/ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS.js'; +import { MENU_CONNECTION_VIEW } from './MENU_CONNECTION_VIEW.js'; +import { ACTION_CONNECTION_VIEW_RESET } from './Actions/ACTION_CONNECTION_VIEW_RESET.js'; +import { ConnectionViewService } from './ConnectionViewService.js'; +import { ConnectionViewResource } from './ConnectionViewResource.js'; + +const ConnectionViewForm = importLazyComponent(() => import('./ConnectionViewForm.js').then(m => m.ConnectionViewForm)); + +@injectable(() => [ + ActionService, + MenuService, + PluginConnectionsSettingsService, + PermissionsService, + ConnectionFormService, + ProjectInfoResource, + ConnectionViewService, + ConnectionViewResource, +]) +export class ConnectionViewPluginBootstrap extends Bootstrap { + constructor( + private readonly actionService: ActionService, + private readonly menuService: MenuService, + private readonly pluginConnectionsSettingsService: PluginConnectionsSettingsService, + private readonly permissionsService: PermissionsService, + private readonly connectionFormService: ConnectionFormService, + private readonly projectInfoResource: ProjectInfoResource, + private readonly connectionViewService: ConnectionViewService, + private readonly connectionViewResource: ConnectionViewResource, + ) { + super(); + } + + override register(): void { + this.menuService.addCreator({ + root: true, + contexts: [DATA_CONTEXT_CONNECTION, DATA_CONTEXT_NAV_NODE], + isApplicable: context => { + if (this.pluginConnectionsSettingsService.hideConnectionViewForUsers && !this.permissionsService.has(EAdminPermission.admin)) { + return false; + } + + const node = context.get(DATA_CONTEXT_NAV_NODE)!; + return node.objectFeatures.includes(EObjectFeature.dataSource); + }, + getItems: (context, items) => [...items, MENU_CONNECTION_VIEW], + }); + + this.menuService.addCreator({ + menus: [MENU_CONNECTION_VIEW], + getItems: (context, items) => [ + ...items, + ACTION_CONNECTION_VIEW_SIMPLE, + ACTION_CONNECTION_VIEW_ADVANCED, + new MenuSeparatorItem(), + ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS, + ACTION_CONNECTION_VIEW_RESET, + ], + }); + + this.actionService.addHandler({ + id: 'connection-view', + actions: [ACTION_CONNECTION_VIEW_SIMPLE, ACTION_CONNECTION_VIEW_ADVANCED, ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS, ACTION_CONNECTION_VIEW_RESET], + contexts: [DATA_CONTEXT_CONNECTION], + isActionApplicable: (context, action) => { + if (action === ACTION_CONNECTION_VIEW_RESET) { + const connectionKey = context.get(DATA_CONTEXT_CONNECTION)!; + const settings = this.connectionViewResource.get(connectionKey); + + if (settings) { + const isShared = this.projectInfoResource.isProjectShared(settings.projectId); + return settings.navigatorSettings.userSettings && isShared; + } + } + + return true; + }, + isChecked: (context, action) => { + const connectionKey = context.get(DATA_CONTEXT_CONNECTION)!; + const settings = this.connectionViewResource.get(connectionKey); + + if (!settings) { + return false; + } + + switch (action) { + case ACTION_CONNECTION_VIEW_SIMPLE: { + return isNavigatorViewSettingsEqual(settings.navigatorSettings, CONNECTION_NAVIGATOR_VIEW_SETTINGS.simple); + } + case ACTION_CONNECTION_VIEW_ADVANCED: { + return isNavigatorViewSettingsEqual(settings.navigatorSettings, CONNECTION_NAVIGATOR_VIEW_SETTINGS.advanced); + } + case ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS: { + return settings.navigatorSettings.showSystemObjects; + } + } + + return false; + }, + handler: async (context, action) => { + const connectionKey = context.get(DATA_CONTEXT_CONNECTION)!; + const settings = await this.connectionViewResource.load(connectionKey); + + switch (action) { + case ACTION_CONNECTION_VIEW_SIMPLE: { + await this.changeConnectionView(connectionKey, CONNECTION_NAVIGATOR_VIEW_SETTINGS.simple); + break; + } + case ACTION_CONNECTION_VIEW_ADVANCED: { + await this.changeConnectionView(connectionKey, CONNECTION_NAVIGATOR_VIEW_SETTINGS.advanced); + break; + } + case ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS: { + const currentSettings = settings.navigatorSettings; + + await this.changeConnectionView(connectionKey, { + ...currentSettings, + showSystemObjects: !currentSettings.showSystemObjects, + }); + break; + } + case ACTION_CONNECTION_VIEW_RESET: { + await this.connectionViewService.clearConnectionView(connectionKey); + break; + } + } + }, + getLoader: context => { + const connectionKey = context.get(DATA_CONTEXT_CONNECTION)!; + return getCachedMapResourceLoaderState(this.connectionViewResource, () => connectionKey, undefined, true); + }, + }); + + this.connectionFormService.connectionContainer.add( + ConnectionViewForm, + undefined, + props => !this.projectInfoResource.isProjectShared(props.formState.state.projectId), + ); + } + + private async changeConnectionView(connectionKey: IConnectionInfoParams, settings: NavigatorViewSettings): Promise { + await this.connectionViewService.changeConnectionView(connectionKey, { ...settings, userSettings: true }); + } +} diff --git a/webapp/packages/plugin-connection-view/src/ConnectionViewResource.ts b/webapp/packages/plugin-connection-view/src/ConnectionViewResource.ts new file mode 100644 index 00000000000..43d9b72a66e --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/ConnectionViewResource.ts @@ -0,0 +1,137 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 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 { runInAction, toJS } from 'mobx'; + +import { + CONNECTION_INFO_PARAM_SCHEMA, + ConnectionInfoActiveProjectKey, + ConnectionInfoProjectKey, + ConnectionInfoResource, + createConnectionParam, + type IConnectionInfoParams, + isConnectionInfoParamEqual, + parseConnectionKey, +} from '@cloudbeaver/core-connections'; +import { injectable } from '@cloudbeaver/core-di'; +import { CachedMapResource, isResourceAlias, type ResourceKey, resourceKeyList, ResourceKeyUtils } from '@cloudbeaver/core-resource'; +import { schemaValidationError } from '@cloudbeaver/core-utils'; +import { GraphQLService, type DatabaseConnectionNavigatorViewSettingsFragment } from '@cloudbeaver/core-sdk'; +import { ProjectsService } from '@cloudbeaver/core-projects'; +import { DEFAULT_NAVIGATOR_VIEW_SETTINGS, type NavigatorViewSettings } from '@cloudbeaver/core-root'; + +type NavigatorViewSettingsInfo = DatabaseConnectionNavigatorViewSettingsFragment; + +@injectable(() => [GraphQLService, ConnectionInfoResource, ProjectsService]) +export class ConnectionViewResource extends CachedMapResource { + constructor( + private readonly graphQLService: GraphQLService, + private readonly connectionInfoResource: ConnectionInfoResource, + private readonly projectsService: ProjectsService, + ) { + super(); + + this.aliases.add(ConnectionInfoProjectKey, param => resourceKeyList(this.keys.filter(key => param.options.projectIds.includes(key.projectId)))); + + this.aliases.add(ConnectionInfoActiveProjectKey, () => + resourceKeyList(this.keys.filter(key => projectsService.activeProjects.some(({ id }) => id === key.projectId))), + ); + + this.sync(this.connectionInfoResource); + this.connectionInfoResource.onItemDelete.addHandler(this.delete.bind(this)); + } + + async changeConnectionView(key: IConnectionInfoParams, settings: NavigatorViewSettings): Promise { + const connectionNavigatorViewSettings = this.get(key)?.navigatorSettings || DEFAULT_NAVIGATOR_VIEW_SETTINGS; + const { connection } = await this.graphQLService.sdk.setConnectionNavigatorSettings({ + connectionId: key.connectionId, + projectId: key.projectId, + settings: { ...connectionNavigatorViewSettings, ...settings }, + }); + + this.set(key, connection); + return this.get(key)!; + } + + async clearConnectionView(key: IConnectionInfoParams): Promise { + const { connection } = await this.graphQLService.sdk.clearConnectionNavigatorSettings({ + id: key.connectionId, + projectId: key.projectId, + }); + + this.set(key, connection); + this.onDataOutdated.execute(key); + + return this.get(key)!; + } + + protected async loader( + originalKey: ResourceKey, + _: any, + refresh?: boolean, + ): Promise> { + const connectionsList: NavigatorViewSettingsInfo[] = []; + let removedConnections: IConnectionInfoParams[] = []; + const parsed = parseConnectionKey({ + originalKey, + aliases: this.aliases, + isOutdated: this.isOutdated.bind(this), + activeProjects: this.projectsService.activeProjects, + refresh, + }); + + let { projectId } = parsed; + const { projectIds, key } = parsed; + + await ResourceKeyUtils.forEachAsync(key, async connectionKey => { + let connectionId: string | undefined; + if (!isResourceAlias(connectionKey)) { + projectId = connectionKey.projectId; + connectionId = connectionKey.connectionId; + } + + const { connections } = await this.graphQLService.sdk.getUserConnectionsNavigatorViewSettings({ + projectId, + connectionId, + projectIds, + }); + + if (connectionId && !connections.some(connection => connection.id === connectionId)) { + throw new Error(`Connection is not found (${connectionId})`); + } + + connectionsList.push(...connections); + }); + + runInAction(() => { + if (isResourceAlias(key)) { + removedConnections = ResourceKeyUtils.toList(this.aliases.transformToKey(key)).filter( + filterKey => !connectionsList.some(connection => isConnectionInfoParamEqual(filterKey, createConnectionParam(connection))), + ); + } + + this.delete(resourceKeyList(removedConnections)); + const keys = resourceKeyList(connectionsList.map(createConnectionParam)); + this.set(keys, connectionsList); + }); + + return this.data; + } + + override isKeyEqual(param: IConnectionInfoParams, second: IConnectionInfoParams): boolean { + return isConnectionInfoParamEqual(param, second); + } + + protected validateKey(key: IConnectionInfoParams): boolean { + const parse = CONNECTION_INFO_PARAM_SCHEMA.safeParse(toJS(key)); + if (!parse.success) { + this.logger.warn(`Invalid resource key ${(schemaValidationError(parse.error).toString(), { prefix: null })}`); + } + return parse.success; + } +} diff --git a/webapp/packages/plugin-connection-view/src/ConnectionViewService.ts b/webapp/packages/plugin-connection-view/src/ConnectionViewService.ts new file mode 100644 index 00000000000..3b2d5fe61df --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/ConnectionViewService.ts @@ -0,0 +1,46 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 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 { ConnectionInfoResource, type IConnectionInfoParams } from '@cloudbeaver/core-connections'; +import { injectable } from '@cloudbeaver/core-di'; +import { NavNodeManagerService } from '@cloudbeaver/core-navigation-tree'; +import { type NavigatorViewSettings } from '@cloudbeaver/core-root'; + +import { ConnectionViewResource } from './ConnectionViewResource.js'; + +@injectable(() => [ConnectionInfoResource, NavNodeManagerService, ConnectionViewResource]) +export class ConnectionViewService { + constructor( + private readonly connectionInfoResource: ConnectionInfoResource, + private readonly navNodeManagerService: NavNodeManagerService, + private readonly connectionViewResource: ConnectionViewResource, + ) {} + + async changeConnectionView(connectionKey: IConnectionInfoParams, settings: NavigatorViewSettings): Promise { + const view = await this.connectionViewResource.changeConnectionView(connectionKey, settings); + + if (settings.userSettings === false && view.navigatorSettings.userSettings) { + return; + } + + await this.syncNode(connectionKey); + } + + async clearConnectionView(connectionKey: IConnectionInfoParams): Promise { + await this.connectionViewResource.clearConnectionView(connectionKey); + await this.syncNode(connectionKey); + } + + private async syncNode(connectionKey: IConnectionInfoParams) { + const connection = await this.connectionInfoResource.load(connectionKey); + + if (connection.nodePath && connection.connected) { + await this.navNodeManagerService.refreshNode(connection.nodePath); + } + } +} diff --git a/webapp/packages/plugin-connection-view/src/LocaleService.ts b/webapp/packages/plugin-connection-view/src/LocaleService.ts new file mode 100644 index 00000000000..5dec550ef8b --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/LocaleService.ts @@ -0,0 +1,38 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 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(() => [LocalizationService]) +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; + case 'vi': + return (await import('./locales/vi.js')).default; + default: + return (await import('./locales/en.js')).default; + } + } +} diff --git a/webapp/packages/plugin-connections/src/ContextMenu/MENU_CONNECTION_VIEW.ts b/webapp/packages/plugin-connection-view/src/MENU_CONNECTION_VIEW.ts similarity index 73% rename from webapp/packages/plugin-connections/src/ContextMenu/MENU_CONNECTION_VIEW.ts rename to webapp/packages/plugin-connection-view/src/MENU_CONNECTION_VIEW.ts index 36e2ec4bfed..6b8b58c143e 100644 --- a/webapp/packages/plugin-connections/src/ContextMenu/MENU_CONNECTION_VIEW.ts +++ b/webapp/packages/plugin-connection-view/src/MENU_CONNECTION_VIEW.ts @@ -1,10 +1,11 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2025 DBeaver Corp and others + * Copyright (C) 2020-2026 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 { createMenu } from '@cloudbeaver/core-view'; -export const MENU_CONNECTION_VIEW = createMenu('connection-view', { label: 'app_navigationTree_connection_view' }); +export const MENU_CONNECTION_VIEW = createMenu('connection-view', { label: 'plugin_connection_view' }); diff --git a/webapp/packages/plugin-connection-view/src/getConnectionViewPart.ts b/webapp/packages/plugin-connection-view/src/getConnectionViewPart.ts new file mode 100644 index 00000000000..18837c1a1d4 --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/getConnectionViewPart.ts @@ -0,0 +1,28 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 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 { IFormState } from '@cloudbeaver/core-ui'; +import { type IConnectionFormState, getConnectionFormOptionsPart } from '@cloudbeaver/plugin-connections'; +import { createDataContext, DATA_CONTEXT_DI_PROVIDER } from '@cloudbeaver/core-data-context'; + +import { ConnectionViewPart } from './ConnectionViewPart.js'; +import { ConnectionViewService } from './ConnectionViewService.js'; +import { ConnectionViewResource } from './ConnectionViewResource.js'; + +const DATA_CONTEXT_CONNECTION_FORM_VIEW_PART = createDataContext('Connection Form View Part'); + +export function getConnectionViewPart(formState: IFormState): ConnectionViewPart { + return formState.getPart(DATA_CONTEXT_CONNECTION_FORM_VIEW_PART, context => { + const di = context.get(DATA_CONTEXT_DI_PROVIDER)!; + const optionsPart = getConnectionFormOptionsPart(formState); + const connectionViewService = di.getService(ConnectionViewService); + const connectionViewResource = di.getService(ConnectionViewResource); + + return new ConnectionViewPart(formState, optionsPart, connectionViewService, connectionViewResource); + }); +} diff --git a/webapp/packages/plugin-connection-view/src/index.ts b/webapp/packages/plugin-connection-view/src/index.ts new file mode 100644 index 00000000000..36eb47b0b19 --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/index.ts @@ -0,0 +1,9 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 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 './module.js'; diff --git a/webapp/packages/plugin-connection-view/src/locales/en.ts b/webapp/packages/plugin-connection-view/src/locales/en.ts new file mode 100644 index 00000000000..c8e606e1f87 --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/locales/en.ts @@ -0,0 +1,7 @@ +export default [ + ['plugin_connection_view', 'Connection view'], + ['plugin_connection_view_option_simple', 'Simple'], + ['plugin_connection_view_option_advanced', 'Advanced'], + ['plugin_connection_view_option_show_system_objects', 'Show system objects'], + ['plugin_connection_view_option_reset_description', 'This will reset the connection view settings to default values'], +]; diff --git a/webapp/packages/plugin-connection-view/src/locales/fr.ts b/webapp/packages/plugin-connection-view/src/locales/fr.ts new file mode 100644 index 00000000000..09a640bdfcd --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/locales/fr.ts @@ -0,0 +1,7 @@ +export default [ + ['plugin_connection_view', 'Vue de connexion'], + ['plugin_connection_view_option_simple', 'Simple'], + ['plugin_connection_view_option_advanced', 'Avancée'], + ['plugin_connection_view_option_custom', 'Personnalisée'], + ['plugin_connection_view_option_reset_description', 'This will reset the connection view settings to default values'], +]; diff --git a/webapp/packages/plugin-connection-view/src/locales/it.ts b/webapp/packages/plugin-connection-view/src/locales/it.ts new file mode 100644 index 00000000000..c46a48d5852 --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/locales/it.ts @@ -0,0 +1,8 @@ +export default [ + ['plugin_connection_view', 'Vista connessione'], + ['plugin_connection_view_option_simple', 'Semplice'], + ['plugin_connection_view_option_advanced', 'Avanzata'], + ['plugin_connection_view_option_custom', 'Personalizzata'], + ['plugin_connection_view_option_show_system_objects', 'Mostra oggetti di sistema'], + ['plugin_connection_view_option_reset_description', 'This will reset the connection view settings to default values'], +]; diff --git a/webapp/packages/plugin-connection-view/src/locales/ru.ts b/webapp/packages/plugin-connection-view/src/locales/ru.ts new file mode 100644 index 00000000000..3669f0a7d1f --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/locales/ru.ts @@ -0,0 +1,7 @@ +export default [ + ['plugin_connection_view', 'Отображение'], + ['plugin_connection_view_option_simple', 'Упрощенное'], + ['plugin_connection_view_option_advanced', 'Продвинутое'], + ['plugin_connection_view_option_show_system_objects', 'Показывать системные объекты'], + ['plugin_connection_view_option_reset_description', 'Это сбросит настройки отображения подключения к значениям по умолчанию'], +]; diff --git a/webapp/packages/plugin-connection-view/src/locales/vi.ts b/webapp/packages/plugin-connection-view/src/locales/vi.ts new file mode 100644 index 00000000000..83ab2697d18 --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/locales/vi.ts @@ -0,0 +1,8 @@ +export default [ + ['plugin_connection_view', 'Chế độ xem kết nối'], + ['plugin_connection_view_option_simple', 'Đơn giản'], + ['plugin_connection_view_option_advanced', 'Nâng cao'], + ['plugin_connection_view_option_custom', 'Tùy chỉnh'], + ['plugin_connection_view_option_show_system_objects', 'Hiển thị đối tượng hệ thống'], + ['plugin_connection_view_option_reset_description', 'This will reset the connection view settings to default values'], +]; diff --git a/webapp/packages/plugin-connection-view/src/locales/zh.ts b/webapp/packages/plugin-connection-view/src/locales/zh.ts new file mode 100644 index 00000000000..de2f8023947 --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/locales/zh.ts @@ -0,0 +1,7 @@ +export default [ + ['plugin_connection_view_option_simple', '简单'], + ['plugin_connection_view_option_advanced', '完善'], + ['plugin_connection_view_option_custom', '自定义'], + ['plugin_connection_view_option_show_system_objects', '展示系统对象'], + ['plugin_connection_view_option_reset_description', 'This will reset the connection view settings to default values'], +]; diff --git a/webapp/packages/plugin-connection-view/src/module.ts b/webapp/packages/plugin-connection-view/src/module.ts new file mode 100644 index 00000000000..df9f270f0e6 --- /dev/null +++ b/webapp/packages/plugin-connection-view/src/module.ts @@ -0,0 +1,26 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 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, ModuleRegistry } from '@cloudbeaver/core-di'; + +import { ConnectionViewPluginBootstrap } from './ConnectionViewPluginBootstrap.js'; +import { LocaleService } from './LocaleService.js'; +import { ConnectionViewService } from './ConnectionViewService.js'; +import { ConnectionViewResource } from './ConnectionViewResource.js'; + +export default ModuleRegistry.add({ + name: '@cloudbeaver/plugin-connection-view', + + configure: serviceCollection => { + serviceCollection + .addSingleton(Bootstrap, ConnectionViewPluginBootstrap) + .addSingleton(Bootstrap, LocaleService) + .addSingleton(ConnectionViewService) + .addSingleton(ConnectionViewResource); + }, +}); diff --git a/webapp/packages/plugin-connection-view/tsconfig.json b/webapp/packages/plugin-connection-view/tsconfig.json new file mode 100644 index 00000000000..b4125f3b827 --- /dev/null +++ b/webapp/packages/plugin-connection-view/tsconfig.json @@ -0,0 +1,73 @@ +{ + "extends": "@cloudbeaver/tsconfig/tsconfig.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib", + "tsBuildInfoFile": "lib/tsconfig.tsbuildinfo", + "composite": true + }, + "references": [ + { + "path": "../../common-typescript/@dbeaver/js-helpers" + }, + { + "path": "../core-blocks" + }, + { + "path": "../core-cli" + }, + { + "path": "../core-connections" + }, + { + "path": "../core-data-context" + }, + { + "path": "../core-di" + }, + { + "path": "../core-events" + }, + { + "path": "../core-localization" + }, + { + "path": "../core-navigation-tree" + }, + { + "path": "../core-projects" + }, + { + "path": "../core-resource" + }, + { + "path": "../core-root" + }, + { + "path": "../core-sdk" + }, + { + "path": "../core-ui" + }, + { + "path": "../core-utils" + }, + { + "path": "../core-view" + }, + { + "path": "../plugin-connections" + } + ], + "include": [ + "__custom_mocks__/**/*", + "src/**/*", + "src/**/*.json", + "src/**/*.css", + "src/**/*.scss" + ], + "exclude": [ + "**/node_modules", + "lib/**/*" + ] +} diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormService.ts b/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormService.ts index 38ddad94ef1..45e764d2f22 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormService.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormService.ts @@ -14,17 +14,19 @@ import { importLazyComponent, PlaceholderContainer } from '@cloudbeaver/core-blo const ConnectionFormBaseActionsLoader = importLazyComponent(() => import('./ConnectionFormBaseActions.js').then(m => m.ConnectionFormBaseActions)); -export type ProviderPropertiesContainerFormProps = { +export type ConnectionFormContainerProps = { formState: IFormState; }; @injectable(() => [LocalizationService, NotificationService]) export class ConnectionFormService extends FormBaseService { - readonly providerPropertiesContainer: PlaceholderContainer; + readonly providerPropertiesContainer: PlaceholderContainer; + readonly connectionContainer: PlaceholderContainer; constructor(localizationService: LocalizationService, notificationService: NotificationService) { super(localizationService, notificationService, 'Connection form'); - this.providerPropertiesContainer = new PlaceholderContainer(); + this.providerPropertiesContainer = new PlaceholderContainer(); + this.connectionContainer = new PlaceholderContainer(); this.actionsContainer.add(ConnectionFormBaseActionsLoader); } } diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/Options/Options.tsx b/webapp/packages/plugin-connections/src/ConnectionForm/Options/Options.tsx index 9d076678536..813cbd19a2d 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/Options/Options.tsx +++ b/webapp/packages/plugin-connections/src/ConnectionForm/Options/Options.tsx @@ -244,6 +244,7 @@ export const Options: TabContainerPanelComponent = observe ))} + {!driver?.anonymousAccess && (authentication.authorized || !edit) && ( {translate('connections_connection_edit_authentication')} @@ -308,6 +309,7 @@ export const Options: TabContainerPanelComponent = observe )} )} + diff --git a/webapp/packages/plugin-connections/src/ContextMenu/ConnectionMenuBootstrap.ts b/webapp/packages/plugin-connections/src/ContextMenu/ConnectionMenuBootstrap.ts index 595a24867c0..434b59c5275 100644 --- a/webapp/packages/plugin-connections/src/ContextMenu/ConnectionMenuBootstrap.ts +++ b/webapp/packages/plugin-connections/src/ContextMenu/ConnectionMenuBootstrap.ts @@ -6,7 +6,6 @@ * you may not use this file except in compliance with the License. */ import { - type Connection, ConnectionInfoAuthPropertiesResource, ConnectionInfoResource, ConnectionsManagerService, @@ -16,43 +15,28 @@ import { } from '@cloudbeaver/core-connections'; import { Bootstrap, injectable } from '@cloudbeaver/core-di'; import { NotificationService } from '@cloudbeaver/core-events'; -import { DATA_CONTEXT_NAV_NODE, EObjectFeature, NavNodeManagerService } from '@cloudbeaver/core-navigation-tree'; +import { DATA_CONTEXT_NAV_NODE, EObjectFeature } from '@cloudbeaver/core-navigation-tree'; import { getCachedMapResourceLoaderState } from '@cloudbeaver/core-resource'; -import { - CONNECTION_NAVIGATOR_VIEW_SETTINGS, - EAdminPermission, - isNavigatorViewSettingsEqual, - type NavigatorViewSettings, - PermissionsService, - ServerConfigResource, -} from '@cloudbeaver/core-root'; -import { ACTION_DELETE, ActionService, MenuSeparatorItem, MenuService } from '@cloudbeaver/core-view'; +import { ServerConfigResource } from '@cloudbeaver/core-root'; +import { ACTION_DELETE, ActionService, MenuService } from '@cloudbeaver/core-view'; import { MENU_APP_ACTIONS } from '@cloudbeaver/plugin-top-app-bar'; -import { PluginConnectionsSettingsService } from '../PluginConnectionsSettingsService.js'; import { PublicConnectionFormService } from '../PublicConnectionForm/PublicConnectionFormService.js'; import { ACTION_CONNECTION_CHANGE_CREDENTIALS } from './Actions/ACTION_CONNECTION_CHANGE_CREDENTIALS.js'; import { ACTION_CONNECTION_DISCONNECT } from './Actions/ACTION_CONNECTION_DISCONNECT.js'; import { ACTION_CONNECTION_DISCONNECT_ALL } from './Actions/ACTION_CONNECTION_DISCONNECT_ALL.js'; import { ACTION_CONNECTION_EDIT } from './Actions/ACTION_CONNECTION_EDIT.js'; -import { ACTION_CONNECTION_VIEW_ADVANCED } from './Actions/ACTION_CONNECTION_VIEW_ADVANCED.js'; -import { ACTION_CONNECTION_VIEW_SIMPLE } from './Actions/ACTION_CONNECTION_VIEW_SIMPLE.js'; -import { ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS } from './Actions/ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS.js'; -import { MENU_CONNECTION_VIEW } from './MENU_CONNECTION_VIEW.js'; import { MENU_CONNECTIONS } from './MENU_CONNECTIONS.js'; @injectable(() => [ NotificationService, ConnectionInfoResource, ConnectionInfoAuthPropertiesResource, - NavNodeManagerService, ConnectionsManagerService, ActionService, MenuService, PublicConnectionFormService, ConnectionsSettingsService, - PluginConnectionsSettingsService, - PermissionsService, ServerConfigResource, ]) export class ConnectionMenuBootstrap extends Bootstrap { @@ -60,14 +44,11 @@ export class ConnectionMenuBootstrap extends Bootstrap { private readonly notificationService: NotificationService, private readonly connectionInfoResource: ConnectionInfoResource, private readonly connectionInfoAuthPropertiesResource: ConnectionInfoAuthPropertiesResource, - private readonly navNodeManagerService: NavNodeManagerService, private readonly connectionsManagerService: ConnectionsManagerService, private readonly actionService: ActionService, private readonly menuService: MenuService, private readonly publicConnectionFormService: PublicConnectionFormService, private readonly connectionsSettingsService: ConnectionsSettingsService, - private readonly pluginConnectionsSettingsService: PluginConnectionsSettingsService, - private readonly permissionsService: PermissionsService, private readonly serverConfigResource: ServerConfigResource, ) { super(); @@ -76,88 +57,6 @@ export class ConnectionMenuBootstrap extends Bootstrap { override register(): void { this.addConnectionsMenuToTopAppBar(); - this.menuService.addCreator({ - root: true, - contexts: [DATA_CONTEXT_CONNECTION, DATA_CONTEXT_NAV_NODE], - isApplicable: context => { - if (this.pluginConnectionsSettingsService.hideConnectionViewForUsers && !this.permissionsService.has(EAdminPermission.admin)) { - return false; - } - - const node = context.get(DATA_CONTEXT_NAV_NODE)!; - - return node.objectFeatures.includes(EObjectFeature.dataSource) && node.objectFeatures.includes(EObjectFeature.dataSourceConnected); - }, - getItems: (context, items) => [...items, MENU_CONNECTION_VIEW], - }); - - this.menuService.addCreator({ - menus: [MENU_CONNECTION_VIEW], - getItems: (context, items) => [ - ...items, - ACTION_CONNECTION_VIEW_SIMPLE, - ACTION_CONNECTION_VIEW_ADVANCED, - new MenuSeparatorItem(), - ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS, - ], - }); - - this.actionService.addHandler({ - id: 'connection-view', - actions: [ACTION_CONNECTION_VIEW_SIMPLE, ACTION_CONNECTION_VIEW_ADVANCED, ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS], - contexts: [DATA_CONTEXT_CONNECTION], - isChecked: (context, action) => { - const connectionKey = context.get(DATA_CONTEXT_CONNECTION)!; - const connection = this.connectionInfoResource.get(connectionKey); - - if (!connection) { - return false; - } - - switch (action) { - case ACTION_CONNECTION_VIEW_SIMPLE: { - return isNavigatorViewSettingsEqual(connection.navigatorSettings, CONNECTION_NAVIGATOR_VIEW_SETTINGS.simple); - } - case ACTION_CONNECTION_VIEW_ADVANCED: { - return isNavigatorViewSettingsEqual(connection.navigatorSettings, CONNECTION_NAVIGATOR_VIEW_SETTINGS.advanced); - } - case ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS: { - return connection.navigatorSettings.showSystemObjects; - } - } - - return false; - }, - handler: async (context, action) => { - const connectionKey = context.get(DATA_CONTEXT_CONNECTION)!; - const connection = await this.connectionInfoResource.load(connectionKey); - - switch (action) { - case ACTION_CONNECTION_VIEW_SIMPLE: { - await this.changeConnectionView(connection, CONNECTION_NAVIGATOR_VIEW_SETTINGS.simple); - break; - } - case ACTION_CONNECTION_VIEW_ADVANCED: { - await this.changeConnectionView(connection, CONNECTION_NAVIGATOR_VIEW_SETTINGS.advanced); - break; - } - case ACTION_CONNECTION_VIEW_SYSTEM_OBJECTS: { - const currentSettings = connection.navigatorSettings; - - await this.changeConnectionView(connection, { - ...currentSettings, - showSystemObjects: !currentSettings.showSystemObjects, - }); - break; - } - } - }, - getLoader: context => { - const connectionKey = context.get(DATA_CONTEXT_CONNECTION)!; - return getCachedMapResourceLoaderState(this.connectionInfoResource, () => connectionKey, undefined, true); - }, - }); - this.menuService.addCreator({ root: true, contexts: [DATA_CONTEXT_CONNECTION], @@ -258,18 +157,6 @@ export class ConnectionMenuBootstrap extends Bootstrap { }); } - private async changeConnectionView(connection: Connection, settings: NavigatorViewSettings) { - try { - connection = await this.connectionInfoResource.changeConnectionView(createConnectionParam(connection), settings); - - if (connection.nodePath) { - await this.navNodeManagerService.refreshNode(connection.nodePath); - } - } catch (exception: any) { - this.notificationService.logException(exception); - } - } - private addConnectionsMenuToTopAppBar() { this.menuService.addCreator({ menus: [MENU_APP_ACTIONS], diff --git a/webapp/packages/plugin-connections/src/index.ts b/webapp/packages/plugin-connections/src/index.ts index 07abfbc8bf4..8aa90694d69 100644 --- a/webapp/packages/plugin-connections/src/index.ts +++ b/webapp/packages/plugin-connections/src/index.ts @@ -24,7 +24,6 @@ export * from './ConnectionForm/Options/getConnectionFormOptionsPart.js'; export * from './ConnectionForm/Options/ConnectionFormOptionsPart.js'; export * from './ConnectionForm/SharedCredentials/CONNECTION_FORM_SHARED_CREDENTIALS_TAB_ID.js'; export * from './ConnectionForm/ConnectionAuthModelCredentials/ConnectionAuthModelCredentialsForm.js'; -export * from './ContextMenu/MENU_CONNECTION_VIEW.js'; export * from './ContextMenu/MENU_CONNECTIONS.js'; export * from './PublicConnectionForm/PublicConnectionFormService.js'; export * from './NavNodes/ConnectionNavNodeService.js'; diff --git a/webapp/packages/plugin-navigation-tree/src/locales/en.ts b/webapp/packages/plugin-navigation-tree/src/locales/en.ts index b3870de6af6..3d6ad220a53 100644 --- a/webapp/packages/plugin-navigation-tree/src/locales/en.ts +++ b/webapp/packages/plugin-navigation-tree/src/locales/en.ts @@ -20,11 +20,6 @@ export default [ ['app_navigationTree_node_empty', 'Empty'], ['app_navigationTree_node_no_results', "We're sorry. There no matching results for '{arg:filter}'"], ['app_navigationTree_node_not_found', 'Node not found'], - ['app_navigationTree_connection_view', 'Connection view'], - ['app_navigationTree_connection_view_option_simple', 'Simple'], - ['app_navigationTree_connection_view_option_advanced', 'Advanced'], - ['app_navigationTree_connection_view_option_custom', 'Custom'], - ['app_navigationTree_connection_view_option_showSystemObjects', 'Show system objects'], ['app_navigationTree_refresh', 'Refresh'], ['app_navigationTree_refresh_error', 'Failed to refresh node'], ['app_navigationTree_node_change_name_error', 'Error occurred while changing name'], diff --git a/webapp/packages/plugin-navigation-tree/src/locales/fr.ts b/webapp/packages/plugin-navigation-tree/src/locales/fr.ts index 54430d672b7..c106f5b30fe 100644 --- a/webapp/packages/plugin-navigation-tree/src/locales/fr.ts +++ b/webapp/packages/plugin-navigation-tree/src/locales/fr.ts @@ -21,10 +21,6 @@ export default [ ['app_navigationTree_node_empty', 'Vide'], ['app_navigationTree_node_no_results', 'Nous sommes désolés. Aucun résultat correspondant pour "{arg:filter}"'], ['app_navigationTree_node_not_found', 'Nœud introuvable'], - ['app_navigationTree_connection_view', 'Vue de connexion'], - ['app_navigationTree_connection_view_option_simple', 'Simple'], - ['app_navigationTree_connection_view_option_advanced', 'Avancée'], - ['app_navigationTree_connection_view_option_custom', 'Personnalisée'], ['app_navigationTree_refresh', 'Actualiser'], ['app_navigationTree_refresh_error', "Échec de l'actualisation du nœud"], ['app_navigationTree_node_change_error', "Une erreur s'est produite lors du changement de nom"], diff --git a/webapp/packages/plugin-navigation-tree/src/locales/it.ts b/webapp/packages/plugin-navigation-tree/src/locales/it.ts index c3d131def04..97096fd6768 100644 --- a/webapp/packages/plugin-navigation-tree/src/locales/it.ts +++ b/webapp/packages/plugin-navigation-tree/src/locales/it.ts @@ -13,18 +13,13 @@ export default [ ['app_navigationTree_node_folder_delete_confirmation', 'Tutti i contenuti nella cartella selezionata saranno eliminati.'], ['app_navigationTree_node_delete_error', 'Impossibile eliminare "{arg:name}"'], ['app_navigationTree_node_rename_error', 'Si è verificato un errore durante la rinominazione'], - ['app_navigationTree_settings_state_title', 'Salva stato dell\'albero'], - ['app_navigationTree_settings_state_description', 'Riapri i nodi espansi dopo l\'aggiornamento della pagina'], + ['app_navigationTree_settings_state_title', "Salva stato dell'albero"], + ['app_navigationTree_settings_state_description', "Riapri i nodi espansi dopo l'aggiornamento della pagina"], ['app_navigationTree_settings_folders_title', 'Cartelle'], - ['app_navigationTree_settings_folders_description', 'Apri qualsiasi nodo come radice dell\'albero'], + ['app_navigationTree_settings_folders_description', "Apri qualsiasi nodo come radice dell'albero"], ['app_navigationTree_node_empty', 'Vuoto'], ['app_navigationTree_node_no_results', 'Siamo spiacenti. Nessun risultato corrispondente per "{arg:filter}"'], ['app_navigationTree_node_not_found', 'Nodo non trovato'], - ['app_navigationTree_connection_view', 'Vista connessione'], - ['app_navigationTree_connection_view_option_simple', 'Semplice'], - ['app_navigationTree_connection_view_option_advanced', 'Avanzata'], - ['app_navigationTree_connection_view_option_custom', 'Personalizzata'], - ['app_navigationTree_connection_view_option_showSystemObjects', 'Mostra oggetti di sistema'], ['app_navigationTree_refresh', 'Aggiorna'], ['app_navigationTree_refresh_error', 'Impossibile aggiornare il nodo'], ['app_navigationTree_context_disconnect', 'Disconnetti'], @@ -34,6 +29,6 @@ export default [ ['plugin_navigation_tree_settings_projects_description', 'Mostra gli elementi sotto i gruppi di progetto'], ['plugin_navigation_tree_settings_projects_title', 'Raggruppa per progetto'], ['plugin_navigation_tree_settings_disable', 'Disabilita'], - ['plugin_navigation_tree_settings_disable_description', 'Disabilita l\'albero di navigazione per tutti gli utenti'], - ['plugin_navigation_tree_toolbar_menu_title', 'Barra degli strumenti dell\'albero'], + ['plugin_navigation_tree_settings_disable_description', "Disabilita l'albero di navigazione per tutti gli utenti"], + ['plugin_navigation_tree_toolbar_menu_title', "Barra degli strumenti dell'albero"], ]; diff --git a/webapp/packages/plugin-navigation-tree/src/locales/ru.ts b/webapp/packages/plugin-navigation-tree/src/locales/ru.ts index 3d11ea49080..4a842f8a2f2 100644 --- a/webapp/packages/plugin-navigation-tree/src/locales/ru.ts +++ b/webapp/packages/plugin-navigation-tree/src/locales/ru.ts @@ -23,11 +23,6 @@ export default [ ['app_navigationTree_node_empty', 'Пусто'], ['app_navigationTree_node_no_results', "Извините, не удалось найти элементы содержащие '{arg:filter}'"], ['app_navigationTree_node_not_found', 'Элемент не найден'], - ['app_navigationTree_connection_view', 'Отображение'], - ['app_navigationTree_connection_view_option_simple', 'Упрощенное'], - ['app_navigationTree_connection_view_option_advanced', 'Продвинутое'], - ['app_navigationTree_connection_view_option_custom', 'Настраиваемое'], - ['app_navigationTree_connection_view_option_showSystemObjects', 'Показывать системные объекты'], ['app_navigationTree_refresh', 'Обновить'], ['app_navigationTree_refresh_error', 'Не удалось обновить узел'], ['app_navigationTree_node_change_name_error', 'Не удалось изменить название'], diff --git a/webapp/packages/plugin-navigation-tree/src/locales/vi.ts b/webapp/packages/plugin-navigation-tree/src/locales/vi.ts index eb0faf24120..d808947c9dc 100644 --- a/webapp/packages/plugin-navigation-tree/src/locales/vi.ts +++ b/webapp/packages/plugin-navigation-tree/src/locales/vi.ts @@ -20,11 +20,6 @@ export default [ ['app_navigationTree_node_empty', 'Trống'], ['app_navigationTree_node_no_results', 'Xin lỗi. Không có kết quả phù hợp cho "{arg:filter}"'], ['app_navigationTree_node_not_found', 'Không tìm thấy nút'], - ['app_navigationTree_connection_view', 'Chế độ xem kết nối'], - ['app_navigationTree_connection_view_option_simple', 'Đơn giản'], - ['app_navigationTree_connection_view_option_advanced', 'Nâng cao'], - ['app_navigationTree_connection_view_option_custom', 'Tùy chỉnh'], - ['app_navigationTree_connection_view_option_showSystemObjects', 'Hiển thị đối tượng hệ thống'], ['app_navigationTree_refresh', 'Làm mới'], ['app_navigationTree_refresh_error', 'Không thể làm mới nút'], ['app_navigationTree_node_change_name_error', 'Đã xảy ra lỗi khi thay đổi tên'], diff --git a/webapp/packages/plugin-navigation-tree/src/locales/zh.ts b/webapp/packages/plugin-navigation-tree/src/locales/zh.ts index 7f4769949e3..9c2ddf11ab5 100644 --- a/webapp/packages/plugin-navigation-tree/src/locales/zh.ts +++ b/webapp/packages/plugin-navigation-tree/src/locales/zh.ts @@ -19,12 +19,7 @@ export default [ ['app_navigationTree_node_empty', '空'], ['app_navigationTree_node_no_results', "抱歉,关键词 '{arg:filter}' 无匹配结果"], ['app_navigationTree_openNodeTab', '打开'], - ['app_navigationTree_connection_view', '连接视图'], ['app_navigationTree_node_not_found', '未找到节点'], - ['app_navigationTree_connection_view_option_simple', '简单'], - ['app_navigationTree_connection_view_option_advanced', '完善'], - ['app_navigationTree_connection_view_option_custom', '自定义'], - ['app_navigationTree_connection_view_option_showSystemObjects', '展示系统对象'], ['app_navigationTree_refresh', '刷新'], ['app_navigationTree_refresh_error', '刷新节点失败'], ['app_navigationTree_node_change_name_error', '更改名称时发生错误'], diff --git a/webapp/packages/plugin-set-common/package.json b/webapp/packages/plugin-set-common/package.json index 16aad78215e..55960b942f2 100644 --- a/webapp/packages/plugin-set-common/package.json +++ b/webapp/packages/plugin-set-common/package.json @@ -66,6 +66,7 @@ "@cloudbeaver/plugin-codemirror6": "workspace:*", "@cloudbeaver/plugin-connection-custom": "workspace:*", "@cloudbeaver/plugin-connection-search": "workspace:*", + "@cloudbeaver/plugin-connection-view": "workspace:*", "@cloudbeaver/plugin-connections": "workspace:*", "@cloudbeaver/plugin-connections-administration": "workspace:*", "@cloudbeaver/plugin-data-export": "workspace:*", diff --git a/webapp/packages/plugin-set-common/src/index.ts b/webapp/packages/plugin-set-common/src/index.ts index 01f89dca695..419481cbf7d 100644 --- a/webapp/packages/plugin-set-common/src/index.ts +++ b/webapp/packages/plugin-set-common/src/index.ts @@ -109,6 +109,7 @@ import pluginCodemirror6 from '@cloudbeaver/plugin-codemirror6/module'; import pluginAsyncTaskConfirmation from '@cloudbeaver/plugin-async-task-confirmation/module'; import pluginSqlAsyncTaskConfirmation from '@cloudbeaver/plugin-sql-async-task-confirmation/module'; import pluginDataViewerConditionalFormatting from '@cloudbeaver/plugin-data-viewer-conditional-formatting/module'; +import pluginConnectionView from '@cloudbeaver/plugin-connection-view/module'; const core = [ coreRouting, // important, should be first because the router starts in load phase first after all plugins register phase @@ -217,4 +218,5 @@ export const commonSet = [ pluginAsyncTaskConfirmation, pluginSqlAsyncTaskConfirmation, pluginDataViewerConditionalFormatting, + pluginConnectionView, ]; diff --git a/webapp/packages/plugin-set-common/tsconfig.json b/webapp/packages/plugin-set-common/tsconfig.json index 8118b202a42..4190a27b9c3 100644 --- a/webapp/packages/plugin-set-common/tsconfig.json +++ b/webapp/packages/plugin-set-common/tsconfig.json @@ -142,6 +142,9 @@ { "path": "../plugin-connection-search" }, + { + "path": "../plugin-connection-view" + }, { "path": "../plugin-connections" }, diff --git a/webapp/yarn.lock b/webapp/yarn.lock index fce94fc738b..2f96b2be17d 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -2679,6 +2679,40 @@ __metadata: languageName: unknown linkType: soft +"@cloudbeaver/plugin-connection-view@workspace:*, @cloudbeaver/plugin-connection-view@workspace:packages/plugin-connection-view": + version: 0.0.0-use.local + resolution: "@cloudbeaver/plugin-connection-view@workspace:packages/plugin-connection-view" + dependencies: + "@cloudbeaver/core-blocks": "workspace:*" + "@cloudbeaver/core-cli": "workspace:*" + "@cloudbeaver/core-connections": "workspace:*" + "@cloudbeaver/core-data-context": "workspace:*" + "@cloudbeaver/core-di": "workspace:*" + "@cloudbeaver/core-events": "workspace:*" + "@cloudbeaver/core-localization": "workspace:*" + "@cloudbeaver/core-navigation-tree": "workspace:*" + "@cloudbeaver/core-projects": "workspace:*" + "@cloudbeaver/core-resource": "workspace:*" + "@cloudbeaver/core-root": "workspace:*" + "@cloudbeaver/core-sdk": "workspace:*" + "@cloudbeaver/core-ui": "workspace:*" + "@cloudbeaver/core-utils": "workspace:*" + "@cloudbeaver/core-view": "workspace:*" + "@cloudbeaver/plugin-connections": "workspace:*" + "@cloudbeaver/tsconfig": "workspace:*" + "@dbeaver/js-helpers": "workspace:*" + "@types/react": "npm:^19" + mobx: "npm:^6" + mobx-react-lite: "npm:^4" + react: "npm:^19" + react-dom: "npm:^19" + rimraf: "npm:^6" + tslib: "npm:^2" + typescript: "npm:^5" + typescript-plugin-css-modules: "npm:^5" + languageName: unknown + linkType: soft + "@cloudbeaver/plugin-connections-administration@workspace:*, @cloudbeaver/plugin-connections-administration@workspace:packages/plugin-connections-administration": version: 0.0.0-use.local resolution: "@cloudbeaver/plugin-connections-administration@workspace:packages/plugin-connections-administration" @@ -3835,6 +3869,7 @@ __metadata: "@cloudbeaver/plugin-codemirror6": "workspace:*" "@cloudbeaver/plugin-connection-custom": "workspace:*" "@cloudbeaver/plugin-connection-search": "workspace:*" + "@cloudbeaver/plugin-connection-view": "workspace:*" "@cloudbeaver/plugin-connections": "workspace:*" "@cloudbeaver/plugin-connections-administration": "workspace:*" "@cloudbeaver/plugin-data-export": "workspace:*"