diff --git a/extensions/agent/src/data/jobStepData.ts b/extensions/agent/src/data/jobStepData.ts index e11ec015c8..79efe4bd39 100644 --- a/extensions/agent/src/data/jobStepData.ts +++ b/extensions/agent/src/data/jobStepData.ts @@ -6,37 +6,47 @@ import { AgentUtils } from '../agentUtils'; import { IAgentDialogData, AgentDialogMode } from '../interfaces'; +import { JobData } from './jobData'; +import * as nls from 'vscode-nls'; + +const localize = nls.loadMessageBundle(); export class JobStepData implements IAgentDialogData { + + // Error Messages + private readonly CreateStepErrorMessage_JobNameIsEmpty = localize('stepData.jobNameRequired', 'Job name must be provided'); + private readonly CreateStepErrorMessage_StepNameIsEmpty = localize('stepData.stepNameRequired', 'Step name must be provided'); + public dialogMode: AgentDialogMode = AgentDialogMode.CREATE; public ownerUri: string; - public jobId: string; // + public jobId: string; public jobName: string; - public script: string; // + public script: string; public scriptName: string; - public stepName: string; // - public subSystem: string; // + public stepName: string; + public subSystem: string; public id: number; - public failureAction: string; // - public successAction: string; // + public failureAction: string; + public successAction: string; public failStepId: number; public successStepId: number; public command: string; public commandExecutionSuccessCode: number; - public databaseName: string; // + public databaseName: string; public databaseUserName: string; public server: string; - public outputFileName: string; // + public outputFileName: string; public appendToLogFile: boolean; public appendToStepHist: boolean; public writeLogToTable: boolean; public appendLogToTable: boolean; - public retryAttempts: number; // - public retryInterval: number; // + public retryAttempts: number; + public retryInterval: number; public proxyName: string; - constructor(ownerUri:string) { + constructor(ownerUri:string, jobModel?: JobData) { this.ownerUri = ownerUri; + this.jobName = jobModel.name; } public async initialize() { @@ -51,7 +61,7 @@ export class JobStepData implements IAgentDialogData { scriptName: this.scriptName, stepName: this.stepName, subSystem: this.subSystem, - id: 1, + id: this.id, failureAction: this.failureAction, successAction: this.successAction, failStepId: this.failStepId, @@ -70,7 +80,26 @@ export class JobStepData implements IAgentDialogData { retryInterval: this.retryInterval, proxyName: this.proxyName }).then(result => { - console.info(result); + if (result && result.success) { + console.info(result); + } }); } + + public validate(): { valid: boolean, errorMessages: string[] } { + let validationErrors: string[] = []; + + if (!(this.stepName && this.stepName.trim())) { + validationErrors.push(this.CreateStepErrorMessage_StepNameIsEmpty); + } + + if (!(this.jobName && this.jobName.trim())) { + validationErrors.push(this.CreateStepErrorMessage_JobNameIsEmpty); + } + + return { + valid: validationErrors.length === 0, + errorMessages: validationErrors + }; + } } \ No newline at end of file diff --git a/extensions/agent/src/dialogs/agentDialog.ts b/extensions/agent/src/dialogs/agentDialog.ts index fa2c1cea85..63d5d240d2 100644 --- a/extensions/agent/src/dialogs/agentDialog.ts +++ b/extensions/agent/src/dialogs/agentDialog.ts @@ -49,10 +49,8 @@ export abstract class AgentDialog { protected async execute() { this.updateModel(); - let success = await this.model.save(); - if (success) { - this._onSuccess.fire(this.model); - } + await this.model.save(); + this._onSuccess.fire(this.model); } protected async cancel() { diff --git a/extensions/agent/src/dialogs/jobDialog.ts b/extensions/agent/src/dialogs/jobDialog.ts index ab86a4f699..8bd76509ee 100644 --- a/extensions/agent/src/dialogs/jobDialog.ts +++ b/extensions/agent/src/dialogs/jobDialog.ts @@ -10,6 +10,7 @@ import { JobStepDialog } from './jobStepDialog'; import { PickScheduleDialog } from './pickScheduleDialog'; import { AlertDialog } from './alertDialog'; import { AgentDialog } from './agentDialog'; +import { AgentUtils } from '../agentUtils'; const localize = nls.loadMessageBundle(); @@ -234,10 +235,14 @@ export class JobDialog extends AgentDialog { width: 80 }).component(); + let stepDialog = new JobStepDialog(this.model.ownerUri, '' , data.length + 1, this.model); + stepDialog.onSuccess((step) => { + this.model.jobSteps.push(step); + this.stepsTable.data = this.convertStepsToData(this.model.jobSteps); + }); this.newStepButton.onDidClick((e)=>{ if (this.nameTextBox.value && this.nameTextBox.value.length > 0) { - let stepDialog = new JobStepDialog(this.model.ownerUri, this.nameTextBox.value, '' , 1, this.model); - stepDialog.openNewStepDialog(); + stepDialog.openDialog(); } else { this.dialog.message = { text: this.BlankJobNameErrorText }; } @@ -273,9 +278,17 @@ export class JobDialog extends AgentDialog { }); this.deleteStepButton.onDidClick((e) => { - // implement delete steps - - + AgentUtils.getAgentService().then((agentService) => { + let steps = this.model.jobSteps ? this.model.jobSteps : []; + agentService.deleteJobStep(this.ownerUri, stepData).then((result) => { + if (result && result.success) { + delete steps[rowNumber]; + this.model.jobSteps = steps; + let data = this.convertStepsToData(steps); + this.stepsTable.data = data; + } + }); + }); }); } }); @@ -529,7 +542,6 @@ export class JobDialog extends AgentDialog { let result = []; alerts.forEach(alert => { let cols = []; - console.log(alert); cols.push(alert.name); cols.push(alert.isEnabled); cols.push(alert.alertType.toString()); diff --git a/extensions/agent/src/dialogs/jobStepDialog.ts b/extensions/agent/src/dialogs/jobStepDialog.ts index a7be6423ab..737851d448 100644 --- a/extensions/agent/src/dialogs/jobStepDialog.ts +++ b/extensions/agent/src/dialogs/jobStepDialog.ts @@ -9,11 +9,12 @@ import * as vscode from 'vscode'; import { JobStepData } from '../data/jobStepData'; import { AgentUtils } from '../agentUtils'; import { JobData } from '../data/jobData'; +import { AgentDialog } from './agentDialog'; const path = require('path'); const localize = nls.loadMessageBundle(); -export class JobStepDialog { +export class JobStepDialog extends AgentDialog { // TODO: localize // Top level @@ -67,7 +68,6 @@ export class JobStepDialog { // UI Components // Dialogs - private dialog: sqlops.window.modelviewdialog.Dialog; private fileBrowserDialog: sqlops.window.modelviewdialog.Dialog; // Dialog tabs @@ -105,35 +105,27 @@ export class JobStepDialog { private fileBrowserTree: sqlops.FileBrowserTreeComponent; private jobModel: JobData; - private model: JobStepData; - private ownerUri: string; private jobName: string; private server: string; private stepId: number; constructor( ownerUri: string, - jobName: string, server: string, stepId: number, jobModel?: JobData ) { - this.model = new JobStepData(ownerUri); + super(ownerUri, new JobStepData(ownerUri, jobModel), 'New Step'); this.stepId = stepId; - this.ownerUri = ownerUri; - this.jobName = jobName; + this.jobName = jobModel.name; this.server = server; this.jobModel = jobModel; } private initializeUIComponents() { - this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle); this.generalTab = sqlops.window.modelviewdialog.createTab(this.GeneralTabText); this.advancedTab = sqlops.window.modelviewdialog.createTab(this.AdvancedTabText); this.dialog.content = [this.generalTab, this.advancedTab]; - this.dialog.okButton.onClick(async () => await this.execute()); - this.dialog.okButton.label = this.OkButtonText; - this.dialog.cancelButton.label = this.CancelButtonText; } private createCommands(view, queryProvider: sqlops.QueryProvider) { @@ -478,7 +470,7 @@ export class JobStepDialog { return outputFileForm; } - protected execute() { + protected updateModel() { this.model.stepName = this.nameTextBox.value; if (!this.model.stepName || this.model.stepName.length === 0) { this.dialog.message = this.dialog.message = { text: this.BlankStepNameErrorText }; @@ -499,12 +491,20 @@ export class JobStepDialog { this.model.appendToLogFile = this.appendToExistingFileCheckbox.checked; } - public async openNewStepDialog() { + public async initializeDialog() { 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); + 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; + }); } } \ No newline at end of file diff --git a/extensions/agent/src/dialogs/pickScheduleDialog.ts b/extensions/agent/src/dialogs/pickScheduleDialog.ts index 76e17e94a3..5fcd1ac1d1 100644 --- a/extensions/agent/src/dialogs/pickScheduleDialog.ts +++ b/extensions/agent/src/dialogs/pickScheduleDialog.ts @@ -74,7 +74,6 @@ export class PickScheduleDialog { let data: any[][] = []; for (let i = 0; i < this.model.schedules.length; ++i) { let schedule = this.model.schedules[i]; - console.log(schedule); data[i] = [ schedule.id, schedule.name, schedule.description ]; } this.schedulesTable.data = data; diff --git a/extensions/agent/src/interfaces.ts b/extensions/agent/src/interfaces.ts index 1ea6f4dc05..0e86394477 100644 --- a/extensions/agent/src/interfaces.ts +++ b/extensions/agent/src/interfaces.ts @@ -13,5 +13,5 @@ export enum AgentDialogMode { export interface IAgentDialogData { dialogMode: AgentDialogMode; initialize(): void; - save(): void; + save(): Promise; } diff --git a/extensions/agent/src/mainController.ts b/extensions/agent/src/mainController.ts index e0d1eedb6a..2797e4512c 100644 --- a/extensions/agent/src/mainController.ts +++ b/extensions/agent/src/mainController.ts @@ -40,9 +40,9 @@ export class MainController { let dialog = new JobDialog(ownerUri, jobInfo); dialog.openDialog(); }); - vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, jobId: string, server: string, stepId: number) => { - let dialog = new JobStepDialog(ownerUri, jobId, server, stepId); - dialog.openNewStepDialog(); + vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, stepId: number) => { + let dialog = new JobStepDialog(ownerUri, server, stepId); + dialog.openDialog(); }); vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string) => { let dialog = new PickScheduleDialog(ownerUri); @@ -57,9 +57,8 @@ export class MainController { dialog.openDialog(); }); vscode.commands.registerCommand('agent.openProxyDialog', (ownerUri: string, proxyInfo: sqlops.AgentProxyInfo, credentials: sqlops.CredentialInfo[]) => { - //@TODO: reenable create proxy after snapping July release (7/14/18) - // let dialog = new ProxyDialog(ownerUri, proxyInfo, credentials); - // dialog.openDialog(); + let dialog = new ProxyDialog(ownerUri, proxyInfo, credentials); + dialog.openDialog(); MainController.showNotYetImplemented(); }); } diff --git a/src/sql/parts/jobManagement/common/interfaces.ts b/src/sql/parts/jobManagement/common/interfaces.ts index f347da987e..2074d9454a 100644 --- a/src/sql/parts/jobManagement/common/interfaces.ts +++ b/src/sql/parts/jobManagement/common/interfaces.ts @@ -25,6 +25,8 @@ export interface IJobManagementService { getJobHistory(connectionUri: string, jobID: string): Thenable; deleteJob(connectionUri: string, job: sqlops.AgentJobInfo): Thenable; + deleteJobStep(connectionUri: string, step: sqlops.AgentJobStepInfo): Thenable; + getAlerts(connectionUri: string): Thenable; deleteAlert(connectionUri: string, alert: sqlops.AgentAlertInfo): Thenable; diff --git a/src/sql/parts/jobManagement/common/jobActions.ts b/src/sql/parts/jobManagement/common/jobActions.ts index fbd8b21317..ef48595e69 100644 --- a/src/sql/parts/jobManagement/common/jobActions.ts +++ b/src/sql/parts/jobManagement/common/jobActions.ts @@ -26,6 +26,7 @@ export enum JobActions { export interface IJobActionInfo { ownerUri: string; targetObject: any; + jobHistoryComponent?: JobHistoryComponent; } // Job actions @@ -230,6 +231,48 @@ export class NewStepAction extends Action { } } +export class DeleteStepAction extends Action { + public static ID = 'jobaction.deleteStep'; + public static LABEL = nls.localize('jobaction.deleteStep', "Delete Step"); + + constructor( + @INotificationService private _notificationService: INotificationService, + @IJobManagementService private _jobService: IJobManagementService, + @IInstantiationService private instantationService: IInstantiationService + ) { + super(DeleteStepAction.ID, DeleteStepAction.LABEL); + } + + public run(actionInfo: IJobActionInfo): TPromise { + let self = this; + let step = actionInfo.targetObject as sqlops.AgentJobStepInfo; + let refreshAction = this.instantationService.createInstance(JobsRefreshAction); + self._notificationService.prompt( + Severity.Info, + nls.localize('jobaction.deleteStepConfirm,', "Are you sure you'd like to delete the step '{0}'?", step.stepName), + [{ + label: DeleteStepAction.LABEL, + run: () => { + self._jobService.deleteJobStep(actionInfo.ownerUri, actionInfo.targetObject).then(result => { + if (!result || !result.success) { + let errorMessage = nls.localize("jobaction.failedToDeleteStep", "Could not delete step '{0}'.\nError: {1}", + step.stepName, result.errorMessage ? result.errorMessage : 'Unknown error'); + self._notificationService.error(errorMessage); + } else { + refreshAction.run(actionInfo.jobHistoryComponent); + } + }); + } + }, { + label: DeleteAlertAction.CancelLabel, + run: () => { } + }] + ); + return TPromise.as(true); + } +} + + // Alert Actions export class NewAlertAction extends Action { diff --git a/src/sql/parts/jobManagement/common/jobManagementService.ts b/src/sql/parts/jobManagement/common/jobManagementService.ts index 401c487a5f..eaa4ceea2e 100644 --- a/src/sql/parts/jobManagement/common/jobManagementService.ts +++ b/src/sql/parts/jobManagement/common/jobManagementService.ts @@ -30,6 +30,7 @@ export class JobManagementService implements IJobManagementService { this._onDidChange.fire(void 0); } + // Jobs public getJobs(connectionUri: string): Thenable { return this._runAction(connectionUri, (runner) => { return runner.getJobs(connectionUri); @@ -42,6 +43,27 @@ export class JobManagementService implements IJobManagementService { }); } + public getJobHistory(connectionUri: string, jobID: string): Thenable { + return this._runAction(connectionUri, (runner) => { + return runner.getJobHistory(connectionUri, jobID); + }); + } + + public jobAction(connectionUri: string, jobName: string, action: string): Thenable { + return this._runAction(connectionUri, (runner) => { + return runner.jobAction(connectionUri, jobName, action); + }); + } + + // Steps + public deleteJobStep(connectionUri: string, stepInfo: sqlops.AgentJobStepInfo): Thenable { + return this._runAction(connectionUri, (runner) => { + return runner.deleteJobStep(connectionUri, stepInfo); + }); + } + + + // Alerts public getAlerts(connectionUri: string): Thenable { return this._runAction(connectionUri, (runner) => { return runner.getAlerts(connectionUri); @@ -54,6 +76,7 @@ export class JobManagementService implements IJobManagementService { }); } + // Operators public getOperators(connectionUri: string): Thenable { return this._runAction(connectionUri, (runner) => { return runner.getOperators(connectionUri); @@ -66,6 +89,7 @@ export class JobManagementService implements IJobManagementService { }); } + // Proxies public getProxies(connectionUri: string): Thenable { return this._runAction(connectionUri, (runner) => { return runner.getProxies(connectionUri); @@ -84,18 +108,6 @@ export class JobManagementService implements IJobManagementService { }); } - public getJobHistory(connectionUri: string, jobID: string): Thenable { - return this._runAction(connectionUri, (runner) => { - return runner.getJobHistory(connectionUri, jobID); - }); - } - - public jobAction(connectionUri: string, jobName: string, action: string): Thenable { - return this._runAction(connectionUri, (runner) => { - return runner.jobAction(connectionUri, jobName, action); - }); - } - private _runAction(uri: string, action: (handler: sqlops.AgentServicesProvider) => Thenable): Thenable { let providerId: string = this._connectionService.getProviderIdFromUri(uri); diff --git a/src/sql/parts/jobManagement/views/jobHistory.component.ts b/src/sql/parts/jobManagement/views/jobHistory.component.ts index fc5971f574..7fe8d1e5ab 100644 --- a/src/sql/parts/jobManagement/views/jobHistory.component.ts +++ b/src/sql/parts/jobManagement/views/jobHistory.component.ts @@ -74,7 +74,6 @@ export class JobHistoryComponent extends JobManagementView implements OnInit { @Inject(forwardRef(() => CommonServiceInterface)) commonService: CommonServiceInterface, @Inject(forwardRef(() => AgentViewComponent)) private _agentViewComponent: AgentViewComponent, @Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService, - @Inject(INotificationService) private _notificationService: INotificationService, @Inject(IInstantiationService) private instantiationService: IInstantiationService, @Inject(IContextMenuService) private contextMenuService: IContextMenuService, @Inject(IJobManagementService) private _jobManagementService: IJobManagementService, diff --git a/src/sql/parts/jobManagement/views/jobStepsView.component.ts b/src/sql/parts/jobManagement/views/jobStepsView.component.ts index 495e62abe8..7a92babbc0 100644 --- a/src/sql/parts/jobManagement/views/jobStepsView.component.ts +++ b/src/sql/parts/jobManagement/views/jobStepsView.component.ts @@ -20,7 +20,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TabChild } from 'sql/base/browser/ui/panel/tab.component'; -import * as dom from 'vs/base/browser/dom'; +import { IJobManagementService } from 'sql/parts/jobManagement/common/interfaces'; export const JOBSTEPSVIEW_SELECTOR: string = 'jobstepsview-component'; @@ -36,7 +36,7 @@ export class JobStepsViewComponent extends JobManagementView implements OnInit, private _treeDataSource = new JobStepsViewDataSource(); private _treeRenderer = new JobStepsViewRenderer(); private _treeFilter = new JobStepsViewFilter(); - private static _pageSize = 1024; + private _pageSize = 1024; @ViewChild('table') private _tableContainer: ElementRef; @@ -66,7 +66,7 @@ export class JobStepsViewComponent extends JobManagementView implements OnInit, }, { verticalScrollMode: ScrollbarVisibility.Visible }); this._register(attachListStyler(this._tree, this.themeService)); } - this._tree.layout(500); + this._tree.layout(this._pageSize); this._tree.setInput(new JobStepsViewModel()); $('jobstepsview-component .steps-tree .monaco-tree').attr('tabIndex', '-1'); $('jobstepsview-component .steps-tree .monaco-tree-row').attr('tabIndex', '0'); diff --git a/src/sql/parts/jobManagement/views/jobStepsViewTree.ts b/src/sql/parts/jobManagement/views/jobStepsViewTree.ts index 49c021f4cd..ac03318b61 100644 --- a/src/sql/parts/jobManagement/views/jobStepsViewTree.ts +++ b/src/sql/parts/jobManagement/views/jobStepsViewTree.ts @@ -10,7 +10,6 @@ import * as TreeDefaults from 'vs/base/parts/tree/browser/treeDefaults'; import { Promise, TPromise } from 'vs/base/common/winjs.base'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { generateUuid } from 'vs/base/common/uuid'; -import { AgentJobHistoryInfo } from 'sqlops'; import { JobManagementUtilities } from 'sql/parts/jobManagement/common/jobManagementUtilities'; export class JobStepsViewRow { @@ -27,7 +26,6 @@ export class JobStepsViewModel { } export class JobStepsViewController extends TreeDefaults.DefaultController { - private _jobHistories: AgentJobHistoryInfo[]; protected onLeftClick(tree: tree.ITree, element: JobStepsViewRow, event: IMouseEvent, origin: string = 'mouse'): boolean { return true; @@ -37,14 +35,6 @@ export class JobStepsViewController extends TreeDefaults.DefaultController { return true; } - public set jobHistories(value: AgentJobHistoryInfo[]) { - this._jobHistories = value; - } - - public get jobHistories(): AgentJobHistoryInfo[] { - return this._jobHistories; - } - } export class JobStepsViewDataSource implements tree.IDataSource { diff --git a/src/sql/parts/jobManagement/views/jobsView.component.ts b/src/sql/parts/jobManagement/views/jobsView.component.ts index 6625051cad..a6646460ca 100644 --- a/src/sql/parts/jobManagement/views/jobsView.component.ts +++ b/src/sql/parts/jobManagement/views/jobsView.component.ts @@ -584,7 +584,12 @@ export class JobsViewComponent extends JobManagementView implements OnInit { self.jobHistories[job.jobId] = result.jobs; self._jobCacheObject.setJobHistory(job.jobId, result.jobs); let jobHistories = self._jobCacheObject.getJobHistory(job.jobId); - let previousRuns = jobHistories.slice(jobHistories.length - 5, jobHistories.length); + let previousRuns: sqlops.AgentJobHistoryInfo[]; + if (jobHistories.length >= 5) { + previousRuns = jobHistories.slice(jobHistories.length - 5, jobHistories.length); + } else { + previousRuns = jobHistories; + } self.createJobChart(job.jobId, previousRuns); if (self._agentViewComponent.expanded.has(job.jobId)) { let lastJobHistory = jobHistories[result.jobs.length - 1]; @@ -645,12 +650,22 @@ export class JobsViewComponent extends JobManagementView implements OnInit { maxDuration = maxDuration === 0 ? 1 : maxDuration; let maxBarHeight: number = 24; let chartHeights = []; + let zeroDurationJobCount = 0; for (let i = 0; i < jobHistories.length; i++) { let duration = jobHistories[i].runDuration; let chartHeight = (maxBarHeight * JobManagementUtilities.convertDurationToSeconds(duration)) / maxDuration; chartHeights.push(`${chartHeight}px`); + if (chartHeight === 0) { + zeroDurationJobCount++; + } + } + // if the durations are all 0 secs, show minimal chart + // instead of nothing + if (zeroDurationJobCount === jobHistories.length) { + return ['5px', '5px', '5px', '5px', '5px']; + } else { + return chartHeights; } - return chartHeights; } private expandJobs(start: boolean): void { diff --git a/src/sql/sqlops.d.ts b/src/sql/sqlops.d.ts index 401cc534e4..a34e97b8dc 100644 --- a/src/sql/sqlops.d.ts +++ b/src/sql/sqlops.d.ts @@ -1537,9 +1537,9 @@ declare module 'sqlops' { getJobDefaults(ownerUri: string): Thenable; // Job Step management methods - createJobStep(ownerUri: string, jobInfo: AgentJobStepInfo): Thenable; - updateJobStep(ownerUri: string, originalJobStepName: string, jobInfo: AgentJobStepInfo): Thenable; - deleteJobStep(ownerUri: string, jobInfo: AgentJobStepInfo): Thenable; + createJobStep(ownerUri: string, stepInfo: AgentJobStepInfo): Thenable; + updateJobStep(ownerUri: string, originalJobStepName: string, stepInfo: AgentJobStepInfo): Thenable; + deleteJobStep(ownerUri: string, stepInfo: AgentJobStepInfo): Thenable; // Alert management methods getAlerts(ownerUri: string): Thenable; diff --git a/src/sql/workbench/api/node/extHostDataProtocol.ts b/src/sql/workbench/api/node/extHostDataProtocol.ts index 95bd9d950a..0d430c383e 100644 --- a/src/sql/workbench/api/node/extHostDataProtocol.ts +++ b/src/sql/workbench/api/node/extHostDataProtocol.ts @@ -596,6 +596,13 @@ export class ExtHostDataProtocol extends ExtHostDataProtocolShape { throw this._resolveProvider(handle).deleteJob(ownerUri, job); } + /** + * Deletes a job step + */ + $deleteJobStep(handle: number, ownerUri: string, step: sqlops.AgentJobStepInfo): Thenable { + throw this._resolveProvider(handle).deleteJobStep(ownerUri, step); + } + /** * Get Agent Alerts list */ diff --git a/src/sql/workbench/api/node/mainThreadDataProtocol.ts b/src/sql/workbench/api/node/mainThreadDataProtocol.ts index ba8fa88f2e..bed01823a2 100644 --- a/src/sql/workbench/api/node/mainThreadDataProtocol.ts +++ b/src/sql/workbench/api/node/mainThreadDataProtocol.ts @@ -359,6 +359,9 @@ export class MainThreadDataProtocol implements MainThreadDataProtocolShape { deleteJob(connectionUri: string, jobInfo: sqlops.AgentJobInfo): Thenable { return self._proxy.$deleteJob(handle, connectionUri, jobInfo); }, + deleteJobStep(connectionUri: string, stepInfo: sqlops.AgentJobStepInfo): Thenable { + return self._proxy.$deleteJobStep(handle, connectionUri, stepInfo); + }, getAlerts(connectionUri: string): Thenable { return self._proxy.$getAlerts(handle, connectionUri); }, diff --git a/src/sql/workbench/api/node/sqlExtHost.protocol.ts b/src/sql/workbench/api/node/sqlExtHost.protocol.ts index 77ce5b268c..7b7d94bda3 100644 --- a/src/sql/workbench/api/node/sqlExtHost.protocol.ts +++ b/src/sql/workbench/api/node/sqlExtHost.protocol.ts @@ -370,6 +370,11 @@ export abstract class ExtHostDataProtocolShape { */ $deleteJob(handle: number, ownerUri: string, job: sqlops.AgentJobInfo): Thenable { throw ni(); } + /** + * Deletes a job step + */ + $deleteJobStep(handle: number, ownerUri: string, step: sqlops.AgentJobStepInfo): Thenable { throw ni(); } + /** * Get Agent Alerts list */