]>
git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/panel/DiskList.js
1 Ext
.define('pmx-disk-list', {
2 extend
: 'Ext.data.Model',
5 { name
: 'size', type
: 'number' },
6 { name
: 'osdid', type
: 'number', defaultValue
: -1 },
9 convert: function(value
, rec
) {
10 if (value
) return value
;
11 if (rec
.data
.health
) {
12 return rec
.data
.health
;
15 if (rec
.data
.type
=== 'partition') {
19 return Proxmox
.Utils
.unknownText
;
24 convert: function(value
, rec
) {
25 if (value
) return value
;
26 if (rec
.data
.devpath
) return rec
.data
.devpath
;
32 convert: function(value
, rec
) {
33 if (value
) return value
;
34 if (rec
.data
.type
) return rec
.data
.type
;
38 'vendor', 'model', 'serial', 'rpm', 'type', 'wearout', 'health',
40 idProperty
: 'devpath',
43 Ext
.define('Proxmox.DiskList', {
44 extend
: 'Ext.tree.Panel',
45 alias
: 'widget.pmxDiskList',
47 supportsWipeDisk
: false,
51 emptyText
: gettext('No Disks found'),
54 stateId
: 'tree-node-disks',
57 xclass
: 'Ext.app.ViewController',
61 let view
= me
.getView();
64 if (view
.includePartitions
) {
65 extraParams
['include-partitions'] = 1;
68 let url
= `${view.baseurl}/list`;
71 extraParams
: extraParams
,
77 openSmartWindow: function() {
79 let view
= me
.getView();
80 let selection
= view
.getSelection();
81 if (!selection
|| selection
.length
< 1) return;
83 let rec
= selection
[0];
84 Ext
.create('Proxmox.window.DiskSmart', {
85 baseurl
: view
.baseurl
,
92 let view
= me
.getView();
93 let selection
= view
.getSelection();
94 if (!selection
|| selection
.length
< 1) return;
96 let rec
= selection
[0];
97 Proxmox
.Utils
.API2Request({
98 url
: `${view.exturl}/initgpt`,
101 params
: { disk
: rec
.data
.name
},
102 failure
: response
=> Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
),
103 success: function(response
, options
) {
104 Ext
.create('Proxmox.window.TaskProgress', {
105 upid
: response
.result
.data
,
106 taskDone: function() {
115 wipeDisk: function() {
117 let view
= me
.getView();
118 let selection
= view
.getSelection();
119 if (!selection
|| selection
.length
< 1) return;
121 let rec
= selection
[0];
122 Proxmox
.Utils
.API2Request({
123 url
: `${view.exturl}/wipedisk`,
126 params
: { disk
: rec
.data
.name
},
127 failure
: response
=> Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
),
128 success: function(response
, options
) {
129 Ext
.create('Proxmox.window.TaskProgress', {
130 upid
: response
.result
.data
,
131 taskDone: function() {
140 init: function(view
) {
141 let nodename
= view
.nodename
|| 'localhost';
142 view
.baseurl
= `/api2/json/nodes/${nodename}/disks`;
143 view
.exturl
= `/api2/extjs/nodes/${nodename}/disks`;
145 this.store
= Ext
.create('Ext.data.Store', {
146 model
: 'pmx-disk-list',
148 this.store
.on('load', this.onLoad
, this);
150 Proxmox
.Utils
.monStoreErrors(view
, this.store
);
154 onLoad: function(store
, records
, success
, operation
) {
156 let view
= this.getView();
159 Proxmox
.Utils
.setErrorMask(
161 Proxmox
.Utils
.getResponseErrorMessage(operation
.getError()),
168 for (const item
of records
) {
169 let data
= item
.data
;
171 data
.expanded
= true;
173 data
.iconCls
= 'fa fa-fw fa-hdd-o x-fa-tree';
175 disks
[data
.devpath
] = data
;
178 for (const item
of records
) {
179 let data
= item
.data
;
181 disks
[data
.parent
].leaf
= false;
182 disks
[data
.parent
].children
.push(data
);
187 for (const [_
, device
] of Object
.entries(disks
)) {
188 children
.push(device
);
196 Proxmox
.Utils
.setErrorMask(view
, false);
200 renderDiskType: function(v
) {
201 if (v
=== undefined) return Proxmox
.Utils
.unknownText
;
203 case 'ssd': return 'SSD';
204 case 'hdd': return 'Hard Disk';
205 case 'usb': return 'USB';
210 renderDiskUsage: function(v
, metaData
, rec
) {
211 let extendedInfo
= '';
214 if (rec
.data
.osdid
!== undefined && rec
.data
.osdid
>= 0) {
215 types
.push(`OSD.${rec.data.osdid.toString()}`);
217 if (rec
.data
.journals
> 0) {
218 types
.push('Journal');
220 if (rec
.data
.db
> 0) {
223 if (rec
.data
.wal
> 0) {
226 if (types
.length
> 0) {
227 extendedInfo
= `, Ceph (${types.join(', ')})`;
230 return v
? `${v}${extendedInfo}` : Proxmox
.Utils
.noText
;
236 header
: gettext('Device'),
239 dataIndex
: 'devpath',
242 header
: gettext('Type'),
245 dataIndex
: 'disk-type',
246 renderer: function(v
) {
248 return me
.renderDiskType(v
);
252 header
: gettext('Usage'),
255 renderer: function(v
, metaData
, rec
) {
257 return me
.renderDiskUsage(v
, metaData
, rec
);
262 header
: gettext('Size'),
266 renderer
: Proxmox
.Utils
.format_size
,
273 renderer
: Proxmox
.Utils
.format_boolean
,
277 header
: gettext('Vendor'),
281 renderer
: Ext
.String
.htmlEncode
,
285 header
: gettext('Model'),
288 renderer
: Ext
.String
.htmlEncode
,
292 header
: gettext('Serial'),
295 renderer
: Ext
.String
.htmlEncode
,
299 header
: 'S.M.A.R.T.',
302 renderer
: Ext
.String
.htmlEncode
,
310 dataIndex
: 'wearout',
311 renderer: function(value
) {
312 if (Ext
.isNumeric(value
)) {
313 return (100 - value
).toString() + '%';
321 itemdblclick
: 'openSmartWindow',
324 initComponent: function() {
329 text
: gettext('Reload'),
333 xtype
: 'proxmoxButton',
334 text
: gettext('Show S.M.A.R.T. values'),
335 parentXType
: 'treepanel',
337 enableFn: function(rec
) {
338 if (!rec
|| rec
.data
.parent
) {
344 handler
: 'openSmartWindow',
347 xtype
: 'proxmoxButton',
348 text
: gettext('Initialize Disk with GPT'),
349 parentXType
: 'treepanel',
351 enableFn: function(rec
) {
352 if (!rec
|| rec
.data
.parent
||
353 (rec
.data
.used
&& rec
.data
.used
!== 'unused')) {
363 if (me
.supportsWipeDisk
) {
366 xtype
: 'proxmoxButton',
367 text
: gettext('Wipe Disk'),
368 parentXType
: 'treepanel',
370 confirmMsg: function(rec
) {
371 const data
= rec
.data
;
373 let mainMessage
= Ext
.String
.format(
374 gettext('Are you sure you want to wipe {0}?'),
377 mainMessage
+= `<br> ${gettext('All data on the device will be lost!')}`;
379 const type
= me
.renderDiskType(data
["disk-type"]);
382 if (data
.children
.length
> 0) {
383 const partitionUsage
= data
.children
.map(
384 partition
=> me
.renderDiskUsage(partition
.used
),
386 usage
= `${gettext('Partitions')} (${partitionUsage})`;
388 usage
= me
.renderDiskUsage(data
.used
, undefined, rec
);
391 const size
= Proxmox
.Utils
.format_size(data
.size
);
392 const serial
= Ext
.String
.htmlEncode(data
.serial
);
394 let additionalInfo
= `${gettext('Type')}: ${type}<br>`;
395 additionalInfo
+= `${gettext('Usage')}: ${usage}<br>`;
396 additionalInfo
+= `${gettext('Size')}: ${size}<br>`;
397 additionalInfo
+= `${gettext('Serial')}: ${serial}`;
399 return `${mainMessage}<br><br>${additionalInfo}`;
402 enableFn: function(rec
) {
403 // TODO enable for partitions once they can be selected for ZFS,LVM,etc. creation
404 if (!rec
|| rec
.data
.parent
) {