Remove "client" folder in Agent extension (#1820)

* Remove "client" folder in Agent extension

* Alert dialog cleanups
This commit is contained in:
Karl Burtram
2018-07-02 14:47:00 -07:00
committed by GitHub
parent af80751a1f
commit a6837dcd40
26 changed files with 599 additions and 3704 deletions

View File

@@ -0,0 +1,38 @@
'use strict';
import * as sqlops from 'sqlops';
export class AgentUtils {
private static _agentService: sqlops.AgentServicesProvider;
private static _connectionService: sqlops.ConnectionProvider;
private static _queryProvider: sqlops.QueryProvider;
public static async getAgentService(): Promise<sqlops.AgentServicesProvider> {
if (!AgentUtils._agentService) {
let currentConnection = await sqlops.connection.getCurrentConnection();
this._agentService = sqlops.dataprotocol.getProvider<sqlops.AgentServicesProvider>(currentConnection.providerName, sqlops.DataProviderType.AgentServicesProvider);
}
return AgentUtils._agentService;
}
public static async getDatabases(ownerUri: string): Promise<string[]> {
if (!AgentUtils._connectionService) {
let currentConnection = await sqlops.connection.getCurrentConnection();
this._connectionService = sqlops.dataprotocol.getProvider<sqlops.ConnectionProvider>(currentConnection.providerName, sqlops.DataProviderType.ConnectionProvider);
}
return AgentUtils._connectionService.listDatabases(ownerUri).then(result => {
if (result && result.databaseNames && result.databaseNames.length > 0) {
return result.databaseNames;
}
});
}
public static async getQueryProvider(): Promise<sqlops.QueryProvider> {
if (!AgentUtils._queryProvider) {
let currentConnection = await sqlops.connection.getCurrentConnection();
this._queryProvider = sqlops.dataprotocol.getProvider<sqlops.QueryProvider>(currentConnection.providerName, sqlops.DataProviderType.QueryProvider);
}
return this._queryProvider;
}
}

View File

@@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------------------------
* 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 vscode from 'vscode';
import * as data from 'sqlops';
/**
* Wrapper class to act as a facade over VSCode and Data APIs and allow us to test / mock callbacks into
* this API from our code
*
* @export
* @class ApiWrapper
*/
export class ApiWrapper {
// Data APIs
public registerWebviewProvider(widgetId: string, handler: (webview: data.DashboardWebview) => void): void {
return data.dashboard.registerWebviewProvider(widgetId, handler);
}
public registerControlHostProvider(widgetId: string, handler: (webview: data.DashboardWebview) => void): void {
return data.dashboard.registerWebviewProvider(widgetId, handler);
}
/**
* Get the configuration for a extensionName
* @param extensionName The string name of the extension to get the configuration for
* @param resource The optional URI, as a URI object or a string, to use to get resource-scoped configurations
*/
public getConfiguration(extensionName: string, resource?: vscode.Uri | string): vscode.WorkspaceConfiguration {
if (typeof resource === 'string') {
try {
resource = this.parseUri(resource);
} catch (e) {
resource = undefined;
}
}
return vscode.workspace.getConfiguration(extensionName, resource as vscode.Uri);
}
/**
* Parse uri
*/
public parseUri(uri: string): vscode.Uri {
return vscode.Uri.parse(uri);
}
public showOpenDialog(options: vscode.OpenDialogOptions): Thenable<vscode.Uri[] | undefined> {
return vscode.window.showOpenDialog(options);
}
public showErrorMessage(message: string, ...items: string[]): Thenable<string | undefined> {
return vscode.window.showErrorMessage(message, ...items);
}
public get workspaceRootPath(): string {
return vscode.workspace.rootPath;
}
}

View File

@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* 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 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() {
}
}

View File

@@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------------------------
* 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 CreateJobData {
private readonly JobCompletionActionCondition_Always: string = 'When the job completes';
private readonly JobCompletionActionCondition_OnFailure: string = 'When the job fails';
private readonly JobCompletionActionCondition_OnSuccess: string = 'When the job succeeds';
// Error Messages
private readonly CreateJobErrorMessage_NameIsEmpty = 'Job name must be provided';
private _ownerUri: string;
private _jobCategories: string[];
private _operators: string[];
private _defaultOwner: string;
private _jobCompletionActionConditions: sqlops.CategoryValue[];
public name: string;
public enabled: boolean = true;
public description: string;
public category: string;
public categoryId: number;
public owner: string;
public emailLevel: sqlops.JobCompletionActionCondition = sqlops.JobCompletionActionCondition.OnFailure;
public pageLevel: sqlops.JobCompletionActionCondition = sqlops.JobCompletionActionCondition.OnFailure;
public eventLogLevel: sqlops.JobCompletionActionCondition = sqlops.JobCompletionActionCondition.OnFailure;
public deleteLevel: sqlops.JobCompletionActionCondition = sqlops.JobCompletionActionCondition.OnSuccess;
public operatorToEmail: string;
public operatorToPage: string;
public jobSteps: sqlops.AgentJobStepInfo[];
public jobSchedules: sqlops.AgentJobScheduleInfo[];
public alerts: sqlops.AgentAlertInfo[];
constructor(ownerUri: string, private _agentService: sqlops.AgentServicesProvider = null) {
this._ownerUri = ownerUri;
}
public get jobCategories(): string[] {
return this._jobCategories;
}
public get operators(): string[] {
return this._operators;
}
public get ownerUri(): string {
return this._ownerUri;
}
public get defaultOwner(): string {
return this._defaultOwner;
}
public get JobCompletionActionConditions(): sqlops.CategoryValue[] {
return this._jobCompletionActionConditions;
}
public async initialize() {
this._agentService = await AgentUtils.getAgentService();
let jobDefaults = await this._agentService.getJobDefaults(this.ownerUri);
if (jobDefaults && jobDefaults.success) {
this._jobCategories = jobDefaults.categories.map((cat) => {
return cat.name;
});
this._defaultOwner = jobDefaults.owner;
this._operators = ['', this._defaultOwner];
}
this._jobCompletionActionConditions = [{
displayName: this.JobCompletionActionCondition_OnSuccess,
name: sqlops.JobCompletionActionCondition.OnSuccess.toString()
}, {
displayName: this.JobCompletionActionCondition_OnFailure,
name: sqlops.JobCompletionActionCondition.OnFailure.toString()
}, {
displayName: this.JobCompletionActionCondition_Always,
name: sqlops.JobCompletionActionCondition.Always.toString()
}];
this.jobSchedules = [];
}
public async save() {
await this._agentService.createJob(this.ownerUri, {
name: this.name,
owner: this.owner,
description: this.description,
EmailLevel: this.emailLevel,
PageLevel: this.pageLevel,
EventLogLevel: this.eventLogLevel,
DeleteLevel: this.deleteLevel,
OperatorToEmail: this.operatorToEmail,
OperatorToPage: this.operatorToPage,
enabled: this.enabled,
category: this.category,
Alerts: this.alerts,
JobSchedules: this.jobSchedules,
JobSteps: this.jobSteps,
// The properties below are not collected from UI
// We could consider using a seperate class for create job request
//
currentExecutionStatus: 0,
lastRunOutcome: 0,
currentExecutionStep: '',
hasTarget: true,
hasSchedule: false,
hasStep: false,
runnable: true,
categoryId: 0,
categoryType: 1, // LocalJob, hard-coding the value, corresponds to the target tab in SSMS
lastRun: '',
nextRun: '',
jobId: ''
}).then(result => {
if (!result.success) {
console.info(result.errorMessage);
}
});
}
public validate(): { valid: boolean, errorMessages: string[] } {
let validationErrors: string[] = [];
if (!(this.name && this.name.trim())) {
validationErrors.push(this.CreateJobErrorMessage_NameIsEmpty);
}
return {
valid: validationErrors.length === 0,
errorMessages: validationErrors
};
}
public addJobSchedule(schedule: sqlops.AgentJobScheduleInfo) {
let existingSchedule = this.jobSchedules.find(item => item.name === schedule.name);
if (!existingSchedule) {
this.jobSchedules.push(schedule);
}
}
}

View File

@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* 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() {
}
}

View File

@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* 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() {
}
}

View File

@@ -0,0 +1,29 @@
/*---------------------------------------------------------------------------------------------
* 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 CreateScheduleData {
public ownerUri: string;
public schedules: sqlops.AgentJobScheduleInfo[];
public selectedSchedule: sqlops.AgentJobScheduleInfo;
constructor(ownerUri:string) {
this.ownerUri = ownerUri;
}
public async initialize() {
let agentService = await AgentUtils.getAgentService();
let result = await agentService.getJobSchedules(this.ownerUri);
if (result && result.success) {
this.schedules = result.schedules;
}
}
public async save() {
}
}

View File

@@ -0,0 +1,71 @@
/*---------------------------------------------------------------------------------------------
* 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 { AgentUtils } from '../agentUtils';
export class CreateStepData {
public ownerUri: string;
public jobId: string; //
public jobName: string;
public script: string; //
public scriptName: string;
public stepName: string; //
public subSystem: string; //
public id: number;
public failureAction: string; //
public successAction: string; //
public failStepId: number;
public successStepId: number;
public command: string;
public commandExecutionSuccessCode: number;
public databaseName: string; //
public databaseUserName: string;
public server: string;
public outputFileName: string; //
public appendToLogFile: boolean;
public appendToStepHist: boolean;
public writeLogToTable: boolean;
public appendLogToTable: boolean;
public retryAttempts: number; //
public retryInterval: number; //
public proxyName: string;
constructor(ownerUri:string) {
this.ownerUri = ownerUri;
}
public async save() {
let agentService = await AgentUtils.getAgentService();
agentService.createJobStep(this.ownerUri, {
jobId: this.jobId,
jobName: this.jobName,
script: this.script,
scriptName: this.scriptName,
stepName: this.stepName,
subSystem: this.subSystem,
id: 1,
failureAction: this.failureAction,
successAction: this.successAction,
failStepId: this.failStepId,
successStepId: this.successStepId,
command: this.command,
commandExecutionSuccessCode: this.commandExecutionSuccessCode,
databaseName: this.databaseName,
databaseUserName: this.databaseUserName,
server: this.server,
outputFileName: this.outputFileName,
appendToLogFile: this.appendToLogFile,
appendToStepHist: this.appendToStepHist,
writeLogToTable: this.writeLogToTable,
appendLogToTable: this.appendLogToTable,
retryAttempts: this.retryAttempts,
retryInterval: this.retryInterval,
proxyName: this.proxyName
}).then(result => {
console.info(result);
});
}
}

View File

@@ -0,0 +1,29 @@
/*---------------------------------------------------------------------------------------------
* 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 PickScheduleData {
public ownerUri: string;
public schedules: sqlops.AgentJobScheduleInfo[];
public selectedSchedule: sqlops.AgentJobScheduleInfo;
constructor(ownerUri:string) {
this.ownerUri = ownerUri;
}
public async initialize() {
let agentService = await AgentUtils.getAgentService();
let result = await agentService.getJobSchedules(this.ownerUri);
if (result && result.success) {
this.schedules = result.schedules;
}
}
public async save() {
}
}

View File

@@ -0,0 +1,222 @@
/*---------------------------------------------------------------------------------------------
* 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 * as vscode from 'vscode';
import { AgentUtils } from '../agentUtils';
import { CreateAlertData } from '../data/createAlertData';
export class CreateAlertDialog {
// Top level
private static readonly DialogTitle: string = 'Create Alert';
private static readonly OkButtonText: string = 'OK';
private static readonly CancelButtonText: string = 'Cancel';
private static readonly GeneralTabText: string = 'General';
private static readonly ResponseTabText: string = 'Response';
private static readonly OptionsTabText: string = 'Options';
// General tab strings
private static readonly NameLabel: string = 'Name';
private static readonly TypeLabel: string = 'Type';
private static readonly DatabaseLabel: string = 'Database name';
private static readonly ErrorNumberLabel: string = 'Error number';
private static readonly SeverityrLabel: string = 'Severity';
private static readonly AlertTypeSqlServerEventString: string = 'SQL Server event alert';
private static readonly AlertTypePerformanceConditionString: string = 'SQL Server performance condition alert';
private static readonly AlertTypeWmiEventString: string = 'WMI event alert';
private static readonly AlertSeverity001Label: string = '001 - Miscellaneous System Information';
private static readonly AlertSeverity002Label: string = '002 - Reserved';
private static readonly AlertSeverity003Label: string = '003 - Reserved';
private static readonly AlertSeverity004Label: string = '004 - Reserved';
private static readonly AlertSeverity005Label: string = '005 - Reserved';
private static readonly AlertSeverity006Label: string = '006 - Reserved';
private static readonly AlertSeverity007Label: string = '007 - Notification: Status Information';
private static readonly AlertSeverity008Label: string = '008 - Notification: User Intervention Required';
private static readonly AlertSeverity009Label: string = '009 - User Defined';
private static readonly AlertSeverity010Label: string = '010 - Information';
private static readonly AlertSeverity011Label: string = '011 - Specified Database Object Not Found';
private static readonly AlertSeverity012Label: string = '012 - Unused';
private static readonly AlertSeverity013Label: string = '013 - User Transaction Syntax Error';
private static readonly AlertSeverity014Label: string = '014 - Insufficient Permission';
private static readonly AlertSeverity015Label: string = '015 - Syntax Error in SQL Statements';
private static readonly AlertSeverity016Label: string = '016 - Miscellaneous User Error';
private static readonly AlertSeverity017Label: string = '017 - Insufficient Resources';
private static readonly AlertSeverity018Label: string = '018 - Nonfatal Internal Error';
private static readonly AlertSeverity019Label: string = '019 - Fatal Error in Resource';
private static readonly AlertSeverity020Label: string = '020 - Fatal Error in Current Process';
private static readonly AlertSeverity021Label: string = '021 - Fatal Error in Database Processes';
private static readonly AlertSeverity022Label: string = '022 - Fatal Error: Table Integrity Suspect';
private static readonly AlertSeverity023Label: string = '023 - Fatal Error: Database Integrity Suspect';
private static readonly AlertSeverity024Label: string = '024 - Fatal Error: Hardware Error';
private static readonly AlertSeverity025Label: string = '025 - Fatal Error';
private static readonly AlertTypes: string[] = [
CreateAlertDialog.AlertTypeSqlServerEventString,
CreateAlertDialog.AlertTypePerformanceConditionString,
CreateAlertDialog.AlertTypeWmiEventString
];
private static readonly AlertSeverities: string[] = [
CreateAlertDialog.AlertSeverity001Label,
CreateAlertDialog.AlertSeverity002Label,
CreateAlertDialog.AlertSeverity003Label,
CreateAlertDialog.AlertSeverity004Label,
CreateAlertDialog.AlertSeverity005Label,
CreateAlertDialog.AlertSeverity006Label,
CreateAlertDialog.AlertSeverity007Label,
CreateAlertDialog.AlertSeverity008Label,
CreateAlertDialog.AlertSeverity009Label,
CreateAlertDialog.AlertSeverity010Label,
CreateAlertDialog.AlertSeverity011Label,
CreateAlertDialog.AlertSeverity012Label,
CreateAlertDialog.AlertSeverity013Label,
CreateAlertDialog.AlertSeverity014Label,
CreateAlertDialog.AlertSeverity015Label,
CreateAlertDialog.AlertSeverity016Label,
CreateAlertDialog.AlertSeverity017Label,
CreateAlertDialog.AlertSeverity018Label,
CreateAlertDialog.AlertSeverity019Label,
CreateAlertDialog.AlertSeverity020Label,
CreateAlertDialog.AlertSeverity021Label,
CreateAlertDialog.AlertSeverity022Label,
CreateAlertDialog.AlertSeverity023Label,
CreateAlertDialog.AlertSeverity024Label,
CreateAlertDialog.AlertSeverity025Label
];
// Response tab strings
private readonly ExecuteJobTextBoxLabel: string = 'Execute Job';
// Options tab strings
private readonly AdditionalMessageTextBoxLabel: string = 'Additional notification message to send';
// History tab strings
private readonly ResetCountTextBoxLabel: string = 'Reset Count';
// 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;
// General tab controls
private nameTextBox: sqlops.InputBoxComponent;
private typeDropDown: sqlops.DropDownComponent;
private severityDropDown: sqlops.DropDownComponent;
private databaseDropDown: sqlops.DropDownComponent;
private raiseAlertMessageCheckBox: sqlops.CheckBoxComponent;
private raiseAlertMessageTextBox: sqlops.InputBoxComponent;
// Response tab controls
private executeJobTextBox: sqlops.InputBoxComponent;
// Options tab controls
private additionalMessageTextBox: sqlops.InputBoxComponent;
// History tab controls
private resetCountTextBox: sqlops.InputBoxComponent;
private model: CreateAlertData;
private _onSuccess: vscode.EventEmitter<CreateAlertData> = new vscode.EventEmitter<CreateAlertData>();
public readonly onSuccess: vscode.Event<CreateAlertData> = this._onSuccess.event;
constructor(public ownerUri: string) {
this.model = new CreateAlertData(ownerUri);
}
public async showDialog() {
let databases = await AgentUtils.getDatabases(this.ownerUri);
await this.model.initialize();
this.dialog = sqlops.window.modelviewdialog.createDialog(CreateAlertDialog.DialogTitle);
this.generalTab = sqlops.window.modelviewdialog.createTab(CreateAlertDialog.GeneralTabText);
this.responseTab = sqlops.window.modelviewdialog.createTab(CreateAlertDialog.ResponseTabText);
this.optionsTab = sqlops.window.modelviewdialog.createTab(CreateAlertDialog.OptionsTabText);
this.initializeGeneralTab(databases);
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 = CreateAlertDialog.OkButtonText;
this.dialog.cancelButton.label = CreateAlertDialog.CancelButtonText;
sqlops.window.modelviewdialog.openDialog(this.dialog);
}
private initializeGeneralTab(databases: string[]) {
this.generalTab.registerContent(async view => {
this.nameTextBox = view.modelBuilder.inputBox().component();
// this.enabledCheckBox = view.modelBuilder.checkBox()
// .withProperties({
// label: this.EnabledCheckboxLabel
// }).component();
this.databaseDropDown = view.modelBuilder.dropDown()
.withProperties({
value: databases[0],
values: databases,
title: CreateAlertDialog.DatabaseLabel
}).component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.nameTextBox,
title: CreateAlertDialog.NameLabel
}, {
component: this.databaseDropDown,
title: CreateAlertDialog.DatabaseLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private initializeResponseTab() {
this.responseTab.registerContent(async view => {
this.executeJobTextBox = view.modelBuilder.inputBox().component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.executeJobTextBox,
title: this.ExecuteJobTextBoxLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private initializeOptionsTab() {
this.optionsTab.registerContent(async view => {
this.additionalMessageTextBox = view.modelBuilder.inputBox().component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.additionalMessageTextBox,
title: this.AdditionalMessageTextBoxLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private async execute() {
this.updateModel();
await this.model.save();
this._onSuccess.fire(this.model);
}
private async cancel() {
}
private updateModel() {
}
}

View File

@@ -0,0 +1,464 @@
/*---------------------------------------------------------------------------------------------
* 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 { CreateJobData } from '../data/createJobData';
import { CreateStepDialog } from './createStepDialog';
import { PickScheduleDialog } from './pickScheduleDialog';
import { CreateAlertDialog } from './createAlertDialog';
export class CreateJobDialog {
// TODO: localize
// Top level
private readonly DialogTitle: string = 'New Job';
private readonly OkButtonText: string = 'OK';
private readonly CancelButtonText: string = 'Cancel';
private readonly GeneralTabText: string = 'General';
private readonly StepsTabText: string = 'Steps';
private readonly SchedulesTabText: string = 'Schedules';
private readonly AlertsTabText: string = 'Alerts';
private readonly NotificationsTabText: string = 'Notifications';
// General tab strings
private readonly NameTextBoxLabel: string = 'Name';
private readonly OwnerTextBoxLabel: string = 'Owner';
private readonly CategoryDropdownLabel: string = 'Category';
private readonly DescriptionTextBoxLabel: string = 'Description';
private readonly EnabledCheckboxLabel: string = 'Enabled';
// Steps tab strings
private readonly JobStepsTopLabelString: string = 'Job step list';
private readonly StepsTable_StepColumnString: string = 'Step';
private readonly StepsTable_NameColumnString: string = 'Name';
private readonly StepsTable_TypeColumnString: string = 'Type';
private readonly StepsTable_SuccessColumnString: string = 'On Success';
private readonly StepsTable_FailureColumnString: string = 'On Failure';
private readonly NewStepButtonString: string = 'New...';
private readonly InsertStepButtonString: string = 'Insert...';
private readonly EditStepButtonString: string = 'Edit';
private readonly DeleteStepButtonString: string = 'Delete';
// Notifications tab strings
private readonly NotificationsTabTopLabelString: string = 'Actions to perform when the job completes';
private readonly EmailCheckBoxString: string = 'Email';
private readonly PagerCheckBoxString: string = 'Page';
private readonly EventLogCheckBoxString: string = 'Write to the Windows Application event log';
private readonly DeleteJobCheckBoxString: string = 'Automatically delete job';
// Schedules tab strings
private readonly SchedulesTopLabelString: string = 'Schedules list';
private readonly PickScheduleButtonString: string = 'Pick Schedule';
// Alerts tab strings
private readonly AlertsTopLabelString: string = 'Alerts list';
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;
private schedulesTab: sqlops.window.modelviewdialog.DialogTab;
private notificationsTab: sqlops.window.modelviewdialog.DialogTab;
// General tab controls
private nameTextBox: sqlops.InputBoxComponent;
private ownerTextBox: sqlops.InputBoxComponent;
private categoryDropdown: sqlops.DropDownComponent;
private descriptionTextBox: sqlops.InputBoxComponent;
private enabledCheckBox: sqlops.CheckBoxComponent;
// Steps tab controls
private stepsTable: sqlops.TableComponent;
private newStepButton: sqlops.ButtonComponent;
private insertStepButton: sqlops.ButtonComponent;
private editStepButton: sqlops.ButtonComponent;
private deleteStepButton: sqlops.ButtonComponent;
// Notifications tab controls
private notificationsTabTopLabel: sqlops.TextComponent;
private emailCheckBox: sqlops.CheckBoxComponent;
private emailOperatorDropdown: sqlops.DropDownComponent;
private emailConditionDropdown: sqlops.DropDownComponent;
private pagerCheckBox: sqlops.CheckBoxComponent;
private pagerOperatorDropdown: sqlops.DropDownComponent;
private pagerConditionDropdown: sqlops.DropDownComponent;
private eventLogCheckBox: sqlops.CheckBoxComponent;
private eventLogConditionDropdown: sqlops.DropDownComponent;
private deleteJobCheckBox: sqlops.CheckBoxComponent;
private deleteJobConditionDropdown: sqlops.DropDownComponent;
// Schedule tab controls
private schedulesTable: sqlops.TableComponent;
private pickScheduleButton: sqlops.ButtonComponent;
// Alert tab controls
private alertsTable: sqlops.TableComponent;
private newAlertButton: sqlops.ButtonComponent;
private model: CreateJobData;
constructor(ownerUri: string) {
this.model = new CreateJobData(ownerUri);
}
public async showDialog() {
await this.model.initialize();
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
this.generalTab = sqlops.window.modelviewdialog.createTab(this.GeneralTabText);
this.stepsTab = sqlops.window.modelviewdialog.createTab(this.StepsTabText);
this.alertsTab = sqlops.window.modelviewdialog.createTab(this.AlertsTabText);
this.schedulesTab = sqlops.window.modelviewdialog.createTab(this.SchedulesTabText);
this.notificationsTab = sqlops.window.modelviewdialog.createTab(this.NotificationsTabText);
this.initializeGeneralTab();
this.initializeStepsTab();
this.initializeAlertsTab();
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();
let validationResult = this.model.validate();
if (!validationResult.valid) {
// TODO: Show Error Messages
console.error(validationResult.errorMessages.join(','));
}
return validationResult.valid;
});
sqlops.window.modelviewdialog.openDialog(this.dialog);
}
private initializeGeneralTab() {
this.generalTab.registerContent(async view => {
this.nameTextBox = view.modelBuilder.inputBox().component();
this.ownerTextBox = view.modelBuilder.inputBox().component();
this.categoryDropdown = view.modelBuilder.dropDown().component();
this.descriptionTextBox = view.modelBuilder.inputBox().withProperties({
multiline: true,
height: 200
}).component();
this.enabledCheckBox = view.modelBuilder.checkBox()
.withProperties({
label: this.EnabledCheckboxLabel
}).component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.nameTextBox,
title: this.NameTextBoxLabel
}, {
component: this.ownerTextBox,
title: this.OwnerTextBoxLabel
}, {
component: this.categoryDropdown,
title: this.CategoryDropdownLabel
}, {
component: this.descriptionTextBox,
title: this.DescriptionTextBoxLabel
}, {
component: this.enabledCheckBox,
title: ''
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
this.ownerTextBox.value = this.model.defaultOwner;
this.categoryDropdown.values = this.model.jobCategories;
this.categoryDropdown.value = this.model.jobCategories[0];
this.enabledCheckBox.checked = this.model.enabled;
this.descriptionTextBox.value = '';
});
}
private initializeStepsTab() {
this.stepsTab.registerContent(async view => {
this.stepsTable = view.modelBuilder.table()
.withProperties({
columns: [
this.StepsTable_StepColumnString,
this.StepsTable_NameColumnString,
this.StepsTable_TypeColumnString,
this.StepsTable_SuccessColumnString,
this.StepsTable_FailureColumnString
],
data: [],
height: 800
}).component();
this.newStepButton = view.modelBuilder.button().withProperties({
label: this.NewStepButtonString,
width: 80
}).component();
this.newStepButton.onDidClick((e)=>{
let stepDialog = new CreateStepDialog(this.model.ownerUri, '', '', 1, this.model);
stepDialog.openNewStepDialog();
});
this.insertStepButton = view.modelBuilder.button().withProperties({
label: this.InsertStepButtonString,
width: 80
}).component();
this.editStepButton = view.modelBuilder.button().withProperties({
label: this.EditStepButtonString,
width: 80
}).component();
this.deleteStepButton = view.modelBuilder.button().withProperties({
label: this.DeleteStepButtonString,
width: 80
}).component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.stepsTable,
title: this.JobStepsTopLabelString,
actions: [this.newStepButton, this.insertStepButton, this.editStepButton, this.deleteStepButton]
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private initializeAlertsTab() {
this.alertsTab.registerContent(async view => {
this.alertsTable = view.modelBuilder.table()
.withProperties({
columns: [
'Alert Name'
],
data: [],
height: 600,
width: 400
}).component();
this.newAlertButton = view.modelBuilder.button().withProperties({
label: this.NewAlertButtonString,
width: 80
}).component();
this.newAlertButton.onDidClick((e)=>{
let alertDialog = new CreateAlertDialog(this.model.ownerUri);
alertDialog.onSuccess((dialogModel) => {
});
alertDialog.showDialog();
});
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.alertsTable,
title: this.AlertsTopLabelString,
actions: [this.newAlertButton]
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private initializeSchedulesTab() {
this.schedulesTab.registerContent(async view => {
this.schedulesTable = view.modelBuilder.table()
.withProperties({
columns: [
'Schedule Name'
],
data: [],
height: 600,
width: 400
}).component();
this.pickScheduleButton = view.modelBuilder.button().withProperties({
label: this.PickScheduleButtonString,
width: 80
}).component();
this.pickScheduleButton.onDidClick((e)=>{
let pickScheduleDialog = new PickScheduleDialog(this.model.ownerUri);
pickScheduleDialog.onSuccess((dialogModel) => {
let selectedSchedule = dialogModel.selectedSchedule;
if (selectedSchedule) {
this.model.addJobSchedule(selectedSchedule);
this.populateScheduleTable();
}
});
pickScheduleDialog.showDialog();
});
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.schedulesTable,
title: this.SchedulesTopLabelString,
actions: [this.pickScheduleButton]
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
this.populateScheduleTable();
});
}
private populateScheduleTable() {
if (this.model.jobSchedules) {
let data: any[][] = [];
for (let i = 0; i < this.model.jobSchedules.length; ++i) {
let schedule = this.model.jobSchedules[i];
data[i] = [ schedule.name ];
}
this.schedulesTable.data = data;
}
}
private initializeNotificationsTab() {
this.notificationsTab.registerContent(async view => {
this.notificationsTabTopLabel = view.modelBuilder.text().withProperties({ value: this.NotificationsTabTopLabelString }).component();
this.emailCheckBox = view.modelBuilder.checkBox().withProperties({
label: this.EmailCheckBoxString,
width: 80
}).component();
this.pagerCheckBox = view.modelBuilder.checkBox().withProperties({
label: this.PagerCheckBoxString,
width: 80
}).component();
this.eventLogCheckBox = view.modelBuilder.checkBox().withProperties({
label: this.EventLogCheckBoxString,
width: 250
}).component();
this.deleteJobCheckBox = view.modelBuilder.checkBox().withProperties({
label: this.DeleteJobCheckBoxString,
width: 250
}).component();
this.emailCheckBox.onChanged(() => {
this.emailConditionDropdown.enabled = this.emailCheckBox.checked;
this.emailOperatorDropdown.enabled = this.emailCheckBox.checked;
});
this.pagerCheckBox.onChanged(() => {
this.pagerConditionDropdown.enabled = this.pagerCheckBox.checked;
this.pagerOperatorDropdown.enabled = this.pagerCheckBox.checked;
});
this.eventLogCheckBox.onChanged(() => {
this.eventLogConditionDropdown.enabled = this.eventLogCheckBox.checked;
});
this.deleteJobCheckBox.onChanged(() => {
this.deleteJobConditionDropdown.enabled = this.deleteJobCheckBox.checked;
});
this.emailOperatorDropdown = view.modelBuilder.dropDown().withProperties({ width: 150 }).component();
this.pagerOperatorDropdown = view.modelBuilder.dropDown().withProperties({ width: 150 }).component();
this.emailConditionDropdown = view.modelBuilder.dropDown().withProperties({ width: 150 }).component();
this.pagerConditionDropdown = view.modelBuilder.dropDown().withProperties({ width: 150 }).component();
this.eventLogConditionDropdown = view.modelBuilder.dropDown().withProperties({ width: 150 }).component();
this.deleteJobConditionDropdown = view.modelBuilder.dropDown().withProperties({ width: 150 }).component();
let emailContainer = this.createRowContainer(view).withItems([this.emailCheckBox, this.emailOperatorDropdown, this.emailConditionDropdown]).component();
let pagerContainer = this.createRowContainer(view).withItems([this.pagerCheckBox, this.pagerOperatorDropdown, this.pagerConditionDropdown]).component();
let eventLogContainer = this.createRowContainer(view).withItems([this.eventLogCheckBox, this.eventLogConditionDropdown]).component();
let deleteJobContainer = this.createRowContainer(view).withItems([this.deleteJobCheckBox, this.deleteJobConditionDropdown]).component();
let formModel = view.modelBuilder.formContainer().withFormItems([
{
component: this.notificationsTabTopLabel,
title: ''
}, {
component: emailContainer,
title: ''
}, {
component: pagerContainer,
title: ''
}, {
component: eventLogContainer,
title: ''
}, {
component: deleteJobContainer,
title: ''
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
this.emailConditionDropdown.values = this.model.JobCompletionActionConditions;
this.pagerConditionDropdown.values = this.model.JobCompletionActionConditions;
this.eventLogConditionDropdown.values = this.model.JobCompletionActionConditions;
this.deleteJobConditionDropdown.values = this.model.JobCompletionActionConditions;
this.setConditionDropdownSelectedValue(this.emailConditionDropdown, this.model.emailLevel);
this.setConditionDropdownSelectedValue(this.pagerConditionDropdown, this.model.pageLevel);
this.setConditionDropdownSelectedValue(this.eventLogConditionDropdown, this.model.eventLogLevel);
this.setConditionDropdownSelectedValue(this.deleteJobConditionDropdown, this.model.deleteLevel);
this.emailOperatorDropdown.values = this.model.operators;
this.pagerOperatorDropdown.values = this.model.operators;
this.emailCheckBox.checked = false;
this.pagerCheckBox.checked = false;
this.eventLogCheckBox.checked = false;
this.deleteJobCheckBox.checked = false;
this.emailOperatorDropdown.enabled = false;
this.pagerOperatorDropdown.enabled = false;
this.emailConditionDropdown.enabled = false;
this.pagerConditionDropdown.enabled = false;
this.eventLogConditionDropdown.enabled = false;
this.deleteJobConditionDropdown.enabled = false;
});
}
private createRowContainer(view: sqlops.ModelView): sqlops.FlexBuilder {
return view.modelBuilder.flexContainer().withLayout({
flexFlow: 'row',
alignItems: 'left',
justifyContent: 'space-between'
});
}
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((<sqlops.CategoryValue>dropdown.values[idx]).name) === selectedValue) {
dropdown.value = dropdown.values[idx];
break;
}
}
}
private updateModel() {
this.model.name = this.nameTextBox.value;
this.model.owner = this.ownerTextBox.value;
this.model.enabled = this.enabledCheckBox.checked;
this.model.description = this.descriptionTextBox.value;
this.model.category = this.getDropdownValue(this.categoryDropdown);
this.model.emailLevel = this.getActualConditionValue(this.emailCheckBox, this.emailConditionDropdown);
this.model.operatorToEmail = this.getDropdownValue(this.emailOperatorDropdown);
this.model.operatorToPage = this.getDropdownValue(this.pagerOperatorDropdown);
this.model.pageLevel = this.getActualConditionValue(this.pagerCheckBox, this.pagerConditionDropdown);
this.model.eventLogLevel = this.getActualConditionValue(this.eventLogCheckBox, this.eventLogConditionDropdown);
this.model.deleteLevel = this.getActualConditionValue(this.deleteJobCheckBox, this.deleteJobConditionDropdown);
}
}

View File

@@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------------------------
* 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 * as vscode from 'vscode';
import { CreateOperatorData } from '../data/createOperatorData';
export class CreateOperatorDialog {
// Top level
private readonly DialogTitle: string = 'Create Operator';
private readonly OkButtonText: string = 'OK';
private readonly CancelButtonText: string = 'Cancel';
private readonly GeneralTabText: string = 'Response';
private readonly ResponseTabText: string = 'Steps';
private readonly OptionsTabText: string = 'Options';
private readonly HistoryTabText: string = 'History';
// General tab strings
private readonly NameTextBoxLabel: string = 'Name';
// Response tab strings
private readonly ExecuteJobTextBoxLabel: string = 'Execute Job';
// Options tab strings
private readonly AdditionalMessageTextBoxLabel: string = 'Additional notification message to send';
// History tab strings
private readonly ResetCountTextBoxLabel: string = 'Reset Count';
// 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;
private historyTab: sqlops.window.modelviewdialog.DialogTab;
private schedulesTable: sqlops.TableComponent;
// General tab controls
private nameTextBox: sqlops.InputBoxComponent;
// Response tab controls
private executeJobTextBox: sqlops.InputBoxComponent;
// Options tab controls
private additionalMessageTextBox: sqlops.InputBoxComponent;
// History tab controls
private resetCountTextBox: sqlops.InputBoxComponent;
private model: CreateOperatorData;
private _onSuccess: vscode.EventEmitter<CreateOperatorData> = new vscode.EventEmitter<CreateOperatorData>();
public readonly onSuccess: vscode.Event<CreateOperatorData> = this._onSuccess.event;
constructor(ownerUri: string) {
this.model = new CreateOperatorData(ownerUri);
}
public async showDialog() {
await this.model.initialize();
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
this.generalTab = sqlops.window.modelviewdialog.createTab(this.GeneralTabText);
this.responseTab = sqlops.window.modelviewdialog.createTab(this.ResponseTabText);
this.optionsTab = sqlops.window.modelviewdialog.createTab(this.OptionsTabText);
this.historyTab = sqlops.window.modelviewdialog.createTab(this.HistoryTabText);
this.initializeGeneralTab();
this.initializeResponseTab();
this.initializeOptionsTab();
this.initializeHistoryTab();
this.dialog.content = [this.generalTab, this.responseTab, this.optionsTab, this.historyTab];
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;
sqlops.window.modelviewdialog.openDialog(this.dialog);
}
private initializeGeneralTab() {
this.generalTab.registerContent(async view => {
this.nameTextBox = view.modelBuilder.inputBox().component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.nameTextBox,
title: this.NameTextBoxLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private initializeResponseTab() {
this.responseTab.registerContent(async view => {
this.executeJobTextBox = view.modelBuilder.inputBox().component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.executeJobTextBox,
title: this.ExecuteJobTextBoxLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private initializeOptionsTab() {
this.optionsTab.registerContent(async view => {
this.additionalMessageTextBox = view.modelBuilder.inputBox().component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.additionalMessageTextBox,
title: this.AdditionalMessageTextBoxLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private initializeHistoryTab() {
this.historyTab.registerContent(async view => {
this.resetCountTextBox = view.modelBuilder.inputBox().component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.resetCountTextBox,
title: this.ResetCountTextBoxLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private async execute() {
this.updateModel();
await this.model.save();
this._onSuccess.fire(this.model);
}
private async cancel() {
}
private updateModel() {
}
}

View File

@@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------------------------
* 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 * as vscode from 'vscode';
import { CreateProxyData } from '../data/createProxyData';
export class CreateProxyDialog {
// Top level
private readonly DialogTitle: string = 'Create Proxy';
private readonly OkButtonText: string = 'OK';
private readonly CancelButtonText: string = 'Cancel';
private readonly GeneralTabText: string = 'Response';
private readonly ResponseTabText: string = 'Steps';
private readonly OptionsTabText: string = 'Options';
private readonly HistoryTabText: string = 'History';
// General tab strings
private readonly NameTextBoxLabel: string = 'Name';
// Response tab strings
private readonly ExecuteJobTextBoxLabel: string = 'Execute Job';
// Options tab strings
private readonly AdditionalMessageTextBoxLabel: string = 'Additional notification message to send';
// History tab strings
private readonly ResetCountTextBoxLabel: string = 'Reset Count';
// 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;
private historyTab: sqlops.window.modelviewdialog.DialogTab;
private schedulesTable: sqlops.TableComponent;
// General tab controls
private nameTextBox: sqlops.InputBoxComponent;
// Response tab controls
private executeJobTextBox: sqlops.InputBoxComponent;
// Options tab controls
private additionalMessageTextBox: sqlops.InputBoxComponent;
// History tab controls
private resetCountTextBox: sqlops.InputBoxComponent;
private model: CreateProxyData;
private _onSuccess: vscode.EventEmitter<CreateProxyData> = new vscode.EventEmitter<CreateProxyData>();
public readonly onSuccess: vscode.Event<CreateProxyData> = this._onSuccess.event;
constructor(ownerUri: string) {
this.model = new CreateProxyData(ownerUri);
}
public async showDialog() {
await this.model.initialize();
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
this.generalTab = sqlops.window.modelviewdialog.createTab(this.GeneralTabText);
this.responseTab = sqlops.window.modelviewdialog.createTab(this.ResponseTabText);
this.optionsTab = sqlops.window.modelviewdialog.createTab(this.OptionsTabText);
this.historyTab = sqlops.window.modelviewdialog.createTab(this.HistoryTabText);
this.initializeGeneralTab();
this.initializeResponseTab();
this.initializeOptionsTab();
this.initializeHistoryTab();
this.dialog.content = [this.generalTab, this.responseTab, this.optionsTab, this.historyTab];
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;
sqlops.window.modelviewdialog.openDialog(this.dialog);
}
private initializeGeneralTab() {
this.generalTab.registerContent(async view => {
this.nameTextBox = view.modelBuilder.inputBox().component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.nameTextBox,
title: this.NameTextBoxLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private initializeResponseTab() {
this.responseTab.registerContent(async view => {
this.executeJobTextBox = view.modelBuilder.inputBox().component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.executeJobTextBox,
title: this.ExecuteJobTextBoxLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private initializeOptionsTab() {
this.optionsTab.registerContent(async view => {
this.additionalMessageTextBox = view.modelBuilder.inputBox().component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.additionalMessageTextBox,
title: this.AdditionalMessageTextBoxLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private initializeHistoryTab() {
this.historyTab.registerContent(async view => {
this.resetCountTextBox = view.modelBuilder.inputBox().component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.resetCountTextBox,
title: this.ResetCountTextBoxLabel
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
});
}
private async execute() {
this.updateModel();
await this.model.save();
this._onSuccess.fire(this.model);
}
private async cancel() {
}
private updateModel() {
}
}

View File

@@ -0,0 +1,91 @@
/*---------------------------------------------------------------------------------------------
* 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 * as vscode from 'vscode';
import { CreateScheduleData } from '../data/createScheduleData';
export class CreateScheduleDialog {
// Top level
private readonly DialogTitle: string = 'New Schedule';
private readonly OkButtonText: string = 'OK';
private readonly CancelButtonText: string = 'Cancel';
// UI Components
private dialog: sqlops.window.modelviewdialog.Dialog;
private schedulesTable: sqlops.TableComponent;
private model: CreateScheduleData;
private _onSuccess: vscode.EventEmitter<CreateScheduleData> = new vscode.EventEmitter<CreateScheduleData>();
public readonly onSuccess: vscode.Event<CreateScheduleData> = this._onSuccess.event;
constructor(ownerUri: string) {
this.model = new CreateScheduleData(ownerUri);
}
public async showDialog() {
await this.model.initialize();
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
this.initializeContent();
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;
sqlops.window.modelviewdialog.openDialog(this.dialog);
}
private initializeContent() {
this.dialog.registerContent(async view => {
this.schedulesTable = view.modelBuilder.table()
.withProperties({
columns: [
'Schedule Name'
],
data: [],
height: 600,
width: 400
}).component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.schedulesTable,
title: 'Schedules'
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
if (this.model.schedules) {
let data: any[][] = [];
for (let i = 0; i < this.model.schedules.length; ++i) {
let schedule = this.model.schedules[i];
data[i] = [ schedule.name ];
}
this.schedulesTable.data = data;
}
});
}
private async execute() {
this.updateModel();
await this.model.save();
this._onSuccess.fire(this.model);
}
private async cancel() {
}
private updateModel() {
let selectedRows = this.schedulesTable.selectedRows;
if (selectedRows && selectedRows.length > 0) {
let selectedRow = selectedRows[0];
this.model.selectedSchedule = this.model.schedules[selectedRow];
}
}
}

View File

@@ -0,0 +1,421 @@
/*---------------------------------------------------------------------------------------------
* 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 * as vscode from 'vscode';
import { CreateStepData } from '../data/createStepData';
import { AgentUtils } from '../agentUtils';
import { CreateJobData } from '../data/createJobData';
export class CreateStepDialog {
// TODO: localize
// Top level
//
private static readonly DialogTitle: string = 'New Job Step';
private static readonly OkButtonText: string = 'OK';
private static readonly CancelButtonText: string = 'Cancel';
private static readonly GeneralTabText: string = 'General';
private static readonly AdvancedTabText: string = 'Advanced';
private static readonly OpenCommandText: string = 'Open...';
private static readonly ParseCommandText: string = 'Parse';
private static readonly NextButtonText: string = 'Next';
private static readonly PreviousButtonText: string = 'Previous';
private static readonly SuccessAction: string = 'On success action';
private static readonly FailureAction: string = 'On failure action';
// Dropdown options
private static readonly TSQLScript: string = 'Transact-SQL script (T-SQL)';
private static readonly AgentServiceAccount: string = 'SQL Server Agent Service Account';
private static readonly NextStep: string = 'Go to the next step';
private static readonly QuitJobReportingSuccess: string = 'Quit the job reporting success';
private static readonly QuitJobReportingFailure: string = 'Quit the job reporting failure';
// UI Components
//
private dialog: sqlops.window.modelviewdialog.Dialog;
private generalTab: sqlops.window.modelviewdialog.DialogTab;
private advancedTab: sqlops.window.modelviewdialog.DialogTab;
private nameTextBox: sqlops.InputBoxComponent;
private typeDropdown: sqlops.DropDownComponent;
private runAsDropdown: sqlops.DropDownComponent;
private databaseDropdown: sqlops.DropDownComponent;
private successActionDropdown: sqlops.DropDownComponent;
private failureActionDropdown: sqlops.DropDownComponent;
private commandTextBox: sqlops.InputBoxComponent;
private openButton: sqlops.ButtonComponent;
private parseButton: sqlops.ButtonComponent;
private nextButton: sqlops.ButtonComponent;
private previousButton: sqlops.ButtonComponent;
private retryAttemptsBox: sqlops.InputBoxComponent;
private retryIntervalBox: sqlops.InputBoxComponent;
private appendToExistingFileCheckbox: sqlops.CheckBoxComponent;
private logToTableCheckbox: sqlops.CheckBoxComponent;
private outputFileNameBox: sqlops.InputBoxComponent;
private outputFileBrowserButton: sqlops.ButtonComponent;
private model: CreateStepData;
private ownerUri: string;
private jobName: string;
private server: string;
private stepId: number;
private jobModel: CreateJobData;
constructor(
ownerUri: string,
jobName: string,
server: string,
stepId: number,
jobModel?: CreateJobData
) {
this.model = new CreateStepData(ownerUri);
this.stepId = stepId;
this.ownerUri = ownerUri;
this.jobName = jobName;
this.server = server;
this.jobModel = jobModel;
}
private initializeUIComponents() {
this.dialog = sqlops.window.modelviewdialog.createDialog(CreateStepDialog.DialogTitle);
this.generalTab = sqlops.window.modelviewdialog.createTab(CreateStepDialog.GeneralTabText);
this.advancedTab = sqlops.window.modelviewdialog.createTab(CreateStepDialog.AdvancedTabText);
this.dialog.content = [this.generalTab, this.advancedTab];
this.dialog.okButton.onClick(async () => await this.execute());
this.dialog.okButton.label = CreateStepDialog.OkButtonText;
this.dialog.cancelButton.label = CreateStepDialog.CancelButtonText;
}
private createCommands(view, queryProvider: sqlops.QueryProvider) {
this.openButton = view.modelBuilder.button()
.withProperties({
label: CreateStepDialog.OpenCommandText,
width: '80px'
}).component();
this.parseButton = view.modelBuilder.button()
.withProperties({
label: CreateStepDialog.ParseCommandText,
width: '80px'
}).component();
this.parseButton.onDidClick(e => {
if (this.commandTextBox.value) {
queryProvider.parseSyntax(this.ownerUri, this.commandTextBox.value).then(result => {
if (result && result.parseable) {
this.dialog.message = { text: 'The command was successfully parsed.', level: 2};
} else if (result && !result.parseable) {
this.dialog.message = { text: 'The command failed' };
}
});
}
});
this.commandTextBox = view.modelBuilder.inputBox()
.withProperties({
height: 300,
width: 400,
multiline: true,
inputType: 'text'
})
.component();
this.nextButton = view.modelBuilder.button()
.withProperties({
label: CreateStepDialog.NextButtonText,
enabled: false,
width: '80px'
}).component();
this.previousButton = view.modelBuilder.button()
.withProperties({
label: CreateStepDialog.PreviousButtonText,
enabled: false,
width: '80px'
}).component();
}
private createGeneralTab(databases: string[], queryProvider: sqlops.QueryProvider) {
this.generalTab.registerContent(async (view) => {
this.nameTextBox = view.modelBuilder.inputBox()
.withProperties({
}).component();
this.nameTextBox.required = true;
this.typeDropdown = view.modelBuilder.dropDown()
.withProperties({
value: CreateStepDialog.TSQLScript,
values: [CreateStepDialog.TSQLScript]
})
.component();
this.runAsDropdown = view.modelBuilder.dropDown()
.withProperties({
value: '',
values: ['']
})
.component();
this.runAsDropdown.enabled = false;
this.typeDropdown.onValueChanged((type) => {
if (type.selected !== CreateStepDialog.TSQLScript) {
this.runAsDropdown.value = CreateStepDialog.AgentServiceAccount;
this.runAsDropdown.values = [this.runAsDropdown.value];
} else {
this.runAsDropdown.value = '';
this.runAsDropdown.values = [''];
}
});
this.databaseDropdown = view.modelBuilder.dropDown()
.withProperties({
value: databases[0],
values: databases
}).component();
// create the commands section
this.createCommands(view, queryProvider);
let buttonContainer = view.modelBuilder.flexContainer()
.withLayout({
flexFlow: 'row',
justifyContent: 'space-between',
width: 420
}).withItems([this.openButton, this.parseButton, this.previousButton, this.nextButton], {
flex: '1 1 50%'
}).component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.nameTextBox,
title: 'Step name'
}, {
component: this.typeDropdown,
title: 'Type'
}, {
component: this.runAsDropdown,
title: 'Run as'
}, {
component: this.databaseDropdown,
title: 'Database'
}, {
component: this.commandTextBox,
title: 'Command',
actions: [buttonContainer]
}], {
horizontal: false,
componentWidth: 420
}).component();
let formWrapper = view.modelBuilder.loadingComponent().withItem(formModel).component();
formWrapper.loading = false;
await view.initializeModel(formWrapper);
});
}
private createRunAsUserOptions(view) {
let userInputBox = view.modelBuilder.inputBox()
.withProperties({ inputType: 'text', width: '100px' }).component();
let viewButton = view.modelBuilder.button()
.withProperties({ label: '...', width: '20px' }).component();
let viewButtonContainer = view.modelBuilder.flexContainer()
.withLayout({ width: 100, textAlign: 'right' })
.withItems([viewButton], { flex: '1 1 50%' }).component();
let userInputBoxContainer = view.modelBuilder.flexContainer()
.withLayout({ width: 200, textAlign: 'left' })
.withItems([userInputBox], { flex: '1 1 50%' }).component();
let runAsUserContainer = view.modelBuilder.flexContainer()
.withLayout({ width: 200 })
.withItems([userInputBoxContainer, viewButtonContainer], { flex: '1 1 50%' })
.component();
let runAsUserForm = view.modelBuilder.formContainer()
.withFormItems([{
component: runAsUserContainer,
title: 'Run as user'
}], { horizontal: true, componentWidth: 200 }).component();
return runAsUserForm;
}
private createAdvancedTab() {
this.advancedTab.registerContent(async (view) => {
this.successActionDropdown = view.modelBuilder.dropDown()
.withProperties({
value: CreateStepDialog.NextStep,
values: [CreateStepDialog.NextStep, CreateStepDialog.QuitJobReportingSuccess, CreateStepDialog.QuitJobReportingFailure]
})
.component();
let retryFlexContainer = this.createRetryCounters(view);
this.failureActionDropdown = view.modelBuilder.dropDown()
.withProperties({
value: CreateStepDialog.QuitJobReportingFailure,
values: [CreateStepDialog.QuitJobReportingFailure, CreateStepDialog.NextStep, CreateStepDialog.QuitJobReportingSuccess]
})
.component();
let optionsGroup = this.createTSQLOptions(view);
let viewButton = view.modelBuilder.button()
.withProperties({ label: 'View', width: '50px' }).component();
viewButton.enabled = false;
this.logToTableCheckbox = view.modelBuilder.checkBox()
.withProperties({
label: 'Log to table'
}).component();
let appendToExistingEntryInTableCheckbox = view.modelBuilder.checkBox()
.withProperties({ label: 'Append output to existing entry in table' }).component();
appendToExistingEntryInTableCheckbox.enabled = false;
this.logToTableCheckbox.onChanged(e => {
viewButton.enabled = e;
appendToExistingEntryInTableCheckbox.enabled = e;
});
let appendCheckboxContainer = view.modelBuilder.groupContainer()
.withItems([appendToExistingEntryInTableCheckbox]).component();
let logToTableContainer = view.modelBuilder.flexContainer()
.withLayout({ flexFlow: 'row', justifyContent: 'space-between', width: 300 })
.withItems([this.logToTableCheckbox, viewButton]).component();
let logStepOutputHistoryCheckbox = view.modelBuilder.checkBox()
.withProperties({ label: 'Include step output in history' }).component();
let runAsUserOptions = this.createRunAsUserOptions(view);
let formModel = view.modelBuilder.formContainer()
.withFormItems(
[{
component: this.successActionDropdown,
title: CreateStepDialog.SuccessAction
}, {
component: retryFlexContainer,
title: ''
}, {
component: this.failureActionDropdown,
title: CreateStepDialog.FailureAction
}, {
component: optionsGroup,
title: 'Transact-SQL script (T-SQL)'
}, {
component: logToTableContainer,
title: ''
}, {
component: appendCheckboxContainer,
title: ' '
}, {
component: logStepOutputHistoryCheckbox,
title: ''
}, {
component: runAsUserOptions,
title: ''
}], {
componentWidth: 400
}).component();
let formWrapper = view.modelBuilder.loadingComponent().withItem(formModel).component();
formWrapper.loading = false;
view.initializeModel(formWrapper);
});
}
private createRetryCounters(view) {
this.retryAttemptsBox = view.modelBuilder.inputBox()
.withValidation(component => component.value >= 0)
.withProperties({
inputType: 'number'
})
.component();
this.retryIntervalBox = view.modelBuilder.inputBox()
.withValidation(component => component.value >= 0)
.withProperties({
inputType: 'number'
}).component();
let retryAttemptsContainer = view.modelBuilder.formContainer()
.withFormItems(
[{
component: this.retryAttemptsBox,
title: 'Retry Attempts'
}], {
horizontal: false
})
.component();
let retryIntervalContainer = view.modelBuilder.formContainer()
.withFormItems(
[{
component: this.retryIntervalBox,
title: 'Retry Interval (minutes)'
}], {
horizontal: false
})
.component();
let retryFlexContainer = view.modelBuilder.flexContainer()
.withLayout({
flexFlow: 'row',
}).withItems([retryAttemptsContainer, retryIntervalContainer]).component();
return retryFlexContainer;
}
private createTSQLOptions(view) {
this.outputFileBrowserButton = view.modelBuilder.button()
.withProperties({ width: '20px', label: '...' }).component();
this.outputFileNameBox = view.modelBuilder.inputBox()
.withProperties({
width: '100px',
inputType: 'text'
}).component();
let outputViewButton = view.modelBuilder.button()
.withProperties({
width: '50px',
label: 'View'
}).component();
outputViewButton.enabled = false;
let outputButtonContainer = view.modelBuilder.flexContainer()
.withLayout({
flexFlow: 'row',
textAlign: 'right',
width: 120
}).withItems([this.outputFileBrowserButton, outputViewButton], { flex: '1 1 50%' }).component();
let outputFlexBox = view.modelBuilder.flexContainer()
.withLayout({
flexFlow: 'row',
width: 350
}).withItems([this.outputFileNameBox, outputButtonContainer], {
flex: '1 1 50%'
}).component();
this.appendToExistingFileCheckbox = view.modelBuilder.checkBox()
.withProperties({
label: 'Append output to existing file'
}).component();
this.appendToExistingFileCheckbox.enabled = false;
this.outputFileNameBox.onTextChanged((input) => {
if (input !== '') {
this.appendToExistingFileCheckbox.enabled = true;
} else {
this.appendToExistingFileCheckbox.enabled = false;
}
});
let outputFileForm = view.modelBuilder.formContainer()
.withFormItems([{
component: outputFlexBox,
title: 'Output file'
}, {
component: this.appendToExistingFileCheckbox,
title: ''
}], { horizontal: true, componentWidth: 200 }).component();
return outputFileForm;
}
private async execute() {
this.model.jobName = this.jobName;
this.model.id = this.stepId;
this.model.server = this.server;
this.model.stepName = this.nameTextBox.value;
this.model.subSystem = this.typeDropdown.value as string;
this.model.databaseName = this.databaseDropdown.value as string;
this.model.script = this.commandTextBox.value;
this.model.successAction = this.successActionDropdown.value as string;
this.model.retryAttempts = +this.retryAttemptsBox.value;
this.model.retryInterval = +this.retryIntervalBox.value;
this.model.failureAction = this.failureActionDropdown.value as string;
this.model.outputFileName = this.outputFileNameBox.value;
await this.model.save();
}
public async openNewStepDialog() {
let databases = await AgentUtils.getDatabases(this.ownerUri);
let queryProvider = await AgentUtils.getQueryProvider();
this.initializeUIComponents();
this.createGeneralTab(databases, queryProvider);
this.createAdvancedTab();
sqlops.window.modelviewdialog.openDialog(this.dialog);
}
}

View File

@@ -0,0 +1,92 @@
/*---------------------------------------------------------------------------------------------
* 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 * as vscode from 'vscode';
import { PickScheduleData } from '../data/pickScheduleData';
export class PickScheduleDialog {
// TODO: localize
// Top level
private readonly DialogTitle: string = 'Job Schedules';
private readonly OkButtonText: string = 'OK';
private readonly CancelButtonText: string = 'Cancel';
private readonly SchedulesTabText: string = 'Schedules';
// UI Components
private dialog: sqlops.window.modelviewdialog.Dialog;
private schedulesTable: sqlops.TableComponent;
private model: PickScheduleData;
private _onSuccess: vscode.EventEmitter<PickScheduleData> = new vscode.EventEmitter<PickScheduleData>();
public readonly onSuccess: vscode.Event<PickScheduleData> = this._onSuccess.event;
constructor(ownerUri: string) {
this.model = new PickScheduleData(ownerUri);
}
public async showDialog() {
await this.model.initialize();
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
this.initializeContent();
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;
sqlops.window.modelviewdialog.openDialog(this.dialog);
}
private initializeContent() {
this.dialog.registerContent(async view => {
this.schedulesTable = view.modelBuilder.table()
.withProperties({
columns: [
'Schedule Name'
],
data: [],
height: 600,
width: 400
}).component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.schedulesTable,
title: 'Schedules'
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
if (this.model.schedules) {
let data: any[][] = [];
for (let i = 0; i < this.model.schedules.length; ++i) {
let schedule = this.model.schedules[i];
data[i] = [ schedule.name ];
}
this.schedulesTable.data = data;
}
});
}
private async execute() {
this.updateModel();
await this.model.save();
this._onSuccess.fire(this.model);
}
private async cancel() {
}
private updateModel() {
let selectedRows = this.schedulesTable.selectedRows;
if (selectedRows && selectedRows.length > 0) {
let selectedRow = selectedRows[0];
this.model.selectedSchedule = this.model.schedules[selectedRow];
}
}
}

View File

@@ -0,0 +1,21 @@
/*---------------------------------------------------------------------------------------------
* 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 vscode = require('vscode');
import { MainController } from './mainController';
export let controller: MainController;
export function activate(context: vscode.ExtensionContext) {
controller = new MainController(context);
controller.activate();
}
// this method is called when your extension is deactivated
export function deactivate(): void {
if (controller) {
controller.deactivate();
}
}

View File

@@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------------------------
* 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 vscode from 'vscode';
import { CreateAlertDialog } from './dialogs/createAlertDialog';
import { CreateJobDialog } from './dialogs/createJobDialog';
import { CreateStepDialog } from './dialogs/createStepDialog';
import { PickScheduleDialog } from './dialogs/pickScheduleDialog';
/**
* The main controller class that initializes the extension
*/
export class MainController {
protected _context: vscode.ExtensionContext;
// PUBLIC METHODS //////////////////////////////////////////////////////
public constructor(context: vscode.ExtensionContext) {
this._context = context;
}
/**
* Activates the extension
*/
public activate(): void {
vscode.commands.registerCommand('agent.openCreateJobDialog', (ownerUri: string) => {
let dialog = new CreateJobDialog(ownerUri);
dialog.showDialog();
});
vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, jobId: string, server: string, stepId: number) => {
let dialog = new CreateStepDialog(ownerUri, jobId, server, stepId);
dialog.openNewStepDialog();
});
vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string) => {
let dialog = new PickScheduleDialog(ownerUri);
dialog.showDialog();
});
vscode.commands.registerCommand('agent.openCreateAlertDialog', (ownerUri: string) => {
let dialog = new CreateAlertDialog(ownerUri);
dialog.showDialog();
});
vscode.commands.registerCommand('agent.openCreateOperatorDialog', (ownerUri: string) => {
});
vscode.commands.registerCommand('agent.openCreateProxyDialog', (ownerUri: string) => {
});
}
/**
* Deactivates the extension
*/
public deactivate(): void {
}
}

View File

@@ -0,0 +1,21 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import 'mocha';
import * as vscode from 'vscode';
import * as sqlops from 'sqlops';
import { CreateJobData } from '../data/createJobData';
import { TestAgentService } from './testAgentService';
const testOwnerUri = 'agent://testuri';
suite('Agent extension', () => {
test('Create Job Data', async () => {
let testAgentService = new TestAgentService();
let data = new CreateJobData(testOwnerUri, testAgentService);
data.save();
});
});

View File

@@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as sqlops from 'sqlops';
export class TestAgentService implements sqlops.AgentServicesProvider {
handle?: number;
readonly providerId: string = 'Test Provider';
// Job management methods
getJobs(ownerUri: string): Thenable<sqlops.AgentJobsResult> {
return undefined;
}
getJobHistory(ownerUri: string, jobId: string): Thenable<sqlops.AgentJobHistoryResult> {
return undefined;
}
jobAction(ownerUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus> {
return undefined;
}
createJob(ownerUri: string, jobInfo: sqlops.AgentJobInfo): Thenable<sqlops.CreateAgentJobResult> {
return undefined;
}
updateJob(ownerUri: string, originalJobName: string, jobInfo: sqlops.AgentJobInfo): Thenable<sqlops.UpdateAgentJobResult> {
return undefined;
}
deleteJob(ownerUri: string, jobInfo: sqlops.AgentJobInfo): Thenable<sqlops.ResultStatus> {
return undefined;
}
getJobDefaults(ownerUri: string): Thenable<sqlops.AgentJobDefaultsResult> {
return undefined;
}
// Job Step management methods
createJobStep(ownerUri: string, jobInfo: sqlops.AgentJobStepInfo): Thenable<sqlops.CreateAgentJobStepResult> {
return undefined;
}
updateJobStep(ownerUri: string, originalJobStepName: string, jobInfo: sqlops.AgentJobStepInfo): Thenable<sqlops.UpdateAgentJobStepResult> {
return undefined;
}
deleteJobStep(ownerUri: string, jobInfo: sqlops.AgentJobStepInfo): Thenable<sqlops.ResultStatus> {
return undefined;
}
// Alert management methods
getAlerts(ownerUri: string): Thenable<sqlops.AgentAlertsResult> {
return undefined;
}
createAlert(ownerUri: string, alertInfo: sqlops.AgentAlertInfo): Thenable<sqlops.CreateAgentAlertResult> {
return undefined;
}
updateAlert(ownerUri: string, originalAlertName: string, alertInfo: sqlops.AgentAlertInfo): Thenable<sqlops.UpdateAgentAlertResult> {
return undefined;
}
deleteAlert(ownerUri: string, alertInfo: sqlops.AgentAlertInfo): Thenable<sqlops.ResultStatus> {
return undefined;
}
// Operator management methods
getOperators(ownerUri: string): Thenable<sqlops.AgentOperatorsResult> {
return undefined;
}
createOperator(ownerUri: string, operatorInfo: sqlops.AgentOperatorInfo): Thenable<sqlops.CreateAgentOperatorResult> {
return undefined;
}
updateOperator(ownerUri: string, originalOperatorName: string, operatorInfo: sqlops.AgentOperatorInfo): Thenable<sqlops.UpdateAgentOperatorResult> {
return undefined;
}
deleteOperator(ownerUri: string, operatorInfo: sqlops.AgentOperatorInfo): Thenable<sqlops.ResultStatus> {
return undefined;
}
// Proxy management methods
getProxies(ownerUri: string): Thenable<sqlops.AgentProxiesResult> {
return undefined;
}
createProxy(ownerUri: string, proxyInfo: sqlops.AgentProxyInfo): Thenable<sqlops.CreateAgentOperatorResult> {
return undefined;
}
updateProxy(ownerUri: string, originalProxyName: string, proxyInfo: sqlops.AgentProxyInfo): Thenable<sqlops.UpdateAgentOperatorResult> {
return undefined;
}
deleteProxy(ownerUri: string, proxyInfo: sqlops.AgentProxyInfo): Thenable<sqlops.ResultStatus> {
return undefined;
}
// Job Schedule management methods
getJobSchedules(ownerUri: string): Thenable<sqlops.AgentJobSchedulesResult> {
return undefined;
}
createJobSchedule(ownerUri: string, scheduleInfo: sqlops.AgentJobScheduleInfo): Thenable<sqlops.CreateAgentJobScheduleResult> {
return undefined;
}
updateJobSchedule(ownerUri: string, originalScheduleName: string, scheduleInfo: sqlops.AgentJobScheduleInfo): Thenable<sqlops.UpdateAgentJobScheduleResult> {
return undefined;
}
deleteJobSchedule(ownerUri: string, scheduleInfo: sqlops.AgentJobScheduleInfo): Thenable<sqlops.ResultStatus> {
return undefined;
}
}

9
extensions/agent/src/typings/ref.d.ts vendored Normal file
View File

@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path='../../../../src/vs/vscode.d.ts'/>
/// <reference path='../../../../src/sql/sqlops.d.ts'/>
/// <reference path='../../../../src/sql/sqlops.proposed.d.ts'/>
/// <reference types='@types/node'/>