diff --git a/extensions/integration-tests/src/objectExplorer.test.ts b/extensions/integration-tests/src/objectExplorer.test.ts index 44c1d21eb6..ee1c8bb618 100644 --- a/extensions/integration-tests/src/objectExplorer.test.ts +++ b/extensions/integration-tests/src/objectExplorer.test.ts @@ -65,7 +65,7 @@ class ObjectExplorerTester { @stressify({ dop: ObjectExplorerTester.ParallelCount }) async sqlDbContextMenuTest(): Promise { const server = await getAzureServer(); - const expectedActions = ['New Notebook', 'Disconnect', 'Delete Connection', 'Refresh', 'New Query', 'Manage', 'Data-tier Application wizard', 'Launch Profiler']; + const expectedActions = ['Disconnect', 'Delete Connection', 'Refresh', 'New Query', 'Manage', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler']; await this.verifyContextMenu(server, expectedActions); } @@ -75,10 +75,10 @@ class ObjectExplorerTester { let expectedActions: string[] = []; // Generate Scripts and Properties come from the admin-tool-ext-win extension which is for Windows only, so the item won't show up on non-Win32 platforms if (process.platform === 'win32') { - expectedActions = ['New Notebook', 'Backup', 'Restore', 'Refresh', 'New Query', 'Manage', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard', 'Generate Scripts...', 'Properties']; + expectedActions = ['Refresh', 'New Query', 'Manage', 'New Notebook', 'Backup', 'Restore', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard', 'Generate Scripts...', 'Properties']; } else { - expectedActions = ['New Notebook', 'Backup', 'Restore', 'Refresh', 'New Query', 'Manage', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard']; + expectedActions = ['Refresh', 'New Query', 'Manage', 'New Notebook', 'Backup', 'Restore', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard']; } await this.verifyDBContextMenu(server, 3000, expectedActions); } @@ -89,10 +89,10 @@ class ObjectExplorerTester { let expectedActions: string[]; // Properties comes from the admin-tool-ext-win extension which is for Windows only, so the item won't show up on non-Win32 platforms if (process.platform === 'win32') { - expectedActions = ['New Notebook', 'Disconnect', 'Delete Connection', 'Refresh', 'New Query', 'Manage', 'Data-tier Application wizard', 'Launch Profiler', 'Properties']; + expectedActions = ['Disconnect', 'Delete Connection', 'Refresh', 'New Query', 'Manage', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler', 'Properties']; } else { - expectedActions = ['New Notebook', 'Disconnect', 'Delete Connection', 'Refresh', 'New Query', 'Manage', 'Data-tier Application wizard', 'Launch Profiler']; + expectedActions = ['Disconnect', 'Delete Connection', 'Refresh', 'New Query', 'Manage', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler']; } await this.verifyContextMenu(server, expectedActions); } diff --git a/src/sql/platform/capabilities/common/capabilitiesService.ts b/src/sql/platform/capabilities/common/capabilitiesService.ts index 82043919f2..acb00c2ecb 100644 --- a/src/sql/platform/capabilities/common/capabilitiesService.ts +++ b/src/sql/platform/capabilities/common/capabilitiesService.ts @@ -3,13 +3,11 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo'; import { ConnectionProviderProperties } from 'sql/workbench/parts/connection/common/connectionProviderExtension'; import * as azdata from 'sqlops'; import { Event } from 'vs/base/common/event'; -import { IAction } from 'vs/base/common/actions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const SERVICE_ID = 'capabilitiesService'; @@ -49,11 +47,6 @@ export interface ICapabilitiesService { */ registerProvider(provider: azdata.CapabilitiesProvider): void; - /** - * Returns true if the feature is available for given connection - */ - isFeatureAvailable(action: IAction, connectionManagementInfo: ConnectionManagementInfo): boolean; - /** * When new capabilities are registered, it emits the @see ProviderFeatures, which can be used to get the new capabilities */ diff --git a/src/sql/platform/capabilities/common/capabilitiesServiceImpl.ts b/src/sql/platform/capabilities/common/capabilitiesServiceImpl.ts index b7a9912792..c89c286ca6 100644 --- a/src/sql/platform/capabilities/common/capabilitiesServiceImpl.ts +++ b/src/sql/platform/capabilities/common/capabilitiesServiceImpl.ts @@ -10,17 +10,13 @@ import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { Registry } from 'vs/platform/registry/common/platform'; -import { IAction } from 'vs/base/common/actions'; import * as azdata from 'azdata'; import { entries } from 'sql/base/common/objects'; -import { RestoreFeatureName, BackupFeatureName } from 'sql/workbench/common/actions'; import { toObject } from 'sql/base/common/map'; import { ConnectionProviderProperties, IConnectionProviderRegistry, Extensions as ConnectionExtensions } from 'sql/workbench/parts/connection/common/connectionProviderExtension'; import { ICapabilitiesService, ProviderFeatures, clientCapabilities } from 'sql/platform/capabilities/common/capabilitiesService'; -import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo'; -import { mssqlProviderName } from 'sql/platform/connection/common/constants'; const connectionRegistry = Registry.as(ConnectionExtensions.ConnectionProviderContributions); @@ -152,38 +148,6 @@ export class CapabilitiesService extends Disposable implements ICapabilitiesServ }); } - /** - * Returns true if the feature is available for given connection - * @param featureComponent a component which should have the feature name - * @param connectionManagementInfo connectionManagementInfo - */ - public isFeatureAvailable(action: IAction, connectionManagementInfo: ConnectionManagementInfo): boolean { - let isCloud = connectionManagementInfo && connectionManagementInfo.serverInfo && connectionManagementInfo.serverInfo.isCloud; - let isMssql = connectionManagementInfo.connectionProfile.providerName === mssqlProviderName; - // TODO: The logic should from capabilities service. - if (action) { - let featureName: string = action.id; - switch (featureName) { - case BackupFeatureName: - if (isMssql) { - return connectionManagementInfo.connectionProfile.databaseName && !isCloud; - } else { - return !!connectionManagementInfo.connectionProfile.databaseName; - } - case RestoreFeatureName: - if (isMssql) { - return !isCloud; - } else { - return !!connectionManagementInfo.connectionProfile.databaseName; - } - default: - return true; - } - } else { - return true; - } - } - private shutdown(): void { this._momento.saveMemento(); } diff --git a/src/sql/workbench/browser/taskUtilities.ts b/src/sql/workbench/browser/taskUtilities.ts index bdf7a3c85a..fc830eaac3 100644 --- a/src/sql/workbench/browser/taskUtilities.ts +++ b/src/sql/workbench/browser/taskUtilities.ts @@ -58,22 +58,6 @@ export function replaceConnection(oldUri: string, newUri: string, connectionServ }); } -export function showBackup(connection: IConnectionProfile, backupUiService: IBackupUiService): Promise { - return new Promise((resolve) => { - backupUiService.showBackup(connection).then(() => { - resolve(void 0); - }); - }); -} - -export function showRestore(connection: IConnectionProfile, restoreDialogService: IRestoreDialogController): Promise { - return new Promise((resolve) => { - restoreDialogService.showDialog(connection).then(() => { - resolve(void 0); - }); - }); -} - export function openInsight(query: IInsightsConfig, profile: IConnectionProfile, insightDialogService: IInsightsDialogService) { insightDialogService.show(query, profile); } diff --git a/src/sql/workbench/common/actions.contribution.ts b/src/sql/workbench/common/actions.contribution.ts index fdb27123b1..f6516b3bf7 100644 --- a/src/sql/workbench/common/actions.contribution.ts +++ b/src/sql/workbench/common/actions.contribution.ts @@ -10,8 +10,6 @@ import * as nls from 'vs/nls'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions as ConfigExtensions } from 'vs/platform/configuration/common/configurationRegistry'; -new Actions.BackupAction().registerTask(); -new Actions.RestoreAction().registerTask(); new Actions.ConfigureDashboardAction().registerTask(); Registry.as(ConfigExtensions.Configuration).registerConfiguration({ diff --git a/src/sql/workbench/common/actions.ts b/src/sql/workbench/common/actions.ts index 278a83d9e1..bcc8df2fcc 100644 --- a/src/sql/workbench/common/actions.ts +++ b/src/sql/workbench/common/actions.ts @@ -4,16 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; -import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; -import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; -import { IScriptingService } from 'sql/platform/scripting/common/scriptingService'; -import { IRestoreDialogController } from 'sql/platform/restore/common/restoreService'; import { IAngularEventingService, AngularEventType } from 'sql/platform/angularEventing/common/angularEventingService'; import { IInsightsDialogService } from 'sql/workbench/services/insights/browser/insightsDialogService'; -import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; -import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; -import { IBackupUiService } from 'sql/workbench/services/backup/common/backupUiService'; import { Task } from 'sql/platform/tasks/browser/tasksRegistry'; import { ObjectMetadata } from 'azdata'; @@ -21,11 +14,7 @@ import { ObjectMetadata } from 'azdata'; import { Action } from 'vs/base/common/actions'; import { IWindowsService } from 'vs/platform/windows/common/windows'; import * as nls from 'vs/nls'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { mssqlProviderName } from 'sql/platform/connection/common/constants'; import { IInsightsConfig } from 'sql/platform/dashboard/browser/insightRegistry'; export interface BaseActionContext { @@ -41,96 +30,6 @@ export interface ManageActionContext extends BaseActionContext { uri: string; } -export const BackupFeatureName = 'backup'; - -export class BackupAction extends Task { - public static readonly ID = BackupFeatureName; - public static readonly LABEL = nls.localize('backupAction.backup', "Backup"); - public static readonly ICON = BackupFeatureName; - - constructor() { - super({ - id: BackupAction.ID, - title: BackupAction.LABEL, - iconPath: undefined, - iconClass: BackupAction.ICON - }); - } - - runTask(accessor: ServicesAccessor, profile: IConnectionProfile): void | Promise { - const configurationService = accessor.get(IConfigurationService); - const previewFeaturesEnabled: boolean = configurationService.getValue('workbench')['enablePreviewFeatures']; - if (!previewFeaturesEnabled) { - return accessor.get(INotificationService).info(nls.localize('backup.isPreviewFeature', "You must enable preview features in order to use backup")); - } - - const connectionManagementService = accessor.get(IConnectionManagementService); - if (!profile) { - const objectExplorerService = accessor.get(IObjectExplorerService); - const workbenchEditorService = accessor.get(IEditorService); - profile = TaskUtilities.getCurrentGlobalConnection(objectExplorerService, connectionManagementService, workbenchEditorService); - } - if (profile) { - const serverInfo = connectionManagementService.getServerInfo(profile.id); - if (serverInfo && serverInfo.isCloud && profile.providerName === mssqlProviderName) { - return accessor.get(INotificationService).info(nls.localize('backup.commandNotSupported', "Backup command is not supported for Azure SQL databases.")); - } - - if (!profile.databaseName && profile.providerName === mssqlProviderName) { - return accessor.get(INotificationService).info(nls.localize('backup.commandNotSupportedForServer', "Backup command is not supported in Server Context. Please select a Database and try again.")); - } - } - - TaskUtilities.showBackup( - profile, - accessor.get(IBackupUiService) - ).then(); - } -} - -export const RestoreFeatureName = 'restore'; - -export class RestoreAction extends Task { - public static readonly ID = RestoreFeatureName; - public static readonly LABEL = nls.localize('restoreAction.restore', "Restore"); - public static readonly ICON = RestoreFeatureName; - - constructor() { - super({ - id: RestoreAction.ID, - title: RestoreAction.LABEL, - iconPath: undefined, - iconClass: RestoreAction.ICON - }); - } - - runTask(accessor: ServicesAccessor, profile: IConnectionProfile): void | Promise { - const configurationService = accessor.get(IConfigurationService); - const previewFeaturesEnabled: boolean = configurationService.getValue('workbench')['enablePreviewFeatures']; - if (!previewFeaturesEnabled) { - return accessor.get(INotificationService).info(nls.localize('restore.isPreviewFeature', "You must enable preview features in order to use restore")); - } - - let connectionManagementService = accessor.get(IConnectionManagementService); - if (!profile) { - const objectExplorerService = accessor.get(IObjectExplorerService); - const workbenchEditorService = accessor.get(IEditorService); - profile = TaskUtilities.getCurrentGlobalConnection(objectExplorerService, connectionManagementService, workbenchEditorService); - } - if (profile) { - const serverInfo = connectionManagementService.getServerInfo(profile.id); - if (serverInfo && serverInfo.isCloud && profile.providerName === mssqlProviderName) { - return accessor.get(INotificationService).info(nls.localize('restore.commandNotSupported', "Restore command is not supported for Azure SQL databases.")); - } - } - - TaskUtilities.showRestore( - profile, - accessor.get(IRestoreDialogController) - ).then(); - } -} - export class ManageAction extends Action { public static ID = 'manage'; public static LABEL = nls.localize('manage', "Manage"); diff --git a/src/sql/workbench/parts/backup/browser/backup.contribution.ts b/src/sql/workbench/parts/backup/browser/backup.contribution.ts new file mode 100644 index 0000000000..a037fcf8df --- /dev/null +++ b/src/sql/workbench/parts/backup/browser/backup.contribution.ts @@ -0,0 +1,80 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; +import { ConnectedContext } from 'azdata'; +import { TreeViewItemHandleArg } from 'sql/workbench/common/views'; +import { BackupAction } from 'sql/workbench/parts/backup/browser/backupActions'; +import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; +import { ManageActionContext } from 'sql/workbench/common/actions'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { ItemContextKey } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext'; +import { MssqlNodeContext } from 'sql/workbench/parts/dataExplorer/common/mssqlNodeContext'; +import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; +import { mssqlProviderName } from 'sql/platform/connection/common/constants'; +import { localize } from 'vs/nls'; +import { ObjectExplorerActionsContext } from 'sql/workbench/parts/objectExplorer/browser/objectExplorerActions'; +import { TreeNodeContextKey } from 'sql/workbench/parts/objectExplorer/common/treeNodeContextKey'; +import { ConnectionContextKey } from 'sql/workbench/parts/connection/common/connectionContextKey'; +import { ServerInfoContextKey } from 'sql/workbench/parts/connection/common/serverInfoContextKey'; + +new BackupAction().registerTask(); + +// data explorer +const DE_BACKUP_COMMAND_ID = 'dataExplorer.backup'; +CommandsRegistry.registerCommand({ + id: DE_BACKUP_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + return commandService.executeCommand(BackupAction.ID, args.$treeItem.payload); + } +}); + +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 4, + command: { + id: DE_BACKUP_COMMAND_ID, + title: localize('backup', "Backup") + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), MssqlNodeContext.IsCloud.toNegated()) +}); + +// oe +const OE_BACKUP_COMMAND_ID = 'objectExplorer.backup'; +CommandsRegistry.registerCommand({ + id: OE_BACKUP_COMMAND_ID, + handler: (accessor, args: ObjectExplorerActionsContext) => { + const commandService = accessor.get(ICommandService); + return commandService.executeCommand(BackupAction.ID, args.connectionProfile); + } +}); + +MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { + group: 'connection', + order: 4, + command: { + id: OE_BACKUP_COMMAND_ID, + title: localize('backup', "Backup") + }, + when: ContextKeyExpr.and(TreeNodeContextKey.NodeType.isEqualTo(NodeType.Database), ConnectionContextKey.Provider.isEqualTo(mssqlProviderName), ServerInfoContextKey.IsCloud.toNegated()) +}); + +// dashboard explorer +const ExplorerBackUpActionID = 'explorer.backup'; +CommandsRegistry.registerCommand(ExplorerBackUpActionID, (accessor, context: ManageActionContext) => { + const commandService = accessor.get(ICommandService); + return commandService.executeCommand(BackupAction.ID, context.profile); +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerBackUpActionID, + title: BackupAction.LABEL + }, + when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('database'), ItemContextKey.ConnectionProvider.isEqualTo('mssql'), ItemContextKey.IsCloud.toNegated()), + order: 2 +}); diff --git a/src/sql/workbench/parts/backup/browser/backupActions.ts b/src/sql/workbench/parts/backup/browser/backupActions.ts new file mode 100644 index 0000000000..d347593068 --- /dev/null +++ b/src/sql/workbench/parts/backup/browser/backupActions.ts @@ -0,0 +1,70 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { localize } from 'vs/nls'; +import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; +import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { getCurrentGlobalConnection } from 'sql/workbench/browser/taskUtilities'; +import { mssqlProviderName } from 'sql/platform/connection/common/constants'; +import { IBackupUiService } from 'sql/workbench/services/backup/common/backupUiService'; +import { Task } from 'sql/platform/tasks/browser/tasksRegistry'; +import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; +import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; + +export const BackupFeatureName = 'backup'; + +export function showBackup(accessor: ServicesAccessor, connection: IConnectionProfile): Promise { + const backupUiService = accessor.get(IBackupUiService); + return backupUiService.showBackup(connection).then(); +} + +export class BackupAction extends Task { + public static readonly ID = BackupFeatureName; + public static readonly LABEL = localize('backupAction.backup', "Backup"); + public static readonly ICON = BackupFeatureName; + + constructor() { + super({ + id: BackupAction.ID, + title: BackupAction.LABEL, + iconPath: undefined, + iconClass: BackupAction.ICON + }); + } + + runTask(accessor: ServicesAccessor, profile: IConnectionProfile): void | Promise { + const configurationService = accessor.get(IConfigurationService); + const previewFeaturesEnabled: boolean = configurationService.getValue('workbench')['enablePreviewFeatures']; + if (!previewFeaturesEnabled) { + return accessor.get(INotificationService).info(localize('backup.isPreviewFeature', "You must enable preview features in order to use backup")); + } + + const connectionManagementService = accessor.get(IConnectionManagementService); + if (!profile) { + const objectExplorerService = accessor.get(IObjectExplorerService); + const workbenchEditorService = accessor.get(IEditorService); + profile = getCurrentGlobalConnection(objectExplorerService, connectionManagementService, workbenchEditorService); + } + if (profile) { + const serverInfo = connectionManagementService.getServerInfo(profile.id); + if (serverInfo && serverInfo.isCloud && profile.providerName === mssqlProviderName) { + return accessor.get(INotificationService).info(localize('backup.commandNotSupported', "Backup command is not supported for Azure SQL databases.")); + } + + if (!profile.databaseName && profile.providerName === mssqlProviderName) { + return accessor.get(INotificationService).info(localize('backup.commandNotSupportedForServer', "Backup command is not supported in Server Context. Please select a Database and try again.")); + } + } + + const capabilitiesService = accessor.get(ICapabilitiesService); + const instantiationService = accessor.get(IInstantiationService); + return instantiationService.invokeFunction(showBackup, new ConnectionProfile(capabilitiesService, profile)); + } +} diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.common.contribution.ts b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.common.contribution.ts index c265e66208..0a5e43f7eb 100644 --- a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.common.contribution.ts +++ b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.common.contribution.ts @@ -6,14 +6,10 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { registerDashboardWidget } from 'sql/platform/dashboard/browser/widgetRegistry'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; -import { ExplorerManageAction, CustomExecuteCommandAction } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeActions'; +import { ExplorerManageAction } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeActions'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ItemContextKey } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext'; -import { BackupAction, RestoreAction } from 'sql/workbench/common/actions'; -import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { NewNotebookAction } from 'sql/workbench/parts/notebook/browser/notebookActions'; -import { NewQueryTask } from 'sql/workbench/parts/query/browser/queryActions'; const explorerSchema: IJSONSchema = { type: 'object', @@ -26,30 +22,6 @@ CommandsRegistry.registerCommand(ExplorerManageAction.ID, (accessor, context) => instantiationService.createInstance(ExplorerManageAction, ExplorerManageAction.ID, ExplorerManageAction.LABEL).run(context); }); -const ExplorerBackUpActionID = 'explorer.backup'; -CommandsRegistry.registerCommand(ExplorerBackUpActionID, (accessor, context) => { - const instantiationService = accessor.get(IInstantiationService); - instantiationService.createInstance(CustomExecuteCommandAction, BackupAction.ID, BackupAction.LABEL).run(context); -}); - -const ExplorerRestoreActionID = 'explorer.restore'; -CommandsRegistry.registerCommand(ExplorerRestoreActionID, (accessor, context) => { - const instantiationService = accessor.get(IInstantiationService); - instantiationService.createInstance(CustomExecuteCommandAction, RestoreAction.ID, RestoreAction.LABEL).run(context); -}); - -const ExplorerNewQueryActionID = 'explorer.query'; -CommandsRegistry.registerCommand(ExplorerNewQueryActionID, (accessor, context) => { - const instantiationService = accessor.get(IInstantiationService); - instantiationService.createInstance(CustomExecuteCommandAction, NewQueryTask.ID, NewQueryTask.LABEL).run(context); -}); - -const ExplorerNotebookActionID = 'explorer.notebook'; -CommandsRegistry.registerCommand(ExplorerNotebookActionID, (accessor, context) => { - const instantiationService = accessor.get(IInstantiationService); - instantiationService.createInstance(CustomExecuteCommandAction, NewNotebookAction.ID, NewNotebookAction.LABEL).run(context); -}); - MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { command: { id: ExplorerManageAction.ID, @@ -58,39 +30,3 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { when: ItemContextKey.ItemType.isEqualTo('database'), order: 1 }); - -MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { - command: { - id: ExplorerNewQueryActionID, - title: NewQueryTask.LABEL - }, - when: ItemContextKey.ItemType.isEqualTo('database'), - order: 1 -}); - -MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { - command: { - id: ExplorerNotebookActionID, - title: NewNotebookAction.LABEL - }, - when: ItemContextKey.ItemType.isEqualTo('database'), - order: 1 -}); - -MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { - command: { - id: ExplorerRestoreActionID, - title: RestoreAction.LABEL - }, - when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('database'), ItemContextKey.ConnectionProvider.isEqualTo('mssql'), ItemContextKey.IsCloud.toNegated()), - order: 2 -}); - -MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { - command: { - id: ExplorerBackUpActionID, - title: BackupAction.LABEL - }, - when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('database'), ItemContextKey.ConnectionProvider.isEqualTo('mssql'), ItemContextKey.IsCloud.toNegated()), - order: 2 -}); diff --git a/src/sql/workbench/parts/dataExplorer/common/extensionActions.ts b/src/sql/workbench/parts/dataExplorer/common/extensionActions.ts new file mode 100644 index 0000000000..6f7836f413 --- /dev/null +++ b/src/sql/workbench/parts/dataExplorer/common/extensionActions.ts @@ -0,0 +1,100 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; +import { TreeViewItemHandleArg } from 'sql/workbench/common/views'; +import * as azdata from 'azdata'; +import { IOEShimService } from 'sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim'; +import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; +import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; +import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; + +export const DATA_TIER_WIZARD_COMMAND_ID = 'dataExplorer.dataTierWizard'; +export const PROFILER_COMMAND_ID = 'dataExplorer.profiler'; +export const IMPORT_COMMAND_ID = 'dataExplorer.flatFileImport'; +export const SCHEMA_COMPARE_COMMAND_ID = 'dataExplorer.schemaCompare'; +export const GENERATE_SCRIPTS_COMMAND_ID = 'dataExplorer.generateScripts'; +export const PROPERTIES_COMMAND_ID = 'dataExplorer.properties'; + + +// Data Tier Wizard +CommandsRegistry.registerCommand({ + id: DATA_TIER_WIZARD_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + const connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; + return commandService.executeCommand('dacFx.start', connectedContext); + } +}); + + +// Flat File Import +CommandsRegistry.registerCommand({ + id: IMPORT_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; + return commandService.executeCommand('flatFileImport.start', connectedContext); + } +}); + +// Schema Compare +CommandsRegistry.registerCommand({ + id: SCHEMA_COMPARE_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; + return commandService.executeCommand('schemaCompare.start', connectedContext); + } +}); + +// Profiler +CommandsRegistry.registerCommand({ + id: PROFILER_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + const oeShimService = accessor.get(IOEShimService); + const objectExplorerContext: azdata.ObjectExplorerContext = { + connectionProfile: args.$treeItem.payload, + isConnectionNode: true, + nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem) + }; + return commandService.executeCommand('profiler.newProfiler', objectExplorerContext); + } +}); + +// Generate Scripts +CommandsRegistry.registerCommand({ + id: GENERATE_SCRIPTS_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + const oeShimService = accessor.get(IOEShimService); + const objectExplorerContext: azdata.ObjectExplorerContext = { + connectionProfile: args.$treeItem.payload, + isConnectionNode: true, + nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem) + }; + return commandService.executeCommand('adminToolExtWin.launchSsmsMinGswDialog', objectExplorerContext); + } +}); + +// Properties +CommandsRegistry.registerCommand({ + id: PROPERTIES_COMMAND_ID, + handler: async (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + const capabilitiesService = accessor.get(ICapabilitiesService); + const connectionManagementService = accessor.get(IConnectionManagementService); + const oeShimService = accessor.get(IOEShimService); + const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); + await connectionManagementService.connectIfNotConnected(profile); + const objectExplorerContext: azdata.ObjectExplorerContext = { + connectionProfile: args.$treeItem.payload, + isConnectionNode: true, + nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem) + }; + return commandService.executeCommand('adminToolExtWin.launchSsmsMinPropertiesDialog', objectExplorerContext); + } +}); diff --git a/src/sql/workbench/parts/dataExplorer/common/extensions.contribution.ts b/src/sql/workbench/parts/dataExplorer/common/extensions.contribution.ts new file mode 100644 index 0000000000..b39e4b86e3 --- /dev/null +++ b/src/sql/workbench/parts/dataExplorer/common/extensions.contribution.ts @@ -0,0 +1,111 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; +import { DATA_TIER_WIZARD_COMMAND_ID, PROFILER_COMMAND_ID, IMPORT_COMMAND_ID, SCHEMA_COMPARE_COMMAND_ID, GENERATE_SCRIPTS_COMMAND_ID, PROPERTIES_COMMAND_ID } from 'sql/workbench/parts/dataExplorer/common/extensionActions'; +import { ContextKeyExpr, ContextKeyRegexExpr } from 'vs/platform/contextkey/common/contextkey'; +import { MssqlNodeContext } from 'sql/workbench/parts/dataExplorer/common/mssqlNodeContext'; +import { mssqlProviderName } from 'sql/platform/connection/common/constants'; +import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; +import { localize } from 'vs/nls'; + +// Data-Tier Application Wizard +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'export', + order: 7, + command: { + id: DATA_TIER_WIZARD_COMMAND_ID, + title: localize('dacFx', "Data-tier Application Wizard") + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.IsDatabaseOrServer) +}); + + +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'export', + order: 7, + command: { + id: DATA_TIER_WIZARD_COMMAND_ID, + title: localize('dacFx', "Data-tier Application Wizard") + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Folder), + MssqlNodeContext.NodeLabel.isEqualTo('Databases')) +}); + +// Profiler +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'profiler', + order: 8, + command: { + id: PROFILER_COMMAND_ID, + title: localize('profiler', "Launch Profiler") + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Server)) +}); + +// Flat File Import +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'import', + order: 10, + command: { + id: IMPORT_COMMAND_ID, + title: localize('flatFileImport', "Import Wizard") + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) +}); + +// Schema Compare +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'export', + order: 9, + command: { + id: SCHEMA_COMPARE_COMMAND_ID, + title: localize('schemaCompare', "Schema Compare") + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) +}); + +// Generate Scripts Action +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'z-AdminToolExt@1', + order: 11, + command: { + id: GENERATE_SCRIPTS_COMMAND_ID, + title: localize('generateScripts', "Generate Scripts...") + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), + MssqlNodeContext.IsWindows) +}); + +// Properties Action +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'z-AdminToolExt@2', + order: 12, + command: { + id: PROPERTIES_COMMAND_ID, + title: localize('properties', "Properties") + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Server), ContextKeyExpr.not('isCloud'), + MssqlNodeContext.IsWindows) +}); + +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'z-AdminToolExt@2', + order: 12, + command: { + id: PROPERTIES_COMMAND_ID, + title: localize('properties', "Properties") + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.IsWindows, + ContextKeyRegexExpr.create('nodeType', /^(Database|Table|Column|Index|Statistic|View|ServerLevelLogin|ServerLevelServerRole|ServerLevelCredential|ServerLevelServerAudit|ServerLevelServerAuditSpecification|StoredProcedure|ScalarValuedFunction|TableValuedFunction|AggregateFunction|Synonym|Assembly|UserDefinedDataType|UserDefinedType|UserDefinedTableType|Sequence|User|DatabaseRole|ApplicationRole|Schema|SecurityPolicy|ServerLevelLinkedServer)$/)) +}); diff --git a/src/sql/workbench/parts/dataExplorer/common/nodeActions.common.contribution.ts b/src/sql/workbench/parts/dataExplorer/common/nodeActions.common.contribution.ts index 65b6436be4..d203555eb5 100644 --- a/src/sql/workbench/parts/dataExplorer/common/nodeActions.common.contribution.ts +++ b/src/sql/workbench/parts/dataExplorer/common/nodeActions.common.contribution.ts @@ -7,11 +7,9 @@ import { localize } from 'vs/nls'; import { mssqlProviderName } from 'sql/platform/connection/common/constants'; import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { - DISCONNECT_COMMAND_ID, MANAGE_COMMAND_ID, REFRESH_COMMAND_ID, - NEW_NOTEBOOK_COMMAND_ID, SCHEMA_COMPARE_COMMAND_ID, DATA_TIER_WIZARD_COMMAND_ID, - IMPORT_COMMAND_ID, BACKUP_COMMAND_ID, RESTORE_COMMAND_ID, PROFILER_COMMAND_ID, GENERATE_SCRIPTS_COMMAND_ID, PROPERTIES_COMMAND_ID + DISCONNECT_COMMAND_ID, REFRESH_COMMAND_ID } from './nodeCommands.common'; -import { ContextKeyExpr, ContextKeyRegexExpr, ContextKeyNotEqualsExpr } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr, ContextKeyNotEqualsExpr } from 'vs/platform/contextkey/common/contextkey'; import { NodeContextKey } from 'sql/workbench/parts/dataExplorer/common/nodeContext'; import { MssqlNodeContext } from 'sql/workbench/parts/dataExplorer/common/mssqlNodeContext'; import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; @@ -51,140 +49,3 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { }, when: NodeContextKey.IsConnectable }); - - -// New Notebook -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'connection', - order: 3, - command: { - id: NEW_NOTEBOOK_COMMAND_ID, - title: localize('newNotebook', "New Notebook") - }, - when: ContextKeyExpr.and(NodeContextKey.IsConnectable, - MssqlNodeContext.IsDatabaseOrServer, - MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName)) -}); - -// Data-Tier Application Wizard -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'export', - order: 7, - command: { - id: DATA_TIER_WIZARD_COMMAND_ID, - title: localize('dacFx', "Data-tier Application Wizard") - }, - when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.IsDatabaseOrServer) -}); - - -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'export', - order: 7, - command: { - id: DATA_TIER_WIZARD_COMMAND_ID, - title: localize('dacFx', "Data-tier Application Wizard") - }, - when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Folder), - MssqlNodeContext.NodeLabel.isEqualTo('Databases')) -}); - -// Profiler -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'profiler', - order: 8, - command: { - id: PROFILER_COMMAND_ID, - title: localize('profiler', "Launch Profiler") - }, - when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Server)) -}); - -// Flat File Import -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'import', - order: 10, - command: { - id: IMPORT_COMMAND_ID, - title: localize('flatFileImport', "Import Wizard") - }, - when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) -}); - -// Schema Compare -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'export', - order: 9, - command: { - id: SCHEMA_COMPARE_COMMAND_ID, - title: localize('schemaCompare', "Schema Compare") - }, - when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) -}); - -// Backup Action -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'connection', - order: 4, - command: { - id: BACKUP_COMMAND_ID, - title: localize('backup', "Backup") - }, - when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) -}); - -// Restore Action -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'connection', - order: 5, - command: { - id: RESTORE_COMMAND_ID, - title: localize('restore', "Restore") - }, - when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) -}); - -// Generate Scripts Action -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'z-AdminToolExt@1', - order: 11, - command: { - id: GENERATE_SCRIPTS_COMMAND_ID, - title: localize('generateScripts', "Generate Scripts...") - }, - when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), - MssqlNodeContext.IsWindows) -}); - -// Properties Action -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'z-AdminToolExt@2', - order: 12, - command: { - id: PROPERTIES_COMMAND_ID, - title: localize('properties', "Properties") - }, - when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Server), ContextKeyExpr.not('isCloud'), - MssqlNodeContext.IsWindows) -}); - -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'z-AdminToolExt@2', - order: 12, - command: { - id: PROPERTIES_COMMAND_ID, - title: localize('properties', "Properties") - }, - when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.IsWindows, - ContextKeyRegexExpr.create('nodeType', /^(Database|Table|Column|Index|Statistic|View|ServerLevelLogin|ServerLevelServerRole|ServerLevelCredential|ServerLevelServerAudit|ServerLevelServerAuditSpecification|StoredProcedure|ScalarValuedFunction|TableValuedFunction|AggregateFunction|Synonym|Assembly|UserDefinedDataType|UserDefinedType|UserDefinedTableType|Sequence|User|DatabaseRole|ApplicationRole|Schema|SecurityPolicy|ServerLevelLinkedServer)$/)) -}); diff --git a/src/sql/workbench/parts/dataExplorer/common/nodeCommands.common.ts b/src/sql/workbench/parts/dataExplorer/common/nodeCommands.common.ts index 6841535f89..5dc00b1a56 100644 --- a/src/sql/workbench/parts/dataExplorer/common/nodeCommands.common.ts +++ b/src/sql/workbench/parts/dataExplorer/common/nodeCommands.common.ts @@ -3,34 +3,15 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as azdata from 'azdata'; import { IOEShimService } from 'sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim'; -import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; -import { ConnectionType, IConnectableInput, IConnectionCompletionOptions, IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; -import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; -import { generateUri } from 'sql/platform/connection/common/utils'; import { ICustomViewDescriptor, TreeViewItemHandleArg } from 'sql/workbench/common/views'; -import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; -import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IViewsRegistry, Extensions } from 'vs/workbench/common/views'; import { IProgressService } from 'vs/platform/progress/common/progress'; import { Registry } from 'vs/platform/registry/common/platform'; -import { BackupAction, RestoreAction } from 'sql/workbench/common/actions'; -import { NewNotebookAction } from 'sql/workbench/parts/notebook/browser/notebookActions'; export const DISCONNECT_COMMAND_ID = 'dataExplorer.disconnect'; -export const MANAGE_COMMAND_ID = 'dataExplorer.manage'; -export const NEW_QUERY_COMMAND_ID = 'dataExplorer.newQuery'; export const REFRESH_COMMAND_ID = 'dataExplorer.refresh'; -export const NEW_NOTEBOOK_COMMAND_ID = 'dataExplorer.newNotebook'; -export const DATA_TIER_WIZARD_COMMAND_ID = 'dataExplorer.dataTierWizard'; -export const PROFILER_COMMAND_ID = 'dataExplorer.profiler'; -export const IMPORT_COMMAND_ID = 'dataExplorer.flatFileImport'; -export const SCHEMA_COMPARE_COMMAND_ID = 'dataExplorer.schemaCompare'; -export const BACKUP_COMMAND_ID = 'dataExplorer.backup'; -export const RESTORE_COMMAND_ID = 'dataExplorer.restore'; -export const GENERATE_SCRIPTS_COMMAND_ID = 'dataExplorer.generateScripts'; -export const PROPERTIES_COMMAND_ID = 'dataExplorer.properties'; // Disconnect CommandsRegistry.registerCommand({ @@ -49,52 +30,6 @@ CommandsRegistry.registerCommand({ } }); -// New Query -CommandsRegistry.registerCommand({ - id: NEW_QUERY_COMMAND_ID, - handler: (accessor, args: TreeViewItemHandleArg) => { - if (args.$treeItem) { - const queryEditorService = accessor.get(IQueryEditorService); - const connectionService = accessor.get(IConnectionManagementService); - const capabilitiesService = accessor.get(ICapabilitiesService); - return queryEditorService.newSqlEditor().then((owner: IConnectableInput) => { - // Connect our editor to the input connection - let options: IConnectionCompletionOptions = { - params: { connectionType: ConnectionType.editor, input: owner }, - saveTheConnection: false, - showDashboard: false, - showConnectionDialogOnError: true, - showFirewallRuleOnError: true - }; - return connectionService.connect(new ConnectionProfile(capabilitiesService, args.$treeItem.payload), owner.uri, options); - }); - } - return Promise.resolve(true); - } -}); - -// Manage -CommandsRegistry.registerCommand({ - id: MANAGE_COMMAND_ID, - handler: (accessor, args: TreeViewItemHandleArg) => { - if (args.$treeItem) { - const connectionService = accessor.get(IConnectionManagementService); - const capabilitiesService = accessor.get(ICapabilitiesService); - let options = { - showDashboard: true, - saveTheConnection: false, - params: undefined, - showConnectionDialogOnError: true, - showFirewallRuleOnError: true - }; - let profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); - let uri = generateUri(profile, 'dashboard'); - return connectionService.connect(new ConnectionProfile(capabilitiesService, args.$treeItem.payload), uri, options); - } - return Promise.resolve(true); - } -}); - // Refresh CommandsRegistry.registerCommand({ id: REFRESH_COMMAND_ID, @@ -112,115 +47,3 @@ CommandsRegistry.registerCommand({ return Promise.resolve(true); } }); - -// New Notebook -CommandsRegistry.registerCommand({ - id: NEW_NOTEBOOK_COMMAND_ID, - handler: (accessor, args: TreeViewItemHandleArg) => { - const capabilitiesService = accessor.get(ICapabilitiesService); - const commandService = accessor.get(ICommandService); - let profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); - const connectedContext: azdata.ConnectedContext = { connectionProfile: profile }; - return commandService.executeCommand(NewNotebookAction.ID, connectedContext); - } -}); - -// Data Tier Wizard -CommandsRegistry.registerCommand({ - id: DATA_TIER_WIZARD_COMMAND_ID, - handler: (accessor, args: TreeViewItemHandleArg) => { - const commandService = accessor.get(ICommandService); - const connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; - return commandService.executeCommand('dacFx.start', connectedContext); - } -}); - - -// Flat File Import -CommandsRegistry.registerCommand({ - id: IMPORT_COMMAND_ID, - handler: (accessor, args: TreeViewItemHandleArg) => { - const commandService = accessor.get(ICommandService); - let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; - return commandService.executeCommand('flatFileImport.start', connectedContext); - } -}); - -// Schema Compare -CommandsRegistry.registerCommand({ - id: SCHEMA_COMPARE_COMMAND_ID, - handler: (accessor, args: TreeViewItemHandleArg) => { - const commandService = accessor.get(ICommandService); - let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; - return commandService.executeCommand('schemaCompare.start', connectedContext); - } -}); - -// Backup -CommandsRegistry.registerCommand({ - id: BACKUP_COMMAND_ID, - handler: (accessor, args: TreeViewItemHandleArg) => { - const commandService = accessor.get(ICommandService); - let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; - return commandService.executeCommand(BackupAction.ID, connectedContext); - } -}); - -// Restore -CommandsRegistry.registerCommand({ - id: RESTORE_COMMAND_ID, - handler: (accessor, args: TreeViewItemHandleArg) => { - const commandService = accessor.get(ICommandService); - let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; - return commandService.executeCommand(RestoreAction.ID, connectedContext); - } -}); - -// Profiler -CommandsRegistry.registerCommand({ - id: PROFILER_COMMAND_ID, - handler: (accessor, args: TreeViewItemHandleArg) => { - const commandService = accessor.get(ICommandService); - const oeShimService = accessor.get(IOEShimService); - const objectExplorerContext: azdata.ObjectExplorerContext = { - connectionProfile: args.$treeItem.payload, - isConnectionNode: true, - nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem) - }; - return commandService.executeCommand('profiler.newProfiler', objectExplorerContext); - } -}); - -// Generate Scripts -CommandsRegistry.registerCommand({ - id: GENERATE_SCRIPTS_COMMAND_ID, - handler: (accessor, args: TreeViewItemHandleArg) => { - const commandService = accessor.get(ICommandService); - const oeShimService = accessor.get(IOEShimService); - const objectExplorerContext: azdata.ObjectExplorerContext = { - connectionProfile: args.$treeItem.payload, - isConnectionNode: true, - nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem) - }; - return commandService.executeCommand('adminToolExtWin.launchSsmsMinGswDialog', objectExplorerContext); - } -}); - -// Properties -CommandsRegistry.registerCommand({ - id: PROPERTIES_COMMAND_ID, - handler: async (accessor, args: TreeViewItemHandleArg) => { - const commandService = accessor.get(ICommandService); - const capabilitiesService = accessor.get(ICapabilitiesService); - const connectionManagementService = accessor.get(IConnectionManagementService); - const oeShimService = accessor.get(IOEShimService); - const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); - await connectionManagementService.connectIfNotConnected(profile); - const objectExplorerContext: azdata.ObjectExplorerContext = { - connectionProfile: args.$treeItem.payload, - isConnectionNode: true, - nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem) - }; - return commandService.executeCommand('adminToolExtWin.launchSsmsMinPropertiesDialog', objectExplorerContext); - } -}); diff --git a/src/sql/workbench/parts/notebook/browser/notebook.common.contribution.ts b/src/sql/workbench/parts/notebook/browser/notebook.common.contribution.ts index ebd12544ef..4e9aaa2748 100644 --- a/src/sql/workbench/parts/notebook/browser/notebook.common.contribution.ts +++ b/src/sql/workbench/parts/notebook/browser/notebook.common.contribution.ts @@ -6,7 +6,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { EditorDescriptor, IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; -import { SyncActionDescriptor, registerAction } from 'vs/platform/actions/common/actions'; +import { SyncActionDescriptor, registerAction, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { NotebookInput } from 'sql/workbench/parts/notebook/browser/models/notebookInput'; import { NotebookEditor } from 'sql/workbench/parts/notebook/browser/notebookEditor'; @@ -23,6 +23,18 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { URI } from 'vs/base/common/uri'; import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; import { IWindowService } from 'vs/platform/windows/common/windows'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { NodeContextKey } from 'sql/workbench/parts/dataExplorer/common/nodeContext'; +import { MssqlNodeContext } from 'sql/workbench/parts/dataExplorer/common/mssqlNodeContext'; +import { mssqlProviderName } from 'sql/platform/connection/common/constants'; +import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; +import { TreeViewItemHandleArg } from 'sql/workbench/common/views'; +import { ConnectedContext } from 'azdata'; +import { TreeNodeContextKey } from 'sql/workbench/parts/objectExplorer/common/treeNodeContextKey'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ObjectExplorerActionsContext } from 'sql/workbench/parts/objectExplorer/browser/objectExplorerActions'; +import { ItemContextKey } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext'; +import { ManageActionContext } from 'sql/workbench/common/actions'; // Model View editor registration const viewModelEditorDescriptor = new EditorDescriptor( @@ -48,6 +60,67 @@ actionRegistry.registerWorkbenchAction( NewNotebookAction.LABEL ); +const DE_NEW_NOTEBOOK_COMMAND_ID = 'dataExplorer.newNotebook'; +// New Notebook +CommandsRegistry.registerCommand({ + id: DE_NEW_NOTEBOOK_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const instantiationService = accessor.get(IInstantiationService); + const connectedContext: ConnectedContext = { connectionProfile: args.$treeItem.payload }; + return instantiationService.createInstance(NewNotebookAction, NewNotebookAction.ID, NewNotebookAction.LABEL).run(connectedContext); + } +}); + +// New Notebook +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: '0_query', + order: 3, + command: { + id: DE_NEW_NOTEBOOK_COMMAND_ID, + title: localize('newNotebook', "New Notebook") + }, + when: ContextKeyExpr.and(NodeContextKey.IsConnectable, + MssqlNodeContext.IsDatabaseOrServer, + MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName)) +}); + +const OE_NEW_NOTEBOOK_COMMAND_ID = 'objectExplorer.newNotebook'; +// New Notebook +CommandsRegistry.registerCommand({ + id: OE_NEW_NOTEBOOK_COMMAND_ID, + handler: (accessor, args: ObjectExplorerActionsContext) => { + const instantiationService = accessor.get(IInstantiationService); + const connectedContext: ConnectedContext = { connectionProfile: args.connectionProfile }; + return instantiationService.createInstance(NewNotebookAction, NewNotebookAction.ID, NewNotebookAction.LABEL).run(connectedContext); + } +}); + +MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { + group: '0_query', + order: 3, + command: { + id: OE_NEW_NOTEBOOK_COMMAND_ID, + title: localize('newQuery', "New Notebook") + }, + when: ContextKeyExpr.or(ContextKeyExpr.and(TreeNodeContextKey.Status.notEqualsTo('Unavailable'), TreeNodeContextKey.NodeType.isEqualTo('Server')), ContextKeyExpr.and(TreeNodeContextKey.Status.notEqualsTo('Unavailable'), TreeNodeContextKey.NodeType.isEqualTo('Database'))) +}); + +const ExplorerNotebookActionID = 'explorer.notebook'; +CommandsRegistry.registerCommand(ExplorerNotebookActionID, (accessor, context: ManageActionContext) => { + const instantiationService = accessor.get(IInstantiationService); + const connectedContext: ConnectedContext = { connectionProfile: context.profile }; + instantiationService.createInstance(NewNotebookAction, NewNotebookAction.ID, NewNotebookAction.LABEL).run(connectedContext); +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerNotebookActionID, + title: NewNotebookAction.LABEL + }, + when: ItemContextKey.ItemType.isEqualTo('database'), + order: 1 +}); + registerAction({ id: 'workbench.action.setWorkspaceAndOpen', handler: async (accessor, options: { forceNewWindow: boolean, folderPath: URI }) => { diff --git a/src/sql/workbench/parts/objectExplorer/browser/serverTreeActionProvider.ts b/src/sql/workbench/parts/objectExplorer/browser/serverTreeActionProvider.ts index 78204e1714..ada3fea78b 100644 --- a/src/sql/workbench/parts/objectExplorer/browser/serverTreeActionProvider.ts +++ b/src/sql/workbench/parts/objectExplorer/browser/serverTreeActionProvider.ts @@ -13,9 +13,6 @@ import { DisconnectConnectionAction, AddServerAction, DeleteConnectionAction, RefreshAction, EditServerGroupAction } from 'sql/workbench/parts/objectExplorer/browser/connectionTreeAction'; -import { - OEAction -} from 'sql/workbench/parts/objectExplorer/browser/objectExplorerActions'; import { TreeNode } from 'sql/workbench/parts/objectExplorer/common/treeNode'; import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; import { ConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup'; @@ -23,13 +20,11 @@ import { ConnectionProfile } from 'sql/platform/connection/common/connectionProf import { TreeUpdateUtils } from 'sql/workbench/parts/objectExplorer/browser/treeUpdateUtils'; import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { MenuId, IMenuService } from 'vs/platform/actions/common/actions'; -import { BackupAction, RestoreAction } from 'sql/workbench/common/actions'; import { ConnectionContextKey } from 'sql/workbench/parts/connection/common/connectionContextKey'; import { TreeNodeContextKey } from 'sql/workbench/parts/objectExplorer/common/treeNodeContextKey'; import { IQueryManagementService } from 'sql/platform/query/common/queryManagement'; import { ServerInfoContextKey } from 'sql/workbench/parts/connection/common/serverInfoContextKey'; import { fillInActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; -import { NewNotebookAction } from 'sql/workbench/parts/notebook/browser/notebookActions'; /** * Provides actions for the server tree elements @@ -107,7 +102,6 @@ export class ServerTreeActionProvider extends ContributableActionProvider { private getBuiltinConnectionActions(context: ObjectExplorerContext): IAction[] { let actions: IAction[] = []; - this.addNewQueryNotebookActions(context, actions); if (this._connectionManagementService.isProfileConnected(context.profile)) { actions.push(this._instantiationService.createInstance(DisconnectConnectionAction, DisconnectConnectionAction.ID, DisconnectConnectionAction.LABEL, context.profile)); @@ -159,24 +153,13 @@ export class ServerTreeActionProvider extends ContributableActionProvider { 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; - this.addNewQueryNotebookActions(context, actions); } else { return actions; } } - let serverInfo = this._connectionManagementService.getServerInfo(context.profile.id); - let isCloud = serverInfo && serverInfo.isCloud; - - if (isAvailableDatabaseNode && !isCloud) { - this.addBackupAction(context, actions); - this.addRestoreAction(context, actions); - } - // 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)); @@ -185,26 +168,6 @@ export class ServerTreeActionProvider extends ContributableActionProvider { return actions; } - private addNewQueryNotebookActions(context: ObjectExplorerContext, actions: IAction[]): void { - if (this._queryManagementService.isProviderRegistered(context.profile.providerName)) { - // Workaround for #6397 right-click and run New Notebook connects to wrong server. Use notebook action instead of generic command action - let notebookAction = this._instantiationService.createInstance(NewNotebookAction, NewNotebookAction.ID, NewNotebookAction.LABEL); - actions.push(notebookAction); - } - } - - 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 isScriptableObject(context: ObjectExplorerContext): boolean { if (context.treeNode) { if (NodeType.SCRIPTABLE_OBJECTS.includes(context.treeNode.nodeTypeId)) { diff --git a/src/sql/workbench/parts/query/browser/query.contribution.ts b/src/sql/workbench/parts/query/browser/query.contribution.ts index 8a921f1224..a845fa0df4 100644 --- a/src/sql/workbench/parts/query/browser/query.contribution.ts +++ b/src/sql/workbench/parts/query/browser/query.contribution.ts @@ -36,6 +36,9 @@ import { SqlFlavorStatusbarItem } from 'sql/workbench/parts/query/browser/flavor import { NewQueryTask, OE_NEW_QUERY_ACTION_ID, DE_NEW_QUERY_COMMAND_ID } from 'sql/workbench/parts/query/browser/queryActions'; import { TreeNodeContextKey } from 'sql/workbench/parts/objectExplorer/common/treeNodeContextKey'; import { MssqlNodeContext } from 'sql/workbench/parts/dataExplorer/common/mssqlNodeContext'; +import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; +import { ManageActionContext } from 'sql/workbench/common/actions'; +import { ItemContextKey } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext'; const gridCommandsWeightBonus = 100; // give our commands a little bit more weight over other default list/tree commands @@ -88,6 +91,21 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { when: MssqlNodeContext.IsDatabaseOrServer }); +const ExplorerNewQueryActionID = 'explorer.query'; +CommandsRegistry.registerCommand(ExplorerNewQueryActionID, (accessor, context: ManageActionContext) => { + const commandService = accessor.get(ICommandService); + return commandService.executeCommand(NewQueryTask.ID, context.profile); +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerNewQueryActionID, + title: NewQueryTask.LABEL + }, + when: ItemContextKey.ItemType.isEqualTo('database'), + order: 1 +}); + // Query Actions actionRegistry.registerWorkbenchAction( new SyncActionDescriptor( diff --git a/src/sql/workbench/parts/restore/browser/restore.contribution.ts b/src/sql/workbench/parts/restore/browser/restore.contribution.ts new file mode 100644 index 0000000000..db964135c8 --- /dev/null +++ b/src/sql/workbench/parts/restore/browser/restore.contribution.ts @@ -0,0 +1,79 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; +import { TreeViewItemHandleArg } from 'sql/workbench/common/views'; +import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; +import { localize } from 'vs/nls'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { MssqlNodeContext } from 'sql/workbench/parts/dataExplorer/common/mssqlNodeContext'; +import { mssqlProviderName } from 'sql/platform/connection/common/constants'; +import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; +import { RestoreAction } from 'sql/workbench/parts/restore/browser/restoreActions'; +import { TreeNodeContextKey } from 'sql/workbench/parts/objectExplorer/common/treeNodeContextKey'; +import { ObjectExplorerActionsContext } from 'sql/workbench/parts/objectExplorer/browser/objectExplorerActions'; +import { ConnectionContextKey } from 'sql/workbench/parts/connection/common/connectionContextKey'; +import { ManageActionContext } from 'sql/workbench/common/actions'; +import { ItemContextKey } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext'; +import { ServerInfoContextKey } from 'sql/workbench/parts/connection/common/serverInfoContextKey'; + +new RestoreAction().registerTask(); + +const DE_RESTORE_COMMAND_ID = 'dataExplorer.restore'; +// Restore +CommandsRegistry.registerCommand({ + id: DE_RESTORE_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + return commandService.executeCommand(RestoreAction.ID, args.$treeItem.payload); + } +}); + +// Restore Action +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 5, + command: { + id: DE_RESTORE_COMMAND_ID, + title: localize('restore', "Restore") + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), MssqlNodeContext.IsCloud.toNegated()) +}); + +// oe +const OE_RESTORE_COMMAND_ID = 'objectExplorer.restore'; +CommandsRegistry.registerCommand({ + id: OE_RESTORE_COMMAND_ID, + handler: (accessor, args: ObjectExplorerActionsContext) => { + const commandService = accessor.get(ICommandService); + return commandService.executeCommand(RestoreAction.ID, args.connectionProfile); + } +}); + +MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { + group: 'connection', + order: 4, + command: { + id: OE_RESTORE_COMMAND_ID, + title: localize('backup', "Restore") + }, + when: ContextKeyExpr.and(TreeNodeContextKey.NodeType.isEqualTo(NodeType.Database), ConnectionContextKey.Provider.isEqualTo(mssqlProviderName), ServerInfoContextKey.IsCloud.toNegated()) +}); + +const ExplorerRestoreActionID = 'explorer.restore'; +CommandsRegistry.registerCommand(ExplorerRestoreActionID, (accessor, context: ManageActionContext) => { + const commandService = accessor.get(ICommandService); + return commandService.executeCommand(RestoreAction.ID, context.profile); +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerRestoreActionID, + title: RestoreAction.LABEL + }, + when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('database'), ItemContextKey.ConnectionProvider.isEqualTo('mssql'), ItemContextKey.IsCloud.toNegated()), + order: 2 +}); diff --git a/src/sql/workbench/parts/restore/browser/restoreActions.ts b/src/sql/workbench/parts/restore/browser/restoreActions.ts new file mode 100644 index 0000000000..8dfb2ccd7b --- /dev/null +++ b/src/sql/workbench/parts/restore/browser/restoreActions.ts @@ -0,0 +1,66 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { getCurrentGlobalConnection } from 'sql/workbench/browser/taskUtilities'; +import { IRestoreDialogController } from 'sql/platform/restore/common/restoreService'; +import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; +import { Task } from 'sql/platform/tasks/browser/tasksRegistry'; +import { mssqlProviderName } from 'sql/platform/connection/common/constants'; +import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; +import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; + +export function showRestore(accessor: ServicesAccessor, connection: IConnectionProfile): Promise { + const restoreDialogService = accessor.get(IRestoreDialogController); + return restoreDialogService.showDialog(connection).then(); +} + +export const RestoreFeatureName = 'restore'; + +export class RestoreAction extends Task { + public static readonly ID = RestoreFeatureName; + public static readonly LABEL = localize('restoreAction.restore', "Restore"); + public static readonly ICON = RestoreFeatureName; + + constructor() { + super({ + id: RestoreAction.ID, + title: RestoreAction.LABEL, + iconPath: undefined, + iconClass: RestoreAction.ICON + }); + } + + runTask(accessor: ServicesAccessor, profile: IConnectionProfile): void | Promise { + const configurationService = accessor.get(IConfigurationService); + const previewFeaturesEnabled: boolean = configurationService.getValue('workbench')['enablePreviewFeatures']; + if (!previewFeaturesEnabled) { + return accessor.get(INotificationService).info(localize('restore.isPreviewFeature', "You must enable preview features in order to use restore")); + } + + let connectionManagementService = accessor.get(IConnectionManagementService); + if (!profile) { + const objectExplorerService = accessor.get(IObjectExplorerService); + const workbenchEditorService = accessor.get(IEditorService); + profile = getCurrentGlobalConnection(objectExplorerService, connectionManagementService, workbenchEditorService); + } + if (profile) { + const serverInfo = connectionManagementService.getServerInfo(profile.id); + if (serverInfo && serverInfo.isCloud && profile.providerName === mssqlProviderName) { + return accessor.get(INotificationService).info(localize('restore.commandNotSupported', "Restore command is not supported for Azure SQL databases.")); + } + } + + const capabilitiesService = accessor.get(ICapabilitiesService); + const instantiationService = accessor.get(IInstantiationService); + return instantiationService.invokeFunction(showRestore, new ConnectionProfile(capabilitiesService, profile)); + } +} diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 4f8fd6f58c..1def2a9181 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -284,6 +284,15 @@ import 'sql/workbench/parts/queryPlan/electron-browser/queryPlan.contribution'; //acounts import 'sql/workbench/parts/accounts/browser/accounts.contribution'; +//backup +import 'sql/workbench/parts/backup/browser/backup.contribution'; + +//extensions +import 'sql/workbench/parts/dataExplorer/common/extensions.contribution'; + +//restore +import 'sql/workbench/parts/restore/browser/restore.contribution'; + import 'sql/workbench/parts/profiler/browser/profiler.contribution'; import 'sql/workbench/parts/profiler/browser/profilerActions.contribution'; import 'sql/workbench/parts/objectExplorer/common/serverGroup.contribution';