mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-07-18 17:34:39 +00:00

Currently this works in the backup view for containers/VMs, but not in the storage backup view. Implement that for the latter part too. Uses the callback functionality of the load() method of the store to properly update the UI as soon as the loading has finished. While at it, refactor the same thing in the grid backup view as well, removing the current hack in the process. Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
240 lines
5.5 KiB
JavaScript
240 lines
5.5 KiB
JavaScript
Ext.define('PVE.storage.BackupView', {
|
|
extend: 'PVE.storage.ContentView',
|
|
|
|
alias: 'widget.pveStorageBackupView',
|
|
|
|
showColumns: ['name', 'notes', 'protected', 'date', 'format', 'size'],
|
|
|
|
initComponent: function() {
|
|
let me = this;
|
|
|
|
let nodename = me.nodename = me.pveSelNode.data.node;
|
|
if (!nodename) {
|
|
throw "no node name specified";
|
|
}
|
|
|
|
let storage = me.storage = me.pveSelNode.data.storage;
|
|
if (!storage) {
|
|
throw "no storage ID specified";
|
|
}
|
|
|
|
me.content = 'backup';
|
|
|
|
let sm = me.sm = Ext.create('Ext.selection.RowModel', {});
|
|
|
|
let pruneButton = Ext.create('Proxmox.button.Button', {
|
|
text: gettext('Prune group'),
|
|
disabled: true,
|
|
selModel: sm,
|
|
setBackupGroup: function(backup) {
|
|
if (backup) {
|
|
let name = backup.text;
|
|
let vmid = backup.vmid;
|
|
let format = backup.format;
|
|
|
|
let vmtype;
|
|
if (name.startsWith('vzdump-lxc-') || format === "pbs-ct") {
|
|
vmtype = 'lxc';
|
|
} else if (name.startsWith('vzdump-qemu-') || format === "pbs-vm") {
|
|
vmtype = 'qemu';
|
|
}
|
|
|
|
if (vmid && vmtype) {
|
|
this.setText(gettext('Prune group') + ` ${vmtype}/${vmid}`);
|
|
this.vmid = vmid;
|
|
this.vmtype = vmtype;
|
|
this.setDisabled(false);
|
|
return;
|
|
}
|
|
}
|
|
this.setText(gettext('Prune group'));
|
|
this.vmid = null;
|
|
this.vmtype = null;
|
|
this.setDisabled(true);
|
|
},
|
|
handler: function(b, e, rec) {
|
|
Ext.create('PVE.window.Prune', {
|
|
autoShow: true,
|
|
nodename,
|
|
storage,
|
|
backup_id: this.vmid,
|
|
backup_type: this.vmtype,
|
|
listeners: {
|
|
destroy: () => me.store.load(),
|
|
},
|
|
});
|
|
},
|
|
});
|
|
|
|
me.on('selectionchange', function(model, srecords, eOpts) {
|
|
if (srecords.length === 1) {
|
|
pruneButton.setBackupGroup(srecords[0].data);
|
|
} else {
|
|
pruneButton.setBackupGroup(null);
|
|
}
|
|
});
|
|
|
|
let isPBS = me.pluginType === 'pbs';
|
|
|
|
me.tbar = [
|
|
{
|
|
xtype: 'proxmoxButton',
|
|
text: gettext('Restore'),
|
|
selModel: sm,
|
|
disabled: true,
|
|
handler: function(b, e, rec) {
|
|
let vmtype;
|
|
if (PVE.Utils.volume_is_qemu_backup(rec.data.volid, rec.data.format)) {
|
|
vmtype = 'qemu';
|
|
} else if (PVE.Utils.volume_is_lxc_backup(rec.data.volid, rec.data.format)) {
|
|
vmtype = 'lxc';
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
Ext.create('PVE.window.Restore', {
|
|
autoShow: true,
|
|
nodename,
|
|
volid: rec.data.volid,
|
|
volidText: PVE.Utils.render_storage_content(rec.data.volid, {}, rec),
|
|
vmtype,
|
|
isPBS,
|
|
listeners: {
|
|
destroy: () => me.store.load(),
|
|
},
|
|
});
|
|
},
|
|
},
|
|
];
|
|
if (isPBS) {
|
|
me.tbar.push({
|
|
xtype: 'proxmoxButton',
|
|
text: gettext('File Restore'),
|
|
disabled: true,
|
|
selModel: sm,
|
|
handler: function(b, e, rec) {
|
|
let isVMArchive = PVE.Utils.volume_is_qemu_backup(rec.data.volid, rec.data.format);
|
|
Ext.create('Proxmox.window.FileBrowser', {
|
|
title: gettext('File Restore') + " - " + rec.data.text,
|
|
listURL: `/api2/json/nodes/localhost/storage/${me.storage}/file-restore/list`,
|
|
downloadURL: `/api2/json/nodes/localhost/storage/${me.storage}/file-restore/download`,
|
|
extraParams: {
|
|
volume: rec.data.volid,
|
|
},
|
|
archive: isVMArchive ? 'all' : undefined,
|
|
autoShow: true,
|
|
});
|
|
},
|
|
});
|
|
}
|
|
me.tbar.push(
|
|
{
|
|
xtype: 'proxmoxButton',
|
|
text: gettext('Show Configuration'),
|
|
disabled: true,
|
|
selModel: sm,
|
|
handler: function(b, e, rec) {
|
|
Ext.create('PVE.window.BackupConfig', {
|
|
autoShow: true,
|
|
volume: rec.data.volid,
|
|
pveSelNode: me.pveSelNode,
|
|
});
|
|
},
|
|
},
|
|
{
|
|
xtype: 'proxmoxButton',
|
|
text: gettext('Edit Notes'),
|
|
disabled: true,
|
|
selModel: sm,
|
|
handler: function(b, e, rec) {
|
|
let volid = rec.data.volid;
|
|
Ext.create('Proxmox.window.Edit', {
|
|
autoShow: true,
|
|
autoLoad: true,
|
|
width: 600,
|
|
height: 400,
|
|
resizable: true,
|
|
title: gettext('Notes'),
|
|
url: `/api2/extjs/nodes/${nodename}/storage/${me.storage}/content/${volid}`,
|
|
layout: 'fit',
|
|
items: [
|
|
{
|
|
xtype: 'textarea',
|
|
layout: 'fit',
|
|
name: 'notes',
|
|
height: '100%',
|
|
},
|
|
],
|
|
listeners: {
|
|
destroy: () => me.store.load(),
|
|
},
|
|
});
|
|
},
|
|
},
|
|
{
|
|
xtype: 'proxmoxButton',
|
|
text: gettext('Change Protection'),
|
|
disabled: true,
|
|
handler: function(button, event, record) {
|
|
const volid = record.data.volid;
|
|
Proxmox.Utils.API2Request({
|
|
url: `/api2/extjs/nodes/${nodename}/storage/${me.storage}/content/${volid}`,
|
|
method: 'PUT',
|
|
waitMsgTarget: me,
|
|
params: { 'protected': record.data.protected ? 0 : 1 },
|
|
failure: response => Ext.Msg.alert('Error', response.htmlStatus),
|
|
success: () => {
|
|
me.store.load({
|
|
callback: () => sm.fireEvent('selectionchange', sm, [record]),
|
|
});
|
|
},
|
|
});
|
|
},
|
|
},
|
|
'-',
|
|
pruneButton,
|
|
);
|
|
|
|
if (isPBS) {
|
|
me.extraColumns = {
|
|
encrypted: {
|
|
header: gettext('Encrypted'),
|
|
dataIndex: 'encrypted',
|
|
renderer: PVE.Utils.render_backup_encryption,
|
|
sorter: {
|
|
property: 'encrypted',
|
|
transform: encrypted => encrypted ? 1 : 0,
|
|
},
|
|
},
|
|
verification: {
|
|
header: gettext('Verify State'),
|
|
dataIndex: 'verification',
|
|
renderer: PVE.Utils.render_backup_verification,
|
|
sorter: {
|
|
property: 'verification',
|
|
transform: value => {
|
|
let state = value?.state ?? 'none';
|
|
let order = PVE.Utils.verificationStateOrder;
|
|
return order[state] ?? order.__default__;
|
|
},
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
me.callParent();
|
|
|
|
me.store.getSorters().clear();
|
|
me.store.setSorters([
|
|
{
|
|
property: 'vmid',
|
|
direction: 'ASC',
|
|
},
|
|
{
|
|
property: 'vdate',
|
|
direction: 'DESC',
|
|
},
|
|
]);
|
|
},
|
|
});
|