[Kimchi-devel] [PATCH 3/9] Adding new-ui base templates and widgets - JS

sguimaraes943 at gmail.com sguimaraes943 at gmail.com
Tue Oct 27 21:22:57 UTC 2015


From: samhenri <samuel.guimaraes at eldorado.org.br>

Signed-off-by: samhenri <samuel.guimaraes at eldorado.org.br>
---
 ui/js/src/wok.confirm.js    |  91 ++++++++++
 ui/js/src/wok.datagrid.js   | 123 +++++++++++++
 ui/js/src/wok.grid.js       | 416 +++++++++++---------------------------------
 ui/js/src/wok.line-chart.js |  74 +++++---
 ui/js/src/wok.list.js       | 302 ++++++++++++++++++++++++++++++++
 ui/js/src/wok.login.js      |   9 +-
 ui/js/src/wok.main.js       |  61 +++++--
 ui/js/src/wok.message.js    |  95 +++-------
 ui/js/src/wok.window.js     |  31 ++--
 ui/js/widgets/grid.js       | 123 -------------
 10 files changed, 749 insertions(+), 576 deletions(-)
 create mode 100644 ui/js/src/wok.confirm.js
 create mode 100644 ui/js/src/wok.datagrid.js
 create mode 100644 ui/js/src/wok.list.js
 delete mode 100644 ui/js/widgets/grid.js

diff --git a/ui/js/src/wok.confirm.js b/ui/js/src/wok.confirm.js
new file mode 100644
index 0000000..63f01c4
--- /dev/null
+++ b/ui/js/src/wok.confirm.js
@@ -0,0 +1,91 @@
+/*
+ * Project Wok
+ *
+ * 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.
+ */
+/**
+ * A public function of confirm box.
+ *
+ * @param msg
+ *            type:[object]
+ * @param msg.title
+ *            The title of the confirm box.
+ * @param msg.content
+ *            The main text of the confirm box.
+ * @param msg.confirm
+ *            The text of the confirm button.
+ * @param msg.cancel
+ *            the text of the cancel button.
+ * @param confirmCallback
+ *            the callback function of click the confirm button.
+ * @param cancelCallback
+ *            The callback function of click the cancel and X button.
+ */
+wok.confirm = function(settings, confirmCallback, cancelCallback) {
+    "use strict";
+    var modalStr = '<div id="wok-confirm-modal" class="modal fade host-modal" tabindex="-1" role="dialog" aria-labelledby="confirmModalLabel" aria-hidden="true"></div>';
+    if ($('#wok-confirm-modal ').size() < 1 && $('#modalWindow').size() < 1 ) {
+        $(document.body).append(modalStr);
+    } else if ($('#wok-confirm-modal ').size() < 1) {
+        $('#modalWindow').after(modalStr);
+    }
+
+    var confirmboxHeader = [
+                '<div class="modal-header', (settings.title === '' || typeof settings.title === 'undefined' ? ' icon' : '' ) ,'">',
+                    '<h4 class="modal-title"><i class="fa fa-exclamation-triangle"></i>'+(settings.title || '')+'</h4>',
+                '</div>'
+    ].join('');
+
+    var confirmboxHtml = [
+        '<div class="modal-dialog  modal-sm">',
+            '<div class="modal-content">',
+                confirmboxHeader,
+                '<div class="modal-body">',
+                    settings.content,
+                '</div>',
+                '<div class="modal-footer">',
+                    '<button id="button-confirm" class="btn btn-default">' + (settings.confirm || i18n['KCHAPI6004M']) + '</button>',
+                    '<button id="button-cancel" class="btn btn-default">' + (settings.cancel || i18n['KCHAPI6003M']) + '</button>',
+                '</div>',
+            '</div>',
+        '</div>'
+    ].join('');
+    var confirmboxNode = $(confirmboxHtml);
+    $('#wok-confirm-modal').append(confirmboxNode);
+    $('#wok-confirm-modal').modal('show');
+    $('#wok-confirm-modal').on("click", "#button-confirm", function(e) {
+        if (confirmCallback) {
+            confirmCallback();
+        }
+        $('#wok-confirm-modal').modal('hide');
+    });
+    $('#wok-confirm-modal').on("click", "#button-cancel", function(e) {
+        if (cancelCallback) {
+            cancelCallback();
+        }
+        $('#wok-confirm-modal').modal('hide');
+    });
+
+    $('#wok-confirm-modal').on('hidden.bs.modal', function () {
+        close();
+    });
+
+    var close = function(){
+        "use strict";
+        $('#wok-confirm-modal').removeData('bs.modal');
+        $('#wok-confirm-modal').remove();
+    };
+
+};
\ No newline at end of file
diff --git a/ui/js/src/wok.datagrid.js b/ui/js/src/wok.datagrid.js
new file mode 100644
index 0000000..9f2f17b
--- /dev/null
+++ b/ui/js/src/wok.datagrid.js
@@ -0,0 +1,123 @@
+/*
+ * Project Wok
+ *
+ * Copyright IBM, Corp. 2015
+ *
+ * Code derived from Project Kimchi
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+$(function(){
+$.widget("wok.dataGrid", {
+    options: {
+        enableSorting: true
+    },
+    _create: function() {
+        var that = this;
+        this.element.addClass('wok-datagrid');
+        var head = $(this.element.children().get(0));
+        var body = $(this.element.children().get(1));
+        head.addClass('wok-datagrid-header');
+        if(this.options.enableSorting){
+            head.children().each(function(){
+                var addSorting = "<span>"+$(this).html()+"</span>";
+                addSorting += '<span><div class="icon-angle-up sort-up"></div><div class="icon-angle-down sort-down"></div></span>';
+                $(this).empty().append(addSorting);
+            });
+        }
+        $('.icon-angle-up', head).click(function(){
+            that.sort(head.children().index($(this).parent().parent()), true);
+        });
+        $('.icon-angle-down', head).click(function(){
+            that.sort(head.children().index($(this).parent().parent()), false);
+        });
+        body.addClass('wok-datagrid-body');
+        body.children().addClass('wok-datagrid-row');
+        this._setRowBackgroud();
+    },
+    _setRowBackgroud: function(){
+        var i=0, classes=['odd', 'even'];
+        $(this.element.children().get(1)).children().each(function(){
+            $(this).removeClass('odd');
+            $(this).removeClass('even');
+            $(this).addClass(classes[i]);
+            i = i==0?1:0;
+        });
+    },
+    sort: function(column, assending) {
+        var head = $(this.element.children().get(0));
+        $('.icon-up-dir', head).removeClass('icon-up-dir').addClass('icon-angle-up');
+        $('.icon-down-dir', head).removeClass('icon-down-dir').addClass('icon-angle-down');
+        var columnCell = $(head.children().get(column));
+        if(assending){
+            $('.icon-angle-up', columnCell).removeClass('icon-angle-up').addClass('icon-up-dir');
+        }else{
+            $('.icon-angle-down', columnCell).removeClass('icon-angle-down').addClass('icon-down-dir');
+        }
+        var container = $(this.element.children().get(1));
+        var nodes = [];
+        container.children().each(function(){
+            nodes.push($(this));
+        });
+        nodes.sort(function(a, b){
+            aVal = $(a.children().get(column)).attr('val');
+            bVal = $(b.children().get(column)).attr('val');
+            return aVal.localeCompare(bVal);
+        });
+        if(!assending) nodes.reverse();
+        container.empty();
+        for(var i=0;i<nodes.length;i++){
+            container.append(nodes[i]);
+        }
+        this._setRowBackgroud();
+    },
+    filter: function(keyword) {
+        keyword = keyword.toLowerCase();
+        var container = $(this.element.children().get(1));
+        container.children().each(function(){
+            var hide = true;
+            $(this).children().each(function(){
+                if($(this).attr('val')&&$(this).attr('val').toLowerCase().indexOf(keyword)!=-1){
+                    hide = false;
+                    return false;
+                }
+            });
+            $(this).css('display', hide?'none':'');
+        });
+        this._setRowBackgroud();
+    },
+    addRow: function(rowNode){
+        $(rowNode).addClass('wok-datagrid-row');
+        this._setRowBackgroud();
+    },
+    deleteRow: function(rowNode){
+        $(rowNode).remove();
+        this._setRowBackgroud();
+    },
+    _destroy: function() {
+        this.element.removeClass('wok-datagrid');
+        var head = $(this.element.children().get(0));
+        var body = $(this.element.children().get(1));
+        head.removeClass('wok-datagrid-header');
+        if(this.options.enableSorting){
+            head.children().each(function(){
+                var oriContent = $($(this).children().get(0)).html()
+                $(this).empty().append(oriContent);
+            });
+        }
+        body.removeClass('wok-datagrid-body');
+        body.children().removeClass('wok-datagrid-row odd even');
+    }
+});
+});
diff --git a/ui/js/src/wok.grid.js b/ui/js/src/wok.grid.js
index 12f191c..0606bc6 100644
--- a/ui/js/src/wok.grid.js
+++ b/ui/js/src/wok.grid.js
@@ -18,106 +18,73 @@
  * limitations under the License.
  */
 wok.widget.Grid = function(opts) {
+    "use strict";
     this.opts = $.extend({}, this.opts, opts);
     this.createDOM();
     this.reload();
 };
 
 wok.widget.Grid.prototype = (function() {
+    "use strict";
     var htmlStr = [
-        '<div id="{id}" class="grid">',
-            '<div class="grid-content">',
-                '<div class="grid-header">',
-                    '<div class="grid-frozen-header-view">',
-                        '<table class="grid-frozen-header-container">',
-                        '</table>',
-                    '</div>',
-                    '<div class="grid-header-view">',
-                        '<div class="grid-header-wrapper">',
-                            '<table class="grid-header-container">',
-                            '</table>',
-                        '</div>',
-                    '</div>',
-                '</div>',
-                '<div class="grid-body">',
-                    '<div class="grid-frozen-body-view">',
-                        '<div class="grid-frozen-body-wrapper">',
-                            '<table class="grid-frozen-body-container">',
-                            '</table>',
-                        '</div>',
-                    '</div>',
-                    '<div class="grid-body-view">',
-                        '<div class="grid-body-wrapper">',
-                            '<table class="grid-body-container">',
-                            '</table>',
-                        '</div>',
-                    '</div>',
+        '<div id="{id}" class="grid wok-grid">',
+            '<div class="wok-grid-message hidden">',
+                '<div class="alert alert-danger fade in" role="alert">',
+                    '<p><strong>{message}</strong> ',
+                    '<span class="detailed-text"></span></p>',
+                    '<p><button class="btn btn-primary btn-xs retry-button">',
+                        '{buttonLabel}',
+                    '</button></p>',
                 '</div>',
-                '<div class="grid-resizer-leftmost hidden"></div>',
-                '<div class="grid-resizer hidden"></div>',
             '</div>',
-            '<div class="grid-footer"></div>',
-            '<div class="grid-mask hidden">',
-                '<div class="grid-loading">',
-                    '<div class="grid-loading-icon"></div>',
-                    '<div class="grid-loading-text">',
-                        '{loading}',
-                    '</div>',
-                '</div>',
+            '<div class="grid-content wok-grid-content">',
+                    '<table class="wok-table table">',
+                        '<thead class="wok-grid-header-container"></thead>',
+                        '<tbody class="wok-grid-body-container">',
+                        '</tbody>',
+                    '</table>',
             '</div>',
-            '<div class="grid-message hidden">',
-                '<div class="grid-message-text">',
-                    '{message}',
-                    '<button class="retry-button btn-small">',
-                        '{buttonLabel}',
-                    '</button>',
-                '</div>',
-                '<div class="detailed-title">',
-                    '{detailedLabel}',
+            '<div class="wok-grid-mask hidden">',
+                '<div class="wok-grid-loader-container">',
+                    '<div class="wok-grid-loading">',
+                        '<div class="wok-grid-loading-icon"></div>',
+                        '<div class="wok-grid-loading-text">',
+                            '{loading}',
+                        '</div>',
+                    '</div>',
                 '</div>',
-                '<div class="detailed-text"></div>',
             '</div>',
         '</div>'
     ].join('');
 
-    var CONTAINER_NORMAL = 0, CONTAINER_FROZEN = 1;
-
     var setupHeaders = function(header, body, fields) {
         var colGroup = $('<colgroup></colgroup>').appendTo(header);
-        var headerHeader = $('<thead></thead>');
-        var headerRow = $('<tr></tr>').appendTo(headerHeader);
+        var headerRow = $('<tr></tr>').appendTo(header);
         $.each(fields || [], function(i, field) {
             $('<col class="' +
                 field['class'] +
             '"/>')
                 .appendTo(colGroup);
-            $('<th><div class="cell-text-wrapper">' +
+            $('<th><div class="wok-text-header">' +
                 field['label'] +
             '</div></th>').appendTo(headerRow);
         });
-        headerHeader.appendTo(header);
 
         var totalWidth = 0;
-        $('col', colGroup).each(function(index, col) {
-            var width = $(col).width();
-            totalWidth += width;
-            $(col).css('width', width + 'px');
-        });
-        $(body).append(colGroup.clone());
         return totalWidth;
     };
 
     var getValue = function(name, obj) {
-        var result=undefined;
+        var result;
         if(!Array.isArray(name)) {
             name=name.parseKey();
         }
-        if(name.length!=0) {
+        if(name.length!==0) {
             var tmpName=name.shift();
-            if(obj[tmpName]!=undefined) {
+            if(obj[tmpName]!==undefined) {
                     result=obj[tmpName];
             }
-            if(name.length!=0) {
+            if(name.length!==0) {
                     result=getValue(name,obj[tmpName]);
             }
         }
@@ -126,55 +93,18 @@ wok.widget.Grid.prototype = (function() {
 
     var fillBody = function(container, fields) {
         var data = this.data;
-        var tbody = ($('tbody', container).length && $('tbody', container))
-            || $('<tbody></tbody>').appendTo(container);
-        tbody.empty();
         $.each(data, function(i, row) {
-            var rowNode = $('<tr></tr>').appendTo(tbody);
+            var rowNode = $('<tr></tr>').appendTo(container);
             $.each(fields, function(fi, field) {
                 var value = getValue(field['name'], row);
-                $('<td><div class="cell-text-wrapper"' +
-                    (field['makeTitle'] === true
-                        ? ' title="' + value + '"'
-                        : ''
-                    ) + '>' + value.toString() + '</div></td>'
+                $('<td><div class="wok-cell-text"' + (field['makeTitle'] === true ? ' title="' + value + '"' : '' ) + '>' + value.toString() + '</div></td>'
                 ).appendTo(rowNode);
             });
         });
     };
 
-    var fixTableLayout = function(style) {
-        $.each([
-            this.frozenHeaderContainer,
-            this.headerContainer,
-            this.frozenBodyContainer,
-            this.bodyContainer
-        ], function(i, tableNode) {
-            $(tableNode).css('table-layout', style || 'fixed');
-        });
-    };
-
-    var initResizing = function(event) {
-        var resizer = event.data.resizer;
-        var pageX = event.pageX;
-        var tailPos = $(this).width() + $(this).offset()['left'];
-        var atResizer = Math.abs(pageX - tailPos) <= 2;
-        var isResizing = !$(resizer).hasClass('hidden');
-        $('body')[(atResizer || isResizing)
-            ? 'addClass'
-            : 'removeClass'
-        ]('resizing');
-    };
-
-    var clearResizing = function(event) {
-        $(event.data.resizer).hasClass('hidden') &&
-            $('body').removeClass('resizing');
-    };
-
     var stylingRow = function(row, className, add) {
         var index = $(row).index() + 1;
-        $('tr', this.frozenBodyContainer)
-            .removeClass(className);
         $('tr', this.bodyContainer)
             .removeClass(className);
 
@@ -182,19 +112,18 @@ wok.widget.Grid.prototype = (function() {
             return;
         }
 
-        $('tr:nth-child(' + index + ')', this.frozenBodyContainer)
-            .addClass(className);
         $('tr:nth-child(' + index + ')', this.bodyContainer)
             .addClass(className);
     };
 
     var setBodyListeners = function() {
-        if(this['opts']['rowSelection'] != 'disabled') {
+        if(this['opts']['rowSelection'] !== 'disabled') {
             $('tr', this.gridBody).on('mouseover', {
                 grid: this
             }, function(event) {
-                if (! $(this).hasClass('no-hover'))
+                if (! $(this).hasClass('no-hover')) {
                     stylingRow.call(event.data.grid, this, 'hover');
+                }
             });
 
             $('tr', this.gridBody).on('mouseout', {
@@ -213,128 +142,16 @@ wok.widget.Grid.prototype = (function() {
             });
         }
 
-        $('.grid-body-view', this.domNode).on('scroll', {
-            grid: this
-        }, function(event) {
-            var grid = event.data.grid;
-            $('.grid-header .grid-header-view', grid.domNode)
-                .prop('scrollLeft', this.scrollLeft);
-            $('.grid-body .grid-frozen-body-view', grid.domNode)
-                .prop('scrollTop', this.scrollTop);
-        });
     };
 
     var setData = function(data) {
         this.data = data;
-        fillBody.call(this, this.frozenBodyContainer, this['opts']['frozenFields']);
         fillBody.call(this, this.bodyContainer, this['opts']['fields']);
         setBodyListeners.call(this);
     };
 
     var getSelected = function() {
-        return this.selectedIndex >= 0
-            ? this.data[this.selectedIndex]
-            : null;
-    };
-
-    var startResizing = function(container, event) {
-        var grid = event.data.grid;
-        wok.widget.Grid.beingResized = grid;
-        if(!($('body').hasClass('resizing')
-                && $(grid.resizer).hasClass('hidden'))) {
-            return;
-        }
-
-        grid.columnBeingResized = container;
-        var pageX = event.pageX;
-        var gridOffsetX = grid.domNode.offset()['left'];
-        var leftmostOffsetX = $(container).offset()['left'] - gridOffsetX;
-        var left = pageX - gridOffsetX;
-        var contentHeight = $('.grid-content', grid.domNode).height();
-        $(grid.resizerLeftmost).css({
-            left: leftmostOffsetX + 'px',
-            height: contentHeight + 'px'
-        });
-        $(grid.resizer).css({
-            left: left + 'px',
-            height: contentHeight + 'px'
-        });
-        $(grid.resizerLeftmost).removeClass('hidden');
-        $(grid.resizer).removeClass('hidden');
-        event.preventDefault();
-    };
-
-    var endResizing = function(event) {
-        var grid = wok.widget.Grid.beingResized;
-        if(!$('body').hasClass('resizing')) {
-            return;
-        }
-        $(grid.resizerLeftmost).addClass('hidden');
-        $(grid.resizer).addClass('hidden');
-        $('body').removeClass('resizing');
-        var leftmostOffset = $(grid.columnBeingResized).offset()['left'];
-        var left = event.pageX;
-        if(leftmostOffset > left) {
-            return;
-        }
-        resizeColumnWidth.call(
-            grid,
-            $(grid.columnBeingResized).index(),
-            left - leftmostOffset
-        );
-        fixTableLayout.call(grid);
-        grid.columnBeingResized = null;
-        wok.widget.Grid.beingResized = null;
-    };
-
-    var resizeColumnWidth = function(index, width) {
-        var width = Math.ceil(width);
-        var widthArray = [];
-        var totalWidth = 0;
-        var header = this.headerContainer;
-        var body = this.bodyContainer;
-        if(this.containerBeingResized === CONTAINER_FROZEN) {
-            header = this.frozenHeaderContainer;
-            body = this.frozenBodyContainer;
-        }
-        $('col', header).each(function(i, colNode) {
-            var w = index === i ? width : $(colNode).width();
-            widthArray.push(w);
-            totalWidth += w;
-        });
-        $.each([header, body], function(i, container) {
-            container.css({
-                'table-layout': 'fixed',
-                width: totalWidth + 'px'
-            });
-            $('col:nth-child(' + (index + 1) + ')', container).css({
-                width: width + 'px'
-            });
-        });
-
-        if(this.containerBeingResized === CONTAINER_FROZEN) {
-            var headerView = $('.grid-header-view', this.domNode);
-            var bodyView = $('.grid-body-view', this.domNode);
-            $.each([headerView, bodyView], function(i, view) {
-                view.css({
-                    left: totalWidth + 'px'
-                });
-            });
-        }
-    };
-
-    var positionResizer = function(event) {
-        var grid = event.data.grid;
-        if($(grid.resizer).hasClass('hidden')) {
-            return;
-        }
-
-        var pageX = event.pageX;
-        var gridOffsetX = $(grid.domNode).offset()['left'];
-        var leftMost = $(grid.resizerLeftmost).position()['left'];
-        var offsetX = pageX - gridOffsetX;
-        offsetX = offsetX >= leftMost ? offsetX : leftMost;
-        $(grid.resizer).css('left', offsetX + 'px');
+        return this.selectedIndex >= 0 ? this.data[this.selectedIndex] : null;
     };
 
     var showMessage = function(msg) {
@@ -368,11 +185,6 @@ wok.widget.Grid.prototype = (function() {
         }
     };
 
-    var destroy = function() {
-        $('body').off('mousemove.grid#' + this['opts']['id'], positionResizer);
-        $('body').off('mouseup.grid#' + this['opts']['id'], endResizing);
-    };
-
     var createDOM = function() {
         var containerID = this['opts']['container'];
         var container = $('#' + containerID);
@@ -387,118 +199,91 @@ wok.widget.Grid.prototype = (function() {
         })).appendTo(container);
         this.domNode = domNode;
 
+        var theTable = $('.wok-table', domNode);
+        var theContainer = $('.wok-grid-content', domNode);
+        var headerContainer = $('.wok-grid-header-container', domNode);
+        var bodyContainer = $('.wok-grid-body-container', domNode);
+        setupHeaders(headerContainer, bodyContainer, this['opts']['fields']);
+        this.theTable = theTable;
+        this.theContainer = theContainer;
+        this.headerContainer = headerContainer;
+        this.bodyContainer = bodyContainer;
+
         var height = domNode.height();
         var width = domNode.width();
 
         var title = this['opts']['title'];
         var titleNode = null;
         if(title) {
-            titleNode = $('<div class="grid-caption">' + title + '</div>')
-                .prependTo(domNode);
+            titleNode = $('<caption class="sr-only">' + title + '</caption>').prependTo(theTable);
         }
 
         var toolbarButtons = this['opts']['toolbarButtons'];
         var toolbarNode = null;
+        var btnHTML, dropHTML = [];
         if(toolbarButtons) {
-            toolbarNode = $('<div class="grid-toolbar"></div>');
-            if(titleNode) {
-                titleNode.after(toolbarNode);
-            }
-            else {
-                toolbarNode.prependTo(domNode);
+            toolbarNode = $('<div class="btn-group"></div>');
+            toolbarNode.prependTo(theContainer);
+            if(toolbarButtons.length > 1) {
+                dropHTML = ['<div class="dropdown menu-flat">',
+                    '<button id="wok-dropdown-button-', containerID, '" class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">',
+                    '<span class="edit-alt"></span>Actions<span class="caret"></span>',
+                    '</button>',
+                    '<ul class="dropdown-menu"></ul>',
+                    '</div>'
+                ].join('');
+                $(dropHTML).appendTo(toolbarNode);
+                $.each(toolbarButtons, function(i, button) {
+                    btnHTML = [
+                        '<li role="presentation"', button.critical === true ? ' class="critical"' : '', '><a data-toggle="modal"',
+                        button.id ? (' id="' + button.id + '"') : '',
+                        ' class="', button.disabled === true ? ' disabled' : '', '">',
+                        button.class ? ('<i class="' + button.class) + '"></i>' : '',
+                        button.label,
+                        '</a></li>'
+                    ].join('');
+                    var btnNode = $(btnHTML).appendTo(toolbarNode[0].children[0].children[1]);
+                    button.onClick && btnNode.on('click', button.onClick);
+                });
+            }else {
+                $.each(toolbarButtons, function(i, button) {
+                    btnHTML = [
+                        '<button data-dismiss="modal" ',
+                            button['id'] ? (' id="' + button['id'] + '"') : '',
+                            ' class="btn btn-primary',
+                                button['class'] ? (' ' + button['class']) : '',
+                                '"',
+                                button['disabled'] === true ? ' disabled' : '',
+                                '>',
+                                button['label'],
+                        '</button>'
+                    ].join('');
+                    var btnNode = $(btnHTML).appendTo(toolbarNode);
+                    button['onClick'] &&
+                        btnNode.on('click', button['onClick']);
+                });      
             }
 
-            $.each(toolbarButtons, function(i, button) {
-                var btnHTML = [
-                    '<button',
-                        button['id'] ? (' id="' + button['id'] + '"') : '',
-                        ' class="grid-toolbar-button',
-                            button['class'] ? (' ' + button['class']) : '',
-                            '"',
-                            button['disabled'] === true ? ' disabled' : '',
-                            '>',
-                            button['label'],
-                    '</button>'
-                ].join('');
-                var btnNode = $(btnHTML).appendTo(toolbarNode);
-                button['onClick'] &&
-                    btnNode.on('click', button['onClick']);
-            });
         }
 
-        var frozenHeaderContainer = $('.grid-frozen-header-container', domNode);
-        var frozenBodyContainer = $('.grid-frozen-body-container', domNode);
-        var frozenWidth = setupHeaders(
-                frozenHeaderContainer,
-                frozenBodyContainer,
-                this['opts']['frozenFields']
-        );
-        this.frozenHeaderContainer = frozenHeaderContainer;
-        this.frozenBodyContainer = frozenBodyContainer;
-
-        var headerContainer = $('.grid-header-container', domNode);
-        var bodyContainer = $('.grid-body-container', domNode);
-        setupHeaders(headerContainer, bodyContainer, this['opts']['fields']);
-        this.headerContainer = headerContainer;
-        this.bodyContainer = bodyContainer;
-
-        fixTableLayout.call(this, 'auto');
+        // var domHeight = domNode && $(domNode).height() || 0;
+        // var toolbarHeight = toolbarNode && $(toolbarNode).height() || 0;
+        // var maskHeight = domHeight - toolbarHeight;
 
-        var gridContentNode = $('.grid-content', domNode);
-        var captionHeight = titleNode && $(titleNode).height() || 0;
-        var toolbarHeight = toolbarNode && $(toolbarNode).height() || 0;
-        gridContentNode.css('top', (captionHeight + toolbarHeight) + 'px');
+        // var maskContainer = $('.wok-grid-loader-container',domNode);
+        // maskContainer.css({'top': toolbarHeight+'px', 'height': maskHeight+'px'});
+        // this.maskContainer = maskContainer;
 
-        var maskNode = $('.grid-mask', domNode);
-        maskNode.css('top', captionHeight + 'px');
+        var maskNode = $('.wok-grid-mask', domNode);
         this.maskNode = maskNode;
 
-        var messageNode = $('.grid-message', domNode);
-        messageNode.css('top', captionHeight + 'px');
+        var messageNode = $('.wok-grid-message', domNode);
         this.messageNode = messageNode;
 
-        var headerView = $('.grid-header-view', domNode);
-        var bodyView = $('.grid-body-view', domNode);
-        headerView.css('left', (frozenWidth) + 'px');
-        bodyView.css('left', (frozenWidth) + 'px');
+        //fixTableLayout.call(this);
 
-        var bodyWidth = width - frozenWidth;
-        headerContainer.css('width', bodyWidth + 'px');
-        bodyContainer.css('width', bodyWidth + 'px');
-
-        fixTableLayout.call(this);
-
-        var gridBody = $('.grid-body', domNode);
+        var gridBody = $('.wok-grid-body', domNode);
         this.gridBody = gridBody;
-        this.resizerLeftmost = $('.grid-resizer-leftmost', domNode);
-        this.resizer = $('.grid-resizer', domNode);
-        var gridHeader = $('.grid-header', domNode);
-        $('th', gridHeader).on('mouseover mousemove', {
-            resizer: this.resizer
-        }, initResizing);
-
-        $('th', gridHeader).on('mouseout', {
-            resizer: this.resizer
-        }, clearResizing);
-
-        this.containerBeingResized = CONTAINER_NORMAL;
-        $('th', frozenHeaderContainer).on('mousedown', {
-            grid: this
-        }, function(event) {
-                event.data.grid.containerBeingResized = CONTAINER_FROZEN;
-                startResizing(this, event);
-        });
-        $('th', headerContainer).on('mousedown', {
-            grid: this
-        }, function(event) {
-                event.data.grid.containerBeingResized = CONTAINER_NORMAL;
-                startResizing(this, event);
-        });
-
-        $('body').on('mousemove.grid#' + this['opts']['id'], {
-            grid: this
-        }, positionResizer);
-        $('body').on('mouseup.grid#' + this['opts']['id'], endResizing);
 
         var data = this['opts']['data'];
 
@@ -517,14 +302,13 @@ wok.widget.Grid.prototype = (function() {
             onRowSelected: null,
             title: null,
             toolbarButtons: null,
-            frozenFields: null,
             fields: null
         },
         createDOM: createDOM,
         setData: setData,
         getSelected: getSelected,
         reload: reload,
-        destroy: destroy,
+        //destroy: destroy,
         showMessage: showMessage
     };
-})();
+})();
\ No newline at end of file
diff --git a/ui/js/src/wok.line-chart.js b/ui/js/src/wok.line-chart.js
index 3c740e6..3eb3494 100644
--- a/ui/js/src/wok.line-chart.js
+++ b/ui/js/src/wok.line-chart.js
@@ -18,13 +18,15 @@
  * limitations under the License.
  */
 
-/**
+/*
  * new wok.widget.LineChart({
  *   node: 'line-chart-cpu',
  *   id: 'line-chart',
  *   type: 'value'
  * });
  */
+ 
+ 
 wok.widget.LineChart = function(params) {
     var container = $('#' + params['node']);
     container.addClass('chart-container');
@@ -82,6 +84,14 @@ wok.widget.LineChart = function(params) {
                 }
             });
         }
+        
+        var defs = [
+            '<defs>',
+                '<pattern id="patternbg" x="0" y="0" width="6" height="6" patternUnits="userSpaceOnUse">',
+                    '<rect x="0" y="0" width="3" height="6" style="stroke:none; fill: #eeeeee;"></rect>',
+                '</pattern>',
+            '</defs>'
+        ].join('');
 
         var canvasNode = $('#' + canvasID);
         canvasNode.length && canvasNode.remove();
@@ -89,25 +99,10 @@ wok.widget.LineChart = function(params) {
           '<svg id="', canvasID, '" class="line-chart"',
               ' height="', height, '" width="', width, '"',
           '>',
+            defs,
             '<rect height="', height, '" width="', width, '" class="background" />'
         ];
 
-        for(var x = linesOffset; x < width; x += linesSpace) {
-            htmlStr.push(
-                '<line x1="', x, '" y1="', 0, '" x2="', x, '" y2="', height, '" />'
-            );
-        }
-
-        linesOffset -= xFactor;
-        while(linesOffset < 0) {
-            linesOffset = linesSpace + linesOffset;
-        }
-
-        for(var y = height - linesSpace; y > 0; y -= linesSpace) {
-            htmlStr.push(
-                '<line x1="', 0, '" y1="', y, '" x2="', width, '" y2="', y, '" />'
-            );
-        }
 
         var maxValueLabel = i18n['KCHHOST6001M'] + ' ' +
             (type === 'value'
@@ -124,12 +119,34 @@ wok.widget.LineChart = function(params) {
             chartVAxis.text(maxValueLabel);
         }
 
+
         seriesNames = [];
         $.each(data, function(i, series) {
             var points = series['points'];
             var className = series['class'];
             var latestPoint = points.slice(-1).pop();
             xStart = latestPoint['x'] - period;
+            htmlStr.push('<path',
+                ' class="series', className ? ' ' + className : '', '"',
+                ' d="M 0,92 '
+            );
+            var first = true;
+            $.each(points, function(i, point) {
+                if(first) {
+                    first = false;
+                }
+                else {
+                    htmlStr.push(' ');
+                }
+
+                var x = xFactor * (point['x'] - xStart);
+                var y = height - yFactor * (type === 'value' ?
+                    point['y'] * 100 / maxValue :
+                    point['y']
+                );
+                htmlStr.push(x, ',', y);
+            });
+            htmlStr.push(' 310,92z" />');
 
             htmlStr.push('<polyline',
                 ' class="series', className ? ' ' + className : '', '"',
@@ -152,6 +169,7 @@ wok.widget.LineChart = function(params) {
                 htmlStr.push(x, ',', y);
             });
             htmlStr.push('" />');
+
         });
 
         htmlStr.push('</svg>');
@@ -160,7 +178,7 @@ wok.widget.LineChart = function(params) {
 
         if(!chartLegend) {
             chartLegend = $('<div class="chart-legend-container"></div>');
-            container.after(chartLegend);
+            container.before(chartLegend);
         }
         else {
             chartLegend.empty();
@@ -169,18 +187,15 @@ wok.widget.LineChart = function(params) {
             var wrapper = $('<div class="legend-wrapper"></div>')
                 .appendTo(chartLegend);
             $([
-                '<svg class="legend-icon" width="20" height="10">',
-                    '<line x1="0" y1="5" x2="20" y2="5"/>',
+                '<svg class="legend-icon" width="5" height="40">',
+                    '<rect  width="5" height="40" />',
                 '</svg>'
             ].join('')).appendTo(wrapper);
-            $('line', wrapper).css({
-                stroke: $(polyline).css('stroke'),
-                'stroke-width': $(polyline).css('stroke-width')
+            $('rect', wrapper).css({
+                fill: $(polyline).css('stroke')
             });
             var label = data[i]['legend'];
             var base = data[i]['base'];
-            $('<label class="legend-label">' + label + '</label>')
-                .appendTo(wrapper);
             var latestPoint = data[i]['points'].slice(-1).pop();
             var latestValue = latestPoint['y'];
             if(type === 'value') {
@@ -189,11 +204,12 @@ wok.widget.LineChart = function(params) {
                     formatSettings
                 );
             }
-            else {
-                latestValue += '%';
+            else {           
+                 latestValue = { v: latestValue, s: '%' };
             }
-            $('<div class="latest-value">' + latestValue + '</div>')
-                .appendTo(wrapper);
+            $('<div class="latest-value"><span class="number">' + latestValue.v + '</span></div>').appendTo(wrapper);
+            $('<span class="legend-label">'+ latestValue.s +'</span><span class="legend-string">'+ label + '</span>').appendTo(wrapper[0].children[1]);
+
         });
     };
 
diff --git a/ui/js/src/wok.list.js b/ui/js/src/wok.list.js
new file mode 100644
index 0000000..21aa9fd
--- /dev/null
+++ b/ui/js/src/wok.list.js
@@ -0,0 +1,302 @@
+/*
+ * Project Wok
+ *
+ * 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.
+ */
+wok.widget.List = function(opts) {
+    "use strict";
+    this.opts = $.extend({}, this.opts, opts);
+    this.createDOM();
+    this.reload();
+};
+
+wok.widget.List.prototype = (function() {
+    "use strict";
+    var htmlStr = [
+        '<div id="{id}-section" class="panel panel-default">',
+            '<div class="panel-heading">',
+            '</div>',
+            '<div id="content-{id}" class="panel-body">',
+                '<div id="{id}-container">',
+                    '<div class="wok-list-message clearfix hidden">',
+                        '<div class="alert alert-danger fade in" role="alert">',
+                            '<p><strong>{message}</strong> ',
+                            '<span class="detailed-text"></span></p>',
+                            '<p><button class="btn btn-primary btn-xs retry-button">',
+                                '{buttonLabel}',
+                            '</button></p>',
+                        '</div>',
+                    '</div>',
+                    '<div id="{id}-btn-group" class="btn-group wok-single-button hidden">',
+
+                    '</div>',
+                    '<div id="{id}" class="row clearfix">',
+                        '<div class="wok-list-content">',
+                            '<table class="wok-list-table table table-striped" id="list">',
+                            '</table>',
+                        '</div>',
+                    '</div>',
+                    '<div class="wok-list-mask hidden">',
+                        '<div class="wok-list-loader-container">',
+                            '<div class="wok-list-loading">',
+                                '<div class="wok-list-loading-icon"></div>',
+                                '<div class="wok-list-loading-text">',
+                                    '{loading}',
+                                '</div>',
+                            '</div>',
+                        '</div>',
+                    '</div>',
+                '</div>',
+            '</div>',
+        '</div>'
+    ].join('');
+
+    var getValue = function(name, obj) {
+        var result;
+        if (!Array.isArray(name)) {
+            name = name.parseKey();
+        }
+        if (name.length !== 0) {
+            var tmpName = name.shift();
+            if (obj[tmpName] !== undefined) {
+                result = obj[tmpName];
+            }
+            if (name.length !== 0) {
+                result = getValue(name, obj[tmpName]);
+            }
+        }
+        return (result);
+    };
+
+
+    var fillButton = function(btnContainer){
+        var addOrGenerateBtn = this.opts.toolbarButtons[0];
+        var singleBtnHTML = [
+                '<a class="btn btn-primary" href="#"', (addOrGenerateBtn.id ? (' id="' + addOrGenerateBtn.id + '"') : ''),' role="button">',
+                    addOrGenerateBtn.class ? ('<i class="' + addOrGenerateBtn.class) + '"></i> ' : '',
+                    addOrGenerateBtn.label,
+                '</a>'
+            ].join('');
+            var singleBtn = $(singleBtnHTML).appendTo(btnContainer);
+            $(singleBtn).click(function(e) {
+              e.preventDefault();
+            });
+            addOrGenerateBtn.onClick && singleBtn.on('click', addOrGenerateBtn.onClick);
+    };
+
+    var fillBody = function(container, fields) {
+
+        var toolbarButtons = this.opts.toolbarButtons;
+        var actionDropdownHtml;
+        var data = this.data;
+        var tbody = ($('tbody', container).length && $('tbody', container)) || $('<tbody></tbody>').appendTo(container);
+        tbody.empty();
+        if (typeof data !== 'undefined' && data.length > 0) {
+            $.each(data, function(i, row) {
+                var rowNode = $('<tr></tr>').appendTo(tbody);
+                var columnNodeHTML;
+                var columnData = '';
+                var state = '';
+                var styleClass = '';
+                if (toolbarButtons) {
+                    actionDropdownHtml = [
+                        '<td>',
+                            '<div class="dropdown menu-flat">',
+                                '<button id="wok-dropdown-button-', i, '" class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">',
+                                    '<span class="edit-alt"></span>Actions<span class="caret"></span>',
+                                '</button>',
+                                '<ul class="dropdown-menu" role="menu" aria-labelledby="action-dropdown-menu-', i, '">',
+                                '</ul>',
+                            '</div>',
+                        '</td>'
+                    ].join('');
+                }
+                $.each(fields, function(fi, field) {
+                    var value = getValue(field.name, row);
+                    if (field.type === 'status' && field.name === 'enabled') {
+                        styleClass = (value === true ? '' : ' disabled');
+                        state = [
+                            '<span class="wok-repository-status ',
+                            value === true ? 'enabled' : 'disabled',
+                            '"><i class="fa fa-power-off"></i></span>'
+                        ].join('');
+                    }
+                    columnData += (field.type === 'name') ? ('<span class="wok-list-name">' + value.toString() + '</span>') : (field.type !== 'status' ? '<span class="wok-list-loading-icon-inline"></span><span class="wok-list-description">' + value.toString() + '</span>' : '');
+
+                });
+                columnNodeHTML = [
+                    '<td>',
+                        '<div class="wok-list-cell', styleClass, '">', state,
+                            columnData,
+                        '</div>',
+                    '</td>'
+                ].join('');
+                $(columnNodeHTML).appendTo(rowNode);
+
+                var actionMenuNode = $(actionDropdownHtml).appendTo(rowNode);
+
+                $.each(toolbarButtons, function(i, button) {
+                    var btnHTML = [
+                        '<li role="presentation"', button.critical === true ? ' class="critical"' : '', '>',
+                        '<a role="menuitem" tabindex="-1" data-dismiss="modal"', (button.id ? (' id="' + button.id + '"') : ''), (button.disabled === true ? ' class="disabled"' : ''),
+                        '>',
+                        button.class ? ('<i class="' + button.class) + '"></i>' : '',
+                        button.label,
+                        '</a></li>'
+                    ].join('');
+                    var btnNode = $(btnHTML).appendTo($('.dropdown-menu', rowNode));
+                    button.onClick && btnNode.on('click', button.onClick);
+                });
+            });        
+        } 
+    };
+
+    var stylingRow = function(row, className, add) {
+        var index = $(row).index() + 1;
+        $('tr', this.bodyContainer)
+            .removeClass(className);
+        if (add === false) {
+            return;
+        }
+        $('tr:nth-child(' + index + ')', this.bodyContainer)
+            .addClass(className);
+    };
+
+    var setBodyListeners = function() {
+        if (this['opts']['rowSelection'] != 'disabled') {
+
+            $('tr', this.bodyContainer).on('click', {
+                grid: this
+            }, function(event) {
+                var grid = event.data.grid;
+                if (!$(this).hasClass('generating')) {
+                    grid.selectedIndex = $(this).index();
+                    stylingRow.call(grid, this, 'selected');
+                    grid['opts']['onRowSelected'] && grid['opts']['onRowSelected']();
+                }
+            });
+        }
+    };
+
+    var setData = function(data) {
+        this.data = data;
+        fillBody.call(this, this.bodyContainer, this.opts.fields);
+        setBodyListeners.call(this);
+    };
+
+    var getSelected = function() {
+        return this.selectedIndex >= 0 ? this.data[this.selectedIndex] : null;
+    };
+
+    var showMessage = function(msg) {
+        $('.detailed-text', this.messageNode).text(msg);
+        $(this.messageNode).removeClass('hidden');
+    };
+
+    var hideMessage = function() {
+        $(this.messageNode).addClass('hidden');
+    };
+
+    var reload = function() {
+        var data = this.opts.data;
+        if (!data) {
+            return;
+        }
+
+        if ($.isArray(data)) {
+            return this.setData(data);
+        }
+
+        if ($.isFunction(data)) {
+            var loadData = data;
+            $(this.maskNode).removeClass('hidden');
+            loadData($.proxy(function(data) {
+                this.setData(data);
+                $(this.maskNode).addClass('hidden');
+            }, this));
+        }
+    };
+
+    var createDOM = function() {
+        var containerID = this.opts.container;
+        var container = $('#' + containerID);
+        var gridID = this.opts.id;
+        var data = this.opts.data;
+        var rowSelection = this.opts.rowSelection || 'single';
+        var domNode = $(wok.substitute(htmlStr, {
+            id: gridID,
+            loading: i18n.KCHGRD6001M,
+            message: i18n.KCHGRD6002M,
+            buttonLabel: i18n.KCHGRD6003M,
+            detailedLabel: i18n.KCHGRD6004
+        })).appendTo(container);
+        this.domNode = domNode;
+
+
+        var titleContainer = $('.panel-heading', domNode);
+        this.titleContainer = titleContainer;
+
+        var title = this.opts.title;
+        var titleNode = null;
+
+        if (title) {
+            titleNode = $('<h3 class="panel-title">' + title + '</h3>').appendTo(titleContainer);
+        }
+
+        var bodyContainer = $('.wok-list-table.table.table-striped', domNode);
+        this.bodyContainer = bodyContainer;
+
+        var singleButtonContainer = $('.wok-single-button', domNode);
+        this.singleButtonContainer = singleButtonContainer;
+
+        var gridBody = $('.wok-list-content', domNode);
+        this.gridBody = gridBody;
+
+        var maskNode = $('.wok-list-mask', domNode);
+        this.maskNode = maskNode;
+
+        var messageNode = $('.wok-list-message', domNode);
+        this.messageNode = messageNode;
+
+
+        fillButton.call(this,this.singleButtonContainer);
+
+        $('.retry-button', domNode).on('click', {
+            grid: this
+        }, function(event) {
+            event.data.grid.reload();
+        });
+
+
+    };
+
+    return {
+        opts: {
+            container: null,
+            id: null,
+            rowSelection: 'single',
+            onRowSelected: null,
+            title: null,
+            toolbarButtons: null,
+            frozenFields: null,
+            fields: null
+        },
+        createDOM: createDOM,
+        setData: setData,
+        getSelected: getSelected,
+        reload: reload,
+        showMessage: showMessage
+    };
+})();
\ No newline at end of file
diff --git a/ui/js/src/wok.login.js b/ui/js/src/wok.login.js
index d9ccae6..13a1da0 100644
--- a/ui/js/src/wok.login.js
+++ b/ui/js/src/wok.login.js
@@ -18,9 +18,12 @@
  * limitations under the License.
  */
 wok.login_main = function() {
-
+    "use strict";
     var selectedLanguage = wok.lang.get();
     $('#userLang').val(selectedLanguage);
+    $('#userLang option[value="'+selectedLanguage+'"]').attr("selected", "selected"); 
+    $('#userLang').next().find('.selectpicker').attr('title',$('#userLang option[value="'+selectedLanguage+'"]').text());    
+    $('#userLang').next().children().find('.filter-option').text($('#userLang option[value="'+selectedLanguage+'"]').text());
 
     $('#userLang').on('change', function() {
         wok.lang.set($(this).val());
@@ -29,7 +32,7 @@ wok.login_main = function() {
 
     var query = window.location.search;
     var error = /.*error=(.*?)(&|$)/g.exec(query);
-    if (error && error[1] == "sessionTimeout") {
+    if (error && error[1] === "sessionTimeout") {
         $("#messSession").show();
     }
 
@@ -59,7 +62,7 @@ wok.login_main = function() {
                 var next_url = lastPage ? lastPage.replace(/\"/g,'') : "/";
             }
             wok.cookie.set('roles',JSON.stringify(data.roles));
-            window.location.replace(window.location.pathname.replace(/\/+login.html/, '') + next_url)
+            window.location.replace(window.location.pathname.replace(/\/+login.html/, '') + next_url);
         }, function() {
             $("#messUserPass").show();
             $("#messSession").hide();
diff --git a/ui/js/src/wok.main.js b/ui/js/src/wok.main.js
index 25fed31..1330ac1 100644
--- a/ui/js/src/wok.main.js
+++ b/ui/js/src/wok.main.js
@@ -27,6 +27,7 @@ wok.main = function() {
         var tabsHtml = [];
         $(tabs).each(function(i, tab) {
             var title = tab['title'];
+            var cssClass = tab['css'];
             var path = tab['path'];
             var mode = tab['mode'];
             if (mode != 'none') {
@@ -34,10 +35,10 @@ wok.main = function() {
                 var disableHelp = (helpPath.length == 0 ? "disableHelp" : helpPath);
                 tabsHtml.push(
                     '<li>',
-                        '<a class="item ', disableHelp,'" href="', path, '">',
+                        '<a class="item ', disableHelp,' ',cssClass,'" href="', path, '">',
                             title,
                         '</a>',
-                        '<input id="helpPathId" name="helpPath" value="' + helpPath + '" type="hidden"/>',
+                        '<input id="helpPathId" name="helpPath" class="sr-only" value="' + helpPath + '" type="hidden"/>',
                     '</li>'
                 );
             }
@@ -51,6 +52,7 @@ wok.main = function() {
             var $tab = $(this);
             var titleKey = $tab.find('title').text();
             var title = i18n[titleKey] ? i18n[titleKey] : titleKey;
+            var css = $tab.find('class').text();
             var path = $tab.find('path').text();
             var roles = wok.cookie.get('roles');
             if (roles) {
@@ -60,6 +62,7 @@ wok.main = function() {
                 tabs.push({
                     title: title,
                     path: path,
+                    css: css,
                     mode: mode
                 });
             } else {
@@ -113,7 +116,8 @@ wok.main = function() {
             DEFAULT_HASH = defaultTabPath &&
                 defaultTabPath.substring(0, defaultTabPath.lastIndexOf('.'))
             }
-            $('#nav-menu').append(genTabs(tabs));
+            $('#nav-menu ul.navbar-nav li.hostname').after(genTabs(tabs));
+            wok.getHostname();
 
             callback && callback();
         }, function(data) {
@@ -142,7 +146,7 @@ wok.main = function() {
          * point to the tab. If nothing found, inform user the URL is invalid
          * and clear location.hash to jump to home page.
          */
-        var tab = $('#nav-menu a[href="' + url + '"]');
+        var tab = $('#nav-menu ul li a[href="' + url + '"]');
         if (tab.length === 0 && url!='wok-empty.html') {
             location.hash = '';
             return;
@@ -150,20 +154,14 @@ wok.main = function() {
 
         //Remove the tab arrow indicator for no plugin
         if(url=='wok-empty.html'){
-          $('.menu-arrow').hide();
           $('#main').html('No plugins installed currently.You can download the available plugins <a href="https://github.com/kimchi-project/kimchi">Kimchi</a> and <a href="https://github.com/kimchi-project/ginger">Ginger</a> from Github').addClass('noPluginMessage');
         }else{
-        // Animate arrow indicator.
-        var left = $(tab).parent().position().left;
-        var width = $(tab).parent().width();
-        $('.menu-arrow').stop().animate({
-            left : left + width / 2 - 10
-        });
-
+        
         // Update the visual style of tabs; focus the selected one.
-        $('#nav-menu a').removeClass('current');
-        $(tab).addClass('current');
+        $('#nav-menu ul li').removeClass('active');
+        $(tab).parent().addClass('active');
         $(tab).focus();
+
         // Disable Help button according to selected tab
         if ($(tab).hasClass("disableHelp")) {
             $('#btn-help').css('cursor', "not-allowed");
@@ -240,7 +238,7 @@ wok.main = function() {
          * Register click listener of tabs. Replace the default reloading page
          * behavior of <a> with Ajax loading.
          */
-        $('#nav-menu').on('click', 'a.item', function(event) {
+        $('#nav-menu ul li').on('click', 'a.item', function(event) {
             var href = $(this).attr('href');
             // Remove file extension from 'href'
             location.hash = href.substring(0,href.lastIndexOf('.'))
@@ -279,7 +277,7 @@ wok.main = function() {
         $('#peers').on('click', function() {
 
             // Check if any request is in progress
-            if ($('.popover', '#peers').is(':visible') || searchingPeers == true)
+            if ($('.dropdown', '#peers').is('.open') || searchingPeers == true)
                 return
 
             $('#search-peers').show();
@@ -294,7 +292,7 @@ wok.main = function() {
                     $('#no-peers').removeClass('hide-content');
 
                 for(var i=0; i<data.length; i++){
-                    $('.dropdown', '#peers').append("<a href='"+data[i]+"' target='_blank'>"+data[i]+"</a>");
+                    $('.dropdown-menu ', '#peers').append("<li><a href='"+data[i]+"' target='_blank'>"+data[i]+"</a></li>");
                 }
                 searchingPeers = false;
             });
@@ -329,6 +327,28 @@ wok.main = function() {
         wok.user.showUser(true);
         initListeners();
         updatePage();
+        
+        // Overriding Bootstrap Modal windows to allow a stack of modal windows and backdrops
+        $(document).on({
+            'show.bs.modal': function () {
+                var zIndex = 1040 + (10 * $('.modal:visible').length);
+                $(this).css('z-index', zIndex);
+                setTimeout(function() {
+                    $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
+                }, 0);
+            },
+            'hidden.bs.modal': function() {
+                if ($('.modal:visible').length > 0) {
+                    // restore the modal-open class to the body element, so that scrolling works
+                    // properly after de-stacking a modal.
+                    setTimeout(function() {
+                        $(document.body).addClass('modal-open');
+                    }, 0);
+                }
+            }
+        }, '.modal'); 
+
+
     };
 
     // Load i18n translation strings first and then render the page.
@@ -361,10 +381,15 @@ wok.checkHelpFile = function(path) {
     return url;
 };
 
+wok.getHostname = function(e) {
+    host = window.location.hostname;
+    $('span.host-location').text(host);
+    return host;
+}
 
 wok.openHelp = function(e) {
     var tab = $('#nav-menu a.current');
     var url = $(tab).parent().find("input[name='helpPath']").val();
     window.open(url, "Wok Help");
     e.preventDefault();
-};
+};
\ No newline at end of file
diff --git a/ui/js/src/wok.message.js b/ui/js/src/wok.message.js
index bd650e0..ce6ba25 100644
--- a/ui/js/src/wok.message.js
+++ b/ui/js/src/wok.message.js
@@ -18,101 +18,48 @@
  * limitations under the License.
  */
 wok.message = function(msg, level, node) {
-    var container = node || $('#messageField');
+    "use strict";
+    var container = node || $('#alert-fields');
     if ($(container).size() < 1) {
-        container = $('<div id="messageField"/>').appendTo(document.body);
+        container = $('<div id="alert-fields"/>').appendTo($('#alert-container'));
     }
-    var message = '<div class="message ' + (level || '') + '" style="display: none;">';
+    var message = '<div role="alert" class="alert ' + (level || '') + ' alert-dismissible fade in" style="display: none;">';
     if(!node) {
-        message += '<div class="close">X</div>';
+        message += '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true"><i class="fa fa-times-circle"></i></span></button>';
     }
-    message += '<div class="content">' + msg + '</div>';
+    message += msg;
     message += '</div>';
     var $message = $(message);
     $(container).append($message);
+    $message.alert();
     $message.fadeIn(100);
 
     setTimeout(function() {
         $message.fadeOut(2000, function() {
+            $message.alert('close');
             $(this).remove();
+            $(container).remove();
+            if ($(container).children().length < 1) {
+                $(container).remove();
+            }
         });
     }, 4000);
-
-    $(container).on("click", ".close", function(e) {
-        $(this).parent().fadeOut(200, function() {
-            $(this).remove();
-        });
-    });
-};
-
-/**
- * A public function of confirm box.
- *
- * @param msg
- *            type:[object]
- * @param msg.title
- *            The title of the confirm box.
- * @param msg.content
- *            The main text of the confirm box.
- * @param msg.confirm
- *            The text of the confirm button.
- * @param msg.cancel
- *            the text of the cancel button.
- * @param confirmCallback
- *            the callback function of click the confirm button.
- * @param cancelCallback
- *            The callback function of click the cancel and X button.
- */
-wok.confirm = function(settings, confirmCallback, cancelCallback) {
-    if ($('#confirmbox-container ').size() < 1) {
-        $(document.body).append('<div id="confirmbox-container" class="bgmask"></div>');
-    }
-    var confirmboxHtml = '<div class="confirmbox">';
-    confirmboxHtml += '<header>';
-    confirmboxHtml += '<h4 class="title">' + (settings.title || '') + '</h4>';
-    confirmboxHtml += '<div class="close cancel">X</div>';
-    confirmboxHtml += '</header>';
-    confirmboxHtml += '<div class="content">';
-    confirmboxHtml += settings.content + '</div>';
-    confirmboxHtml += '<footer>';
-    confirmboxHtml += '<div class="btn-group">';
-    confirmboxHtml += '<button id="button-confirm" class="btn-small"><span class="text">' + (settings.confirm || i18n['KCHAPI6004M']) + '</span></button>';
-    confirmboxHtml += '<button id="button-cancel" class="btn-small cancel"><span class="text">' + (settings.cancel || i18n['KCHAPI6003M']) + '</span></button>';
-    confirmboxHtml += '</div>';
-    confirmboxHtml += '</footer>';
-    confirmboxHtml += '</div>';
-    var confirmboxNode = $(confirmboxHtml);
-    $('#confirmbox-container').append(confirmboxNode);
-    confirmboxNode.fadeIn();
-
-    $('#confirmbox-container').on("click", "#button-confirm", function(e) {
-        if (confirmCallback) {
-            confirmCallback();
-        }
-        confirmboxNode.fadeOut(1, function() {
-            $('#confirmbox-container').remove();
-        });
-    });
-    $('#confirmbox-container').on("click", ".cancel", function(e) {
-        if (cancelCallback) {
-            cancelCallback();
-        }
-        confirmboxNode.fadeOut(1, function() {
-            $('#confirmbox-container').remove();
-        });
-    });
 };
 
 wok.message.warn = function(msg, node) {
-    wok.message(msg, 'warn', node);
+    "use strict";
+    wok.message(msg, 'alert-warning', node); 
 };
 wok.message.error = function(msg, node) {
-    wok.message(msg, 'error', node);
+    "use strict";
+    wok.message(msg, 'alert-danger', node);
 };
 wok.message.error.code = function(code) {
-    msg = code + ": " + i18n[code]
-    wok.message(msg, 'error');
+    "use strict";
+    msg = code + ": " + i18n[code];
+    wok.message(msg, 'alert-danger');
 };
 wok.message.success = function(msg, node) {
-    wok.message(msg, 'success', node);
+    "use strict";
+    wok.message(msg, 'alert-success', node);
 };
diff --git a/ui/js/src/wok.window.js b/ui/js/src/wok.window.js
index ef00a77..d50fc6d 100644
--- a/ui/js/src/wok.window.js
+++ b/ui/js/src/wok.window.js
@@ -18,13 +18,16 @@
  * limitations under the License.
  */
 wok.window = (function() {
+    "use strict";
     var _windows = [];
     var _listeners = {};
-    var open = function(settings) {
-        var settings = jQuery.type(settings) === 'object' ? settings : {
+    var open = function(settings, target) {
+        settings = jQuery.type(settings) === 'object' ? settings : {
             url: settings
         };
 
+        target = (typeof target === 'undefined') ? 'modalWindow' : target;
+
         var windowID = settings['id'] || 'window-' + _windows.length;
 
         if ($('#' + windowID).length) {
@@ -33,14 +36,15 @@ wok.window = (function() {
 
         _windows.push(windowID);
         _listeners[windowID] = settings['close'];
-        var windowNode = $('<div></div>', {
-            id: windowID,
-            'class': settings['class'] ? settings['class'] + ' bgmask remove-when-logged-off' : 'bgmask remove-when-logged-off'
-        });
+        var windowNode = $('<div id="' + windowID + '" class="modal-dialog"></div>');
 
-        $(windowNode).css(settings['style'] || '');
+        $('#' + target).modal('show');
 
-        $(windowNode).appendTo('body').on('click', '.window .close', function() {
+        $('#' + target).on('hidden.bs.modal', function() {
+            $('#' + windowID).remove();
+        });
+
+        $(windowNode).appendTo('#' + target).on('click', '.window .close', function() {
             wok.window.close();
         });
 
@@ -54,15 +58,16 @@ wok.window = (function() {
 
     var close = function() {
         var windowID = _windows.pop();
-        if(_listeners[windowID]) {
+        if (_listeners[windowID]) {
             _listeners[windowID]();
             _listeners[windowID] = null;
         }
-        delete _listeners[windowID];
+        $('#' + windowID).parent().modal('toggle');
+        $('#' + windowID).parent().on('hidden.bs.modal', function() {
+            delete _listeners[windowID];
+            $('#' + windowID).remove();
+        })
 
-        $('#' + windowID).fadeOut(100, function() {
-            $(this).remove();
-        });
     };
 
     return {
diff --git a/ui/js/widgets/grid.js b/ui/js/widgets/grid.js
deleted file mode 100644
index 1f47495..0000000
--- a/ui/js/widgets/grid.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Project Wok
- *
- * Copyright IBM, Corp. 2015
- *
- * Code derived from Project Kimchi
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-$(function(){
-$.widget("wok.grid", {
-    options: {
-        enableSorting: true
-    },
-    _create: function() {
-        var that = this;
-        this.element.addClass('grid');
-        var head = $(this.element.children().get(0));
-        var body = $(this.element.children().get(1));
-        head.addClass('header c1 bold grey');
-        if(this.options.enableSorting){
-            head.children().each(function(){
-                var addSorting = "<span>"+$(this).html()+"</span>";
-                addSorting += "<span><div class='icon-angle-up sort-up'></div><div class='icon-angle-down sort-down'></div></span>";
-                $(this).empty().append(addSorting);
-            });
-        }
-        $('.icon-angle-up', head).click(function(){
-            that.sort(head.children().index($(this).parent().parent()), true);
-        });
-        $('.icon-angle-down', head).click(function(){
-            that.sort(head.children().index($(this).parent().parent()), false);
-        });
-        body.addClass('body c1 normal dark-grey');
-        body.children().addClass('row');
-        this._setRowBackgroud();
-    },
-    _setRowBackgroud: function(){
-        var i=0, classes=['odd', 'even'];
-        $(this.element.children().get(1)).children().each(function(){
-            $(this).removeClass('odd');
-            $(this).removeClass('even');
-            $(this).addClass(classes[i]);
-            i = i==0?1:0;
-        });
-    },
-    sort: function(column, assending) {
-        var head = $(this.element.children().get(0));
-        $('.icon-up-dir', head).removeClass('icon-up-dir').addClass('icon-angle-up');
-        $('.icon-down-dir', head).removeClass('icon-down-dir').addClass('icon-angle-down');
-        var columnCell = $(head.children().get(column));
-        if(assending){
-            $('.icon-angle-up', columnCell).removeClass('icon-angle-up').addClass('icon-up-dir');
-        }else{
-            $('.icon-angle-down', columnCell).removeClass('icon-angle-down').addClass('icon-down-dir');
-        }
-        var container = $(this.element.children().get(1));
-        var nodes = [];
-        container.children().each(function(){
-            nodes.push($(this));
-        });
-        nodes.sort(function(a, b){
-            aVal = $(a.children().get(column)).attr('val');
-            bVal = $(b.children().get(column)).attr('val');
-            return aVal.localeCompare(bVal);
-        });
-        if(!assending) nodes.reverse();
-        container.empty();
-        for(var i=0;i<nodes.length;i++){
-            container.append(nodes[i]);
-        }
-        this._setRowBackgroud();
-    },
-    filter: function(keyword) {
-        keyword = keyword.toLowerCase();
-        var container = $(this.element.children().get(1));
-        container.children().each(function(){
-            var hide = true;
-            $(this).children().each(function(){
-                if($(this).attr('val')&&$(this).attr('val').toLowerCase().indexOf(keyword)!=-1){
-                    hide = false;
-                    return false;
-                }
-            });
-            $(this).css('display', hide?'none':'');
-        });
-        this._setRowBackgroud();
-    },
-    addRow: function(rowNode){
-        $(rowNode).addClass('row');
-        this._setRowBackgroud();
-    },
-    deleteRow: function(rowNode){
-        $(rowNode).remove();
-        this._setRowBackgroud();
-    },
-    _destroy: function() {
-        this.element.removeClass('grid');
-        var head = $(this.element.children().get(0));
-        var body = $(this.element.children().get(1));
-        head.removeClass('header c1 bold grey');
-        if(this.options.enableSorting){
-            head.children().each(function(){
-                var oriContent = $($(this).children().get(0)).html()
-                $(this).empty().append(oriContent);
-            });
-        }
-        body.removeClass('body c1 normal dark-grey');
-        body.children().removeClass('row odd even');
-    }
-});
-});
-- 
1.9.3




More information about the Kimchi-devel mailing list