Skip to content

Commit a269f53

Browse files
authored
added Abort Job button to the top-level Job Details page [BA-5370] (#657)
1 parent 42a1c33 commit a269f53

File tree

6 files changed

+47
-2
lines changed

6 files changed

+47
-2
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Job Manager Change Log
22

3+
## v1.2.2 Release Notes
4+
5+
### Added 'Abort Job' button to Job Details page.
6+
37
## v1.2.1 Release Notes
48

59
### Added logic to avoid 500 error on Job Details page when a task does not have a start time.

ui/src/app/job-details/job-details.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ describe('JobDetailsComponent', () => {
4949
let fixture: ComponentFixture<TestJobDetailsComponent>;
5050
let router: Router;
5151
let fakeJobService: FakeJobManagerService;
52-
let snackBar: MatSnackBar;
5352

5453
const jobId = '123';
5554
function testJob(): JobMetadataResponse {
@@ -65,7 +64,7 @@ describe('JobDetailsComponent', () => {
6564
beforeEach(async(() => {
6665
fakeJobService = new FakeJobManagerService([testJob()]);
6766
let fakeCapabilitiesService: FakeCapabilitiesService = new FakeCapabilitiesService({});
68-
let authService = new AuthService(null, fakeCapabilitiesService, null, snackBar);
67+
let authService = new AuthService(null, fakeCapabilitiesService, null, null);
6968
let settingsService: SettingsService = new SettingsService(authService, fakeCapabilitiesService, localStorage);
7069

7170
TestBed.configureTestingModule({
@@ -115,6 +114,7 @@ describe('JobDetailsComponent', () => {
115114
{provide: SettingsService, useValue: settingsService},
116115
{provide: CapabilitiesService, useValue: fakeCapabilitiesService},
117116
{provide: AuthService, useValue: authService},
117+
{provide: MatSnackBar},
118118
JobDetailsResolver
119119
],
120120
}).compileComponents();

ui/src/app/job-details/panels/panels.component.css

+7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ p {
2626
height: 2.25rem;
2727
}
2828

29+
button.mat-raised-button {
30+
background-color: #74AE43;
31+
color: #fff;
32+
font-weight: 500;
33+
text-transform: uppercase;
34+
}
35+
2936
.job-id {
3037
margin-bottom: 0.5rem;
3138
}

ui/src/app/job-details/panels/panels.component.html

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
</clr-tooltip-content>
1919
</clr-tooltip>
2020
</button>
21+
<button *ngIf="canAbort()" (click)="abortJob()" class="close mat-raised-button">Abort job</button>
2122
<p class="job-id">ID: <b>{{ job.id }}</b></p>
2223
<div *ngIf="hasPrimaryLabels()" class="job-labels">
2324
<span class="label" *ngFor="let l of primaryLabels">

ui/src/app/job-details/panels/panels.component.spec.ts

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
MatCardModule,
88
MatGridListModule,
99
MatMenuModule,
10+
MatSnackBar,
1011
MatTabsModule,
1112
MatTableModule
1213
} from '@angular/material';
@@ -17,6 +18,8 @@ import {JobMetadataResponse} from '../../shared/model/JobMetadataResponse';
1718
import {JobPanelsComponent} from './panels.component';
1819
import {JobFailuresTableComponent} from "../common/failures-table/failures-table.component";
1920
import {JobDebugIconsComponent} from "../common/debug-icons/debug-icons.component";
21+
import {JobManagerService} from "../../core/job-manager.service";
22+
import {FakeJobManagerService} from "../../testing/fake-job-manager.service";
2023

2124
describe('JobPanelsComponent', () => {
2225

@@ -43,6 +46,7 @@ describe('JobPanelsComponent', () => {
4346
statusDetail: 'success',
4447
}
4548
};
49+
let fakeJobService = new FakeJobManagerService([minimalJob, completeJob]);
4650

4751
beforeEach(async(() => {
4852
TestBed.configureTestingModule({
@@ -64,6 +68,10 @@ describe('JobPanelsComponent', () => {
6468
MatTableModule,
6569
SharedModule
6670
],
71+
providers: [
72+
{provide: JobManagerService, useValue: fakeJobService},
73+
{provide: MatSnackBar},
74+
]
6775
}).compileComponents();
6876
}));
6977

ui/src/app/job-details/panels/panels.component.ts

+25
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import {JobStatus} from '../../shared/model/JobStatus';
1212
import {JobFailuresTableComponent} from "../common/failures-table/failures-table.component";
1313
import {JobStatusIcon} from "../../shared/common";
1414
import {DisplayField} from "../../shared/model/DisplayField";
15+
import {JobManagerService} from "../../core/job-manager.service";
16+
import {MatSnackBar} from "@angular/material";
17+
import {ErrorMessageFormatterPipe} from "../../shared/pipes/error-message-formatter.pipe";
1518

1619
@Component({
1720
selector: 'jm-panels',
@@ -38,6 +41,10 @@ export class JobPanelsComponent implements OnInit {
3841
numTasks: number = 0;
3942
public readonly numOfErrorsToShow = 4;
4043

44+
constructor(
45+
private readonly snackBar: MatSnackBar,
46+
private readonly jobManagerService: JobManagerService) { }
47+
4148
ngOnInit() {
4249
this.setUpExtensions();
4350
if (this.job.labels) {
@@ -115,4 +122,22 @@ export class JobPanelsComponent implements OnInit {
115122
getStatusIcon(status: JobStatus): string {
116123
return JobStatusIcon[status];
117124
}
125+
126+
abortJob() {
127+
this.jobManagerService.abortJob(this.job.id)
128+
.then(() => {
129+
window.location.reload();
130+
})
131+
.catch((error) => this.handleError(error));
132+
}
133+
134+
canAbort(): boolean {
135+
return !this.hasParent() && (this.job.status == JobStatus.Submitted || this.job.status == JobStatus.Running);
136+
}
137+
138+
handleError(error: any) {
139+
this.snackBar.open(
140+
new ErrorMessageFormatterPipe().transform(error),
141+
'Dismiss');
142+
}
118143
}

0 commit comments

Comments
 (0)