diff --git a/src/sql/base/common/lifecycle.ts b/src/sql/base/common/lifecycle.ts index 548f9e2d75..6bbcbc7791 100644 --- a/src/sql/base/common/lifecycle.ts +++ b/src/sql/base/common/lifecycle.ts @@ -4,12 +4,19 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; - +import { OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; -import { IDisposable } from 'vs/base/common/lifecycle'; + +import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; export function subscriptionToDisposable(sub: Subscription): IDisposable { return { dispose: sub.unsubscribe }; } + +export class AngularDisposable extends Disposable implements OnDestroy { + ngOnDestroy() { + this.dispose(); + } +} diff --git a/src/sql/parts/dashboard/common/dashboardPage.component.ts b/src/sql/parts/dashboard/common/dashboardPage.component.ts index 1fb0e65deb..0ee8147898 100644 --- a/src/sql/parts/dashboard/common/dashboardPage.component.ts +++ b/src/sql/parts/dashboard/common/dashboardPage.component.ts @@ -23,6 +23,7 @@ import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; import * as dashboardHelper from 'sql/parts/dashboard/common/dashboardHelper'; import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution'; import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution'; +import { AngularDisposable } from 'sql/base/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import * as types from 'vs/base/common/types'; @@ -46,7 +47,7 @@ const dashboardRegistry = Registry.as(DashboardExtensions.Da selector: 'dashboard-page', templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/common/dashboardPage.component.html')) }) -export abstract class DashboardPage extends Disposable implements OnDestroy { +export abstract class DashboardPage extends AngularDisposable { protected tabs: Array = []; @@ -259,10 +260,6 @@ export abstract class DashboardPage extends Disposable implements OnDestroy { } } - ngOnDestroy() { - this.dispose(); - } - private getProperties(): Array { let properties = this.dashboardService.getSettings([this.context, 'properties'].join('.')); this._propertiesConfigLocation = 'default'; diff --git a/src/sql/parts/dashboard/common/interfaces.ts b/src/sql/parts/dashboard/common/interfaces.ts index ca2400a32a..9fb2c1e984 100644 --- a/src/sql/parts/dashboard/common/interfaces.ts +++ b/src/sql/parts/dashboard/common/interfaces.ts @@ -3,9 +3,10 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable } from 'vs/base/common/lifecycle'; import Event from 'vs/base/common/event'; +import { AngularDisposable } from 'sql/base/common/lifecycle'; + export enum Conditional { 'equals', 'notEquals', @@ -16,7 +17,7 @@ export enum Conditional { 'always' } -export abstract class DashboardTab extends Disposable { +export abstract class DashboardTab extends AngularDisposable { public abstract layout(): void; public abstract readonly id: string; public abstract readonly editable: boolean; diff --git a/src/sql/parts/dashboard/contents/dashboardWidgetWrapper.component.ts b/src/sql/parts/dashboard/contents/dashboardWidgetWrapper.component.ts index 2f48792211..d1ed5b123d 100644 --- a/src/sql/parts/dashboard/contents/dashboardWidgetWrapper.component.ts +++ b/src/sql/parts/dashboard/contents/dashboardWidgetWrapper.component.ts @@ -15,6 +15,7 @@ import { WidgetConfig, WIDGET_CONFIG, IDashboardWidget } from 'sql/parts/dashboa import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry'; import { error } from 'sql/base/common/log'; import { RefreshWidgetAction, ToggleMoreWidgetAction, DeleteWidgetAction, CollapseWidgetAction } from 'sql/parts/dashboard/common/actions'; +import { AngularDisposable } from 'sql/base/common/lifecycle'; /* Widgets */ import { PropertiesWidgetComponent } from 'sql/parts/dashboard/widgets/properties/propertiesWidget.component'; @@ -47,7 +48,7 @@ const componentMap: { [x: string]: Type } = { selector: 'dashboard-widget-wrapper', templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/contents/dashboardWidgetWrapper.component.html')) }) -export class DashboardWidgetWrapper implements OnInit, OnDestroy { +export class DashboardWidgetWrapper extends AngularDisposable implements OnInit { @Input() private _config: WidgetConfig; @Input() private collapsable = false; @@ -73,7 +74,6 @@ export class DashboardWidgetWrapper implements OnInit, OnDestroy { return generateUuid(); } - private _themeDispose: IDisposable; private _actions: Array; private _component: IDashboardWidget; private _actionbar: ActionBar; @@ -88,13 +88,15 @@ export class DashboardWidgetWrapper implements OnInit, OnDestroy { @Inject(forwardRef(() => DashboardServiceInterface)) private _bootstrap: DashboardServiceInterface, @Inject(forwardRef(() => ChangeDetectorRef)) private _changeref: ChangeDetectorRef, @Inject(forwardRef(() => Injector)) private _injector: Injector - ) { } + ) { + super(); + } ngOnInit() { let self = this; - self._themeDispose = self._bootstrap.themeService.onDidColorThemeChange((event: IColorTheme) => { + this._register(self._bootstrap.themeService.onDidColorThemeChange((event: IColorTheme) => { self.updateTheme(event); - }); + })); } ngAfterViewInit() { @@ -113,10 +115,6 @@ export class DashboardWidgetWrapper implements OnInit, OnDestroy { this.layout(); } - ngOnDestroy() { - this._themeDispose.dispose(); - } - public refresh(): void { if (this._component && this._component.refresh) { this._component.refresh(); diff --git a/src/sql/parts/dashboard/contents/webviewContent.component.ts b/src/sql/parts/dashboard/contents/webviewContent.component.ts index 58692237ce..4ed960d733 100644 --- a/src/sql/parts/dashboard/contents/webviewContent.component.ts +++ b/src/sql/parts/dashboard/contents/webviewContent.component.ts @@ -11,20 +11,21 @@ import Webview from 'vs/workbench/parts/html/browser/webview'; import { Parts } from 'vs/workbench/services/part/common/partService'; import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { addDisposableListener, EventType } from 'vs/base/browser/dom'; +import { memoize } from 'vs/base/common/decorators'; import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget'; import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service'; import { IDashboardWebview } from 'sql/services/dashboardWebview/common/dashboardWebviewService'; +import { AngularDisposable } from 'sql/base/common/lifecycle'; import * as sqlops from 'sqlops'; -import { memoize } from 'vs/base/common/decorators'; @Component({ template: '', selector: 'webview-content' }) -export class WebviewContent extends Disposable implements OnInit, IDashboardWebview { +export class WebviewContent extends AngularDisposable implements OnInit, IDashboardWebview { @Input() private webviewId: string; private _onResize = new Emitter(); diff --git a/src/sql/parts/dashboard/dashboard.component.ts b/src/sql/parts/dashboard/dashboard.component.ts index 4a9cef5330..be306cc45e 100644 --- a/src/sql/parts/dashboard/dashboard.component.ts +++ b/src/sql/parts/dashboard/dashboard.component.ts @@ -12,11 +12,12 @@ import { DashboardServiceInterface } from './services/dashboardServiceInterface. import { IConnectionProfile } from 'sql/parts/connection/common/interfaces'; import * as Utils from 'sql/parts/connection/common/utils'; import { RefreshWidgetAction, EditDashboardAction } from 'sql/parts/dashboard/common/actions'; +import { DashboardPage } from 'sql/parts/dashboard/common/dashboardPage.component'; +import { AngularDisposable } from 'sql/base/common/lifecycle'; import { IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IDisposable } from 'vs/base/common/lifecycle'; import * as themeColors from 'vs/workbench/common/theme'; -import { DashboardPage } from 'sql/parts/dashboard/common/dashboardPage.component'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; export const DASHBOARD_SELECTOR: string = 'dashboard-component'; @@ -25,8 +26,7 @@ export const DASHBOARD_SELECTOR: string = 'dashboard-component'; selector: DASHBOARD_SELECTOR, templateUrl: decodeURI(require.toUrl('./dashboard.component.html')) }) -export class DashboardComponent implements OnInit, OnDestroy { - private _subs: Array = new Array(); +export class DashboardComponent extends AngularDisposable implements OnInit { private _currentPage: DashboardPage; @ViewChild('header', { read: ElementRef }) private header: ElementRef; @@ -39,10 +39,12 @@ export class DashboardComponent implements OnInit, OnDestroy { @Inject(forwardRef(() => DashboardServiceInterface)) private _bootstrapService: DashboardServiceInterface, @Inject(forwardRef(() => Router)) private _router: Router, @Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef - ) { } + ) { + super(); + } ngOnInit() { - this._subs.push(this._bootstrapService.themeService.onDidColorThemeChange(this.updateTheme, this)); + this._register(this._bootstrapService.themeService.onDidColorThemeChange(this.updateTheme, this)); this.updateTheme(this._bootstrapService.themeService.getColorTheme()); let profile: IConnectionProfile = this._bootstrapService.getOriginalConnectionProfile(); this.actionbar = new ActionBar(this.actionbarContainer.nativeElement); @@ -61,12 +63,6 @@ export class DashboardComponent implements OnInit, OnDestroy { } } - ngOnDestroy() { - this._subs.forEach((value) => { - value.dispose(); - }); - } - private updateTheme(theme: IColorTheme): void { let headerEl = this.header.nativeElement; headerEl.style.borderBottomColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString(); diff --git a/src/sql/parts/dashboard/services/breadcrumb.service.ts b/src/sql/parts/dashboard/services/breadcrumb.service.ts index dcb8de6e0a..2e6193bd61 100644 --- a/src/sql/parts/dashboard/services/breadcrumb.service.ts +++ b/src/sql/parts/dashboard/services/breadcrumb.service.ts @@ -19,10 +19,9 @@ export enum BreadcrumbClass { }; @Injectable() -export class BreadcrumbService implements IBreadcrumbService, OnDestroy { +export class BreadcrumbService implements IBreadcrumbService { public breadcrumbItem: Subject; private itemBreadcrums: MenuItem[]; - private _disposables: IDisposable[] = []; private _currentPage: BreadcrumbClass; constructor( @Inject(forwardRef(() => DashboardServiceInterface)) private _bootstrap: DashboardServiceInterface) { @@ -42,7 +41,7 @@ export class BreadcrumbService implements IBreadcrumbService, OnDestroy { private getBreadcrumbsLink(page: BreadcrumbClass): MenuItem[] { this.itemBreadcrums = []; let profile = this._bootstrap.connectionManagementService.connectionInfo.connectionProfile; - this.itemBreadcrums.push({ label: nls.localize('homeCrumb', 'Home')}); + this.itemBreadcrums.push({ label: nls.localize('homeCrumb', 'Home') }); switch (page) { case BreadcrumbClass.DatabasePage: this.itemBreadcrums.push(this.getServerBreadcrumb(profile)); @@ -67,8 +66,4 @@ export class BreadcrumbService implements IBreadcrumbService, OnDestroy { routerLink: ['database-dashboard'] }; } - - ngOnDestroy() { - this._disposables = dispose(this._disposables); - } } \ No newline at end of file diff --git a/src/sql/parts/dashboard/services/dashboardServiceInterface.service.ts b/src/sql/parts/dashboard/services/dashboardServiceInterface.service.ts index 616eeda030..f44f2bea31 100644 --- a/src/sql/parts/dashboard/services/dashboardServiceInterface.service.ts +++ b/src/sql/parts/dashboard/services/dashboardServiceInterface.service.ts @@ -24,6 +24,7 @@ import { AngularEventType, IAngularEvent, IAngularEventingService } from 'sql/se import { IDashboardTab } from 'sql/platform/dashboard/common/dashboardRegistry'; import { TabSettingConfig } from 'sql/parts/dashboard/common/dashboardWidget'; import { IDashboardWebviewService } from 'sql/services/dashboardWebview/common/dashboardWebviewService'; +import { AngularDisposable } from 'sql/base/common/lifecycle'; import { ProviderMetadata, DatabaseInfo, SimpleExecuteResult } from 'sqlops'; @@ -112,33 +113,34 @@ export class SingleQueryManagementService { usage of a widget. */ @Injectable() -export class DashboardServiceInterface implements OnDestroy { +export class DashboardServiceInterface extends AngularDisposable { private _uniqueSelector: string; private _uri: string; private _bootstrapParams: DashboardComponentParams; - private _disposables: IDisposable[] = []; - /* Services */ + /* Static Services */ + private _themeService = this._bootstrapService.themeService; + private _contextMenuService = this._bootstrapService.contextMenuService; + private _instantiationService = this._bootstrapService.instantiationService; + private _configService = this._bootstrapService.configurationService; + private _insightsDialogService = this._bootstrapService.insightsDialogService; + private _contextViewService = this._bootstrapService.contextViewService; + private _messageService = this._bootstrapService.messageService; + private _workspaceContextService = this._bootstrapService.workspaceContextService; + private _storageService = this._bootstrapService.storageService; + private _capabilitiesService = this._bootstrapService.capabilitiesService; + private _configurationEditingService = this._bootstrapService.configurationEditorService; + private _commandService = this._bootstrapService.commandService; + private _dashboardWebviewService = this._bootstrapService.dashboardWebviewService; + private _partService = this._bootstrapService.partService; + private _angularEventingService = this._bootstrapService.angularEventingService; + + /* Special Services */ private _metadataService: SingleConnectionMetadataService; private _connectionManagementService: SingleConnectionManagementService; - private _themeService: IWorkbenchThemeService; - private _contextMenuService: IContextMenuService; - private _instantiationService: IInstantiationService; private _adminService: SingleAdminService; private _queryManagementService: SingleQueryManagementService; - private _configService: IConfigurationService; - private _insightsDialogService: IInsightsDialogService; - private _contextViewService: IContextViewService; - private _messageService: IMessageService; - private _workspaceContextService: IWorkspaceContextService; - private _storageService: IStorageService; - private _capabilitiesService: ICapabilitiesService; - private _configurationEditingService: ConfigurationEditingService; - private _commandService: ICommandService; - private _dashboardWebviewService: IDashboardWebviewService; - private _partService: IPartService; private _contextKeyService: IContextKeyService; - private _angularEventingService: IAngularEventingService; private _updatePage = new Emitter(); public readonly onUpdatePage: Event = this._updatePage.event; @@ -155,32 +157,13 @@ export class DashboardServiceInterface implements OnDestroy { private _onCloseTab = new Emitter(); public readonly onCloseTab: Event = this._onCloseTab.event; - private _numberOfPageNavigations: number; + private _numberOfPageNavigations = 0; constructor( @Inject(BOOTSTRAP_SERVICE_ID) private _bootstrapService: IBootstrapService, @Inject(forwardRef(() => Router)) private _router: Router, ) { - this._themeService = this._bootstrapService.themeService; - this._contextMenuService = this._bootstrapService.contextMenuService; - this._instantiationService = this._bootstrapService.instantiationService; - this._configService = this._bootstrapService.configurationService; - this._insightsDialogService = this._bootstrapService.insightsDialogService; - this._contextViewService = this._bootstrapService.contextViewService; - this._messageService = this._bootstrapService.messageService; - this._workspaceContextService = this._bootstrapService.workspaceContextService; - this._storageService = this._bootstrapService.storageService; - this._capabilitiesService = this._bootstrapService.capabilitiesService; - this._configurationEditingService = this._bootstrapService.configurationEditorService; - this._commandService = this._bootstrapService.commandService; - this._dashboardWebviewService = this._bootstrapService.dashboardWebviewService; - this._partService = this._bootstrapService.partService; - this._angularEventingService = this._bootstrapService.angularEventingService; - this._numberOfPageNavigations = 0; - } - - ngOnDestroy() { - this._disposables.forEach((item) => item.dispose()); + super(); } public get messageService(): IMessageService { @@ -279,7 +262,7 @@ export class DashboardServiceInterface implements OnDestroy { this._connectionManagementService = new SingleConnectionManagementService(this._bootstrapService.connectionManagementService, this._uri); this._adminService = new SingleAdminService(this._bootstrapService.adminService, this._uri); this._queryManagementService = new SingleQueryManagementService(this._bootstrapService.queryManagementService, this._uri); - this._disposables.push(toDisposableSubscription(this._bootstrapService.angularEventingService.onAngularEvent(this._uri, (event) => this.handleDashboardEvent(event)))); + this._register(toDisposableSubscription(this._bootstrapService.angularEventingService.onAngularEvent(this._uri, (event) => this.handleDashboardEvent(event)))); } /**