Skip to content
Snippets Groups Projects
Commit b4ec85bd authored by Sam Kagan's avatar Sam Kagan
Browse files

Moved Planes checklist into execution-detail component

parent d9ec9d7d
No related branches found
No related tags found
2 merge requests!25Merge 2.4.3 UI to main,!21Added tiles checklist for Accept-and-Archiving calibration jobs
......@@ -33,7 +33,6 @@ import {JobspecTargetComponent} from './jobspecs/jobspec/jobspec-detail/jobspec-
import {JobspecInputComponent} from './jobspecs/jobspec/jobspec-detail/jobspec-input/jobspec-input.component';
import {JobspecExecutionComponent} from './jobspecs/jobspec/jobspec-detail/jobspec-execution/jobspec-execution.component';
import {ExecutionDetailComponent} from './executions/execution/execution-detail/execution-detail.component';
import {ExecutionDetailPlanesComponent} from './executions/execution/execution-detail/execution-detail-planes/execution-detail-planes.component';
import {FontAwesomeModule} from "@fortawesome/angular-fontawesome";
import {LoadingComponent} from './loading/loading.component';
import {QueueSettingsComponent} from './settings/queue-settings/queue-settings.component';
......@@ -77,7 +76,6 @@ export function init_app(configService: ConfigurationService) {
JobspecInputComponent,
JobspecExecutionComponent,
ExecutionDetailComponent,
ExecutionDetailPlanesComponent,
LoadingComponent,
QueueSettingsComponent,
FutureProductComponent,
......
<form [formGroup]="planesFormGroup" (ngSubmit)="acceptPlanes()" class="mb-2">
<h4 class="pt-2 border-top">
Planes
</h4>
<div class="w-100" *ngFor="let plane of getPlaneKeys()">
<label><input type="checkbox" [formControlName]="plane" value="{{plane}}" checked/>{{plane}}</label>
</div>
<button type="submit" class="btn btn-success btn-sm">
Accept &amp; Archive Selected Planes
</button>
</form>
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ExecutionDetailPlanesComponent} from './execution-detail-planes.component';
describe('ExecutionDetailPlanesComponent', () => {
let component: ExecutionDetailPlanesComponent;
let fixture: ComponentFixture<ExecutionDetailPlanesComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ExecutionDetailPlanesComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ExecutionDetailPlanesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import {Component, EventEmitter, Input, Output, OnDestroy, OnInit} from '@angular/core';
import {FormControl, FormGroup} from '@angular/forms';
import {AlertService} from '../../../../services/alert.service';
import {JobsService} from '../../../../services/jobs.service';
import {Job} from '../../../../model/job';
import {Observable} from 'rxjs';
@Component({
selector: 'app-execution-detail-planes',
templateUrl: './execution-detail-planes.component.html',
styleUrls: ['./execution-detail-planes.component.scss']
})
export class ExecutionDetailPlanesComponent implements OnInit, OnDestroy {
@Input() job: Job;
@Output() planesWritten: EventEmitter<any> = new EventEmitter();
planes: Observable<string>;
planeKeys: string[];
planesFormGroup: FormGroup;
constructor(
private jobService: JobsService,
private alertService: AlertService
) {
// Form group to contain the plane checkboxes
this.planesFormGroup = new FormGroup({});
this.planeKeys = null;
}
ngOnInit(): void {
}
ngOnDestroy(): void {
}
// 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);
},
() => {
// Trigger acceptQa on the parent if there were no errors during the save
this.planesWritten.emit();
this.alertService.success('Planes Saved');
});
}
}
}
<ng-container *ngIf="jobDetail; else loading">
<div class="row no-gutters" *ngIf="jobDetail.queueName !== 'se_coarse_cube_imaging' && canAcceptArchive(jobDetail.status, jobDetail.archiveStatus)">
<div class="col">
<button type="button" class="btn btn-success btn-sm" (click)="acceptQa()">Accept &amp; Archive</button>
</div>
<div class="col" *ngIf="jobDetail.queueName == 'quicklook'">
<button type="button" class="btn btn-danger btn-sm" (click)="rejectQa()">Reject &amp; Archive</button>
</div>
</div>
<p><b>SDM ID:</b> {{ job.jobspec_sdm_id }} </p>
......@@ -26,7 +18,7 @@
</a>
</p>
<form [formGroup]="noteFormGroup" (ngSubmit)="updateNotes()" class="mb-2">
<form formGroup="noteFormGroup" (ngSubmit)="updateNotes()" class="mb-2">
<div class="row mt-3 mr-0">
<div class="col-auto">
<h4 class="pt-2">
......@@ -43,10 +35,34 @@
</div>
</form>
<app-execution-detail-planes [job]="job"
(planesWritten)="acceptQa()"
*ngIf="jobDetail.queueName === 'se_coarse_cube_imaging' && canAcceptArchive(jobDetail.status, jobDetail.archiveStatus)">
</app-execution-detail-planes>
<div>
<h4 class="pt-2 border-top">
Planes
</h4>
<div class="w-100" *ngFor="let plane of getPlaneKeys()" formGroup="planesFormGroup">
<label><input type="checkbox" formControlName="plane" value="{{plane}}" checked/>{{plane}}</label>
</div>
</div>
<div *ngIf="canSelectPlanes()">
<h4 class="pt-2 border-top">
Tiles
</h4>
<div class="w-100" *ngFor="let plane of getPlaneKeys()" formGroup="planesFormGroup">
<label><input type="checkbox" formControlName="plane" value="{{plane}}" checked/>{{plane}}</label>
</div>
</div>
<div class="row no-gutters" *ngIf="jobDetail.queueName !== 'se_coarse_cube_imaging' && canAcceptArchive(jobDetail.status, jobDetail.archiveStatus)">
<div class="col">
<button type="button" class="btn btn-success btn-sm" (click)="acceptQa()">Accept &amp; Archive</button>
</div>
<div class="col" *ngIf="jobDetail.queueName == 'quicklook'">
<button type="button" class="btn btn-danger btn-sm" (click)="rejectQa()">Reject &amp; Archive</button>
</div>
</div>
<h4 class="pt-2 border-top">
<fa-icon [icon]="faList"></fa-icon>
......
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
import {Job, JobExecution} from "../../../model/job";
import {Subject} from "rxjs";
import {Subject, Observable} from "rxjs";
import {JobsService} from "../../../services/jobs.service";
import {FormControl, FormGroup} from "@angular/forms";
import {ConfigurationService} from "../../../env/configuration.service";
......@@ -14,31 +14,32 @@ import {auditTime, takeUntil} from "rxjs/operators";
styleUrls: ['./execution-detail.component.scss']
})
export class ExecutionDetailComponent implements OnInit, OnDestroy {
noteFormGroup = new FormGroup({
notes: new FormControl(),
id: new FormControl()
});
planesFormGroup = new FormGroup({});
private ngUnsubscribe = new Subject<void>();
@Input() job: Job;
@Output() reload = new EventEmitter();
public jobDetail: JobExecution;
noteFormGroup: FormGroup;
public faSave = faSave;
public faList = faList;
public faCheckCircle = faCheckCircle;
public faStickyNote = faStickyNote;
public faCopy = faCopy;
public weblogUrl;
public weblogUrl: string;
planes: Observable<string>;
planeKeys: string[];
constructor(
private configService: ConfigurationService,
private jobService: JobsService,
private alertService: AlertService
) {
this.noteFormGroup = new FormGroup({
notes: new FormControl(),
id: new FormControl()
});
}
ngOnInit() {
......@@ -128,6 +129,9 @@ export class ExecutionDetailComponent implements OnInit, OnDestroy {
}
acceptQa() {
if (this.canSelectPlanes()) {
this.acceptPlanes();
}
this.updateNotes(); // make sure notes are saved before submitting
this.alertService.info('Accepting ' + this.job.job_id);
this.performQa(this.job.job_id, 'accept');
......@@ -162,6 +166,62 @@ export class ExecutionDetailComponent implements OnInit, OnDestroy {
}
};
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');
});
}
}
ngOnDestroy(): void {
this.ngUnsubscribe.next();
......
......@@ -171,6 +171,14 @@ export class JobsService {
}));
}
// Returns a JSON encoded string of plane information
public getTiles(id: number): Observable<string[]> {
return this.http.get<string[]>(this.configService.config.url + this.endPoint + 'jobs/' + id + '/tiles', {observe: 'response'}).pipe(
map(response => {
return response.body;
}));
}
// Writes a string of plane names
public writePlanes(id: number, planes: string): Observable<any> {
return this.http.put(this.configService.config.url + this.endPoint + 'jobs/' + id + '/writePlanes', {planes}, {observe: 'response'}).pipe(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment