Edit Agent Job dialog updates (#1925)

* Fill in job name and description on edit

* Hook up update job request call

* Clean up table styles
This commit is contained in:
Karl Burtram
2018-07-13 22:57:09 -07:00
committed by GitHub
parent e1485e49d3
commit 408a8a6f19
7 changed files with 132 additions and 78 deletions

View File

@@ -4,18 +4,22 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict'; 'use strict';
import * as nls from 'vscode-nls';
import * as sqlops from 'sqlops'; import * as sqlops from 'sqlops';
import * as vscode from 'vscode';
import { AgentUtils } from '../agentUtils'; import { AgentUtils } from '../agentUtils';
import { IAgentDialogData, AgentDialogMode } from '../interfaces'; import { IAgentDialogData, AgentDialogMode } from '../interfaces';
const localize = nls.loadMessageBundle();
export class JobData implements IAgentDialogData { export class JobData implements IAgentDialogData {
private readonly JobCompletionActionCondition_Always: string = 'When the job completes'; private readonly JobCompletionActionCondition_Always: string = localize('jobData.whenJobCompletes', 'When the job completes');
private readonly JobCompletionActionCondition_OnFailure: string = 'When the job fails'; private readonly JobCompletionActionCondition_OnFailure: string = localize('jobData.whenJobFails', 'When the job fails');
private readonly JobCompletionActionCondition_OnSuccess: string = 'When the job succeeds'; private readonly JobCompletionActionCondition_OnSuccess: string = localize('jobData.whenJobSucceeds', 'When the job succeeds');
// Error Messages // Error Messages
private readonly CreateJobErrorMessage_NameIsEmpty = 'Job name must be provided'; private readonly CreateJobErrorMessage_NameIsEmpty = localize('jobData.jobNameRequired', 'Job name must be provided');
private _ownerUri: string; private _ownerUri: string;
private _jobCategories: string[]; private _jobCategories: string[];
@@ -25,6 +29,7 @@ export class JobData implements IAgentDialogData {
public dialogMode: AgentDialogMode = AgentDialogMode.CREATE; public dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
public name: string; public name: string;
public originalName: string;
public enabled: boolean = true; public enabled: boolean = true;
public description: string; public description: string;
public category: string; public category: string;
@@ -49,6 +54,10 @@ export class JobData implements IAgentDialogData {
if (jobInfo) { if (jobInfo) {
this.dialogMode = AgentDialogMode.EDIT; this.dialogMode = AgentDialogMode.EDIT;
this.name = jobInfo.name; this.name = jobInfo.name;
this.originalName = jobInfo.name;
this.owner = jobInfo.owner;
this.category = jobInfo.category;
this.description = jobInfo.description;
this.enabled = jobInfo.enabled; this.enabled = jobInfo.enabled;
} }
} }
@@ -101,7 +110,39 @@ export class JobData implements IAgentDialogData {
} }
public async save() { public async save() {
await this._agentService.createJob(this.ownerUri, { let jobInfo: sqlops.AgentJobInfo = this.toAgentJobInfo();
let result = this.dialogMode === AgentDialogMode.CREATE
? await this._agentService.createJob(this.ownerUri, jobInfo)
: await this._agentService.updateJob(this.ownerUri, this.originalName, jobInfo);
if (!result || !result.success) {
vscode.window.showErrorMessage(
localize('alertData.saveErrorMessage', "Alert update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown'));
}
}
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);
}
}
public toAgentJobInfo(): sqlops.AgentJobInfo {
return {
name: this.name, name: this.name,
owner: this.owner, owner: this.owner,
description: this.description, description: this.description,
@@ -131,30 +172,6 @@ export class JobData implements IAgentDialogData {
lastRun: '', lastRun: '',
nextRun: '', nextRun: '',
jobId: '' 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

@@ -109,7 +109,7 @@ export class JobDialog extends AgentDialog<JobData> {
constructor(ownerUri: string, jobInfo: sqlops.AgentJobInfo = undefined) { constructor(ownerUri: string, jobInfo: sqlops.AgentJobInfo = undefined) {
super( super(
ownerUri, ownerUri,
new JobData(ownerUri), new JobData(ownerUri, jobInfo),
jobInfo ? JobDialog.EditDialogTitle : JobDialog.CreateDialogTitle); jobInfo ? JobDialog.EditDialogTitle : JobDialog.CreateDialogTitle);
} }
@@ -180,9 +180,15 @@ export class JobDialog extends AgentDialog<JobData> {
this.nameTextBox.value = this.model.name; this.nameTextBox.value = this.model.name;
this.ownerTextBox.value = this.model.defaultOwner; this.ownerTextBox.value = this.model.defaultOwner;
this.categoryDropdown.values = this.model.jobCategories; this.categoryDropdown.values = this.model.jobCategories;
this.categoryDropdown.value = this.model.jobCategories[0];
let idx: number = undefined;
if (this.model.category && this.model.category !== '') {
idx = this.model.jobCategories.indexOf(this.model.category);
}
this.categoryDropdown.value = this.model.jobCategories[idx > 0 ? idx : 0];
this.enabledCheckBox.checked = this.model.enabled; this.enabledCheckBox.checked = this.model.enabled;
this.descriptionTextBox.value = ''; this.descriptionTextBox.value = this.model.description;
}); });
} }
@@ -198,7 +204,7 @@ export class JobDialog extends AgentDialog<JobData> {
this.StepsTable_FailureColumnString this.StepsTable_FailureColumnString
], ],
data: [], data: [],
height: 800 height: 300
}).component(); }).component();
this.moveStepUpButton = view.modelBuilder.button() this.moveStepUpButton = view.modelBuilder.button()
@@ -255,7 +261,7 @@ export class JobDialog extends AgentDialog<JobData> {
this.AlertNameLabelString this.AlertNameLabelString
], ],
data: [], data: [],
height: 600, height: 300,
width: 400 width: 400
}).component(); }).component();
@@ -290,7 +296,7 @@ export class JobDialog extends AgentDialog<JobData> {
this.ScheduleNameLabelString this.ScheduleNameLabelString
], ],
data: [], data: [],
height: 600, height: 300,
width: 420 width: 420
}).component(); }).component();

View File

@@ -44,22 +44,6 @@ export class Telemetry {
private static platformInformation: PlatformInformation; private static platformInformation: PlatformInformation;
private static disabled: boolean; private static disabled: boolean;
// Get the unique ID for the current user of the extension
public static getUserId(): Promise<string> {
return new Promise<string>(resolve => {
// Generate the user id if it has not been created already
if (typeof this.userId === 'undefined') {
let id = Utils.generateUserId();
id.then(newId => {
this.userId = newId;
resolve(this.userId);
});
} else {
resolve(this.userId);
}
});
}
public static getPlatformInformation(): Promise<PlatformInformation> { public static getPlatformInformation(): Promise<PlatformInformation> {
if (this.platformInformation) { if (this.platformInformation) {
return Promise.resolve(this.platformInformation); return Promise.resolve(this.platformInformation);
@@ -143,8 +127,7 @@ export class Telemetry {
} }
// Augment the properties structure with additional common properties before sending // Augment the properties structure with additional common properties before sending
Promise.all([this.getUserId(), this.getPlatformInformation()]).then(() => { Promise.all([this.getPlatformInformation()]).then(() => {
properties['userId'] = this.userId;
properties['distribution'] = (this.platformInformation && this.platformInformation.distribution) ? properties['distribution'] = (this.platformInformation && this.platformInformation.distribution) ?
`${this.platformInformation.distribution.name}, ${this.platformInformation.distribution.version}` : ''; `${this.platformInformation.distribution.name}, ${this.platformInformation.distribution.version}` : '';

View File

@@ -327,4 +327,73 @@ jobsview-component .actionbar-container {
jobsview-component .jobview-grid .slick-cell.error-row { jobsview-component .jobview-grid .slick-cell.error-row {
opacity: 0; opacity: 0;
} }
.vs-dark #alertsDiv jobalertsview-component .jobalertsview-grid .grid-canvas .ui-widget-content.slick-row .slick-cell {
background:#333333;
}
#alertsDiv jobalertsview-component .jobalertsview-grid .grid-canvas .ui-widget-content.slick-row .slick-cell {
background: white;
border-right: transparent !important;
border-left: transparent !important;
line-height: 33px !important;
}
#alertsDiv .jobalertsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row:hover > .slick-cell,
#alertsDiv .jobalertsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row.hovered > .slick-cell,
#alertsDiv .jobalertsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row> .slick-cell.hovered {
background: #dcdcdc !important;
}
.vs-dark #alertsDiv .jobalertsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row:hover > .slick-cell,
.vs-dark #alertsDiv .jobalertsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row > .slick-cell.hovered,
.vs-dark #alertsDiv .jobalertsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row.hovered > .slick-cell {
background: #444444 !important;
}
.vs-dark #operatorsDiv joboperatorsview-component .joboperatorsview-grid .grid-canvas .ui-widget-content.slick-row .slick-cell {
background:#333333;
}
#operatorsDiv joboperatorsview-component .joboperatorsview-grid .grid-canvas .ui-widget-content.slick-row .slick-cell {
background: white;
border-right: transparent !important;
border-left: transparent !important;
line-height: 33px !important;
}
#operatorsDiv .joboperatorsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row:hover > .slick-cell,
#operatorsDiv .joboperatorsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row.hovered > .slick-cell,
#operatorsDiv .joboperatorsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row> .slick-cell.hovered {
background: #dcdcdc !important;
}
.vs-dark #operatorsDiv .joboperatorsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row:hover > .slick-cell,
.vs-dark #operatorsDiv .joboperatorsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row > .slick-cell.hovered,
.vs-dark #operatorsDiv .joboperatorsview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row.hovered > .slick-cell {
background: #444444 !important;
}
.vs-dark #proxiesDiv jobproxiesview-component .jobproxiesview-grid .grid-canvas .ui-widget-content.slick-row .slick-cell {
background:#333333;
}
#proxiesDiv jobproxiesview-component .jobproxiesview-grid .grid-canvas .ui-widget-content.slick-row .slick-cell {
background: white;
border-right: transparent !important;
border-left: transparent !important;
line-height: 33px !important;
}
#proxiesDiv .jobproxiesview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row:hover > .slick-cell,
#proxiesDiv .jobproxiesview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row.hovered > .slick-cell,
#proxiesDiv .jobproxiesview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row> .slick-cell.hovered {
background: #dcdcdc !important;
}
.vs-dark #proxiesDiv .jobproxiesview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row:hover > .slick-cell,
.vs-dark #proxiesDiv .jobproxiesview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row > .slick-cell.hovered,
.vs-dark #proxiesDiv .jobproxiesview-grid > .monaco-table .slick-viewport > .grid-canvas > .ui-widget-content.slick-row.hovered > .slick-cell {
background: #444444 !important;
}

View File

@@ -32,7 +32,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IDashboardService } from 'sql/services/dashboard/common/dashboardService'; import { IDashboardService } from 'sql/services/dashboard/common/dashboardService';
export const VIEW_SELECTOR: string = 'jobalertsview-component'; export const VIEW_SELECTOR: string = 'jobalertsview-component';
export const ROW_HEIGHT: number = 45; export const ROW_HEIGHT: number = 30;
@Component({ @Component({
selector: VIEW_SELECTOR, selector: VIEW_SELECTOR,
@@ -103,13 +103,6 @@ export class AlertsViewComponent extends JobManagementView implements OnInit {
column.rerenderOnResize = true; column.rerenderOnResize = true;
return column; return column;
}); });
let options = <Slick.GridOptions<any>>{
syncColumnCellResize: true,
enableColumnReorder: false,
rowHeight: ROW_HEIGHT,
enableCellNavigation: true,
forceFitColumns: true
};
this.dataView = new Slick.Data.DataView(); this.dataView = new Slick.Data.DataView();

View File

@@ -32,7 +32,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IDashboardService } from 'sql/services/dashboard/common/dashboardService'; import { IDashboardService } from 'sql/services/dashboard/common/dashboardService';
export const VIEW_SELECTOR: string = 'joboperatorsview-component'; export const VIEW_SELECTOR: string = 'joboperatorsview-component';
export const ROW_HEIGHT: number = 45; export const ROW_HEIGHT: number = 30;
@Component({ @Component({
selector: VIEW_SELECTOR, selector: VIEW_SELECTOR,
@@ -104,13 +104,6 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit
column.rerenderOnResize = true; column.rerenderOnResize = true;
return column; return column;
}); });
let options = <Slick.GridOptions<any>>{
syncColumnCellResize: true,
enableColumnReorder: false,
rowHeight: ROW_HEIGHT,
enableCellNavigation: true,
forceFitColumns: true
};
this.dataView = new Slick.Data.DataView(); this.dataView = new Slick.Data.DataView();

View File

@@ -32,7 +32,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IDashboardService } from 'sql/services/dashboard/common/dashboardService'; import { IDashboardService } from 'sql/services/dashboard/common/dashboardService';
export const VIEW_SELECTOR: string = 'jobproxiesview-component'; export const VIEW_SELECTOR: string = 'jobproxiesview-component';
export const ROW_HEIGHT: number = 45; export const ROW_HEIGHT: number = 30;
@Component({ @Component({
selector: VIEW_SELECTOR, selector: VIEW_SELECTOR,
@@ -106,13 +106,6 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit {
column.rerenderOnResize = true; column.rerenderOnResize = true;
return column; return column;
}); });
let options = <Slick.GridOptions<any>>{
syncColumnCellResize: true,
enableColumnReorder: false,
rowHeight: ROW_HEIGHT,
enableCellNavigation: true,
forceFitColumns: true
};
this.dataView = new Slick.Data.DataView(); this.dataView = new Slick.Data.DataView();