Dynamic columns in GAB table
[sdc.git] / catalog-ui / src / app / ng2 / components / logic / generic-artifact-browser / generic-artifact-browser.component.ts
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 Nokia. All rights reserved.
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
21 import {Component, Input, ViewEncapsulation} from "@angular/core";
22 import {GabService, IServerResponse} from "../../../services/gab.service";
23 import {PathsAndNamesDefinition} from "../../../../models/paths-and-names";
24
25 const COLUMN_PREFIX: string = 'col';
26
27 @Component({
28   selector: 'gab',
29   templateUrl: './generic-artifact-browser.component.html',
30   styleUrls: ['./generic-artifact-browser.component.less'],
31   encapsulation: ViewEncapsulation.None
32 })
33 export class GenericArtifactBrowserComponent {
34   @Input()
35   pathsandnames: PathsAndNamesDefinition[];
36   @Input()
37   artifactid: string;
38   @Input()
39   resourceid: string;
40
41   columns: ColumnDefinition[];
42   originColumns: ColumnDefinition[];
43   rows: any[];
44   originRows: any[];
45   isLoading: boolean;
46   ready: boolean;
47   columnsFilters: Map<string, string>;
48   addNewColumn: boolean;
49
50   constructor(private gabService: GabService) {
51   }
52
53   ngOnInit() {
54     this.ready = false;
55     this.isLoading = true;
56     this.columns = [];
57     this.loadArtifacts();
58   }
59
60   loadArtifacts() {
61     this.addNewColumn = false;
62     this.columnsFilters = new Map<string, string>();
63     let paths: string[] = this.pathsandnames.map(item => item.path);
64     this.gabService.getArtifact(this.artifactid, this.resourceid, paths)
65     .subscribe(
66         response => {
67           let typedServerResponse: IServerResponse = response.json() as IServerResponse;
68           this.normalizeDataForNgxDatatable(typedServerResponse.data);
69         },
70         () => {
71             this.ready = false;
72             this.isLoading = false;
73         },
74         () => {
75           this.ready = true;
76           this.isLoading = false;
77         }
78     );
79   }
80
81   refresh() {
82     this.loadArtifacts();
83   }
84
85   canBeDeleted(name: string){
86     return this.originColumns.filter(function(column){
87       return column.name === name;
88     }).length === 0;
89   }
90
91   deleteColumn(col: ColumnDefinition) {
92     this.pathsandnames = this.pathsandnames.filter(function(pathandname){
93       return pathandname.friendlyName != col.name;
94     });
95     this.columns = this.columns.filter(function(column){
96       return column != col;
97     })
98   }
99
100   hideAddNewColumn() {
101     this.addNewColumn = false;
102   }
103
104   showAddNewColumn() {
105     this.addNewColumn = true;
106   }
107
108   updateColumnFilter(event, column) {
109     const val = event.target.value.toLowerCase();
110     this.columnsFilters.set(column, val);
111     let temp_rows = [...this.originRows];
112
113     this.columnsFilters.forEach((value: string, key: string) => {
114       temp_rows = this.updateSingleColumnFilter(value, key, temp_rows);
115     });
116
117     // update the rows
118     this.rows = temp_rows
119   }
120
121   private updateSingleColumnFilter(value, column, rows) {
122     return rows.filter(function (obj) {
123       const row = obj[column];
124       return row !== undefined && row.toLowerCase().indexOf(value) !== -1 || !value;
125     });
126   }
127
128   private normalizeDataForNgxDatatable(data: [{ [key: string]: string }]) {
129     let result: NormalizationResult = this.getNormalizationResult(data, this.pathsandnames);
130     this.rows = result.rows;
131     this.originRows = result.rows;
132     this.columns = result.columns;
133     if (!this.originColumns){
134       this.originColumns = [...result.columns];
135     }
136   }
137
138   private getNormalizationResult(data: [{ [key: string]: string }],
139                                  pathsAndNames: PathsAndNamesDefinition[]): NormalizationResult {
140     //Prepare column names and column data property names
141     let mappingsPathToProp = new Map<string, string>();
142     let columnsDefinitions = this.normalizeColumns(pathsAndNames, mappingsPathToProp);
143
144     //Convert rows from { "string": "string" } to { prop : "string" } format
145     //This is required by NgxDatatable component
146     let arrayOfRows = this.normalizeRows(data, mappingsPathToProp);
147
148     return new NormalizationResult(arrayOfRows, columnsDefinitions);
149   }
150
151   private normalizeColumns(pathsAndNames: PathsAndNamesDefinition[], mappingsPathToProp: Map<string, string>) {
152     let columnsDefinitions: ColumnDefinition[] = [];
153     let index: number = 1;
154
155     pathsAndNames.forEach(function (col) {
156       let columnDataPropertyName: string = COLUMN_PREFIX + index;
157       mappingsPathToProp.set(col.path, columnDataPropertyName);
158       let cell: ColumnDefinition = new ColumnDefinition(col.friendlyName, columnDataPropertyName);
159       columnsDefinitions.push(cell);
160       index += 1;
161     });
162     return columnsDefinitions;
163   }
164
165   private normalizeRows(data: [{ [key: string]: string }], mappingsPathToProp: Map<string, string>) {
166     let arrayOfRows = [];
167     data.forEach(function (col) {
168       let row = {};
169       for (let key in col) {
170         if (col.hasOwnProperty(key)) {
171           let columnNameAsProp = mappingsPathToProp.get(key);
172           row[columnNameAsProp] = col[key];
173         }
174       }
175       arrayOfRows.push(row);
176     });
177
178     return arrayOfRows;
179   }
180 }
181
182 class NormalizationResult {
183   constructor(public rows: any[], public columns: ColumnDefinition[]) {
184   }
185 }
186
187 export class ColumnDefinition {
188   constructor(public name: string, public prop: string) {
189   }
190 }
191