]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
23c2e46d5e2507d04fecc3f922be0568aadf3ba1
[ceph.git] /
1 import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
2
3 import * as _ from 'lodash';
4
5 import { CellTemplate } from '../../enum/cell-template.enum';
6 import { CdTableColumn } from '../../models/cd-table-column';
7
8 /**
9  * Display the given data in a 2 column data table. The left column
10  * shows the 'key' attribute, the right column the 'value' attribute.
11  * The data table has the following characteristics:
12  * - No header and footer is displayed
13  * - The relation of the width for the columns 'key' and 'value' is 1:3
14  * - The 'key' column is displayed in bold text
15  */
16 @Component({
17   selector: 'cd-table-key-value',
18   templateUrl: './table-key-value.component.html',
19   styleUrls: ['./table-key-value.component.scss']
20 })
21 export class TableKeyValueComponent implements OnInit, OnChanges {
22   columns: Array<CdTableColumn> = [];
23
24   @Input()
25   data: any;
26   @Input()
27   autoReload: any = 5000;
28
29   @Input()
30   renderObjects = false;
31   // Only used if objects are rendered
32   @Input()
33   appendParentKey = true;
34
35   tableData: {
36     key: string;
37     value: any;
38   }[];
39
40   /**
41    * The function that will be called to update the input data.
42    */
43   @Output()
44   fetchData = new EventEmitter();
45
46   constructor() {}
47
48   ngOnInit() {
49     this.columns = [
50       {
51         prop: 'key',
52         flexGrow: 1,
53         cellTransformation: CellTemplate.bold
54       },
55       {
56         prop: 'value',
57         flexGrow: 3
58       }
59     ];
60     this.useData();
61   }
62
63   ngOnChanges(changes) {
64     this.useData();
65   }
66
67   useData() {
68     if (!this.data) {
69       return; // Wait for data
70     }
71     this.tableData = this._makePairs(this.data);
72   }
73
74   _makePairs(data: any) {
75     let temp = [];
76     if (!data) {
77       return; // Wait for data
78     } else if (_.isArray(data)) {
79       temp = this._makePairsFromArray(data);
80     } else if (_.isPlainObject(data)) {
81       temp = this._makePairsFromObject(data);
82     } else {
83       throw new Error('Wrong data format');
84     }
85     temp = temp.map((v) => this._convertValue(v)).filter((o) => o); // Filters out undefined
86     return this.renderObjects ? this._insertFlattenObjects(temp) : temp;
87   }
88
89   _makePairsFromArray(data: any[]) {
90     let temp = [];
91     const first = data[0];
92     if (_.isPlainObject(first)) {
93       if (_.has(first, 'key') && _.has(first, 'value')) {
94         temp = [...data];
95       } else {
96         throw new Error('Wrong object array format: {key: string, value: any}[]');
97       }
98     } else {
99       if (_.isArray(first)) {
100         if (first.length === 2) {
101           temp = data.map((a) => ({
102             key: a[0],
103             value: a[1]
104           }));
105         } else {
106           throw new Error('Wrong array format: [string, any][]');
107         }
108       }
109     }
110     return temp;
111   }
112
113   _makePairsFromObject(data: object) {
114     return Object.keys(data).map((k) => ({
115       key: k,
116       value: data[k]
117     }));
118   }
119
120   _insertFlattenObjects(temp: any[]) {
121     temp.forEach((v, i) => {
122       if (_.isPlainObject(v.value)) {
123         temp.splice(i, 1);
124         this._makePairs(v.value).forEach((item) => {
125           if (this.appendParentKey) {
126             item.key = v.key + ' ' + item.key;
127           }
128           temp.splice(i, 0, item);
129           i++;
130         });
131       }
132     });
133     return temp;
134   }
135
136   _convertValue(v: any) {
137     if (_.isArray(v.value)) {
138       v.value = v.value
139         .map((item) => (_.isPlainObject(item) ? JSON.stringify(item) : item))
140         .join(', ');
141     } else if (_.isPlainObject(v.value) && !this.renderObjects) {
142       return;
143     }
144     return v;
145   }
146
147   reloadData() {
148     // Forward event triggered by the 'cd-table' datatable.
149     this.fetchData.emit();
150   }
151 }