]> git.proxmox.com Git - pve-manager.git/blobdiff - www/manager6/grid/BackupView.js
ui: fw grid: eslint auto-fixes
[pve-manager.git] / www / manager6 / grid / BackupView.js
index a74c6ccb6cc4ac713fa1e059d8f79b2214c90ba9..7f7e1b62db11ffc1b75aaf9f6ddb81fa4814e26a 100644 (file)
@@ -8,7 +8,7 @@ Ext.define('PVE.grid.BackupView', {
     stateful: true,
     stateId: 'grid-guest-backup',
 
-    initComponent : function() {
+    initComponent: function() {
        var me = this;
 
        var nodename = me.pveSelNode.data.node;
@@ -41,43 +41,67 @@ Ext.define('PVE.grid.BackupView', {
 
        var searchFilter = {
            property: 'volid',
-       // on initial store display only our vmid backups
-       // surround with minus sign to prevent the 2016 VMID bug
-           value: vmtype + '-' + vmid + '-',
+           value: '',
            anyMatch: true,
-           caseSensitive: false
+           caseSensitive: false,
+       };
+
+       var vmidFilter = {
+           property: 'vmid',
+           value: vmid,
+           exactMatch: true,
        };
 
        me.store = Ext.create('Ext.data.Store', {
            model: 'pve-storage-content',
-           sorters: { 
-               property: 'volid', 
-               order: 'DESC' 
-           },
+           sorters: [
+               {
+                   property: 'vmid',
+                   direction: 'ASC',
+               },
+               {
+                   property: 'vdate',
+                   direction: 'DESC',
+               },
+           ],
            filters: [
                vmtypeFilter,
-               searchFilter
-               ]
+               searchFilter,
+               vmidFilter,
+               ],
        });
 
+       let updateFilter = function() {
+           me.store.filter([
+               vmtypeFilter,
+               searchFilter,
+               vmidFilter,
+           ]);
+       };
+
        var reload = Ext.Function.createBuffered(function() {
            if (me.store) {
                me.store.load();
            }
        }, 100);
 
+       let isPBS = false;
        var setStorage = function(storage) {
            var url = '/api2/json/nodes/' + nodename + '/storage/' + storage + '/content';
            url += '?content=backup';
 
            me.store.setProxy({
                type: 'proxmox',
-               url: url
+               url: url,
            });
 
+           Proxmox.Utils.monStoreErrors(me.view, me.store, true);
+
            reload();
        };
 
+       let file_restore_btn;
+
        var storagesel = Ext.create('PVE.form.StorageSelector', {
            nodename: nodename,
            fieldLabel: gettext('Storage'),
@@ -86,9 +110,24 @@ Ext.define('PVE.grid.BackupView', {
            allowBlank: false,
            listeners: {
                change: function(f, value) {
+                   let storage = f.getStore().findRecord('storage', value, 0, false, true, true);
+                   if (storage) {
+                       isPBS = storage.data.type === 'pbs';
+                       me.getColumns().forEach((column) => {
+                           let id = column.dataIndex;
+                           if (id === 'verification' || id === 'encrypted') {
+                               column.setHidden(!isPBS);
+                           }
+                       });
+                   } else {
+                       isPBS = false;
+                   }
                    setStorage(value);
-               }
-           }
+                   if (file_restore_btn) {
+                       file_restore_btn.setHidden(!isPBS);
+                   }
+               },
+           },
        });
 
        var storagefilter = Ext.create('Ext.form.field.Text', {
@@ -102,12 +141,21 @@ Ext.define('PVE.grid.BackupView', {
                keyup: function(field) {
                    me.store.clearFilter(true);
                    searchFilter.value = field.getValue();
-                   me.store.filter([
-                       vmtypeFilter,
-                       searchFilter
-                   ]);
-               }
-           }
+                   updateFilter();
+               },
+           },
+       });
+
+       var vmidfilterCB = Ext.create('Ext.form.field.Checkbox', {
+           boxLabel: gettext('Filter VMID'),
+           value: '1',
+           listeners: {
+               change: function(cb, value) {
+                   vmidFilter.value = value ? vmid : '';
+                   vmidFilter.exactMatch = !!value;
+                   updateFilter();
+               },
+           },
        });
 
        var sm = Ext.create('Ext.selection.RowModel', {});
@@ -115,19 +163,19 @@ Ext.define('PVE.grid.BackupView', {
        var backup_btn = Ext.create('Ext.button.Button', {
            text: gettext('Backup now'),
            handler: function() {
-               var win = Ext.create('PVE.window.Backup', { 
+               var win = Ext.create('PVE.window.Backup', {
                    nodename: nodename,
                    vmid: vmid,
                    vmtype: vmtype,
                    storage: storagesel.getValue(),
-                   listeners : {
+                   listeners: {
                        close: function() {
                            reload();
-                       }
-                   }
+                       },
+                   },
                });
                win.show();
-           }
+           },
        });
 
        var restore_btn = Ext.create('Proxmox.button.Button', {
@@ -138,92 +186,203 @@ Ext.define('PVE.grid.BackupView', {
                return !!rec;
            },
            handler: function(b, e, rec) {
-               var volid = rec.data.volid;
-
-               var win = Ext.create('PVE.window.Restore', {
+               let win = Ext.create('PVE.window.Restore', {
                    nodename: nodename,
                    vmid: vmid,
                    volid: rec.data.volid,
                    volidText: PVE.Utils.render_storage_content(rec.data.volid, {}, rec),
-                   vmtype: vmtype
+                   vmtype: vmtype,
+                   isPBS: isPBS,
                });
                win.show();
                win.on('destroy', reload);
-           }
+           },
        });
 
-       var delete_btn = Ext.create('Proxmox.button.StdRemoveButton', {
+       let delete_btn = Ext.create('Proxmox.button.StdRemoveButton', {
            selModel: sm,
            dangerous: true,
            delay: 5,
-           confirmMsg: function(rec) {
-               var msg = Ext.String.format(gettext('Are you sure you want to remove entry {0}'),
-                                           "'" + rec.data.volid + "'");
-               msg += " " + gettext('This will permanently erase all data.');
-
-               return msg;
+           enableFn: rec => !rec?.data?.protected,
+           confirmMsg: ({ data }) => {
+               let msg = Ext.String.format(
+                   gettext('Are you sure you want to remove entry {0}'), `'${data.volid}'`);
+               return msg + " " + gettext('This will permanently erase all data.');
            },
-           getUrl: function(rec) {
-               var storage = storagesel.getValue();
-               return '/nodes/' + nodename + '/storage/' + storage + '/content/' + rec.data.volid;
-           },
-           callback: function() {
-               reload();
-           }
+           getUrl: ({ data }) => `/nodes/${nodename}/storage/${storagesel.getValue()}/content/${data.volid}`,
+           callback: () => reload(),
        });
 
-       var config_btn = Ext.create('Proxmox.button.Button', {
+       let config_btn = Ext.create('Proxmox.button.Button', {
            text: gettext('Show Configuration'),
            disabled: true,
            selModel: sm,
-           enableFn: function(rec) {
-               return !!rec;
-           },
+           enableFn: rec => !!rec,
            handler: function(b, e, rec) {
-               var storage = storagesel.getValue();
+               let storage = storagesel.getValue();
                if (!storage) {
                    return;
                }
-
-               var win = Ext.create('PVE.window.BackupConfig', {
+               Ext.create('PVE.window.BackupConfig', {
                    volume: rec.data.volid,
-                   pveSelNode: me.pveSelNode
+                   pveSelNode: me.pveSelNode,
+                   autoShow: true,
                });
+           },
+       });
 
-               win.show();
-           }
+       // declared above so that the storage selector can change this buttons hidden state
+       file_restore_btn = Ext.create('Proxmox.button.Button', {
+           text: gettext('File Restore'),
+           disabled: true,
+           selModel: sm,
+           enableFn: rec => !!rec && isPBS,
+           hidden: !isPBS,
+           handler: function(b, e, rec) {
+               let storage = storagesel.getValue();
+               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/${storage}/file-restore/list`,
+                   downloadURL: `/api2/json/nodes/localhost/storage/${storage}/file-restore/download`,
+                   extraParams: {
+                       volume: rec.data.volid,
+                   },
+                   archive: isVMArchive ? 'all' : undefined,
+                   autoShow: true,
+               });
+           },
        });
 
        Ext.apply(me, {
            selModel: sm,
-           tbar: [ backup_btn, restore_btn, delete_btn,config_btn, '->', storagesel, storagefilter ],
+           tbar: {
+               overflowHandler: 'scroller',
+               items: [
+                   backup_btn,
+                   '-',
+                   restore_btn,
+                   file_restore_btn,
+                   config_btn,
+                   {
+                       xtype: 'proxmoxButton',
+                       text: gettext('Edit Notes'),
+                       disabled: true,
+                       handler: function() {
+                           let volid = sm.getSelection()[0].data.volid;
+                           var storage = storagesel.getValue();
+                           Ext.create('Proxmox.window.Edit', {
+                               autoLoad: true,
+                               width: 600,
+                               height: 400,
+                               resizable: true,
+                               title: gettext('Notes'),
+                               url: `/api2/extjs/nodes/${nodename}/storage/${storage}/content/${volid}`,
+                               layout: 'fit',
+                               items: [
+                                   {
+                                       xtype: 'textarea',
+                                       layout: 'fit',
+                                       name: 'notes',
+                                       height: '100%',
+                                   },
+                               ],
+                               listeners: {
+                                   destroy: () => reload(),
+                               },
+                           }).show();
+                       },
+                   },
+                   {
+                       xtype: 'proxmoxButton',
+                       text: gettext('Change Protection'),
+                       disabled: true,
+                       handler: function(button, event, record) {
+                           let volid = record.data.volid, storage = storagesel.getValue();
+                           let url = `/api2/extjs/nodes/${nodename}/storage/${storage}/content/${volid}`;
+                           let newProtection = record.data.protected ? 0 : 1;
+                           Proxmox.Utils.API2Request({
+                               url: url,
+                               method: 'PUT',
+                               waitMsgTarget: me,
+                               params: {
+                                   'protected': newProtection,
+                               },
+                               failure: (response) => Ext.Msg.alert('Error', response.htmlStatus),
+                               success: (response) => {
+                                   reload();
+                                   // propagate to remove button, fake for event as reload is to slow
+                                   record.data.protected = newProtection; // TODO: check if writing is OK!
+                                   sm.fireEvent('selectionchange', sm, [record]);
+                               },
+                           });
+                       },
+                   },
+                   '-',
+                   delete_btn,
+                   '->',
+                   storagesel,
+                   '-',
+                   vmidfilterCB,
+                   storagefilter,
+               ],
+           },
            columns: [
                {
                    header: gettext('Name'),
-                   flex: 1,
+                   flex: 2,
                    sortable: true,
                    renderer: PVE.Utils.render_storage_content,
-                   dataIndex: 'volid'
+                   dataIndex: 'volid',
+               },
+               {
+                   header: gettext('Notes'),
+                   dataIndex: 'notes',
+                   flex: 1,
+                   renderer: Ext.htmlEncode,
+               },
+               {
+                   header: `<i class="fa fa-shield"></i>`,
+                   tooltip: gettext('Protected'),
+                   width: 30,
+                   renderer: v => v ? `<i data-qtip="${gettext('Protected')}" class="fa fa-shield"></i>` : '',
+                   sorter: (a, b) => (b.data.protected || 0) - (a.data.protected || 0),
+                   dataIndex: 'protected',
                },
                {
                    header: gettext('Date'),
                    width: 150,
-                   dataIndex: 'vdate'
+                   dataIndex: 'vdate',
                },
                {
                    header: gettext('Format'),
                    width: 100,
-                   dataIndex: 'format'
+                   dataIndex: 'format',
                },
                {
                    header: gettext('Size'),
                    width: 100,
                    renderer: Proxmox.Utils.format_size,
-                   dataIndex: 'size'
-               }
-           ]
+                   dataIndex: 'size',
+               },
+               {
+                   header: gettext('VMID'),
+                   dataIndex: 'vmid',
+                   hidden: true,
+               },
+               {
+                   header: gettext('Encrypted'),
+                   dataIndex: 'encrypted',
+                   renderer: PVE.Utils.render_backup_encryption,
+               },
+               {
+                   header: gettext('Verify State'),
+                   dataIndex: 'verification',
+                   renderer: PVE.Utils.render_backup_verification,
+               },
+           ],
        });
 
        me.callParent();
-    }
+    },
 });