Agent: Edit Job improvements (#2721)

* fixed right click context menu bug in jobs view

* added stepInfo and edit job WIP

* show jobs in job edit

* added schedule description on select schedule

* fetch schedules during history and show in edit job

* added alerts to job histories and show in edit

* made history calls async

* filter menus now close when esc is pressed

* fixed bug where clicking on error row wouldnt populate job details
This commit is contained in:
Aditya Bist
2018-10-04 13:52:25 -07:00
committed by GitHub
parent 0693080630
commit b097b54792
10 changed files with 217 additions and 43 deletions

View File

@@ -59,6 +59,9 @@ export class JobData implements IAgentDialogData {
this.category = jobInfo.category; this.category = jobInfo.category;
this.description = jobInfo.description; this.description = jobInfo.description;
this.enabled = jobInfo.enabled; this.enabled = jobInfo.enabled;
this.jobSteps = jobInfo.JobSteps;
this.jobSchedules = jobInfo.JobSchedules;
this.alerts = jobInfo.Alerts;
} }
} }
@@ -105,8 +108,6 @@ export class JobData implements IAgentDialogData {
displayName: this.JobCompletionActionCondition_Always, displayName: this.JobCompletionActionCondition_Always,
name: sqlops.JobCompletionActionCondition.Always.toString() name: sqlops.JobCompletionActionCondition.Always.toString()
}]; }];
this.jobSchedules = [];
} }
public async save() { public async save() {

View File

@@ -62,6 +62,8 @@ export class JobDialog extends AgentDialog<JobData> {
private readonly AlertsTopLabelString: string = localize('jobDialog.alertsList', 'Alerts list'); private readonly AlertsTopLabelString: string = localize('jobDialog.alertsList', 'Alerts list');
private readonly NewAlertButtonString: string = localize('jobDialog.newAlert', 'New Alert'); private readonly NewAlertButtonString: string = localize('jobDialog.newAlert', 'New Alert');
private readonly AlertNameLabelString: string = localize('jobDialog.alertNameLabel', 'Alert Name'); private readonly AlertNameLabelString: string = localize('jobDialog.alertNameLabel', 'Alert Name');
private readonly AlertEnabledLabelString: string = localize('jobDialog.alertEnabledLabel', 'Enabled');
private readonly AlertTypeLabelString: string = localize('jobDialog.alertTypeLabel', 'Type');
// UI Components // UI Components
private generalTab: sqlops.window.modelviewdialog.DialogTab; private generalTab: sqlops.window.modelviewdialog.DialogTab;
@@ -197,6 +199,8 @@ export class JobDialog extends AgentDialog<JobData> {
.withProperties({ .withProperties({
value: 'Feature Preview' value: 'Feature Preview'
}).component(); }).component();
let steps = this.model.jobSteps ? this.model.jobSteps : [];
let data = this.convertStepsToData(steps);
this.stepsTable = view.modelBuilder.table() this.stepsTable = view.modelBuilder.table()
.withProperties({ .withProperties({
columns: [ columns: [
@@ -206,8 +210,8 @@ export class JobDialog extends AgentDialog<JobData> {
this.StepsTable_SuccessColumnString, this.StepsTable_SuccessColumnString,
this.StepsTable_FailureColumnString this.StepsTable_FailureColumnString
], ],
data: [], data: data,
height: 430 height: 750
}).component(); }).component();
this.moveStepUpButton = view.modelBuilder.button() this.moveStepUpButton = view.modelBuilder.button()
@@ -250,6 +254,31 @@ export class JobDialog extends AgentDialog<JobData> {
}).component(); }).component();
this.stepsTable.enabled = false; this.stepsTable.enabled = false;
this.editStepButton.enabled = false;
this.deleteStepButton.enabled = false;
this.stepsTable.onRowSelected(() => {
// only let edit or delete steps if there's
// one step selection
if (this.stepsTable.selectedRows.length === 1) {
let rowNumber = this.stepsTable.selectedRows[0];
let stepData = steps[rowNumber];
this.deleteStepButton.enabled = true;
this.editStepButton.enabled = true;
this.editStepButton.onDidClick((e) => {
// implement edit steps
// let stepDialog = new JobStepDialog(this.model.ownerUri, this.nameTextBox.value, '' , 1, this.model);
// stepDialog.openNewStepDialog();
});
this.deleteStepButton.onDidClick((e) => {
// implement delete steps
});
}
});
let formModel = view.modelBuilder.formContainer() let formModel = view.modelBuilder.formContainer()
.withFormItems([{ .withFormItems([{
@@ -271,12 +300,16 @@ export class JobDialog extends AgentDialog<JobData> {
.withProperties({ .withProperties({
value: 'Feature Preview' value: 'Feature Preview'
}).component(); }).component();
let alerts = this.model.alerts ? this.model.alerts : [];
let data = this.convertAlertsToData(alerts);
this.alertsTable = view.modelBuilder.table() this.alertsTable = view.modelBuilder.table()
.withProperties({ .withProperties({
columns: [ columns: [
this.AlertNameLabelString this.AlertNameLabelString,
this.AlertEnabledLabelString,
this.AlertTypeLabelString
], ],
data: [], data: data,
height: 430, height: 430,
width: 400 width: 400
}).component(); }).component();
@@ -312,10 +345,12 @@ export class JobDialog extends AgentDialog<JobData> {
this.schedulesTable = view.modelBuilder.table() this.schedulesTable = view.modelBuilder.table()
.withProperties({ .withProperties({
columns: [ columns: [
this.ScheduleNameLabelString PickScheduleDialog.SchedulesIDText,
PickScheduleDialog.ScheduleNameLabelText,
PickScheduleDialog.ScheduleDescription
], ],
data: [], data: [],
height: 430, height: 750,
width: 420 width: 420
}).component(); }).component();
@@ -350,13 +385,11 @@ export class JobDialog extends AgentDialog<JobData> {
} }
private populateScheduleTable() { private populateScheduleTable() {
if (this.model.jobSchedules) { let schedules = this.model.jobSchedules ? this.model.jobSchedules : [];
let data: any[][] = []; let data = this.convertSchedulesToData(schedules);
for (let i = 0; i < this.model.jobSchedules.length; ++i) { if (data.length > 0) {
let schedule = this.model.jobSchedules[i];
data[i] = [ schedule.name ];
}
this.schedulesTable.data = data; this.schedulesTable.data = data;
this.schedulesTable.height = 750;
} }
} }
@@ -466,6 +499,45 @@ export class JobDialog extends AgentDialog<JobData> {
}); });
} }
private convertStepsToData(jobSteps: sqlops.AgentJobStepInfo[]): any[][] {
let result = [];
jobSteps.forEach(jobStep => {
let cols = [];
cols.push(jobStep.id);
cols.push(jobStep.stepName);
cols.push(jobStep.subSystem);
cols.push(jobStep.successAction);
cols.push(jobStep.failureAction);
result.push(cols);
});
return result;
}
private convertSchedulesToData(jobSchedules: sqlops.AgentJobScheduleInfo[]): any[][] {
let result = [];
jobSchedules.forEach(schedule => {
let cols = [];
cols.push(schedule.id);
cols.push(schedule.name);
cols.push(schedule.description);
result.push(cols);
});
return result;
}
private convertAlertsToData(alerts: sqlops.AgentAlertInfo[]): any[][] {
let result = [];
alerts.forEach(alert => {
let cols = [];
console.log(alert);
cols.push(alert.name);
cols.push(alert.isEnabled);
cols.push(alert.alertType.toString());
result.push(cols);
});
return result;
}
protected updateModel() { protected updateModel() {
this.model.name = this.nameTextBox.value; this.model.name = this.nameTextBox.value;
this.model.owner = this.ownerTextBox.value; this.model.owner = this.ownerTextBox.value;

View File

@@ -18,8 +18,11 @@ export class PickScheduleDialog {
private readonly DialogTitle: string = localize('pickSchedule.jobSchedules', 'Job Schedules'); private readonly DialogTitle: string = localize('pickSchedule.jobSchedules', 'Job Schedules');
private readonly OkButtonText: string = localize('pickSchedule.ok', 'OK'); private readonly OkButtonText: string = localize('pickSchedule.ok', 'OK');
private readonly CancelButtonText: string = localize('pickSchedule.cancel', 'Cancel'); private readonly CancelButtonText: string = localize('pickSchedule.cancel', 'Cancel');
private readonly ScheduleNameLabelText: string = localize('pickSchedule.scheduleName', 'Schedule Name'); private readonly SchedulesLabelText: string = localize('pickSchedule.availableSchedules', 'Available Schedules:');
private readonly SchedulesLabelText: string = localize('pickSchedule.schedules', 'Schedules'); public static readonly ScheduleNameLabelText: string = localize('pickSchedule.scheduleName', 'Name');
public static readonly SchedulesIDText: string = localize('pickSchedule.scheduleID','ID');
public static readonly ScheduleDescription: string = localize('pickSchedule.description','Description');
// UI Components // UI Components
private dialog: sqlops.window.modelviewdialog.Dialog; private dialog: sqlops.window.modelviewdialog.Dialog;
@@ -50,11 +53,13 @@ export class PickScheduleDialog {
this.schedulesTable = view.modelBuilder.table() this.schedulesTable = view.modelBuilder.table()
.withProperties({ .withProperties({
columns: [ columns: [
this.ScheduleNameLabelText PickScheduleDialog.SchedulesIDText,
PickScheduleDialog.ScheduleNameLabelText,
PickScheduleDialog.ScheduleDescription
], ],
data: [], data: [],
height: '80em', height: 750,
width: '40em' width: 430
}).component(); }).component();
let formModel = view.modelBuilder.formContainer() let formModel = view.modelBuilder.formContainer()
@@ -69,7 +74,8 @@ export class PickScheduleDialog {
let data: any[][] = []; let data: any[][] = [];
for (let i = 0; i < this.model.schedules.length; ++i) { for (let i = 0; i < this.model.schedules.length; ++i) {
let schedule = this.model.schedules[i]; let schedule = this.model.schedules[i];
data[i] = [ schedule.name ]; console.log(schedule);
data[i] = [ schedule.id, schedule.name, schedule.description ];
} }
this.schedulesTable.data = data; this.schedulesTable.data = data;
} }

View File

@@ -39,16 +39,26 @@ export class HeaderFilter {
this.handler.subscribe(this.grid.onHeaderCellRendered, (e, args) => this.handleHeaderCellRendered(e , args)) this.handler.subscribe(this.grid.onHeaderCellRendered, (e, args) => this.handleHeaderCellRendered(e , args))
.subscribe(this.grid.onBeforeHeaderCellDestroy, (e, args) => this.handleBeforeHeaderCellDestroy(e, args)) .subscribe(this.grid.onBeforeHeaderCellDestroy, (e, args) => this.handleBeforeHeaderCellDestroy(e, args))
.subscribe(this.grid.onClick, (e) => this.handleBodyMouseDown) .subscribe(this.grid.onClick, (e) => this.handleBodyMouseDown)
.subscribe(this.grid.onColumnsResized, () => this.columnsResized()); .subscribe(this.grid.onColumnsResized, () => this.columnsResized())
.subscribe(this.grid.onKeyDown, (e) => this.handleKeyDown);
this.grid.setColumns(this.grid.getColumns()); this.grid.setColumns(this.grid.getColumns());
$(document.body).bind('mousedown', this.handleBodyMouseDown); $(document.body).bind('mousedown', this.handleBodyMouseDown);
$(document.body).bind('keydown', this.handleKeyDown);
} }
public destroy() { public destroy() {
this.handler.unsubscribeAll(); this.handler.unsubscribeAll();
$(document.body).unbind('mousedown', this.handleBodyMouseDown); $(document.body).unbind('mousedown', this.handleBodyMouseDown);
$(document.body).unbind('keydown', this.handleKeyDown);
}
private handleKeyDown = (e) => {
if (this.$menu && (e.key === 'Escape' || e.keyCode === 27)) {
this.hideMenu();
e.preventDefault();
e.stopPropagation();
}
} }
private handleBodyMouseDown = (e) => { private handleBodyMouseDown = (e) => {

View File

@@ -17,7 +17,9 @@ export class JobManagementUtilities {
switch(status) { switch(status) {
case(0): return nls.localize('agentUtilities.failed','Failed'); case(0): return nls.localize('agentUtilities.failed','Failed');
case(1): return nls.localize('agentUtilities.succeeded', 'Succeeded'); case(1): return nls.localize('agentUtilities.succeeded', 'Succeeded');
case(3): return nls.localize('agentUtilities.canceled', 'Canceled'); case(2): return nls.localize('agentUtilities.retry', 'Retry');
case(3): return nls.localize('agentUtilities.canceled', 'Cancelled');
case(4): return nls.localize('agentUtilities.inProgress', 'In Progress');
case(5): return nls.localize('agentUtilities.statusUnknown', 'Status Unknown'); case(5): return nls.localize('agentUtilities.statusUnknown', 'Status Unknown');
default: return nls.localize('agentUtilities.statusUnknown', 'Status Unknown'); default: return nls.localize('agentUtilities.statusUnknown', 'Status Unknown');
} }

View File

@@ -185,8 +185,8 @@ export class JobHistoryComponent extends JobManagementView implements OnInit {
stepViewRow.runStatus = jobStepStatus ? JobManagementUtilities.convertToStatusString(0) : stepViewRow.runStatus = jobStepStatus ? JobManagementUtilities.convertToStatusString(0) :
JobManagementUtilities.convertToStatusString(step.runStatus); JobManagementUtilities.convertToStatusString(step.runStatus);
self._runStatus = JobManagementUtilities.convertToStatusString(self.agentJobHistoryInfo.runStatus); self._runStatus = JobManagementUtilities.convertToStatusString(self.agentJobHistoryInfo.runStatus);
stepViewRow.stepName = step.stepName; stepViewRow.stepName = step.stepDetails.stepName;
stepViewRow.stepID = step.stepId.toString(); stepViewRow.stepId = step.stepDetails.id.toString();
return stepViewRow; return stepViewRow;
}); });
this._showSteps = self._stepRows.length > 0; this._showSteps = self._stepRows.length > 0;

View File

@@ -66,7 +66,7 @@ export class JobStepsViewComponent extends JobManagementView implements OnInit,
}, { verticalScrollMode: ScrollbarVisibility.Visible }); }, { verticalScrollMode: ScrollbarVisibility.Visible });
this._register(attachListStyler(this._tree, this.themeService)); this._register(attachListStyler(this._tree, this.themeService));
} }
this._tree.layout(JobStepsViewComponent._pageSize); this._tree.layout(500);
this._tree.setInput(new JobStepsViewModel()); this._tree.setInput(new JobStepsViewModel());
$('jobstepsview-component .steps-tree .monaco-tree').attr('tabIndex', '-1'); $('jobstepsview-component .steps-tree .monaco-tree').attr('tabIndex', '-1');
$('jobstepsview-component .steps-tree .monaco-tree-row').attr('tabIndex', '0'); $('jobstepsview-component .steps-tree .monaco-tree-row').attr('tabIndex', '0');
@@ -74,8 +74,6 @@ export class JobStepsViewComponent extends JobManagementView implements OnInit,
} }
ngOnInit() { ngOnInit() {
let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri;
this._tree = new Tree(this._tableContainer.nativeElement, { this._tree = new Tree(this._tableContainer.nativeElement, {
controller: this._treeController, controller: this._treeController,
dataSource: this._treeDataSource, dataSource: this._treeDataSource,

View File

@@ -14,7 +14,7 @@ import { AgentJobHistoryInfo } from 'sqlops';
import { JobManagementUtilities } from 'sql/parts/jobManagement/common/jobManagementUtilities'; import { JobManagementUtilities } from 'sql/parts/jobManagement/common/jobManagementUtilities';
export class JobStepsViewRow { export class JobStepsViewRow {
public stepID: string; public stepId: string;
public stepName: string; public stepName: string;
public message: string; public message: string;
public rowID: string = generateUuid(); public rowID: string = generateUuid();
@@ -121,7 +121,7 @@ export class JobStepsViewRenderer implements tree.IRenderer {
public renderElement(tree: tree.ITree, element: JobStepsViewRow, templateId: string, templateData: IListTemplate): void { public renderElement(tree: tree.ITree, element: JobStepsViewRow, templateId: string, templateData: IListTemplate): void {
let stepIdCol: HTMLElement = DOM.$('div'); let stepIdCol: HTMLElement = DOM.$('div');
stepIdCol.className = 'tree-id-col'; stepIdCol.className = 'tree-id-col';
stepIdCol.innerText = element.stepID; stepIdCol.innerText = element.stepId;
let stepNameCol: HTMLElement = DOM.$('div'); let stepNameCol: HTMLElement = DOM.$('div');
stepNameCol.className = 'tree-name-col'; stepNameCol.className = 'tree-name-col';
stepNameCol.innerText = element.stepName; stepNameCol.innerText = element.stepName;

View File

@@ -37,6 +37,7 @@ import { IDashboardService } from 'sql/services/dashboard/common/dashboardServic
import { escape } from 'sql/base/common/strings'; import { escape } from 'sql/base/common/strings';
import { IWorkbenchThemeService, IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IWorkbenchThemeService, IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { tableBackground, cellBackground, tableHoverBackground, jobsHeadingBackground, cellBorderColor } from 'sql/common/theme/colors'; import { tableBackground, cellBackground, tableHoverBackground, jobsHeadingBackground, cellBorderColor } from 'sql/common/theme/colors';
import { JobStepsViewRow } from 'sql/parts/jobManagement/views/jobStepsViewTree';
export const JOBSVIEW_SELECTOR: string = 'jobsview-component'; export const JOBSVIEW_SELECTOR: string = 'jobsview-component';
export const ROW_HEIGHT: number = 45; export const ROW_HEIGHT: number = 45;
@@ -171,7 +172,6 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
}); });
this.rowDetail = rowDetail; this.rowDetail = rowDetail;
columns.unshift(this.rowDetail.getColumnDefinition()); columns.unshift(this.rowDetail.getColumnDefinition());
let filterPlugin = new HeaderFilter({}, this._themeService); let filterPlugin = new HeaderFilter({}, this._themeService);
this.filterPlugin = filterPlugin; this.filterPlugin = filterPlugin;
$(this._gridEl.nativeElement).empty(); $(this._gridEl.nativeElement).empty();
@@ -475,7 +475,7 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
case ('Failed'): case ('Failed'):
resultIndicatorClass = 'jobview-jobnameindicatorfailure'; resultIndicatorClass = 'jobview-jobnameindicatorfailure';
break; break;
case ('Canceled'): case ('Cancelled'):
resultIndicatorClass = 'jobview-jobnameindicatorcancel'; resultIndicatorClass = 'jobview-jobnameindicatorcancel';
break; break;
case ('Status Unknown'): case ('Status Unknown'):
@@ -523,17 +523,15 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
this.rowDetail.applyTemplateNewLineHeight(item, true); this.rowDetail.applyTemplateNewLineHeight(item, true);
} }
private loadJobHistories(): void { private async loadJobHistories() {
if (this.jobs) { if (this.jobs) {
let erroredJobs = 0;
let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri; let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri;
let separatedJobs = this.separateFailingJobs(); let separatedJobs = this.separateFailingJobs();
// grab histories of the failing jobs first // grab histories of the failing jobs first
// so they can be expanded quicker // so they can be expanded quicker
let failing = separatedJobs[0]; let failing = separatedJobs[0];
this.curateJobHistory(failing, ownerUri);
let passing = separatedJobs[1]; let passing = separatedJobs[1];
this.curateJobHistory(passing, ownerUri); Promise.all([this.curateJobHistory(failing, ownerUri), this.curateJobHistory(passing, ownerUri)]);
} }
} }
@@ -578,11 +576,10 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
return job; return job;
} }
private curateJobHistory(jobs: sqlops.AgentJobInfo[], ownerUri: string) { private async curateJobHistory(jobs: sqlops.AgentJobInfo[], ownerUri: string) {
const self = this; const self = this;
for (let i = 0; i < jobs.length; i++) { jobs.forEach(async (job) => {
let job = jobs[i]; await this._jobManagementService.getJobHistory(ownerUri, job.jobId).then((result) => {
this._jobManagementService.getJobHistory(ownerUri, job.jobId).then((result) => {
if (result && result.jobs) { if (result && result.jobs) {
self.jobHistories[job.jobId] = result.jobs; self.jobHistories[job.jobId] = result.jobs;
self._jobCacheObject.setJobHistory(job.jobId, result.jobs); self._jobCacheObject.setJobHistory(job.jobId, result.jobs);
@@ -600,7 +597,7 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
} }
} }
}); });
} });
} }
private createJobChart(jobId: string, jobHistories: sqlops.AgentJobHistoryInfo[]): void { private createJobChart(jobId: string, jobHistories: sqlops.AgentJobHistoryInfo[]): void {
@@ -848,6 +845,40 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
return TPromise.as(actions); return TPromise.as(actions);
} }
protected convertStepsToStepInfos(steps: sqlops.AgentJobStep[], job: sqlops.AgentJobInfo): sqlops.AgentJobStepInfo[] {
let result = [];
steps.forEach(step => {
let stepInfo: sqlops.AgentJobStepInfo = {
jobId: job.jobId,
jobName: job.name,
script: null,
scriptName: null,
stepName: step.stepName,
subSystem: null,
id: +step.stepId,
failureAction: null,
successAction: null,
failStepId: null,
successStepId: null,
command: null,
commandExecutionSuccessCode: null,
databaseName: null,
databaseUserName: null,
server: null,
outputFileName: null,
appendToLogFile: null,
appendToStepHist: null,
writeLogToTable: null,
appendLogToTable: null,
retryAttempts: null,
retryInterval: null,
proxyName: null
};
result.push(stepInfo);
});
return result;
}
protected getCurrentTableObject(rowIndex: number): any { protected getCurrentTableObject(rowIndex: number): any {
let data = this._table.grid.getData(); let data = this._table.grid.getData();
if (!data || rowIndex >= data.getLength()) { if (!data || rowIndex >= data.getLength()) {
@@ -855,10 +886,60 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
} }
let jobId = data.getItem(rowIndex).jobId; let jobId = data.getItem(rowIndex).jobId;
let job = this.jobs.filter(job => { if (!jobId) {
// if we couldn't find the ID, check if it's an
// error row
let isErrorRow: boolean = data.getItem(rowIndex).id.indexOf('error') >= 0;
if (isErrorRow) {
jobId = data.getItem(rowIndex - 1).jobId;
}
}
let job: sqlops.AgentJobInfo[] = this.jobs.filter(job => {
return job.jobId === jobId; return job.jobId === jobId;
}); });
let jobHistories = this.jobHistories[jobId];
let steps: sqlops.AgentJobStep[] = undefined;
let schedules: sqlops.AgentJobScheduleInfo[] = undefined;
let alerts: sqlops.AgentAlertInfo[] = undefined;
if (jobHistories && jobHistories[jobHistories.length-1]) {
// add steps
steps = jobHistories[jobHistories.length-1].steps;
if (steps && steps.length > 0) {
if (!job[0].JobSteps) {
job[0].JobSteps = [];
}
if (job[0].JobSteps.length !== steps.length) {
job[0].JobSteps = [];
steps.forEach(step => {
job[0].JobSteps.push(step.stepDetails);
});
}
}
// add schedules
schedules = jobHistories[jobHistories.length-1].schedules;
if (schedules && schedules.length > 0) {
if (!job[0].JobSchedules) {
job[0].JobSchedules = [];
}
if (job[0].JobSchedules.length !== schedules.length) {
job[0].JobSchedules = [];
schedules.forEach(schedule => {
job[0].JobSchedules.push(schedule);
});
}
}
// add alerts
alerts = jobHistories[jobHistories.length-1].alerts;
if (!job[0].Alerts) {
job[0].Alerts = [];
}
if (job[0].Alerts.length !== alerts.length) {
job[0].Alerts = [];
alerts.forEach(alert => {
job[0].Alerts.push(alert);
});
}
}
return job && job.length > 0 ? job[0] : undefined; return job && job.length > 0 ? job[0] : undefined;
} }

4
src/sql/sqlops.d.ts vendored
View File

@@ -1313,6 +1313,7 @@ declare module 'sqlops' {
jobCount: number; jobCount: number;
activeEndDate: string; activeEndDate: string;
scheduleUid: string; scheduleUid: string;
description: string;
} }
export interface AgentJobStep { export interface AgentJobStep {
@@ -1322,6 +1323,7 @@ declare module 'sqlops' {
message: string; message: string;
runDate: string; runDate: string;
runStatus: number; runStatus: number;
stepDetails: AgentJobStepInfo;
} }
export interface AgentJobStepInfo { export interface AgentJobStepInfo {
@@ -1369,6 +1371,8 @@ declare module 'sqlops' {
retriesAttempted: string; retriesAttempted: string;
server: string; server: string;
steps: AgentJobStep[]; steps: AgentJobStep[];
schedules: AgentJobScheduleInfo[];
alerts: AgentAlertInfo[];
} }
export interface AgentProxyInfo { export interface AgentProxyInfo {