]> git.proxmox.com Git - proxmox-backup.git/commitdiff
ui: tape: rework BackupOverview
authorDominik Csapak <d.csapak@proxmox.com>
Tue, 2 Feb 2021 13:00:36 +0000 (14:00 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 2 Feb 2021 13:46:43 +0000 (14:46 +0100)
instead of grouping by tape (which is rarely interesting),
group by pool -> group -> id -> mediaset

this way a user looking for a backup of specific vm can do just that

we may want to have an additional view here were we list all snapshots
included in the selected media-set ?

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
www/Utils.js
www/tape/BackupOverview.js

index acfc4556bf68120f135d81dda02d839e7147ff78..3bb709e42547d267544267523018da91ce032477 100644 (file)
@@ -260,6 +260,15 @@ Ext.define('PBS.Utils', {
        return dedup;
     },
 
+    parse_snapshot_id: function(snapshot) {
+       if (!snapshot) {
+           return [undefined, undefined, undefined];
+       }
+       let [_match, type, group, id] = /^([^/]+)\/([^/]+)\/(.+)$/.exec(snapshot);
+
+       return [type, group, id];
+    },
+
     get_type_icon_cls: function(btype) {
        var cls = '';
        if (btype.startsWith('vm')) {
index 4743dcc011c76215c40cc5b22e1b22bd973c0863..f850c29a6daecf1e25369a24b4a843d9c25c7891 100644 (file)
@@ -16,50 +16,98 @@ Ext.define('PBS.TapeManagement.BackupOverview', {
            }).show();
        },
 
-       reload: async function() {
+       restore: function(button, record) {
            let me = this;
            let view = me.getView();
+           let selection = view.getSelection();
+           if (!selection || selection.length < 1) {
+               return;
+           }
 
-           Proxmox.Utils.setErrorMask(view, true);
+           let mediaset = selection[0].data.text;
+           let uuid = selection[0].data.uuid;
+           Ext.create('PBS.TapeManagement.TapeRestoreWindow', {
+               mediaset,
+               uuid,
+               listeners: {
+                   destroy: function() {
+                       me.reload();
+                   },
+               },
+           }).show();
+       },
 
-           try {
-               let list_response = await PBS.Async.api2({
-                   url: '/api2/extjs/tape/media/list',
-               });
-               let list = list_response.result.data.sort(
-                   (a, b) => a['label-text'].localeCompare(b['label-text']),
-               );
+       loadContent: async function() {
+           let content_response = await PBS.Async.api2({
+               url: '/api2/extjs/tape/media/content',
+           });
+           let data = {};
+
+           for (const entry of content_response.result.data) {
+               let pool = entry.pool;
+               let [type, group_id, id] = PBS.Utils.parse_snapshot_id(entry.snapshot);
+               let group = `${type}/${group_id}`;
+               let media_set = entry['media-set-name'];
+               let uuid = entry['media-set-uuid'];
+               let ctime = entry['media-set-ctime'];
+               if (data[pool] === undefined) {
+                   data[pool] = {};
+               }
 
-               let content = {};
+               if (data[pool][group] === undefined) {
+                   data[pool][group] = {};
+               }
 
-               let content_response = await PBS.Async.api2({
-                   url: '/api2/extjs/tape/media/content',
+               if (data[pool][group][id] === undefined) {
+                   data[pool][group][id] = [];
+               }
+               data[pool][group][id].push({
+                   text: media_set,
+                   uuid,
+                   ctime,
+                   leaf: true,
                });
+           }
 
-               let content_list = content_response.result.data.sort(
-                   (a, b) => a.snapshot.localeCompare(b.snapshot),
-               );
-
-               for (let entry of content_list) {
-                   let tape = entry['label-text'];
-                   entry['label-text'] = entry.snapshot;
-                   entry.leaf = true;
-                   if (content[tape] === undefined) {
-                       content[tape] = [entry];
-                   } else {
-                       content[tape].push(entry);
+           let list = [];
+
+           for (const [pool, groups] of Object.entries(data)) {
+               let pool_entry = {
+                   text: pool,
+                   leaf: false,
+                   children: [],
+               };
+               for (const [group, ids] of Object.entries(groups)) {
+                   let group_entry = {
+                       text: group,
+                       iconCls: "fa " + PBS.Utils.get_type_icon_cls(group),
+                       leaf: false,
+                       children: [],
+                   };
+                   for (const [id, media_sets] of Object.entries(ids)) {
+                       let id_entry = {
+                           text: `${group}/${id}`,
+                           leaf: false,
+                           children: media_sets,
+                       };
+                       group_entry.children.push(id_entry);
                    }
+                   pool_entry.children.push(group_entry);
                }
+               list.push(pool_entry);
+           }
 
-               for (let child of list) {
-                   let tape = child['label-text'];
-                   if (content[tape]) {
-                       child.children = content[tape];
-                       child.leaf = false;
-                   } else {
-                       child.leaf = true;
-                   }
-               }
+           return list;
+       },
+
+       reload: async function() {
+           let me = this;
+           let view = me.getView();
+
+           Proxmox.Utils.setErrorMask(view, true);
+
+           try {
+               let list = await me.loadContent();
 
                view.setRootNode({
                    expanded: true,
@@ -78,8 +126,14 @@ Ext.define('PBS.TapeManagement.BackupOverview', {
     },
 
     store: {
-       sorters: 'label-text',
        data: [],
+       sorters: function(a, b) {
+           if (a.data.leaf && b.data.leaf) {
+               return a.data.ctime - b.data.ctime;
+           } else {
+               return a.data.text.localeCompare(b.data.text);
+           }
+       },
     },
 
     rootVisible: false,
@@ -99,50 +153,15 @@ Ext.define('PBS.TapeManagement.BackupOverview', {
     columns: [
        {
            xtype: 'treecolumn',
-           text: gettext('Tape/Backup'),
-           dataIndex: 'label-text',
+           text: gettext('Pool/Group/Snapshot/Media Set'),
+           dataIndex: 'text',
+           sortable: false,
            flex: 3,
        },
        {
-           text: gettext('Location'),
-           dataIndex: 'location',
-           flex: 1,
-           renderer: function(value) {
-               if (!value) {
-                   return "";
-               }
-               let result;
-               if ((result = /^online-(.+)$/.exec(value)) !== null) {
-                   return Ext.htmlEncode(result[1]);
-               }
-
-               return value;
-           },
-       },
-       {
-           text: gettext('Status'),
-           dataIndex: 'status',
-           flex: 1,
-       },
-       {
-           text: gettext('Media Set'),
-           dataIndex: 'media-set-name',
-           flex: 2,
-       },
-       {
-           text: gettext('Pool'),
-           dataIndex: 'pool',
-           flex: 1,
-       },
-       {
-           text: gettext('Sequence Nr.'),
-           dataIndex: 'seq-nr',
-           flex: 0.5,
-       },
-       {
-           text: gettext('Backup Time'),
-           dataIndex: 'backup-time',
-           renderer: (time) => time !== undefined ? new Date(time*1000) : "",
+           text: gettext('Media Set UUID'),
+           dataIndex: 'uuid',
+           sortable: false,
            flex: 1,
        },
     ],