Agent/alerts (#2943)

* alerts view is now cached

* added styling to alerts page

* fixed row detail view import
This commit is contained in:
Aditya Bist
2018-10-23 14:42:31 -07:00
committed by GitHub
parent c56dd2cdbd
commit 89e959c2e3
9 changed files with 135 additions and 35 deletions

View File

@@ -7,7 +7,7 @@
import * as sqlops from 'sqlops';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { JobCacheObject, ProxiesCacheObject } from './jobManagementService';
import { JobCacheObject, AlertsCacheObject, ProxiesCacheObject } from './jobManagementService';
import { Event } from 'vs/base/common/event';
export const SERVICE_ID = 'jobManagementService';
@@ -39,7 +39,8 @@ export interface IJobManagementService {
getCredentials(connectionUri: string): Thenable<sqlops.GetCredentialsResult>;
jobAction(connectionUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus>;
addToCache(server: string, cache: JobCacheObject | ProxiesCacheObject);
jobCacheObjectMap: { [server: string]: JobCacheObject; };
alertsCacheObjectMap: { [server: string]: AlertsCacheObject; };
proxiesCacheObjectMap: {[server: string]: ProxiesCacheObject };
addToCache(server: string, cache: JobCacheObject | ProxiesCacheObject | AlertsCacheObject);
}

View File

@@ -20,6 +20,7 @@ export class JobManagementService implements IJobManagementService {
private _providers: { [handle: string]: sqlops.AgentServicesProvider; } = Object.create(null);
private _jobCacheObjectMap : {[server: string]: JobCacheObject; } = {};
private _alertsCacheObject: {[server: string]: AlertsCacheObject; } = {};
private _proxiesCacheObjectMap: {[server: string]: ProxiesCacheObject; } = {};
constructor(
@@ -131,13 +132,19 @@ export class JobManagementService implements IJobManagementService {
return this._jobCacheObjectMap;
}
public get alertsCacheObjectMap(): {[server: string]: AlertsCacheObject; } {
return this._alertsCacheObject;
}
public get proxiesCacheObjectMap(): {[server: string]: ProxiesCacheObject; } {
return this._proxiesCacheObjectMap;
}
public addToCache(server: string, cacheObject: JobCacheObject | ProxiesCacheObject) {
public addToCache(server: string, cacheObject: JobCacheObject | AlertsCacheObject | ProxiesCacheObject) {
if (cacheObject instanceof JobCacheObject) {
this._jobCacheObjectMap[server] = cacheObject;
this._jobCacheObjectMap[server] = cacheObject;;
} else if (cacheObject instanceof AlertsCacheObject) {
this._alertsCacheObject[server] = cacheObject;
} else if (cacheObject instanceof ProxiesCacheObject) {
this._proxiesCacheObjectMap[server] = cacheObject;
}
@@ -145,7 +152,7 @@ export class JobManagementService implements IJobManagementService {
}
/**
* Server level caching of jobs/job histories
* Server level caching of jobs/job histories and their views
*/
export class JobCacheObject {
_serviceBrand: any;
@@ -242,6 +249,44 @@ export class JobCacheObject {
}
}
/**
* Server level caching of job alerts and the alerts view
*/
export class AlertsCacheObject {
_serviceBrand: any;
private _alerts: sqlops.AgentAlertInfo[];
private _dataView: Slick.Data.DataView<any>;
private _serverName: string;
/** Getters */
public get alerts(): sqlops.AgentAlertInfo[] {
return this._alerts;
}
public get dataview(): Slick.Data.DataView<any> {
return this._dataView;
}
public get serverName(): string {
return this._serverName;
}
/** Setters */
public set alerts(value: sqlops.AgentAlertInfo[]) {
this._alerts = value;
}
public set dataview(value: Slick.Data.DataView<any>) {
this._dataView = value;
}
public set serverName(value: string) {
this._serverName = value;
}
}
/**
* Server level caching of job proxies and proxies view
*/
@@ -267,6 +312,7 @@ export class ProxiesCacheObject {
}
/** Setters */
public set proxies(value: sqlops.AgentProxyInfo[]) {
this._proxies = value;
}
@@ -278,5 +324,4 @@ export class ProxiesCacheObject {
public set serverName(value: string) {
this._serverName = value;
}
}

View File

@@ -104,6 +104,7 @@ jobhistory-component {
display: inline-block;
}
#alertsDiv .jobalertsview-grid .slick-cell.l1.r1 .alertview-alertnametext,
#proxiesDiv .jobproxiesview-grid .slick-cell.l1.r1 .proxyview-proxynametext {
text-overflow: ellipsis;
width: 100%;
@@ -400,11 +401,14 @@ jobsview-component .jobview-grid .slick-cell.error-row {
margin-bottom: 0px;
}
#alertsDiv .alertview-alertnameindicatorenabled,
#proxiesDiv .proxyview-proxynameindicatorenabled {
width: 5px;
background: green;
}
#proxiesDiv .proxyview-proxynameindicatordisabled {
#alertsDiv .alertview-alertnameindicatordisabled,
#proxiesDiv .proxyview-proxynameindicatordisabled {
width: 5px;
background: red;
}

View File

@@ -30,9 +30,11 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IDashboardService } from 'sql/services/dashboard/common/dashboardService';
import { AlertsCacheObject } from 'sql/parts/jobManagement/common/jobManagementService';
import { RowDetailView } from 'sql/base/browser/ui/table/plugins/rowdetailview';
export const VIEW_SELECTOR: string = 'jobalertsview-component';
export const ROW_HEIGHT: number = 30;
export const ROW_HEIGHT: number = 45;
@Component({
selector: VIEW_SELECTOR,
@@ -42,11 +44,17 @@ export const ROW_HEIGHT: number = 30;
export class AlertsViewComponent extends JobManagementView implements OnInit {
private columns: Array<Slick.Column<any>> = [
{ name: nls.localize('jobAlertColumns.name', 'Name'), field: 'name', width: 200, id: 'name' },
{ name: nls.localize('jobAlertColumns.lastOccurrenceDate', 'Last Occurrence'), field: 'lastOccurrenceDate', width: 200, id: 'lastOccurrenceDate' },
{ name: nls.localize('jobAlertColumns.enabled', 'Enabled'), field: 'enabled', width: 200, id: 'enabled' },
{ name: nls.localize('jobAlertColumns.databaseName', 'Database Name'), field: 'databaseName', width: 200, id: 'databaseName' },
{ name: nls.localize('jobAlertColumns.categoryName', 'Category Name'), field: 'categoryName', width: 200, id: 'categoryName' },
{
name: nls.localize('jobAlertColumns.name', 'Name'),
field: 'name',
formatter: (row, cell, value, columnDef, dataContext) => this.renderName(row, cell, value, columnDef, dataContext),
width: 500,
id: 'name'
},
{ name: nls.localize('jobAlertColumns.lastOccurrenceDate', 'Last Occurrence'), field: 'lastOccurrenceDate', width: 150, id: 'lastOccurrenceDate' },
{ name: nls.localize('jobAlertColumns.enabled', 'Enabled'), field: 'enabled', width: 80, id: 'enabled' },
{ name: nls.localize('jobAlertColumns.delayBetweenResponses', 'Delay Between Responses (in secs)'), field: 'delayBetweenResponses', width: 200, id: 'delayBetweenResponses' },
{ name: nls.localize('jobAlertColumns.categoryName', 'Category Name'), field: 'categoryName', width: 250, id: 'categoryName' },
];
private options: Slick.GridOptions<any> = {
@@ -59,6 +67,7 @@ export class AlertsViewComponent extends JobManagementView implements OnInit {
private dataView: any;
private _isCloud: boolean;
private _alertsCacheObject: AlertsCacheObject;
@ViewChild('jobalertsgrid') _gridEl: ElementRef;
@@ -78,6 +87,15 @@ export class AlertsViewComponent extends JobManagementView implements OnInit {
@Inject(IDashboardService) _dashboardService: IDashboardService) {
super(commonService, _dashboardService, contextMenuService, keybindingService, instantiationService);
this._isCloud = commonService.connectionManagementService.connectionInfo.serverInfo.isCloud;
let alertsCacheObjectMap = this._jobManagementService.alertsCacheObjectMap;
let alertsCache = alertsCacheObjectMap[this._serverName];
if (alertsCache) {
this._alertsCacheObject = alertsCache;
} else {
this._alertsCacheObject = new AlertsCacheObject();
this._alertsCacheObject.serverName = this._serverName;
this._jobManagementService.addToCache(this._serverName, this._alertsCacheObject);
}
}
ngOnInit(){
@@ -92,44 +110,67 @@ export class AlertsViewComponent 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._alertsCacheObject.serverName === this._serverName) {
if (this._alertsCacheObject.alerts && this._alertsCacheObject.alerts.length > 0) {
cached = true;
this.alerts = this._alertsCacheObject.alerts;
}
}
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();
this.initActionBar();
this._table = new Table(this._gridEl.nativeElement, {columns}, this.options);
this._table.grid.setData(this.dataView, true);
this._register(this._table.onContextMenu(e => {
self.openContextMenu(e);
}));
let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri;
this._jobManagementService.getAlerts(ownerUri).then((result) => {
if (result && result.alerts) {
self.alerts = result.alerts;
self.onAlertsAvailable(result.alerts);
} else {
// TODO: handle error
}
// check for cached state
if (cached && this._agentViewComponent.refresh !== true) {
self.onAlertsAvailable(this.alerts);
this._showProgressWheel = false;
if (this.isVisible) {
this._cd.detectChanges();
}
});
} else {
let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri;
this._jobManagementService.getAlerts(ownerUri).then((result) => {
if (result && result.alerts) {
self.alerts = result.alerts;
self._alertsCacheObject.alerts = result.alerts;
self.onAlertsAvailable(result.alerts);
} else {
// TODO: handle error
}
this._showProgressWheel = false;
if (this.isVisible) {
this._cd.detectChanges();
}
});
}
}
private onAlertsAvailable(alerts: sqlops.AgentAlertInfo[]) {
@@ -139,7 +180,7 @@ export class AlertsViewComponent extends JobManagementView implements OnInit {
name: item.name,
lastOccurrenceDate: item.lastOccurrenceDate,
enabled: item.isEnabled,
databaseName: item.databaseName,
delayBetweenResponses: item.delayBetweenResponses,
categoryName: item.categoryName
};
});
@@ -147,6 +188,7 @@ export class AlertsViewComponent extends JobManagementView implements OnInit {
this.dataView.beginUpdate();
this.dataView.setItems(items);
this.dataView.endUpdate();
this._alertsCacheObject.dataview = this.dataView;
this._table.autosizeColumns();
this._table.resizeCanvas();
}
@@ -164,6 +206,17 @@ export class AlertsViewComponent extends JobManagementView implements OnInit {
: undefined;
}
private renderName(row, cell, value, columnDef, dataContext) {
let resultIndicatorClass = dataContext.enabled ? 'alertview-alertnameindicatorenabled' :
'alertview-alertnameindicatordisabled';
return '<table class="alertview-alertnametable"><tr class="alertview-alertnamerow">' +
'<td nowrap class=' + resultIndicatorClass + '></td>' +
'<td nowrap class="alertview-alertnametext">' + dataContext.name + '</td>' +
'</tr></table>';
}
public openCreateAlertDialog() {
let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri;
this._jobManagementService.getJobs(ownerUri).then((result) => {

View File

@@ -63,7 +63,6 @@ export class JobHistoryComponent extends JobManagementView implements OnInit {
private _jobCacheObject: JobCacheObject;
private _agentJobInfo: sqlops.AgentJobInfo;
private _noJobsAvailable: boolean = false;
private _serverName: string;
private static readonly INITIAL_TREE_HEIGHT: number = 780;
private static readonly HEADING_HEIGHT: number = 24;

View File

@@ -28,6 +28,7 @@ export abstract class JobManagementView extends TabChild implements AfterContent
protected _parentComponent: AgentViewComponent;
protected _table: Table<any>;
protected _actionBar: Taskbar;
protected _serverName: string;
public contextAction: any;
@ViewChild('actionbarContainer') protected actionBarContainer: ElementRef;
@@ -41,6 +42,7 @@ export abstract class JobManagementView extends TabChild implements AfterContent
super();
let self = this;
this._serverName = this._commonService.connectionManagementService.connectionInfo.connectionProfile.serverName;
this._dashboardService.onLayout((d) => {
self.layout();
});

View File

@@ -78,7 +78,6 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
private rowDetail: RowDetailView;
private filterPlugin: any;
private dataView: any;
private _serverName: string;
private _isCloud: boolean;
private filterStylingMap: { [columnName: string]: [any]; } = {};
private filterStack = ['start'];
@@ -109,7 +108,6 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
) {
super(commonService, _dashboardService, contextMenuService, keybindingService, instantiationService);
let jobCacheObjectMap = this._jobManagementService.jobCacheObjectMap;
this._serverName = commonService.connectionManagementService.connectionInfo.connectionProfile.serverName;
let jobCache = jobCacheObjectMap[this._serverName];
if (jobCache) {
this._jobCacheObject = jobCache;

View File

@@ -57,7 +57,6 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit
};
private dataView: any;
private _serverName: string;
private _isCloud: boolean;
@ViewChild('operatorsgrid') _gridEl: ElementRef;

View File

@@ -69,7 +69,6 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit {
};
private dataView: any;
private _serverName: string;
private _isCloud: boolean;
private _proxiesCacheObject: ProxiesCacheObject;