1 import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
2 import { I18n } from '@ngx-translate/i18n-polyfill';
4 import { getterForProp } from '@swimlane/ngx-datatable/release/utils';
5 import * as _ from 'lodash';
7 import { CellTemplate } from '../../../../shared/enum/cell-template.enum';
8 import { Icons } from '../../../../shared/enum/icons.enum';
9 import { CdTableColumn } from '../../../../shared/models/cd-table-column';
10 import { DimlessBinaryPipe } from '../../../../shared/pipes/dimless-binary.pipe';
11 import { InventoryDeviceFilter } from './inventory-device-filter.interface';
12 import { InventoryDeviceFiltersChangeEvent } from './inventory-device-filters-change-event.interface';
13 import { InventoryDevice } from './inventory-device.model';
16 selector: 'cd-inventory-devices',
17 templateUrl: './inventory-devices.component.html',
18 styleUrls: ['./inventory-devices.component.scss']
20 export class InventoryDevicesComponent implements OnInit, OnChanges {
22 @Input() devices: InventoryDevice[] = [];
24 // Do not display these columns
25 @Input() hiddenColumns: string[] = [];
27 // Show filters for these columns, specify empty array to disable
28 @Input() filterColumns = [
30 'human_readable_type',
37 // Device table row selection type
38 @Input() selectionType: string = undefined;
40 @Output() filterChange = new EventEmitter<InventoryDeviceFiltersChangeEvent>();
42 filterInDevices: InventoryDevice[] = [];
43 filterOutDevices: InventoryDevice[] = [];
46 columns: Array<CdTableColumn> = [];
47 filters: InventoryDeviceFilter[] = [];
49 constructor(private dimlessBinary: DimlessBinaryPipe, private i18n: I18n) {}
54 name: this.i18n('Hostname'),
59 name: this.i18n('Device path'),
64 name: this.i18n('Type'),
65 prop: 'human_readable_type',
67 cellTransformation: CellTemplate.badge,
68 customTemplateConfig: {
70 hdd: { value: 'HDD', class: 'badge-hdd' },
71 'ssd/nvme': { value: 'SSD', class: 'badge-ssd' }
76 name: this.i18n('Available'),
81 name: this.i18n('Vendor'),
82 prop: 'sys_api.vendor',
86 name: this.i18n('Model'),
87 prop: 'sys_api.model',
91 name: this.i18n('Size'),
94 pipe: this.dimlessBinary
97 name: this.i18n('OSDs'),
100 cellTransformation: CellTemplate.badge,
101 customTemplateConfig: {
108 this.columns = columns.filter((col: any) => {
109 return !this.hiddenColumns.includes(col.prop);
113 this.filters = this.columns
114 .filter((col: any) => {
115 return this.filterColumns.includes(col.prop);
123 options: [{ value: '*', formatValue: '*' }],
128 this.filterInDevices = [...this.devices];
129 this.updateFilterOptions(this.devices);
133 this.updateFilterOptions(this.devices);
134 this.filterInDevices = [...this.devices];
135 // TODO: apply filter, columns changes, filter changes
138 updateFilterOptions(devices: InventoryDevice[]) {
139 // update filter options to all possible values in a column, might be time-consuming
140 this.filters.forEach((filter) => {
141 const values = _.sortedUniq(_.map(devices, filter.prop).sort());
142 const options = values.map((v: string) => {
145 formatValue: filter.pipe ? filter.pipe.transform(v) : v
148 filter.options = [{ value: '*', formatValue: '*' }, ...options];
153 this.filterOutDevices = [];
154 const appliedFilters = [];
155 let devices: any = [...this.devices];
156 this.filters.forEach((filter) => {
157 if (filter.value === filter.initValue) {
160 appliedFilters.push({
164 formatValue: filter.pipe ? filter.pipe.transform(filter.value) : filter.value
166 // Separate devices to filter-in and filter-out parts.
167 // Cast column value to string type because options are always string.
168 const parts = _.partition(devices, (row) => {
169 // use getter from ngx-datatable for props like 'sys_api.size'
170 const valueGetter = getterForProp(filter.prop);
171 return `${valueGetter(row, filter.prop)}` === filter.value;
174 this.filterOutDevices = [...this.filterOutDevices, ...parts[1]];
176 this.filterInDevices = devices;
177 this.filterChange.emit({
178 filters: appliedFilters,
179 filterInDevices: this.filterInDevices,
180 filterOutDevices: this.filterOutDevices
189 this.filters.forEach((item) => {
190 item.value = item.initValue;
192 this.filterInDevices = [...this.devices];
193 this.filterOutDevices = [];
194 this.filterChange.emit({
196 filterInDevices: this.filterInDevices,
197 filterOutDevices: this.filterOutDevices