X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=webapp-frontend%2Fsrc%2Fapp%2Fei-coordinator%2Fjobs-list%2Fjobs-list.component.ts;h=f06202ccabf00ee2232e775dceb516f9fae7ecdd;hb=refs%2Fchanges%2F71%2F6071%2F2;hp=7fea5376883d334eb2465953cae59e08d02439f6;hpb=fb9a5699b247ad1518c5714224396205485a3c4c;p=portal%2Fnonrtric-controlpanel.git diff --git a/webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.ts b/webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.ts index 7fea537..f06202c 100644 --- a/webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.ts +++ b/webapp-frontend/src/app/ei-coordinator/jobs-list/jobs-list.component.ts @@ -17,17 +17,17 @@ * limitations under the License. * ========================LICENSE_END=================================== */ -import { Component, OnInit, ViewChild } from '@angular/core'; -import { FormControl, FormGroup } from '@angular/forms'; -import { MatPaginator } from '@angular/material/paginator'; -import { Sort } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; -import { forkJoin } from 'rxjs'; -import { BehaviorSubject } from 'rxjs/BehaviorSubject'; -import { mergeMap, finalize, tap } from 'rxjs/operators'; -import { EIJob } from '@interfaces/ei.types'; -import { EIService } from '@services/ei/ei.service'; -import { UiService } from '@services/ui/ui.service'; +import { Component, OnInit, ViewChild } from "@angular/core"; +import { FormControl, FormGroup } from "@angular/forms"; +import { MatPaginator } from "@angular/material/paginator"; +import { Sort } from "@angular/material/sort"; +import { MatTableDataSource } from "@angular/material/table"; +import { EMPTY, forkJoin, Subscription, timer } from "rxjs"; +import { BehaviorSubject } from "rxjs/BehaviorSubject"; +import { mergeMap, finalize, map, tap, switchMap } from "rxjs/operators"; +import { JobInfo } from "@interfaces/producer.types"; +import { ProducerService } from "@services/ei/producer.service"; +import { UiService } from "@services/ui/ui.service"; export interface Job { jobId: string; @@ -39,51 +39,55 @@ export interface Job { } @Component({ - selector: 'nrcp-jobs-list', - templateUrl: './jobs-list.component.html', - styleUrls: ['./jobs-list.component.scss'] + selector: "nrcp-jobs-list", + templateUrl: "./jobs-list.component.html", + styleUrls: ["./jobs-list.component.scss"], }) export class JobsListComponent implements OnInit { - @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; - - darkMode: boolean; jobsDataSource: MatTableDataSource; jobForm: FormGroup; - private loadingSubject = new BehaviorSubject(false); - private jobsSubject = new BehaviorSubject([]); - public loading$ = this.loadingSubject.asObservable(); - - constructor( - private eiSvc: EIService, - private ui: UiService - ) { + darkMode: boolean; + + private jobsSubject$ = new BehaviorSubject([]); + private refresh$ = new BehaviorSubject(""); + private loadingSubject$ = new BehaviorSubject(false); + private polling$ = new BehaviorSubject(0); + public loading$ = this.loadingSubject$.asObservable(); + subscription: Subscription; + checked: boolean = false; + firstTime: boolean = true; + + constructor(private producerService: ProducerService, private ui: UiService) { this.jobForm = new FormGroup({ - jobId: new FormControl(''), - typeId: new FormControl(''), - owner: new FormControl(''), - targetUri: new FormControl(''), - prodId: new FormControl('') + jobId: new FormControl(""), + typeId: new FormControl(""), + owner: new FormControl(""), + targetUri: new FormControl(""), + prodId: new FormControl(""), }); } ngOnInit(): void { - this.loadJobs(); - this.jobsSubject.subscribe((data) => { + this.subscription = this.dataSubscription(); + + this.jobsSubject$.subscribe((data) => { this.jobsDataSource = new MatTableDataSource(data); this.jobsDataSource.paginator = this.paginator; this.jobsDataSource.filterPredicate = ((data: Job, filter) => { let searchTerms = JSON.parse(filter); - return this.isDataIncluding(data.targetUri, searchTerms.targetUri) - && this.isDataIncluding(data.jobId, searchTerms.jobId) - && this.isDataIncluding(data.owner, searchTerms.owner) - && this.isDataIncluding(data.typeId, searchTerms.typeId) - && this.isDataIncluding(data.prodId, searchTerms.prodId); + return ( + this.isDataIncluding(data.targetUri, searchTerms.targetUri) && + this.isDataIncluding(data.jobId, searchTerms.jobId) && + this.isDataIncluding(data.owner, searchTerms.owner) && + this.isDataIncluding(data.typeId, searchTerms.typeId) && + this.isDataIncluding(data.prodId, searchTerms.prodId) + ); }) as (data: Job, filter: any) => boolean; }); - this.jobForm.valueChanges.subscribe(value => { + this.jobForm.valueChanges.subscribe((value) => { this.jobsDataSource.filter = JSON.stringify(value); }); @@ -92,36 +96,77 @@ export class JobsListComponent implements OnInit { }); } + dataSubscription(): Subscription { + let prodId = []; + const jobs$ = this.producerService.getProducerIds().pipe( + tap((data) => (prodId = data)), + mergeMap((prodIds) => + forkJoin(prodIds.map((id) => this.producerService.getJobsForProducer(id))) + ), + finalize(() => this.loadingSubject$.next(false)) + ); + + const refreshedJobs$ = this.refresh$.pipe( + switchMap((_) => + timer(0, 10000).pipe( + tap((_) => { + this.loadingSubject$.next(true); + }), + switchMap((_) => jobs$), + map((response) => this.extractJobs(prodId, response)) + ) + ) + ); + + return this.polling$ + .pipe( + switchMap((value) => { + let pollCondition = value == 0 || this.checked; + return pollCondition ? refreshedJobs$ : EMPTY; + }) + ) + .subscribe(); + } + ngOnDestroy() { - if (!this.jobsSubject) this.jobsSubject.unsubscribe(); - if (!this.loadingSubject) this.loadingSubject.unsubscribe(); - if (!this.ui.darkModeState) this.ui.darkModeState.unsubscribe(); + this.subscription.unsubscribe(); } clearFilter() { - this.jobForm.get('jobId').setValue(''); - this.jobForm.get('typeId').setValue(''); - this.jobForm.get('owner').setValue(''); - this.jobForm.get('targetUri').setValue(''); - this.jobForm.get('prodId').setValue(''); + this.jobForm.get("jobId").setValue(""); + this.jobForm.get("typeId").setValue(""); + this.jobForm.get("owner").setValue(""); + this.jobForm.get("targetUri").setValue(""); + this.jobForm.get("prodId").setValue(""); } sortJobs(sort: Sort) { - const data = this.jobsDataSource.data + const data = this.jobsDataSource.data; data.sort((a: Job, b: Job) => { - const isAsc = sort.direction === 'asc'; + const isAsc = sort.direction === "asc"; switch (sort.active) { - case 'jobId': return this.compare(a.jobId, b.jobId, isAsc); - case 'typeId': return this.compare(a.typeId, b.typeId, isAsc); - case 'owner': return this.compare(a.owner, b.owner, isAsc); - case 'targetUri': return this.compare(a.targetUri, b.targetUri, isAsc); - case 'prodId': return this.compare(a.prodId, b.prodId, isAsc); - default: return 0; + case "jobId": + return this.compare(a.jobId, b.jobId, isAsc); + case "typeId": + return this.compare(a.typeId, b.typeId, isAsc); + case "owner": + return this.compare(a.owner, b.owner, isAsc); + case "targetUri": + return this.compare(a.targetUri, b.targetUri, isAsc); + case "prodId": + return this.compare(a.prodId, b.prodId, isAsc); + default: + return 0; } }); this.jobsDataSource.data = data; } + stopPolling(checked) { + this.checked = checked; + this.polling$.next(this.jobs().length); + } + compare(a: any, b: any, isAsc: boolean) { return (a < b ? -1 : 1) * (isAsc ? 1 : -1); } @@ -135,54 +180,59 @@ export class JobsListComponent implements OnInit { return data.toLowerCase().includes(transformedFilter); } - getJobTypeId(eiJob: Job): string { - if (eiJob.typeId) { - return eiJob.typeId; + getJobTypeId(job: Job): string { + if (job.typeId) { + return job.typeId; } - return '< No type >'; + return "< No type >"; } - getJobOwner(eiJob: Job): string { - if (eiJob.owner) { - return eiJob.owner; + getJobOwner(job: Job): string { + if (job.owner) { + return job.owner; } - return '< No owner >'; + return "< No owner >"; } public jobs(): Job[] { - return this.jobsSubject.value; + return this.jobsSubject$.value; } - loadJobs() { - this.loadingSubject.next(true); - let jobs = []; - let prodId = []; - this.eiSvc.getProducerIds().pipe( - tap(data => prodId = data), - mergeMap(prodIds => - forkJoin(prodIds.map(id => this.eiSvc.getJobsForProducer(id)))), - finalize(() => this.loadingSubject.next(false)) - ).subscribe(result => { - jobs = this.createJobList(prodId, result); - this.jobsSubject.next(jobs); + private extractJobs(prodId: number[], res: JobInfo[][]) { + this.clearFilter(); + let jobList = []; + prodId.forEach((element, index) => { + let jobs = res[index]; + jobList = jobList.concat(jobs.map((job) => this.createJob(element, job))); }); + this.jobsSubject$.next(jobList); + if (this.firstTime && jobList.length > 0) { + this.polling$.next(jobList.length); + this.firstTime = false; + } + return jobList; } - createJobList(prodId: any[], result: EIJob[][]) { + + createJobList(prodId: any[], result: JobInfo[][]) { let jobList = []; prodId.forEach((element, index) => { let jobs = result[index]; - jobList = jobList.concat(jobs.map(job => this.createJob(element, job))); + jobList = jobList.concat(jobs.map((job) => this.createJob(element, job))); }); return jobList; } - createJob(element: any, job: EIJob): any { - let eiJob = {}; - eiJob.jobId = job.ei_job_identity; - eiJob.typeId = job.ei_type_identity; - eiJob.owner = job.owner; - eiJob.targetUri = job.target_uri; - eiJob.prodId = element; - return eiJob; + + createJob(element: any, job: JobInfo): any { + let infoJob = {}; + infoJob.jobId = job.info_job_identity; + infoJob.typeId = job.info_type_identity; + infoJob.owner = job.owner; + infoJob.targetUri = job.target_uri; + infoJob.prodId = element; + return infoJob; } + refreshDataClick() { + this.refresh$.next(""); + } }