Add filters to the Jobs table of the EIC
[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 { animate, state, style, transition, trigger } from '@angular/animations';
22 import { FormBuilder, FormGroup, AbstractControl } from '@angular/forms';
23 import { MatTableDataSource } from '@angular/material';
24
25 import { defer, BehaviorSubject, Observable } from 'rxjs';
26 import { map, withLatestFrom, startWith } from 'rxjs/operators';
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     producers$: Observable<EIProducer[]>;
55     filteredProducers$: Observable<EIProducer[]>;
56
57     eiJobInfo = new Map<string, EIJobInfo>();
58     darkMode: boolean;
59     searchString: string;
60     formGroup: FormGroup;
61     jobsDataSource: MatTableDataSource<EIJob>;
62
63     readonly jobsFormControl: AbstractControl;
64
65     constructor(
66         private eiJobsDataSource: EIJobDataSource,
67         private eiProducersDataSource: EIProducerDataSource,
68         private ui: UiService,
69         private formBuilder: FormBuilder) {
70
71         this.formGroup = formBuilder.group({ filter: [""] });
72         this.jobsFormControl = formBuilder.group({
73             id: '',
74             typeId: '',
75             owner: '',
76             targetUri:'',
77         })
78     }
79
80     ngOnInit() {
81         this.eiJobsDataSource.getJobs();
82         this.jobsDataSource = new MatTableDataSource(this.eiJobsDataSource.eiJobsSubject.value);
83
84         this.jobsFormControl.valueChanges.subscribe(value => {
85             const filter = {...value, id: value.id.trim().toLowerCase()} as string;
86             this.jobsDataSource.filter = filter;
87         });
88
89         this.jobsDataSource.filterPredicate = ((data, filter) => {
90             return this.isDataIncluding(data.ei_job_identity, filter.id) 
91                 && this.isDataIncluding(data.target_uri, filter.target_uri)
92                 && this.isDataIncluding(data.owner, filter.owner)
93                 && this.isDataIncluding(data.ei_type_identity, filter.typeId);
94           }) as (EIJob, string) => boolean;
95
96         this.producers$= this.eiProducersDataSource.loadProducers();
97         this.filteredProducers$ = defer(() => this.formGroup.get("filter")
98         .valueChanges.pipe(
99             startWith(""),
100             withLatestFrom(this.producers$),
101             map(([val, producers]) =>
102             !val ? producers : producers.filter((x) =>
103             x.ei_producer_id.toLowerCase().includes(val))))
104         );
105
106         this.ui.darkModeState.subscribe((isDark) => {
107             this.darkMode = isDark;
108         });
109     }
110
111     isDataIncluding(data: string, filter: string) : boolean {
112         return !filter || data.toLowerCase().includes(filter);
113     }
114
115     getEIJobInfo(eiJob: EIJob): EIJobInfo {
116         let info: EIJobInfo = this.eiJobInfo.get(eiJob.ei_job_data);
117         if (!info) {
118             info = new EIJobInfo(eiJob);
119             this.eiJobInfo.set(eiJob.ei_job_data, info);
120         }
121         return info;
122     }
123
124     getDisplayName(eiJob: EIJob): string {
125         if (eiJob.ei_job_identity) {
126             return eiJob.ei_job_identity;
127         }
128         return '< No id >';
129     }
130
131     getEITypeId(eiJob: EIJob): string {
132         if (eiJob.ei_type_identity) {
133             return eiJob.ei_type_identity;
134         }
135         return '< No type >';
136     }
137
138     getTargetUri(eiJob: EIJob): string {
139         if (eiJob.target_uri) {
140             return eiJob.target_uri;
141         }
142         return '< No target URI >';
143     }
144
145     isInstancesShown(eiJob: EIJob): boolean {
146         return this.getEIJobInfo(eiJob).isExpanded.getValue();
147     }
148
149     getExpandedObserver(eiJob: EIJob): Observable<boolean> {
150         return this.getEIJobInfo(eiJob).isExpanded.asObservable();
151     }
152
153     getEIProducerId(eiProducer: EIProducer): string {
154         if (eiProducer.ei_producer_id) {
155             return eiProducer.ei_producer_id;
156         }
157         return '< No id>';
158     }
159
160     getEIProducerTypes(eiProducer: EIProducer): string[] {
161         if (eiProducer.ei_producer_types) {
162             return eiProducer.ei_producer_types;
163         }
164         return ['< No types >'];
165     }
166
167     getEIProducerStatus(eiProducer: EIProducer): string {
168         if (eiProducer.status) {
169             return eiProducer.status;
170         }
171         return '< No status >';
172     }
173
174     refreshTables() {
175         this.eiJobsDataSource.getJobs();
176         this.eiProducersDataSource.loadProducers();
177     }
178 }