Refresh agent dashboard panel after create\update\delete operations (#1861)

* Edit alert WIP

* A couple alert edit bugs

* Hook up dashboard refresh notification

* Hook onchange event to other agent service calls

* Switch update handler to scalar value

* Add null check on handler callback
This commit is contained in:
Karl Burtram
2018-07-06 08:57:30 -07:00
committed by GitHub
parent 6f9a27ecc7
commit 21bad7a01f
25 changed files with 280 additions and 103 deletions

View File

@@ -4,14 +4,20 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as nls from 'vscode-nls';
import * as vscode from 'vscode';
import * as sqlops from 'sqlops';
import { AgentUtils } from '../agentUtils';
import { IAgentDialogData } from '../interfaces';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
const localize = nls.loadMessageBundle();
export class AlertData implements IAgentDialogData {
ownerUri: string;
dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
id: number;
name: string;
originalName: string;
delayBetweenResponses: number;
eventDescriptionKeyword: string;
eventSource: string;
@@ -34,8 +40,36 @@ export class AlertData implements IAgentDialogData {
wmiEventNamespace: string;
wmiEventQuery: string;
constructor(ownerUri:string) {
constructor(ownerUri:string, alertInfo: sqlops.AgentAlertInfo) {
this.ownerUri = ownerUri;
if (alertInfo) {
this.dialogMode = AgentDialogMode.EDIT;
this.id = alertInfo.id;
this.name = alertInfo.name;
this.originalName = alertInfo.name;
this.delayBetweenResponses = alertInfo.delayBetweenResponses;
this.eventDescriptionKeyword = alertInfo.eventDescriptionKeyword;
this.eventSource = alertInfo.eventSource;
this.hasNotification = alertInfo.hasNotification;
this.includeEventDescription = alertInfo.includeEventDescription.toString();
this.isEnabled = alertInfo.isEnabled;
this.jobId = alertInfo.jobId;
this.jobName = alertInfo.jobName;
this.lastOccurrenceDate = alertInfo.lastOccurrenceDate;
this.lastResponseDate = alertInfo.lastResponseDate;
this.messageId = alertInfo.messageId;
this.notificationMessage = alertInfo.notificationMessage;
this.occurrenceCount = alertInfo.occurrenceCount;
this.performanceCondition = alertInfo.performanceCondition;
this.severity = alertInfo.severity;
this.databaseName = alertInfo.databaseName;
this.countResetDate = alertInfo.countResetDate;
this.categoryName = alertInfo.categoryName;
this.alertType = alertInfo.alertType.toString();
this.wmiEventNamespace = alertInfo.wmiEventNamespace;
this.wmiEventQuery = alertInfo.wmiEventQuery;
}
}
public async initialize() {
@@ -43,9 +77,13 @@ export class AlertData implements IAgentDialogData {
public async save() {
let agentService = await AgentUtils.getAgentService();
let result = await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo());
let result = this.dialogMode === AgentDialogMode.CREATE
? await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo())
: await agentService.updateAlert(this.ownerUri, this.originalName, this.toAgentAlertInfo());
if (!result || !result.success) {
// TODO handle error here
vscode.window.showErrorMessage(
localize('alertData.saveErrorMessage', "Alert update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown'));
}
}
@@ -76,4 +114,4 @@ export class AlertData implements IAgentDialogData {
wmiEventQuery: this.wmiEventQuery
};
}
}
}

View File

@@ -6,7 +6,7 @@
import * as sqlops from 'sqlops';
import { AgentUtils } from '../agentUtils';
import { IAgentDialogData } from '../interfaces';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
export class JobData implements IAgentDialogData {
@@ -23,6 +23,7 @@ export class JobData implements IAgentDialogData {
private _defaultOwner: string;
private _jobCompletionActionConditions: sqlops.CategoryValue[];
public dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
public name: string;
public enabled: boolean = true;
public description: string;

View File

@@ -5,9 +5,10 @@
'use strict';
import { AgentUtils } from '../agentUtils';
import { IAgentDialogData } from '../interfaces';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
export class JobStepData implements IAgentDialogData {
public dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
public ownerUri: string;
public jobId: string; //
public jobName: string;

View File

@@ -6,9 +6,10 @@
import * as sqlops from 'sqlops';
import { AgentUtils } from '../agentUtils';
import { IAgentDialogData } from '../interfaces';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
export class OperatorData implements IAgentDialogData {
public dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
ownerUri: string;
name: string;
id: number;

View File

@@ -6,9 +6,10 @@
import * as sqlops from 'sqlops';
import { AgentUtils } from '../agentUtils';
import { IAgentDialogData } from '../interfaces';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
export class PickScheduleData implements IAgentDialogData {
public dialogMode: AgentDialogMode = AgentDialogMode.VIEW;
public ownerUri: string;
public schedules: sqlops.AgentJobScheduleInfo[];
public selectedSchedule: sqlops.AgentJobScheduleInfo;

View File

@@ -6,9 +6,10 @@
import * as sqlops from 'sqlops';
import { AgentUtils } from '../agentUtils';
import { IAgentDialogData } from '../interfaces';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
export class ProxyData implements IAgentDialogData {
public dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
ownerUri: string;
id: number;
accountName: string;

View File

@@ -6,9 +6,10 @@
import * as sqlops from 'sqlops';
import { AgentUtils } from '../agentUtils';
import { IAgentDialogData } from '../interfaces';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
export class ScheduleData implements IAgentDialogData {
public dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
public ownerUri: string;
public schedules: sqlops.AgentJobScheduleInfo[];
public selectedSchedule: sqlops.AgentJobScheduleInfo;

View File

@@ -7,14 +7,14 @@
import * as nls from 'vscode-nls';
import * as sqlops from 'sqlops';
import * as vscode from 'vscode';
import { IAgentDialogData } from '../interfaces';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
const localize = nls.loadMessageBundle();
export abstract class AgentDialog<T extends IAgentDialogData> {
private static readonly OkButtonText: string = localize('createAlert.OK', 'OK');
private static readonly CancelButtonText: string = localize('createAlert.Cancel', 'Cancel');
private static readonly OkButtonText: string = localize('agentDialog.OK', 'OK');
private static readonly CancelButtonText: string = localize('agentDialog.Cancel', 'Cancel');
protected _onSuccess: vscode.EventEmitter<T> = new vscode.EventEmitter<T>();
public readonly onSuccess: vscode.Event<T> = this._onSuccess.event;
@@ -23,6 +23,10 @@ export abstract class AgentDialog<T extends IAgentDialogData> {
constructor(public ownerUri: string, public model: T, public title: string) {
}
public get dialogMode(): AgentDialogMode {
return this.model.dialogMode;
}
protected abstract async updateModel();
protected abstract async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog);

View File

@@ -16,48 +16,49 @@ const localize = nls.loadMessageBundle();
export class AlertDialog extends AgentDialog<AlertData> {
// Top level
private static readonly DialogTitle: string = localize('createAlert.createAlert', 'Create Alert');
private static readonly GeneralTabText: string = localize('createAlert.General', 'General');
private static readonly ResponseTabText: string = localize('createAlert.Response', 'Response');
private static readonly OptionsTabText: string = localize('createAlert.Options', 'Options');
private static readonly CreateDialogTitle: string = localize('alertDialog.createAlert', 'Create Alert');
private static readonly EditDialogTitle: string = localize('alertDialog.editAlert', 'Edit Alert');
private static readonly GeneralTabText: string = localize('alertDialog.General', 'General');
private static readonly ResponseTabText: string = localize('alertDialog.Response', 'Response');
private static readonly OptionsTabText: string = localize('alertDialog.Options', 'Options');
// General tab strings
private static readonly NameLabel: string = localize('createAlert.Name', 'Name');
private static readonly TypeLabel: string = localize('createAlert.Type', 'Type');
private static readonly EnabledCheckboxLabel: string = localize('createAlert.Enabled', 'Enabled');
private static readonly DatabaseLabel: string = localize('createAlert.DatabaseName', 'Database name');
private static readonly ErrorNumberLabel: string = localize('createAlert.ErrorNumber', 'Error number');
private static readonly SeverityLabel: string = localize('createAlert.Severity', 'Severity');
private static readonly RaiseIfMessageContainsLabel: string = localize('createAlert.RaiseAlertContains', 'Raise alert when message contains');
private static readonly MessageTextLabel: string = localize('createAlert.MessageText', 'Message text');
private static readonly AlertTypeSqlServerEventString: string = localize('createAlert.SqlServerEventAlert', 'SQL Server event alert');
private static readonly AlertTypePerformanceConditionString: string = localize('createAlert.PerformanceCondition', 'SQL Server performance condition alert');
private static readonly AlertTypeWmiEventString: string = localize('createAlert.WmiEvent', 'WMI event alert');
private static readonly AlertSeverity001Label: string = localize('createAlert.Severity001', '001 - Miscellaneous System Information');
private static readonly AlertSeverity002Label: string = localize('createAlert.Severity002', '002 - Reserved');
private static readonly AlertSeverity003Label: string = localize('createAlert.Severity003', '003 - Reserved');
private static readonly AlertSeverity004Label: string = localize('createAlert.Severity004', '004 - Reserved');
private static readonly AlertSeverity005Label: string = localize('createAlert.Severity005', '005 - Reserved');
private static readonly AlertSeverity006Label: string = localize('createAlert.Severity006', '006 - Reserved');
private static readonly AlertSeverity007Label: string = localize('createAlert.Severity007', '007 - Notification: Status Information');
private static readonly AlertSeverity008Label: string = localize('createAlert.Severity008', '008 - Notification: User Intervention Required');
private static readonly AlertSeverity009Label: string = localize('createAlert.Severity009', '009 - User Defined');
private static readonly AlertSeverity010Label: string = localize('createAlert.Severity010', '010 - Information');
private static readonly AlertSeverity011Label: string = localize('createAlert.Severity011', '011 - Specified Database Object Not Found');
private static readonly AlertSeverity012Label: string = localize('createAlert.Severity012', '012 - Unused');
private static readonly AlertSeverity013Label: string = localize('createAlert.Severity013', '013 - User Transaction Syntax Error');
private static readonly AlertSeverity014Label: string = localize('createAlert.Severity014', '014 - Insufficient Permission');
private static readonly AlertSeverity015Label: string = localize('createAlert.Severity015', '015 - Syntax Error in SQL Statements');
private static readonly AlertSeverity016Label: string = localize('createAlert.Severity016', '016 - Miscellaneous User Error');
private static readonly AlertSeverity017Label: string = localize('createAlert.Severity017', '017 - Insufficient Resources');
private static readonly AlertSeverity018Label: string = localize('createAlert.Severity018', '018 - Nonfatal Internal Error');
private static readonly AlertSeverity019Label: string = localize('createAlert.Severity019', '019 - Fatal Error in Resource');
private static readonly AlertSeverity020Label: string = localize('createAlert.Severity020', '020 - Fatal Error in Current Process');
private static readonly AlertSeverity021Label: string = localize('createAlert.Severity021', '021 - Fatal Error in Database Processes');
private static readonly AlertSeverity022Label: string = localize('createAlert.Severity022', '022 - Fatal Error: Table Integrity Suspect');
private static readonly AlertSeverity023Label: string = localize('createAlert.Severity023', '023 - Fatal Error: Database Integrity Suspect');
private static readonly AlertSeverity024Label: string = localize('createAlert.Severity024', '024 - Fatal Error: Hardware Error');
private static readonly AlertSeverity025Label: string = localize('createAlert.Severity025', '025 - Fatal Error');
private static readonly NameLabel: string = localize('alertDialog.Name', 'Name');
private static readonly TypeLabel: string = localize('alertDialog.Type', 'Type');
private static readonly EnabledCheckboxLabel: string = localize('alertDialog.Enabled', 'Enabled');
private static readonly DatabaseLabel: string = localize('alertDialog.DatabaseName', 'Database name');
private static readonly ErrorNumberLabel: string = localize('alertDialog.ErrorNumber', 'Error number');
private static readonly SeverityLabel: string = localize('alertDialog.Severity', 'Severity');
private static readonly RaiseIfMessageContainsLabel: string = localize('alertDialog.RaiseAlertContains', 'Raise alert when message contains');
private static readonly MessageTextLabel: string = localize('alertDialog.MessageText', 'Message text');
private static readonly AlertTypeSqlServerEventString: string = localize('alertDialog.SqlServerEventAlert', 'SQL Server event alert');
private static readonly AlertTypePerformanceConditionString: string = localize('alertDialog.PerformanceCondition', 'SQL Server performance condition alert');
private static readonly AlertTypeWmiEventString: string = localize('alertDialog.WmiEvent', 'WMI event alert');
private static readonly AlertSeverity001Label: string = localize('alertDialog.Severity001', '001 - Miscellaneous System Information');
private static readonly AlertSeverity002Label: string = localize('alertDialog.Severity002', '002 - Reserved');
private static readonly AlertSeverity003Label: string = localize('alertDialog.Severity003', '003 - Reserved');
private static readonly AlertSeverity004Label: string = localize('alertDialog.Severity004', '004 - Reserved');
private static readonly AlertSeverity005Label: string = localize('alertDialog.Severity005', '005 - Reserved');
private static readonly AlertSeverity006Label: string = localize('alertDialog.Severity006', '006 - Reserved');
private static readonly AlertSeverity007Label: string = localize('alertDialog.Severity007', '007 - Notification: Status Information');
private static readonly AlertSeverity008Label: string = localize('alertDialog.Severity008', '008 - Notification: User Intervention Required');
private static readonly AlertSeverity009Label: string = localize('alertDialog.Severity009', '009 - User Defined');
private static readonly AlertSeverity010Label: string = localize('alertDialog.Severity010', '010 - Information');
private static readonly AlertSeverity011Label: string = localize('alertDialog.Severity011', '011 - Specified Database Object Not Found');
private static readonly AlertSeverity012Label: string = localize('alertDialog.Severity012', '012 - Unused');
private static readonly AlertSeverity013Label: string = localize('alertDialog.Severity013', '013 - User Transaction Syntax Error');
private static readonly AlertSeverity014Label: string = localize('alertDialog.Severity014', '014 - Insufficient Permission');
private static readonly AlertSeverity015Label: string = localize('alertDialog.Severity015', '015 - Syntax Error in SQL Statements');
private static readonly AlertSeverity016Label: string = localize('alertDialog.Severity016', '016 - Miscellaneous User Error');
private static readonly AlertSeverity017Label: string = localize('alertDialog.Severity017', '017 - Insufficient Resources');
private static readonly AlertSeverity018Label: string = localize('alertDialog.Severity018', '018 - Nonfatal Internal Error');
private static readonly AlertSeverity019Label: string = localize('alertDialog.Severity019', '019 - Fatal Error in Resource');
private static readonly AlertSeverity020Label: string = localize('alertDialog.Severity020', '020 - Fatal Error in Current Process');
private static readonly AlertSeverity021Label: string = localize('alertDialog.Severity021', '021 - Fatal Error in Database Processes');
private static readonly AlertSeverity022Label: string = localize('alertDialog.Severity022', '022 - Fatal Error: Table Integrity Suspect');
private static readonly AlertSeverity023Label: string = localize('alertDialog.Severity023', '023 - Fatal Error: Database Integrity Suspect');
private static readonly AlertSeverity024Label: string = localize('alertDialog.Severity024', '024 - Fatal Error: Hardware Error');
private static readonly AlertSeverity025Label: string = localize('alertDialog.Severity025', '025 - Fatal Error');
private static readonly AlertTypes: string[] = [
AlertDialog.AlertTypeSqlServerEventString,
@@ -94,23 +95,23 @@ export class AlertDialog extends AgentDialog<AlertData> {
];
// Response tab strings
private static readonly ExecuteJobCheckBoxLabel: string = localize('createAlert.ExecuteJob', 'Execute Job');
private static readonly ExecuteJobTextBoxLabel: string = localize('createAlert.ExecuteJobName', 'Job Name');
private static readonly NotifyOperatorsTextBoxLabel: string = localize('createAlert.NotifyOperators', 'Notify Operators');
private static readonly NewJobButtonLabel: string = localize('createAlert.NewJob', 'New Job');
private static readonly OperatorListLabel: string = localize('createAlert.OperatorList', 'Operator List');
private static readonly OperatorNameColumnLabel: string = localize('createAlert.OperatorName', 'Operator');
private static readonly OperatorEmailColumnLabel: string = localize('createAlert.OperatorEmail', 'E-mail');
private static readonly OperatorPagerColumnLabel: string = localize('createAlert.OperatorPager', 'Pager');
private static readonly NewOperatorButtonLabel: string = localize('createAlert.NewOperator', 'New Operator');
private static readonly ExecuteJobCheckBoxLabel: string = localize('alertDialog.ExecuteJob', 'Execute Job');
private static readonly ExecuteJobTextBoxLabel: string = localize('alertDialog.ExecuteJobName', 'Job Name');
private static readonly NotifyOperatorsTextBoxLabel: string = localize('alertDialog.NotifyOperators', 'Notify Operators');
private static readonly NewJobButtonLabel: string = localize('alertDialog.NewJob', 'New Job');
private static readonly OperatorListLabel: string = localize('alertDialog.OperatorList', 'Operator List');
private static readonly OperatorNameColumnLabel: string = localize('alertDialog.OperatorName', 'Operator');
private static readonly OperatorEmailColumnLabel: string = localize('alertDialog.OperatorEmail', 'E-mail');
private static readonly OperatorPagerColumnLabel: string = localize('alertDialog.OperatorPager', 'Pager');
private static readonly NewOperatorButtonLabel: string = localize('alertDialog.NewOperator', 'New Operator');
// Options tab strings
private static readonly IncludeErrorInEmailCheckBoxLabel: string = localize('createAlert.IncludeErrorInEmail', 'Include alert error text in e-mail');
private static readonly IncludeErrorInPagerCheckBoxLabel: string = localize('createAlert.IncludeErrorInPager', 'Include alert error text in pager');
private static readonly AdditionalMessageTextBoxLabel: string = localize('createAlert.AdditionalNotification', 'Additional notification message to send');
private static readonly DelayBetweenResponsesTextBoxLabel: string = localize('createAlert.DelayBetweenResponse', 'Delay between responses');
private static readonly DelayMinutesTextBoxLabel: string = localize('createAlert.DelayMinutes', 'Delay Minutes');
private static readonly DelaySecondsTextBoxLabel: string = localize('createAlert.DelaySeconds', 'Delay Seconds');
private static readonly IncludeErrorInEmailCheckBoxLabel: string = localize('alertDialog.IncludeErrorInEmail', 'Include alert error text in e-mail');
private static readonly IncludeErrorInPagerCheckBoxLabel: string = localize('alertDialog.IncludeErrorInPager', 'Include alert error text in pager');
private static readonly AdditionalMessageTextBoxLabel: string = localize('alertDialog.AdditionalNotification', 'Additional notification message to send');
private static readonly DelayBetweenResponsesTextBoxLabel: string = localize('alertDialog.DelayBetweenResponse', 'Delay between responses');
private static readonly DelayMinutesTextBoxLabel: string = localize('alertDialog.DelayMinutes', 'Delay Minutes');
private static readonly DelaySecondsTextBoxLabel: string = localize('alertDialog.DelaySeconds', 'Delay Seconds');
// UI Components
private generalTab: sqlops.window.modelviewdialog.DialogTab;
@@ -141,8 +142,10 @@ export class AlertDialog extends AgentDialog<AlertData> {
private delayMinutesTextBox: sqlops.InputBoxComponent;
private delaySecondsTextBox: sqlops.InputBoxComponent;
constructor(ownerUri: string) {
super(ownerUri, new AlertData(ownerUri), AlertDialog.DialogTitle);
constructor(ownerUri: string, alertInfo: sqlops.AgentAlertInfo = null) {
super(ownerUri,
new AlertData(ownerUri, alertInfo),
alertInfo ? AlertDialog.EditDialogTitle : AlertDialog.CreateDialogTitle);
}
protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) {
@@ -210,7 +213,7 @@ export class AlertDialog extends AgentDialog<AlertData> {
title: AlertDialog.SeverityLabel
}, {
component: this.raiseAlertMessageCheckBox,
title: AlertDialog.RaiseIfMessageContainsLabel
title: ''
}, {
component: this.raiseAlertMessageTextBox,
title: AlertDialog.MessageTextLabel
@@ -218,6 +221,9 @@ export class AlertDialog extends AgentDialog<AlertData> {
]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
this.nameTextBox.value = this.model.name;
this.enabledCheckBox.checked = this.model.isEnabled;
});
}
@@ -326,7 +332,7 @@ export class AlertDialog extends AgentDialog<AlertData> {
if (selected) {
let index = AlertDialog.AlertSeverities.indexOf(selected);
if (index >= 0) {
severityNumber = index;
severityNumber = index + 1;
}
}
return severityNumber;
@@ -339,6 +345,7 @@ export class AlertDialog extends AgentDialog<AlertData> {
this.model.alertType = this.getDropdownValue(this.typeDropDown);
this.model.databaseName = this.getDropdownValue(this.databaseDropDown);
this.model.severity = this.getSeverityNumber();
this.model.messageId = undefined;
let raiseIfError = this.raiseAlertMessageCheckBox.checked;
if (raiseIfError) {

View File

@@ -81,9 +81,9 @@ export class OperatorDialog extends AgentDialog<OperatorData> {
private initializeGeneralTab() {
this.generalTab.registerContent(async view => {
this.nameTextBox = view.modelBuilder.inputBox()
.withProperties({ width: '100%' })
.component();
this.nameTextBox = view.modelBuilder.inputBox().component();
this.enabledCheckBox = view.modelBuilder.checkBox()
.withProperties({
label: OperatorDialog.EnabledCheckboxLabel

View File

@@ -4,7 +4,14 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
export enum AgentDialogMode {
CREATE = 1,
EDIT = 2,
VIEW = 3
}
export interface IAgentDialogData {
dialogMode: AgentDialogMode;
initialize(): void;
save(): void;
}

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as sqlops from 'sqlops';
import * as vscode from 'vscode';
import { AlertDialog } from './dialogs/alertDialog';
import { JobDialog } from './dialogs/jobDialog';
@@ -38,8 +39,8 @@ export class MainController {
let dialog = new PickScheduleDialog(ownerUri);
dialog.showDialog();
});
vscode.commands.registerCommand('agent.openCreateAlertDialog', (ownerUri: string) => {
let dialog = new AlertDialog(ownerUri);
vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, alertInfo: sqlops.AgentAlertInfo) => {
let dialog = new AlertDialog(ownerUri, alertInfo);
dialog.openDialog();
});
vscode.commands.registerCommand('agent.openCreateOperatorDialog', (ownerUri: string) => {

View File

@@ -99,4 +99,7 @@ export class TestAgentService implements sqlops.AgentServicesProvider {
deleteJobSchedule(ownerUri: string, scheduleInfo: sqlops.AgentJobScheduleInfo): Thenable<sqlops.ResultStatus> {
return undefined;
}
registerOnUpdated(handler: () => any): void {
}
}