diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index e0cb9c8719..4c2f1cb5dd 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -151,7 +151,7 @@ const copyrightFilter = [ '!src/sql/workbench/parts/notebook/common/models/nbformat.ts', '!extensions/markdown-language-features/media/tomorrow.css', '!src/sql/workbench/browser/modelComponents/media/highlight.css', - '!src/sql/parts/modelComponents/highlight.css', + '!src/sql/workbench/parts/notebook/electron-browser/cellViews/media/highlight.css', '!extensions/mssql/sqltoolsservice/**', '!extensions/import/flatfileimportservice/**', '!extensions/notebook/src/prompts/**', diff --git a/src/sql/platform/accounts/browser/accountDialog.ts b/src/sql/platform/accounts/browser/accountDialog.ts index 6cd03a4d6c..1ec472a70b 100644 --- a/src/sql/platform/accounts/browser/accountDialog.ts +++ b/src/sql/platform/accounts/browser/accountDialog.ts @@ -35,6 +35,7 @@ import { IClipboardService } from 'sql/platform/clipboard/common/clipboardServic import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; class AccountPanel extends ViewletPanel { public index: number; @@ -124,7 +125,8 @@ export class AccountDialog extends Modal { @ITelemetryService telemetryService: ITelemetryService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { super( localize('linkedAccounts', "Linked accounts"), @@ -134,6 +136,7 @@ export class AccountDialog extends Modal { clipboardService, themeService, logService, + textResourcePropertiesService, contextKeyService, { hasSpinner: true } ); diff --git a/src/sql/platform/accounts/browser/accountManagement.contribution.ts b/src/sql/platform/accounts/browser/accountManagement.contribution.ts index 9de3ced7f9..d1c63657a2 100644 --- a/src/sql/platform/accounts/browser/accountManagement.contribution.ts +++ b/src/sql/platform/accounts/browser/accountManagement.contribution.ts @@ -6,7 +6,7 @@ import { IExtensionPointUser, ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { localize } from 'vs/nls'; -import { join } from 'path'; +import { join } from 'vs/base/common/path'; import { createCSSRule } from 'vs/base/browser/dom'; import { URI } from 'vs/base/common/uri'; diff --git a/src/sql/platform/accounts/browser/autoOAuthDialog.ts b/src/sql/platform/accounts/browser/autoOAuthDialog.ts index 2f8fe7f189..7af2c0c55c 100644 --- a/src/sql/platform/accounts/browser/autoOAuthDialog.ts +++ b/src/sql/platform/accounts/browser/autoOAuthDialog.ts @@ -23,6 +23,7 @@ import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export class AutoOAuthDialog extends Modal { private _copyAndOpenButton: Button; @@ -49,7 +50,8 @@ export class AutoOAuthDialog extends Modal { @ITelemetryService telemetryService: ITelemetryService, @IContextKeyService contextKeyService: IContextKeyService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { super( '', @@ -59,6 +61,7 @@ export class AutoOAuthDialog extends Modal { clipboardService, themeService, logService, + textResourcePropertiesService, contextKeyService, { isFlyout: true, diff --git a/src/sql/platform/accounts/browser/firewallRuleDialog.ts b/src/sql/platform/accounts/browser/firewallRuleDialog.ts index da8353348f..76266a0aeb 100644 --- a/src/sql/platform/accounts/browser/firewallRuleDialog.ts +++ b/src/sql/platform/accounts/browser/firewallRuleDialog.ts @@ -29,6 +29,7 @@ import { IAccountPickerService } from 'sql/platform/accounts/common/accountPicke import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; // TODO: Make the help link 1) extensible (01/08/2018, https://github.com/Microsoft/azuredatastudio/issues/450) // in case that other non-Azure sign in is to be used @@ -71,7 +72,8 @@ export class FirewallRuleDialog extends Modal { @IContextKeyService contextKeyService: IContextKeyService, @IWindowsService private _windowsService: IWindowsService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { super( localize('createNewFirewallRule', "Create new firewall rule"), @@ -81,6 +83,7 @@ export class FirewallRuleDialog extends Modal { clipboardService, themeService, logService, + textResourcePropertiesService, contextKeyService, { isFlyout: true, diff --git a/src/sql/platform/accounts/test/browser/accountDialogController.test.ts b/src/sql/platform/accounts/test/browser/accountDialogController.test.ts index 7c4a79b22e..3af867243f 100644 --- a/src/sql/platform/accounts/test/browser/accountDialogController.test.ts +++ b/src/sql/platform/accounts/test/browser/accountDialogController.test.ts @@ -86,7 +86,7 @@ function createInstantiationService(addAccountFailureEmitter?: Emitter): .returns(() => undefined); // Create a mock account dialog - let accountDialog = new AccountDialog(null, null, instantiationService.object, null, null, null, null, new MockContextKeyService(), null, undefined); + let accountDialog = new AccountDialog(null, null, instantiationService.object, null, null, null, null, new MockContextKeyService(), null, undefined, undefined); let mockAccountDialog = TypeMoq.Mock.ofInstance(accountDialog); mockAccountDialog.setup(x => x.onAddAccountErrorEvent) .returns(() => { return addAccountFailureEmitter ? addAccountFailureEmitter.event : mockEvent.event; }); diff --git a/src/sql/platform/accounts/test/browser/autoOAuthDialogController.test.ts b/src/sql/platform/accounts/test/browser/autoOAuthDialogController.test.ts index da7b854814..f4036f52ec 100644 --- a/src/sql/platform/accounts/test/browser/autoOAuthDialogController.test.ts +++ b/src/sql/platform/accounts/test/browser/autoOAuthDialogController.test.ts @@ -37,7 +37,7 @@ suite('auto OAuth dialog controller tests', () => { mockOnCloseEvent = new Emitter(); // Create a mock auto OAuth dialog - let autoOAuthDialog = new AutoOAuthDialog(null, null, null, null, new MockContextKeyService(), null, undefined); + let autoOAuthDialog = new AutoOAuthDialog(null, null, null, null, new MockContextKeyService(), null, undefined, undefined); mockAutoOAuthDialog = TypeMoq.Mock.ofInstance(autoOAuthDialog); mockAutoOAuthDialog.setup(x => x.onCancel).returns(() => mockOnCancelEvent.event); diff --git a/src/sql/platform/accounts/test/browser/firewallRuleDialogController.test.ts b/src/sql/platform/accounts/test/browser/firewallRuleDialogController.test.ts index 93c0ec4c6e..e2c8887666 100644 --- a/src/sql/platform/accounts/test/browser/firewallRuleDialogController.test.ts +++ b/src/sql/platform/accounts/test/browser/firewallRuleDialogController.test.ts @@ -60,7 +60,7 @@ suite('Firewall rule dialog controller tests', () => { .returns(() => mockFirewallRuleViewModel.object); // Create a mock account picker - let firewallRuleDialog = new FirewallRuleDialog(null, null, null, instantiationService.object, null, null, new MockContextKeyService(), null, null, undefined); + let firewallRuleDialog = new FirewallRuleDialog(null, null, null, instantiationService.object, null, null, new MockContextKeyService(), null, null, undefined, undefined); mockFirewallRuleDialog = TypeMoq.Mock.ofInstance(firewallRuleDialog); let mockEvent = new Emitter(); diff --git a/src/sql/platform/dialog/browser/dialogModal.ts b/src/sql/platform/dialog/browser/dialogModal.ts index d3f08f5c2d..4966729f41 100644 --- a/src/sql/platform/dialog/browser/dialogModal.ts +++ b/src/sql/platform/dialog/browser/dialogModal.ts @@ -23,6 +23,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { append, $ } from 'vs/base/browser/dom'; import { ILogService } from 'vs/platform/log/common/log'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export class DialogModal extends Modal { private _dialogPane: DialogPane; @@ -43,9 +44,10 @@ export class DialogModal extends Modal { @IContextKeyService contextKeyService: IContextKeyService, @IClipboardService clipboardService: IClipboardService, @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService, @IInstantiationService private _instantiationService: IInstantiationService ) { - super(_dialog.title, name, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService, options); + super(_dialog.title, name, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, options); } public layout(): void { diff --git a/src/sql/platform/dialog/browser/wizardModal.ts b/src/sql/platform/dialog/browser/wizardModal.ts index e4ed94ae55..dd47cd7695 100644 --- a/src/sql/platform/dialog/browser/wizardModal.ts +++ b/src/sql/platform/dialog/browser/wizardModal.ts @@ -24,6 +24,7 @@ import { append, $ } from 'vs/base/browser/dom'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export class WizardModal extends Modal { private _dialogPanes = new Map(); @@ -53,9 +54,10 @@ export class WizardModal extends Modal { @IContextKeyService contextKeyService: IContextKeyService, @IInstantiationService private _instantiationService: IInstantiationService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super(_wizard.title, name, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService, options); + super(_wizard.title, name, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, options); this._useDefaultMessageBoxLocation = false; } diff --git a/src/sql/platform/notebooks/common/outputRegistry.ts b/src/sql/platform/notebooks/common/outputRegistry.ts new file mode 100644 index 0000000000..67d04c8f40 --- /dev/null +++ b/src/sql/platform/notebooks/common/outputRegistry.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Registry } from 'vs/platform/registry/common/platform'; + +export const Extensions = { + CellComponentContributions: 'notebook.contributions.cells' +}; + +export interface ICellComponenetRegistry { + registerComponent(component: any): void; + getComponents(): Array; +} + +class CellComponenetRegistry implements ICellComponenetRegistry { + private components = new Array(); + + registerComponent(component: any): void { + this.components.push(component); + } + + getComponents(): any[] { + return this.components.slice(); + } +} + +const componentRegistry = new CellComponenetRegistry(); +Registry.add(Extensions.CellComponentContributions, componentRegistry); + +export function registerCellComponent(component: any): void { + componentRegistry.registerComponent(component); +} \ No newline at end of file diff --git a/src/sql/platform/query/common/queryManagement.ts b/src/sql/platform/query/common/queryManagement.ts index 157c036ac5..ed2fb48e15 100644 --- a/src/sql/platform/query/common/queryManagement.ts +++ b/src/sql/platform/query/common/queryManagement.ts @@ -22,6 +22,8 @@ export const IQueryManagementService = createDecorator( export interface IQueryManagementService { _serviceBrand: any; + onHandlerAdded: Event; + addQueryRequestHandler(queryType: string, runner: IQueryRequestHandler): IDisposable; isProviderRegistered(providerId: string): boolean; getRegisteredProviders(): string[]; diff --git a/src/sql/platform/scripting/common/scriptingService.ts b/src/sql/platform/scripting/common/scriptingService.ts index d1fd1b6c96..5c6a7660b3 100644 --- a/src/sql/platform/scripting/common/scriptingService.ts +++ b/src/sql/platform/scripting/common/scriptingService.ts @@ -6,13 +6,23 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; -import { ScriptOperation } from 'sql/workbench/common/taskUtilities'; import * as azdata from 'azdata'; import { ILogService } from 'vs/platform/log/common/log'; + export const SERVICE_ID = 'scriptingService'; export const IScriptingService = createDecorator(SERVICE_ID); +export enum ScriptOperation { + Select = 0, + Create = 1, + Insert = 2, + Update = 3, + Delete = 4, + Execute = 5, + Alter = 6 +} + export interface IScriptingService { _serviceBrand: any; diff --git a/src/sql/workbench/api/browser/mainThreadConnectionManagement.ts b/src/sql/workbench/api/browser/mainThreadConnectionManagement.ts index 9ca101de3e..3c47655bf7 100644 --- a/src/sql/workbench/api/browser/mainThreadConnectionManagement.ts +++ b/src/sql/workbench/api/browser/mainThreadConnectionManagement.ts @@ -10,7 +10,7 @@ import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { IConnectionManagementService, ConnectionType } 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 * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { isUndefinedOrNull } from 'vs/base/common/types'; diff --git a/src/sql/workbench/api/browser/mainThreadNotebookDocumentsAndEditors.ts b/src/sql/workbench/api/browser/mainThreadNotebookDocumentsAndEditors.ts index c4978afa06..84f7fc3fc6 100644 --- a/src/sql/workbench/api/browser/mainThreadNotebookDocumentsAndEditors.ts +++ b/src/sql/workbench/api/browser/mainThreadNotebookDocumentsAndEditors.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as azdata from 'azdata'; -import * as path from 'path'; +import * as path from 'vs/base/common/path'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { URI, UriComponents } from 'vs/base/common/uri'; diff --git a/src/sql/workbench/browser/modal/modal.ts b/src/sql/workbench/browser/modal/modal.ts index 0c759f7b09..f9e10b6546 100644 --- a/src/sql/workbench/browser/modal/modal.ts +++ b/src/sql/workbench/browser/modal/modal.ts @@ -20,11 +20,13 @@ import * as TelemetryUtils from 'sql/platform/telemetry/common/telemetryUtilitie import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; import { localize } from 'vs/nls'; import { MessageLevel } from 'sql/workbench/api/common/sqlExtHostTypes'; -import * as os from 'os'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; +import { URI } from 'vs/base/common/uri'; +import { Schemas } from 'vs/base/common/network'; export const MODAL_SHOWING_KEY = 'modalShowing'; export const MODAL_SHOWING_CONTEXT = new RawContextKey>(MODAL_SHOWING_KEY, []); @@ -142,11 +144,12 @@ export abstract class Modal extends Disposable implements IThemable { constructor( private _title: string, private _name: string, - private _telemetryService: ITelemetryService, - protected layoutService: IWorkbenchLayoutService, - protected _clipboardService: IClipboardService, - protected _themeService: IThemeService, - protected logService: ILogService, + private readonly _telemetryService: ITelemetryService, + protected readonly layoutService: IWorkbenchLayoutService, + protected readonly _clipboardService: IClipboardService, + protected readonly _themeService: IThemeService, + protected readonly logService: ILogService, + protected readonly textResourcePropertiesService: ITextResourcePropertiesService, _contextKeyService: IContextKeyService, options?: IModalOptions ) { @@ -284,7 +287,8 @@ export abstract class Modal extends Disposable implements IThemable { } private getTextForClipboard(): string { - return this._messageDetailText === '' ? this._messageSummaryText : `${this._messageSummaryText}${os.EOL}========================${os.EOL}${this._messageDetailText}`; + const eol = this.textResourcePropertiesService.getEOL(URI.from({ scheme: Schemas.untitled })); + return this._messageDetailText === '' ? this._messageSummaryText : `${this._messageSummaryText}${eol}========================${eol}${this._messageDetailText}`; } private updateExpandMessageState() { diff --git a/src/sql/workbench/browser/modal/optionsDialog.ts b/src/sql/workbench/browser/modal/optionsDialog.ts index 47c3ab3753..dbc6084427 100644 --- a/src/sql/workbench/browser/modal/optionsDialog.ts +++ b/src/sql/workbench/browser/modal/optionsDialog.ts @@ -33,6 +33,7 @@ import { append, $ } from 'vs/base/browser/dom'; import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export class CategoryView extends ViewletPanel { @@ -95,9 +96,10 @@ export class OptionsDialog extends Modal { @ITelemetryService telemetryService: ITelemetryService, @IContextKeyService contextKeyService: IContextKeyService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super(title, name, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService, options); + super(title, name, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, options); } public render() { diff --git a/src/sql/workbench/browser/taskUtilities.ts b/src/sql/workbench/browser/taskUtilities.ts new file mode 100644 index 0000000000..158dfa8f64 --- /dev/null +++ b/src/sql/workbench/browser/taskUtilities.ts @@ -0,0 +1,151 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; +import { + IConnectableInput, IConnectionManagementService, + IConnectionCompletionOptions, ConnectionType, + RunQueryOnConnectionMode, IConnectionResult +} from 'sql/platform/connection/common/connectionManagement'; +import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; +import { EditDataInput } from 'sql/workbench/parts/editData/common/editDataInput'; +import { IRestoreDialogController } from 'sql/platform/restore/common/restoreService'; +import { IInsightsDialogService } from 'sql/workbench/services/insights/browser/insightsDialogService'; +import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; +import { QueryInput } from 'sql/workbench/parts/query/common/queryInput'; +import { DashboardInput } from 'sql/workbench/parts/dashboard/common/dashboardInput'; +import { ProfilerInput } from 'sql/workbench/parts/profiler/browser/profilerInput'; +import { IBackupUiService } from 'sql/workbench/services/backup/common/backupUiService'; + +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IInsightsConfig } from 'sql/platform/dashboard/browser/insightRegistry'; + +export function newQuery( + connectionProfile: IConnectionProfile, + connectionService: IConnectionManagementService, + queryEditorService: IQueryEditorService, + objectExplorerService: IObjectExplorerService, + workbenchEditorService: IEditorService, + sqlContent?: string, + executeOnOpen: RunQueryOnConnectionMode = RunQueryOnConnectionMode.none +): Promise { + return new Promise((resolve) => { + if (!connectionProfile) { + connectionProfile = getCurrentGlobalConnection(objectExplorerService, connectionService, workbenchEditorService); + } + queryEditorService.newSqlEditor(sqlContent).then((owner: IConnectableInput) => { + // Connect our editor to the input connection + let options: IConnectionCompletionOptions = { + params: { connectionType: ConnectionType.editor, runQueryOnCompletion: executeOnOpen, input: owner }, + saveTheConnection: false, + showDashboard: false, + showConnectionDialogOnError: true, + showFirewallRuleOnError: true + }; + if (connectionProfile) { + connectionService.connect(connectionProfile, owner.uri, options).then(() => { + resolve(); + }); + } else { + resolve(); + } + }); + }); +} + +export function replaceConnection(oldUri: string, newUri: string, connectionService: IConnectionManagementService): Promise { + return new Promise((resolve, reject) => { + let defaultResult: IConnectionResult = { + connected: false, + errorMessage: undefined, + errorCode: undefined, + callStack: undefined + }; + if (connectionService) { + let connectionProfile = connectionService.getConnectionProfile(oldUri); + if (connectionProfile) { + let options: IConnectionCompletionOptions = { + params: { connectionType: ConnectionType.editor, runQueryOnCompletion: RunQueryOnConnectionMode.none }, + saveTheConnection: false, + showDashboard: false, + showConnectionDialogOnError: true, + showFirewallRuleOnError: true + }; + connectionService.disconnect(oldUri).then(() => { + connectionService.connect(connectionProfile, newUri, options).then(result => { + resolve(result); + }, connectError => { + reject(connectError); + }); + }, disconnectError => { + reject(disconnectError); + }); + + } else { + resolve(defaultResult); + } + } else { + resolve(defaultResult); + } + }); +} + +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); +} + +/** + * Get the current global connection, which is the connection from the active editor, unless OE + * is focused or there is no such editor, in which case it comes from the OE selection. Returns + * undefined when there is no such connection. + * + * @param topLevelOnly If true, only return top-level (i.e. connected) Object Explorer connections instead of database connections when appropriate +*/ +export function getCurrentGlobalConnection(objectExplorerService: IObjectExplorerService, connectionManagementService: IConnectionManagementService, workbenchEditorService: IEditorService, topLevelOnly: boolean = false): IConnectionProfile { + let connection: IConnectionProfile; + + let objectExplorerSelection = objectExplorerService.getSelectedProfileAndDatabase(); + if (objectExplorerSelection) { + let objectExplorerProfile = objectExplorerSelection.profile; + if (connectionManagementService.isProfileConnected(objectExplorerProfile)) { + if (objectExplorerSelection.databaseName && !topLevelOnly) { + connection = objectExplorerProfile.cloneWithDatabase(objectExplorerSelection.databaseName); + } else { + connection = objectExplorerProfile; + } + } + if (objectExplorerService.isFocused()) { + return connection; + } + } + + let activeInput = workbenchEditorService.activeEditor; + if (activeInput) { + if (activeInput instanceof QueryInput || activeInput instanceof EditDataInput || activeInput instanceof DashboardInput) { + connection = connectionManagementService.getConnectionProfile(activeInput.uri); + } + else if (activeInput instanceof ProfilerInput) { + connection = activeInput.connection; + } + } + + return connection; +} diff --git a/src/sql/workbench/common/actions.ts b/src/sql/workbench/common/actions.ts index f844d14b60..b5ef0de8cb 100644 --- a/src/sql/workbench/common/actions.ts +++ b/src/sql/workbench/common/actions.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; -import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +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'; @@ -67,162 +67,6 @@ export class NewQueryAction extends Task { } } -export class ScriptSelectAction extends Action { - public static ID = 'selectTop'; - public static LABEL = nls.localize('scriptSelect', "Select Top 1000"); - - constructor( - id: string, label: string, - @IQueryEditorService protected _queryEditorService: IQueryEditorService, - @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, - @IScriptingService protected _scriptingService: IScriptingService - ) { - super(id, label); - } - - public run(actionContext: BaseActionContext): Promise { - return TaskUtilities.scriptSelect( - actionContext.profile, - actionContext.object, - this._connectionManagementService, - this._queryEditorService, - this._scriptingService - ).then(() => true); - } -} - -export class ScriptExecuteAction extends Action { - public static ID = 'scriptExecute'; - public static LABEL = nls.localize('scriptExecute', "Script as Execute"); - - constructor( - id: string, label: string, - @IQueryEditorService protected _queryEditorService: IQueryEditorService, - @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, - @IScriptingService protected _scriptingService: IScriptingService, - @IErrorMessageService protected _errorMessageService: IErrorMessageService - ) { - super(id, label); - } - - public run(actionContext: BaseActionContext): Promise { - return TaskUtilities.script( - actionContext.profile, - actionContext.object, - this._connectionManagementService, - this._queryEditorService, - this._scriptingService, - TaskUtilities.ScriptOperation.Execute, - this._errorMessageService - ).then(() => true); - } -} - -export class ScriptAlterAction extends Action { - public static ID = 'scriptAlter'; - public static LABEL = nls.localize('scriptAlter', "Script as Alter"); - - constructor( - id: string, label: string, - @IQueryEditorService protected _queryEditorService: IQueryEditorService, - @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, - @IScriptingService protected _scriptingService: IScriptingService, - @IErrorMessageService protected _errorMessageService: IErrorMessageService - ) { - super(id, label); - } - - public run(actionContext: BaseActionContext): Promise { - return TaskUtilities.script( - actionContext.profile, - actionContext.object, - this._connectionManagementService, - this._queryEditorService, - this._scriptingService, - TaskUtilities.ScriptOperation.Alter, - this._errorMessageService - ).then(() => true); - } -} - -export class EditDataAction extends Action { - public static ID = 'editData'; - public static LABEL = nls.localize('editData', "Edit Data"); - - constructor( - id: string, label: string, - @IQueryEditorService protected _queryEditorService: IQueryEditorService, - @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, - @IScriptingService protected _scriptingService: IScriptingService - ) { - super(id, label); - } - - public run(actionContext: BaseActionContext): Promise { - return TaskUtilities.scriptEditSelect( - actionContext.profile, - actionContext.object, - this._connectionManagementService, - this._queryEditorService, - this._scriptingService - ).then(() => true); - } -} - -export class ScriptCreateAction extends Action { - public static ID = 'scriptCreate'; - public static LABEL = nls.localize('scriptCreate', "Script as Create"); - - constructor( - id: string, label: string, - @IQueryEditorService protected _queryEditorService: IQueryEditorService, - @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, - @IScriptingService protected _scriptingService: IScriptingService, - @IErrorMessageService protected _errorMessageService: IErrorMessageService - ) { - super(id, label); - } - - public run(actionContext: BaseActionContext): Promise { - return TaskUtilities.script( - actionContext.profile, - actionContext.object, - this._connectionManagementService, - this._queryEditorService, - this._scriptingService, - TaskUtilities.ScriptOperation.Create, - this._errorMessageService - ).then(() => true); - } -} - -export class ScriptDeleteAction extends Action { - public static ID = 'scriptDelete'; - public static LABEL = nls.localize('scriptDelete', "Script as Drop"); - - constructor( - id: string, label: string, - @IQueryEditorService protected _queryEditorService: IQueryEditorService, - @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, - @IScriptingService protected _scriptingService: IScriptingService, - @IErrorMessageService protected _errorMessageService: IErrorMessageService - ) { - super(id, label); - } - - public run(actionContext: BaseActionContext): Promise { - return TaskUtilities.script( - actionContext.profile, - actionContext.object, - this._connectionManagementService, - this._queryEditorService, - this._scriptingService, - TaskUtilities.ScriptOperation.Delete, - this._errorMessageService - ).then(() => true); - } -} - export const BackupFeatureName = 'backup'; export class BackupAction extends Task { diff --git a/src/sql/workbench/common/customInputConverter.ts b/src/sql/workbench/common/customInputConverter.ts index 93fdd8e829..17bb8bd7d4 100644 --- a/src/sql/workbench/common/customInputConverter.ts +++ b/src/sql/workbench/common/customInputConverter.ts @@ -17,8 +17,6 @@ import { INotebookService } from 'sql/workbench/services/notebook/common/noteboo import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; -const fs = require('fs'); - ////// Exported public functions/vars // prefix for untitled sql editors @@ -53,9 +51,7 @@ export function convertEditorInput(input: EditorInput, options: IQueryEditorOpti //QueryPlanInput uri = getQueryPlanEditorUri(input); if (uri) { - let queryPlanXml: string = fs.readFileSync(uri.fsPath); - let queryPlanInput: QueryPlanInput = instantiationService.createInstance(QueryPlanInput, queryPlanXml, 'aaa', undefined); - return queryPlanInput; + return instantiationService.createInstance(QueryPlanInput, uri, undefined); } } diff --git a/src/sql/workbench/contrib/welcome/page/browser/az_data_welcome_page.ts b/src/sql/workbench/contrib/welcome/page/browser/az_data_welcome_page.ts index c8c76fbb08..f79f4cc434 100644 --- a/src/sql/workbench/contrib/welcome/page/browser/az_data_welcome_page.ts +++ b/src/sql/workbench/contrib/welcome/page/browser/az_data_welcome_page.ts @@ -86,4 +86,4 @@ export default () => ` -`; \ No newline at end of file +`; diff --git a/src/sql/workbench/electron-browser/scriptingActions.ts b/src/sql/workbench/electron-browser/scriptingActions.ts new file mode 100644 index 0000000000..70687b35c3 --- /dev/null +++ b/src/sql/workbench/electron-browser/scriptingActions.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Action } from 'vs/base/common/actions'; +import * as nls from 'vs/nls'; +import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; +import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; +import { IScriptingService, ScriptOperation } from 'sql/platform/scripting/common/scriptingService'; +import { BaseActionContext } from 'sql/workbench/common/actions'; +import { scriptSelect, script, scriptEditSelect } from 'sql/workbench/electron-browser/scriptingUtils'; +import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; + +export class ScriptSelectAction extends Action { + public static ID = 'selectTop'; + public static LABEL = nls.localize('scriptSelect', "Select Top 1000"); + + constructor( + id: string, label: string, + @IQueryEditorService protected _queryEditorService: IQueryEditorService, + @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, + @IScriptingService protected _scriptingService: IScriptingService + ) { + super(id, label); + } + + public run(actionContext: BaseActionContext): Promise { + return scriptSelect( + actionContext.profile, + actionContext.object, + this._connectionManagementService, + this._queryEditorService, + this._scriptingService + ).then(() => true); + } +} + +export class ScriptExecuteAction extends Action { + public static ID = 'scriptExecute'; + public static LABEL = nls.localize('scriptExecute', "Script as Execute"); + + constructor( + id: string, label: string, + @IQueryEditorService protected _queryEditorService: IQueryEditorService, + @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, + @IScriptingService protected _scriptingService: IScriptingService, + @IErrorMessageService protected _errorMessageService: IErrorMessageService + ) { + super(id, label); + } + + public run(actionContext: BaseActionContext): Promise { + return script( + actionContext.profile, + actionContext.object, + this._connectionManagementService, + this._queryEditorService, + this._scriptingService, + ScriptOperation.Execute, + this._errorMessageService + ).then(() => true); + } +} + +export class ScriptAlterAction extends Action { + public static ID = 'scriptAlter'; + public static LABEL = nls.localize('scriptAlter', "Script as Alter"); + + constructor( + id: string, label: string, + @IQueryEditorService protected _queryEditorService: IQueryEditorService, + @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, + @IScriptingService protected _scriptingService: IScriptingService, + @IErrorMessageService protected _errorMessageService: IErrorMessageService + ) { + super(id, label); + } + + public run(actionContext: BaseActionContext): Promise { + return script( + actionContext.profile, + actionContext.object, + this._connectionManagementService, + this._queryEditorService, + this._scriptingService, + ScriptOperation.Alter, + this._errorMessageService + ).then(() => true); + } +} + +export class EditDataAction extends Action { + public static ID = 'editData'; + public static LABEL = nls.localize('editData', "Edit Data"); + + constructor( + id: string, label: string, + @IQueryEditorService protected _queryEditorService: IQueryEditorService, + @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, + @IScriptingService protected _scriptingService: IScriptingService + ) { + super(id, label); + } + + public run(actionContext: BaseActionContext): Promise { + return scriptEditSelect( + actionContext.profile, + actionContext.object, + this._connectionManagementService, + this._queryEditorService, + this._scriptingService + ).then(() => true); + } +} + +export class ScriptCreateAction extends Action { + public static ID = 'scriptCreate'; + public static LABEL = nls.localize('scriptCreate', "Script as Create"); + + constructor( + id: string, label: string, + @IQueryEditorService protected _queryEditorService: IQueryEditorService, + @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, + @IScriptingService protected _scriptingService: IScriptingService, + @IErrorMessageService protected _errorMessageService: IErrorMessageService + ) { + super(id, label); + } + + public run(actionContext: BaseActionContext): Promise { + return script( + actionContext.profile, + actionContext.object, + this._connectionManagementService, + this._queryEditorService, + this._scriptingService, + ScriptOperation.Create, + this._errorMessageService + ).then(() => true); + } +} + +export class ScriptDeleteAction extends Action { + public static ID = 'scriptDelete'; + public static LABEL = nls.localize('scriptDelete', "Script as Drop"); + + constructor( + id: string, label: string, + @IQueryEditorService protected _queryEditorService: IQueryEditorService, + @IConnectionManagementService protected _connectionManagementService: IConnectionManagementService, + @IScriptingService protected _scriptingService: IScriptingService, + @IErrorMessageService protected _errorMessageService: IErrorMessageService + ) { + super(id, label); + } + + public run(actionContext: BaseActionContext): Promise { + return script( + actionContext.profile, + actionContext.object, + this._connectionManagementService, + this._queryEditorService, + this._scriptingService, + ScriptOperation.Delete, + this._errorMessageService + ).then(() => true); + } +} diff --git a/src/sql/workbench/common/taskUtilities.ts b/src/sql/workbench/electron-browser/scriptingUtils.ts similarity index 61% rename from src/sql/workbench/common/taskUtilities.ts rename to src/sql/workbench/electron-browser/scriptingUtils.ts index ee47baa120..e7281e450e 100644 --- a/src/sql/workbench/common/taskUtilities.ts +++ b/src/sql/workbench/electron-browser/scriptingUtils.ts @@ -3,34 +3,18 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as os from 'os'; - -import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; -import { - IConnectableInput, IConnectionManagementService, - IConnectionCompletionOptions, ConnectionType, - RunQueryOnConnectionMode, IConnectionResult -} from 'sql/platform/connection/common/connectionManagement'; -import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; -import { IScriptingService } from 'sql/platform/scripting/common/scriptingService'; -import { EditDataInput } from 'sql/workbench/parts/editData/common/editDataInput'; -import { IRestoreDialogController } from 'sql/platform/restore/common/restoreService'; -import { IInsightsDialogService } from 'sql/workbench/services/insights/browser/insightsDialogService'; -import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo'; -import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; -import { QueryInput } from 'sql/workbench/parts/query/common/queryInput'; -import { DashboardInput } from 'sql/workbench/parts/dashboard/common/dashboardInput'; -import { ProfilerInput } from 'sql/workbench/parts/profiler/browser/profilerInput'; -import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; -import { IBackupUiService } from 'sql/workbench/services/backup/common/backupUiService'; - import * as azdata from 'azdata'; - -import Severity from 'vs/base/common/severity'; -import * as nls from 'vs/nls'; import * as path from 'vs/base/common/path'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IInsightsConfig } from 'sql/platform/dashboard/browser/insightRegistry'; +import * as os from 'os'; +import { IConnectionManagementService, IConnectionCompletionOptions, ConnectionType, IConnectableInput, RunQueryOnConnectionMode } from 'sql/platform/connection/common/connectionManagement'; +import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo'; +import * as nls from 'vs/nls'; +import Severity from 'vs/base/common/severity'; +import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; +import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; +import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; +import { IScriptingService, ScriptOperation } from 'sql/platform/scripting/common/scriptingService'; +import { EditDataInput } from 'sql/workbench/parts/editData/common/editDataInput'; // map for the version of SQL Server (default is 140) const scriptCompatibilityOptionMap = { @@ -55,35 +39,6 @@ const targetDatabaseEngineEditionMap = { 7: 'SqlServerStretchEdition' }; -export enum ScriptOperation { - Select = 0, - Create = 1, - Insert = 2, - Update = 3, - Delete = 4, - Execute = 5, - Alter = 6 -} - -export function GetScriptOperationName(operation: ScriptOperation) { - let defaultName: string = ScriptOperation[operation]; - switch (operation) { - case ScriptOperation.Select: - return nls.localize('selectOperationName', "Select"); - case ScriptOperation.Create: - return nls.localize('createOperationName', "Create"); - case ScriptOperation.Insert: - return nls.localize('insertOperationName', "Insert"); - case ScriptOperation.Update: - return nls.localize('updateOperationName', "Update"); - case ScriptOperation.Delete: - return nls.localize('deleteOperationName', "Delete"); - default: - // return the raw, non-localized string name - return defaultName; - } -} - /** * Select the top rows from an object */ @@ -154,6 +109,27 @@ export function scriptEditSelect(connectionProfile: IConnectionProfile, metadata }); } + + +export function GetScriptOperationName(operation: ScriptOperation) { + let defaultName: string = ScriptOperation[operation]; + switch (operation) { + case ScriptOperation.Select: + return nls.localize('selectOperationName', "Select"); + case ScriptOperation.Create: + return nls.localize('createOperationName', "Create"); + case ScriptOperation.Insert: + return nls.localize('insertOperationName', "Insert"); + case ScriptOperation.Update: + return nls.localize('updateOperationName', "Update"); + case ScriptOperation.Delete: + return nls.localize('deleteOperationName', "Delete"); + default: + // return the raw, non-localized string name + return defaultName; + } +} + /** * Script the object as a statement based on the provided action (except Select) */ @@ -214,134 +190,6 @@ export function script(connectionProfile: IConnectionProfile, metadata: azdata.O }); } -export function newQuery( - connectionProfile: IConnectionProfile, - connectionService: IConnectionManagementService, - queryEditorService: IQueryEditorService, - objectExplorerService: IObjectExplorerService, - workbenchEditorService: IEditorService, - sqlContent?: string, - executeOnOpen: RunQueryOnConnectionMode = RunQueryOnConnectionMode.none -): Promise { - return new Promise((resolve) => { - if (!connectionProfile) { - connectionProfile = getCurrentGlobalConnection(objectExplorerService, connectionService, workbenchEditorService); - } - queryEditorService.newSqlEditor(sqlContent).then((owner: IConnectableInput) => { - // Connect our editor to the input connection - let options: IConnectionCompletionOptions = { - params: { connectionType: ConnectionType.editor, runQueryOnCompletion: executeOnOpen, input: owner }, - saveTheConnection: false, - showDashboard: false, - showConnectionDialogOnError: true, - showFirewallRuleOnError: true - }; - if (connectionProfile) { - connectionService.connect(connectionProfile, owner.uri, options).then(() => { - resolve(); - }); - } else { - resolve(); - } - }); - }); -} - -export function replaceConnection(oldUri: string, newUri: string, connectionService: IConnectionManagementService): Promise { - return new Promise((resolve, reject) => { - let defaultResult: IConnectionResult = { - connected: false, - errorMessage: undefined, - errorCode: undefined, - callStack: undefined - }; - if (connectionService) { - let connectionProfile = connectionService.getConnectionProfile(oldUri); - if (connectionProfile) { - let options: IConnectionCompletionOptions = { - params: { connectionType: ConnectionType.editor, runQueryOnCompletion: RunQueryOnConnectionMode.none }, - saveTheConnection: false, - showDashboard: false, - showConnectionDialogOnError: true, - showFirewallRuleOnError: true - }; - connectionService.disconnect(oldUri).then(() => { - connectionService.connect(connectionProfile, newUri, options).then(result => { - resolve(result); - }, connectError => { - reject(connectError); - }); - }, disconnectError => { - reject(disconnectError); - }); - - } else { - resolve(defaultResult); - } - } else { - resolve(defaultResult); - } - }); -} - -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); -} - -/** - * Get the current global connection, which is the connection from the active editor, unless OE - * is focused or there is no such editor, in which case it comes from the OE selection. Returns - * undefined when there is no such connection. - * - * @param topLevelOnly If true, only return top-level (i.e. connected) Object Explorer connections instead of database connections when appropriate -*/ -export function getCurrentGlobalConnection(objectExplorerService: IObjectExplorerService, connectionManagementService: IConnectionManagementService, workbenchEditorService: IEditorService, topLevelOnly: boolean = false): IConnectionProfile { - let connection: IConnectionProfile; - - let objectExplorerSelection = objectExplorerService.getSelectedProfileAndDatabase(); - if (objectExplorerSelection) { - let objectExplorerProfile = objectExplorerSelection.profile; - if (connectionManagementService.isProfileConnected(objectExplorerProfile)) { - if (objectExplorerSelection.databaseName && !topLevelOnly) { - connection = objectExplorerProfile.cloneWithDatabase(objectExplorerSelection.databaseName); - } else { - connection = objectExplorerProfile; - } - } - if (objectExplorerService.isFocused()) { - return connection; - } - } - - let activeInput = workbenchEditorService.activeEditor; - if (activeInput) { - if (activeInput instanceof QueryInput || activeInput instanceof EditDataInput || activeInput instanceof DashboardInput) { - connection = connectionManagementService.getConnectionProfile(activeInput.uri); - } - else if (activeInput instanceof ProfilerInput) { - connection = activeInput.connection; - } - } - - return connection; -} - function getScriptingParamDetails(connectionService: IConnectionManagementService, ownerUri: string, metadata: azdata.ObjectMetadata): azdata.ScriptingParamDetails { let serverInfo: azdata.ServerInfo = getServerInfo(connectionService, ownerUri); let paramDetails: azdata.ScriptingParamDetails = { @@ -353,6 +201,11 @@ function getScriptingParamDetails(connectionService: IConnectionManagementServic return paramDetails; } +function getServerInfo(connectionService: IConnectionManagementService, ownerUri: string): azdata.ServerInfo { + let connection: ConnectionManagementInfo = connectionService.getConnectionInfo(ownerUri); + return connection.serverInfo; +} + function getFilePath(metadata: azdata.ObjectMetadata): string { let schemaName: string = metadata.schema; let objectName: string = metadata.name; @@ -362,9 +215,4 @@ function getFilePath(metadata: azdata.ObjectMetadata): string { } else { return path.join(os.tmpdir(), `${objectName}_${timestamp}.txt`); } -} - -function getServerInfo(connectionService: IConnectionManagementService, ownerUri: string): azdata.ServerInfo { - let connection: ConnectionManagementInfo = connectionService.getConnectionInfo(ownerUri); - return connection.serverInfo; -} +} \ No newline at end of file diff --git a/src/sql/workbench/parts/backup/browser/backupDialog.ts b/src/sql/workbench/parts/backup/browser/backupDialog.ts index cb1d719b21..0584b6c9ee 100644 --- a/src/sql/workbench/parts/backup/browser/backupDialog.ts +++ b/src/sql/workbench/parts/backup/browser/backupDialog.ts @@ -19,6 +19,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService import { append, $ } from 'vs/base/browser/dom'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export class BackupDialog extends Modal { private _body: HTMLElement; @@ -32,9 +33,10 @@ export class BackupDialog extends Modal { @IContextKeyService contextKeyService: IContextKeyService, @IInstantiationService private _instantiationService: IInstantiationService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super('', TelemetryKeys.Backup, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService, { isAngular: true, hasErrors: true }); + super('', TelemetryKeys.Backup, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, { isAngular: true, hasErrors: true }); } protected renderBody(container: HTMLElement) { diff --git a/src/sql/workbench/parts/charts/browser/actions.ts b/src/sql/workbench/parts/charts/browser/actions.ts index b0a2c5f394..c42cba6c6d 100644 --- a/src/sql/workbench/parts/charts/browser/actions.ts +++ b/src/sql/workbench/parts/charts/browser/actions.ts @@ -3,24 +3,23 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IInsight } from './interfaces'; -import { Graph } from './graphInsight'; +import { IInsight } from 'sql/workbench/parts/charts/browser/interfaces'; +import { Graph } from 'sql/workbench/parts/charts/browser/graphInsight'; import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService'; -import { resolveCurrentDirectory, getRootPath } from 'sql/platform/common/pathUtilities'; import { localize } from 'vs/nls'; import { Action } from 'vs/base/common/actions'; -import { join, normalize } from 'vs/base/common/path'; -import { writeFile } from 'vs/base/node/pfs'; -import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows'; +import { IWindowsService } from 'vs/platform/windows/common/windows'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { URI } from 'vs/base/common/uri'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { QueryInput } from 'sql/workbench/parts/query/common/queryInput'; import { IInsightsConfig } from 'sql/platform/dashboard/browser/insightRegistry'; import { IInsightOptions } from 'sql/workbench/parts/charts/common/interfaces'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { VSBuffer } from 'vs/base/common/buffer'; export interface IChartActionContext { options: IInsightOptions; @@ -143,70 +142,52 @@ export class SaveImageAction extends Action { public static ICON = 'saveAsImage'; constructor( - @IWindowsService private windowsService: IWindowsService, - @IWindowService private windowService: IWindowService, - @INotificationService private notificationService: INotificationService, - @IEditorService private editorService: IEditorService, - @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService + @IWindowsService private readonly windowsService: IWindowsService, + @INotificationService private readonly notificationService: INotificationService, + @IFileService private readonly fileService: IFileService, + @IFileDialogService private readonly fileDialogService: IFileDialogService ) { super(SaveImageAction.ID, SaveImageAction.LABEL, SaveImageAction.ICON); } - public run(context: IChartActionContext): Promise { + public async run(context: IChartActionContext): Promise { if (context.insight instanceof Graph) { - return this.promptForFilepath().then(filePath => { - let data = (context.insight).getCanvasData(); - if (!data) { - this.showError(localize('chartNotFound', "Could not find chart to save")); - return false; + const filePath = await this.fileDialogService.pickFileToSave({}); + const data = (context.insight).getCanvasData(); + if (!data) { + this.notificationService.error(localize('chartNotFound', "Could not find chart to save")); + return false; + } + if (filePath) { + let buffer = this.decodeBase64Image(data); + try { + await this.fileService.writeFile(filePath, buffer); + } catch (err) { + if (err) { + this.notificationService.error(err.message); + } else { + this.windowsService.openExternal(filePath.toString()); + this.notificationService.notify({ + severity: Severity.Error, + message: localize('chartSaved', 'Saved Chart to path: {0}', filePath.toString()) + }); + } } - if (filePath) { - let buffer = this.decodeBase64Image(data); - writeFile(filePath, buffer).then(undefined, (err) => { - if (err) { - this.showError(err.message); - } else { - let fileUri = URI.file(filePath); - this.windowsService.openExternal(fileUri.toString()); - this.notificationService.notify({ - severity: Severity.Error, - message: localize('chartSaved', 'Saved Chart to path: {0}', filePath) - }); - } - }); - } - return true; - }); + } + return true; } return Promise.resolve(false); } - private decodeBase64Image(data: string): Buffer { - let matches = data.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/); - return Buffer.from(matches[2], 'base64'); - } - - private promptForFilepath(): Promise { - let filepathPlaceHolder = resolveCurrentDirectory(this.getActiveUriString(), getRootPath(this.workspaceContextService)); - filepathPlaceHolder = join(filepathPlaceHolder, 'chart.png'); - return this.windowService.showSaveDialog({ - title: localize('chartViewer.saveAsFileTitle', "Choose Results File"), - defaultPath: normalize(filepathPlaceHolder) - }); - } - - private showError(errorMsg: string) { - this.notificationService.notify({ - severity: Severity.Error, - message: errorMsg - }); - } - - private getActiveUriString(): string { - let editor = this.editorService.activeEditor; - if (editor instanceof QueryInput) { - return editor.uri; + private decodeBase64Image(data: string): VSBuffer { + const marker = ';base64,'; + const raw = atob(data.substring(data.indexOf(marker) + marker.length)); + const n = raw.length; + const a = new Uint8Array(new ArrayBuffer(n)); + for (let i = 0; i < n; i++) { + a[i] = raw.charCodeAt(i); } - return undefined; + return VSBuffer.wrap(a); } + } diff --git a/src/sql/workbench/parts/commandLine/electron-browser/commandLine.ts b/src/sql/workbench/parts/commandLine/electron-browser/commandLine.ts index a8da6c44c2..0465a7c219 100644 --- a/src/sql/workbench/parts/commandLine/electron-browser/commandLine.ts +++ b/src/sql/workbench/parts/commandLine/electron-browser/commandLine.ts @@ -14,7 +14,7 @@ import * as Constants from 'sql/platform/connection/common/constants'; import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; import * as platform from 'vs/platform/registry/common/platform'; import { IConnectionProviderRegistry, Extensions as ConnectionProviderExtensions } from 'sql/workbench/parts/connection/common/connectionProviderExtension'; -import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ICommandService } from 'vs/platform/commands/common/commands'; diff --git a/src/sql/workbench/parts/connection/browser/connectionStatus.ts b/src/sql/workbench/parts/connection/browser/connectionStatus.ts index 809a443d59..1edd8c9ba8 100644 --- a/src/sql/workbench/parts/connection/browser/connectionStatus.ts +++ b/src/sql/workbench/parts/connection/browser/connectionStatus.ts @@ -8,7 +8,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; -import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/platform/statusbar/common/statusbar'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { localize } from 'vs/nls'; diff --git a/src/sql/workbench/parts/connection/common/connectionProviderExtension.ts b/src/sql/workbench/parts/connection/common/connectionProviderExtension.ts index 0f5a53828a..8f068036e9 100644 --- a/src/sql/workbench/parts/connection/common/connectionProviderExtension.ts +++ b/src/sql/workbench/parts/connection/common/connectionProviderExtension.ts @@ -11,7 +11,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { deepClone } from 'vs/base/common/objects'; import * as azdata from 'azdata'; -import * as path from 'path'; +import * as path from 'vs/base/common/path'; import { URI } from 'vs/base/common/uri'; export interface ConnectionProviderProperties { diff --git a/src/sql/workbench/parts/dashboard/browser/containers/dashboardNavSection.contribution.ts b/src/sql/workbench/parts/dashboard/browser/containers/dashboardNavSection.contribution.ts index 6a459e4487..832e932030 100644 --- a/src/sql/workbench/parts/dashboard/browser/containers/dashboardNavSection.contribution.ts +++ b/src/sql/workbench/parts/dashboard/browser/containers/dashboardNavSection.contribution.ts @@ -6,7 +6,7 @@ import { IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import * as nls from 'vs/nls'; -import { join } from 'path'; +import { join } from 'vs/base/common/path'; import { createCSSRule } from 'vs/base/browser/dom'; import { URI } from 'vs/base/common/uri'; import { IdGenerator } from 'vs/base/common/idGenerator'; diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTree.ts b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTree.ts index 3daf53c652..fcfda06f74 100644 --- a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTree.ts +++ b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTree.ts @@ -6,95 +6,24 @@ import { Router } from '@angular/router'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; -import { MetadataType, IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; -import { SingleConnectionManagementService } from 'sql/platform/bootstrap/browser/commonServiceInterface.service'; -import { - NewQueryAction, ScriptSelectAction, EditDataAction, ScriptCreateAction, ScriptExecuteAction, ScriptAlterAction, - BackupAction, ManageActionContext, BaseActionContext, ManageAction, RestoreAction -} from 'sql/workbench/common/actions'; -import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; -import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo'; -import * as Constants from 'sql/platform/connection/common/constants'; -import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; -import { IScriptingService } from 'sql/platform/scripting/common/scriptingService'; -import { IAngularEventingService } from 'sql/platform/angularEventing/common/angularEventingService'; -import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; - -import { ObjectMetadata } from 'azdata'; +import { MetadataType } from 'sql/platform/connection/common/connectionManagement'; +import { SingleConnectionManagementService, CommonServiceInterface } from 'sql/platform/bootstrap/browser/commonServiceInterface.service'; +import { ManageActionContext, BaseActionContext } from 'sql/workbench/common/actions'; import * as tree from 'vs/base/parts/tree/browser/tree'; import * as TreeDefaults from 'vs/base/parts/tree/browser/treeDefaults'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IAction } from 'vs/base/common/actions'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { generateUuid } from 'vs/base/common/uuid'; import { $ } from 'vs/base/browser/dom'; -import { ExecuteCommandAction } from 'vs/platform/actions/common/actions'; +import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IEditorProgressService } from 'vs/platform/progress/common/progress'; -import { NewNotebookAction } from 'sql/workbench/parts/notebook/browser/notebookActions'; - -export class ObjectMetadataWrapper implements ObjectMetadata { - public metadataType: MetadataType; - public metadataTypeName: string; - public urn: string; - public name: string; - public schema: string; - - constructor(from?: ObjectMetadata) { - if (from) { - this.metadataType = from.metadataType; - this.metadataTypeName = from.metadataTypeName; - this.urn = from.urn; - this.name = from.name; - this.schema = from.schema; - } - } - - public matches(other: ObjectMetadataWrapper): boolean { - if (!other) { - return false; - } - - return this.metadataType === other.metadataType - && this.schema === other.schema - && this.name === other.name; - } - - public static createFromObjectMetadata(objectMetadata: ObjectMetadata[]): ObjectMetadataWrapper[] { - if (!objectMetadata) { - return undefined; - } - - return objectMetadata.map(m => new ObjectMetadataWrapper(m)); - } - - // custom sort : Table > View > Stored Procedures > Function - public static sort(metadata1: ObjectMetadataWrapper, metadata2: ObjectMetadataWrapper): number { - // compare the object type - if (metadata1.metadataType < metadata2.metadataType) { - return -1; - } else if (metadata1.metadataType > metadata2.metadataType) { - return 1; - - // otherwise compare the schema - } else { - const schemaCompare: number = metadata1.schema && metadata2.schema - ? metadata1.schema.localeCompare(metadata2.schema) - // schemas are not expected to be undefined, but if they are then compare using object names - : 0; - - if (schemaCompare !== 0) { - return schemaCompare; - - // otherwise compare the object name - } else { - return metadata1.name.localeCompare(metadata2.name); - } - } - } -} +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; +import { ItemContextKey } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext'; +import { ObjectMetadataWrapper } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/objectMetadataWrapper'; export declare type TreeResource = IConnectionProfile | ObjectMetadataWrapper; @@ -104,15 +33,18 @@ export class ExplorerModel { } export class ExplorerController extends TreeDefaults.DefaultController { + private readonly contextKey = new ItemContextKey(this.contextKeyService); + constructor( // URI for the dashboard for managing, should look into some other way of doing this private _uri, private _connectionService: SingleConnectionManagementService, private _router: Router, - private _contextMenuService: IContextMenuService, - private _capabilitiesService: ICapabilitiesService, - private _instantiationService: IInstantiationService, - private _progressService: IEditorProgressService + private readonly bootStrapService: CommonServiceInterface, + @IContextMenuService private readonly contextMenuService: IContextMenuService, + @IEditorProgressService private readonly progressService: IEditorProgressService, + @IMenuService private readonly menuService: IMenuService, + @IContextKeyService private readonly contextKeyService: IContextKeyService ) { super(); } @@ -143,6 +75,12 @@ export class ExplorerController extends TreeDefaults.DefaultController { } public onContextMenu(tree: tree.ITree, element: TreeResource, event: tree.ContextMenuEvent): boolean { + this.contextKey.set({ + resource: element, + providerName: this.bootStrapService.connectionManagementService.connectionInfo.providerId, + isCloud: this.bootStrapService.connectionManagementService.connectionInfo.serverInfo.isCloud + }); + let context: ManageActionContext | BaseActionContext; if (element instanceof ObjectMetadataWrapper) { @@ -157,9 +95,15 @@ export class ExplorerController extends TreeDefaults.DefaultController { }; } - this._contextMenuService.showContextMenu({ + const menu = this.menuService.createMenu(MenuId.ExplorerWidgetContext, this.contextKeyService); + const primary: IAction[] = []; + const secondary: IAction[] = []; + const result = { primary, secondary }; + createAndFillInContextMenuActions(menu, { shouldForwardArgs: true }, result, this.contextMenuService, g => g === 'inline'); + + this.contextMenuService.showContextMenu({ getAnchor: () => { return { x: event.posx, y: event.posy }; }, - getActions: () => getExplorerActions(element, this._instantiationService, this._capabilitiesService, this._connectionService.connectionInfo), + getActions: () => result.secondary, getActionsContext: () => context }); @@ -167,7 +111,7 @@ export class ExplorerController extends TreeDefaults.DefaultController { } private handleItemDoubleClick(element: IConnectionProfile): void { - this._progressService.showWhile(this._connectionService.changeDatabase(element.databaseName).then(result => { + this.progressService.showWhile(this._connectionService.changeDatabase(element.databaseName).then(result => { this._router.navigate(['database-dashboard']); })); } @@ -370,144 +314,3 @@ export class ExplorerFilter implements tree.IFilter { this._filterString = val; } } - -function getExplorerActions(element: TreeResource, instantiationService: IInstantiationService, capabilitiesService: ICapabilitiesService, info: ConnectionManagementInfo): IAction[] { - const actions: IAction[] = []; - - if (element instanceof ObjectMetadataWrapper) { - if (element.metadataType === MetadataType.View || element.metadataType === MetadataType.Table) { - actions.push(instantiationService.createInstance(ExplorerScriptSelectAction, ScriptSelectAction.ID, ScriptSelectAction.LABEL)); - } - - if (element.metadataType === MetadataType.Table) { - actions.push(instantiationService.createInstance(EditDataAction, EditDataAction.ID, EditDataAction.LABEL)); - } - - if (element.metadataType === MetadataType.SProc && info.connectionProfile.providerName === Constants.mssqlProviderName) { - actions.push(instantiationService.createInstance(ExplorerScriptExecuteAction, ScriptExecuteAction.ID, ScriptExecuteAction.LABEL)); - } - - if ((element.metadataType === MetadataType.SProc || element.metadataType === MetadataType.Function || element.metadataType === MetadataType.View) - && info.connectionProfile.providerName === Constants.mssqlProviderName) { - actions.push(instantiationService.createInstance(ExplorerScriptAlterAction, ScriptAlterAction.ID, ScriptAlterAction.LABEL)); - } - } else { - actions.push(instantiationService.createInstance(CustomExecuteCommandAction, NewQueryAction.ID, NewQueryAction.LABEL)); - actions.push(instantiationService.createInstance(CustomExecuteCommandAction, NewNotebookAction.ID, NewNotebookAction.LABEL)); - - let action: IAction = instantiationService.createInstance(CustomExecuteCommandAction, RestoreAction.ID, RestoreAction.LABEL); - if (capabilitiesService.isFeatureAvailable(action, info)) { - actions.push(action); - } - - action = instantiationService.createInstance(CustomExecuteCommandAction, BackupAction.ID, BackupAction.LABEL); - if (capabilitiesService.isFeatureAvailable(action, info)) { - actions.push(action); - } - - actions.push(instantiationService.createInstance(ExplorerManageAction, ManageAction.ID, ManageAction.LABEL)); - return actions; - } - - actions.push(instantiationService.createInstance(ExplorerScriptCreateAction, ScriptCreateAction.ID, ScriptCreateAction.LABEL)); - - return actions; -} - -class CustomExecuteCommandAction extends ExecuteCommandAction { - run(context: ManageActionContext): Promise { - return super.run(context.profile); - } -} - -class ExplorerScriptSelectAction extends ScriptSelectAction { - constructor( - id: string, label: string, - @IQueryEditorService queryEditorService: IQueryEditorService, - @IConnectionManagementService connectionManagementService: IConnectionManagementService, - @IScriptingService scriptingService: IScriptingService, - @IEditorProgressService private progressService: IEditorProgressService - ) { - super(id, label, queryEditorService, connectionManagementService, scriptingService); - } - - public run(actionContext: BaseActionContext): Promise { - const promise = super.run(actionContext); - this.progressService.showWhile(promise); - return promise; - } -} - -class ExplorerScriptCreateAction extends ScriptCreateAction { - constructor( - id: string, label: string, - @IQueryEditorService queryEditorService: IQueryEditorService, - @IConnectionManagementService connectionManagementService: IConnectionManagementService, - @IScriptingService scriptingService: IScriptingService, - @IErrorMessageService errorMessageService: IErrorMessageService, - @IEditorProgressService private progressService: IEditorProgressService - ) { - super(id, label, queryEditorService, connectionManagementService, scriptingService, errorMessageService); - } - - public run(actionContext: BaseActionContext): Promise { - const promise = super.run(actionContext); - this.progressService.showWhile(promise); - return promise; - } -} - -class ExplorerScriptAlterAction extends ScriptAlterAction { - constructor( - id: string, label: string, - @IQueryEditorService queryEditorService: IQueryEditorService, - @IConnectionManagementService connectionManagementService: IConnectionManagementService, - @IScriptingService scriptingService: IScriptingService, - @IErrorMessageService errorMessageService: IErrorMessageService, - @IEditorProgressService private progressService: IEditorProgressService - ) { - super(id, label, queryEditorService, connectionManagementService, scriptingService, errorMessageService); - } - - public run(actionContext: BaseActionContext): Promise { - const promise = super.run(actionContext); - this.progressService.showWhile(promise); - return promise; - } -} - -class ExplorerScriptExecuteAction extends ScriptExecuteAction { - constructor( - id: string, label: string, - @IQueryEditorService queryEditorService: IQueryEditorService, - @IConnectionManagementService connectionManagementService: IConnectionManagementService, - @IScriptingService scriptingService: IScriptingService, - @IErrorMessageService errorMessageService: IErrorMessageService, - @IEditorProgressService private progressService: IEditorProgressService - ) { - super(id, label, queryEditorService, connectionManagementService, scriptingService, errorMessageService); - } - - public run(actionContext: BaseActionContext): Promise { - const promise = super.run(actionContext); - this.progressService.showWhile(promise); - return promise; - } -} - -class ExplorerManageAction extends ManageAction { - constructor( - id: string, label: string, - @IConnectionManagementService connectionManagementService: IConnectionManagementService, - @IAngularEventingService angularEventingService: IAngularEventingService, - @IEditorProgressService private _progressService: IEditorProgressService - ) { - super(id, label, connectionManagementService, angularEventingService); - } - - public run(actionContext: ManageActionContext): Promise { - const promise = super.run(actionContext); - this._progressService.showWhile(promise); - return promise; - } -} diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeActions.ts b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeActions.ts new file mode 100644 index 0000000000..9d05fd458c --- /dev/null +++ b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeActions.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ManageAction, ManageActionContext } from 'sql/workbench/common/actions'; +import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; +import { IAngularEventingService } from 'sql/platform/angularEventing/common/angularEventingService'; +import { IEditorProgressService } from 'vs/platform/progress/common/progress'; +import { ExecuteCommandAction } from 'vs/platform/actions/common/actions'; + +export class ExplorerManageAction extends ManageAction { + public static readonly ID = 'explorerwidget.manage'; + constructor( + id: string, label: string, + @IConnectionManagementService connectionManagementService: IConnectionManagementService, + @IAngularEventingService angularEventingService: IAngularEventingService, + @IEditorProgressService private _progressService: IEditorProgressService + ) { + super(id, label, connectionManagementService, angularEventingService); + } + + public run(actionContext: ManageActionContext): Promise { + const promise = super.run(actionContext); + this._progressService.showWhile(promise); + return promise; + } +} + +export class CustomExecuteCommandAction extends ExecuteCommandAction { + run(context: ManageActionContext): Promise { + return super.run(context.profile); + } +} diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext.ts b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext.ts new file mode 100644 index 0000000000..dad7f2ccde --- /dev/null +++ b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext.ts @@ -0,0 +1,77 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; +import { MetadataType } from 'sql/platform/connection/common/connectionManagement'; +import { ObjectMetadataWrapper } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/objectMetadataWrapper'; + +export declare type ContextResource = IConnectionProfile | ObjectMetadataWrapper; + +export interface IContextValue { + resource: ContextResource; + providerName: string; + isCloud: boolean; +} + +export class ItemContextKey extends Disposable implements IContextKey { + + static readonly ItemType = new RawContextKey('itemType', undefined); + static readonly Item = new RawContextKey('item', undefined); + static readonly ConnectionProvider = new RawContextKey('provider', undefined); + static readonly IsCloud = new RawContextKey('isCloud', undefined); + + private _itemTypeKey: IContextKey; + private _itemKey: IContextKey; + private _connectionProviderKey: IContextKey; + private _isCloudKey: IContextKey; + + constructor( + @IContextKeyService contextKeyService: IContextKeyService + ) { + super(); + + this._itemTypeKey = ItemContextKey.ItemType.bindTo(contextKeyService); + this._itemKey = ItemContextKey.Item.bindTo(contextKeyService); + this._connectionProviderKey = ItemContextKey.ConnectionProvider.bindTo(contextKeyService); + this._isCloudKey = ItemContextKey.IsCloud.bindTo(contextKeyService); + } + + set(value: IContextValue) { + this._itemKey.set(value); + this._connectionProviderKey.set(value.providerName.toLowerCase()); + this._isCloudKey.set(value.isCloud); + if (value.resource instanceof ObjectMetadataWrapper) { + switch (value.resource.metadataType) { + case MetadataType.Function: + this._itemTypeKey.set('function'); + break; + case MetadataType.SProc: + this._itemTypeKey.set('sproc'); + break; + case MetadataType.Table: + this._itemTypeKey.set('table'); + break; + case MetadataType.View: + this._itemTypeKey.set('view'); + break; + } + } else { + this._itemTypeKey.set('database'); + } + } + + reset(): void { + this._itemTypeKey.reset(); + this._itemKey.reset(); + this._connectionProviderKey.reset(); + this._isCloudKey.reset(); + } + + get(): IContextValue | undefined { + return this._itemKey.get(); + } +} 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 new file mode 100644 index 0000000000..bb193195a4 --- /dev/null +++ b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.common.contribution.ts @@ -0,0 +1,95 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +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 { 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, NewQueryAction } from 'sql/workbench/common/actions'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { NewNotebookAction } from 'sql/workbench/parts/notebook/browser/notebookActions'; + +const explorerSchema: IJSONSchema = { + type: 'object', +}; + +registerDashboardWidget('explorer-widget', '', explorerSchema); + +CommandsRegistry.registerCommand(ExplorerManageAction.ID, (accessor, context) => { + const instantiationService = accessor.get(IInstantiationService); + 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, NewQueryAction.ID, NewQueryAction.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, + title: ExplorerManageAction.LABEL + }, + when: ItemContextKey.ItemType.isEqualTo('database'), + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerNewQueryActionID, + title: NewQueryAction.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/dashboard/browser/widgets/explorer/explorerWidget.component.ts b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.component.ts index 7b1b6314b6..183354a40e 100644 --- a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.component.ts +++ b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.component.ts @@ -12,7 +12,7 @@ import { Router } from '@angular/router'; import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/workbench/parts/dashboard/browser/core/dashboardWidget'; import { CommonServiceInterface } from 'sql/platform/bootstrap/browser/commonServiceInterface.service'; -import { ExplorerFilter, ExplorerRenderer, ExplorerDataSource, ExplorerController, ObjectMetadataWrapper, ExplorerModel } from './explorerTree'; +import { ExplorerFilter, ExplorerRenderer, ExplorerDataSource, ExplorerController, ExplorerModel } from './explorerTree'; import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; @@ -22,12 +22,12 @@ import * as nls from 'vs/nls'; import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { getContentHeight } from 'vs/base/browser/dom'; import { Delayer } from 'vs/base/common/async'; -import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IEditorProgressService } from 'vs/platform/progress/common/progress'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { subscriptionToDisposable } from 'sql/base/browser/lifecycle'; +import { ObjectMetadataWrapper } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/objectMetadataWrapper'; @Component({ selector: 'explorer-widget', @@ -37,14 +37,11 @@ export class ExplorerWidget extends DashboardWidget implements IDashboardWidget, private _input: InputBox; private _tree: Tree; private _filterDelayer = new Delayer(200); - private _treeController = new ExplorerController( + private _treeController = this.instantiationService.createInstance(ExplorerController, this._bootstrap.getUnderlyingUri(), this._bootstrap.connectionManagementService, this._router, - this.contextMenuService, - this.capabilitiesService, - this.instantiationService, - this.progressService + this._bootstrap ); private _treeRenderer = new ExplorerRenderer(); private _treeDataSource = new ExplorerDataSource(); @@ -56,16 +53,14 @@ export class ExplorerWidget extends DashboardWidget implements IDashboardWidget, @ViewChild('table') private _tableContainer: ElementRef; constructor( - @Inject(forwardRef(() => CommonServiceInterface)) private _bootstrap: CommonServiceInterface, - @Inject(forwardRef(() => Router)) private _router: Router, + @Inject(forwardRef(() => CommonServiceInterface)) private readonly _bootstrap: CommonServiceInterface, + @Inject(forwardRef(() => Router)) private readonly _router: Router, @Inject(WIDGET_CONFIG) protected _config: WidgetConfig, - @Inject(forwardRef(() => ElementRef)) private _el: ElementRef, - @Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService, - @Inject(IContextViewService) private contextViewService: IContextViewService, - @Inject(IInstantiationService) private instantiationService: IInstantiationService, - @Inject(IContextMenuService) private contextMenuService: IContextMenuService, - @Inject(ICapabilitiesService) private capabilitiesService: ICapabilitiesService, - @Inject(IEditorProgressService) private progressService: IEditorProgressService + @Inject(forwardRef(() => ElementRef)) private readonly _el: ElementRef, + @Inject(IWorkbenchThemeService) private readonly themeService: IWorkbenchThemeService, + @Inject(IContextViewService) private readonly contextViewService: IContextViewService, + @Inject(IInstantiationService) private readonly instantiationService: IInstantiationService, + @Inject(ICapabilitiesService) private readonly capabilitiesService: ICapabilitiesService ) { super(); this.init(); diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.contribution.ts b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.contribution.ts deleted file mode 100644 index 03e5e6db54..0000000000 --- a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.contribution.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IJSONSchema } from 'vs/base/common/jsonSchema'; -import { registerDashboardWidget } from 'sql/platform/dashboard/browser/widgetRegistry'; - -const explorerSchema: IJSONSchema = { - type: 'object', -}; - -registerDashboardWidget('explorer-widget', '', explorerSchema); \ No newline at end of file diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/objectMetadataWrapper.ts b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/objectMetadataWrapper.ts new file mode 100644 index 0000000000..fcc04b6cd3 --- /dev/null +++ b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/objectMetadataWrapper.ts @@ -0,0 +1,68 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { MetadataType } from 'sql/platform/connection/common/connectionManagement'; +import { ObjectMetadata } from 'azdata'; + +export class ObjectMetadataWrapper implements ObjectMetadata { + public metadataType: MetadataType; + public metadataTypeName: string; + public urn: string; + public name: string; + public schema: string; + + constructor(from?: ObjectMetadata) { + if (from) { + this.metadataType = from.metadataType; + this.metadataTypeName = from.metadataTypeName; + this.urn = from.urn; + this.name = from.name; + this.schema = from.schema; + } + } + + public matches(other: ObjectMetadataWrapper): boolean { + if (!other) { + return false; + } + + return this.metadataType === other.metadataType + && this.schema === other.schema + && this.name === other.name; + } + + public static createFromObjectMetadata(objectMetadata: ObjectMetadata[]): ObjectMetadataWrapper[] { + if (!objectMetadata) { + return undefined; + } + + return objectMetadata.map(m => new ObjectMetadataWrapper(m)); + } + + // custom sort : Table > View > Stored Procedures > Function + public static sort(metadata1: ObjectMetadataWrapper, metadata2: ObjectMetadataWrapper): number { + // compare the object type + if (metadata1.metadataType < metadata2.metadataType) { + return -1; + } else if (metadata1.metadataType > metadata2.metadataType) { + return 1; + + // otherwise compare the schema + } else { + const schemaCompare: number = metadata1.schema && metadata2.schema + ? metadata1.schema.localeCompare(metadata2.schema) + // schemas are not expected to be undefined, but if they are then compare using object names + : 0; + + if (schemaCompare !== 0) { + return schemaCompare; + + // otherwise compare the object name + } else { + return metadata1.name.localeCompare(metadata2.name); + } + } + } +} \ No newline at end of file diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/insights/actions.ts b/src/sql/workbench/parts/dashboard/browser/widgets/insights/actions.ts index 32c466b844..a4a0566c87 100644 --- a/src/sql/workbench/parts/dashboard/browser/widgets/insights/actions.ts +++ b/src/sql/workbench/parts/dashboard/browser/widgets/insights/actions.ts @@ -6,7 +6,7 @@ import { Action } from 'vs/base/common/actions'; import * as nls from 'vs/nls'; -import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; import { RunQueryOnConnectionMode, IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; import { InsightActionContext } from 'sql/workbench/common/actions'; diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/insights/insightsWidget.contribution.ts b/src/sql/workbench/parts/dashboard/browser/widgets/insights/insightsWidget.contribution.ts index f9a9e9317c..3f1052c59b 100644 --- a/src/sql/workbench/parts/dashboard/browser/widgets/insights/insightsWidget.contribution.ts +++ b/src/sql/workbench/parts/dashboard/browser/widgets/insights/insightsWidget.contribution.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { join } from 'path'; +import { join } from 'vs/base/common/path'; import { registerDashboardWidget, registerNonCustomDashboardWidget } from 'sql/platform/dashboard/browser/widgetRegistry'; import { Extensions as InsightExtensions, IInsightRegistry } from 'sql/platform/dashboard/browser/insightRegistry'; diff --git a/src/sql/workbench/parts/dashboard/electron-browser/widgets/explorer/explorerTreeActions.ts b/src/sql/workbench/parts/dashboard/electron-browser/widgets/explorer/explorerTreeActions.ts new file mode 100644 index 0000000000..19b627806e --- /dev/null +++ b/src/sql/workbench/parts/dashboard/electron-browser/widgets/explorer/explorerTreeActions.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 { ScriptSelectAction, ScriptCreateAction, ScriptAlterAction, ScriptExecuteAction } from 'sql/workbench/electron-browser/scriptingActions'; +import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; +import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; +import { IScriptingService } from 'sql/platform/scripting/common/scriptingService'; +import { IEditorProgressService, IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; +import { BaseActionContext } from 'sql/workbench/common/actions'; +import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; + +export class ExplorerScriptSelectAction extends ScriptSelectAction { + constructor( + id: string, label: string, + @IQueryEditorService queryEditorService: IQueryEditorService, + @IConnectionManagementService connectionManagementService: IConnectionManagementService, + @IScriptingService scriptingService: IScriptingService, + @IProgressService private readonly progressService: IProgressService + ) { + super(id, label, queryEditorService, connectionManagementService, scriptingService); + } + + public run(actionContext: BaseActionContext): Promise { + return this.progressService.withProgress({ location: ProgressLocation.Window }, () => super.run(actionContext)); + } +} + +export class ExplorerScriptCreateAction extends ScriptCreateAction { + constructor( + id: string, label: string, + @IQueryEditorService queryEditorService: IQueryEditorService, + @IConnectionManagementService connectionManagementService: IConnectionManagementService, + @IScriptingService scriptingService: IScriptingService, + @IErrorMessageService errorMessageService: IErrorMessageService, + @IProgressService private readonly progressService: IProgressService + ) { + super(id, label, queryEditorService, connectionManagementService, scriptingService, errorMessageService); + } + + public run(actionContext: BaseActionContext): Promise { + return this.progressService.withProgress({ location: ProgressLocation.Window }, () => super.run(actionContext)); + } +} + +export class ExplorerScriptAlterAction extends ScriptAlterAction { + constructor( + id: string, label: string, + @IQueryEditorService queryEditorService: IQueryEditorService, + @IConnectionManagementService connectionManagementService: IConnectionManagementService, + @IScriptingService scriptingService: IScriptingService, + @IErrorMessageService errorMessageService: IErrorMessageService, + @IProgressService private readonly progressService: IProgressService + ) { + super(id, label, queryEditorService, connectionManagementService, scriptingService, errorMessageService); + } + + public run(actionContext: BaseActionContext): Promise { + return this.progressService.withProgress({ location: ProgressLocation.Window }, () => super.run(actionContext)); + } +} + +export class ExplorerScriptExecuteAction extends ScriptExecuteAction { + constructor( + id: string, label: string, + @IQueryEditorService queryEditorService: IQueryEditorService, + @IConnectionManagementService connectionManagementService: IConnectionManagementService, + @IScriptingService scriptingService: IScriptingService, + @IErrorMessageService errorMessageService: IErrorMessageService, + @IProgressService private readonly progressService: IProgressService + ) { + super(id, label, queryEditorService, connectionManagementService, scriptingService, errorMessageService); + } + + public run(actionContext: BaseActionContext): Promise { + return this.progressService.withProgress({ location: ProgressLocation.Window }, () => super.run(actionContext)); + } +} diff --git a/src/sql/workbench/parts/dashboard/electron-browser/widgets/explorer/explorerWidget.contribution.ts b/src/sql/workbench/parts/dashboard/electron-browser/widgets/explorer/explorerWidget.contribution.ts new file mode 100644 index 0000000000..1fc5ad098c --- /dev/null +++ b/src/sql/workbench/parts/dashboard/electron-browser/widgets/explorer/explorerWidget.contribution.ts @@ -0,0 +1,109 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; +import { ExplorerScriptSelectAction, ExplorerScriptExecuteAction, ExplorerScriptAlterAction, ExplorerScriptCreateAction } from 'sql/workbench/parts/dashboard/electron-browser/widgets/explorer/explorerTreeActions'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ItemContextKey } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { EditDataAction } from 'sql/workbench/electron-browser/scriptingActions'; + +CommandsRegistry.registerCommand(ExplorerScriptSelectAction.ID, (accessor, context) => { + const instantiationService = accessor.get(IInstantiationService); + instantiationService.createInstance(ExplorerScriptSelectAction, ExplorerScriptSelectAction.ID, ExplorerScriptSelectAction.LABEL).run(context); +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerScriptSelectAction.ID, + title: ExplorerScriptSelectAction.LABEL + }, + when: ItemContextKey.ItemType.isEqualTo('view'), + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerScriptSelectAction.ID, + title: ExplorerScriptSelectAction.LABEL + }, + when: ItemContextKey.ItemType.isEqualTo('table'), + order: 2 +}); + +const ExplorerEditDataActionID = 'explorer.editData'; +CommandsRegistry.registerCommand(ExplorerEditDataActionID, (accessor, context) => { + const instantiationService = accessor.get(IInstantiationService); + instantiationService.createInstance(EditDataAction, EditDataAction.ID, EditDataAction.LABEL).run(context); +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerEditDataActionID, + title: EditDataAction.LABEL + }, + when: ItemContextKey.ItemType.isEqualTo('table'), + order: 2 +}); + +CommandsRegistry.registerCommand(ExplorerScriptExecuteAction.ID, (accessor, context) => { + const instantiationService = accessor.get(IInstantiationService); + instantiationService.createInstance(ExplorerScriptExecuteAction, ExplorerScriptExecuteAction.ID, ExplorerScriptExecuteAction.LABEL).run(context); +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerScriptExecuteAction.ID, + title: ExplorerScriptExecuteAction.LABEL + }, + when: ItemContextKey.ItemType.isEqualTo('sproc'), + order: 2 +}); + +CommandsRegistry.registerCommand(ExplorerScriptAlterAction.ID, (accessor, context) => { + const instantiationService = accessor.get(IInstantiationService); + instantiationService.createInstance(ExplorerScriptAlterAction, ExplorerScriptAlterAction.ID, ExplorerScriptAlterAction.LABEL).run(context); +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerScriptAlterAction.ID, + title: ExplorerScriptAlterAction.LABEL + }, + when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('sproc'), ItemContextKey.ConnectionProvider.isEqualTo('mssql')), + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerScriptAlterAction.ID, + title: ExplorerScriptAlterAction.LABEL + }, + when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('function'), ItemContextKey.ConnectionProvider.isEqualTo('mssql')), + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerScriptAlterAction.ID, + title: ExplorerScriptAlterAction.LABEL + }, + when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('view'), ItemContextKey.ConnectionProvider.isEqualTo('mssql')), + order: 2 +}); + +CommandsRegistry.registerCommand(ExplorerScriptCreateAction.ID, (accessor, context) => { + const instantiationService = accessor.get(IInstantiationService); + instantiationService.createInstance(ExplorerScriptCreateAction, ExplorerScriptCreateAction.ID, ExplorerScriptCreateAction.LABEL).run(context); +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { + command: { + id: ExplorerScriptCreateAction.ID, + title: ExplorerScriptCreateAction.LABEL + }, + order: 2 +}); diff --git a/src/sql/workbench/parts/dashboard/test/electron-browser/explorerWidget.component.test.ts b/src/sql/workbench/parts/dashboard/test/electron-browser/explorerWidget.component.test.ts index 83fcb43d5a..6a7d027d9b 100644 --- a/src/sql/workbench/parts/dashboard/test/electron-browser/explorerWidget.component.test.ts +++ b/src/sql/workbench/parts/dashboard/test/electron-browser/explorerWidget.component.test.ts @@ -3,10 +3,10 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ObjectMetadataWrapper } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTree'; import { MetadataType } from 'sql/platform/connection/common/connectionManagement'; import * as assert from 'assert'; +import { ObjectMetadataWrapper } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/objectMetadataWrapper'; suite('Explorer Widget Tests', () => { test('Sorting dashboard search objects works correctly', () => { diff --git a/src/sql/workbench/parts/dataExplorer/common/mssqlNodeContext.ts b/src/sql/workbench/parts/dataExplorer/common/mssqlNodeContext.ts index 939671b554..113ea9ccfc 100644 --- a/src/sql/workbench/parts/dataExplorer/common/mssqlNodeContext.ts +++ b/src/sql/workbench/parts/dataExplorer/common/mssqlNodeContext.ts @@ -3,7 +3,6 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as os from 'os'; import { INodeContextValue } from 'sql/workbench/parts/dataExplorer/common/nodeContext'; import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -13,6 +12,7 @@ import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilit import { mssqlProviderName } from 'sql/platform/connection/common/constants'; import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; import { ExtensionNodeType } from 'sql/workbench/api/common/sqlExtHostTypes'; +import { isWindows } from 'vs/base/common/platform'; export class MssqlNodeContext extends Disposable { @@ -28,7 +28,7 @@ export class MssqlNodeContext extends Disposable { // General node context keys static NodeProvider = new RawContextKey('nodeProvider', undefined); static IsDatabaseOrServer = new RawContextKey('isDatabaseOrServer', false); - static IsWindows = new RawContextKey('isWindows', os.platform() === 'win32'); + static IsWindows = new RawContextKey('isWindows', isWindows); static IsCloud = new RawContextKey('isCloud', false); static NodeType = new RawContextKey('nodeType', undefined); static NodeLabel = new RawContextKey('nodeLabel', undefined); diff --git a/src/sql/workbench/parts/dataExplorer/common/nodeActions.common.contribution.ts b/src/sql/workbench/parts/dataExplorer/common/nodeActions.common.contribution.ts new file mode 100644 index 0000000000..68e1bbaa5a --- /dev/null +++ b/src/sql/workbench/parts/dataExplorer/common/nodeActions.common.contribution.ts @@ -0,0 +1,213 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { mssqlProviderName } from 'sql/platform/connection/common/constants'; +import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; +import { + DISCONNECT_COMMAND_ID, MANAGE_COMMAND_ID, NEW_QUERY_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 +} from './nodeCommands.common'; +import { ContextKeyExpr, ContextKeyRegexExpr, 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'; + + +// Disconnect +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 4, + command: { + id: DISCONNECT_COMMAND_ID, + title: localize('disconnect', "Disconnect") + }, + when: ContextKeyExpr.and(NodeContextKey.IsConnected, + ContextKeyNotEqualsExpr.create('nodeType', NodeType.Folder)) +}); + +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 3, + command: { + id: DISCONNECT_COMMAND_ID, + title: localize('disconnect', "Disconnect") + }, + when: ContextKeyExpr.and(NodeContextKey.IsConnected, + MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.IsDatabaseOrServer) +}); + +// New Query +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 2, + command: { + id: NEW_QUERY_COMMAND_ID, + title: localize('newQuery', "New Query") + }, + when: MssqlNodeContext.IsDatabaseOrServer +}); + +// Manage +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 1, + command: { + id: MANAGE_COMMAND_ID, + title: localize('manage', "Manage") + }, + when: MssqlNodeContext.IsDatabaseOrServer +}); + + +// Refresh +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 6, + command: { + id: REFRESH_COMMAND_ID, + title: localize('refresh', "Refresh") + }, + 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/electron-browser/nodeCommands.ts b/src/sql/workbench/parts/dataExplorer/common/nodeCommands.common.ts similarity index 79% rename from src/sql/workbench/parts/dataExplorer/electron-browser/nodeCommands.ts rename to src/sql/workbench/parts/dataExplorer/common/nodeCommands.common.ts index f4c2f96942..6841535f89 100644 --- a/src/sql/workbench/parts/dataExplorer/electron-browser/nodeCommands.ts +++ b/src/sql/workbench/parts/dataExplorer/common/nodeCommands.common.ts @@ -175,3 +175,52 @@ CommandsRegistry.registerCommand({ 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/dataExplorer/common/nodeContextUtils.ts b/src/sql/workbench/parts/dataExplorer/common/nodeContextUtils.ts index 2772c30c54..dbd1466ac8 100644 --- a/src/sql/workbench/parts/dataExplorer/common/nodeContextUtils.ts +++ b/src/sql/workbench/parts/dataExplorer/common/nodeContextUtils.ts @@ -3,7 +3,6 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as os from 'os'; import { INodeContextValue } from 'sql/workbench/parts/dataExplorer/common/nodeContext'; import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -13,6 +12,7 @@ import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilit import { mssqlProviderName } from 'sql/platform/connection/common/constants'; import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; import { ExtensionNodeType } from 'sql/workbench/api/common/sqlExtHostTypes'; +import { isWindows } from 'vs/base/common/platform'; export class NodeContextUtils extends Disposable { @@ -28,7 +28,7 @@ export class NodeContextUtils extends Disposable { // General node context keys static NodeProvider = new RawContextKey('nodeProvider', undefined); static IsDatabaseOrServer = new RawContextKey('isDatabaseOrServer', false); - static IsWindows = new RawContextKey('isWindows', os.platform() === 'win32'); + static IsWindows = new RawContextKey('isWindows', isWindows); static IsCloud = new RawContextKey('isCloud', false); static NodeType = new RawContextKey('nodeType', undefined); static NodeLabel = new RawContextKey('nodeLabel', undefined); diff --git a/src/sql/workbench/parts/dataExplorer/electron-browser/nodeActions.contribution.ts b/src/sql/workbench/parts/dataExplorer/electron-browser/nodeActions.contribution.ts index 76977ab650..17da35eef0 100644 --- a/src/sql/workbench/parts/dataExplorer/electron-browser/nodeActions.contribution.ts +++ b/src/sql/workbench/parts/dataExplorer/electron-browser/nodeActions.contribution.ts @@ -3,221 +3,10 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -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, NEW_QUERY_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 -} from './nodeCommands'; -import { - PROFILER_COMMAND_ID, GENERATE_SCRIPTS_COMMAND_ID, PROPERTIES_COMMAND_ID, - SCRIPT_AS_CREATE_COMMAND_ID, SCRIPT_AS_DELETE_COMMAND_ID, SCRIPT_AS_SELECT_COMMAND_ID, - SCRIPT_AS_EXECUTE_COMMAND_ID, SCRIPT_AS_ALTER_COMMAND_ID, EDIT_DATA_COMMAND_ID -} from 'sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShimActions'; -import { ContextKeyExpr, ContextKeyRegexExpr, ContextKeyNotEqualsExpr } from 'vs/platform/contextkey/common/contextkey'; -import { NodeContextKey } from 'sql/workbench/parts/dataExplorer/common/nodeContext'; +import { SCRIPT_AS_CREATE_COMMAND_ID, SCRIPT_AS_DELETE_COMMAND_ID, SCRIPT_AS_SELECT_COMMAND_ID, SCRIPT_AS_EXECUTE_COMMAND_ID, SCRIPT_AS_ALTER_COMMAND_ID, EDIT_DATA_COMMAND_ID } from 'sql/workbench/parts/dataExplorer/electron-browser/nodeCommand'; import { MssqlNodeContext } from 'sql/workbench/parts/dataExplorer/common/mssqlNodeContext'; -import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; - - -// Disconnect -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'connection', - order: 4, - command: { - id: DISCONNECT_COMMAND_ID, - title: localize('disconnect', "Disconnect") - }, - when: ContextKeyExpr.and(NodeContextKey.IsConnected, - ContextKeyNotEqualsExpr.create('nodeType', NodeType.Folder)) -}); - -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'connection', - order: 3, - command: { - id: DISCONNECT_COMMAND_ID, - title: localize('disconnect', "Disconnect") - }, - when: ContextKeyExpr.and(NodeContextKey.IsConnected, - MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.IsDatabaseOrServer) -}); - -// New Query -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'connection', - order: 2, - command: { - id: NEW_QUERY_COMMAND_ID, - title: localize('newQuery', "New Query") - }, - when: MssqlNodeContext.IsDatabaseOrServer -}); - -// Manage -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'connection', - order: 1, - command: { - id: MANAGE_COMMAND_ID, - title: localize('manage', "Manage") - }, - when: MssqlNodeContext.IsDatabaseOrServer -}); - - -// Refresh -MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { - group: 'connection', - order: 6, - command: { - id: REFRESH_COMMAND_ID, - title: localize('refresh', "Refresh") - }, - 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)$/)) -}); - -//////////////// Scripting Actions ///////////////// +import { localize } from 'vs/nls'; // Script as Create MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { diff --git a/src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShimActions.ts b/src/sql/workbench/parts/dataExplorer/electron-browser/nodeCommand.ts similarity index 76% rename from src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShimActions.ts rename to src/sql/workbench/parts/dataExplorer/electron-browser/nodeCommand.ts index 6955867c6b..fa18b562f0 100644 --- a/src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShimActions.ts +++ b/src/sql/workbench/parts/dataExplorer/electron-browser/nodeCommand.ts @@ -3,23 +3,20 @@ * 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 { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; -import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; -import { TreeViewItemHandleArg } from 'sql/workbench/common/views'; -import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; -import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; +import { VIEWLET_ID } from 'sql/workbench/parts/dataExplorer/browser/dataExplorerExtensionPoint'; import { IScriptingService } from 'sql/platform/scripting/common/scriptingService'; import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { TreeViewItemHandleArg } from 'sql/workbench/common/views'; +import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; +import { IOEShimService } from 'sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim'; +import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; +import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { IProgressService } from 'vs/platform/progress/common/progress'; -import { ScriptCreateAction, BaseActionContext, ScriptDeleteAction, ScriptSelectAction, ScriptExecuteAction, ScriptAlterAction, EditDataAction } from 'sql/workbench/common/actions'; -import { VIEWLET_ID } from 'sql/workbench/parts/dataExplorer/browser/dataExplorerExtensionPoint'; +import { BaseActionContext } from 'sql/workbench/common/actions'; +import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; +import { ScriptCreateAction, ScriptDeleteAction, ScriptSelectAction, ScriptExecuteAction, ScriptAlterAction, EditDataAction } from 'sql/workbench/electron-browser/scriptingActions'; -export const PROFILER_COMMAND_ID = 'dataExplorer.profiler'; -export const GENERATE_SCRIPTS_COMMAND_ID = 'dataExplorer.generateScripts'; -export const PROPERTIES_COMMAND_ID = 'dataExplorer.properties'; export const SCRIPT_AS_CREATE_COMMAND_ID = 'dataExplorer.scriptAsCreate'; export const SCRIPT_AS_DELETE_COMMAND_ID = 'dataExplorer.scriptAsDelete'; export const SCRIPT_AS_SELECT_COMMAND_ID = 'dataExplorer.scriptAsSelect'; @@ -27,57 +24,6 @@ export const SCRIPT_AS_EXECUTE_COMMAND_ID = 'dataExplorer.scriptAsExecute'; export const SCRIPT_AS_ALTER_COMMAND_ID = 'dataExplorer.scriptAsAlter'; export const EDIT_DATA_COMMAND_ID = 'dataExplorer.scriptAsAlter'; -// 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); - } -}); - -//////////////// Scripting Actions ///////////////// - // Script as Create CommandsRegistry.registerCommand({ id: SCRIPT_AS_CREATE_COMMAND_ID, diff --git a/src/sql/workbench/parts/notebook/browser/cellViews/linkHandler.directive.ts b/src/sql/workbench/parts/notebook/browser/cellViews/linkHandler.directive.ts index 7245ed653d..6654116759 100644 --- a/src/sql/workbench/parts/notebook/browser/cellViews/linkHandler.directive.ts +++ b/src/sql/workbench/parts/notebook/browser/cellViews/linkHandler.directive.ts @@ -5,14 +5,12 @@ import { Directive, Inject, HostListener, Input } from '@angular/core'; -import * as types from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { onUnexpectedError } from 'vs/base/common/errors'; -import product from 'vs/platform/product/node/product'; import { INotebookService } from 'sql/workbench/services/notebook/common/notebookService'; -const knownSchemes = new Set(['http', 'https', 'file', 'mailto', 'data', `${product.urlProtocol}`, 'azuredatastudio', 'azuredatastudio-insiders', 'vscode', 'vscode-insiders', 'vscode-resource']); +const knownSchemes = new Set(['http', 'https', 'file', 'mailto', 'data', 'azuredatastudio', 'azuredatastudio-insiders', 'vscode', 'vscode-insiders', 'vscode-resource']); @Directive({ selector: '[link-handler]', }) diff --git a/src/sql/workbench/parts/notebook/browser/notebook.contribution.ts b/src/sql/workbench/parts/notebook/browser/notebook.common.contribution.ts similarity index 95% rename from src/sql/workbench/parts/notebook/browser/notebook.contribution.ts rename to src/sql/workbench/parts/notebook/browser/notebook.common.contribution.ts index 17d85c97bc..4fffecf371 100644 --- a/src/sql/workbench/parts/notebook/browser/notebook.contribution.ts +++ b/src/sql/workbench/parts/notebook/browser/notebook.common.contribution.ts @@ -19,7 +19,6 @@ import { GridOutputComponent } from 'sql/workbench/parts/notebook/browser/output import { PlotlyOutputComponent } from 'sql/workbench/parts/notebook/browser/outputs/plotlyOutput.component'; import { registerComponentType } from 'sql/workbench/parts/notebook/browser/outputs/mimeRegistry'; import { MimeRendererComponent } from 'sql/workbench/parts/notebook/browser/outputs/mimeRenderer.component'; -import { MarkdownOutputComponent } from 'sql/workbench/parts/notebook/browser/outputs/markdownOutput.component'; 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'; @@ -175,17 +174,6 @@ registerComponentType({ selector: MimeRendererComponent.SELECTOR }); -/** - * A mime renderer component for Markdown. - */ -registerComponentType({ - mimeTypes: ['text/markdown'], - rank: 60, - safe: true, - ctor: MarkdownOutputComponent, - selector: MarkdownOutputComponent.SELECTOR -}); - /** * A mime renderer component for Plotly graphs. */ diff --git a/src/sql/workbench/parts/notebook/browser/notebook.component.ts b/src/sql/workbench/parts/notebook/browser/notebook.component.ts index 15dca69885..a33b8942af 100644 --- a/src/sql/workbench/parts/notebook/browser/notebook.component.ts +++ b/src/sql/workbench/parts/notebook/browser/notebook.component.ts @@ -34,7 +34,7 @@ import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar'; import { KernelsDropdown, AttachToDropdown, AddCellAction, TrustedAction, RunAllCellsAction, ClearAllOutputsAction } from 'sql/workbench/parts/notebook/browser/notebookActions'; import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; -import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes'; import { IConnectionDialogService } from 'sql/workbench/services/connection/common/connectionDialogService'; import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; @@ -54,7 +54,7 @@ import { Button } from 'sql/base/browser/ui/button/button'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { IBootstrapParams } from 'sql/platform/bootstrap/common/bootstrapParams'; import { getErrorMessage } from 'vs/base/common/errors'; -import product from 'vs/platform/product/node/product'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; export const NOTEBOOK_SELECTOR: string = 'notebook-component'; @@ -104,7 +104,8 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe @Inject(ICapabilitiesService) private capabilitiesService: ICapabilitiesService, @Inject(ITextFileService) private textFileService: ITextFileService, @Inject(ILogService) private readonly logService: ILogService, - @Inject(ITelemetryService) private telemetryService: ITelemetryService + @Inject(ITelemetryService) private telemetryService: ITelemetryService, + @Inject(IEnvironmentService) private readonly environmentService: IEnvironmentService ) { super(); this.updateProfile(); @@ -441,7 +442,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe protected initNavSection(): void { this._navProvider = this.notebookService.getNavigationProvider(this._notebookParams.notebookUri); - if (product.quality !== 'stable' && + if (this.environmentService.appQuality !== 'stable' && this.contextKeyService.getContextKeyValue('bookOpened') && this._navProvider) { this._navProvider.getNavigation(this._notebookParams.notebookUri).then(result => { diff --git a/src/sql/workbench/parts/notebook/browser/notebook.module.ts b/src/sql/workbench/parts/notebook/browser/notebook.module.ts index 389dc0d21c..fcd93bad4f 100644 --- a/src/sql/workbench/parts/notebook/browser/notebook.module.ts +++ b/src/sql/workbench/parts/notebook/browser/notebook.module.ts @@ -16,7 +16,6 @@ import { NotebookComponent } from 'sql/workbench/parts/notebook/browser/notebook import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { CodeComponent } from 'sql/workbench/parts/notebook/browser/cellViews/code.component'; import { CodeCellComponent } from 'sql/workbench/parts/notebook/browser/cellViews/codeCell.component'; -import { TextCellComponent } from 'sql/workbench/parts/notebook/browser/cellViews/textCell.component'; import { OutputAreaComponent } from 'sql/workbench/parts/notebook/browser/cellViews/outputArea.component'; import { OutputComponent } from 'sql/workbench/parts/notebook/browser/cellViews/output.component'; import { StdInComponent } from 'sql/workbench/parts/notebook/browser/cellViews/stdin.component'; @@ -29,12 +28,16 @@ import { IMimeComponentRegistry, Extensions } from 'sql/workbench/parts/notebook import { Registry } from 'vs/platform/registry/common/platform'; import { LinkHandlerDirective } from 'sql/workbench/parts/notebook/browser/cellViews/linkHandler.directive'; import { IBootstrapParams, ISelector } from 'sql/platform/bootstrap/common/bootstrapParams'; +import { ICellComponenetRegistry, Extensions as OutputComponentExtensions } from 'sql/platform/notebooks/common/outputRegistry'; + +const outputComponentRegistry = Registry.as(OutputComponentExtensions.CellComponentContributions); export const NotebookModule = (params, selector: string, instantiationService: IInstantiationService): any => { let outputComponents = Registry.as(Extensions.MimeComponentContribution).getAllCtors(); @NgModule({ declarations: [ + ...outputComponentRegistry.getComponents(), Checkbox, SelectBox, EditableDropDown, @@ -42,7 +45,6 @@ export const NotebookModule = (params, selector: string, instantiationService: I LoadingSpinner, CodeComponent, CodeCellComponent, - TextCellComponent, PlaceholderCellComponent, NotebookComponent, ComponentHostDirective, diff --git a/src/sql/workbench/parts/notebook/common/models/notebookUtils.ts b/src/sql/workbench/parts/notebook/common/models/notebookUtils.ts index 86e95a0325..11b8325ff6 100644 --- a/src/sql/workbench/parts/notebook/common/models/notebookUtils.ts +++ b/src/sql/workbench/parts/notebook/common/models/notebookUtils.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; +import * as path from 'vs/base/common/path'; import { nb } from 'azdata'; import { DEFAULT_NOTEBOOK_PROVIDER, DEFAULT_NOTEBOOK_FILETYPE, INotebookService } from 'sql/workbench/services/notebook/common/notebookService'; import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; diff --git a/src/sql/workbench/parts/notebook/browser/cellViews/media/highlight.css b/src/sql/workbench/parts/notebook/electron-browser/cellViews/media/highlight.css similarity index 100% rename from src/sql/workbench/parts/notebook/browser/cellViews/media/highlight.css rename to src/sql/workbench/parts/notebook/electron-browser/cellViews/media/highlight.css diff --git a/src/sql/workbench/parts/notebook/browser/cellViews/media/markdown.css b/src/sql/workbench/parts/notebook/electron-browser/cellViews/media/markdown.css similarity index 100% rename from src/sql/workbench/parts/notebook/browser/cellViews/media/markdown.css rename to src/sql/workbench/parts/notebook/electron-browser/cellViews/media/markdown.css diff --git a/src/sql/workbench/parts/notebook/browser/cellViews/textCell.component.html b/src/sql/workbench/parts/notebook/electron-browser/cellViews/textCell.component.html similarity index 100% rename from src/sql/workbench/parts/notebook/browser/cellViews/textCell.component.html rename to src/sql/workbench/parts/notebook/electron-browser/cellViews/textCell.component.html diff --git a/src/sql/workbench/parts/notebook/browser/cellViews/textCell.component.ts b/src/sql/workbench/parts/notebook/electron-browser/cellViews/textCell.component.ts similarity index 99% rename from src/sql/workbench/parts/notebook/browser/cellViews/textCell.component.ts rename to src/sql/workbench/parts/notebook/electron-browser/cellViews/textCell.component.ts index a511292c5f..0ed0a4b11b 100644 --- a/src/sql/workbench/parts/notebook/browser/cellViews/textCell.component.ts +++ b/src/sql/workbench/parts/notebook/electron-browser/cellViews/textCell.component.ts @@ -7,7 +7,6 @@ import 'vs/css!./media/markdown'; import 'vs/css!./media/highlight'; import { OnInit, Component, Input, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnChanges, SimpleChange, HostListener } from '@angular/core'; -import * as path from 'path'; import { localize } from 'vs/nls'; import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; @@ -22,7 +21,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { toDisposable } from 'vs/base/common/lifecycle'; import { IMarkdownRenderResult } from 'vs/editor/contrib/markdown/markdownRenderer'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { NotebookMarkdownRenderer } from 'sql/workbench/parts/notebook/browser/outputs/notebookMarkdown'; +import { NotebookMarkdownRenderer } from 'sql/workbench/parts/notebook/electron-browser/outputs/notebookMarkdown'; import { CellView } from 'sql/workbench/parts/notebook/browser/cellViews/interfaces'; import { ICellModel } from 'sql/workbench/parts/notebook/common/models/modelInterfaces'; import { NotebookModel } from 'sql/workbench/parts/notebook/common/models/notebookModel'; diff --git a/src/sql/workbench/parts/notebook/browser/cellViews/textCell.css b/src/sql/workbench/parts/notebook/electron-browser/cellViews/textCell.css similarity index 100% rename from src/sql/workbench/parts/notebook/browser/cellViews/textCell.css rename to src/sql/workbench/parts/notebook/electron-browser/cellViews/textCell.css diff --git a/src/sql/workbench/parts/notebook/electron-browser/notebook.contribution.ts b/src/sql/workbench/parts/notebook/electron-browser/notebook.contribution.ts new file mode 100644 index 0000000000..9c454fc4f1 --- /dev/null +++ b/src/sql/workbench/parts/notebook/electron-browser/notebook.contribution.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { registerComponentType } from 'sql/workbench/parts/notebook/browser/outputs/mimeRegistry'; +import { MarkdownOutputComponent } from 'sql/workbench/parts/notebook/electron-browser/outputs/markdownOutput.component'; +import { registerCellComponent } from 'sql/platform/notebooks/common/outputRegistry'; +import { TextCellComponent } from 'sql/workbench/parts/notebook/electron-browser/cellViews/textCell.component'; + +/** + * A mime renderer component for Markdown. + */ +registerComponentType({ + mimeTypes: ['text/markdown'], + rank: 60, + safe: true, + ctor: MarkdownOutputComponent, + selector: MarkdownOutputComponent.SELECTOR +}); + +registerCellComponent(TextCellComponent); \ No newline at end of file diff --git a/src/sql/workbench/parts/notebook/browser/outputs/markdownOutput.component.html b/src/sql/workbench/parts/notebook/electron-browser/outputs/markdownOutput.component.html similarity index 100% rename from src/sql/workbench/parts/notebook/browser/outputs/markdownOutput.component.html rename to src/sql/workbench/parts/notebook/electron-browser/outputs/markdownOutput.component.html diff --git a/src/sql/workbench/parts/notebook/browser/outputs/markdownOutput.component.ts b/src/sql/workbench/parts/notebook/electron-browser/outputs/markdownOutput.component.ts similarity index 99% rename from src/sql/workbench/parts/notebook/browser/outputs/markdownOutput.component.ts rename to src/sql/workbench/parts/notebook/electron-browser/outputs/markdownOutput.component.ts index fd77c7fb5a..8d9f447718 100644 --- a/src/sql/workbench/parts/notebook/browser/outputs/markdownOutput.component.ts +++ b/src/sql/workbench/parts/notebook/electron-browser/outputs/markdownOutput.component.ts @@ -15,7 +15,7 @@ import { IMimeComponent } from 'sql/workbench/parts/notebook/browser/outputs/mim import { INotebookService } from 'sql/workbench/services/notebook/common/notebookService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { NotebookMarkdownRenderer } from 'sql/workbench/parts/notebook/browser/outputs/notebookMarkdown'; +import { NotebookMarkdownRenderer } from 'sql/workbench/parts/notebook/electron-browser/outputs/notebookMarkdown'; import { MimeModel } from 'sql/workbench/parts/notebook/common/models/mimemodel'; import { ICellModel } from 'sql/workbench/parts/notebook/common/models/modelInterfaces'; import { useInProcMarkdown, convertVscodeResourceToFileInSubDirectories } from 'sql/workbench/parts/notebook/common/models/notebookUtils'; diff --git a/src/sql/workbench/parts/notebook/browser/outputs/notebookMarkdown.ts b/src/sql/workbench/parts/notebook/electron-browser/outputs/notebookMarkdown.ts similarity index 98% rename from src/sql/workbench/parts/notebook/browser/outputs/notebookMarkdown.ts rename to src/sql/workbench/parts/notebook/electron-browser/outputs/notebookMarkdown.ts index 3594e5863e..d2de8f9d4c 100644 --- a/src/sql/workbench/parts/notebook/browser/outputs/notebookMarkdown.ts +++ b/src/sql/workbench/parts/notebook/electron-browser/outputs/notebookMarkdown.ts @@ -2,17 +2,17 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; +import * as path from 'vs/base/common/path'; +import * as fs from 'fs'; import { URI } from 'vs/base/common/uri'; import { RenderOptions } from 'vs/base/browser/htmlContentRenderer'; import { IMarkdownString, removeMarkdownEscapes } from 'vs/base/common/htmlContent'; import { IMarkdownRenderResult } from 'vs/editor/contrib/markdown/markdownRenderer'; -import marked = require('vs/base/common/marked/marked'); +import * as marked from 'vs/base/common/marked/marked'; import { defaultGenerator } from 'vs/base/common/idGenerator'; import { revive } from 'vs/base/common/marshalling'; -import * as fs from 'fs'; // Based off of HtmlContentRenderer export class NotebookMarkdownRenderer { diff --git a/src/sql/workbench/parts/objectExplorer/browser/connectionTreeAction.ts b/src/sql/workbench/parts/objectExplorer/browser/connectionTreeAction.ts index e019a5c9d2..5e69acae9b 100644 --- a/src/sql/workbench/parts/objectExplorer/browser/connectionTreeAction.ts +++ b/src/sql/workbench/parts/objectExplorer/browser/connectionTreeAction.ts @@ -12,7 +12,7 @@ import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/q import { ServerTreeView } from 'sql/workbench/parts/objectExplorer/browser/serverTreeView'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { ConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup'; -import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; import { ITree } from 'vs/base/parts/tree/browser/tree'; import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; import { TreeNode } from 'sql/workbench/parts/objectExplorer/common/treeNode'; diff --git a/src/sql/workbench/parts/objectExplorer/browser/objectExplorerActions.ts b/src/sql/workbench/parts/objectExplorer/browser/objectExplorerActions.ts index 334b731ea2..95207cf966 100644 --- a/src/sql/workbench/parts/objectExplorer/browser/objectExplorerActions.ts +++ b/src/sql/workbench/parts/objectExplorer/browser/objectExplorerActions.ts @@ -12,10 +12,6 @@ import { ICommandService } from 'vs/platform/commands/common/commands'; import * as azdata from 'azdata'; import { IConnectionManagementService, IConnectionCompletionOptions } from 'sql/platform/connection/common/connectionManagement'; import { TreeNode } from 'sql/workbench/parts/objectExplorer/common/treeNode'; -import { - ScriptSelectAction, EditDataAction, ScriptCreateAction, - ScriptExecuteAction, ScriptDeleteAction, ScriptAlterAction -} from 'sql/workbench/common/actions'; import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; import { TreeUpdateUtils } from 'sql/workbench/parts/objectExplorer/browser/treeUpdateUtils'; import { TreeSelectionHandler } from 'sql/workbench/parts/objectExplorer/browser/treeSelectionHandler'; @@ -28,6 +24,7 @@ import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; +import { ScriptSelectAction, EditDataAction, ScriptCreateAction, ScriptExecuteAction, ScriptAlterAction, ScriptDeleteAction } from 'sql/workbench/electron-browser/scriptingActions'; export class ObjectExplorerActionsContext implements azdata.ObjectExplorerContext { diff --git a/src/sql/workbench/parts/objectExplorer/browser/serverGroupDialog.ts b/src/sql/workbench/parts/objectExplorer/browser/serverGroupDialog.ts index 456c582c22..b3f94f9e7c 100644 --- a/src/sql/workbench/parts/objectExplorer/browser/serverGroupDialog.ts +++ b/src/sql/workbench/parts/objectExplorer/browser/serverGroupDialog.ts @@ -27,6 +27,7 @@ import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export class ServerGroupDialog extends Modal { private _addServerButton: Button; @@ -55,9 +56,10 @@ export class ServerGroupDialog extends Modal { @ITelemetryService telemetryService: ITelemetryService, @IContextKeyService contextKeyService: IContextKeyService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super(localize('ServerGroupsDialogTitle', "Server Groups"), TelemetryKeys.ServerGroups, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService); + super(localize('ServerGroupsDialogTitle', "Server Groups"), TelemetryKeys.ServerGroups, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService); } public render() { diff --git a/src/sql/workbench/parts/profiler/browser/profilerActions.contribution.ts b/src/sql/workbench/parts/profiler/browser/profilerActions.contribution.ts index 573e3159c3..e0028f483a 100644 --- a/src/sql/workbench/parts/profiler/browser/profilerActions.contribution.ts +++ b/src/sql/workbench/parts/profiler/browser/profilerActions.contribution.ts @@ -8,7 +8,7 @@ import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiati import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { ProfilerInput } from 'sql/workbench/parts/profiler/browser/profilerInput'; -import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; import { IProfilerService } from 'sql/workbench/services/profiler/common/interfaces'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ProfilerEditor } from 'sql/workbench/parts/profiler/browser/profilerEditor'; diff --git a/src/sql/workbench/parts/profiler/browser/profilerColumnEditorDialog.ts b/src/sql/workbench/parts/profiler/browser/profilerColumnEditorDialog.ts index b1e2759a93..61bd8717d4 100644 --- a/src/sql/workbench/parts/profiler/browser/profilerColumnEditorDialog.ts +++ b/src/sql/workbench/parts/profiler/browser/profilerColumnEditorDialog.ts @@ -26,6 +26,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; class EventItem { @@ -316,9 +317,10 @@ export class ProfilerColumnEditorDialog extends Modal { @IContextKeyService contextKeyService: IContextKeyService, @IContextViewService private _contextViewService: IContextViewService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super(nls.localize('profilerColumnDialog.profiler', "Profiler"), TelemetryKeys.Profiler, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService); + super(nls.localize('profilerColumnDialog.profiler', "Profiler"), TelemetryKeys.Profiler, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService); } public render(): void { diff --git a/src/sql/workbench/parts/profiler/browser/profilerCopyHandler.ts b/src/sql/workbench/parts/profiler/browser/profilerCopyHandler.ts index fcf325e091..b2f467aa7b 100644 --- a/src/sql/workbench/parts/profiler/browser/profilerCopyHandler.ts +++ b/src/sql/workbench/parts/profiler/browser/profilerCopyHandler.ts @@ -2,10 +2,12 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as os from 'os'; import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; +import { Schemas } from 'vs/base/common/network'; +import { URI } from 'vs/base/common/uri'; -export function handleCopyRequest(clipboardService: IClipboardService, range: Slick.Range, getCellValue: (row, cell) => string): void { +export function handleCopyRequest(clipboardService: IClipboardService, textResourcePropertiesService: ITextResourcePropertiesService, range: Slick.Range, getCellValue: (row, cell) => string): void { if (range) { let results = ''; for (let i = range.fromRow; i <= range.toRow; i++) { @@ -18,9 +20,9 @@ export function handleCopyRequest(clipboardService: IClipboardService, range: Sl } if (i !== range.toRow) { - results += os.EOL; + results += textResourcePropertiesService.getEOL(URI.from({ scheme: Schemas.untitled })); } } clipboardService.writeText(results); } -} \ No newline at end of file +} diff --git a/src/sql/workbench/parts/profiler/browser/profilerEditor.ts b/src/sql/workbench/parts/profiler/browser/profilerEditor.ts index 7c35a4b413..041306b6e7 100644 --- a/src/sql/workbench/parts/profiler/browser/profilerEditor.ts +++ b/src/sql/workbench/parts/profiler/browser/profilerEditor.ts @@ -50,6 +50,7 @@ import { CopyKeybind } from 'sql/base/browser/ui/table/plugins/copyKeybind.plugi import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService'; import { CellSelectionModel } from 'sql/base/browser/ui/table/plugins/cellSelectionModel.plugin'; import { handleCopyRequest } from 'sql/workbench/parts/profiler/browser/profilerCopyHandler'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; class BasicView implements IView { public get element(): HTMLElement { @@ -161,7 +162,8 @@ export class ProfilerEditor extends BaseEditor { @IContextViewService private _contextViewService: IContextViewService, @IEditorService editorService: IEditorService, @IStorageService storageService: IStorageService, - @IClipboardService private _clipboardService: IClipboardService + @IClipboardService private _clipboardService: IClipboardService, + @ITextResourcePropertiesService private readonly textResourcePropertiesService: ITextResourcePropertiesService ) { super(ProfilerEditor.ID, telemetryService, themeService, storageService); this._profilerEditorContextKey = CONTEXT_PROFILER_EDITOR.bindTo(this._contextKeyService); @@ -392,7 +394,7 @@ export class ProfilerEditor extends BaseEditor { detailTableCopyKeybind.onCopy((ranges: Slick.Range[]) => { // we always only get 1 item in the ranges if (ranges && ranges.length === 1) { - handleCopyRequest(this._clipboardService, ranges[0], (row, cell) => { + handleCopyRequest(this._clipboardService, this.textResourcePropertiesService, ranges[0], (row, cell) => { const item = this._detailTableData.getItem(row); // only 2 columns in this table return cell === 0 ? item.label : item.value; diff --git a/src/sql/workbench/parts/profiler/browser/profilerFilterDialog.ts b/src/sql/workbench/parts/profiler/browser/profilerFilterDialog.ts index 0fa20afbb7..7bb7c4fa99 100644 --- a/src/sql/workbench/parts/profiler/browser/profilerFilterDialog.ts +++ b/src/sql/workbench/parts/profiler/browser/profilerFilterDialog.ts @@ -25,6 +25,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ProfilerFilter, ProfilerFilterClause, ProfilerFilterClauseOperator, IProfilerService } from 'sql/workbench/services/profiler/common/interfaces'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; const ClearText: string = localize('profilerFilterDialog.clear', "Clear all"); @@ -77,9 +78,10 @@ export class ProfilerFilterDialog extends Modal { @IContextKeyService contextKeyService: IContextKeyService, @ILogService logService: ILogService, @IContextViewService private contextViewService: IContextViewService, - @IProfilerService private profilerService: IProfilerService + @IProfilerService private profilerService: IProfilerService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super('', TelemetryKeys.ProfilerFilter, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService, { isFlyout: false, hasTitleIcon: true }); + super('', TelemetryKeys.ProfilerFilter, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, { isFlyout: false, hasTitleIcon: true }); } public open(input: ProfilerInput) { diff --git a/src/sql/workbench/parts/profiler/browser/profilerTableEditor.ts b/src/sql/workbench/parts/profiler/browser/profilerTableEditor.ts index 5419d88451..b3cd864d5d 100644 --- a/src/sql/workbench/parts/profiler/browser/profilerTableEditor.ts +++ b/src/sql/workbench/parts/profiler/browser/profilerTableEditor.ts @@ -32,6 +32,7 @@ import { localize } from 'vs/nls'; import { CopyKeybind } from 'sql/base/browser/ui/table/plugins/copyKeybind.plugin'; import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService'; import { handleCopyRequest } from 'sql/workbench/parts/profiler/browser/profilerCopyHandler'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export interface ProfilerTableViewState { scrollTop: number; @@ -66,7 +67,8 @@ export class ProfilerTableEditor extends BaseEditor implements IProfilerControll @IInstantiationService private _instantiationService: IInstantiationService, @IStorageService storageService: IStorageService, @IStatusbarService private _statusbarService: IStatusbarService, - @IClipboardService private _clipboardService: IClipboardService + @IClipboardService private _clipboardService: IClipboardService, + @ITextResourcePropertiesService private readonly textResourcePropertiesService: ITextResourcePropertiesService ) { super(ProfilerTableEditor.ID, telemetryService, _themeService, storageService); this._actionMap[ACTION_IDS.FIND_NEXT] = this._instantiationService.createInstance(ProfilerFindNext, this); @@ -98,7 +100,7 @@ export class ProfilerTableEditor extends BaseEditor implements IProfilerControll // in context of this table, the selection mode is row selection, copy the whole row will get a lot of unwanted data // ignore the passed in range and create a range so that it only copies the currently selected cell value. const activeCell = this._profilerTable.activeCell; - handleCopyRequest(this._clipboardService, new Slick.Range(activeCell.row, activeCell.cell), (row, cell) => { + handleCopyRequest(this._clipboardService, this.textResourcePropertiesService, new Slick.Range(activeCell.row, activeCell.cell), (row, cell) => { const fieldName = this._input.columns[cell].field; return this._input.data.getItem(row)[fieldName]; }); diff --git a/src/sql/workbench/parts/queryPlan/browser/queryPlanEditor.ts b/src/sql/workbench/parts/queryPlan/browser/queryPlanEditor.ts index fa6bbb564d..17996b6611 100644 --- a/src/sql/workbench/parts/queryPlan/browser/queryPlanEditor.ts +++ b/src/sql/workbench/parts/queryPlan/browser/queryPlanEditor.ts @@ -60,11 +60,11 @@ export class QueryPlanEditor extends BaseEditor { public layout(dimension: DOM.Dimension): void { } - public setInput(input: QueryPlanInput, options: EditorOptions): Promise { + public async setInput(input: QueryPlanInput, options: EditorOptions): Promise { if (this.input instanceof QueryPlanInput && this.input.matches(input)) { return Promise.resolve(undefined); } - + await input.resolve(); if (!input.hasInitialized) { this.bootstrapAngular(input); } diff --git a/src/sql/workbench/parts/queryPlan/common/queryPlanInput.ts b/src/sql/workbench/parts/queryPlan/common/queryPlanInput.ts index 4e7493d0f6..098d4fd205 100644 --- a/src/sql/workbench/parts/queryPlan/common/queryPlanInput.ts +++ b/src/sql/workbench/parts/queryPlan/common/queryPlanInput.ts @@ -7,6 +7,8 @@ import { EditorInput, EditorModel } from 'vs/workbench/common/editor'; import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo'; +import { IFileService } from 'vs/platform/files/common/files'; +import { URI } from 'vs/base/common/uri'; export class QueryPlanInput extends EditorInput { @@ -14,8 +16,12 @@ export class QueryPlanInput extends EditorInput { public static SCHEMA: string = 'queryplan'; private _uniqueSelector: string; + private _xml: string; - constructor(private _xml: string, private _uri: string, private _connection: ConnectionManagementInfo) { + constructor( + private _uri: URI, private _connection: ConnectionManagementInfo, + @IFileService private readonly fileService: IFileService + ) { super(); } @@ -36,7 +42,7 @@ export class QueryPlanInput extends EditorInput { } public getUri(): string { - return this._uri; + return this._uri.toString(); } public supportsSplitEditor(): boolean { @@ -48,7 +54,10 @@ export class QueryPlanInput extends EditorInput { return undefined; } - public resolve(refresh?: boolean): Promise { + public async resolve(refresh?: boolean): Promise { + if (!this._xml) { + this._xml = (await this.fileService.readFile(this._uri)).value.toString(); + } return undefined; } diff --git a/src/sql/workbench/parts/restore/browser/restoreDialog.ts b/src/sql/workbench/parts/restore/browser/restoreDialog.ts index 126dcffdcb..f439cfec90 100644 --- a/src/sql/workbench/parts/restore/browser/restoreDialog.ts +++ b/src/sql/workbench/parts/restore/browser/restoreDialog.ts @@ -43,6 +43,7 @@ import { IClipboardService } from 'sql/platform/clipboard/common/clipboardServic import { IFileBrowserDialogController } from 'sql/workbench/services/fileBrowser/common/fileBrowserDialogController'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; interface FileListElement { logicalFileName: string; @@ -136,9 +137,10 @@ export class RestoreDialog extends Modal { @IContextKeyService contextKeyService: IContextKeyService, @IFileBrowserDialogController private fileBrowserDialogService: IFileBrowserDialogController, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super(localize('RestoreDialogTitle', "Restore database"), TelemetryKeys.Restore, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService, { hasErrors: true, isWide: true, hasSpinner: true }); + super(localize('RestoreDialogTitle', "Restore database"), TelemetryKeys.Restore, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, { hasErrors: true, isWide: true, hasSpinner: true }); this._restoreTitle = localize('restoreDialog.restoreTitle', "Restore database"); this._databaseTitle = localize('restoreDialog.database', "Database"); this._backupFileTitle = localize('restoreDialog.backupFile', "Backup file"); diff --git a/src/sql/workbench/parts/webview/browser/webViewDialog.ts b/src/sql/workbench/parts/webview/browser/webViewDialog.ts index 0788d06f1b..2e320cc913 100644 --- a/src/sql/workbench/parts/webview/browser/webViewDialog.ts +++ b/src/sql/workbench/parts/webview/browser/webViewDialog.ts @@ -20,6 +20,7 @@ import * as DOM from 'vs/base/browser/dom'; import { ILogService } from 'vs/platform/log/common/log'; import { IWebviewService, WebviewElement } from 'vs/workbench/contrib/webview/common/webview'; import { generateUuid } from 'vs/base/common/uuid'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export class WebViewDialog extends Modal { @@ -47,9 +48,10 @@ export class WebViewDialog extends Modal { @ITelemetryService telemetryService: ITelemetryService, @IContextKeyService contextKeyService: IContextKeyService, @ILogService logService: ILogService, - @IWebviewService private readonly webviewService: IWebviewService + @IWebviewService private readonly webviewService: IWebviewService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super('', TelemetryKeys.WebView, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService, { isFlyout: false, hasTitleIcon: true }); + super('', TelemetryKeys.WebView, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, { isFlyout: false, hasTitleIcon: true }); this._okLabel = localize('webViewDialog.ok', "OK"); this._closeLabel = localize('webViewDialog.close', "Close"); } diff --git a/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts b/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts index a34e8258ba..d9ca5c3399 100644 --- a/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts +++ b/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts @@ -18,7 +18,6 @@ import { RecentConnectionTreeController, RecentConnectionActionsProvider } from import { SavedConnectionTreeController } from 'sql/workbench/parts/connection/browser/savedConnectionTreeController'; import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; import { ClearRecentConnectionsAction } from 'sql/workbench/parts/connection/common/connectionActions'; -import * as Constants from 'sql/platform/connection/common/constants'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { Event, Emitter } from 'vs/base/common/event'; @@ -37,6 +36,7 @@ import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export interface OnShowUIResponse { selectedProviderDisplayName: string; @@ -97,9 +97,10 @@ export class ConnectionDialogWidget extends Modal { @IContextMenuService private _contextMenuService: IContextMenuService, @IContextViewService private _contextViewService: IContextViewService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super(localize('connection', "Connection"), TelemetryKeys.Connection, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService, { hasSpinner: true, hasErrors: true }); + super(localize('connection', "Connection"), TelemetryKeys.Connection, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, { hasSpinner: true, hasErrors: true }); } /** diff --git a/src/sql/workbench/services/dashboard/browser/newDashboardTabDialogImpl.ts b/src/sql/workbench/services/dashboard/browser/newDashboardTabDialogImpl.ts index 5f5218831f..7f52b08e94 100644 --- a/src/sql/workbench/services/dashboard/browser/newDashboardTabDialogImpl.ts +++ b/src/sql/workbench/services/dashboard/browser/newDashboardTabDialogImpl.ts @@ -27,6 +27,7 @@ import { IDashboardTab } from 'sql/platform/dashboard/browser/dashboardRegistry' import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; class ExtensionListDelegate implements IListVirtualDelegate { @@ -112,7 +113,8 @@ export class NewDashboardTabDialog extends Modal { @ITelemetryService telemetryService: ITelemetryService, @IContextKeyService contextKeyService: IContextKeyService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { super( localize('newDashboardTab.openDashboardExtensions', "Open dashboard extensions"), @@ -122,6 +124,7 @@ export class NewDashboardTabDialog extends Modal { clipboardService, themeService, logService, + textResourcePropertiesService, contextKeyService, { hasSpinner: true } ); diff --git a/src/sql/workbench/services/errorMessage/browser/errorMessageDialog.ts b/src/sql/workbench/services/errorMessage/browser/errorMessageDialog.ts index 2e6af2f9d6..fc84115514 100644 --- a/src/sql/workbench/services/errorMessage/browser/errorMessageDialog.ts +++ b/src/sql/workbench/services/errorMessage/browser/errorMessageDialog.ts @@ -22,6 +22,7 @@ import { IAction } from 'vs/base/common/actions'; import * as DOM from 'vs/base/browser/dom'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; const maxActions = 1; @@ -47,9 +48,10 @@ export class ErrorMessageDialog extends Modal { @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, @ITelemetryService telemetryService: ITelemetryService, @IContextKeyService contextKeyService: IContextKeyService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super('', TelemetryKeys.ErrorMessage, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService, { isFlyout: false, hasTitleIcon: true }); + super('', TelemetryKeys.ErrorMessage, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, { isFlyout: false, hasTitleIcon: true }); this._okLabel = localize('errorMessageDialog.ok', "OK"); this._closeLabel = localize('errorMessageDialog.close', "Close"); } diff --git a/src/sql/workbench/services/fileBrowser/browser/fileBrowserDialog.ts b/src/sql/workbench/services/fileBrowser/browser/fileBrowserDialog.ts index e693e23c74..1391eb91d4 100644 --- a/src/sql/workbench/services/fileBrowser/browser/fileBrowserDialog.ts +++ b/src/sql/workbench/services/fileBrowser/browser/fileBrowserDialog.ts @@ -31,6 +31,7 @@ import { IClipboardService } from 'sql/platform/clipboard/common/clipboardServic import { IThemeService } from 'vs/platform/theme/common/themeService'; import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; export class FileBrowserDialog extends Modal { private _viewModel: FileBrowserViewModel; @@ -55,9 +56,10 @@ export class FileBrowserDialog extends Modal { @ITelemetryService telemetryService: ITelemetryService, @IContextKeyService contextKeyService: IContextKeyService, @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService + @ILogService logService: ILogService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super(title, TelemetryKeys.Backup, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService, { isFlyout: true, hasTitleIcon: false, hasBackButton: true, hasSpinner: true }); + super(title, TelemetryKeys.Backup, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService, { isFlyout: true, hasTitleIcon: false, hasBackButton: true, hasSpinner: true }); this._viewModel = this._instantiationService.createInstance(FileBrowserViewModel); this._viewModel.onAddFileTree(args => this.handleOnAddFileTree(args.rootNode, args.selectedNode, args.expandedNodes)); this._viewModel.onPathValidate(args => this.handleOnValidate(args.succeeded, args.message)); diff --git a/src/sql/workbench/services/insights/browser/insightsDialogView.ts b/src/sql/workbench/services/insights/browser/insightsDialogView.ts index 94a99f0506..f6f8b7b824 100644 --- a/src/sql/workbench/services/insights/browser/insightsDialogView.ts +++ b/src/sql/workbench/services/insights/browser/insightsDialogView.ts @@ -41,6 +41,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { IInsightsConfigDetails } from 'sql/platform/dashboard/browser/insightRegistry'; import { TaskRegistry } from 'sql/platform/tasks/browser/tasksRegistry'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; const labelDisplay = nls.localize("insights.item", "Item"); const valueDisplay = nls.localize("insights.value", "Value"); @@ -166,9 +167,10 @@ export class InsightsDialogView extends Modal { @IInstantiationService private readonly _instantiationService: IInstantiationService, @IContextMenuService private readonly _contextMenuService: IContextMenuService, @ICommandService private readonly _commandService: ICommandService, - @ICapabilitiesService private readonly _capabilitiesService: ICapabilitiesService + @ICapabilitiesService private readonly _capabilitiesService: ICapabilitiesService, + @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService ) { - super(nls.localize("InsightsDialogTitle", "Insights"), TelemetryKeys.Insights, telemetryService, layoutService, clipboardService, themeService, logService, contextKeyService); + super(nls.localize("InsightsDialogTitle", "Insights"), TelemetryKeys.Insights, telemetryService, layoutService, clipboardService, themeService, logService, textResourcePropertiesService, contextKeyService); this._model.onDataChange(e => this.build()); } diff --git a/src/sql/workbench/services/notebook/common/notebookServiceImpl.ts b/src/sql/workbench/services/notebook/common/notebookServiceImpl.ts index d3828fd12d..073223d7e7 100644 --- a/src/sql/workbench/services/notebook/common/notebookServiceImpl.ts +++ b/src/sql/workbench/services/notebook/common/notebookServiceImpl.ts @@ -41,7 +41,7 @@ import { Schemas } from 'vs/base/common/network'; import { ILogService } from 'vs/platform/log/common/log'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/contracts'; -import product from 'vs/platform/product/node/product'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; export interface NotebookProviderProperties { provider: string; @@ -127,7 +127,8 @@ export class NotebookService extends Disposable implements INotebookService { @IConfigurationService private readonly _configurationService: IConfigurationService, @IFileService private readonly _fileService: IFileService, @ILogService private readonly _logService: ILogService, - @IQueryManagementService private readonly _queryManagementService + @IQueryManagementService private readonly _queryManagementService: IQueryManagementService, + @IEnvironmentService environmentService: IEnvironmentService ) { super(); this._providersMemento = new Memento('notebookProviders', this._storageService); @@ -152,7 +153,7 @@ export class NotebookService extends Disposable implements INotebookService { this.cleanupProviders(); // If providers have already registered by this point, add them now (since onHandlerAdded will never fire) - if (this._queryManagementService.registeredProviders && this._queryManagementService.registeredProviders.length > 0) { + if (this._queryManagementService.getRegisteredProviders().length > 0) { this.updateSQLRegistrationWithConnectionProviders(); } @@ -169,7 +170,7 @@ export class NotebookService extends Disposable implements INotebookService { this.hookContextKeyListeners(); this.hookNotebookThemesAndConfigListener(); // Temporary (issue #6427 will remove): Add a product quality key so we can only show books on Insiders - this._contextKeyService.createKey('notebookQuality', product.quality); + this._contextKeyService.createKey('notebookQuality', environmentService.appQuality); } diff --git a/src/sql/workbench/services/notebook/sql/sqlSessionManager.ts b/src/sql/workbench/services/notebook/sql/sqlSessionManager.ts index b249976592..25084f629c 100644 --- a/src/sql/workbench/services/notebook/sql/sqlSessionManager.ts +++ b/src/sql/workbench/services/notebook/sql/sqlSessionManager.ts @@ -3,7 +3,6 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as os from 'os'; import { nb, QueryExecuteSubsetResult, IDbColumn, BatchSummary, IResultMessage, ResultSetSummary } from 'azdata'; import { localize } from 'vs/nls'; import { FutureInternal, notebookConstants } from 'sql/workbench/parts/notebook/common/models/modelInterfaces'; @@ -23,6 +22,8 @@ import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilit import { ILogService } from 'vs/platform/log/common/log'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { ILanguageMagic } from 'sql/workbench/services/notebook/common/notebookService'; +import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; +import { URI } from 'vs/base/common/uri'; export const sqlKernelError: string = localize("sqlKernelError", "SQL kernel error"); export const MAX_ROWS = 5000; @@ -168,7 +169,8 @@ class SqlKernel extends Disposable implements nb.IKernel { @IInstantiationService private _instantiationService: IInstantiationService, @IErrorMessageService private _errorMessageService: IErrorMessageService, @IConfigurationService private _configurationService: IConfigurationService, - @ILogService private readonly logService: ILogService + @ILogService private readonly logService: ILogService, + @ITextResourcePropertiesService private readonly textResourcePropertiesService: ITextResourcePropertiesService ) { super(); this.initMagics(); @@ -275,7 +277,7 @@ class SqlKernel extends Disposable implements nb.IKernel { private getCodeWithoutCellMagic(content: nb.IExecuteRequest): string { let code = Array.isArray(content.code) ? content.code.join('') : content.code; - let firstLineEnd = code.indexOf(os.EOL); + let firstLineEnd = code.indexOf(this.textResourcePropertiesService.getEOL(URI.file(this._path))); let firstLine = code.substring(0, (firstLineEnd >= 0) ? firstLineEnd : 0).trimLeft(); if (firstLine.startsWith('%%')) { // Strip out the line diff --git a/src/sql/workbench/services/queryEditor/browser/queryEditorService.ts b/src/sql/workbench/services/queryEditor/browser/queryEditorService.ts index bb9ed7af72..f803bfb96f 100644 --- a/src/sql/workbench/services/queryEditor/browser/queryEditorService.ts +++ b/src/sql/workbench/services/queryEditor/browser/queryEditorService.ts @@ -10,7 +10,7 @@ import { IConnectableInput, IConnectionManagementService } from 'sql/platform/co import { IQueryEditorService, IQueryEditorOptions } from 'sql/workbench/services/queryEditor/common/queryEditorService'; import { QueryPlanInput } from 'sql/workbench/parts/queryPlan/common/queryPlanInput'; import { sqlModeId, untitledFilePrefix, getSupportedInputResource } from 'sql/workbench/common/customInputConverter'; -import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; import { IMode } from 'vs/editor/common/modes'; import { ITextModel } from 'vs/editor/common/model'; @@ -31,8 +31,7 @@ import { ILanguageSelection } from 'vs/editor/common/services/modeService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; - -const fs = require('fs'); +import { IFileService } from 'vs/platform/files/common/files'; /** * Service wrapper for opening and creating SQL documents as sql editor inputs @@ -62,7 +61,8 @@ export class QueryEditorService implements IQueryEditorService { @IInstantiationService private _instantiationService: IInstantiationService, @IEditorService private _editorService: IEditorService, @IConnectionManagementService private _connectionManagementService: IConnectionManagementService, - @IConfigurationService private _configurationService: IConfigurationService + @IConfigurationService private _configurationService: IConfigurationService, + @IFileService private readonly fileService: IFileService ) { QueryEditorService.editorService = _editorService; QueryEditorService.instantiationService = _instantiationService; @@ -78,7 +78,7 @@ export class QueryEditorService implements IQueryEditorService { return new Promise(async (resolve, reject) => { try { // Create file path and file URI - let filePath = this.createUntitledSqlFilePath(); + let filePath = await this.createUntitledSqlFilePath(); let docUri: URI = URI.from({ scheme: Schemas.untitled, path: filePath }); // Create a sql document pane with accoutrements @@ -107,26 +107,16 @@ export class QueryEditorService implements IQueryEditorService { }); } - // Creates a new query plan document - public newQueryPlanEditor(xmlShowPlan: string): Promise { - const self = this; - return new Promise((resolve, reject) => { - let queryPlanInput: QueryPlanInput = self._instantiationService.createInstance(QueryPlanInput, xmlShowPlan, 'aaa', undefined); - self._editorService.openEditor(queryPlanInput, { pinned: true }, ACTIVE_GROUP); - resolve(true); - }); - } - /** * Creates new edit data session */ public newEditDataEditor(schemaName: string, tableName: string, sqlContent: string): Promise { - return new Promise((resolve, reject) => { + return new Promise(async (resolve, reject) => { try { // Create file path and file URI let objectName = schemaName ? schemaName + '.' + tableName : tableName; - let filePath = this.createPrefixedSqlFilePath(objectName); + let filePath = await this.createPrefixedSqlFilePath(objectName); let docUri: URI = URI.from({ scheme: Schemas.untitled, path: filePath }); // Create a sql document pane with accoutrements @@ -260,11 +250,11 @@ export class QueryEditorService implements IQueryEditorService { ////// Private functions - private createUntitledSqlFilePath(): string { + private createUntitledSqlFilePath(): Promise { return this.createPrefixedSqlFilePath(untitledFilePrefix); } - private createPrefixedSqlFilePath(prefix: string): string { + private async createPrefixedSqlFilePath(prefix: string): Promise { let prefixFileName = (counter: number): string => { return `${prefix}_${counter}`; }; @@ -272,7 +262,7 @@ export class QueryEditorService implements IQueryEditorService { let counter = 1; // Get document name and check if it exists let filePath = prefixFileName(counter); - while (fs.existsSync(filePath)) { + while (await this.fileService.exists(URI.file(filePath))) { counter++; filePath = prefixFileName(counter); } diff --git a/src/sql/workbench/services/queryEditor/common/queryEditorService.ts b/src/sql/workbench/services/queryEditor/common/queryEditorService.ts index 7a8bd669b8..7dd2bce676 100644 --- a/src/sql/workbench/services/queryEditor/common/queryEditorService.ts +++ b/src/sql/workbench/services/queryEditor/common/queryEditorService.ts @@ -25,9 +25,6 @@ export interface IQueryEditorService { // Creates new untitled document for SQL queries and opens it in a new editor tab newSqlEditor(sqlContent?: string, connectionProviderName?: string, isDirty?: boolean, objectName?: string): Promise; - // Creates a new query plan document - newQueryPlanEditor(xmlShowPlan: string): Promise; - // Creates new edit data session newEditDataEditor(schemaName: string, tableName: string, queryString: string): Promise; diff --git a/src/sql/workbench/test/common/taskUtilities.test.ts b/src/sql/workbench/test/common/taskUtilities.test.ts index d968db3e16..1c55b404e8 100644 --- a/src/sql/workbench/test/common/taskUtilities.test.ts +++ b/src/sql/workbench/test/common/taskUtilities.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import * as TypeMoq from 'typemoq'; -import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; import { TestConnectionManagementService } from 'sql/platform/connection/test/common/testConnectionManagementService'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; diff --git a/src/sql/workbench/test/electron-browser/api/mainThreadNotebook.test.ts b/src/sql/workbench/test/electron-browser/api/mainThreadNotebook.test.ts index f00f950585..d9807b9da2 100644 --- a/src/sql/workbench/test/electron-browser/api/mainThreadNotebook.test.ts +++ b/src/sql/workbench/test/electron-browser/api/mainThreadNotebook.test.ts @@ -15,11 +15,10 @@ import { NotebookService } from 'sql/workbench/services/notebook/common/notebook import { INotebookProvider } from 'sql/workbench/services/notebook/common/notebookService'; import { INotebookManagerDetails, INotebookSessionDetails, INotebookKernelDetails, INotebookFutureDetails } from 'sql/workbench/api/common/sqlExtHostTypes'; import { LocalContentManager } from 'sql/workbench/services/notebook/common/localContentManager'; -import { TestLifecycleService } from 'vs/workbench/test/workbenchTestServices'; +import { TestLifecycleService, TestEnvironmentService } from 'vs/workbench/test/workbenchTestServices'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { ExtHostNotebookShape } from 'sql/workbench/api/common/sqlExtHost.protocol'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; suite('MainThreadNotebook Tests', () => { @@ -35,7 +34,8 @@ suite('MainThreadNotebook Tests', () => { getProxy: proxyType => mockProxy.object }; const instantiationService = new TestInstantiationService(); - mockNotebookService = TypeMoq.Mock.ofType(NotebookService, undefined, new TestLifecycleService(), undefined, undefined, undefined, instantiationService, new MockContextKeyService()); + mockNotebookService = TypeMoq.Mock.ofType(NotebookService, undefined, new TestLifecycleService(), undefined, undefined, undefined, instantiationService, new MockContextKeyService(), + undefined, undefined, undefined, undefined, undefined, undefined, TestEnvironmentService); notebookUri = URI.parse('file:/user/default/my.ipynb'); mainThreadNotebook = new MainThreadNotebook(extContext, mockNotebookService.object, instantiationService); }); diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 95f21e79b9..01366f7848 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -95,11 +95,11 @@ export const enum MenuId { TouchBarContext, ViewItemContext, ViewTitle, - // {{SQL CARBON EDIT}} - ObjectExplorerItemContext, - NotebookToolbar, - DataExplorerContext, - DataExplorerAction, + ObjectExplorerItemContext, // {{SQL CARBON EDIT}} + NotebookToolbar, // {{SQL CARBON EDIT}} + DataExplorerContext, // {{SQL CARBON EDIT}} + DataExplorerAction, // {{SQL CARBON EDIT}} + ExplorerWidgetContext, // {{SQL CARBON EDIT}} CommentThreadTitle, CommentThreadActions, CommentTitle, diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 182b19d986..035f810297 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -15,7 +15,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; // {{SQL CARBON EDIT}} import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions, - InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, IExtensionIdentifier, INSTALL_ERROR_INCOMPATIBLE + InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, IExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, areSameExtensions, getMaliciousExtensionsSet, groupByExtension, ExtensionIdentifierWithVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; @@ -40,8 +40,6 @@ import { IProductService } from 'vs/platform/product/common/product'; import { asDomUri } from 'vs/base/browser/dom'; // {{SQL CARBON EDIT}} -import { ExtensionManagementError } from 'vs/platform/extensionManagement/node/extensionManagementService'; -import pkg from 'vs/platform/product/node/package'; import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator'; interface IExtensionStateProvider { @@ -835,8 +833,8 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension // Check both the vscode version and azure data studio version // The check is added here because we want to fail fast instead of downloading the VSIX and then fail. if (gallery.properties.engine && (!isEngineValid(gallery.properties.engine, this.productService.vscodeVersion) - || (gallery.properties.azDataEngine && !isEngineValid(gallery.properties.azDataEngine, pkg.version)))) { - return Promise.reject(new ExtensionManagementError(nls.localize('incompatible2', "Unable to install version '{2}' of extension '{0}' as it is not compatible with Azure Data Studio '{1}'.", extension.gallery!.identifier.id, pkg.version, gallery.version), INSTALL_ERROR_INCOMPATIBLE)); + || (gallery.properties.azDataEngine && !isEngineValid(gallery.properties.azDataEngine, this.productService.version)))) { + return Promise.reject(new Error(nls.localize('incompatible2', "Unable to install version '{2}' of extension '{0}' as it is not compatible with Azure Data Studio '{1}'.", extension.gallery!.identifier.id, this.productService.version, gallery.version))); } return this.installWithProgress(async () => { diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 8c37dc0102..9cdf6d5b6e 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -50,7 +50,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; -import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import * as TaskUtilities from 'sql/workbench/browser/taskUtilities'; export const NEW_FILE_COMMAND_ID = 'explorer.newFile'; export const NEW_FILE_LABEL = nls.localize('newFile', "New File"); diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 3c64eb80af..451c1f7fe2 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -467,6 +467,7 @@ import 'sql/workbench/parts/tasks/browser/tasks.contribution'; import 'sql/workbench/parts/dataExplorer/browser/dataExplorer.contribution'; import 'sql/workbench/parts/dataExplorer/browser/dataExplorerViewlet'; import 'sql/workbench/parts/dataExplorer/browser/dataExplorerExtensionPoint'; +import 'sql/workbench/parts/dataExplorer/common/nodeActions.common.contribution'; import 'sql/workbench/parts/dataExplorer/electron-browser/nodeActions.contribution'; import 'sql/workbench/parts/telemetry/common/telemetry.contribution'; @@ -506,7 +507,8 @@ import 'sql/workbench/parts/dashboard/browser/dashboard.contribution'; import 'sql/workbench/common/actions.contribution'; /* Widgets */ import 'sql/workbench/parts/dashboard/browser/widgets/insights/insightsWidget.contribution'; -import 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.contribution'; +import 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerWidget.common.contribution'; +import 'sql/workbench/parts/dashboard/electron-browser/widgets/explorer/explorerWidget.contribution'; import 'sql/workbench/parts/dashboard/browser/widgets/tasks/tasksWidget.contribution'; import 'sql/workbench/parts/dashboard/browser/widgets/webview/webviewWidget.contribution'; import 'sql/workbench/parts/dashboard/browser/dashboardConfig.contribution'; @@ -515,7 +517,8 @@ import 'sql/workbench/browser/modelComponents/components.contribution'; /* View Model Editor */ import 'sql/workbench/browser/modelComponents/modelViewEditor.contribution'; /* Notebook Editor */ -import 'sql/workbench/parts/notebook/browser/notebook.contribution'; +import 'sql/workbench/parts/notebook/browser/notebook.common.contribution'; +import 'sql/workbench/parts/notebook/electron-browser/notebook.contribution'; /* Containers */ import 'sql/workbench/parts/dashboard/browser/containers/dashboardWebviewContainer.contribution'; import 'sql/workbench/parts/dashboard/browser/containers/dashboardControlHostContainer.contribution';