Update server tree action contributions (#15525)

* Update server tree action contributions

* Fix test
This commit is contained in:
Charles Gagnon
2021-05-20 12:41:56 -07:00
committed by GitHub
parent c61c53976a
commit 2ec720d5b9
19 changed files with 176 additions and 213 deletions

View File

@@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/**
* Set of IDs used to identify SQL contributed icons, which override the default
* codicon behavior vs/base/common/codicons.ts
*/
export const enum SqlIconId {
book = 'book',
dataExplorer = 'dataExplorer',
addServerGroupAction = 'add-server-group-action',
addServerAction = 'add-server-action',
activeConnectionsAction = 'active-connections-action',
serverPage = 'server-page'
}

View File

@@ -5,11 +5,10 @@
import { IConfigurationRegistry, Extensions as ConfigExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { IConfigurationRegistry, Extensions as ConfigExtensions } from 'vs/platform/configuration/common/configurationRegistry';
import { Registry } from 'vs/platform/registry/common/platform'; import { Registry } from 'vs/platform/registry/common/platform';
import { AddServerGroupAction, AddServerAction } from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction';
import { ClearRecentConnectionsAction, GetCurrentConnectionStringAction } from 'sql/workbench/services/connection/browser/connectionActions'; import { ClearRecentConnectionsAction, GetCurrentConnectionStringAction } from 'sql/workbench/services/connection/browser/connectionActions';
import * as azdata from 'azdata'; import * as azdata from 'azdata';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { MenuId, MenuRegistry, SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { ConnectionStatusbarItem } from 'sql/workbench/contrib/connection/browser/connectionStatus'; import { ConnectionStatusbarItem } from 'sql/workbench/contrib/connection/browser/connectionStatus';
import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { CommandsRegistry } from 'vs/platform/commands/common/commands';
@@ -20,12 +19,18 @@ import { integrated, azureMFA } from 'sql/platform/connection/common/constants';
import { AuthenticationType } from 'sql/workbench/services/connection/browser/connectionWidget'; import { AuthenticationType } from 'sql/workbench/services/connection/browser/connectionWidget';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { ConnectionViewletPanel } from 'sql/workbench/contrib/dataExplorer/browser/connectionViewletPanel';
import { ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey';
import { ActiveConnectionsFilterAction, AddServerAction, AddServerGroupAction } from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction';
import { CONTEXT_SERVER_TREE_VIEW, CONTEXT_SERVER_TREE_HAS_CONNECTIONS } from 'sql/workbench/contrib/objectExplorer/browser/serverTreeView';
import { SqlIconId } from 'sql/base/common/codicons';
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench); const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
workbenchRegistry.registerWorkbenchContribution(ConnectionStatusbarItem, LifecyclePhase.Restored); workbenchRegistry.registerWorkbenchContribution(ConnectionStatusbarItem, LifecyclePhase.Restored);
import 'sql/workbench/contrib/connection/common/connectionTreeProviderExentionPoint'; import 'sql/workbench/contrib/connection/common/connectionTreeProviderExentionPoint';
import { ServerTreeViewView } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService';
// Connection Dashboard registration // Connection Dashboard registration
@@ -50,6 +55,15 @@ actionRegistry.registerWorkbenchAction(
AddServerGroupAction.LABEL AddServerGroupAction.LABEL
); );
actionRegistry.registerWorkbenchAction(
SyncActionDescriptor.create(
ActiveConnectionsFilterAction,
ActiveConnectionsFilterAction.ID,
ActiveConnectionsFilterAction.SHOW_ACTIVE_CONNECTIONS_LABEL
),
ActiveConnectionsFilterAction.SHOW_ACTIVE_CONNECTIONS_LABEL
);
actionRegistry.registerWorkbenchAction( actionRegistry.registerWorkbenchAction(
SyncActionDescriptor.create( SyncActionDescriptor.create(
AddServerAction, AddServerAction,
@@ -59,6 +73,45 @@ actionRegistry.registerWorkbenchAction(
AddServerAction.LABEL AddServerAction.LABEL
); );
MenuRegistry.appendMenuItem(MenuId.ViewTitle, {
group: 'navigation',
order: 10,
command: {
id: AddServerAction.ID,
title: AddServerAction.LABEL,
icon: { id: SqlIconId.addServerAction }
},
when: ContextKeyEqualsExpr.create('view', ConnectionViewletPanel.ID),
});
MenuRegistry.appendMenuItem(MenuId.ViewTitle, {
group: 'navigation',
order: 20,
command: {
id: AddServerGroupAction.ID,
title: AddServerGroupAction.LABEL,
icon: { id: SqlIconId.addServerGroupAction }
},
when: ContextKeyEqualsExpr.create('view', ConnectionViewletPanel.ID),
});
MenuRegistry.appendMenuItem(MenuId.ViewTitle, {
group: 'navigation',
order: 30,
command: {
id: ActiveConnectionsFilterAction.ID,
title: ActiveConnectionsFilterAction.SHOW_ACTIVE_CONNECTIONS_LABEL,
icon: { id: SqlIconId.activeConnectionsAction },
precondition: CONTEXT_SERVER_TREE_HAS_CONNECTIONS,
toggled: {
condition: CONTEXT_SERVER_TREE_VIEW.isEqualTo(ServerTreeViewView.active),
icon: { id: SqlIconId.serverPage },
tooltip: ActiveConnectionsFilterAction.SHOW_ALL_CONNECTIONS_LABEL
}
},
when: ContextKeyEqualsExpr.create('view', ConnectionViewletPanel.ID),
});
CommandsRegistry.registerCommand('azdata.connect', CommandsRegistry.registerCommand('azdata.connect',
function (accessor, args: { function (accessor, args: {
serverName: string, serverName: string,

View File

@@ -10,12 +10,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IAction } from 'vs/base/common/actions';
import { ServerTreeView } from 'sql/workbench/contrib/objectExplorer/browser/serverTreeView'; import { ServerTreeView } from 'sql/workbench/contrib/objectExplorer/browser/serverTreeView';
import {
ActiveConnectionsFilterAction,
AddServerAction, AddServerGroupAction
} from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction';
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService'; import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPane'; import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPane';
@@ -33,9 +28,6 @@ export class ConnectionViewletPanel extends ViewPane {
private _root?: HTMLElement; private _root?: HTMLElement;
private _serverTreeView: ServerTreeView; private _serverTreeView: ServerTreeView;
private _addServerAction: IAction;
private _addServerGroupAction: IAction;
private _activeConnectionsFilterAction: ActiveConnectionsFilterAction;
constructor( constructor(
private options: IViewletViewOptions, private options: IViewletViewOptions,
@@ -52,18 +44,11 @@ export class ConnectionViewletPanel extends ViewPane {
@ITelemetryService telemetryService: ITelemetryService, @ITelemetryService telemetryService: ITelemetryService,
) { ) {
super({ ...(options as IViewPaneOptions) }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, opener, themeService, telemetryService); super({ ...(options as IViewPaneOptions) }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, opener, themeService, telemetryService);
this._addServerAction = this.instantiationService.createInstance(AddServerAction, this._serverTreeView = this.objectExplorerService.getServerTreeView() as ServerTreeView;
AddServerAction.ID,
AddServerAction.LABEL);
this._addServerGroupAction = this.instantiationService.createInstance(AddServerGroupAction,
AddServerGroupAction.ID,
AddServerGroupAction.LABEL);
this._serverTreeView = <any>this.objectExplorerService.getServerTreeView() as ServerTreeView;
if (!this._serverTreeView) { if (!this._serverTreeView) {
this._serverTreeView = this.instantiationService.createInstance(ServerTreeView); this._serverTreeView = this.instantiationService.createInstance(ServerTreeView);
this.objectExplorerService.registerServerTreeView(this._serverTreeView); this.objectExplorerService.registerServerTreeView(this._serverTreeView);
} }
this._activeConnectionsFilterAction = this._serverTreeView.activeConnectionsFilterAction;
} }
protected renderHeader(container: HTMLElement): void { protected renderHeader(container: HTMLElement): void {
@@ -114,14 +99,6 @@ export class ConnectionViewletPanel extends ViewPane {
return 0; return 0;
} }
public getActions(): IAction[] {
return [
this._addServerAction,
this._addServerGroupAction,
this._activeConnectionsFilterAction
];
}
public clearSearch() { public clearSearch() {
this._serverTreeView.refreshTree(); this._serverTreeView.refreshTree();
} }

View File

@@ -27,6 +27,7 @@ import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneCont
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { Viewlet } from 'vs/workbench/browser/viewlet'; import { Viewlet } from 'vs/workbench/browser/viewlet';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { SqlIconId } from 'sql/base/common/codicons';
export const VIEWLET_ID = 'workbench.view.connections'; export const VIEWLET_ID = 'workbench.view.connections';
@@ -132,8 +133,6 @@ export class DataExplorerViewPaneContainer extends ViewPaneContainer {
} }
} }
export const dataExplorerIconId = 'dataExplorer';
export const VIEW_CONTAINER = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({ export const VIEW_CONTAINER = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({
id: VIEWLET_ID, id: VIEWLET_ID,
title: localize('dataexplorer.name', "Connections"), title: localize('dataexplorer.name', "Connections"),
@@ -144,7 +143,7 @@ export const VIEW_CONTAINER = Registry.as<IViewContainersRegistry>(ViewContainer
keybindings: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_D }, keybindings: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_D },
order: 0 order: 0
}, },
icon: { id: 'dataExplorer' }, icon: { id: SqlIconId.dataExplorer },
order: 0, order: 0,
storageId: `${VIEWLET_ID}.state` storageId: `${VIEWLET_ID}.state`
}, ViewContainerLocation.Sidebar, { isDefault: true }); }, ViewContainerLocation.Sidebar, { isDefault: true });

View File

@@ -4,29 +4,38 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
/* Icons for various registered servers actions */ /* Icons for various registered servers actions */
.monaco-workbench .add-server-action { .monaco-workbench .dataExplorer-viewlet .actions-container .action-label.add-server-action {
background-image: url('add_server.svg'); background-image: url('add_server.svg') !important;
} }
.monaco-workbench.vs-dark .add-server-action, .monaco-workbench.vs-dark .dataExplorer-viewlet .actions-container .action-label.add-server-action,
.monaco-workbench.hc-black .add-server-action { .monaco-workbench.hc-black .dataExplorer-viewlet .actions-container .action-label.add-server-action {
background-image: url('add_server_inverse.svg'); background-image: url('add_server_inverse.svg') !important;
} }
.monaco-workbench .add-server-group-action { .monaco-workbench .dataExplorer-viewlet .actions-container .action-label.add-server-group-action {
background-image: url('new_servergroup.svg'); background-image: url('new_servergroup.svg') !important;
} }
.monaco-workbench.vs-dark .add-server-group-action, .monaco-workbench.vs-dark .dataExplorer-viewlet .actions-container .action-label.add-server-group-action,
.monaco-workbench.hc-black .add-server-group-action { .monaco-workbench.hc-black .dataExplorer-viewlet .actions-container .action-label.add-server-group-action {
background-image: url('new_servergroup_inverse.svg'); background-image: url('new_servergroup_inverse.svg') !important;
} }
.monaco-workbench .active-connections-action { .monaco-workbench .dataExplorer-viewlet .actions-container .action-label.active-connections-action {
background-image: url('connected_active_server.svg'); background-image: url('connected_active_server.svg') !important;
} }
.monaco-workbench.vs-dark .active-connections-action, .monaco-workbench.vs-dark .dataExplorer-viewlet .actions-container .action-label.active-connections-action,
.monaco-workbench.hc-black .active-connections-action{ .monaco-workbench.hc-black .dataExplorer-viewlet .actions-container .action-label.active-connections-action {
background-image: url('connected_active_server_inverse.svg'); background-image: url('connected_active_server_inverse.svg') !important;
}
.monaco-workbench .dataExplorer-viewlet .actions-container .action-label.server-page {
background-image: url('server_page.svg') !important;
}
.monaco-workbench.vs-dark .dataExplorer-viewlet .actions-container .action-label.server-page,
.monaco-workbench.hc-black .dataExplorer-viewlet .actions-container .action-label.server-page {
background-image: url('server_page_inverse.svg') !important;
} }

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#212121;}.cls-2{fill:#231f20;}</style></defs><title>server_16x16</title><path class="cls-1" d="M0,0V16H10.53V0ZM1,1H9.53v9H1ZM9.53,15H1V11H9.53Z"/><path class="cls-2" d="M4.39,4.23H1.94V1.77H4.39Zm-2-.5H3.89V2.27H2.44Z"/></svg>

After

Width:  |  Height:  |  Size: 345 B

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>server_inverse_16x16</title><path class="cls-1" d="M2.73,0V16H13.26V0Zm1,1h8.53v9H3.73ZM12.26,15H3.73V11h8.53Z"/><path class="cls-1" d="M7.21,4.23H4.75V1.77H7.21Zm-2-.5H6.71V2.27H5.25Z"/></svg>

After

Width:  |  Height:  |  Size: 339 B

View File

@@ -19,12 +19,11 @@ import { append, $, hide, show } from 'vs/base/browser/dom';
import { ConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup'; import { ConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup';
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import * as ConnectionUtils from 'sql/platform/connection/common/utils'; import * as ConnectionUtils from 'sql/platform/connection/common/utils';
import { ActiveConnectionsFilterAction } from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { TreeCreationUtils } from 'sql/workbench/services/objectExplorer/browser/treeCreationUtils'; import { TreeCreationUtils } from 'sql/workbench/services/objectExplorer/browser/treeCreationUtils';
import { TreeUpdateUtils } from 'sql/workbench/services/objectExplorer/browser/treeUpdateUtils'; import { TreeUpdateUtils } from 'sql/workbench/services/objectExplorer/browser/treeUpdateUtils';
import { TreeSelectionHandler } from 'sql/workbench/services/objectExplorer/browser/treeSelectionHandler'; import { TreeSelectionHandler } from 'sql/workbench/services/objectExplorer/browser/treeSelectionHandler';
import { IObjectExplorerService, IServerTreeView } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService'; import { IObjectExplorerService, IServerTreeView, ServerTreeViewView } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { Button } from 'sql/base/browser/ui/button/button'; import { Button } from 'sql/base/browser/ui/button/button';
import { TreeNode, TreeItemCollapsibleState } from 'sql/workbench/services/objectExplorer/common/treeNode'; import { TreeNode, TreeItemCollapsibleState } from 'sql/workbench/services/objectExplorer/common/treeNode';
@@ -42,6 +41,10 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { AsyncServerTree, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree'; import { AsyncServerTree, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree';
import { coalesce } from 'vs/base/common/arrays'; import { coalesce } from 'vs/base/common/arrays';
import { CONNECTIONS_SORT_BY_CONFIG_KEY } from 'sql/platform/connection/common/connectionConfig'; import { CONNECTIONS_SORT_BY_CONFIG_KEY } from 'sql/platform/connection/common/connectionConfig';
import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
export const CONTEXT_SERVER_TREE_VIEW = new RawContextKey<ServerTreeViewView>('serverTreeView.view', ServerTreeViewView.all);
export const CONTEXT_SERVER_TREE_HAS_CONNECTIONS = new RawContextKey<boolean>('serverTreeView.hasConnections', false);
/** /**
* ServerTreeview implements the dynamic tree view. * ServerTreeview implements the dynamic tree view.
@@ -51,10 +54,11 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
public messages?: HTMLElement; public messages?: HTMLElement;
private _buttonSection?: HTMLElement; private _buttonSection?: HTMLElement;
private _treeSelectionHandler: TreeSelectionHandler; private _treeSelectionHandler: TreeSelectionHandler;
private _activeConnectionsFilterAction: ActiveConnectionsFilterAction;
private _tree?: ITree | AsyncServerTree; private _tree?: ITree | AsyncServerTree;
private _onSelectionOrFocusChange: Emitter<void>; private _onSelectionOrFocusChange: Emitter<void>;
private _actionProvider: ServerTreeActionProvider; private _actionProvider: ServerTreeActionProvider;
private _viewKey: IContextKey<ServerTreeViewView>;
private _hasConnectionsKey: IContextKey<boolean>;
constructor( constructor(
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService, @IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
@@ -65,14 +69,12 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
@IConfigurationService private _configurationService: IConfigurationService, @IConfigurationService private _configurationService: IConfigurationService,
@ICapabilitiesService capabilitiesService: ICapabilitiesService, @ICapabilitiesService capabilitiesService: ICapabilitiesService,
@IContextMenuService private _contextMenuService: IContextMenuService, @IContextMenuService private _contextMenuService: IContextMenuService,
@IKeybindingService private _keybindingService: IKeybindingService @IKeybindingService private _keybindingService: IKeybindingService,
@IContextKeyService contextKeyService: IContextKeyService
) { ) {
super(); super();
this._activeConnectionsFilterAction = this._instantiationService.createInstance( this._hasConnectionsKey = CONTEXT_SERVER_TREE_HAS_CONNECTIONS.bindTo(contextKeyService);
ActiveConnectionsFilterAction, this._viewKey = CONTEXT_SERVER_TREE_VIEW.bindTo(contextKeyService);
ActiveConnectionsFilterAction.ID,
ActiveConnectionsFilterAction.LABEL,
this);
this._treeSelectionHandler = this._instantiationService.createInstance(TreeSelectionHandler); this._treeSelectionHandler = this._instantiationService.createInstance(TreeSelectionHandler);
this._onSelectionOrFocusChange = new Emitter(); this._onSelectionOrFocusChange = new Emitter();
this._actionProvider = this._instantiationService.createInstance(ServerTreeActionProvider); this._actionProvider = this._instantiationService.createInstance(ServerTreeActionProvider);
@@ -93,11 +95,8 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
this.registerCommands(); this.registerCommands();
} }
/** public get view(): ServerTreeViewView {
* Get active connections filter action return this._viewKey.get();
*/
public get activeConnectionsFilterAction(): ActiveConnectionsFilterAction {
return this._activeConnectionsFilterAction;
} }
/** /**
@@ -146,7 +145,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
hide(this.messages); hide(this.messages);
if (!this._connectionManagementService.hasRegisteredServers()) { if (!this._connectionManagementService.hasRegisteredServers()) {
this._activeConnectionsFilterAction.enabled = false;
this._buttonSection = append(container, $('.button-section')); this._buttonSection = append(container, $('.button-section'));
const connectButton = new Button(this._buttonSection); const connectButton = new Button(this._buttonSection);
connectButton.label = localize('serverTree.addConnection', "Add Connection"); connectButton.label = localize('serverTree.addConnection', "Add Connection");
@@ -248,7 +246,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
private async handleAddConnectionProfile(newProfile?: IConnectionProfile): Promise<void> { private async handleAddConnectionProfile(newProfile?: IConnectionProfile): Promise<void> {
if (this._buttonSection) { if (this._buttonSection) {
hide(this._buttonSection); hide(this._buttonSection);
this._activeConnectionsFilterAction.enabled = true;
} }
if (this._tree instanceof AsyncServerTree) { if (this._tree instanceof AsyncServerTree) {
@@ -369,7 +366,8 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
public async refreshTree(): Promise<void> { public async refreshTree(): Promise<void> {
hide(this.messages!); hide(this.messages!);
this.clearOtherActions(); this._viewKey.set(ServerTreeViewView.all);
this._hasConnectionsKey.set(this._connectionManagementService.hasRegisteredServers());
return TreeUpdateUtils.registeredServerUpdate(this._tree!, this._connectionManagementService); return TreeUpdateUtils.registeredServerUpdate(this._tree!, this._connectionManagementService);
} }
@@ -419,10 +417,9 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
/** /**
* Set tree elements based on the view (recent/active) * Set tree elements based on the view (recent/active)
*/ */
public showFilteredTree(view: string): void { public showFilteredTree(view: ServerTreeViewView): void {
hide(this.messages!); hide(this.messages!);
// Clear other action views if user switched between two views this._viewKey.set(view);
this.clearOtherActions(view);
const root = TreeUpdateUtils.getTreeInput(this._connectionManagementService); const root = TreeUpdateUtils.getTreeInput(this._connectionManagementService);
let treeInput: ConnectionProfileGroup | undefined = undefined; let treeInput: ConnectionProfileGroup | undefined = undefined;
if (root) { if (root) {
@@ -466,7 +463,7 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
} }
hide(this.messages!); hide(this.messages!);
// Clear other actions if user searched during other views // Clear other actions if user searched during other views
this.clearOtherActions(); this._viewKey.set(ServerTreeViewView.all);
// Filter connections based on search // Filter connections based on search
const filteredResults = this.searchConnections(searchString); const filteredResults = this.searchConnections(searchString);
if (!filteredResults || filteredResults.length === 0) { if (!filteredResults || filteredResults.length === 0) {
@@ -533,18 +530,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
return false; return false;
} }
/**
* Clears the toggle icons for active and recent
*/
private clearOtherActions(view?: string) {
if (!view) {
this._activeConnectionsFilterAction.isSet = false;
}
if (view === 'recent') {
this._activeConnectionsFilterAction.isSet = false;
}
}
private onSelected(event: any): void { private onSelected(event: any): void {
this._treeSelectionHandler.onTreeSelect(event, this._tree!, this._connectionManagementService, this._objectExplorerService, () => this._onSelectionOrFocusChange.fire()); this._treeSelectionHandler.onTreeSelect(event, this._tree!, this._connectionManagementService, this._objectExplorerService, () => this._onSelectionOrFocusChange.fire());
this._onSelectionOrFocusChange.fire(); this._onSelectionOrFocusChange.fire();

View File

@@ -8,8 +8,7 @@ import * as assert from 'assert';
import { ConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup'; import { ConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup';
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import { import {
RefreshAction, EditConnectionAction, AddServerAction, DeleteConnectionAction, DisconnectConnectionAction, RefreshAction, EditConnectionAction, DeleteConnectionAction, DisconnectConnectionAction, ActiveConnectionsFilterAction, AddServerAction
ActiveConnectionsFilterAction, RecentConnectionsFilterAction
} }
from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction'; from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction';
import { TestConnectionManagementService } from 'sql/platform/connection/test/common/testConnectionManagementService'; import { TestConnectionManagementService } from 'sql/platform/connection/test/common/testConnectionManagementService';
@@ -17,7 +16,7 @@ import { TestErrorMessageService } from 'sql/platform/errorMessage/test/common/t
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServerTreeView } from 'sql/workbench/contrib/objectExplorer/browser/serverTreeView'; import { ServerTreeView } from 'sql/workbench/contrib/objectExplorer/browser/serverTreeView';
import * as LocalizedConstants from 'sql/workbench/services/connection/browser/localizedConstants'; import * as LocalizedConstants from 'sql/workbench/services/connection/browser/localizedConstants';
import { ObjectExplorerService, ObjectExplorerNodeEventArgs } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService'; import { ObjectExplorerService, ObjectExplorerNodeEventArgs, ServerTreeViewView } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService';
import { TreeNode } from 'sql/workbench/services/objectExplorer/common/treeNode'; import { TreeNode } from 'sql/workbench/services/objectExplorer/common/treeNode';
import { NodeType } from 'sql/workbench/services/objectExplorer/common/nodeType'; import { NodeType } from 'sql/workbench/services/objectExplorer/common/nodeType';
import { Emitter, Event } from 'vs/base/common/event'; import { Emitter, Event } from 'vs/base/common/event';
@@ -263,12 +262,15 @@ suite('SQL Connection Tree Action tests', () => {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
}); });
let serverTreeView = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Strict, undefined, instantiationService.object, undefined, undefined, undefined, undefined, capabilitiesService); let serverTreeView = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Strict, undefined, instantiationService.object, undefined, undefined, undefined, undefined, capabilitiesService, undefined, undefined, new MockContextKeyService());
serverTreeView.setup(x => x.showFilteredTree(TypeMoq.It.isAnyString())); serverTreeView.setup(x => x.showFilteredTree(TypeMoq.It.isAny()));
serverTreeView.setup(x => x.refreshTree()); serverTreeView.setup(x => x.refreshTree());
let connectionTreeAction: ActiveConnectionsFilterAction = new ActiveConnectionsFilterAction(ActiveConnectionsFilterAction.ID, ActiveConnectionsFilterAction.LABEL, serverTreeView.object); serverTreeView.setup(x => x.view).returns(() => ServerTreeViewView.all);
const mockObjectExplorerService = TypeMoq.Mock.ofType(ObjectExplorerService);
mockObjectExplorerService.setup(x => x.getServerTreeView()).returns(() => serverTreeView.object);
let connectionTreeAction: ActiveConnectionsFilterAction = new ActiveConnectionsFilterAction(ActiveConnectionsFilterAction.ID, ActiveConnectionsFilterAction.SHOW_ACTIVE_CONNECTIONS_LABEL, mockObjectExplorerService.object);
return connectionTreeAction.run().then((value) => { return connectionTreeAction.run().then((value) => {
serverTreeView.verify(x => x.showFilteredTree('active'), TypeMoq.Times.once()); serverTreeView.verify(x => x.showFilteredTree(ServerTreeViewView.active), TypeMoq.Times.once());
}); });
}); });
@@ -278,42 +280,13 @@ suite('SQL Connection Tree Action tests', () => {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
}); });
let serverTreeView = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Strict, undefined, instantiationService.object, undefined, undefined, undefined, undefined, capabilitiesService); let serverTreeView = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Strict, undefined, instantiationService.object, undefined, undefined, undefined, undefined, capabilitiesService, undefined, undefined, new MockContextKeyService());
serverTreeView.setup(x => x.showFilteredTree(TypeMoq.It.isAnyString())); serverTreeView.setup(x => x.showFilteredTree(TypeMoq.It.isAny()));
serverTreeView.setup(x => x.refreshTree()); serverTreeView.setup(x => x.refreshTree());
let connectionTreeAction: ActiveConnectionsFilterAction = new ActiveConnectionsFilterAction(ActiveConnectionsFilterAction.ID, ActiveConnectionsFilterAction.LABEL, serverTreeView.object); serverTreeView.setup(x => x.view).returns(() => ServerTreeViewView.active);
connectionTreeAction.isSet = true; const mockObjectExplorerService = TypeMoq.Mock.ofType(ObjectExplorerService);
return connectionTreeAction.run().then((value) => { mockObjectExplorerService.setup(x => x.getServerTreeView()).returns(() => serverTreeView.object);
serverTreeView.verify(x => x.refreshTree(), TypeMoq.Times.once()); let connectionTreeAction: ActiveConnectionsFilterAction = new ActiveConnectionsFilterAction(ActiveConnectionsFilterAction.ID, ActiveConnectionsFilterAction.SHOW_ACTIVE_CONNECTIONS_LABEL, mockObjectExplorerService.object);
});
});
test('RecentConnectionsFilterAction - test if view is called to display filtered results', () => {
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
return new Promise((resolve) => resolve({}));
});
let serverTreeView = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Strict, undefined, instantiationService.object, undefined, undefined, undefined, undefined, capabilitiesService);
serverTreeView.setup(x => x.showFilteredTree(TypeMoq.It.isAnyString()));
serverTreeView.setup(x => x.refreshTree());
let connectionTreeAction: RecentConnectionsFilterAction = new RecentConnectionsFilterAction(RecentConnectionsFilterAction.ID, RecentConnectionsFilterAction.LABEL, serverTreeView.object);
return connectionTreeAction.run().then((value) => {
serverTreeView.verify(x => x.showFilteredTree('recent'), TypeMoq.Times.once());
});
});
test('RecentConnectionsFilterAction - test if view is called refresh results if action is toggled', () => {
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
return new Promise((resolve) => resolve({}));
});
let serverTreeView = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Strict, undefined, instantiationService.object, undefined, undefined, undefined, undefined, capabilitiesService);
serverTreeView.setup(x => x.showFilteredTree(TypeMoq.It.isAnyString()));
serverTreeView.setup(x => x.refreshTree());
let connectionTreeAction: RecentConnectionsFilterAction = new RecentConnectionsFilterAction(RecentConnectionsFilterAction.ID, RecentConnectionsFilterAction.LABEL, serverTreeView.object);
connectionTreeAction.isSet = true;
return connectionTreeAction.run().then((value) => { return connectionTreeAction.run().then((value) => {
serverTreeView.verify(x => x.refreshTree(), TypeMoq.Times.once()); serverTreeView.verify(x => x.refreshTree(), TypeMoq.Times.once());
}); });

View File

@@ -16,6 +16,7 @@ import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServic
import { TreeItemCollapsibleState } from 'sql/workbench/services/objectExplorer/common/treeNode'; import { TreeItemCollapsibleState } from 'sql/workbench/services/objectExplorer/common/treeNode';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import * as assert from 'assert'; import * as assert from 'assert';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
suite('ServerTreeView onAddConnectionProfile handler tests', () => { suite('ServerTreeView onAddConnectionProfile handler tests', () => {
@@ -37,7 +38,7 @@ suite('ServerTreeView onAddConnectionProfile handler tests', () => {
); );
mockConnectionManagementService.setup(x => x.getConnectionGroups()).returns(x => []); mockConnectionManagementService.setup(x => x.getConnectionGroups()).returns(x => []);
mockConnectionManagementService.setup(x => x.hasRegisteredServers()).returns(() => true); mockConnectionManagementService.setup(x => x.hasRegisteredServers()).returns(() => true);
serverTreeView = new ServerTreeView(mockConnectionManagementService.object, instantiationService, undefined, new TestThemeService(), undefined, undefined, capabilitiesService, undefined, undefined); serverTreeView = new ServerTreeView(mockConnectionManagementService.object, instantiationService, undefined, new TestThemeService(), undefined, undefined, capabilitiesService, undefined, undefined, new MockContextKeyService());
mockTree = TypeMoq.Mock.ofType(TestTree); mockTree = TypeMoq.Mock.ofType(TestTree);
(serverTreeView as any)._tree = mockTree.object; (serverTreeView as any)._tree = mockTree.object;
mockRefreshTreeMethod = TypeMoq.Mock.ofType(Function); mockRefreshTreeMethod = TypeMoq.Mock.ofType(Function);

View File

@@ -22,6 +22,7 @@ import { createObjectExplorerServiceMock } from 'sql/workbench/services/objectEx
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TestTree } from 'sql/workbench/test/treeMock'; import { TestTree } from 'sql/workbench/test/treeMock';
import { TestConnectionManagementService } from 'sql/platform/connection/test/common/testConnectionManagementService'; import { TestConnectionManagementService } from 'sql/platform/connection/test/common/testConnectionManagementService';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
const connection: azdata.IConnectionProfile = { const connection: azdata.IConnectionProfile = {
options: [], options: [],
@@ -64,7 +65,7 @@ suite('Scripting Actions', () => {
instantiationService = new InstantiationService(collection); instantiationService = new InstantiationService(collection);
const capabilitiesService = new TestCapabilitiesService(); const capabilitiesService = new TestCapabilitiesService();
const connectionManagementServiceMock = TypeMoq.Mock.ofType(TestConnectionManagementService, TypeMoq.MockBehavior.Loose); const connectionManagementServiceMock = TypeMoq.Mock.ofType(TestConnectionManagementService, TypeMoq.MockBehavior.Loose);
const serverTreeViewMock = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Loose, connectionManagementServiceMock.object, instantiationService, undefined, undefined, undefined, undefined, capabilitiesService); const serverTreeViewMock = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Loose, connectionManagementServiceMock.object, instantiationService, undefined, undefined, undefined, undefined, capabilitiesService, undefined, undefined, new MockContextKeyService());
treeMock = TypeMoq.Mock.ofType(TestTree); treeMock = TypeMoq.Mock.ofType(TestTree);
serverTreeViewMock.setup(x => x.tree).returns(() => treeMock.object); serverTreeViewMock.setup(x => x.tree).returns(() => treeMock.object);
collection.set(IObjectExplorerService, createObjectExplorerServiceMock({ serverTreeView: serverTreeViewMock.object, treeNode: treeNode })); collection.set(IObjectExplorerService, createObjectExplorerServiceMock({ serverTreeView: serverTreeViewMock.object, treeNode: treeNode }));

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { AddServerAction } from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction';
import { escape } from 'vs/base/common/strings'; import { escape } from 'vs/base/common/strings';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
@@ -37,7 +38,7 @@ export default () => `
</div> </div>
<div class="row header-bottom-nav-tiles ads-grid"> <div class="row header-bottom-nav-tiles ads-grid">
<div class="col"> <div class="col">
<a role="button" class="header-bottom-nav-tile-link ads-welcome-page-link" href="command:registeredServers.addConnection"> <a role="button" class="header-bottom-nav-tile-link ads-welcome-page-link" href="command:${AddServerAction.ID}">
<div class="header-bottom-nav-tile tile tile-connection"> <div class="header-bottom-nav-tile tile tile-connection">
<h3>${escape(localize('welcomePage.createConnection', "Create a connection"))}</h3> <h3>${escape(localize('welcomePage.createConnection', "Create a connection"))}</h3>
<p>${escape(localize('welcomePage.createConnectionBody', "Connect to a database instance through the connection dialog."))}</p> <p>${escape(localize('welcomePage.createConnectionBody', "Connect to a database instance through the connection dialog."))}</p>

View File

@@ -22,8 +22,8 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Button } from 'sql/base/browser/ui/button/button'; import { Button } from 'sql/base/browser/ui/button/button';
import { extensionsViewIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons'; import { extensionsViewIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons';
import { settingsViewBarIcon } from 'vs/workbench/browser/parts/activitybar/activitybarPart'; import { settingsViewBarIcon } from 'vs/workbench/browser/parts/activitybar/activitybarPart';
import { dataExplorerIconId } from 'sql/workbench/contrib/dataExplorer/browser/dataExplorerViewlet';
import { notebookIconId } from 'sql/workbench/contrib/notebook/browser/notebookExplorer/notebookExplorerViewlet'; import { notebookIconId } from 'sql/workbench/contrib/notebook/browser/notebookExplorer/notebookExplorerViewlet';
import { SqlIconId } from 'sql/base/common/codicons';
const $ = dom.$; const $ = dom.$;
interface TourData { interface TourData {
@@ -44,7 +44,7 @@ interface TourData {
popupImage: string; popupImage: string;
} }
const dataExplorerIconCssSelector = `.action-label.${dataExplorerIconId}`; const dataExplorerIconCssSelector = `.action-label.${SqlIconId.dataExplorer}`;
const notebookIconCssSelector = `.action-label.${notebookIconId}`; const notebookIconCssSelector = `.action-label.${notebookIconId}`;
const extensionsIconCssSelector = ThemeIcon.asCSSSelector(extensionsViewIcon); const extensionsIconCssSelector = ThemeIcon.asCSSSelector(extensionsViewIcon);
const settingsGearIconCssSelector = ThemeIcon.asCSSSelector(settingsViewBarIcon); const settingsGearIconCssSelector = ThemeIcon.asCSSSelector(settingsViewBarIcon);

View File

@@ -54,6 +54,7 @@ import { ICommandAction, MenuItemAction } from 'vs/platform/actions/common/actio
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { attachButtonStyler } from 'vs/platform/theme/common/styler'; import { attachButtonStyler } from 'vs/platform/theme/common/styler';
import { AddServerAction } from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction';
const configurationKey = 'workbench.startupEditor'; const configurationKey = 'workbench.startupEditor';
const oldConfigurationKey = 'workbench.welcome.enabled'; const oldConfigurationKey = 'workbench.welcome.enabled';
const telemetryFrom = 'welcomePage'; const telemetryFrom = 'welcomePage';
@@ -211,7 +212,7 @@ const extensionPackStrings = {
const NewActionItems: ICommandAction[] = [ const NewActionItems: ICommandAction[] = [
{ {
title: localize('welcomePage.newConnection', "New connection"), title: localize('welcomePage.newConnection', "New connection"),
id: 'registeredServers.addConnection' id: AddServerAction.ID
}, { }, {
title: localize('welcomePage.newQuery', "New query"), title: localize('welcomePage.newQuery', "New query"),
id: 'workbench.action.files.newUntitledFile' id: 'workbench.action.files.newUntitledFile'

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { AddServerAction } from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction';
import { escape } from 'vs/base/common/strings'; import { escape } from 'vs/base/common/strings';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
@@ -18,7 +19,7 @@ export default () => `
<div class="section start"> <div class="section start">
<h2 class="caption">${escape(localize('welcomePage.start', "Start"))}</h2> <h2 class="caption">${escape(localize('welcomePage.start', "Start"))}</h2>
<ul> <ul>
<li><a href="command:registeredServers.addConnection">${escape(localize('welcomePage.newConnection', "New connection"))}</a></li> <li><a href="command:${AddServerAction.ID}">${escape(localize('welcomePage.newConnection', "New connection"))}</a></li>
<li><a href="command:workbench.action.files.newUntitledFile">${escape(localize('welcomePage.newQuery', "New query"))}</a></li> <li><a href="command:workbench.action.files.newUntitledFile">${escape(localize('welcomePage.newQuery', "New query"))}</a></li>
<li><a href="command:notebook.command.new">${escape(localize('welcomePage.newNotebook', "New notebook"))}</a></li> <li><a href="command:notebook.command.new">${escape(localize('welcomePage.newNotebook', "New notebook"))}</a></li>
<li class="mac-only"><a href="command:workbench.action.files.openLocalFileFolder">${escape(localize('welcomePage.openFileMac', "Open file"))}</a></li> <li class="mac-only"><a href="command:workbench.action.files.openLocalFileFolder">${escape(localize('welcomePage.openFileMac', "Open file"))}</a></li>

View File

@@ -10,7 +10,7 @@ import { IConnectionManagementService } from 'sql/platform/connection/common/con
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { ConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup'; import { ConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup';
import { ITree } from 'vs/base/parts/tree/browser/tree'; import { ITree } from 'vs/base/parts/tree/browser/tree';
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService'; import { IObjectExplorerService, ServerTreeViewView } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService';
import { TreeNode } from 'sql/workbench/services/objectExplorer/common/treeNode'; import { TreeNode } from 'sql/workbench/services/objectExplorer/common/treeNode';
import Severity from 'vs/base/common/severity'; import Severity from 'vs/base/common/severity';
import { ObjectExplorerActionsContext } from 'sql/workbench/services/objectExplorer/browser/objectExplorerActions'; import { ObjectExplorerActionsContext } from 'sql/workbench/services/objectExplorer/browser/objectExplorerActions';
@@ -19,6 +19,7 @@ import { UNSAVED_GROUP_ID } from 'sql/platform/connection/common/constants';
import { IServerGroupController } from 'sql/platform/serverGroup/common/serverGroupController'; import { IServerGroupController } from 'sql/platform/serverGroup/common/serverGroupController';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
import { AsyncServerTree, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree'; import { AsyncServerTree, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree';
import { SqlIconId } from 'sql/base/common/codicons';
export interface IServerView { export interface IServerView {
showFilteredTree(filter: string): void; showFilteredTree(filter: string): void;
@@ -158,8 +159,7 @@ export class AddServerAction extends Action {
label: string, label: string,
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService @IConnectionManagementService private _connectionManagementService: IConnectionManagementService
) { ) {
super(id, label); super(id, label, SqlIconId.addServerAction);
this.class = 'add-server-action';
} }
public async run(element: ConnectionProfileGroup): Promise<boolean> { public async run(element: ConnectionProfileGroup): Promise<boolean> {
@@ -187,7 +187,7 @@ export class AddServerAction extends Action {
} }
/** /**
* Actions to add a server to the group * Action to open up the dialog to create a new server group
*/ */
export class AddServerGroupAction extends Action { export class AddServerGroupAction extends Action {
public static ID = 'registeredServers.addServerGroup'; public static ID = 'registeredServers.addServerGroup';
@@ -198,8 +198,7 @@ export class AddServerGroupAction extends Action {
label: string, label: string,
@IServerGroupController private readonly serverGroupController: IServerGroupController @IServerGroupController private readonly serverGroupController: IServerGroupController
) { ) {
super(id, label); super(id, label, SqlIconId.addServerGroupAction);
this.class = 'add-server-group-action';
} }
public async run(): Promise<boolean> { public async run(): Promise<boolean> {
@@ -232,96 +231,33 @@ export class EditServerGroupAction extends Action {
} }
/** /**
* Display active connections in the tree * Action to toggle filtering the server connections tree to only show
* active connections or not.
*/ */
export class ActiveConnectionsFilterAction extends Action { export class ActiveConnectionsFilterAction extends Action {
public static ID = 'registeredServers.recentConnections'; public static ID = 'registeredServers.recentConnections';
public static LABEL = localize('activeConnections', "Show Active Connections"); public static SHOW_ACTIVE_CONNECTIONS_LABEL = localize('activeConnections', "Show Active Connections");
private static enabledClass = 'active-connections-action'; public static SHOW_ALL_CONNECTIONS_LABEL = localize('showAllConnections', "Show All Connections");
private static disabledClass = 'icon server-page';
private static showAllConnectionsLabel = localize('showAllConnections', "Show All Connections");
private _isSet: boolean = false;
public static readonly ACTIVE = 'active'; public static readonly ACTIVE = 'active';
public get isSet(): boolean {
return this._isSet;
}
public set isSet(value: boolean) {
this._isSet = value;
this.class = (!this._isSet) ?
ActiveConnectionsFilterAction.enabledClass : ActiveConnectionsFilterAction.disabledClass;
}
constructor( constructor(
id: string, id: string,
label: string, label: string,
private view: IServerView @IObjectExplorerService private _objectExplorerService: IObjectExplorerService
) { ) {
super(id, label); super(id, label, SqlIconId.activeConnectionsAction);
this.class = ActiveConnectionsFilterAction.enabledClass;
} }
public run(): Promise<boolean> { public async run(): Promise<boolean> {
if (!this.view) { const serverTreeView = this._objectExplorerService.getServerTreeView();
// return without doing anything if (serverTreeView.view !== ServerTreeViewView.active) {
return Promise.resolve(true);
}
if (this.class === ActiveConnectionsFilterAction.enabledClass) {
// show active connections in the tree // show active connections in the tree
this.view.showFilteredTree(ActiveConnectionsFilterAction.ACTIVE); serverTreeView.showFilteredTree(ServerTreeViewView.active);
this.isSet = true;
this.label = ActiveConnectionsFilterAction.showAllConnectionsLabel;
} else { } else {
// show full tree // show full tree
this.view.refreshTree(); await serverTreeView.refreshTree();
this.isSet = false;
this.label = ActiveConnectionsFilterAction.LABEL;
} }
return Promise.resolve(true); return true;
}
}
/**
* Display recent connections in the tree
*/
export class RecentConnectionsFilterAction extends Action {
public static ID = 'registeredServers.recentConnections';
public static LABEL = localize('recentConnections', "Recent Connections");
private static enabledClass = 'recent-connections-action';
private static disabledClass = 'recent-connections-action-set';
private _isSet: boolean;
public get isSet(): boolean {
return this._isSet;
}
public set isSet(value: boolean) {
this._isSet = value;
this.class = (!this._isSet) ?
RecentConnectionsFilterAction.enabledClass : RecentConnectionsFilterAction.disabledClass;
}
constructor(
id: string,
label: string,
private view: IServerView
) {
super(id, label);
this.class = RecentConnectionsFilterAction.enabledClass;
this._isSet = false;
}
public run(): Promise<boolean> {
if (!this.view) {
// return without doing anything
return Promise.resolve(true);
}
if (this.class === RecentConnectionsFilterAction.enabledClass) {
// show recent connections in the tree
this.view.showFilteredTree('recent');
this.isSet = true;
} else {
// show full tree
this.view.refreshTree();
this.isSet = false;
}
return Promise.resolve(true);
} }
} }

View File

@@ -20,7 +20,6 @@ import { entries } from 'sql/base/common/collections';
import { values } from 'vs/base/common/collections'; import { values } from 'vs/base/common/collections';
import { startsWith } from 'vs/base/common/strings'; import { startsWith } from 'vs/base/common/strings';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry'; import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import { IAction } from 'vs/base/common/actions';
import { ServerTreeActionProvider } from 'sql/workbench/services/objectExplorer/browser/serverTreeActionProvider'; import { ServerTreeActionProvider } from 'sql/workbench/services/objectExplorer/browser/serverTreeActionProvider';
import { ITree } from 'vs/base/parts/tree/browser/tree'; import { ITree } from 'vs/base/parts/tree/browser/tree';
import { AsyncServerTree, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree'; import { AsyncServerTree, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree';
@@ -33,6 +32,11 @@ export interface NodeExpandInfoWithProviderId extends azdata.ObjectExplorerExpan
providerId: string; providerId: string;
} }
export const enum ServerTreeViewView {
all = 'all',
active = 'active'
}
export interface IServerTreeView { export interface IServerTreeView {
readonly tree: ITree | AsyncServerTree; readonly tree: ITree | AsyncServerTree;
readonly onSelectionOrFocusChange: Event<void>; readonly onSelectionOrFocusChange: Event<void>;
@@ -47,9 +51,10 @@ export interface IServerTreeView {
setExpandedState(node: ServerTreeElement, state?: TreeItemCollapsibleState): Promise<void>; setExpandedState(node: ServerTreeElement, state?: TreeItemCollapsibleState): Promise<void>;
setSelected(node: ServerTreeElement, selected?: boolean, clearOtherSelections?: boolean): Promise<void>; setSelected(node: ServerTreeElement, selected?: boolean, clearOtherSelections?: boolean): Promise<void>;
refreshTree(): Promise<void>; refreshTree(): Promise<void>;
readonly activeConnectionsFilterAction: IAction;
renderBody(container: HTMLElement): Promise<void>; renderBody(container: HTMLElement): Promise<void>;
layout(size: number): void; layout(size: number): void;
showFilteredTree(view: ServerTreeViewView): void;
view: ServerTreeViewView;
} }
export interface IObjectExplorerService { export interface IObjectExplorerService {

View File

@@ -9,8 +9,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { import {
DisconnectConnectionAction, AddServerAction, EditConnectionAction, DisconnectConnectionAction, EditConnectionAction,
DeleteConnectionAction, RefreshAction, EditServerGroupAction DeleteConnectionAction, RefreshAction, EditServerGroupAction, AddServerAction
} from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction'; } from 'sql/workbench/services/objectExplorer/browser/connectionTreeAction';
import { TreeNode } from 'sql/workbench/services/objectExplorer/common/treeNode'; import { TreeNode } from 'sql/workbench/services/objectExplorer/common/treeNode';
import { NodeType } from 'sql/workbench/services/objectExplorer/common/nodeType'; import { NodeType } from 'sql/workbench/services/objectExplorer/common/nodeType';
@@ -157,6 +157,7 @@ export class ServerTreeActionProvider {
* Return actions for connection group elements * Return actions for connection group elements
*/ */
private getConnectionProfileGroupActions(element: ConnectionProfileGroup): IAction[] { private getConnectionProfileGroupActions(element: ConnectionProfileGroup): IAction[] {
// TODO: Should look into using the MenuRegistry for this
return [ return [
this._instantiationService.createInstance(AddServerAction, AddServerAction.ID, AddServerAction.LABEL), this._instantiationService.createInstance(AddServerAction, AddServerAction.ID, AddServerAction.LABEL),
this._instantiationService.createInstance(EditServerGroupAction, EditServerGroupAction.ID, EditServerGroupAction.LABEL, element), this._instantiationService.createInstance(EditServerGroupAction, EditServerGroupAction.ID, EditServerGroupAction.LABEL, element),

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { SqlIconId } from 'sql/base/common/codicons';
import { codiconStartMarker } from 'vs/base/common/codicon'; import { codiconStartMarker } from 'vs/base/common/codicon';
import { Emitter, Event } from 'vs/base/common/event'; import { Emitter, Event } from 'vs/base/common/event';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
@@ -91,9 +92,9 @@ export namespace CSSIcon {
let [, id, modifier] = match; let [, id, modifier] = match;
// {{SQL CARBON EDIT}} Modifying method to not add 'codicon' in front of sql carbon icons. // {{SQL CARBON EDIT}} Modifying method to not add 'codicon' in front of sql carbon icons.
let sqlCarbonIcons = ['book', 'dataExplorer']; let sqlCarbonIcons: string[] = [SqlIconId.book, SqlIconId.dataExplorer, SqlIconId.activeConnectionsAction, SqlIconId.addServerAction, SqlIconId.addServerGroupAction, SqlIconId.serverPage];
if (sqlCarbonIcons.includes(id)) { if (sqlCarbonIcons.includes(id)) {
return [id]; return ['codicon', id];
// {{SQL CARBON EDIT}} End of edit // {{SQL CARBON EDIT}} End of edit
} else { } else {
const classNames = ['codicon', 'codicon-' + id]; const classNames = ['codicon', 'codicon-' + id];