From 6c3d85cc45788f49f50ba010112ea76465cb8f62 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Thu, 5 Jul 2018 08:26:03 -0700 Subject: [PATCH] New Operator, Alert and Proxy request handlers (#1846) * Add agent dialog class * Rename agent dialog data classes * Alert dialog data updates * Create operator and proxy handlers --- extensions/agent/src/data/alertData.ts | 79 +++++++++++++++++++ .../agent/src/data/createOperatorData.ts | 25 ------ extensions/agent/src/data/createProxyData.ts | 25 ------ .../src/data/{createJobData.ts => jobData.ts} | 3 +- .../{createStepData.ts => jobStepData.ts} | 6 +- extensions/agent/src/data/operatorData.ts | 67 ++++++++++++++++ extensions/agent/src/data/pickScheduleData.ts | 3 +- extensions/agent/src/data/proxyData.ts | 47 +++++++++++ ...{createScheduleData.ts => scheduleData.ts} | 3 +- extensions/agent/src/dialogs/agentDialog.ts | 74 +++++++++++++++++ extensions/agent/src/dialogs/alertDialog.ts | 67 ++++++++-------- extensions/agent/src/dialogs/jobDialog.ts | 55 ++----------- extensions/agent/src/dialogs/jobStepDialog.ts | 12 +-- .../agent/src/dialogs/operatorDialog.ts | 39 +++------ extensions/agent/src/dialogs/proxyDialog.ts | 42 +++------- .../agent/src/dialogs/scheduleDialog.ts | 10 +-- .../createAlertData.ts => interfaces.ts} | 21 +---- extensions/agent/src/mainController.ts | 8 +- extensions/agent/src/test/agent.test.ts | 4 +- .../parts/jobManagement/common/jobActions.ts | 2 +- 20 files changed, 359 insertions(+), 233 deletions(-) create mode 100644 extensions/agent/src/data/alertData.ts delete mode 100644 extensions/agent/src/data/createOperatorData.ts delete mode 100644 extensions/agent/src/data/createProxyData.ts rename extensions/agent/src/data/{createJobData.ts => jobData.ts} (97%) rename extensions/agent/src/data/{createStepData.ts => jobStepData.ts} (94%) create mode 100644 extensions/agent/src/data/operatorData.ts create mode 100644 extensions/agent/src/data/proxyData.ts rename extensions/agent/src/data/{createScheduleData.ts => scheduleData.ts} (89%) create mode 100644 extensions/agent/src/dialogs/agentDialog.ts rename extensions/agent/src/{data/createAlertData.ts => interfaces.ts} (50%) diff --git a/extensions/agent/src/data/alertData.ts b/extensions/agent/src/data/alertData.ts new file mode 100644 index 0000000000..f2a4807ca7 --- /dev/null +++ b/extensions/agent/src/data/alertData.ts @@ -0,0 +1,79 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as sqlops from 'sqlops'; +import { AgentUtils } from '../agentUtils'; +import { IAgentDialogData } from '../interfaces'; + +export class AlertData implements IAgentDialogData { + ownerUri: string; + id: number; + name: string; + delayBetweenResponses: number; + eventDescriptionKeyword: string; + eventSource: string; + hasNotification: number; + includeEventDescription: string; + isEnabled: boolean; + jobId: string; + jobName: string; + lastOccurrenceDate: string; + lastResponseDate: string; + messageId: number; + notificationMessage: string; + occurrenceCount: number; + performanceCondition: string; + severity: number; + databaseName: string; + countResetDate: string; + categoryName: string; + alertType: string; + wmiEventNamespace: string; + wmiEventQuery: string; + + constructor(ownerUri:string) { + this.ownerUri = ownerUri; + } + + public async initialize() { + } + + public async save() { + let agentService = await AgentUtils.getAgentService(); + let result = await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo()); + if (!result || !result.success) { + // TODO handle error here + } + } + + public toAgentAlertInfo(): sqlops.AgentAlertInfo { + return { + id: this.id, + name: this.name, + delayBetweenResponses: this.delayBetweenResponses, + eventDescriptionKeyword: this.eventDescriptionKeyword, + eventSource: this.eventSource, + hasNotification: this.hasNotification, + includeEventDescription: sqlops.NotifyMethods.none, // this.includeEventDescription, + isEnabled: this.isEnabled, + jobId: this.jobId, + jobName: this.jobName, + lastOccurrenceDate: this.lastOccurrenceDate, + lastResponseDate: this.lastResponseDate, + messageId: this.messageId, + notificationMessage: this.notificationMessage, + occurrenceCount: this.occurrenceCount, + performanceCondition: this.performanceCondition, + severity: this.severity, + databaseName: this.databaseName, + countResetDate: this.countResetDate, + categoryName: this.categoryName, + alertType: sqlops.AlertType.sqlServerEvent, //this.alertType, + wmiEventNamespace: this.wmiEventNamespace, + wmiEventQuery: this.wmiEventQuery + }; + } +} diff --git a/extensions/agent/src/data/createOperatorData.ts b/extensions/agent/src/data/createOperatorData.ts deleted file mode 100644 index 00c3fa8d1a..0000000000 --- a/extensions/agent/src/data/createOperatorData.ts +++ /dev/null @@ -1,25 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import * as sqlops from 'sqlops'; -import { AgentUtils } from '../agentUtils'; - -export class CreateOperatorData { - public ownerUri: string; - private _alert: sqlops.AgentOperatorInfo; - - constructor(ownerUri:string) { - this.ownerUri = ownerUri; - } - - public async initialize() { - let agentService = await AgentUtils.getAgentService(); - - } - - public async save() { - } -} diff --git a/extensions/agent/src/data/createProxyData.ts b/extensions/agent/src/data/createProxyData.ts deleted file mode 100644 index d4d72e1cff..0000000000 --- a/extensions/agent/src/data/createProxyData.ts +++ /dev/null @@ -1,25 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import * as sqlops from 'sqlops'; -import { AgentUtils } from '../agentUtils'; - -export class CreateProxyData { - public ownerUri: string; - private _alert: sqlops.AgentProxyInfo; - - constructor(ownerUri:string) { - this.ownerUri = ownerUri; - } - - public async initialize() { - let agentService = await AgentUtils.getAgentService(); - - } - - public async save() { - } -} diff --git a/extensions/agent/src/data/createJobData.ts b/extensions/agent/src/data/jobData.ts similarity index 97% rename from extensions/agent/src/data/createJobData.ts rename to extensions/agent/src/data/jobData.ts index 1c2ea77790..f8291a153d 100644 --- a/extensions/agent/src/data/createJobData.ts +++ b/extensions/agent/src/data/jobData.ts @@ -6,8 +6,9 @@ import * as sqlops from 'sqlops'; import { AgentUtils } from '../agentUtils'; +import { IAgentDialogData } from '../interfaces'; -export class CreateJobData { +export class JobData implements IAgentDialogData { private readonly JobCompletionActionCondition_Always: string = 'When the job completes'; private readonly JobCompletionActionCondition_OnFailure: string = 'When the job fails'; diff --git a/extensions/agent/src/data/createStepData.ts b/extensions/agent/src/data/jobStepData.ts similarity index 94% rename from extensions/agent/src/data/createStepData.ts rename to extensions/agent/src/data/jobStepData.ts index e8e5bb6f07..6631a6bca1 100644 --- a/extensions/agent/src/data/createStepData.ts +++ b/extensions/agent/src/data/jobStepData.ts @@ -5,8 +5,9 @@ 'use strict'; import { AgentUtils } from '../agentUtils'; +import { IAgentDialogData } from '../interfaces'; -export class CreateStepData { +export class JobStepData implements IAgentDialogData { public ownerUri: string; public jobId: string; // public jobName: string; @@ -37,6 +38,9 @@ export class CreateStepData { this.ownerUri = ownerUri; } + public async initialize() { + } + public async save() { let agentService = await AgentUtils.getAgentService(); agentService.createJobStep(this.ownerUri, { diff --git a/extensions/agent/src/data/operatorData.ts b/extensions/agent/src/data/operatorData.ts new file mode 100644 index 0000000000..e39044618a --- /dev/null +++ b/extensions/agent/src/data/operatorData.ts @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as sqlops from 'sqlops'; +import { AgentUtils } from '../agentUtils'; +import { IAgentDialogData } from '../interfaces'; + +export class OperatorData implements IAgentDialogData { + ownerUri: string; + name: string; + id: number; + emailAddress: string; + enabled: boolean; + lastEmailDate: string; + lastNetSendDate: string; + lastPagerDate: string; + pagerAddress: string; + categoryName: string; + pagerDays: string; + saturdayPagerEndTime: string; + saturdayPagerStartTime: string; + sundayPagerEndTime: string; + sundayPagerStartTime: string; + netSendAddress: string; + weekdayPagerStartTime: string; + weekdayPagerEndTime: string; + + constructor(ownerUri:string) { + this.ownerUri = ownerUri; + } + + public async initialize() { + } + + public async save() { + let agentService = await AgentUtils.getAgentService(); + let result = await agentService.createOperator(this.ownerUri, this.toAgentOperatorInfo()); + if (!result || !result.success) { + // TODO handle error here + } + } + + public toAgentOperatorInfo(): sqlops.AgentOperatorInfo { + return { + name: this.name, + id: this.id, + emailAddress: this.emailAddress, + enabled: this.enabled, + lastEmailDate: this.lastEmailDate, + lastNetSendDate: this.lastNetSendDate, + lastPagerDate: this.lastPagerDate, + pagerAddress: this.pagerAddress, + categoryName: this.categoryName, + pagerDays: sqlops.WeekDays.weekDays, //this.pagerDays, + saturdayPagerEndTime: this.saturdayPagerEndTime, + saturdayPagerStartTime: this.saturdayPagerStartTime, + sundayPagerEndTime: this.sundayPagerEndTime, + sundayPagerStartTime: this.sundayPagerStartTime, + netSendAddress: this.netSendAddress, + weekdayPagerStartTime: this.weekdayPagerStartTime, + weekdayPagerEndTime: this.weekdayPagerEndTime + }; + } +} diff --git a/extensions/agent/src/data/pickScheduleData.ts b/extensions/agent/src/data/pickScheduleData.ts index 9c4f45c55b..cf867fa7ac 100644 --- a/extensions/agent/src/data/pickScheduleData.ts +++ b/extensions/agent/src/data/pickScheduleData.ts @@ -6,8 +6,9 @@ import * as sqlops from 'sqlops'; import { AgentUtils } from '../agentUtils'; +import { IAgentDialogData } from '../interfaces'; -export class PickScheduleData { +export class PickScheduleData implements IAgentDialogData { public ownerUri: string; public schedules: sqlops.AgentJobScheduleInfo[]; public selectedSchedule: sqlops.AgentJobScheduleInfo; diff --git a/extensions/agent/src/data/proxyData.ts b/extensions/agent/src/data/proxyData.ts new file mode 100644 index 0000000000..f29b96c689 --- /dev/null +++ b/extensions/agent/src/data/proxyData.ts @@ -0,0 +1,47 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as sqlops from 'sqlops'; +import { AgentUtils } from '../agentUtils'; +import { IAgentDialogData } from '../interfaces'; + +export class ProxyData implements IAgentDialogData { + ownerUri: string; + id: number; + accountName: string; + description: string; + credentialName: string; + credentialIdentity: string; + credentialId: number; + isEnabled: boolean; + + constructor(ownerUri:string) { + this.ownerUri = ownerUri; + } + + public async initialize() { + } + + public async save() { + let agentService = await AgentUtils.getAgentService(); + let result = await agentService.createProxy(this.ownerUri, this.toAgentProxyInfo()); + if (!result || !result.success) { + // TODO handle error here + } + } + + public toAgentProxyInfo(): sqlops.AgentProxyInfo { + return { + id: this.id, + accountName: this.accountName, + description: this.description, + credentialName: this.credentialName, + credentialIdentity: this.credentialIdentity, + credentialId: this.credentialId, + isEnabled: this.isEnabled + }; + } +} diff --git a/extensions/agent/src/data/createScheduleData.ts b/extensions/agent/src/data/scheduleData.ts similarity index 89% rename from extensions/agent/src/data/createScheduleData.ts rename to extensions/agent/src/data/scheduleData.ts index 16d8fc3a8f..a1237b3d11 100644 --- a/extensions/agent/src/data/createScheduleData.ts +++ b/extensions/agent/src/data/scheduleData.ts @@ -6,8 +6,9 @@ import * as sqlops from 'sqlops'; import { AgentUtils } from '../agentUtils'; +import { IAgentDialogData } from '../interfaces'; -export class CreateScheduleData { +export class ScheduleData implements IAgentDialogData { public ownerUri: string; public schedules: sqlops.AgentJobScheduleInfo[]; public selectedSchedule: sqlops.AgentJobScheduleInfo; diff --git a/extensions/agent/src/dialogs/agentDialog.ts b/extensions/agent/src/dialogs/agentDialog.ts new file mode 100644 index 0000000000..67a2133786 --- /dev/null +++ b/extensions/agent/src/dialogs/agentDialog.ts @@ -0,0 +1,74 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as nls from 'vscode-nls'; +import * as sqlops from 'sqlops'; +import * as vscode from 'vscode'; +import { IAgentDialogData } from '../interfaces'; + +const localize = nls.loadMessageBundle(); + +export abstract class AgentDialog { + + private static readonly OkButtonText: string = localize('createAlert.OK', 'OK'); + private static readonly CancelButtonText: string = localize('createAlert.Cancel', 'Cancel'); + + protected _onSuccess: vscode.EventEmitter = new vscode.EventEmitter(); + public readonly onSuccess: vscode.Event = this._onSuccess.event; + public dialog: sqlops.window.modelviewdialog.Dialog; + + constructor(public ownerUri: string, public model: T, public title: string) { + } + + protected abstract async updateModel(); + + protected abstract async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog); + + public async openDialog() { + this.dialog = sqlops.window.modelviewdialog.createDialog(this.title); + + await this.model.initialize(); + + await this.initializeDialog(this.dialog); + + this.dialog.okButton.label = AgentDialog.OkButtonText; + this.dialog.okButton.onClick(async () => await this.execute()); + + this.dialog.cancelButton.label = AgentDialog.CancelButtonText; + this.dialog.cancelButton.onClick(async () => await this.cancel()); + + sqlops.window.modelviewdialog.openDialog(this.dialog); + } + + protected async execute() { + this.updateModel(); + let success = await this.model.save(); + if (success) { + this._onSuccess.fire(this.model); + } + } + + protected async cancel() { + } + + protected getActualConditionValue(checkbox: sqlops.CheckBoxComponent, dropdown: sqlops.DropDownComponent): sqlops.JobCompletionActionCondition { + return checkbox.checked ? Number(this.getDropdownValue(dropdown)) : sqlops.JobCompletionActionCondition.Never; + } + + protected getDropdownValue(dropdown: sqlops.DropDownComponent): string { + return (typeof dropdown.value === 'string') ? dropdown.value : dropdown.value.name; + } + + protected setConditionDropdownSelectedValue(dropdown: sqlops.DropDownComponent, selectedValue: number) { + let idx: number = 0; + for (idx = 0; idx < dropdown.values.length; idx++) { + if (Number((dropdown.values[idx]).name) === selectedValue) { + dropdown.value = dropdown.values[idx]; + break; + } + } + } +} \ No newline at end of file diff --git a/extensions/agent/src/dialogs/alertDialog.ts b/extensions/agent/src/dialogs/alertDialog.ts index 846481d370..b5f860fc91 100644 --- a/extensions/agent/src/dialogs/alertDialog.ts +++ b/extensions/agent/src/dialogs/alertDialog.ts @@ -5,20 +5,18 @@ 'use strict'; -import * as sqlops from 'sqlops'; -import * as vscode from 'vscode'; -import { AgentUtils } from '../agentUtils'; -import { CreateAlertData } from '../data/createAlertData'; import * as nls from 'vscode-nls'; +import * as sqlops from 'sqlops'; +import { AgentDialog } from './agentDialog'; +import { AgentUtils } from '../agentUtils'; +import { AlertData } from '../data/alertData'; const localize = nls.loadMessageBundle(); -export class AlertDialog { +export class AlertDialog extends AgentDialog { // Top level private static readonly DialogTitle: string = localize('createAlert.createAlert', 'Create Alert'); - private static readonly OkButtonText: string = localize('createAlert.OK', 'OK'); - private static readonly CancelButtonText: string = localize('createAlert.Cancel', 'Cancel'); 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'); @@ -115,7 +113,6 @@ export class AlertDialog { private static readonly DelaySecondsTextBoxLabel: string = localize('createAlert.DelaySeconds', 'Delay Seconds'); // UI Components - private dialog: sqlops.window.modelviewdialog.Dialog; private generalTab: sqlops.window.modelviewdialog.DialogTab; private responseTab: sqlops.window.modelviewdialog.DialogTab; private optionsTab: sqlops.window.modelviewdialog.DialogTab; @@ -144,21 +141,12 @@ export class AlertDialog { private delayMinutesTextBox: sqlops.InputBoxComponent; private delaySecondsTextBox: sqlops.InputBoxComponent; - - private model: CreateAlertData; - - private _onSuccess: vscode.EventEmitter = new vscode.EventEmitter(); - public readonly onSuccess: vscode.Event = this._onSuccess.event; - - constructor(public ownerUri: string) { - this.model = new CreateAlertData(ownerUri); + constructor(ownerUri: string) { + super(ownerUri, new AlertData(ownerUri), AlertDialog.DialogTitle); } - public async showDialog() { - + protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) { let databases = await AgentUtils.getDatabases(this.ownerUri); - await this.model.initialize(); - this.dialog = sqlops.window.modelviewdialog.createDialog(AlertDialog.DialogTitle); this.generalTab = sqlops.window.modelviewdialog.createTab(AlertDialog.GeneralTabText); this.responseTab = sqlops.window.modelviewdialog.createTab(AlertDialog.ResponseTabText); this.optionsTab = sqlops.window.modelviewdialog.createTab(AlertDialog.OptionsTabText); @@ -167,13 +155,7 @@ export class AlertDialog { this.initializeResponseTab(); this.initializeOptionsTab(); - this.dialog.content = [this.generalTab, this.responseTab, this.optionsTab]; - this.dialog.okButton.onClick(async () => await this.execute()); - this.dialog.cancelButton.onClick(async () => await this.cancel()); - this.dialog.okButton.label = AlertDialog.OkButtonText; - this.dialog.cancelButton.label = AlertDialog.CancelButtonText; - - sqlops.window.modelviewdialog.openDialog(this.dialog); + dialog.content = [this.generalTab, this.responseTab, this.optionsTab]; } private initializeGeneralTab(databases: string[]) { @@ -223,6 +205,9 @@ export class AlertDialog { }, { component: this.databaseDropDown, title: AlertDialog.DatabaseLabel + }, { + component: this.severityDropDown, + title: AlertDialog.SeverityLabel }, { component: this.raiseAlertMessageCheckBox, title: AlertDialog.RaiseIfMessageContainsLabel @@ -335,15 +320,29 @@ export class AlertDialog { }); } - private async execute() { - this.updateModel(); - await this.model.save(); - this._onSuccess.fire(this.model); + private getSeverityNumber(): number { + let selected = this.getDropdownValue(this.severityDropDown); + let severityNumber: number = 0; + if (selected) { + let index = AlertDialog.AlertSeverities.indexOf(selected); + if (index >= 0) { + severityNumber = index; + } + } + return severityNumber; } - private async cancel() { - } + protected updateModel() { + this.model.name = this.nameTextBox.value; + this.model.isEnabled = this.enabledCheckBox.checked; - private updateModel() { + this.model.alertType = this.getDropdownValue(this.typeDropDown); + this.model.databaseName = this.getDropdownValue(this.databaseDropDown); + this.model.severity = this.getSeverityNumber(); + + let raiseIfError = this.raiseAlertMessageCheckBox.checked; + if (raiseIfError) { + let messageText = this.raiseAlertMessageTextBox.value; + } } } diff --git a/extensions/agent/src/dialogs/jobDialog.ts b/extensions/agent/src/dialogs/jobDialog.ts index eb617ed483..62f5dd4ddc 100644 --- a/extensions/agent/src/dialogs/jobDialog.ts +++ b/extensions/agent/src/dialogs/jobDialog.ts @@ -4,18 +4,17 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as sqlops from 'sqlops'; -import { CreateJobData } from '../data/createJobData'; +import { JobData } from '../data/jobData'; import { JobStepDialog } from './jobStepDialog'; import { PickScheduleDialog } from './pickScheduleDialog'; import { AlertDialog } from './alertDialog'; +import { AgentDialog } from './agentDialog'; -export class JobDialog { +export class JobDialog extends AgentDialog { // TODO: localize // Top level - private readonly DialogTitle: string = 'New Job'; - private readonly OkButtonText: string = 'OK'; - private readonly CancelButtonText: string = 'Cancel'; + private static readonly DialogTitle: string = 'New Job'; private readonly GeneralTabText: string = 'General'; private readonly StepsTabText: string = 'Steps'; private readonly SchedulesTabText: string = 'Schedules'; @@ -57,7 +56,6 @@ export class JobDialog { private readonly NewAlertButtonString: string = 'New Alert'; // UI Components - private dialog: sqlops.window.modelviewdialog.Dialog; private generalTab: sqlops.window.modelviewdialog.DialogTab; private stepsTab: sqlops.window.modelviewdialog.DialogTab; private alertsTab: sqlops.window.modelviewdialog.DialogTab; @@ -99,15 +97,11 @@ export class JobDialog { private alertsTable: sqlops.TableComponent; private newAlertButton: sqlops.ButtonComponent; - private model: CreateJobData; - constructor(ownerUri: string) { - this.model = new CreateJobData(ownerUri); + super(ownerUri, new JobData(ownerUri), JobDialog.DialogTitle); } - public async showDialog() { - await this.model.initialize(); - this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle); + protected async initializeDialog() { this.generalTab = sqlops.window.modelviewdialog.createTab(this.GeneralTabText); this.stepsTab = sqlops.window.modelviewdialog.createTab(this.StepsTabText); this.alertsTab = sqlops.window.modelviewdialog.createTab(this.AlertsTabText); @@ -119,10 +113,6 @@ export class JobDialog { this.initializeSchedulesTab(); this.initializeNotificationsTab(); this.dialog.content = [this.generalTab, this.stepsTab, this.schedulesTab, this.alertsTab, this.notificationsTab]; - this.dialog.okButton.onClick(async () => await this.execute()); - this.dialog.cancelButton.onClick(async () => await this.cancel()); - this.dialog.okButton.label = this.OkButtonText; - this.dialog.cancelButton.label = this.CancelButtonText; this.dialog.registerCloseValidator(() => { this.updateModel(); @@ -134,8 +124,6 @@ export class JobDialog { return validationResult.valid; }); - - sqlops.window.modelviewdialog.openDialog(this.dialog); } private initializeGeneralTab() { @@ -250,7 +238,7 @@ export class JobDialog { let alertDialog = new AlertDialog(this.model.ownerUri); alertDialog.onSuccess((dialogModel) => { }); - alertDialog.showDialog(); + alertDialog.openDialog(); }); let formModel = view.modelBuilder.formContainer() @@ -421,34 +409,7 @@ export class JobDialog { }); } - private async execute() { - this.updateModel(); - await this.model.save(); - } - - private async cancel() { - - } - - private getActualConditionValue(checkbox: sqlops.CheckBoxComponent, dropdown: sqlops.DropDownComponent): sqlops.JobCompletionActionCondition { - return checkbox.checked ? Number(this.getDropdownValue(dropdown)) : sqlops.JobCompletionActionCondition.Never; - } - - private getDropdownValue(dropdown: sqlops.DropDownComponent): string { - return (typeof dropdown.value === 'string') ? dropdown.value : dropdown.value.name; - } - - private setConditionDropdownSelectedValue(dropdown: sqlops.DropDownComponent, selectedValue: number) { - let idx: number = 0; - for (idx = 0; idx < dropdown.values.length; idx++) { - if (Number((dropdown.values[idx]).name) === selectedValue) { - dropdown.value = dropdown.values[idx]; - break; - } - } - } - - private updateModel() { + protected updateModel() { this.model.name = this.nameTextBox.value; this.model.owner = this.ownerTextBox.value; this.model.enabled = this.enabledCheckBox.checked; diff --git a/extensions/agent/src/dialogs/jobStepDialog.ts b/extensions/agent/src/dialogs/jobStepDialog.ts index 4a8d82de64..56cbd6acfb 100644 --- a/extensions/agent/src/dialogs/jobStepDialog.ts +++ b/extensions/agent/src/dialogs/jobStepDialog.ts @@ -5,9 +5,9 @@ 'use strict'; import * as sqlops from 'sqlops'; import * as vscode from 'vscode'; -import { CreateStepData } from '../data/createStepData'; +import { JobStepData } from '../data/jobStepData'; import { AgentUtils } from '../agentUtils'; -import { CreateJobData } from '../data/createJobData'; +import { JobData } from '../data/jobData'; const path = require('path'); export class JobStepDialog { @@ -75,8 +75,8 @@ export class JobStepDialog { private logToTableCheckbox: sqlops.CheckBoxComponent; private fileBrowserTree: sqlops.FileBrowserTreeComponent; - private jobModel: CreateJobData; - private model: CreateStepData; + private jobModel: JobData; + private model: JobStepData; private ownerUri: string; private jobName: string; private server: string; @@ -87,9 +87,9 @@ export class JobStepDialog { jobName: string, server: string, stepId: number, - jobModel?: CreateJobData + jobModel?: JobData ) { - this.model = new CreateStepData(ownerUri); + this.model = new JobStepData(ownerUri); this.stepId = stepId; this.ownerUri = ownerUri; this.jobName = jobName; diff --git a/extensions/agent/src/dialogs/operatorDialog.ts b/extensions/agent/src/dialogs/operatorDialog.ts index 6fd813698f..0fc5c7cb96 100644 --- a/extensions/agent/src/dialogs/operatorDialog.ts +++ b/extensions/agent/src/dialogs/operatorDialog.ts @@ -7,17 +7,16 @@ import * as sqlops from 'sqlops'; import * as vscode from 'vscode'; -import { CreateOperatorData } from '../data/createOperatorData'; +import { OperatorData } from '../data/operatorData'; import * as nls from 'vscode-nls'; +import { AgentDialog } from './agentDialog'; const localize = nls.loadMessageBundle(); -export class OperatorDialog { +export class OperatorDialog extends AgentDialog { // Top level private static readonly DialogTitle: string = localize('createOperator.createOperator', 'Create Operator'); - private static readonly OkButtonText: string = localize('createOperator.OK', 'OK'); - private static readonly CancelButtonText: string = localize('createOperator.Cancel', 'Cancel'); private static readonly GeneralTabText: string = localize('createOperator.General', 'General'); private static readonly NotificationsTabText: string = localize('createOperator.Notifications', 'Notifications'); @@ -41,7 +40,6 @@ export class OperatorDialog { private static readonly AlertPagerColumnLabel: string = localize('createOperator.AlertPagerColumnLabel', 'Pager'); // UI Components - private dialog: sqlops.window.modelviewdialog.Dialog; private generalTab: sqlops.window.modelviewdialog.DialogTab; private notificationsTab: sqlops.window.modelviewdialog.DialogTab; @@ -61,18 +59,11 @@ export class OperatorDialog { // Notification tab controls private alertsTable: sqlops.TableComponent; - private model: CreateOperatorData; - - private _onSuccess: vscode.EventEmitter = new vscode.EventEmitter(); - public readonly onSuccess: vscode.Event = this._onSuccess.event; - constructor(ownerUri: string) { - this.model = new CreateOperatorData(ownerUri); + super(ownerUri, new OperatorData(ownerUri), OperatorDialog.DialogTitle); } - public async showDialog() { - await this.model.initialize(); - this.dialog = sqlops.window.modelviewdialog.createDialog(OperatorDialog.DialogTitle); + protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) { this.generalTab = sqlops.window.modelviewdialog.createTab(OperatorDialog.GeneralTabText); this.notificationsTab = sqlops.window.modelviewdialog.createTab(OperatorDialog.NotificationsTabText); @@ -80,12 +71,6 @@ export class OperatorDialog { this.initializeNotificationTab(); this.dialog.content = [this.generalTab, this.notificationsTab]; - this.dialog.okButton.onClick(async () => await this.execute()); - this.dialog.cancelButton.onClick(async () => await this.cancel()); - this.dialog.okButton.label = OperatorDialog.OkButtonText; - this.dialog.cancelButton.label = OperatorDialog.CancelButtonText; - - sqlops.window.modelviewdialog.openDialog(this.dialog); } private initializeGeneralTab() { @@ -202,15 +187,9 @@ export class OperatorDialog { }); } - private async execute() { - this.updateModel(); - await this.model.save(); - this._onSuccess.fire(this.model); - } - - private async cancel() { - } - - private updateModel() { + protected updateModel() { + this.model.name = this.nameTextBox.value; + this.model.enabled = this.enabledCheckBox.checked; + this.model.emailAddress = this.emailNameTextBox.value; } } diff --git a/extensions/agent/src/dialogs/proxyDialog.ts b/extensions/agent/src/dialogs/proxyDialog.ts index 06efebd8e0..1dc155de18 100644 --- a/extensions/agent/src/dialogs/proxyDialog.ts +++ b/extensions/agent/src/dialogs/proxyDialog.ts @@ -5,19 +5,17 @@ 'use strict'; -import * as sqlops from 'sqlops'; -import * as vscode from 'vscode'; -import { CreateProxyData } from '../data/createProxyData'; import * as nls from 'vscode-nls'; +import * as sqlops from 'sqlops'; +import { AgentDialog } from './agentDialog'; +import { ProxyData } from '../data/proxyData'; const localize = nls.loadMessageBundle(); -export class ProxyDialog { +export class ProxyDialog extends AgentDialog { // Top level private static readonly DialogTitle: string = localize('createProxy.createAlert', 'Create Alert'); - private static readonly OkButtonText: string = localize('createProxy.OK', 'OK'); - private static readonly CancelButtonText: string = localize('createProxy.Cancel', 'Cancel'); private static readonly GeneralTabText: string = localize('createProxy.General', 'General'); // General tab strings @@ -28,7 +26,6 @@ export class ProxyDialog { private static readonly SubsystemNameColumnLabel: string = localize('createProxy.SubsystemName', 'Subsystem'); // UI Components - private dialog: sqlops.window.modelviewdialog.Dialog; private generalTab: sqlops.window.modelviewdialog.DialogTab; // General tab controls @@ -37,29 +34,16 @@ export class ProxyDialog { private descriptionTextBox: sqlops.InputBoxComponent; private subsystemsTable: sqlops.TableComponent; - private model: CreateProxyData; - - private _onSuccess: vscode.EventEmitter = new vscode.EventEmitter(); - public readonly onSuccess: vscode.Event = this._onSuccess.event; - constructor(ownerUri: string) { - this.model = new CreateProxyData(ownerUri); + super(ownerUri, new ProxyData(ownerUri), ProxyDialog.DialogTitle); } - public async showDialog() { - await this.model.initialize(); - this.dialog = sqlops.window.modelviewdialog.createDialog(ProxyDialog.DialogTitle); + protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) { this.generalTab = sqlops.window.modelviewdialog.createTab(ProxyDialog.GeneralTabText); this.initializeGeneralTab(); this.dialog.content = [this.generalTab]; - this.dialog.okButton.onClick(async () => await this.execute()); - this.dialog.cancelButton.onClick(async () => await this.cancel()); - this.dialog.okButton.label = ProxyDialog.OkButtonText; - this.dialog.cancelButton.label = ProxyDialog.CancelButtonText; - - sqlops.window.modelviewdialog.openDialog(this.dialog); } private initializeGeneralTab() { @@ -99,15 +83,9 @@ export class ProxyDialog { }); } - private async execute() { - this.updateModel(); - await this.model.save(); - this._onSuccess.fire(this.model); - } - - private async cancel() { - } - - private updateModel() { + protected updateModel() { + this.model.accountName = this.proxyNameTextBox.value; + this.model.credentialName = this.credentialNameTextBox.value; + this.model.description = this.descriptionTextBox.value; } } diff --git a/extensions/agent/src/dialogs/scheduleDialog.ts b/extensions/agent/src/dialogs/scheduleDialog.ts index b408279b8e..792002396c 100644 --- a/extensions/agent/src/dialogs/scheduleDialog.ts +++ b/extensions/agent/src/dialogs/scheduleDialog.ts @@ -7,7 +7,7 @@ import * as sqlops from 'sqlops'; import * as vscode from 'vscode'; -import { CreateScheduleData } from '../data/createScheduleData'; +import { ScheduleData } from '../data/scheduleData'; export class ScheduleDialog { @@ -20,13 +20,13 @@ export class ScheduleDialog { private dialog: sqlops.window.modelviewdialog.Dialog; private schedulesTable: sqlops.TableComponent; - private model: CreateScheduleData; + private model: ScheduleData; - private _onSuccess: vscode.EventEmitter = new vscode.EventEmitter(); - public readonly onSuccess: vscode.Event = this._onSuccess.event; + private _onSuccess: vscode.EventEmitter = new vscode.EventEmitter(); + public readonly onSuccess: vscode.Event = this._onSuccess.event; constructor(ownerUri: string) { - this.model = new CreateScheduleData(ownerUri); + this.model = new ScheduleData(ownerUri); } public async showDialog() { diff --git a/extensions/agent/src/data/createAlertData.ts b/extensions/agent/src/interfaces.ts similarity index 50% rename from extensions/agent/src/data/createAlertData.ts rename to extensions/agent/src/interfaces.ts index ae36fe575d..ca38d722a7 100644 --- a/extensions/agent/src/data/createAlertData.ts +++ b/extensions/agent/src/interfaces.ts @@ -4,22 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import * as sqlops from 'sqlops'; -import { AgentUtils } from '../agentUtils'; - -export class CreateAlertData { - public ownerUri: string; - private _alert: sqlops.AgentAlertInfo; - - constructor(ownerUri:string) { - this.ownerUri = ownerUri; - } - - public async initialize() { - let agentService = await AgentUtils.getAgentService(); - - } - - public async save() { - } +export interface IAgentDialogData { + initialize(): void; + save(): void; } diff --git a/extensions/agent/src/mainController.ts b/extensions/agent/src/mainController.ts index fc7b992d19..1926b29632 100644 --- a/extensions/agent/src/mainController.ts +++ b/extensions/agent/src/mainController.ts @@ -28,7 +28,7 @@ export class MainController { public activate(): void { vscode.commands.registerCommand('agent.openCreateJobDialog', (ownerUri: string) => { let dialog = new JobDialog(ownerUri); - dialog.showDialog(); + dialog.openDialog(); }); vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, jobId: string, server: string, stepId: number) => { let dialog = new JobStepDialog(ownerUri, jobId, server, stepId); @@ -40,15 +40,15 @@ export class MainController { }); vscode.commands.registerCommand('agent.openCreateAlertDialog', (ownerUri: string) => { let dialog = new AlertDialog(ownerUri); - dialog.showDialog(); + dialog.openDialog(); }); vscode.commands.registerCommand('agent.openCreateOperatorDialog', (ownerUri: string) => { let dialog = new OperatorDialog(ownerUri); - dialog.showDialog(); + dialog.openDialog(); }); vscode.commands.registerCommand('agent.openCreateProxyDialog', (ownerUri: string) => { let dialog = new ProxyDialog(ownerUri); - dialog.showDialog(); + dialog.openDialog(); }); } diff --git a/extensions/agent/src/test/agent.test.ts b/extensions/agent/src/test/agent.test.ts index 55e2a7d43f..b16ae4e150 100644 --- a/extensions/agent/src/test/agent.test.ts +++ b/extensions/agent/src/test/agent.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import 'mocha'; import * as vscode from 'vscode'; import * as sqlops from 'sqlops'; -import { CreateJobData } from '../data/createJobData'; +import { JobData } from '../data/jobData'; import { TestAgentService } from './testAgentService'; const testOwnerUri = 'agent://testuri'; @@ -15,7 +15,7 @@ const testOwnerUri = 'agent://testuri'; suite('Agent extension', () => { test('Create Job Data', async () => { let testAgentService = new TestAgentService(); - let data = new CreateJobData(testOwnerUri, testAgentService); + let data = new JobData(testOwnerUri, testAgentService); data.save(); }); }); diff --git a/src/sql/parts/jobManagement/common/jobActions.ts b/src/sql/parts/jobManagement/common/jobActions.ts index d5002c65e1..80cc0cc671 100644 --- a/src/sql/parts/jobManagement/common/jobActions.ts +++ b/src/sql/parts/jobManagement/common/jobActions.ts @@ -31,7 +31,7 @@ export interface IJobActionInfo { export class JobsRefreshAction extends Action { public static ID = 'jobaction.refresh'; - public static LABEL = nls.localize('jobaction.refresh', "Refresh Jobs"); + public static LABEL = nls.localize('jobaction.refresh', "Refresh"); constructor( ) {