mirror of
https://git.proxmox.com/git/proxmox-backup
synced 2025-05-27 23:52:12 +00:00

The API now exposes the field 'available' as well, with which the unprivileged total is calculated in all corresponsing views in the frontend. The rrd charts now also display the total as the unprivileged total if available, otherwise the absolute total is used. Signed-off-by: Daniel Tschlatscher <d.tschlatscher@proxmox.com>
248 lines
4.8 KiB
JavaScript
248 lines
4.8 KiB
JavaScript
// Summary Panel for a single datastore in overview
|
|
Ext.define('PBS.datastore.DataStoreListSummary', {
|
|
extend: 'Ext.panel.Panel',
|
|
alias: 'widget.pbsDataStoreListSummary',
|
|
mixins: ['Proxmox.Mixin.CBind'],
|
|
|
|
cbind: {
|
|
title: '{datastore}',
|
|
},
|
|
|
|
referenceHolder: true,
|
|
bodyPadding: 10,
|
|
|
|
layout: {
|
|
type: 'hbox',
|
|
align: 'stretch',
|
|
},
|
|
|
|
viewModel: {
|
|
data: {
|
|
full: "N/A",
|
|
stillbad: 0,
|
|
deduplication: 1.0,
|
|
error: "",
|
|
maintenance: '',
|
|
},
|
|
},
|
|
setTasks: function(taskdata, since) {
|
|
let me = this;
|
|
me.down('pbsTaskSummary').updateTasks(taskdata, since);
|
|
},
|
|
|
|
setStatus: function(statusData) {
|
|
let me = this;
|
|
let vm = me.getViewModel();
|
|
|
|
if (statusData.error !== undefined) {
|
|
Proxmox.Utils.API2Request({
|
|
url: `/config/datastore/${statusData.store}`,
|
|
success: (response) => {
|
|
const config = response.result.data;
|
|
if (config['maintenance-mode']) {
|
|
const [_type, msg] = PBS.Utils.parseMaintenanceMode(config['maintenance-mode']);
|
|
vm.set('maintenance', `${gettext('Datastore is in maintenance mode')}${msg ? ': ' + msg : ''}`);
|
|
}
|
|
},
|
|
});
|
|
vm.set('error', statusData.error);
|
|
return;
|
|
} else {
|
|
vm.set('error', "");
|
|
vm.set('maintenance', '');
|
|
}
|
|
|
|
let total = statusData.avail + statusData.used;
|
|
let usage = statusData.used / total;
|
|
let usagetext = Ext.String.format(gettext('{0} of {1}'),
|
|
Proxmox.Utils.format_size(statusData.used, true),
|
|
Proxmox.Utils.format_size(total, true),
|
|
);
|
|
|
|
let usagePanel = me.lookup('usage');
|
|
usagePanel.updateValue(usage, usagetext);
|
|
|
|
let estimate = PBS.Utils.render_estimate(statusData['estimated-full-date']);
|
|
vm.set('full', estimate);
|
|
vm.set('deduplication', PBS.Utils.calculate_dedup_factor(statusData['gc-status']).toFixed(2));
|
|
vm.set('stillbad', statusData['gc-status']['still-bad']);
|
|
|
|
let last = 0;
|
|
let time = statusData['history-start'];
|
|
let delta = statusData['history-delta'];
|
|
let data = statusData.history.map((val) => {
|
|
if (val === null) {
|
|
val = last;
|
|
} else {
|
|
last = val;
|
|
}
|
|
let entry = {
|
|
time: time*1000, // js Dates are ms since epoch
|
|
val,
|
|
};
|
|
|
|
time += delta;
|
|
return entry;
|
|
});
|
|
|
|
me.lookup('historychart').setData(data);
|
|
},
|
|
|
|
items: [
|
|
{
|
|
xtype: 'container',
|
|
layout: {
|
|
type: 'vbox',
|
|
align: 'stretch',
|
|
},
|
|
|
|
width: 375,
|
|
padding: '5 25 5 5',
|
|
|
|
defaults: {
|
|
padding: 2,
|
|
},
|
|
|
|
items: [
|
|
{
|
|
xtype: 'box',
|
|
hidden: true,
|
|
tpl: [
|
|
'<center>',
|
|
`<h3>${gettext("Error")}</h3>`,
|
|
'<i class="fa fa-5x fa-exclamation-circle critical"></i>',
|
|
'<br /><br/>',
|
|
'{text}',
|
|
'</center>',
|
|
],
|
|
bind: {
|
|
visible: '{error && !maintenance}',
|
|
data: {
|
|
text: '{error}',
|
|
},
|
|
},
|
|
},
|
|
{
|
|
xtype: 'box',
|
|
hidden: true,
|
|
tpl: [
|
|
'<center>',
|
|
`<h3>${gettext("Maintenance mode")}</h3>`,
|
|
'<i class="fa fa-5x fa-wrench"></i>',
|
|
'<br /><br/>',
|
|
'{text}',
|
|
'</center>',
|
|
],
|
|
bind: {
|
|
visible: '{maintenance}',
|
|
data: {
|
|
text: '{maintenance}',
|
|
},
|
|
},
|
|
},
|
|
{
|
|
xtype: 'proxmoxGauge',
|
|
warningThreshold: 0.8,
|
|
criticalThreshold: 0.95,
|
|
flex: 1,
|
|
reference: 'usage',
|
|
bind: {
|
|
visible: '{!error}',
|
|
},
|
|
},
|
|
{
|
|
xtype: 'pmxInfoWidget',
|
|
iconCls: 'fa fa-fw fa-line-chart',
|
|
title: gettext('Estimated Full'),
|
|
printBar: false,
|
|
bind: {
|
|
data: {
|
|
text: '{full}',
|
|
},
|
|
visible: '{!error}',
|
|
},
|
|
},
|
|
{
|
|
xtype: 'pmxInfoWidget',
|
|
iconCls: 'fa fa-fw fa-compress',
|
|
title: gettext('Deduplication Factor'),
|
|
printBar: false,
|
|
bind: {
|
|
data: {
|
|
text: '{deduplication}',
|
|
},
|
|
visible: '{!error}',
|
|
},
|
|
},
|
|
{
|
|
xtype: 'pmxInfoWidget',
|
|
iconCls: 'fa critical fa-fw fa-exclamation-triangle',
|
|
title: gettext('Bad Chunks'),
|
|
printBar: false,
|
|
hidden: true,
|
|
bind: {
|
|
data: {
|
|
text: '{stillbad}',
|
|
},
|
|
visible: '{stillbad}',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
xtype: 'container',
|
|
layout: {
|
|
type: 'vbox',
|
|
align: 'stretch',
|
|
},
|
|
|
|
flex: 1,
|
|
|
|
items: [
|
|
{
|
|
padding: 5,
|
|
xtype: 'pbsUsageChart',
|
|
reference: 'historychart',
|
|
title: gettext('Usage History'),
|
|
height: 100,
|
|
bind: {
|
|
visible: '{!error}',
|
|
},
|
|
},
|
|
{
|
|
xtype: 'container',
|
|
flex: 1,
|
|
layout: {
|
|
type: 'vbox',
|
|
align: 'stretch',
|
|
},
|
|
|
|
defaults: {
|
|
padding: 5,
|
|
},
|
|
|
|
items: [
|
|
{
|
|
xtype: 'label',
|
|
text: gettext('Task Summary')
|
|
+ ` (${Ext.String.format(gettext('{0} days'), 30)})`,
|
|
},
|
|
{
|
|
xtype: 'pbsTaskSummary',
|
|
border: false,
|
|
header: false,
|
|
subPanelModal: true,
|
|
flex: 2,
|
|
bodyPadding: 0,
|
|
minHeight: 0,
|
|
cbind: {
|
|
datastore: '{datastore}',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
});
|