]> git.proxmox.com Git - proxmox-backup.git/commitdiff
ui: add SyncView
authorDominik Csapak <d.csapak@proxmox.com>
Fri, 29 May 2020 08:53:42 +0000 (10:53 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Fri, 29 May 2020 09:32:40 +0000 (11:32 +0200)
shows a nice overview of sync jobs (incl status of last run, estimated
next run, etc.) with options to add/edit/remove and also show the
log of the last run and manually run it now

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
www/Makefile
www/NavigationTree.js
www/config/SyncView.js [new file with mode: 0644]

index 3f0063e4b237d966d36a38ca0d3be18e7219f095..51de6fb28c803d1f52ff6a656c2624aab1ac6a16 100644 (file)
@@ -11,6 +11,7 @@ JSSRC=                                                        \
        config/UserView.js                              \
        config/RemoteView.js                            \
        config/ACLView.js                               \
+       config/SyncView.js                              \
        window/UserEdit.js                              \
        window/RemoteEdit.js                            \
        window/SyncJobEdit.js                           \
index 6d4d2455ae9171fcff5ad5a6651329b92e028602..57b46daea6722a543919e30aaf766da36da10dc1 100644 (file)
@@ -36,6 +36,12 @@ Ext.define('PBS.store.NavigationStore', {
                        path: 'pbsRemoteView',
                        leaf: true,
                    },
+                   {
+                       text: gettext('Sync Jobs'),
+                       iconCls: 'fa fa-refresh',
+                       path: 'pbsSyncJobView',
+                       leaf: true,
+                   },
                    {
                        text: gettext('Data Store'),
                        iconCls: 'fa fa-archive',
diff --git a/www/config/SyncView.js b/www/config/SyncView.js
new file mode 100644 (file)
index 0000000..5c5d044
--- /dev/null
@@ -0,0 +1,251 @@
+Ext.define('pbs-sync-jobs-status', {
+    extend: 'Ext.data.Model',
+    fields: [
+       'id', 'remote', 'remote-store', 'store', 'schedule',
+       'next-run', 'last-run-upid', 'last-run-state', 'last-run-endtime',
+       {
+           name: 'duration',
+           calculate: function(data) {
+               let endtime = data['last-run-endtime'];
+               if (!endtime) return undefined;
+               let task = Proxmox.Utils.parse_task_upid(data['last-run-upid']);
+               return endtime - task.starttime;
+           },
+       },
+    ],
+    idProperty: 'id',
+    proxy: {
+       type: 'proxmox',
+       url: '/api2/json/admin/sync',
+    },
+});
+
+Ext.define('PBS.config.SyncJobView', {
+    extend: 'Ext.grid.GridPanel',
+    alias: 'widget.pbsSyncJobView',
+
+    stateful: true,
+    stateId: 'grid-sync-jobs',
+
+    title: gettext('Sync Jobs'),
+
+    controller: {
+       xclass: 'Ext.app.ViewController',
+
+       addSyncJob: function() {
+           let me = this;
+            Ext.create('PBS.window.SyncJobEdit', {
+               listeners: {
+                   destroy: function() {
+                       me.reload();
+                   },
+               },
+            }).show();
+       },
+
+       editSyncJob: function() {
+           let me = this;
+           let view = me.getView();
+           let selection = view.getSelection();
+           if (selection.length < 1) return;
+
+            Ext.create('PBS.window.SyncJobEdit', {
+                id: selection[0].data.id,
+               listeners: {
+                   destroy: function() {
+                       me.reload();
+                   },
+               },
+            }).show();
+       },
+
+       openTaskLog: function() {
+           let me = this;
+           let view = me.getView();
+           let selection = view.getSelection();
+           if (selection.length < 1) return;
+
+           let upid = selection[0].data['last-run-upid'];
+           if (!upid) return;
+
+           Ext.create('Proxmox.window.TaskViewer', {
+               upid
+           }).show();
+       },
+
+       runSyncJob: function() {
+           let me = this;
+           let view = me.getView();
+           let selection = view.getSelection();
+           if (selection.length < 1) return;
+
+           let id = selection[0].data.id;
+           Proxmox.Utils.API2Request({
+               method: 'POST',
+               url: `/admin/sync/${id}/run`,
+               success: function(response, opt) {
+                   Ext.create('Proxmox.window.TaskViewer', {
+                       upid: response.result.data,
+                       taskDone: function(success) {
+                           me.reload();
+                       },
+                   }).show();
+               },
+               failure: function(response, opt) {
+                   Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+               },
+           });
+       },
+
+       render_sync_status: function(value, metadata, record) {
+           if (!record.data['last-run-upid']) {
+               return '-';
+           }
+
+           if (!record.data['last-run-endtime']) {
+               metadata.tdCls = 'x-grid-row-loading';
+               return '';
+           }
+
+           if (value === 'OK') {
+               return `<i class="fa fa-check good"></i> ${gettext("OK")}`;
+           }
+
+           return `<i class="fa fa-times critical"></i> ${gettext("Error")}:${value}`;
+       },
+
+       render_optional_timestamp: function(value) {
+           if (!value) return '-';
+           return Proxmox.Utils.render_timestamp(value);
+       },
+
+       reload: function() { this.getView().getStore().rstore.load(); },
+
+       init: function(view) {
+           Proxmox.Utils.monStoreErrors(view, view.getStore().rstore);
+       },
+    },
+
+    listeners: {
+       activate: 'reload',
+       itemdblclick: 'editSyncJob',
+    },
+
+    store: {
+       type: 'diff',
+       autoDestroy: true,
+       autoDestroyRstore: true,
+       sorters: 'id',
+       rstore: {
+           type: 'update',
+           storeid: 'pbs-sync-jobs-status',
+           model: 'pbs-sync-jobs-status',
+           autoStart: true,
+           interval: 5000,
+       },
+    },
+
+    tbar: [
+       {
+           xtype: 'proxmoxButton',
+           text: gettext('Add'),
+           handler: 'addSyncJob',
+           selModel: false,
+       },
+       {
+           xtype: 'proxmoxButton',
+           text: gettext('Edit'),
+           handler: 'editSyncJob',
+           disabled: true,
+       },
+       {
+           xtype: 'proxmoxStdRemoveButton',
+           baseurl: '/config/sync/',
+           callback: 'reload',
+       },
+       '-',
+       {
+           xtype: 'proxmoxButton',
+           text: gettext('Log'),
+           handler: 'openTaskLog',
+           enableFn: (rec) => !!rec.data['last-run-upid'],
+           disabled: true,
+       },
+       {
+           xtype: 'proxmoxButton',
+           text: gettext('Run now'),
+           handler: 'runSyncJob',
+           disabled: true,
+       },
+    ],
+
+    viewConfig: {
+       trackOver: false,
+    },
+
+    columns: [
+       {
+           header: gettext('Sync Job'),
+           width: 200,
+           sortable: true,
+           renderer: Ext.String.htmlEncode,
+           dataIndex: 'id',
+       },
+       {
+           header: gettext('Remote'),
+           width: 200,
+           sortable: true,
+           dataIndex: 'remote',
+       },
+       {
+           header: gettext('Remote Store'),
+           width: 200,
+           sortable: true,
+           dataIndex: 'remote-store',
+       },
+       {
+           header: gettext('Local Store'),
+           width: 200,
+           sortable: true,
+           dataIndex: 'store',
+       },
+       {
+           header: gettext('Schedule'),
+           sortable: true,
+           dataIndex: 'schedule',
+       },
+       {
+           header: gettext('Status'),
+           dataIndex: 'last-run-state',
+           flex: 1,
+           renderer: 'render_sync_status',
+       },
+       {
+           header: gettext('Last Sync'),
+           sortable: true,
+           minWidth: 200,
+           renderer: 'render_optional_timestamp',
+           dataIndex: 'last-run-endtime',
+       },
+       {
+           text: gettext('Duration'),
+           dataIndex: 'duration',
+           width: 60,
+           renderer: Proxmox.Utils.render_duration,
+       },
+       {
+           header: gettext('Next Run'),
+           sortable: true,
+           minWidth: 200,
+           renderer: 'render_optional_timestamp',
+           dataIndex: 'next-run',
+       },
+       {
+           header: gettext('Comment'),
+           hidden: true,
+           sortable: true,
+           renderer: Ext.String.htmlEncode,
+           dataIndex: 'comment',
+       },
+    ],
+});