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 cellClass: 'text-center',
68 cellTransformation: CellTemplate.badge,
69 customTemplateConfig: {
71 hdd: { value: 'HDD', class: 'badge-hdd' },
72 'ssd/nvme': { value: 'SSD', class: 'badge-ssd' }
77 name: this.i18n('Available'),
82 name: this.i18n('Vendor'),
83 prop: 'sys_api.vendor',
87 name: this.i18n('Model'),
88 prop: 'sys_api.model',
92 name: this.i18n('Size'),
95 pipe: this.dimlessBinary
98 name: this.i18n('OSDs'),
101 cellClass: 'text-center',
102 cellTransformation: CellTemplate.badge,
103 customTemplateConfig: {
110 this.columns = columns.filter((col: any) => {
111 return !this.hiddenColumns.includes(col.prop);
115 this.filters = this.columns
116 .filter((col: any) => {
117 return this.filterColumns.includes(col.prop);
125 options: [{ value: '*', formatValue: '*' }],
130 this.filterInDevices = [...this.devices];
131 this.updateFilterOptions(this.devices);
135 this.updateFilterOptions(this.devices);
136 this.filterInDevices = [...this.devices];
137 // TODO: apply filter, columns changes, filter changes
140 updateFilterOptions(devices: InventoryDevice[]) {
141 // update filter options to all possible values in a column, might be time-consuming
142 this.filters.forEach((filter) => {
143 const values = _.sortedUniq(_.map(devices, filter.prop).sort());
144 const options = values.map((v: string) => {
147 formatValue: filter.pipe ? filter.pipe.transform(v) : v
150 filter.options = [{ value: '*', formatValue: '*' }, ...options];
155 this.filterOutDevices = [];
156 const appliedFilters = [];
157 let devices: any = [...this.devices];
158 this.filters.forEach((filter) => {
159 if (filter.value === filter.initValue) {
162 appliedFilters.push({
166 formatValue: filter.pipe ? filter.pipe.transform(filter.value) : filter.value
168 // Separate devices to filter-in and filter-out parts.
169 // Cast column value to string type because options are always string.
170 const parts = _.partition(devices, (row) => {
171 // use getter from ngx-datatable for props like 'sys_api.size'
172 const valueGetter = getterForProp(filter.prop);
173 return `${valueGetter(row, filter.prop)}` === filter.value;
176 this.filterOutDevices = [...this.filterOutDevices, ...parts[1]];
178 this.filterInDevices = devices;
179 this.filterChange.emit({
180 filters: appliedFilters,
181 filterInDevices: this.filterInDevices,
182 filterOutDevices: this.filterOutDevices
191 this.filters.forEach((item) => {
192 item.value = item.initValue;
194 this.filterInDevices = [...this.devices];
195 this.filterOutDevices = [];
196 this.filterChange.emit({
198 filterInDevices: this.filterInDevices,
199 filterOutDevices: this.filterOutDevices