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