]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
a440bb1ffa693cbaf00a41d7caee798b36badc49
[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() data: any;
25   @Input() autoReload: any = 5000;
26
27   @Input() renderObjects = false;
28   // Only used if objects are rendered
29   @Input() appendParentKey = true;
30
31   tableData: {
32     key: string;
33     value: any;
34   }[];
35
36   /**
37    * The function that will be called to update the input data.
38    */
39   @Output() fetchData = new EventEmitter();
40
41   constructor() {}
42
43   ngOnInit() {
44     this.columns = [
45       {
46         prop: 'key',
47         flexGrow: 1,
48         cellTransformation: CellTemplate.bold
49       },
50       {
51         prop: 'value',
52         flexGrow: 3
53       }
54     ];
55     this.useData();
56   }
57
58   ngOnChanges(changes) {
59     this.useData();
60   }
61
62   useData() {
63     if (!this.data) {
64       return; // Wait for data
65     }
66     this.tableData = this._makePairs(this.data);
67   }
68
69   _makePairs(data: any) {
70     let temp = [];
71     if (!data) {
72       return; // Wait for data
73     } else if (_.isArray(data)) {
74       temp = this._makePairsFromArray(data);
75     } else if (_.isPlainObject(data)) {
76       temp = this._makePairsFromObject(data);
77     } else {
78       throw new Error('Wrong data format');
79     }
80     temp = temp.map((v) => this._convertValue(v)).filter((o) => o); // Filters out undefined
81     return this.renderObjects ? this._insertFlattenObjects(temp) : temp;
82   }
83
84   _makePairsFromArray(data: any[]) {
85     let temp = [];
86     const first = data[0];
87     if (_.isPlainObject(first)) {
88       if (_.has(first, 'key') && _.has(first, 'value')) {
89         temp = [...data];
90       } else {
91         throw new Error('Wrong object array format: {key: string, value: any}[]');
92       }
93     } else {
94       if (_.isArray(first)) {
95         if (first.length === 2) {
96           temp = data.map((a) => ({
97             key: a[0],
98             value: a[1]
99           }));
100         } else {
101           throw new Error('Wrong array format: [string, any][]');
102         }
103       }
104     }
105     return temp;
106   }
107
108   _makePairsFromObject(data: object) {
109     return Object.keys(data).map((k) => ({
110       key: k,
111       value: data[k]
112     }));
113   }
114
115   _insertFlattenObjects(temp: any[]) {
116     temp.forEach((v, i) => {
117       if (_.isPlainObject(v.value)) {
118         temp.splice(i, 1);
119         this._makePairs(v.value).forEach((item) => {
120           if (this.appendParentKey) {
121             item.key = v.key + ' ' + item.key;
122           }
123           temp.splice(i, 0, item);
124           i++;
125         });
126       }
127     });
128     return temp;
129   }
130
131   _convertValue(v: any) {
132     if (_.isArray(v.value)) {
133       v.value = v.value
134         .map((item) => (_.isPlainObject(item) ? JSON.stringify(item) : item))
135         .join(', ');
136     } else if (_.isPlainObject(v.value) && !this.renderObjects) {
137       return;
138     }
139     return v;
140   }
141
142   reloadData() {
143     // Forward event triggered by the 'cd-table' datatable.
144     this.fetchData.emit();
145   }
146 }