mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Feature/agent1 adbist (#973)
* WIP * wip * SQL Agent wip * wip * Initial control host (wip) * Initial hookup of SQL Agent service to job component * Update agent package.json * Hook up getJobs call * A couple job view updates * Add some more agent views * added back button, run actions and overview accordion * refactoring * overview table complete * fixed the dropdown arrow for the overview section * added table for prev job list * fixed agent job result type * Rename some 'agent' classes to 'jobManagement' * code cleaning and code review comments * fixed yarn.lock conflicts * added function for job history * changed vscode-languageclient version * changed yarn lock file * fixed yarn lock file * fixed yarn file * fixed css paths * added images to packaging step * fix resource path for packaging * job history page (#852) * added back button, run actions and overview accordion * refactoring * overview table complete * fixed the dropdown arrow for the overview section * added table for prev job list * fixed agent job result type * code cleaning and code review comments * fixed yarn.lock conflicts * added function for job history * changed vscode-languageclient version * changed yarn lock file * fixed yarn lock file * fixed yarn file * fixed css paths * added images to packaging step * fix resource path for packaging * added steps lists * fixed style and dimensions * fixed conflicts * Switch back getJobs return type * Make enum const * Remove sqlops const * WIP * WIP * implemented job list * added the Date and Status columns * update yarn files * merged feature/agent1 * added theme styling for light theme * changed yarn lock files * Feature/agent1 adbist (#899) * added back button, run actions and overview accordion * refactoring * overview table complete * fixed the dropdown arrow for the overview section * added table for prev job list * fixed agent job result type * code cleaning and code review comments * fixed yarn.lock conflicts * added function for job history * changed vscode-languageclient version * changed yarn lock file * fixed yarn lock file * fixed yarn file * fixed css paths * added images to packaging step * fix resource path for packaging * added steps lists * fixed style and dimensions * fixed conflicts * implemented job list * added the Date and Status columns * update yarn files * merged feature/agent1 * added theme styling for light theme * changed yarn lock files * made job history page css more specific * Add visiblity check to job view * added method signatures for job history with DMP * Clean up jobs styling and call getJobHistory * Add more Job Table styling * Enable detail view in job table * Use updated slickgrid repo * vbumped slickgrid * added methods for job running * added job actions to sqlops * Convert rowdetail slickgrid plug to TypeScript * Feature/agent1 adbist (#945) * added back button, run actions and overview accordion * refactoring * overview table complete * fixed the dropdown arrow for the overview section * added table for prev job list * fixed agent job result type * code cleaning and code review comments * fixed yarn.lock conflicts * added function for job history * changed vscode-languageclient version * changed yarn lock file * fixed yarn lock file * fixed yarn file * fixed css paths * added images to packaging step * fix resource path for packaging * added steps lists * fixed style and dimensions * fixed conflicts * implemented job list * added the Date and Status columns * update yarn files * merged feature/agent1 * added theme styling for light theme * changed yarn lock files * added method signatures for job history with DMP * added methods for job running * added job actions to sqlops * Refer to dataprotocol from feature/agentDmp1 branch * Update SQL Tools version to 1.4.0-alpha.13 * Change Feb to March in release note prompt * SQL Agent extension metadata * add feature explicitly in client creation * Update Agent job registration * navigation works but is really slow to load data * Update package.json * fixed conflicts * Feature/agent1 adbist (#955) * added back button, run actions and overview accordion * refactoring * overview table complete * fixed the dropdown arrow for the overview section * added table for prev job list * fixed agent job result type * code cleaning and code review comments * fixed yarn.lock conflicts * added function for job history * changed vscode-languageclient version * changed yarn lock file * fixed yarn lock file * fixed yarn file * fixed css paths * added images to packaging step * fix resource path for packaging * added steps lists * fixed style and dimensions * fixed conflicts * implemented job list * added the Date and Status columns * update yarn files * merged feature/agent1 * added theme styling for light theme * changed yarn lock files * added method signatures for job history with DMP * added methods for job running * added job actions to sqlops * navigation works but is really slow to load data * Add jobs view icon * fixed bug where not all steps were being shown * added more to history page * added loadHistories and code review comments * made the params standard * fixed json local paths
This commit is contained in:
@@ -15,10 +15,10 @@
|
|||||||
<!-- Actions -->
|
<!-- Actions -->
|
||||||
<ul class="action-buttons">
|
<ul class="action-buttons">
|
||||||
<li>
|
<li>
|
||||||
<div class="icon-start" (click)="jobAction('start')">Run</div>
|
<div class="icon-start" (click)="jobAction('run', agentJobInfo.name)">Run</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="icon-stop" (click)="jobAction('stop')">Stop</div>
|
<div class="icon-stop" (click)="jobAction('stop', agentJobInfo.name)">Stop</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -34,10 +34,10 @@
|
|||||||
<table align='left'>
|
<table align='left'>
|
||||||
<tr>
|
<tr>
|
||||||
<td id='col1'>
|
<td id='col1'>
|
||||||
User:
|
Category:
|
||||||
</td>
|
</td>
|
||||||
<td id='col2'>
|
<td id='col2'>
|
||||||
|
{{agentJobInfo.category}}
|
||||||
</td>
|
</td>
|
||||||
<td id='col3'>
|
<td id='col3'>
|
||||||
Enabled:
|
Enabled:
|
||||||
@@ -48,30 +48,30 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td id='col1'>
|
<td id='col1'>
|
||||||
Alert:
|
Has Alert:
|
||||||
</td>
|
</td>
|
||||||
<td id='col2'>
|
<td id='col2'>
|
||||||
|
{{agentJobInfo.hasTarget}}
|
||||||
</td>
|
</td>
|
||||||
<td id='col3'>
|
<td id='col3'>
|
||||||
Notification:
|
Has Schedule:
|
||||||
</td>
|
</td>
|
||||||
<td id='col4'>
|
<td id='col4'>
|
||||||
|
{{agentJobInfo.hasSchedule}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td id='col1'>
|
<td id='col1'>
|
||||||
Schedule:
|
Last Run:
|
||||||
</td>
|
</td>
|
||||||
<td id='col2'>
|
<td id='col2'>
|
||||||
|
{{agentJobInfo.lastRun}}
|
||||||
</td>
|
</td>
|
||||||
<td id='col3'>
|
<td id='col3'>
|
||||||
Target Server:
|
Next Run:
|
||||||
</td>
|
</td>
|
||||||
<td id='col4'>
|
<td id='col4'>
|
||||||
|
{{agentJobInfo.nextRun}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -98,31 +98,31 @@
|
|||||||
<!-- Job Steps -->
|
<!-- Job Steps -->
|
||||||
<div class="job-steps">
|
<div class="job-steps">
|
||||||
<h1 class="job-heading">
|
<h1 class="job-heading">
|
||||||
{{agentJobInfo.lastRun}}
|
{{agentJobHistoryInfo?.runDate}}
|
||||||
</h1>
|
</h1>
|
||||||
<table class="step-list">
|
<table class="step-list">
|
||||||
<tr class="step-row">
|
<tr class="step-row">
|
||||||
<td height="30">
|
<td height="30">
|
||||||
<h3>Status:</h3>
|
<h3>Status:</h3>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td height="30">
|
||||||
<h3></h3>
|
<h3></h3>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="step-row">
|
<tr class="step-row">
|
||||||
<td height="30">
|
<td height="30">
|
||||||
Error Message:
|
Message:
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td height="30">
|
||||||
|
{{agentJobHistoryInfo?.message}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="step-row">
|
<tr class="step-row">
|
||||||
<td height="30">
|
<td height="30">
|
||||||
Duration:
|
Duration:
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td height="30">
|
||||||
|
{{agentJobHistoryInfo?.runDuration}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="step-row">
|
<tr class="step-row">
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
<td height="30">
|
<td height="30">
|
||||||
SQL message ID:
|
SQL message ID:
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td height="30">
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -145,8 +145,8 @@
|
|||||||
<td height="30">
|
<td height="30">
|
||||||
Retries Attempted:
|
Retries Attempted:
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td height="30">
|
||||||
|
{{agentJobHistoryInfo?.retriesAttempted}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -5,25 +5,20 @@
|
|||||||
|
|
||||||
import 'vs/css!./jobHistory';
|
import 'vs/css!./jobHistory';
|
||||||
|
|
||||||
import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild, Input } from '@angular/core';
|
import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild, Input, Injectable } from '@angular/core';
|
||||||
import { ICancelableEvent } from 'vs/base/parts/tree/browser/treeDefaults';
|
|
||||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
import { attachListStyler } from 'vs/platform/theme/common/styler';
|
import { attachListStyler } from 'vs/platform/theme/common/styler';
|
||||||
import { getContentHeight } from 'vs/base/browser/dom';
|
|
||||||
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
|
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { PanelComponent } from 'sql/base/browser/ui/panel/panel.component';
|
import { PanelComponent } from 'sql/base/browser/ui/panel/panel.component';
|
||||||
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
|
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
|
||||||
import { IJobManagementService } from '../common/interfaces';
|
import { IJobManagementService } from '../common/interfaces';
|
||||||
import { ExplorerDataSource } from 'sql/parts/dashboard/widgets/explorer/explorerTree';
|
|
||||||
import { TreeCreationUtils } from 'sql/parts/registeredServer/viewlet/treeCreationUtils';
|
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
||||||
import { JobHistoryController, JobHistoryDataSource,
|
import { JobHistoryController, JobHistoryDataSource,
|
||||||
JobHistoryRenderer, JobHistoryFilter, JobHistoryModel, JobHistoryRow } from 'sql/parts/jobManagement/views/jobHistoryTree';
|
JobHistoryRenderer, JobHistoryFilter, JobHistoryModel, JobHistoryRow } from 'sql/parts/jobManagement/views/jobHistoryTree';
|
||||||
import { AgentJobHistoryInfo, AgentJobInfo } from 'sqlops';
|
import { AgentJobHistoryInfo, AgentJobInfo } from 'sqlops';
|
||||||
import { toDisposableSubscription } from '../../common/rxjsUtils';
|
|
||||||
|
|
||||||
|
|
||||||
export const DASHBOARD_SELECTOR: string = 'jobhistory-component';
|
export const DASHBOARD_SELECTOR: string = 'jobhistory-component';
|
||||||
@@ -46,9 +41,8 @@ export class JobHistoryComponent extends Disposable implements OnInit, OnDestroy
|
|||||||
@Input() public agentJobInfo: AgentJobInfo = undefined;
|
@Input() public agentJobInfo: AgentJobInfo = undefined;
|
||||||
@Input() public jobId: string = undefined;
|
@Input() public jobId: string = undefined;
|
||||||
@Input() public agentJobHistoryInfo: AgentJobHistoryInfo = undefined;
|
@Input() public agentJobHistoryInfo: AgentJobHistoryInfo = undefined;
|
||||||
private prevJobId: string = undefined;
|
|
||||||
private jobName: string = undefined;
|
|
||||||
|
|
||||||
|
private prevJobId: string = undefined;
|
||||||
private isVisible: boolean = false;
|
private isVisible: boolean = false;
|
||||||
|
|
||||||
|
|
||||||
@@ -65,8 +59,32 @@ export class JobHistoryComponent extends Disposable implements OnInit, OnDestroy
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
this.loadHistory();
|
const self = this;
|
||||||
this._treeDataSource.data = [];
|
this._treeController.onClick = (tree, element, event, origin = 'mouse') => {
|
||||||
|
const payload = { origin: origin };
|
||||||
|
const isDoubleClick = (origin === 'mouse' && event.detail === 2);
|
||||||
|
// Cancel Event
|
||||||
|
const isMouseDown = event && event.browserEvent && event.browserEvent.type === 'mousedown';
|
||||||
|
|
||||||
|
if (!isMouseDown) {
|
||||||
|
event.preventDefault(); // we cannot preventDefault onMouseDown because this would break DND otherwise
|
||||||
|
}
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
tree.setFocus(element, payload);
|
||||||
|
|
||||||
|
if (element && isDoubleClick) {
|
||||||
|
event.preventDefault(); // focus moves to editor, we need to prevent default
|
||||||
|
} else {
|
||||||
|
tree.setFocus(element, payload);
|
||||||
|
tree.setSelection([element], payload);
|
||||||
|
self.agentJobHistoryInfo = self._treeController.jobHistories.filter(history => history.instanceId === element.instanceID)[0];
|
||||||
|
self.agentJobHistoryInfo.runDate = self.formatTime(self.agentJobHistoryInfo.runDate);
|
||||||
|
self._cd.detectChanges();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
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,
|
||||||
@@ -75,7 +93,6 @@ export class JobHistoryComponent extends Disposable implements OnInit, OnDestroy
|
|||||||
});
|
});
|
||||||
this._register(attachListStyler(this._tree, this.bootstrapService.themeService));
|
this._register(attachListStyler(this._tree, this.bootstrapService.themeService));
|
||||||
this._tree.layout(1024);
|
this._tree.layout(1024);
|
||||||
//this._tree.setInput(new JobHistoryModel());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
@@ -83,7 +100,7 @@ export class JobHistoryComponent extends Disposable implements OnInit, OnDestroy
|
|||||||
|
|
||||||
ngAfterContentChecked() {
|
ngAfterContentChecked() {
|
||||||
if (this.isVisible === false && this._tableContainer.nativeElement.offsetParent !== null) {
|
if (this.isVisible === false && this._tableContainer.nativeElement.offsetParent !== null) {
|
||||||
if (this.prevJobId !== undefined && this.prevJobId !== this.jobId) {
|
if (this.prevJobId !== this.jobId) {
|
||||||
this.loadHistory();
|
this.loadHistory();
|
||||||
this.prevJobId = this.jobId;
|
this.prevJobId = this.jobId;
|
||||||
}
|
}
|
||||||
@@ -91,12 +108,17 @@ export class JobHistoryComponent extends Disposable implements OnInit, OnDestroy
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadHistory() {
|
loadHistory() {
|
||||||
|
const self = this;
|
||||||
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
this._jobManagementService.getJobHistory(ownerUri, this.jobId).then((result) => {
|
this._jobManagementService.getJobHistory(ownerUri, this.jobId).then((result) => {
|
||||||
if (result.jobs) {
|
if (result.jobs) {
|
||||||
let jobHistory = result.jobs;
|
self._treeController.jobHistories = result.jobs;
|
||||||
this._treeDataSource.data = jobHistory.map(job => this.convertToJobHistoryRow(job));
|
let jobHistoryRows = self._treeController.jobHistories.map(job => self.convertToJobHistoryRow(job));
|
||||||
this._tree.setInput(new JobHistoryModel());
|
self._treeDataSource.data = jobHistoryRows;
|
||||||
|
self._tree.setInput(new JobHistoryModel());
|
||||||
|
self.agentJobHistoryInfo = self._treeController.jobHistories[0];
|
||||||
|
self.agentJobHistoryInfo.runDate = self.formatTime(self.agentJobHistoryInfo.runDate);
|
||||||
|
self._cd.detectChanges();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -111,22 +133,26 @@ export class JobHistoryComponent extends Disposable implements OnInit, OnDestroy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private jobAction(action: string): void {
|
private jobAction(action: string, jobName: string): void {
|
||||||
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
this._jobManagementService.jobAction(ownerUri, 'jobName', action);
|
this._jobManagementService.jobAction(ownerUri, jobName, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
private goToJobs(): void {
|
private goToJobs(): void {
|
||||||
|
this.isVisible = false;
|
||||||
this._agentViewComponent.showHistory = false;
|
this._agentViewComponent.showHistory = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private convertToJobHistoryRow(historyInfo: AgentJobHistoryInfo): JobHistoryRow {
|
private convertToJobHistoryRow(historyInfo: AgentJobHistoryInfo): JobHistoryRow {
|
||||||
let jobHistoryRow = {
|
let jobHistoryRow = new JobHistoryRow();
|
||||||
runDate: historyInfo.runDate,
|
jobHistoryRow.runDate = historyInfo.runDate;
|
||||||
runStatus: JobHistoryRow.convertToStatusString(historyInfo.runStatus),
|
jobHistoryRow.runStatus = JobHistoryRow.convertToStatusString(historyInfo.runStatus);
|
||||||
jobID: historyInfo.jobID
|
jobHistoryRow.instanceID = historyInfo.instanceId;
|
||||||
};
|
|
||||||
return jobHistoryRow;
|
return jobHistoryRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private formatTime(time: string): string {
|
||||||
|
return time.replace('T', ' ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ input#accordion:checked ~ .accordion-content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
table.step-list tr.step-row td {
|
table.step-list tr.step-row td {
|
||||||
padding-right: 100px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-details {
|
.history-details {
|
||||||
|
|||||||
@@ -26,11 +26,14 @@ import { generateUuid } from 'vs/base/common/uuid';
|
|||||||
import * as DOM from 'vs/base/browser/dom';
|
import * as DOM from 'vs/base/browser/dom';
|
||||||
import { OEAction } from 'sql/parts/registeredServer/viewlet/objectExplorerActions';
|
import { OEAction } from 'sql/parts/registeredServer/viewlet/objectExplorerActions';
|
||||||
import { Builder, $, withElementById } from 'vs/base/browser/builder';
|
import { Builder, $, withElementById } from 'vs/base/browser/builder';
|
||||||
|
import { AgentJobHistoryInfo } from 'sqlops';
|
||||||
|
import { Agent } from 'vs/base/node/request';
|
||||||
|
|
||||||
export class JobHistoryRow {
|
export class JobHistoryRow {
|
||||||
runDate: string;
|
runDate: string;
|
||||||
runStatus: string;
|
runStatus: string;
|
||||||
jobID: string;
|
instanceID: number;
|
||||||
|
rowID: string = generateUuid();
|
||||||
|
|
||||||
public static convertToStatusString(status: number): string {
|
public static convertToStatusString(status: number): string {
|
||||||
switch(status) {
|
switch(status) {
|
||||||
@@ -47,28 +50,9 @@ export class JobHistoryModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class JobHistoryController extends TreeDefaults.DefaultController {
|
export class JobHistoryController extends TreeDefaults.DefaultController {
|
||||||
|
private _jobHistories: AgentJobHistoryInfo[];
|
||||||
|
|
||||||
protected onLeftClick(tree: tree.ITree, element: JobHistoryRow, event: IMouseEvent, origin: string = 'mouse'): boolean {
|
protected onLeftClick(tree: tree.ITree, element: JobHistoryRow, event: IMouseEvent, origin: string = 'mouse'): boolean {
|
||||||
const payload = { origin: origin };
|
|
||||||
const isDoubleClick = (origin === 'mouse' && event.detail === 2);
|
|
||||||
// Cancel Event
|
|
||||||
const isMouseDown = event && event.browserEvent && event.browserEvent.type === 'mousedown';
|
|
||||||
|
|
||||||
if (!isMouseDown) {
|
|
||||||
event.preventDefault(); // we cannot preventDefault onMouseDown because this would break DND otherwise
|
|
||||||
}
|
|
||||||
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
tree.setFocus(element, payload);
|
|
||||||
|
|
||||||
if (element && isDoubleClick) {
|
|
||||||
event.preventDefault(); // focus moves to editor, we need to prevent default
|
|
||||||
} else {
|
|
||||||
tree.setFocus(element, payload);
|
|
||||||
tree.setSelection([element], payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +60,14 @@ export class JobHistoryController extends TreeDefaults.DefaultController {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public set jobHistories(value: AgentJobHistoryInfo[]) {
|
||||||
|
this._jobHistories = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get jobHistories(): AgentJobHistoryInfo[] {
|
||||||
|
return this._jobHistories;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class JobHistoryDataSource implements tree.IDataSource {
|
export class JobHistoryDataSource implements tree.IDataSource {
|
||||||
@@ -85,7 +77,7 @@ export class JobHistoryDataSource implements tree.IDataSource {
|
|||||||
if (element instanceof JobHistoryModel) {
|
if (element instanceof JobHistoryModel) {
|
||||||
return JobHistoryModel.id;
|
return JobHistoryModel.id;
|
||||||
} else {
|
} else {
|
||||||
return (element as JobHistoryRow).jobID;
|
return (element as JobHistoryRow).rowID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,36 +93,6 @@ export class JobsViewComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadJobHistories() {
|
|
||||||
if (this.jobs) {
|
|
||||||
this.jobs.forEach((job) => {
|
|
||||||
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
|
||||||
this._jobManagementService.getJobHistory(ownerUri, job.jobId).then((result) => {
|
|
||||||
if (result.jobs) {
|
|
||||||
this.jobHistories[job.jobId] = result.jobs;
|
|
||||||
this.expandJobsWithFailures();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private expandJobsWithFailures(): void {
|
|
||||||
for (let i: number = 0; i < this.jobs.length; ++i) {
|
|
||||||
let job = this.jobs[i];
|
|
||||||
let jobHistory = this.jobHistories[job.jobId];
|
|
||||||
if (jobHistory && jobHistory.length > 0) {
|
|
||||||
let latestExecution = jobHistory[jobHistory.length - 1];
|
|
||||||
if (latestExecution.runStatus !== 0) {
|
|
||||||
this.expandJobRowDetails(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private expandJobRowDetails(rowIdx: number): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
onFirstVisible() {
|
onFirstVisible() {
|
||||||
let self = this;
|
let self = this;
|
||||||
let columns = this.columns.map((column) => {
|
let columns = this.columns.map((column) => {
|
||||||
@@ -157,11 +127,6 @@ export class JobsViewComponent implements OnInit, OnDestroy {
|
|||||||
let job = self.getJob(args);
|
let job = self.getJob(args);
|
||||||
self._agentViewComponent.jobId = job.jobId;
|
self._agentViewComponent.jobId = job.jobId;
|
||||||
self._agentViewComponent.agentJobInfo = job;
|
self._agentViewComponent.agentJobInfo = job;
|
||||||
self.getJobHistoryInfo(ownerUri, job).then(result => {
|
|
||||||
if (result) {
|
|
||||||
this._agentViewComponent.agentJobHistoryInfo = result;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
self.isVisible = false;
|
self.isVisible = false;
|
||||||
self._agentViewComponent.showHistory = true;
|
self._agentViewComponent.showHistory = true;
|
||||||
});
|
});
|
||||||
@@ -176,22 +141,6 @@ export class JobsViewComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getJobHistoryInfo(ownerUri: string, job: any): Thenable<sqlops.AgentJobHistoryInfo[]> {
|
|
||||||
return new Promise<sqlops.AgentJobHistoryInfo[]>((resolve, reject) => {
|
|
||||||
if (this.jobHistories[job.jobId]){
|
|
||||||
Promise.resolve(this.jobHistories[job.jobId]);
|
|
||||||
} else {
|
|
||||||
this._jobManagementService.getJobHistory(ownerUri, job.jobId).then(result => {
|
|
||||||
if (result && result.jobs) {
|
|
||||||
Promise.resolve(result.jobs);
|
|
||||||
} else {
|
|
||||||
Promise.reject(undefined);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onJobsAvailable(jobs: sqlops.AgentJobInfo[]) {
|
onJobsAvailable(jobs: sqlops.AgentJobInfo[]) {
|
||||||
let jobViews = jobs.map((job) => {
|
let jobViews = jobs.map((job) => {
|
||||||
return {
|
return {
|
||||||
@@ -225,7 +174,6 @@ export class JobsViewComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
this._table.resizeCanvas();
|
this._table.resizeCanvas();
|
||||||
this._table.autosizeColumns();
|
this._table.autosizeColumns();
|
||||||
|
|
||||||
this.loadJobHistories();
|
this.loadJobHistories();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,6 +194,19 @@ export class JobsViewComponent implements OnInit, OnDestroy {
|
|||||||
'</tr></table>';
|
'</tr></table>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadJobHistories() {
|
||||||
|
if (this.jobs) {
|
||||||
|
this.jobs.forEach((job) => {
|
||||||
|
let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
|
||||||
|
this._jobManagementService.getJobHistory(ownerUri, job.jobId).then((result) => {
|
||||||
|
if (result.jobs) {
|
||||||
|
this.jobHistories[job.jobId] = result.jobs;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private getJob(args: Slick.OnClickEventArgs<any>): sqlops.AgentJobInfo {
|
private getJob(args: Slick.OnClickEventArgs<any>): sqlops.AgentJobInfo {
|
||||||
let cell = args.cell;
|
let cell = args.cell;
|
||||||
let jobName = args.grid.getCellNode(1, cell).innerText.trim();
|
let jobName = args.grid.getCellNode(1, cell).innerText.trim();
|
||||||
|
|||||||
10
src/sql/sqlops.d.ts
vendored
10
src/sql/sqlops.d.ts
vendored
@@ -1061,13 +1061,13 @@ declare module 'sqlops' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentJobHistoryInfo {
|
export interface AgentJobHistoryInfo {
|
||||||
instanceID: number;
|
instanceId: number;
|
||||||
sqlMessageID: number;
|
sqlMessageId: number;
|
||||||
message: string;
|
message: string;
|
||||||
stepID: number;
|
stepId: number;
|
||||||
stepName: string;
|
stepName: string;
|
||||||
sqlSeverity: number;
|
sqlSeverity: number;
|
||||||
jobID: string;
|
jobId: string;
|
||||||
jobName: string;
|
jobName: string;
|
||||||
runStatus: number;
|
runStatus: number;
|
||||||
runDate: string;
|
runDate: string;
|
||||||
@@ -1081,7 +1081,7 @@ declare module 'sqlops' {
|
|||||||
|
|
||||||
export interface AgentServicesProvider extends DataProvider {
|
export interface AgentServicesProvider extends DataProvider {
|
||||||
getJobs(connectionUri: string): Thenable<AgentJobsResult>;
|
getJobs(connectionUri: string): Thenable<AgentJobsResult>;
|
||||||
getJobHistory(connectionUri: string, jobID: string): Thenable<AgentJobHistoryResult>;
|
getJobHistory(connectionUri: string, jobId: string): Thenable<AgentJobHistoryResult>;
|
||||||
jobAction(connectionUri: string, jobName: string, action: string): Thenable<AgentJobActionResult>;
|
jobAction(connectionUri: string, jobName: string, action: string): Thenable<AgentJobActionResult>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user