Files
azuredatastudio/src/sql/parts/objectExplorer/viewlet/serverTreeActionProvider.ts
AlexFsmn bfb68254a4 Added context menu for DBs in explorer view to backup & restore db. (#2277)
* Added context menu for DBs in explorer view to backup & restore db.
Fixed bug where progress bar didn't complete on backup/restore menuclick
#2084

* Fix merge conflicts
2019-01-11 10:00:16 -08:00

224 lines
9.4 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { ITree } from 'vs/base/parts/tree/browser/tree';
import { ContributableActionProvider } from 'vs/workbench/browser/actions';
import { IAction } from 'vs/base/common/actions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { fillInActions } from 'vs/platform/actions/browser/menuItemActionItem';
import {
DisconnectConnectionAction, AddServerAction,
DeleteConnectionAction, RefreshAction, EditServerGroupAction
}
from 'sql/parts/objectExplorer/viewlet/connectionTreeAction';
import {
ObjectExplorerActionUtilities, ManageConnectionAction, OEAction
} from 'sql/parts/objectExplorer/viewlet/objectExplorerActions';
import { TreeNode } from 'sql/parts/objectExplorer/common/treeNode';
import { NodeType } from 'sql/parts/objectExplorer/common/nodeType';
import { ConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { TreeUpdateUtils } from 'sql/parts/objectExplorer/viewlet/treeUpdateUtils';
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
import { MenuId, IMenuService } from 'vs/platform/actions/common/actions';
import { NewQueryAction, BackupAction, RestoreAction } from 'sql/workbench/common/actions';
import { ConnectionContextKey } from 'sql/parts/connection/common/connectionContextKey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { TreeNodeContextKey } from './treeNodeContextKey';
import { IQueryManagementService } from 'sql/parts/query/common/queryManagement';
import { IScriptingService } from 'sql/services/scripting/scriptingService';
import * as constants from 'sql/common/constants';
/**
* Provides actions for the server tree elements
*/
export class ServerTreeActionProvider extends ContributableActionProvider {
constructor(
@IInstantiationService private _instantiationService: IInstantiationService,
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
@IQueryManagementService private _queryManagementService: IQueryManagementService,
@IScriptingService private _scriptingService: IScriptingService,
@IContextMenuService private contextMenuService: IContextMenuService,
@IMenuService private menuService: IMenuService,
@IContextKeyService private _contextKeyService: IContextKeyService
) {
super();
}
public hasActions(tree: ITree, element: any): boolean {
return element instanceof ConnectionProfileGroup || (element instanceof ConnectionProfile) || (element instanceof TreeNode);
}
/**
* Return actions given an element in the tree
*/
public getActions(tree: ITree, element: any): TPromise<IAction[]> {
if (element instanceof ConnectionProfile) {
return TPromise.as(this.getConnectionActions(tree, element));
}
if (element instanceof ConnectionProfileGroup) {
return TPromise.as(this.getConnectionProfileGroupActions(tree, element));
}
if (element instanceof TreeNode) {
return TPromise.as(this.getObjectExplorerNodeActions({
tree: tree,
profile: element.getConnectionProfile(),
treeNode: element
}));
}
return TPromise.as([]);
}
public hasSecondaryActions(tree: ITree, element: any): boolean {
return false;
}
public getSecondaryActions(tree: ITree, element: any): TPromise<IAction[]> {
return super.getSecondaryActions(tree, element);
}
/**
* Return actions for connection elements
*/
public getConnectionActions(tree: ITree, profile: ConnectionProfile): IAction[] {
let node = new TreeNode(NodeType.Server, '', false, '', '', '', undefined, undefined, undefined, undefined);
return this.getAllActions({
tree: tree,
profile: profile,
treeNode: node
}, (context) => this.getBuiltinConnectionActions(context));
}
private getAllActions(context: ObjectExplorerContext, getDefaultActions: (ObjectExplorerContext) => IAction[]) {
// Create metadata needed to get a useful set of actions
let scopedContextService = this.getContextKeyService(context);
let menu = this.menuService.createMenu(MenuId.ObjectExplorerItemContext, scopedContextService);
// Fill in all actions
let actions = getDefaultActions(context);
let options = { arg: undefined, shouldForwardArgs: true };
const groups = menu.getActions(options);
fillInActions(groups, actions, this.contextMenuService);
// Cleanup
scopedContextService.dispose();
menu.dispose();
return actions;
}
private getBuiltinConnectionActions(context: ObjectExplorerContext): IAction[] {
let actions: IAction[] = [];
actions.push(this._instantiationService.createInstance(ManageConnectionAction, ManageConnectionAction.ID, ManageConnectionAction.LABEL, context.tree));
this.addNewQueryAction(context, actions);
if (this._connectionManagementService.isProfileConnected(context.profile)) {
actions.push(this._instantiationService.createInstance(DisconnectConnectionAction, DisconnectConnectionAction.ID, DisconnectConnectionAction.LABEL, context.profile));
}
actions.push(this._instantiationService.createInstance(DeleteConnectionAction, DeleteConnectionAction.ID, DeleteConnectionAction.DELETE_CONNECTION_LABEL, context.profile));
actions.push(this._instantiationService.createInstance(RefreshAction, RefreshAction.ID, RefreshAction.LABEL, context.tree, context.profile));
return actions;
}
private getContextKeyService(context: ObjectExplorerContext): IContextKeyService {
let scopedContextService = this._contextKeyService.createScoped();
let connectionContextKey = new ConnectionContextKey(scopedContextService);
connectionContextKey.set(context.profile);
let treeNodeContextKey = new TreeNodeContextKey(scopedContextService);
if (context.treeNode) {
treeNodeContextKey.set(context.treeNode);
}
return scopedContextService;
}
/**
* Return actions for connection group elements
*/
public getConnectionProfileGroupActions(tree: ITree, element: ConnectionProfileGroup): IAction[] {
return [
this._instantiationService.createInstance(AddServerAction, AddServerAction.ID, AddServerAction.LABEL),
this._instantiationService.createInstance(EditServerGroupAction, EditServerGroupAction.ID, EditServerGroupAction.LABEL, element),
this._instantiationService.createInstance(DeleteConnectionAction, DeleteConnectionAction.ID, DeleteConnectionAction.DELETE_CONNECTION_GROUP_LABEL, element)
];
}
/**
* Return actions for OE elements
*/
private getObjectExplorerNodeActions(context: ObjectExplorerContext): IAction[] {
return this.getAllActions(context, (context) => this.getBuiltInNodeActions(context));
}
private getBuiltInNodeActions(context: ObjectExplorerContext): IAction[] {
let actions: IAction[] = [];
let treeNode = context.treeNode;
let isAvailableDatabaseNode = false;
if (TreeUpdateUtils.isDatabaseNode(treeNode)) {
if (TreeUpdateUtils.isAvailableDatabaseNode(treeNode)) {
isAvailableDatabaseNode = true;
actions.push(this._instantiationService.createInstance(ManageConnectionAction, ManageConnectionAction.ID, ManageConnectionAction.LABEL, context.tree));
this.addNewQueryAction(context, actions);
} else {
return actions;
}
}
this.addScriptingActions(context, actions);
if (isAvailableDatabaseNode) {
this.addBackupAction(context, actions);
this.addRestoreAction(context, actions);
}
actions.push(this._instantiationService.createInstance(RefreshAction, RefreshAction.ID, RefreshAction.LABEL, context.tree, treeNode));
return actions;
}
private addNewQueryAction(context: ObjectExplorerContext, actions: IAction[]): void {
if (this._queryManagementService.isProviderRegistered(context.profile.providerName)) {
actions.push(this._instantiationService.createInstance(OEAction, NewQueryAction.ID, NewQueryAction.LABEL));
}
}
private addBackupAction(context: ObjectExplorerContext, actions: IAction[]): void {
if (this._queryManagementService.isProviderRegistered(context.profile.providerName)) {
actions.push(this._instantiationService.createInstance(OEAction, BackupAction.ID, BackupAction.LABEL));
}
}
private addRestoreAction(context: ObjectExplorerContext, actions: IAction[]): void {
if (this._queryManagementService.isProviderRegistered(context.profile.providerName)) {
actions.push(this._instantiationService.createInstance(OEAction, RestoreAction.ID, RestoreAction.LABEL));
}
}
private addScriptingActions(context: ObjectExplorerContext, actions: IAction[]): void {
if (this._scriptingService.isProviderRegistered(context.profile.providerName)) {
let scriptMap: Map<NodeType, any[]> = ObjectExplorerActionUtilities.getScriptMap(context.treeNode);
let supportedActions = scriptMap.get(context.treeNode.nodeTypeId);
let self = this;
if (supportedActions !== null && supportedActions !== undefined) {
supportedActions.forEach(action => {
actions.push(self._instantiationService.createInstance(action, action.ID, action.LABEL));
});
}
}
}
}
interface ObjectExplorerContext {
tree: ITree;
profile: ConnectionProfile;
treeNode?: TreeNode;
}