Adding prodId column to Jobs table
[portal/nonrtric-controlpanel.git] / webapp-frontend / src / app / ei-coordinator / jobs-list / jobs-list.component.ts
1 /*-
2  * ========================LICENSE_START=================================
3  * O-RAN-SC
4  * %%
5  * Copyright (C) 2021 Nordix Foundation
6  * %%
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ========================LICENSE_END===================================
19  */
20 import { Component, OnInit, ViewChild } from '@angular/core';
21 import { FormControl, FormGroup } from '@angular/forms';
22 import { MatPaginator } from '@angular/material/paginator';
23 import { Sort } from '@angular/material/sort';
24 import { MatTableDataSource } from '@angular/material/table';
25 import { forkJoin } from 'rxjs';
26 import { BehaviorSubject } from 'rxjs/BehaviorSubject';
27 import { mergeMap, finalize, tap } from 'rxjs/operators';
28 import { EIJob } from '@interfaces/ei.types';
29 import { EIService } from '@services/ei/ei.service';
30 import { UiService } from '@services/ui/ui.service';
31
32 export interface Job {
33   jobId: string;
34   jobData: any;
35   typeId: string;
36   targetUri: string;
37   owner: string;
38   prodId: string;
39 }
40
41 @Component({
42   selector: 'nrcp-jobs-list',
43   templateUrl: './jobs-list.component.html',
44   styleUrls: ['./jobs-list.component.scss']
45 })
46 export class JobsListComponent implements OnInit {
47
48   @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
49
50   darkMode: boolean;
51   jobsDataSource: MatTableDataSource<Job>;
52   jobForm: FormGroup;
53   private loadingSubject = new BehaviorSubject<boolean>(false);
54   private jobsSubject = new BehaviorSubject<Job[]>([]);
55   public loading$ = this.loadingSubject.asObservable();
56
57   constructor(
58     private eiSvc: EIService,
59     private ui: UiService
60   ) {
61     this.jobForm = new FormGroup({
62       jobId: new FormControl(''),
63       typeId: new FormControl(''),
64       owner: new FormControl(''),
65       targetUri: new FormControl(''),
66       prodId: new FormControl('')
67     });
68   }
69
70   ngOnInit(): void {
71     this.loadJobs();
72     this.jobsSubject.subscribe((data) => {
73       this.jobsDataSource = new MatTableDataSource<Job>(data);
74       this.jobsDataSource.paginator = this.paginator;
75
76       this.jobsDataSource.filterPredicate = ((data: Job, filter) => {
77         let searchTerms = JSON.parse(filter);
78         return this.isDataIncluding(data.targetUri, searchTerms.targetUri)
79           && this.isDataIncluding(data.jobId, searchTerms.jobId)
80           && this.isDataIncluding(data.owner, searchTerms.owner)
81           && this.isDataIncluding(data.typeId, searchTerms.typeId)
82           && this.isDataIncluding(data.prodId, searchTerms.prodId);
83       }) as (data: Job, filter: any) => boolean;
84     });
85
86     this.jobForm.valueChanges.subscribe(value => {
87       this.jobsDataSource.filter = JSON.stringify(value);
88     });
89
90     this.ui.darkModeState.subscribe((isDark) => {
91       this.darkMode = isDark;
92     });
93   }
94
95   ngOnDestroy() {
96     if (!this.jobsSubject) this.jobsSubject.unsubscribe();
97     if (!this.loadingSubject) this.loadingSubject.unsubscribe();
98     if (!this.ui.darkModeState) this.ui.darkModeState.unsubscribe();
99   }
100
101   clearFilter() {
102     this.jobForm.get('jobId').setValue('');
103     this.jobForm.get('typeId').setValue('');
104     this.jobForm.get('owner').setValue('');
105     this.jobForm.get('targetUri').setValue('');
106     this.jobForm.get('prodId').setValue('');
107   }
108
109   sortJobs(sort: Sort) {
110     const data = this.jobsDataSource.data
111     data.sort((a: Job, b: Job) => {
112       const isAsc = sort.direction === 'asc';
113       switch (sort.active) {
114         case 'jobId': return this.compare(a.jobId, b.jobId, isAsc);
115         case 'typeId': return this.compare(a.typeId, b.typeId, isAsc);
116         case 'owner': return this.compare(a.owner, b.owner, isAsc);
117         case 'targetUri': return this.compare(a.targetUri, b.targetUri, isAsc);
118         case 'prodId': return this.compare(a.prodId, b.prodId, isAsc);
119         default: return 0;
120       }
121     });
122     this.jobsDataSource.data = data;
123   }
124
125   compare(a: any, b: any, isAsc: boolean) {
126     return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
127   }
128
129   stopSort(event: any) {
130     event.stopPropagation();
131   }
132
133   isDataIncluding(data: string, filter: string): boolean {
134     const transformedFilter = filter.trim().toLowerCase();
135     return data.toLowerCase().includes(transformedFilter);
136   }
137
138   getJobTypeId(eiJob: Job): string {
139     if (eiJob.typeId) {
140       return eiJob.typeId;
141     }
142     return '< No type >';
143   }
144
145   getJobOwner(eiJob: Job): string {
146     if (eiJob.owner) {
147       return eiJob.owner;
148     }
149     return '< No owner >';
150   }
151
152   public jobs(): Job[] {
153     return this.jobsSubject.value;
154   }
155
156   loadJobs() {
157     this.loadingSubject.next(true);
158     let jobs = [];
159     let prodId = [];
160     this.eiSvc.getProducerIds().pipe(
161       tap(data => prodId = data),
162       mergeMap(prodIds =>
163         forkJoin(prodIds.map(id => this.eiSvc.getJobsForProducer(id)))),
164       finalize(() => this.loadingSubject.next(false))
165     ).subscribe(result => {
166       jobs = this.createJobList(prodId, result);
167       this.jobsSubject.next(jobs);
168     });
169   }
170   createJobList(prodId: any[], result: EIJob[][]) {
171     let jobList = [];
172     prodId.forEach((element, index) => {
173       let jobs = result[index];
174       jobList = jobList.concat(jobs.map(job => this.createJob(element, job)));
175     });
176     return jobList;
177   }
178   createJob(element: any, job: EIJob): any {
179     let eiJob = <Job>{};
180     eiJob.jobId = job.ei_job_identity;
181     eiJob.typeId = job.ei_type_identity;
182     eiJob.owner = job.owner;
183     eiJob.targetUri = job.target_uri;
184     eiJob.prodId = element;
185     return eiJob;
186   }
187
188 }