mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-08 09:38:26 -05:00
Committer week - Agent fixes and refactor (#5547)
* refactored job actions to wait for job objects to load * sorted the jobs in descending order * decreased steps table height in jobs dialog * cannot open multiple instances of dialogs now * fixed edit job not show up some times when re opening history page * fix broken icon * fix a bunch of stuff and refactored code * added isopen prop to dialog
This commit is contained in:
@@ -17,6 +17,7 @@ export abstract class AgentDialog<T extends IAgentDialogData> {
|
||||
private static readonly CancelButtonText: string = localize('agentDialog.Cancel', 'Cancel');
|
||||
|
||||
protected _onSuccess: vscode.EventEmitter<T> = new vscode.EventEmitter<T>();
|
||||
protected _isOpen: boolean = false;
|
||||
public readonly onSuccess: vscode.Event<T> = this._onSuccess.event;
|
||||
public dialog: azdata.window.Dialog;
|
||||
|
||||
@@ -35,29 +36,34 @@ export abstract class AgentDialog<T extends IAgentDialogData> {
|
||||
protected abstract async initializeDialog(dialog: azdata.window.Dialog);
|
||||
|
||||
public async openDialog(dialogName?: string) {
|
||||
let event = dialogName ? dialogName : null;
|
||||
this.dialog = azdata.window.createModelViewDialog(this.title, event);
|
||||
if (!this._isOpen) {
|
||||
this._isOpen = true;
|
||||
let event = dialogName ? dialogName : null;
|
||||
this.dialog = azdata.window.createModelViewDialog(this.title, event);
|
||||
|
||||
await this.model.initialize();
|
||||
await this.model.initialize();
|
||||
|
||||
await this.initializeDialog(this.dialog);
|
||||
await this.initializeDialog(this.dialog);
|
||||
|
||||
this.dialog.okButton.label = AgentDialog.OkButtonText;
|
||||
this.dialog.okButton.onClick(async () => await this.execute());
|
||||
this.dialog.okButton.label = AgentDialog.OkButtonText;
|
||||
this.dialog.okButton.onClick(async () => await this.execute());
|
||||
|
||||
this.dialog.cancelButton.label = AgentDialog.CancelButtonText;
|
||||
this.dialog.cancelButton.onClick(async () => await this.cancel());
|
||||
this.dialog.cancelButton.label = AgentDialog.CancelButtonText;
|
||||
this.dialog.cancelButton.onClick(async () => await this.cancel());
|
||||
|
||||
azdata.window.openDialog(this.dialog);
|
||||
azdata.window.openDialog(this.dialog);
|
||||
}
|
||||
}
|
||||
|
||||
protected async execute() {
|
||||
this.updateModel();
|
||||
await this.model.save();
|
||||
this._isOpen = false;
|
||||
this._onSuccess.fire(this.model);
|
||||
}
|
||||
|
||||
protected async cancel() {
|
||||
this._isOpen = false;
|
||||
}
|
||||
|
||||
protected getActualConditionValue(checkbox: azdata.CheckBoxComponent, dropdown: azdata.DropDownComponent): azdata.JobCompletionActionCondition {
|
||||
@@ -77,4 +83,8 @@ export abstract class AgentDialog<T extends IAgentDialogData> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public get isOpen(): boolean {
|
||||
return this._isOpen;
|
||||
}
|
||||
}
|
||||
@@ -229,7 +229,7 @@ export class JobDialog extends AgentDialog<JobData> {
|
||||
this.StepsTable_FailureColumnString
|
||||
],
|
||||
data: data,
|
||||
height: 650
|
||||
height: 500
|
||||
}).component();
|
||||
|
||||
this.startStepDropdown = view.modelBuilder.dropDown().withProperties({ width: 180 }).component();
|
||||
|
||||
@@ -97,16 +97,16 @@ export class RunJobAction extends Action {
|
||||
}
|
||||
|
||||
public run(context: IJobActionInfo): Promise<boolean> {
|
||||
let jobName = context.targetObject.name;
|
||||
let jobName = context.targetObject.job.name;
|
||||
let ownerUri = context.ownerUri;
|
||||
let refreshAction = this.instantationService.createInstance(JobsRefreshAction);
|
||||
this.telemetryService.publicLog(TelemetryKeys.RunAgentJob);
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
this.jobManagementService.jobAction(ownerUri, jobName, JobActions.Run).then(result => {
|
||||
this.jobManagementService.jobAction(ownerUri, jobName, JobActions.Run).then(async (result) => {
|
||||
if (result.success) {
|
||||
let startMsg = nls.localize('jobSuccessfullyStarted', ': The job was successfully started.');
|
||||
this.notificationService.info(jobName + startMsg);
|
||||
refreshAction.run(context);
|
||||
await refreshAction.run(context);
|
||||
resolve(true);
|
||||
} else {
|
||||
this.errorMessageService.showDialog(Severity.Error, errorLabel, result.errorMessage);
|
||||
@@ -137,9 +137,9 @@ export class StopJobAction extends Action {
|
||||
let refreshAction = this.instantationService.createInstance(JobsRefreshAction);
|
||||
this.telemetryService.publicLog(TelemetryKeys.StopAgentJob);
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
this.jobManagementService.jobAction(ownerUri, jobName, JobActions.Stop).then(result => {
|
||||
this.jobManagementService.jobAction(ownerUri, jobName, JobActions.Stop).then(async (result) => {
|
||||
if (result.success) {
|
||||
refreshAction.run(context);
|
||||
await refreshAction.run(context);
|
||||
let stopMsg = nls.localize('jobSuccessfullyStopped', ': The job was successfully stopped.');
|
||||
this.notificationService.info(jobName + stopMsg);
|
||||
resolve(true);
|
||||
@@ -261,12 +261,12 @@ export class DeleteStepAction extends Action {
|
||||
label: DeleteStepAction.LABEL,
|
||||
run: () => {
|
||||
this._telemetryService.publicLog(TelemetryKeys.DeleteAgentJobStep);
|
||||
self._jobService.deleteJobStep(actionInfo.ownerUri, actionInfo.targetObject).then(result => {
|
||||
self._jobService.deleteJobStep(actionInfo.ownerUri, actionInfo.targetObject).then(async (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._errorMessageService.showDialog(Severity.Error, errorLabel, errorMessage);
|
||||
refreshAction.run(actionInfo);
|
||||
await refreshAction.run(actionInfo);
|
||||
} else {
|
||||
let successMessage = nls.localize('jobaction.deletedStep', 'The job step was successfully deleted');
|
||||
self._notificationService.info(successMessage);
|
||||
|
||||
@@ -219,8 +219,8 @@ export class AlertsViewComponent extends JobManagementView implements OnInit, On
|
||||
'</tr></table>';
|
||||
}
|
||||
|
||||
public openCreateAlertDialog() {
|
||||
public async openCreateAlertDialog() {
|
||||
let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri;
|
||||
this._commandService.executeCommand('agent.openAlertDialog', ownerUri, null, null);
|
||||
await this._commandService.executeCommand('agent.openAlertDialog', ownerUri, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { JobManagementView } from 'sql/workbench/parts/jobManagement/electron-browser/jobManagementView';
|
||||
import { JobManagementView, JobActionContext } from 'sql/workbench/parts/jobManagement/electron-browser/jobManagementView';
|
||||
import { TabChild } from 'sql/base/electron-browser/ui/panel/tab.component';
|
||||
import { IDashboardService } from 'sql/platform/dashboard/browser/dashboardService';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
@@ -67,6 +67,12 @@ export class JobHistoryComponent extends JobManagementView implements OnInit {
|
||||
private _agentJobInfo: azdata.AgentJobInfo;
|
||||
private _noJobsAvailable: boolean = false;
|
||||
|
||||
// Job Actions
|
||||
private _editJobAction: EditJobAction;
|
||||
private _runJobAction: RunJobAction;
|
||||
private _stopJobAction: StopJobAction;
|
||||
private _refreshAction: JobsRefreshAction;
|
||||
|
||||
private static readonly HEADING_HEIGHT: number = 24;
|
||||
|
||||
constructor(
|
||||
@@ -102,9 +108,8 @@ export class JobHistoryComponent extends JobManagementView implements OnInit {
|
||||
// set base class elements
|
||||
this._visibilityElement = this._tableContainer;
|
||||
this._parentComponent = this._agentViewComponent;
|
||||
|
||||
let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri;
|
||||
this._agentJobInfo = this._agentViewComponent.agentJobInfo;
|
||||
this.initActionBar();
|
||||
const self = this;
|
||||
this._treeController.onClick = (tree, element, event, origin = 'mouse') => {
|
||||
const payload = { origin: origin };
|
||||
@@ -146,7 +151,6 @@ export class JobHistoryComponent extends JobManagementView implements OnInit {
|
||||
this._register(attachListStyler(this._tree, this.themeService));
|
||||
this._tree.layout(dom.getContentHeight(this._tableContainer.nativeElement));
|
||||
this._telemetryService.publicLog(TelemetryKeys.JobHistoryView);
|
||||
this.initActionBar();
|
||||
}
|
||||
|
||||
private loadHistory() {
|
||||
@@ -165,21 +169,29 @@ export class JobHistoryComponent extends JobManagementView implements OnInit {
|
||||
this._agentViewComponent.agentJobInfo.alerts = this._jobCacheObject.getJobAlerts(jobId);
|
||||
this._agentJobInfo = this._agentViewComponent.agentJobInfo;
|
||||
if (result.histories.length > 0) {
|
||||
self._noJobsAvailable = false;
|
||||
self._showPreviousRuns = true;
|
||||
self.buildHistoryTree(self, result.histories);
|
||||
if (self._agentViewComponent.showHistory) {
|
||||
self._cd.detectChanges();
|
||||
}
|
||||
} else {
|
||||
self._jobCacheObject.setJobHistory(self._agentViewComponent.jobId, result.histories);
|
||||
self._noJobsAvailable = true;
|
||||
self._showPreviousRuns = false;
|
||||
}
|
||||
} else {
|
||||
self._noJobsAvailable = true;
|
||||
self._showPreviousRuns = false;
|
||||
self._showSteps = false;
|
||||
if (self._agentViewComponent.showHistory) {
|
||||
self._cd.detectChanges();
|
||||
}
|
||||
}
|
||||
this._actionBar.context = { targetObject: { canEdit: true, job: this._agentJobInfo }, ownerUri: this.ownerUri, component: this };
|
||||
this._editJobAction.enabled = true;
|
||||
this._actionBar.setContent([
|
||||
{ action: this._runJobAction },
|
||||
{ action: this._stopJobAction },
|
||||
{ action: this._refreshAction },
|
||||
{ action: this._editJobAction }
|
||||
]);
|
||||
if (self._agentViewComponent.showHistory) {
|
||||
self._cd.detectChanges();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -234,8 +246,13 @@ export class JobHistoryComponent extends JobManagementView implements OnInit {
|
||||
|
||||
private buildHistoryTree(self: any, jobHistories: azdata.AgentJobHistoryInfo[]) {
|
||||
self._treeController.jobHistories = jobHistories;
|
||||
let jobHistoryRows = this._treeController.jobHistories.map(job => self.convertToJobHistoryRow(job));
|
||||
self._treeDataSource.data = jobHistoryRows;
|
||||
let jobHistoryRows: JobHistoryRow[] = this._treeController.jobHistories.map(job => self.convertToJobHistoryRow(job));
|
||||
let sortedRows = jobHistoryRows.sort((row1, row2) => {
|
||||
let date1 = new Date(row1.runDate).getTime();
|
||||
let date2 = new Date(row2.runDate).getTime();
|
||||
return date2 - date1;
|
||||
});
|
||||
self._treeDataSource.data = sortedRows;
|
||||
self._tree.setInput(new JobHistoryModel());
|
||||
self.agentJobHistoryInfo = self._treeController.jobHistories[0];
|
||||
if (self.agentJobHistoryInfo) {
|
||||
@@ -294,23 +311,32 @@ export class JobHistoryComponent extends JobManagementView implements OnInit {
|
||||
}
|
||||
|
||||
let jobHistories = this._jobCacheObject.jobHistories[this._agentViewComponent.jobId];
|
||||
if (jobHistories && jobHistories.length > 0) {
|
||||
const self = this;
|
||||
if (this._jobCacheObject.prevJobID === this._agentViewComponent.jobId || jobHistories[0].jobId === this._agentViewComponent.jobId) {
|
||||
this._showPreviousRuns = true;
|
||||
this._agentViewComponent.agentJobInfo.jobSteps = this._jobCacheObject.getJobSteps(this._agentJobInfo.jobId);
|
||||
this._agentViewComponent.agentJobInfo.jobSchedules = this._jobCacheObject.getJobSchedules(this._agentJobInfo.jobId);
|
||||
this._agentViewComponent.agentJobInfo.alerts = this._jobCacheObject.getJobAlerts(this._agentJobInfo.jobId);
|
||||
this._agentJobInfo = this._agentViewComponent.agentJobInfo;
|
||||
this.buildHistoryTree(self, jobHistories);
|
||||
this._actionBar.context = { targetObject: this._agentJobInfo, ownerUri: this.ownerUri, jobHistoryComponent: this };
|
||||
this._cd.detectChanges();
|
||||
if (jobHistories) {
|
||||
if (jobHistories.length > 0) {
|
||||
const self = this;
|
||||
this._noJobsAvailable = false;
|
||||
if (this._jobCacheObject.prevJobID === this._agentViewComponent.jobId || jobHistories[0].jobId === this._agentViewComponent.jobId) {
|
||||
this._showPreviousRuns = true;
|
||||
this._agentViewComponent.agentJobInfo.jobSteps = this._jobCacheObject.getJobSteps(this._agentJobInfo.jobId);
|
||||
this._agentViewComponent.agentJobInfo.jobSchedules = this._jobCacheObject.getJobSchedules(this._agentJobInfo.jobId);
|
||||
this._agentViewComponent.agentJobInfo.alerts = this._jobCacheObject.getJobAlerts(this._agentJobInfo.jobId);
|
||||
this._agentJobInfo = this._agentViewComponent.agentJobInfo;
|
||||
this.buildHistoryTree(self, jobHistories);
|
||||
}
|
||||
} else if (jobHistories.length === 0) {
|
||||
this._showPreviousRuns = false;
|
||||
this._showSteps = false;
|
||||
this._noJobsAvailable = true;
|
||||
}
|
||||
} else if (jobHistories && jobHistories.length === 0) {
|
||||
this._showPreviousRuns = false;
|
||||
this._showSteps = false;
|
||||
this._noJobsAvailable = true;
|
||||
this._editJobAction.enabled = true;
|
||||
this._actionBar.setContent([
|
||||
{ action: this._runJobAction },
|
||||
{ action: this._stopJobAction },
|
||||
{ action: this._refreshAction },
|
||||
{ action: this._editJobAction }
|
||||
]);
|
||||
this._cd.detectChanges();
|
||||
|
||||
} else {
|
||||
this.loadHistory();
|
||||
}
|
||||
@@ -339,18 +365,20 @@ export class JobHistoryComponent extends JobManagementView implements OnInit {
|
||||
}
|
||||
|
||||
protected initActionBar() {
|
||||
let runJobAction = this.instantiationService.createInstance(RunJobAction);
|
||||
let stopJobAction = this.instantiationService.createInstance(StopJobAction);
|
||||
let editJobAction = this.instantiationService.createInstance(EditJobAction);
|
||||
let refreshAction = this.instantiationService.createInstance(JobsRefreshAction);
|
||||
this._runJobAction = this.instantiationService.createInstance(RunJobAction);
|
||||
this._stopJobAction = this.instantiationService.createInstance(StopJobAction);
|
||||
this._editJobAction = this.instantiationService.createInstance(EditJobAction);
|
||||
this._refreshAction = this.instantiationService.createInstance(JobsRefreshAction);
|
||||
let taskbar = <HTMLElement>this.actionBarContainer.nativeElement;
|
||||
this._actionBar = new Taskbar(taskbar);
|
||||
this._actionBar.context = { targetObject: this._agentJobInfo, ownerUri: this.ownerUri, component: this };
|
||||
this._editJobAction.enabled = !this.showProgressWheel();
|
||||
let targetObject: JobActionContext = { canEdit: !this.showProgressWheel(), job: this._agentJobInfo };
|
||||
this._actionBar.context = { targetObject: targetObject, ownerUri: this.ownerUri, component: this };
|
||||
this._actionBar.setContent([
|
||||
{ action: runJobAction },
|
||||
{ action: stopJobAction },
|
||||
{ action: refreshAction },
|
||||
{ action: editJobAction }
|
||||
{ action: this._runJobAction },
|
||||
{ action: this._stopJobAction },
|
||||
{ action: this._refreshAction },
|
||||
{ action: this._editJobAction }
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -79,10 +79,10 @@ export abstract class JobManagementView extends TabChild implements AfterContent
|
||||
let actions = this.getTableActions(targetObject);
|
||||
if (actions) {
|
||||
let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri;
|
||||
let actionContext = {
|
||||
let actionContext: IJobActionInfo = {
|
||||
ownerUri: ownerUri,
|
||||
targetObject: targetObject
|
||||
|
||||
targetObject: targetObject,
|
||||
component: this
|
||||
};
|
||||
|
||||
let anchor = { x: event.pageX + 1, y: event.pageY };
|
||||
@@ -117,7 +117,7 @@ export abstract class JobManagementView extends TabChild implements AfterContent
|
||||
{ action: refreshAction },
|
||||
{ action: newAction }
|
||||
]);
|
||||
let context: IJobActionInfo = { component: this };
|
||||
let context: IJobActionInfo = { component: this, ownerUri: this._commonService.connectionManagementService.connectionInfo.ownerUri };
|
||||
this._actionBar.context = context;
|
||||
}
|
||||
|
||||
|
||||
@@ -605,9 +605,11 @@ export class JobsViewComponent extends JobManagementView implements OnInit, OnDe
|
||||
let item = self.dataView.getItemById(job.jobId + '.error');
|
||||
let noStepsMessage = nls.localize('jobsView.noSteps', 'No Steps available for this job.');
|
||||
let errorMessage = lastJobHistory ? lastJobHistory.message : noStepsMessage;
|
||||
item['name'] = nls.localize('jobsView.error', 'Error: ') + errorMessage;
|
||||
self._agentViewComponent.setExpanded(job.jobId, item['name']);
|
||||
self.dataView.updateItem(job.jobId + '.error', item);
|
||||
if (item) {
|
||||
item['name'] = nls.localize('jobsView.error', 'Error: ') + errorMessage;
|
||||
self._agentViewComponent.setExpanded(job.jobId, item['name']);
|
||||
self.dataView.updateItem(job.jobId + '.error', item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,8 +215,8 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit,
|
||||
'</tr></table>';
|
||||
}
|
||||
|
||||
public openCreateOperatorDialog() {
|
||||
public async openCreateOperatorDialog() {
|
||||
let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri;
|
||||
this._commandService.executeCommand('agent.openOperatorDialog', ownerUri);
|
||||
await this._commandService.executeCommand('agent.openOperatorDialog', ownerUri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,9 +221,9 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit, O
|
||||
|
||||
public openCreateProxyDialog() {
|
||||
let ownerUri: string = this._commonService.connectionManagementService.connectionInfo.ownerUri;
|
||||
this._jobManagementService.getCredentials(ownerUri).then((result) => {
|
||||
this._jobManagementService.getCredentials(ownerUri).then(async (result) => {
|
||||
if (result && result.credentials) {
|
||||
this._commandService.executeCommand('agent.openProxyDialog', ownerUri, undefined, result.credentials);
|
||||
await this._commandService.executeCommand('agent.openProxyDialog', ownerUri, undefined, result.credentials);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user