import {Component, OnDestroy, OnInit} from '@angular/core'; import {Subscription} from "rxjs"; import {FormControl, FormGroup} from "@angular/forms"; import {debounceTime, distinctUntilChanged, map} from "rxjs/operators"; import {JobsService} from "../services/jobs.service"; import {Job, JobQueue, JobSpec} from "../model/job"; import {ActivatedRoute} from "@angular/router"; import {AlertService} from "../services/alert.service"; import {FiltersService} from "../services/filters.service"; import {Setting} from "../model/setting"; import {SettingsService} from "../services/settings.service"; import {Epoch} from "../model/epoch"; import {faFastBackward, faFastForward, faStepBackward, faStepForward} from "@fortawesome/free-solid-svg-icons"; @Component({ selector: 'app-jobspecs', templateUrl: './jobspecs.component.html', styleUrls: ['./jobspecs.component.scss'] }) export class JobspecsComponent implements OnInit, OnDestroy { public epochs: Array<Epoch>; public queues: Array<JobQueue>; public statuses: Array<string>; public jobs$: Subscription; public jobs: Array<JobSpec>; public pattern: string = ""; public resultsPerPage: number = 100; public currentPage: number = 1; public numResults: number = 0; public pages: number = 1; private pages$: Subscription; private readonly settings$: Subscription; public canDeleteJobs = false; private filters$: Subscription; public filters: object; public sortColumns: Array<string>; public sortDirections: Array<string>; public formGroup: FormGroup; public faFastBackward = faFastBackward; public faStepBackward = faStepBackward; public faFastForward = faFastForward; public faStepForward = faStepForward; constructor( private jobService: JobsService, private route: ActivatedRoute, private alertService: AlertService, private filterService: FiltersService, private settingsService: SettingsService ) { this.epochs = this.filterService.getFilter('EPOCH'); this.queues = this.filterService.getFilter('JOB_QUEUE'); this.statuses = this.filterService.getFilter('JOB_STATUS'); this.settings$ = this.settingsService.getSettings().subscribe((s: Setting) => { if (s) { this.canDeleteJobs = s.allowJobDeletion; } else { this.canDeleteJobs = false; } }, error => { this.canDeleteJobs = false; }); this.sortColumns = this.filterService.getFilter('JOBSPEC_SORT'); this.sortDirections = this.filterService.getFilter('SORT_DIRECTION'); } ngOnInit() { this.formGroup = new FormGroup({ pattern: new FormControl() }); this.route.queryParams.subscribe(params => { if (params.hasOwnProperty('pattern')) { this.pattern = params.pattern; this.formGroup.get('pattern').setValue(params.pattern); } if (params.hasOwnProperty('status')) { this.filterService.setCurrentSetting('JOB_STATUS', params.status); } if (params.hasOwnProperty('queue')) { const paramQueue = Job.getQueueFromName(params.queue); if (paramQueue) { this.filterService.setCurrentSetting('JOB_QUEUE', paramQueue); } } if (params.hasOwnProperty('epoch')) { const paramEpoch = Epoch.getEpochFromId(params.epoch); if (paramEpoch) { this.filterService.setCurrentSetting('EPOCHS', paramEpoch); } } }); this.formGroup.get('pattern').valueChanges.pipe( debounceTime(400), distinctUntilChanged(), map(results => results) ).subscribe((val: string) => { this.pattern = val; this.getPageInfoAndJobSpec(); }); this.filters$ = this.filterService.currentSettings$.subscribe((filters: object) => { this.filters = filters; this.getPageInfoAndJobSpec(); }); this.getPageInfoAndJobSpec(); } setEpoch(epoch: Epoch) { this.filterService.setCurrentSetting('EPOCH', epoch); } setQueue(queue: JobQueue): void { this.filterService.setCurrentSetting('JOB_QUEUE', queue); } setStatus(status: string): void { this.filterService.setCurrentSetting('JOB_STATUS', status); } setSortColumn(column: string): void { this.filterService.setCurrentSetting('JOBSPEC_SORT', column); } setSortDirection(direction: string): void { this.filterService.setCurrentSetting('SORT_DIRECTION', direction); } getPrettyName(name: string): string { return FiltersService.prettyName(name); } goToPage(page: number): boolean { if (page < 1) { page = 1; } if (page > this.pages) { page = this.pages; } if (this.currentPage == page) { return false; } this.currentPage = page; this.getJobSpecs(); } getPages(): Array<any> { return new Array(this.pages); } getPageCount(): void { const epoch = this.filterService.getCurrentSetting('EPOCH'); const queue = this.filterService.getCurrentSetting('JOB_QUEUE'); const status = this.filterService.getCurrentSetting('JOB_STATUS'); this.pages$ = this.jobService.getJobSpecRecordCount(epoch.id, queue.name, this.pattern, status).subscribe((jobSpecNumber: number) => { this.numResults = jobSpecNumber; this.pages = Math.ceil(jobSpecNumber / this.resultsPerPage); console.log('num', jobSpecNumber); if (this.currentPage > this.pages) { this.currentPage = this.pages; } if (this.currentPage < 1) { this.currentPage = 1; } this.getJobSpecs(); }); } getJobSpecs(): void { // clear a previous call if (this.jobs$) { this.jobs$.unsubscribe(); } this.jobs = null; const epoch = this.filterService.getCurrentSetting('EPOCH'); const queue = this.filterService.getCurrentSetting('JOB_QUEUE'); const status = this.filterService.getCurrentSetting('JOB_STATUS'); this.alertService.info('Getting ' + queue.label); this.jobs$ = this.jobService.getJobSpecPage(epoch.id, queue.name, this.currentPage - 1, this.pattern, status).subscribe((jobSpecs: Array<JobSpec>) => { if (jobSpecs && jobSpecs.length > 0) { this.alertService.success(queue.label + ' loaded.'); this.jobs = jobSpecs; } else { this.jobs = []; this.alertService.error('No ' + queue.label + ' found.') } }); } getJobSpecById(id: number): void { // clear a previous call if (this.jobs$) { this.jobs$.unsubscribe(); } this.jobs$ = this.jobService.getJobSpecById(id).subscribe((jobSpec: JobSpec) => { this.jobs = [jobSpec]; this.numResults = 1; this.pages = 1; this.currentPage = 1; }); } getPageInfoAndJobSpec(): void { let possible_id = parseInt(this.pattern); if (isNaN(possible_id)) { this.getPageCount(); this.getJobSpecs(); } else { this.getJobSpecById(possible_id); } } /* getJobs(): void { if (this.jobs$) { this.jobs$.unsubscribe(); } this.jobs = null; var possibleId = parseInt(this.pattern); var id = null; if (!isNaN(possibleId)) { id = possibleId; } const queue = this.filterService.getCurrentSetting('JOB_QUEUE'); const status = this.filterService.getCurrentSetting('JOB_STATUS'); this.alertService.info('Getting ' + queue.label + ' Jobs'); if (!!id) { this.jobs$ = this.jobService.getJobSpec(id).subscribe((j: JobSpec) => { this.alertService.success(queue.label + ' jobs retrieved'); const arr = []; arr.push(this.jobService.jobSpecToJob(j)); this.jobs = arr; }); } else { this.jobs$ = this.jobService.getJobSpecs(queue.name, id, this.pattern, status).subscribe((j: Array<Job>) => { if (j && j.length > 0) { this.alertService.success(queue.label + ' jobs retrieved'); this.jobs = j; } else { this.jobs = []; this.alertService.error('No ' + queue.label + ' jobs found'); } }); } } */ ngOnDestroy(): void { if (this.jobs$) { this.jobs$.unsubscribe(); } if (this.filters$) { this.filters$.unsubscribe(); } if (this.settings$) { this.settings$.unsubscribe(); } if (this.pages$) { this.pages$.unsubscribe(); } } }