"...execution/gitlab@gitlab.nrao.edu:ssa/vlass-manager-ui.git" did not exist on "c900e4ffc585802286bd11d91b0d25eb09462d23"
Newer
Older

Reid Givens
committed
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
import {Job, JobExecution} from "../../../model/job";
import {Subject, Observable} from "rxjs";
import {JobsService} from "../../../services/jobs.service";
import {FormControl, FormGroup} from "@angular/forms";
import {ConfigurationService} from "../../../env/configuration.service";
import {faCheckCircle, faCopy, faList, faSave, faStickyNote} from "@fortawesome/free-solid-svg-icons";
import {AlertService} from "../../../services/alert.service";

Reid Givens
committed
import {auditTime, takeUntil} from "rxjs/operators";
@Component({
selector: 'app-execution-detail',
templateUrl: './execution-detail.component.html',
styleUrls: ['./execution-detail.component.scss']
})
export class ExecutionDetailComponent implements OnInit, OnDestroy {
noteFormGroup = new FormGroup({
notes: new FormControl(),
id: new FormControl()
});
planesFormGroup = new FormGroup({});

Reid Givens
committed
private ngUnsubscribe = new Subject<void>();

Reid Givens
committed
@Output() reload = new EventEmitter();
public jobDetail: JobExecution;
public faSave = faSave;
public faList = faList;
public faCheckCircle = faCheckCircle;
public faStickyNote = faStickyNote;
public faCopy = faCopy;
public weblogUrl: string;
planes: Observable<string>;
planeKeys: string[];

Daniel Nemergut
committed
constructor(
private configService: ConfigurationService,
private jobService: JobsService,
private alertService: AlertService
) {
}
ngOnInit() {

Reid Givens
committed
this.jobService.getJobExecution(this.job.job_id).pipe(takeUntil(this.ngUnsubscribe)).subscribe((j: JobExecution) => {
if (j) {
this.jobDetail = j;
this.noteFormGroup.get('notes').setValue(j.notes);
this.noteFormGroup.get('id').setValue(j.id);

Daniel Nemergut
committed
this.loadWeblogUrl();

Reid Givens
committed
// autosave the form on changes
this.noteFormGroup.valueChanges.pipe(auditTime(2000),takeUntil(this.ngUnsubscribe)).subscribe(() => this.updateNotes());
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
}
copyToClipboard(text: string): void {
const selBox = document.createElement('textarea');
selBox.style.position = 'fixed';
selBox.style.left = '0';
selBox.style.top = '0';
selBox.style.opacity = '0';
selBox.value = text;
document.body.appendChild(selBox);
selBox.focus();
selBox.select();
document.execCommand('copy');
document.body.removeChild(selBox);
}
getTaskStatusBgClass(status: string) {
switch (status) {
case 'ERROR':
return 'badge-danger';
case 'SUCCESS':
return 'badge-success';
default:
return 'badge-info';
}
}
canAcceptArchive(status: string, archiveStatus: string): boolean {
if (status === 'QA_READY' || status === 'QA_MANUAL' || archiveStatus === 'ARCHIVE_ERROR') {
return true;
} else {
return false;
}
}
getConfigRootDataDirectory(): string {
return this.configService.config.rootDataDirectory;
}
getConfigWebLogBaseUrl(): string {
return this.configService.config.weblogbaseurl;
}

Daniel Nemergut
committed
loadWeblogUrl(): void {
// The base URL opens up to a file navigation URL, that's the default if the service doesn't find a pipeline directory
let weblogUrl = this.getConfigWebLogBaseUrl() + '/vlass/weblog/' + this.jobDetail.queueName + '/' + this.job.job_name;

Daniel Nemergut
committed
this.jobService.getWeblogLink(this.job.job_id).subscribe(response => {
// Append the pipeline directory and /html to the base weblog URL (both contained in the response)

Daniel Nemergut
committed
if (response !== null && response.body !== null && response.body !== '') {

Daniel Nemergut
committed
weblogUrl = weblogUrl + '/' + response.body;

Daniel Nemergut
committed
}
},
error => {
this.alertService.error('Could not find a pipeline dir, using the base weblog URL.');
},
() => {
this.weblogUrl = weblogUrl;
});
}
updateNotes() {
this.alertService.info('Saving Notes');
let notes = this.noteFormGroup.get('notes').value;
let id = this.noteFormGroup.get('id').value;
this.jobService.updateNotes(id, notes).subscribe(response => {
this.alertService.success('Notes Saved');
},
error => {
this.alertService.error('Notes did not save. ' + error);
});
}
acceptQa() {
if (this.canSelectPlanes()) {
this.acceptPlanes();
}

Reid Givens
committed
this.updateNotes(); // make sure notes are saved before submitting

Reid Givens
committed
this.alertService.info('Accepting ' + this.job.job_id);
this.performQa(this.job.job_id, 'accept');
}
rejectQa() {
let yesno = confirm("Are you sure you want to reject this image?");
if (yesno) {

Reid Givens
committed
this.alertService.info('Rejecting ' + this.job.job_id);
this.performQa(this.job.job_id, 'reject');
}
}
performQa(id: number, status: string) {
//console.log(status + 'ing QA');
let newStatus;
if (status == 'accept' && (this.job.job_status === 'QA_READY' || this.job.job_status === 'QA_MANUAL')) {
newStatus = 'QA_ACCEPTED';
} else if (status == 'reject' && (this.job.job_status === 'QA_READY' || this.job.job_status === 'QA_MANUAL')) {
newStatus = 'QA_REJECTED';
}
if (['QA_ACCEPTED', 'QA_MANUAL_ACCEPTED', 'QA_REJECTED', 'QA_MANUAL_REJECTED'].indexOf(newStatus) > -1) {

Reid Givens
committed
this.jobService.performQA(this.job.job_id, newStatus, this.jobDetail.queueName).subscribe(response => {

Reid Givens
committed
this.alertService.success('QA Performed for ' + id);
this.reload.emit('reload');
}, error => {
this.alertService.error('QA Failed for ' + id);
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
canSelectPlanes(): boolean {
return this.jobDetail.queueName === 'se_continuum_cube_imaging';
}
// Reads plane names from a JSON file and returns them in a list
getPlaneKeys(): string[] {
// Return the plane names if we already fetched them
if (this.planeKeys !== null) {
return this.planeKeys;
}
this.planeKeys = [];
// Get the plane names from the spectral window numbers in the planes.json file
this.jobService.getPlanes(this.job.job_id).subscribe(response => {
this.planeKeys = Object.keys(response.body);
// Create a form control for each of the plane checkboxes and add them into the same group
this.planeKeys.forEach(control => this.planesFormGroup.addControl(control, new FormControl(true)));
// Set the planes data here to signal that the controls are done being added and the HTML can finish loading
this.planes = response.body;
},
error => {
this.alertService.error('Could not retrieve planes from planes.json. ' + error);
});
return this.planeKeys;
}
// Writes to a file in lustre to flag planes to be accepted
acceptPlanes(): void {
this.alertService.info('Flagging accepted planes to be cached');
// Collect the selected planes and write their names separated by a newline
let planesText = '';
const planes = this.planesFormGroup.value;
Object.keys(planes).forEach(key => {
if (planes[key] === true) {
planesText += key + '\n';
}
});
planesText = planesText.trim();
// Write out the planes string if any are selected
if (planesText.length > 0) {
this.jobService.writePlanes(this.job.job_id, planesText).subscribe(
result => {},
error => {
this.alertService.error('Planes did not save. ' + error);
},
() => {
this.alertService.success('Planes Saved');
});
}
}

Reid Givens
committed
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();