[Kimchi-devel] [PATCH 13/16] V6 Ginger Base : base plugin ui/js files

chandra at linux.vnet.ibm.com chandra at linux.vnet.ibm.com
Fri Oct 16 14:39:13 UTC 2015


From: chandrureddy <chandra at linux.vnet.ibm.com>

---
 src/wok/plugins/gingerbase/ui/js/Makefile.am       |  27 +
 .../plugins/gingerbase/ui/js/src/gingerbase.api.js | 373 +++++++++
 .../gingerbase/ui/js/src/gingerbase.host.js        | 861 +++++++++++++++++++++
 .../gingerbase/ui/js/src/gingerbase.main.js        |  28 +
 .../ui/js/src/gingerbase.report_add_main.js        |  74 ++
 .../ui/js/src/gingerbase.report_rename_main.js     |  68 ++
 .../ui/js/src/gingerbase.repository_add_main.js    |  98 +++
 .../ui/js/src/gingerbase.repository_edit_main.js   |  76 ++
 src/wok/plugins/kimchi/ui/js/src/kimchi.host.js    | 858 --------------------
 .../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 --
 13 files changed, 1605 insertions(+), 1166 deletions(-)
 create mode 100644 src/wok/plugins/gingerbase/ui/js/Makefile.am
 create mode 100644 src/wok/plugins/gingerbase/ui/js/src/gingerbase.api.js
 create mode 100644 src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js
 create mode 100644 src/wok/plugins/gingerbase/ui/js/src/gingerbase.main.js
 create mode 100644 src/wok/plugins/gingerbase/ui/js/src/gingerbase.report_add_main.js
 create mode 100644 src/wok/plugins/gingerbase/ui/js/src/gingerbase.report_rename_main.js
 create mode 100644 src/wok/plugins/gingerbase/ui/js/src/gingerbase.repository_add_main.js
 create mode 100644 src/wok/plugins/gingerbase/ui/js/src/gingerbase.repository_edit_main.js
 delete mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.host.js
 delete mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
 delete mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
 delete mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
 delete mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js

diff --git a/src/wok/plugins/gingerbase/ui/js/Makefile.am b/src/wok/plugins/gingerbase/ui/js/Makefile.am
new file mode 100644
index 0000000..fa7f3cf
--- /dev/null
+++ b/src/wok/plugins/gingerbase/ui/js/Makefile.am
@@ -0,0 +1,27 @@
+#
+# Ginger Base
+#
+# Copyright IBM, Corp. 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.
+
+EXTRA_DIST = src
+
+jsdir = $(datadir)/wok/plugins/gingerbase/ui/js
+
+dist_js_DATA = gingerbase.min.js $(filter-out gingerbase.min.js, $(wildcard *.js))
+
+gingerbase.min.js: src/*.js
+	cat $(sort $^) > $@
+
+CLEANFILES = gingerbase.min.js
diff --git a/src/wok/plugins/gingerbase/ui/js/src/gingerbase.api.js b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.api.js
new file mode 100644
index 0000000..60ec35a
--- /dev/null
+++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.api.js
@@ -0,0 +1,373 @@
+/*
+ * Project Ginger Base
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * Code derived from Project Kimchi
+ *
+ * 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/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js
new file mode 100644
index 0000000..73f3dae
--- /dev/null
+++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js
@@ -0,0 +1,861 @@
+/*
+ * Project Ginger Base
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * Code derived from Project Kimchi
+ *
+ * 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 wok.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 wok.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 wok.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 wok.widget.LineChart({
+                id: 'chart-cpu',
+                node: 'container-chart-cpu',
+                type: 'percent'
+            }),
+            memory: new wok.widget.LineChart({
+                id: 'chart-memory',
+                node: 'container-chart-memory',
+                type: 'value'
+            }),
+            diskIO: new wok.widget.LineChart({
+                id: 'chart-disk-io',
+                node: 'container-chart-disk-io',
+                type: 'value'
+            }),
+            networkIO: new wok.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/src/wok/plugins/gingerbase/ui/js/src/gingerbase.main.js b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.main.js
new file mode 100644
index 0000000..326f943
--- /dev/null
+++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.main.js
@@ -0,0 +1,28 @@
+/*
+ * Project Ginger Base
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * Code derived from Project Kimchi
+ *
+ * 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/src/wok/plugins/gingerbase/ui/js/src/gingerbase.report_add_main.js b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.report_add_main.js
new file mode 100644
index 0000000..105465d
--- /dev/null
+++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.report_add_main.js
@@ -0,0 +1,74 @@
+/*
+ * Project Ginger Base
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * Code derived from Project Kimchi
+ *
+ * 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/src/wok/plugins/gingerbase/ui/js/src/gingerbase.report_rename_main.js b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.report_rename_main.js
new file mode 100644
index 0000000..b5538f1
--- /dev/null
+++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.report_rename_main.js
@@ -0,0 +1,68 @@
+/*
+ * Project Ginger Base
+ *
+ * Copyright IBM, Corp. 2015
+ *
+ * Code derived from Project Kimchi
+ *
+ * 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/src/wok/plugins/gingerbase/ui/js/src/gingerbase.repository_add_main.js b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.repository_add_main.js
new file mode 100644
index 0000000..59fe7a5
--- /dev/null
+++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.repository_add_main.js
@@ -0,0 +1,98 @@
+/*
+ * Project Ginger Base
+ *
+ * Copyright IBM, Corp. 2015
+ *
+ * Code derived from Project Kimchi
+ *
+ * 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/src/wok/plugins/gingerbase/ui/js/src/gingerbase.repository_edit_main.js b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.repository_edit_main.js
new file mode 100644
index 0000000..24677cc
--- /dev/null
+++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.repository_edit_main.js
@@ -0,0 +1,76 @@
+/*
+ * Project Ginger Base
+ *
+ * Copyright IBM, Corp. 2015
+ *
+ * Code derived from Project Kimchi
+ *
+ * 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/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js
deleted file mode 100644
index c3765dc..0000000
--- a/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- * 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.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[display_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 wok.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 wok.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 wok.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 wok.widget.LineChart({
-                id: 'chart-cpu',
-                node: 'container-chart-cpu',
-                type: 'percent'
-            }),
-            memory: new wok.widget.LineChart({
-                id: 'chart-memory',
-                node: 'container-chart-memory',
-                type: 'value'
-            }),
-            diskIO: new wok.widget.LineChart({
-                id: 'chart-disk-io',
-                node: 'container-chart-disk-io',
-                type: 'value'
-            }),
-            networkIO: new wok.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/src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
deleted file mode 100644
index 5f098d3..0000000
--- a/src/wok/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/src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
deleted file mode 100644
index 1bdb8d9..0000000
--- a/src/wok/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/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
deleted file mode 100644
index 656306b..0000000
--- a/src/wok/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/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
deleted file mode 100644
index 5bfc51e..0000000
--- a/src/wok/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