1 Ext
.define('PBS.TapeManagement.DriveStatus', {
2 extend
: 'Ext.panel.Panel',
3 alias
: 'widget.pbsDriveStatus',
4 mixins
: ['Proxmox.Mixin.CBind'],
6 tools
: [PBS
.Utils
.get_help_tool("tape_backup")],
8 cbindData: function(config
) {
10 me
.setTitle(`${gettext('Drive')}: ${me.drive}`);
11 let baseurl
= `/api2/json/tape/drive/${me.drive}/`;
13 driveStatusUrl
: `${baseurl}/status`,
14 cartridgeMemoryUrl
: `${baseurl}/cartridge-memory`,
34 xclass
: 'Ext.app.ViewController',
38 me
.lookup('statusgrid').rstore
.load();
43 let statusgrid
= me
.lookup('statusgrid');
44 let online
= statusgrid
.getObjectValue('file-number') !== undefined;
45 let vm
= me
.getViewModel();
46 vm
.set('online', online
);
49 onStateLoad: function(store
) {
51 let view
= me
.getView();
52 let vm
= me
.getViewModel();
53 let driveRecord
= store
.findRecord('name', view
.drive
, 0, false, true, true);
54 let busy
= !!driveRecord
.data
.state
;
56 let statusgrid
= me
.lookup('statusgrid');
57 if (!vm
.get('loaded')) {
59 // have to use a timeout so that the component can be rendered first
60 // otherwise the 'mask' call errors out
61 setTimeout(function() {
62 statusgrid
.mask(gettext('Drive is busy'));
65 // have to use a timeout so that the component can be rendered first
66 // otherwise the 'mask' call errors out
67 setTimeout(function() {
71 vm
.set('loaded', true);
76 labelMedia: function() {
78 Ext
.create('PBS.TapeManagement.LabelMediaWindow', {
79 driveid
: me
.getView().drive
,
85 let view
= me
.getView();
86 let driveid
= view
.drive
;
87 PBS
.Utils
.driveCommand(driveid
, 'format-media', {
90 success: function(response
) {
91 Ext
.create('Proxmox.window.TaskProgress', {
92 upid
: response
.result
.data
,
93 taskDone: function() {
101 ejectMedia: function() {
103 let view
= me
.getView();
104 let driveid
= view
.drive
;
105 PBS
.Utils
.driveCommand(driveid
, 'eject-media', {
108 success: function(response
) {
109 Ext
.create('Proxmox.window.TaskProgress', {
110 upid
: response
.result
.data
,
111 taskDone: function() {
119 catalog: function() {
121 let view
= me
.getView();
122 let drive
= view
.drive
;
123 PBS
.Utils
.driveCommand(drive
, 'catalog', {
126 success: function(response
) {
127 Ext
.create('Proxmox.window.TaskViewer', {
128 upid
: response
.result
.data
,
129 taskDone: function() {
137 readLabel: function() {
139 let view
= me
.getView();
140 let drive
= view
.drive
;
142 PBS
.Utils
.driveCommand(drive
, 'read-label', {
144 success
: PBS
.Utils
.showMediaLabelWindow
,
148 volumeStatistics: function() {
150 let view
= me
.getView();
151 let drive
= view
.drive
;
152 PBS
.Utils
.driveCommand(drive
, 'volume-statistics', {
154 success
: PBS
.Utils
.showVolumeStatisticsWindow
,
158 cartridgeMemory: function() {
160 let view
= me
.getView();
161 let drive
= view
.drive
;
162 PBS
.Utils
.driveCommand(drive
, 'cartridge-memory', {
163 waitMsgTarget
: me
.getView(),
164 success
: PBS
.Utils
.showCartridgeMemoryWindow
,
168 init: function(view
) {
170 me
.mon(me
.lookup('statusgrid').getStore().rstore
, 'load', 'onLoad');
171 let tapeStore
= Ext
.ComponentQuery
.query('navigationtree')[0].tapestore
;
172 me
.mon(tapeStore
, 'load', 'onStateLoad');
173 if (tapeStore
.isLoaded()) {
174 me
.onStateLoad(tapeStore
);
181 xtype
: 'proxmoxButton',
183 text
: gettext('Reload'),
191 text
: gettext('Label Media'),
192 xtype
: 'proxmoxButton',
193 handler
: 'labelMedia',
194 iconCls
: 'fa fa-barcode',
197 disabled
: '{!online}',
201 text
: gettext('Eject'),
202 xtype
: 'proxmoxButton',
203 handler
: 'ejectMedia',
204 iconCls
: 'fa fa-eject',
207 disabled
: '{!online}',
211 text
: gettext('Format'),
212 xtype
: 'proxmoxButton',
214 iconCls
: 'fa fa-trash-o',
216 confirmMsg
: gettext('Are you sure you want to erase the inserted tape?'),
219 disabled
: '{!online}',
223 text
: gettext('Catalog'),
224 xtype
: 'proxmoxButton',
226 iconCls
: 'fa fa-book',
229 disabled
: '{!online}',
233 text
: gettext('Read Label'),
234 xtype
: 'proxmoxButton',
235 handler
: 'readLabel',
236 iconCls
: 'fa fa-tag',
239 disabled
: '{!online}',
243 text
: gettext('Volume Statistics'),
244 xtype
: 'proxmoxButton',
245 handler
: 'volumeStatistics',
246 iconCls
: 'fa fa-line-chart',
249 disabled
: '{!online}',
253 text
: gettext('Cartridge Memory'),
254 xtype
: 'proxmoxButton',
255 iconCls
: 'fa fa-hdd-o',
256 handler
: 'cartridgeMemory',
259 disabled
: '{!online}',
278 xtype
: 'pbsDriveInfoPanel',
284 xtype
: 'pbsDriveStatusGrid',
285 reference
: 'statusgrid',
287 url
: '{driveStatusUrl}',
295 Ext
.define('PBS.TapeManagement.DriveStatusGrid', {
296 extend
: 'Proxmox.grid.ObjectGrid',
297 alias
: 'widget.pbsDriveStatusGrid',
299 title
: gettext('Status'),
304 header
: gettext('Tape Density'),
308 header
: gettext('Block Size'),
309 renderer: function(value
) {
311 return gettext('Dynamic');
313 return `${gettext('Fixed')} - ${Proxmox.Utils.format_size(value)}`;
318 header
: gettext('Write Protect'),
323 header
: gettext('Buffer Mode'),
327 header
: gettext('Compression'),
330 header
: gettext('File Number'),
333 header
: gettext('Block Number'),
336 header
: gettext('Tape Manufacture Date'),
337 renderer: function(value
) {
339 return Ext
.Date
.format(new Date(value
*1000), "Y-m-d");
345 header
: gettext('Tape Read'),
346 renderer
: Proxmox
.Utils
.format_size
,
349 header
: gettext('Tape Written'),
350 renderer
: Proxmox
.Utils
.format_size
,
353 header
: gettext('Tape Passes'),
356 header
: gettext('Tape Wearout'),
357 renderer: function(value
) {
358 if (value
!== undefined) {
359 return (value
*100).toFixed(2) + "%";
367 Ext
.define('PBS.TapeManagement.DriveInfoPanel', {
368 extend
: 'Ext.panel.Panel',
369 alias
: 'widget.pbsDriveInfoPanel',
371 title
: gettext('Information'),
385 driveState: function(get) {
386 let drive
= get('drive');
387 return PBS
.Utils
.renderDriveState(drive
.state
, {});
394 xtype
: 'pmxInfoWidget',
395 title
: gettext('Name'),
398 text
: '{drive.name}',
403 xtype
: 'pmxInfoWidget',
404 title
: gettext('Vendor'),
407 text
: '{drive.vendor}',
412 xtype
: 'pmxInfoWidget',
413 title
: gettext('Model'),
416 text
: '{drive.model}',
421 xtype
: 'pmxInfoWidget',
422 title
: gettext('Serial'),
425 text
: '{drive.serial}',
430 xtype
: 'pmxInfoWidget',
431 title
: gettext('Path'),
434 text
: '{drive.path}',
439 xtype
: 'pmxInfoWidget',
440 reference
: 'statewidget',
441 title
: gettext('State'),
444 text
: '{driveState}',
450 clickState: function(e
, t
, eOpts
) {
452 let vm
= me
.getViewModel();
453 let drive
= vm
.get('drive');
454 if (t
.classList
.contains('right-aligned')) {
455 let upid
= drive
.state
;
456 if (!upid
|| !upid
.startsWith("UPID")) {
460 Ext
.create('Proxmox.window.TaskViewer', {
467 updateData: function(store
) {
472 let record
= store
.findRecord('name', me
.drive
, 0, false, true, true);
477 let vm
= me
.getViewModel();
478 vm
.set('drive', record
.data
);
483 updatePointer: function() {
485 let stateWidget
= me
.down('pmxInfoWidget[reference=statewidget]');
486 let stateEl
= stateWidget
.getEl();
488 setTimeout(function() {
494 let vm
= me
.getViewModel();
495 let drive
= vm
.get('drive');
498 stateEl
.addCls('info-pointer');
500 stateEl
.removeCls('info-pointer');
505 afterrender: function() {
507 let stateWidget
= me
.down('pmxInfoWidget[reference=statewidget]');
508 let stateEl
= stateWidget
.getEl();
509 stateEl
.on('click', me
.clickState
, me
);
513 initComponent: function() {
516 throw "no drive given";
521 let tapeStore
= Ext
.ComponentQuery
.query('navigationtree')[0].tapestore
;
522 me
.mon(tapeStore
, 'load', me
.updateData
, me
);
523 if (tapeStore
.isLoaded()) {
524 me
.updateData(tapeStore
);