X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=webapp-frontend%2Fsrc%2Fapp%2Fei-coordinator%2Fjobs-list%2Fjobs-list.component.ts;h=097e450daa3ef75113d747725969d3d673897eae;hb=3ee775c98e03fb575e58ef0fed4e6aa00bb8d80a;hp=a85e57747612e80185bdff0d99e9a044aea065b3;hpb=a8fd8da95fbdc2ccac30b1327edeb410f16a505a;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 a85e577..097e450 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 @@ -22,31 +22,20 @@ 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 { EMPTY, forkJoin, of, pipe, Subscription, concat, Observable } from "rxjs"; import { BehaviorSubject } from "rxjs/BehaviorSubject"; -import { - mergeMap, - finalize, - map, - tap, - switchMap -} from "rxjs/operators"; -import { EIJob } from "@interfaces/ei.types"; -import { EIService } from "@services/ei/ei.service"; +import { mergeMap, finalize, map, tap, concatMap, delay, skip, catchError } from "rxjs/operators"; +import { ConsumerService } from "@services/ei/consumer.service"; import { UiService } from "@services/ui/ui.service"; +import { OperationalState } from '@app/interfaces/consumer.types'; export interface Job { jobId: string; - jobData: any; typeId: string; targetUri: string; owner: string; - prodId: string; + prodIds: string[]; + status: OperationalState; } @Component({ @@ -63,18 +52,21 @@ export class JobsListComponent implements OnInit { private jobsSubject$ = new BehaviorSubject([]); private refresh$ = new BehaviorSubject(""); private loadingSubject$ = new BehaviorSubject(false); - private polling$ = new BehaviorSubject(true); + private polling$ = new BehaviorSubject(0); public loading$ = this.loadingSubject$.asObservable(); subscription: Subscription; checked: boolean = false; + firstTime: boolean = true; + jobList: Job[] = []; - constructor(private eiSvc: EIService, private ui: UiService) { + constructor(private consumerService: ConsumerService, private ui: UiService) { this.jobForm = new FormGroup({ jobId: new FormControl(""), typeId: new FormControl(""), owner: new FormControl(""), targetUri: new FormControl(""), - prodId: new FormControl(""), + prodIds: new FormControl(""), + status: new FormControl("") }); } @@ -92,7 +84,8 @@ export class JobsListComponent implements OnInit { this.isDataIncluding(data.jobId, searchTerms.jobId) && this.isDataIncluding(data.owner, searchTerms.owner) && this.isDataIncluding(data.typeId, searchTerms.typeId) && - this.isDataIncluding(data.prodId, searchTerms.prodId) + this.isArrayIncluding(data.prodIds, searchTerms.prodIds) && + this.isDataIncluding(data.status, searchTerms.status) ); }) as (data: Job, filter: any) => boolean; }); @@ -107,32 +100,59 @@ export class JobsListComponent implements OnInit { } dataSubscription(): Subscription { - let prodId = []; - const jobs$ = this.eiSvc.getProducerIds().pipe( - tap((data) => (prodId = data)), - mergeMap((prodIds) => - forkJoin(prodIds.map((id) => this.eiSvc.getJobsForProducer(id))) + const jobsInfo$ = this.consumerService.getJobIds().pipe( + tap((_) => { + this.jobList = [] as Job[]; + }), + mergeMap((jobIds) => + forkJoin(jobIds.map((jobId) => { + return forkJoin([ + of(jobId).pipe( + catchError(err => { + return of([-1]); + }) + ), + this.consumerService.getJobInfo(jobId).pipe( + catchError(err => { + return of([-1]); + })), + this.consumerService.getConsumerStatus(jobId).pipe( + catchError(err => { + return of([-1]); + })), + ]) + })) ), - finalize(() => this.loadingSubject$.next(false)) + finalize(() => { + this.loadingSubject$.next(false); + this.jobsSubject$.next(this.jobList); + }) + ); + + const whenToRefresh$ = of('').pipe( + delay(10000), + tap((_) => this.refresh$.next('')), + skip(1), + ); + + const poll$ = concat(jobsInfo$, whenToRefresh$); + + const refreshedJobs$ = this.refresh$.pipe( + tap((_) => { + this.loadingSubject$.next(true); + }), + concatMap((_) => this.checked ? poll$ : jobsInfo$), + map((response) => this.extractJobs(response)) ); - const refreshedJobs$ = this.refresh$ + return this.polling$ .pipe( - switchMap((_) => timer(0, 10000).pipe( - tap((_) => { - this.loadingSubject$.next(true); - }), - switchMap((_) => jobs$), - map((response) => this.extractJobs(prodId, response)) - ) - ) - ); - - return this.polling$.pipe( - switchMap(p => { - return p ? refreshedJobs$ : EMPTY; - }) - ).subscribe(); + concatMap((value) => { + let pollCondition = value == 0 || this.checked; + return pollCondition ? refreshedJobs$ : EMPTY; + }) + ) + .subscribe(); } ngOnDestroy() { @@ -144,7 +164,8 @@ export class JobsListComponent implements OnInit { this.jobForm.get("typeId").setValue(""); this.jobForm.get("owner").setValue(""); this.jobForm.get("targetUri").setValue(""); - this.jobForm.get("prodId").setValue(""); + this.jobForm.get("prodIds").setValue(""); + this.jobForm.get("status").setValue(""); } sortJobs(sort: Sort) { @@ -160,8 +181,10 @@ export class JobsListComponent implements OnInit { 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); + case "prodIds": + return this.compare(a.prodIds, b.prodIds, isAsc); + case "status": + return this.compare(a.status, b.status, isAsc); default: return 0; } @@ -169,8 +192,12 @@ export class JobsListComponent implements OnInit { this.jobsDataSource.data = data; } - stopPolling(checked){ - this.polling$.next(checked); + stopPolling(checked) { + this.checked = checked; + this.polling$.next(this.jobs().length); + if (this.checked) { + this.refreshDataClick(); + } } compare(a: any, b: any, isAsc: boolean) { @@ -186,16 +213,24 @@ export class JobsListComponent implements OnInit { return data.toLowerCase().includes(transformedFilter); } - getJobTypeId(eiJob: Job): string { - if (eiJob.typeId) { - return eiJob.typeId; + isArrayIncluding(data: string[], filter: string): boolean { + if (!data) + return true; + for (let i = 0; i < data.length; i++) { + return this.isDataIncluding(data[i], filter); + } + } + + getJobTypeId(job: Job): string { + if (job.typeId) { + return job.typeId; } 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 >"; } @@ -204,37 +239,49 @@ export class JobsListComponent implements OnInit { return this.jobsSubject$.value; } - private extractJobs(prodId: number[], res: EIJob[][]) { + private extractJobs(res: any) { 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); - return jobList; - } - - createJobList(prodId: any[], result: EIJob[][]) { - let jobList = []; - prodId.forEach((element, index) => { - let jobs = result[index]; - jobList = jobList.concat(jobs.map((job) => this.createJob(element, job))); + res.forEach(element => { + if (element[0] != -1) { + if (element[1] != -1 && element[2] != -1) { + let jobObj = {}; + jobObj.jobId = element[0]; + jobObj.owner = element[1].job_owner; + jobObj.targetUri = element[1].job_result_uri; + jobObj.typeId = element[1].info_type_id; + jobObj.prodIds = (element[2].producers) ? element[2].producers : ["No Producers"]; + jobObj.status = element[2].info_job_status; + this.jobList = this.jobList.concat(jobObj); + } else { + let jobObj = {}; + jobObj.jobId = element[0]; + if (element[1] == -1) { + jobObj.owner = "--Missing information--"; + jobObj.targetUri = "--Missing information--"; + jobObj.typeId = "--Missing information--"; + } + if (element[2] == -1) { + jobObj.prodIds = "--Missing information--" as unknown as []; + jobObj.status = "--Missing information--" as OperationalState; + } + this.jobList = this.jobList.concat(jobObj); + } + } }); - 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; + if (this.firstTime && this.jobList.length > 0) { + this.polling$.next(this.jobList.length); + this.firstTime = false; + } + return this.jobList; } refreshDataClick() { this.refresh$.next(""); } + + hasJobs(): boolean { + return this.jobs().length > 0; + } + }