new checked_command helper, add APT.js
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 21 Sep 2017 11:05:07 +0000 (13:05 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Mon, 25 Sep 2017 10:31:36 +0000 (12:31 +0200)
Makefile
Utils.js
node/APT.js [new file with mode: 0644]

index d135796..9f08eca 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -38,6 +38,7 @@ JSSRC=                                        \
        window/Edit.js                  \
        window/PasswordEdit.js          \
        window/TaskViewer.js            \
+       node/APT.js                     \
        node/NetworkEdit.js             \
        node/NetworkView.js             \
        node/DNSEdit.js                 \
index a0f0b69..fd23eb1 100644 (file)
--- a/Utils.js
+++ b/Utils.js
@@ -60,6 +60,11 @@ Ext.define('Proxmox.Utils', { utilities: {
     stateText: gettext('State'),
     groupText: gettext('Group'),
 
+    getNoSubKeyHtml: function(url) {
+       // url http://www.proxmox.com/products/proxmox-ve/subscription-service-plans
+       return Ext.String.format('You do not have a valid subscription for this server. Please visit <a target="_blank" href="{0}">www.proxmox.com</a> to get a list of available options.', url || 'http://www.proxmox.com');
+    },
+
     format_boolean_with_default: function(value) {
        if (Ext.isDefined(value) && value !== '__default__') {
            return value ? Proxmox.Utils.yesText : Proxmox.Utils.noText;
@@ -288,6 +293,37 @@ Ext.define('Proxmox.Utils', { utilities: {
        Ext.Ajax.request(newopts);
     },
 
+    checked_command: function(orig_cmd) {
+       Proxmox.Utils.API2Request({
+           url: '/nodes/localhost/subscription',
+           method: 'GET',
+           //waitMsgTarget: me,
+           failure: function(response, opts) {
+               Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+           },
+           success: function(response, opts) {
+               var data = response.result.data;
+
+               if (data.status !== 'Active') {
+                   Ext.Msg.show({
+                       title: gettext('No valid subscription'),
+                       icon: Ext.Msg.WARNING,
+                       msg: Proxmox.Utils.getNoSubKeyHtml(data.url),
+                       buttons: Ext.Msg.OK,
+                       callback: function(btn) {
+                           if (btn !== 'ok') {
+                               return;
+                           }
+                           orig_cmd();
+                       }
+                   });
+               } else {
+                   orig_cmd();
+               }
+           }
+       });
+    },
+
     assemble_field_data: function(values, data) {
         if (Ext.isObject(data)) {
            Ext.Object.each(data, function(name, val) {
diff --git a/node/APT.js b/node/APT.js
new file mode 100644 (file)
index 0000000..68075b6
--- /dev/null
@@ -0,0 +1,207 @@
+Ext.define('apt-pkglist', {
+    extend: 'Ext.data.Model',
+    fields: [ 'Package', 'Title', 'Description', 'Section', 'Arch',
+             'Priority', 'Version', 'OldVersion', 'ChangeLogUrl', 'Origin' ],
+    idProperty: 'Package'
+});
+
+Ext.define('Proxmox.node.APT', {
+    extend: 'Ext.grid.GridPanel',
+
+    xtype: 'proxmoxNodeAPT',
+
+    upgradeBtn: undefined,
+
+    columns: [
+       {
+           header: gettext('Package'),
+           width: 200,
+           sortable: true,
+           dataIndex: 'Package'
+       },
+       {
+           text: gettext('Version'),
+           columns: [
+               {
+                   header: gettext('current'),
+                   width: 100,
+                   sortable: false,
+                   dataIndex: 'OldVersion'
+               },
+               {
+                   header: gettext('new'),
+                   width: 100,
+                   sortable: false,
+                   dataIndex: 'Version'
+               }
+           ]
+       },
+       {
+           header: gettext('Description'),
+           sortable: false,
+           dataIndex: 'Title',
+           flex: 1
+       }
+    ],
+
+    initComponent : function() {
+       var me = this;
+
+       if (!me.nodename) {
+           throw "no node name specified";
+       }
+
+       var store = Ext.create('Ext.data.Store', {
+           model: 'apt-pkglist',
+           groupField: 'Origin',
+           proxy: {
+                type: 'proxmox',
+                url: "/api2/json/nodes/" + me.nodename + "/apt/update"
+           },
+           sorters: [
+               {
+                   property : 'Package',
+                   direction: 'ASC'
+               }
+           ]
+       });
+
+       var groupingFeature = Ext.create('Ext.grid.feature.Grouping', {
+            groupHeaderTpl: '{[ "Origin: " + values.name ]} ({rows.length} Item{[values.rows.length > 1 ? "s" : ""]})',
+           enableGroupingMenu: false
+       });
+
+       var rowBodyFeature = Ext.create('Ext.grid.feature.RowBody', {
+            getAdditionalData: function (data, rowIndex, record, orig) {
+                var headerCt = this.view.headerCt;
+                var colspan = headerCt.getColumnCount();
+                // Usually you would style the my-body-class in CSS file
+                return {
+                    rowBody: '<div style="padding: 1em">' +
+                       Ext.String.htmlEncode(data.Description) +
+                       '</div>',
+                    rowBodyColspan: colspan
+                };
+           }
+       });
+
+       var reload = function() {
+           store.load();
+       };
+
+       Proxmox.Utils.monStoreErrors(me, store, true);
+
+       var apt_command = function(cmd){
+           Proxmox.Utils.API2Request({
+               url: "/nodes/" + me.nodename + "/apt/" + cmd,
+               method: 'POST',
+               failure: function(response, opts) {
+                   Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+               },
+               success: function(response, opts) {
+                   var upid = response.result.data;
+
+                   var win = Ext.create('Proxmox.window.TaskViewer', {
+                       upid: upid
+                   });
+                   win.show();
+                   me.mon(win, 'close', reload);
+               }
+           });
+       };
+
+       var sm = Ext.create('Ext.selection.RowModel', {});
+
+       var update_btn = new Ext.Button({
+           text: gettext('Refresh'),
+           handler: function(){
+               Proxmox.Utils.checked_command(function() { apt_command('update'); });
+           }
+       });
+
+       var show_changelog = function(rec) {
+           if (!rec || !rec.data || !(rec.data.ChangeLogUrl && rec.data.Package)) {
+               return;
+           }
+
+           var view = Ext.createWidget('component', {
+               autoScroll: true,
+               style: {
+                   'background-color': 'white',
+                   'white-space': 'pre',
+                   'font-family': 'monospace',
+                   padding: '5px'
+               }
+           });
+
+           var win = Ext.create('Ext.window.Window', {
+               title: gettext('Changelog') + ": " + rec.data.Package,
+               width: 800,
+               height: 400,
+               layout: 'fit',
+               modal: true,
+               items: [ view ]
+           });
+
+           Proxmox.Utils.API2Request({
+               waitMsgTarget: me,
+               url: "/nodes/" + me.nodename + "/apt/changelog",
+               params: {
+                   name: rec.data.Package,
+                   version: rec.data.Version
+               },
+               method: 'GET',
+               failure: function(response, opts) {
+                   win.close();
+                   Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+               },
+               success: function(response, opts) {
+                   win.show();
+                   view.update(Ext.htmlEncode(response.result.data));
+               }
+           });
+
+       };
+
+       var changelog_btn = new Proxmox.button.Button({
+           text: gettext('Changelog'),
+           selModel: sm,
+           disabled: true,
+           enableFn: function(rec) {
+               if (!rec || !rec.data || !(rec.data.ChangeLogUrl && rec.data.Package)) {
+                   return false;
+               }
+               return true;
+           },
+           handler: function(b, e, rec) {
+               show_changelog(rec);
+           }
+       });
+
+       if (me.upgradeBtn) {
+           me.tbar =  [ update_btn, me.upgradeBtn, changelog_btn ];
+       } else {
+           me.tbar =  [ update_btn, changelog_btn ];
+       }
+
+       Ext.apply(me, {
+           store: store,
+           stateful: true,
+           stateId: 'grid-update',
+           selModel: sm,
+            viewConfig: {
+               stripeRows: false,
+               emptyText: '<div style="display:table; width:100%; height:100%;"><div style="display:table-cell; vertical-align: middle; text-align:center;"><b>' + gettext('No updates available.') + '</div></div>'
+           },
+           features: [ groupingFeature, rowBodyFeature ],
+           listeners: {
+               activate: reload,
+               itemdblclick: function(v, rec) {
+                   show_changelog(rec);
+               }
+           }
+       });
+
+       me.callParent();
+    }
+});