725117dfc468030b1037e915436d0eff9af51474
[portal/nonrtric-controlpanel.git] / webapp-frontend / src / app / ei-coordinator / producers-list / producers-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 { MatSort, Sort } from '@angular/material/sort';
23 import { MatTableDataSource } from '@angular/material/table';
24 import { forkJoin, of } from 'rxjs';
25 import { BehaviorSubject } from 'rxjs/BehaviorSubject';
26 import { mergeMap, finalize } from 'rxjs/operators';
27 import { ProducerService } from '@services/ei/producer.service';
28 import { Producer } from '@interfaces/producer.types';
29 import { UiService } from '@services/ui/ui.service';
30
31 @Component({
32   selector: 'nrcp-producers-list',
33   templateUrl: './producers-list.component.html',
34   styleUrls: ['./producers-list.component.scss']
35 })
36 export class ProducersListComponent implements OnInit {
37
38   @ViewChild(MatSort) sort: MatSort;
39
40   producersDataSource: MatTableDataSource<Producer>;
41   producerForm: FormGroup;
42   darkMode: boolean;
43
44   private loadingSubject = new BehaviorSubject<boolean>(false);
45   private producerSubject = new BehaviorSubject<Producer[]>([]);
46   public loading$ = this.loadingSubject.asObservable();
47
48   constructor(
49     private producerService: ProducerService,
50     private ui: UiService) {
51
52     this.producerForm = new FormGroup({
53       producer_id: new FormControl(''),
54       producer_types: new FormControl(''),
55       status: new FormControl('')
56     });
57   }
58
59   ngOnInit(): void {
60     this.loadProducers();
61     this.producerSubject.subscribe((data) => {
62       this.producersDataSource = new MatTableDataSource<Producer>(data);
63
64       this.producersDataSource.filterPredicate = ((data, filter) => {
65         let searchTerms = JSON.parse(filter);
66         return this.isDataIncluding(data.producer_id, searchTerms.producer_id)
67           && this.isDataIncluding(data.producer_types.join(','), searchTerms.producer_types)
68           && this.isDataIncluding(data.status, searchTerms.status);
69       }) as (data: Producer, filter: any) => boolean;
70     });
71
72     this.producerForm.valueChanges.subscribe(value => {
73       this.producersDataSource.filter = JSON.stringify(value);
74     });
75
76     this.ui.darkModeState.subscribe((isDark) => {
77       this.darkMode = isDark;
78     });
79   }
80
81   ngOnDestroy() {
82     if (!this.producerSubject) this.producerSubject.unsubscribe();
83     if (!this.loadingSubject) this.loadingSubject.unsubscribe();
84     if (!this.ui.darkModeState) this.ui.darkModeState.unsubscribe();
85   }
86
87   isDataIncluding(data: string, filter: string): boolean {
88     const transformedFilter = filter.trim().toLowerCase();
89     return data.toLowerCase().includes(transformedFilter);
90   }
91
92   clearFilter() {
93     this.producerForm.get('producer_id').setValue('');
94     this.producerForm.get('producer_types').setValue('');
95     this.producerForm.get('status').setValue('');
96   }
97
98   sortProducers(sort: Sort) {
99     const data = this.producersDataSource.data
100     data.sort((a: Producer, b: Producer) => {
101       const isAsc = sort.direction === 'asc';
102       switch (sort.active) {
103         case 'id': return this.compare(a.producer_id, b.producer_id, isAsc);
104         case 'types': return this.compare(a.producer_types, b.producer_types, isAsc);
105         case 'status': return this.compare(a.status, b.status, isAsc);
106         default: return 0;
107       }
108     });
109     this.producersDataSource.data = data;
110   }
111
112   compare(a: any, b: any, isAsc: boolean) {
113     return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
114   }
115
116   stopSort(event: any) {
117     event.stopPropagation();
118   }
119
120   getProducerTypes(producer: Producer): string[] {
121     if (producer.producer_types) {
122       return producer.producer_types;
123     }
124     return ['< No types >'];
125   }
126
127   getProducerStatus(producer: Producer): string {
128     if (producer.status) {
129       return producer.status;
130     }
131     return '< No status >';
132   }
133
134   public producers(): Producer[] {
135     return this.producerSubject.value;
136   }
137
138   loadProducers() {
139     this.loadingSubject.next(true);
140     let producers = [];
141
142     this.producerService.getProducerIds().pipe(
143       mergeMap(prodIds =>
144         forkJoin(prodIds.map(id => {
145           return forkJoin([
146             of(id),
147             this.producerService.getProducer(id),
148             this.producerService.getProducerStatus(id)
149           ])
150         })
151         )),
152       finalize(() => this.loadingSubject.next(false)),
153     ).subscribe(result => {
154       producers = result.map(producer => {
155         let producerObj = <Producer>{};
156         producerObj.producer_id = producer[0];
157         if (producer[1].supported_info_types) {
158           producerObj.producer_types = producer[1].supported_info_types;
159         }
160         if (producer[2].operational_state) {
161           producerObj.status = producer[2].operational_state.toString();
162         }
163         return producerObj;
164       });
165       this.producerSubject.next(producers);
166     }, err => {
167       console.error("Subscribe function error:" + err);
168     });
169   }
170 }