]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | import { |
2 | Component, | |
3 | EventEmitter, | |
4 | Input, | |
5 | OnDestroy, | |
6 | OnInit, | |
7 | Output, | |
8 | ViewChild | |
9 | } from '@angular/core'; | |
9f95a23c | 10 | |
f67539c2 | 11 | import _ from 'lodash'; |
9f95a23c TL |
12 | import { Subscription } from 'rxjs'; |
13 | ||
f67539c2 TL |
14 | import { HostService } from '~/app/shared/api/host.service'; |
15 | import { OrchestratorService } from '~/app/shared/api/orchestrator.service'; | |
16 | import { FormModalComponent } from '~/app/shared/components/form-modal/form-modal.component'; | |
17 | import { TableComponent } from '~/app/shared/datatable/table/table.component'; | |
18 | import { CellTemplate } from '~/app/shared/enum/cell-template.enum'; | |
19 | import { Icons } from '~/app/shared/enum/icons.enum'; | |
20 | import { NotificationType } from '~/app/shared/enum/notification-type.enum'; | |
21 | import { CdTableAction } from '~/app/shared/models/cd-table-action'; | |
22 | import { CdTableColumn } from '~/app/shared/models/cd-table-column'; | |
23 | import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change'; | |
24 | import { CdTableSelection } from '~/app/shared/models/cd-table-selection'; | |
25 | import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum'; | |
26 | import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface'; | |
27 | import { Permission } from '~/app/shared/models/permissions'; | |
28 | import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe'; | |
29 | import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; | |
30 | import { ModalService } from '~/app/shared/services/modal.service'; | |
31 | import { NotificationService } from '~/app/shared/services/notification.service'; | |
9f95a23c TL |
32 | import { InventoryDevice } from './inventory-device.model'; |
33 | ||
34 | @Component({ | |
35 | selector: 'cd-inventory-devices', | |
36 | templateUrl: './inventory-devices.component.html', | |
37 | styleUrls: ['./inventory-devices.component.scss'] | |
38 | }) | |
39 | export class InventoryDevicesComponent implements OnInit, OnDestroy { | |
40 | @ViewChild(TableComponent, { static: true }) | |
41 | table: TableComponent; | |
42 | ||
43 | // Devices | |
44 | @Input() devices: InventoryDevice[] = []; | |
45 | ||
46 | // Do not display these columns | |
47 | @Input() hiddenColumns: string[] = []; | |
48 | ||
49 | // Show filters for these columns, specify empty array to disable | |
50 | @Input() filterColumns = [ | |
51 | 'hostname', | |
52 | 'human_readable_type', | |
53 | 'available', | |
54 | 'sys_api.vendor', | |
55 | 'sys_api.model', | |
56 | 'sys_api.size' | |
57 | ]; | |
58 | ||
59 | // Device table row selection type | |
60 | @Input() selectionType: string = undefined; | |
61 | ||
62 | @Output() filterChange = new EventEmitter<CdTableColumnFiltersChange>(); | |
63 | ||
64 | @Output() fetchInventory = new EventEmitter(); | |
65 | ||
66 | icons = Icons; | |
67 | columns: Array<CdTableColumn> = []; | |
68 | selection: CdTableSelection = new CdTableSelection(); | |
69 | permission: Permission; | |
70 | tableActions: CdTableAction[]; | |
71 | fetchInventorySub: Subscription; | |
72 | ||
f67539c2 TL |
73 | @Input() orchStatus: OrchestratorStatus = undefined; |
74 | ||
75 | actionOrchFeatures = { | |
76 | identify: [OrchestratorFeature.DEVICE_BLINK_LIGHT] | |
77 | }; | |
78 | ||
9f95a23c TL |
79 | constructor( |
80 | private authStorageService: AuthStorageService, | |
81 | private dimlessBinary: DimlessBinaryPipe, | |
f67539c2 | 82 | private modalService: ModalService, |
9f95a23c | 83 | private notificationService: NotificationService, |
f67539c2 TL |
84 | private orchService: OrchestratorService, |
85 | private hostService: HostService | |
9f95a23c TL |
86 | ) {} |
87 | ||
88 | ngOnInit() { | |
89 | this.permission = this.authStorageService.getPermissions().osd; | |
90 | this.tableActions = [ | |
91 | { | |
92 | permission: 'update', | |
93 | icon: Icons.show, | |
94 | click: () => this.identifyDevice(), | |
f67539c2 TL |
95 | name: $localize`Identify`, |
96 | disable: (selection: CdTableSelection) => this.getDisable('identify', selection), | |
9f95a23c TL |
97 | canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection, |
98 | visible: () => _.isString(this.selectionType) | |
99 | } | |
100 | ]; | |
101 | const columns = [ | |
102 | { | |
f67539c2 | 103 | name: $localize`Hostname`, |
9f95a23c TL |
104 | prop: 'hostname', |
105 | flexGrow: 1 | |
106 | }, | |
107 | { | |
f67539c2 | 108 | name: $localize`Device path`, |
9f95a23c TL |
109 | prop: 'path', |
110 | flexGrow: 1 | |
111 | }, | |
112 | { | |
f67539c2 | 113 | name: $localize`Type`, |
9f95a23c TL |
114 | prop: 'human_readable_type', |
115 | flexGrow: 1, | |
116 | cellTransformation: CellTemplate.badge, | |
117 | customTemplateConfig: { | |
118 | map: { | |
119 | hdd: { value: 'HDD', class: 'badge-hdd' }, | |
120 | ssd: { value: 'SSD', class: 'badge-ssd' } | |
121 | } | |
122 | } | |
123 | }, | |
124 | { | |
f67539c2 | 125 | name: $localize`Available`, |
9f95a23c | 126 | prop: 'available', |
f6b5b4d7 TL |
127 | flexGrow: 1, |
128 | cellClass: 'text-center', | |
129 | cellTransformation: CellTemplate.checkIcon | |
9f95a23c TL |
130 | }, |
131 | { | |
f67539c2 | 132 | name: $localize`Vendor`, |
9f95a23c TL |
133 | prop: 'sys_api.vendor', |
134 | flexGrow: 1 | |
135 | }, | |
136 | { | |
f67539c2 | 137 | name: $localize`Model`, |
9f95a23c TL |
138 | prop: 'sys_api.model', |
139 | flexGrow: 1 | |
140 | }, | |
141 | { | |
f67539c2 | 142 | name: $localize`Size`, |
9f95a23c TL |
143 | prop: 'sys_api.size', |
144 | flexGrow: 1, | |
145 | pipe: this.dimlessBinary | |
146 | }, | |
147 | { | |
f67539c2 | 148 | name: $localize`OSDs`, |
9f95a23c TL |
149 | prop: 'osd_ids', |
150 | flexGrow: 1, | |
151 | cellTransformation: CellTemplate.badge, | |
152 | customTemplateConfig: { | |
153 | class: 'badge-dark', | |
154 | prefix: 'osd.' | |
155 | } | |
156 | } | |
157 | ]; | |
158 | ||
159 | this.columns = columns.filter((col: any) => { | |
160 | return !this.hiddenColumns.includes(col.prop); | |
161 | }); | |
162 | ||
163 | // init column filters | |
164 | _.forEach(this.filterColumns, (prop) => { | |
165 | const col = _.find(this.columns, { prop: prop }); | |
166 | if (col) { | |
167 | col.filterable = true; | |
168 | } | |
169 | }); | |
170 | ||
171 | if (this.fetchInventory.observers.length > 0) { | |
172 | this.fetchInventorySub = this.table.fetchData.subscribe(() => { | |
173 | this.fetchInventory.emit(); | |
174 | }); | |
175 | } | |
176 | } | |
177 | ||
178 | ngOnDestroy() { | |
179 | if (this.fetchInventorySub) { | |
180 | this.fetchInventorySub.unsubscribe(); | |
181 | } | |
182 | } | |
183 | ||
184 | onColumnFiltersChanged(event: CdTableColumnFiltersChange) { | |
185 | this.filterChange.emit(event); | |
186 | } | |
187 | ||
f67539c2 TL |
188 | getDisable(action: 'identify', selection: CdTableSelection): boolean | string { |
189 | if (!selection.hasSingleSelection) { | |
190 | return true; | |
191 | } | |
192 | return this.orchService.getTableActionDisableDesc( | |
193 | this.orchStatus, | |
194 | this.actionOrchFeatures[action] | |
195 | ); | |
196 | } | |
197 | ||
9f95a23c TL |
198 | updateSelection(selection: CdTableSelection) { |
199 | this.selection = selection; | |
200 | } | |
201 | ||
202 | identifyDevice() { | |
203 | const selected = this.selection.first(); | |
204 | const hostname = selected.hostname; | |
205 | const device = selected.path || selected.device_id; | |
206 | this.modalService.show(FormModalComponent, { | |
f67539c2 TL |
207 | titleText: $localize`Identify device ${device}`, |
208 | message: $localize`Please enter the duration how long to blink the LED.`, | |
209 | fields: [ | |
210 | { | |
211 | type: 'select', | |
212 | name: 'duration', | |
213 | value: 300, | |
214 | required: true, | |
215 | typeConfig: { | |
216 | options: [ | |
217 | { text: $localize`1 minute`, value: 60 }, | |
218 | { text: $localize`2 minutes`, value: 120 }, | |
219 | { text: $localize`5 minutes`, value: 300 }, | |
220 | { text: $localize`10 minutes`, value: 600 }, | |
221 | { text: $localize`15 minutes`, value: 900 } | |
222 | ] | |
9f95a23c | 223 | } |
9f95a23c | 224 | } |
f67539c2 TL |
225 | ], |
226 | submitButtonText: $localize`Execute`, | |
227 | onSubmit: (values: any) => { | |
228 | this.hostService.identifyDevice(hostname, device, values.duration).subscribe(() => { | |
229 | this.notificationService.show( | |
230 | NotificationType.success, | |
231 | $localize`Identifying '${device}' started on host '${hostname}'` | |
232 | ); | |
233 | }); | |
9f95a23c TL |
234 | } |
235 | }); | |
236 | } | |
237 | } |