diff --git a/src/sql/workbench/parts/objectExplorer/browser/serverTreeActionProvider.ts b/src/sql/workbench/parts/objectExplorer/browser/serverTreeActionProvider.ts index 09a15bdbfd..353edce2ac 100644 --- a/src/sql/workbench/parts/objectExplorer/browser/serverTreeActionProvider.ts +++ b/src/sql/workbench/parts/objectExplorer/browser/serverTreeActionProvider.ts @@ -118,8 +118,11 @@ export class ServerTreeActionProvider extends ContributableActionProvider { 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)); + // Contribute refresh action for scriptable objects via contribution + if (!this.isScriptableObject(context)) { + actions.push(this._instantiationService.createInstance(RefreshAction, RefreshAction.ID, RefreshAction.LABEL, context.tree, context.profile)); + } return actions; } @@ -180,7 +183,10 @@ export class ServerTreeActionProvider extends ContributableActionProvider { this.addRestoreAction(context, actions); } - actions.push(this._instantiationService.createInstance(RefreshAction, RefreshAction.ID, RefreshAction.LABEL, context.tree, treeNode)); + // Contribute refresh action for scriptable objects via contribution + if (!this.isScriptableObject(context)) { + actions.push(this._instantiationService.createInstance(RefreshAction, RefreshAction.ID, RefreshAction.LABEL, context.tree, context.profile)); + } return actions; } @@ -205,6 +211,15 @@ export class ServerTreeActionProvider extends ContributableActionProvider { actions.push(this._instantiationService.createInstance(OEAction, RestoreAction.ID, RestoreAction.LABEL)); } } + + private isScriptableObject(context: ObjectExplorerContext): boolean { + if (context.treeNode) { + if (NodeType.SCRIPTABLE_OBJECTS.includes(context.treeNode.nodeTypeId)) { + return true; + } + } + return false; + } } interface ObjectExplorerContext { diff --git a/src/sql/workbench/parts/objectExplorer/common/nodeType.ts b/src/sql/workbench/parts/objectExplorer/common/nodeType.ts index 0d35b53170..9a968c2fb7 100644 --- a/src/sql/workbench/parts/objectExplorer/common/nodeType.ts +++ b/src/sql/workbench/parts/objectExplorer/common/nodeType.ts @@ -93,6 +93,10 @@ export class NodeType { public static ExternalTable = 'ExternalTable'; public static ColumnMasterKey = 'ColumnMasterKey'; public static ColumnEncryptionKey = 'ColumnEncryptionKey'; + + public static readonly SCRIPTABLE_OBJECTS = [NodeType.Table, NodeType.View, NodeType.Schema, NodeType.User, NodeType.UserDefinedTableType, + NodeType.StoredProcedure, NodeType.AggregateFunction, NodeType.PartitionFunction, NodeType.ScalarValuedFunction, + NodeType.TableValuedFunction]; } export interface SqlThemeIcon { diff --git a/src/sql/workbench/parts/objectExplorer/electron-browser/objectExplorerScripting.contribution.ts b/src/sql/workbench/parts/objectExplorer/electron-browser/objectExplorerScripting.contribution.ts index 2142898893..d77d420db1 100644 --- a/src/sql/workbench/parts/objectExplorer/electron-browser/objectExplorerScripting.contribution.ts +++ b/src/sql/workbench/parts/objectExplorer/electron-browser/objectExplorerScripting.contribution.ts @@ -3,16 +3,21 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SCRIPT_AS_SELECT_COMMAND_ID, EDIT_DATA_COMMAND_ID, SCRIPT_AS_CREATE_COMMAND_ID, SCRIPT_AS_EXECUTE_COMMAND_ID, SCRIPT_AS_ALTER_COMMAND_ID, SCRIPT_AS_DELETE_COMMAND_ID } from 'sql/workbench/parts/objectExplorer/electron-browser/objectExplorerScriptingActions'; +import { + SCRIPT_AS_SELECT_COMMAND_ID, EDIT_DATA_COMMAND_ID, SCRIPT_AS_CREATE_COMMAND_ID, + SCRIPT_AS_EXECUTE_COMMAND_ID, SCRIPT_AS_ALTER_COMMAND_ID, SCRIPT_AS_DELETE_COMMAND_ID, + REFRESH_OE_COMMAND_ID +} from 'sql/workbench/parts/objectExplorer/electron-browser/objectExplorerScriptingActions'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { localize } from 'vs/nls'; import { ConnectionContextKey } from 'sql/workbench/parts/connection/common/connectionContextKey'; import { TreeNodeContextKey } from 'sql/workbench/parts/objectExplorer/common/treeNodeContextKey'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { group: 'scripting', - order: 3, + order: 1, command: { id: SCRIPT_AS_SELECT_COMMAND_ID, title: localize('scriptSelect', "Select Top 1000") @@ -22,7 +27,7 @@ MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { group: 'scripting', - order: 3, + order: 2, command: { id: EDIT_DATA_COMMAND_ID, title: localize('editData', "Edit Data") @@ -52,7 +57,7 @@ MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { group: 'scripting', - order: 3, + order: 6, command: { id: SCRIPT_AS_EXECUTE_COMMAND_ID, title: localize('scriptExecute', "Script as Execute") @@ -62,7 +67,7 @@ MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { group: 'scripting', - order: 3, + order: 5, command: { id: SCRIPT_AS_ALTER_COMMAND_ID, title: localize('scriptAlter', "Script as Alter") @@ -71,41 +76,61 @@ MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { ContextKeyExpr.or( ContextKeyExpr.and( ConnectionContextKey.Provider.isEqualTo('MSSQL'), - TreeNodeContextKey.NodeType.isEqualTo('StoredProcedure')), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.StoredProcedure)), ContextKeyExpr.and( ConnectionContextKey.Provider.isEqualTo('MSSQL'), - TreeNodeContextKey.NodeType.isEqualTo('View')), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.View)), ContextKeyExpr.and( ConnectionContextKey.Provider.isEqualTo('MSSQL'), - TreeNodeContextKey.NodeType.isEqualTo('AggregateFunction')), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.AggregateFunction)), ContextKeyExpr.and( ConnectionContextKey.Provider.isEqualTo('MSSQL'), - TreeNodeContextKey.NodeType.isEqualTo('PartitionFunction')), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.PartitionFunction)), ContextKeyExpr.and( ConnectionContextKey.Provider.isEqualTo('MSSQL'), - TreeNodeContextKey.NodeType.isEqualTo('ScalarValuedFunction')), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.ScalarValuedFunction)), ContextKeyExpr.and( ConnectionContextKey.Provider.isEqualTo('MSSQL'), - TreeNodeContextKey.NodeType.isEqualTo('TableValuedFunction')), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.TableValuedFunction)), ) }); MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { group: 'scripting', - order: 3, + order: 4, command: { id: SCRIPT_AS_DELETE_COMMAND_ID, title: localize('scriptDelete', "Script as Drop") }, when: ContextKeyExpr.or( - TreeNodeContextKey.NodeType.isEqualTo('Table'), - TreeNodeContextKey.NodeType.isEqualTo('View'), - TreeNodeContextKey.NodeType.isEqualTo('Schema'), - TreeNodeContextKey.NodeType.isEqualTo('User'), - TreeNodeContextKey.NodeType.isEqualTo('UserDefinedTableType'), - TreeNodeContextKey.NodeType.isEqualTo('StoredProcedure'), - TreeNodeContextKey.NodeType.isEqualTo('AggregateFunction'), - TreeNodeContextKey.NodeType.isEqualTo('PartitionFunction'), - TreeNodeContextKey.NodeType.isEqualTo('ScalarValuedFunction'), - TreeNodeContextKey.NodeType.isEqualTo('TableValuedFunction')) + TreeNodeContextKey.NodeType.isEqualTo(NodeType.Table), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.View), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.Schema), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.User), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.UserDefinedTableType), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.StoredProcedure), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.AggregateFunction), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.PartitionFunction), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.ScalarValuedFunction), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.TableValuedFunction)) +}); + +MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { + group: 'scripting', + order: 7, + command: { + id: REFRESH_OE_COMMAND_ID, + title: localize('refreshNode', "Refresh") + }, + when: ContextKeyExpr.or( + TreeNodeContextKey.NodeType.isEqualTo(NodeType.Table), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.View), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.Schema), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.User), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.UserDefinedTableType), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.StoredProcedure), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.AggregateFunction), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.PartitionFunction), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.ScalarValuedFunction), + TreeNodeContextKey.NodeType.isEqualTo(NodeType.TableValuedFunction)) }); diff --git a/src/sql/workbench/parts/objectExplorer/electron-browser/objectExplorerScriptingActions.ts b/src/sql/workbench/parts/objectExplorer/electron-browser/objectExplorerScriptingActions.ts index 51129f8f13..16fa367cf7 100644 --- a/src/sql/workbench/parts/objectExplorer/electron-browser/objectExplorerScriptingActions.ts +++ b/src/sql/workbench/parts/objectExplorer/electron-browser/objectExplorerScriptingActions.ts @@ -12,6 +12,10 @@ import { ObjectExplorerActionsContext, getTreeNode } from 'sql/workbench/parts/o import { TreeUpdateUtils } from 'sql/workbench/parts/objectExplorer/browser/treeUpdateUtils'; import { TreeNode } from 'sql/workbench/parts/objectExplorer/common/treeNode'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; +import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; +import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; +import Severity from 'vs/base/common/severity'; export const SCRIPT_AS_CREATE_COMMAND_ID = 'objectExplorer.scriptAsCreate'; export const SCRIPT_AS_DELETE_COMMAND_ID = 'objectExplorer.scriptAsDelete'; @@ -19,8 +23,9 @@ export const SCRIPT_AS_SELECT_COMMAND_ID = 'objectExplorer.scriptAsSelect'; export const SCRIPT_AS_EXECUTE_COMMAND_ID = 'objectExplorer.scriptAsExecute'; export const SCRIPT_AS_ALTER_COMMAND_ID = 'objectExplorer.scriptAsAlter'; export const EDIT_DATA_COMMAND_ID = 'objectExplorer.scriptAsEdit'; +export const REFRESH_OE_COMMAND_ID = 'objectExplorer.refreshNode'; -// Script as Create +// Script as Select CommandsRegistry.registerCommand({ id: SCRIPT_AS_SELECT_COMMAND_ID, handler: async (accessor, args: ObjectExplorerActionsContext) => { @@ -42,6 +47,7 @@ CommandsRegistry.registerCommand({ } }); +// Edit Data CommandsRegistry.registerCommand({ id: EDIT_DATA_COMMAND_ID, handler: async (accessor, args: ObjectExplorerActionsContext) => { @@ -60,6 +66,7 @@ CommandsRegistry.registerCommand({ } }); +// Script as Create CommandsRegistry.registerCommand({ id: SCRIPT_AS_CREATE_COMMAND_ID, handler: async (accessor, args: ObjectExplorerActionsContext) => { @@ -81,6 +88,7 @@ CommandsRegistry.registerCommand({ } }); +// Script as Execute CommandsRegistry.registerCommand({ id: SCRIPT_AS_EXECUTE_COMMAND_ID, handler: async (accessor, args: ObjectExplorerActionsContext) => { @@ -102,6 +110,7 @@ CommandsRegistry.registerCommand({ } }); +// Script as Alter CommandsRegistry.registerCommand({ id: SCRIPT_AS_ALTER_COMMAND_ID, handler: async (accessor, args: ObjectExplorerActionsContext) => { @@ -123,6 +132,8 @@ CommandsRegistry.registerCommand({ } }); + +// Script as Delete CommandsRegistry.registerCommand({ id: SCRIPT_AS_DELETE_COMMAND_ID, handler: async (accessor, args: ObjectExplorerActionsContext) => { @@ -144,3 +155,42 @@ CommandsRegistry.registerCommand({ }); } }); + +// Refresh Action for Scriptable objects +CommandsRegistry.registerCommand({ + id: REFRESH_OE_COMMAND_ID, + handler: async (accessor, args: ObjectExplorerActionsContext) => { + const connectionManagementService = accessor.get(IConnectionManagementService); + const capabilitiesService = accessor.get(ICapabilitiesService); + const objectExplorerService = accessor.get(IObjectExplorerService); + const errorMessageService = accessor.get(IErrorMessageService); + const connection = new ConnectionProfile(capabilitiesService, args.connectionProfile); + let treeNode: TreeNode; + if (connectionManagementService.isConnected(undefined, connection)) { + treeNode = await getTreeNode(args, objectExplorerService); + if (treeNode === undefined) { + objectExplorerService.updateObjectExplorerNodes(connection.toIConnectionProfile()).then(() => { + treeNode = objectExplorerService.getObjectExplorerNode(connection); + }); + } + } + const tree = objectExplorerService.getServerTreeView().tree; + if (treeNode) { + return tree.collapse(treeNode).then(() => { + return objectExplorerService.refreshTreeNode(treeNode.getSession(), treeNode).then(() => { + return tree.refresh(treeNode).then(() => { + return tree.expand(treeNode); + }, refreshError => { + return Promise.resolve(true); + }); + }, error => { + errorMessageService.showDialog(Severity.Error, '', error); + return Promise.resolve(true); + }); + }, collapseError => { + return Promise.resolve(true); + }); + } + return Promise.resolve(true); + } +});