diff --git a/src/sql/parts/jobManagement/common/interfaces.ts b/src/sql/parts/jobManagement/common/interfaces.ts index 19fbbe2088..6f60c8cd87 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 } from './jobManagementService'; +import { JobCacheObject, ProxiesCacheObject } from './jobManagementService'; import { Event } from 'vs/base/common/event'; export const SERVICE_ID = 'jobManagementService'; @@ -39,6 +39,7 @@ export interface IJobManagementService { getCredentials(connectionUri: string): Thenable; jobAction(connectionUri: string, jobName: string, action: string): Thenable; - addToCache(server: string, cache: JobCacheObject); + addToCache(server: string, cache: JobCacheObject | ProxiesCacheObject); jobCacheObjectMap: { [server: string]: JobCacheObject; }; + proxiesCacheObjectMap: {[server: string]: ProxiesCacheObject }; } \ 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 cb8de9e61c..edd8a07039 100644 --- a/src/sql/parts/jobManagement/common/jobManagementService.ts +++ b/src/sql/parts/jobManagement/common/jobManagementService.ts @@ -19,7 +19,8 @@ export class JobManagementService implements IJobManagementService { public readonly onDidChange: Event = this._onDidChange.event; private _providers: { [handle: string]: sqlops.AgentServicesProvider; } = Object.create(null); - private _jobCacheObject : {[server: string]: JobCacheObject; } = {}; + private _jobCacheObjectMap : {[server: string]: JobCacheObject; } = {}; + private _proxiesCacheObjectMap: {[server: string]: ProxiesCacheObject; } = {}; constructor( @IConnectionManagementService private _connectionService: IConnectionManagementService @@ -127,11 +128,19 @@ export class JobManagementService implements IJobManagementService { } public get jobCacheObjectMap(): {[server: string]: JobCacheObject;} { - return this._jobCacheObject; + return this._jobCacheObjectMap; } - public addToCache(server: string, cacheObject: JobCacheObject) { - this._jobCacheObject[server] = cacheObject; + public get proxiesCacheObjectMap(): {[server: string]: ProxiesCacheObject; } { + return this._proxiesCacheObjectMap; + } + + public addToCache(server: string, cacheObject: JobCacheObject | ProxiesCacheObject) { + if (cacheObject instanceof JobCacheObject) { + this._jobCacheObjectMap[server] = cacheObject; + } else if (cacheObject instanceof ProxiesCacheObject) { + this._proxiesCacheObjectMap[server] = cacheObject; + } } } @@ -231,4 +240,43 @@ export class JobCacheObject { public setJobSchedules(jobID: string, value: sqlops.AgentJobScheduleInfo[]) { this._jobSchedules[jobID] = value; } +} + +/** + * Server level caching of job proxies and proxies view + */ +export class ProxiesCacheObject { + _serviceBrand: any; + private _proxies: sqlops.AgentProxyInfo[]; + private _dataView: Slick.Data.DataView; + private _serverName: string; + + /** + * Getters + */ + public get proxies(): sqlops.AgentProxyInfo[] { + return this._proxies; + } + + public get dataview(): Slick.Data.DataView { + return this._dataView; + } + + public get serverName(): string { + return this._serverName; + } + + /** Setters */ + public set proxies(value: sqlops.AgentProxyInfo[]) { + this._proxies = value; + } + + public set dataview(value: Slick.Data.DataView) { + this._dataView = value; + } + + public set serverName(value: string) { + this._serverName = value; + } + } \ No newline at end of file diff --git a/src/sql/parts/jobManagement/common/media/jobs.css b/src/sql/parts/jobManagement/common/media/jobs.css index 4e0a2dd446..fcf43edc72 100644 --- a/src/sql/parts/jobManagement/common/media/jobs.css +++ b/src/sql/parts/jobManagement/common/media/jobs.css @@ -104,6 +104,14 @@ jobhistory-component { display: inline-block; } +#proxiesDiv .jobproxiesview-grid .slick-cell.l1.r1 .proxyview-proxynametext { + text-overflow: ellipsis; + width: 100%; + overflow: hidden; + white-space: nowrap; + display: inline-block; +} + #jobsDiv .job-with-error { border-bottom: none; } @@ -390,4 +398,13 @@ jobsview-component .jobview-grid .slick-cell.error-row { .overview-container > .overview-tab > label { margin-bottom: 0px; +} + +#proxiesDiv .proxyview-proxynameindicatorenabled { + width: 5px; + background: green; +} + #proxiesDiv .proxyview-proxynameindicatordisabled { + width: 5px; + background: red; } \ No newline at end of file diff --git a/src/sql/parts/jobManagement/views/proxiesView.component.ts b/src/sql/parts/jobManagement/views/proxiesView.component.ts index ac66a2f1cb..e9697bc451 100644 --- a/src/sql/parts/jobManagement/views/proxiesView.component.ts +++ b/src/sql/parts/jobManagement/views/proxiesView.component.ts @@ -30,9 +30,11 @@ import { IAction } from 'vs/base/common/actions'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IDashboardService } from 'sql/services/dashboard/common/dashboardService'; +import { ProxiesCacheObject } from 'sql/parts/jobManagement/common/jobManagementService'; +import { RowDetailView } from 'sql/base/browser/ui/table/plugins/rowdetailview'; export const VIEW_SELECTOR: string = 'jobproxiesview-component'; -export const ROW_HEIGHT: number = 30; +export const ROW_HEIGHT: number = 45; @Component({ selector: VIEW_SELECTOR, @@ -46,8 +48,16 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit { private RefreshText: string = nls.localize('jobProxyToolbar-Refresh', "Refresh"); private columns: Array> = [ - { name: nls.localize('jobProxiesView.accountName', 'Account Name'), field: 'accountName', width: 200, id: 'accountName' }, + { + name: nls.localize('jobProxiesView.accountName', 'Account Name'), + field: 'accountName', + formatter: (row, cell, value, columnDef, dataContext) => this.renderName(row, cell, value, columnDef, dataContext), + width: 200, + id: 'accountName' + }, { name: nls.localize('jobProxiesView.credentialName', 'Credential Name'), field: 'credentialName', width: 200, id: 'credentialName' }, + { name: nls.localize('jobProxiesView.description', 'Description'), field: 'description', width: 200, id: 'description'}, + { name: nls.localize('jobProxiesView.isEnabled', 'Enabled'), field: 'isEnabled', width: 200, id: 'isEnabled'} ]; private options: Slick.GridOptions = { @@ -61,6 +71,7 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit { private dataView: any; private _serverName: string; private _isCloud: boolean; + private _proxiesCacheObject: ProxiesCacheObject; public proxies: sqlops.AgentProxyInfo[]; public readonly contextAction = NewProxyAction; @@ -81,6 +92,15 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit { ) { super(commonService, _dashboardService, contextMenuService, keybindingService, instantiationService); this._isCloud = commonService.connectionManagementService.connectionInfo.serverInfo.isCloud; + let proxiesCacheObjectMap = this._jobManagementService.proxiesCacheObjectMap; + let proxiesCacheObject = proxiesCacheObjectMap[this._serverName]; + if (proxiesCacheObject) { + this._proxiesCacheObject = proxiesCacheObject; + } else { + this._proxiesCacheObject = new ProxiesCacheObject(); + this._proxiesCacheObject.serverName = this._serverName; + this._jobManagementService.addToCache(this._serverName, this._proxiesCacheObject); + } } ngOnInit(){ @@ -95,19 +115,35 @@ export class ProxiesViewComponent 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._proxiesCacheObject.serverName === this._serverName) { + if (this._proxiesCacheObject.proxies && this._proxiesCacheObject.proxies.length > 0) { + cached = true; + this.proxies = this._proxiesCacheObject.proxies; + } + } + 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(); @@ -119,20 +155,29 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit { self.openContextMenu(e); })); - let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri; - this._jobManagementService.getProxies(ownerUri).then((result) => { - if (result && result.proxies) { - self.proxies = result.proxies; - self.onProxiesAvailable(result.proxies); - } else { - // TODO: handle error - } - + // checked for cached state + if (cached && this._agentViewComponent.refresh !== true) { + self.onProxiesAvailable(this.proxies); this._showProgressWheel = false; if (this.isVisible) { this._cd.detectChanges(); } - }); + } else { + let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri; + this._jobManagementService.getProxies(ownerUri).then((result) => { + if (result && result.proxies) { + self.proxies = result.proxies; + self._proxiesCacheObject.proxies = result.proxies; + self.onProxiesAvailable(result.proxies); + } else { + // TODO: handle error + } + this._showProgressWheel = false; + if (this.isVisible) { + this._cd.detectChanges(); + } + }); + } } private onProxiesAvailable(proxies: sqlops.AgentProxyInfo[]) { @@ -140,13 +185,16 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit { return { id: item.accountName, accountName: item.accountName, - credentialName: item.credentialName + credentialName: item.credentialName, + description: item.description, + isEnabled: item.isEnabled }; }); this.dataView.beginUpdate(); this.dataView.setItems(items); this.dataView.endUpdate(); + this._proxiesCacheObject.dataview = this.dataView; this._table.autosizeColumns(); this._table.resizeCanvas(); } @@ -164,6 +212,15 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit { : undefined; } + private renderName(row, cell, value, columnDef, dataContext) { + let resultIndicatorClass = dataContext.isEnabled ? 'proxyview-proxynameindicatorenabled' : + 'proxyview-proxynameindicatordisabled'; + return '' + + '' + + '' + + '
' + dataContext.accountName + '
'; + } + public openCreateProxyDialog() { let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri; this._jobManagementService.getCredentials(ownerUri).then((result) => {