From 408a8a6f19b9fd12a51c6288fd0718695aee38a8 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Fri, 13 Jul 2018 22:57:09 -0700 Subject: [PATCH] Edit Agent Job dialog updates (#1925) * Fill in job name and description on edit * Hook up update job request call * Clean up table styles --- extensions/agent/src/data/jobData.ts | 75 ++++++++++++------- extensions/agent/src/dialogs/jobDialog.ts | 18 +++-- extensions/mssql/src/telemetry.ts | 19 +---- .../parts/jobManagement/common/media/jobs.css | 71 +++++++++++++++++- .../views/alertsView.component.ts | 9 +-- .../views/operatorsView.component.ts | 9 +-- .../views/proxiesView.component.ts | 9 +-- 7 files changed, 132 insertions(+), 78 deletions(-) diff --git a/extensions/agent/src/data/jobData.ts b/extensions/agent/src/data/jobData.ts index cec2baae7e..71bb365262 100644 --- a/extensions/agent/src/data/jobData.ts +++ b/extensions/agent/src/data/jobData.ts @@ -4,18 +4,22 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; +import * as nls from 'vscode-nls'; import * as sqlops from 'sqlops'; +import * as vscode from 'vscode'; import { AgentUtils } from '../agentUtils'; import { IAgentDialogData, AgentDialogMode } from '../interfaces'; +const localize = nls.loadMessageBundle(); + export class JobData implements IAgentDialogData { - 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'; + private readonly JobCompletionActionCondition_Always: string = localize('jobData.whenJobCompletes', 'When the job completes'); + private readonly JobCompletionActionCondition_OnFailure: string = localize('jobData.whenJobFails', 'When the job fails'); + private readonly JobCompletionActionCondition_OnSuccess: string = localize('jobData.whenJobSucceeds', 'When the job succeeds'); // 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 _jobCategories: string[]; @@ -25,6 +29,7 @@ export class JobData implements IAgentDialogData { public dialogMode: AgentDialogMode = AgentDialogMode.CREATE; public name: string; + public originalName: string; public enabled: boolean = true; public description: string; public category: string; @@ -49,6 +54,10 @@ export class JobData implements IAgentDialogData { if (jobInfo) { this.dialogMode = AgentDialogMode.EDIT; this.name = jobInfo.name; + this.originalName = jobInfo.name; + this.owner = jobInfo.owner; + this.category = jobInfo.category; + this.description = jobInfo.description; this.enabled = jobInfo.enabled; } } @@ -101,7 +110,39 @@ export class JobData implements IAgentDialogData { } 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, owner: this.owner, description: this.description, @@ -131,30 +172,6 @@ export class JobData implements IAgentDialogData { 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); - } - } } \ No newline at end of file diff --git a/extensions/agent/src/dialogs/jobDialog.ts b/extensions/agent/src/dialogs/jobDialog.ts index 5ff73b8ecf..9f8700fbed 100644 --- a/extensions/agent/src/dialogs/jobDialog.ts +++ b/extensions/agent/src/dialogs/jobDialog.ts @@ -109,7 +109,7 @@ export class JobDialog extends AgentDialog { constructor(ownerUri: string, jobInfo: sqlops.AgentJobInfo = undefined) { super( ownerUri, - new JobData(ownerUri), + new JobData(ownerUri, jobInfo), jobInfo ? JobDialog.EditDialogTitle : JobDialog.CreateDialogTitle); } @@ -180,9 +180,15 @@ export class JobDialog extends AgentDialog { this.nameTextBox.value = this.model.name; this.ownerTextBox.value = this.model.defaultOwner; 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.descriptionTextBox.value = ''; + this.descriptionTextBox.value = this.model.description; }); } @@ -198,7 +204,7 @@ export class JobDialog extends AgentDialog { this.StepsTable_FailureColumnString ], data: [], - height: 800 + height: 300 }).component(); this.moveStepUpButton = view.modelBuilder.button() @@ -255,7 +261,7 @@ export class JobDialog extends AgentDialog { this.AlertNameLabelString ], data: [], - height: 600, + height: 300, width: 400 }).component(); @@ -290,7 +296,7 @@ export class JobDialog extends AgentDialog { this.ScheduleNameLabelString ], data: [], - height: 600, + height: 300, width: 420 }).component(); diff --git a/extensions/mssql/src/telemetry.ts b/extensions/mssql/src/telemetry.ts index 60fbf61822..99e555a42e 100644 --- a/extensions/mssql/src/telemetry.ts +++ b/extensions/mssql/src/telemetry.ts @@ -44,22 +44,6 @@ export class Telemetry { private static platformInformation: PlatformInformation; private static disabled: boolean; - // Get the unique ID for the current user of the extension - public static getUserId(): Promise { - return new Promise(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 { if (this.platformInformation) { return Promise.resolve(this.platformInformation); @@ -143,8 +127,7 @@ export class Telemetry { } // Augment the properties structure with additional common properties before sending - Promise.all([this.getUserId(), this.getPlatformInformation()]).then(() => { - properties['userId'] = this.userId; + Promise.all([this.getPlatformInformation()]).then(() => { properties['distribution'] = (this.platformInformation && this.platformInformation.distribution) ? `${this.platformInformation.distribution.name}, ${this.platformInformation.distribution.version}` : ''; diff --git a/src/sql/parts/jobManagement/common/media/jobs.css b/src/sql/parts/jobManagement/common/media/jobs.css index 818df082b6..df2579e6bc 100644 --- a/src/sql/parts/jobManagement/common/media/jobs.css +++ b/src/sql/parts/jobManagement/common/media/jobs.css @@ -327,4 +327,73 @@ jobsview-component .actionbar-container { jobsview-component .jobview-grid .slick-cell.error-row { opacity: 0; -} \ No newline at end of file +} + +.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; +} diff --git a/src/sql/parts/jobManagement/views/alertsView.component.ts b/src/sql/parts/jobManagement/views/alertsView.component.ts index c399d49548..48d0c0dfd1 100644 --- a/src/sql/parts/jobManagement/views/alertsView.component.ts +++ b/src/sql/parts/jobManagement/views/alertsView.component.ts @@ -32,7 +32,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IDashboardService } from 'sql/services/dashboard/common/dashboardService'; export const VIEW_SELECTOR: string = 'jobalertsview-component'; -export const ROW_HEIGHT: number = 45; +export const ROW_HEIGHT: number = 30; @Component({ selector: VIEW_SELECTOR, @@ -103,13 +103,6 @@ export class AlertsViewComponent extends JobManagementView implements OnInit { column.rerenderOnResize = true; return column; }); - let options = >{ - syncColumnCellResize: true, - enableColumnReorder: false, - rowHeight: ROW_HEIGHT, - enableCellNavigation: true, - forceFitColumns: true - }; this.dataView = new Slick.Data.DataView(); diff --git a/src/sql/parts/jobManagement/views/operatorsView.component.ts b/src/sql/parts/jobManagement/views/operatorsView.component.ts index 60cfe91010..67ef8efdc5 100644 --- a/src/sql/parts/jobManagement/views/operatorsView.component.ts +++ b/src/sql/parts/jobManagement/views/operatorsView.component.ts @@ -32,7 +32,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IDashboardService } from 'sql/services/dashboard/common/dashboardService'; export const VIEW_SELECTOR: string = 'joboperatorsview-component'; -export const ROW_HEIGHT: number = 45; +export const ROW_HEIGHT: number = 30; @Component({ selector: VIEW_SELECTOR, @@ -104,13 +104,6 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit column.rerenderOnResize = true; return column; }); - let options = >{ - syncColumnCellResize: true, - enableColumnReorder: false, - rowHeight: ROW_HEIGHT, - enableCellNavigation: true, - forceFitColumns: true - }; this.dataView = new Slick.Data.DataView(); diff --git a/src/sql/parts/jobManagement/views/proxiesView.component.ts b/src/sql/parts/jobManagement/views/proxiesView.component.ts index 4dfc18652b..b009a9298a 100644 --- a/src/sql/parts/jobManagement/views/proxiesView.component.ts +++ b/src/sql/parts/jobManagement/views/proxiesView.component.ts @@ -32,7 +32,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IDashboardService } from 'sql/services/dashboard/common/dashboardService'; export const VIEW_SELECTOR: string = 'jobproxiesview-component'; -export const ROW_HEIGHT: number = 45; +export const ROW_HEIGHT: number = 30; @Component({ selector: VIEW_SELECTOR, @@ -106,13 +106,6 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit { column.rerenderOnResize = true; return column; }); - let options = >{ - syncColumnCellResize: true, - enableColumnReorder: false, - rowHeight: ROW_HEIGHT, - enableCellNavigation: true, - forceFitColumns: true - }; this.dataView = new Slick.Data.DataView();