feat(core-connections): CB-179 add navigator view switch

This commit is contained in:
Naumov Alexey
2021-02-02 19:40:16 +03:00
parent 5967cda02b
commit 22385e95bb
18 changed files with 226 additions and 23 deletions
@@ -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();
}
}
+1
View File
@@ -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)
}
+15
View File
@@ -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));
},
@@ -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>
</>
);
});
@@ -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;
@@ -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>
</>
@@ -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', 'Вы собираетесь изменить критичные настройки, приложение будет перезагружено.'],