From 3d392725361b73db7a44f4f7bb8ff228bccede1d Mon Sep 17 00:00:00 2001 From: Aditya Bist Date: Tue, 23 Oct 2018 15:22:44 -0700 Subject: [PATCH] Agent/operators (#2962) * added caching and view for operators * fixed row detail import --- .../parts/jobManagement/common/interfaces.ts | 6 +- .../common/jobManagementService.ts | 55 ++++++++++-- .../parts/jobManagement/common/media/jobs.css | 3 + .../views/operatorsView.component.ts | 86 +++++++++++++++---- 4 files changed, 126 insertions(+), 24 deletions(-) diff --git a/src/sql/parts/jobManagement/common/interfaces.ts b/src/sql/parts/jobManagement/common/interfaces.ts index 589f5bb335..eee4a79997 100644 --- a/src/sql/parts/jobManagement/common/interfaces.ts +++ b/src/sql/parts/jobManagement/common/interfaces.ts @@ -7,7 +7,7 @@ import * as sqlops from 'sqlops'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { JobCacheObject, AlertsCacheObject, ProxiesCacheObject } from './jobManagementService'; +import { JobCacheObject, AlertsCacheObject, ProxiesCacheObject, OperatorsCacheObject } from './jobManagementService'; import { Event } from 'vs/base/common/event'; export const SERVICE_ID = 'jobManagementService'; @@ -39,8 +39,10 @@ export interface IJobManagementService { getCredentials(connectionUri: string): Thenable; jobAction(connectionUri: string, jobName: string, action: string): Thenable; + addToCache(server: string, cache: JobCacheObject | OperatorsCacheObject); jobCacheObjectMap: { [server: string]: JobCacheObject; }; + operatorsCacheObjectMap: { [server: string]: OperatorsCacheObject; }; alertsCacheObjectMap: { [server: string]: AlertsCacheObject; }; proxiesCacheObjectMap: {[server: string]: ProxiesCacheObject }; - addToCache(server: string, cache: JobCacheObject | ProxiesCacheObject | AlertsCacheObject); + addToCache(server: string, cache: JobCacheObject | ProxiesCacheObject | AlertsCacheObject | OperatorsCacheObject); } \ No newline at end of file diff --git a/src/sql/parts/jobManagement/common/jobManagementService.ts b/src/sql/parts/jobManagement/common/jobManagementService.ts index acbf3fe9cf..b793eaefac 100644 --- a/src/sql/parts/jobManagement/common/jobManagementService.ts +++ b/src/sql/parts/jobManagement/common/jobManagementService.ts @@ -20,6 +20,7 @@ export class JobManagementService implements IJobManagementService { private _providers: { [handle: string]: sqlops.AgentServicesProvider; } = Object.create(null); private _jobCacheObjectMap : {[server: string]: JobCacheObject; } = {}; + private _operatorsCacheObjectMap: {[server: string]: OperatorsCacheObject; } = {}; private _alertsCacheObject: {[server: string]: AlertsCacheObject; } = {}; private _proxiesCacheObjectMap: {[server: string]: ProxiesCacheObject; } = {}; @@ -140,9 +141,15 @@ export class JobManagementService implements IJobManagementService { return this._proxiesCacheObjectMap; } - public addToCache(server: string, cacheObject: JobCacheObject | AlertsCacheObject | ProxiesCacheObject) { + public get operatorsCacheObjectMap(): {[server: string]: OperatorsCacheObject} { + return this._operatorsCacheObjectMap; + } + + public addToCache(server: string, cacheObject: JobCacheObject | OperatorsCacheObject | ProxiesCacheObject | AlertsCacheObject) { if (cacheObject instanceof JobCacheObject) { - this._jobCacheObjectMap[server] = cacheObject;; + this._jobCacheObjectMap[server] = cacheObject; + } else if (cacheObject instanceof OperatorsCacheObject) { + this._operatorsCacheObjectMap[server] = cacheObject; } else if (cacheObject instanceof AlertsCacheObject) { this._alertsCacheObject[server] = cacheObject; } else if (cacheObject instanceof ProxiesCacheObject) { @@ -250,15 +257,52 @@ export class JobCacheObject { } /** - * Server level caching of job alerts and the alerts view + * Server level caching of Operators */ -export class AlertsCacheObject { +export class OperatorsCacheObject { _serviceBrand: any; - private _alerts: sqlops.AgentAlertInfo[]; + private _operators: sqlops.AgentOperatorInfo[]; private _dataView: Slick.Data.DataView; private _serverName: string; /** Getters */ + public get operators(): sqlops.AgentOperatorInfo[] { + return this._operators; + } + + public get dataview(): Slick.Data.DataView { + return this._dataView; + } + + public get serverName(): string { + return this._serverName; + } + + /** Setters */ + public set operators(value: sqlops.AgentOperatorInfo[]) { + this._operators = value; + } + + public set dataview(value: Slick.Data.DataView) { + this._dataView = value; + } + + public set serverName(value: string) { + this._serverName = value; + } + +} + +/* +* Server level caching of job alerts and the alerts view +*/ +export class AlertsCacheObject { + _serviceBrand: any; + private _alerts: sqlops.AgentAlertInfo[]; + private _dataView: Slick.Data.DataView; + private _serverName: string; + + /** Getters */ public get alerts(): sqlops.AgentAlertInfo[] { return this._alerts; } @@ -272,7 +316,6 @@ export class AlertsCacheObject { } /** Setters */ - public set alerts(value: sqlops.AgentAlertInfo[]) { this._alerts = value; } diff --git a/src/sql/parts/jobManagement/common/media/jobs.css b/src/sql/parts/jobManagement/common/media/jobs.css index 03bc804c9a..acd85e9e42 100644 --- a/src/sql/parts/jobManagement/common/media/jobs.css +++ b/src/sql/parts/jobManagement/common/media/jobs.css @@ -104,6 +104,7 @@ jobhistory-component { display: inline-block; } +#operatorsDiv .joboperatorsview-grid .slick-cell.l1.r1 .operatorview-operatornametext, #alertsDiv .jobalertsview-grid .slick-cell.l1.r1 .alertview-alertnametext, #proxiesDiv .jobproxiesview-grid .slick-cell.l1.r1 .proxyview-proxynametext { text-overflow: ellipsis; @@ -401,12 +402,14 @@ jobsview-component .jobview-grid .slick-cell.error-row { margin-bottom: 0px; } +#operatorsDiv .operatorview-operatornameindicatorenabled, #alertsDiv .alertview-alertnameindicatorenabled, #proxiesDiv .proxyview-proxynameindicatorenabled { width: 5px; background: green; } +#operatorsDiv .operatorview-operatornameindicatordisabled, #alertsDiv .alertview-alertnameindicatordisabled, #proxiesDiv .proxyview-proxynameindicatordisabled { width: 5px; diff --git a/src/sql/parts/jobManagement/views/operatorsView.component.ts b/src/sql/parts/jobManagement/views/operatorsView.component.ts index a50e2e1ddc..9b33c1f1d4 100644 --- a/src/sql/parts/jobManagement/views/operatorsView.component.ts +++ b/src/sql/parts/jobManagement/views/operatorsView.component.ts @@ -30,9 +30,11 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IAction } from 'vs/base/common/actions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IDashboardService } from 'sql/services/dashboard/common/dashboardService'; +import { OperatorsCacheObject } from 'sql/parts/jobManagement/common/jobManagementService'; +import { RowDetailView } from 'sql/base/browser/ui/table/plugins/rowdetailview'; export const VIEW_SELECTOR: string = 'joboperatorsview-component'; -export const ROW_HEIGHT: number = 30; +export const ROW_HEIGHT: number = 45; @Component({ selector: VIEW_SELECTOR, @@ -43,7 +45,13 @@ export const ROW_HEIGHT: number = 30; export class OperatorsViewComponent extends JobManagementView implements OnInit { private columns: Array> = [ - { name: nls.localize('jobOperatorsView.name', 'Name'), field: 'name', width: 200, id: 'name' }, + { + name: nls.localize('jobOperatorsView.name', 'Name'), + field: 'name', + formatter: (row, cell, value, columnDef, dataContext) => this.renderName(row, cell, value, columnDef, dataContext), + width: 200, + id: 'name' + }, { name: nls.localize('jobOperatorsView.emailAddress', 'Email Address'), field: 'emailAddress', width: 200, id: 'emailAddress' }, { name: nls.localize('jobOperatorsView.enabled', 'Enabled'), field: 'enabled', width: 200, id: 'enabled' }, ]; @@ -58,6 +66,7 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit private dataView: any; private _isCloud: boolean; + private _operatorsCacheObject: OperatorsCacheObject; @ViewChild('operatorsgrid') _gridEl: ElementRef; @@ -78,6 +87,15 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit ) { super(commonService, _dashboardService, contextMenuService, keybindingService, instantiationService); this._isCloud = commonService.connectionManagementService.connectionInfo.serverInfo.isCloud; + let operatorsCacheObject = this._jobManagementService.operatorsCacheObjectMap; + let operatorsCache = operatorsCacheObject[this._serverName]; + if (operatorsCache) { + this._operatorsCacheObject = operatorsCache; + } else { + this._operatorsCacheObject = new OperatorsCacheObject(); + this._operatorsCacheObject.serverName = this._serverName; + this._jobManagementService.addToCache(this._serverName, this._operatorsCacheObject); + } } ngOnInit(){ @@ -92,19 +110,36 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit height = 0; } - this._table.layout(new dom.Dimension( - dom.getContentWidth(this._gridEl.nativeElement), - height)); + if (this._table) { + this._table.layout(new dom.Dimension( + dom.getContentWidth(this._gridEl.nativeElement), + height)); + } } onFirstVisible() { let self = this; + + let cached: boolean = false; + if (this._operatorsCacheObject.serverName === this._serverName) { + if (this._operatorsCacheObject.operators && this._operatorsCacheObject.operators.length > 0) { + cached = true; + this.operators = this._operatorsCacheObject.operators; + } + } + let columns = this.columns.map((column) => { column.rerenderOnResize = true; return column; }); - this.dataView = new Slick.Data.DataView(); + this.dataView = new Slick.Data.DataView({ inlineFilters: false }); + let rowDetail = new RowDetailView({ + cssClass: '_detail_selector', + useRowClick: false, + panelRows: 1 + }); + columns.unshift(rowDetail.getColumnDefinition()); $(this._gridEl.nativeElement).empty(); $(this.actionBarContainer.nativeElement).empty(); @@ -116,20 +151,29 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit self.openContextMenu(e); })); - let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri; - this._jobManagementService.getOperators(ownerUri).then((result) => { - if (result && result.operators) { - self.operators = result.operators; - self.onOperatorsAvailable(result.operators); - } else { - // TODO: handle error - } - + // check for cached state + if (cached && this._agentViewComponent.refresh !== true) { + this.onOperatorsAvailable(this.operators); this._showProgressWheel = false; if (this.isVisible) { this._cd.detectChanges(); } - }); + } else { + let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri; + this._jobManagementService.getOperators(ownerUri).then((result) => { + if (result && result.operators) { + self.operators = result.operators; + self._operatorsCacheObject.operators = result.operators; + self.onOperatorsAvailable(result.operators); + } else { + // TODO: handle error + } + this._showProgressWheel = false; + if (this.isVisible) { + this._cd.detectChanges(); + } + }); + } } private onOperatorsAvailable(operators: sqlops.AgentOperatorInfo[]) { @@ -145,6 +189,7 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit this.dataView.beginUpdate(); this.dataView.setItems(items); this.dataView.endUpdate(); + this._operatorsCacheObject.dataview = this.dataView; this._table.autosizeColumns(); this._table.resizeCanvas(); } @@ -162,6 +207,15 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit : undefined; } + private renderName(row, cell, value, columnDef, dataContext) { + let resultIndicatorClass = dataContext.enabled ? 'operatorview-operatornameindicatorenabled' : + 'operatorview-operatornameindicatordisabled'; + return '' + + '' + + '' + + '
' + dataContext.name + '
'; + } + public openCreateOperatorDialog() { let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri; this._commandService.executeCommand('agent.openOperatorDialog', ownerUri);