mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
feat(core-connections): CB-179 add navigator view switch
This commit is contained in:
@@ -6,26 +6,34 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { ConnectionViewService, CONNECTION_NAVIGATOR_VIEW_SETTINGS } from '@cloudbeaver/core-connections';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { ContextMenuService, IMenuPanel } from '@cloudbeaver/core-dialogs';
|
||||
|
||||
import type { NavNode } from '../shared/NodesManager/EntityTypes';
|
||||
import { EObjectFeature } from '../shared/NodesManager/EObjectFeature';
|
||||
import { NavNodeManagerService } from '../shared/NodesManager/NavNodeManagerService';
|
||||
|
||||
@injectable()
|
||||
export class NavigationTreeContextMenuService {
|
||||
static nodeContextType = 'NodeWithParent';
|
||||
private static nodeViewMenuItemToken = 'nodeView';
|
||||
private static menuToken = 'navTreeMenu';
|
||||
|
||||
constructor(
|
||||
private contextMenuService: ContextMenuService,
|
||||
private navNodeManagerService: NavNodeManagerService
|
||||
private navNodeManagerService: NavNodeManagerService,
|
||||
private connectionViewService: ConnectionViewService
|
||||
) { }
|
||||
|
||||
getMenuToken() {
|
||||
return NavigationTreeContextMenuService.menuToken;
|
||||
}
|
||||
|
||||
getNodeViewMenuItemToken() {
|
||||
return NavigationTreeContextMenuService.nodeViewMenuItemToken;
|
||||
}
|
||||
|
||||
constructMenuWithContext(node: NavNode): IMenuPanel {
|
||||
return this.contextMenuService.createContextMenu<NavNode>({
|
||||
menuId: this.getMenuToken(),
|
||||
@@ -35,6 +43,52 @@ export class NavigationTreeContextMenuService {
|
||||
});
|
||||
}
|
||||
|
||||
registerNodeViewMenuItem() {
|
||||
this.contextMenuService.addMenuItem<NavNode>(
|
||||
this.contextMenuService.getRootMenuToken(),
|
||||
{
|
||||
id: this.getNodeViewMenuItemToken(),
|
||||
isPresent(context) {
|
||||
return context.contextType === NavigationTreeContextMenuService.nodeContextType
|
||||
&& context.data.objectFeatures.includes(EObjectFeature.dataSource);
|
||||
},
|
||||
order: 2,
|
||||
title: 'app_navigationTree_connection_view',
|
||||
isPanel: true,
|
||||
}
|
||||
);
|
||||
this.contextMenuService.addMenuItem<NavNode>(
|
||||
this.getNodeViewMenuItemToken(),
|
||||
{
|
||||
id: 'simple',
|
||||
isPresent(context) {
|
||||
return context.contextType === NavigationTreeContextMenuService.nodeContextType
|
||||
&& context.data.objectFeatures.includes(EObjectFeature.dataSource);
|
||||
},
|
||||
onClick: context => {
|
||||
const node = context.data;
|
||||
this.connectionViewService.changeConnectionView(node.id, CONNECTION_NAVIGATOR_VIEW_SETTINGS.simple);
|
||||
},
|
||||
title: 'app_navigationTree_connection_view_simple_option',
|
||||
}
|
||||
);
|
||||
this.contextMenuService.addMenuItem<NavNode>(
|
||||
this.getNodeViewMenuItemToken(),
|
||||
{
|
||||
id: 'advanced',
|
||||
isPresent(context) {
|
||||
return context.contextType === NavigationTreeContextMenuService.nodeContextType
|
||||
&& context.data.objectFeatures.includes(EObjectFeature.dataSource);
|
||||
},
|
||||
title: 'app_navigationTree_connection_view_advanced_option',
|
||||
onClick: context => {
|
||||
const node = context.data;
|
||||
this.connectionViewService.changeConnectionView(node.id, CONNECTION_NAVIGATOR_VIEW_SETTINGS.advanced);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
registerMenuItems() {
|
||||
this.contextMenuService.addMenuItem<NavNode>(
|
||||
this.contextMenuService.getRootMenuToken(),
|
||||
@@ -67,5 +121,7 @@ export class NavigationTreeContextMenuService {
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
this.registerNodeViewMenuItem();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ export * from './shared/NavigationTabs/TabNavigationContext';
|
||||
export * from './shared/ToolsPanel/LogViewTab/LogViewerMenuService';
|
||||
export * from './shared/ToolsPanel/LogViewTab/LogViewerService';
|
||||
export * from './shared/SessionExpireDialog/SessionExpiredDialogService';
|
||||
export * from './shared/NodesManager/NavNodeManagerService';
|
||||
export * from './NavigationTree/ElementsTree';
|
||||
export * from './NavigationTree/TreeContext';
|
||||
export * from './NavigationTree/NavigationTreeService';
|
||||
|
||||
@@ -10,6 +10,9 @@ export default [
|
||||
['app_shared_settingsMenu_lang', 'Language'],
|
||||
['app_topnavbar_connection_schema_manager_not_selected', '-- not selected --'],
|
||||
['app_navigationTree_openNodeTab', 'Open'],
|
||||
['app_navigationTree_connection_view', 'Connection view'],
|
||||
['app_navigationTree_connection_view_simple_option', 'Simple'],
|
||||
['app_navigationTree_connection_view_advanced_option', 'Advanced'],
|
||||
['app_navigationTree_refreshNode', 'Refresh'],
|
||||
['app_navigationTree_context_disconnect', 'Disconnect'],
|
||||
['app_shared_inlineEditor_dialog_title', 'Edit mode'],
|
||||
|
||||
@@ -13,6 +13,9 @@ export default [
|
||||
'Нет открытых объектов для отображения. Дважды нажмите на элемент в дереве навигации, чтобы открыть его.',
|
||||
],
|
||||
['app_navigationTree_openNodeTab', 'Открыть'],
|
||||
['app_navigationTree_connection_view', 'Отображение'],
|
||||
['app_navigationTree_connection_view_simple_option', 'Упрощенное'],
|
||||
['app_navigationTree_connection_view_advanced_option', 'Продвинутое'],
|
||||
['app_navigationTree_refreshNode', 'Обновить'],
|
||||
['app_navigationTree_context_disconnect', 'Отключить'],
|
||||
['app_shared_inlineEditor_dialog_title', 'Редактирование'],
|
||||
|
||||
@@ -55,6 +55,7 @@ import {
|
||||
DBDriverResource,
|
||||
DatabaseAuthModelsResource,
|
||||
ConnectionAuthService,
|
||||
ConnectionViewService,
|
||||
ConnectionsAdministrationService,
|
||||
ConnectionsResource,
|
||||
ConnectionsLocaleService,
|
||||
@@ -156,6 +157,7 @@ export const coreManifest: PluginManifest = {
|
||||
NavigationTabsService,
|
||||
DatabaseAuthModelsResource,
|
||||
ConnectionAuthService,
|
||||
ConnectionViewService,
|
||||
ConnectionsAdministrationNavService,
|
||||
ConnectionManualService,
|
||||
ConnectionSearchService,
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 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 { NavigatorSettingsInput } from '@cloudbeaver/core-sdk';
|
||||
|
||||
type NavigatorView = 'simple' | 'advanced';
|
||||
|
||||
export const CONNECTION_NAVIGATOR_VIEW_SETTINGS: Record<NavigatorView, NavigatorSettingsInput> = {
|
||||
simple: {
|
||||
showOnlyEntities: true,
|
||||
hideFolders: true,
|
||||
hideVirtualModel: true,
|
||||
hideSchemas: false,
|
||||
mergeEntities: false,
|
||||
showSystemObjects: false,
|
||||
showUtilityObjects: false,
|
||||
},
|
||||
advanced: {
|
||||
showOnlyEntities: false,
|
||||
hideFolders: false,
|
||||
hideVirtualModel: false,
|
||||
hideSchemas: false,
|
||||
mergeEntities: false,
|
||||
showSystemObjects: false,
|
||||
showUtilityObjects: false,
|
||||
},
|
||||
};
|
||||
|
||||
export function isSimpleNavigatorView(settings: NavigatorSettingsInput): boolean {
|
||||
return settings.hideVirtualModel && settings.showOnlyEntities && settings.hideFolders;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 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 { NavNodeManagerService, NodeManagerUtils } from '@cloudbeaver/core-app';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { GraphQLService, NavigatorSettingsInput } from '@cloudbeaver/core-sdk';
|
||||
|
||||
@injectable()
|
||||
export class ConnectionViewService {
|
||||
constructor(
|
||||
private graphQLService: GraphQLService,
|
||||
private navNodeManagerService: NavNodeManagerService,
|
||||
private notificationService: NotificationService
|
||||
) { }
|
||||
|
||||
async changeConnectionView(nodeId: string, settings: NavigatorSettingsInput): Promise<void> {
|
||||
const connectionId = NodeManagerUtils.connectionNodeIdToConnectionId(nodeId);
|
||||
|
||||
try {
|
||||
await this.graphQLService.sdk.setConnectionNavigatorSettings({
|
||||
id: connectionId,
|
||||
settings,
|
||||
});
|
||||
|
||||
await this.navNodeManagerService.refreshTree(nodeId);
|
||||
} catch (exception) {
|
||||
this.notificationService.logException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ export * from './extensions/IConnectionSetter';
|
||||
export * from './ConnectionsManagerService';
|
||||
export * from './ConnectionInfoResource';
|
||||
export * from './ConnectionAuthService';
|
||||
export * from './ConnectionViewService';
|
||||
export * from './DriverPropertiesService';
|
||||
export * from './EConnectionFeature';
|
||||
export * from './ContainerResource';
|
||||
@@ -23,3 +24,4 @@ export * from './DBDriverResource';
|
||||
export * from './useConnectionInfo';
|
||||
export * from './useDBDriver';
|
||||
export * from './getUniqueConnectionName';
|
||||
export * from './ConnectionNavigatorViewSettings';
|
||||
|
||||
@@ -71,7 +71,7 @@ const MenuPanel = observer(function MenuPanel({
|
||||
}
|
||||
|
||||
return styled(styles)(
|
||||
<Menu {...menu} aria-label={panel.id}>
|
||||
<Menu {...menu} aria-label={panel.id} modal>
|
||||
{panel.menuItems.map(item => (
|
||||
<MenuPanelElement key={item.id} item={item} menu={menu} style={style} />
|
||||
))}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
mutation setConnectionNavigatorSettings($id: ID!, $settings: NavigatorSettingsInput!) {
|
||||
setConnectionNavigatorSettings(id: $id, settings: $settings)
|
||||
}
|
||||
@@ -1134,6 +1134,13 @@ export type RefreshSessionConnectionsMutationVariables = Exact<{ [key: string]:
|
||||
|
||||
export type RefreshSessionConnectionsMutation = Pick<Mutation, 'refreshSessionConnections'>;
|
||||
|
||||
export type SetConnectionNavigatorSettingsMutationVariables = Exact<{
|
||||
id: Scalars['ID'];
|
||||
settings: NavigatorSettingsInput;
|
||||
}>;
|
||||
|
||||
export type SetConnectionNavigatorSettingsMutation = Pick<Mutation, 'setConnectionNavigatorSettings'>;
|
||||
|
||||
export type GetTemplateConnectionsQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export interface GetTemplateConnectionsQuery { connections: Array<Pick<ConnectionInfo, 'id' | 'name' | 'description' | 'driverId' | 'connected' | 'readOnly' | 'authNeeded' | 'authModel' | 'features' | 'supportedDataFormats'>> }
|
||||
@@ -1937,6 +1944,11 @@ export const RefreshSessionConnectionsDocument = `
|
||||
refreshSessionConnections
|
||||
}
|
||||
`;
|
||||
export const SetConnectionNavigatorSettingsDocument = `
|
||||
mutation setConnectionNavigatorSettings($id: ID!, $settings: NavigatorSettingsInput!) {
|
||||
setConnectionNavigatorSettings(id: $id, settings: $settings)
|
||||
}
|
||||
`;
|
||||
export const GetTemplateConnectionsDocument = `
|
||||
query getTemplateConnections {
|
||||
connections: templateConnections {
|
||||
@@ -2517,6 +2529,9 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
|
||||
refreshSessionConnections(variables?: RefreshSessionConnectionsMutationVariables): Promise<RefreshSessionConnectionsMutation> {
|
||||
return withWrapper(() => client.request<RefreshSessionConnectionsMutation>(RefreshSessionConnectionsDocument, variables));
|
||||
},
|
||||
setConnectionNavigatorSettings(variables: SetConnectionNavigatorSettingsMutationVariables): Promise<SetConnectionNavigatorSettingsMutation> {
|
||||
return withWrapper(() => client.request<SetConnectionNavigatorSettingsMutation>(SetConnectionNavigatorSettingsDocument, variables));
|
||||
},
|
||||
getTemplateConnections(variables?: GetTemplateConnectionsQueryVariables): Promise<GetTemplateConnectionsQuery> {
|
||||
return withWrapper(() => client.request<GetTemplateConnectionsQuery>(GetTemplateConnectionsDocument, variables));
|
||||
},
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 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 React, { useCallback } from 'react';
|
||||
|
||||
import { FormGroup, Switch } from '@cloudbeaver/core-blocks';
|
||||
import { isSimpleNavigatorView, CONNECTION_NAVIGATOR_VIEW_SETTINGS } from '@cloudbeaver/core-connections';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
|
||||
import type { IServerConfigurationPageState } from '../IServerConfigurationPageState';
|
||||
|
||||
interface Props {
|
||||
configs: IServerConfigurationPageState;
|
||||
}
|
||||
|
||||
export const ServerConfigurationNavigatorViewForm: React.FC<Props> = observer(function ServerConfigurationNavigatorViewForm({
|
||||
configs,
|
||||
}) {
|
||||
const translate = useTranslate();
|
||||
|
||||
const isSimpleView = isSimpleNavigatorView(configs.navigatorConfig);
|
||||
|
||||
const onNavigatorViewChangeHandler = useCallback((value: boolean) => {
|
||||
if (value) {
|
||||
configs.navigatorConfig = { ...CONNECTION_NAVIGATOR_VIEW_SETTINGS.simple };
|
||||
} else {
|
||||
configs.navigatorConfig = { ...CONNECTION_NAVIGATOR_VIEW_SETTINGS.advanced };
|
||||
}
|
||||
}, [configs]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormGroup>
|
||||
<Switch
|
||||
name='simpleNavigatorViewEnabled'
|
||||
description={translate('administration_configuration_wizard_configuration_navigation_tree_view_description')}
|
||||
mod={['primary']}
|
||||
checked={isSimpleView}
|
||||
long
|
||||
onChange={onNavigatorViewChangeHandler}
|
||||
>
|
||||
{translate('administration_configuration_wizard_configuration_navigation_tree_view')}
|
||||
</Switch>
|
||||
</FormGroup>
|
||||
</>
|
||||
);
|
||||
});
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { NavigatorSettingsInput, ServerConfigInput } from '@cloudbeaver/core-sdk';
|
||||
import type { NavigatorSettingsInput, ServerConfigInput } from '@cloudbeaver/core-sdk';
|
||||
|
||||
export interface IServerConfigurationPageState {
|
||||
serverConfig: ServerConfigInput;
|
||||
|
||||
+2
@@ -19,6 +19,7 @@ import { useStyles, composes } from '@cloudbeaver/core-theming';
|
||||
import { ServerConfigurationAdminForm } from './Form/ServerConfigurationAdminForm';
|
||||
import { ServerConfigurationConfigurationForm } from './Form/ServerConfigurationConfigurationForm';
|
||||
import { ServerConfigurationInfoForm } from './Form/ServerConfigurationInfoForm';
|
||||
import { ServerConfigurationNavigatorViewForm } from './Form/ServerConfigurationNavigatorViewForm';
|
||||
import { ServerConfigurationPageController } from './ServerConfigurationPageController';
|
||||
import { ServerConfigurationService } from './ServerConfigurationService';
|
||||
|
||||
@@ -111,6 +112,7 @@ export const ServerConfigurationPage = observer(function ServerConfigurationPage
|
||||
</FormBoxElement>
|
||||
<FormBoxElement>
|
||||
<ServerConfigurationConfigurationForm serverConfig={controller.state.serverConfig} />
|
||||
<ServerConfigurationNavigatorViewForm configs={controller.state} />
|
||||
</FormBoxElement>
|
||||
</FormBox>
|
||||
</>
|
||||
|
||||
+6
-20
@@ -10,6 +10,7 @@ import { observable, makeObservable } from 'mobx';
|
||||
|
||||
import { AdministrationScreenService } from '@cloudbeaver/core-administration';
|
||||
import { UsersResource } from '@cloudbeaver/core-authentication';
|
||||
import { CONNECTION_NAVIGATOR_VIEW_SETTINGS } from '@cloudbeaver/core-connections';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { IExecutor, Executor } from '@cloudbeaver/core-executor';
|
||||
@@ -130,8 +131,8 @@ export class ServerConfigurationService {
|
||||
}
|
||||
if (this.administrationScreenService.isConfigurationMode) {
|
||||
if (!this.state.serverConfig.adminName
|
||||
|| this.state.serverConfig.adminName.length < 6
|
||||
|| !this.state.serverConfig.adminPassword
|
||||
|| this.state.serverConfig.adminName.length < 6
|
||||
|| !this.state.serverConfig.adminPassword
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@@ -151,15 +152,8 @@ export class ServerConfigurationService {
|
||||
customConnectionsEnabled: true,
|
||||
sessionExpireTime: 30,
|
||||
},
|
||||
navigatorConfig: {
|
||||
hideFolders: false,
|
||||
hideSchemas: false,
|
||||
hideVirtualModel: false,
|
||||
mergeEntities: false,
|
||||
showOnlyEntities: false,
|
||||
showSystemObjects: false,
|
||||
showUtilityObjects: false,
|
||||
},
|
||||
navigatorConfig: CONNECTION_NAVIGATOR_VIEW_SETTINGS.advanced,
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -171,15 +165,7 @@ export class ServerConfigurationService {
|
||||
customConnectionsEnabled: config.supportsCustomConnections,
|
||||
sessionExpireTime: (config.sessionExpireTime ?? 1800000) / 1000 / 60,
|
||||
},
|
||||
navigatorConfig: {
|
||||
hideFolders: false,
|
||||
hideSchemas: false,
|
||||
hideVirtualModel: false,
|
||||
mergeEntities: false,
|
||||
showOnlyEntities: false,
|
||||
showSystemObjects: false,
|
||||
showUtilityObjects: false,
|
||||
},
|
||||
navigatorConfig: config.defaultNavigatorSettings,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,3 +5,4 @@ export default manifest;
|
||||
export * from './ConfigurationWizard/ServerConfiguration/Form/ServerConfigurationAdminForm';
|
||||
export * from './ConfigurationWizard/ServerConfiguration/Form/ServerConfigurationConfigurationForm';
|
||||
export * from './ConfigurationWizard/ServerConfiguration/Form/ServerConfigurationInfoForm';
|
||||
export * from './ConfigurationWizard/ServerConfiguration/Form/ServerConfigurationNavigatorViewForm';
|
||||
|
||||
@@ -22,6 +22,8 @@ export default [
|
||||
['administration_configuration_wizard_configuration_authentication', 'Enable users authentication'],
|
||||
['administration_configuration_wizard_configuration_authentication_description', 'Allows users to authenticate. Otherwise only anonymous access is enabled'],
|
||||
['administration_configuration_wizard_configuration_custom_connections', 'Enable custom connections'],
|
||||
['administration_configuration_wizard_configuration_navigation_tree_view', 'Enable navigation tree simple view'],
|
||||
['administration_configuration_wizard_configuration_navigation_tree_view_description', "By default, all user's new connections will contain only basic information in navigation tree"],
|
||||
['administration_configuration_wizard_configuration_custom_connections_description', 'Allows users to create custom connections. Otherwise, all new connections can be created from the administration part only'],
|
||||
['administration_configuration_wizard_configuration_navigator', 'Navigator'],
|
||||
['administration_configuration_wizard_configuration_navigator_hide_folders', 'Hide Folders'],
|
||||
|
||||
@@ -2,6 +2,8 @@ export default [
|
||||
['administration_configuration_wizard_configuration', 'Настройки сервера'],
|
||||
['administration_configuration_wizard_configuration_server_session_lifetime', 'Время сессии'],
|
||||
['administration_configuration_wizard_configuration_custom_connections', 'Разрешить пользовательские подключения'],
|
||||
['administration_configuration_wizard_configuration_navigation_tree_view', 'Отображать упрощенную версию дерева навигации'],
|
||||
['administration_configuration_wizard_configuration_navigation_tree_view_description', 'Все новые подключения, созданные пользователем, будут иметь только базовую информацию в дереве навигации'],
|
||||
['administration_configuration_wizard_configuration_custom_connections_description', 'Позволяет пользователям создавать собственные подключения. Иначе, любые подключения могут быть добавлены только со страницы администрирования'],
|
||||
['administration_server_configuration_save_confirmation_title', 'Изменение настроек сервера'],
|
||||
['administration_server_configuration_save_confirmation_message', 'Вы собираетесь изменить критичные настройки, приложение будет перезагружено.'],
|
||||
|
||||
Reference in New Issue
Block a user