9 } from '@angular/core';
11 import * as _ from 'lodash';
13 import { CellTemplate } from '../../enum/cell-template.enum';
14 import { CdTableColumn } from '../../models/cd-table-column';
15 import { TableComponent } from '../table/table.component';
18 * Display the given data in a 2 column data table. The left column
19 * shows the 'key' attribute, the right column the 'value' attribute.
20 * The data table has the following characteristics:
21 * - No header and footer is displayed
22 * - The relation of the width for the columns 'key' and 'value' is 1:3
23 * - The 'key' column is displayed in bold text
26 selector: 'cd-table-key-value',
27 templateUrl: './table-key-value.component.html',
28 styleUrls: ['./table-key-value.component.scss']
30 export class TableKeyValueComponent implements OnInit, OnChanges {
31 @ViewChild(TableComponent)
32 table: TableComponent;
37 autoReload: any = 5000;
39 renderObjects = false;
40 // Only used if objects are rendered
42 appendParentKey = true;
44 columns: Array<CdTableColumn> = [];
51 * The function that will be called to update the input data.
54 fetchData = new EventEmitter();
63 cellTransformation: CellTemplate.bold
70 // We need to subscribe the 'fetchData' event here and not in the
71 // HTML template, otherwise the data table will display the loading
72 // indicator infinitely if data is only bound via '[data]="xyz"'.
73 // See for 'loadingIndicator' in 'TableComponent::ngOnInit()'.
74 if (this.fetchData.observers.length > 0) {
75 this.table.fetchData.subscribe(() => {
76 // Forward event triggered by the 'cd-table' data table.
77 this.fetchData.emit();
83 ngOnChanges(changes) {
89 return; // Wait for data
91 this.tableData = this._makePairs(this.data);
94 _makePairs(data: any) {
97 return; // Wait for data
98 } else if (_.isArray(data)) {
99 temp = this._makePairsFromArray(data);
100 } else if (_.isObject(data)) {
101 temp = this._makePairsFromObject(data);
103 throw new Error('Wrong data format');
105 temp = temp.map((v) => this._convertValue(v)).filter((o) => o); // Filters out undefined
106 return this.renderObjects ? this._insertFlattenObjects(temp) : temp;
109 _makePairsFromArray(data: any[]) {
111 const first = data[0];
112 if (_.isArray(first)) {
113 if (first.length === 2) {
114 temp = data.map((a) => ({
119 throw new Error('Wrong array format: [string, any][]');
121 } else if (_.isObject(first)) {
122 if (_.has(first, 'key') && _.has(first, 'value')) {
126 (previous: any[], item) => previous.concat(this._makePairsFromObject(item)),
134 _makePairsFromObject(data: object) {
135 return Object.keys(data).map((k) => ({
141 _insertFlattenObjects(temp: any[]) {
142 const itemsToRemoveIndexes = [];
143 const itemsToAdd = [];
144 temp.forEach((v, i) => {
145 if (_.isObject(v.value)) {
146 if (_.isEmpty(v.value)) {
147 temp[i]['value'] = '';
149 itemsToRemoveIndexes.push(i);
150 this._makePairs(v.value).forEach((item) => {
151 if (this.appendParentKey) {
152 item.key = v.key + ' ' + item.key;
154 itemsToAdd.push(item);
161 _.remove(temp, (item, itemIndex) => {
162 return _.includes(itemsToRemoveIndexes, itemIndex);
164 itemsToAdd.forEach((item) => {
171 _convertValue(v: any) {
172 if (_.isArray(v.value)) {
173 v.value = v.value.map((item) => (_.isObject(item) ? JSON.stringify(item) : item)).join(', ');
174 } else if (_.isObject(v.value) && !this.renderObjects) {