proxmox-backup/www/tape/DriveStatus.js
Dominik Csapak 6f3714b9aa ui: tape/DriveStatus: use the drive state to determine a status-load
since the status api call blocks the drive, it only makes sense to do
when the drive is idle.

so do not reload on activate, but when the drive changes the first
time from busy to idle

also disable the reload button when the drive is busy

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-03-02 12:52:39 +01:00

364 lines
7.0 KiB
JavaScript

Ext.define('PBS.TapeManagement.DriveStatus', {
extend: 'Ext.panel.Panel',
alias: 'widget.pbsDriveStatus',
mixins: ['Proxmox.Mixin.CBind'],
cbindData: function(config) {
let me = this;
me.setTitle(`${gettext('Drive')}: ${me.drive}`);
return {
driveStatusUrl: `/api2/json/tape/drive/${me.drive}/status`,
};
},
scrollable: true,
bodyPadding: 5,
viewModel: {
data: {
online: false,
busy: true,
loaded: false,
},
},
controller: {
xclass: 'Ext.app.ViewController',
reload: function() {
let me = this;
me.lookup('statusgrid').rstore.load();
},
onLoad: function() {
let me = this;
let statusgrid = me.lookup('statusgrid');
let statusFlags = (statusgrid.getObjectValue('status') || "").split(/\s+|\s+/);
let online = statusFlags.indexOf('ONLINE') !== -1;
let vm = me.getViewModel();
vm.set('online', online);
},
onStateLoad: function(store) {
let me = this;
let view = me.getView();
let vm = me.getViewModel();
let driveRecord = store.findRecord('name', view.drive, 0, false, true, true);
let busy = !!driveRecord.data.state;
vm.set('busy', busy);
let statusgrid = me.lookup('statusgrid');
if (!vm.get('loaded')) {
if (busy) {
// have to use a timeout so that the component can be rendered first
// otherwise the 'mask' call errors out
setTimeout(function() {
statusgrid.mask(gettext('Drive is busy'));
}, 10);
} else {
// have to use a timeout so that the component can be rendered first
// otherwise the 'mask' call errors out
setTimeout(function() {
statusgrid.unmask();
}, 10);
me.reload();
vm.set('loaded', true);
}
}
},
labelMedia: function() {
let me = this;
Ext.create('PBS.TapeManagement.LabelMediaWindow', {
driveid: me.getView().drive,
}).show();
},
eject: function() {
let me = this;
let view = me.getView();
let driveid = view.drive;
PBS.Utils.driveCommand(driveid, 'eject-media', {
waitMsgTarget: view,
method: 'POST',
success: function(response) {
Ext.create('Proxmox.window.TaskProgress', {
upid: response.result.data,
taskDone: function() {
me.reload();
},
}).show();
},
});
},
catalog: function() {
let me = this;
let view = me.getView();
let drive = view.drive;
PBS.Utils.driveCommand(drive, 'catalog', {
waitMsgTarget: view,
method: 'POST',
success: function(response) {
Ext.create('Proxmox.window.TaskViewer', {
upid: response.result.data,
taskDone: function() {
me.reload();
},
}).show();
},
});
},
init: function(view) {
let me = this;
me.mon(me.lookup('statusgrid').getStore().rstore, 'load', 'onLoad');
let tapeStore = Ext.ComponentQuery.query('navigationtree')[0].tapestore;
me.mon(tapeStore, 'load', 'onStateLoad');
if (tapeStore.isLoaded()) {
me.onStateLoad(tapeStore);
}
},
},
tbar: [
{
xtype: 'proxmoxButton',
handler: 'reload',
text: gettext('Reload'),
disabled: true,
bind: {
disabled: '{busy}',
},
},
'-',
{
text: gettext('Label Media'),
xtype: 'proxmoxButton',
handler: 'labelMedia',
iconCls: 'fa fa-barcode',
disabled: true,
bind: {
disabled: '{!online}',
},
},
{
text: gettext('Eject'),
xtype: 'proxmoxButton',
handler: 'ejectMedia',
iconCls: 'fa fa-eject',
disabled: true,
bind: {
disabled: '{!online}',
},
},
{
text: gettext('Catalog'),
xtype: 'proxmoxButton',
handler: 'catalog',
iconCls: 'fa fa-book',
disabled: true,
bind: {
disabled: '{!online}',
},
},
],
items: [
{
xtype: 'container',
layout: {
type: 'hbox',
align: 'stretch',
},
defaults: {
padding: 5,
flex: 1,
},
items: [
{
xtype: 'pbsDriveInfoPanel',
cbind: {
drive: '{drive}',
},
},
{
xtype: 'pbsDriveStatusGrid',
reference: 'statusgrid',
cbind: {
url: '{driveStatusUrl}',
},
},
],
},
],
});
Ext.define('PBS.TapeManagement.DriveStatusGrid', {
extend: 'Proxmox.grid.ObjectGrid',
alias: 'widget.pbsDriveStatusGrid',
title: gettext('Status'),
rows: {
'blocksize': {
required: true,
header: gettext('Blocksize'),
renderer: function(value) {
if (!value) {
return gettext('Dynamic');
}
return `${gettext('Fixed')} - ${Proxmox.Utils.format_size(value)}`;
},
},
'options': {
required: true,
header: gettext('Options'),
defaultValue: '',
},
'status': {
required: true,
header: gettext('Status'),
},
'density': {
header: gettext('Tape Density'),
},
'manufactured': {
header: gettext('Tape Manufacture Date'),
renderer: function(value) {
if (value) {
return new Date(value*1000);
}
return "";
},
},
'bytes-read': {
header: gettext('Tape Read'),
renderer: Proxmox.Utils.format_size,
},
'bytes-written': {
header: gettext('Tape Written'),
renderer: Proxmox.Utils.format_size,
},
'medium-passes': {
header: gettext('Tape Passes'),
},
'medium-wearout': {
header: gettext('Tape Wearout'),
},
},
});
Ext.define('PBS.TapeManagement.DriveInfoPanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.pbsDriveInfoPanel',
title: gettext('Information'),
defaults: {
printBar: false,
padding: 5,
},
bodyPadding: 15,
viewModel: {
data: {
drive: {},
},
formulas: {
driveState: function(get) {
let drive = get('drive');
return PBS.Utils.renderDriveState(drive.state, {});
},
},
},
items: [
{
xtype: 'pmxInfoWidget',
title: gettext('Name'),
bind: {
data: {
text: '{drive.name}',
},
},
},
{
xtype: 'pmxInfoWidget',
title: gettext('Vendor'),
bind: {
data: {
text: '{drive.vendor}',
},
},
},
{
xtype: 'pmxInfoWidget',
title: gettext('Model'),
bind: {
data: {
text: '{drive.model}',
},
},
},
{
xtype: 'pmxInfoWidget',
title: gettext('Serial'),
bind: {
data: {
text: '{drive.serial}',
},
},
},
{
xtype: 'pmxInfoWidget',
title: gettext('Path'),
bind: {
data: {
text: '{drive.path}',
},
},
},
{
xtype: 'pmxInfoWidget',
title: gettext('State'),
bind: {
data: {
text: '{driveState}',
},
},
},
],
updateData: function(store) {
let me = this;
if (!store) {
return;
}
let record = store.findRecord('name', me.drive, 0, false, true, true);
if (!record) {
return;
}
let vm = me.getViewModel();
vm.set('drive', record.data);
vm.notify();
},
initComponent: function() {
let me = this;
if (!me.drive) {
throw "no drive given";
}
let tapeStore = Ext.ComponentQuery.query('navigationtree')[0].tapestore;
me.mon(tapeStore, 'load', me.updateData, me);
if (tapeStore.isLoaded()) {
me.updateData(tapeStore);
}
me.callParent();
},
});