9 } from '@angular/core';
11 import * as _ from 'lodash';
12 import { Subscription } from 'rxjs';
14 import { OrchestratorService } from '../../../../shared/api/orchestrator.service';
15 import { FormModalComponent } from '../../../../shared/components/form-modal/form-modal.component';
16 import { TableComponent } from '../../../../shared/datatable/table/table.component';
17 import { CellTemplate } from '../../../../shared/enum/cell-template.enum';
18 import { Icons } from '../../../../shared/enum/icons.enum';
19 import { NotificationType } from '../../../../shared/enum/notification-type.enum';
20 import { CdTableAction } from '../../../../shared/models/cd-table-action';
21 import { CdTableColumn } from '../../../../shared/models/cd-table-column';
22 import { CdTableColumnFiltersChange } from '../../../../shared/models/cd-table-column-filters-change';
23 import { CdTableSelection } from '../../../../shared/models/cd-table-selection';
24 import { OrchestratorFeature } from '../../../../shared/models/orchestrator.enum';
25 import { OrchestratorStatus } from '../../../../shared/models/orchestrator.interface';
26 import { Permission } from '../../../../shared/models/permissions';
27 import { DimlessBinaryPipe } from '../../../../shared/pipes/dimless-binary.pipe';
28 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
29 import { ModalService } from '../../../../shared/services/modal.service';
30 import { NotificationService } from '../../../../shared/services/notification.service';
31 import { InventoryDevice } from './inventory-device.model';
34 selector: 'cd-inventory-devices',
35 templateUrl: './inventory-devices.component.html',
36 styleUrls: ['./inventory-devices.component.scss']
38 export class InventoryDevicesComponent implements OnInit, OnDestroy {
39 @ViewChild(TableComponent, { static: true })
40 table: TableComponent;
43 @Input() devices: InventoryDevice[] = [];
45 // Do not display these columns
46 @Input() hiddenColumns: string[] = [];
48 // Show filters for these columns, specify empty array to disable
49 @Input() filterColumns = [
51 'human_readable_type',
58 // Device table row selection type
59 @Input() selectionType: string = undefined;
61 @Output() filterChange = new EventEmitter<CdTableColumnFiltersChange>();
63 @Output() fetchInventory = new EventEmitter();
66 columns: Array<CdTableColumn> = [];
67 selection: CdTableSelection = new CdTableSelection();
68 permission: Permission;
69 tableActions: CdTableAction[];
70 fetchInventorySub: Subscription;
72 @Input() orchStatus: OrchestratorStatus = undefined;
74 actionOrchFeatures = {
75 identify: [OrchestratorFeature.DEVICE_BLINK_LIGHT]
79 private authStorageService: AuthStorageService,
80 private dimlessBinary: DimlessBinaryPipe,
81 private modalService: ModalService,
82 private notificationService: NotificationService,
83 private orchService: OrchestratorService
87 this.permission = this.authStorageService.getPermissions().osd;
92 click: () => this.identifyDevice(),
93 name: $localize`Identify`,
94 disable: (selection: CdTableSelection) => this.getDisable('identify', selection),
95 canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection,
96 visible: () => _.isString(this.selectionType)
101 name: $localize`Hostname`,
106 name: $localize`Device path`,
111 name: $localize`Type`,
112 prop: 'human_readable_type',
114 cellTransformation: CellTemplate.badge,
115 customTemplateConfig: {
117 hdd: { value: 'HDD', class: 'badge-hdd' },
118 ssd: { value: 'SSD', class: 'badge-ssd' }
123 name: $localize`Available`,
126 cellClass: 'text-center',
127 cellTransformation: CellTemplate.checkIcon
130 name: $localize`Vendor`,
131 prop: 'sys_api.vendor',
135 name: $localize`Model`,
136 prop: 'sys_api.model',
140 name: $localize`Size`,
141 prop: 'sys_api.size',
143 pipe: this.dimlessBinary
146 name: $localize`OSDs`,
149 cellTransformation: CellTemplate.badge,
150 customTemplateConfig: {
157 this.columns = columns.filter((col: any) => {
158 return !this.hiddenColumns.includes(col.prop);
161 // init column filters
162 _.forEach(this.filterColumns, (prop) => {
163 const col = _.find(this.columns, { prop: prop });
165 col.filterable = true;
169 if (this.fetchInventory.observers.length > 0) {
170 this.fetchInventorySub = this.table.fetchData.subscribe(() => {
171 this.fetchInventory.emit();
177 if (this.fetchInventorySub) {
178 this.fetchInventorySub.unsubscribe();
182 onColumnFiltersChanged(event: CdTableColumnFiltersChange) {
183 this.filterChange.emit(event);
186 getDisable(action: 'identify', selection: CdTableSelection): boolean | string {
187 if (!selection.hasSingleSelection) {
190 return this.orchService.getTableActionDisableDesc(
192 this.actionOrchFeatures[action]
196 updateSelection(selection: CdTableSelection) {
197 this.selection = selection;
201 const selected = this.selection.first();
202 const hostname = selected.hostname;
203 const device = selected.path || selected.device_id;
204 this.modalService.show(FormModalComponent, {
205 titleText: $localize`Identify device ${device}`,
206 message: $localize`Please enter the duration how long to blink the LED.`,
215 { text: $localize`1 minute`, value: 60 },
216 { text: $localize`2 minutes`, value: 120 },
217 { text: $localize`5 minutes`, value: 300 },
218 { text: $localize`10 minutes`, value: 600 },
219 { text: $localize`15 minutes`, value: 900 }
224 submitButtonText: $localize`Execute`,
225 onSubmit: (values: any) => {
226 this.orchService.identifyDevice(hostname, device, values.duration).subscribe(() => {
227 this.notificationService.show(
228 NotificationType.success,
229 $localize`Identifying '${device}' started on host '${hostname}'`