proxmox-backup/www/datastore/DataStoreList.js
Dominik Csapak 2371c1e371 ui: add Panels necessary for Datastores Overview
a panel for a single datastore that gets updated from an external caller
shows the usage, estimated full date, history and task summary grid

a panel that dynamically generates the panel above for each datastore

and a tabpanel that includes the panel above, as well as a global
syncview, verifiyview and aclview

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2020-11-09 16:37:24 +01:00

230 lines
4.5 KiB
JavaScript

// Overview over all datastores
Ext.define('PBS.datastore.DataStoreList', {
extend: 'Ext.panel.Panel',
alias: 'widget.pbsDataStoreList',
title: gettext('Summary'),
scrollable: true,
bodyPadding: 5,
defaults: {
xtype: 'pbsDataStoreListSummary',
padding: 5,
},
datastores: {},
tasks: {},
updateTasks: function(taskStore, records, success) {
let me = this;
if (!success) {
return;
}
for (const store of Object.keys(me.tasks)) {
me.tasks[store] = {};
}
records.forEach(record => {
let task = record.data;
if (!task.worker_id) {
return;
}
let type = task.worker_type;
if (type === 'syncjob') {
type = 'sync';
}
if (type.startsWith('verif')) {
type = 'verify';
}
let datastore = PBS.Utils.parse_datastore_worker_id(type, task.worker_id);
if (!datastore) {
return;
}
if (!me.tasks[datastore]) {
me.tasks[datastore] = {};
}
if (!me.tasks[datastore][type]) {
me.tasks[datastore][type] = {};
}
if (me.tasks[datastore][type] && task.status) {
let parsed = Proxmox.Utils.parse_task_status(task.status);
if (!me.tasks[datastore][type][parsed]) {
me.tasks[datastore][type][parsed] = 0;
}
me.tasks[datastore][type][parsed]++;
}
});
for (const [store, panel] of Object.entries(me.datastores)) {
panel.setTasks(me.tasks[store], me.since);
}
},
updateStores: function(usageStore, records, success) {
let me = this;
if (!success) {
return;
}
let found = {};
records.forEach((rec) => {
found[rec.data.store] = true;
me.addSorted(rec.data);
});
for (const [store, panel] of Object.entries(me.datastores)) {
if (!found[store]) {
me.remove(panel);
}
}
},
addSorted: function(data) {
let me = this;
let i = 0;
let datastores = Object
.keys(me.datastores)
.sort((a, b) => a.localeCompare(b));
for (const datastore of datastores) {
let result = datastore.localeCompare(data.store);
if (result === 0) {
me.datastores[datastore].setStatus(data);
return;
} else if (result > 0) {
break;
}
i++;
}
me.datastores[data.store] = me.insert(i, {
datastore: data.store,
});
me.datastores[data.store].setStatus(data);
me.datastores[data.store].setTasks(me.tasks[data.store], me.since);
},
initComponent: function() {
let me = this;
me.items = [];
me.datastores = {};
// todo make configurable?
me.since = (Date.now()/1000 - 30 * 24*3600).toFixed(0);
me.usageStore = Ext.create('Proxmox.data.UpdateStore', {
storeid: 'datastore-overview-usage',
interval: 5000,
proxy: {
type: 'proxmox',
url: '/api2/json/status/datastore-usage',
},
listeners: {
load: {
fn: me.updateStores,
scope: me,
},
},
});
me.taskStore = Ext.create('Proxmox.data.UpdateStore', {
storeid: 'datastore-overview-tasks',
interval: 15000,
model: 'proxmox-tasks',
proxy: {
type: 'proxmox',
url: '/api2/json/nodes/localhost/tasks',
extraParams: {
limit: 0,
since: me.since,
},
},
listeners: {
load: {
fn: me.updateTasks,
scope: me,
},
},
});
me.callParent();
Proxmox.Utils.monStoreErrors(me, me.usageStore);
Proxmox.Utils.monStoreErrors(me, me.taskStore);
me.on('activate', function() {
me.usageStore.startUpdate();
me.taskStore.startUpdate();
});
me.on('destroy', function() {
me.usageStore.stopUpdate();
me.taskStore.stopUpdate();
});
me.on('deactivate', function() {
me.usageStore.stopUpdate();
me.taskStore.stopUpdate();
});
},
});
Ext.define('PBS.datastore.DataStores', {
extend: 'Ext.tab.Panel',
alias: 'widget.pbsDataStores',
title: gettext('Datastores'),
stateId: 'pbs-datastores-panel',
stateful: true,
stateEvents: ['tabchange'],
applyState: function(state) {
let me = this;
if (state.tab !== undefined) {
me.setActiveTab(state.tab);
}
},
getState: function() {
let me = this;
return {
tab: me.getActiveTab().getItemId(),
};
},
border: false,
defaults: {
border: false,
},
items: [
{
xtype: 'pbsDataStoreList',
iconCls: 'fa fa-book',
},
{
iconCls: 'fa fa-refresh',
itemId: 'syncjobs',
xtype: 'pbsSyncJobView',
},
{
iconCls: 'fa fa-check-circle',
itemId: 'verifyjobs',
xtype: 'pbsVerifyJobView',
},
{
itemId: 'acl',
xtype: 'pbsACLView',
iconCls: 'fa fa-unlock',
aclPath: '/datastore',
},
],
});