I've just noticed when the backend takes some time to check for packages
update the "Software Update"
appears empty, and after some time the grid is shown.
I'd suggest to always display the an empty grid and update it when the
request finishes.
What do you think?
On 03/04/2014 03:18 AM, Hongliang Wang wrote:
Added UI support for software updating. The Host Tab will initially
list available updates to user if there are any; or we will disable
"Update All" Button if no updates available.
Please apply following patch first:
* [PATCH] [UI] Grid Widget - Enable/Disable Row Selection
v4 -> v5:
5a) Disable row selection in software update grid
(Thanks to Royce's comment)
v3 -> v4:
4a) Added the last update output
(Thanks to Aline's comment)
4b) Disabled horizontal resize function of output textarea
(Thanks to Aline's comment)
4c) Added "Update Progress" label to the output textarea
(Thanks to Aline's comment)
4d) Added refreshing the software grid after updating is finished
(Thanks to Aline's comment)
4e) Added software updates grid cleanup when host tab is unloaded
v2 -> v3:
3a) Fixed "Update All" Button always being disabled issue
(Thanks to Paulo and Aline's comment)
3b) Updated REST API calling according to back-end change
3c) Added in-progress message when system is being updated
(Thanks to Aline's comment)
v1 -> v2:
2a) Fixed "Update All" Button always being disabled issue
(Thanks to Paulo Ricardo Paz Vital's comment)
Signed-off-by: Hongliang Wang <hlwang(a)linux.vnet.ibm.com>
---
ui/css/theme-default/host.css | 29 ++++++++++++++
ui/js/src/kimchi.api.js | 53 ++++++++++++++++++++++++++
ui/js/src/kimchi.host.js | 89 +++++++++++++++++++++++++++++++++++++++++++
ui/pages/i18n.html.tmpl | 10 +++++
ui/pages/tabs/host.html.tmpl | 17 +++++++++
5 files changed, 198 insertions(+)
diff --git a/ui/css/theme-default/host.css b/ui/css/theme-default/host.css
index 470ed1b..0f8b941 100644
--- a/ui/css/theme-default/host.css
+++ b/ui/css/theme-default/host.css
@@ -224,3 +224,32 @@
width: 300px;
}
/* End of Debug Report */
+
+/* Software Updates */
+.host-panel #software-updates-grid {
+ border-color: #ddd;
+ height: 300px;
+ width: 850px;
+}
+
+.software-update-id {
+ width: 30px;
+}
+
+.software-update-name,
+.software-update-repos {
+ width: 220px;
+}
+
+.software-update-version,
+.software-update-arch {
+ width: 190px;
+}
+
+.host-panel #software-updates-progress-textarea {
+ border: 1px solid #ddd;
+ height: 100px;
+ resize: vertical;
+ width: 846px;
+}
+/* End of Software Updates */
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index fdd9cfc..beaf314 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -727,5 +727,58 @@ var kimchi = {
success : suc,
error : err
});
+ },
+
+ listSoftwareUpdates : function(suc, err) {
+ kimchi.requestJSON({
+ url : kimchi.url + 'host/packagesupdate',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ updateSoftwares : function(suc, err, progress) {
+ var taskID = -1;
+ var onResponse = function(data) {
+ taskID = data['id'];
+ trackTask();
+ };
+
+ var trackTask = function() {
+ kimchi.getTask(taskID, onTaskResponse, err);
+ };
+
+ var onTaskResponse = function(result) {
+ var taskStatus = result['status'];
+ switch(taskStatus) {
+ case 'running':
+ progress && progress(result);
+ setTimeout(function() {
+ trackTask();
+ }, 200);
+ break;
+ case 'finished':
+ suc(result);
+ break;
+ case 'failed':
+ err(result);
+ break;
+ default:
+ break;
+ }
+ };
+
+ kimchi.requestJSON({
+ url : kimchi.url + 'host/swupdate',
+ type : "POST",
+ contentType : "application/json",
+ dataType : "json",
+ success : onResponse,
+ error : err
+ });
}
};
diff --git a/ui/js/src/kimchi.host.js b/ui/js/src/kimchi.host.js
index 7974054..e146a75 100644
--- a/ui/js/src/kimchi.host.js
+++ b/ui/js/src/kimchi.host.js
@@ -133,6 +133,88 @@ kimchi.host_main = function() {
});
};
+ var softwareUpdatesGridID = 'software-updates-grid';
+ var softwareUpdatesGrid = null;
+ var progressAreaID = 'software-updates-progress-textarea';
+ var reloadProgressArea = function(result) {
+ var progressArea = $('#' + progressAreaID)[0];
+ $(progressArea).text(result['message']);
+ var scrollTop = $(progressArea).prop('scrollHeight');
+ $(progressArea).prop('scrollTop', scrollTop);
+ };
+
+ var initSoftwareUpdatesGrid = function(softwareUpdates) {
+ softwareUpdatesGrid = new kimchi.widget.Grid({
+ container: 'software-updates-grid-container',
+ id: softwareUpdatesGridID,
+ title: i18n['KCHUPD6001M'],
+ rowSelection: 'disabled',
+ toolbarButtons: [{
+ id: softwareUpdatesGridID + '-update-button',
+ label: i18n['KCHUPD6006M'],
+ disabled: true,
+ onClick: function(event) {
+ var updateButton = $(this);
+ var progressArea = $('#' + progressAreaID)[0];
+
$('#software-updates-progress-container').removeClass('hidden');
+ $(progressArea).text('');
+ !kimchi.isElementInViewport(progressArea) &&
+ progressArea.scrollIntoView();
+
$(updateButton).text(i18n['KCHUPD6007M']).prop('disabled', true);
+
+ kimchi.updateSoftwares(function(result) {
+ reloadProgressArea(result);
+
$(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
+ kimchi.topic('kimchi/softwareUpdated').publish({
+ result: result
+ });
+ }, function() {}, reloadProgressArea);
+ }
+ }],
+ frozenFields: [{
+ name: 'id',
+ label: ' ',
+ 'class': 'software-update-id'
+ }],
+ fields: [{
+ name: 'package_name',
+ label: i18n['KCHUPD6002M'],
+ 'class': 'software-update-name'
+ }, {
+ name: 'version',
+ label: i18n['KCHUPD6003M'],
+ 'class': 'software-update-version'
+ }, {
+ name: 'arch',
+ label: i18n['KCHUPD6004M'],
+ 'class': 'software-update-arch'
+ }, {
+ name: 'repository',
+ label: i18n['KCHUPD6005M'],
+ 'class': 'software-update-repos'
+ }],
+ data: softwareUpdates
+ });
+ };
+
+ var listSoftwareUpdates = function() {
+ kimchi.listSoftwareUpdates(function(softwareUpdates) {
+ $.each(softwareUpdates, function(i, item) {
+ softwareUpdates[i]['id'] = i + 1;
+ });
+
+ if(softwareUpdatesGrid) {
+ softwareUpdatesGrid.setData(softwareUpdates);
+ }
+ else {
+ initSoftwareUpdatesGrid(softwareUpdates);
+ }
+
+ var updateButton = $('#' + softwareUpdatesGridID +
'-update-button');
+ $(updateButton).prop('disabled', softwareUpdates.length === 0);
+ });
+ };
+
var shutdownButtonID = '#host-button-shutdown';
var restartButtonID = '#host-button-restart';
var shutdownHost = function(params) {
@@ -191,6 +273,8 @@ kimchi.host_main = function() {
kimchi.keepMonitoringHost = this['checked'];
});
+ listSoftwareUpdates();
+
kimchi.getCapabilities(function(capabilities) {
if(!capabilities['system_report_tool']) {
return;
@@ -204,6 +288,10 @@ kimchi.host_main = function() {
listDebugReports();
});
+ kimchi.topic('kimchi/softwareUpdated').subscribe(function() {
+ listSoftwareUpdates();
+ });
+
kimchi.getHost(function(data) {
var htmlTmpl = $('#host-tmpl').html();
data['logo'] = data['logo'] || '';
@@ -469,5 +557,6 @@ kimchi.host_main = function() {
delete kimchi.hostTimer;
}
reportGrid && reportGrid.destroy();
+ softwareUpdatesGrid && softwareUpdatesGrid.destroy();
});
};
diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl
index 38f71d9..c96f804 100644
--- a/ui/pages/i18n.html.tmpl
+++ b/ui/pages/i18n.html.tmpl
@@ -89,6 +89,16 @@ var i18n = {
'KCHDR6010M': "$_("Download")",
'KCHDR6011M': "$_("Report name should contain only letters,
digits and/or hyphen ('-').")",
+
+ 'KCHUPD6001M': "$_("Software Updates")",
+ 'KCHUPD6002M': "$_("Package Name")",
+ 'KCHUPD6003M': "$_("Version")",
+ 'KCHUPD6004M': "$_("Architecture")",
+ 'KCHUPD6005M': "$_("Repository")",
+ 'KCHUPD6006M': "$_("Update All")",
+ 'KCHUPD6007M': "$_("Updating...")",
+
+
'KCHVM6001M': "$_("This will delete the virtual machine and its
virtual disks. This operation cannot be undone. Would you like to continue?")",
'KCHVM6002M': "$_("Delete Confirmation")",
diff --git a/ui/pages/tabs/host.html.tmpl b/ui/pages/tabs/host.html.tmpl
index 23b9853..f6ecd47 100644
--- a/ui/pages/tabs/host.html.tmpl
+++ b/ui/pages/tabs/host.html.tmpl
@@ -120,6 +120,23 @@
</div>
</div>
</div>
+ <div id="software-update-section"
class="host-section">
+ <h3 class="section-header"
+ aria-controls="content-software-update">
+ $_("Software Updates")
+ </h3>
+ <div id="content-software-update"
class="section-content">
+ <div class="section-row">
+ <div class="section-value">
+ <div
id="software-updates-grid-container"></div>
+ <div id="software-updates-progress-container"
class="hidden">
+ <label
for="software-updates-progress-textarea">$_("Update
Progress")</label>
+ <textarea
id="software-updates-progress-textarea" readonly></textarea>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
<div id="debug-report-section" class="host-section
hidden">
<h3 class="section-header"
aria-controls="content-sys-reports">