[Kimchi-devel] [PATCH 12/15] V3 Ginger Base : base plugin ui/js files

Daniel Henrique Barboza dhbarboza82 at gmail.com
Wed Oct 7 13:10:31 UTC 2015


Reviewed-by: Daniel Barboza <dhbarboza82 at gmail.com>

On 10/07/2015 07:46 AM, chandra at linux.vnet.ibm.com wrote:
> 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 | 371 +++++++++
>   .../gingerbase/ui/js/src/gingerbase.host.js        | 859 +++++++++++++++++++++
>   .../gingerbase/ui/js/src/gingerbase.main.js        |  26 +
>   .../ui/js/src/gingerbase.report_add_main.js        |  72 ++
>   .../ui/js/src/gingerbase.report_rename_main.js     |  66 ++
>   .../ui/js/src/gingerbase.repository_add_main.js    |  96 +++
>   .../ui/js/src/gingerbase.repository_edit_main.js   |  74 ++
>   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, 1591 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..a3aca4a
> --- /dev/null
> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.api.js
> @@ -0,0 +1,371 @@
> +/*
> + * Project Ginger Base
> + *
> + * Copyright IBM, Corp. 2013-2015
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +var kimchi = {
> +
> +    widget: {},
> +
> +    trackingTasks: [],
> +
> +    /**
> +     *
> +     * Get host capabilities
> +     * suc: callback if succeed err: callback if failed
> +     */
> +    getCapabilities : function(suc, err, done) {
> +        done = typeof done !== 'undefined' ? done: function(){};
> +        wok.requestJSON({
> +            url : "plugins/gingerbase/host/capabilities",
> +            type : "GET",
> +            contentType : "application/json",
> +            dataType : "json",
> +            success: suc,
> +            error: err,
> +            complete: done
> +        });
> +    },
> +
> +    /**
> +     * Get the i18 strings.
> +     */
> +    getI18n: function(suc, err, url, sync) {
> +        wok.requestJSON({
> +            url : url ? url : 'plugins/gingerbase/i18n.json',
> +            type : 'GET',
> +            resend: true,
> +            dataType : 'json',
> +            async : !sync,
> +            success : suc,
> +            error: err
> +        });
> +    },
> +
> +    /**
> +     * Get the host static information.
> +     */
> +    getHost: function(suc, err) {
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/host',
> +            type : 'GET',
> +            resend: true,
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            success : suc,
> +            error: err
> +        });
> +    },
> +
> +    /**
> +     * Get the dynamic host stats (usually used for monitoring).
> +     */
> +    getHostStats : function(suc, err) {
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/host/stats',
> +            type : 'GET',
> +            contentType : 'application/json',
> +            headers: {'Wok-Robot': 'wok-robot'},
> +            dataType : 'json',
> +            success : suc,
> +            error: err
> +        });
> +    },
> +
> +    /**
> +     * Get the historic host stats.
> +     */
> +    getHostStatsHistory : function(suc, err) {
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/host/stats/history',
> +            type : 'GET',
> +            resend: true,
> +            contentType : 'application/json',
> +            headers: {'Wok-Robot': 'wok-robot'},
> +            dataType : 'json',
> +            success : suc,
> +            error: err
> +        });
> +    },
> +
> +    getTask : function(taskId, suc, err) {
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/tasks/' + encodeURIComponent(taskId),
> +            type : 'GET',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    getTasksByFilter : function(filter, suc, err, sync) {
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/tasks?' + filter,
> +            type : 'GET',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            async : !sync,
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    listReports : function(suc, err) {
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/debugreports',
> +            type : 'GET',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            resend: true,
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    trackTask : function(taskID, suc, err, progress) {
> +        var onTaskResponse = function(result) {
> +            var taskStatus = result['status'];
> +            switch(taskStatus) {
> +            case 'running':
> +                progress && progress(result);
> +                setTimeout(function() {
> +                    kimchi.trackTask(taskID, suc, err, progress);
> +                }, 2000);
> +                break;
> +            case 'finished':
> +                suc && suc(result);
> +                break;
> +            case 'failed':
> +                err && err(result);
> +                break;
> +            default:
> +                break;
> +            }
> +        };
> +
> +        kimchi.getTask(taskID, onTaskResponse, err);
> +        if(kimchi.trackingTasks.indexOf(taskID) < 0)
> +            kimchi.trackingTasks.push(taskID);
> +    },
> +
> +    createReport: function(settings, suc, err, progress) {
> +        var onResponse = function(data) {
> +            taskID = data['id'];
> +            kimchi.trackTask(taskID, suc, err, progress);
> +        };
> +
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/debugreports',
> +            type : "POST",
> +            contentType : "application/json",
> +            data : JSON.stringify(settings),
> +            dataType : "json",
> +            success : onResponse,
> +            error : err
> +        });
> +    },
> +
> +    renameReport : function(name, settings, suc, err) {
> +        $.ajax({
> +            url : "plugins/gingerbase/debugreports/" + encodeURIComponent(name),
> +            type : 'PUT',
> +            contentType : 'application/json',
> +            data : JSON.stringify(settings),
> +            dataType : 'json',
> +            success: suc,
> +            error: err
> +        });
> +    },
> +
> +    deleteReport: function(settings, suc, err) {
> +        var reportName = encodeURIComponent(settings['name']);
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/debugreports/' + reportName,
> +            type : 'DELETE',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    downloadReport: function(settings, suc, err) {
> +        window.open(settings['file']);
> +    },
> +
> +    shutdown: function(settings, suc, err) {
> +        var reboot = settings && settings['reboot'] === true;
> +        var url = 'plugins/gingerbase/host/' + (reboot ? 'reboot' : 'shutdown');
> +        wok.requestJSON({
> +            url : url,
> +            type : 'POST',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    listHostPartitions : function(suc, err) {
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/host/partitions',
> +            type : 'GET',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    listSoftwareUpdates : function(suc, err) {
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/host/packagesupdate',
> +            type : 'GET',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            resend: true,
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    updateSoftware : function(suc, err, progress) {
> +        var taskID = -1;
> +        var onResponse = function(data) {
> +            taskID = data['id'];
> +            trackTask();
> +        };
> +
> +        var trackTask = function() {
> +            kimchi.getTask(taskID, onTaskResponse, err);
> +        };
> +
> +        var onTaskResponse = function(result) {
> +            var taskStatus = result['status'];
> +            switch(taskStatus) {
> +            case 'running':
> +                progress && progress(result);
> +                setTimeout(function() {
> +                    trackTask();
> +                }, 200);
> +                break;
> +            case 'finished':
> +            case 'failed':
> +                suc(result);
> +                break;
> +            default:
> +                break;
> +            }
> +        };
> +
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/host/swupdate',
> +            type : "POST",
> +            contentType : "application/json",
> +            dataType : "json",
> +            success : onResponse,
> +            error : err
> +        });
> +    },
> +
> +    createRepository : function(settings, suc, err) {
> +        wok.requestJSON({
> +            url : "plugins/gingerbase/host/repositories",
> +            type : "POST",
> +            contentType : "application/json",
> +            data : JSON.stringify(settings),
> +            dataType : "json",
> +            success: suc,
> +            error: err
> +        });
> +    },
> +
> +    retrieveRepository : function(repository, suc, err) {
> +        var reposID = encodeURIComponent(repository);
> +        wok.requestJSON({
> +            url : "plugins/gingerbase/host/repositories/" + reposID,
> +            type : 'GET',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    updateRepository : function(name, settings, suc, err) {
> +        var reposID = encodeURIComponent(name);
> +        $.ajax({
> +            url : "plugins/gingerbase/host/repositories/" + reposID,
> +            type : 'PUT',
> +            contentType : 'application/json',
> +            data : JSON.stringify(settings),
> +            dataType : 'json',
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    enableRepository : function(name, enable, suc, err) {
> +        var reposID = encodeURIComponent(name);
> +        $.ajax({
> +            url : "plugins/gingerbase/host/repositories/" + reposID +
> +                  '/' + (enable === true ? 'enable' : 'disable'),
> +            type : 'POST',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    deleteRepository : function(repository, suc, err) {
> +        var reposID = encodeURIComponent(repository);
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/host/repositories/' + reposID,
> +            type : 'DELETE',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    listRepositories : function(suc, err) {
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/host/repositories',
> +            type : 'GET',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            resend: true,
> +            success : suc,
> +            error : err
> +        });
> +    },
> +
> +    getCPUInfo : function(suc, err) {
> +        wok.requestJSON({
> +            url : 'plugins/gingerbase/host/cpuinfo',
> +            type : 'GET',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            resend : true,
> +            success : suc,
> +            error : err ? err : function(data) {
> +                wok.message.error(data.responseJSON.reason);
> +            }
> +        });
> +    }
> +};
> diff --git a/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..8808e17
> --- /dev/null
> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js
> @@ -0,0 +1,859 @@
> +/*
> + * Project Ginger Base
> + *
> + * 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['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..824673d
> --- /dev/null
> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.main.js
> @@ -0,0 +1,26 @@
> +/*
> + * Project Ginger Base
> + *
> + * 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.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..e8a2f4d
> --- /dev/null
> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.report_add_main.js
> @@ -0,0 +1,72 @@
> +/*
> + * Project Ginger Base
> + *
> + * 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.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..b107ce5
> --- /dev/null
> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.report_rename_main.js
> @@ -0,0 +1,66 @@
> +/*
> + * Project 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.
> + */
> +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..e612cdf
> --- /dev/null
> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.repository_add_main.js
> @@ -0,0 +1,96 @@
> +/*
> + * Project 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.
> + */
> +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..a6e0371
> --- /dev/null
> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.repository_edit_main.js
> @@ -0,0 +1,74 @@
> +/*
> + * Project 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.
> + */
> +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);
> -};




More information about the Kimchi-devel mailing list