[Kimchi-devel] [PATCH 12/17] Ginger Base : base plugin ui/js files
chandra at linux.vnet.ibm.com
chandra at linux.vnet.ibm.com
Tue Sep 1 18:01:30 UTC 2015
From: chandrureddy <chandra at linux.vnet.ibm.com>
---
plugins/gingerbase/ui/js/Makefile.am | 27 +
plugins/gingerbase/ui/js/src/gingerbase.api.js | 371 +++++++++
plugins/gingerbase/ui/js/src/gingerbase.form.js | 48 ++
plugins/gingerbase/ui/js/src/gingerbase.grid.js | 528 +++++++++++++
plugins/gingerbase/ui/js/src/gingerbase.host.js | 859 +++++++++++++++++++++
.../gingerbase/ui/js/src/gingerbase.line-chart.js | 202 +++++
plugins/gingerbase/ui/js/src/gingerbase.main.js | 26 +
.../ui/js/src/gingerbase.report_add_main.js | 72 ++
.../ui/js/src/gingerbase.report_rename_main.js | 66 ++
.../ui/js/src/gingerbase.repository_add_main.js | 96 +++
.../ui/js/src/gingerbase.repository_edit_main.js | 74 ++
plugins/gingerbase/ui/js/src/gingerbase.select.js | 50 ++
plugins/gingerbase/ui/js/widgets/circleGauge.js | 100 +++
plugins/kimchi/ui/js/src/kimchi.host.js | 858 --------------------
plugins/kimchi/ui/js/src/kimchi.report_add_main.js | 72 --
.../kimchi/ui/js/src/kimchi.report_rename_main.js | 66 --
.../kimchi/ui/js/src/kimchi.repository_add_main.js | 96 ---
.../ui/js/src/kimchi.repository_edit_main.js | 74 --
18 files changed, 2519 insertions(+), 1166 deletions(-)
create mode 100644 plugins/gingerbase/ui/js/Makefile.am
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.api.js
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.form.js
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.grid.js
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.host.js
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.line-chart.js
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.main.js
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.report_add_main.js
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.report_rename_main.js
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.repository_add_main.js
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.repository_edit_main.js
create mode 100644 plugins/gingerbase/ui/js/src/gingerbase.select.js
create mode 100644 plugins/gingerbase/ui/js/widgets/circleGauge.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.host.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.report_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
diff --git a/plugins/gingerbase/ui/js/Makefile.am b/plugins/gingerbase/ui/js/Makefile.am
new file mode 100644
index 0000000..142ccdb
--- /dev/null
+++ b/plugins/gingerbase/ui/js/Makefile.am
@@ -0,0 +1,27 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EXTRA_DIST = src widgets
+
+jsdir = $(datadir)/wok/plugins/gingerbase/ui/js
+
+dist_js_DATA = gingerbase.min.js $(filter-out gingerbase.min.js, $(wildcard *.js))
+
+gingerbase.min.js: widgets/*.js src/*.js
+ cat $(sort $^) > $@
+
+CLEANFILES = gingerbase.min.js
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.api.js b/plugins/gingerbase/ui/js/src/gingerbase.api.js
new file mode 100644
index 0000000..480f6fb
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.api.js
@@ -0,0 +1,371 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var kimchi = {
+
+ widget: {},
+
+ trackingTasks: [],
+
+ /**
+ *
+ * Get host capabilities
+ * suc: callback if succeed err: callback if failed
+ */
+ getCapabilities : function(suc, err, done) {
+ done = typeof done !== 'undefined' ? done: function(){};
+ wok.requestJSON({
+ url : "plugins/gingerbase/host/capabilities",
+ type : "GET",
+ contentType : "application/json",
+ dataType : "json",
+ success: suc,
+ error: err,
+ complete: done
+ });
+ },
+
+ /**
+ * Get the i18 strings.
+ */
+ getI18n: function(suc, err, url, sync) {
+ wok.requestJSON({
+ url : url ? url : 'plugins/gingerbase/i18n.json',
+ type : 'GET',
+ resend: true,
+ dataType : 'json',
+ async : !sync,
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ * Get the host static information.
+ */
+ getHost: function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/gingerbase/host',
+ type : 'GET',
+ resend: true,
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ * Get the dynamic host stats (usually used for monitoring).
+ */
+ getHostStats : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/gingerbase/host/stats',
+ type : 'GET',
+ contentType : 'application/json',
+ headers: {'Wok-Robot': 'wok-robot'},
+ dataType : 'json',
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ * Get the historic host stats.
+ */
+ getHostStatsHistory : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/gingerbase/host/stats/history',
+ type : 'GET',
+ resend: true,
+ contentType : 'application/json',
+ headers: {'Wok-Robot': 'wok-robot'},
+ dataType : 'json',
+ success : suc,
+ error: err
+ });
+ },
+
+ getTask : function(taskId, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/gingerbase/tasks/' + encodeURIComponent(taskId),
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ getTasksByFilter : function(filter, suc, err, sync) {
+ wok.requestJSON({
+ url : 'plugins/gingerbase/tasks?' + filter,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ async : !sync,
+ success : suc,
+ error : err
+ });
+ },
+
+ listReports : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/gingerbase/debugreports',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ trackTask : function(taskID, suc, err, progress) {
+ var onTaskResponse = function(result) {
+ var taskStatus = result['status'];
+ switch(taskStatus) {
+ case 'running':
+ progress && progress(result);
+ setTimeout(function() {
+ kimchi.trackTask(taskID, suc, err, progress);
+ }, 2000);
+ break;
+ case 'finished':
+ suc && suc(result);
+ break;
+ case 'failed':
+ err && err(result);
+ break;
+ default:
+ break;
+ }
+ };
+
+ kimchi.getTask(taskID, onTaskResponse, err);
+ if(kimchi.trackingTasks.indexOf(taskID) < 0)
+ kimchi.trackingTasks.push(taskID);
+ },
+
+ createReport: function(settings, suc, err, progress) {
+ var onResponse = function(data) {
+ taskID = data['id'];
+ kimchi.trackTask(taskID, suc, err, progress);
+ };
+
+ wok.requestJSON({
+ url : 'plugins/gingerbase/debugreports',
+ type : "POST",
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json",
+ success : onResponse,
+ error : err
+ });
+ },
+
+ renameReport : function(name, settings, suc, err) {
+ $.ajax({
+ url : "plugins/gingerbase/debugreports/" + encodeURIComponent(name),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
+ deleteReport: function(settings, suc, err) {
+ var reportName = encodeURIComponent(settings['name']);
+ wok.requestJSON({
+ url : 'plugins/gingerbase/debugreports/' + reportName,
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ downloadReport: function(settings, suc, err) {
+ window.open(settings['file']);
+ },
+
+ shutdown: function(settings, suc, err) {
+ var reboot = settings && settings['reboot'] === true;
+ var url = 'plugins/gingerbase/host/' + (reboot ? 'reboot' : 'shutdown');
+ wok.requestJSON({
+ url : url,
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listHostPartitions : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/gingerbase/host/partitions',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listSoftwareUpdates : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/gingerbase/host/packagesupdate',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ updateSoftware : 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':
+ case 'failed':
+ suc(result);
+ break;
+ default:
+ break;
+ }
+ };
+
+ wok.requestJSON({
+ url : 'plugins/gingerbase/host/swupdate',
+ type : "POST",
+ contentType : "application/json",
+ dataType : "json",
+ success : onResponse,
+ error : err
+ });
+ },
+
+ createRepository : function(settings, suc, err) {
+ wok.requestJSON({
+ url : "plugins/gingerbase/host/repositories",
+ type : "POST",
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json",
+ success: suc,
+ error: err
+ });
+ },
+
+ retrieveRepository : function(repository, suc, err) {
+ var reposID = encodeURIComponent(repository);
+ wok.requestJSON({
+ url : "plugins/gingerbase/host/repositories/" + reposID,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ updateRepository : function(name, settings, suc, err) {
+ var reposID = encodeURIComponent(name);
+ $.ajax({
+ url : "plugins/gingerbase/host/repositories/" + reposID,
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ enableRepository : function(name, enable, suc, err) {
+ var reposID = encodeURIComponent(name);
+ $.ajax({
+ url : "plugins/gingerbase/host/repositories/" + reposID +
+ '/' + (enable === true ? 'enable' : 'disable'),
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ deleteRepository : function(repository, suc, err) {
+ var reposID = encodeURIComponent(repository);
+ wok.requestJSON({
+ url : 'plugins/gingerbase/host/repositories/' + reposID,
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listRepositories : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/gingerbase/host/repositories',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ getCPUInfo : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/gingerbase/host/cpuinfo',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ }
+};
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.form.js b/plugins/gingerbase/ui/js/src/gingerbase.form.js
new file mode 100644
index 0000000..0bb7c4b
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.form.js
@@ -0,0 +1,48 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+(function($) {
+ $.fn.serializeObject = function() {
+ var formDataArray = $(this).serializeArray();
+ var formData = new Object();
+ $.each(formDataArray, function(index, data) {
+ formData.setDeepValue(data.name, data.value);
+ });
+ return formData;
+ };
+}(jQuery));
+
+(function($) {
+ $.fn.fillWithObject = function(obj) {
+ $(this).find("input").each(function(){
+ switch($(this).attr('type')) {
+ case 'text':
+ $(this).val(obj.getDeepValue($(this).attr("name")));
+ break;
+ case 'radio':
+ case 'checkbox':
+ var a=String($(this).val());
+ var b=String(obj.getDeepValue($(this).attr("name")));
+ $(this).prop("checked",(a==b));
+ break;
+ default:
+ break;
+ }
+ });
+ };
+}(jQuery));
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.grid.js b/plugins/gingerbase/ui/js/src/gingerbase.grid.js
new file mode 100644
index 0000000..4553135
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.grid.js
@@ -0,0 +1,528 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+kimchi.widget.Grid = function(opts) {
+ this.opts = $.extend({}, this.opts, opts);
+ this.createDOM();
+ this.reload();
+};
+
+kimchi.widget.Grid.prototype = (function() {
+ var htmlStr = [
+ '<div id="{id}" class="grid">',
+ '<div class="grid-content">',
+ '<div class="grid-header">',
+ '<div class="grid-frozen-header-view">',
+ '<table class="grid-frozen-header-container">',
+ '</table>',
+ '</div>',
+ '<div class="grid-header-view">',
+ '<div class="grid-header-wrapper">',
+ '<table class="grid-header-container">',
+ '</table>',
+ '</div>',
+ '</div>',
+ '</div>',
+ '<div class="grid-body">',
+ '<div class="grid-frozen-body-view">',
+ '<div class="grid-frozen-body-wrapper">',
+ '<table class="grid-frozen-body-container">',
+ '</table>',
+ '</div>',
+ '</div>',
+ '<div class="grid-body-view">',
+ '<div class="grid-body-wrapper">',
+ '<table class="grid-body-container">',
+ '</table>',
+ '</div>',
+ '</div>',
+ '</div>',
+ '<div class="grid-resizer-leftmost hidden"></div>',
+ '<div class="grid-resizer hidden"></div>',
+ '</div>',
+ '<div class="grid-footer"></div>',
+ '<div class="grid-mask hidden">',
+ '<div class="grid-loading">',
+ '<div class="grid-loading-icon"></div>',
+ '<div class="grid-loading-text">',
+ '{loading}',
+ '</div>',
+ '</div>',
+ '</div>',
+ '<div class="grid-message hidden">',
+ '<div class="grid-message-text">',
+ '{message}',
+ '<button class="retry-button btn-small">',
+ '{buttonLabel}',
+ '</button>',
+ '</div>',
+ '<div class="detailed-title">',
+ '{detailedLabel}',
+ '</div>',
+ '<div class="detailed-text"></div>',
+ '</div>',
+ '</div>'
+ ].join('');
+
+ var CONTAINER_NORMAL = 0, CONTAINER_FROZEN = 1;
+
+ var setupHeaders = function(header, body, fields) {
+ var colGroup = $('<colgroup></colgroup>').appendTo(header);
+ var headerHeader = $('<thead></thead>');
+ var headerRow = $('<tr></tr>').appendTo(headerHeader);
+ $.each(fields || [], function(i, field) {
+ $('<col class="' +
+ field['class'] +
+ '"/>')
+ .appendTo(colGroup);
+ $('<th><div class="cell-text-wrapper">' +
+ field['label'] +
+ '</div></th>').appendTo(headerRow);
+ });
+ headerHeader.appendTo(header);
+
+ var totalWidth = 0;
+ $('col', colGroup).each(function(index, col) {
+ var width = $(col).width();
+ totalWidth += width;
+ $(col).css('width', width + 'px');
+ });
+ $(body).append(colGroup.clone());
+ return totalWidth;
+ };
+
+ var getValue = function(name, obj) {
+ var result=undefined;
+ if(!Array.isArray(name)) {
+ name=name.parseKey();
+ }
+ if(name.length!=0) {
+ var tmpName=name.shift();
+ if(obj[tmpName]!=undefined) {
+ result=obj[tmpName];
+ }
+ if(name.length!=0) {
+ result=getValue(name,obj[tmpName]);
+ }
+ }
+ return(result);
+ };
+
+ var fillBody = function(container, fields) {
+ var data = this.data;
+ var tbody = ($('tbody', container).length && $('tbody', container))
+ || $('<tbody></tbody>').appendTo(container);
+ tbody.empty();
+ $.each(data, function(i, row) {
+ var rowNode = $('<tr></tr>').appendTo(tbody);
+ $.each(fields, function(fi, field) {
+ var value = getValue(field['name'], row);
+ $('<td><div class="cell-text-wrapper"' +
+ (field['makeTitle'] === true
+ ? ' title="' + value + '"'
+ : ''
+ ) + '>' + value.toString() + '</div></td>'
+ ).appendTo(rowNode);
+ });
+ });
+ };
+
+ var fixTableLayout = function(style) {
+ $.each([
+ this.frozenHeaderContainer,
+ this.headerContainer,
+ this.frozenBodyContainer,
+ this.bodyContainer
+ ], function(i, tableNode) {
+ $(tableNode).css('table-layout', style || 'fixed');
+ });
+ };
+
+ var initResizing = function(event) {
+ var resizer = event.data.resizer;
+ var pageX = event.pageX;
+ var tailPos = $(this).width() + $(this).offset()['left'];
+ var atResizer = Math.abs(pageX - tailPos) <= 2;
+ var isResizing = !$(resizer).hasClass('hidden');
+ $('body')[(atResizer || isResizing)
+ ? 'addClass'
+ : 'removeClass'
+ ]('resizing');
+ };
+
+ var clearResizing = function(event) {
+ $(event.data.resizer).hasClass('hidden') &&
+ $('body').removeClass('resizing');
+ };
+
+ var stylingRow = function(row, className, add) {
+ var index = $(row).index() + 1;
+ $('tr', this.frozenBodyContainer)
+ .removeClass(className);
+ $('tr', this.bodyContainer)
+ .removeClass(className);
+
+ if(add === false) {
+ return;
+ }
+
+ $('tr:nth-child(' + index + ')', this.frozenBodyContainer)
+ .addClass(className);
+ $('tr:nth-child(' + index + ')', this.bodyContainer)
+ .addClass(className);
+ };
+
+ var setBodyListeners = function() {
+ if(this['opts']['rowSelection'] != 'disabled') {
+ $('tr', this.gridBody).on('mouseover', {
+ grid: this
+ }, function(event) {
+ if (! $(this).hasClass('no-hover'))
+ stylingRow.call(event.data.grid, this, 'hover');
+ });
+
+ $('tr', this.gridBody).on('mouseout', {
+ grid: this
+ }, function(event) {
+ stylingRow.call(event.data.grid, this, 'hover', false);
+ });
+
+ $('tr', this.gridBody).on('click', {
+ grid: this
+ }, function(event) {
+ var grid = event.data.grid;
+ grid.selectedIndex = $(this).index();
+ stylingRow.call(grid, this, 'selected');
+ grid['opts']['onRowSelected'] && grid['opts']['onRowSelected']();
+ });
+ }
+
+ $('.grid-body-view', this.domNode).on('scroll', {
+ grid: this
+ }, function(event) {
+ var grid = event.data.grid;
+ $('.grid-header .grid-header-view', grid.domNode)
+ .prop('scrollLeft', this.scrollLeft);
+ $('.grid-body .grid-frozen-body-view', grid.domNode)
+ .prop('scrollTop', this.scrollTop);
+ });
+ };
+
+ var setData = function(data) {
+ this.data = data;
+ fillBody.call(this, this.frozenBodyContainer, this['opts']['frozenFields']);
+ fillBody.call(this, this.bodyContainer, this['opts']['fields']);
+ setBodyListeners.call(this);
+ };
+
+ var getSelected = function() {
+ return this.selectedIndex >= 0
+ ? this.data[this.selectedIndex]
+ : null;
+ };
+
+ var startResizing = function(container, event) {
+ var grid = event.data.grid;
+ kimchi.widget.Grid.beingResized = grid;
+ if(!($('body').hasClass('resizing')
+ && $(grid.resizer).hasClass('hidden'))) {
+ return;
+ }
+
+ grid.columnBeingResized = container;
+ var pageX = event.pageX;
+ var gridOffsetX = grid.domNode.offset()['left'];
+ var leftmostOffsetX = $(container).offset()['left'] - gridOffsetX;
+ var left = pageX - gridOffsetX;
+ var contentHeight = $('.grid-content', grid.domNode).height();
+ $(grid.resizerLeftmost).css({
+ left: leftmostOffsetX + 'px',
+ height: contentHeight + 'px'
+ });
+ $(grid.resizer).css({
+ left: left + 'px',
+ height: contentHeight + 'px'
+ });
+ $(grid.resizerLeftmost).removeClass('hidden');
+ $(grid.resizer).removeClass('hidden');
+ event.preventDefault();
+ };
+
+ var endResizing = function(event) {
+ var grid = kimchi.widget.Grid.beingResized;
+ if(!$('body').hasClass('resizing')) {
+ return;
+ }
+ $(grid.resizerLeftmost).addClass('hidden');
+ $(grid.resizer).addClass('hidden');
+ $('body').removeClass('resizing');
+ var leftmostOffset = $(grid.columnBeingResized).offset()['left'];
+ var left = event.pageX;
+ if(leftmostOffset > left) {
+ return;
+ }
+ resizeColumnWidth.call(
+ grid,
+ $(grid.columnBeingResized).index(),
+ left - leftmostOffset
+ );
+ fixTableLayout.call(grid);
+ grid.columnBeingResized = null;
+ kimchi.widget.Grid.beingResized = null;
+ };
+
+ var resizeColumnWidth = function(index, width) {
+ var width = Math.ceil(width);
+ var widthArray = [];
+ var totalWidth = 0;
+ var header = this.headerContainer;
+ var body = this.bodyContainer;
+ if(this.containerBeingResized === CONTAINER_FROZEN) {
+ header = this.frozenHeaderContainer;
+ body = this.frozenBodyContainer;
+ }
+ $('col', header).each(function(i, colNode) {
+ var w = index === i ? width : $(colNode).width();
+ widthArray.push(w);
+ totalWidth += w;
+ });
+ $.each([header, body], function(i, container) {
+ container.css({
+ 'table-layout': 'fixed',
+ width: totalWidth + 'px'
+ });
+ $('col:nth-child(' + (index + 1) + ')', container).css({
+ width: width + 'px'
+ });
+ });
+
+ if(this.containerBeingResized === CONTAINER_FROZEN) {
+ var headerView = $('.grid-header-view', this.domNode);
+ var bodyView = $('.grid-body-view', this.domNode);
+ $.each([headerView, bodyView], function(i, view) {
+ view.css({
+ left: totalWidth + 'px'
+ });
+ });
+ }
+ };
+
+ var positionResizer = function(event) {
+ var grid = event.data.grid;
+ if($(grid.resizer).hasClass('hidden')) {
+ return;
+ }
+
+ var pageX = event.pageX;
+ var gridOffsetX = $(grid.domNode).offset()['left'];
+ var leftMost = $(grid.resizerLeftmost).position()['left'];
+ var offsetX = pageX - gridOffsetX;
+ offsetX = offsetX >= leftMost ? offsetX : leftMost;
+ $(grid.resizer).css('left', offsetX + 'px');
+ };
+
+ var showMessage = function(msg) {
+ $('.detailed-text', this.messageNode).text(msg);
+ $(this.messageNode).removeClass('hidden');
+ };
+
+ var hideMessage = function() {
+ $(this.messageNode).addClass('hidden');
+ };
+
+ var reload = function() {
+ var data = this['opts']['data'];
+ if(!data) {
+ return;
+ }
+
+ $(this.messageNode).addClass('hidden');
+
+ if($.isArray(data)) {
+ return this.setData(data);
+ }
+
+ if($.isFunction(data)) {
+ var loadData = data;
+ $(this.maskNode).removeClass('hidden');
+ loadData($.proxy(function(data) {
+ this.setData(data);
+ $(this.maskNode).addClass('hidden');
+ }, this));
+ }
+ };
+
+ var destroy = function() {
+ $('body').off('mousemove.grid#' + this['opts']['id'], positionResizer);
+ $('body').off('mouseup.grid#' + this['opts']['id'], endResizing);
+ };
+
+ var createDOM = function() {
+ var containerID = this['opts']['container'];
+ var container = $('#' + containerID);
+ var gridID = this['opts']['id'];
+ var rowSelection = this['opts']['rowSelection'] || 'single';
+ var domNode = $(wok.substitute(htmlStr, {
+ id: gridID,
+ loading: i18n['GGBGRD6001M'],
+ message: i18n['GGBGRD6002M'],
+ buttonLabel: i18n['GGBGRD6003M'],
+ detailedLabel: i18n['GGBGRD6004M']
+ })).appendTo(container);
+ this.domNode = domNode;
+
+ var height = domNode.height();
+ var width = domNode.width();
+
+ var title = this['opts']['title'];
+ var titleNode = null;
+ if(title) {
+ titleNode = $('<div class="grid-caption">' + title + '</div>')
+ .prependTo(domNode);
+ }
+
+ var toolbarButtons = this['opts']['toolbarButtons'];
+ var toolbarNode = null;
+ if(toolbarButtons) {
+ toolbarNode = $('<div class="grid-toolbar"></div>');
+ if(titleNode) {
+ titleNode.after(toolbarNode);
+ }
+ else {
+ toolbarNode.prependTo(domNode);
+ }
+
+ $.each(toolbarButtons, function(i, button) {
+ var btnHTML = [
+ '<button',
+ button['id'] ? (' id="' + button['id'] + '"') : '',
+ ' class="grid-toolbar-button',
+ button['class'] ? (' ' + button['class']) : '',
+ '"',
+ button['disabled'] === true ? ' disabled' : '',
+ '>',
+ button['label'],
+ '</button>'
+ ].join('');
+ var btnNode = $(btnHTML).appendTo(toolbarNode);
+ button['onClick'] &&
+ btnNode.on('click', button['onClick']);
+ });
+ }
+
+ var frozenHeaderContainer = $('.grid-frozen-header-container', domNode);
+ var frozenBodyContainer = $('.grid-frozen-body-container', domNode);
+ var frozenWidth = setupHeaders(
+ frozenHeaderContainer,
+ frozenBodyContainer,
+ this['opts']['frozenFields']
+ );
+ this.frozenHeaderContainer = frozenHeaderContainer;
+ this.frozenBodyContainer = frozenBodyContainer;
+
+ var headerContainer = $('.grid-header-container', domNode);
+ var bodyContainer = $('.grid-body-container', domNode);
+ setupHeaders(headerContainer, bodyContainer, this['opts']['fields']);
+ this.headerContainer = headerContainer;
+ this.bodyContainer = bodyContainer;
+
+ fixTableLayout.call(this, 'auto');
+
+ var gridContentNode = $('.grid-content', domNode);
+ var captionHeight = titleNode && $(titleNode).height() || 0;
+ var toolbarHeight = toolbarNode && $(toolbarNode).height() || 0;
+ gridContentNode.css('top', (captionHeight + toolbarHeight) + 'px');
+
+ var maskNode = $('.grid-mask', domNode);
+ maskNode.css('top', captionHeight + 'px');
+ this.maskNode = maskNode;
+
+ var messageNode = $('.grid-message', domNode);
+ messageNode.css('top', captionHeight + 'px');
+ this.messageNode = messageNode;
+
+ var headerView = $('.grid-header-view', domNode);
+ var bodyView = $('.grid-body-view', domNode);
+ headerView.css('left', (frozenWidth) + 'px');
+ bodyView.css('left', (frozenWidth) + 'px');
+
+ var bodyWidth = width - frozenWidth;
+ headerContainer.css('width', bodyWidth + 'px');
+ bodyContainer.css('width', bodyWidth + 'px');
+
+ fixTableLayout.call(this);
+
+ var gridBody = $('.grid-body', domNode);
+ this.gridBody = gridBody;
+ this.resizerLeftmost = $('.grid-resizer-leftmost', domNode);
+ this.resizer = $('.grid-resizer', domNode);
+ var gridHeader = $('.grid-header', domNode);
+ $('th', gridHeader).on('mouseover mousemove', {
+ resizer: this.resizer
+ }, initResizing);
+
+ $('th', gridHeader).on('mouseout', {
+ resizer: this.resizer
+ }, clearResizing);
+
+ this.containerBeingResized = CONTAINER_NORMAL;
+ $('th', frozenHeaderContainer).on('mousedown', {
+ grid: this
+ }, function(event) {
+ event.data.grid.containerBeingResized = CONTAINER_FROZEN;
+ startResizing(this, event);
+ });
+ $('th', headerContainer).on('mousedown', {
+ grid: this
+ }, function(event) {
+ event.data.grid.containerBeingResized = CONTAINER_NORMAL;
+ startResizing(this, event);
+ });
+
+ $('body').on('mousemove.grid#' + this['opts']['id'], {
+ grid: this
+ }, positionResizer);
+ $('body').on('mouseup.grid#' + this['opts']['id'], endResizing);
+
+ var data = this['opts']['data'];
+
+ $('.retry-button', domNode).on('click', {
+ grid: this
+ }, function(event) {
+ event.data.grid.reload();
+ });
+ };
+
+ return {
+ opts: {
+ container: null,
+ id: null,
+ rowSelection: 'single',
+ onRowSelected: null,
+ title: null,
+ toolbarButtons: null,
+ frozenFields: null,
+ fields: null
+ },
+ createDOM: createDOM,
+ setData: setData,
+ getSelected: getSelected,
+ reload: reload,
+ destroy: destroy,
+ showMessage: showMessage
+ };
+})();
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.host.js b/plugins/gingerbase/ui/js/src/gingerbase.host.js
new file mode 100644
index 0000000..989461c
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.host.js
@@ -0,0 +1,859 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+kimchi.host={};
+
+kimchi.host_main = function() {
+ var expand = function(header, toExpand) {
+ var controlledNode = $(header).attr('aria-controls');
+ $('#' + controlledNode)[toExpand ? 'removeClass' : 'addClass']('hidden');
+ $(header).attr('aria-expanded', toExpand ? 'true' : 'false');
+ };
+
+ var repositoriesGrid = null;
+ var initRepositoriesGrid = function(repo_type) {
+ var gridFields=[];
+ if (repo_type == "yum") {
+ gridFields=[{
+ name: 'repo_id',
+ label: i18n['GGBREPO6004M'],
+ 'class': 'repository-id'
+ }, {
+ name: 'config[repo_name]',
+ label: i18n['GGBREPO6005M'],
+ 'class': 'repository-name'
+ }, {
+ name: 'enabled',
+ label: i18n['GGBREPO6009M'],
+ 'class': 'repository-enabled'
+ }];
+ }
+ else if (repo_type == "deb") {
+ gridFields=[{
+ name: 'baseurl',
+ label: i18n['GGBREPO6006M'],
+ makeTitle: true,
+ 'class': 'repository-baseurl deb'
+ }, {
+ name: 'enabled',
+ label: i18n['GGBREPO6009M'],
+ 'class': 'repository-enabled deb'
+ }, {
+ name: 'config[dist]',
+ label: "dist",
+ 'class': 'repository-gpgcheck deb'
+ }, {
+ name: 'config[comps]',
+ label: "comps",
+ 'class': 'repository-gpgcheck deb'
+ }];
+ }
+ else {
+ gridFields=[{
+ name: 'repo_id',
+ label: i18n['GGBREPO6004M'],
+ 'class': 'repository-id'
+ }, {
+ name: 'enabled',
+ label: i18n['GGBREPO6009M'],
+ 'class': 'repository-enabled'
+ }, {
+ name: 'baseurl',
+ label: i18n['GGBREPO6006M'],
+ makeTitle: true,
+ 'class': 'repository-baseurl'
+ }];
+ }
+ repositoriesGrid = new kimchi.widget.Grid({
+ container: 'repositories-grid-container',
+ id: 'repositories-grid',
+ title: i18n['GGBREPO6003M'],
+ toolbarButtons: [{
+ id: 'repositories-grid-add-button',
+ label: i18n['GGBREPO6012M'],
+ onClick: function(event) {
+ wok.window.open({url:'plugins/gingerbase/repository-add.html',
+ class: repo_type});
+ }
+ }, {
+ id: 'repositories-grid-enable-button',
+ label: i18n['GGBREPO6016M'],
+ disabled: true,
+ onClick: function(event) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+ var name = repository['repo_id'];
+ var enable = !repository['enabled'];
+ $(this).prop('disabled', true);
+ kimchi.enableRepository(name, enable, function() {
+ wok.topic('kimchi/repositoryUpdated').publish();
+ });
+ }
+ }, {
+ id: 'repositories-grid-edit-button',
+ label: i18n['GGBREPO6013M'],
+ disabled: true,
+ onClick: function(event) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+ kimchi.selectedRepository = repository['repo_id'];
+ wok.window.open({url:'plugins/gingerbase/repository-edit.html',
+ class: repo_type});
+ }
+ }, {
+ id: 'repositories-grid-remove-button',
+ label: i18n['GGBREPO6014M'],
+ disabled: true,
+ onClick: function(event) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+
+ var settings = {
+ title : i18n['GGBREPO6001M'],
+ content : i18n['GGBREPO6002M'],
+ confirm : i18n['GGBAPI6004M'],
+ cancel : i18n['GGBAPI6003M']
+ };
+
+ wok.confirm(settings, function() {
+ kimchi.deleteRepository(
+ repository['repo_id'],
+ function(result) {
+ wok.topic('kimchi/repositoryDeleted').publish(result);
+ }, function(error) {
+ }
+ );
+ });
+ }
+ }],
+ onRowSelected: function(row) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+ $('#repositories-grid-remove-button').prop('disabled', false);
+ $('#repositories-grid-edit-button').prop('disabled', false);
+ var enabled = repository['enabled'];
+ $('#repositories-grid-enable-button')
+ .text(i18n[enabled ? 'GGBREPO6017M' : 'GGBREPO6016M'])
+ .prop('disabled', false);
+ },
+ frozenFields: [],
+ fields: gridFields,
+ data: listRepositories
+ });
+ };
+
+ var listRepositories = function(gridCallback) {
+ kimchi.listRepositories(function(repositories) {
+ if($.isFunction(gridCallback)) {
+ gridCallback(repositories);
+ }
+ else {
+ if(repositoriesGrid) {
+ repositoriesGrid.setData(repositories);
+ }
+ else {
+ initRepositoriesGrid();
+ repositoriesGrid.setData(repositories);
+ }
+ }
+ },
+ function(error) {
+ var message = error && error['responseJSON'] && error['responseJSON']['reason'];
+
+ if($.isFunction(gridCallback)) {
+ gridCallback([]);
+ }
+ repositoriesGrid &&
+ repositoriesGrid.showMessage(message || i18n['GGBUPD6008M']);
+ });
+
+ $('#repositories-grid-remove-button').prop('disabled', true);
+ $('#repositories-grid-edit-button').prop('disabled', true);
+ $('#repositories-grid-enable-button').prop('disabled', true);
+ };
+
+ 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['GGBUPD6001M'],
+ rowSelection: 'disabled',
+ toolbarButtons: [{
+ id: softwareUpdatesGridID + '-update-button',
+ label: i18n['GGBUPD6006M'],
+ disabled: true,
+ onClick: function(event) {
+ var updateButton = $(this);
+ var progressArea = $('#' + progressAreaID)[0];
+ $('#software-updates-progress-container').removeClass('hidden');
+ $(progressArea).text('');
+ !wok.isElementInViewport(progressArea) &&
+ progressArea.scrollIntoView();
+ $(updateButton).text(i18n['GGBUPD6007M']).prop('disabled', true);
+
+ kimchi.updateSoftware(function(result) {
+ reloadProgressArea(result);
+ $(updateButton).text(i18n['GGBUPD6006M']).prop('disabled', false);
+ wok.topic('kimchi/softwareUpdated').publish({
+ result: result
+ });
+ }, function(error) {
+ var message = error && error['responseJSON'] && error['responseJSON']['reason'];
+ wok.message.error(message || i18n['GGBUPD6009M']);
+ $(updateButton).text(i18n['GGBUPD6006M']).prop('disabled', false);
+ }, reloadProgressArea);
+ }
+ }],
+ frozenFields: [],
+ fields: [{
+ name: 'package_name',
+ label: i18n['GGBUPD6002M'],
+ 'class': 'software-update-name'
+ }, {
+ name: 'version',
+ label: i18n['GGBUPD6003M'],
+ 'class': 'software-update-version'
+ }, {
+ name: 'arch',
+ label: i18n['GGBUPD6004M'],
+ 'class': 'software-update-arch'
+ }, {
+ name: 'repository',
+ label: i18n['GGBUPD6005M'],
+ 'class': 'software-update-repos'
+ }],
+ data: listSoftwareUpdates
+ });
+ };
+
+ var listSoftwareUpdates = function(gridCallback) {
+ kimchi.listSoftwareUpdates(function(softwareUpdates) {
+ if($.isFunction(gridCallback)) {
+ gridCallback(softwareUpdates);
+ }
+ else {
+ if(softwareUpdatesGrid) {
+ softwareUpdatesGrid.setData(softwareUpdates);
+ }
+ else {
+ initSoftwareUpdatesGrid(softwareUpdates);
+ }
+ }
+
+ var updateButton = $('#' + softwareUpdatesGridID + '-update-button');
+ $(updateButton).prop('disabled', softwareUpdates.length === 0);
+ }, function(error) {
+ var message = error && error['responseJSON'] && error['responseJSON']['reason'];
+ if($.isFunction(gridCallback)) {
+ gridCallback([]);
+ }
+ softwareUpdatesGrid &&
+ softwareUpdatesGrid.showMessage(message || i18n['GGBUPD6008M']);
+ });
+ };
+
+ var reportGridID = 'available-reports-grid';
+ var reportGrid = null;
+ var enableReportButtons = function(toEnable) {
+ var buttonID = '#{grid}-{btn}-button';
+ $.each(['rename', 'remove', 'download'], function(i, n) {
+ $(wok.substitute(buttonID, {
+ grid: reportGridID,
+ btn: n
+ })).prop('disabled', !toEnable);
+ });
+ };
+ var initReportGrid = function(reports) {
+ reportGrid = new kimchi.widget.Grid({
+ container: 'available-reports-grid-container',
+ id: reportGridID,
+ title: i18n['GGBDR6002M'],
+ toolbarButtons: [{
+ id: reportGridID + '-generate-button',
+ label: i18n['GGBDR6006M'],
+ onClick: function(event) {
+ wok.window.open('plugins/gingerbase/report-add.html');
+ }
+ }, {
+ id: reportGridID + '-rename-button',
+ label: i18n['GGBDR6008M'],
+ disabled: true,
+ onClick: function(event) {
+ var report = reportGrid.getSelected();
+ if(!report) {
+ return;
+ }
+
+ kimchi.selectedReport = report['name'];
+ wok.window.open('plugins/gingerbase/report-rename.html');
+ }
+ }, {
+ id: reportGridID + '-remove-button',
+ label: i18n['GGBDR6009M'],
+ disabled: true,
+ onClick: function(event) {
+ var report = reportGrid.getSelected();
+ if(!report) {
+ return;
+ }
+
+ var settings = {
+ title : i18n['GGBAPI6004M'],
+ content : i18n['GGBDR6001M'],
+ confirm : i18n['GGBAPI6002M'],
+ cancel : i18n['GGBAPI6003M']
+ };
+
+ wok.confirm(settings, function() {
+ kimchi.deleteReport({
+ name: report['name']
+ }, function(result) {
+ listDebugReports();
+ }, function(error) {
+ wok.message.error(error.responseJSON.reason);
+ });
+ });
+ }
+ }, {
+ id: reportGridID + '-download-button',
+ label: i18n['GGBDR6010M'],
+ disabled: true,
+ onClick: function(event) {
+ var report = reportGrid.getSelected();
+ if(!report) {
+ return;
+ }
+
+ kimchi.downloadReport({
+ file: report['uri']
+ });
+ }
+ }],
+ onRowSelected: function(row) {
+ var report = reportGrid.getSelected();
+ // Only enable report buttons if the selected line is not a
+ // pending report
+ if (report['time'] == i18n['GGBDR6007M']) {
+ var gridElement = $('#'+ reportGridID);
+ var row = $('tr:contains(' + report['name'] + ')', gridElement);
+ enableReportButtons(false);
+ row.attr('class', '');
+ }
+ else {
+ enableReportButtons(true);
+ }
+ },
+ frozenFields: [],
+ fields: [{
+ name: 'name',
+ label: i18n['GGBDR6003M'],
+ 'class': 'debug-report-name'
+ }, {
+ name: 'time',
+ label: i18n['GGBDR6005M'],
+ 'class': 'debug-report-time'
+ }],
+ data: reports
+ });
+ };
+
+ var getPendingReports = function() {
+ var reports = []
+ var filter = 'status=running&target_uri=' + encodeURIComponent('^/plugins/gingerbase/debugreports/*')
+
+ kimchi.getTasksByFilter(filter, function(tasks) {
+ for(var i = 0; i < tasks.length; i++) {
+ reportName = tasks[i].target_uri.replace(/^\/plugins\/gingerbase\/debugreports\//, '') || i18n['GGBDR6012M'];
+ reports.push({'name': reportName, 'time': i18n['GGBDR6007M']})
+
+ if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
+ continue;
+ }
+
+ kimchi.trackTask(tasks[i].id, function(result) {
+ wok.topic('kimchi/debugReportAdded').publish();
+ }, function(result) {
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
+ }
+ // Error message from standard kimchi exception
+ else {
+ var errText = result['responseJSON']['reason'];
+ }
+ result && wok.message.error(errText);
+ wok.topic('kimchi/debugReportAdded').publish();
+ }, null);
+ }
+ }, null, true);
+
+ return reports;
+ };
+
+ var listDebugReports = function() {
+ kimchi.listReports(function(reports) {
+ pendingReports = getPendingReports();
+ allReports = pendingReports.concat(reports);
+ $('#debug-report-section').removeClass('hidden');
+
+ // Row selection will be cleared so disable buttons here
+ enableReportButtons(false);
+
+ if(reportGrid) {
+ reportGrid.setData(allReports);
+ }
+ else {
+ initReportGrid(allReports);
+ }
+
+ // Set id-debug-img to pending reports
+ // It will display a loading icon
+ var gridElement = $('#' + reportGridID);
+ $.each($('td:contains(' + i18n['GGBDR6007M'] + ')', gridElement), function(index, row) {
+ $(row).parent().addClass('no-hover');
+ $(row).attr('id', 'id-debug-img');
+ });
+ }, function(error) {
+ if(error['status'] == 403) {
+ $('#debug-report-section').addClass('hidden');
+ return;
+ }
+ $('#debug-report-section').removeClass('hidden');
+ });
+ };
+
+ var shutdownButtonID = '#host-button-shutdown';
+ var restartButtonID = '#host-button-restart';
+ var shutdownHost = function(params) {
+ var settings = {
+ title : i18n['GGBAPI6004M'],
+ content : i18n['GGBHOST6008M'],
+ confirm : i18n['GGBAPI6002M'],
+ cancel : i18n['GGBAPI6003M']
+ };
+
+ wok.confirm(settings, function() {
+ kimchi.shutdown(params);
+ $(shutdownButtonID).prop('disabled', true);
+ $(restartButtonID).prop('disabled', true);
+ // Check if there is any VM is running.
+ // FIXME : Find alternative way to figure out if any vms running
+ // kimchi.listVMs(function(vms) {
+ // for(var i = 0; i < vms.length; i++) {
+ // if(vms[i]['state'] === 'running') {
+ // wok.message.error.code('GGBHOST6001E');
+ // $(shutdownButtonID).prop('disabled', false);
+ // $(restartButtonID).prop('disabled', false);
+ // return;
+ // }
+ // }
+ //
+ // });
+ }, function() {
+ });
+ };
+
+ var initPage = function() {
+ $('#host-info-container .section-header').each(function(i, header) {
+ $('<span class="arrow"></span>').prependTo(header);
+ var toExpand = $(header).attr('aria-expanded') !== 'false';
+ expand(header, toExpand);
+ });
+
+ $('#host-info-container').on('click', '.section-header', function(event) {
+ var toExpand = $(this).attr('aria-expanded') === 'false';
+ expand(this, toExpand);
+ });
+
+ $('#host-button-shutdown').on('click', function(event) {
+ shutdownHost(null);
+ });
+
+ $('#host-button-restart').on('click', function(event) {
+ shutdownHost({
+ reboot: true
+ });
+ });
+
+ var setupUI = function() {
+ if (kimchi.capabilities == undefined) {
+ setTimeout(setupUI, 2000);
+ return;
+ }
+
+ if((kimchi.capabilities['repo_mngt_tool']) && (kimchi.capabilities['repo_mngt_tool']!="None")) {
+ initRepositoriesGrid(kimchi.capabilities['repo_mngt_tool']);
+ $('#repositories-section').switchClass('hidden', kimchi.capabilities['repo_mngt_tool']);
+ wok.topic('kimchi/repositoryAdded')
+ .subscribe(listRepositories);
+ wok.topic('kimchi/repositoryUpdated')
+ .subscribe(listRepositories);
+ wok.topic('kimchi/repositoryDeleted')
+ .subscribe(listRepositories);
+ }
+
+ if(kimchi.capabilities['update_tool']) {
+ $('#software-update-section').removeClass('hidden');
+ initSoftwareUpdatesGrid();
+ wok.topic('kimchi/softwareUpdated')
+ .subscribe(listSoftwareUpdates);
+ $('#software-updates-progress-container').accordion({
+ collapsible: true
+ });
+ }
+
+ if(kimchi.capabilities['system_report_tool']) {
+ listDebugReports();
+ wok.topic('kimchi/debugReportAdded')
+ .subscribe(listDebugReports);
+ wok.topic('kimchi/debugReportRenamed')
+ .subscribe(listDebugReports);
+ }
+ };
+ setupUI();
+ };
+
+ kimchi.getHost(function(data) {
+ var htmlTmpl = $('#host-tmpl').html();
+ data['logo'] = data['logo'] || '';
+ data['memory'] = wok.formatMeasurement(data['memory'], {
+ fixed: 2
+ });
+ var templated = wok.substitute(htmlTmpl, data);
+ $('#host-content-container').html(templated);
+
+ initPage();
+ initTracker();
+ });
+
+ var StatsMgr = function() {
+ var statsArray = {
+ cpu: {
+ u: {
+ type: 'percent',
+ legend: i18n['GGBHOST6002M'],
+ points: []
+ }
+ },
+ memory: {
+ u: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ legend: i18n['GGBHOST6003M'],
+ points: []
+ }
+ },
+ diskIO: {
+ r: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['GGBHOST6004M'],
+ points: []
+ },
+ w: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['GGBHOST6005M'],
+ 'class': 'disk-write',
+ points: []
+ }
+ },
+ networkIO: {
+ r: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['GGBHOST6006M'],
+ points: []
+ },
+ s: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['GGBHOST6007M'],
+ 'class': 'network-sent',
+ points: []
+ }
+ }
+ };
+ var SIZE = 20;
+ var cursor = SIZE;
+
+ var add = function(stats) {
+ for(var key in stats) {
+ var item = stats[key];
+ for(var metrics in item) {
+ var value = item[metrics]['v'];
+ var max = item[metrics]['max'];
+ var unifiedMetrics = statsArray[key][metrics];
+ var ps = unifiedMetrics['points'];
+ if(!Array.isArray(value)){
+ ps.push(value);
+ if(ps.length > SIZE + 1) {
+ ps.shift();
+ }
+ }
+ else{
+ ps=ps.concat(value);
+ ps.splice(0, ps.length-SIZE-1);
+ unifiedMetrics['points']=ps;
+ }
+ if(max !== undefined) {
+ unifiedMetrics['max'] = max;
+ }
+ else {
+ if(unifiedMetrics['type'] !== 'value') {
+ continue;
+ }
+ max = -Infinity;
+ $.each(ps, function(i, value) {
+ if(value > max) {
+ max = value;
+ }
+ });
+ if(max === 0) {
+ ++max;
+ }
+ max *= 1.1;
+ unifiedMetrics['max'] = max;
+ }
+ }
+ }
+ cursor++;
+ };
+
+ var get = function(which) {
+ var stats = statsArray[which];
+ var lines = [];
+ for(var k in stats) {
+ var obj = stats[k];
+ var line = {
+ type: obj['type'],
+ base: obj['base'],
+ unit: obj['unit'],
+ fixed: obj['fixed'],
+ legend: obj['legend']
+ };
+ if(obj['max']) {
+ line['max'] = obj['max'];
+ }
+ if(obj['class']) {
+ line['class'] = obj['class'];
+ }
+ var ps = obj['points'];
+ var numStats = ps.length;
+ var unifiedPoints = [];
+ $.each(ps, function(i, value) {
+ unifiedPoints.push({
+ x: cursor - numStats + i,
+ y: value
+ });
+ });
+ line['points'] = unifiedPoints;
+ lines.push(line);
+ }
+ return lines;
+ };
+
+ return {
+ add: add,
+ get: get
+ };
+ };
+
+ var Tracker = function(charts) {
+ var charts = charts;
+ var timer = null;
+ var statsPool = new StatsMgr();
+ var setCharts = function(newCharts) {
+ charts = newCharts;
+ for(var key in charts) {
+ var chart = charts[key];
+ chart.updateUI(statsPool.get(key));
+ }
+ };
+
+ var self = this;
+
+ var UnifyStats = function(stats) {
+ var result= {
+ cpu: {
+ u: {
+ v: stats['cpu_utilization']
+ }
+ },
+ memory: {
+ u: {
+ }
+ },
+ diskIO: {
+ r: {
+ v: stats['disk_read_rate']
+ },
+ w: {
+ v: stats['disk_write_rate']
+ }
+ },
+ networkIO: {
+ r: {
+ v: stats['net_recv_rate']
+ },
+ s: {
+ v: stats['net_sent_rate']
+ }
+ }
+ };
+ if(Array.isArray(stats['memory'])){
+ result.memory.u['v']=[];
+ result.memory.u['max']=-Infinity;
+ for(var i=0;i<stats['memory'].length;i++){
+ result.memory.u['v'].push(stats['memory'][i]['avail']);
+ result.memory.u['max']=Math.max(result.memory.u['max'],stats['memory'][i]['total']);
+ }
+ }
+ else {
+ result.memory.u['v']=stats['memory']['avail'],
+ result.memory.u['max']=stats['memory']['total']
+ }
+ return(result);
+ };
+
+
+ var statsCallback = function(stats) {
+ var unifiedStats = UnifyStats(stats);
+ statsPool.add(unifiedStats);
+ for(var key in charts) {
+ var chart = charts[key];
+ chart.updateUI(statsPool.get(key));
+ }
+ timer = setTimeout(function() {
+ continueTrack();
+ }, 1000);
+ };
+
+ var track = function() {
+ kimchi.getHostStatsHistory(statsCallback,
+ function() {
+ continueTrack();
+ });
+ };
+
+ var continueTrack = function() {
+ kimchi.getHostStats(statsCallback,
+ function() {
+ continueTrack();
+ });
+ };
+
+ var destroy = function() {
+ timer && clearTimeout(timer);
+ timer = null;
+ };
+
+ return {
+ setCharts: setCharts,
+ start: track,
+ stop: destroy
+ };
+ };
+
+ var initTracker = function() {
+ // TODO: Extend tabs with onUnload event to unregister timers.
+ if(kimchi.hostTimer) {
+ kimchi.hostTimer.stop();
+ delete kimchi.hostTimer;
+ }
+
+ var trackedCharts = {
+ cpu: new kimchi.widget.LineChart({
+ id: 'chart-cpu',
+ node: 'container-chart-cpu',
+ type: 'percent'
+ }),
+ memory: new kimchi.widget.LineChart({
+ id: 'chart-memory',
+ node: 'container-chart-memory',
+ type: 'value'
+ }),
+ diskIO: new kimchi.widget.LineChart({
+ id: 'chart-disk-io',
+ node: 'container-chart-disk-io',
+ type: 'value'
+ }),
+ networkIO: new kimchi.widget.LineChart({
+ id: 'chart-network-io',
+ node: 'container-chart-network-io',
+ type: 'value'
+ })
+ };
+
+ if(kimchi.hostTimer) {
+ kimchi.hostTimer.setCharts(trackedCharts);
+ }
+ else {
+ kimchi.hostTimer = new Tracker(trackedCharts);
+ kimchi.hostTimer.start();
+ }
+ };
+
+ $('#host-root-container').on('remove', function() {
+ if(kimchi.hostTimer) {
+ kimchi.hostTimer.stop();
+ delete kimchi.hostTimer;
+ }
+
+ repositoriesGrid && repositoriesGrid.destroy();
+ wok.topic('kimchi/repositoryAdded')
+ .unsubscribe(listRepositories);
+ wok.topic('kimchi/repositoryUpdated')
+ .unsubscribe(listRepositories);
+ wok.topic('kimchi/repositoryDeleted')
+ .unsubscribe(listRepositories);
+
+ softwareUpdatesGrid && softwareUpdatesGrid.destroy();
+ wok.topic('kimchi/softwareUpdated').unsubscribe(listSoftwareUpdates);
+
+ reportGrid && reportGrid.destroy();
+ wok.topic('kimchi/debugReportAdded').unsubscribe(listDebugReports);
+ wok.topic('kimchi/debugReportRenamed').unsubscribe(listDebugReports);
+ });
+};
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.line-chart.js b/plugins/gingerbase/ui/js/src/gingerbase.line-chart.js
new file mode 100644
index 0000000..13bbee1
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.line-chart.js
@@ -0,0 +1,202 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * new kimchi.widget.LineChart({
+ * node: 'line-chart-cpu',
+ * id: 'line-chart',
+ * type: 'value'
+ * });
+ */
+kimchi.widget.LineChart = function(params) {
+ var container = $('#' + params['node']);
+ container.addClass('chart-container');
+ var height = container.height();
+ var width = container.width();
+ var numHLines = 4;
+ var linesSpace = height / numHLines;
+ var period = params['period'] || 20;
+ var xFactor = width / period;
+ var yFactor = height / 100;
+ var xStart = params['xStart'] || 0;
+ var linesOffset = 0;
+ var canvasID = params['id'];
+ var maxValue = params['maxValue'] || -Infinity;
+ var type = params['type'];
+ var chartVAxis = null;
+ var chartTitle = null;
+ var chartLegend = null;
+ var seriesMap = {};
+ var formatSettings = {};
+
+ var setMaxValue = function(newValue) {
+ maxValue = newValue;
+ };
+
+ /**
+ *
+ * settings: {
+ * 'class': 'disk-read-rate'
+ * }
+ */
+ var updateUI = function(data) {
+ var container = $('#' + params['node']);
+ if(!container.length) {
+ return;
+ }
+
+ if(!$.isArray(data)) {
+ data = [data];
+ }
+ var seriesCount = 0;
+ var singleSeries = data.length === 1;
+ var firstSeries = data[0];
+
+ // TODO: Multiple axes support.
+ if(type === 'value') {
+ $.each(data, function(i, series) {
+ if(series['max'] > maxValue) {
+ maxValue = series['max'];
+ formatSettings = {
+ base: series['base'],
+ unit: series['unit'],
+ fixed: series['fixed']
+ };
+ }
+ });
+ }
+
+ var canvasNode = $('#' + canvasID);
+ canvasNode.length && canvasNode.remove();
+ var htmlStr = [
+ '<svg id="', canvasID, '" class="line-chart"',
+ ' height="', height, '" width="', width, '"',
+ '>',
+ '<rect height="', height, '" width="', width, '" class="background" />'
+ ];
+
+ for(var x = linesOffset; x < width; x += linesSpace) {
+ htmlStr.push(
+ '<line x1="', x, '" y1="', 0, '" x2="', x, '" y2="', height, '" />'
+ );
+ }
+
+ linesOffset -= xFactor;
+ while(linesOffset < 0) {
+ linesOffset = linesSpace + linesOffset;
+ }
+
+ for(var y = height - linesSpace; y > 0; y -= linesSpace) {
+ htmlStr.push(
+ '<line x1="', 0, '" y1="', y, '" x2="', width, '" y2="', y, '" />'
+ );
+ }
+
+ var maxValueLabel = i18n['GGBHOST6001M'] + ' ' +
+ (type === 'value'
+ ? wok.formatMeasurement(maxValue, formatSettings)
+ : '100%');
+ if(!chartVAxis) {
+ chartVAxis = $('<div class="chart-vaxis-container">' +
+ maxValueLabel +
+ '</div>'
+ );
+ container.before(chartVAxis);
+ }
+ else {
+ chartVAxis.text(maxValueLabel);
+ }
+
+ seriesNames = [];
+ $.each(data, function(i, series) {
+ var points = series['points'];
+ var className = series['class'];
+ var latestPoint = points.slice(-1).pop();
+ xStart = latestPoint['x'] - period;
+
+ htmlStr.push('<polyline',
+ ' class="series', className ? ' ' + className : '', '"',
+ ' points="'
+ );
+ var first = true;
+ $.each(points, function(i, point) {
+ if(first) {
+ first = false;
+ }
+ else {
+ htmlStr.push(' ');
+ }
+
+ var x = xFactor * (point['x'] - xStart);
+ var y = height - yFactor * (type === 'value' ?
+ point['y'] * 100 / maxValue :
+ point['y']
+ );
+ htmlStr.push(x, ',', y);
+ });
+ htmlStr.push('" />');
+ });
+
+ htmlStr.push('</svg>');
+
+ var canvasNode = $(htmlStr.join('')).appendTo(container);
+
+ if(!chartLegend) {
+ chartLegend = $('<div class="chart-legend-container"></div>');
+ container.after(chartLegend);
+ }
+ else {
+ chartLegend.empty();
+ }
+ $('polyline.series', canvasNode).each(function(i, polyline) {
+ var wrapper = $('<div class="legend-wrapper"></div>')
+ .appendTo(chartLegend);
+ $([
+ '<svg class="legend-icon" width="20" height="10">',
+ '<line x1="0" y1="5" x2="20" y2="5"/>',
+ '</svg>'
+ ].join('')).appendTo(wrapper);
+ $('line', wrapper).css({
+ stroke: $(polyline).css('stroke'),
+ 'stroke-width': $(polyline).css('stroke-width')
+ });
+ var label = data[i]['legend'];
+ var base = data[i]['base'];
+ $('<label class="legend-label">' + label + '</label>')
+ .appendTo(wrapper);
+ var latestPoint = data[i]['points'].slice(-1).pop();
+ var latestValue = latestPoint['y'];
+ if(type === 'value') {
+ latestValue = wok.formatMeasurement(
+ latestValue,
+ formatSettings
+ );
+ }
+ else {
+ latestValue += '%';
+ }
+ $('<div class="latest-value">' + latestValue + '</div>')
+ .appendTo(wrapper);
+ });
+ };
+
+ return {
+ setMaxValue: setMaxValue,
+ updateUI: updateUI
+ }
+};
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.main.js b/plugins/gingerbase/ui/js/src/gingerbase.main.js
new file mode 100644
index 0000000..2fdeb85
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.main.js
@@ -0,0 +1,26 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+kimchi.capabilities = undefined;
+kimchi.getCapabilities(function(result) {
+ kimchi.capabilities = result;
+
+ if(kimchi.capabilities.federation=="on")
+ $('#peers').removeClass('hide-content');
+}, function() {
+ kimchi.capabilities = {};
+});
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.report_add_main.js b/plugins/gingerbase/ui/js/src/gingerbase.report_add_main.js
new file mode 100644
index 0000000..87010b1
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.report_add_main.js
@@ -0,0 +1,72 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+kimchi.report_add_main = function() {
+ var reportGridID = 'available-reports-grid';
+ var addReportForm = $('#form-report-add');
+ var submitButton = $('#button-report-add');
+ var nameTextbox = $('input[name="name"]', addReportForm);
+ nameTextbox.select();
+
+ var submitForm = function(event) {
+ if(submitButton.prop('disabled')) {
+ return false;
+ }
+ var reportName = nameTextbox.val();
+ var validator = RegExp("^[_A-Za-z0-9-]*$");
+ if (!validator.test(reportName)) {
+ wok.message.error.code('GGBDR6011M');
+ return false;
+ }
+ var formData = addReportForm.serializeObject();
+ var taskAccepted = false;
+ var onTaskAccepted = function() {
+ if(taskAccepted) {
+ return;
+ }
+ taskAccepted = true;
+ wok.window.close();
+ wok.topic('kimchi/debugReportAdded').publish();
+ };
+
+ kimchi.createReport(formData, function(result) {
+ onTaskAccepted();
+ wok.topic('kimchi/debugReportAdded').publish();
+ }, function(result) {
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
+ }
+ // Error message from standard kimchi exception
+ else {
+ var errText = result['responseJSON']['reason'];
+ }
+ result && wok.message.error(errText);
+
+ taskAccepted &&
+ $('.grid-body-view table tr:first-child',
+ '#' + reportGridID).remove();
+ submitButton.prop('disabled', false);
+ nameTextbox.select();
+ }, onTaskAccepted);
+
+ event.preventDefault();
+ };
+
+ addReportForm.on('submit', submitForm);
+ submitButton.on('click', submitForm);
+};
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.report_rename_main.js b/plugins/gingerbase/ui/js/src/gingerbase.report_rename_main.js
new file mode 100644
index 0000000..6134b2e
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.report_rename_main.js
@@ -0,0 +1,66 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+kimchi.report_rename_main = function() {
+ var renameReportForm = $('#form-report-rename');
+ var submitButton = $('#button-report-rename');
+ var nameTextbox = $('input[name="name"]', renameReportForm);
+ var submitForm = function(event) {
+ if(submitButton.prop('disabled')) {
+ return false;
+ }
+ var reportName = nameTextbox.val();
+
+ // if the user hasn't changed the report's name,
+ // nothing should be done.
+ if (reportName == kimchi.selectedReport) {
+ wok.message.error.code('GGBDR6013M');
+ return false;
+ }
+
+ var validator = RegExp("^[A-Za-z0-9-]*$");
+ if (!validator.test(reportName)) {
+ wok.message.error.code('GGBDR6011M');
+ return false;
+ }
+ var formData = renameReportForm.serializeObject();
+ submitButton.prop('disabled', true);
+ nameTextbox.prop('disabled', true);
+ kimchi.renameReport(kimchi.selectedReport, formData, function(result) {
+ submitButton.prop('disabled', false);
+ nameTextbox.prop('disabled', false);
+ wok.window.close();
+ wok.topic('kimchi/debugReportRenamed').publish({
+ result: result
+ });
+ }, function(result) {
+ var errText = result &&
+ result['responseJSON'] &&
+ result['responseJSON']['reason'];
+ wok.message.error(errText);
+ submitButton.prop('disabled', false);
+ nameTextbox.prop('disabled', false).focus();
+ });
+
+ event.preventDefault();
+ };
+
+ renameReportForm.on('submit', submitForm);
+ submitButton.on('click', submitForm);
+
+ nameTextbox.val(kimchi.selectedReport).select();
+};
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.repository_add_main.js b/plugins/gingerbase/ui/js/src/gingerbase.repository_add_main.js
new file mode 100644
index 0000000..656306b
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.repository_add_main.js
@@ -0,0 +1,96 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+kimchi.repository_add_main = function() {
+
+ var addForm = $('#form-repository-add');
+ var addButton = $('#button-repository-add');
+
+ var validateField = function(event) {
+ var valid=($(this).val()!=='');
+ $(addButton).prop('disabled', !valid);
+ return(valid);
+ };
+
+ var validateForm = function(event) {
+ var valid=false;
+ addForm.find('input.required').each( function() {
+ valid=($(this).val()!=='');
+ return(!valid);
+ });
+ return(valid);
+ }
+
+ addForm.find('input.required').on('input propertychange', validateField);
+
+ var weedObject = function(obj) {
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ if((typeof(obj[key])==="object") && !Array.isArray(obj[key])) {
+ weedObject(obj[key]);
+ }
+ else if(obj[key] == '') {
+ delete obj[key];
+ }
+ }
+ }
+ }
+
+ var addRepository = function(event) {
+ var valid = validateForm();
+ if(!valid) {
+ return false;
+ }
+
+ var formData = $(addForm).serializeObject();
+
+ if (formData && formData.isMirror!=undefined) {
+ formData.isMirror=(String(formData.isMirror).toLowerCase() === 'true');
+ }
+ if(formData.isMirror) {
+ if(formData.config==undefined) {
+ formData.config=new Object();
+ }
+ formData.config.mirrorlist=formData.baseurl;
+ delete formData.baseurl;
+ delete formData.isMirror;
+ }
+ weedObject(formData);
+ if(formData.config && formData.config.comps) {
+ formData.config.comps=formData.config.comps.split(/[,\s]/);
+ for(var i=0; i>formData.config.comps.length; i++) {
+ formData.config.comps[i]=formData.config.comps[i].trim();
+ }
+ for (var j=formData.config.comps.indexOf(""); j!=-1; j=formData.config.comps.indexOf("")) {
+ formData.config.comps.splice(j, 1);
+ }
+ }
+
+ kimchi.createRepository(formData, function() {
+ wok.topic('kimchi/repositoryAdded').publish();
+ wok.window.close();
+ }, function(jqXHR, textStatus, errorThrown) {
+ var reason = jqXHR &&
+ jqXHR['responseJSON'] &&
+ jqXHR['responseJSON']['reason'];
+ wok.message.error(reason);
+ });
+ return false;
+ };
+
+ $(addForm).on('submit', addRepository);
+};
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.repository_edit_main.js b/plugins/gingerbase/ui/js/src/gingerbase.repository_edit_main.js
new file mode 100644
index 0000000..5bfc51e
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.repository_edit_main.js
@@ -0,0 +1,74 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+kimchi.repository_edit_main = function() {
+
+ var editForm = $('#form-repository-edit');
+
+ var saveButton = $('#repository-edit-button-save');
+
+ if(kimchi.capabilities['repo_mngt_tool']=="yum") {
+ editForm.find('input.deb').prop('disabled', true);
+ }
+ else if(kimchi.capabilities['repo_mngt_tool']=="deb") {
+ editForm.find('input.yum').prop('disabled', true);
+ }
+
+ kimchi.retrieveRepository(kimchi.selectedRepository, function(repository) {
+ editForm.fillWithObject(repository);
+
+ $('input', editForm).on('input propertychange', function(event) {
+ if($(this).val() !== '') {
+ $(saveButton).prop('disabled', false);
+ }
+ });
+ });
+
+
+ var editRepository = function(event) {
+ var formData = $(editForm).serializeObject();
+
+ if (formData && formData.config) {
+ formData.config.gpgcheck=(String(formData.config.gpgcheck).toLowerCase() === 'true');
+ }
+
+ if(formData.config && formData.config.comps) {
+ formData.config.comps=formData.config.comps.split(/[,\s]/);
+ for(var i=0; i>formData.config.comps.length; i++) {
+ formData.config.comps[i]=formData.config.comps[i].trim();
+ }
+ for (var j=formData.config.comps.indexOf(""); j!=-1; j=formData.config.comps.indexOf("")) {
+ formData.config.comps.splice(j, 1);
+ }
+ }
+
+ kimchi.updateRepository(kimchi.selectedRepository, formData, function() {
+ wok.topic('kimchi/repositoryUpdated').publish();
+ wok.window.close();
+ }, function(jqXHR, textStatus, errorThrown) {
+ var reason = jqXHR &&
+ jqXHR['responseJSON'] &&
+ jqXHR['responseJSON']['reason'];
+ wok.message.error(reason);
+ });
+
+ return false;
+ };
+
+ $(editForm).on('submit', editRepository);
+ $(saveButton).on('click', editRepository);
+};
diff --git a/plugins/gingerbase/ui/js/src/gingerbase.select.js b/plugins/gingerbase/ui/js/src/gingerbase.select.js
new file mode 100644
index 0000000..751167f
--- /dev/null
+++ b/plugins/gingerbase/ui/js/src/gingerbase.select.js
@@ -0,0 +1,50 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+kimchi.select = function(id, options) {
+ var listControl = $('#'+ id);
+ var targetId = listControl.data('target');
+ var labelId = listControl.data('label');
+ var value = $('#' + targetId).val();
+ var item;
+ var itemTag = 'li';
+ var selectedClass = 'active';
+ $.each(options, function(index, option) {
+ item = $('<' + itemTag + '></' + itemTag + '>');
+ item.text(option.label);
+ item.data('value', option.value);
+ if(option.value === value) {
+ item.addClass(selectedClass);
+ $('#' + labelId).text(option.label);
+ }
+ listControl.append(item);
+ });
+
+ listControl.on('click', itemTag, function() {
+ listControl.children().removeClass(selectedClass);
+ $(this).addClass(selectedClass);
+ $('#' + labelId).text($(this).text());
+ var target = $('#' + targetId);
+ var oldValue = target.val();
+ var newValue = $(this).data('value');
+ target.val(newValue);
+ if(oldValue !== newValue) {
+ target.change();
+ }
+ });
+};
diff --git a/plugins/gingerbase/ui/js/widgets/circleGauge.js b/plugins/gingerbase/ui/js/widgets/circleGauge.js
new file mode 100644
index 0000000..32973ac
--- /dev/null
+++ b/plugins/gingerbase/ui/js/widgets/circleGauge.js
@@ -0,0 +1,100 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ (function($) {
+ $.widget('kimchi.circleGauge', {
+
+ options : {
+ color : '#87C004',
+ fillColor : '#87C004',
+ lineWidth : 20,
+ shadowSize : '2px',
+ font : 'bold 13px Geneva, sans-serif',
+ textAlign : 'center',
+ radius : 35,
+ peakRate : 100,
+ display : 0,
+ circle : 0,
+ label : ''
+ },
+
+ _create : function() {
+ //valuesAttr="{" + this.element.data('value')+ "}";
+ //console.info(valuesAttr);
+ //values=eval("(" + valuesAttr + ")");
+ //$.extend(this.options, values);
+ this.options.display=this.element.data('display');
+ this.options.percentage=this.element.data('percentage');
+ this._fixupPeakRate();
+ this._draw();
+ },
+
+ setValues : function(values) {
+ $.extend(this.options, values);
+ this._fixupPeakRate();
+ this._draw();
+ },
+
+ _fixupPeakRate : function() {
+ if (this.options.circle>this.options.peakRate) {
+ this.options.peakRate=this.options.circle;
+ }
+ },
+
+ _draw : function() {
+ this.element.empty();
+ var canvas = document.createElement('canvas');
+ //this.element.append($(canvas)); //I don't quite understand this line so trying the one below...
+ this.element.append(canvas);
+
+ var ctx = canvas.getContext('2d');
+ var radius = this.options.radius;
+
+ var shadowSize = 2;
+ var width = height = radius * 2;
+ $(canvas).attr('height', height);
+ $(canvas).attr('width', width);
+
+ $(canvas).css({
+ 'boxShadow' : shadowSize + 'px ' + shadowSize + 'px ' + shadowSize + 'px #fff, -' + shadowSize + 'px -' + shadowSize + 'px ' + shadowSize + 'px #eaeaea',
+ borderRadius : radius + 'px'
+ });
+
+ ctx.clearRect(0, 0, width, height);
+ ctx.fillStyle = this.options.fillColor;
+ ctx.font = this.options.font;
+ ctx.textAlign = 'center';
+ var originPos = radius;
+ ctx.textBaseline = 'middle';
+ ctx.fillText(this.options.display, originPos, originPos);
+ ctx.strokeStyle = this.options.color;
+ ctx.lineWidth = this.options.lineWidth;
+ ctx.beginPath();
+ ctx.arc(originPos, originPos, radius, -.5 * Math.PI, (this.options.percentage / 50 - .5) * Math.PI);
+ ctx.stroke();
+ },
+
+ destroy : function() {
+ this.element.empty();
+ $.Widget.prototype.destroy.call(this);
+ }
+ });
+}(jQuery));
+
+kimchi.circleGauge = function(selector) {
+ $(selector).circleGauge();
+};
diff --git a/plugins/kimchi/ui/js/src/kimchi.host.js b/plugins/kimchi/ui/js/src/kimchi.host.js
deleted file mode 100644
index ab02333..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.host.js
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-kimchi.host={};
-
-kimchi.host_main = function() {
- var expand = function(header, toExpand) {
- var controlledNode = $(header).attr('aria-controls');
- $('#' + controlledNode)[toExpand ? 'removeClass' : 'addClass']('hidden');
- $(header).attr('aria-expanded', toExpand ? 'true' : 'false');
- };
-
- var repositoriesGrid = null;
- var initRepositoriesGrid = function(repo_type) {
- var gridFields=[];
- if (repo_type == "yum") {
- gridFields=[{
- name: 'repo_id',
- label: i18n['KCHREPO6004M'],
- 'class': 'repository-id'
- }, {
- name: 'config[repo_name]',
- label: i18n['KCHREPO6005M'],
- 'class': 'repository-name'
- }, {
- name: 'enabled',
- label: i18n['KCHREPO6009M'],
- 'class': 'repository-enabled'
- }];
- }
- else if (repo_type == "deb") {
- gridFields=[{
- name: 'baseurl',
- label: i18n['KCHREPO6006M'],
- makeTitle: true,
- 'class': 'repository-baseurl deb'
- }, {
- name: 'enabled',
- label: i18n['KCHREPO6009M'],
- 'class': 'repository-enabled deb'
- }, {
- name: 'config[dist]',
- label: "dist",
- 'class': 'repository-gpgcheck deb'
- }, {
- name: 'config[comps]',
- label: "comps",
- 'class': 'repository-gpgcheck deb'
- }];
- }
- else {
- gridFields=[{
- name: 'repo_id',
- label: i18n['KCHREPO6004M'],
- 'class': 'repository-id'
- }, {
- name: 'enabled',
- label: i18n['KCHREPO6009M'],
- 'class': 'repository-enabled'
- }, {
- name: 'baseurl',
- label: i18n['KCHREPO6006M'],
- makeTitle: true,
- 'class': 'repository-baseurl'
- }];
- }
- repositoriesGrid = new kimchi.widget.Grid({
- container: 'repositories-grid-container',
- id: 'repositories-grid',
- title: i18n['KCHREPO6003M'],
- toolbarButtons: [{
- id: 'repositories-grid-add-button',
- label: i18n['KCHREPO6012M'],
- onClick: function(event) {
- wok.window.open({url:'plugins/kimchi/repository-add.html',
- class: repo_type});
- }
- }, {
- id: 'repositories-grid-enable-button',
- label: i18n['KCHREPO6016M'],
- disabled: true,
- onClick: function(event) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
- var name = repository['repo_id'];
- var enable = !repository['enabled'];
- $(this).prop('disabled', true);
- kimchi.enableRepository(name, enable, function() {
- wok.topic('kimchi/repositoryUpdated').publish();
- });
- }
- }, {
- id: 'repositories-grid-edit-button',
- label: i18n['KCHREPO6013M'],
- disabled: true,
- onClick: function(event) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
- kimchi.selectedRepository = repository['repo_id'];
- wok.window.open({url:'plugins/kimchi/repository-edit.html',
- class: repo_type});
- }
- }, {
- id: 'repositories-grid-remove-button',
- label: i18n['KCHREPO6014M'],
- disabled: true,
- onClick: function(event) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
-
- var settings = {
- title : i18n['KCHREPO6001M'],
- content : i18n['KCHREPO6002M'],
- confirm : i18n['KCHAPI6004M'],
- cancel : i18n['KCHAPI6003M']
- };
-
- wok.confirm(settings, function() {
- kimchi.deleteRepository(
- repository['repo_id'],
- function(result) {
- wok.topic('kimchi/repositoryDeleted').publish(result);
- }, function(error) {
- }
- );
- });
- }
- }],
- onRowSelected: function(row) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
- $('#repositories-grid-remove-button').prop('disabled', false);
- $('#repositories-grid-edit-button').prop('disabled', false);
- var enabled = repository['enabled'];
- $('#repositories-grid-enable-button')
- .text(i18n[enabled ? 'KCHREPO6017M' : 'KCHREPO6016M'])
- .prop('disabled', false);
- },
- frozenFields: [],
- fields: gridFields,
- data: listRepositories
- });
- };
-
- var listRepositories = function(gridCallback) {
- kimchi.listRepositories(function(repositories) {
- if($.isFunction(gridCallback)) {
- gridCallback(repositories);
- }
- else {
- if(repositoriesGrid) {
- repositoriesGrid.setData(repositories);
- }
- else {
- initRepositoriesGrid();
- repositoriesGrid.setData(repositories);
- }
- }
- },
- function(error) {
- var message = error && error['responseJSON'] && error['responseJSON']['reason'];
-
- if($.isFunction(gridCallback)) {
- gridCallback([]);
- }
- repositoriesGrid &&
- repositoriesGrid.showMessage(message || i18n['KCHUPD6008M']);
- });
-
- $('#repositories-grid-remove-button').prop('disabled', true);
- $('#repositories-grid-edit-button').prop('disabled', true);
- $('#repositories-grid-enable-button').prop('disabled', true);
- };
-
- 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('');
- !wok.isElementInViewport(progressArea) &&
- progressArea.scrollIntoView();
- $(updateButton).text(i18n['KCHUPD6007M']).prop('disabled', true);
-
- kimchi.updateSoftware(function(result) {
- reloadProgressArea(result);
- $(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
- wok.topic('kimchi/softwareUpdated').publish({
- result: result
- });
- }, function(error) {
- var message = error && error['responseJSON'] && error['responseJSON']['reason'];
- wok.message.error(message || i18n['KCHUPD6009M']);
- $(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
- }, reloadProgressArea);
- }
- }],
- frozenFields: [],
- 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: listSoftwareUpdates
- });
- };
-
- var listSoftwareUpdates = function(gridCallback) {
- kimchi.listSoftwareUpdates(function(softwareUpdates) {
- if($.isFunction(gridCallback)) {
- gridCallback(softwareUpdates);
- }
- else {
- if(softwareUpdatesGrid) {
- softwareUpdatesGrid.setData(softwareUpdates);
- }
- else {
- initSoftwareUpdatesGrid(softwareUpdates);
- }
- }
-
- var updateButton = $('#' + softwareUpdatesGridID + '-update-button');
- $(updateButton).prop('disabled', softwareUpdates.length === 0);
- }, function(error) {
- var message = error && error['responseJSON'] && error['responseJSON']['reason'];
- if($.isFunction(gridCallback)) {
- gridCallback([]);
- }
- softwareUpdatesGrid &&
- softwareUpdatesGrid.showMessage(message || i18n['KCHUPD6008M']);
- });
- };
-
- var reportGridID = 'available-reports-grid';
- var reportGrid = null;
- var enableReportButtons = function(toEnable) {
- var buttonID = '#{grid}-{btn}-button';
- $.each(['rename', 'remove', 'download'], function(i, n) {
- $(wok.substitute(buttonID, {
- grid: reportGridID,
- btn: n
- })).prop('disabled', !toEnable);
- });
- };
- var initReportGrid = function(reports) {
- reportGrid = new kimchi.widget.Grid({
- container: 'available-reports-grid-container',
- id: reportGridID,
- title: i18n['KCHDR6002M'],
- toolbarButtons: [{
- id: reportGridID + '-generate-button',
- label: i18n['KCHDR6006M'],
- onClick: function(event) {
- wok.window.open('plugins/kimchi/report-add.html');
- }
- }, {
- id: reportGridID + '-rename-button',
- label: i18n['KCHDR6008M'],
- disabled: true,
- onClick: function(event) {
- var report = reportGrid.getSelected();
- if(!report) {
- return;
- }
-
- kimchi.selectedReport = report['name'];
- wok.window.open('plugins/kimchi/report-rename.html');
- }
- }, {
- id: reportGridID + '-remove-button',
- label: i18n['KCHDR6009M'],
- disabled: true,
- onClick: function(event) {
- var report = reportGrid.getSelected();
- if(!report) {
- return;
- }
-
- var settings = {
- title : i18n['KCHAPI6004M'],
- content : i18n['KCHDR6001M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
-
- wok.confirm(settings, function() {
- kimchi.deleteReport({
- name: report['name']
- }, function(result) {
- listDebugReports();
- }, function(error) {
- wok.message.error(error.responseJSON.reason);
- });
- });
- }
- }, {
- id: reportGridID + '-download-button',
- label: i18n['KCHDR6010M'],
- disabled: true,
- onClick: function(event) {
- var report = reportGrid.getSelected();
- if(!report) {
- return;
- }
-
- kimchi.downloadReport({
- file: report['uri']
- });
- }
- }],
- onRowSelected: function(row) {
- var report = reportGrid.getSelected();
- // Only enable report buttons if the selected line is not a
- // pending report
- if (report['time'] == i18n['KCHDR6007M']) {
- var gridElement = $('#'+ reportGridID);
- var row = $('tr:contains(' + report['name'] + ')', gridElement);
- enableReportButtons(false);
- row.attr('class', '');
- }
- else {
- enableReportButtons(true);
- }
- },
- frozenFields: [],
- fields: [{
- name: 'name',
- label: i18n['KCHDR6003M'],
- 'class': 'debug-report-name'
- }, {
- name: 'time',
- label: i18n['KCHDR6005M'],
- 'class': 'debug-report-time'
- }],
- data: reports
- });
- };
-
- var getPendingReports = function() {
- var reports = []
- var filter = 'status=running&target_uri=' + encodeURIComponent('^/plugins/kimchi/debugreports/*')
-
- kimchi.getTasksByFilter(filter, function(tasks) {
- for(var i = 0; i < tasks.length; i++) {
- reportName = tasks[i].target_uri.replace(/^\/plugins\/kimchi\/debugreports\//, '') || i18n['KCHDR6012M'];
- reports.push({'name': reportName, 'time': i18n['KCHDR6007M']})
-
- if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
- continue;
- }
-
- kimchi.trackTask(tasks[i].id, function(result) {
- wok.topic('kimchi/debugReportAdded').publish();
- }, function(result) {
- // Error message from Async Task status
- if (result['message']) {
- var errText = result['message'];
- }
- // Error message from standard kimchi exception
- else {
- var errText = result['responseJSON']['reason'];
- }
- result && wok.message.error(errText);
- wok.topic('kimchi/debugReportAdded').publish();
- }, null);
- }
- }, null, true);
-
- return reports;
- };
-
- var listDebugReports = function() {
- kimchi.listReports(function(reports) {
- pendingReports = getPendingReports();
- allReports = pendingReports.concat(reports);
- $('#debug-report-section').removeClass('hidden');
-
- // Row selection will be cleared so disable buttons here
- enableReportButtons(false);
-
- if(reportGrid) {
- reportGrid.setData(allReports);
- }
- else {
- initReportGrid(allReports);
- }
-
- // Set id-debug-img to pending reports
- // It will display a loading icon
- var gridElement = $('#' + reportGridID);
- $.each($('td:contains(' + i18n['KCHDR6007M'] + ')', gridElement), function(index, row) {
- $(row).parent().addClass('no-hover');
- $(row).attr('id', 'id-debug-img');
- });
- }, function(error) {
- if(error['status'] == 403) {
- $('#debug-report-section').addClass('hidden');
- return;
- }
- $('#debug-report-section').removeClass('hidden');
- });
- };
-
- var shutdownButtonID = '#host-button-shutdown';
- var restartButtonID = '#host-button-restart';
- var shutdownHost = function(params) {
- var settings = {
- title : i18n['KCHAPI6004M'],
- content : i18n['KCHHOST6008M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
-
- wok.confirm(settings, function() {
- kimchi.shutdown(params);
- $(shutdownButtonID).prop('disabled', true);
- $(restartButtonID).prop('disabled', true);
- // Check if there is any VM is running.
- kimchi.listVMs(function(vms) {
- for(var i = 0; i < vms.length; i++) {
- if(vms[i]['state'] === 'running') {
- wok.message.error.code('KCHHOST6001E');
- $(shutdownButtonID).prop('disabled', false);
- $(restartButtonID).prop('disabled', false);
- return;
- }
- }
-
- });
- }, function() {
- });
- };
-
- var initPage = function() {
- $('#host-info-container .section-header').each(function(i, header) {
- $('<span class="arrow"></span>').prependTo(header);
- var toExpand = $(header).attr('aria-expanded') !== 'false';
- expand(header, toExpand);
- });
-
- $('#host-info-container').on('click', '.section-header', function(event) {
- var toExpand = $(this).attr('aria-expanded') === 'false';
- expand(this, toExpand);
- });
-
- $('#host-button-shutdown').on('click', function(event) {
- shutdownHost(null);
- });
-
- $('#host-button-restart').on('click', function(event) {
- shutdownHost({
- reboot: true
- });
- });
-
- var setupUI = function() {
- if (kimchi.capabilities == undefined) {
- setTimeout(setupUI, 2000);
- return;
- }
-
- if((kimchi.capabilities['repo_mngt_tool']) && (kimchi.capabilities['repo_mngt_tool']!="None")) {
- initRepositoriesGrid(kimchi.capabilities['repo_mngt_tool']);
- $('#repositories-section').switchClass('hidden', kimchi.capabilities['repo_mngt_tool']);
- wok.topic('kimchi/repositoryAdded')
- .subscribe(listRepositories);
- wok.topic('kimchi/repositoryUpdated')
- .subscribe(listRepositories);
- wok.topic('kimchi/repositoryDeleted')
- .subscribe(listRepositories);
- }
-
- if(kimchi.capabilities['update_tool']) {
- $('#software-update-section').removeClass('hidden');
- initSoftwareUpdatesGrid();
- wok.topic('kimchi/softwareUpdated')
- .subscribe(listSoftwareUpdates);
- $('#software-updates-progress-container').accordion({
- collapsible: true
- });
- }
-
- if(kimchi.capabilities['system_report_tool']) {
- listDebugReports();
- wok.topic('kimchi/debugReportAdded')
- .subscribe(listDebugReports);
- wok.topic('kimchi/debugReportRenamed')
- .subscribe(listDebugReports);
- }
- };
- setupUI();
- };
-
- kimchi.getHost(function(data) {
- var htmlTmpl = $('#host-tmpl').html();
- data['logo'] = data['logo'] || '';
- data['memory'] = wok.formatMeasurement(data['memory'], {
- fixed: 2
- });
- var templated = wok.substitute(htmlTmpl, data);
- $('#host-content-container').html(templated);
-
- initPage();
- initTracker();
- });
-
- var StatsMgr = function() {
- var statsArray = {
- cpu: {
- u: {
- type: 'percent',
- legend: i18n['KCHHOST6002M'],
- points: []
- }
- },
- memory: {
- u: {
- type: 'value',
- base: 2,
- fixed: 2,
- legend: i18n['KCHHOST6003M'],
- points: []
- }
- },
- diskIO: {
- r: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6004M'],
- points: []
- },
- w: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6005M'],
- 'class': 'disk-write',
- points: []
- }
- },
- networkIO: {
- r: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6006M'],
- points: []
- },
- s: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6007M'],
- 'class': 'network-sent',
- points: []
- }
- }
- };
- var SIZE = 20;
- var cursor = SIZE;
-
- var add = function(stats) {
- for(var key in stats) {
- var item = stats[key];
- for(var metrics in item) {
- var value = item[metrics]['v'];
- var max = item[metrics]['max'];
- var unifiedMetrics = statsArray[key][metrics];
- var ps = unifiedMetrics['points'];
- if(!Array.isArray(value)){
- ps.push(value);
- if(ps.length > SIZE + 1) {
- ps.shift();
- }
- }
- else{
- ps=ps.concat(value);
- ps.splice(0, ps.length-SIZE-1);
- unifiedMetrics['points']=ps;
- }
- if(max !== undefined) {
- unifiedMetrics['max'] = max;
- }
- else {
- if(unifiedMetrics['type'] !== 'value') {
- continue;
- }
- max = -Infinity;
- $.each(ps, function(i, value) {
- if(value > max) {
- max = value;
- }
- });
- if(max === 0) {
- ++max;
- }
- max *= 1.1;
- unifiedMetrics['max'] = max;
- }
- }
- }
- cursor++;
- };
-
- var get = function(which) {
- var stats = statsArray[which];
- var lines = [];
- for(var k in stats) {
- var obj = stats[k];
- var line = {
- type: obj['type'],
- base: obj['base'],
- unit: obj['unit'],
- fixed: obj['fixed'],
- legend: obj['legend']
- };
- if(obj['max']) {
- line['max'] = obj['max'];
- }
- if(obj['class']) {
- line['class'] = obj['class'];
- }
- var ps = obj['points'];
- var numStats = ps.length;
- var unifiedPoints = [];
- $.each(ps, function(i, value) {
- unifiedPoints.push({
- x: cursor - numStats + i,
- y: value
- });
- });
- line['points'] = unifiedPoints;
- lines.push(line);
- }
- return lines;
- };
-
- return {
- add: add,
- get: get
- };
- };
-
- var Tracker = function(charts) {
- var charts = charts;
- var timer = null;
- var statsPool = new StatsMgr();
- var setCharts = function(newCharts) {
- charts = newCharts;
- for(var key in charts) {
- var chart = charts[key];
- chart.updateUI(statsPool.get(key));
- }
- };
-
- var self = this;
-
- var UnifyStats = function(stats) {
- var result= {
- cpu: {
- u: {
- v: stats['cpu_utilization']
- }
- },
- memory: {
- u: {
- }
- },
- diskIO: {
- r: {
- v: stats['disk_read_rate']
- },
- w: {
- v: stats['disk_write_rate']
- }
- },
- networkIO: {
- r: {
- v: stats['net_recv_rate']
- },
- s: {
- v: stats['net_sent_rate']
- }
- }
- };
- if(Array.isArray(stats['memory'])){
- result.memory.u['v']=[];
- result.memory.u['max']=-Infinity;
- for(var i=0;i<stats['memory'].length;i++){
- result.memory.u['v'].push(stats['memory'][i]['avail']);
- result.memory.u['max']=Math.max(result.memory.u['max'],stats['memory'][i]['total']);
- }
- }
- else {
- result.memory.u['v']=stats['memory']['avail'],
- result.memory.u['max']=stats['memory']['total']
- }
- return(result);
- };
-
-
- var statsCallback = function(stats) {
- var unifiedStats = UnifyStats(stats);
- statsPool.add(unifiedStats);
- for(var key in charts) {
- var chart = charts[key];
- chart.updateUI(statsPool.get(key));
- }
- timer = setTimeout(function() {
- continueTrack();
- }, 1000);
- };
-
- var track = function() {
- kimchi.getHostStatsHistory(statsCallback,
- function() {
- continueTrack();
- });
- };
-
- var continueTrack = function() {
- kimchi.getHostStats(statsCallback,
- function() {
- continueTrack();
- });
- };
-
- var destroy = function() {
- timer && clearTimeout(timer);
- timer = null;
- };
-
- return {
- setCharts: setCharts,
- start: track,
- stop: destroy
- };
- };
-
- var initTracker = function() {
- // TODO: Extend tabs with onUnload event to unregister timers.
- if(kimchi.hostTimer) {
- kimchi.hostTimer.stop();
- delete kimchi.hostTimer;
- }
-
- var trackedCharts = {
- cpu: new kimchi.widget.LineChart({
- id: 'chart-cpu',
- node: 'container-chart-cpu',
- type: 'percent'
- }),
- memory: new kimchi.widget.LineChart({
- id: 'chart-memory',
- node: 'container-chart-memory',
- type: 'value'
- }),
- diskIO: new kimchi.widget.LineChart({
- id: 'chart-disk-io',
- node: 'container-chart-disk-io',
- type: 'value'
- }),
- networkIO: new kimchi.widget.LineChart({
- id: 'chart-network-io',
- node: 'container-chart-network-io',
- type: 'value'
- })
- };
-
- if(kimchi.hostTimer) {
- kimchi.hostTimer.setCharts(trackedCharts);
- }
- else {
- kimchi.hostTimer = new Tracker(trackedCharts);
- kimchi.hostTimer.start();
- }
- };
-
- $('#host-root-container').on('remove', function() {
- if(kimchi.hostTimer) {
- kimchi.hostTimer.stop();
- delete kimchi.hostTimer;
- }
-
- repositoriesGrid && repositoriesGrid.destroy();
- wok.topic('kimchi/repositoryAdded')
- .unsubscribe(listRepositories);
- wok.topic('kimchi/repositoryUpdated')
- .unsubscribe(listRepositories);
- wok.topic('kimchi/repositoryDeleted')
- .unsubscribe(listRepositories);
-
- softwareUpdatesGrid && softwareUpdatesGrid.destroy();
- wok.topic('kimchi/softwareUpdated').unsubscribe(listSoftwareUpdates);
-
- reportGrid && reportGrid.destroy();
- wok.topic('kimchi/debugReportAdded').unsubscribe(listDebugReports);
- wok.topic('kimchi/debugReportRenamed').unsubscribe(listDebugReports);
- });
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.report_add_main.js b/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
deleted file mode 100644
index 5f098d3..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-kimchi.report_add_main = function() {
- var reportGridID = 'available-reports-grid';
- var addReportForm = $('#form-report-add');
- var submitButton = $('#button-report-add');
- var nameTextbox = $('input[name="name"]', addReportForm);
- nameTextbox.select();
-
- var submitForm = function(event) {
- if(submitButton.prop('disabled')) {
- return false;
- }
- var reportName = nameTextbox.val();
- var validator = RegExp("^[_A-Za-z0-9-]*$");
- if (!validator.test(reportName)) {
- wok.message.error.code('KCHDR6011M');
- return false;
- }
- var formData = addReportForm.serializeObject();
- var taskAccepted = false;
- var onTaskAccepted = function() {
- if(taskAccepted) {
- return;
- }
- taskAccepted = true;
- wok.window.close();
- wok.topic('kimchi/debugReportAdded').publish();
- };
-
- kimchi.createReport(formData, function(result) {
- onTaskAccepted();
- wok.topic('kimchi/debugReportAdded').publish();
- }, function(result) {
- // Error message from Async Task status
- if (result['message']) {
- var errText = result['message'];
- }
- // Error message from standard kimchi exception
- else {
- var errText = result['responseJSON']['reason'];
- }
- result && wok.message.error(errText);
-
- taskAccepted &&
- $('.grid-body-view table tr:first-child',
- '#' + reportGridID).remove();
- submitButton.prop('disabled', false);
- nameTextbox.select();
- }, onTaskAccepted);
-
- event.preventDefault();
- };
-
- addReportForm.on('submit', submitForm);
- submitButton.on('click', submitForm);
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js b/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
deleted file mode 100644
index 1bdb8d9..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-kimchi.report_rename_main = function() {
- var renameReportForm = $('#form-report-rename');
- var submitButton = $('#button-report-rename');
- var nameTextbox = $('input[name="name"]', renameReportForm);
- var submitForm = function(event) {
- if(submitButton.prop('disabled')) {
- return false;
- }
- var reportName = nameTextbox.val();
-
- // if the user hasn't changed the report's name,
- // nothing should be done.
- if (reportName == kimchi.selectedReport) {
- wok.message.error.code('KCHDR6013M');
- return false;
- }
-
- var validator = RegExp("^[A-Za-z0-9-]*$");
- if (!validator.test(reportName)) {
- wok.message.error.code('KCHDR6011M');
- return false;
- }
- var formData = renameReportForm.serializeObject();
- submitButton.prop('disabled', true);
- nameTextbox.prop('disabled', true);
- kimchi.renameReport(kimchi.selectedReport, formData, function(result) {
- submitButton.prop('disabled', false);
- nameTextbox.prop('disabled', false);
- wok.window.close();
- wok.topic('kimchi/debugReportRenamed').publish({
- result: result
- });
- }, function(result) {
- var errText = result &&
- result['responseJSON'] &&
- result['responseJSON']['reason'];
- wok.message.error(errText);
- submitButton.prop('disabled', false);
- nameTextbox.prop('disabled', false).focus();
- });
-
- event.preventDefault();
- };
-
- renameReportForm.on('submit', submitForm);
- submitButton.on('click', submitForm);
-
- nameTextbox.val(kimchi.selectedReport).select();
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js b/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
deleted file mode 100644
index 656306b..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-kimchi.repository_add_main = function() {
-
- var addForm = $('#form-repository-add');
- var addButton = $('#button-repository-add');
-
- var validateField = function(event) {
- var valid=($(this).val()!=='');
- $(addButton).prop('disabled', !valid);
- return(valid);
- };
-
- var validateForm = function(event) {
- var valid=false;
- addForm.find('input.required').each( function() {
- valid=($(this).val()!=='');
- return(!valid);
- });
- return(valid);
- }
-
- addForm.find('input.required').on('input propertychange', validateField);
-
- var weedObject = function(obj) {
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- if((typeof(obj[key])==="object") && !Array.isArray(obj[key])) {
- weedObject(obj[key]);
- }
- else if(obj[key] == '') {
- delete obj[key];
- }
- }
- }
- }
-
- var addRepository = function(event) {
- var valid = validateForm();
- if(!valid) {
- return false;
- }
-
- var formData = $(addForm).serializeObject();
-
- if (formData && formData.isMirror!=undefined) {
- formData.isMirror=(String(formData.isMirror).toLowerCase() === 'true');
- }
- if(formData.isMirror) {
- if(formData.config==undefined) {
- formData.config=new Object();
- }
- formData.config.mirrorlist=formData.baseurl;
- delete formData.baseurl;
- delete formData.isMirror;
- }
- weedObject(formData);
- if(formData.config && formData.config.comps) {
- formData.config.comps=formData.config.comps.split(/[,\s]/);
- for(var i=0; i>formData.config.comps.length; i++) {
- formData.config.comps[i]=formData.config.comps[i].trim();
- }
- for (var j=formData.config.comps.indexOf(""); j!=-1; j=formData.config.comps.indexOf("")) {
- formData.config.comps.splice(j, 1);
- }
- }
-
- kimchi.createRepository(formData, function() {
- wok.topic('kimchi/repositoryAdded').publish();
- wok.window.close();
- }, function(jqXHR, textStatus, errorThrown) {
- var reason = jqXHR &&
- jqXHR['responseJSON'] &&
- jqXHR['responseJSON']['reason'];
- wok.message.error(reason);
- });
- return false;
- };
-
- $(addForm).on('submit', addRepository);
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js b/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
deleted file mode 100644
index 5bfc51e..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-kimchi.repository_edit_main = function() {
-
- var editForm = $('#form-repository-edit');
-
- var saveButton = $('#repository-edit-button-save');
-
- if(kimchi.capabilities['repo_mngt_tool']=="yum") {
- editForm.find('input.deb').prop('disabled', true);
- }
- else if(kimchi.capabilities['repo_mngt_tool']=="deb") {
- editForm.find('input.yum').prop('disabled', true);
- }
-
- kimchi.retrieveRepository(kimchi.selectedRepository, function(repository) {
- editForm.fillWithObject(repository);
-
- $('input', editForm).on('input propertychange', function(event) {
- if($(this).val() !== '') {
- $(saveButton).prop('disabled', false);
- }
- });
- });
-
-
- var editRepository = function(event) {
- var formData = $(editForm).serializeObject();
-
- if (formData && formData.config) {
- formData.config.gpgcheck=(String(formData.config.gpgcheck).toLowerCase() === 'true');
- }
-
- if(formData.config && formData.config.comps) {
- formData.config.comps=formData.config.comps.split(/[,\s]/);
- for(var i=0; i>formData.config.comps.length; i++) {
- formData.config.comps[i]=formData.config.comps[i].trim();
- }
- for (var j=formData.config.comps.indexOf(""); j!=-1; j=formData.config.comps.indexOf("")) {
- formData.config.comps.splice(j, 1);
- }
- }
-
- kimchi.updateRepository(kimchi.selectedRepository, formData, function() {
- wok.topic('kimchi/repositoryUpdated').publish();
- wok.window.close();
- }, function(jqXHR, textStatus, errorThrown) {
- var reason = jqXHR &&
- jqXHR['responseJSON'] &&
- jqXHR['responseJSON']['reason'];
- wok.message.error(reason);
- });
-
- return false;
- };
-
- $(editForm).on('submit', editRepository);
- $(saveButton).on('click', editRepository);
-};
--
2.1.0
More information about the Kimchi-devel
mailing list