From 7b23ca8ee702f6a9c93ab32a9492a8ed00760d7f Mon Sep 17 00:00:00 2001 From: Madeline MacDonald Date: Mon, 16 Jul 2018 11:44:14 -0700 Subject: [PATCH] Improving profiler controls and toolbar (#1931) * Profiler toolbar improvements * Fixing formatting issues --- .../parts/profiler/contrib/profilerActions.ts | 9 +++-- .../parts/profiler/editor/profilerEditor.ts | 12 +++++++ .../parts/profiler/editor/profilerInput.ts | 33 +++++++++++++++++-- .../parts/profiler/service/profilerService.ts | 8 ++++- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/sql/parts/profiler/contrib/profilerActions.ts b/src/sql/parts/profiler/contrib/profilerActions.ts index 8fefb22408..342e67d658 100644 --- a/src/sql/parts/profiler/contrib/profilerActions.ts +++ b/src/sql/parts/profiler/contrib/profilerActions.ts @@ -77,7 +77,6 @@ export class ProfilerStart extends Action { } public run(input: ProfilerInput): TPromise { - this.enabled = false; input.data.clear(); return TPromise.wrap(this._profilerService.startSession(input.id)); } @@ -127,7 +126,6 @@ export class ProfilerStop extends Action { } public run(input: ProfilerInput): TPromise { - this.enabled = false; return TPromise.wrap(this._profilerService.stopSession(input.id)); } } @@ -137,7 +135,7 @@ export class ProfilerClear extends Action { public static LABEL = nls.localize('profiler.clear', "Clear Data"); constructor(id: string, label: string) { - super(id, label, 'stop'); + super(id, label); } run(input: ProfilerInput): TPromise { @@ -148,14 +146,15 @@ export class ProfilerClear extends Action { export class ProfilerAutoScroll extends Action { public static ID = 'profiler.autoscroll'; - public static LABEL = nls.localize('profiler.toggleAutoscroll', "Toggle Auto Scroll"); + public static LABEL = nls.localize('profiler.autoscrollOn', "Auto Scroll: On"); constructor(id: string, label: string) { - super(id, label, 'stop'); + super(id, label); } run(input: ProfilerInput): TPromise { this.checked = !this.checked; + this._setLabel(this.checked ? nls.localize('profilerAction.autoscrollOn', "Auto Scroll: On") : nls.localize('profilerAction.autoscrollOff', "Auto Scroll: Off")); input.state.change({ autoscroll: this.checked }); return TPromise.as(true); } diff --git a/src/sql/parts/profiler/editor/profilerEditor.ts b/src/sql/parts/profiler/editor/profilerEditor.ts index 472b53b811..204a6c822d 100644 --- a/src/sql/parts/profiler/editor/profilerEditor.ts +++ b/src/sql/parts/profiler/editor/profilerEditor.ts @@ -116,6 +116,7 @@ export class ProfilerEditor extends BaseEditor { private _viewTemplateSelector: SelectBox; private _viewTemplates: Array; + private _connectionInfoText: HTMLElement; // Actions private _connectAction: Actions.ProfilerConnect; @@ -199,8 +200,16 @@ export class ProfilerEditor extends BaseEditor { })); let dropdownContainer = document.createElement('div'); dropdownContainer.style.width = '150px'; + dropdownContainer.style.paddingRight = '5px'; this._viewTemplateSelector.render(dropdownContainer); + this._connectionInfoText = document.createElement('div'); + this._connectionInfoText.style.paddingRight = '5px'; + this._connectionInfoText.innerText = ''; + this._connectionInfoText.style.textAlign = 'center'; + this._connectionInfoText.style.display = 'flex'; + this._connectionInfoText.style.alignItems = 'center'; + this._register(attachSelectBoxStyler(this._viewTemplateSelector, this.themeService)); this._actionBar.setContent([ @@ -211,6 +220,8 @@ export class ProfilerEditor extends BaseEditor { { action: this._autoscrollAction }, { action: this._instantiationService.createInstance(Actions.ProfilerClear, Actions.ProfilerClear.ID, Actions.ProfilerClear.LABEL) }, { element: dropdownContainer }, + { element: Taskbar.createTaskbarSeparator() }, + { element: this._connectionInfoText } ]); } @@ -361,6 +372,7 @@ export class ProfilerEditor extends BaseEditor { autoscroll: true, isPanelCollapsed: true }); + this._connectionInfoText.innerText = input.connectionName; this._profilerTableEditor.updateState(); this._splitView.layout(); this._profilerTableEditor.focus(); diff --git a/src/sql/parts/profiler/editor/profilerInput.ts b/src/sql/parts/profiler/editor/profilerInput.ts index e5ac07f8a2..24bb70ea02 100644 --- a/src/sql/parts/profiler/editor/profilerInput.ts +++ b/src/sql/parts/profiler/editor/profilerInput.ts @@ -9,6 +9,7 @@ import { ProfilerState } from './profilerState'; import { IConnectionProfile } from 'sql/parts/connection/common/interfaces'; import * as sqlops from 'sqlops'; +import * as nls from 'vs/nls'; import { TPromise } from 'vs/base/common/winjs.base'; import { EditorInput } from 'vs/workbench/common/editor'; @@ -17,8 +18,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { INotificationService } from 'vs/platform/notification/common/notification'; import { Event, Emitter } from 'vs/base/common/event'; import { generateUuid } from 'vs/base/common/uuid'; - -import * as nls from 'vs/nls'; +import { IDialogService, IConfirmation, IConfirmationResult } from 'vs/platform/dialogs/common/dialogs'; export class ProfilerInput extends EditorInput implements IProfilerSession { @@ -40,7 +40,8 @@ export class ProfilerInput extends EditorInput implements IProfilerSession { private _connection: IConnectionProfile, @IInstantiationService private _instantiationService: IInstantiationService, @IProfilerService private _profilerService: IProfilerService, - @INotificationService private _notificationService: INotificationService + @INotificationService private _notificationService: INotificationService, + @IDialogService private _dialogService: IDialogService ) { super(); this._state = new ProfilerState(); @@ -64,6 +65,23 @@ export class ProfilerInput extends EditorInput implements IProfilerSession { return ret; }; this._data = new TableDataView(undefined, searchFn); + + this.onDispose(() => { + if (this._state.isRunning || this.state.isPaused) { + let confirm: IConfirmation = { + message: nls.localize('confirmStopProfilerSession', "Would you like to stop the running XEvent session?"), + primaryButton: nls.localize('profilerClosingActions.yes', 'Yes'), + secondaryButton: nls.localize('profilerClosingActions.no', 'No'), + type: 'question' + }; + + this._dialogService.confirm(confirm).then(result => { + if (result.confirmed) { + this._profilerService.stopSession(this.id); + } + }); + } + }); } public set viewTemplate(template: IProfilerViewTemplate) { @@ -130,6 +148,15 @@ export class ProfilerInput extends EditorInput implements IProfilerSession { this._onColumnsChanged.fire(this.columns); } + public get connectionName(): string { + if (this._connection !== null) { + return `${ this._connection.serverName } ${ this._connection.databaseName }`; + } + else { + return nls.localize('profilerInput.notConnected', "Not connected"); + } + } + public get id(): ProfilerSessionID { return this._id; } diff --git a/src/sql/parts/profiler/service/profilerService.ts b/src/sql/parts/profiler/service/profilerService.ts index 5543b77514..873d5d5e0e 100644 --- a/src/sql/parts/profiler/service/profilerService.ts +++ b/src/sql/parts/profiler/service/profilerService.ts @@ -17,6 +17,7 @@ import * as sqlops from 'sqlops'; import { TPromise } from 'vs/base/common/winjs.base'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { INotificationService } from 'vs/platform/notification/common/notification'; class TwoWayMap { private forwardMap: Map; @@ -52,7 +53,8 @@ export class ProfilerService implements IProfilerService { constructor( @IConnectionManagementService private _connectionService: IConnectionManagementService, @IConfigurationService public _configurationService: IConfigurationService, - @IInstantiationService private _instantiationService: IInstantiationService + @IInstantiationService private _instantiationService: IInstantiationService, + @INotificationService private _notificationService: INotificationService ) { } public registerProvider(providerId: string, provider: sqlops.ProfilerProvider): void { @@ -99,6 +101,8 @@ export class ProfilerService implements IProfilerService { return this._runAction(id, provider => provider.startSession(this._idMap.get(id))).then(() => { this._sessionMap.get(this._idMap.reverseGet(id)).onSessionStateChanged({ isRunning: true, isStopped: false, isPaused: false }); return true; + }, (reason) => { + this._notificationService.error(reason.message); }); } @@ -110,6 +114,8 @@ export class ProfilerService implements IProfilerService { return this._runAction(id, provider => provider.stopSession(this._idMap.get(id))).then(() => { this._sessionMap.get(this._idMap.reverseGet(id)).onSessionStateChanged({ isStopped: true, isPaused: false, isRunning: false }); return true; + }, (reason) => { + this._notificationService.error(reason.message); }); }