Adding sorting for tables of EI
[portal/nonrtric-controlpanel.git] / webapp-frontend / src / app / ei-coordinator / ei-coordinator.component.ts
1 /*-
2  * ========================LICENSE_START=================================
3  * O-RAN-SC
4  * %%
5  * Copyright (C) 2019 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 } from '@angular/core';
21 import { Sort } from '@angular/material/sort';
22 import { animate, state, style, transition, trigger } from '@angular/animations';
23 import { FormBuilder, FormGroup, AbstractControl } from '@angular/forms';
24 import { MatTableDataSource } from '@angular/material';
25
26 import { BehaviorSubject, Observable } from 'rxjs';
27
28 import { EIJob, EIProducer } from '../interfaces/ei.types';
29 import { EIJobDataSource } from './ei-job.datasource';
30 import { EIProducerDataSource } from './ei-producer.datasource';
31 import { UiService } from '../services/ui/ui.service';
32
33 class EIJobInfo {
34     constructor(public eiJob: EIJob) { }
35
36     isExpanded: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
37 }
38
39 @Component({
40     selector: 'nrcp-ei-coordinator',
41     templateUrl: './ei-coordinator.component.html',
42     styleUrls: ['./ei-coordinator.component.scss'],
43     animations: [
44         trigger('detailExpand', [
45             state('collapsed, void', style({ height: '0px', minHeight: '0', display: 'none' })),
46             state('expanded', style({ height: '*' })),
47             transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
48             transition('expanded <=> void', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)'))
49         ]),
50     ],
51 })
52 export class EICoordinatorComponent implements OnInit {
53
54     eiJobInfo = new Map<string, EIJobInfo>();
55     darkMode: boolean;
56     searchString: string;
57     formGroup: FormGroup;
58     jobsDataSource: MatTableDataSource<EIJob>;
59     producersDataSource: MatTableDataSource<EIProducer>;
60
61     readonly jobsFormControl: AbstractControl;
62     readonly producersFormControl: AbstractControl;
63
64     constructor(
65         private eiJobsDataSource: EIJobDataSource,
66         private eiProducersDataSource: EIProducerDataSource,
67         private ui: UiService,
68         private formBuilder: FormBuilder) {
69             this.formGroup = formBuilder.group({ filter: [""] });
70
71             this.jobsFormControl = formBuilder.group({
72                 id: '',
73                 typeId: '',
74                 owner: '',
75                 targetUri:''
76             });
77             this.producersFormControl = formBuilder.group({
78                 ei_producer_id: '',
79                 ei_producer_types: '',
80                 status: ''
81             });
82     }
83
84     ngOnInit() {
85         this.eiJobsDataSource.loadJobs();
86         this.eiProducersDataSource.loadProducers();
87         this.jobsDataSource = this.eiJobsDataSource.jobsDataSource();
88         this.producersDataSource = new MatTableDataSource(this.eiProducersDataSource.eiProducers());
89
90         this.jobsFormControl.valueChanges.subscribe(value => {
91             const filter = {...value, id: value.id.trim().toLowerCase()} as string;
92             this.jobsDataSource.filter = filter;
93         });
94         this.producersFormControl.valueChanges.subscribe(value => {
95             const filter = {...value, ei_producer_id: value.ei_producer_id.trim().toLowerCase()} as string;
96             this.producersDataSource.filter = filter;
97         });
98
99         this.jobsDataSource.filterPredicate = ((data: EIJob, filter) => {
100             return this.isDataIncluding(data.ei_job_identity, filter.id)
101                 && this.isDataIncluding(data.target_uri, filter.target_uri)
102                 && this.isDataIncluding(data.owner, filter.owner)
103                 && this.isDataIncluding(data.ei_type_identity, filter.typeId);
104           }) as (EIJob, string) => boolean;
105
106         this.producersDataSource.filterPredicate = ((data, filter) => {
107             return this.isDataIncluding(data.ei_producer_id, filter.ei_producer_id)
108                 && this.isDataIncluding(data.ei_producer_types.join(','), filter.ei_producer_types)
109                 && this.isDataIncluding(data.status, filter.status);
110           }) as (EIProducer, string) => boolean;
111
112         this.ui.darkModeState.subscribe((isDark) => {
113             this.darkMode = isDark;
114         });
115     }
116
117     sortJobs(sort: Sort){
118         console.log('Jobs new sort: ', sort);
119         const data = this.jobsDataSource.data
120         data.sort((a: EIJob, b: EIJob) => {
121             const isAsc = sort.direction === 'asc';
122             switch (sort.active) {
123               case 'id': return this.compare(a.ei_job_identity, b.ei_job_identity, isAsc);
124               case 'typeId': return this.compare(a.ei_type_identity, b.ei_type_identity, isAsc);
125               case 'owner': return this.compare(a.owner, b.owner, isAsc);
126               case 'targetUri': return this.compare(a.target_uri, b.owner, isAsc);
127               default: return 0;
128             }
129           });
130           this.jobsDataSource.data = data;
131     }
132
133     sortProducers(sort: Sort){
134         const data = this.producersDataSource.data
135         data.sort((a: EIProducer, b: EIProducer) => {
136             const isAsc = sort.direction === 'asc';
137             switch (sort.active) {
138               case 'id': return this.compare(a.ei_producer_id, b.ei_producer_id, isAsc);
139               case 'types': return this.compare(a.ei_producer_types, b.ei_producer_types, isAsc);
140               case 'status': return this.compare(a.status, b.status, isAsc);
141               default: return 0;
142             }
143           });
144           this.producersDataSource.data = data;
145     }
146     
147     compare(a: any, b: any, isAsc: boolean) {
148       return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
149     }
150
151     stopSort(event: any){
152         event.stopPropagation();
153     }
154
155     isDataIncluding(data: string, filter: string) : boolean {
156         return !filter || data.toLowerCase().includes(filter);
157     }
158
159     getEIJobInfo(eiJob: EIJob): EIJobInfo {
160         let info: EIJobInfo = this.eiJobInfo.get(eiJob.ei_job_data);
161         if (!info) {
162             info = new EIJobInfo(eiJob);
163             this.eiJobInfo.set(eiJob.ei_job_data, info);
164         }
165         return info;
166     }
167
168     getDisplayName(eiJob: EIJob): string {
169         if (eiJob.ei_job_identity) {
170             return eiJob.ei_job_identity;
171         }
172         return '< No id >';
173     }
174
175     getEITypeId(eiJob: EIJob): string {
176         if (eiJob.ei_type_identity) {
177             return eiJob.ei_type_identity;
178         }
179         return '< No type >';
180     }
181
182     getTargetUri(eiJob: EIJob): string {
183         if (eiJob.target_uri) {
184             return eiJob.target_uri;
185         }
186         return '< No target URI >';
187     }
188
189     isInstancesShown(eiJob: EIJob): boolean {
190         return this.getEIJobInfo(eiJob).isExpanded.getValue();
191     }
192
193     getExpandedObserver(eiJob: EIJob): Observable<boolean> {
194         return this.getEIJobInfo(eiJob).isExpanded.asObservable();
195     }
196
197     getEIProducerId(eiProducer: EIProducer): string {
198         if (eiProducer.ei_producer_id) {
199             return eiProducer.ei_producer_id;
200         }
201         return '< No id>';
202     }
203
204     getEIProducerTypes(eiProducer: EIProducer): string[] {
205         if (eiProducer.ei_producer_types) {
206             return eiProducer.ei_producer_types;
207         }
208         return ['< No types >'];
209     }
210
211     getEIProducerStatus(eiProducer: EIProducer): string {
212         if (eiProducer.status) {
213             return eiProducer.status;
214         }
215         return '< No status >';
216     }
217
218     refreshTables() {
219         this.eiJobsDataSource.loadJobs();
220         this.jobsDataSource = this.eiJobsDataSource.jobsDataSource();
221         this.eiProducersDataSource.loadProducers();
222         this.producersDataSource.data = this.eiProducersDataSource.eiProducers();
223     }
224 }