;
}
+
+export interface IAgentJobCacheService {
+ _serviceBrand: any;
+
+ jobs: sqlops.AgentJobInfo[];
+
+ jobHistories: { [jobId: string]: sqlops.AgentJobHistoryInfo[]; };
+
+ prevJobID: string;
+
+ getJobHistory(jobID: string): sqlops.AgentJobHistoryInfo[];
+
+ setJobHistory(jobID: string, value: sqlops.AgentJobHistoryInfo[]);
+}
\ No newline at end of file
diff --git a/src/sql/parts/jobManagement/common/media/jobs.css b/src/sql/parts/jobManagement/common/media/jobs.css
index eed821245c..e946d5f10f 100644
--- a/src/sql/parts/jobManagement/common/media/jobs.css
+++ b/src/sql/parts/jobManagement/common/media/jobs.css
@@ -132,3 +132,7 @@ jobhistory-component {
.vs-dark .jobsview-icon {
content: url('./job_inverse.svg');
}
+
+agentview-component .tabbedPanel .tabList .tab .tabLabel.icon {
+ padding: 20px 15px !important;
+}
\ No newline at end of file
diff --git a/src/sql/parts/jobManagement/views/jobHistory.component.html b/src/sql/parts/jobManagement/views/jobHistory.component.html
index 96b92c9947..9764e56ec1 100644
--- a/src/sql/parts/jobManagement/views/jobHistory.component.html
+++ b/src/sql/parts/jobManagement/views/jobHistory.component.html
@@ -114,7 +114,7 @@
Job ID:
|
- {{agentJobHistoryInfo?.jobId}}
+ {{agentJobHistoryInfo?.jobId || agentJobInfo?.jobId}}
|
diff --git a/src/sql/parts/jobManagement/views/jobHistory.component.ts b/src/sql/parts/jobManagement/views/jobHistory.component.ts
index f6edf9f762..d73e18d077 100644
--- a/src/sql/parts/jobManagement/views/jobHistory.component.ts
+++ b/src/sql/parts/jobManagement/views/jobHistory.component.ts
@@ -5,7 +5,7 @@
import 'vs/css!./jobHistory';
-import { OnInit, OnChanges, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild, Input, Injectable } from '@angular/core';
+import { OnInit, OnChanges, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild, Input, Injectable, ChangeDetectionStrategy } from '@angular/core';
import { AgentJobHistoryInfo, AgentJobInfo } from 'sqlops';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { attachListStyler } from 'vs/platform/theme/common/styler';
@@ -14,7 +14,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { PanelComponent } from 'sql/base/browser/ui/panel/panel.component';
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
-import { IJobManagementService } from '../common/interfaces';
+import { IJobManagementService, IAgentJobCacheService } from '../common/interfaces';
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
import { JobHistoryController, JobHistoryDataSource,
@@ -29,28 +29,31 @@ export const DASHBOARD_SELECTOR: string = 'jobhistory-component';
@Component({
selector: DASHBOARD_SELECTOR,
- templateUrl: decodeURI(require.toUrl('./jobHistory.component.html'))
+ templateUrl: decodeURI(require.toUrl('./jobHistory.component.html')),
+ changeDetection: ChangeDetectionStrategy.OnPush
})
export class JobHistoryComponent extends Disposable implements OnInit {
private _jobManagementService: IJobManagementService;
private _tree: Tree;
- private _treeController = new JobHistoryController();
- private _treeDataSource = new JobHistoryDataSource();
- private _treeRenderer = new JobHistoryRenderer();
- private _treeFilter = new JobHistoryFilter();
+ private _treeController: JobHistoryController;
+ private _treeDataSource: JobHistoryDataSource;
+ private _treeRenderer: JobHistoryRenderer;
+ private _treeFilter: JobHistoryFilter;
@ViewChild('table') private _tableContainer: ElementRef;
@Input() public agentJobInfo: AgentJobInfo = undefined;
@Input() public jobId: string = undefined;
- @Input() public agentJobHistoryInfo: AgentJobHistoryInfo = undefined;
+ @Input() public agentJobHistories: AgentJobHistoryInfo[] = undefined;
+ public agentJobHistoryInfo: AgentJobHistoryInfo = undefined;
- private _prevJobId: string = undefined;
private _isVisible: boolean = false;
private _stepRows: JobStepsViewRow[] = [];
private _showSteps: boolean = false;
private _runStatus: string = undefined;
+ private _messageService: IMessageService;
+ private _agentJobCacheService: IAgentJobCacheService;
private _notificationService: INotificationService;
constructor(
@@ -61,7 +64,13 @@ export class JobHistoryComponent extends Disposable implements OnInit {
@Inject(forwardRef(() => AgentViewComponent)) private _agentViewComponent: AgentViewComponent
) {
super();
+ this._treeController = new JobHistoryController();
+ this._treeDataSource = new JobHistoryDataSource();
+ this._treeRenderer = new JobHistoryRenderer();
+ this._treeFilter = new JobHistoryFilter();
this._jobManagementService = bootstrapService.jobManagementService;
+ this._messageService = bootstrapService.messageService;
+ this._agentJobCacheService = bootstrapService.agentJobCacheService;
this._notificationService = bootstrapService.notificationService;
}
@@ -115,10 +124,24 @@ export class JobHistoryComponent extends Disposable implements OnInit {
ngAfterContentChecked() {
if (this._isVisible === false && this._tableContainer.nativeElement.offsetParent !== null) {
- if (this._prevJobId !== this.jobId) {
+ this._isVisible = true;
+ if (this.agentJobHistories && this.agentJobHistories.length > 0) {
+ if (this._agentJobCacheService.prevJobID === this.jobId || this.agentJobHistories[0].jobId === this.jobId) {
+ this.agentJobHistoryInfo = this.agentJobHistories[0];
+ this.agentJobHistoryInfo.runDate = this.formatTime(this.agentJobHistories[0].runDate);
+ this._treeController.jobHistories = this.agentJobHistories;
+ this._agentJobCacheService.setJobHistory(this.jobId, this.agentJobHistories);
+ let jobHistoryRows = this._treeController.jobHistories.map(job => this.convertToJobHistoryRow(job));
+ this._treeDataSource.data = jobHistoryRows;
+ this._tree.setInput(new JobHistoryModel());
+ this._cd.detectChanges();
+ }
+ } else {
this.loadHistory();
- this._prevJobId = this.jobId;
}
+ this._agentJobCacheService.prevJobID = this.jobId;
+ } else if (this._isVisible === true && this._tableContainer.nativeElement.offsetParent === null) {
+ this._isVisible = false;
}
}
@@ -128,6 +151,7 @@ export class JobHistoryComponent extends Disposable implements OnInit {
this._jobManagementService.getJobHistory(ownerUri, this.jobId).then((result) => {
if (result && result.jobs) {
self._treeController.jobHistories = result.jobs;
+ self._agentJobCacheService.setJobHistory(self.jobId, result.jobs);
let jobHistoryRows = self._treeController.jobHistories.map(job => self.convertToJobHistoryRow(job));
self._treeDataSource.data = jobHistoryRows;
self._tree.setInput(new JobHistoryModel());
diff --git a/src/sql/parts/jobManagement/views/jobsView.component.ts b/src/sql/parts/jobManagement/views/jobsView.component.ts
index 3eac711029..679131e586 100644
--- a/src/sql/parts/jobManagement/views/jobsView.component.ts
+++ b/src/sql/parts/jobManagement/views/jobsView.component.ts
@@ -11,16 +11,15 @@ import 'vs/css!sql/parts/grid/media/slickGrid';
import 'vs/css!../common/media/jobs';
import 'vs/css!../common/media/detailview';
-import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild } from '@angular/core';
+import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, Input } from '@angular/core';
import * as Utils from 'sql/parts/connection/common/utils';
-import { RefreshWidgetAction, EditDashboardAction } from 'sql/parts/dashboard/common/actions';
import { IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { IDisposable } from 'vs/base/common/lifecycle';
import * as themeColors from 'vs/workbench/common/theme';
import { DashboardPage } from 'sql/parts/dashboard/common/dashboardPage.component';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
-import { IJobManagementService } from '../common/interfaces';
+import { IJobManagementService, IAgentJobCacheService } from '../common/interfaces';
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
import * as sqlops from 'sqlops';
import * as vscode from 'vscode';
@@ -32,6 +31,7 @@ import { attachTableStyler } from 'sql/common/theme/styler';
import { JobHistoryComponent } from './jobHistory.component';
import { AgentViewComponent } from '../agent/agentView.component';
import { RowDetailView } from 'sql/base/browser/ui/table/plugins/rowdetailview';
+import { AgentJobCacheService } from 'sql/parts/jobManagement/common/agentJobCacheService';
export const JOBSVIEW_SELECTOR: string = 'jobsview-component';
@@ -39,9 +39,10 @@ export const JOBSVIEW_SELECTOR: string = 'jobsview-component';
selector: JOBSVIEW_SELECTOR,
templateUrl: decodeURI(require.toUrl('./jobsView.component.html'))
})
-export class JobsViewComponent implements OnInit, OnDestroy {
+export class JobsViewComponent {
private _jobManagementService: IJobManagementService;
+ private _jobCacheService: IAgentJobCacheService;
private _disposables = new Array();
@@ -64,11 +65,8 @@ export class JobsViewComponent implements OnInit, OnDestroy {
@ViewChild('jobsgrid') _gridEl: ElementRef;
private isVisible: boolean = false;
private isInitialized: boolean = false;
-
private _table: Table;
-
public jobs: sqlops.AgentJobInfo[];
-
public jobHistories: { [jobId: string]: sqlops.AgentJobHistoryInfo[]; } = Object.create(null);
constructor(
@@ -79,21 +77,28 @@ export class JobsViewComponent implements OnInit, OnDestroy {
@Inject(forwardRef(() => AgentViewComponent)) private _agentViewComponent: AgentViewComponent
) {
this._jobManagementService = bootstrapService.jobManagementService;
+ this._jobCacheService = bootstrapService.agentJobCacheService;
}
ngAfterContentChecked() {
if (this.isVisible === false && this._gridEl.nativeElement.offsetParent !== null) {
this.isVisible = true;
if (!this.isInitialized) {
- this.onFirstVisible();
- this.isInitialized = true;
+ if (this._jobCacheService.jobs !== undefined) {
+ this.jobs = this._jobCacheService.jobs;
+ this.onFirstVisible(true);
+ this.isInitialized = true;
+ } else {
+ this.onFirstVisible(false);
+ this.isInitialized = true;
+ }
}
} else if (this.isVisible === true && this._gridEl.nativeElement.offsetParent === null) {
this.isVisible = false;
}
}
- onFirstVisible() {
+ onFirstVisible(cached?: boolean) {
let self = this;
let columns = this.columns.map((column) => {
column.rerenderOnResize = true;
@@ -128,17 +133,26 @@ export class JobsViewComponent implements OnInit, OnDestroy {
self._agentViewComponent.jobId = job.jobId;
self._agentViewComponent.agentJobInfo = job;
self.isVisible = false;
- self._agentViewComponent.showHistory = true;
+ if (self._jobCacheService.getJobHistory(job.jobId)) {
+ self._agentViewComponent.agentJobHistories = self._jobCacheService.getJobHistory(job.jobId);
+ }
+ setTimeout(() => {
+ self._agentViewComponent.showHistory = true;
+ }, 500);
});
this._cd.detectChanges();
-
- let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
- this._jobManagementService.getJobs(ownerUri).then((result) => {
- if (result && result.jobs) {
- this.jobs = result.jobs;
- this.onJobsAvailable(result.jobs);
- }
- });
+ if (cached) {
+ this.onJobsAvailable(this._jobCacheService.jobs);
+ } else {
+ let ownerUri: string = this._dashboardService.connectionManagementService.connectionInfo.ownerUri;
+ this._jobManagementService.getJobs(ownerUri).then((result) => {
+ if (result && result.jobs) {
+ this.jobs = result.jobs;
+ this._jobCacheService.jobs = this.jobs;
+ this.onJobsAvailable(result.jobs);
+ }
+ });
+ }
}
onJobsAvailable(jobs: sqlops.AgentJobInfo[]) {
@@ -177,12 +191,6 @@ export class JobsViewComponent implements OnInit, OnDestroy {
this.loadJobHistories();
}
- ngOnInit() {
- }
-
- ngOnDestroy() {
- }
-
loadingTemplate() {
return 'Loading...
';
}
@@ -201,6 +209,7 @@ export class JobsViewComponent implements OnInit, OnDestroy {
this._jobManagementService.getJobHistory(ownerUri, job.jobId).then((result) => {
if (result.jobs) {
this.jobHistories[job.jobId] = result.jobs;
+ this._jobCacheService.setJobHistory(job.jobId, result.jobs);
}
});
});
diff --git a/src/sql/services/bootstrap/bootstrapService.ts b/src/sql/services/bootstrap/bootstrapService.ts
index d8001c721a..415b47ce57 100644
--- a/src/sql/services/bootstrap/bootstrapService.ts
+++ b/src/sql/services/bootstrap/bootstrapService.ts
@@ -40,7 +40,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ConfigurationEditingService } from 'vs/workbench/services/configuration/node/configurationEditingService';
import { ICommandService } from 'vs/platform/commands/common/commands';
-import { IJobManagementService } from 'sql/parts/jobManagement/common/interfaces';
+import { IJobManagementService, IAgentJobCacheService } from 'sql/parts/jobManagement/common/interfaces';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { INotificationService } from 'vs/platform/notification/common/notification';
@@ -95,6 +95,7 @@ export interface IBootstrapService {
commandService: ICommandService;
dashboardWebviewService: IDashboardWebviewService;
jobManagementService: IJobManagementService;
+ agentJobCacheService: IAgentJobCacheService;
environmentService: IEnvironmentService;
/*
diff --git a/src/sql/services/bootstrap/bootstrapServiceImpl.ts b/src/sql/services/bootstrap/bootstrapServiceImpl.ts
index 9c9cbf274a..6d09882f41 100644
--- a/src/sql/services/bootstrap/bootstrapServiceImpl.ts
+++ b/src/sql/services/bootstrap/bootstrapServiceImpl.ts
@@ -44,7 +44,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ConfigurationEditingService } from 'vs/workbench/services/configuration/node/configurationEditingService';
import { ICommandService } from 'vs/platform/commands/common/commands';
-import { IJobManagementService } from 'sql/parts/jobManagement/common/interfaces';
+import { IJobManagementService, IAgentJobCacheService } from 'sql/parts/jobManagement/common/interfaces';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { INotificationService } from 'vs/platform/notification/common/notification';
@@ -104,6 +104,7 @@ export class BootstrapService implements IBootstrapService {
@ICommandService public commandService: ICommandService,
@IDashboardWebviewService public dashboardWebviewService: IDashboardWebviewService,
@IJobManagementService public jobManagementService: IJobManagementService,
+ @IAgentJobCacheService public agentJobCacheService: IAgentJobCacheService
@IEnvironmentService public environmentService: IEnvironmentService
) {
this.configurationEditorService = this.instantiationService.createInstance(ConfigurationEditingService);
diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts
index 5ca2aa82c4..747b319278 100644
--- a/src/vs/workbench/electron-browser/workbench.ts
+++ b/src/vs/workbench/electron-browser/workbench.ts
@@ -130,8 +130,9 @@ import { IQueryManagementService, QueryManagementService } from 'sql/parts/query
import { IEditorDescriptorService, EditorDescriptorService } from 'sql/parts/query/editor/editorDescriptorService';
import { IScriptingService, ScriptingService } from 'sql/services/scripting/scriptingService';
import { IAdminService, AdminService } from 'sql/parts/admin/common/adminService';
-import { IJobManagementService } from 'sql/parts/jobManagement/common/interfaces';
+import { IJobManagementService, IAgentJobCacheService } from 'sql/parts/jobManagement/common/interfaces';
import { JobManagementService } from 'sql/parts/jobManagement/common/jobManagementService';
+import { AgentJobCacheService } from 'sql/parts/jobManagement/common/agentJobCacheService';
import { IBackupService, IBackupUiService } from 'sql/parts/disasterRecovery/backup/common/backupService';
import { BackupService, BackupUiService } from 'sql/parts/disasterRecovery/backup/common/backupServiceImp';
import { IRestoreDialogController, IRestoreService } from 'sql/parts/disasterRecovery/restore/common/restoreService';
@@ -702,6 +703,7 @@ export class Workbench implements IPartService {
serviceCollection.set(IScriptingService, this.instantiationService.createInstance(ScriptingService));
serviceCollection.set(IAdminService, this.instantiationService.createInstance(AdminService));
serviceCollection.set(IJobManagementService, this.instantiationService.createInstance(JobManagementService));
+ serviceCollection.set(IAgentJobCacheService, this.instantiationService.createInstance(AgentJobCacheService));
serviceCollection.set(IBackupService, this.instantiationService.createInstance(BackupService));
serviceCollection.set(IBackupUiService, this.instantiationService.createInstance(BackupUiService));
serviceCollection.set(IRestoreService, this.instantiationService.createInstance(RestoreService));