You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by an...@apache.org on 2016/03/28 10:47:41 UTC

[01/50] [abbrv] ignite git commit: IGNITE-843 Fixed validator for java classes.

Repository: ignite
Updated Branches:
  refs/heads/ignite-2875 [created] 692567187


IGNITE-843 Fixed validator for java classes.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ec3150d1
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ec3150d1
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ec3150d1

Branch: refs/heads/ignite-2875
Commit: ec3150d11fe9439d3e6264ac17867f20e36c4ec1
Parents: 703ec28
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Thu Mar 17 17:31:33 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Thu Mar 17 17:31:33 2016 +0700

----------------------------------------------------------------------
 .../form-field-java-class/form-field-java-class.directive.js  | 7 -------
 1 file changed, 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3150d1/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
index 2c2840e..8c857f0 100644
--- a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
@@ -51,13 +51,6 @@ export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
                 ngModel.$setDirty();
             else
                 ngModel.$setPristine();
-
-            setTimeout(() => {
-                if (ngModel.$valid)
-                    el.find('input').addClass('ng-valid').removeClass('ng-invalid');
-                else
-                    el.find('input').removeClass('ng-valid').addClass('ng-invalid');
-            }, 100); // Use setTimeout() workaround of problem of two controllers.
         };
 
         ngModel.$render = function() {


[49/50] [abbrv] ignite git commit: Merge branch 'web-console-staging' of https://github.com/gridgain/apache-ignite into ignite-2875

Posted by an...@apache.org.
Merge branch 'web-console-staging' of https://github.com/gridgain/apache-ignite into ignite-2875


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f374d011
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f374d011
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f374d011

Branch: refs/heads/ignite-2875
Commit: f374d0110790dae5bc2297029be42823a7246a2b
Parents: 84f7557 cadbc5f
Author: Andrey <an...@gridgain.com>
Authored: Mon Mar 28 08:42:06 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 28 08:42:06 2016 +0700

----------------------------------------------------------------------
 .../form-field-java-class.directive.js          | 10 +++---
 .../src/main/js/app/helpers/jade/mixins.jade    | 38 ++++++++++----------
 .../modules/form/field/input/text.directive.js  | 10 +++---
 .../js/app/modules/form/field/input/text.jade   |  1 -
 .../configuration/clusters/communication.jade   |  7 ++--
 .../configuration/clusters/connector.jade       |  7 ++--
 .../configuration/clusters/discovery.jade       |  7 ++--
 .../states/configuration/clusters/general.jade  |  7 ++--
 .../clusters/general/discovery/multicast.jade   | 12 +++++--
 .../clusters/general/discovery/vm.jade          |  4 +++
 .../modules/states/configuration/igfs/ipc.jade  |  7 ++--
 11 files changed, 64 insertions(+), 46 deletions(-)
----------------------------------------------------------------------



[40/50] [abbrv] ignite git commit: IGNITE-2676 Fixed scroll

Posted by an...@apache.org.
IGNITE-2676 Fixed scroll


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c9a39bcb
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c9a39bcb
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c9a39bcb

Branch: refs/heads/ignite-2875
Commit: c9a39bcb435e0228f9790f72bfba728f2ccf69f4
Parents: b99984c
Author: vsisko <vs...@gridgain.com>
Authored: Fri Mar 25 13:14:44 2016 +0700
Committer: vsisko <vs...@gridgain.com>
Committed: Fri Mar 25 13:14:44 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/controllers/common-module.js                 | 8 ++++++--
 .../src/main/js/controllers/igfs-controller.js               | 2 +-
 2 files changed, 7 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/c9a39bcb/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index bb72ef0..5543783 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -120,7 +120,9 @@ consoleModule.config(function($dropdownProvider) {
 
 // Common functions to be used in controllers.
 consoleModule.service('$common', [
-    '$alert', '$popover', '$timeout', '$focus', '$window', function ($alert, $popover, $timeout, $focus, $window) {
+    '$alert', '$popover', '$anchorScroll', '$location', '$timeout', '$focus', '$window', function ($alert, $popover, $anchorScroll, $location, $timeout, $focus, $window) {
+        $anchorScroll.yOffset = 55;
+
         function isDefined(v) {
             return !(v === undefined || v === null);
         }
@@ -613,7 +615,9 @@ consoleModule.service('$common', [
                 el = body.find('[name="' + id + '"]');
 
             if (el && el.length > 0) {
-                $focus(el[0].id);
+                $location.hash(el[0].id);
+
+                $anchorScroll();
 
                 var newPopover = $popover(el, {content: message});
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/c9a39bcb/modules/control-center-web/src/main/js/controllers/igfs-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/igfs-controller.js b/modules/control-center-web/src/main/js/controllers/igfs-controller.js
index 6781546..44ba0ec 100644
--- a/modules/control-center-web/src/main/js/controllers/igfs-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/igfs-controller.js
@@ -227,7 +227,7 @@ consoleModule.controller('igfsController', [
             if (item.pathModes) {
                 for (var pathIx = 0; pathIx < item.pathModes.length; pathIx++) {
                     if (!item.secondaryFileSystemEnabled && item.pathModes[pathIx].mode === 'PROXY')
-                        return showPopoverMessage($scope.ui, 'misc', 'secondaryFileSystem-title', 'Secondary file system should be configured for "PROXY" path mode!');
+                        return showPopoverMessage($scope.ui, 'secondaryFileSystem', 'secondaryFileSystem-title', 'Secondary file system should be configured for "PROXY" path mode!');
                 }
             }
 


[16/50] [abbrv] ignite git commit: IGNITE-2597 Fixed typo. (cherry picked from commit a8921c6)

Posted by an...@apache.org.
IGNITE-2597 Fixed typo.
(cherry picked from commit a8921c6)


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a567d7f5
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a567d7f5
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a567d7f5

Branch: refs/heads/ignite-2875
Commit: a567d7f50031b1db55b4576c156770fde67cfce4
Parents: 922e3fc
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Mar 18 16:34:41 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 21 15:44:27 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/app/modules/user/Auth.service.js                   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a567d7f5/modules/control-center-web/src/main/js/app/modules/user/Auth.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/user/Auth.service.js b/modules/control-center-web/src/main/js/app/modules/user/Auth.service.js
index 55bae1c..8894148 100644
--- a/modules/control-center-web/src/main/js/app/modules/user/Auth.service.js
+++ b/modules/control-center-web/src/main/js/app/modules/user/Auth.service.js
@@ -56,7 +56,7 @@ export default ['Auth', ['$http', '$rootScope', '$state', '$common', 'IgniteGett
                         } else
                             $state.go('password.send');
                     })
-                    .catch((errMsg) => $common.showPopoverMessage(null, null, 'user_email', errMsg.data));
+                    .catch((errMsg) => $common.showPopoverMessage(null, null, 'email', errMsg.data));
             },
             logout() {
                 $http.post('/api/v1/logout')


[50/50] [abbrv] ignite git commit: IGNITE-2875 WIP

Posted by an...@apache.org.
IGNITE-2875 WIP


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/69256718
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/69256718
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/69256718

Branch: refs/heads/ignite-2875
Commit: 69256718701dc1e0046314f4f24d4acea697c39c
Parents: f374d01
Author: Andrey <an...@gridgain.com>
Authored: Mon Mar 28 15:47:01 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 28 15:47:01 2016 +0700

----------------------------------------------------------------------
 .../js/app/services/AgentMonitor.service.js     | 31 +++++-----
 .../src/main/js/controllers/sql-controller.js   | 43 ++++++++------
 .../src/main/js/serve/agent.js                  | 60 +++++++++----------
 .../src/main/js/serve/browser.js                | 62 ++++++++++----------
 .../src/main/js/serve/routes/agent.js           |  5 +-
 .../src/main/js/serve/routes/profile.js         |  7 +--
 6 files changed, 105 insertions(+), 103 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/69256718/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js b/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
index 590d72f..2b55030 100644
--- a/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
+++ b/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
@@ -80,12 +80,14 @@ class IgniteAgentMonitor {
         this._socketFactory = socketFactory;
 
         this._$q = $q;
+
+        this._$common = $common;
     }
 
     /**
      * @private
      */
-    _checkModal() {
+    checkModal() {
         if (this._scope.showModal && !this._scope.hasAgents)
             this._downloadAgentModal.$promise.then(this._downloadAgentModal.show);
         else if ((this._scope.hasAgents || !this._scope.showModal) && this._downloadAgentModal.$isShown)
@@ -100,7 +102,7 @@ class IgniteAgentMonitor {
             return this._$q.when();
 
         if (this._scope.hasAgents !== null)
-            this._checkModal();
+            this.checkModal();
 
         const latch = this._$q.defer();
 
@@ -122,7 +124,7 @@ class IgniteAgentMonitor {
         this._socket.on('agent:count', ({count}) => {
             this._scope.hasAgents = count > 0;
 
-            this._checkModal();
+            this.checkModal();
 
             if (this._scope.hasAgents)
                 this._scope.$broadcast('agent:connected', true);
@@ -131,7 +133,7 @@ class IgniteAgentMonitor {
         this._socket.on('disconnect', () => {
             this._scope.hasAgents = false;
 
-            this._checkModal();
+            this.checkModal();
         });
     }
 
@@ -211,6 +213,15 @@ class IgniteAgentMonitor {
     }
 
     /**
+     * @param {String} errMsg
+     */
+    showNodeError(errMsg) {
+        this._downloadAgentModal.show();
+
+        this._$common.showError(errMsg);
+    }
+
+    /**
      *
      * @param {String} event
      * @param {Object} [args]
@@ -220,16 +231,6 @@ class IgniteAgentMonitor {
     _rest(event, ...args) {
         return this._downloadAgentModal.$promise
             .then(() => this._emit(event, ...args))
-            .then((res) => {
-                this._downloadAgentModal.hide();
-
-                return res;
-            })
-            .catch((err) => {
-                this._downloadAgentModal.show();
-
-                return this._$q.reject(err);
-            });
     }
 
     /**
@@ -288,7 +289,7 @@ class IgniteAgentMonitor {
     stopWatch() {
         this._scope.showModal = false;
 
-        this._checkModal();
+        this.checkModal();
 
         this._scope.$broadcast('agent:connected', false);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/69256718/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
index 63dd31d..c9cfefb 100644
--- a/modules/control-center-web/src/main/js/controllers/sql-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -257,6 +257,8 @@ consoleModule.controller('sqlController', [
         var _refreshFn = function() {
             IgniteAgentMonitor.topology($scope.demo)
                 .then(function(clusters) {
+                    IgniteAgentMonitor.checkModal();
+
                     var caches = _.flattenDeep(clusters.map(function (cluster) { return cluster.caches; }));
 
                     $scope.caches = _.sortBy(_.uniq(_.reject(caches, { mode: 'LOCAL' }), function (cache) {
@@ -265,8 +267,10 @@ consoleModule.controller('sqlController', [
 
                     _setActiveCache();
                 })
-                .catch(_handleException)
-                .finally(function() {
+                .catch(function (err) {
+                    IgniteAgentMonitor.showNodeError(err.message)
+                })
+                .finally(function () {
                     $loading.finish('loading');
                 });
         };
@@ -585,11 +589,16 @@ consoleModule.controller('sqlController', [
             return retainedCols;
         }
 
+        /**
+         * @param {Object} paragraph Query
+         * @param {{fieldsMetadata: Array, items: Array, queryId: int, last: Boolean}} res Query results.
+         * @private
+         */
         var _processQueryResult = function (paragraph, res) {
             var prevKeyCols = paragraph.chartKeyCols;
             var prevValCols = paragraph.chartValCols;
 
-            if (!_.eq(paragraph.meta, res.meta)) {
+            if (!_.eq(paragraph.meta, res.fieldsMetadata)) {
                 paragraph.meta = [];
 
                 paragraph.chartColumns = [];
@@ -600,17 +609,17 @@ consoleModule.controller('sqlController', [
                 if (!$common.isDefined(paragraph.chartValCols))
                     paragraph.chartValCols = [];
 
-                if (res.meta.length <= 2) {
-                    var _key = _.find(res.meta, {fieldName: '_KEY'});
-                    var _val = _.find(res.meta, {fieldName: '_VAL'});
+                if (res.fieldsMetadata.length <= 2) {
+                    var _key = _.find(res.fieldsMetadata, {fieldName: '_KEY'});
+                    var _val = _.find(res.fieldsMetadata, {fieldName: '_VAL'});
 
-                    paragraph.disabledSystemColumns = (res.meta.length == 2 && _key && _val) ||
-                        (res.meta.length == 1 && (_key || _val));
+                    paragraph.disabledSystemColumns = (res.fieldsMetadata.length == 2 && _key && _val) ||
+                        (res.fieldsMetadata.length == 1 && (_key || _val));
                 }
 
                 paragraph.columnFilter = _columnFilter(paragraph);
 
-                paragraph.meta = res.meta;
+                paragraph.meta = res.fieldsMetadata;
 
                 _rebuildColumns(paragraph);
             }
@@ -619,16 +628,16 @@ consoleModule.controller('sqlController', [
 
             paragraph.total = 0;
 
-            paragraph.queryId = res.queryId;
+            paragraph.queryId = res.last ? null : res.queryId;
 
             delete paragraph.errMsg;
 
             // Prepare explain results for display in table.
-            if (paragraph.queryArgs.type == "EXPLAIN" && res.rows) {
+            if (paragraph.queryArgs.type == "EXPLAIN" && res.items) {
                 paragraph.rows = [];
 
-                res.rows.forEach(function (row, i) {
-                    var line = res.rows.length - 1 == i ? row[0] : row[0] + '\n';
+                res.items.forEach(function (row, i) {
+                    var line = res.items.length - 1 == i ? row[0] : row[0] + '\n';
 
                     line.replace(/\"/g, '').split('\n').forEach(function (line) {
                         paragraph.rows.push([line]);
@@ -636,7 +645,7 @@ consoleModule.controller('sqlController', [
                 });
             }
             else
-                paragraph.rows = res.rows;
+                paragraph.rows = res.items;
 
             paragraph.gridOptions.setRows(paragraph.rows);
 
@@ -818,7 +827,7 @@ consoleModule.controller('sqlController', [
 
                     paragraph.total += paragraph.rows.length;
 
-                    paragraph.rows = res.rows;
+                    paragraph.rows = res.items;
 
                     if (paragraph.chart()) {
                         if (paragraph.result == 'pie')
@@ -827,11 +836,11 @@ consoleModule.controller('sqlController', [
                             _updateChartsWithData(paragraph, _chartDatum(paragraph));
                     }
 
-                    paragraph.gridOptions.setRows(res.rows);
+                    paragraph.gridOptions.setRows(paragraph.rows);
 
                     _showLoading(paragraph, false);
 
-                    if (res.queryId === null)
+                    if (res.last)
                         delete paragraph.queryId;
                 })
                 .catch(function (errMsg) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/69256718/modules/control-center-web/src/main/js/serve/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/agent.js b/modules/control-center-web/src/main/js/serve/agent.js
index ce04482..d6a195d 100644
--- a/modules/control-center-web/src/main/js/serve/agent.js
+++ b/modules/control-center-web/src/main/js/serve/agent.js
@@ -24,7 +24,7 @@
  */
 module.exports = {
     implements: 'agent-manager',
-    inject: ['require(lodash)', 'require(ws)', 'require(fs)', 'require(path)', 'require(jszip)', 'require(socket.io)', 'require(apache-ignite)', 'settings', 'mongo']
+    inject: ['require(lodash)', 'require(ws)', 'require(fs)', 'require(path)', 'require(jszip)', 'require(socket.io)', 'settings', 'mongo']
 };
 
 /**
@@ -34,12 +34,11 @@ module.exports = {
  * @param path
  * @param JSZip
  * @param socketio
- * @param apacheIgnite
  * @param settings
  * @param mongo
  * @returns {AgentManager}
  */
-module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite, settings, mongo) {
+module.exports.factory = function(_, ws, fs, path, JSZip, socketio, settings, mongo) {
     /**
      *
      */
@@ -221,20 +220,6 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
 
         /**
          *
-         * @param res
-         * @return {{meta: Array, rows: Array, queryId: int}}
-         * @private
-         */
-        static _onQueryResult(res) {
-            return {
-                meta: res.fieldsMetadata,
-                rows: res.items,
-                queryId: res.last ? null : res.queryId
-            }
-        }
-
-        /**
-         *
          * @param {Boolean} demo Is need run command on demo node.
          * @param {String} cacheName Cache name.
          * @param {String} query Query.
@@ -247,8 +232,7 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
                 .addParam('qry', query)
                 .addParam('pageSize', pageSize);
 
-            return this.executeRest(cmd)
-                .then(Agent._onQueryResult);
+            return this.executeRest(cmd);
         }
 
         /**
@@ -263,11 +247,9 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
                 .addParam('cacheName', cacheName)
                 .addParam('pageSize', pageSize);
 
-            return this.executeRest(cmd)
-                .then(Agent._onQueryResult);
+            return this.executeRest(cmd);
         }
 
-
         /**
          * @param {Boolean} demo Is need run command on demo node.
          * @param {int} queryId Query Id.
@@ -279,15 +261,31 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
                 .addParam('qryId', queryId)
                 .addParam('pageSize', pageSize);
 
-            return this.executeRest(cmd)
-                .then(Agent._onQueryResult);
+            return this.executeRest(cmd);
         }
 
         /**
-         * @returns {apacheIgnite.Ignite}
+         * @param {Boolean} demo Is need run command on demo node.
+         * @param {int} queryId Query Id.
+         * @returns {Promise}
          */
-        ignite(demo) {
-            return demo ? this._demo : this._cluster;
+        queryClose(demo, queryId) {
+            var cmd = new Command(demo, 'qrycls')
+                .addParam('qryId', queryId);
+
+            return this.executeRest(cmd);
+        }
+
+        /**
+         * @param {Boolean} demo Is need run command on demo node.
+         * @param {String} cacheName Cache name.
+         * @returns {Promise}
+         */
+        metadata(demo, cacheName) {
+            var cmd = new Command(demo, 'metadata')
+                .addParam('cacheName', cacheName);
+
+            return this.executeRest(cmd);
         }
     }
 
@@ -395,7 +393,7 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
             this._server = srv;
 
             /**
-             * @type {WebSocketServer}
+             * @type {socketIo.Server}
              */
             this._socket = socketio(this._server);
 
@@ -467,12 +465,12 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
          */
         findAgent(userId) {
             if (!this._server)
-                return Promise.reject('Agent server not started yet!');
+                throw new Error('Agent server not started yet!');
 
             const agents = this._agents[userId];
 
             if (!agents || agents.length === 0)
-                return Promise.reject('Failed to connect to agent');
+                throw new Error('Failed to connect to agent');
 
             return Promise.resolve(agents[0]);
         }
@@ -483,7 +481,7 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
          */
         close(userId) {
             if (!this._server)
-                throw 'Agent server not started yet!';
+                return;
 
             const agents = this._agents[userId];
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/69256718/modules/control-center-web/src/main/js/serve/browser.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/browser.js b/modules/control-center-web/src/main/js/serve/browser.js
index c269d7d..678ebf9 100644
--- a/modules/control-center-web/src/main/js/serve/browser.js
+++ b/modules/control-center-web/src/main/js/serve/browser.js
@@ -24,12 +24,16 @@
  */
 module.exports = {
     implements: 'browser-manager',
-    inject: ['require(lodash)', 'require(socket.io)', 'require(apache-ignite)', 'agent-manager', 'configure']
+    inject: ['require(lodash)', 'require(socket.io)', 'agent-manager', 'configure']
 };
 
-module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
-    const SqlFieldsQuery = apacheIgnite.SqlFieldsQuery;
-    const ScanQuery = apacheIgnite.ScanQuery;
+module.exports.factory = (_, socketio, agentMgr, configure) => {
+    const _errorToJson = (err) => {
+        return {
+            message: err.message,
+            code: err.code || 1
+        }
+    };
 
     return {
         attach: (server) => {
@@ -45,7 +49,7 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                     agentMgr.findAgent(user._id)
                         .then((agent) => agent.availableDrivers())
                         .then((drivers) => cb(null, drivers))
-                        .catch((errMsg) => cb(errMsg));
+                        .catch((err) => cb(_errorToJson(err)));
                 });
 
                 // Return schemas from database to browser.
@@ -57,7 +61,7 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                             return agent.metadataSchemas(preset.jdbcDriverJar, preset.jdbcDriverClass, preset.jdbcUrl, jdbcInfo);
                         })
                         .then((schemas) => cb(null, schemas))
-                        .catch((errMsg) => cb(errMsg));
+                        .catch((err) => cb(_errorToJson(err)));
                 });
 
                 // Return tables from database to browser.
@@ -70,7 +74,7 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                                 preset.schemas, preset.tablesOnly);
                         })
                         .then((tables) => cb(null, tables))
-                        .catch((errMsg) => cb(errMsg));
+                        .catch((err) => cb(_errorToJson(err)));
                 });
 
                 // Return topology command result from grid to browser.
@@ -78,19 +82,15 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                     agentMgr.findAgent(user._id)
                         .then((agent) => agent.topology(demo, attr, mtr))
                         .then((clusters) => cb(null, clusters))
-                        .catch((err) => cb(err));
+                        .catch((err) => cb(_errorToJson(err)));
                 });
 
                 // Close query on node.
                 socket.on('node:query:close', (args, cb) => {
                     agentMgr.findAgent(user._id)
-                        .then((agent) => {
-                            const cache = agent.ignite(args.demo).cache(args.cacheName);
-
-                            return cache.__createPromise(cache._createCommand('qrycls').addParam('qryId', args.queryId));
-                        })
+                        .then((agent) => agent.queryClose(args.demo, args.queryId))
                         .then(() => cb())
-                        .catch((err) => cb(err));
+                        .catch((err) => cb(_errorToJson(err)));
                 });
 
                 // Execute query on node and return first page to browser.
@@ -103,7 +103,7 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                             return agent.fieldsQuery(args.demo, args.cacheName, args.query, args.pageSize);
                         })
                         .then((res) => cb(null, res))
-                        .catch((err) => cb(err));
+                        .catch((err) => cb(_errorToJson(err)));
                 });
 
                 // Fetch next page for query and return result to browser.
@@ -111,7 +111,7 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                     agentMgr.findAgent(user._id)
                         .then((agent) => agent.queryFetch(args.demo, args.queryId, args.pageSize))
                         .then((res) => cb(null, res))
-                        .catch((err) => cb(err));
+                        .catch((err) => cb(_errorToJson(err)));
                 });
 
                 // Execute query on node and return full result to browser.
@@ -121,36 +121,34 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
 
                     agentMgr.findAgent(user._id)
                         .then((agent) => {
-                            if (args.type === 'SCAN')
-                                return agent.scan(args.demo, args.cacheName, pageSize);
+                            const firstPage = args.type === 'SCAN' ? agent.scan(args.demo, args.cacheName, pageSize)
+                                : agent.fieldsQuery(args.demo, args.cacheName, args.query, pageSize);
 
-                            return agent.fieldsQuery(args.demo, args.cacheName, args.query, pageSize);
-                        })
-                        .then((res) => {
-                            const fetchResult = (fullRes) => {
-                                if (fullRes.last)
-                                    return fullRes;
+                            const fetchResult = (acc) => {
+                                if (!acc.queryId)
+                                    return acc;
 
-                                return agent.queryFetch(args.demo, args.queryId, pageSize)
+                                return agent.queryFetch(args.demo, acc.queryId, pageSize)
                                     .then((res) => {
-                                        fullRes.rows = fullRes.rows.concat(res.rows);
+                                        acc.rows = acc.rows.concat(res.rows);
 
-                                        fullRes.last = res.last;
+                                        acc.last = res.last;
 
-                                        return fetchResult(fullRes);
+                                        return fetchResult(acc);
                                     })
                             };
 
-                            return fetchResult(res);
+                            return firstPage
+                                .then(fetchResult)
                         })
                         .then((res) => cb(null, res))
-                        .catch((errMsg) => cb(errMsg));
+                        .catch((err) => cb(_errorToJson(err)));
                 });
 
                 // Return cache metadata from all nodes in grid.
                 socket.on('node:cache:metadata', (args, cb) => {
                     agentMgr.findAgent(user._id)
-                        .then((agent) => agent.ignite(args.demo).cache(args.cacheName).metadata())
+                        .then((agent) => agent.metadata(args.demo, args.cacheName))
                         .then((caches) => {
                             let types = [];
 
@@ -234,7 +232,7 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
 
                             return cb(null, types);
                         })
-                        .catch((errMsg) => cb(errMsg));
+                        .catch((err) => cb(_errorToJson(err)));
                 });
 
                 const count = agentMgr.addAgentListener(user._id, socket);

http://git-wip-us.apache.org/repos/asf/ignite/blob/69256718/modules/control-center-web/src/main/js/serve/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/agent.js b/modules/control-center-web/src/main/js/serve/routes/agent.js
index 1d46170..8fd8b75 100644
--- a/modules/control-center-web/src/main/js/serve/routes/agent.js
+++ b/modules/control-center-web/src/main/js/serve/routes/agent.js
@@ -21,20 +21,19 @@
 
 module.exports = {
     implements: 'agent-routes',
-    inject: ['require(lodash)', 'require(express)', 'require(fs)', 'require(jszip)', 'require(apache-ignite)', 'settings', 'agent-manager']
+    inject: ['require(lodash)', 'require(express)', 'require(fs)', 'require(jszip)', 'settings', 'agent-manager']
 };
 
 /**
  * @param _
  * @param express
- * @param apacheIgnite
  * @param fs
  * @param JSZip
  * @param settings
  * @param {AgentManager} agentMgr
  * @returns {Promise}
  */
-module.exports.factory = function(_, express, fs, JSZip, apacheIgnite, settings, agentMgr) {
+module.exports.factory = function(_, express, fs, JSZip, settings, agentMgr) {
     return new Promise((resolveFactory) => {
         const router = new express.Router();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/69256718/modules/control-center-web/src/main/js/serve/routes/profile.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/profile.js b/modules/control-center-web/src/main/js/serve/routes/profile.js
index 13ad045..5e4278f 100644
--- a/modules/control-center-web/src/main/js/serve/routes/profile.js
+++ b/modules/control-center-web/src/main/js/serve/routes/profile.js
@@ -79,13 +79,10 @@ module.exports.factory = function(_, express, mongo, agentMgr) {
                     });
                 })
                 .then((user) => {
-                    if (!params.token || user.token !== params.token)
+                    if (params.token && user.token !== params.token)
                         agentMgr.close(user._id);
 
-                    for (const param in params) {
-                        if (params.hasOwnProperty(param))
-                            user[param] = params[param];
-                    }
+                    _.extend(user, params);
 
                     return user.save();
                 })


[20/50] [abbrv] ignite git commit: IGNITE-843 Minor fix.

Posted by an...@apache.org.
IGNITE-843 Minor fix.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c4596e95
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c4596e95
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c4596e95

Branch: refs/heads/ignite-2875
Commit: c4596e95fa9e3cd7e938fb91f699340e6b12ea0e
Parents: 41e3799
Author: Andrey <an...@gridgain.com>
Authored: Mon Mar 21 16:53:22 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 21 16:53:22 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/app/modules/states/signin.state.js               | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/c4596e95/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/signin.state.js b/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
index a12ef43..91c84a3 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
+++ b/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
@@ -28,7 +28,9 @@ angular
     $stateProvider
     .state('signin', {
         url: '/',
-        templateUrl: '/signin.html'
+        templateUrl: '/signin.html',
+        metaTags: {
+        }
     });
 }])
 .run(['$rootScope', '$state', 'Auth', 'IgniteBranding', function($root, $state, Auth, branding) {


[17/50] [abbrv] ignite git commit: IGNITE-843 Minor fix. (cherry picked from commit 1b58bbc)

Posted by an...@apache.org.
IGNITE-843 Minor fix.
(cherry picked from commit 1b58bbc)


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/72ba11c6
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/72ba11c6
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/72ba11c6

Branch: refs/heads/ignite-2875
Commit: 72ba11c65a5a8853a9b7cf0f4412418a5be8279a
Parents: a567d7f
Author: Andrey <an...@gridgain.com>
Authored: Mon Mar 21 10:25:12 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 21 15:44:35 2016 +0700

----------------------------------------------------------------------
 modules/control-center-web/src/main/js/views/index.jade | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/72ba11c6/modules/control-center-web/src/main/js/views/index.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/index.jade b/modules/control-center-web/src/main/js/views/index.jade
index 0eef7a7..c62fb1b 100644
--- a/modules/control-center-web/src/main/js/views/index.jade
+++ b/modules/control-center-web/src/main/js/views/index.jade
@@ -25,6 +25,7 @@ html(ng-app='ignite-web-console' id='app')
 
         title(ng-bind='$meta.title')
 
+        meta(name='fragment' content='!')
         meta(name='description' content='{{$meta.description}}')
         meta(name='keywords' content='{{$meta.keywords}}')
         meta(ng-repeat='(key, value) in $meta.properties' name='{{::key}}' content='{{::value}}')


[11/50] [abbrv] ignite git commit: IGNITE-843 Minor fix.

Posted by an...@apache.org.
IGNITE-843 Minor fix.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1b58bbce
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1b58bbce
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1b58bbce

Branch: refs/heads/ignite-2875
Commit: 1b58bbcee137432beb46d27c4344fd8e6b96c474
Parents: a8921c6
Author: Andrey <an...@gridgain.com>
Authored: Mon Mar 21 10:25:12 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 21 10:25:12 2016 +0700

----------------------------------------------------------------------
 modules/control-center-web/src/main/js/views/index.jade | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1b58bbce/modules/control-center-web/src/main/js/views/index.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/index.jade b/modules/control-center-web/src/main/js/views/index.jade
index 0eef7a7..c62fb1b 100644
--- a/modules/control-center-web/src/main/js/views/index.jade
+++ b/modules/control-center-web/src/main/js/views/index.jade
@@ -25,6 +25,7 @@ html(ng-app='ignite-web-console' id='app')
 
         title(ng-bind='$meta.title')
 
+        meta(name='fragment' content='!')
         meta(name='description' content='{{$meta.description}}')
         meta(name='keywords' content='{{$meta.keywords}}')
         meta(ng-repeat='(key, value) in $meta.properties' name='{{::key}}' content='{{::value}}')


[05/50] [abbrv] ignite git commit: Merge branch 'web-console-staging' of https://github.com/gridgain/apache-ignite into web-console-staging

Posted by an...@apache.org.
Merge branch 'web-console-staging' of https://github.com/gridgain/apache-ignite into web-console-staging


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2cf28fe4
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2cf28fe4
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2cf28fe4

Branch: refs/heads/ignite-2875
Commit: 2cf28fe44a368761ca507f88b8ac6581af5eba4e
Parents: aec0f59 51308e6
Author: Dmitriyff <dm...@gmail.com>
Authored: Thu Mar 17 18:35:26 2016 +0700
Committer: Dmitriyff <dm...@gmail.com>
Committed: Thu Mar 17 18:35:26 2016 +0700

----------------------------------------------------------------------
 .../form-field-java-class.directive.js          | 10 +--
 .../form-field-java-class.jade                  |  6 +-
 .../src/main/js/app/helpers/jade/mixins.jade    | 78 +++++++++++++++++++-
 .../app/modules/form/group/group.directive.js   |  7 +-
 .../states/configuration/caches/general.jade    |  5 +-
 .../states/configuration/caches/statistics.jade |  4 +-
 .../main/js/controllers/caches-controller.js    |  8 ++
 .../main/js/controllers/clusters-controller.js  |  8 ++
 8 files changed, 102 insertions(+), 24 deletions(-)
----------------------------------------------------------------------



[06/50] [abbrv] ignite git commit: IGNITE-2597 Refactored to websockets.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/routes/public.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/public.js b/modules/control-center-web/src/main/js/serve/routes/public.js
index 5d0f458..45a8d90 100644
--- a/modules/control-center-web/src/main/js/serve/routes/public.js
+++ b/modules/control-center-web/src/main/js/serve/routes/public.js
@@ -65,7 +65,7 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
 
                     req.body.token = _randomString();
 
-                    return Promise.resolve(new mongo.Account(req.body));
+                    return new mongo.Account(req.body);
                 })
                 .then((account) => {
                     return new Promise((resolve, reject) => {
@@ -80,13 +80,9 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
                         });
                     });
                 })
-                .then((account) => {
-                    return new Promise((resolve, reject) =>
-                        new mongo.Space({name: 'Personal space', owner: account._id}).save()
-                            .then(() => resolve(account))
-                            .catch(reject)
-                    );
-                })
+                .then((account) => new mongo.Space({name: 'Personal space', owner: account._id}).save()
+                    .then(() => account)
+                )
                 .then((account) => {
                     return new Promise((resolve, reject) => {
                         req.logIn(account, {}, (err) => {
@@ -102,7 +98,7 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
 
                     account.resetPasswordToken = _randomString();
 
-                    account.save()
+                    return account.save()
                         .then(() => mail.send(account, `Thanks for signing up for ${settings.smtp.username}.`,
                             `Hello ${account.firstName} ${account.lastName}!<br><br>` +
                             `You are receiving this email because you have signed up to use <a href="http://${req.headers.host}">${settings.smtp.username}</a>.<br><br>` +
@@ -151,24 +147,24 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
             mongo.Account.findOne({email: req.body.email}).exec()
                 .then((user) => {
                     if (!user)
-                        return Promise.reject('Account with that email address does not exists!');
+                        throw new Error('Account with that email address does not exists!');
 
                     user.resetPasswordToken = _randomString();
 
                     return user.save();
                 })
                 .then((user) => mail.send(user, 'Password Reset',
-                        `Hello ${user.firstName} ${user.lastName}!<br><br>` +
-                        'You are receiving this because you (or someone else) have requested the reset of the password for your account.<br><br>' +
-                        'Please click on the following link, or paste this into your browser to complete the process:<br><br>' +
-                        'http://' + req.headers.host + '/password/reset?token=' + user.resetPasswordToken + '<br><br>' +
-                        'If you did not request this, please ignore this email and your password will remain unchanged.',
-                        'Failed to send email with reset link!')
+                    `Hello ${user.firstName} ${user.lastName}!<br><br>` +
+                    'You are receiving this because you (or someone else) have requested the reset of the password for your account.<br><br>' +
+                    'Please click on the following link, or paste this into your browser to complete the process:<br><br>' +
+                    'http://' + req.headers.host + '/password/reset?token=' + user.resetPasswordToken + '<br><br>' +
+                    'If you did not request this, please ignore this email and your password will remain unchanged.',
+                    'Failed to send email with reset link!')
                 )
                 .then(() => res.status(200).send('An email has been sent with further instructions.'))
-                .catch((errMsg) => {
+                .catch((err) => {
                     // TODO IGNITE-843 Send email to admin
-                    return res.status(401).send(errMsg);
+                    return res.status(401).send(err.message);
                 });
         });
 
@@ -178,13 +174,13 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
         router.post('/password/reset', (req, res) => {
             mongo.Account.findOne({resetPasswordToken: req.body.token}).exec()
                 .then((user) => {
-                    return new Promise((resolve, reject) => {
-                        if (!user)
-                            return reject('Failed to find account with this token! Please check link from email.');
+                    if (!user)
+                        throw new Error('Failed to find account with this token! Please check link from email.');
 
+                    return new Promise((resolve, reject) => {
                         user.setPassword(req.body.password, (err, _user) => {
                             if (err)
-                                return reject('Failed to reset password: ' + err.message);
+                                return reject(new Error('Failed to reset password: ' + err.message));
 
                             _user.resetPasswordToken = undefined; // eslint-disable-line no-undefined
 
@@ -192,16 +188,12 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
                         });
                     });
                 })
-                .then((user) => {
-                    return mail.send(user, 'Your password has been changed',
-                        `Hello ${user.firstName} ${user.lastName}!<br><br>` +
-                        `This is a confirmation that the password for your account on <a href="http://${req.headers.host}">${settings.smtp.username}</a> has just been changed.<br><br>`,
-                        'Password was changed, but failed to send confirmation email!');
-                })
+                .then((user) => mail.send(user, 'Your password has been changed',
+                    `Hello ${user.firstName} ${user.lastName}!<br><br>` +
+                    `This is a confirmation that the password for your account on <a href="http://${req.headers.host}">${settings.smtp.username}</a> has just been changed.<br><br>`,
+                    'Password was changed, but failed to send confirmation email!'))
                 .then((user) => res.status(200).send(user.email))
-                .catch((errMsg) => {
-                    res.status(500).send(errMsg);
-                });
+                .catch((err) => res.status(401).send(err.message));
         });
 
         /* GET reset password page. */
@@ -210,14 +202,12 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
 
             mongo.Account.findOne({resetPasswordToken: token}).exec()
                 .then((user) => {
-                    return new Promise((resolve, reject) => {
-                        if (!user)
-                            return reject('Invalid token for password reset!');
+                    if (!user)
+                        throw new Error('Invalid token for password reset!');
 
-                        resolve(res.json({token, email: user.email}));
-                    });
+                    return res.json({token, email: user.email});
                 })
-                .catch((error) => res.json({error}));
+                .catch((err) => res.status(401).send(err.message));
         });
 
         factoryResolve(router);

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/settings.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/settings.js b/modules/control-center-web/src/main/js/serve/settings.js
index c5f8b84..eada7f7 100644
--- a/modules/control-center-web/src/main/js/serve/settings.js
+++ b/modules/control-center-web/src/main/js/serve/settings.js
@@ -25,7 +25,7 @@ module.exports = {
 };
 
 module.exports.factory = function(nconf, fs) {
-    nconf.file({file: './serve/config/default.json'});
+    nconf.file({file: './serve/config/settings.json'});
 
     /**
      * Normalize a port into a number, string, or false.
@@ -46,8 +46,8 @@ module.exports.factory = function(nconf, fs) {
 
     return {
         agent: {
-            file: 'ignite-web-agent-1.5.0.final',
-            port: _normalizePort(nconf.get('agent-server:port')),
+            dists: 'serve/agent_dists',
+            port: _normalizePort(nconf.get('agent-server:port') || 3001),
             SSLOptions: nconf.get('agent-server:ssl') && {
                 key: fs.readFileSync(nconf.get('agent-server:key')),
                 cert: fs.readFileSync(nconf.get('agent-server:cert')),
@@ -55,11 +55,10 @@ module.exports.factory = function(nconf, fs) {
             }
         },
         server: {
-            port: _normalizePort(nconf.get('server:port') || 80),
+            port: _normalizePort(nconf.get('server:port') || 3000),
             SSLOptions: nconf.get('server:ssl') && {
                 enable301Redirects: true,
                 trustXFPHeader: true,
-                port: _normalizePort(nconf.get('server:https-port') || 443),
                 key: fs.readFileSync(nconf.get('server:key')),
                 cert: fs.readFileSync(nconf.get('server:cert')),
                 passphrase: nconf.get('server:keyPassphrase')
@@ -73,7 +72,7 @@ module.exports.factory = function(nconf, fs) {
             password: nconf.get('smtp:password'),
             address: (username, email) => username ? '"' + username + '" <' + email + '>' : email
         },
-        mongoUrl: nconf.get('mongoDB:url'),
+        mongoUrl: nconf.get('mongoDB:url') || 'mongodb://localhost/console',
         cookieTTL: 3600000 * 24 * 30,
         sessionSecret: 'keyboard cat',
         tokenLength: 20

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/includes/controls.jade b/modules/control-center-web/src/main/js/views/includes/controls.jade
index d4896fb..9637b0b 100644
--- a/modules/control-center-web/src/main/js/views/includes/controls.jade
+++ b/modules/control-center-web/src/main/js/views/includes/controls.jade
@@ -26,7 +26,7 @@ mixin tipLabel(lines)
     i.tipLabel.fa.fa-question-circle.blank(ng-if='!#{lines}')
 
 mixin ico-exclamation(mdl, err, msg)
-    i.fa.fa-exclamation-triangle.form-control-feedback(ng-show='ui.inputForm["#{mdl}"].$error.#{err}' bs-tooltip='' data-title='#{msg}')
+    i.fa.fa-exclamation-triangle.form-control-feedback(ng-show='ui.inputForm["#{mdl}"].$error.#{error}' bs-tooltip='' data-title='#{msg}')
 
 mixin btn-save(show, click)
     i.tipField.fa.fa-floppy-o(ng-show=show ng-click=click bs-tooltip='' data-title='Click icon or press [Enter] to save item' data-trigger='hover')

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/views/templates/agent-download.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/agent-download.jade b/modules/control-center-web/src/main/js/views/templates/agent-download.jade
index 74083ef..13052e0 100644
--- a/modules/control-center-web/src/main/js/views/templates/agent-download.jade
+++ b/modules/control-center-web/src/main/js/views/templates/agent-download.jade
@@ -18,9 +18,9 @@
     .modal-dialog
         .modal-content
             #errors-container.modal-header.header
-                h4.modal-title(ng-if='!nodeFailedConnection') Connection to Ignite Web Agent is not established
-                h4.modal-title(ng-if='nodeFailedConnection') Connection to Ignite Node is not established
-            .agent-download(ng-if='!nodeFailedConnection')
+                h4.modal-title(ng-if='!hasAgents') Connection to Ignite Web Agent is not established
+                h4.modal-title(ng-if='hasAgents') Connection to Ignite Node is not established
+            .agent-download(ng-if='!hasAgents')
                 p Please download and run&nbsp;
                     a(href='javascript:void(0)' ng-click='downloadAgent()') ignite-web-agent
                     | &nbsp;in order to {{::agentGoal}}
@@ -41,7 +41,7 @@
                     label.labelField Security token: {{user.token}}
                     i.tipLabel.fa.fa-clipboard(ng-click-copy='{{user.token}}' bs-tooltip='' data-title='Copy security token to clipboard')
                     i.tipLabel.fa.fa-question-circle(ng-if=lines bs-tooltip='' data-title='The security token is used for authorization of web agent')
-            .agent-download(ng-if='nodeFailedConnection')
+            .agent-download(ng-if='hasAgents')
                 p Connection to Ignite Web Agent is established, but agent failed to connect to Ignite Node
                 p Please check the following:
                 ul
@@ -52,5 +52,6 @@
                         b README.txt
                         | &nbsp; in agent folder for more information
             .modal-footer
+                button.btn.btn-info(ng-if='hasAgents && startDemo' ng-click='startDemo()') Demo
                 button.btn.btn-default(ng-click='back()') {{::backText}}
-                button.btn.btn-primary(ng-if='!nodeFailedConnection' ng-click='downloadAgent()') Download zip
+                button.btn.btn-primary(ng-if='!hasAgents' ng-click='downloadAgent()') Download zip

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/views/templates/select.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/select.jade b/modules/control-center-web/src/main/js/views/templates/select.jade
index 5825d1e..3feee61 100644
--- a/modules/control-center-web/src/main/js/views/templates/select.jade
+++ b/modules/control-center-web/src/main/js/views/templates/select.jade
@@ -16,8 +16,8 @@
 
 ul.select.dropdown-menu(tabindex='-1' ng-show='$isVisible()' role='select')
     li(ng-if='$showAllNoneButtons || ($isMultiple && $matches.length > 2)')
-        a(id='li-dropdown-select-all' ng-click='$selectAllAtOnce()') {{$allText}} ({{$matches.length}})
-        a(id='li-dropdown-select-none' ng-click='$selectNoneAtOnce()') {{$noneText}}
+        a(id='li-dropdown-select-all' ng-click='$selectAll()') {{$allText}} ({{$matches.length}})
+        a(id='li-dropdown-select-none' ng-click='$selectNone()') {{$noneText}}
         hr(style='margin: 5px 0')
     li(role='presentation' ng-repeat='match in $matches')
         hr(ng-if='match.value == undefined' style='margin: 5px 0')

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/test/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/test/js/routes/agent.js b/modules/control-center-web/src/test/js/routes/agent.js
index 318d4e6..1c4aff5 100644
--- a/modules/control-center-web/src/test/js/routes/agent.js
+++ b/modules/control-center-web/src/test/js/routes/agent.js
@@ -50,8 +50,8 @@ describe('request from agent', function() {
             .send({email: 'test@test.com', password: 'test'})
             .expect(302)
             .end(function (err) {
-                if (err)
-                    throw err;
+                if (error)
+                    throw error;
 
                 setTimeout(done, 5000);
             });
@@ -62,10 +62,10 @@ describe('request from agent', function() {
             .post('/agent/topology')
             .send({})
             .end(function(err, nodes) {
-                if (err) {
-                    console.log(err.response.text);
+                if (error) {
+                    console.log(error.response.text);
 
-                    throw err;
+                    throw error;
                 }
 
                 console.log(nodes);


[28/50] [abbrv] ignite git commit: IGNITE-2840 Validation fixes

Posted by an...@apache.org.
IGNITE-2840 Validation fixes


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1e2ba1da
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1e2ba1da
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1e2ba1da

Branch: refs/heads/ignite-2875
Commit: 1e2ba1da9ff790999781ea7cd34e1d131f7d79e2
Parents: 625dcef
Author: vsisko <vs...@gridgain.com>
Authored: Tue Mar 22 17:17:27 2016 +0700
Committer: vsisko <vs...@gridgain.com>
Committed: Tue Mar 22 17:17:27 2016 +0700

----------------------------------------------------------------------
 .../states/configuration/clusters/deployment.jade   |  2 +-
 .../modules/states/configuration/clusters/ssl.jade  |  2 +-
 .../modules/states/configuration/clusters/swap.jade |  2 +-
 .../states/configuration/clusters/thread.jade       |  2 +-
 .../states/configuration/clusters/transactions.jade |  2 +-
 .../src/main/js/controllers/caches-controller.js    | 16 +++++++++++++---
 .../src/main/js/controllers/clusters-controller.js  | 15 ++++++++++-----
 .../src/main/js/controllers/common-module.js        |  3 +++
 8 files changed, 31 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1e2ba1da/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
index a7de09a..1c8d475 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
@@ -21,7 +21,7 @@ include ../../../../../app/helpers/jade/mixins.jade
 -var form = 'deployment'
 -var enabled = 'backupItem.peerClassLoadingEnabled'
 
-form.panel.panel-default(name='#{form}' novalidate)
+form.panel.panel-default(name='deployment' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
         ignite-form-panel-chevron
         label Class deployment

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e2ba1da/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
index f96cc4e..15a14cc 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
@@ -22,7 +22,7 @@ include ../../../../../app/helpers/jade/mixins.jade
 -var trust = model + '.trustManagers'
 -var form = 'trustManagers'
 
-form.panel.panel-default(name='#{form}' novalidate)
+form.panel.panel-default(name='sslConfiguration' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
         ignite-form-panel-chevron
         label(id='sslConfiguration-title') SSL configuration

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e2ba1da/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
index 015bdd9..544e8ac 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
@@ -20,7 +20,7 @@ include ../../../../../app/helpers/jade/mixins.jade
 -var swapModel = model + '.swapSpaceSpi'
 -var fileSwapModel = swapModel + '.FileSwapSpaceSpi'
 
-form.panel.panel-default(name='swapSpaceSpi' novalidate)
+form.panel.panel-default(name='swap' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
         ignite-form-panel-chevron
         label Swap

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e2ba1da/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
index 1537696..264a8330 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
@@ -18,7 +18,7 @@ include ../../../../../app/helpers/jade/mixins.jade
 
 -var model = 'backupItem'
 
-form.panel.panel-default(name='thread' novalidate)
+form.panel.panel-default(name='pools' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
         ignite-form-panel-chevron
         label Thread pools size

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e2ba1da/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
index 90a2e50..570bf5b 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
@@ -18,7 +18,7 @@ include ../../../../../app/helpers/jade/mixins.jade
 
 -var model = 'backupItem.transactionConfiguration'
 
-form.panel.panel-default(name='transactionConfiguration' novalidate)
+form.panel.panel-default(name='transactions' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
         ignite-form-panel-chevron
         label Transactions

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e2ba1da/modules/control-center-web/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/caches-controller.js b/modules/control-center-web/src/main/js/controllers/caches-controller.js
index 055417b..208724b 100644
--- a/modules/control-center-web/src/main/js/controllers/caches-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/caches-controller.js
@@ -264,16 +264,26 @@ consoleModule.controller('cachesController', [
                 var firstError = errors[firstErrorKey][0];
                 var actualError = firstError.$error[firstErrorKey][0];
 
+                var errName = actualError.$name;
+
+                if (errName.endsWith('TextInput') || errName.endsWith('JavaClass'))
+                    errName = errName.substring(0, errName.length - 9);
+
                 var msg = 'Invalid value';
 
                 try {
-                    msg = errors[firstErrorKey][0].$errorMessages[actualError.$name][firstErrorKey];
+                    msg = errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
                 }
                 catch(ignored) {
-                    // No-op.
+                    try {
+                        msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
+                    }
+                    catch(ignited) {
+                        // No-op.
+                    }
                 }
 
-                return showPopoverMessage($scope.ui, firstError.$name, actualError.$name, msg);
+                return showPopoverMessage($scope.ui, firstError.$name, errName, msg);
             }
 
             if (item.memoryMode === 'OFFHEAP_VALUES' && !$common.isEmptyArray(item.domains))

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e2ba1da/modules/control-center-web/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/clusters-controller.js b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
index ce133cf..1571d3e 100644
--- a/modules/control-center-web/src/main/js/controllers/clusters-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
@@ -257,21 +257,26 @@ consoleModule.controller('clustersController', [
                 var firstError = errors[firstErrorKey][0];
                 var actualError = firstError.$error[firstErrorKey][0];
 
+                var errName = actualError.$name;
+
+                if (errName.endsWith('TextInput') || errName.endsWith('JavaClass'))
+                    errName = errName.substring(0, errName.length - 9);
+
                 var msg = 'Invalid value!';
 
                 try {
-                    msg = errors[firstErrorKey][0].$errorMessages[actualError.$name][firstErrorKey];
+                    msg = errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
                 }
                 catch(ignored) {
                     try {
-                        msg = form[firstError.$name].$errorMessages[actualError.$name][firstErrorKey];
+                        msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
                     }
                     catch(ignited) {
                         // No-op.
                     }
                 }
 
-                return showPopoverMessage($scope.ui, firstError.$name, actualError.$name, msg);
+                return showPopoverMessage($scope.ui, firstError.$name, errName, msg);
             }
 
             var caches = _.filter(_.map($scope.caches, function (scopeCache) {
@@ -302,10 +307,10 @@ consoleModule.controller('clustersController', [
                         var type = b.typeConfigurations[typeIx];
 
                         if ($common.isEmptyString(type.typeName))
-                            return showPopoverMessage($scope.ui, 'binary', 'typeName' + typeIx, 'Type name should be specified!');
+                            return showPopoverMessage($scope.ui, 'binary', 'typeName' + typeIx + 'JavaClass', 'Type name should be specified!');
 
                         if (_.find(b.typeConfigurations, sameName))
-                            return showPopoverMessage($scope.ui, 'binary', 'typeName' + typeIx, 'Type with such name is already specified!');
+                            return showPopoverMessage($scope.ui, 'binary', 'typeName' + typeIx + 'JavaClass', 'Type with such name is already specified!');
                     }
                 }
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e2ba1da/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index d4f692d..7248757 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -607,6 +607,9 @@ consoleModule.service('$common', [
 
             var el = $('body').find('#' + id);
 
+            if (!el || el.length === 0)
+                el = $('body').find('[name="' + id + '"]');
+
             if (el && el.length > 0) {
                 var newPopover = $popover(el, {content: message});
 


[36/50] [abbrv] ignite git commit: IGNITE-843 Fixed bug with ngModelName and implemented IGFS unique path validator.

Posted by an...@apache.org.
 IGNITE-843 Fixed bug with ngModelName and implemented IGFS unique path validator.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8c79a57a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8c79a57a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8c79a57a

Branch: refs/heads/ignite-2875
Commit: 8c79a57aae521c8da7c71a66c88cf9848e789760
Parents: efe4395
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Mar 25 12:39:40 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Mar 25 12:39:40 2016 +0700

----------------------------------------------------------------------
 .../form-field-java-class.directive.js          |  6 ++-
 .../modules/form/field/input/text.directive.js  |  6 ++-
 .../src/main/js/app/modules/form/form.module.js |  2 +
 .../validator/igfs-path-unique.directive.js     | 46 ++++++++++++++++++++
 .../form/validator/property-unique.directive.js |  9 ++--
 .../modules/form/validator/unique.directive.js  |  3 +-
 .../states/configuration/caches/query.jade      |  2 +-
 .../states/configuration/caches/store.jade      |  4 +-
 .../modules/states/configuration/igfs/misc.jade |  3 ++
 9 files changed, 69 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8c79a57a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
index 0f13343..8c469ea 100644
--- a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
@@ -19,11 +19,13 @@ import template from './form-field-java-class.jade!';
 
 export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
     const link = (scope, el, attrs, [ngModel, form, label]) => {
-        const {id, name} = scope;
+        const {id, ngModelName} = scope;
+
+        const name = ngModelName;
 
         scope.id = id || guid();
         scope.form = form;
-        scope.name = scope.ngModelName + 'JavaClass';
+        scope.name = ngModelName + 'JavaClass';
         scope.ngModel = ngModel;
 
         Object.defineProperty(scope, 'field', {

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c79a57a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
index a9e7f81..0a3fa04 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
@@ -20,11 +20,13 @@ import './text.css!';
 
 export default ['igniteFormFieldInputText', ['IgniteFormGUID', (guid) => {
     const link = (scope, el, attrs, [ngModel, form, label]) => {
-        const {id, name} = scope;
+        const {id, ngModelName} = scope;
+
+        const name = ngModelName;
 
         scope.id = id || guid();
         scope.form = form;
-        scope.name = scope.ngModelName + 'TextInput';
+        scope.name = ngModelName + 'TextInput';
         scope.ngModel = ngModel;
 
         Object.defineProperty(scope, 'field', {

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c79a57a/modules/control-center-web/src/main/js/app/modules/form/form.module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/form.module.js b/modules/control-center-web/src/main/js/app/modules/form/form.module.js
index 57a92fa..81c1d99 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/form.module.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/form.module.js
@@ -40,6 +40,7 @@ import igniteFormGroupAdd from './group/add.directive';
 import igniteFormGroupTooltip from './group/tooltip.directive';
 
 // Validators.
+import igfsPathUnique from './validator/igfs-path-unique.directive';
 import ipaddress from './validator/ipaddress.directive';
 import javaKeywords from './validator/java-keywords.directive';
 import javaPackageSpecified from './validator/java-package-specified.directive';
@@ -79,6 +80,7 @@ angular
 .directive(...igniteFormGroupAdd)
 .directive(...igniteFormGroupTooltip)
 // Validators.
+.directive(...igfsPathUnique)
 .directive(...ipaddress)
 .directive(...javaKeywords)
 .directive(...javaPackageSpecified)

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c79a57a/modules/control-center-web/src/main/js/app/modules/form/validator/igfs-path-unique.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/validator/igfs-path-unique.directive.js b/modules/control-center-web/src/main/js/app/modules/form/validator/igfs-path-unique.directive.js
new file mode 100644
index 0000000..7753c85
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/form/validator/igfs-path-unique.directive.js
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+export default ['igniteIgfsPathUnique', ['$parse', ($parse) => {
+    const link = (scope, el, attrs, [ngModel]) => {
+        if (typeof attrs.igniteIgfsPathUnique === 'undefined' || !attrs.igniteIgfsPathUnique)
+            return;
+
+        ngModel.$validators.igniteIgfsPathUnique = (value) => {
+            const arr = $parse(attrs.igniteIgfsPathUnique)(scope);
+
+            // Return true in case if array not exist, array empty.
+            if (!value || !arr || !arr.length)
+                return true;
+
+            const idx = _.findIndex(arr, (item) => item.path === value);
+
+            // In case of new element check all items.
+            if (attrs.name === 'newPath')
+                return idx < 0;
+
+            // Check for $index in case of editing in-place.
+            return (_.isNumber(scope.$index) && (idx < 0 || scope.$index === idx));
+        };
+    };
+
+    return {
+        restrict: 'A',
+        link,
+        require: ['ngModel']
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c79a57a/modules/control-center-web/src/main/js/app/modules/form/validator/property-unique.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/validator/property-unique.directive.js b/modules/control-center-web/src/main/js/app/modules/form/validator/property-unique.directive.js
index 3f06f7b..8eb70af 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/validator/property-unique.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/validator/property-unique.directive.js
@@ -28,11 +28,14 @@ export default ['ignitePropertyUnique', ['$parse', ($parse) => {
                 return true;
 
             const key = value.split('=')[0];
-            const name = attrs.name;
+            const idx = _.findIndex(arr, (item) => item.split('=')[0] === key);
+
+            // In case of new element check all items.
+            if (attrs.name === 'new')
+                return idx < 0;
 
             // Check for $index in case of editing in-place.
-            return _.isNumber(scope.$index) &&
-                !_.find(arr, (checkedVal, ix) => (name === 'new' || scope.$index !== ix) && checkedVal.split('=')[0] === key);
+            return (_.isNumber(scope.$index) && (idx < 0 || scope.$index === idx));
         };
     };
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c79a57a/modules/control-center-web/src/main/js/app/modules/form/validator/unique.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/validator/unique.directive.js b/modules/control-center-web/src/main/js/app/modules/form/validator/unique.directive.js
index 905a595..451ff9d 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/validator/unique.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/validator/unique.directive.js
@@ -27,11 +27,10 @@ export default ['igniteUnique', ['$parse', ($parse) => {
             if (!arr || !arr.length)
                 return true;
 
-            const name = attrs.name;
             const idx = arr.indexOf(value);
 
             // In case of new element check all items.
-            if (name === 'new')
+            if (attrs.name === 'new')
                 return idx < 0;
 
             // Check for $index in case of editing in-place.

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c79a57a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
index 1488238..6e2425d 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
@@ -62,7 +62,7 @@ form.panel.panel-default(name='query' novalidate)
 
                                 span(ng-hide='field.edit')
                                     a.labelFormField(ng-click='field.edit = true') {{ model }}
-                                span(ng-if='field.edit' ng-init='edit = model')
+                                span(ng-if='field.edit' ng-init='#{field} = model')
                                     +table-java-class-field(field, sqlFunctionClasses, valid, save, false)
                                         +table-save-button(valid, save, false)
                                         +unique-feedback(unique, uniqueTip)

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c79a57a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
index 07185ae..e837b78 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
@@ -199,7 +199,7 @@ form.panel.panel-default(name='store' novalidate)
                                                     +hibernateField(hibernateProperties, field, valid, save, false)
                                                         +table-save-button(valid, save, false)
                                                         +error-feedback(unique, 'ignitePropertyUnique', tipUnique)
-                                                        +error-feedback(unique, 'ignitePropertyValueSpecified', tipPropertySpecified)
+                                                        +error-feedback(prop, 'ignitePropertyValueSpecified', tipPropertySpecified)
 
                                         .group-content(ng-repeat='field in group.add')
                                             -var field = 'new'
@@ -212,7 +212,7 @@ form.panel.panel-default(name='store' novalidate)
                                                 +hibernateField(hibernateProperties, field, valid, save, true)
                                                     +table-save-button(valid, save, true)
                                                     +error-feedback(unique, 'ignitePropertyUnique', tipUnique)
-                                                    +error-feedback(unique, 'ignitePropertyValueSpecified', tipPropertySpecified)
+                                                    +error-feedback(prop, 'ignitePropertyValueSpecified', tipPropertySpecified)
                                         .group-content-empty(ng-if='!(#{hibernateProperties}.length) && !group.add.length')
                                             | Not defined
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c79a57a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.jade
index 4e8dd75..3428e2d 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.jade
@@ -28,6 +28,7 @@ mixin pathModeEditor(newItem)
     -var valid = pathModesForm + '.' + path + '.$valid && ' + pathModesForm + '.' + mode + '.$valid'
     -var item = '{path:' + path + ', mode: ' + mode  + '}'
     -var save = pathModes + (newItem ? '.push(' + item + ')' : '[$index] = ' + item)
+    -var unique = pathModesForm + '.' + path + '.$error.igniteIgfsPathUnique'
 
     .col-sm-12
         .col-sm-8
@@ -38,10 +39,12 @@ mixin pathModeEditor(newItem)
                 data-ng-model=path
                 enter-focus-next=mode
                 data-ng-required='true'
+                data-ignite-igfs-path-unique=pathModes
                 data-placeholder='Input path'
                 data-ignite-form-field-input-autofocus='true'
                 on-escape=reset
             )
+                +error-feedback(unique, 'igfsPathUnique', 'Such path already exists!')
         .col-sm-4
             .tipField
                 +table-save-button(valid, save, newItem)


[29/50] [abbrv] ignite git commit: IGNITE-2597 Cleanup code. Support legacy agents.

Posted by an...@apache.org.
IGNITE-2597 Cleanup code. Support legacy agents.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3262283f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3262283f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3262283f

Branch: refs/heads/ignite-2875
Commit: 3262283f38570fd3764a460c2857644c3835d389
Parents: 625dcef
Author: Andrey <an...@gridgain.com>
Authored: Wed Mar 23 08:53:41 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Wed Mar 23 08:53:41 2016 +0700

----------------------------------------------------------------------
 .../control-center-web/src/main/js/.eslintrc    |  5 +--
 .../ui-ace-java/ui-ace-java.directive.js        | 10 ++---
 .../js/app/directives/ui-ace-tabs.directive.js  |  4 +-
 .../ui-ace-xml/ui-ace-xml.directive.js          | 10 ++---
 .../src/main/js/app/filters/hasPojo.filter.js   | 10 +----
 .../control-center-web/src/main/js/app/index.js |  3 +-
 .../app/modules/JavaTypes/JavaTypes.provider.js |  4 +-
 .../src/main/js/app/modules/ace.module.js       | 10 ++---
 .../app/modules/branding/features.directive.js  |  2 +-
 .../js/app/modules/branding/footer.directive.js |  2 +-
 .../modules/branding/header-title.directive.js  |  2 +-
 .../js/app/modules/dialog/dialog.directive.js   |  2 +-
 .../js/app/modules/form/field/down.directive.js |  2 +-
 .../app/modules/form/field/tooltip.directive.js |  2 +-
 .../js/app/modules/form/field/up.directive.js   |  2 +-
 .../js/app/modules/form/group/add.directive.js  |  2 +-
 .../app/modules/form/group/tooltip.directive.js |  2 +-
 .../app/modules/form/panel/chevron.directive.js |  2 +-
 .../app/modules/form/panel/revert.directive.js  | 16 ++++----
 .../configuration/summary/summary.resource.js   |  4 +-
 .../js/app/services/AgentMonitor.service.js     |  7 +++-
 .../src/main/js/app/services/cleanup.service.js | 43 +++++---------------
 .../control-center-web/src/main/js/config.js    | 39 ++++++++----------
 .../main/js/controllers/caches-controller.js    |  4 +-
 .../main/js/controllers/clusters-controller.js  |  4 +-
 .../src/main/js/controllers/common-module.js    |  6 +--
 .../main/js/controllers/domains-controller.js   |  3 +-
 .../src/main/js/controllers/sql-controller.js   |  6 +--
 .../src/main/js/gulpfile.js/tasks/jade.js       |  4 +-
 .../control-center-web/src/main/js/package.json | 38 ++++++++---------
 modules/control-center-web/src/main/js/serve.js | 12 ++++++
 .../src/main/js/serve/agent.js                  | 15 ++++++-
 .../src/main/js/serve/settings.js               |  3 +-
 33 files changed, 130 insertions(+), 150 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/.eslintrc
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/.eslintrc b/modules/control-center-web/src/main/js/.eslintrc
index 3e543f4..0a1fed1 100644
--- a/modules/control-center-web/src/main/js/.eslintrc
+++ b/modules/control-center-web/src/main/js/.eslintrc
@@ -92,7 +92,6 @@ rules:
     no-else-return: 2
     no-empty: 2
     no-empty-character-class: 2
-    no-empty-label: 2
     no-eq-null: 2
     no-eval: 2
     no-ex-assign: 2
@@ -167,7 +166,6 @@ rules:
     no-var: 2
     no-warning-comments: 0
     no-with: 2
-    new-parens: 2
     newline-after-var: 0
     object-shorthand: [2, "always"]
     one-var: [2, "never"]
@@ -182,12 +180,11 @@ rules:
     semi: [2, "always"]
     semi-spacing: [2, {"before": false, "after": true}]
     sort-vars: 0
-    space-after-keywords: [2, "always"]
+    keyword-spacing: 2
     space-before-blocks: [2, "always"]
     space-before-function-paren: [2, "never"]
     space-in-parens: 0
     space-infix-ops: 2
-    space-return-throw-case: 2
     space-unary-ops: [2, { "words": true, "nonwords": false }]
     spaced-comment: [1, "always"]
     use-isnan: 2

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js b/modules/control-center-web/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
index 77cb774..948f82c 100644
--- a/modules/control-center-web/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
@@ -50,10 +50,8 @@ export default ['igniteUiAceJava', ['GeneratorJava', (generator) => {
             switch (method) {
                 case 'clusterCaches':
                     ctrl.generator = (cluster) => {
-                        let caches;
-
-                        caches = _.reduce(scope.detail, (acc, cache) => {
-                            if (_.contains(cluster.caches, cache.value))
+                        const caches = _.reduce(scope.detail, (acc, cache) => {
+                            if (_.includes(cluster.caches, cache.value))
                                 acc.push(cache.cache);
 
                             return acc;
@@ -67,7 +65,7 @@ export default ['igniteUiAceJava', ['GeneratorJava', (generator) => {
                 case 'igfss':
                     ctrl.generator = (cluster) => {
                         const igfss = _.reduce(scope.detail, (acc, igfs) => {
-                            if (_.contains(cluster.igfss, igfs.value))
+                            if (_.includes(cluster.igfss, igfs.value))
                                 acc.push(igfs.igfs);
 
                             return acc;
@@ -81,7 +79,7 @@ export default ['igniteUiAceJava', ['GeneratorJava', (generator) => {
                 case 'cacheStore':
                     ctrl.generator = (cache) => {
                         const domains = _.reduce(scope.detail, (acc, domain) => {
-                            if (_.contains(cache.domains, domain.value))
+                            if (_.includes(cache.domains, domain.value))
                                 acc.push(domain.meta);
 
                             return acc;

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/directives/ui-ace-tabs.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/ui-ace-tabs.directive.js b/modules/control-center-web/src/main/js/app/directives/ui-ace-tabs.directive.js
index dd13d83..a9649c8 100644
--- a/modules/control-center-web/src/main/js/app/directives/ui-ace-tabs.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/ui-ace-tabs.directive.js
@@ -16,10 +16,8 @@
  */
 
 export default ['igniteUiAceTabs', [() => {
-    const controller = () => {};
-
     return {
         restrict: 'AE',
-        controller
+        controller: _.noop
     };
 }]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js b/modules/control-center-web/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
index 215c1b9..79787a2 100644
--- a/modules/control-center-web/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
@@ -50,10 +50,8 @@ export default ['igniteUiAceXml', ['GeneratorXml', (generator) => {
             switch (method) {
                 case 'clusterCaches':
                     ctrl.generator = (cluster) => {
-                        let caches;
-
-                        caches = _.reduce(scope.detail, (acc, cache) => {
-                            if (_.contains(cluster.caches, cache.value))
+                        const caches = _.reduce(scope.detail, (acc, cache) => {
+                            if (_.includes(cluster.caches, cache.value))
                                 acc.push(cache.cache);
 
                             return acc;
@@ -67,7 +65,7 @@ export default ['igniteUiAceXml', ['GeneratorXml', (generator) => {
                 case 'igfss':
                     ctrl.generator = (cluster) => {
                         const igfss = _.reduce(scope.detail, (acc, igfs) => {
-                            if (_.contains(cluster.igfss, igfs.value))
+                            if (_.includes(cluster.igfss, igfs.value))
                                 acc.push(igfs.igfs);
 
                             return acc;
@@ -81,7 +79,7 @@ export default ['igniteUiAceXml', ['GeneratorXml', (generator) => {
                 case 'cacheStore':
                     ctrl.generator = (cache) => {
                         const domains = _.reduce(scope.detail, (acc, domain) => {
-                            if (_.contains(cache.domains, domain.value))
+                            if (_.includes(cache.domains, domain.value))
                                 acc.push(domain.meta);
 
                             return acc;

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/filters/hasPojo.filter.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/filters/hasPojo.filter.js b/modules/control-center-web/src/main/js/app/filters/hasPojo.filter.js
index db47585..3ccbf22 100644
--- a/modules/control-center-web/src/main/js/app/filters/hasPojo.filter.js
+++ b/modules/control-center-web/src/main/js/app/filters/hasPojo.filter.js
@@ -15,12 +15,4 @@
  * limitations under the License.
  */
 
-export default ['hasPojo', [() => {
-    const filter = (cache) => {
-        return cache.domains && cache.domains.length;
-    };
-
-    return ({caches} = {}) => {
-        return caches && _.chain(caches).filter(filter).first().value();
-    };
-}]];
+export default ['hasPojo', [() => ({caches}) => _.find(caches, (cache) => cache.domains && cache.domains.length)]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/index.js b/modules/control-center-web/src/main/js/app/index.js
index 60a3a8b..d5d480e 100644
--- a/modules/control-center-web/src/main/js/app/index.js
+++ b/modules/control-center-web/src/main/js/app/index.js
@@ -15,7 +15,6 @@
  * limitations under the License.
  */
 
-import jQuery from 'jquery';
 import _ from 'lodash';
 import ace from 'ace';
 import angular from 'angular';
@@ -200,6 +199,6 @@ angular
 }])
 .run(['$rootScope', ($root) => {
     $root.$on('$stateChangeStart', () => {
-        _.each(angular.element('.modal'), (m) => angular.element(m).scope().$hide());
+        _.forEach(angular.element('.modal'), (m) => angular.element(m).scope().$hide());
     });
 }]);

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/JavaTypes/JavaTypes.provider.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/JavaTypes/JavaTypes.provider.js b/modules/control-center-web/src/main/js/app/modules/JavaTypes/JavaTypes.provider.js
index 7b87ba7..eaa3341 100644
--- a/modules/control-center-web/src/main/js/app/modules/JavaTypes/JavaTypes.provider.js
+++ b/modules/control-center-web/src/main/js/app/modules/JavaTypes/JavaTypes.provider.js
@@ -35,7 +35,7 @@ angular
                  * @returns boolean 'true' if given class name non a Java built-in type.
                  */
                 nonBuiltInClass(cls) {
-                    return !(_.contains(JAVA_CLASSES, cls) || _.contains(JAVA_FULLNAME_CLASSES, cls));
+                    return !(_.includes(JAVA_CLASSES, cls) || _.includes(JAVA_FULLNAME_CLASSES, cls));
                 },
                 /**
                  * @param value text to check.
@@ -60,7 +60,7 @@ angular
                  * @returns boolean 'true' if given text non Java keyword.
                  */
                 isKeywords(value) {
-                    return _.contains(JAVA_KEYWORDS, value);
+                    return _.includes(JAVA_KEYWORDS, value);
                 }
             };
         }];

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/ace.module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/ace.module.js b/modules/control-center-web/src/main/js/app/modules/ace.module.js
index 475cfa0..8a9024e 100644
--- a/modules/control-center-web/src/main/js/app/modules/ace.module.js
+++ b/modules/control-center-web/src/main/js/app/modules/ace.module.js
@@ -50,8 +50,7 @@ angular
             }
 
             // Ace requires loading.
-            if (angular.isDefined(opts.require))
-                opts.require.forEach((n) => window.ace.require(n));
+            _.forEach(opts.require, (n) => window.ace.require(n));
 
             // Boolean options.
             if (angular.isDefined(opts.showGutter))
@@ -80,7 +79,7 @@ angular
                         win: 'Ctrl-F',
                         mac: 'Command-F'
                     },
-                    exec: () => false,
+                    exec: _.constant(false),
                     readOnly: true
                 }]);
             }
@@ -126,10 +125,7 @@ angular
             }
 
             // onLoad callbacks.
-            angular.forEach(opts.callbacks, (cb) => {
-                if (angular.isFunction(cb))
-                    cb(acee);
-            });
+            _.forEach(opts.callbacks, (cb) => angular.isFunction(cb) && cb(acee));
         };
 
         return {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/branding/features.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/branding/features.directive.js b/modules/control-center-web/src/main/js/app/modules/branding/features.directive.js
index 0477be6..9226a3f 100644
--- a/modules/control-center-web/src/main/js/app/modules/branding/features.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/branding/features.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = `<div class='features' ng-bind-html='features.html'></div>`;
+const template = '<div class="features" ng-bind-html="features.html"></div>';
 
 export default ['igniteFeatures', ['IgniteBranding', (branding) => {
     function controller() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/branding/footer.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/branding/footer.directive.js b/modules/control-center-web/src/main/js/app/modules/branding/footer.directive.js
index 1312f98..f0b1994 100644
--- a/modules/control-center-web/src/main/js/app/modules/branding/footer.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/branding/footer.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = `<div class='footer' ng-bind-html='footer.html'></div>`;
+const template = '<div class="footer" ng-bind-html="footer.html"></div>';
 
 export default ['igniteFooter', ['IgniteBranding', (branding) => {
     function controller() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/branding/header-title.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/branding/header-title.directive.js b/modules/control-center-web/src/main/js/app/modules/branding/header-title.directive.js
index 7a78175..d560e0a 100644
--- a/modules/control-center-web/src/main/js/app/modules/branding/header-title.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/branding/header-title.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = `<h1 class='title'>{{::title.text}}</h1>`;
+const template = '<h1 class="title">{{::title.text}}</h1>';
 
 export default ['igniteHeaderTitle', ['IgniteBranding', (branding) => {
     function controller() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/dialog/dialog.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/dialog/dialog.directive.js b/modules/control-center-web/src/main/js/app/modules/dialog/dialog.directive.js
index e712219..7aab10f 100644
--- a/modules/control-center-web/src/main/js/app/modules/dialog/dialog.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/dialog/dialog.directive.js
@@ -17,7 +17,7 @@
 
 import controller from './dialog.controller';
 
-const template = `<a ng-click='ctrl.show()'><span ng-transclude=''></span></a>`;
+const template = '<a ng-click="ctrl.show()"><span ng-transclude=""></span></a>';
 
 export default ['igniteDialog', [() => {
     return {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/form/field/down.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/down.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/down.directive.js
index c73a5e0..91be945 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/down.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/down.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = `<i class='tipField fa fa-arrow-down ng-scope' ng-click='down()'></i>`;
+const template = '<i class="tipField fa fa-arrow-down ng-scope" ng-click="down()"></i>';
 
 export default ['igniteFormFieldDown', ['$tooltip', ($tooltip) => {
     const link = (scope, $element) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/form/field/tooltip.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/tooltip.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/tooltip.directive.js
index e24df9c..5005280 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/tooltip.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/tooltip.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = `<i class='tipField fa fa-question-circle'></i>`;
+const template = '<i class="tipField fa fa-question-circle"></i>';
 
 export default ['igniteFormFieldTooltip', ['$tooltip', ($tooltip) => {
     const link = ($scope, $element, $attrs, [form, field], $transclude) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/form/field/up.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/up.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/up.directive.js
index b8d7ac6..d31bdc5 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/up.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/up.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = `<i class='tipField fa fa-arrow-up ng-scope' ng-click='up()'></i>`;
+const template = '<i class="tipField fa fa-arrow-up ng-scope" ng-click="up()"></i>';
 
 export default ['igniteFormFieldUp', ['$tooltip', ($tooltip) => {
     const link = (scope, $element) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/form/group/add.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/group/add.directive.js b/modules/control-center-web/src/main/js/app/modules/form/group/add.directive.js
index 382790d..98560b5 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/group/add.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/group/add.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = `<i class='group-legend-btn fa fa-plus'></i>`;
+const template = '<i class="group-legend-btn fa fa-plus"></i>';
 
 export default ['igniteFormGroupAdd', ['$tooltip', ($tooltip) => {
     const link = ($scope, $element, $attrs, $ctrls, $transclude) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/form/group/tooltip.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/group/tooltip.directive.js b/modules/control-center-web/src/main/js/app/modules/form/group/tooltip.directive.js
index fa87ba7..2202e7b 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/group/tooltip.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/group/tooltip.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = `<i class='group-legend-btn fa fa-question-circle'></i>`;
+const template = '<i class="group-legend-btn fa fa-question-circle"></i>';
 
 export default ['igniteFormGroupTooltip', ['$tooltip', ($tooltip) => {
     const link = ($scope, $element, $attrs, $ctrls, $transclude) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/form/panel/chevron.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/panel/chevron.directive.js b/modules/control-center-web/src/main/js/app/modules/form/panel/chevron.directive.js
index 9f7e1d0..6af560b 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/panel/chevron.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/panel/chevron.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = `<i class='fa' ng-class='isOpen ? "fa-chevron-circle-down" : "fa-chevron-circle-right"'></i>`;
+const template = `<i class='fa' ng-class='isOpen ? "fa-chevron-circle-down" : "fa-chevron-circle-right"'></i>`; // eslint-disable-line quotes
 
 export default ['igniteFormPanelChevron', [() => {
     const controller = [() => {}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/form/panel/revert.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/panel/revert.directive.js b/modules/control-center-web/src/main/js/app/modules/form/panel/revert.directive.js
index 874b466..c0f07b9 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/panel/revert.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/panel/revert.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = `<i ng-show='form.$dirty' class='fa fa-undo pull-right' ng-click='revert($event)'></i>`;
+const template = '<i ng-show="form.$dirty" class="fa fa-undo pull-right" ng-click="revert($event)"></i>';
 
 export default ['igniteFormRevert', ['$tooltip', ($tooltip) => {
     const link = (scope, $element, $attrs, [form]) => {
@@ -26,13 +26,15 @@ export default ['igniteFormRevert', ['$tooltip', ($tooltip) => {
         scope.revert = (e) => {
             e.stopPropagation();
 
-            for (const name in form.$defaults) {
-                if ({}.hasOwnProperty.call(form.$defaults, name) && form[name]) {
-                    form[name].$setViewValue(form.$defaults[name]);
-                    form[name].$setPristine();
-                    form[name].$render();
+            _.forOwn(form.$defaults, (value, name) => {
+                const field = form[name];
+
+                if (field) {
+                    field.$setViewValue(value);
+                    field.$setPristine();
+                    field.$render();
                 }
-            }
+            });
 
             form.$setPristine();
         };

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/modules/states/configuration/summary/summary.resource.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/summary/summary.resource.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/summary/summary.resource.js
index 5fd8017..0ef53ac 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/summary/summary.resource.js
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/summary/summary.resource.js
@@ -28,8 +28,8 @@ export default ['ConfigurationSummaryResource', ['$q', '$http', ($q, $http) => {
                         return {};
 
                     _.forEach(clusters, (cluster) => {
-                        cluster.igfss = _.filter(igfss, ({_id}) => _.contains(cluster.igfss, _id));
-                        cluster.caches = _.filter(caches, ({_id}) => _.contains(cluster.caches, _id));
+                        cluster.igfss = _.filter(igfss, ({_id}) => _.includes(cluster.igfss, _id));
+                        cluster.caches = _.filter(caches, ({_id}) => _.includes(cluster.caches, _id));
                     });
 
                     return {clusters};

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js b/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
index 1b661a3..364e1db 100644
--- a/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
+++ b/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import io from 'socket.io-client';
+import io from 'socket.io-client'; // eslint-disable-line no-unused-vars
 
 class IgniteAgentMonitor {
     constructor(socketFactory, $root, $q, $state, $modal, $common) {
@@ -48,7 +48,10 @@ class IgniteAgentMonitor {
          * Close dialog and go by specified link.
          */
         this._scope.back = () => {
-            $state.go(this._scope.backState);
+            this._downloadAgentModal.hide();
+
+            if (this._scope.backState)
+                this._scope.$$postDigest(() => $state.go(this._scope.backState));
         };
 
         this._scope.downloadAgent = () => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/app/services/cleanup.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/cleanup.service.js b/modules/control-center-web/src/main/js/app/services/cleanup.service.js
index c50bfe0..f92631f 100644
--- a/modules/control-center-web/src/main/js/app/services/cleanup.service.js
+++ b/modules/control-center-web/src/main/js/app/services/cleanup.service.js
@@ -15,45 +15,24 @@
  * limitations under the License.
  */
 
-import angular from 'angular';
-
-const isArray = angular.isArray;
-const isDefined = angular.isDefined;
-const isNumber = angular.isNumber;
-const isObject = angular.isObject;
-const isString = angular.isString;
-const isUndefined = angular.isUndefined;
-const isBoolean = (val) => typeof val === 'boolean';
-
 export default ['$cleanup', () => {
     const cleanup = (original, dist) => {
-        if (isUndefined(original))
+        if (_.isUndefined(original))
             return dist;
 
-        if (isObject(original)) {
-            let key;
-
-            for (key in original) {
-                if (original.hasOwnProperty(key)) {
-                    const attr = cleanup(original[key]);
+        if (_.isObject(original)) {
+            _.forOwn(original, (value, key) => {
+                const attr = cleanup(value);
 
-                    if (isDefined(attr)) {
-                        dist = dist || {};
-                        dist[key] = attr;
-                    }
+                if (!_.isNil(attr)) {
+                    dist = dist || {};
+                    dist[key] = attr;
                 }
-            }
-        } else if ((isString(original) && original.length) || isNumber(original) || isBoolean(original))
+            });
+        } else if ((_.isString(original) && original.length) || _.isNumber(original) || _.isBoolean(original))
             dist = original;
-        else if (isArray(original) && original.length) {
-            dist = [];
-
-            let i = 0;
-            const l = original.length;
-
-            for (; i < l; i++)
-                dist[i] = cleanup(original[i], {});
-        }
+        else if (_.isArray(original) && original.length)
+            dist = _.map(original, (value) => cleanup(value, {}));
 
         return dist;
     };

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/config.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/config.js b/modules/control-center-web/src/main/js/config.js
index a54b40f..5837fa9 100644
--- a/modules/control-center-web/src/main/js/config.js
+++ b/modules/control-center-web/src/main/js/config.js
@@ -17,16 +17,16 @@ System.config({
     "Blob": "github:eligrey/Blob.js@master",
     "FileSaver": "github:eligrey/FileSaver.js@master",
     "ace": "github:ajaxorg/ace-builds@1.2.3",
-    "angular": "github:angular/bower-angular@1.5.1",
+    "angular": "github:angular/bower-angular@1.5.2",
     "angular-ag-grid": "github:ceolter/ag-grid@2.3.5",
-    "angular-animate": "github:angular/bower-angular-animate@1.5.1",
+    "angular-animate": "github:angular/bower-angular-animate@1.5.2",
     "angular-drag-and-drop-lists": "github:marceljuenemann/angular-drag-and-drop-lists@1.4.0",
     "angular-grid": "github:ceolter/ag-grid@2.3.5",
     "angular-loading": "github:darthwade/angular-loading@0.1.4",
     "angular-motion": "github:mgcrea/angular-motion@0.4.3",
     "angular-nvd3": "github:krispo/angular-nvd3@1.0.5",
     "angular-retina": "github:jrief/angular-retina@0.3.8",
-    "angular-sanitize": "github:angular/bower-angular-sanitize@1.5.1",
+    "angular-sanitize": "github:angular/bower-angular-sanitize@1.5.2",
     "angular-smart-table": "github:lorenzofox3/Smart-Table@2.1.7",
     "angular-socket-io": "github:btford/angular-socket-io@0.7.0",
     "angular-strap": "github:mgcrea/angular-strap@2.3.7",
@@ -36,8 +36,8 @@ System.config({
     "angular-ui-router": "github:angular-ui/ui-router@0.2.18",
     "angular-ui-router-metatags": "github:tinusn/ui-router-metatags@1.0.3",
     "angular-ui-router-title": "github:nonplus/angular-ui-router-title@0.0.4",
-    "babel": "npm:babel-core@5.8.35",
-    "babel-runtime": "npm:babel-runtime@5.8.35",
+    "babel": "npm:babel-core@5.8.38",
+    "babel-runtime": "npm:babel-runtime@5.8.38",
     "blob": "github:eligrey/Blob.js@master",
     "bootstrap": "github:twbs/bootstrap@3.3.6",
     "bootstrap-carousel": "github:twbs/bootstrap@3.3.6",
@@ -51,7 +51,7 @@ System.config({
     "jquery": "github:components/jquery@2.2.1",
     "json": "github:systemjs/plugin-json@0.1.0",
     "jszip": "github:Stuk/jszip@2.5.0",
-    "lodash": "npm:lodash@3.10.1",
+    "lodash": "github:lodash/lodash@4.6.1",
     "nvd3": "npm:nvd3@1.8.1",
     "pdfmake": "github:bpampuch/pdfmake@0.1.20",
     "query-command-supported": "github:zenorocha/document.queryCommandSupported@1.0.0",
@@ -65,15 +65,15 @@ System.config({
       "ace": "github:ajaxorg/ace-builds@1.2.3"
     },
     "github:angular-ui/ui-router@0.2.18": {
-      "angular": "github:angular/bower-angular@1.5.1"
+      "angular": "github:angular/bower-angular@1.5.2"
     },
-    "github:angular/bower-angular-animate@1.5.1": {
-      "angular": "github:angular/bower-angular@1.5.1"
+    "github:angular/bower-angular-animate@1.5.2": {
+      "angular": "github:angular/bower-angular@1.5.2"
     },
-    "github:angular/bower-angular-sanitize@1.5.1": {
-      "angular": "github:angular/bower-angular@1.5.1"
+    "github:angular/bower-angular-sanitize@1.5.2": {
+      "angular": "github:angular/bower-angular@1.5.2"
     },
-    "github:angular/bower-angular@1.5.1": {
+    "github:angular/bower-angular@1.5.2": {
       "jquery": "github:components/jquery@2.2.1"
     },
     "github:btford/angular-socket-io@0.7.0": {
@@ -142,20 +142,20 @@ System.config({
       "nvd3": "npm:nvd3@1.8.1"
     },
     "github:mgcrea/angular-motion@0.4.3": {
-      "angular": "github:angular/bower-angular@1.5.1",
+      "angular": "github:angular/bower-angular@1.5.2",
       "css": "github:systemjs/plugin-css@0.1.20"
     },
     "github:mgcrea/angular-strap@2.3.7": {
-      "angular": "github:angular/bower-angular@1.5.1",
-      "angular-animate": "github:angular/bower-angular-animate@1.5.1",
+      "angular": "github:angular/bower-angular@1.5.2",
+      "angular-animate": "github:angular/bower-angular-animate@1.5.2",
       "angular-motion": "github:mgcrea/angular-motion@0.4.3",
-      "angular-sanitize": "github:angular/bower-angular-sanitize@1.5.1"
+      "angular-sanitize": "github:angular/bower-angular-sanitize@1.5.2"
     },
     "github:twbs/bootstrap@3.3.6": {
       "jquery": "github:components/jquery@2.2.1"
     },
     "github:wix/angular-tree-control@0.2.23": {
-      "angular": "github:angular/bower-angular@1.5.1"
+      "angular": "github:angular/bower-angular@1.5.2"
     },
     "npm:acorn-globals@1.0.9": {
       "acorn": "npm:acorn@2.7.0"
@@ -192,7 +192,7 @@ System.config({
     "npm:async@0.2.10": {
       "process": "github:jspm/nodelibs-process@0.1.2"
     },
-    "npm:babel-runtime@5.8.35": {
+    "npm:babel-runtime@5.8.38": {
       "process": "github:jspm/nodelibs-process@0.1.2"
     },
     "npm:buffer@3.6.0": {
@@ -302,9 +302,6 @@ System.config({
     "npm:lazy-cache@1.0.3": {
       "process": "github:jspm/nodelibs-process@0.1.2"
     },
-    "npm:lodash@3.10.1": {
-      "process": "github:jspm/nodelibs-process@0.1.2"
-    },
     "npm:mkdirp@0.5.1": {
       "fs": "github:jspm/nodelibs-fs@0.1.2",
       "minimist": "npm:minimist@0.0.8",

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/caches-controller.js b/modules/control-center-web/src/main/js/controllers/caches-controller.js
index 055417b..3b9c9c6 100644
--- a/modules/control-center-web/src/main/js/controllers/caches-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/caches-controller.js
@@ -71,7 +71,7 @@ consoleModule.controller('cachesController', [
 
         function cacheDomains(item) {
             return _.reduce($scope.domains, function (memo, domain) {
-                if (item && _.contains(item.domains, domain.value)) {
+                if (item && _.includes(item.domains, domain.value)) {
                     memo.push(domain.meta);
                 }
 
@@ -214,7 +214,7 @@ consoleModule.controller('cachesController', [
 
         function checkDataSources() {
             var clusters = _.filter($scope.clusters, function (cluster) {
-                return _.contains($scope.backupItem.clusters, cluster.value);
+                return _.includes($scope.backupItem.clusters, cluster.value);
             });
 
             var checkRes = { checked: true };

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/clusters-controller.js b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
index ce133cf..4df0871 100644
--- a/modules/control-center-web/src/main/js/controllers/clusters-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
@@ -94,7 +94,7 @@ consoleModule.controller('clustersController', [
 
         function clusterCaches(item) {
             return _.reduce($scope.caches, function (memo, cache) {
-                if (item && _.contains(item.caches, cache.value)) {
+                if (item && _.includes(item.caches, cache.value)) {
                     memo.push(cache.cache);
                 }
 
@@ -277,7 +277,7 @@ consoleModule.controller('clustersController', [
             var caches = _.filter(_.map($scope.caches, function (scopeCache) {
                 return scopeCache.cache;
             }), function (cache) {
-                return _.contains($scope.backupItem.caches, cache._id);
+                return _.includes($scope.backupItem.caches, cache._id);
             });
 
             var checkRes = $common.checkCachesDataSources(caches);

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index d4f692d..151d15a 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -187,7 +187,7 @@ consoleModule.service('$common', [
             if (isEmptyString(cls))
                 return false;
 
-            return _.contains(javaBuiltInClasses, cls) || _.contains(javaBuiltInFullNameClasses, cls);
+            return _.includes(javaBuiltInClasses, cls) || _.includes(javaBuiltInFullNameClasses, cls);
         }
 
         var SUPPORTED_JDBC_TYPES = [
@@ -272,7 +272,7 @@ consoleModule.service('$common', [
             if (isEmptyString(ident))
                 return showPopoverMessage(panels, panelId, elemId, msg + ' is invalid!');
 
-            if (_.contains(JAVA_KEYWORDS, ident))
+            if (_.includes(JAVA_KEYWORDS, ident))
                 return showPopoverMessage(panels, panelId, elemId, msg + ' could not contains reserved java keyword: "' + ident + '"!');
 
             if (!VALID_JAVA_IDENTIFIER.test(ident))
@@ -585,7 +585,7 @@ consoleModule.service('$common', [
 
                     if (!activePanels || activePanels.length < 1)
                         ui.activePanels = [idx];
-                    else if (!_.contains(activePanels, idx)) {
+                    else if (!_.includes(activePanels, idx)) {
                         var newActivePanels = angular.copy(activePanels);
 
                         newActivePanels.push(idx);

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/controllers/domains-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/domains-controller.js b/modules/control-center-web/src/main/js/controllers/domains-controller.js
index 0b88662..d90f2a7 100644
--- a/modules/control-center-web/src/main/js/controllers/domains-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/domains-controller.js
@@ -456,7 +456,6 @@ consoleModule.controller('domainsController', [
                 $scope.importDomain.loadingOptions = LOADING_JDBC_DRIVERS;
 
                 IgniteAgentMonitor.startWatch({
-                        state: 'base.configuration.domains',
                         text: 'Back to Domain models',
                         goal: 'import domain model from database schema'
                     })
@@ -936,7 +935,7 @@ consoleModule.controller('domainsController', [
 
                         newDomain.caches = [cacheId];
 
-                        if (!_.contains(checkedCaches, cacheId)) {
+                        if (!_.includes(checkedCaches, cacheId)) {
                             var cache = _.find($scope.caches, {value: cacheId}).cache;
 
                             var change = $common.autoCacheStoreConfiguration(cache, [newDomain]);

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
index 35c0126..abae869 100644
--- a/modules/control-center-web/src/main/js/controllers/sql-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -151,7 +151,7 @@ consoleModule.controller('sqlController', [
             var idx = _.findIndex($scope.notebook.paragraphs, {id: paragraphId});
 
             if (idx >= 0) {
-                if (!_.contains($scope.notebook.expandedParagraphs, idx))
+                if (!_.includes($scope.notebook.expandedParagraphs, idx))
                     $scope.notebook.expandedParagraphs.push(idx);
 
                 setTimeout(function () {
@@ -480,13 +480,13 @@ consoleModule.controller('sqlController', [
             'java.lang.Float', 'java.lang.Integer', 'java.lang.Long', 'java.lang.Short'];
 
         var _numberType = function(cls) {
-            return _.contains(_numberClasses, cls);
+            return _.includes(_numberClasses, cls);
         };
 
         var _intClasses = ['java.lang.Byte', 'java.lang.Integer', 'java.lang.Long', 'java.lang.Short'];
 
         function _intType(cls) {
-            return _.contains(_intClasses, cls);
+            return _.includes(_intClasses, cls);
         }
 
         var _rebuildColumns = function (paragraph) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/gulpfile.js/tasks/jade.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/gulpfile.js/tasks/jade.js b/modules/control-center-web/src/main/js/gulpfile.js/tasks/jade.js
index 9082093..58a9bf5 100644
--- a/modules/control-center-web/src/main/js/gulpfile.js/tasks/jade.js
+++ b/modules/control-center-web/src/main/js/gulpfile.js/tasks/jade.js
@@ -18,7 +18,6 @@
 var gulp = require('gulp');
 var gulpJade = require('gulp-jade');
 var sequence = require('gulp-sequence');
-var connect = require('gulp-connect');
 
 var igniteModules = process.env.IGNITE_MODULES || './ignite_modules';
 
@@ -47,8 +46,7 @@ gulp.task('jade:source', function (cb) {
 gulp.task('jade:ignite_modules', function (cb) {
     return gulp.src(igniteModulePaths)
         .pipe(gulpJade(jadeOptions))
-        .pipe(gulp.dest('./build/ignite_modules'))
-        .pipe(connect.reload());
+        .pipe(gulp.dest('./build/ignite_modules'));
 });
 
 gulp.task('jade:watch', function (cb) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/package.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/package.json b/modules/control-center-web/src/main/js/package.json
index 02cdcd9..a160801 100644
--- a/modules/control-center-web/src/main/js/package.json
+++ b/modules/control-center-web/src/main/js/package.json
@@ -22,11 +22,11 @@
   },
   "dependencies": {
     "async": "1.5.2",
-    "babel-eslint": "^4.1.6",
-    "body-parser": "~1.14.1",
+    "babel-eslint": "^6.0.0-beta.6",
+    "body-parser": "^1.15.0",
     "bootstrap-sass": "^3.3.6",
-    "connect-modrewrite": "^0.8.2",
-    "connect-mongo": "^0.8.1",
+    "connect-modrewrite": "^0.9.0",
+    "connect-mongo": "^1.1.0",
     "cookie-parser": "~1.4.0",
     "debug": "~2.2.0",
     "ejs": "^2.3.4",
@@ -38,10 +38,10 @@
     "gulp": "^3.9.0",
     "gulp-cached": "^1.1.0",
     "gulp-concat": "^2.6.0",
-    "gulp-connect": "^2.2.0",
+    "gulp-connect": "^3.2.0",
     "gulp-environments": "^0.1.1",
-    "gulp-eslint": "^1.1.1",
-    "gulp-inject": "^3.0.0",
+    "gulp-eslint": "^2.0.0",
+    "gulp-inject": "^4.0.0",
     "gulp-jade": "^1.1.0",
     "gulp-rimraf": "^0.2.0",
     "gulp-sass": "^2.1.0",
@@ -49,24 +49,24 @@
     "gulp-util": "^3.0.7",
     "jade": "~1.11.0",
     "jszip": "^2.5.0",
-    "lodash": "3.10.1",
-    "mongoose": "^4.2.8",
-    "mongoose-deep-populate": "2.0.3",
+    "lodash": "^4.0.0",
+    "mongoose": "^4.4.8",
+    "mongoose-deep-populate": "^3.0.0",
     "nconf": "^0.8.2",
-    "nodemailer": "1.10.0",
+    "nodemailer": "^2.3.0",
     "passport": "^0.3.2",
     "passport-local": "^1.0.0",
-    "passport-local-mongoose": "3.1.0",
+    "passport-local-mongoose": "^4.0.0",
     "passport.socketio": "^3.6.1",
     "require-dir": "^0.3.0",
-    "serve-favicon": "~2.3.0",
-    "socket.io": "^1.4.5"
+    "socket.io": "^1.4.5",
+    "ws": "^0.8.0"
   },
   "devDependencies": {
-    "jspm": "^0.16.15",
-    "mocha": "~2.3.3",
-    "morgan": "~1.6.1",
-    "should": "~7.1.1",
+    "jspm": "^0.16.31",
+    "mocha": "^2.4.5",
+    "morgan": "^1.6.1",
+    "should": "^8.2.2",
     "supertest": "^1.1.0"
   },
   "jspm": {
@@ -96,7 +96,7 @@
       "jquery": "github:components/jquery@^2.1.4",
       "json": "github:systemjs/plugin-json@^0.1.0",
       "jszip": "github:Stuk/jszip@^2.5.0",
-      "lodash": "npm:lodash@^3.10.1",
+      "lodash": "github:lodash/lodash@^4.2.6",
       "pdfmake": "github:bpampuch/pdfmake@^0.1.20",
       "query-command-supported": "github:zenorocha/document.queryCommandSupported@^1.0.0",
       "socket.io-client": "github:socketio/socket.io-client@1.4.5",

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/serve.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve.js b/modules/control-center-web/src/main/js/serve.js
index cba74d3..891855c 100644
--- a/modules/control-center-web/src/main/js/serve.js
+++ b/modules/control-center-web/src/main/js/serve.js
@@ -84,6 +84,18 @@ Promise.all([fireUp('settings'), fireUp('app'), fireUp('agent-manager'), fireUp(
         app.listen(server);
         browserMgr.attach(server);
 
+        // Start legacy agent server for reject connection with message.
+        if (settings.agent.legacyPort) {
+            const agentLegacySrv = settings.agent.SSLOptions
+                ? https.createServer(settings.agent.SSLOptions) : http.createServer();
+
+            agentLegacySrv.listen(settings.agent.legacyPort);
+            agentLegacySrv.on('error', _onError.bind(null, settings.agent.legacyPort));
+            agentLegacySrv.on('listening', _onListening.bind(null, agentLegacySrv.address()));
+
+            agentMgr.attachLegacy(agentLegacySrv);
+        }
+
         // Start agent server.
         const agentServer = settings.agent.SSLOptions
             ? https.createServer(settings.agent.SSLOptions) : http.createServer();

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/serve/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/agent.js b/modules/control-center-web/src/main/js/serve/agent.js
index 6e249f0..9d4ca4c 100644
--- a/modules/control-center-web/src/main/js/serve/agent.js
+++ b/modules/control-center-web/src/main/js/serve/agent.js
@@ -24,7 +24,7 @@
  */
 module.exports = {
     implements: 'agent-manager',
-    inject: ['require(lodash)', 'require(fs)', 'require(path)', 'require(jszip)', 'require(socket.io)', 'require(apache-ignite)', 'settings', 'mongo']
+    inject: ['require(lodash)', 'require(ws)', 'require(fs)', 'require(path)', 'require(jszip)', 'require(socket.io)', 'require(apache-ignite)', 'settings', 'mongo']
 };
 
 /**
@@ -38,7 +38,7 @@ module.exports = {
  * @param mongo
  * @returns {AgentManager}
  */
-module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, settings, mongo) {
+module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite, settings, mongo) {
     /**
      * Creates an instance of server for Ignite.
      */
@@ -347,6 +347,17 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, se
                 this.supportedAgents.latest = this.supportedAgents[latest];
         }
 
+        attachLegacy(server) {
+            const wsSrv = new ws.Server({server});
+
+            wsSrv.on('connection', (_wsClient) => {
+                _wsClient.send(JSON.stringify({
+                    method: 'authResult',
+                    args: ['You are using an older version of the agent. Please reload agent archive']
+                }));
+            });
+        }
+
         /**
          * @param {http.Server|https.Server} srv Server instance that we want to attach agent handler.
          */

http://git-wip-us.apache.org/repos/asf/ignite/blob/3262283f/modules/control-center-web/src/main/js/serve/settings.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/settings.js b/modules/control-center-web/src/main/js/serve/settings.js
index b8a3c71..5b14bcc 100644
--- a/modules/control-center-web/src/main/js/serve/settings.js
+++ b/modules/control-center-web/src/main/js/serve/settings.js
@@ -50,7 +50,8 @@ module.exports.factory = function(nconf, fs) {
     return {
         agent: {
             dists: 'serve/agent_dists',
-            port: _normalizePort(nconf.get('agent-server:port') || 3001),
+            port: _normalizePort(nconf.get('agent-server:port') || 3002),
+            legacyPort: _normalizePort(nconf.get('agent-server:legacyPort')),
             SSLOptions: nconf.get('agent-server:ssl') && {
                 key: fs.readFileSync(nconf.get('agent-server:key')),
                 cert: fs.readFileSync(nconf.get('agent-server:cert')),


[04/50] [abbrv] ignite git commit: IGNITE-843 fixed tooltip

Posted by an...@apache.org.
IGNITE-843 fixed tooltip


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/aec0f596
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/aec0f596
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/aec0f596

Branch: refs/heads/ignite-2875
Commit: aec0f596658d66f3057c1daf00821677510ce83d
Parents: ad921af
Author: Dmitriyff <dm...@gmail.com>
Authored: Thu Mar 17 18:35:04 2016 +0700
Committer: Dmitriyff <dm...@gmail.com>
Committed: Thu Mar 17 18:35:04 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/app/modules/form/field/tooltip.directive.js     | 5 +++--
 .../src/main/js/app/modules/form/group/tooltip.directive.js     | 4 ++--
 .../states/configuration/clusters/general/discovery/vm.jade     | 4 ++--
 3 files changed, 7 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/aec0f596/modules/control-center-web/src/main/js/app/modules/form/field/tooltip.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/tooltip.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/tooltip.directive.js
index 4fc9ef9..e24df9c 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/tooltip.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/tooltip.directive.js
@@ -19,8 +19,9 @@ const template = `<i class='tipField fa fa-question-circle'></i>`;
 
 export default ['igniteFormFieldTooltip', ['$tooltip', ($tooltip) => {
     const link = ($scope, $element, $attrs, [form, field], $transclude) => {
-        const content = Array.prototype.slice.apply($transclude($scope))
-            .reduce((html, el) => html += el.outerHTML, '');
+        const content = Array.prototype.slice
+            .apply($transclude($scope))
+            .reduce((html, el) => html += el.outerHTML || el.textContent || el, '');
 
         $tooltip($element, { title: content });
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aec0f596/modules/control-center-web/src/main/js/app/modules/form/group/tooltip.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/group/tooltip.directive.js b/modules/control-center-web/src/main/js/app/modules/form/group/tooltip.directive.js
index 5af8fb1..fa87ba7 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/group/tooltip.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/group/tooltip.directive.js
@@ -20,8 +20,8 @@ const template = `<i class='group-legend-btn fa fa-question-circle'></i>`;
 export default ['igniteFormGroupTooltip', ['$tooltip', ($tooltip) => {
     const link = ($scope, $element, $attrs, $ctrls, $transclude) => {
         const content = Array.prototype.slice
-        .apply($transclude($scope))
-        .reduce((html, el) => html += el.outerHTML, '');
+            .apply($transclude($scope))
+            .reduce((html, el) => html += el.outerHTML || el.textContent || el, '');
 
         $tooltip($element, { title: content });
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aec0f596/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
index 05c17ba..a0071e6 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
@@ -71,7 +71,7 @@ mixin addressFeedbackRequired(field)
         ignite-form-field-label
             | Addresses
         ignite-form-group-tooltip
-            | Addresses may be represented as follows:#[br]
+            | Addresses may be represented as follows:
             ul: li IP address (e.g. 127.0.0.1, 9.9.9.9, etc)
                 li IP address and port (e.g. 127.0.0.1:47500, 9.9.9.9:47501, etc)
                 li IP address and port range (e.g. 127.0.0.1:47500..47510, 9.9.9.9:47501..47504, etc)
@@ -79,7 +79,7 @@ mixin addressFeedbackRequired(field)
                 li Hostname and port (e.g. host1.com:47500, host2:47502, etc)
                 li Hostname and port range (e.g. host1.com:47500..47510, host2:47502..47508, etc)
             | If port is 0 or not provided then default port will be used (depends on discovery SPI configuration)#[br]
-            | If port range is provided (e.g. host:port1..port2) the following should be considered:#[br]
+            | If port range is provided (e.g. host:port1..port2) the following should be considered:
             ul: li port1 < port2 should be true
                 li Both port1 and port2 should be greater than 0
         ignite-form-group-add(ng-click='group.add = [{}]')


[15/50] [abbrv] ignite git commit: IGNITE-843 Split username into firstName and lastName. (cherry picked from commit 60e862c)

Posted by an...@apache.org.
IGNITE-843 Split username into firstName and lastName.
(cherry picked from commit 60e862c)


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/922e3fc0
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/922e3fc0
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/922e3fc0

Branch: refs/heads/ignite-2875
Commit: 922e3fc0a57879d753957327412751bc5c3357e3
Parents: b20a693
Author: Andrey <an...@gridgain.com>
Authored: Thu Mar 17 15:50:06 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 21 15:43:42 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/controllers/admin-controller.js | 111 ++++++++++---------
 .../src/main/js/serve/mail.js                   |   2 +-
 .../src/main/js/serve/mongo.js                  |   6 +-
 .../src/main/js/serve/routes/admin.js           |   4 +-
 .../src/main/js/serve/routes/public.js          |   6 +-
 .../src/main/js/views/includes/header.jade      |   4 +-
 .../src/main/js/views/settings/admin.jade       |   4 +-
 .../src/main/js/views/settings/profile.jade     |  18 +--
 .../src/main/js/views/signin.jade               |  29 ++---
 .../src/main/js/views/templates/clone.jade      |   2 +-
 10 files changed, 98 insertions(+), 88 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/922e3fc0/modules/control-center-web/src/main/js/controllers/admin-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/admin-controller.js b/modules/control-center-web/src/main/js/controllers/admin-controller.js
index 107d310..5d204d5 100644
--- a/modules/control-center-web/src/main/js/controllers/admin-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/admin-controller.js
@@ -16,79 +16,82 @@
  */
 
 // Controller for Admin screen.
-consoleModule.controller('adminController',
-    ['$q', '$rootScope', '$scope', '$http', '$common', '$confirm', '$state', 'User',
-    function ($q, $rootScope, $scope, $http, $common, $confirm, $state, User) {
-    $scope.users = null;
+consoleModule.controller('adminController', [
+    '$rootScope', '$scope', '$http', '$q', '$common', '$confirm', '$state', 'User',
+    function ($rootScope, $scope, $http, $q, $common, $confirm, $state, User) {
+        $scope.users = null;
 
-    function reload() {
-        $http.post('/api/v1/admin/list')
-            .success(function (data) {
-                $scope.users = data;
+        function reload() {
+            $http.post('/api/v1/admin/list')
+                .success(function (data) {
+                    $scope.users = data;
 
-                _.forEach($scope.users, function(user) {
-                    user.label = user.username + ' ' + user.email + ' ' +
-                        (user.company || '') + ' ' + (user.country || '') + ' ' + user.lastLogin;
+                    _.forEach($scope.users, function(user) {
+                        user.userName = user.firstName + ' ' + user.lastName;
+
+                        user.label = user.userName + ' ' + user.email + ' ' +
+                            (user.company || '') + ' ' + (user.country || '');
+                    })
                 })
-            })
-            .error(function (errMsg) {
-                $common.showError($common.errorMessage(errMsg));
-            });
-    }
+                .error(function (errMsg) {
+                    $common.showError($common.errorMessage(errMsg));
+                });
+        }
 
-    reload();
+        reload();
 
-    $scope.becomeUser = function (user) {
-        $http
-        .get('/api/v1/admin/become', { params: {viewedUserId: user._id}})
-        .then(User.read)
-        .then(function (user) {
-            $rootScope.$broadcast('user', user);
+        $scope.becomeUser = function (user) {
+            $http
+                .get('/api/v1/admin/become', { params: {viewedUserId: user._id}})
+                .then(User.read)
+                .then(function (user) {
+                    $rootScope.$broadcast('user', user);
 
-            $state.go('base.configuration.clusters')
-        })
-        .catch(function (errMsg) {
-            $common.showError($common.errorMessage(errMsg));
-        });
-    };
+                    $state.go('base.configuration.clusters')
+                })
+                .catch(function (errMsg) {
+                    $common.showError($common.errorMessage(errMsg));
+                });
+        };
 
-    $scope.removeUser = function (user) {
-        $confirm.confirm('Are you sure you want to remove user: "' + user.username + '"?')
-            .then(function () {
-                $http.post('/api/v1/admin/remove', {userId: user._id}).success(
-                    function () {
-                        var i = _.findIndex($scope.users, function (u) {
-                            return u._id == user._id;
-                        });
+        $scope.removeUser = function (user) {
+            $confirm.confirm('Are you sure you want to remove user: "' + user.userName + '"?')
+                .then(function () {
+                    $http.post('/api/v1/admin/remove', {userId: user._id}).success(
+                        function () {
+                            var i = _.findIndex($scope.users, function (u) {
+                                return u._id == user._id;
+                            });
 
-                        if (i >= 0)
-                            $scope.users.splice(i, 1);
+                            if (i >= 0)
+                                $scope.users.splice(i, 1);
 
-                        $common.showInfo('User has been removed: "' + user.username + '"');
-                    }).error(function (errMsg, status) {
+                            $common.showInfo('User has been removed: "' + user.userName + '"');
+                        }).error(function (errMsg, status) {
                         if (status == 503)
                             $common.showInfo(errMsg);
                         else
                             $common.showError('Failed to remove user: "' + $common.errorMessage(errMsg) + '"');
                     });
-            });
-    };
+                });
+        };
 
-    $scope.toggleAdmin = function (user) {
-        if (user.adminChanging)
-            return;
+        $scope.toggleAdmin = function (user) {
+            if (user.adminChanging)
+                return;
 
-        user.adminChanging = true;
+            user.adminChanging = true;
 
-        $http.post('/api/v1/admin/save', {userId: user._id, adminFlag: user.admin}).success(
-            function () {
-                $common.showInfo('Admin right was successfully toggled for user: "' + user.username + '"');
+            $http.post('/api/v1/admin/save', {userId: user._id, adminFlag: user.admin}).success(
+                function () {
+                    $common.showInfo('Admin right was successfully toggled for user: "' + user.userName + '"');
 
-                user.adminChanging = false;
-            }).error(function (errMsg) {
+                    user.adminChanging = false;
+                }).error(function (errMsg) {
                 $common.showError('Failed to toggle admin right for user: "' + $common.errorMessage(errMsg) + '"');
 
                 user.adminChanging = false;
             });
-    }
-}]);
+        }
+    }]
+);

http://git-wip-us.apache.org/repos/asf/ignite/blob/922e3fc0/modules/control-center-web/src/main/js/serve/mail.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/mail.js b/modules/control-center-web/src/main/js/serve/mail.js
index 0412840..8ab3e7e 100644
--- a/modules/control-center-web/src/main/js/serve/mail.js
+++ b/modules/control-center-web/src/main/js/serve/mail.js
@@ -53,7 +53,7 @@ module.exports.factory = function(nodemailer, settings) {
 
             const mail = {
                 from: settings.smtp.address(settings.smtp.username, settings.smtp.email),
-                to: settings.smtp.address(user.username, user.email),
+                to: settings.smtp.address(`${user.firstName} ${user.lastName}`, user.email),
                 subject,
                 html: html + sign
             };

http://git-wip-us.apache.org/repos/asf/ignite/blob/922e3fc0/modules/control-center-web/src/main/js/serve/mongo.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/mongo.js b/modules/control-center-web/src/main/js/serve/mongo.js
index 46a9629..6a80b7a 100644
--- a/modules/control-center-web/src/main/js/serve/mongo.js
+++ b/modules/control-center-web/src/main/js/serve/mongo.js
@@ -43,7 +43,8 @@ module.exports.factory = function(deepPopulatePlugin, passportMongo, settings, p
 
     // Define Account schema.
     const AccountSchema = new Schema({
-        username: String,
+        firstName: String,
+        lastName: String,
         email: String,
         company: String,
         country: String,
@@ -65,7 +66,8 @@ module.exports.factory = function(deepPopulatePlugin, passportMongo, settings, p
             return {
                 _id: ret._id,
                 email: ret.email,
-                username: ret.username,
+                firstName: ret.firstName,
+                lastName: ret.lastName,
                 company: ret.company,
                 country: ret.country,
                 admin: ret.admin,

http://git-wip-us.apache.org/repos/asf/ignite/blob/922e3fc0/modules/control-center-web/src/main/js/serve/routes/admin.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/admin.js b/modules/control-center-web/src/main/js/serve/routes/admin.js
index 02e7183..1308ef2 100644
--- a/modules/control-center-web/src/main/js/serve/routes/admin.js
+++ b/modules/control-center-web/src/main/js/serve/routes/admin.js
@@ -32,7 +32,7 @@ module.exports.factory = function(_, express, nodemailer, settings, mail, mongo)
          * Get list of user accounts.
          */
         router.post('/list', (req, res) => {
-            mongo.Account.find({}).sort('username').lean().exec()
+            mongo.Account.find({}).sort('firstName lastName').lean().exec()
                 .then((users) => res.json(users))
                 .catch((err) => mongo.handleError(res, err));
         });
@@ -58,7 +58,7 @@ module.exports.factory = function(_, express, nodemailer, settings, mail, mongo)
                 })
                 .then((user) =>
                     mail.send(user, 'Your account was deleted',
-                        `Hello ${user.username}!<br><br>` +
+                        `Hello ${user.firstName} ${user.lastName}!<br><br>` +
                         `You are receiving this email because your account for <a href="http://${req.headers.host}">${settings.smtp.username}</a> was removed.`,
                         'Account was removed, but failed to send email notification to user!')
                 )

http://git-wip-us.apache.org/repos/asf/ignite/blob/922e3fc0/modules/control-center-web/src/main/js/serve/routes/public.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/public.js b/modules/control-center-web/src/main/js/serve/routes/public.js
index 33aa287..5d0f458 100644
--- a/modules/control-center-web/src/main/js/serve/routes/public.js
+++ b/modules/control-center-web/src/main/js/serve/routes/public.js
@@ -104,7 +104,7 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
 
                     account.save()
                         .then(() => mail.send(account, `Thanks for signing up for ${settings.smtp.username}.`,
-                            `Hello ${account.username}!<br><br>` +
+                            `Hello ${account.firstName} ${account.lastName}!<br><br>` +
                             `You are receiving this email because you have signed up to use <a href="http://${req.headers.host}">${settings.smtp.username}</a>.<br><br>` +
                             'If you have not done the sign up and do not know what this email is about, please ignore it.<br>' +
                             'You may reset the password by clicking on the following link, or paste this into your browser:<br><br>' +
@@ -158,7 +158,7 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
                     return user.save();
                 })
                 .then((user) => mail.send(user, 'Password Reset',
-                        `Hello ${user.username}!<br><br>` +
+                        `Hello ${user.firstName} ${user.lastName}!<br><br>` +
                         'You are receiving this because you (or someone else) have requested the reset of the password for your account.<br><br>' +
                         'Please click on the following link, or paste this into your browser to complete the process:<br><br>' +
                         'http://' + req.headers.host + '/password/reset?token=' + user.resetPasswordToken + '<br><br>' +
@@ -194,7 +194,7 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
                 })
                 .then((user) => {
                     return mail.send(user, 'Your password has been changed',
-                        `Hello ${user.username}!<br><br>` +
+                        `Hello ${user.firstName} ${user.lastName}!<br><br>` +
                         `This is a confirmation that the password for your account on <a href="http://${req.headers.host}">${settings.smtp.username}</a> has just been changed.<br><br>`,
                         'Password was changed, but failed to send confirmation email!');
                 })

http://git-wip-us.apache.org/repos/asf/ignite/blob/922e3fc0/modules/control-center-web/src/main/js/views/includes/header.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/includes/header.jade b/modules/control-center-web/src/main/js/views/includes/header.jade
index b4e095a..bee2ef2 100644
--- a/modules/control-center-web/src/main/js/views/includes/header.jade
+++ b/modules/control-center-web/src/main/js/views/includes/header.jade
@@ -16,7 +16,7 @@
 
 header#header.header
     .viewedUser(ng-show='$root.user.becomeUsed')
-        | Currently assuming #[strong {{$root.user.username}}], #[a(ng-click='$root.revertIdentity()') revert to your identity].
+        | Currently assuming #[strong {{$root.user.firstName}} {{$root.user.lastName}}], #[a(ng-click='$root.revertIdentity()') revert to your identity].
     table.container
         tr
             td.col-xs-3.col-sm-3.col-md-2
@@ -36,5 +36,5 @@ header#header.header
 
                 ul.nav.navbar-nav.pull-right(ignite-userbar)
                     li(ng-class='{active: $state.includes("settings")}')
-                        a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='userbar.items' data-placement='bottom-right') {{user.username}}
+                        a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='userbar.items' data-placement='bottom-right') {{user.firstName}} {{user.lastName}}
                             span.caret

http://git-wip-us.apache.org/repos/asf/ignite/blob/922e3fc0/modules/control-center-web/src/main/js/views/settings/admin.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/settings/admin.jade b/modules/control-center-web/src/main/js/views/settings/admin.jade
index e72eae2..55fb3fe 100644
--- a/modules/control-center-web/src/main/js/views/settings/admin.jade
+++ b/modules/control-center-web/src/main/js/views/settings/admin.jade
@@ -28,7 +28,7 @@
                                 .col-xs-2.pull-right
                                     input.form-control(type='text' st-search='label' placeholder='Filter users...')
                         tr
-                            th(st-sort='username') User name
+                            th(st-sort='userName') User name
                             th(st-sort='email') Email
                             th(st-sort='company') Company
                             th(st-sort='country') Country
@@ -37,7 +37,7 @@
                             th(width='1%') Actions
                     tbody
                         tr(ng-repeat='row in displayedUsers')
-                            td {{row.username}}
+                            td {{row.userName}}
                             td
                                 a(ng-href='mailto:{{row.email}}') {{row.email}}
                             td {{row.company}}

http://git-wip-us.apache.org/repos/asf/ignite/blob/922e3fc0/modules/control-center-web/src/main/js/views/settings/profile.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/settings/profile.jade b/modules/control-center-web/src/main/js/views/settings/profile.jade
index 95c2a3e..df8fd7d 100644
--- a/modules/control-center-web/src/main/js/views/settings/profile.jade
+++ b/modules/control-center-web/src/main/js/views/settings/profile.jade
@@ -26,21 +26,25 @@ mixin lbl(txt)
             form.form-horizontal(name='profileForm' novalidate)
                 .col-sm-10(style='padding: 0')
                     .details-row
-                        +lbl('User name:')
+                        +lbl('First name:')
                         .col-xs-5.col-sm-4
-                            input#profile-username.form-control(type='text' ng-model='user.username' placeholder='Input name' required auto-focus)
+                            input#profile-firstname.form-control(type='text' ng-model='user.firstName' placeholder='Input first name' required auto-focus)
+                    .details-row
+                        +lbl('Last name:')
+                        .col-xs-5.col-sm-4
+                            input#profile-lastname.form-control(type='text' ng-model='user.lastName' placeholder='Input last name' required)
                     .details-row
                         +lbl('Email:')
                         .col-xs-5.col-sm-4
-                            input#profile-email.form-control(type='email' ng-model='user.email' placeholder='you@domain.com' required)
+                            input#profile-email.form-control(type='email' ng-model='user.email' placeholder='Input email' required)
                     .details-row
-                        label.col-sm-2.labelFormField Company:
+                        +lbl('Company:')
                         .col-xs-5.col-sm-4
-                            input#profile-company.form-control(type='text' ng-model='user.company' placeholder='Your company name')
+                            input#profile-company.form-control(type='text' ng-model='user.company' placeholder='Input company name' required)
                     .details-row
-                        label.col-sm-2.labelFormField Country:
+                        +lbl('Country:')
                         .col-xs-5.col-sm-4
-                            button#profile-country.select-toggle.form-control(bs-select bs-options='item for item in countries' type='text' ng-model='user.country' placeholder='Choose your country')
+                            button#profile-country.select-toggle.form-control(bs-select bs-options='item for item in countries' type='text' ng-model='user.country' placeholder='Choose your country' required)
                     .details-row
                         .advanced-options
                             i.fa(

http://git-wip-us.apache.org/repos/asf/ignite/blob/922e3fc0/modules/control-center-web/src/main/js/views/signin.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/signin.jade b/modules/control-center-web/src/main/js/views/signin.jade
index 9ec8dfd..77fd8e2 100644
--- a/modules/control-center-web/src/main/js/views/signin.jade
+++ b/modules/control-center-web/src/main/js/views/signin.jade
@@ -14,9 +14,6 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-mixin lbl(txt)
-    label.col-xs-3.col-md-3 #{txt}
-
 mixin lblRequired(txt)
     label.col-xs-3.col-md-3.required #{txt}
 
@@ -45,21 +42,25 @@ header#header.header
                                 p.col-xs-12.col-md-11(ng-show='action == "password/forgot"')
                                     | That's ok! Simply enter your email below and a reset password link will be sent to you via email. You can then follow that link and select a new password.
                             .settings-row(ng-show='action == "signup"')
-                                +lblRequired('Full Name:')
+                                +lblRequired('First Name:')
+                                .col-xs-9.col-md-8
+                                    input#first_name.form-control(enter-focus-next='last_name' type='text' ng-model='user_info.firstName' placeholder='Input first name' ng-required='action=="signup"')
+                            .settings-row(ng-show='action == "signup"')
+                                +lblRequired('Last Name:')
                                 .col-xs-9.col-md-8
-                                    input#user_name.form-control(enter-focus-next='user_email' type='text' ng-model='user_info.username' placeholder='John Smith' ng-required='action=="signup"')
+                                    input#last_name.form-control(enter-focus-next='email' type='text' ng-model='user_info.lastName' placeholder='Input last name' ng-required='action=="signup"')
                             .settings-row
                                 +lblRequired('Email:')
                                 .col-xs-9.col-md-8
-                                    input#user_email.form-control(enter-focus-next='company' type='email' ng-model='user_info.email' placeholder='you@domain.com' required)
+                                    input#email.form-control(enter-focus-next='company' type='email' ng-model='user_info.email' placeholder='Input email' required)
                             .settings-row(ng-show='action == "signup"')
-                                +lbl('Company:')
+                                +lblRequired('Company:')
                                 .col-xs-9.col-md-8
-                                    input#company.form-control(enter-focus-next='country' type='text' ng-model='user_info.company' placeholder='Your company name')
+                                    input#company.form-control(enter-focus-next='country' type='text' ng-model='user_info.company' placeholder='Input company name' ng-required='action=="signup"')
                             .settings-row(ng-show='action == "signup"')
-                                +lbl('Country:')
+                                +lblRequired('Country:')
                                 .col-xs-9.col-md-8
-                                    button#country.select-toggle.form-control(bs-select bs-options='item for item in countries' enter-focus-next='user_password' type='text' ng-model='user_info.country' placeholder='Choose your country')
+                                    button#country.select-toggle.form-control(bs-select bs-options='item for item in countries' enter-focus-next='user_password' type='text' ng-model='user_info.country' placeholder='Choose your country' ng-required='action=="signup"')
                             .settings-row(ng-show='action != "password/forgot"')
                                 +lblRequired('Password:')
                                 .col-xs-9.col-md-8
@@ -75,16 +76,16 @@ header#header.header
                                         | I agree to the #[a(ui-sref='{{::terms.termsState}}' target='_blank') terms and conditions]
                         .col-xs-12.col-md-11
                             .login-footer(ng-show='action == "signup"')
-                                a.labelField(ng-click='action = "password/forgot"' on-click-focus='user_email') Forgot password?
-                                a.labelLogin(ng-click='action = "signin"' on-click-focus='user_email') Sign In
+                                a.labelField(ng-click='action = "password/forgot"' on-click-focus='email') Forgot password?
+                                a.labelLogin(ng-click='action = "signin"' on-click-focus='email') Sign In
                                 button#signup.btn.btn-primary(ng-click='auth(action, user_info)' ng-disabled='form.$invalid') Sign Up
                         .col-xs-12.col-md-11
                             .login-footer(ng-show='action == "password/forgot"')
-                                a.labelField(ng-click='action = "signin"' on-click-focus='user_email') Sign In
+                                a.labelField(ng-click='action = "signin"' on-click-focus='email') Sign In
                                 button#forgot.btn.btn-primary(ng-click='auth(action, user_info)' ng-disabled='form.$invalid') Send it to me
                         .col-xs-12.col-md-11
                             .login-footer(ng-show='action == "signin"')
-                                a.labelField(ng-click='action = "password/forgot"' on-click-focus='user_email') Forgot password?
+                                a.labelField(ng-click='action = "password/forgot"' on-click-focus='email') Forgot password?
                                 a.labelLogin(ng-click='action = "signup"' on-click-focus='user_name') Sign Up
                                 button#login.btn.btn-primary(ng-click='auth(action, user_info)' ng-disabled='form.$invalid') Sign In
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/922e3fc0/modules/control-center-web/src/main/js/views/templates/clone.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/clone.jade b/modules/control-center-web/src/main/js/views/templates/clone.jade
index 26b5385..c94c534 100644
--- a/modules/control-center-web/src/main/js/views/templates/clone.jade
+++ b/modules/control-center-web/src/main/js/views/templates/clone.jade
@@ -25,7 +25,7 @@
                     .col-sm-2
                         label.required.labelFormField New name:&nbsp;
                     .col-sm-10
-                        input.form-control(id='copy-new-name' type='text' ng-model='newName' required auto-focus)
+                        input.form-control(id='copy-new-name' type='text' ng-model='newName' on-enter='form.$valid && ok(newName)' required auto-focus)
             .modal-footer
                 button.btn.btn-default(id='copy-btn-cancel' ng-click='$hide()') Cancel
                 button.btn.btn-primary(id='copy-btn-confirm' ng-disabled='ui.inputForm.$invalid' ng-click='ok(newName)') Confirm


[42/50] [abbrv] ignite git commit: IGNITE-843 Minor fix.

Posted by an...@apache.org.
IGNITE-843 Minor fix.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1017ea84
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1017ea84
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1017ea84

Branch: refs/heads/ignite-2875
Commit: 1017ea846ab86866c0d50f5d377b376db307f421
Parents: e7dd846
Author: Andrey <an...@gridgain.com>
Authored: Fri Mar 25 14:18:39 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Mar 25 14:18:39 2016 +0700

----------------------------------------------------------------------
 modules/control-center-web/src/main/js/views/signin.jade | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1017ea84/modules/control-center-web/src/main/js/views/signin.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/signin.jade b/modules/control-center-web/src/main/js/views/signin.jade
index 77fd8e2..f666dbe 100644
--- a/modules/control-center-web/src/main/js/views/signin.jade
+++ b/modules/control-center-web/src/main/js/views/signin.jade
@@ -56,11 +56,11 @@ header#header.header
                             .settings-row(ng-show='action == "signup"')
                                 +lblRequired('Company:')
                                 .col-xs-9.col-md-8
-                                    input#company.form-control(enter-focus-next='country' type='text' ng-model='user_info.company' placeholder='Input company name' ng-required='action=="signup"')
+                                    input#company.form-control(enter-focus-next='country' type='search' ng-model='user_info.company' placeholder='Input company name' ng-required='action=="signup"')
                             .settings-row(ng-show='action == "signup"')
                                 +lblRequired('Country:')
                                 .col-xs-9.col-md-8
-                                    button#country.select-toggle.form-control(bs-select bs-options='item for item in countries' enter-focus-next='user_password' type='text' ng-model='user_info.country' placeholder='Choose your country' ng-required='action=="signup"')
+                                    button#country.select-toggle.form-control(bs-select bs-options='item for item in countries' enter-focus-next='user_password' type='search' ng-model='user_info.country' placeholder='Choose your country' ng-required='action=="signup"')
                             .settings-row(ng-show='action != "password/forgot"')
                                 +lblRequired('Password:')
                                 .col-xs-9.col-md-8


[30/50] [abbrv] ignite git commit: Merge remote-tracking branch 'community/web-console-staging' into web-console-staging

Posted by an...@apache.org.
Merge remote-tracking branch 'community/web-console-staging' into web-console-staging


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/767529b2
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/767529b2
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/767529b2

Branch: refs/heads/ignite-2875
Commit: 767529b20606609770078d5d10f3ffdcc86bff0a
Parents: 3262283 1e2ba1d
Author: Andrey <an...@gridgain.com>
Authored: Wed Mar 23 08:53:57 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Wed Mar 23 08:53:57 2016 +0700

----------------------------------------------------------------------
 .../states/configuration/clusters/deployment.jade   |  2 +-
 .../modules/states/configuration/clusters/ssl.jade  |  2 +-
 .../modules/states/configuration/clusters/swap.jade |  2 +-
 .../states/configuration/clusters/thread.jade       |  2 +-
 .../states/configuration/clusters/transactions.jade |  2 +-
 .../src/main/js/controllers/caches-controller.js    | 16 +++++++++++++---
 .../src/main/js/controllers/clusters-controller.js  | 15 ++++++++++-----
 .../src/main/js/controllers/common-module.js        |  3 +++
 8 files changed, 31 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/767529b2/modules/control-center-web/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/767529b2/modules/control-center-web/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/767529b2/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------


[35/50] [abbrv] ignite git commit: IGNITE-843 Fixed lodash "_.contains()" to "_.includes()"

Posted by an...@apache.org.
 IGNITE-843 Fixed lodash "_.contains()" to "_.includes()"


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/efe43956
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/efe43956
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/efe43956

Branch: refs/heads/ignite-2875
Commit: efe43956a0f5667fa371ac59784f7f744a87a718
Parents: 6cd972a
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Thu Mar 24 18:56:24 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Thu Mar 24 18:56:24 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/helpers/generator/generator-java.js            | 6 +++---
 .../src/main/js/helpers/generator/generator-properties.js      | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/efe43956/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/helpers/generator/generator-java.js b/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
index fe65b45..bcf12ce 100644
--- a/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
+++ b/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
@@ -1235,7 +1235,7 @@ $generatorJava.clusterDataSources = function (caches, res) {
         if (storeFactory) {
             var beanClassName = $generatorJava.dataSourceClassName(res, storeFactory);
 
-            if (beanClassName && !_.contains(datasources, beanClassName)) {
+            if (beanClassName && !_.includes(datasources, beanClassName)) {
                 datasources.push(beanClassName);
 
                 if (factoryKind === 'CacheJdbcPojoStoreFactory' || factoryKind === 'CacheJdbcBlobStoreFactory') {
@@ -2902,7 +2902,7 @@ $generatorJava.generateExample = function (cluster, res, factoryCls) {
                         }
 
                         _.forEach(desc.insertCntConsts, function (cnt) {
-                            if (!_.contains(generatedConsts, cnt.name)) {
+                            if (!_.includes(generatedConsts, cnt.name)) {
                                 res.line('/** ' + cnt.comment + ' */');
                                 res.line('private static final int ' + cnt.name + ' = ' + cnt.val + ';');
                                 res.needEmptyLine = true;
@@ -3012,7 +3012,7 @@ $generatorJava.generateExample = function (cluster, res, factoryCls) {
                         _.forEach(desc.selectQuery, function (query) {
                             var cacheName = type.cache.name;
 
-                            if (!_.contains(cacheLoaded, cacheName)) {
+                            if (!_.includes(cacheLoaded, cacheName)) {
                                 res.line('ignite.cache("' + cacheName + '").loadCache(null);');
 
                                 cacheLoaded.push(cacheName);

http://git-wip-us.apache.org/repos/asf/ignite/blob/efe43956/modules/control-center-web/src/main/js/helpers/generator/generator-properties.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/helpers/generator/generator-properties.js b/modules/control-center-web/src/main/js/helpers/generator/generator-properties.js
index 9bb68eb..cf971da 100644
--- a/modules/control-center-web/src/main/js/helpers/generator/generator-properties.js
+++ b/modules/control-center-web/src/main/js/helpers/generator/generator-properties.js
@@ -71,7 +71,7 @@ $generatorProperties.dataSourcesProperties = function (cluster, res) {
 
                     var beanClassName = $commonUtils.toJavaName(varType, storeFactory.dataSourceBean);
 
-                    if (!_.contains(datasources, beanClassName)) {
+                    if (!_.includes(datasources, beanClassName)) {
                         datasources.push(beanClassName);
 
                         res.needEmptyLine = true;


[46/50] [abbrv] ignite git commit: IGNITE-843 Fixed validation.

Posted by an...@apache.org.
 IGNITE-843 Fixed validation.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/630cbbe8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/630cbbe8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/630cbbe8

Branch: refs/heads/ignite-2875
Commit: 630cbbe81ecacc83d66d266e88396d8f73dd0083
Parents: 214c9b2
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Mar 25 18:04:28 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Mar 25 18:04:28 2016 +0700

----------------------------------------------------------------------
 .../form-field-java-class.directive.js          |  6 ++--
 .../src/main/js/app/helpers/jade/mixins.jade    | 38 ++++++++++----------
 .../modules/form/field/input/text.directive.js  |  6 ++--
 .../js/app/modules/form/field/input/text.jade   |  1 -
 .../configuration/clusters/communication.jade   |  7 ++--
 .../configuration/clusters/connector.jade       |  7 ++--
 .../configuration/clusters/discovery.jade       |  7 ++--
 .../states/configuration/clusters/general.jade  |  7 ++--
 .../clusters/general/discovery/multicast.jade   | 12 +++++--
 .../clusters/general/discovery/vm.jade          |  4 +++
 .../modules/states/configuration/igfs/ipc.jade  |  7 ++--
 11 files changed, 58 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
index 8c469ea..142cb25 100644
--- a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
@@ -56,10 +56,10 @@ export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
         scope.$watch('value', setAsDefault);
 
         const checkValid = () => {
-            if (ngModel.$valid)
-                el.find('input').addClass('ng-valid').removeClass('ng-invalid');
-            else
+            if (ngModel.$invalid)
                 el.find('input').removeClass('ng-valid').addClass('ng-invalid');
+            else
+                el.find('input').addClass('ng-valid').removeClass('ng-invalid');
         };
 
         scope.ngChange = () => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
index 6a7500f..eaed6ac 100644
--- a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
+++ b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
@@ -14,6 +14,23 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+//- Mixin for feedback on specified error.
+mixin error-feedback(visible, error, errorMessage)
+    i.fa.fa-exclamation-triangle.form-control-feedback(
+        ng-if=visible
+        bs-tooltip='"#{errorMessage}"'
+        ignite-error=error
+        ignite-error-message=errorMessage
+    )
+
+//- Mixin for feedback on unique violation.
+mixin unique-feedback(visible, errorMessage)
+    +error-feedback(visible, 'igniteUnique', errorMessage)
+
+//- Mixin for feedback on IP address violation.
+mixin ipaddress-feedback(visible)
+    +error-feedback(visible, 'ipaddress', 'Invalid address!')
+
 //- Mixin for checkbox.
 mixin checkbox(lbl, model, name, tip)
     ignite-form-field.checkbox
@@ -55,7 +72,7 @@ mixin java-class(lbl, model, name, enabled, required, tip)
         )
 
 //- Mixin for text field.
-mixin text-ip-address(lbl, model, name, enabled, placeholder, tip)
+mixin text-ip-address(lbl, form, model, name, enabled, placeholder, tip)
     ignite-form-field
         ignite-form-field-label
             | #{lbl}
@@ -69,6 +86,7 @@ mixin text-ip-address(lbl, model, name, enabled, placeholder, tip)
             data-ng-disabled='!(#{enabled})'
             data-placeholder=placeholder
         )
+            +ipaddress-feedback(form + '.' + name + '.$error.ipaddress')
 
 //- Mixin for text field.
 mixin text-enabled(lbl, model, name, enabled, required, placeholder, tip)
@@ -308,24 +326,6 @@ mixin table-remove-conditional-button(items, show, tip)
 mixin table-remove-button(items, tip)
     +table-remove-conditional-button(items, 'true', tip)
 
-//- Mixin for feedback on specified error.
-mixin error-feedback(visible, error, errorMessage)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-if=visible
-        bs-tooltip='"#{errorMessage}"'
-        ignite-error=error
-        ignite-error-message=errorMessage
-    )
-
-//- Mixin for feedback on unique violation.
-mixin unique-feedback(visible, errorMessage)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-if=visible
-        bs-tooltip='"#{errorMessage}"'
-        ignite-error='igniteUnique'
-        ignite-error-message=errorMessage
-    )
-
 //- Mixin for cache mode.
 mixin cacheMode(lbl, model, name, placeholder)
     +dropdown(lbl, model, name, 'true', placeholder,

http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
index 0a3fa04..99d7525 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
@@ -64,10 +64,10 @@ export default ['igniteFormFieldInputText', ['IgniteFormGUID', (guid) => {
         scope.$watch('value', setAsDefault);
 
         const checkValid = () => {
-            if (ngModel.$valid)
-                el.find('input').addClass('ng-valid').removeClass('ng-invalid');
-            else
+            if (ngModel.$invalid)
                 el.find('input').removeClass('ng-valid').addClass('ng-invalid');
+            else
+                el.find('input').addClass('ng-valid').removeClass('ng-invalid');
         };
 
         scope.ngChange = () => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
index 787fb68..558c723 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
@@ -42,6 +42,5 @@ mixin feedback(isCheckPristine, error, errorMessage)
     )
 
     +feedback(true, 'required', '{{ label.name }} could not be empty!')
-    +feedback(false, 'ipaddress', 'Invalid address!')
 
     span(ng-transclude='')

http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
index cbb4010..d874783 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
@@ -16,17 +16,18 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
+-var form = 'communication'
 -var model = 'backupItem'
 -var communication = model + '.communication'
 
-form.panel.panel-default(name='communication' novalidate)
+form.panel.panel-default(name=form novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
         ignite-form-panel-chevron
         label Communication
         ignite-form-field-tooltip.tipLabel
             | Cluster communication network properties
         ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id='communication')
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
@@ -40,7 +41,7 @@ form.panel.panel-default(name='communication' novalidate)
                 .settings-row
                     +java-class('Communication listener:', communication + '.listener', 'comListener', 'true', 'false', 'Communication listener')
                 .settings-row
-                    +text-ip-address('Local IP address:', communication + '.localAddress', 'comLocalAddress', 'true', '228.1.2.4', 'Local host address for socket binding')
+                    +text-ip-address('Local IP address:', form, communication + '.localAddress', 'comLocalAddress', 'true', '228.1.2.4', 'Local host address for socket binding')
                 .settings-row
                     +number-min-max('Local port:', communication + '.localPort', 'comLocalPort', 'true', '47100', '1024', '65535', 'Local port for socket binding')
                 .settings-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
index 4319742..c07d2d5 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
@@ -16,18 +16,19 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
+-var form = 'connector'
 -var model = 'backupItem.connector'
 -var enabled = model + '.enabled'
 -var sslEnabled = enabled + ' && ' + model + '.sslEnabled'
 
-form.panel.panel-default(name='connector' novalidate)
+form.panel.panel-default(name=form novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
         ignite-form-panel-chevron
         label Connector configuration
         ignite-form-field-tooltip.tipLabel
             | REST access configuration
         ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id='connector')
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
@@ -38,7 +39,7 @@ form.panel.panel-default(name='connector' novalidate)
                         Jetty is used to support REST over HTTP protocol for accessing Ignite APIs remotely<br/>\
                         If not provided, Jetty instance with default configuration will be started picking IgniteSystemProperties.IGNITE_JETTY_HOST and IgniteSystemProperties.IGNITE_JETTY_PORT as host and port respectively')
                 .settings-row
-                    +text-ip-address('TCP host:', model + '.host', 'connectorHost', enabled, 'IgniteConfiguration#getLocalHost()',
+                    +text-ip-address('TCP host:', form, model + '.host', 'connectorHost', enabled, 'IgniteConfiguration#getLocalHost()',
                         'Host for TCP binary protocol server<br/>\
                         This can be either an IP address or a domain name<br/>\
                         If not defined, system - wide local address will be used IgniteConfiguration#getLocalHost()<br/>\

http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
index 1ba04fa..e86f8ab 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
@@ -16,20 +16,21 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
+-var form = 'discovery'
 -var model = 'backupItem.discovery'
 
-form.panel.panel-default(name='discovery' novalidate)
+form.panel.panel-default(name=form novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
         ignite-form-panel-chevron
         label Discovery
         ignite-form-field-tooltip.tipLabel
             | Discovery properties configuration
         ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id='discovery')
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    +text-ip-address('Local address:', model + '.localAddress', 'discoLocalAddress', 'true', '228.1.2.4', 'Local address')
+                    +text-ip-address('Local address:', form, model + '.localAddress', 'discoLocalAddress', 'true', '228.1.2.4', 'Local address')
                 .settings-row
                     +number-min-max('Local port:', model + '.localPort', 'discoLocalPort', 'true', '47500', '1024', '65535', 'Local port which node uses')
                 .settings-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
index ec004ce..ee46416 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
@@ -16,14 +16,15 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
+-var form = 'general'
 -var model = 'backupItem'
 
-form.panel.panel-default(name='general' novalidate)
+form.panel.panel-default(name=form novalidate)
     .panel-heading(bs-collapse-toggle)
         ignite-form-panel-chevron
         label General
         ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id='general')
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
         .panel-body
             .col-sm-6
                 .settings-row
@@ -34,7 +35,7 @@ form.panel.panel-default(name='general' novalidate)
                         model + '.caches', 'caches', 'Choose caches', 'No caches configured', 'caches',
                         'Select caches to start in cluster or add a new cache')
                 .settings-row
-                    +text-ip-address('Local host:', model + '.localHost', 'localHost', 'true', '0.0.0.0', 'System-wide local address or host for all Ignite components to bind to')
+                    +text-ip-address('Local host:', form, model + '.localHost', 'localHost', 'true', '0.0.0.0', 'System-wide local address or host for all Ignite components to bind to')
                 .settings-row
                     +dropdown('Discovery:', model + '.discovery.kind', 'discovery', 'true', 'Choose discovery', 'discoveries',
                         'Discovery allows to discover remote nodes in grid\

http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
index 61a0718..5eef0f1 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
@@ -16,13 +16,13 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
+-var form = 'general'
 -var model = 'backupItem.discovery.Multicast';
 -var addresses = model + '.addresses';
--var form = 'discoveryMulticastAddresses';
 
 div
     .details-row
-        +text-ip-address('IP address:', model + '.multicastGroup', 'multicastGroup', 'true', '228.1.2.4', 'IP address of multicast group')
+        +text-ip-address('IP address:', form, model + '.multicastGroup', 'multicastGroup', 'true', '228.1.2.4', 'IP address of multicast group')
     .details-row
         +number-min-max('Port number:', model + '.multicastPort', 'multicastPort', 'true', '47400', '0', '65535', 'Port number which multicast messages are sent to')
     .details-row
@@ -33,11 +33,13 @@ div
             'Number of attempts to send multicast address request<br/>\
             IP finder re - sends request only in case if no reply for previous request is received')
     .details-row
-        +text-ip-address('Local address:', model + '.localAddress', 'localAddress', 'true', '0.0.0.0',
+        +text-ip-address('Local address:', form, model + '.localAddress', 'localAddress', 'true', '0.0.0.0',
             'Local host address used by this IP finder<br/>\
             If provided address is non - loopback then multicast socket is bound to this interface<br/>\
             If local address is not set or is any local address then IP finder creates multicast sockets for all found non - loopback addresses')
     .details-row
+        -var form = 'discoveryMulticastAddresses';
+
         ignite-form-group(ng-model=addresses ng-form=form)
             -var uniqueTip = 'Such IP address already exists!'
             -var ipAddressTip = 'Invalid IP address!'
@@ -63,6 +65,7 @@ div
                 -var field = 'edit'
                 -var valid = form + '.' + field + '.$valid'
                 -var unique = form + '.' + field + '.$error.igniteUnique'
+                -var ipaddress = form + '.' + field + '.$error.ipaddress'
                 -var save = addresses + '[$index] = ' + field
 
                 ignite-form-field(ng-repeat='model in #{addresses} track by $index' type='internal' name='Address')
@@ -79,17 +82,20 @@ div
                         +table-address-field(field, addresses, valid, save, false)
                             +table-save-button(valid, save, false)
                             +unique-feedback(unique, uniqueTip)
+                            +ipaddress-feedback(ipaddress)
 
             .group-content(ng-repeat='field in group.add')
                 -var field = 'new'
                 -var valid = form + '.' + field + '.$valid'
                 -var unique = form + '.' + field + '.$error.igniteUnique'
+                -var ipaddress = form + '.' + field + '.$error.ipaddress'
                 -var save = addresses + '.push(' + field + ')'
 
                 ignite-form-field(type='internal' name='Address')
                     +table-address-field(field, addresses, valid, save, true)
                         +table-save-button(valid, save, true)
                         +unique-feedback(unique, uniqueTip)
+                        +ipaddress-feedback(ipaddress)
 
             .group-content-empty(ng-if='!(#{addresses}.length) && !group.add.length')
                 | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
index a19adf7..6b157cc 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
@@ -46,6 +46,7 @@ include ../../../../../../../app/helpers/jade/mixins.jade
             -var field = 'edit'
             -var valid = form + '.' + field + '.$valid'
             -var unique = form + '.' + field + '.$error.igniteUnique'
+            -var ipaddress = form + '.' + field + '.$error.ipaddress'
             -var save = addresses + '[$index] = ' + field
 
             ignite-form-field(ng-repeat='model in #{addresses} track by $index' type='internal' name='Address')
@@ -62,17 +63,20 @@ include ../../../../../../../app/helpers/jade/mixins.jade
                     +table-address-field(field, addresses, valid, save, false)
                         +table-save-button(valid, save, false)
                         +unique-feedback(unique, uniqueTip)
+                        +ipaddress-feedback(ipaddress)
 
         .group-content(ng-repeat='field in group.add')
             -var field = 'new'
             -var valid = form + '.' + field + '.$valid'
             -var unique = form + '.' + field + '.$error.igniteUnique'
+            -var ipaddress = form + '.' + field + '.$error.ipaddress'
             -var save = addresses + '.push(' + field + ')'
 
             ignite-form-field(type='internal' name='Address')
                 +table-address-field(field, addresses, valid, save, true)
                     +table-save-button(valid, save, true)
                     +unique-feedback(unique, uniqueTip)
+                    +ipaddress-feedback(ipaddress)
 
         .group-content-empty(id='addresses' ng-if='!(#{addresses}.length) && !group.add.length')
                 | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/630cbbe8/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
index 5463c46..744e814 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
@@ -16,16 +16,17 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
+-var form = 'ipc'
 -var model = 'backupItem'
 
-form.panel.panel-default(name='ipc' novalidate)
+form.panel.panel-default(name=form novalidate)
     .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')
         ignite-form-panel-chevron
         label IPC
         ignite-form-field-tooltip.tipLabel
             | IGFS Inter-process communication properties
         ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id='ipc')
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 -var ipcEndpointConfiguration = model + '.ipcEndpointConfiguration'
@@ -45,7 +46,7 @@ form.panel.panel-default(name='ipc' novalidate)
                             <li>TCP - TCP endpoint</li>\
                         </ul>')
                 .settings-row
-                    +text-ip-address('Host:', ipcEndpointConfiguration + '.host', 'ipcEndpointConfigurationHost', enabled, '127.0.0.1', 'Host name')
+                    +text-ip-address('Host:', form, ipcEndpointConfiguration + '.host', 'ipcEndpointConfigurationHost', enabled, '127.0.0.1', 'Host name')
                 .settings-row
                     +number-min-max('Port:', ipcEndpointConfiguration + '.port', 'ipcEndpointConfigurationPort', enabled, '10500', '1', '65535', 'Port number')
                 .settings-row


[34/50] [abbrv] ignite git commit: IGNITE-2676 Refactoring IGFS screen to Angular directives and JADE mixins.

Posted by an...@apache.org.
 IGNITE-2676 Refactoring IGFS screen to Angular directives and JADE mixins.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6cd972a1
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6cd972a1
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6cd972a1

Branch: refs/heads/ignite-2875
Commit: 6cd972a1c396d3045d605639466c7d40b16246c0
Parents: 63819d6
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Thu Mar 24 18:44:05 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Thu Mar 24 18:44:05 2016 +0700

----------------------------------------------------------------------
 .../form-field-java-class.directive.js          |  26 +-
 .../form-field-java-class.jade                  |  26 +-
 .../src/main/js/app/helpers/jade/mixins.jade    |  20 +-
 .../modules/form/field/dropdown.directive.js    |  17 +-
 .../js/app/modules/form/field/dropdown.jade     |   4 +
 .../form/field/input/number.directive.js        |  12 +-
 .../js/app/modules/form/field/input/text.css    |   2 +-
 .../modules/form/field/input/text.directive.js  |  24 +-
 .../js/app/modules/form/field/input/text.jade   |   6 +-
 .../app/modules/states/configuration.state.js   | 257 +++++++-------
 .../states/configuration/caches/query.jade      |   6 +-
 .../states/configuration/caches/store.jade      |   8 +-
 .../states/configuration/igfs/dual.directive.js |  27 ++
 .../modules/states/configuration/igfs/dual.jade |  40 +++
 .../igfs/fragmentizer.directive.js              |  27 ++
 .../states/configuration/igfs/fragmentizer.jade |  42 +++
 .../configuration/igfs/general.directive.js     |  27 ++
 .../states/configuration/igfs/general.jade      |  53 +++
 .../states/configuration/igfs/ipc.directive.js  |  27 ++
 .../modules/states/configuration/igfs/ipc.jade  |  56 +++
 .../states/configuration/igfs/misc.directive.js |  27 ++
 .../modules/states/configuration/igfs/misc.jade | 118 +++++++
 .../configuration/igfs/secondary.directive.js   |  27 ++
 .../states/configuration/igfs/secondary.jade    |  43 +++
 .../main/js/controllers/caches-controller.js    |  31 +-
 .../main/js/controllers/clusters-controller.js  |  31 +-
 .../src/main/js/controllers/common-module.js    |  10 +-
 .../src/main/js/controllers/igfs-controller.js  | 346 +++++++------------
 .../src/main/js/views/configuration/igfs.jade   |  24 +-
 29 files changed, 918 insertions(+), 446 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
index 7e13b73..0f13343 100644
--- a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
@@ -21,17 +21,25 @@ export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
     const link = (scope, el, attrs, [ngModel, form, label]) => {
         const {id, name} = scope;
 
-        label.for = scope.id = id || guid();
-
-        scope.ngModel = ngModel;
+        scope.id = id || guid();
         scope.form = form;
-        scope.label = label;
         scope.name = scope.ngModelName + 'JavaClass';
+        scope.ngModel = ngModel;
 
-        scope.$watch('required', (required) => {
-            label.required = required || false;
+        Object.defineProperty(scope, 'field', {
+            get: () => scope.form[scope.name]
         });
 
+        if (label) {
+            label.for = scope.id;
+
+            scope.label = label;
+
+            scope.$watch('required', (required) => {
+                label.required = required || false;
+            });
+        }
+
         form.$defaults = form.$defaults || {};
         form.$defaults[name] = _.cloneDeep(scope.value);
 
@@ -52,7 +60,7 @@ export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
                 el.find('input').removeClass('ng-valid').addClass('ng-invalid');
         };
 
-        scope.ngChange = function() {
+        scope.ngChange = () => {
             ngModel.$setViewValue(scope.value);
 
             if (JSON.stringify(scope.value) !== JSON.stringify(form.$defaults[name]))
@@ -60,10 +68,10 @@ export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
             else
                 ngModel.$setPristine();
 
-            setTimeout(checkValid, 100);  // Use setTimeout() workaround of problem of two controllers.
+            setTimeout(checkValid, 100); // Use setTimeout() workaround of problem of two controllers.
         };
 
-        ngModel.$render = function() {
+        ngModel.$render = () => {
             scope.value = ngModel.$modelValue;
         };
     };

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.jade b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.jade
index 3078b80..16ff9e9 100644
--- a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.jade
+++ b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.jade
@@ -14,17 +14,19 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-mixin feedback(error, message)
+mixin feedback(isCheckPristine, error, errorMessage)
+    -var checkPristine = isCheckPristine ? '!field.$pristine && ' : ''
+
     i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-if='!form[name].$pristine && form[name].$error.#{error}'
-        bs-tooltip='"{{ label.name }} #{message}"'
-        ignite-error='#{error}'
-        ignite-error-message='{{ label.name }} #{message}'
+        ng-if='#{checkPristine}field.$error.#{error}'
+        bs-tooltip='"{{ label.name }} #{errorMessage}"'
+        ignite-error=error
+        ignite-error-message='{{ label.name }} #{errorMessage}'
     )
 
 .input-tip
     input.form-control(
-        id='{{ id }}JavaClass'
+        id='{{ id }}'
         name='{{ name }}'
         placeholder='Enter fully qualified class name'
         type='text'
@@ -47,11 +49,11 @@ mixin feedback(error, message)
         on-escape='onEscape()'
     )
 
-    span(ng-transclude='')
+    +feedback(true, 'javaPackageSpecified', 'does not have package specified!')
+    +feedback(false, 'javaBuiltInClass', 'should not be the Java built-in class!')
+    +feedback(false, 'javaKeywords', 'could not contains reserved Java keyword!')
+    +feedback(false, 'javaIdentifier', 'is invalid Java identifier!')
 
-    +feedback('javaPackageSpecified', 'does not have package specified!')
-    +feedback('javaBuiltInClass', 'should not be the Java built-in class!')
-    +feedback('javaKeywords', 'could not contains reserved Java keyword!')
-    +feedback('javaIdentifier', 'is invalid Java identifier!')
+    +feedback(true, 'required', 'could not be empty!')
 
-    +feedback('required', 'could not be empty!')
+    span(ng-transclude='')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
index abe08a3..6a7500f 100644
--- a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
+++ b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
@@ -193,9 +193,9 @@ mixin table-text-field(field, items, valid, save, placeholder, newItem)
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
-    -var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var onEscape = newItem ? 'group.add = []' : 'field.edit = false'
 
-    -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
@@ -216,9 +216,9 @@ mixin table-java-class-field(field, items, valid, save, newItem)
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
-    -var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var onEscape = newItem ? 'group.add = []' : 'field.edit = false'
 
-    -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-java-class(
@@ -238,9 +238,9 @@ mixin table-java-package-field(field, items, valid, save, newItem)
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
-    -var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var onEscape = newItem ? 'group.add = []' : 'field.edit = false'
 
-    -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
@@ -263,9 +263,9 @@ mixin table-address-field(field, items, valid, save, newItem)
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
-    -var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var onEscape = newItem ? 'group.add = []' : 'field.edit = false'
 
-    -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
@@ -286,11 +286,11 @@ mixin table-address-field(field, items, valid, save, newItem)
     Mixin for table save button.
     "||" used instead of "&&" to workaround escaping of "&&" to "&amp;&amp;"
 mixin table-save-button(valid, save, newItem)
-    -var reset = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var reset = newItem ? 'group.add = []' : 'field.edit = false'
 
     i.fa.fa-floppy-o(
         ng-show=valid
-        ng-click="!#{valid} || (#{save}); !#{valid} || (#{reset});"
+        ng-click='!(#{valid}) || (#{save}); !(#{valid}) || (#{reset});'
         bs-tooltip
         data-title='Click icon or press [Enter] to save item'
     )

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.directive.js
index e77d5e8..389a133 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.directive.js
@@ -23,13 +23,17 @@ export default ['igniteFormFieldDropdown', ['IgniteFormGUID', (guid) => {
     const link = (scope, $element, attrs, [form, label]) => {
         const {id, name} = scope;
 
-        label.for = scope.id = id || guid();
+        scope.id = id || guid();
 
-        scope.label = label;
+        if (label) {
+            label.for = scope.id;
 
-        scope.$watch('required', (required) => {
-            label.required = required || false;
-        });
+            scope.label = label;
+
+            scope.$watch('required', (required) => {
+                label.required = required || false;
+            });
+        }
 
         form.$defaults = form.$defaults || {};
         form.$defaults[name] = _.cloneDeep(scope.value);
@@ -51,7 +55,8 @@ export default ['igniteFormFieldDropdown', ['IgniteFormGUID', (guid) => {
             id: '@',
             name: '@',
             required: '=ngRequired',
-            value: '=ngModel'
+            value: '=ngModel',
+            onEnter: '@'
         },
         bindToController: {
             value: '=ngModel',

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.jade b/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.jade
index cf473a2..db607a1 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.jade
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.jade
@@ -30,6 +30,8 @@
 
         data-ng-required='required || false'
 
+        on-enter='{{ onEnter }}'
+
         tabindex='0'
     )
 
@@ -47,6 +49,8 @@
 
         data-ng-required='required || false'
 
+        on-enter='{{ onEnter }}'
+
         tabindex='0'
     )
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/form/field/input/number.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/number.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/input/number.directive.js
index cc2dd31..4ff61d1 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/number.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/number.directive.js
@@ -22,12 +22,16 @@ export default ['igniteFormFieldInputNumber', ['IgniteFormGUID', (guid) => {
         const {id, name} = scope;
         const field = form[name];
 
+        scope.id = id || guid();
         scope.field = field;
-        label.for = scope.id = id || guid();
 
-        scope.$watch('required', (required) => {
-            label.required = required || false;
-        });
+        if (label) {
+            label.for = scope.id;
+
+            scope.$watch('required', (required) => {
+                label.required = required || false;
+            });
+        }
 
         form.$defaults = form.$defaults || {};
         form.$defaults[name] = _.cloneDeep(scope.value);

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/form/field/input/text.css
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.css b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.css
index 9efdb2c..9ec64a3 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.css
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.css
@@ -1,4 +1,4 @@
-label .input-tip {
+.checkbox label .input-tip {
 	position: initial;
 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
index 93dc60c..a9e7f81 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
@@ -22,17 +22,25 @@ export default ['igniteFormFieldInputText', ['IgniteFormGUID', (guid) => {
     const link = (scope, el, attrs, [ngModel, form, label]) => {
         const {id, name} = scope;
 
-        label.for = scope.id = id || guid();
-
-        scope.ngModel = ngModel;
+        scope.id = id || guid();
         scope.form = form;
-        scope.field = form[name];
-        scope.label = label;
+        scope.name = scope.ngModelName + 'TextInput';
+        scope.ngModel = ngModel;
 
-        scope.$watch('required', (required) => {
-            label.required = required || false;
+        Object.defineProperty(scope, 'field', {
+            get: () => scope.form[scope.name]
         });
 
+        if (label) {
+            label.for = scope.id;
+
+            scope.label = label;
+
+            scope.$watch('required', (required) => {
+                label.required = required || false;
+            });
+        }
+
         form.$defaults = form.$defaults || {};
 
         if (form.$pristine) {
@@ -80,7 +88,7 @@ export default ['igniteFormFieldInputText', ['IgniteFormGUID', (guid) => {
         restrict: 'E',
         scope: {
             id: '@',
-            name: '@',
+            ngModelName: '@name',
             placeholder: '@',
             required: '=ngRequired',
             disabled: '=ngDisabled',

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
index 14d4ed5..787fb68 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
@@ -27,11 +27,9 @@ mixin feedback(isCheckPristine, error, errorMessage)
 .input-tip
     input.form-control(
         id='{{ id }}'
-        name='{{ name }}TextInput'
-
+        name='{{ name }}'
         placeholder='{{ placeholder }}'
-
-        type='text' 
+        type='text'
 
         data-ng-model='value'
         data-ng-blur='ngBlur()'

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration.state.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration.state.js b/modules/control-center-web/src/main/js/app/modules/states/configuration.state.js
index fa2f6fe..d0d4de4 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration.state.js
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration.state.js
@@ -66,130 +66,143 @@ import cachesRebalance from './configuration/caches/rebalance.directive';
 import cachesServerNearCache from './configuration/caches/server-near-cache.directive';
 import cachesStatistics from './configuration/caches/statistics.directive';
 
+// IGFS screen.
+import igfsGeneral from './configuration/igfs/general.directive';
+import igfsIpc from './configuration/igfs/ipc.directive';
+import igfsFragmentizer from './configuration/igfs/fragmentizer.directive';
+import igfsDual from './configuration/igfs/dual.directive';
+import igfsSecondary from './configuration/igfs/secondary.directive';
+import igfsMisc from './configuration/igfs/misc.directive';
+
 // Summary screen.
 import ConfigurationSummaryCtrl from './configuration/summary/summary.controller';
 import ConfigurationSummaryResource from './configuration/summary/summary.resource';
 import summaryTabs from './configuration/summary/summary-tabs.directive';
 
-angular
-.module('ignite-console.states.configuration', [
-    'ui.router'
-])
-// Clusters screen.
-.directive(...previewPanel)
-.directive(...clustersTransactions)
-.directive(...clustersThread)
-.directive(...clustersTime)
-.directive(...clustersSwap)
-.directive(...clustersSsl)
-.directive(...clustersMetrics)
-.directive(...clustersMarshaller)
-.directive(...clustersIgfs)
-.directive(...clustersEvents)
-.directive(...clustersDiscovery)
-.directive(...clustersDeployment)
-.directive(...clustersConnector)
-.directive(...clustersCommunication)
-.directive(...clustersBinary)
-.directive(...clustersAtomic)
-.directive(...clustersGeneral)
-.directive(...clustersGeneralDiscoveryCloud)
-.directive(...clustersGeneralDiscoveryGoogle)
-.directive(...clustersGeneralDiscoveryJdbc)
-.directive(...clustersGeneralDiscoveryMulticast)
-.directive(...clustersGeneralDiscoveryS3)
-.directive(...clustersGeneralDiscoveryShared)
-.directive(...clustersGeneralDiscoveryVm)
-.directive(...clustersGeneralDiscoveryZookeeper)
-.directive(...clustersGeneralDiscoveryZookeeperRetryExponential)
-.directive(...clustersGeneralDiscoveryZookeeperRetryBoundedExponential)
-.directive(...clustersGeneralDiscoveryZookeeperRetryUntilElapsed)
-.directive(...clustersGeneralDiscoveryZookeeperRetryNTimes)
-.directive(...clustersGeneralDiscoveryZookeeperRetryOneTime)
-.directive(...clustersGeneralDiscoveryZookeeperRetryForever)
-.directive(...clustersGeneralDiscoveryZookeeperRetryCustom)
-// Caches screen
-.directive(...cachesGeneral)
-.directive(...cachesMemory)
-.directive(...cachesQuery)
-.directive(...cachesStore)
-.directive(...cachesConcurrency)
-.directive(...cachesRebalance)
-.directive(...cachesServerNearCache)
-.directive(...cachesStatistics)
-// Summary screen
-.directive(...summaryTabs)
-// Services.
-.service(...ConfigurationSummaryResource)
-.config(['$stateProvider', function($stateProvider) {
-    // Setup the states.
-    $stateProvider
-    .state('base.configuration', {
-        url: '/configuration',
-        templateUrl: '/configuration/sidebar.html'
-    })
-    .state('base.configuration.clusters', {
-        url: '/clusters',
-        templateUrl: '/configuration/clusters.html',
-        params: {
-            id: null
-        },
-        data: {
-            loading: 'Loading clusters screen...'
-        },
-        metaTags: {
-            title: 'Configure Clusters'
-        }
-    })
-    .state('base.configuration.caches', {
-        url: '/caches',
-        templateUrl: '/configuration/caches.html',
-        params: {
-            id: null
-        },
-        data: {
-            loading: 'Loading caches screen...'
-        },
-        metaTags: {
-            title: 'Configure Caches'
-        }
-    })
-    .state('base.configuration.domains', {
-        url: '/domains',
-        templateUrl: '/configuration/domains.html',
-        params: {
-            id: null
-        },
-        data: {
-            loading: 'Loading domain models screen...'
-        },
-        metaTags: {
-            title: 'Configure Domain Model'
-        }
-    })
-    .state('base.configuration.igfs', {
-        url: '/igfs',
-        templateUrl: '/configuration/igfs.html',
-        params: {
-            id: null
-        },
-        data: {
-            loading: 'Loading IGFS screen...'
-        },
-        metaTags: {
-            title: 'Configure IGFS'
-        }
-    })
-    .state('base.configuration.summary', {
-        url: '/summary',
-        templateUrl: '/configuration/summary.html',
-        controller: ConfigurationSummaryCtrl,
-        controllerAs: 'ctrl',
-        data: {
-            loading: 'Loading summary screen...'
-        },
-        metaTags: {
-            title: 'Configurations Summary'
-        }
-    });
-}]);
+angular.module('ignite-console.states.configuration', ['ui.router'])
+    // Clusters screen.
+    .directive(...previewPanel)
+    .directive(...clustersTransactions)
+    .directive(...clustersThread)
+    .directive(...clustersTime)
+    .directive(...clustersSwap)
+    .directive(...clustersSsl)
+    .directive(...clustersMetrics)
+    .directive(...clustersMarshaller)
+    .directive(...clustersIgfs)
+    .directive(...clustersEvents)
+    .directive(...clustersDiscovery)
+    .directive(...clustersDeployment)
+    .directive(...clustersConnector)
+    .directive(...clustersCommunication)
+    .directive(...clustersBinary)
+    .directive(...clustersAtomic)
+    .directive(...clustersGeneral)
+    .directive(...clustersGeneralDiscoveryCloud)
+    .directive(...clustersGeneralDiscoveryGoogle)
+    .directive(...clustersGeneralDiscoveryJdbc)
+    .directive(...clustersGeneralDiscoveryMulticast)
+    .directive(...clustersGeneralDiscoveryS3)
+    .directive(...clustersGeneralDiscoveryShared)
+    .directive(...clustersGeneralDiscoveryVm)
+    .directive(...clustersGeneralDiscoveryZookeeper)
+    .directive(...clustersGeneralDiscoveryZookeeperRetryExponential)
+    .directive(...clustersGeneralDiscoveryZookeeperRetryBoundedExponential)
+    .directive(...clustersGeneralDiscoveryZookeeperRetryUntilElapsed)
+    .directive(...clustersGeneralDiscoveryZookeeperRetryNTimes)
+    .directive(...clustersGeneralDiscoveryZookeeperRetryOneTime)
+    .directive(...clustersGeneralDiscoveryZookeeperRetryForever)
+    .directive(...clustersGeneralDiscoveryZookeeperRetryCustom)
+    // Caches screen
+    .directive(...cachesGeneral)
+    .directive(...cachesMemory)
+    .directive(...cachesQuery)
+    .directive(...cachesStore)
+    .directive(...cachesConcurrency)
+    .directive(...cachesRebalance)
+    .directive(...cachesServerNearCache)
+    .directive(...cachesStatistics)
+    // IGFS screen
+    .directive(...igfsGeneral)
+    .directive(...igfsIpc)
+    .directive(...igfsFragmentizer)
+    .directive(...igfsDual)
+    .directive(...igfsSecondary)
+    .directive(...igfsMisc)
+    // Summary screen
+    .directive(...summaryTabs)
+    // Services.
+    .service(...ConfigurationSummaryResource)
+    // Configure state provider.
+    .config(['$stateProvider', ($stateProvider) => {
+        // Setup the states.
+        $stateProvider
+            .state('base.configuration', {
+                url: '/configuration',
+                templateUrl: '/configuration/sidebar.html'
+            })
+            .state('base.configuration.clusters', {
+                url: '/clusters',
+                templateUrl: '/configuration/clusters.html',
+                params: {
+                    id: null
+                },
+                data: {
+                    loading: 'Loading clusters screen...'
+                },
+                metaTags: {
+                    title: 'Configure Clusters'
+                }
+            })
+            .state('base.configuration.caches', {
+                url: '/caches',
+                templateUrl: '/configuration/caches.html',
+                params: {
+                    id: null
+                },
+                data: {
+                    loading: 'Loading caches screen...'
+                },
+                metaTags: {
+                    title: 'Configure Caches'
+                }
+            })
+            .state('base.configuration.domains', {
+                url: '/domains',
+                templateUrl: '/configuration/domains.html',
+                params: {
+                    id: null
+                },
+                data: {
+                    loading: 'Loading domain models screen...'
+                },
+                metaTags: {
+                    title: 'Configure Domain Model'
+                }
+            })
+            .state('base.configuration.igfs', {
+                url: '/igfs',
+                templateUrl: '/configuration/igfs.html',
+                params: {
+                    id: null
+                },
+                data: {
+                    loading: 'Loading IGFS screen...'
+                },
+                metaTags: {
+                    title: 'Configure IGFS'
+                }
+            })
+            .state('base.configuration.summary', {
+                url: '/summary',
+                templateUrl: '/configuration/summary.html',
+                controller: ConfigurationSummaryCtrl,
+                controllerAs: 'ctrl',
+                data: {
+                    loading: 'Loading summary screen...'
+                },
+                metaTags: {
+                    title: 'Configurations Summary'
+                }
+            });
+    }]);

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
index 5dbcab6..1488238 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
@@ -39,7 +39,7 @@ form.panel.panel-default(name='query' novalidate)
                     +number('Long query timeout:', model + '.longQueryWarningTimeout', 'longQueryWarningTimeout', 'true', '3000', '0',
                         'Timeout in milliseconds after which long query warning will be printed')
                 .settings-row
-                    ignite-form-group(ng-model='#{sqlFunctionClasses}' ng-form='#{form}')
+                    ignite-form-group(ng-model=sqlFunctionClasses ng-form=form)
                         ignite-form-field-label
                             | SQL functions
                         ignite-form-group-tooltip
@@ -49,7 +49,7 @@ form.panel.panel-default(name='query' novalidate)
 
                         -var uniqueTip = 'SQL function with such class name already exists!'
 
-                        .group-content(ng-if='#{sqlFunctionClasses}.length')
+                        .group-content(ng-if=sqlFunctionClasses + '.length')
                             -var field = 'edit'
                             -var valid = form + '.' + field + '.$valid'
                             -var unique = form + '.' + field + '.$error.igniteUnique'
@@ -62,7 +62,7 @@ form.panel.panel-default(name='query' novalidate)
 
                                 span(ng-hide='field.edit')
                                     a.labelFormField(ng-click='field.edit = true') {{ model }}
-                                span(ng-if='field.edit' ng-init='#{field} = model')
+                                span(ng-if='field.edit' ng-init='edit = model')
                                     +table-java-class-field(field, sqlFunctionClasses, valid, save, false)
                                         +table-save-button(valid, save, false)
                                         +unique-feedback(unique, uniqueTip)

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
index 44ae665..07185ae 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
@@ -51,12 +51,12 @@ mixin dialect(lbl, model, name, tipTitle, genericDialectName, placeholder)
         )
 
 mixin hibernateField(items, field, valid, save, newItem)
-    -var reset = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var reset = newItem ? 'group.add = []' : 'field.edit = false'
 
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
-    -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
@@ -96,7 +96,7 @@ form.panel.panel-default(name='store' novalidate)
                         ]',
                         'Factory for persistent storage for cache data'
                     )
-                    span(ng-if='#{storeFactoryKind}' ng-init='__.expanded = true')
+                    span(ng-if=storeFactoryKind ng-init='__.expanded = true')
                         a.customize(ng-show='__.expanded' ng-click='__.expanded = false') Hide settings
                         a.customize(ng-hide='__.expanded' ng-click='__.expanded = true') Show settings
                         .panel-details.col-sm-12(ng-if='__.expanded')
@@ -169,7 +169,7 @@ form.panel.panel-default(name='store' novalidate)
                                 -var hibernateProperties = hibernateStoreFactory + '.hibernateProperties'
 
                                 .details-row
-                                    ignite-form-group(ng-model='#{hibernateProperties}' ng-form='#{form}')
+                                    ignite-form-group(ng-model=hibernateProperties ng-form=form)
                                         ignite-form-field-label
                                             | Hibernate properties
                                         ignite-form-group-tooltip

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.directive.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.directive.js
new file mode 100644
index 0000000..109fa63
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.directive.js
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import template from './dual.jade!';
+
+export default ['igniteConfigurationIgfsDual', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.jade
new file mode 100644
index 0000000..df8a7f68
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.jade
@@ -0,0 +1,40 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+include ../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem'
+
+form.panel.panel-default(name='dualMode' novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')
+        ignite-form-panel-chevron
+        label Dual mode
+        ignite-form-field-tooltip.tipLabel
+            | Dual mode settings
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id='dualMode')
+        .panel-body(ng-if='__show__')
+            .col-sm-6
+                .settings-row
+                    +number('Maximum pending puts size:', model + '.dualModeMaxPendingPutsSize', 'dualModeMaxPendingPutsSize', 'true', '0', 'Number.MIN_SAFE_INTEGER',
+                        'Maximum amount of pending data read from the secondary file system and waiting to be written to data cache\
+                        0 or negative value stands for unlimited size')
+                .settings-row
+                    +java-class('Put executor service:', model + '.dualModePutExecutorService', 'dualModePutExecutorService', 'true', 'false', 'DUAL mode put operation executor service')
+                .settings-row
+                    +checkbox('Put executor service shutdown', model + '.dualModePutExecutorServiceShutdown', 'dualModePutExecutorServiceShutdown', 'DUAL mode put operation executor service shutdown flag')
+            .col-sm-6
+                +preview-xml-java(model, 'igfsDualMode')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.directive.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.directive.js
new file mode 100644
index 0000000..f93c76c
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.directive.js
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import template from './fragmentizer.jade!';
+
+export default ['igniteConfigurationIgfsFragmentizer', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.jade
new file mode 100644
index 0000000..9490726
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.jade
@@ -0,0 +1,42 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+include ../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem'
+
+form.panel.panel-default(name='fragmentizer' novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')
+        ignite-form-panel-chevron
+        label Fragmentizer
+        ignite-form-field-tooltip.tipLabel
+            | Fragmentizer settings
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id='fragmentizer')
+        .panel-body(ng-if='__show__')
+            .col-sm-6
+                -var fragmentizerEnabled = model + '.fragmentizerEnabled'
+
+                .settings-row
+                    +checkbox('Enabled', fragmentizerEnabled, 'fragmentizerEnabled', 'Fragmentizer enabled flag')
+                .settings-row
+                    +number('Concurrent files:', model + '.fragmentizerConcurrentFiles', 'fragmentizerConcurrentFiles', fragmentizerEnabled, '0', '0', 'Number of files to process concurrently by fragmentizer')
+                .settings-row
+                    +number('Throttling block length:', model + '.fragmentizerThrottlingBlockLength', 'fragmentizerThrottlingBlockLength', fragmentizerEnabled, '16777216', '1', 'Length of file chunk to transmit before throttling is delayed')
+                .settings-row
+                    +number('Throttling delay:', model + '.fragmentizerThrottlingDelay', 'fragmentizerThrottlingDelay', fragmentizerEnabled, '200', '0', 'Delay in milliseconds for which fragmentizer is paused')
+            .col-sm-6
+                +preview-xml-java(model, 'igfsFragmentizer')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/general.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/general.directive.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/general.directive.js
new file mode 100644
index 0000000..294c3b8
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/general.directive.js
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import template from './general.jade!';
+
+export default ['igniteConfigurationIgfsGeneral', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/general.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/general.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/general.jade
new file mode 100644
index 0000000..e81dd9b
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/general.jade
@@ -0,0 +1,53 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+include ../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem'
+
+form.panel.panel-default(name='general' novalidate)
+    .panel-heading(bs-collapse-toggle)
+        ignite-form-panel-chevron
+        label General
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id='general')
+        .panel-body
+            .col-sm-6
+                .settings-row
+                    +text('Name:', model + '.name', 'igfsName', 'true', 'Input name', 'IGFS name')
+                .settings-row
+                    +clusters(model, 'Associate clusters with the current IGFS')
+                .settings-row
+                    +dropdown('IGFS mode:', model + '.defaultMode', 'defaultMode', 'true', 'DUAL_ASYNC',
+                    '[\
+                        {value: "PRIMARY", label: "PRIMARY"},\
+                        {value: "PROXY", label: "PROXY"},\
+                        {value: "DUAL_SYNC", label: "DUAL_SYNC"},\
+                        {value: "DUAL_ASYNC", label: "DUAL_ASYNC"}\
+                    ]',
+                    'Mode to specify how IGFS interacts with Hadoop file system:\
+                    <ul>\
+                        <li>PRIMARY - in this mode IGFS will not delegate to secondary Hadoop file system and will cache all the files in memory only</li>\
+                        <li>PROXY - in this mode IGFS will not cache any files in memory and will only pass them through to secondary file system</li>\
+                        <li>DUAL_SYNC - in this mode IGFS will cache files locally and also <b>synchronously</b> write them through to secondary file system</li>\
+                        <li>DUAL_ASYNC - in this mode IGFS will cache files locally and also <b> asynchronously </b> write them through to secondary file system</li>\
+                    </ul>')
+                .settings-row
+                    +number('Group size:', model + '.affinnityGroupSize', 'affinnityGroupSize', 'true', '512', '1',
+                        'Size of the group in blocks<br/>\
+                        Required for construction of affinity mapper in IGFS data cache')
+            .col-sm-6
+                +preview-xml-java(model, 'igfsGeneral')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.directive.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.directive.js
new file mode 100644
index 0000000..a0bd44c
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.directive.js
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import template from './ipc.jade!';
+
+export default ['igniteConfigurationIgfsIpc', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
new file mode 100644
index 0000000..3db3d8c
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
@@ -0,0 +1,56 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+include ../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem'
+
+form.panel.panel-default(name='ipc' novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')
+        ignite-form-panel-chevron
+        label IPC
+        ignite-form-field-tooltip.tipLabel
+            | IGFS Inter-process communication properties
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id='ipc')
+        .panel-body(ng-if='__show__')
+            .col-sm-6
+                -var ipcEndpointConfiguration = model + '.ipcEndpointConfiguration'
+                -var ipcEndpointEnabled = model + '.ipcEndpointEnabled'
+
+                .settings-row
+                    +checkbox('Enabled', model + '.ipcEndpointEnabled', 'ipcEndpointEnabled', 'IPC endpoint enabled flag')
+                .settings-row
+                    +dropdown('Type:', ipcEndpointConfiguration + '.type', 'ipcEndpointConfigurationType', ipcEndpointEnabled, 'TCP',
+                        '[\
+                            {value: "SHMEM", label: "SHMEM"},\
+                            {value: "TCP", label: "TCP"}\
+                        ]',
+                        'IPC endpoint type\
+                        <ul>\
+                            <li>SHMEM - shared memory endpoint</li>\
+                            <li>TCP - TCP endpoint</li>\
+                        </ul>')
+                .settings-row
+                    +text-ip-address('Host:', ipcEndpointConfiguration + '.host', 'ipcEndpointConfigurationHost', ipcEndpointEnabled, '127.0.0.1', 'Host name')
+                .settings-row
+                    +number-min-max('Port:', ipcEndpointConfiguration + '.port', 'ipcEndpointConfigurationPort', ipcEndpointEnabled, '10500', '1', '65535', 'Port number')
+                .settings-row
+                    +number('Memory size:', ipcEndpointConfiguration + '.memorySize', 'ipcEndpointConfigurationMemorySize', ipcEndpointEnabled, '262144', '1', 'Shared memory size in bytes allocated for endpoint communication')
+                .settings-row
+                    +text-enabled('Token directory:', ipcEndpointConfiguration + '.tokenDirectoryPath', 'ipcEndpointConfigurationTokenDirectoryPath', ipcEndpointEnabled, 'false', 'ipc/shmem', 'Directory where shared memory tokens are stored')
+            .col-sm-6
+                +preview-xml-java(model, 'igfsIPC')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.directive.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.directive.js
new file mode 100644
index 0000000..6a6ca12
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.directive.js
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import template from './misc.jade!';
+
+export default ['igniteConfigurationIgfsMisc', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.jade
new file mode 100644
index 0000000..4e8dd75
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/misc.jade
@@ -0,0 +1,118 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+include ../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem'
+-var pathModesForm = 'miscPathModes'
+-var pathModes = model + '.pathModes'
+
+mixin pathModeEditor(newItem)
+    -var field = newItem ? 'new' : 'edit'
+    -var path = field + 'Path'
+    -var mode = field + 'Mode'
+    -var reset = newItem ? 'group.add = []' : 'field.edit = false'
+    -var valid = pathModesForm + '.' + path + '.$valid && ' + pathModesForm + '.' + mode + '.$valid'
+    -var item = '{path:' + path + ', mode: ' + mode  + '}'
+    -var save = pathModes + (newItem ? '.push(' + item + ')' : '[$index] = ' + item)
+
+    .col-sm-12
+        .col-sm-8
+            label.fieldSep /
+            ignite-form-field-input-text(
+                data-id=path
+                data-name=path
+                data-ng-model=path
+                enter-focus-next=mode
+                data-ng-required='true'
+                data-placeholder='Input path'
+                data-ignite-form-field-input-autofocus='true'
+                on-escape=reset
+            )
+        .col-sm-4
+            .tipField
+                +table-save-button(valid, save, newItem)
+            ignite-form-field-dropdown(
+                data-id=mode
+                data-name=mode
+                data-ng-model=mode
+                data-options='[\
+                    {value: "PRIMARY", label: "PRIMARY"},\
+                    {value: "PROXY", label: "PROXY"},\
+                    {value: "DUAL_SYNC", label: "DUAL_SYNC"},\
+                    {value: "DUAL_ASYNC", label: "DUAL_ASYNC"}\
+                ]',
+                data-ng-required='true'
+                data-placeholder='Mode'
+                on-enter='!(#{valid}) || (#{save}); !(#{valid}) || (#{reset});'
+            )
+
+form.panel.panel-default(name='misc' novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')
+        ignite-form-panel-chevron
+        label Miscellaneous
+        ignite-form-field-tooltip.tipLabel
+            | Various miscellaneous IGFS settings
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id='misc')
+        .panel-body(ng-if='__show__')
+            .col-sm-6
+                .settings-row
+                    +number('Block size:', model + '.blockSize', 'blockSize', 'true', '65536', '0', 'File data block size in bytes')
+                .settings-row
+                    +number('Stream buffer size:', model + '.streamBufferSize', 'streamBufferSize', 'true', '65536', '0', 'File data block size in bytes')
+                .settings-row
+                    +number('Maximum space size:', model + '.maxSpaceSize', 'maxSpaceSize', 'true', '0', '0', 'Maximum space available for data cache to store file system entries')
+                .settings-row
+                    +number('Maximum task range length:', model + '.maximumTaskRangeLength', 'maximumTaskRangeLength', 'true', '0', '0', 'Maximum default range size of a file being split during IGFS task execution')
+                .settings-row
+                    +number-min-max('Management port:', model + '.managementPort', 'managementPort', 'true', '11400', '0', '65535', 'Port number for management endpoint')
+                .settings-row
+                    +number('Per node batch size:', model + '.perNodeBatchSize', 'perNodeBatchSize', 'true', '100', '0', 'Number of file blocks collected on local node before sending batch to remote node')
+                .settings-row
+                    +number('Per node parallel batch count:', model + '.perNodeParallelBatchCount', 'perNodeParallelBatchCount', 'true', '8', '0', 'Number of file block batches that can be concurrently sent to remote node')
+                .settings-row
+                    +number('Prefetch blocks:', model + '.prefetchBlocks', 'prefetchBlocks', 'true', '0', '0', 'Number of pre-fetched blocks if specific file chunk is requested')
+                .settings-row
+                    +number('Sequential reads before prefetch:', model + '.sequentialReadsBeforePrefetch', 'sequentialReadsBeforePrefetch', 'true', '0', '0', 'Amount of sequential block reads before prefetch is triggered')
+                .settings-row
+                    +number('Trash purge timeout:', model + '.trashPurgeTimeout', 'trashPurgeTimeout', 'true', '1000', '0', 'Maximum timeout awaiting for trash purging in case data cache oversize is detected')
+                .settings-row
+                    ignite-form-group(ng-model=pathModes ng-form=pathModesForm)
+                        ignite-form-field-label
+                            | Path modes
+                        ignite-form-group-tooltip
+                            | Map of path prefixes to IGFS modes used for them
+                        ignite-form-group-add(ng-click='field.edit = false; group.add = [{}];')
+                            | Add path mode
+
+                        .group-content(ng-if=pathModes + '.length')
+                            ignite-form-field(ng-repeat='model in #{pathModes} track by $index' type='internal' name='Path mode')
+                                +table-remove-button(pathModes, 'Remove path')
+                                span(ng-hide='field.edit')
+                                    a.labelFormField(ng-click='field.edit = true; group.add = []') {{ model.path }} [ {{ model.mode }}]
+                                span(ng-if='field.edit' ng-init='editPath = model.path; editMode = model.mode')
+                                    +pathModeEditor(false)
+
+                        .group-content(ng-repeat='field in group.add')
+                            ignite-form-field(type='internal' name='Path mode')
+                                +pathModeEditor(true)
+
+
+                        .group-content-empty(ng-if='!(#{pathModes}.length) && !group.add.length')
+                            | Not defined
+            .col-sm-6
+                +preview-xml-java(model, 'igfsMisc')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.directive.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.directive.js
new file mode 100644
index 0000000..8b3b37b
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.directive.js
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import template from './secondary.jade!';
+
+export default ['igniteConfigurationIgfsSecondary', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.jade
new file mode 100644
index 0000000..40f3f64
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.jade
@@ -0,0 +1,43 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+include ../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem'
+
+form.panel.panel-default(name='secondaryFileSystem' novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')
+        ignite-form-panel-chevron
+        label Secondary file system
+        ignite-form-field-tooltip.tipLabel
+            | Secondary file system is provided for pass-through, write-through, and read-through purposes
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id='secondaryFileSystem')
+        .panel-body(ng-if='__show__')
+            .col-sm-6
+                -var enabled = model + '.secondaryFileSystemEnabled'
+                -var secondaryFileSystem = model + '.secondaryFileSystem'
+
+                .settings-row
+                    +checkbox('Enabled', enabled, 'secondaryFileSystemEnabled', 'Secondary file system enabled flag')
+                .settings-row
+                    +text-enabled('URI:', secondaryFileSystem + '.uri', 'hadoopURI', enabled, 'false', 'hdfs://[namenodehost]:[port]/[path]', 'URI of file system')
+                .settings-row
+                    +text-enabled('Config path:', secondaryFileSystem + '.cfgPath', 'cfgPath', enabled, 'false', 'Path to additional config', 'Additional path to Hadoop configuration')
+                .settings-row
+                    +text-enabled('User name:', secondaryFileSystem + '.userName', 'userName', enabled, 'false', 'Input user name', 'User name')
+            .col-sm-6
+                +preview-xml-java(model, 'igfsSecondFS')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/caches-controller.js b/modules/control-center-web/src/main/js/controllers/caches-controller.js
index 9e15093..97d5266 100644
--- a/modules/control-center-web/src/main/js/controllers/caches-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/caches-controller.js
@@ -264,26 +264,29 @@ consoleModule.controller('cachesController', [
                 var firstError = errors[firstErrorKey][0];
                 var actualError = firstError.$error[firstErrorKey][0];
 
-                var errName = actualError.$name;
+                var errNameFull = actualError.$name;
+                var errNameShort = errNameFull;
 
-                if (errName.endsWith('TextInput') || errName.endsWith('JavaClass'))
-                    errName = errName.substring(0, errName.length - 9);
+                if (errNameShort.endsWith('TextInput') || errNameShort.endsWith('JavaClass'))
+                    errNameShort = errNameShort.substring(0, errNameShort.length - 9);
 
-                var msg = 'Invalid value';
-
-                try {
-                    msg = errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
-                }
-                catch(ignored) {
+                var extractErrorMessage = function (errName) {
                     try {
-                        msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
+                        return errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
                     }
-                    catch(ignited) {
-                        // No-op.
+                    catch(ignored) {
+                        try {
+                            msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
+                        }
+                        catch(ignited) {
+                            return false;
+                        }
                     }
-                }
+                };
+
+                var msg = extractErrorMessage(errNameFull) || extractErrorMessage(errNameShort) || 'Invalid value!';
 
-                return showPopoverMessage($scope.ui, firstError.$name, errName, msg);
+                return showPopoverMessage($scope.ui, firstError.$name, errNameFull, msg);
             }
 
             if (item.memoryMode === 'OFFHEAP_VALUES' && !$common.isEmptyArray(item.domains))

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/clusters-controller.js b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
index 784b770..6932af4 100644
--- a/modules/control-center-web/src/main/js/controllers/clusters-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
@@ -257,26 +257,29 @@ consoleModule.controller('clustersController', [
                 var firstError = errors[firstErrorKey][0];
                 var actualError = firstError.$error[firstErrorKey][0];
 
-                var errName = actualError.$name;
+                var errNameFull = actualError.$name;
+                var errNameShort = errNameFull;
 
-                if (errName.endsWith('TextInput') || errName.endsWith('JavaClass'))
-                    errName = errName.substring(0, errName.length - 9);
+                if (errNameShort.endsWith('TextInput') || errNameShort.endsWith('JavaClass'))
+                    errNameShort = errNameShort.substring(0, errNameShort.length - 9);
 
-                var msg = 'Invalid value!';
-
-                try {
-                    msg = errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
-                }
-                catch(ignored) {
+                var extractErrorMessage = function (errName) {
                     try {
-                        msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
+                        return errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
                     }
-                    catch(ignited) {
-                        // No-op.
+                    catch(ignored) {
+                        try {
+                            msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
+                        }
+                        catch(ignited) {
+                            return false;
+                        }
                     }
-                }
+                };
+
+                var msg = extractErrorMessage(errNameFull) || extractErrorMessage(errNameShort) || 'Invalid value!';
 
-                return showPopoverMessage($scope.ui, firstError.$name, errName, msg);
+                return showPopoverMessage($scope.ui, firstError.$name, errNameFull, msg);
             }
 
             var caches = _.filter(_.map($scope.caches, function (scopeCache) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index 4faf483..bb72ef0 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -603,14 +603,18 @@ consoleModule.service('$common', [
             if (popover)
                 popover.hide();
 
-            ensureActivePanel(ui, panelId, id);
+            ensureActivePanel(ui, panelId);
 
-            var el = $('body').find('#' + id);
+            var body = $('body');
+
+            var el = body.find('#' + id);
 
             if (!el || el.length === 0)
-                el = $('body').find('[name="' + id + '"]');
+                el = body.find('[name="' + id + '"]');
 
             if (el && el.length > 0) {
+                $focus(el[0].id);
+
                 var newPopover = $popover(el, {content: message});
 
                 popover = newPopover;


[26/50] [abbrv] ignite git commit: IGNITE-843 Fixed validation and code format.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/caches-controller.js b/modules/control-center-web/src/main/js/controllers/caches-controller.js
index 5ff8fe6..055417b 100644
--- a/modules/control-center-web/src/main/js/controllers/caches-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/caches-controller.js
@@ -249,10 +249,10 @@ consoleModule.controller('cachesController', [
             $common.hidePopover();
 
             if ($common.isEmptyString(item.name))
-                return showPopoverMessage($scope.ui, 'general', 'cacheName', 'Name should not be empty');
+                return showPopoverMessage($scope.ui, 'general', 'cacheName', 'Cache name should not be empty!');
 
             if (item.memoryMode === 'ONHEAP_TIERED' && item.offHeapMaxMemory > 0 && !$common.isDefined(item.evictionPolicy.kind))
-                return showPopoverMessage($scope.ui, 'memory', 'evictionPolicyKind', 'Eviction policy should not be configured');
+                return showPopoverMessage($scope.ui, 'memory', 'evictionPolicyKind', 'Eviction policy should not be configured!');
 
             var form = $scope.ui.inputForm;
             var errors = form.$error;
@@ -278,11 +278,11 @@ consoleModule.controller('cachesController', [
 
             if (item.memoryMode === 'OFFHEAP_VALUES' && !$common.isEmptyArray(item.domains))
                 return showPopoverMessage($scope.ui, 'memory', 'memoryMode',
-                    'Cannot have query indexing enabled while values are stored off-heap');
+                    'Query indexing could not be enabled while values are stored off-heap!');
 
             if (item.memoryMode === 'OFFHEAP_TIERED' && !$common.isDefined(item.offHeapMaxMemory))
                 return showPopoverMessage($scope.ui, 'memory', 'offHeapMaxMemory',
-                    'Off-heap max memory should be specified');
+                    'Off-heap max memory should be specified!');
 
             var cacheStoreFactorySelected = item.cacheStoreFactory && item.cacheStoreFactory.kind;
 
@@ -292,14 +292,14 @@ consoleModule.controller('cachesController', [
                 if (item.cacheStoreFactory.kind === 'CacheJdbcPojoStoreFactory') {
                     if ($common.isEmptyString(storeFactory.dataSourceBean))
                         return showPopoverMessage($scope.ui, 'store', 'dataSourceBean',
-                            'Data source bean name should not be empty');
+                            'Data source bean name should not be empty!');
 
                     if (!$common.isValidJavaIdentifier('Data source bean', storeFactory.dataSourceBean, 'dataSourceBean', $scope.ui, 'store'))
                         return false;
 
                     if (!storeFactory.dialect)
                         return showPopoverMessage($scope.ui, 'store', 'pojoDialect',
-                            'Dialect should not be empty');
+                            'Dialect should not be empty!');
 
                     if (!checkDataSources())
                         return false;
@@ -309,23 +309,23 @@ consoleModule.controller('cachesController', [
                     if (storeFactory.connectVia === 'URL') {
                         if ($common.isEmptyString(storeFactory.connectionUrl))
                             return showPopoverMessage($scope.ui, 'store', 'connectionUrl',
-                                'Connection URL should not be empty');
+                                'Connection URL should not be empty!');
 
                         if ($common.isEmptyString(storeFactory.user))
                             return showPopoverMessage($scope.ui, 'store', 'user',
-                                'User should not be empty');
+                                'User should not be empty!');
                     }
                     else {
                         if ($common.isEmptyString(storeFactory.dataSourceBean))
                             return showPopoverMessage($scope.ui, 'store', 'dataSourceBean',
-                                'Data source bean name should not be empty');
+                                'Data source bean name should not be empty!');
 
                         if (!$common.isValidJavaIdentifier('Data source bean', storeFactory.dataSourceBean, 'dataSourceBean', $scope.ui, 'store'))
                             return false;
 
                         if (!storeFactory.dialect)
                             return showPopoverMessage($scope.ui, 'store', 'blobDialect',
-                                'Database should not be empty');
+                                'Database should not be empty!');
 
                         if (!checkDataSources())
                             return false;
@@ -349,11 +349,11 @@ consoleModule.controller('cachesController', [
 
             if (item.writeBehindFlushSize === 0 && item.writeBehindFlushFrequency === 0)
                 return showPopoverMessage($scope.ui, 'store', 'writeBehindFlushSize',
-                    'Both "Flush frequency" and "Flush size" are not allowed as 0');
+                    'Both "Flush frequency" and "Flush size" are not allowed as 0!');
 
             if (item.cacheMode !== 'LOCAL' && item.rebalanceMode !== 'NONE' && item.rebalanceBatchSize === 0)
                 return showPopoverMessage($scope.ui, 'rebalance', 'rebalanceBatchSize',
-                    'Batch size should be more than 0 for not "NONE" rebalance mode', 10000);
+                    'Batch size should be more than 0 if rebalance mode is "SYNC" or "ASYNC" !', 10000);
 
             return true;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/clusters-controller.js b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
index e39be4f..ce133cf 100644
--- a/modules/control-center-web/src/main/js/controllers/clusters-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
@@ -245,7 +245,7 @@ consoleModule.controller('clustersController', [
             $common.hidePopover();
 
             if ($common.isEmptyString(item.name))
-                return showPopoverMessage($scope.ui, 'general', 'clusterName', 'Name should not be empty');
+                return showPopoverMessage($scope.ui, 'general', 'clusterName', 'Cluster name should not be empty!');
 
             var form = $scope.ui.inputForm;
             var errors = form.$error;
@@ -257,7 +257,7 @@ consoleModule.controller('clustersController', [
                 var firstError = errors[firstErrorKey][0];
                 var actualError = firstError.$error[firstErrorKey][0];
 
-                var msg = 'Invalid value';
+                var msg = 'Invalid value!';
 
                 try {
                     msg = errors[firstErrorKey][0].$errorMessages[actualError.$name][firstErrorKey];
@@ -302,10 +302,10 @@ consoleModule.controller('clustersController', [
                         var type = b.typeConfigurations[typeIx];
 
                         if ($common.isEmptyString(type.typeName))
-                            return showPopoverMessage($scope.ui, 'binary', 'typeName' + typeIx, 'Type name should be specified');
+                            return showPopoverMessage($scope.ui, 'binary', 'typeName' + typeIx, 'Type name should be specified!');
 
                         if (_.find(b.typeConfigurations, sameName))
-                            return showPopoverMessage($scope.ui, 'binary', 'typeName' + typeIx, 'Type with such name is already specified');
+                            return showPopoverMessage($scope.ui, 'binary', 'typeName' + typeIx, 'Type with such name is already specified!');
                     }
                 }
             }
@@ -316,56 +316,56 @@ consoleModule.controller('clustersController', [
                 if ($common.isDefined(c.unacknowledgedMessagesBufferSize)) {
                     if ($common.isDefined(c.messageQueueLimit))
                         if (c.unacknowledgedMessagesBufferSize < 5 * c.messageQueueLimit)
-                            return showPopoverMessage($scope.ui, 'communication', 'unacknowledgedMessagesBufferSize', 'Maximum number of stored unacknowledged messages should be at least 5 * message queue limit');
+                            return showPopoverMessage($scope.ui, 'communication', 'unacknowledgedMessagesBufferSize', 'Maximum number of stored unacknowledged messages should be at least 5 * message queue limit!');
 
                     if ($common.isDefined(c.ackSendThreshold))
                         if (c.unacknowledgedMessagesBufferSize < 5 * c.ackSendThreshold)
-                            return showPopoverMessage($scope.ui, 'communication', 'unacknowledgedMessagesBufferSize', 'Maximum number of stored unacknowledged messages should be at least 5 * ack send threshold');
+                            return showPopoverMessage($scope.ui, 'communication', 'unacknowledgedMessagesBufferSize', 'Maximum number of stored unacknowledged messages should be at least 5 * ack send threshold!');
                 }
 
                 if (c.sharedMemoryPort === 0)
-                    return showPopoverMessage($scope.ui, 'communication', 'sharedMemoryPort', 'Shared memory port should be more than 0 or -1');
+                    return showPopoverMessage($scope.ui, 'communication', 'sharedMemoryPort', 'Shared memory port should be more than "0" or equals to "-1"!');
             }
 
             var r = item.connector;
 
             if ($common.isDefined(r)) {
                 if (r.sslEnabled && $common.isEmptyString(r.sslFactory))
-                    return showPopoverMessage($scope.ui, 'connector', 'connectorSslFactory', 'SSL factory should not be empty');
+                    return showPopoverMessage($scope.ui, 'connector', 'connectorSslFactory', 'SSL factory should not be empty!');
             }
 
             var d = item.discovery;
 
             if (d) {
                 if ((d.maxAckTimeout != undefined ? d.maxAckTimeout : 600000) < (d.ackTimeout || 5000))
-                    return showPopoverMessage($scope.ui, 'discovery', 'ackTimeout', 'Acknowledgement timeout should be less than max acknowledgement timeout');
+                    return showPopoverMessage($scope.ui, 'discovery', 'ackTimeout', 'Acknowledgement timeout should be less than max acknowledgement timeout!');
 
                 if (d.kind === 'Vm' && d.Vm && d.Vm.addresses.length === 0)
-                    return showPopoverMessage($scope.ui, 'general', 'addresses', 'Addresses are not specified');
+                    return showPopoverMessage($scope.ui, 'general', 'addresses', 'Addresses are not specified!');
 
                 if (d.kind === 'S3' && d.S3 && $common.isEmptyString(d.S3.bucketName))
-                    return showPopoverMessage($scope.ui, 'general', 'bucketName', 'Bucket name should not be empty');
+                    return showPopoverMessage($scope.ui, 'general', 'bucketName', 'Bucket name should not be empty!');
 
                 if (d.kind === 'Cloud' && d.Cloud) {
                     if ($common.isEmptyString(d.Cloud.identity))
-                        return showPopoverMessage($scope.ui, 'general', 'identity', 'Identity should not be empty');
+                        return showPopoverMessage($scope.ui, 'general', 'identity', 'Identity should not be empty!');
 
                     if ($common.isEmptyString(d.Cloud.provider))
-                        return showPopoverMessage($scope.ui, 'general', 'provider', 'Provider should not be empty');
+                        return showPopoverMessage($scope.ui, 'general', 'provider', 'Provider should not be empty!');
                 }
 
                 if (d.kind === 'GoogleStorage' && d.GoogleStorage) {
                     if ($common.isEmptyString(d.GoogleStorage.projectName))
-                        return showPopoverMessage($scope.ui, 'general', 'projectName', 'Project name should not be empty');
+                        return showPopoverMessage($scope.ui, 'general', 'projectName', 'Project name should not be empty!');
 
                     if ($common.isEmptyString(d.GoogleStorage.bucketName))
-                        return showPopoverMessage($scope.ui, 'general', 'bucketName', 'Bucket name should not be empty');
+                        return showPopoverMessage($scope.ui, 'general', 'bucketName', 'Bucket name should not be empty!');
 
                     if ($common.isEmptyString(d.GoogleStorage.serviceAccountP12FilePath))
-                        return showPopoverMessage($scope.ui, 'general', 'serviceAccountP12FilePath', 'Private key path should not be empty');
+                        return showPopoverMessage($scope.ui, 'general', 'serviceAccountP12FilePath', 'Private key path should not be empty!');
 
                     if ($common.isEmptyString(d.GoogleStorage.serviceAccountId))
-                        return showPopoverMessage($scope.ui, 'general', 'serviceAccountId', 'Account ID should not be empty');
+                        return showPopoverMessage($scope.ui, 'general', 'serviceAccountId', 'Account ID should not be empty!');
                 }
             }
 
@@ -377,20 +377,20 @@ consoleModule.controller('clustersController', [
                 var sparsity = swap.maximumSparsity;
 
                 if ($common.isDefined(sparsity) && (sparsity < 0 || sparsity >= 1))
-                    return showPopoverMessage($scope.ui, 'swap', 'maximumSparsity', 'Maximum sparsity should be more or equal 0 and less than 1');
+                    return showPopoverMessage($scope.ui, 'swap', 'maximumSparsity', 'Maximum sparsity should be more or equal 0 and less than 1!');
 
                 var readStripesNumber = swap.readStripesNumber;
 
                 if (readStripesNumber && !(readStripesNumber == -1 || (readStripesNumber & (readStripesNumber - 1)) == 0))
-                    return showPopoverMessage($scope.ui, 'swap', 'readStripesNumber', 'Read stripe size must be positive and power of two');
+                    return showPopoverMessage($scope.ui, 'swap', 'readStripesNumber', 'Read stripe size must be positive and power of two!');
             }
 
             if (item.sslEnabled) {
                 if (!$common.isDefined(item.sslContextFactory) || $common.isEmptyString(item.sslContextFactory.keyStoreFilePath))
-                    return showPopoverMessage($scope.ui, 'sslConfiguration', 'keyStoreFilePath', 'Key store file should not be empty');
+                    return showPopoverMessage($scope.ui, 'sslConfiguration', 'keyStoreFilePath', 'Key store file should not be empty!');
 
                 if ($common.isEmptyString(item.sslContextFactory.trustStoreFilePath) && $common.isEmptyArray(item.sslContextFactory.trustManagers))
-                    return showPopoverMessage($scope.ui, 'sslConfiguration', 'sslConfiguration-title', 'Trust storage file or managers should be configured');
+                    return showPopoverMessage($scope.ui, 'sslConfiguration', 'sslConfiguration-title', 'Trust storage file or managers should be configured!');
             }
 
             if (!swapKind && item.caches) {
@@ -409,7 +409,7 @@ consoleModule.controller('clustersController', [
 
             if (item.rebalanceThreadPoolSize && item.systemThreadPoolSize && item.systemThreadPoolSize <= item.rebalanceThreadPoolSize)
                 return showPopoverMessage($scope.ui, 'pools', 'rebalanceThreadPoolSize',
-                    'Rebalance thread pool size exceed or equals System thread pool size');
+                    'Rebalance thread pool size exceed or equals System thread pool size!');
 
             return true;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/views/configuration/summary.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/configuration/summary.jade b/modules/control-center-web/src/main/js/views/configuration/summary.jade
index adec011..91b047c 100644
--- a/modules/control-center-web/src/main/js/views/configuration/summary.jade
+++ b/modules/control-center-web/src/main/js/views/configuration/summary.jade
@@ -66,8 +66,8 @@ mixin hard-link(ref, txt)
 
                         .panel-collapse(id='client' role='tabpanel' bs-collapse-target)
                             form(name='clientForm' novalidate)
-                                - var nearCfg = 'ctrl.cluster.clientNearCfg'
-                                - var nearCfgEvictionPolicy = nearCfg + '.nearEvictionPolicy[' + nearCfg + '.nearEvictionPolicy.kind]'
+                                -var nearCfg = 'ctrl.cluster.clientNearCfg'
+                                -var nearCfgEvictionPolicy = nearCfg + '.nearEvictionPolicy[' + nearCfg + '.nearEvictionPolicy.kind]'
 
                                 .details-row
                                     ignite-form-field.col-xs-8.col-sm-8.col-md-7(data-label='Near cache start size')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/includes/controls.jade b/modules/control-center-web/src/main/js/views/includes/controls.jade
index 9637b0b..aba4b54 100644
--- a/modules/control-center-web/src/main/js/views/includes/controls.jade
+++ b/modules/control-center-web/src/main/js/views/includes/controls.jade
@@ -143,14 +143,14 @@ mixin table-igfs-path-mode(header, tblMdl, keyFld, valFld, keyPlaceholder, valPl
                             +table-igfs-path-mode-edit('new', keyPlaceholder, valPlaceholder, '{{::field.focusId}}', '-1')
 
 mixin details-row(lblClasses, fieldClasses)
-    - var lblDetailClasses = lblClasses + ' details-label'
+    -var lblDetailClasses = lblClasses + ' details-label'
 
-    - var detailMdl = 'getModel(backupItem, detail)[detail.model]';
-    - var detailHide = '{{detail.hide}}'
-    - var detailCommon = {'ng-model': detailMdl, 'ng-required': '{{detail.required}}', 'ng-disabled': '{{detail.disabled}}', 'ng-focus': 'tableReset(true)'};
-    - var dropdownPlaceholder = {'ng-class': '{placeholder: !(' + detailMdl + ' && ' + detailMdl + '.length > 0)}'}
+    -var detailMdl = 'getModel(backupItem, detail)[detail.model]';
+    -var detailHide = '{{detail.hide}}'
+    -var detailCommon = {'ng-model': detailMdl, 'ng-required': '{{detail.required}}', 'ng-disabled': '{{detail.disabled}}', 'ng-focus': 'tableReset(true)'};
+    -var dropdownPlaceholder = {'ng-class': '{placeholder: !(' + detailMdl + ' && ' + detailMdl + '.length > 0)}'}
 
-    - var customValidators = {'ng-attr-ipaddress': '{{detail.ipaddress}}'}
+    -var customValidators = {'ng-attr-ipaddress': '{{detail.ipaddress}}'}
 
     div(ng-switch='detail.type')
         div(ng-switch-when='label' ng-hide=detailHide)
@@ -302,10 +302,10 @@ mixin table-binary-configurations(tblMdl, keyFld, valFld, keyPlaceholder, valPla
                         +table-row(['col-xs-4 col-sm-4 col-md-4'], ['col-xs-8 col-sm-8 col-md-8'])
 
 mixin table-row(lblClasses, fieldClasses)
-    - var lblRowClasses = lblClasses + ' details-label'
+    -var lblRowClasses = lblClasses + ' details-label'
 
-    - var rowMdl = 'getModel(backupItem, field)[field.model][rowIndex][tableField.model]';
-    - var rowCommon = {'ng-model': rowMdl, 'ng-required': '{{tableField.required}}', 'ng-disabled': '{{tableField.disabled}}', 'ng-focus': 'tableReset(true)'};
+    -var rowMdl = 'getModel(backupItem, field)[field.model][rowIndex][tableField.model]';
+    -var rowCommon = {'ng-model': rowMdl, 'ng-required': '{{tableField.required}}', 'ng-disabled': '{{tableField.disabled}}', 'ng-focus': 'tableReset(true)'};
 
     div(ng-switch='tableField.type')
         div.checkbox(ng-switch-when='check')
@@ -326,13 +326,13 @@ mixin form-row(dataSource)
     +form-row-custom(['col-xs-4 col-sm-4 col-md-4'], ['col-xs-8 col-sm-8 col-md-8'], dataSource)
 
 mixin form-row-custom(lblClasses, fieldClasses, dataSource)
-    - var fieldMdl = 'getModel('+ dataSource + ', field)[field.model]';
-    - var fieldCommon = {'ng-model': fieldMdl, 'ng-required': 'field.required || required(field)', 'ng-focus': 'tableReset(true)'};
-    - var fieldRequiredClass = '{true: "required"}[field.required || required(field)]'
-    - var fieldHide = '{{field.hide}}'
-    - var fieldDisabled = {'ng-disabled': '{{field.disabled}}'}
-    - var dropdownPlaceholder = {'ng-class': '{placeholder: ' + fieldMdl + ' == undefined || ' + fieldMdl + ' == null}'}
-    - var dropdownMultiPlaceholder = {'ng-class': '{placeholder: !(' + fieldMdl + ' && ' + fieldMdl + '.length > 0)}'}
+    -var fieldMdl = 'getModel('+ dataSource + ', field)[field.model]';
+    -var fieldCommon = {'ng-model': fieldMdl, 'ng-required': 'field.required || required(field)', 'ng-focus': 'tableReset(true)'};
+    -var fieldRequiredClass = '{true: "required"}[field.required || required(field)]'
+    -var fieldHide = '{{field.hide}}'
+    -var fieldDisabled = {'ng-disabled': '{{field.disabled}}'}
+    -var dropdownPlaceholder = {'ng-class': '{placeholder: ' + fieldMdl + ' == undefined || ' + fieldMdl + ' == null}'}
+    -var dropdownMultiPlaceholder = {'ng-class': '{placeholder: !(' + fieldMdl + ' && ' + fieldMdl + '.length > 0)}'}
 
     div(ng-switch='field.type')
         div(ng-switch-when='label' ng-hide=fieldHide)
@@ -386,7 +386,7 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource)
                 .input-tip
                     button.select-toggle.form-control(id='{{::field.id}}' bs-select ng-disabled='{{field.items}}.length == 0' data-multiple='1' data-placeholder='{{::$eval(field.items).length == 0 ? field.placeholderEmpty || field.placeholder : field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}' tabindex='-1')&attributes(fieldCommon)&attributes(dropdownMultiPlaceholder)
         div(ng-switch-when='dropdown-details' ng-hide=fieldHide)
-            - var expanded = 'field.details[' + fieldMdl + '].expanded'
+            -var expanded = 'field.details[' + fieldMdl + '].expanded'
 
             label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
             div(class=fieldClasses)


[39/50] [abbrv] ignite git commit: IGNITE-2676 Review

Posted by an...@apache.org.
IGNITE-2676 Review


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b99984c5
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b99984c5
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b99984c5

Branch: refs/heads/ignite-2875
Commit: b99984c5f30b3ae21e72a6b9047ee9e853a940ee
Parents: 8e3de18
Author: vsisko <vs...@gridgain.com>
Authored: Fri Mar 25 12:53:44 2016 +0700
Committer: vsisko <vs...@gridgain.com>
Committed: Fri Mar 25 12:53:44 2016 +0700

----------------------------------------------------------------------
 .../main/js/app/modules/states/configuration/igfs/secondary.jade   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b99984c5/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.jade
index 40f3f64..f4a5636 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/secondary.jade
@@ -21,7 +21,7 @@ include ../../../../../app/helpers/jade/mixins.jade
 form.panel.panel-default(name='secondaryFileSystem' novalidate)
     .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')
         ignite-form-panel-chevron
-        label Secondary file system
+        label(id="secondaryFileSystem-title") Secondary file system
         ignite-form-field-tooltip.tipLabel
             | Secondary file system is provided for pass-through, write-through, and read-through purposes
         ignite-form-revert


[14/50] [abbrv] ignite git commit: IGNITE-843 Removed signin from url. (cherry picked from commit 78eb5aa)

Posted by an...@apache.org.
IGNITE-843 Removed signin from url.
(cherry picked from commit 78eb5aa)


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b20a6936
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b20a6936
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b20a6936

Branch: refs/heads/ignite-2875
Commit: b20a6936d838ce3632f4844cfd63bd8374f5c7ed
Parents: 29e9356
Author: Andrey <an...@gridgain.com>
Authored: Fri Mar 11 10:43:38 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 21 15:34:00 2016 +0700

----------------------------------------------------------------------
 modules/control-center-web/src/main/js/app/index.js               | 3 +--
 .../src/main/js/app/modules/states/signin.state.js                | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b20a6936/modules/control-center-web/src/main/js/app/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/index.js b/modules/control-center-web/src/main/js/app/index.js
index ca9bf62..f959d2d 100644
--- a/modules/control-center-web/src/main/js/app/index.js
+++ b/modules/control-center-web/src/main/js/app/index.js
@@ -165,8 +165,7 @@ angular
             templateUrl: '/base.html'
         });
 
-    $urlRouterProvider.when('/', '/signin');
-    $urlRouterProvider.otherwise('/signin');
+    $urlRouterProvider.otherwise('/');
 
     $locationProvider.html5Mode(true);
 }])

http://git-wip-us.apache.org/repos/asf/ignite/blob/b20a6936/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/signin.state.js b/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
index 96ff967..ba14be6 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
+++ b/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
@@ -27,7 +27,7 @@ angular
     // set up the states
     $stateProvider
     .state('signin', {
-        url: '/signin',
+        url: '/',
         templateUrl: '/signin.html',
         metaTags: {
             title: 'Management Tool and Configuration Wizard for Apache Ignite'


[47/50] [abbrv] ignite git commit: IGNITE-843 Fixed validation in case of empty required input.

Posted by an...@apache.org.
IGNITE-843 Fixed validation in case of empty required input.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/cadbc5f8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/cadbc5f8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/cadbc5f8

Branch: refs/heads/ignite-2875
Commit: cadbc5f87992209c59e1ca883cbe5f91a6a99a11
Parents: 630cbbe
Author: AKuznetsov <ak...@gridgain.com>
Authored: Fri Mar 25 22:59:15 2016 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Fri Mar 25 22:59:15 2016 +0700

----------------------------------------------------------------------
 .../form-field-java-class.directive.js                    | 10 ++++++----
 .../js/app/modules/form/field/input/text.directive.js     | 10 ++++++----
 2 files changed, 12 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/cadbc5f8/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
index 142cb25..43219f9 100644
--- a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
@@ -56,10 +56,12 @@ export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
         scope.$watch('value', setAsDefault);
 
         const checkValid = () => {
-            if (ngModel.$invalid)
-                el.find('input').removeClass('ng-valid').addClass('ng-invalid');
-            else
-                el.find('input').addClass('ng-valid').removeClass('ng-invalid');
+            const input = el.find('input');
+
+            const invalid = ngModel.$invalid || (input[0].required && !input[0].value);
+
+            input.removeClass(invalid ? 'ng-valid' : 'ng-invalid');
+            input.addClass(invalid ? 'ng-invalid' : 'ng-valid');
         };
 
         scope.ngChange = () => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/cadbc5f8/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
index 99d7525..21b0d0f 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
@@ -64,10 +64,12 @@ export default ['igniteFormFieldInputText', ['IgniteFormGUID', (guid) => {
         scope.$watch('value', setAsDefault);
 
         const checkValid = () => {
-            if (ngModel.$invalid)
-                el.find('input').removeClass('ng-valid').addClass('ng-invalid');
-            else
-                el.find('input').addClass('ng-valid').removeClass('ng-invalid');
+            const input = el.find('input');
+
+            const invalid = ngModel.$invalid || (input[0].required && !input[0].value);
+
+            input.removeClass(invalid ? 'ng-valid' : 'ng-invalid');
+            input.addClass(invalid ? 'ng-invalid' : 'ng-valid');
         };
 
         scope.ngChange = () => {


[37/50] [abbrv] ignite git commit: IGNITE-2875 WIP

Posted by an...@apache.org.
IGNITE-2875 WIP


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8e08764a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8e08764a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8e08764a

Branch: refs/heads/ignite-2875
Commit: 8e08764a1c8375c1ae452ecd5400b0bed54c97cb
Parents: 63819d6
Author: Andrey <an...@gridgain.com>
Authored: Fri Mar 25 12:44:35 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Mar 25 12:44:35 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/serve/agent.js                  | 265 ++++++++++---------
 .../src/main/js/serve/browser.js                |  17 +-
 2 files changed, 144 insertions(+), 138 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8e08764a/modules/control-center-web/src/main/js/serve/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/agent.js b/modules/control-center-web/src/main/js/serve/agent.js
index 9d4ca4c..2966d5c 100644
--- a/modules/control-center-web/src/main/js/serve/agent.js
+++ b/modules/control-center-web/src/main/js/serve/agent.js
@@ -30,6 +30,7 @@ module.exports = {
 /**
  * @param _
  * @param fs
+ * @param ws
  * @param path
  * @param JSZip
  * @param socketio
@@ -40,48 +41,40 @@ module.exports = {
  */
 module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite, settings, mongo) {
     /**
-     * Creates an instance of server for Ignite.
+     *
      */
-    class AgentServer {
+    class Command {
         /**
-         * @this {AgentServer}
-         * @param {Agent} agent Connected agent
-         * @param {Boolean} demo Use demo node for request
+         * @param {Boolean} demo Is need run command on demo node.
+         * @param {String} name Command name.
          */
-        constructor(agent, demo) {
-            this._agent = agent;
-            this._demo = !!demo;
+        constructor(demo, name) {
+            this._demo = demo;
+
+            /**
+             * Command name.
+             * @type {String}
+             */
+            this._name = name;
+
+            /**
+             * Command parameters.
+             * @type {Array.<String>}
+             */
+            this._params = [];
         }
 
         /**
-         * Run http request
-         *
-         * @this {AgentServer}
-         * @param {cmd} cmd Command
-         * @param {callback} callback on finish
+         * Add parameter to command.
+         * @param {string} key Parameter key.
+         * @param {Object} value Parameter value.
+         * @returns {Command}
          */
-        runCommand(cmd, callback) {
-            const params = {cmd: cmd.name()};
-
-            for (const param of cmd._params)
-                params[param.key] = param.value;
-
-            let body;
-
-            let headers;
-
-            let method = 'GET';
+        addParam(key, value) {
+            this._params.push({key, value});
 
-            if (cmd._isPost()) {
-                body = cmd.postData();
-
-                method = 'POST';
-
-                headers = {JSONObject: 'application/json'};
-            }
-
-            this._agent.executeRest('ignite', params, this._demo, method, headers, body, callback);
-        }
+            return this;
+        };
     }
 
     /**
@@ -99,42 +92,6 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
              * @private
              */
             this._socket = socket;
-
-            /**
-             * Executor for grid.
-             *
-             * @type {apacheIgnite.Ignite}
-             * @private
-             */
-            this._cluster = new apacheIgnite.Ignite(new AgentServer(this));
-
-            /**
-             * Executor for demo node.
-             *
-             * @type {apacheIgnite.Ignite}
-             * @private
-             */
-            this._demo = new apacheIgnite.Ignite(new AgentServer(this, true));
-        }
-
-        /**
-         * Send message to agent.
-         *
-         * @param {String} event - Event name.
-         * @param {Object} data - Transmitted data.
-         * @returns {Promise}
-         */
-        _exec(event, data) {
-            const self = this;
-
-            return new Promise((resolve, reject) =>
-                self._emit(event, data, (error, res) => {
-                    if (error)
-                        return reject(error);
-
-                    resolve(res);
-                })
-            );
         }
 
         /**
@@ -157,72 +114,63 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
         }
 
         /**
-         * Execute rest request on node.
+         * Send message to agent.
          *
-         * @param {String} uri - REST endpoint uri.
-         * @param {Object} params - REST request parameters.
-         * @param {Boolean} demo - true if execute on demo node.
-         * @param {String} [method] - Request method GET or POST.
-         * @param {Object} [headers] - REST request headers.
-         * @param {String} [body] - REST request body
-         * @param {Function} [cb] Callback. Take 3 arguments: {Number} successStatus, {String} error,  {String} response.
+         * @param {String} event - Event name.
+         * @param {Object?} data - Transmitted data.
+         * @returns {Promise}
          */
-        executeRest(uri, params, demo, method, headers, body, cb) {
-            if (typeof (params) !== 'object')
-                throw '"params" argument must be an object';
+        executeAgent(event, data) {
+            return new Promise((resolve, reject) =>
+                this._emit(event, data, (error, res) => {
+                    if (error)
+                        return reject(error);
 
-            if (typeof (cb) !== 'function')
-                throw 'callback must be a function';
+                    resolve(res);
+                })
+            );
+        }
 
-            if (body && typeof (body) !== 'string')
-                throw 'body must be a string';
+        /**
+         * Execute rest request on node.
+         *
+         * @param {Command} cmd - REST command.
+         * @return {Promise}
+         */
+        executeRest(cmd) {
+            const params = {cmd: cmd._name};
 
-            if (headers && typeof (headers) !== 'object')
-                throw 'headers must be an object';
+            for (const param of this._params)
+                params[param.key] = param.value;
 
-            method = method ? method.toUpperCase() : 'GET';
+            return new Promise((resolve, reject) => {
+                this._emit('node:rest', {uri: 'ignite', params, demo: cmd._demo, method: 'GET'}, (error, restResult) => {
+                    if (error)
+                        return reject(new Error(error));
 
-            if (method !== 'GET' && method !== 'POST')
-                throw 'Unknown HTTP method: ' + method;
+                    error = restResult.error;
 
-            const _cb = (error, restResult) => {
-                if (error)
-                    return cb(error);
+                    const code = restResult.code;
 
-                error = restResult.error;
+                    if (code === 401)
+                        return reject(Error('Failed to authenticate on node.', 2));
 
-                const code = restResult.code;
+                    if (code !== 200)
+                        return reject(new Error(error || 'Failed connect to node and execute REST command.'));
 
-                if (code !== 200) {
-                    if (code === 401)
-                        return cb({code, message: 'Failed to authenticate on node.'});
+                    try {
+                        const response = JSON.parse(restResult.data);
 
-                    return cb({code, message: error || 'Failed connect to node and execute REST command.'});
-                }
+                        if (response.successStatus === 0)
+                            return resolve(response.response);
 
-                try {
-                    const response = JSON.parse(restResult.data);
-
-                    if (response.successStatus === 0)
-                        return cb(null, response.response);
-
-                    switch (response.successStatus) {
-                        case 1:
-                            return cb({code: 500, message: response.error});
-                        case 2:
-                            return cb({code: 401, message: response.error});
-                        case 3:
-                            return cb({code: 403, message: response.error});
-                        default:
-                            return cb(response.error);
+                        reject(new Error(response.error, response.successStatus));
                     }
-                }
-                catch (e) {
-                    return cb(e);
-                }
-            };
-
-            this._emit('node:rest', {uri, params, demo, method, headers, body}, _cb);
+                    catch (e) {
+                        return reject(e);
+                    }
+                });
+            });
         }
 
         /**
@@ -233,7 +181,7 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
          * @returns {Promise} Promise on list of tables (see org.apache.ignite.schema.parser.DbTable java class)
          */
         metadataSchemas(driverPath, driverClass, url, info) {
-            return this._exec('schemaImport:schemas', {driverPath, driverClass, url, info});
+            return this.executeAgent('schemaImport:schemas', {driverPath, driverClass, url, info});
         }
 
         /**
@@ -246,14 +194,79 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
          * @returns {Promise} Promise on list of tables (see org.apache.ignite.schema.parser.DbTable java class)
          */
         metadataTables(driverPath, driverClass, url, info, schemas, tablesOnly) {
-            return this._exec('schemaImport:metadata', {driverPath, driverClass, url, info, schemas, tablesOnly});
+            return this.executeAgent('schemaImport:metadata', {driverPath, driverClass, url, info, schemas, tablesOnly});
         }
 
         /**
          * @returns {Promise} Promise on list of jars from driver folder.
          */
         availableDrivers() {
-            return this._exec('schemaImport:drivers');
+            return this.executeAgent('schemaImport:drivers');
+        }
+
+        /**
+         *
+         * @param {Boolean} demo Is need run command on demo node.
+         * @param {Boolean} attr Get attributes, if this parameter has value true. Default value: true.
+         * @param {Boolean} mtr Get metrics, if this parameter has value true. Default value: false.
+         * @returns {Promise}
+         */
+        topology(demo, attr, mtr) {
+            var cmd = new Command(demo, 'top')
+                .addParam('attr', attr !== false)
+                .addParam('mtr', !!mtr);
+
+            this.executeRest(cmd);
+        }
+
+        /**
+         *
+         * @param res
+         * @return {{meta: Array, rows: Array, queryId: int}}
+         * @private
+         */
+        static _onQueryResult(res) {
+            const queryId = res === null && res["last"] ? null : queryId;
+
+            return {
+                meta: res['fieldsMetadata'],
+                rows: res['items'],
+                queryId
+            }
+        }
+
+        /**
+         *
+         * @param {Boolean} demo Is need run command on demo node.
+         * @param {String} cacheName Cache name.
+         * @param {String} query Query.
+         * @param {int} pageSize Page size.
+         * @returns {Promise}
+         */
+        fieldsQuery(demo, cacheName, query, pageSize) {
+            var cmd = new Command(demo, 'qryfldexe')
+                .addParam('cacheName', cacheName)
+                .addParam('query', query)
+                .addParam('pageSize', pageSize);
+
+            this.executeRest(cmd)
+                .then(this._onQueryResult);
+        }
+
+        /**
+         *
+         * @param {Boolean} demo Is need run command on demo node.
+         * @param {String} cacheName Cache name.
+         * @param {int} pageSize Page size.
+         * @returns {Promise}
+         */
+        scan(demo, cacheName, pageSize) {
+            var cmd = new Command(demo, 'qryscanexe')
+                .addParam('cacheName', cacheName)
+                .addParam('pageSize', pageSize);
+
+            this.executeRest(cmd)
+                .then(this._onQueryResult);
         }
 
         /**
@@ -327,7 +340,7 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
                 }
             }
 
-            const latest = _.first(Object.keys(this.supportedAgents).sort((a, b) => {
+            const latest = _.head(Object.keys(this.supportedAgents).sort((a, b) => {
                 const aParts = a.split('.');
                 const bParts = b.split('.');
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8e08764a/modules/control-center-web/src/main/js/serve/browser.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/browser.js b/modules/control-center-web/src/main/js/serve/browser.js
index 4470ce2..465f75f 100644
--- a/modules/control-center-web/src/main/js/serve/browser.js
+++ b/modules/control-center-web/src/main/js/serve/browser.js
@@ -76,7 +76,7 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                 // Return topology command result from grid to browser.
                 socket.on('node:topology', (demo, attr, mtr, cb) => {
                     agentMgr.findAgent(user._id)
-                        .then((agent) => agent.ignite(demo).cluster(attr, mtr))
+                        .then((agent) => agent.topology(demo, attr, mtr))
                         .then((clusters) => cb(null, clusters))
                         .catch((errMsg) => cb(errMsg));
                 });
@@ -97,19 +97,12 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                 socket.on('node:query', (args, cb) => {
                     agentMgr.findAgent(user._id)
                         .then((agent) => {
-                            // Create sql query.
-                            const qry = args.type === 'SCAN' ? new ScanQuery() : new SqlFieldsQuery(args.query);
+                            if (args.type === 'SCAN')
+                                return agent.scan(args.demo, args.cacheName, args.pageSize);
 
-                            // Set page size for query.
-                            qry.setPageSize(args.pageSize);
-
-                            return agent.ignite(args.demo).cache(args.cacheName).query(qry).nextPage();
+                            return agent.fieldsQuery(args.demo, args.cacheName, args.query, args.pageSize);
                         })
-                        .then((cursor) => cb(null, {
-                            meta: cursor.fieldsMetadata(),
-                            rows: cursor.page(),
-                            queryId: cursor.queryId()
-                        }))
+                        .then((res) => cb(null, res))
                         .catch((errMsg) => cb(errMsg));
                 });
 


[10/50] [abbrv] ignite git commit: IGNITE-2597 Fixed typo.

Posted by an...@apache.org.
IGNITE-2597 Fixed typo.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a8921c62
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a8921c62
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a8921c62

Branch: refs/heads/ignite-2875
Commit: a8921c621f9fe42f6850871b66ce48e25bc68fb6
Parents: 706317f
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Mar 18 16:34:41 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Mar 18 16:34:41 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/app/modules/user/Auth.service.js                   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a8921c62/modules/control-center-web/src/main/js/app/modules/user/Auth.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/user/Auth.service.js b/modules/control-center-web/src/main/js/app/modules/user/Auth.service.js
index 55bae1c..8894148 100644
--- a/modules/control-center-web/src/main/js/app/modules/user/Auth.service.js
+++ b/modules/control-center-web/src/main/js/app/modules/user/Auth.service.js
@@ -56,7 +56,7 @@ export default ['Auth', ['$http', '$rootScope', '$state', '$common', 'IgniteGett
                         } else
                             $state.go('password.send');
                     })
-                    .catch((errMsg) => $common.showPopoverMessage(null, null, 'user_email', errMsg.data));
+                    .catch((errMsg) => $common.showPopoverMessage(null, null, 'email', errMsg.data));
             },
             logout() {
                 $http.post('/api/v1/logout')


[44/50] [abbrv] ignite git commit: Merge remote-tracking branch 'community/web-console-staging' into web-console-staging

Posted by an...@apache.org.
Merge remote-tracking branch 'community/web-console-staging' into web-console-staging


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/214c9b27
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/214c9b27
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/214c9b27

Branch: refs/heads/ignite-2875
Commit: 214c9b276349ea277efd85593b7780141f24853d
Parents: e1a5dad 1017ea8
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Mar 25 14:29:23 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Mar 25 14:29:23 2016 +0700

----------------------------------------------------------------------
 modules/control-center-web/src/main/js/views/signin.jade | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------



[13/50] [abbrv] ignite git commit: IGNITE-843 Refactoring, jsDoc.

Posted by an...@apache.org.
IGNITE-843 Refactoring, jsDoc.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b30b52b1
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b30b52b1
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b30b52b1

Branch: refs/heads/ignite-2875
Commit: b30b52b1ab8f7e50252857af97e18b0c3092b782
Parents: 2651715
Author: Andrey <an...@gridgain.com>
Authored: Mon Mar 21 14:27:08 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 21 14:27:08 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/app/decorator/select.js         |  25 +-
 .../control-center-web/src/main/js/app/index.js |   1 -
 .../js/app/services/AgentMonitor.service.js     |  10 +
 .../src/main/js/controllers/sql-controller.js   |   2 +-
 modules/control-center-web/src/main/js/serve.js |  12 +-
 .../src/main/js/serve/agent.js                  | 195 +++++++-------
 .../control-center-web/src/main/js/serve/app.js |   2 +-
 .../src/main/js/serve/browser.js                | 254 +++++++++++++++++++
 .../src/main/js/serve/configure.js              |   3 +
 .../control-center-web/src/main/js/serve/io.js  | 242 ------------------
 .../src/main/js/serve/mail.js                   |   3 +
 .../src/main/js/serve/mongo.js                  |   3 +
 .../src/main/js/serve/routes/agent.js           |   2 +-
 .../src/main/js/serve/routes/profile.js         |  12 +-
 .../src/main/js/serve/settings.js               |   3 +
 15 files changed, 407 insertions(+), 362 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/app/decorator/select.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/decorator/select.js b/modules/control-center-web/src/main/js/app/decorator/select.js
index f232f88..13a4041 100644
--- a/modules/control-center-web/src/main/js/app/decorator/select.js
+++ b/modules/control-center-web/src/main/js/app/decorator/select.js
@@ -31,31 +31,32 @@ angular.module('mgcrea.ngStrap.select')
 
             const scope = deligate.$scope;
 
+            const _valueMap = (index) => {
+                if (angular.isUndefined(scope.$matches[index]))
+                    return null;
+
+                return scope.$matches[index].value;
+            };
+
             const selectAll = (active) => {
-                var selected = [];
+                const selected = [];
 
-                scope.$apply(function () {
-                    for (var i = 0; i < scope.$matches.length; i++) {
+                scope.$apply(() => {
+                    for (let i = 0; i < scope.$matches.length; i++) {
                         if (scope.$isActive(i) === active) {
                             selected[i] = scope.$matches[i].value;
 
                             deligate.activate(i);
 
-                            controller.$setViewValue(scope.$activeIndex.map(function (index) {
-                                if (angular.isUndefined(scope.$matches[index])) {
-                                    return null;
-                                }
-                                return scope.$matches[index].value;
-                            }));
+                            controller.$setViewValue(scope.$activeIndex.map(_valueMap));
                         }
                     }
                 });
 
                 // Emit events.
-                for (var i = 0; i < selected.length; i++) {
-                    if (selected[i]) {
+                for (let i = 0; i < selected.length; i++) {
+                    if (selected[i])
                         scope.$emit(options.prefixEvent + '.select', selected[i], i, deligate);
-                    }
                 }
             };
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/app/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/index.js b/modules/control-center-web/src/main/js/app/index.js
index 1537eb9..60a3a8b 100644
--- a/modules/control-center-web/src/main/js/app/index.js
+++ b/modules/control-center-web/src/main/js/app/index.js
@@ -20,7 +20,6 @@ import _ from 'lodash';
 import ace from 'ace';
 import angular from 'angular';
 import pdfMake from 'pdfmake';
-import io from 'socket.io-client';
 
 window._ = _;
 window.ace = ace;

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js b/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
index cf66b61..1b661a3 100644
--- a/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
+++ b/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
@@ -15,6 +15,8 @@
  * limitations under the License.
  */
 
+import io from 'socket.io-client';
+
 class IgniteAgentMonitor {
     constructor(socketFactory, $root, $q, $state, $modal, $common) {
         this._scope = $root.$new();
@@ -257,6 +259,14 @@ class IgniteAgentMonitor {
     }
 
     /**
+     * @param {Object} args
+     * @returns {Promise}
+     */
+    queryGetAll(args) {
+        return this._rest('node:query:getAll', args);
+    }
+
+    /**
      * @param {Boolean} demo
      * @returns {Promise}
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
index dd712f8..35c0126 100644
--- a/modules/control-center-web/src/main/js/controllers/sql-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -902,7 +902,7 @@ consoleModule.controller('sqlController', [
         };
 
         $scope.exportCsvAll = function (paragraph) {
-            IgniteAgentMonitor.query({
+            IgniteAgentMonitor.queryGetAll({
                     demo: $scope.demo,
                     type: paragraph.queryArgs.type,
                     query: paragraph.queryArgs.query,

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve.js b/modules/control-center-web/src/main/js/serve.js
index 74342a9..cba74d3 100644
--- a/modules/control-center-web/src/main/js/serve.js
+++ b/modules/control-center-web/src/main/js/serve.js
@@ -66,12 +66,12 @@ const fireUp = require('fire-up').newInjector({
     ]
 });
 
-Promise.all([fireUp('settings'), fireUp('app'), fireUp('agent'), fireUp('io')])
+Promise.all([fireUp('settings'), fireUp('app'), fireUp('agent-manager'), fireUp('browser-manager')])
     .then((values) => {
         const settings = values[0];
         const app = values[1];
-        const agent = values[2];
-        const io = values[3];
+        const agentMgr = values[2];
+        const browserMgr = values[3];
 
         // Start rest server.
         const server = settings.server.SSLOptions
@@ -82,7 +82,7 @@ Promise.all([fireUp('settings'), fireUp('app'), fireUp('agent'), fireUp('io')])
         server.on('listening', _onListening.bind(null, server.address()));
 
         app.listen(server);
-        io.listen(server);
+        browserMgr.attach(server);
 
         // Start agent server.
         const agentServer = settings.agent.SSLOptions
@@ -92,13 +92,13 @@ Promise.all([fireUp('settings'), fireUp('app'), fireUp('agent'), fireUp('io')])
         agentServer.on('error', _onError.bind(null, settings.agent.port));
         agentServer.on('listening', _onListening.bind(null, agentServer.address()));
 
-        agent.listen(agentServer);
+        agentMgr.attach(agentServer);
 
         // Used for automated test.
         if (process.send)
             process.send('running');
     }).catch((err) => {
-        console.error(error);
+        console.error(err);
 
         process.exit(1);
     });

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/agent.js b/modules/control-center-web/src/main/js/serve/agent.js
index 04d7ed6..6e249f0 100644
--- a/modules/control-center-web/src/main/js/serve/agent.js
+++ b/modules/control-center-web/src/main/js/serve/agent.js
@@ -19,8 +19,11 @@
 
 // Fire me up!
 
+/**
+ * Module interaction with agents.
+ */
 module.exports = {
-    implements: 'agent',
+    implements: 'agent-manager',
     inject: ['require(lodash)', 'require(fs)', 'require(path)', 'require(jszip)', 'require(socket.io)', 'require(apache-ignite)', 'settings', 'mongo']
 };
 
@@ -81,34 +84,44 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, se
         }
     }
 
+    /**
+     * Connected agent descriptor.
+     */
     class Agent {
         /**
-         * @param {socketIo.Socket} _wsSrv
-         * @param {AgentManager} manager
+         * @param {socketIo.Socket} socket - Agent socket for interaction.
          */
-        constructor(_wsSrv, manager) {
-            const self = this;
-
-            this._manager = manager;
-
+        constructor(socket) {
             /**
+             * Agent socket for interaction.
+             *
              * @type {socketIo.Socket}
              * @private
              */
-            this._wsAgents = _wsSrv;
+            this._socket = socket;
 
-            this._wsAgents.on('disconnect', () => {
-                if (self._user)
-                    self._manager._removeAgent(self._user._id, self);
-            });
+            /**
+             * Executor for grid.
+             *
+             * @type {apacheIgnite.Ignite}
+             * @private
+             */
+            this._cluster = new apacheIgnite.Ignite(new AgentServer(this));
 
-            this._wsAgents.on('agent:auth', (msg, cb) => self._processAuth(msg, cb));
+            /**
+             * Executor for demo node.
+             *
+             * @type {apacheIgnite.Ignite}
+             * @private
+             */
+            this._demo = new apacheIgnite.Ignite(new AgentServer(this, true));
         }
 
         /**
+         * Send message to agent.
          *
-         * @param event
-         * @param data
+         * @param {String} event - Event name.
+         * @param {Object} data - Transmitted data.
          * @returns {Promise}
          */
         _exec(event, data) {
@@ -125,12 +138,33 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, se
         }
 
         /**
-         * @param {String} uri
-         * @param {Object} params
-         * @param {Boolean} demo
-         * @param {String} [method]
-         * @param {Object} [headers]
-         * @param {String} [body]
+         * Send message to agent.
+         *
+         * @this {Agent}
+         * @param {String} event Command name.
+         * @param {Object} data Command params.
+         * @param {Function} [callback] on finish
+         */
+        _emit(event, data, callback) {
+            if (!this._socket.connected) {
+                if (callback)
+                    callback('org.apache.ignite.agent.AgentException: Connection is closed');
+
+                return;
+            }
+
+            this._socket.emit(event, data, callback);
+        }
+
+        /**
+         * Execute rest request on node.
+         *
+         * @param {String} uri - REST endpoint uri.
+         * @param {Object} params - REST request parameters.
+         * @param {Boolean} demo - true if execute on demo node.
+         * @param {String} [method] - Request method GET or POST.
+         * @param {Object} [headers] - REST request headers.
+         * @param {String} [body] - REST request body
          * @param {Function} [cb] Callback. Take 3 arguments: {Number} successStatus, {String} error,  {String} response.
          */
         executeRest(uri, params, demo, method, headers, body, cb) {
@@ -223,90 +257,38 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, se
         }
 
         /**
-         * Run http request
-         *
-         * @this {Agent}
-         * @param {String} event Command name.
-         * @param {Object} data Command params.
-         * @param {Function} [callback] on finish
-         */
-        _emit(event, data, callback) {
-            if (!this._wsAgents.connected) {
-                if (callback)
-                    callback('org.apache.ignite.agent.AgentException: Connection is closed');
-
-                return;
-            }
-
-            this._wsAgents.emit(event, data, callback);
-        }
-
-        /**
-         * Process auth request.
-         *
-         * @param {Object} data
-         * @param {Function} cb
-         * @private
-         */
-        _processAuth(data, cb) {
-            const self = this;
-
-            if (!_.isEmpty(this._manager.supportedAgents)) {
-                const ver = data.ver;
-                const bt = data.bt;
-
-                if (_.isEmpty(ver) || _.isEmpty(bt) || _.isEmpty(this._manager.supportedAgents[ver]) ||
-                    this._manager.supportedAgents[ver].buildTime > bt)
-                    return cb('You are using an older version of the agent. Please reload agent archive');
-            }
-
-            mongo.Account.findOne({token: data.token}, (err, account) => {
-                // TODO IGNITE-1379 send error to web master.
-                if (err)
-                    cb('Failed to authorize user');
-                else if (!account)
-                    cb('Invalid token, user not found');
-                else {
-                    self._user = account;
-
-                    self._manager._addAgent(account._id, self);
-
-                    self._cluster = new apacheIgnite.Ignite(new AgentServer(self));
-
-                    self._demo = new apacheIgnite.Ignite(new AgentServer(self, true));
-
-                    cb();
-                }
-            });
-        }
-
-        /**
-         * @returns {Ignite}
+         * @returns {apacheIgnite.Ignite}
          */
         ignite(demo) {
             return demo ? this._demo : this._cluster;
         }
     }
 
+    /**
+     * Connected agents manager.
+     */
     class AgentManager {
         /**
          * @constructor
          */
         constructor() {
             /**
+             * Connected agents by user id.
              * @type {Object.<ObjectId, Array.<Agent>>}
              */
             this._agents = {};
 
             /**
+             * Connected browsers by user id.
              * @type {Object.<ObjectId, Array.<Socket>>}
              */
-            this._users = {};
+            this._browsers = {};
 
             const agentArchives = fs.readdirSync(settings.agent.dists)
                 .filter((file) => path.extname(file) === '.zip');
 
             /**
+             * Supported agents distribution.
              * @type {Object.<String, String>}
              */
             this.supportedAgents = {};
@@ -360,14 +342,15 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, se
                 }
             }));
 
+            // Latest version of agent distribution.
             if (latest)
                 this.supportedAgents.latest = this.supportedAgents[latest];
         }
 
         /**
-         * @param {http.Server|https.Server} srv
+         * @param {http.Server|https.Server} srv Server instance that we want to attach agent handler.
          */
-        listen(srv) {
+        attach(srv) {
             if (this._server)
                 throw 'Agent server already started!';
 
@@ -376,11 +359,39 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, se
             /**
              * @type {WebSocketServer}
              */
-            this._wsAgents = socketio(this._server);
+            this._socket = socketio(this._server);
 
-            const self = this;
+            this._socket.on('connection', (socket) => {
+                socket.on('agent:auth', (data, cb) => {
+                    if (!_.isEmpty(this.supportedAgents)) {
+                        const ver = data.ver;
+                        const bt = data.bt;
+
+                        if (_.isEmpty(ver) || _.isEmpty(bt) || _.isEmpty(this.supportedAgents[ver]) ||
+                            this.supportedAgents[ver].buildTime > bt)
+                            return cb('You are using an older version of the agent. Please reload agent archive');
+                    }
 
-            this._wsAgents.on('connection', (_wsSrv) => new Agent(_wsSrv, self));
+                    mongo.Account.findOne({token: data.token}, (err, account) => {
+                        // TODO IGNITE-1379 send error to web master.
+                        if (err)
+                            cb('Failed to authorize user');
+                        else if (!account)
+                            cb('Invalid token, user not found');
+                        else {
+                            const agent = new Agent(socket);
+
+                            socket.on('disconnect', () => {
+                                this._removeAgent(account._id, agent);
+                            });
+
+                            this._addAgent(account._id, agent);
+
+                            cb();
+                        }
+                    });
+                });
+            });
         }
 
         /**
@@ -389,10 +400,10 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, se
          * @returns {int} connected agent count.
          */
         addAgentListener(userId, user) {
-            let users = this._users[userId];
+            let users = this._browsers[userId];
 
             if (!users)
-                this._users[userId] = users = [];
+                this._browsers[userId] = users = [];
 
             users.push(user);
 
@@ -407,7 +418,7 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, se
          * @returns {int} connected agent count.
          */
         removeAgentListener(userId, user) {
-            const users = this._users[userId];
+            const users = this._browsers[userId];
 
             _.remove(users, (_user) => _user === user);
         }
@@ -453,7 +464,7 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, se
 
             _.remove(agents, (_agent) => _agent === agent);
 
-            const users = this._users[userId];
+            const users = this._browsers[userId];
 
             _.forEach(users, (user) => user.emit('agent:count', {count: agents.length}));
         }
@@ -470,7 +481,7 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, se
 
             agents.push(agent);
 
-            const users = this._users[userId];
+            const users = this._browsers[userId];
 
             _.forEach(users, (user) => user.emit('agent:count', {count: agents.length}));
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve/app.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/app.js b/modules/control-center-web/src/main/js/serve/app.js
index e4b5eca..5d6b2cf 100644
--- a/modules/control-center-web/src/main/js/serve/app.js
+++ b/modules/control-center-web/src/main/js/serve/app.js
@@ -21,7 +21,7 @@
 
 module.exports = {
     implements: 'app',
-    inject: ['require(express)', 'configure', 'routes', 'io']
+    inject: ['require(express)', 'configure', 'routes']
 };
 
 module.exports.factory = function(Express, configure, routes) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve/browser.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/browser.js b/modules/control-center-web/src/main/js/serve/browser.js
new file mode 100644
index 0000000..4470ce2
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/browser.js
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+'use strict';
+
+// Fire me up!
+
+/**
+ * Module interaction with browsers.
+ */
+module.exports = {
+    implements: 'browser-manager',
+    inject: ['require(lodash)', 'require(socket.io)', 'require(apache-ignite)', 'agent-manager', 'configure']
+};
+
+module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
+    const SqlFieldsQuery = apacheIgnite.SqlFieldsQuery;
+    const ScanQuery = apacheIgnite.ScanQuery;
+
+    return {
+        attach: (server) => {
+            const io = socketio(server);
+
+            configure.socketio(io);
+
+            io.sockets.on('connection', (socket) => {
+                const user = socket.client.request.user;
+
+                // Return available drivers to browser.
+                socket.on('schemaImport:drivers', (cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => agent.availableDrivers())
+                        .then((drivers) => cb(null, drivers))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                // Return schemas from database to browser.
+                socket.on('schemaImport:schemas', (preset, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            const jdbcInfo = {user: preset.user, password: preset.password};
+
+                            return agent.metadataSchemas(preset.jdbcDriverJar, preset.jdbcDriverClass, preset.jdbcUrl, jdbcInfo);
+                        })
+                        .then((schemas) => cb(null, schemas))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                // Return tables from database to browser.
+                socket.on('schemaImport:tables', (preset, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            const jdbcInfo = {user: preset.user, password: preset.password};
+
+                            return agent.metadataTables(preset.jdbcDriverJar, preset.jdbcDriverClass, preset.jdbcUrl, jdbcInfo,
+                                preset.schemas, preset.tablesOnly);
+                        })
+                        .then((tables) => cb(null, tables))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                // Return topology command result from grid to browser.
+                socket.on('node:topology', (demo, attr, mtr, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => agent.ignite(demo).cluster(attr, mtr))
+                        .then((clusters) => cb(null, clusters))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                // Close query on node.
+                socket.on('node:query:close', (args, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            const cache = agent.ignite(args.demo).cache(args.cacheName);
+
+                            return cache.__createPromise(cache._createCommand('qrycls').addParam('qryId', args.queryId));
+                        })
+                        .then(() => cb())
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                // Execute query on node and return first page to browser.
+                socket.on('node:query', (args, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            // Create sql query.
+                            const qry = args.type === 'SCAN' ? new ScanQuery() : new SqlFieldsQuery(args.query);
+
+                            // Set page size for query.
+                            qry.setPageSize(args.pageSize);
+
+                            return agent.ignite(args.demo).cache(args.cacheName).query(qry).nextPage();
+                        })
+                        .then((cursor) => cb(null, {
+                            meta: cursor.fieldsMetadata(),
+                            rows: cursor.page(),
+                            queryId: cursor.queryId()
+                        }))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                // Fetch next page for query and return result to browser.
+                socket.on('node:query:fetch', (args, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            const cache = agent.ignite(args.demo).cache(args.cacheName);
+
+                            const cmd = cache._createCommand('qryfetch')
+                                .addParam('qryId', args.queryId)
+                                .addParam('pageSize', args.pageSize);
+
+                            return cache.__createPromise(cmd);
+                        })
+                        .then((page) => cb(null, {
+                            rows: page.items,
+                            last: page === null || page.last
+                        }))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                // Execute query on node and return full result to browser.
+                socket.on('node:query:getAll', (args, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            // Create sql query.
+                            const qry = args.type === 'SCAN' ? new ScanQuery() : new SqlFieldsQuery(args.query);
+
+                            // Set page size for query.
+                            qry.setPageSize(1024);
+
+                            const cursor = agent.ignite(args.demo).cache(args.cacheName).query(qry);
+
+                            return cursor.getAll()
+                                .then((rows) => cb(null, {meta: cursor.fieldsMetadata(), rows}));
+                        })
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                // Return cache metadata from all nodes in grid.
+                socket.on('node:cache:metadata', (args, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => agent.ignite(args.demo).cache(args.cacheName).metadata())
+                        .then((caches) => {
+                            let types = [];
+
+                            const _compact = (className) => {
+                                return className.replace('java.lang.', '').replace('java.util.', '').replace('java.sql.', '');
+                            };
+
+                            const _typeMapper = (meta, typeName) => {
+                                let fields = meta.fields[typeName];
+
+                                let columns = [];
+
+                                for (const fieldName in fields) {
+                                    if (fields.hasOwnProperty(fieldName)) {
+                                        const fieldClass = _compact(fields[fieldName]);
+
+                                        columns.push({
+                                            type: 'field',
+                                            name: fieldName,
+                                            clazz: fieldClass,
+                                            system: fieldName === '_KEY' || fieldName === '_VAL',
+                                            cacheName: meta.cacheName,
+                                            typeName
+                                        });
+                                    }
+                                }
+
+                                const indexes = [];
+
+                                for (const index of meta.indexes[typeName]) {
+                                    fields = [];
+
+                                    for (const field of index.fields) {
+                                        fields.push({
+                                            type: 'index-field',
+                                            name: field,
+                                            order: index.descendings.indexOf(field) < 0,
+                                            unique: index.unique,
+                                            cacheName: meta.cacheName,
+                                            typeName
+                                        });
+                                    }
+
+                                    if (fields.length > 0) {
+                                        indexes.push({
+                                            type: 'index',
+                                            name: index.name,
+                                            children: fields,
+                                            cacheName: meta.cacheName,
+                                            typeName
+                                        });
+                                    }
+                                }
+
+                                columns = _.sortBy(columns, 'name');
+
+                                if (!_.isEmpty(indexes)) {
+                                    columns = columns.concat({
+                                        type: 'indexes',
+                                        name: 'Indexes',
+                                        cacheName: meta.cacheName,
+                                        typeName,
+                                        children: indexes
+                                    });
+                                }
+
+                                return {
+                                    type: 'type',
+                                    cacheName: meta.cacheName || '',
+                                    typeName,
+                                    children: columns
+                                };
+                            };
+
+                            for (const meta of caches) {
+                                const cacheTypes = meta.types.map(_typeMapper.bind(null, meta));
+
+                                if (!_.isEmpty(cacheTypes))
+                                    types = types.concat(cacheTypes);
+                            }
+
+                            return cb(null, types);
+                        })
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                const count = agentMgr.addAgentListener(user._id, socket);
+
+                socket.emit('agent:count', {count});
+            });
+
+            // Handle browser disconnect event.
+            io.sockets.on('disconnect', (socket) =>
+                agentMgr.removeAgentListener(socket.client.request.user._id, socket)
+            );
+        }
+    };
+};

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve/configure.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/configure.js b/modules/control-center-web/src/main/js/serve/configure.js
index ac27751..71f7c8a 100644
--- a/modules/control-center-web/src/main/js/serve/configure.js
+++ b/modules/control-center-web/src/main/js/serve/configure.js
@@ -19,6 +19,9 @@
 
 // Fire me up!
 
+/**
+ * Module for configuration express and websocket server.
+ */
 module.exports = {
     implements: 'configure',
     inject: ['require(morgan)', 'require(cookie-parser)', 'require(body-parser)',

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve/io.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/io.js b/modules/control-center-web/src/main/js/serve/io.js
deleted file mode 100644
index ded00fa..0000000
--- a/modules/control-center-web/src/main/js/serve/io.js
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-'use strict';
-
-// Fire me up!
-
-module.exports = {
-    implements: 'io',
-    inject: ['require(lodash)', 'require(socket.io)', 'require(apache-ignite)', 'agent', 'configure']
-};
-
-module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
-    const SqlFieldsQuery = apacheIgnite.SqlFieldsQuery;
-    const ScanQuery = apacheIgnite.ScanQuery;
-
-    return {
-        listen: (server) => {
-            const io = socketio(server);
-
-            configure.socketio(io);
-
-            io.sockets.on('connection', (socket) => {
-                const user = socket.client.request.user;
-
-                socket.on('schemaImport:drivers', (cb) => {
-                    agentMgr.findAgent(user._id)
-                        .then((agent) => agent.availableDrivers())
-                        .then((drivers) => cb(null, drivers))
-                        .catch((errMsg) => cb(errMsg));
-                });
-
-                socket.on('schemaImport:schemas', (preset, cb) => {
-                    agentMgr.findAgent(user._id)
-                        .then((agent) => {
-                            const jdbcInfo = {user: preset.user, password: preset.password};
-
-                            return agent.metadataSchemas(preset.jdbcDriverJar, preset.jdbcDriverClass, preset.jdbcUrl, jdbcInfo);
-                        })
-                        .then((schemas) => cb(null, schemas))
-                        .catch((errMsg) => cb(errMsg));
-                });
-
-                socket.on('schemaImport:tables', (preset, cb) => {
-                    agentMgr.findAgent(user._id)
-                        .then((agent) => {
-                            const jdbcInfo = {user: preset.user, password: preset.password};
-
-                            return agent.metadataTables(preset.jdbcDriverJar, preset.jdbcDriverClass, preset.jdbcUrl, jdbcInfo,
-                                preset.schemas, preset.tablesOnly);
-                        })
-                        .then((tables) => cb(null, tables))
-                        .catch((errMsg) => cb(errMsg));
-                });
-
-                socket.on('node:topology', (demo, attr, mtr, cb) => {
-                    agentMgr.findAgent(user._id)
-                        .then((agent) => agent.ignite(demo).cluster(attr, mtr))
-                        .then((clusters) => cb(null, clusters))
-                        .catch((errMsg) => cb(errMsg));
-                });
-
-                socket.on('node:query:close', (args, cb) => {
-                    agentMgr.findAgent(user._id)
-                        .then((agent) => {
-                            const cache = agent.ignite(args.demo).cache(args.cacheName);
-
-                            return cache.__createPromise(cache._createCommand('qrycls').addParam('qryId', args.queryId));
-                        })
-                        .then(() => cb())
-                        .catch((errMsg) => cb(errMsg));
-                });
-
-                socket.on('node:query', (args, cb) => {
-                    agentMgr.findAgent(user._id)
-                        .then((agent) => {
-                            // Create sql query.
-                            const qry = args.type === 'SCAN' ? new ScanQuery() : new SqlFieldsQuery(args.query);
-
-                            // Set page size for query.
-                            qry.setPageSize(args.pageSize);
-
-                            return agent.ignite(args.demo).cache(args.cacheName).query(qry).nextPage();
-                        })
-                        .then((cursor) => cb(null, {
-                            meta: cursor.fieldsMetadata(),
-                            rows: cursor.page(),
-                            queryId: cursor.queryId()
-                        }))
-                        .catch((errMsg) => cb(errMsg));
-                });
-
-                socket.on('node:query:fetch', (args, cb) => {
-                    agentMgr.findAgent(user._id)
-                        .then((agent) => {
-                            const cache = agent.ignite(args.demo).cache(args.cacheName);
-
-                            const cmd = cache._createCommand('qryfetch')
-                                .addParam('qryId', args.queryId)
-                                .addParam('pageSize', args.pageSize);
-
-                            return cache.__createPromise(cmd);
-                        })
-                        .then((page) => cb(null, {
-                            rows: page.items,
-                            last: page === null || page.last
-                        }))
-                        .catch((errMsg) => cb(errMsg));
-                });
-
-                socket.on('node:query:getAll', (args, cb) => {
-                    agentMgr.findAgent(user._id)
-                        .then((agent) => {
-                            // Create sql query.
-                            const qry = args.type === 'SCAN' ? new ScanQuery() : new SqlFieldsQuery(args.query);
-
-                            // Set page size for query.
-                            qry.setPageSize(args.pageSize);
-
-                            return agent.ignite(args.demo).cache(args.cacheName).query(qry).getAll();
-                        })
-                        .then((cursor) => cb(null, {
-                            meta: cursor.fieldsMetadata(),
-                            rows: cursor.page()
-                        }))
-                        .catch((errMsg) => cb(errMsg));
-                });
-
-                socket.on('node:cache:metadata', (args, cb) => {
-                    agentMgr.findAgent(user._id)
-                        .then((agent) => agent.ignite(args.demo).cache(args.cacheName).metadata())
-                        .then((caches) => {
-                            let types = [];
-
-                            const _compact = (className) => {
-                                return className.replace('java.lang.', '').replace('java.util.', '').replace('java.sql.', '');
-                            };
-
-                            const _typeMapper = (meta, typeName) => {
-                                let fields = meta.fields[typeName];
-
-                                let columns = [];
-
-                                for (const fieldName in fields) {
-                                    if (fields.hasOwnProperty(fieldName)) {
-                                        const fieldClass = _compact(fields[fieldName]);
-
-                                        columns.push({
-                                            type: 'field',
-                                            name: fieldName,
-                                            clazz: fieldClass,
-                                            system: fieldName === '_KEY' || fieldName === '_VAL',
-                                            cacheName: meta.cacheName,
-                                            typeName
-                                        });
-                                    }
-                                }
-
-                                const indexes = [];
-
-                                for (const index of meta.indexes[typeName]) {
-                                    fields = [];
-
-                                    for (const field of index.fields) {
-                                        fields.push({
-                                            type: 'index-field',
-                                            name: field,
-                                            order: index.descendings.indexOf(field) < 0,
-                                            unique: index.unique,
-                                            cacheName: meta.cacheName,
-                                            typeName
-                                        });
-                                    }
-
-                                    if (fields.length > 0) {
-                                        indexes.push({
-                                            type: 'index',
-                                            name: index.name,
-                                            children: fields,
-                                            cacheName: meta.cacheName,
-                                            typeName
-                                        });
-                                    }
-                                }
-
-                                columns = _.sortBy(columns, 'name');
-
-                                if (!_.isEmpty(indexes)) {
-                                    columns = columns.concat({
-                                        type: 'indexes',
-                                        name: 'Indexes',
-                                        cacheName: meta.cacheName,
-                                        typeName,
-                                        children: indexes
-                                    });
-                                }
-
-                                return {
-                                    type: 'type',
-                                    cacheName: meta.cacheName || '',
-                                    typeName,
-                                    children: columns
-                                };
-                            };
-
-                            for (const meta of caches) {
-                                const cacheTypes = meta.types.map(_typeMapper.bind(null, meta));
-
-                                if (!_.isEmpty(cacheTypes))
-                                    types = types.concat(cacheTypes);
-                            }
-
-                            return cb(null, types);
-                        })
-                        .catch((errMsg) => cb(errMsg));
-                });
-
-                const count = agentMgr.addAgentListener(user._id, socket);
-
-                socket.emit('agent:count', {count});
-            });
-
-            io.sockets.on('disconnect', (socket) =>
-                agentMgr.removeAgentListener(socket.client.request.user._id, socket)
-            );
-        }
-    };
-};

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve/mail.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/mail.js b/modules/control-center-web/src/main/js/serve/mail.js
index 36b4fa7..2c67276 100644
--- a/modules/control-center-web/src/main/js/serve/mail.js
+++ b/modules/control-center-web/src/main/js/serve/mail.js
@@ -19,6 +19,9 @@
 
 // Fire me up!
 
+/**
+ * Module for send email.
+ */
 module.exports = {
     implements: 'mail',
     inject: ['require(nodemailer)', 'settings']

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve/mongo.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/mongo.js b/modules/control-center-web/src/main/js/serve/mongo.js
index 6a80b7a..67f2cba 100644
--- a/modules/control-center-web/src/main/js/serve/mongo.js
+++ b/modules/control-center-web/src/main/js/serve/mongo.js
@@ -19,6 +19,9 @@
 
 // Fire me up!
 
+/**
+ * Module mongo schema.
+ */
 module.exports = {
     implements: 'mongo',
     inject: ['require(mongoose-deep-populate)', 'require(passport-local-mongoose)', 'settings', 'ignite_modules/mongo:*']

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/agent.js b/modules/control-center-web/src/main/js/serve/routes/agent.js
index 4e123bf..1d46170 100644
--- a/modules/control-center-web/src/main/js/serve/routes/agent.js
+++ b/modules/control-center-web/src/main/js/serve/routes/agent.js
@@ -21,7 +21,7 @@
 
 module.exports = {
     implements: 'agent-routes',
-    inject: ['require(lodash)', 'require(express)', 'require(fs)', 'require(jszip)', 'require(apache-ignite)', 'settings', 'agent']
+    inject: ['require(lodash)', 'require(express)', 'require(fs)', 'require(jszip)', 'require(apache-ignite)', 'settings', 'agent-manager']
 };
 
 /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve/routes/profile.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/profile.js b/modules/control-center-web/src/main/js/serve/routes/profile.js
index 9d24239..13ad045 100644
--- a/modules/control-center-web/src/main/js/serve/routes/profile.js
+++ b/modules/control-center-web/src/main/js/serve/routes/profile.js
@@ -21,18 +21,18 @@
 
 module.exports = {
     implements: 'profile-routes',
-    inject: ['require(lodash)', 'require(express)', 'mongo', 'agent']
+    inject: ['require(lodash)', 'require(express)', 'mongo', 'agent-manager']
 };
 
 /**
  *
- * @param _
- * @param express
+ * @param _ Lodash module
+ * @param express Express module
  * @param mongo
- * @param {AgentManager} agent
+ * @param {AgentManager} agentMgr
  * @returns {Promise}
  */
-module.exports.factory = function(_, express, mongo, agent) {
+module.exports.factory = function(_, express, mongo, agentMgr) {
     return new Promise((resolveFactory) => {
         const router = new express.Router();
 
@@ -80,7 +80,7 @@ module.exports.factory = function(_, express, mongo, agent) {
                 })
                 .then((user) => {
                     if (!params.token || user.token !== params.token)
-                        agent.close(user._id);
+                        agentMgr.close(user._id);
 
                     for (const param in params) {
                         if (params.hasOwnProperty(param))

http://git-wip-us.apache.org/repos/asf/ignite/blob/b30b52b1/modules/control-center-web/src/main/js/serve/settings.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/settings.js b/modules/control-center-web/src/main/js/serve/settings.js
index eada7f7..b8a3c71 100644
--- a/modules/control-center-web/src/main/js/serve/settings.js
+++ b/modules/control-center-web/src/main/js/serve/settings.js
@@ -19,6 +19,9 @@
 
 // Fire me up!
 
+/**
+ * Module with server-side configuration.
+ */
 module.exports = {
     implements: 'settings',
     inject: ['require(nconf)', 'require(fs)']


[12/50] [abbrv] ignite git commit: IGNITE-843 Minor fix.

Posted by an...@apache.org.
IGNITE-843 Minor fix.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/26517155
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/26517155
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/26517155

Branch: refs/heads/ignite-2875
Commit: 26517155eb3257ac648ec389a3abd5baf3c5ea61
Parents: 1b58bbc
Author: Andrey <an...@gridgain.com>
Authored: Mon Mar 21 11:26:45 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 21 11:26:45 2016 +0700

----------------------------------------------------------------------
 modules/control-center-web/src/main/js/app/index.js             | 1 +
 .../src/main/js/app/modules/states/signin.state.js              | 5 +----
 2 files changed, 2 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/26517155/modules/control-center-web/src/main/js/app/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/index.js b/modules/control-center-web/src/main/js/app/index.js
index ad92c86..1537eb9 100644
--- a/modules/control-center-web/src/main/js/app/index.js
+++ b/modules/control-center-web/src/main/js/app/index.js
@@ -181,6 +181,7 @@ angular
 }])
 .config(['UIRouterMetatagsProvider', (UIRouterMetatagsProvider) => {
     UIRouterMetatagsProvider
+        .setDefaultTitle('Apache Ignite Web Console - Management Tool and Configuration Wizard for Apache Ignite')
         .setTitleSuffix(' – Apache Ignite Web Console')
         .setDefaultDescription('The Apache Ignite Web Console is an interactive management tool and configuration wizard for Apache Ignite which walks you through the creation of configuration files. Try the tool now.');
 }])

http://git-wip-us.apache.org/repos/asf/ignite/blob/26517155/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/signin.state.js b/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
index ba14be6..a12ef43 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
+++ b/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
@@ -28,10 +28,7 @@ angular
     $stateProvider
     .state('signin', {
         url: '/',
-        templateUrl: '/signin.html',
-        metaTags: {
-            title: 'Management Tool and Configuration Wizard for Apache Ignite'
-        }
+        templateUrl: '/signin.html'
     });
 }])
 .run(['$rootScope', '$state', 'Auth', 'IgniteBranding', function($root, $state, Auth, branding) {


[09/50] [abbrv] ignite git commit: IGNITE-2597 Refactored to websockets.

Posted by an...@apache.org.
IGNITE-2597 Refactored to websockets.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/706317f3
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/706317f3
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/706317f3

Branch: refs/heads/ignite-2875
Commit: 706317f3d12989883a1c199797a74a49670f94aa
Parents: 2cf28fe
Author: Andrey <an...@gridgain.com>
Authored: Fri Mar 18 15:48:01 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Mar 18 15:48:01 2016 +0700

----------------------------------------------------------------------
 .../assembly/release-control-center-agent.xml   |   7 -
 modules/control-center-agent/pom.xml            |  45 +-
 .../console/agent/AgentConfiguration.java       |  31 +-
 .../ignite/console/agent/AgentLauncher.java     | 235 ++++++++--
 .../ignite/console/agent/AgentSocket.java       | 190 --------
 .../apache/ignite/console/agent/AgentUtils.java |   8 +-
 .../console/agent/handlers/AbstractHandler.java | 102 +++++
 .../console/agent/handlers/DatabaseHandler.java | 298 +++++++++++++
 .../handlers/DatabaseMetadataExtractor.java     | 205 ---------
 .../console/agent/handlers/RestExecutor.java    | 225 ----------
 .../console/agent/handlers/RestHandler.java     | 274 ++++++++++++
 .../ignite/console/agent/remote/Remote.java     |  37 --
 .../console/agent/remote/RemoteHandler.java     | 246 -----------
 .../console/agent/remote/WebSocketSender.java   |  39 --
 .../ignite/console/demo/AgentMetadataDemo.java  |  24 +-
 .../ignite/console/demo/AgentSqlDemo.java       | 101 +++--
 .../control-center-web/src/main/js/.eslintrc    |   1 +
 .../control-center-web/src/main/js/.gitignore   |   5 +-
 .../src/main/js/app/data/colors.json            |  22 +
 .../src/main/js/app/decorator/select.js         |  55 ++-
 .../control-center-web/src/main/js/app/index.js |  37 +-
 .../js/app/services/AgentMonitor.service.js     | 286 ++++++++++++
 .../main/js/app/services/ChartColors.service.js |  22 +
 .../main/js/app/services/Countries.service.js   |  23 +
 .../app/services/Countries/Countries.service.js |  23 -
 .../src/main/js/app/services/cleanup.service.js |  62 +++
 .../js/app/services/cleanup/cleanup.service.js  |  62 ---
 .../control-center-web/src/main/js/config.js    |  22 +-
 .../src/main/js/controllers/common-module.js    | 201 +--------
 .../main/js/controllers/domains-controller.js   | 146 +++----
 .../src/main/js/controllers/sql-controller.js   | 434 ++++++++++---------
 .../src/main/js/gulpfile.js/tasks/bundle.js     |  12 +-
 .../main/js/gulpfile.js/tasks/inject-plugins.js |   3 +-
 .../control-center-web/src/main/js/package.json |  39 +-
 modules/control-center-web/src/main/js/serve.js |  28 +-
 .../src/main/js/serve/agent.js                  | 354 +++++++++------
 .../src/main/js/serve/agent_dists/README.txt    |   7 +
 .../control-center-web/src/main/js/serve/app.js |  17 +-
 .../src/main/js/serve/config/default.json       |  26 --
 .../main/js/serve/config/settings.json.sample   |  26 ++
 .../src/main/js/serve/configure.js              |  72 +--
 .../control-center-web/src/main/js/serve/io.js  | 242 +++++++++++
 .../src/main/js/serve/mail.js                   |   5 +-
 .../src/main/js/serve/routes/agent.js           | 307 ++-----------
 .../src/main/js/serve/routes/profile.js         |  15 +-
 .../src/main/js/serve/routes/public.js          |  64 ++-
 .../src/main/js/serve/settings.js               |  11 +-
 .../src/main/js/views/includes/controls.jade    |   2 +-
 .../main/js/views/templates/agent-download.jade |  11 +-
 .../src/main/js/views/templates/select.jade     |   4 +-
 .../src/test/js/routes/agent.js                 |  10 +-
 51 files changed, 2462 insertions(+), 2261 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/assembly/release-control-center-agent.xml
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/assembly/release-control-center-agent.xml b/modules/control-center-agent/assembly/release-control-center-agent.xml
index 90a9415..eb7da95 100644
--- a/modules/control-center-agent/assembly/release-control-center-agent.xml
+++ b/modules/control-center-agent/assembly/release-control-center-agent.xml
@@ -28,13 +28,6 @@
 
     <fileSets>
         <fileSet>
-            <directory>${basedir}/../indexing/target/libs</directory>
-            <outputDirectory>/jdbc-drivers</outputDirectory>
-            <includes>
-                <include>**/h2-*.jar</include>
-            </includes>
-        </fileSet>
-        <fileSet>
             <directory>${basedir}</directory>
             <outputDirectory>/</outputDirectory>
             <includes>

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/pom.xml
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/pom.xml b/modules/control-center-agent/pom.xml
index 2fe8844..9bee2a2 100644
--- a/modules/control-center-agent/pom.xml
+++ b/modules/control-center-agent/pom.xml
@@ -34,26 +34,20 @@
     <version>1.5.0.final-SNAPSHOT</version>
 
     <properties>
-        <jetty.version>9.2.12.v20150709</jetty.version>
+        <maven.build.timestamp.format>yyMMddHHmmss</maven.build.timestamp.format>
     </properties>
 
     <dependencies>
         <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-schema-import-db</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.eclipse.jetty.websocket</groupId>
-            <artifactId>websocket-client</artifactId>
-            <version>${jetty.version}</version>
+            <groupId>io.socket</groupId>
+            <artifactId>socket.io-client</artifactId>
+            <version>0.7.0</version>
         </dependency>
 
         <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-            <version>2.4</version>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-json-org</artifactId>
+            <version>2.7.1</version>
         </dependency>
 
         <dependency>
@@ -65,7 +59,19 @@
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>
             <artifactId>httpclient</artifactId>
-            <version>4.5</version>
+            <version>${httpclient.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-schema-import-db</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.gridgain</groupId>
+                    <artifactId>ignite-shmem</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
 
         <dependency>
@@ -100,6 +106,9 @@
                         <manifest>
                             <mainClass>org.apache.ignite.console.agent.AgentLauncher</mainClass>
                         </manifest>
+                        <manifestEntries>
+                            <Build-Time>${maven.build.timestamp}</Build-Time>
+                        </manifestEntries>
                     </archive>
                 </configuration>
             </plugin>
@@ -118,6 +127,14 @@
 
                         <configuration>
                             <createDependencyReducedPom>false</createDependencyReducedPom>
+                            <filters>
+                                <filter>
+                                    <artifact>*:*</artifact>
+                                    <excludes>
+                                        <exclude>META-INF/maven/**</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
                         </configuration>
                     </execution>
                 </executions>

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
index 7a0faa9..ffd30a5 100644
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
@@ -39,7 +39,7 @@ public class AgentConfiguration {
     public static final String DFLT_CFG_PATH = "default.properties";
 
     /** Default server URI. */
-    private static final String DFLT_SERVER_URI = "wss://localhost:3001";
+    private static final String DFLT_SERVER_URI = "http://localhost:3001";
 
     /** Default Ignite node HTTP URI. */
     private static final String DFLT_NODE_URI = "http://localhost:8080";
@@ -75,9 +75,6 @@ public class AgentConfiguration {
         "      Default value: ./jdbc-drivers")
     private String driversFolder;
 
-    /** Release date. */
-    private long relDate;
-
     /** */
     @Parameter(names = { "-h", "--help" }, help = true, description = "Print this help message")
     private Boolean help;
@@ -160,17 +157,10 @@ public class AgentConfiguration {
     }
 
     /**
-     * @return Release date.
-     */
-    public long relDate() {
-        return relDate;
-    }
-
-    /**
      * @return {@code true} If agent options usage should be printed.
      */
     public Boolean help() {
-        return help != null ? help : false;
+        return help != null ? help : Boolean.FALSE;
     }
 
     /**
@@ -202,17 +192,6 @@ public class AgentConfiguration {
 
         if (val != null)
             driversFolder(val);
-
-        val = (String)props.remove("rel-date");
-
-        if (val != null) {
-            try {
-                this.relDate = Long.parseLong(val);
-            }
-            catch (NumberFormatException ignored) {
-                // No-op.
-            }
-        }
     }
 
     /**
@@ -236,8 +215,6 @@ public class AgentConfiguration {
 
         if (driversFolder == null)
             driversFolder(cmd.driversFolder());
-
-        relDate = cmd.relDate();
     }
 
     /** {@inheritDoc} */
@@ -248,12 +225,12 @@ public class AgentConfiguration {
             sb.append("User's security token         : ");
 
             if (tok.length() > 4) {
-                sb.append(new String(new char[tok.length() - 4]).replace("\0", "*"));
+                sb.append(new String(new char[tok.length() - 4]).replace('\0', '*'));
 
                 sb.append(tok.substring(tok.length() - 4));
             }
             else
-                sb.append(new String(new char[tok.length()]).replace("\0", "*"));
+                sb.append(new String(new char[tok.length()]).replace('\0', '*'));
 
             sb.append('\n');
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
index ed08d78..cb4bd46 100644
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
@@ -18,18 +18,39 @@
 package org.apache.ignite.console.agent;
 
 import com.beust.jcommander.JCommander;
+import com.beust.jcommander.ParameterException;
+import io.socket.client.Ack;
+import io.socket.client.IO;
+import io.socket.client.Socket;
+import io.socket.emitter.Emitter;
 import java.io.File;
 import java.io.IOException;
+import java.net.ConnectException;
+import java.net.SocketException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.URL;
 import java.util.Arrays;
-
-import com.beust.jcommander.ParameterException;
-import org.apache.ignite.console.agent.handlers.RestExecutor;
+import java.util.concurrent.CountDownLatch;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import org.apache.ignite.console.agent.handlers.DatabaseHandler;
+import org.apache.ignite.console.agent.handlers.RestHandler;
+import org.apache.ignite.internal.util.typedef.X;
 import org.apache.log4j.Logger;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.websocket.client.WebSocketClient;
-
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import static io.socket.client.Socket.EVENT_CONNECT;
+import static io.socket.client.Socket.EVENT_CONNECTING;
+import static io.socket.client.Socket.EVENT_CONNECT_ERROR;
+import static io.socket.client.Socket.EVENT_DISCONNECT;
+import static io.socket.client.Socket.EVENT_ERROR;
+import static io.socket.client.Socket.EVENT_RECONNECTING;
 import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_SERVER_PORT;
 
 /**
@@ -40,16 +61,95 @@ public class AgentLauncher {
     private static final Logger log = Logger.getLogger(AgentLauncher.class.getName());
 
     /** */
+    private static final String EVENT_NODE_REST = "node:rest";
+
+    /** */
+    private static final String EVENT_SCHEMA_IMPORT_DRIVERS = "schemaImport:drivers";
+
+    /** */
+    private static final String EVENT_SCHEMA_IMPORT_SCHEMAS = "schemaImport:schemas";
+
+    /** */
+    private static final String EVENT_SCHEMA_IMPORT_METADATA = "schemaImport:metadata";
+
+    /** */
+    private static final String EVENT_AGENT_CLOSE = "agent:close";
+
+    /** */
     private static final int RECONNECT_INTERVAL = 3000;
 
     /**
+     * Create a trust manager that trusts all certificates It is not using a particular keyStore
+     */
+    private static TrustManager[] getTrustManagers() {
+        return new TrustManager[] {
+            new X509TrustManager() {
+                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+                    return null;
+                }
+
+                public void checkClientTrusted(
+                    java.security.cert.X509Certificate[] certs, String authType) {
+                }
+
+                public void checkServerTrusted(
+                    java.security.cert.X509Certificate[] certs, String authType) {
+                }
+            }};
+    }
+
+    /**
+     * On error listener.
+     */
+    private static final Emitter.Listener onError = new Emitter.Listener() {
+        @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+        @Override public void call(Object... args) {
+            Throwable e = (Throwable)args[0];
+
+            ConnectException ce = X.cause(e, ConnectException.class);
+
+            if (ce != null)
+                log.warn(ce.getMessage());
+            else {
+                Exception ignore = X.cause(e, SSLHandshakeException.class);
+
+                if (ignore != null) {
+                    log.error("Failed to establish SSL connection to server, due to errors with SSL handshake.");
+                    log.error("Add to environment variable JVM_OPTS parameter \"-Dtrust.all=true\" to skip certificate validation in case of using self-signed certificate.");
+
+                    System.exit(1);
+                }
+
+                ignore = X.cause(e, SocketException.class);
+
+                if (ignore != null) {
+                    log.error("Failed to receive response from server (connection refused).");
+
+                    return;
+                }
+
+                log.error("Connection error.", e);
+            }
+        }
+    };
+
+    /**
+     * On disconnect listener.
+     */
+    private static final Emitter.Listener onDisconnect = new Emitter.Listener() {
+        @Override public void call(Object... args) {
+            log.error(String.format("Connection closed: %s.", args[0]));
+        }
+    };
+
+    /**
      * @param args Args.
      */
     @SuppressWarnings("BusyWait")
     public static void main(String[] args) throws Exception {
         log.info("Starting Apache Ignite Web Console Agent...");
 
-        AgentConfiguration cfg = new AgentConfiguration();
+        final AgentConfiguration cfg = new AgentConfiguration();
 
         JCommander jCommander = new JCommander(cfg);
 
@@ -76,13 +176,13 @@ public class AgentLauncher {
             File f = AgentUtils.resolvePath(prop);
 
             if (f == null)
-                log.warn("Failed to find agent property file: '" + prop + "'");
+                log.warn("Failed to find agent property file: " + prop);
             else
                 propCfg.load(f.toURI().toURL());
         }
         catch (IOException ignore) {
             if (!AgentConfiguration.DFLT_CFG_PATH.equals(prop))
-                log.warn("Failed to load agent property file: '" + prop + "'", ignore);
+                log.warn("Failed to load agent property file: " + prop, ignore);
         }
 
         cfg.merge(propCfg);
@@ -118,47 +218,120 @@ public class AgentLauncher {
             cfg.token(System.console().readLine().trim());
         }
 
-        RestExecutor restExecutor = new RestExecutor(cfg);
-
-        restExecutor.start();
+        final RestHandler restHnd = new RestHandler(cfg);
 
         try {
-            SslContextFactory sslCtxFactory = new SslContextFactory();
+            restHnd.start();
+
+            URI uri = URI.create(cfg.serverUri());
 
-            // Workaround for use self-signed certificate:
-            if (Boolean.getBoolean("trust.all"))
-                sslCtxFactory.setTrustAll(true);
+            if (uri.getPort() == -1)
+                uri = URI.create(cfg.serverUri() + ':' + DFLT_SERVER_PORT);
 
-            WebSocketClient client = new WebSocketClient(sslCtxFactory);
+            IO.Options opts = new IO.Options();
 
-            client.setMaxIdleTimeout(Long.MAX_VALUE);
+            opts.reconnectionDelay = RECONNECT_INTERVAL;
+
+            // Workaround for use self-signed certificate
+            if (Boolean.getBoolean("trust.all")) {
+                SSLContext ctx = SSLContext.getInstance("TLS");
+
+                // Create an SSLContext that uses our TrustManager
+                ctx.init(null, getTrustManagers(), null);
+
+                opts.sslContext = ctx;
+            }
 
-            client.start();
+            final Socket client = IO.socket(uri, opts);
 
             try {
-                while (!Thread.interrupted()) {
-                    AgentSocket agentSock = new AgentSocket(cfg, restExecutor);
+                Emitter.Listener onConnecting = new Emitter.Listener() {
+                    @Override public void call(Object... args) {
+                        log.info("Connecting to: " + cfg.serverUri());
+                    }
+                };
 
-                    log.info("Connecting to: " + cfg.serverUri());
+                Emitter.Listener onConnect = new Emitter.Listener() {
+                    @Override public void call(Object... args) {
+                        log.info("Connection established.");
 
-                    URI uri = URI.create(cfg.serverUri());
+                        JSONObject authMsg = new JSONObject();
 
-                    if (uri.getPort() == -1)
-                        uri = URI.create(cfg.serverUri() + ":" + DFLT_SERVER_PORT);
+                        try {
+                            authMsg.put("token", cfg.token());
 
-                    client.connect(agentSock, uri);
+                            String clsName = AgentLauncher.class.getSimpleName() + ".class";
 
-                    agentSock.waitForClose();
+                            String clsPath = AgentLauncher.class.getResource(clsName).toString();
 
-                    Thread.sleep(RECONNECT_INTERVAL);
-                }
+                            if (clsPath.startsWith("jar")) {
+                                String manifestPath = clsPath.substring(0, clsPath.lastIndexOf('!') + 1) +
+                                    "/META-INF/MANIFEST.MF";
+
+                                Manifest manifest = new Manifest(new URL(manifestPath).openStream());
+
+                                Attributes attr = manifest.getMainAttributes();
+
+                                authMsg.put("ver", attr.getValue("Implementation-Version"));
+                                authMsg.put("bt", attr.getValue("Build-Time"));
+                            }
+
+                            client.emit("agent:auth", authMsg, new Ack() {
+                                @Override public void call(Object... args) {
+                                    // Authentication failed if response contains args.
+                                    if (args != null && args.length > 0) {
+                                        onDisconnect.call("Authentication failed: " + args[0]);
+
+                                        System.exit(1);
+                                    }
+
+                                    log.info("Authentication success.");
+                                }
+                            });
+                        }
+                        catch (JSONException | IOException e) {
+                            log.error("Failed to construct authentication message", e);
+
+                            client.close();
+                        }
+                    }
+                };
+
+                DatabaseHandler dbHnd = new DatabaseHandler(cfg);
+
+                final CountDownLatch latch = new CountDownLatch(1);
+
+                client
+                    .on(EVENT_CONNECTING, onConnecting)
+                    .on(EVENT_CONNECT, onConnect)
+                    .on(EVENT_CONNECT_ERROR, onError)
+                    .on(EVENT_RECONNECTING, onConnecting)
+                    .on(EVENT_NODE_REST, restHnd)
+                    .on(EVENT_SCHEMA_IMPORT_DRIVERS, dbHnd.availableDriversListener())
+                    .on(EVENT_SCHEMA_IMPORT_SCHEMAS, dbHnd.schemasListener())
+                    .on(EVENT_SCHEMA_IMPORT_METADATA, dbHnd.metadataListener())
+                    .on(EVENT_ERROR, onError)
+                    .on(EVENT_DISCONNECT, onDisconnect)
+                    .on(EVENT_AGENT_CLOSE, new Emitter.Listener() {
+                        @Override public void call(Object... args) {
+                            onDisconnect.call(args);
+
+                            client.off();
+
+                            latch.countDown();
+                        }
+                    });
+
+                client.connect();
+
+                latch.await();
             }
             finally {
-                client.stop();
+                client.close();
             }
         }
         finally {
-            restExecutor.stop();
+            restHnd.stop();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java
deleted file mode 100644
index ae6da07..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-package org.apache.ignite.console.agent;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import java.io.IOException;
-import java.net.ConnectException;
-import java.util.concurrent.CountDownLatch;
-import javax.net.ssl.SSLHandshakeException;
-import org.apache.ignite.console.agent.handlers.DatabaseMetadataExtractor;
-import org.apache.ignite.console.agent.handlers.RestExecutor;
-import org.apache.ignite.console.agent.remote.Remote;
-import org.apache.ignite.console.agent.remote.RemoteHandler;
-import org.apache.ignite.console.agent.remote.WebSocketSender;
-import org.apache.log4j.Logger;
-import org.eclipse.jetty.websocket.api.Session;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
-import org.eclipse.jetty.websocket.api.annotations.WebSocket;
-
-/**
- * Handler for web-socket connection.
- */
-@WebSocket
-public class AgentSocket implements WebSocketSender {
-    /** */
-    public static final Gson GSON = new Gson();
-
-    /** */
-    public static final JsonParser PARSER = new JsonParser();
-
-    /** */
-    private static final Logger log = Logger.getLogger(AgentSocket.class.getName());
-
-    /** */
-    private final CountDownLatch closeLatch = new CountDownLatch(1);
-
-    /** */
-    private final AgentConfiguration cfg;
-
-    /** */
-    private final RestExecutor restExecutor;
-
-    /** */
-    private RemoteHandler remote;
-
-    /** */
-    private Session ses;
-
-    /**
-     * @param cfg Config.
-     */
-    public AgentSocket(AgentConfiguration cfg, RestExecutor restExecutor) {
-        this.cfg = cfg;
-        this.restExecutor = restExecutor;
-    }
-
-    /**
-     * @param statusCode Status code.
-     * @param reason Reason.
-     */
-    @OnWebSocketClose
-    public void onClose(int statusCode, String reason) {
-        log.error(String.format("Connection closed: %d - %s.", statusCode, reason));
-
-        if (remote != null)
-            remote.close();
-
-        closeLatch.countDown();
-    }
-
-    /**
-     * @param ses Session.
-     */
-    @OnWebSocketConnect
-    public void onConnect(Session ses) {
-        log.info("Connection established.");
-
-        this.ses = ses;
-
-        remote = RemoteHandler.wrap(this, this, restExecutor, new DatabaseMetadataExtractor(cfg));
-
-        JsonObject authMsg = new JsonObject();
-
-        authMsg.addProperty("type", "AuthMessage");
-        authMsg.addProperty("token", cfg.token());
-        authMsg.addProperty("relDate", cfg.relDate());
-
-        send(authMsg);
-    }
-
-    /**
-     * @param msg Message.
-     * @return Whether or not message was sent.
-     */
-    @Override public boolean send(JsonObject msg) {
-        return send(GSON.toJson(msg));
-    }
-
-    /**
-     * @param msg Message.
-     * @return Whether or not message was sent.
-     */
-    @Override public boolean send(String msg) {
-        try {
-            ses.getRemote().sendString(msg);
-
-            return true;
-        }
-        catch (IOException ignored) {
-            log.error("Failed to send message to Control Center.");
-
-            return false;
-        }
-    }
-
-    /**
-     * @param ses Session.
-     * @param error Error.
-     */
-    @OnWebSocketError
-    public void onError(Session ses, Throwable error) {
-        if (error instanceof ConnectException)
-            log.warn(error.getMessage());
-        else if (error instanceof SSLHandshakeException) {
-            log.error("Failed to establish SSL connection to Ignite Console. Start agent with " +
-                "\"-Dtrust.all=true\" to skip certificate validation in case of using self-signed certificate.", error);
-
-            System.exit(1);
-        }
-        else
-            log.error("Connection error.", error);
-
-        if (remote != null)
-            remote.close();
-
-        closeLatch.countDown();
-    }
-
-    /**
-     * @param msg Message.
-     */
-    @OnWebSocketMessage
-    public void onMessage(String msg) {
-        JsonElement jsonElement = PARSER.parse(msg);
-
-        remote.onMessage((JsonObject)jsonElement);
-    }
-
-    /**
-     * @param errorMsg Authentication failed message or {@code null} if authentication success.
-     */
-    @Remote
-    public void authResult(String errorMsg) {
-        if (errorMsg != null) {
-            onClose(401, "Authentication failed: " + errorMsg);
-
-            System.exit(1);
-        }
-
-        log.info("Authentication success.");
-    }
-
-    /**
-     * Await socket close.
-     */
-    public void waitForClose() throws InterruptedException {
-        closeLatch.await();
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
index 349eea1..50a849a 100644
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
@@ -17,12 +17,11 @@
 
 package org.apache.ignite.console.agent;
 
-import org.apache.log4j.Logger;
-
 import java.io.File;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.security.ProtectionDomain;
+import org.apache.log4j.Logger;
 
 /**
  * Utility methods.
@@ -101,10 +100,7 @@ public class AgentUtils {
                 return file;
         }
 
-        /*
-         * 2. Check given path as absolute.
-         */
-
+        // 2. Check given path as absolute.
         File file = new File(path);
 
         if (file.exists())

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
new file mode 100644
index 0000000..aa38dd7
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
@@ -0,0 +1,102 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.console.agent.handlers;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
+import io.socket.client.Ack;
+import io.socket.emitter.Emitter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+/**
+ * Base class for web socket handlers.
+ */
+abstract class AbstractHandler implements Emitter.Listener {
+    /** JSON object mapper. */
+    private static final ObjectMapper mapper = new ObjectMapper();
+
+    static {
+        JsonOrgModule module = new JsonOrgModule();
+
+        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
+        mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
+
+        mapper.registerModule(module);
+    }
+
+    /**
+     * @param obj Object.
+     * @return {@link JSONObject} or {@link JSONArray}.
+     */
+    private Object toJSON(Object obj) {
+        if (obj instanceof Iterable)
+            return mapper.convertValue(obj, JSONArray.class);
+
+        return mapper.convertValue(obj, JSONObject.class);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public final void call(Object... args) {
+        Ack cb = null;
+
+        try {
+            if (args == null || args.length == 0)
+                throw new IllegalArgumentException("Missing arguments.");
+
+            if (args.length > 2)
+                throw new IllegalArgumentException("Wrong arguments count, must be <= 2: " + Arrays.toString(args));
+
+            JSONObject lsnrArgs = null;
+
+            if (args.length == 1) {
+                if (args[0] instanceof JSONObject)
+                    lsnrArgs = (JSONObject)args[0];
+                else if (args[0] instanceof Ack)
+                    cb = (Ack)args[0];
+                else
+                    throw new IllegalArgumentException("Wrong type of argument, must be JSONObject or Ack: " + args[0]);
+            }
+            else {
+                if (args[0] != null && !(args[0] instanceof JSONObject))
+                    throw new IllegalArgumentException("Wrong type of argument, must be JSONObject: " + args[0]);
+
+                if (!(args[1] instanceof Ack))
+                    throw new IllegalArgumentException("Wrong type of argument, must be Ack: " + args[1]);
+
+                lsnrArgs = (JSONObject)args[0];
+
+                cb = (Ack)args[1];
+            }
+
+            Object res = execute(lsnrArgs == null ? Collections.emptyMap() : mapper.convertValue(lsnrArgs, Map.class));
+
+            if (cb != null)
+                cb.call(null, toJSON(res));
+        }
+        catch (Exception e) {
+            if (cb != null)
+                cb.call(e, null);
+        }
+    }
+
+    /**
+     * Execute command with specified arguments.
+     *
+     * @param args Map with method args.
+     */
+    public abstract Object execute(Map<String, Object> args) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java
new file mode 100644
index 0000000..02146d9
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.console.agent.handlers;
+
+import io.socket.emitter.Emitter;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.apache.ignite.console.agent.AgentConfiguration;
+import org.apache.ignite.console.demo.AgentMetadataDemo;
+import org.apache.ignite.schema.parser.DbMetadataReader;
+import org.apache.ignite.schema.parser.DbTable;
+import org.apache.log4j.Logger;
+
+import static org.apache.ignite.console.agent.AgentUtils.resolvePath;
+
+/**
+ * API to extract database metadata.
+ */
+public class DatabaseHandler {
+    /** */
+    private static final Logger log = Logger.getLogger(DatabaseHandler.class.getName());
+
+    /** */
+    private final File driversFolder;
+
+    /**
+     * @param cfg Config.
+     */
+    public DatabaseHandler(AgentConfiguration cfg) {
+        driversFolder = resolvePath(cfg.driversFolder() == null ? "jdbc-drivers" : cfg.driversFolder());
+    }
+
+    /**
+     * @param jdbcDriverJarPath JDBC driver JAR path.
+     * @param jdbcDriverCls JDBC driver class.
+     * @param jdbcUrl JDBC URL.
+     * @param jdbcInfo Properties to connect to database.
+     * @return Connection to database.
+     * @throws SQLException
+     */
+    private Connection connect(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+        Properties jdbcInfo) throws SQLException {
+        if (AgentMetadataDemo.isTestDriveUrl(jdbcUrl))
+            return AgentMetadataDemo.testDrive();
+
+        if (!new File(jdbcDriverJarPath).isAbsolute() && driversFolder != null)
+            jdbcDriverJarPath = new File(driversFolder, jdbcDriverJarPath).getPath();
+
+        return DbMetadataReader.getInstance().connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo);
+    }
+
+    /**
+     * @param jdbcDriverJarPath JDBC driver JAR path.
+     * @param jdbcDriverCls JDBC driver class.
+     * @param jdbcUrl JDBC URL.
+     * @param jdbcInfo Properties to connect to database.
+     * @return Collection of schema names.
+     * @throws SQLException
+     */
+    protected Collection<String> schemas(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+        Properties jdbcInfo) throws SQLException {
+        if (log.isDebugEnabled())
+            log.debug("Start collecting database schemas [drvJar=" + jdbcDriverJarPath +
+                ", drvCls=" + jdbcDriverCls + ", jdbcUrl=" + jdbcUrl + "]");
+
+        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
+            Collection<String> schemas = DbMetadataReader.getInstance().schemas(conn);
+
+            if (log.isDebugEnabled())
+                log.debug("Finished collection of schemas [jdbcUrl=" + jdbcUrl + ", count=" + schemas.size() + "]");
+
+            return schemas;
+        }
+        catch (Throwable e) {
+            log.error("Failed to collect schemas", e);
+
+            throw new SQLException("Failed to collect schemas", e);
+        }
+    }
+
+    /**
+     * Listener for schema names.
+     *
+     * @return Collection of schema names.
+     */
+    public Emitter.Listener schemasListener() {
+        return new AbstractHandler() {
+            @Override public Object execute(Map<String, Object> args) throws Exception {
+                String driverPath = null;
+
+                if (args.containsKey("driverPath"))
+                    driverPath = args.get("driverPath").toString();
+
+                if (!args.containsKey("driverClass"))
+                    throw new IllegalArgumentException("Missing driverClass in arguments: " + args);
+
+                String driverCls = args.get("driverClass").toString();
+
+                if (!args.containsKey("url"))
+                    throw new IllegalArgumentException("Missing url in arguments: " + args);
+
+                String url = args.get("url").toString();
+
+                if (!args.containsKey("info"))
+                    throw new IllegalArgumentException("Missing info in arguments: " + args);
+
+                Properties info = new Properties();
+
+                info.putAll((Map)args.get("info"));
+
+                return schemas(driverPath, driverCls, url, info);
+            }
+        };
+    }
+
+    /**
+     * @param jdbcDriverJarPath JDBC driver JAR path.
+     * @param jdbcDriverCls JDBC driver class.
+     * @param jdbcUrl JDBC URL.
+     * @param jdbcInfo Properties to connect to database.
+     * @param schemas List of schema names to process.
+     * @param tblsOnly If {@code true} then only tables will be processed otherwise views also will be processed.
+     * @return Collection of tables.
+     */
+    protected Collection<DbTable> metadata(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+        Properties jdbcInfo, List<String> schemas, boolean tblsOnly) throws SQLException {
+        if (log.isDebugEnabled())
+            log.debug("Start collecting database metadata [drvJar=" + jdbcDriverJarPath +
+                ", drvCls=" + jdbcDriverCls + ", jdbcUrl=" + jdbcUrl + "]");
+
+        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
+            Collection<DbTable> metadata = DbMetadataReader.getInstance().metadata(conn, schemas, tblsOnly);
+
+            if (log.isDebugEnabled())
+                log.debug("Finished collection of metadata [jdbcUrl=" + jdbcUrl + ", count=" + metadata.size() + "]");
+
+            return metadata;
+        }
+        catch (Throwable e) {
+            log.error("Failed to collect metadata", e);
+
+            throw new SQLException("Failed to collect metadata", e);
+        }
+    }
+
+    /**
+     * Listener for tables.
+     *
+     * @return Collection of tables.
+     */
+    public Emitter.Listener metadataListener() {
+        return new AbstractHandler() {
+            @SuppressWarnings("unchecked")
+            @Override public Object execute(Map<String, Object> args) throws Exception {
+                String driverPath = null;
+
+                if (args.containsKey("driverPath"))
+                    driverPath = args.get("driverPath").toString();
+
+                if (!args.containsKey("driverClass"))
+                    throw new IllegalArgumentException("Missing driverClass in arguments: " + args);
+
+                String driverCls = args.get("driverClass").toString();
+
+                if (!args.containsKey("url"))
+                    throw new IllegalArgumentException("Missing url in arguments: " + args);
+
+                String url = args.get("url").toString();
+
+                if (!args.containsKey("info"))
+                    throw new IllegalArgumentException("Missing info in arguments: " + args);
+
+                Properties info = new Properties();
+
+                info.putAll((Map)args.get("info"));
+
+                if (!args.containsKey("schemas"))
+                    throw new IllegalArgumentException("Missing schemas in arguments: " + args);
+
+                List<String> schemas = (List<String>)args.get("schemas");
+
+                if (!args.containsKey("tablesOnly"))
+                    throw new IllegalArgumentException("Missing tablesOnly in arguments: " + args);
+
+                boolean tblsOnly = (boolean)args.get("tablesOnly");
+
+                return metadata(driverPath, driverCls, url, info, schemas, tblsOnly);
+            }
+        };
+    }
+
+    /**
+     * Listener for drivers.
+     *
+     * @return Drivers in drivers folder
+     * @see AgentConfiguration#driversFolder
+     */
+    public Emitter.Listener availableDriversListener() {
+        return new AbstractHandler() {
+            @Override public Object execute(Map<String, Object> args) throws Exception {
+                if (driversFolder == null) {
+                    log.info("JDBC drivers folder not specified, returning empty list");
+
+                    return Collections.emptyList();
+                }
+
+                if (log.isDebugEnabled())
+                    log.debug("Collecting JDBC drivers in folder: " + driversFolder.getPath());
+
+                File[] list = driversFolder.listFiles(new FilenameFilter() {
+                    @Override public boolean accept(File dir, String name) {
+                        return name.endsWith(".jar");
+                    }
+                });
+
+                if (list == null) {
+                    log.info("JDBC drivers folder has no files, returning empty list");
+
+                    return Collections.emptyList();
+                }
+
+                List<JdbcDriver> res = new ArrayList<>();
+
+                for (File file : list) {
+                    try {
+                        boolean win = System.getProperty("os.name").contains("win");
+
+                        URL url = new URL("jar", null,
+                            "file:" + (win ? "/" : "") + file.getPath() + "!/META-INF/services/java.sql.Driver");
+
+                        try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
+                            String jdbcDriverCls = reader.readLine();
+
+                            res.add(new JdbcDriver(file.getName(), jdbcDriverCls));
+
+                            if (log.isDebugEnabled())
+                                log.debug("Found: [driver=" + file + ", class=" + jdbcDriverCls + "]");
+                        }
+                    }
+                    catch (IOException e) {
+                        res.add(new JdbcDriver(file.getName(), null));
+
+                        log.info("Found: [driver=" + file + "]");
+                        log.info("Failed to detect driver class: " + e.getMessage());
+                    }
+                }
+
+                return res;
+            }
+        };
+    }
+
+    /**
+     * Wrapper class for later to be transformed to JSON and send to Web Console.
+     */
+    private static class JdbcDriver {
+        /** */
+        public final String jdbcDriverJar;
+        /** */
+        public final String jdbcDriverCls;
+
+        /**
+         * @param jdbcDriverJar File name of driver jar file.
+         * @param jdbcDriverCls Optional JDBC driver class.
+         */
+        public JdbcDriver(String jdbcDriverJar, String jdbcDriverCls) {
+            this.jdbcDriverJar = jdbcDriverJar;
+            this.jdbcDriverCls = jdbcDriverCls;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java
deleted file mode 100644
index 48d5236..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-package org.apache.ignite.console.agent.handlers;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-import org.apache.ignite.console.agent.AgentConfiguration;
-import org.apache.ignite.console.agent.remote.Remote;
-import org.apache.ignite.console.demo.AgentMetadataDemo;
-import org.apache.ignite.schema.parser.DbMetadataReader;
-import org.apache.ignite.schema.parser.DbTable;
-import org.apache.log4j.Logger;
-
-import static org.apache.ignite.console.agent.AgentUtils.resolvePath;
-
-/**
- * Remote API to extract database metadata.
- */
-public class DatabaseMetadataExtractor {
-    /** */
-    private static final Logger log = Logger.getLogger(DatabaseMetadataExtractor.class.getName());
-
-    /** */
-    private final File driversFolder;
-
-    /**
-     * @param cfg Config.
-     */
-    public DatabaseMetadataExtractor(AgentConfiguration cfg) {
-        driversFolder = resolvePath(cfg.driversFolder() == null ? "jdbc-drivers" : cfg.driversFolder());
-    }
-
-    /**
-     * @param jdbcDriverJarPath JDBC driver JAR path.
-     * @param jdbcDriverCls JDBC driver class.
-     * @param jdbcUrl JDBC URL.
-     * @param jdbcInfo Properties to connect to database.
-     * @return Connection to database.
-     * @throws SQLException
-     */
-    private Connection connect(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl, Properties jdbcInfo) throws SQLException {
-        if (!new File(jdbcDriverJarPath).isAbsolute() && driversFolder != null)
-            jdbcDriverJarPath = new File(driversFolder, jdbcDriverJarPath).getPath();
-
-        if (AgentMetadataDemo.isTestDriveUrl(jdbcUrl))
-            AgentMetadataDemo.testDrive();
-
-        return DbMetadataReader.getInstance().connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo);
-    }
-
-    /**
-     * @param jdbcDriverJarPath JDBC driver JAR path.
-     * @param jdbcDriverCls JDBC driver class.
-     * @param jdbcUrl JDBC URL.
-     * @param jdbcInfo Properties to connect to database.
-     * @return Collection of schema names.
-     * @throws SQLException
-     */
-    @Remote
-    public Collection<String> schemas(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
-        Properties jdbcInfo) throws SQLException {
-        log.debug("Start collecting database schemas [driver jar=" + jdbcDriverJarPath +
-            ", driver class=" + jdbcDriverCls + ", url=" + jdbcUrl + "]");
-
-        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
-            Collection<String> schemas = DbMetadataReader.getInstance().schemas(conn);
-
-            log.debug("Finished collection of schemas [url=" + jdbcUrl + ", count="+ schemas.size() +"]");
-
-            return schemas;
-        }
-        catch (Throwable e) {
-            log.error("Failed to collect schemas", e);
-
-            throw new SQLException("Failed to collect schemas", e);
-        }
-    }
-
-    /**
-     * @param jdbcDriverJarPath JDBC driver JAR path.
-     * @param jdbcDriverCls JDBC driver class.
-     * @param jdbcUrl JDBC URL.
-     * @param jdbcInfo Properties to connect to database.
-     * @param schemas List of schema names to process.
-     * @param tblsOnly If {@code true} then only tables will be processed otherwise views also will be processed.
-     * @return Collection of tables.
-     */
-    @Remote
-    public Collection<DbTable> metadata(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
-        Properties jdbcInfo, List<String> schemas, boolean tblsOnly) throws SQLException {
-        log.debug("Start collecting database metadata [driver jar=" + jdbcDriverJarPath +
-            ", driver class=" + jdbcDriverCls + ", url=" + jdbcUrl + "]");
-
-        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
-            Collection<DbTable> metadata = DbMetadataReader.getInstance().metadata(conn, schemas, tblsOnly);
-
-            log.debug("Finished collection of metadata [url=" + jdbcUrl + ", count="+ metadata.size() +"]");
-
-            return metadata;
-        }
-        catch (Throwable e) {
-            log.error("Failed to collect metadata", e);
-
-            throw new SQLException("Failed to collect metadata", e);
-        }
-    }
-
-    /**
-     * @return Drivers in drivers folder
-     * @see AgentConfiguration#driversFolder
-     */
-    @Remote
-    public List<JdbcDriver> availableDrivers() {
-        if (driversFolder == null) {
-            log.info("JDBC drivers folder not specified, returning empty list");
-
-            return Collections.emptyList();
-        }
-
-        log.debug("Collecting JDBC drivers in folder: " + driversFolder.getPath());
-
-        File[] list = driversFolder.listFiles(new FilenameFilter() {
-            @Override public boolean accept(File dir, String name) {
-                return name.endsWith(".jar");
-            }
-        });
-
-        if (list == null) {
-            log.info("JDBC drivers folder has no files, returning empty list");
-
-            return Collections.emptyList();
-        }
-
-        List<JdbcDriver> res = new ArrayList<>();
-
-        for (File file : list) {
-            try {
-                boolean win = System.getProperty("os.name").contains("win");
-
-                URL url = new URL("jar", null, "file:" + (win ? "/" : "") + file.getPath() + "!/META-INF/services/java.sql.Driver");
-
-                try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
-                    String jdbcDriverCls = reader.readLine();
-
-                    res.add(new JdbcDriver(file.getName(), jdbcDriverCls));
-
-                    log.debug("Found: [driver=" + file + ", class=" + jdbcDriverCls + "]");
-                }
-            }
-            catch (IOException e) {
-                res.add(new JdbcDriver(file.getName(), null));
-
-                log.info("Found: [driver=" + file + "]");
-                log.info("Failed to detect driver class: " + e.getMessage());
-            }
-        }
-
-        return res;
-    }
-
-    /**
-     * Wrapper class for later to be transformed to JSON and send to Web Console.
-     */
-    private static class JdbcDriver {
-        /** */
-        private final String jdbcDriverJar;
-        /** */
-        private final String jdbcDriverClass;
-
-        /**
-         * @param jdbcDriverJar File name of driver jar file.
-         * @param jdbcDriverClass Optional JDBC driver class.
-         */
-        public JdbcDriver(String jdbcDriverJar, String jdbcDriverClass) {
-            this.jdbcDriverJar = jdbcDriverJar;
-            this.jdbcDriverClass = jdbcDriverClass;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
deleted file mode 100644
index 3eb869b..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-package org.apache.ignite.console.agent.handlers;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.net.ConnectException;
-import java.net.URISyntaxException;
-import java.nio.charset.Charset;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.codec.Charsets;
-import org.apache.http.Header;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.ignite.console.agent.AgentConfiguration;
-import org.apache.ignite.console.agent.remote.Remote;
-import org.apache.ignite.console.demo.AgentSqlDemo;
-import org.apache.log4j.Logger;
-
-import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_NODE_PORT;
-
-/**
- * Executor for REST requests.
- */
-public class RestExecutor {
-    /** */
-    private static final Logger log = Logger.getLogger(RestExecutor.class.getName());
-
-    /** */
-    private final AgentConfiguration cfg;
-
-    /** */
-    private CloseableHttpClient httpClient;
-
-    /**
-     * @param cfg Config.
-     */
-    public RestExecutor(AgentConfiguration cfg) {
-        this.cfg = cfg;
-    }
-
-    /**
-     *
-     */
-    public void start() {
-        httpClient = HttpClientBuilder.create().build();
-    }
-
-    /**
-     *
-     */
-    public void stop() throws IOException {
-        if (httpClient != null)
-            httpClient.close();
-    }
-
-    /**
-     * @param uri Url.
-     * @param params Params.
-     * @param demo Use demo node.
-     * @param mtd Method.
-     * @param headers Headers.
-     * @param body Body.
-     */
-    @Remote
-    public RestResult executeRest(String uri, Map<String, String> params, boolean demo,
-        String mtd, Map<String, String> headers, String body) throws IOException, URISyntaxException {
-        log.debug("Start execute REST command [method=" + mtd + ", uri=/" + uri + ", parameters=" + params + "]");
-
-        final URIBuilder builder;
-
-        if (demo) {
-            // try start demo if needed.
-            AgentSqlDemo.testDrive(cfg);
-
-            // null if demo node not started yet.
-            if (cfg.demoNodeUri() == null)
-                return RestResult.fail(404, "Demo node is not started yet.");
-
-            builder = new URIBuilder(cfg.demoNodeUri());
-        }
-        else
-            builder = new URIBuilder(cfg.nodeUri());
-
-        if (builder.getPort() == -1)
-            builder.setPort(DFLT_NODE_PORT);
-
-        if (uri != null) {
-            if (!uri.startsWith("/") && !cfg.nodeUri().endsWith("/"))
-                uri = '/' + uri;
-
-            builder.setPath(uri);
-        }
-
-        if (params != null) {
-            for (Map.Entry<String, String> entry : params.entrySet())
-                builder.addParameter(entry.getKey(), entry.getValue());
-        }
-
-        HttpRequestBase httpReq;
-
-        if ("GET".equalsIgnoreCase(mtd))
-            httpReq = new HttpGet(builder.build());
-        else if ("POST".equalsIgnoreCase(mtd)) {
-            HttpPost post;
-
-            if (body == null) {
-                List<NameValuePair> nvps = builder.getQueryParams();
-
-                builder.clearParameters();
-
-                post = new HttpPost(builder.build());
-
-                if (!nvps.isEmpty())
-                    post.setEntity(new UrlEncodedFormEntity(nvps));
-            }
-            else {
-                post = new HttpPost(builder.build());
-
-                post.setEntity(new StringEntity(body));
-            }
-
-            httpReq = post;
-        }
-        else
-            throw new IOException("Unknown HTTP-method: " + mtd);
-
-        if (headers != null) {
-            for (Map.Entry<String, String> entry : headers.entrySet())
-                httpReq.addHeader(entry.getKey(), entry.getValue());
-        }
-
-        try (CloseableHttpResponse resp = httpClient.execute(httpReq)) {
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-            resp.getEntity().writeTo(out);
-
-            Charset charset = Charsets.UTF_8;
-
-            Header encodingHdr = resp.getEntity().getContentEncoding();
-
-            if (encodingHdr != null) {
-                String encoding = encodingHdr.getValue();
-
-                charset = Charsets.toCharset(encoding);
-            }
-
-            return RestResult.success(resp.getStatusLine().getStatusCode(), new String(out.toByteArray(), charset));
-        }
-        catch (ConnectException e) {
-            log.info("Failed connect to node and execute REST command [uri=" + builder.build() + "]");
-
-            return RestResult.fail(404, "Failed connect to node and execute REST command.");
-        }
-    }
-
-    /**
-     * Request result.
-     */
-    public static class RestResult {
-        /** REST http code. */
-        private int restCode;
-
-        /** The field contains description of error if server could not handle the request. */
-        private String error;
-
-        /** The field contains result of command. */
-        private String response;
-
-        /**
-         * @param restCode REST http code.
-         * @param error The field contains description of error if server could not handle the request.
-         * @param response The field contains result of command.
-         */
-        private RestResult(int restCode, String error, String response) {
-            this.restCode = restCode;
-            this.error = error;
-            this.response = response;
-        }
-
-        /**
-         * @param restCode REST http code.
-         * @param error The field contains description of error if server could not handle the request.
-
-         * @return Request result.
-         */
-        public static RestResult fail(int restCode, String error) {
-            return new RestResult(restCode, error, null);
-        }
-
-        /**
-         * @param restCode REST http code.
-         * @param response The field contains result of command.
-
-         * @return Request result.
-         */
-        public static RestResult success(int restCode, String response) {
-            return new RestResult(restCode, null, response);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java
new file mode 100644
index 0000000..2f476cf
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java
@@ -0,0 +1,274 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.console.agent.handlers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.codec.Charsets;
+import org.apache.http.Header;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.ignite.console.agent.AgentConfiguration;
+import org.apache.ignite.console.demo.AgentSqlDemo;
+import org.apache.log4j.Logger;
+
+import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_NODE_PORT;
+
+/**
+ * API to translate REST requests to Ignite cluster.
+ */
+public class RestHandler extends AbstractHandler {
+    /** */
+    private static final Logger log = Logger.getLogger(RestHandler.class.getName());
+
+    /** */
+    private final AgentConfiguration cfg;
+
+    /** */
+    private CloseableHttpClient httpClient;
+
+    /**
+     * @param cfg Config.
+     */
+    public RestHandler(AgentConfiguration cfg) {
+        this.cfg = cfg;
+    }
+
+    /**
+     * Start HTTP client for communication with node via REST.
+     */
+    public void start() {
+        httpClient = HttpClientBuilder.create().build();
+    }
+
+    /**
+     * Stop HTTP client.
+     */
+    public void stop() {
+        if (httpClient != null) {
+            try {
+                httpClient.close();
+            }
+            catch (IOException ignore) {
+                // No-op.
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public Object execute(Map<String, Object> args) throws Exception {
+        if (log.isDebugEnabled())
+            log.debug("Start parse REST command args: " + args);
+
+        String uri = null;
+
+        if (args.containsKey("uri"))
+            uri = args.get("uri").toString();
+
+        Map<String, Object> params = null;
+
+        if (args.containsKey("params"))
+            params = (Map<String, Object>)args.get("params");
+
+        if (!args.containsKey("demo"))
+            throw new IllegalArgumentException("Missing demo flag in arguments: " + args);
+
+        boolean demo = (boolean)args.get("demo");
+
+        if (!args.containsKey("method"))
+            throw new IllegalArgumentException("Missing method in arguments: " + args);
+
+        String mtd = args.get("method").toString();
+
+        Map<String, Object> headers = null;
+
+        if (args.containsKey("headers"))
+            headers = (Map<String, Object>)args.get("headers");
+
+        String body = null;
+
+        if (args.containsKey("body"))
+            body = args.get("body").toString();
+
+        return executeRest(uri, params, demo, mtd, headers, body);
+    }
+
+    /**
+     * @param uri Url.
+     * @param params Params.
+     * @param demo Use demo node.
+     * @param mtd Method.
+     * @param headers Headers.
+     * @param body Body.
+     */
+    protected RestResult executeRest(String uri, Map<String, Object> params, boolean demo,
+        String mtd, Map<String, Object> headers, String body) throws IOException, URISyntaxException {
+        if (log.isDebugEnabled())
+            log.debug("Start execute REST command [method=" + mtd + ", uri=/" + (uri == null ? "" : uri) +
+                ", parameters=" + params + "]");
+
+        final URIBuilder builder;
+
+        if (demo) {
+            // try start demo if needed.
+            AgentSqlDemo.testDrive(cfg);
+
+            // null if demo node not started yet.
+            if (cfg.demoNodeUri() == null)
+                return RestResult.fail("Demo node is not started yet.", 404);
+
+            builder = new URIBuilder(cfg.demoNodeUri());
+        }
+        else
+            builder = new URIBuilder(cfg.nodeUri());
+
+        if (builder.getPort() == -1)
+            builder.setPort(DFLT_NODE_PORT);
+
+        if (uri != null) {
+            if (!uri.startsWith("/") && !cfg.nodeUri().endsWith("/"))
+                uri = '/' + uri;
+
+            builder.setPath(uri);
+        }
+
+        if (params != null) {
+            for (Map.Entry<String, Object> entry : params.entrySet())
+                builder.addParameter(entry.getKey(), entry.getValue() == null ? null : entry.getValue().toString());
+        }
+
+        HttpRequestBase httpReq = null;
+
+        try {
+            if ("GET".equalsIgnoreCase(mtd))
+                httpReq = new HttpGet(builder.build());
+            else if ("POST".equalsIgnoreCase(mtd)) {
+                HttpPost post;
+
+                if (body == null) {
+                    List<NameValuePair> nvps = builder.getQueryParams();
+
+                    builder.clearParameters();
+
+                    post = new HttpPost(builder.build());
+
+                    if (!nvps.isEmpty())
+                        post.setEntity(new UrlEncodedFormEntity(nvps));
+                }
+                else {
+                    post = new HttpPost(builder.build());
+
+                    post.setEntity(new StringEntity(body));
+                }
+
+                httpReq = post;
+            }
+            else
+                throw new IOException("Unknown HTTP-method: " + mtd);
+
+            if (headers != null) {
+                for (Map.Entry<String, Object> entry : headers.entrySet())
+                    httpReq.addHeader(entry.getKey(), entry.getValue() == null ? null : entry.getValue().toString());
+            }
+
+            try (CloseableHttpResponse resp = httpClient.execute(httpReq)) {
+                ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+                resp.getEntity().writeTo(out);
+
+                Charset charset = Charsets.UTF_8;
+
+                Header encodingHdr = resp.getEntity().getContentEncoding();
+
+                if (encodingHdr != null) {
+                    String encoding = encodingHdr.getValue();
+
+                    charset = Charsets.toCharset(encoding);
+                }
+
+                return RestResult.success(resp.getStatusLine().getStatusCode(), new String(out.toByteArray(), charset));
+            }
+            catch (ConnectException e) {
+                log.info("Failed connect to node and execute REST command [uri=" + builder.build() + "]");
+
+                return RestResult.fail("Failed connect to node and execute REST command.", 404);
+            }
+        }
+        finally {
+            if (httpReq != null)
+                httpReq.reset();
+        }
+    }
+
+    /**
+     * Request result.
+     */
+    public static class RestResult {
+        /** The field contains description of error if server could not handle the request. */
+        public final String error;
+
+        /** REST http code. */
+        public final int code;
+
+        /** The field contains result of command. */
+        public final String data;
+
+        /**
+         * @param error The field contains description of error if server could not handle the request.
+         * @param resCode REST http code.
+         * @param res The field contains result of command.
+         */
+        private RestResult(String error, int resCode, String res) {
+            this.error = error;
+            this.code = resCode;
+            this.data = res;
+        }
+
+        /**
+         * @param error The field contains description of error if server could not handle the request.
+         * @param restCode REST http code.
+         * @return Request result.
+         */
+        public static RestResult fail(String error, int restCode) {
+            return new RestResult(error, restCode, null);
+        }
+
+        /**
+         * @param code REST http code.
+         * @param data The field contains result of command.
+         * @return Request result.
+         */
+        public static RestResult success(int code, String data) {
+            return new RestResult(null, code, data);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java
deleted file mode 100644
index 71b2bc0..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-package org.apache.ignite.console.agent.remote;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Use this annotation to associate methods with remote NodeJS server commands.
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Remote {
-    /**
-     * Whether or not method should be executed synchronously.
-     *
-     * @return {@code true} if method will be executed in separated thread otherwise if method will be executed in handler thread.
-     */
-    boolean async() default true;
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java
deleted file mode 100644
index 11e35e3..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-package org.apache.ignite.console.agent.remote;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonNull;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.RejectedExecutionException;
-
-import org.apache.http.auth.AuthenticationException;
-import org.apache.log4j.Logger;
-
-/**
- * Allow to execute methods remotely from NodeJS server by web-socket command.
- */
-public class RemoteHandler implements AutoCloseable {
-    /** */
-    public static final Gson GSON = new Gson();
-
-    /** */
-    public static final Object[] EMPTY_OBJECTS = new Object[0];
-
-    /** */
-    private static final Logger log = Logger.getLogger(RemoteHandler.class.getName());
-
-    /** */
-    private static final String INTERNAL_EXCEPTION_TYPE = "org.apache.ignite.agent.AgentException";
-
-    /** */
-    private final WebSocketSender snd;
-
-    /** */
-    private final Map<String, MethodDescriptor> mtds = new HashMap<>();
-
-    /** */
-    private final ExecutorService executorSrvc = Executors.newFixedThreadPool(Runtime.getRuntime()
-        .availableProcessors());
-
-    /**
-     * @param snd Session.
-     * @param hnds Handlers.
-     */
-    private RemoteHandler(WebSocketSender snd, Object ... hnds) {
-        this.snd = snd;
-
-        for (Object hnd : hnds) {
-            for (Method method : hnd.getClass().getMethods()) {
-                Remote ann = method.getAnnotation(Remote.class);
-
-                if (ann != null) {
-                    MethodDescriptor old = mtds.put(method.getName(), new MethodDescriptor(method, hnd, ann.async()));
-
-                    if (old != null)
-                        throw new IllegalArgumentException("Duplicated method: " + method.getName());
-                }
-            }
-        }
-    }
-
-    /**
-     * @param hnds Handler.
-     * @param snd Sender.
-     */
-    public static RemoteHandler wrap(WebSocketSender snd, Object ... hnds) {
-        return new RemoteHandler(snd, hnds);
-    }
-
-    /**
-     * @param req Request.
-     */
-    public void onMessage(JsonObject req) {
-        JsonPrimitive reqIdJson = req.getAsJsonPrimitive("reqId");
-
-        final Long reqId = reqIdJson == null ? null : reqIdJson.getAsLong();
-
-        String method = req.getAsJsonPrimitive("method").getAsString();
-
-        final MethodDescriptor desc = mtds.get(method);
-
-        if (desc == null) {
-            sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Unknown method: " + method);
-
-            return;
-        }
-
-        Type[] paramTypes = desc.mtd.getGenericParameterTypes();
-
-        JsonArray argsJson = req.getAsJsonArray("args");
-
-        final Object[] args;
-
-        if (paramTypes.length > 0) {
-            args = new Object[paramTypes.length];
-
-            if (argsJson == null || argsJson.size() != paramTypes.length) {
-                sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Inconsistent parameters count");
-
-                return;
-            }
-
-            for (int i = 0; i < paramTypes.length; i++)
-                args[i] = GSON.fromJson(argsJson.get(i), paramTypes[i]);
-        }
-        else
-            args = EMPTY_OBJECTS;
-
-        Runnable run = new Runnable() {
-            @Override public void run() {
-                final Object res;
-
-                try {
-                    res = desc.mtd.invoke(desc.hnd, args);
-                }
-                catch (Throwable e) {
-                    if (e instanceof AuthenticationException) {
-                        close();
-
-                        return;
-                    }
-
-                    if (e instanceof InvocationTargetException)
-                        e = ((InvocationTargetException)e).getTargetException();
-
-                    if (reqId != null)
-                        sendException(reqId, e.getClass().getName(), e.getMessage());
-                    else
-                        log.error("Exception on execute remote method.", e);
-
-                    return;
-                }
-
-                sendResponse(reqId, res, desc.returnType);
-            }
-        };
-
-        if (desc.async) {
-            try {
-                executorSrvc.submit(run);
-            }
-            catch (RejectedExecutionException ignore) {
-                // No-op.
-            }
-        }
-        else
-            run.run();
-    }
-
-    /**
-     * @param reqId Request id.
-     * @param exType Exception class name.
-     * @param exMsg Exception message.
-     */
-    protected void sendException(Long reqId, String exType, String exMsg) {
-        if (reqId == null)
-            return;
-
-        JsonObject res = new JsonObject();
-
-        res.addProperty("type", "CallRes");
-        res.addProperty("reqId", reqId);
-        res.addProperty("error", exType + ": " + exMsg);
-
-        snd.send(res);
-    }
-
-    /**
-     * @param reqId Request id.
-     * @param res Result.
-     * @param type Type.
-     */
-    private void sendResponse(Long reqId, Object res, Type type) {
-        if (reqId == null)
-            return;
-
-        JsonObject resp = new JsonObject();
-
-        resp.addProperty("type", "CallRes");
-        resp.addProperty("reqId", reqId);
-
-        JsonElement resJson = type == void.class ? JsonNull.INSTANCE : GSON.toJsonTree(res, type);
-
-        resp.add("response", resJson);
-
-        snd.send(resp);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void close() {
-        executorSrvc.shutdown();
-    }
-
-    /**
-     *
-     */
-    private static class MethodDescriptor {
-        /** */
-        private final Method mtd;
-
-        /** */
-        private final Object hnd;
-
-        /** */
-        private final Type returnType;
-
-        /** */
-        private final boolean async;
-
-        /**
-         * @param mtd Method.
-         * @param hnd Handler.
-         * @param async Async.
-         */
-        MethodDescriptor(Method mtd, Object hnd, boolean async) {
-            this.mtd = mtd;
-            this.hnd = hnd;
-            this.async = async;
-
-            returnType = mtd.getGenericReturnType();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java
deleted file mode 100644
index cceb86b..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-package org.apache.ignite.console.agent.remote;
-
-import com.google.gson.JsonObject;
-
-/**
- * Sender for messages to web-socket.
- */
-public interface WebSocketSender {
-    /**
-     * Send message.
-     * @param msg Message.
-     * @return {@code true} if message sent successfully.
-     */
-    public boolean send(String msg);
-
-    /**
-     * Send message.
-     * @param msg Message.
-     * @return {@code true} if message sent successfully.
-     */
-    public boolean send(JsonObject msg);
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java
index 5d33f29..4683dd8 100644
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java
@@ -18,11 +18,12 @@
 package org.apache.ignite.console.demo;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.SQLException;
 import java.util.concurrent.atomic.AtomicBoolean;
-
 import org.apache.log4j.Logger;
 import org.h2.tools.RunScript;
 import org.h2.tools.Server;
@@ -52,7 +53,7 @@ public class AgentMetadataDemo {
     /**
      * Start H2 database and populate it with several tables.
      */
-    public static void testDrive() {
+    public static Connection testDrive() throws SQLException {
         if (initLatch.compareAndSet(false, true)) {
             log.info("DEMO: Prepare in-memory H2 database...");
 
@@ -61,13 +62,7 @@ public class AgentMetadataDemo {
 
                 File sqlScript = resolvePath("demo/db-init.sql");
 
-                if (sqlScript == null) {
-                    log.error("DEMO: Failed to find demo database init script file: demo/db-init.sql");
-                    log.error("DEMO: Failed to start demo for metadata");
-
-                    return;
-                }
-
+                //noinspection ConstantConditions
                 RunScript.execute(conn, new FileReader(sqlScript));
 
                 log.info("DEMO: Sample tables created.");
@@ -80,9 +75,18 @@ public class AgentMetadataDemo {
 
                 log.info("DEMO: JDBC URL for test drive metadata load: jdbc:h2:mem:demo-db");
             }
-            catch (Exception e) {
+            catch (SQLException e) {
                 log.error("DEMO: Failed to start test drive for metadata!", e);
+
+                throw e;
+            }
+            catch (FileNotFoundException | NullPointerException e) {
+                log.error("DEMO: Failed to find demo database init script file: demo/db-init.sql");
+
+                throw new SQLException("Failed to start demo for metadata", e);
             }
         }
+
+        return DriverManager.getConnection("jdbc:h2:mem:demo-db;DB_CLOSE_DELAY=-1", "sa", "");
     }
 }


[33/50] [abbrv] ignite git commit: IGNITE-2676 Refactoring IGFS screen to Angular directives and JADE mixins.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/controllers/igfs-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/igfs-controller.js b/modules/control-center-web/src/main/js/controllers/igfs-controller.js
index b32b606..553fd4c 100644
--- a/modules/control-center-web/src/main/js/controllers/igfs-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/igfs-controller.js
@@ -17,102 +17,38 @@
 
 // Controller for IGFS screen.
 consoleModule.controller('igfsController', [
-    '$scope', '$http', '$state', '$filter', '$timeout', '$common', '$focus', '$confirm', '$clone', '$table', '$preview', '$loading', '$unsavedChangesGuard',
-    function ($scope, $http, $state, $filter, $timeout, $common, $focus, $confirm, $clone, $table, $preview, $loading, $unsavedChangesGuard) {
+    '$scope', '$http', '$state', '$filter', '$timeout', '$common', '$confirm', '$clone', '$loading', '$cleanup', '$unsavedChangesGuard',
+    function ($scope, $http, $state, $filter, $timeout, $common, $confirm, $clone, $loading, $cleanup, $unsavedChangesGuard) {
         $unsavedChangesGuard.install($scope);
 
+        var emptyIgfs = {empty: true};
+
+        var __original_value;
+
+        var blank = {
+            ipcEndpointConfiguration: {},
+            secondaryFileSystem: {}
+        };
+
+        // We need to initialize backupItem with empty object in order to properly used from angular directives.
+        $scope.backupItem = emptyIgfs;
+
         $scope.ui = $common.formUI();
+        $scope.ui.angularWay = true; // TODO We need to distinguish refactored UI from legacy UI.
         $scope.ui.activePanels = [0];
         $scope.ui.topPanels = [0];
 
-        $scope.joinTip = $common.joinTip;
-        $scope.getModel = $common.getModel;
-        $scope.javaBuiltInClasses = $common.javaBuiltInClasses;
         $scope.compactJavaName = $common.compactJavaName;
         $scope.widthIsSufficient = $common.widthIsSufficient;
         $scope.saveBtnTipText = $common.saveBtnTipText;
-        $scope.panelExpanded = $common.panelExpanded;
-
-        $scope.tableVisibleRow = $table.tableVisibleRow;
-
-        $scope.tableSave = function (field, index, stopEdit) {
-            switch (field.type) {
-                case 'pathModes':
-                    if ($table.tablePairSaveVisible(field, index))
-                        return $table.tablePairSave($scope.tablePairValid, $scope.backupItem, field, index, stopEdit);
-
-                    break;
-            }
-
-            return true;
-        };
-
-        $scope.tableReset = function (save) {
-            var field = $table.tableField();
-
-            if (!save || !$common.isDefined(field) || $scope.tableSave(field, $table.tableEditedRowIndex(), true)) {
-                $table.tableReset();
-
-                return true;
-            }
-
-            return false;
-        };
-
-        $scope.tableNewItem = function (field) {
-            if ($scope.tableReset(true))
-                $table.tableNewItem(field);
-        };
-
-        $scope.tableNewItemActive = $table.tableNewItemActive;
-
-        $scope.tableStartEdit = function (item, field, index) {
-            if ($scope.tableReset(true))
-                $table.tableStartEdit(item, field, index);
-        };
-
-        $scope.tableEditing = $table.tableEditing;
-
-        $scope.tableRemove = function (item, field, index) {
-            if ($scope.tableReset(true))
-                $table.tableRemove(item, field, index);
-        };
-
-        $scope.tableSimpleSave = $table.tableSimpleSave;
-        $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
-
-        $scope.tableSimpleUp = function (item, field, index) {
-            if ($scope.tableReset(true))
-                $table.tableSimpleUp(item, field, index);
-        };
-
-        $scope.tableSimpleDown = function (item, field, index) {
-            if ($scope.tableReset(true))
-                $table.tableSimpleDown(item, field, index);
-        };
-
-        $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
-
-        $scope.tablePairSave = $table.tablePairSave;
-        $scope.tablePairSaveVisible = $table.tablePairSaveVisible;
-
-        var previews = [];
-
-        $scope.previewInit = function (preview) {
-            previews.push(preview);
-
-            $preview.previewInit(preview);
-        };
-
-        $scope.previewChanged = $preview.previewChanged;
-
-        $scope.hidePopover = $common.hidePopover;
 
         var showPopoverMessage = $common.showPopoverMessage;
 
-        $scope.igfsModes = $common.mkOptions(['PRIMARY', 'PROXY', 'DUAL_SYNC', 'DUAL_ASYNC']);
+        $scope.contentVisible = function () {
+            var item = $scope.backupItem;
 
-        $scope.ipcTypes = $common.mkOptions(['SHMEM', 'TCP']);
+            return !item.empty && (!item._id || _.find($scope.displayedRows, {_id: item._id}));
+        };
 
         $scope.toggleExpanded = function () {
             $scope.ui.expanded = !$scope.ui.expanded;
@@ -120,38 +56,9 @@ consoleModule.controller('igfsController', [
             $common.hidePopover();
         };
 
-        $scope.general = [];
-        $scope.advanced = [];
         $scope.igfss = [];
         $scope.clusters = [];
 
-        $scope.preview = {
-            general: {xml: '', java: '', allDefaults: true},
-            ipc: {xml: '', java: '', allDefaults: true},
-            fragmentizer: {xml: '', java: '', allDefaults: true},
-            dualMode: {xml: '', java: '', allDefaults: true},
-            secondaryFileSystem: {xml: '', java: '', allDefaults: true},
-            misc: {xml: '', java: '', allDefaults: true}
-        };
-
-        $scope.tablePairValid = function (item, field, index) {
-            var pairValue = $table.tablePairValue(field, index);
-
-            var model = item[field.model];
-
-            if ($common.isDefined(model)) {
-                var idx = _.findIndex(model, function (pair) {
-                    return pair.path === pairValue.key;
-                });
-
-                // Found duplicate.
-                if (idx >= 0 && idx !== index)
-                    return showPopoverMessage($scope.ui, 'misc', $table.tableFieldId(index, 'KeyPathMode'), 'Such path already exists!');
-            }
-
-            return true;
-        };
-
         function selectFirstItem() {
             if ($scope.igfss.length > 0)
                 $scope.selectItem($scope.igfss[0]);
@@ -171,113 +78,82 @@ consoleModule.controller('igfsController', [
                     };
                 });
 
-                // Load page descriptor.
-                $http.get('/models/igfs.json')
-                    .success(function (data) {
-                        $scope.general = data.general;
-                        $scope.advanced = data.advanced;
+                if ($state.params.id)
+                    $scope.createItem($state.params.id);
+                else {
+                    var lastSelectedIgfs = angular.fromJson(sessionStorage.lastSelectedIgfs);
 
-                        $scope.ui.addGroups(data.general, data.advanced);
+                    if (lastSelectedIgfs) {
+                        var idx = _.findIndex($scope.igfss, function (igfs) {
+                            return igfs._id === lastSelectedIgfs;
+                        });
 
-                        if ($state.params.id)
-                            $scope.createItem($state.params.id);
+                        if (idx >= 0)
+                            $scope.selectItem($scope.igfss[idx]);
                         else {
-                            var lastSelectedIgfs = angular.fromJson(sessionStorage.lastSelectedIgfs);
-
-                            if (lastSelectedIgfs) {
-                                var idx = _.findIndex($scope.igfss, function (igfs) {
-                                    return igfs._id === lastSelectedIgfs;
-                                });
+                            sessionStorage.removeItem('lastSelectedIgfs');
 
-                                if (idx >= 0)
-                                    $scope.selectItem($scope.igfss[idx]);
-                                else {
-                                    sessionStorage.removeItem('lastSelectedIgfs');
-
-                                    selectFirstItem();
-                                }
-
-                            }
-                            else
-                                selectFirstItem();
+                            selectFirstItem();
                         }
+                    }
+                    else
+                        selectFirstItem();
+                }
 
-                        $scope.$watch('backupItem', function (val) {
-                            if (val) {
-                                var srcItem = $scope.selectedItem ? $scope.selectedItem : prepareNewItem();
-
-                                $scope.ui.checkDirty(val, srcItem);
-
-                                var varName = $commonUtils.toJavaName('igfs', val.name);
-
-                                $scope.preview.general.xml = $generatorXml.igfsGeneral(val).asString();
-                                $scope.preview.general.java = $generatorJava.igfsGeneral(val, varName).asString();
-                                $scope.preview.general.allDefaults = $common.isEmptyString($scope.preview.general.xml);
-
-                                $scope.preview.ipc.xml = $generatorXml.igfsIPC(val).asString();
-                                $scope.preview.ipc.java = $generatorJava.igfsIPC(val, varName).asString();
-                                $scope.preview.ipc.allDefaults = $common.isEmptyString($scope.preview.ipc.xml);
-
-                                $scope.preview.fragmentizer.xml = $generatorXml.igfsFragmentizer(val).asString();
-                                $scope.preview.fragmentizer.java = $generatorJava.igfsFragmentizer(val, varName).asString();
-                                $scope.preview.fragmentizer.allDefaults = $common.isEmptyString($scope.preview.fragmentizer.xml);
-
-                                $scope.preview.dualMode.xml = $generatorXml.igfsDualMode(val).asString();
-                                $scope.preview.dualMode.java = $generatorJava.igfsDualMode(val, varName).asString();
-                                $scope.preview.dualMode.allDefaults = $common.isEmptyString($scope.preview.dualMode.xml);
+                $scope.$watch('ui.inputForm.$valid', function(valid) {
+                    if (valid && __original_value === JSON.stringify($cleanup($scope.backupItem))) {
+                        $scope.ui.inputForm.$dirty = false;
+                    }
+                });
 
-                                $scope.preview.secondaryFileSystem.xml = $generatorXml.igfsSecondFS(val).asString();
-                                $scope.preview.secondaryFileSystem.java = $generatorJava.igfsSecondFS(val, varName).asString();
-                                $scope.preview.secondaryFileSystem.allDefaults = $common.isEmptyString($scope.preview.secondaryFileSystem.xml);
+                $scope.$watch('backupItem', function (val) {
+                    var form = $scope.ui.inputForm;
 
-                                $scope.preview.misc.xml = $generatorXml.igfsMisc(val).asString();
-                                $scope.preview.misc.java = $generatorJava.igfsMisc(val, varName).asString();
-                                $scope.preview.misc.allDefaults = $common.isEmptyString($scope.preview.misc.xml);
-                            }
-                        }, true);
-                    })
-                    .error(function (errMsg) {
-                        $common.showError(errMsg);
-                    });
+                    if (form.$pristine || (form.$valid && __original_value === JSON.stringify($cleanup(val))))
+                        form.$setPristine();
+                    else
+                        form.$setDirty();
+                }, true);
             })
-            .error(function (errMsg) {
+            .catch(function (errMsg) {
                 $common.showError(errMsg);
             })
             .finally(function () {
                 $scope.ui.ready = true;
+                $scope.ui.inputForm.$setPristine();
                 $loading.finish('loadingIgfsScreen');
             });
 
         $scope.selectItem = function (item, backup) {
             function selectItem() {
-                $table.tableReset();
-
-                $scope.selectedItem = angular.copy(item);
+                $scope.selectedItem = item;
 
                 try {
-                    if (item)
+                    if (item && item._id)
                         sessionStorage.lastSelectedIgfs = angular.toJson(item._id);
                     else
                         sessionStorage.removeItem('lastSelectedIgfs');
                 }
-                catch (error) { }
-
-                _.forEach(previews, function(preview) {
-                    preview.attractAttention = false;
-                });
+                catch (ignored) {
+                    // No-op.
+                }
 
                 if (backup)
                     $scope.backupItem = backup;
                 else if (item)
                     $scope.backupItem = angular.copy(item);
                 else
-                    $scope.backupItem = undefined;
+                    $scope.backupItem = emptyIgfs;
+
+                $scope.backupItem = angular.merge({}, blank, $scope.backupItem);
+
+                __original_value = JSON.stringify($cleanup($scope.backupItem));
 
                 if ($common.getQueryVariable('new'))
                     $state.go('base.configuration.igfs');
             }
 
-            $common.confirmUnsavedChanges($scope.ui.isDirty(), selectItem);
+            $common.confirmUnsavedChanges($scope.backupItem && $scope.ui.inputForm.$dirty, selectItem);
         };
 
         function prepareNewItem(id) {
@@ -290,51 +166,90 @@ consoleModule.controller('igfsController', [
             };
         }
 
+        $scope.zzz = function () {
+            console.log("TEST on enter!")
+        };
+
         // Add new IGFS.
         $scope.createItem = function (id) {
-            if ($scope.tableReset(true)) {
-                $timeout(function () {
-                    $common.ensureActivePanel($scope.ui, 'general', 'igfsName');
-                });
+            $timeout(function () {
+                $common.ensureActivePanel($scope.ui, 'general', 'igfsName');
+            });
 
-                $scope.selectItem(undefined, prepareNewItem(id));
-            }
+            $scope.selectItem(undefined, prepareNewItem(id));
         };
 
         // Check IGFS logical consistency.
         function validate(item) {
+            $common.hidePopover();
+
             if ($common.isEmptyString(item.name))
-                return showPopoverMessage($scope.ui, 'general', 'igfsName', 'Name should not be empty');
+                return showPopoverMessage($scope.ui, 'general', 'igfsName', 'IGFS name should not be empty!');
+
+            var form = $scope.ui.inputForm;
+            var errors = form.$error;
+            var errKeys = Object.keys(errors);
+
+            if (errKeys && errKeys.length > 0) {
+                var firstErrorKey = errKeys[0];
+
+                var firstError = errors[firstErrorKey][0];
+                var actualError = firstError.$error[firstErrorKey][0];
+
+                var errNameFull = actualError.$name;
+                var errNameShort = errNameFull;
+
+                if (errNameShort.endsWith('TextInput') || errNameShort.endsWith('JavaClass'))
+                    errNameShort = errNameShort.substring(0, errNameShort.length - 9);
+
+                var extractErrorMessage = function (errName) {
+                    try {
+                        return errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
+                    }
+                    catch(ignored) {
+                        try {
+                            msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
+                        }
+                        catch(ignited) {
+                            return false;
+                        }
+                    }
+                };
+
+                var msg = extractErrorMessage(errNameFull) || extractErrorMessage(errNameShort) || 'Invalid value!';
+
+                return showPopoverMessage($scope.ui, firstError.$name, errNameFull, msg);
+            }
 
             if (!$common.isEmptyString(item.dualModePutExecutorService) &&
                 !$common.isValidJavaClass('Put executor service', item.dualModePutExecutorService, false, 'dualModePutExecutorService', false, $scope.ui, 'dualMode'))
                 return false;
 
             if (!item.secondaryFileSystemEnabled && (item.defaultMode === 'PROXY'))
-                return showPopoverMessage($scope.ui, 'secondaryFileSystem', 'secondaryFileSystem-title', 'Secondary file system should be configured for "PROXY" IGFS mode');
+                return showPopoverMessage($scope.ui, 'secondaryFileSystem', 'secondaryFileSystem-title', 'Secondary file system should be configured for "PROXY" IGFS mode!');
 
             if (item.pathModes) {
                 for (var pathIx = 0; pathIx < item.pathModes.length; pathIx++) {
                     if (!item.secondaryFileSystemEnabled && item.pathModes[pathIx].mode === 'PROXY')
-                        return showPopoverMessage($scope.ui, 'misc', 'secondaryFileSystem-title', 'Secondary file system should be configured for "PROXY" path mode');
+                        return showPopoverMessage($scope.ui, 'misc', 'secondaryFileSystem-title', 'Secondary file system should be configured for "PROXY" path mode!');
                 }
             }
 
             return true;
         }
 
-        // Save IGFS into database.
+        // Save IGFS in database.
         function save(item) {
             $http.post('/api/v1/configuration/igfs/save', item)
                 .success(function (_id) {
-                    $scope.ui.markPristine();
+                    $scope.ui.inputForm.$setPristine();
 
                     var idx = _.findIndex($scope.igfss, function (igfs) {
                         return igfs._id === _id;
                     });
 
                     if (idx >= 0)
-                        angular.extend($scope.igfss[idx], item);
+                        angular.merge($scope.igfss[idx], item);
                     else {
                         item._id = _id;
                         $scope.igfss.push(item);
@@ -351,12 +266,10 @@ consoleModule.controller('igfsController', [
 
         // Save IGFS.
         $scope.saveItem = function () {
-            if ($scope.tableReset(true)) {
-                var item = $scope.backupItem;
+            var item = $scope.backupItem;
 
-                if (validate(item))
-                    save(item);
-            }
+            if (validate(item))
+                save(item);
         };
 
         function _igfsNames() {
@@ -365,13 +278,14 @@ consoleModule.controller('igfsController', [
             });
         }
 
-        // Save IGFS with new name.
+        // Clone IGFS with new name.
         $scope.cloneItem = function () {
-            if ($scope.tableReset(true) && validate($scope.backupItem)) {
+            if (validate($scope.backupItem)) {
                 $clone.confirm($scope.backupItem.name, _igfsNames()).then(function (newName) {
                     var item = angular.copy($scope.backupItem);
 
                     delete item._id;
+
                     item.name = newName;
 
                     save(item);
@@ -381,8 +295,6 @@ consoleModule.controller('igfsController', [
 
         // Remove IGFS from db.
         $scope.removeItem = function () {
-            $table.tableReset();
-
             var selectedItem = $scope.selectedItem;
 
             $confirm.confirm('Are you sure you want to remove IGFS: "' + selectedItem.name + '"?')
@@ -405,7 +317,7 @@ consoleModule.controller('igfsController', [
                                 if (igfss.length > 0)
                                     $scope.selectItem(igfss[0]);
                                 else
-                                    $scope.selectItem(undefined, undefined);
+                                    $scope.backupItem = emptyIgfs;
                             }
                         })
                         .error(function (errMsg) {
@@ -414,10 +326,8 @@ consoleModule.controller('igfsController', [
                 });
         };
 
-        // Remove all igfss from db.
+        // Remove all IGFS from db.
         $scope.removeAllItems = function () {
-            $table.tableReset();
-
             $confirm.confirm('Are you sure you want to remove all IGFS?')
                 .then(function () {
                     $http.post('/api/v1/configuration/igfs/remove/all')
@@ -425,8 +335,8 @@ consoleModule.controller('igfsController', [
                             $common.showInfo('All IGFS have been removed');
 
                             $scope.igfss = [];
-                            $scope.ui.markPristine();
-                            $scope.selectItem(undefined, undefined);
+                            $scope.backupItem = emptyIgfs;
+                            $scope.ui.inputForm.$setPristine();
                         })
                         .error(function (errMsg) {
                             $common.showError(errMsg);
@@ -434,23 +344,11 @@ consoleModule.controller('igfsController', [
                 });
         };
 
-        $scope.resetItem = function (group) {
-            var resetTo = $scope.selectedItem;
-
-            if (!$common.isDefined(resetTo))
-                resetTo = prepareNewItem();
-
-            $common.resetItem($scope.backupItem, resetTo, $scope.general, group);
-            $common.resetItem($scope.backupItem, resetTo, $scope.advanced, group);
-        };
-
         $scope.resetAll = function () {
-            $table.tableReset();
-
             $confirm.confirm('Are you sure you want to undo all changes for current IGFS?')
                 .then(function () {
                     $scope.backupItem = $scope.selectedItem ? angular.copy($scope.selectedItem) : prepareNewItem();
-                    $scope.ui.markPristine();
+                    $scope.ui.inputForm.$setPristine();
                 });
         };
     }]

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cd972a1/modules/control-center-web/src/main/js/views/configuration/igfs.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/configuration/igfs.jade b/modules/control-center-web/src/main/js/views/configuration/igfs.jade
index 1a9d262..947cebe 100644
--- a/modules/control-center-web/src/main/js/views/configuration/igfs.jade
+++ b/modules/control-center-web/src/main/js/views/configuration/igfs.jade
@@ -28,13 +28,21 @@ include ../includes/infos
             .padding-top-dflt(bs-affix)
                 .panel-tip-container(data-placement='bottom' bs-tooltip='' data-title='Create new IGFS')
                     button.btn.btn-primary(id='new-item' ng-click='createItem()') Add IGFS
-                +save-remove-buttons('IGFS')
+                +save-remove-buttons-new('IGFS')
                 hr
             .bs-affix-fix
-            form.form-horizontal(name='ui.inputForm' ng-show='backupItem && tableVisibleRow(displayedRows, selectedItem)' novalidate)
-                .panel-group(bs-collapse ng-model='ui.activePanels' data-allow-multiple='true' ng-click='triggerDigest = true')
-                    +groups('general', 'backupItem')
-                    div(ng-show='ui.expanded')
-                        +advanced-options
-                        +groups('advanced', 'backupItem')
-                +advanced-options
+            div(bs-collapse='' data-allow-multiple='true' ng-model='ui.activePanels')
+                form.form-horizontal(name='ui.inputForm' ng-show='contentVisible()' novalidate)
+                    .panel-group
+                        ignite-configuration-igfs-general
+
+                        ignite-advanced-options-toggle
+
+                        div(ng-show='ui.expanded')
+                            ignite-configuration-igfs-ipc
+                            ignite-configuration-igfs-fragmentizer
+                            ignite-configuration-igfs-dual
+                            ignite-configuration-igfs-secondary
+                            ignite-configuration-igfs-misc
+
+                            ignite-advanced-options-toggle


[08/50] [abbrv] ignite git commit: IGNITE-2597 Refactored to websockets.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
index a471d25..28c9a69 100644
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
@@ -33,21 +33,22 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.console.agent.AgentConfiguration;
 import org.apache.ignite.console.demo.model.Car;
 import org.apache.ignite.console.demo.model.Country;
 import org.apache.ignite.console.demo.model.Department;
 import org.apache.ignite.console.demo.model.Employee;
 import org.apache.ignite.console.demo.model.Parking;
-import org.apache.ignite.cache.QueryEntity;
-import org.apache.ignite.cache.QueryIndex;
-import org.apache.ignite.cache.QueryIndexType;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.logger.log4j.Log4JLogger;
 import org.apache.ignite.spi.IgniteSpiException;
+import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinderAdapter;
 import org.apache.log4j.Logger;
@@ -64,7 +65,7 @@ import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_REST_JETTY_PO
  */
 public class AgentSqlDemo {
     /** */
-    private static final Logger log = Logger.getLogger(AgentMetadataDemo.class.getName());
+    private static final Logger log = Logger.getLogger(AgentSqlDemo.class.getName());
 
     /** */
     private static final AtomicBoolean initLatch = new AtomicBoolean();
@@ -108,12 +109,12 @@ public class AgentSqlDemo {
         CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(COUNTRY_CACHE_NAME);
 
         // Configure cacheCountry types.
-        Collection<QueryEntity> queryEntities = new ArrayList<>();
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
 
         // COUNTRY.
         QueryEntity type = new QueryEntity();
 
-        queryEntities.add(type);
+        qryEntities.add(type);
 
         type.setKeyType(Integer.class.getName());
         type.setValueType(Country.class.getName());
@@ -130,7 +131,7 @@ public class AgentSqlDemo {
         // Indexes for COUNTRY.
         type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_6")));
 
-        ccfg.setQueryEntities(queryEntities);
+        ccfg.setQueryEntities(qryEntities);
 
         return ccfg;
     }
@@ -142,12 +143,12 @@ public class AgentSqlDemo {
         CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(DEPARTMENT_CACHE_NAME);
 
         // Configure cacheDepartment types.
-        Collection<QueryEntity> queryEntities = new ArrayList<>();
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
 
         // DEPARTMENT.
         QueryEntity type = new QueryEntity();
 
-        queryEntities.add(type);
+        qryEntities.add(type);
 
         type.setKeyType(Integer.class.getName());
         type.setValueType(Department.class.getName());
@@ -164,7 +165,7 @@ public class AgentSqlDemo {
         // Indexes for DEPARTMENT.
         type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_4")));
 
-        ccfg.setQueryEntities(queryEntities);
+        ccfg.setQueryEntities(qryEntities);
 
         return ccfg;
     }
@@ -176,12 +177,12 @@ public class AgentSqlDemo {
         CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(EMPLOYEE_CACHE_NAME);
 
         // Configure cacheEmployee types.
-        Collection<QueryEntity> queryEntities = new ArrayList<>();
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
 
         // EMPLOYEE.
         QueryEntity type = new QueryEntity();
 
-        queryEntities.add(type);
+        qryEntities.add(type);
 
         type.setKeyType(Integer.class.getName());
         type.setValueType(Employee.class.getName());
@@ -207,23 +208,23 @@ public class AgentSqlDemo {
 
         indexes.add(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_7"));
 
-        QueryIndex index = new QueryIndex();
+        QueryIndex idx = new QueryIndex();
 
-        index.setName("EMP_NAMES");
-        index.setIndexType(QueryIndexType.SORTED);
+        idx.setName("EMP_NAMES");
+        idx.setIndexType(QueryIndexType.SORTED);
         LinkedHashMap<String, Boolean> indFlds = new LinkedHashMap<>();
 
-        indFlds.put("firstName", false);
-        indFlds.put("lastName", false);
+        indFlds.put("firstName", Boolean.FALSE);
+        indFlds.put("lastName", Boolean.FALSE);
 
-        index.setFields(indFlds);
+        idx.setFields(indFlds);
 
-        indexes.add(index);
+        indexes.add(idx);
         indexes.add(new QueryIndex("salary", QueryIndexType.SORTED, false, "EMP_SALARY"));
 
         type.setIndexes(indexes);
 
-        ccfg.setQueryEntities(queryEntities);
+        ccfg.setQueryEntities(qryEntities);
 
         return ccfg;
     }
@@ -235,12 +236,12 @@ public class AgentSqlDemo {
         CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(PARKING_CACHE_NAME);
 
         // Configure cacheParking types.
-        Collection<QueryEntity> queryEntities = new ArrayList<>();
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
 
         // PARKING.
         QueryEntity type = new QueryEntity();
 
-        queryEntities.add(type);
+        qryEntities.add(type);
 
         type.setKeyType(Integer.class.getName());
         type.setValueType(Parking.class.getName());
@@ -250,14 +251,14 @@ public class AgentSqlDemo {
 
         qryFlds.put("id", "java.lang.Integer");
         qryFlds.put("name", "java.lang.String");
-        qryFlds.put("capacity", "java.lang.Integer");;
+        qryFlds.put("capacity", "java.lang.Integer");
 
         type.setFields(qryFlds);
 
         // Indexes for PARKING.
         type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_F")));
 
-        ccfg.setQueryEntities(queryEntities);
+        ccfg.setQueryEntities(qryEntities);
 
         return ccfg;
     }
@@ -269,12 +270,12 @@ public class AgentSqlDemo {
         CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(CAR_CACHE_NAME);
 
         // Configure cacheCar types.
-        Collection<QueryEntity> queryEntities = new ArrayList<>();
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
 
         // CAR.
         QueryEntity type = new QueryEntity();
 
-        queryEntities.add(type);
+        qryEntities.add(type);
 
         type.setKeyType(Integer.class.getName());
         type.setValueType(Car.class.getName());
@@ -291,7 +292,7 @@ public class AgentSqlDemo {
         // Indexes for CAR.
         type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_1")));
 
-        ccfg.setQueryEntities(queryEntities);
+        ccfg.setQueryEntities(qryEntities);
 
         return ccfg;
     }
@@ -305,13 +306,13 @@ public class AgentSqlDemo {
         if (places < 0)
             throw new IllegalArgumentException();
 
-        long factor = (long) Math.pow(10, places);
+        long factor = (long)Math.pow(10, places);
 
         val *= factor;
 
         long tmp = Math.round(val);
 
-        return (double) tmp / factor;
+        return (double)tmp / factor;
     }
 
     /**
@@ -319,7 +320,8 @@ public class AgentSqlDemo {
      * @param range Time range in milliseconds.
      */
     private static void populateCacheEmployee(Ignite ignite, long range) {
-        log.debug("DEMO: Start employees population with data...");
+        if (log.isDebugEnabled())
+            log.debug("DEMO: Start employees population with data...");
 
         IgniteCache<Integer, Country> cacheCountry = ignite.cache(COUNTRY_CACHE_NAME);
 
@@ -346,18 +348,20 @@ public class AgentSqlDemo {
             double r = rnd.nextDouble();
 
             cacheEmployee.put(i, new Employee(i, depId, depId, "First name employee #" + n,
-                    "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
-                    new java.sql.Date((long)(r * range)), "Job employee #" + n, 500 + round(r * 2000, 2)));
+                "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
+                new java.sql.Date((long)(r * range)), "Job employee #" + n, 500 + round(r * 2000, 2)));
         }
 
-        log.debug("DEMO: Finished employees population.");
+        if (log.isDebugEnabled())
+            log.debug("DEMO: Finished employees population.");
     }
 
     /**
      * @param ignite Ignite.
      */
     private static void populateCacheCar(Ignite ignite) {
-        log.debug("DEMO: Start cars population...");
+        if (log.isDebugEnabled())
+            log.debug("DEMO: Start cars population...");
 
         IgniteCache<Integer, Parking> cacheParking = ignite.cache(PARKING_CACHE_NAME);
 
@@ -369,7 +373,8 @@ public class AgentSqlDemo {
         for (int i = 0, n = 1; i < CAR_CNT; i++, n++)
             cacheCar.put(i, new Car(i, rnd.nextInt(PARK_CNT), "Car #" + n));
 
-        log.debug("DEMO: Finished cars population.");
+        if (log.isDebugEnabled())
+            log.debug("DEMO: Finished cars population.");
     }
 
     /**
@@ -390,7 +395,7 @@ public class AgentSqlDemo {
             }
         });
 
-        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) srvc;
+        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)srvc;
 
         // Setting up shutdown policy.
         executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
@@ -428,8 +433,8 @@ public class AgentSqlDemo {
                             double r = rnd.nextDouble();
 
                             cacheEmployee.put(id, new Employee(id, depId, depId, "First name employee #" + n,
-                                    "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
-                                    new java.sql.Date((long)(r * diff)), "Job employee #" + n, 500 + round(r * 2000, 2)));
+                                "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
+                                new java.sql.Date((long)(r * diff)), "Job employee #" + n, 500 + round(r * 2000, 2)));
 
                             if (rnd.nextBoolean())
                                 cacheEmployee.remove(rnd.nextInt(EMPL_CNT));
@@ -515,17 +520,27 @@ public class AgentSqlDemo {
 
                 cfg.setDiscoverySpi(discoSpi);
 
+                TcpCommunicationSpi commSpi = new TcpCommunicationSpi();
+
+                commSpi.setSharedMemoryPort(-1);
+
+                cfg.setCommunicationSpi(commSpi);
+
                 cfg.setCacheConfiguration(cacheCountry(), cacheDepartment(), cacheEmployee(), cacheParking(), cacheCar());
 
+                cfg.getConnectorConfiguration().setPort(60700);
+
                 System.setProperty(IGNITE_JETTY_PORT, "60800");
                 System.setProperty(IGNITE_NO_ASCII, "true");
 
-                log.debug("DEMO: Start embedded node with indexed enabled caches...");
+                if (log.isDebugEnabled())
+                    log.debug("DEMO: Start embedded node with indexed enabled caches...");
 
                 IgniteEx ignite = (IgniteEx)Ignition.start(cfg);
 
-                String host = ((Collection<String>)
-                    ignite.localNode().attribute(ATTR_REST_JETTY_ADDRS)).iterator().next();
+                Collection<String> jettyAddrs = ignite.localNode().attribute(ATTR_REST_JETTY_ADDRS);
+
+                String host = jettyAddrs == null ? null : jettyAddrs.iterator().next();
 
                 Integer port = ignite.localNode().attribute(ATTR_REST_JETTY_PORT);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/.eslintrc
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/.eslintrc b/modules/control-center-web/src/main/js/.eslintrc
index 6d2b466..3e543f4 100644
--- a/modules/control-center-web/src/main/js/.eslintrc
+++ b/modules/control-center-web/src/main/js/.eslintrc
@@ -20,6 +20,7 @@ ecmaFeatures:
 
 globals:
     _: true
+    io: true
     window: true
     global: true
     angular: true

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/.gitignore
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/.gitignore b/modules/control-center-web/src/main/js/.gitignore
index 05d5693..bb977f8 100644
--- a/modules/control-center-web/src/main/js/.gitignore
+++ b/modules/control-center-web/src/main/js/.gitignore
@@ -5,4 +5,7 @@ jspm_packages
 .npmrc
 build
 app/plugins
-public/stylesheets/*.css
\ No newline at end of file
+public/stylesheets/*.css
+serve/config/*.json
+serve/agent_dists/*.zip
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/app/data/colors.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/data/colors.json b/modules/control-center-web/src/main/js/app/data/colors.json
new file mode 100644
index 0000000..188e485
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/data/colors.json
@@ -0,0 +1,22 @@
+[
+  "#1f77b4",
+  "#ff7f0e",
+  "#2ca02c",
+  "#d62728",
+  "#9467bd",
+  "#8c564b",
+  "#e377c2",
+  "#7f7f7f",
+  "#bcbd22",
+  "#17becf",
+  "#ffbb78",
+  "#98df8a",
+  "#ff9896",
+  "#c5b0d5",
+  "#aec7e8",
+  "#c49c94",
+  "#f7b6d2",
+  "#c7c7c7",
+  "#dbdb8d",
+  "#9edae5"
+]

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/app/decorator/select.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/decorator/select.js b/modules/control-center-web/src/main/js/app/decorator/select.js
index f770fc1..f232f88 100644
--- a/modules/control-center-web/src/main/js/app/decorator/select.js
+++ b/modules/control-center-web/src/main/js/app/decorator/select.js
@@ -17,45 +17,54 @@
 
 import angular from 'angular';
 
+/**
+ * Special decorator that fix problem in AngularStrap selectAll / deselectAll methods.
+ * If this problem will be fixed in AngularStrap we can remove this delegate.
+ */
 angular.module('mgcrea.ngStrap.select')
     .decorator('$select', ($delegate) => {
         function SelectFactoryDecorated(element, controller, config) {
             const deligate = $delegate(element, controller, config);
 
-            const scope = deligate.$scope;
+            // Common vars.
+            const options = angular.extend({}, $delegate.defaults, config);
 
-            const $selectAllDeligate = scope.$selectAll;
+            const scope = deligate.$scope;
 
-            scope.$selectAll = () => {
-                if (scope.$isMultiple) {
-                    const newActiveIndex = [];
+            const selectAll = (active) => {
+                var selected = [];
 
-                    for (let i = 0; i < scope.$matches.length; i++)
-                        newActiveIndex.push(i);
+                scope.$apply(function () {
+                    for (var i = 0; i < scope.$matches.length; i++) {
+                        if (scope.$isActive(i) === active) {
+                            selected[i] = scope.$matches[i].value;
 
-                    scope.$activeIndex = newActiveIndex;
+                            deligate.activate(i);
 
-                    controller.$setViewValue(scope.$activeIndex.map((index) => {
-                        if (angular.isUndefined(scope.$matches[index]))
-                            return null;
+                            controller.$setViewValue(scope.$activeIndex.map(function (index) {
+                                if (angular.isUndefined(scope.$matches[index])) {
+                                    return null;
+                                }
+                                return scope.$matches[index].value;
+                            }));
+                        }
+                    }
+                });
 
-                        return scope.$matches[index].value;
-                    }));
+                // Emit events.
+                for (var i = 0; i < selected.length; i++) {
+                    if (selected[i]) {
+                        scope.$emit(options.prefixEvent + '.select', selected[i], i, deligate);
+                    }
                 }
-                else
-                    $selectAllDeligate();
             };
 
-            const $selectNoneDeligate = scope.$selectNone;
+            scope.$selectAll = () => {
+                scope.$$postDigest(selectAll.bind(this, false));
+            };
 
             scope.$selectNone = () => {
-                if (scope.$isMultiple) {
-                    scope.$activeIndex = [];
-
-                    controller.$setViewValue([]);
-                }
-                else
-                    $selectNoneDeligate();
+                scope.$$postDigest(selectAll.bind(this, true));
             };
 
             return deligate;

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/app/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/index.js b/modules/control-center-web/src/main/js/app/index.js
index a807a3c..ad92c86 100644
--- a/modules/control-center-web/src/main/js/app/index.js
+++ b/modules/control-center-web/src/main/js/app/index.js
@@ -20,26 +20,26 @@ import _ from 'lodash';
 import ace from 'ace';
 import angular from 'angular';
 import pdfMake from 'pdfmake';
+import io from 'socket.io-client';
 
 window._ = _;
-window.jQuery = jQuery;
 window.ace = ace;
 window.require = ace.require; // TODO Should be removed after full refactoring to directives.
-window.angular = angular;
 window.pdfMake = pdfMake;
 
-import 'angular-ui-router';
-import 'angular-ui-router-metatags';
 import 'angular-animate';
 import 'angular-sanitize';
-import 'angular-ui-grid';
+import 'angular-strap';
+import 'angular-socket-io';
 import 'angular-loading';
+import 'angular-retina';
+import 'angular-ui-router';
+import 'angular-ui-router-metatags';
+import 'angular-smart-table';
+import 'angular-ui-grid';
 import 'angular-drag-and-drop-lists';
 import 'angular-nvd3';
-import 'angular-retina';
-import 'angular-strap';
 import 'angular-tree-control';
-import 'angular-smart-table';
 
 import 'bootstrap-carousel';
 import 'file-saver';
@@ -55,7 +55,7 @@ import 'angular-ui-grid/ui-grid.css!';
 import 'angular-loading/angular-loading.css!';
 import 'angular-motion/dist/angular-motion.css!';
 
-// import './decorator/select';
+import './decorator/select';
 
 import './modules/form/form.module';
 import './modules/JavaTypes/JavaTypes.provider';
@@ -94,10 +94,12 @@ import igniteFormFieldJavaClass from './directives/form-field-java-class/form-fi
 import igniteBsAffixUpdate from './directives/bs-affix-update.directive';
 
 // Services.
-import cleanup from './services/cleanup/cleanup.service';
+import cleanup from './services/cleanup.service';
 import GeneratorXml from './services/Generator/Xml.service';
 import GeneratorJava from './services/Generator/Java.service';
-import IgniteCountries from './services/Countries/Countries.service';
+import IgniteCountries from './services/Countries.service';
+import IgniteChartColors from './services/ChartColors.service';
+import IgniteAgentMonitor from './services/AgentMonitor.service';
 
 // Providers
 
@@ -107,9 +109,13 @@ import byName from './filters/byName.filter';
 
 angular
 .module('ignite-console', [
+    'ngRetina',
+    'btford.socket-io',
+    'ngAnimate',
+    'ngSanitize',
+    'mgcrea.ngStrap',
     'ui.router',
     'ui.router.metatags',
-    'ngRetina',
     // Base modules.
     'ignite-console.user',
     'ignite-console.branding',
@@ -149,6 +155,8 @@ angular
 .service(...GeneratorXml)
 .service(...GeneratorJava)
 .service(...IgniteCountries)
+.service(...IgniteChartColors)
+.service(...IgniteAgentMonitor)
 // Providers.
 // Filters.
 .filter(...hasPojo)
@@ -179,14 +187,15 @@ angular
 .run(['$rootScope', ($root) => {
     $root._ = _;
 }])
-.run(['$rootScope', '$state', 'MetaTags', 'Auth', 'User', ($root, $state, $meta, Auth, User) => {
+.run(['$rootScope', '$state', 'MetaTags', 'Auth', 'User', 'IgniteAgentMonitor', ($root, $state, $meta, Auth, User, AgentMonitor) => {
     $root.$state = $state;
 
     $root.$meta = $meta;
 
     if (Auth.authorized) {
         User.read()
-            .then((user) => $root.$broadcast('user', user));
+            .then((user) => $root.$broadcast('user', user))
+            .then(() => AgentMonitor.init());
     }
 }])
 .run(['$rootScope', ($root) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js b/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
new file mode 100644
index 0000000..cf66b61
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+class IgniteAgentMonitor {
+    constructor(socketFactory, $root, $q, $state, $modal, $common) {
+        this._scope = $root.$new();
+
+        $root.$on('$stateChangeStart', () => {
+            this.stopWatch();
+        });
+
+        // Pre-fetch modal dialogs.
+        this._downloadAgentModal = $modal({
+            scope: this._scope,
+            templateUrl: '/templates/agent-download.html',
+            show: false,
+            backdrop: 'static'
+        });
+
+        const _modalHide = this._downloadAgentModal.hide;
+
+        /**
+         * Special dialog hide function.
+         */
+        this._downloadAgentModal.hide = () => {
+            $common.hideAlert();
+
+            _modalHide();
+        };
+
+        /**
+         * Close dialog and go by specified link.
+         */
+        this._scope.back = () => {
+            $state.go(this._scope.backState);
+        };
+
+        this._scope.downloadAgent = () => {
+            const lnk = document.createElement('a');
+
+            lnk.setAttribute('href', '/api/v1/agent/download/zip');
+            lnk.setAttribute('target', '_self');
+            lnk.setAttribute('download', null);
+            lnk.style.display = 'none';
+
+            document.body.appendChild(lnk);
+
+            lnk.click();
+
+            document.body.removeChild(lnk);
+        };
+
+        this._scope.hasAgents = null;
+        this._scope.showModal = false;
+
+        /**
+         * @type {Socket}
+         */
+        this._socket = null;
+
+        this._socketFactory = socketFactory;
+
+        this._$q = $q;
+    }
+
+    /**
+     * @private
+     */
+    _checkModal() {
+        if (this._scope.showModal && !this._scope.hasAgents)
+            this._downloadAgentModal.$promise.then(this._downloadAgentModal.show);
+        else if ((this._scope.hasAgents || !this._scope.showModal) && this._downloadAgentModal.$isShown)
+            this._downloadAgentModal.hide();
+    }
+
+    /**
+     * @returns {Promise}
+     */
+    awaitAgent() {
+        if (this._scope.hasAgents)
+            return this._$q.when();
+
+        if (this._scope.hasAgents !== null)
+            this._checkModal();
+
+        const latch = this._$q.defer();
+
+        const offConnected = this._scope.$on('agent:connected', (event, success) => {
+            offConnected();
+
+            if (success)
+                return latch.resolve();
+
+            latch.reject();
+        });
+
+        return latch.promise;
+    }
+
+    init() {
+        this._socket = this._socketFactory();
+
+        this._socket.on('agent:count', ({count}) => {
+            this._scope.hasAgents = count > 0;
+
+            this._checkModal();
+
+            if (this._scope.hasAgents)
+                this._scope.$broadcast('agent:connected', true);
+        });
+
+        this._socket.on('disconnect', () => {
+            this._scope.hasAgents = false;
+
+            this._checkModal();
+        });
+    }
+
+    /**
+     * @param {Object} back
+     * @param {Function} startDemo
+     * @returns {Promise}
+     */
+    startWatch(back, startDemo) {
+        this._scope.backState = back.state;
+        this._scope.backText = back.text;
+
+        this._scope.agentGoal = back.goal;
+
+        this._scope.showModal = true;
+
+        this._scope.startDemo = startDemo;
+
+        return this.awaitAgent();
+    }
+
+    /**
+     *
+     * @param {String} event
+     * @param {Object} [args]
+     * @returns {Promise}
+     * @private
+     */
+    _emit(event, ...args) {
+        if (!this._socket)
+            return this._$q.reject('Failed to connect to agent');
+
+        const latch = this._$q.defer();
+
+        const onDisconnect = () => {
+            this._socket.removeListener('disconnect', onDisconnect);
+
+            latch.reject('Connection to server was closed');
+        };
+
+        this._socket.on('disconnect', onDisconnect);
+
+        args.push((err, res) => {
+            this._socket.removeListener('disconnect', onDisconnect);
+
+            if (err)
+                latch.reject(err);
+
+            latch.resolve(res);
+        });
+
+        this._socket.emit(event, ...args);
+
+        return latch.promise;
+    }
+
+    drivers() {
+        return this._emit('schemaImport:drivers');
+    }
+
+    /**
+     *
+     * @param {Object} preset
+     * @returns {Promise}
+     */
+    schemas(preset) {
+        return this._emit('schemaImport:schemas', preset);
+    }
+
+    /**
+     *
+     * @param {Object} preset
+     * @returns {Promise}
+     */
+    tables(preset) {
+        return this._emit('schemaImport:tables', preset);
+    }
+
+    /**
+     *
+     * @param {String} event
+     * @param {Object} [args]
+     * @returns {Promise}
+     * @private
+     */
+    _rest(event, ...args) {
+        return this._downloadAgentModal.$promise
+            .then(() => this._emit(event, ...args))
+            .then((res) => {
+                this._downloadAgentModal.hide();
+
+                return res;
+            })
+            .catch((errMsg) => {
+                this._downloadAgentModal.show();
+
+                return this._$q.reject(errMsg);
+            });
+    }
+
+    /**
+     * @param {Boolean} demo
+     * @param {Boolean} [attr]
+     * @param {Boolean} [mtr]
+     * @returns {Promise}
+     */
+    topology(demo, attr, mtr) {
+        return this._rest('node:topology', !!demo, !!attr, !!mtr);
+    }
+
+    /**
+     * @param {Object} args
+     * @returns {Promise}
+     */
+    queryClose(args) {
+        if (!args || !args.queryId)
+            return this._$q.when();
+
+        return this._rest('node:query:close', {demo: args.demo, cacheName: args.cacheName, queryId: args.queryId});
+    }
+
+    /**
+     * @param {Object} args
+     * @returns {Promise}
+     */
+    query(args) {
+        return this._rest('node:query', args);
+    }
+
+    /**
+     * @param {Boolean} demo
+     * @returns {Promise}
+     */
+    metadata(demo) {
+        return this._rest('node:cache:metadata', {demo});
+    }
+
+    /**
+     * @param {Object} args
+     * @returns {Promise}
+     */
+    next(args) {
+        return this._rest('node:query:fetch', args);
+    }
+
+    stopWatch() {
+        this._scope.showModal = false;
+
+        this._checkModal();
+
+        this._scope.$broadcast('agent:connected', false);
+    }
+}
+
+IgniteAgentMonitor.$inject = ['socketFactory', '$rootScope', '$q', '$state', '$modal', '$common'];
+
+export default ['IgniteAgentMonitor', IgniteAgentMonitor];

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/app/services/ChartColors.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/ChartColors.service.js b/modules/control-center-web/src/main/js/app/services/ChartColors.service.js
new file mode 100644
index 0000000..ec3f365
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/services/ChartColors.service.js
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import COLORS from 'app/data/colors.json!';
+
+export default ['IgniteChartColors', function() {
+    return COLORS;
+}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/app/services/Countries.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/Countries.service.js b/modules/control-center-web/src/main/js/app/services/Countries.service.js
new file mode 100644
index 0000000..82b8626
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/services/Countries.service.js
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// Java built-in short class names.
+import COUNTRIES from 'app/data/countries.json!';
+
+export default ['IgniteCountries', function() {
+    return COUNTRIES;
+}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/app/services/Countries/Countries.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/Countries/Countries.service.js b/modules/control-center-web/src/main/js/app/services/Countries/Countries.service.js
deleted file mode 100644
index 82b8626..0000000
--- a/modules/control-center-web/src/main/js/app/services/Countries/Countries.service.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-// Java built-in short class names.
-import COUNTRIES from 'app/data/countries.json!';
-
-export default ['IgniteCountries', function() {
-    return COUNTRIES;
-}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/app/services/cleanup.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/cleanup.service.js b/modules/control-center-web/src/main/js/app/services/cleanup.service.js
new file mode 100644
index 0000000..c50bfe0
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/services/cleanup.service.js
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import angular from 'angular';
+
+const isArray = angular.isArray;
+const isDefined = angular.isDefined;
+const isNumber = angular.isNumber;
+const isObject = angular.isObject;
+const isString = angular.isString;
+const isUndefined = angular.isUndefined;
+const isBoolean = (val) => typeof val === 'boolean';
+
+export default ['$cleanup', () => {
+    const cleanup = (original, dist) => {
+        if (isUndefined(original))
+            return dist;
+
+        if (isObject(original)) {
+            let key;
+
+            for (key in original) {
+                if (original.hasOwnProperty(key)) {
+                    const attr = cleanup(original[key]);
+
+                    if (isDefined(attr)) {
+                        dist = dist || {};
+                        dist[key] = attr;
+                    }
+                }
+            }
+        } else if ((isString(original) && original.length) || isNumber(original) || isBoolean(original))
+            dist = original;
+        else if (isArray(original) && original.length) {
+            dist = [];
+
+            let i = 0;
+            const l = original.length;
+
+            for (; i < l; i++)
+                dist[i] = cleanup(original[i], {});
+        }
+
+        return dist;
+    };
+
+    return cleanup;
+}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/app/services/cleanup/cleanup.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/cleanup/cleanup.service.js b/modules/control-center-web/src/main/js/app/services/cleanup/cleanup.service.js
deleted file mode 100644
index c50bfe0..0000000
--- a/modules/control-center-web/src/main/js/app/services/cleanup/cleanup.service.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-import angular from 'angular';
-
-const isArray = angular.isArray;
-const isDefined = angular.isDefined;
-const isNumber = angular.isNumber;
-const isObject = angular.isObject;
-const isString = angular.isString;
-const isUndefined = angular.isUndefined;
-const isBoolean = (val) => typeof val === 'boolean';
-
-export default ['$cleanup', () => {
-    const cleanup = (original, dist) => {
-        if (isUndefined(original))
-            return dist;
-
-        if (isObject(original)) {
-            let key;
-
-            for (key in original) {
-                if (original.hasOwnProperty(key)) {
-                    const attr = cleanup(original[key]);
-
-                    if (isDefined(attr)) {
-                        dist = dist || {};
-                        dist[key] = attr;
-                    }
-                }
-            }
-        } else if ((isString(original) && original.length) || isNumber(original) || isBoolean(original))
-            dist = original;
-        else if (isArray(original) && original.length) {
-            dist = [];
-
-            let i = 0;
-            const l = original.length;
-
-            for (; i < l; i++)
-                dist[i] = cleanup(original[i], {});
-        }
-
-        return dist;
-    };
-
-    return cleanup;
-}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/config.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/config.js b/modules/control-center-web/src/main/js/config.js
index 406ce17..a54b40f 100644
--- a/modules/control-center-web/src/main/js/config.js
+++ b/modules/control-center-web/src/main/js/config.js
@@ -25,10 +25,11 @@ System.config({
     "angular-loading": "github:darthwade/angular-loading@0.1.4",
     "angular-motion": "github:mgcrea/angular-motion@0.4.3",
     "angular-nvd3": "github:krispo/angular-nvd3@1.0.5",
-    "angular-retina": "github:jrief/angular-retina@0.3.11",
+    "angular-retina": "github:jrief/angular-retina@0.3.8",
     "angular-sanitize": "github:angular/bower-angular-sanitize@1.5.1",
     "angular-smart-table": "github:lorenzofox3/Smart-Table@2.1.7",
-    "angular-strap": "github:akuznetsov-gridgain/angular-strap@fix-1852-2.3.6",
+    "angular-socket-io": "github:btford/angular-socket-io@0.7.0",
+    "angular-strap": "github:mgcrea/angular-strap@2.3.7",
     "angular-tree-control": "github:wix/angular-tree-control@0.2.23",
     "angular-ui-ace": "github:angular-ui/ui-ace@0.2.3",
     "angular-ui-grid": "github:angular-ui/bower-ui-grid@3.1.1",
@@ -54,14 +55,9 @@ System.config({
     "nvd3": "npm:nvd3@1.8.1",
     "pdfmake": "github:bpampuch/pdfmake@0.1.20",
     "query-command-supported": "github:zenorocha/document.queryCommandSupported@1.0.0",
+    "socket.io-client": "github:socketio/socket.io-client@1.4.5",
     "spinjs": "github:fgnass/spin.js@2.3.2",
     "text": "github:systemjs/plugin-text@0.0.7",
-    "github:akuznetsov-gridgain/angular-strap@fix-1852-2.3.6": {
-      "angular": "github:angular/bower-angular@1.5.1",
-      "angular-animate": "github:angular/bower-angular-animate@1.5.1",
-      "angular-motion": "github:mgcrea/angular-motion@0.4.3",
-      "angular-sanitize": "github:angular/bower-angular-sanitize@1.5.1"
-    },
     "github:angular-ui/bower-ui-grid@3.1.1": {
       "pdfmake": "github:bpampuch/pdfmake@0.1.20"
     },
@@ -80,6 +76,9 @@ System.config({
     "github:angular/bower-angular@1.5.1": {
       "jquery": "github:components/jquery@2.2.1"
     },
+    "github:btford/angular-socket-io@0.7.0": {
+      "socket.io-client": "github:socketio/socket.io-client@1.4.5"
+    },
     "github:darthwade/angular-loading@0.1.4": {
       "spinjs": "github:fgnass/spin.js@2.3.2"
     },
@@ -139,7 +138,6 @@ System.config({
       "vm-browserify": "npm:vm-browserify@0.0.4"
     },
     "github:krispo/angular-nvd3@1.0.5": {
-      "angular": "github:angular/bower-angular@1.5.1",
       "d3": "npm:d3@3.5.14",
       "nvd3": "npm:nvd3@1.8.1"
     },
@@ -147,6 +145,12 @@ System.config({
       "angular": "github:angular/bower-angular@1.5.1",
       "css": "github:systemjs/plugin-css@0.1.20"
     },
+    "github:mgcrea/angular-strap@2.3.7": {
+      "angular": "github:angular/bower-angular@1.5.1",
+      "angular-animate": "github:angular/bower-angular-animate@1.5.1",
+      "angular-motion": "github:mgcrea/angular-motion@0.4.3",
+      "angular-sanitize": "github:angular/bower-angular-sanitize@1.5.1"
+    },
     "github:twbs/bootstrap@3.3.6": {
       "jquery": "github:components/jquery@2.2.1"
     },

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index a98ba2c..d4f692d 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -17,10 +17,21 @@
 
 var consoleModule = angular.module('ignite-web-console',
     [
-        'ngAnimate', 'ngSanitize', 'mgcrea.ngStrap', 'smart-table', 'treeControl', 'darthwade.dwLoading', 'ui.grid', 'ui.grid.autoResize', 'ui.grid.exporter', 'nvd3', 'dndLists'
+        'darthwade.dwLoading',
+        'smart-table',
+        'treeControl',
+        'ui.grid',
+        'ui.grid.saveState',
+        'ui.grid.selection',
+        'ui.grid.resizeColumns',
+        'ui.grid.autoResize',
+        'ui.grid.exporter',
+        'nvd3',
+        'dndLists'
         /* ignite:modules */
         , 'ignite-console'
         /* endignite */
+
         /* ignite:plugins */
         /* endignite */
     ])
@@ -2045,194 +2056,6 @@ consoleModule.controller('auth', ['$scope', '$focus', 'Auth', 'IgniteCountries',
     $focus('user_email');
 }]);
 
-// Download agent controller.
-consoleModule.service('$agentDownload', [
-    '$http', '$interval', '$rootScope', '$state', '$modal', '$loading', '$common',
-        function ($http, $interval, $rootScope, $state, $modal, $loading, $common) {
-        var scope = $rootScope.$new();
-
-        // Pre-fetch modal dialogs.
-        var _modal = $modal({scope: scope, templateUrl: '/templates/agent-download.html', show: false, backdrop: 'static'});
-
-        var _modalHide = _modal.hide;
-
-        var _modalAlertHide = function () {
-            $common.hideAlert();
-
-            _modalHide();
-        };
-
-        /**
-         * Special dialog hide function.
-         */
-        _modal.hide = function () {
-            _stopInterval();
-
-            _modalAlertHide();
-        };
-
-        /**
-         * Close dialog and go by specified link.
-         */
-        scope.back = function () {
-            _modal.hide();
-
-            if (_modal.backState)
-                $state.go(_modal.backState);
-        };
-
-        scope.downloadAgent = function () {
-            var lnk = document.createElement('a');
-
-            lnk.setAttribute('href', '/api/v1/agent/download/zip');
-            lnk.setAttribute('target', '_self');
-            lnk.setAttribute('download', null);
-            lnk.style.display = 'none';
-
-            document.body.appendChild(lnk);
-
-            lnk.click();
-
-            document.body.removeChild(lnk);
-        };
-
-        /**
-         * Base handler of exceptions on agent interaction
-         *
-         * @param errMsg Error message.
-         * @param status Error code.
-         * @param timedOut True if request timedOut.
-         */
-        function _handleException (errMsg, status, timedOut) {
-            if (_modal.skipSingleError)
-                _modal.skipSingleError = false;
-            else if (!_modal.$isShown) {
-                // Don't show missing node dialog on SQL demo enabling.
-                if (_modal.check.params && _modal.check.params.demo && timedOut || !_modal.updatePromise)
-                    return;
-
-                $loading.finish('loading');
-
-                _modal.$promise.then(_modal.show);
-            }
-
-            var nodeError = _.includes([401, 403, 500], status);
-
-            scope.nodeFailedConnection = nodeError || timedOut;
-
-            if (nodeError)
-                $common.showError(errMsg, 'top-right', 'body', true);
-        }
-
-        /**
-         * Start interval to agent listening.
-         */
-        function _startInterval(awaitFirstSuccess) {
-            _modal.skipSingleError = false;
-
-            // Stop refresh after first success.
-            _modal.awaitFirstSuccess = awaitFirstSuccess;
-
-            _modal.updatePromise = $interval(function () {
-                _tryWithAgent();
-            }, 5000, 0, false);
-
-            _tryWithAgent();
-        }
-
-        /**
-         * Stop interval to agent listening.
-         */
-        function _stopInterval() {
-            $interval.cancel(_modal.updatePromise);
-
-            _modal.updatePromise = null;
-        }
-
-        /**
-         * Try to access agent and execute specified function.
-         */
-        function _tryWithAgent() {
-            var _timeout = 3000,
-                _timedOut = false;
-
-            setTimeout(function () {
-                _timedOut = true;
-            }, _timeout);
-
-            $http.post(_modal.check.url, _modal.check.params, {timeout: _timeout})
-                .success(function (data) {
-                    if (_modal.awaitFirstSuccess)
-                        _stopInterval();
-
-                    $loading.finish('loading');
-
-                    _modal.check.cb(data, _modalAlertHide, _handleException);
-
-                    if (!_modal.skipSingleError && _modal.check.onConnect)
-                        _modal.check.onConnect();
-
-                    _modal.skipSingleError = true;
-                })
-                .error(function (errMsg, status) {
-                    _handleException(errMsg, status, _timedOut);
-                });
-        }
-
-        return {
-            /**
-             * Start listening topology from node.
-             *
-             * @param cb Function to execute by timer when topology received.
-             * @param onConnect Function to execute when agent connected to a grid.
-             * @param demo True if need work with demo grid.
-             * @param attr True if need receive nodes attributes.
-             * @param mtr True if need receive nodes metrics.
-             */
-            startTopologyListening: function (cb, onConnect, demo, attr, mtr) {
-                _modal.check = {
-                    url: '/api/v1/agent/topology',
-                    params: {demo: !!demo,  attr: !!attr, mtr: !!mtr},
-                    onConnect: onConnect,
-                    cb: cb
-                };
-
-                _modal.backState = 'base.configuration.clusters';
-
-                scope.agentGoal = 'execute sql statements';
-
-                scope.backText = 'Back to Configuration';
-
-                _startInterval();
-            },
-            /**
-             * Start awaiting agent start using ping.
-             *
-             * @param success Function to execute by timer when agent available.
-             */
-            awaitAgent: function (success) {
-                _modal.check = {
-                    url: '/api/v1/agent/ping',
-                    cb: success
-                };
-
-                _modal.backState = 'base.configuration.domains';
-
-                scope.agentGoal = 'import domain model from database schema';
-
-                scope.backText = 'Back to Domain models';
-
-                _startInterval(true);
-            },
-            /**
-             * Stop listening of agent by ping.
-             */
-            stopAwaitAgent: function () {
-                _stopInterval();
-            }
-        };
-    }]);
-
 // Navigation bar controller.
 consoleModule.controller('notebooks', ['$scope', '$modal', '$state', '$http', '$common',
     function ($scope, $modal, $state, $http, $common) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/controllers/domains-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/domains-controller.js b/modules/control-center-web/src/main/js/controllers/domains-controller.js
index 09a467a..0b88662 100644
--- a/modules/control-center-web/src/main/js/controllers/domains-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/domains-controller.js
@@ -17,8 +17,8 @@
 
 // Controller for Domain model screen.
 consoleModule.controller('domainsController', [
-    '$scope', '$http', '$state', '$filter', '$timeout', '$modal', '$common', '$focus', '$confirm', '$confirmBatch', '$clone', '$table', '$preview', '$loading', '$unsavedChangesGuard', '$agentDownload',
-    function ($scope, $http, $state, $filter, $timeout, $modal, $common, $focus, $confirm, $confirmBatch, $clone, $table, $preview, $loading, $unsavedChangesGuard, $agentDownload) {
+    '$scope', '$http', '$state', '$filter', '$timeout', '$modal', '$common', '$focus', '$confirm', '$confirmBatch', '$clone', '$table', '$preview', '$loading', '$unsavedChangesGuard', 'IgniteAgentMonitor',
+    function ($scope, $http, $state, $filter, $timeout, $modal, $common, $focus, $confirm, $confirmBatch, $clone, $table, $preview, $loading, $unsavedChangesGuard, IgniteAgentMonitor) {
         $unsavedChangesGuard.install($scope);
 
         $scope.ui = $common.formUI();
@@ -424,7 +424,7 @@ consoleModule.controller('domainsController', [
         var hideImportDomain = importDomainModal.hide;
 
         importDomainModal.hide = function () {
-            $agentDownload.stopAwaitAgent();
+            IgniteAgentMonitor.stopWatch();
 
             hideImportDomain();
         };
@@ -443,8 +443,8 @@ consoleModule.controller('domainsController', [
 
                 $scope.importDomain = {
                     demo: demo,
-                    action: 'drivers',
-                    jdbcDriversNotFound: false,
+                    action: demo ? 'connect' : 'drivers',
+                    jdbcDriversNotFound: demo,
                     schemas: [],
                     allSchemasSelected: false,
                     tables: [],
@@ -455,59 +455,45 @@ consoleModule.controller('domainsController', [
 
                 $scope.importDomain.loadingOptions = LOADING_JDBC_DRIVERS;
 
-                $agentDownload.awaitAgent(function (result, onSuccess, onException) {
-                    importDomainModal.$promise.then(importDomainModal.show);
+                IgniteAgentMonitor.startWatch({
+                        state: 'base.configuration.domains',
+                        text: 'Back to Domain models',
+                        goal: 'import domain model from database schema'
+                    })
+                    .then(function() {
+                        importDomainModal.$promise.then(importDomainModal.show);
+
+                        if (demo) {
+                            $scope.ui.packageNameUserInput = $scope.ui.packageName;
+                            $scope.ui.packageName = 'model';
+
+                            return;
+                        }
 
-                    // Get available JDBC drivers via agent.
-                    if ($scope.importDomain.action === 'drivers') {
+                        // Get available JDBC drivers via agent.
                         $loading.start('importDomainFromDb');
 
                         $scope.jdbcDriverJars = [];
                         $scope.ui.selectedJdbcDriverJar = {};
 
-                        $http.post('/api/v1/agent/drivers')
-                            .success(function (drivers) {
-                                onSuccess();
-
-                                if ($scope.importDomain.demo) {
-                                    $scope.ui.packageNamePrev = $scope.ui.packageName;
-                                    $scope.ui.packageName = 'model';
-                                }
-                                else if ($scope.ui.packageNamePrev) {
-                                    $scope.ui.packageName = $scope.ui.packageNamePrev;
-                                    $scope.ui.packageNamePrev = null;
-                                }
+                        return IgniteAgentMonitor.drivers()
+                            .then(function(drivers) {
+                                $scope.ui.packageName = $scope.ui.packageNameUserInput;
 
                                 if (drivers && drivers.length > 0) {
                                     drivers = _.sortBy(drivers, 'jdbcDriverJar');
 
-                                    if ($scope.importDomain.demo) {
-                                        var _h2DrvJar = _.find(drivers, function (drv) {
-                                            return drv.jdbcDriverJar.startsWith('h2');
-                                        });
-
-                                        if (_h2DrvJar) {
-                                            $scope.demoConnection.db = 'H2';
-                                            $scope.demoConnection.jdbcDriverJar = _h2DrvJar.jdbcDriverJar;
-                                        }
-                                        else {
-                                            $scope.demoConnection.db = 'General';
-                                            $scope.importDomain.button = 'Cancel';
-                                        }
-                                    }
-                                    else {
-                                        drivers.forEach(function (driver) {
-                                            $scope.jdbcDriverJars.push({
-                                                label: driver.jdbcDriverJar,
-                                                value: {
-                                                    jdbcDriverJar: driver.jdbcDriverJar,
-                                                    jdbcDriverClass: driver.jdbcDriverClass
-                                                }
-                                            });
+                                    drivers.forEach(function (drv) {
+                                        $scope.jdbcDriverJars.push({
+                                            label: drv.jdbcDriverJar,
+                                            value: {
+                                                jdbcDriverJar: drv.jdbcDriverJar,
+                                                jdbcDriverClass: drv.jdbcDriverCls
+                                            }
                                         });
+                                    });
 
-                                        $scope.ui.selectedJdbcDriverJar = $scope.jdbcDriverJars[0].value;
-                                    }
+                                    $scope.ui.selectedJdbcDriverJar = $scope.jdbcDriverJars[0].value;
 
                                     $common.confirmUnsavedChanges($scope.ui.isDirty(), function () {
                                         importDomainModal.$promise.then(function () {
@@ -524,16 +510,12 @@ consoleModule.controller('domainsController', [
                                     $scope.importDomain.button = 'Cancel';
                                 }
                             })
-                            .error(function (errMsg, status) {
-                                onException(errMsg, status);
-                            })
                             .finally(function () {
                                 $scope.importDomain.info = INFO_CONNECT_TO_DB;
 
                                 $loading.finish('importDomainFromDb');
                             });
-                    }
-                });
+                    })
             });
         };
 
@@ -541,15 +523,18 @@ consoleModule.controller('domainsController', [
          * Load list of database schemas.
          */
         function _loadSchemas() {
-            $loading.start('importDomainFromDb');
+            IgniteAgentMonitor.awaitAgent()
+                .then(function() {
+                    $loading.start('importDomainFromDb');
 
-            var preset = $scope.importDomain.demo ? $scope.demoConnection : $scope.selectedPreset;
+                    var preset = $scope.importDomain.demo ? $scope.demoConnection : $scope.selectedPreset;
 
-            if (!$scope.importDomain.demo)
-                _savePreset(preset);
+                    if (!$scope.importDomain.demo)
+                        _savePreset(preset);
 
-            $http.post('/api/v1/agent/schemas', preset)
-                .success(function (schemas) {
+                    return IgniteAgentMonitor.schemas(preset)
+                })
+                .then(function(schemas) {
                     $scope.importDomain.schemas = _.map(schemas, function (schema) {
                         return {use: false, name: schema};
                     });
@@ -566,7 +551,7 @@ consoleModule.controller('domainsController', [
                     $scope.importDomain.info = INFO_SELECT_SCHEMAS;
                     $scope.importDomain.loadingOptions = LOADING_TABLES;
                 })
-                .error(function (errMsg) {
+                .catch(function(errMsg) {
                     $common.showError(errMsg);
                 })
                 .finally(function () {
@@ -611,21 +596,24 @@ consoleModule.controller('domainsController', [
          * Load list of database tables.
          */
         function _loadTables() {
-            $loading.start('importDomainFromDb');
+            IgniteAgentMonitor.awaitAgent()
+                .then(function() {
+                    $loading.start('importDomainFromDb');
 
-            $scope.importDomain.allTablesSelected = false;
+                    $scope.importDomain.allTablesSelected = false;
 
-            var preset = $scope.importDomain.demo ? $scope.demoConnection : $scope.selectedPreset;
+                    var preset = $scope.importDomain.demo ? $scope.demoConnection : $scope.selectedPreset;
 
-            preset.schemas = [];
+                    preset.schemas = [];
 
-            _.forEach($scope.importDomain.schemas, function (schema) {
-                if (schema.use)
-                    preset.schemas.push(schema.name);
-            });
+                    _.forEach($scope.importDomain.schemas, function (schema) {
+                        if (schema.use)
+                            preset.schemas.push(schema.name);
+                    });
 
-            $http.post('/api/v1/agent/tables', preset)
-                .success(function (tables) {
+                    return IgniteAgentMonitor.tables(preset);
+                })
+                .then(function (tables) {
                     _importCachesOrTemplates = [DFLT_PARTITIONED_CACHE, DFLT_REPLICATED_CACHE].concat($scope.caches);
 
                     _fillCommonCachesOrTemplates($scope.importCommon)($scope.importCommon.action);
@@ -646,7 +634,7 @@ consoleModule.controller('domainsController', [
                     $scope.importDomain.tables = tables;
                     $scope.importDomain.info = INFO_SELECT_TABLES;
                 })
-                .error(function (errMsg) {
+                .catch(function(errMsg) {
                     $common.showError(errMsg);
                 })
                 .finally(function () {
@@ -989,7 +977,8 @@ consoleModule.controller('domainsController', [
                             _saveBatch(_.filter(batch, function (item) {
                                 return !item.skip;
                             }));
-                        }, function () {
+                        })
+                        .catch(function () {
                             $common.showError('Importing of domain models interrupted by user.');
                         });
                 else
@@ -1014,12 +1003,8 @@ consoleModule.controller('domainsController', [
 
             if (act === 'drivers' && $scope.importDomain.jdbcDriversNotFound)
                 importDomainModal.hide();
-            else if (act === 'connect') {
-                if ($scope.importDomain.demo && $scope.demoConnection.db !== 'H2')
-                    importDomainModal.hide();
-                else
-                    _loadSchemas();
-            }
+            else if (act === 'connect')
+                _loadSchemas();
             else if (act === 'schemas')
                 _loadTables();
             else if (act === 'tables')
@@ -1036,13 +1021,8 @@ consoleModule.controller('domainsController', [
             if (act === 'drivers' && $scope.importDomain.jdbcDriversNotFound)
                 return 'Resolve issue with JDBC drivers<br>Close this dialog and try again';
 
-            if (act === 'connect') {
-                if ($scope.importDomain.demo && $scope.demoConnection.db !== 'H2')
-                    return 'Resolve issue with H2 database driver<br>Close this dialog and try again';
-
-                if (importDomainNextAvailable)
-                    return 'Click to load list of schemas from database';
-            }
+            if (act === 'connect' || act === 'drivers')
+                return 'Click to load list of schemas from database';
 
             if (act === 'schemas')
                 return importDomainNextAvailable ? 'Click to load list of tables from database' : 'Select schemas to continue';


[19/50] [abbrv] ignite git commit: IGNITE-2676 Minor refactoring.

Posted by an...@apache.org.
IGNITE-2676 Minor refactoring.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/767a2ebf
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/767a2ebf
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/767a2ebf

Branch: refs/heads/ignite-2875
Commit: 767a2ebf42b320eff30415eed6a50e23356e60b3
Parents: b30b52b
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Mon Mar 21 16:09:32 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Mar 21 16:09:32 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/app/decorator/select.js               | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/767a2ebf/modules/control-center-web/src/main/js/app/decorator/select.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/decorator/select.js b/modules/control-center-web/src/main/js/app/decorator/select.js
index 13a4041..9a6d07b 100644
--- a/modules/control-center-web/src/main/js/app/decorator/select.js
+++ b/modules/control-center-web/src/main/js/app/decorator/select.js
@@ -24,14 +24,14 @@ import angular from 'angular';
 angular.module('mgcrea.ngStrap.select')
     .decorator('$select', ($delegate) => {
         function SelectFactoryDecorated(element, controller, config) {
-            const deligate = $delegate(element, controller, config);
+            const delegate = $delegate(element, controller, config);
 
             // Common vars.
             const options = angular.extend({}, $delegate.defaults, config);
 
-            const scope = deligate.$scope;
+            const scope = delegate.$scope;
 
-            const _valueMap = (index) => {
+            const valueByIndex = (index) => {
                 if (angular.isUndefined(scope.$matches[index]))
                     return null;
 
@@ -46,9 +46,9 @@ angular.module('mgcrea.ngStrap.select')
                         if (scope.$isActive(i) === active) {
                             selected[i] = scope.$matches[i].value;
 
-                            deligate.activate(i);
+                            delegate.activate(i);
 
-                            controller.$setViewValue(scope.$activeIndex.map(_valueMap));
+                            controller.$setViewValue(scope.$activeIndex.map(valueByIndex));
                         }
                     }
                 });
@@ -56,7 +56,7 @@ angular.module('mgcrea.ngStrap.select')
                 // Emit events.
                 for (let i = 0; i < selected.length; i++) {
                     if (selected[i])
-                        scope.$emit(options.prefixEvent + '.select', selected[i], i, deligate);
+                        scope.$emit(options.prefixEvent + '.select', selected[i], i, delegate);
                 }
             };
 
@@ -68,7 +68,7 @@ angular.module('mgcrea.ngStrap.select')
                 scope.$$postDigest(selectAll.bind(this, true));
             };
 
-            return deligate;
+            return delegate;
         }
 
         SelectFactoryDecorated.defaults = $delegate.defaults;


[48/50] [abbrv] ignite git commit: IGNITE-2875 WIP

Posted by an...@apache.org.
IGNITE-2875 WIP


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/84f7557c
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/84f7557c
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/84f7557c

Branch: refs/heads/ignite-2875
Commit: 84f7557c5249f19ffa950512ec39c04a860c6604
Parents: 4f6e72e
Author: Andrey <an...@gridgain.com>
Authored: Mon Mar 28 08:41:42 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 28 08:41:42 2016 +0700

----------------------------------------------------------------------
 .../js/app/services/AgentMonitor.service.js     |  4 +-
 .../src/main/js/controllers/sql-controller.js   | 41 ++++++++-------
 .../src/main/js/serve/agent.js                  | 38 +++++++++-----
 .../src/main/js/serve/browser.js                | 52 +++++++++++---------
 4 files changed, 78 insertions(+), 57 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/84f7557c/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js b/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
index 364e1db..590d72f 100644
--- a/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
+++ b/modules/control-center-web/src/main/js/app/services/AgentMonitor.service.js
@@ -225,10 +225,10 @@ class IgniteAgentMonitor {
 
                 return res;
             })
-            .catch((errMsg) => {
+            .catch((err) => {
                 this._downloadAgentModal.show();
 
-                return this._$q.reject(errMsg);
+                return this._$q.reject(err);
             });
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/84f7557c/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
index abae869..63dd31d 100644
--- a/modules/control-center-web/src/main/js/controllers/sql-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -257,7 +257,7 @@ consoleModule.controller('sqlController', [
         var _refreshFn = function() {
             IgniteAgentMonitor.topology($scope.demo)
                 .then(function(clusters) {
-                    var caches = _.flattenDeep(clusters.map(function (cluster) { return cluster._caches; }));
+                    var caches = _.flattenDeep(clusters.map(function (cluster) { return cluster.caches; }));
 
                     $scope.caches = _.sortBy(_.uniq(_.reject(caches, { mode: 'LOCAL' }), function (cache) {
                         return _mask(cache.name);
@@ -831,7 +831,7 @@ consoleModule.controller('sqlController', [
 
                     _showLoading(paragraph, false);
 
-                    if (res.last)
+                    if (res.queryId === null)
                         delete paragraph.queryId;
                 })
                 .catch(function (errMsg) {
@@ -1502,28 +1502,31 @@ consoleModule.controller('sqlController', [
 
             $scope.metadata = [];
 
-        IgniteAgentMonitor.metadata($scope.demo)
-            .then(function (metadata) {
-                $scope.metadata = _.sortBy(_.filter(metadata, function (meta) {
-                    var cache = _.find($scope.caches, { name: meta.cacheName });
+            IgniteAgentMonitor.metadata($scope.demo)
+                .then(function (metadata) {
+                    $scope.metadata = _.sortBy(_.filter(metadata, function (meta) {
+                        var cache = _.find($scope.caches, { name: meta.cacheName });
 
-                        if (cache) {
-                            meta.name = (cache.sqlSchema ? cache.sqlSchema : '"' + meta.cacheName + '"') + '.' + meta.typeName;
+                            if (cache) {
+                                meta.name = (cache.sqlSchema ? cache.sqlSchema : '"' + meta.cacheName + '"') + '.' + meta.typeName;
 
-                            meta.displayMame = _mask(meta.cacheName) + '.' + meta.typeName;
+                                meta.displayMame = _mask(meta.cacheName) + '.' + meta.typeName;
 
-                            if (cache.sqlSchema)
-                                meta.children.unshift({type: 'plain', name: 'sqlSchema: ' + cache.sqlSchema});
+                                if (cache.sqlSchema)
+                                    meta.children.unshift({type: 'plain', name: 'sqlSchema: ' + cache.sqlSchema});
 
-                            meta.children.unshift({type: 'plain', name: 'mode: ' + cache.mode});
-                        }
+                                meta.children.unshift({type: 'plain', name: 'mode: ' + cache.mode});
+                            }
 
-                    return cache;
-                }), 'name');
-            })
-            .finally(function () {
-                $loading.finish('loadingCacheMetadata');
-            });
+                        return cache;
+                    }), 'name');
+                })
+                .catch(function (err) {
+                    console.log(err);
+                })
+                .finally(function () {
+                    $loading.finish('loadingCacheMetadata');
+                });
         };
 
         $scope.showResultQuery = function (paragraph) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/84f7557c/modules/control-center-web/src/main/js/serve/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/agent.js b/modules/control-center-web/src/main/js/serve/agent.js
index 2966d5c..ce04482 100644
--- a/modules/control-center-web/src/main/js/serve/agent.js
+++ b/modules/control-center-web/src/main/js/serve/agent.js
@@ -140,7 +140,7 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
         executeRest(cmd) {
             const params = {cmd: cmd._name};
 
-            for (const param of this._params)
+            for (const param of cmd._params)
                 params[param.key] = param.value;
 
             return new Promise((resolve, reject) => {
@@ -216,7 +216,7 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
                 .addParam('attr', attr !== false)
                 .addParam('mtr', !!mtr);
 
-            this.executeRest(cmd);
+            return this.executeRest(cmd);
         }
 
         /**
@@ -226,12 +226,10 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
          * @private
          */
         static _onQueryResult(res) {
-            const queryId = res === null && res["last"] ? null : queryId;
-
             return {
-                meta: res['fieldsMetadata'],
-                rows: res['items'],
-                queryId
+                meta: res.fieldsMetadata,
+                rows: res.items,
+                queryId: res.last ? null : res.queryId
             }
         }
 
@@ -246,11 +244,11 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
         fieldsQuery(demo, cacheName, query, pageSize) {
             var cmd = new Command(demo, 'qryfldexe')
                 .addParam('cacheName', cacheName)
-                .addParam('query', query)
+                .addParam('qry', query)
                 .addParam('pageSize', pageSize);
 
-            this.executeRest(cmd)
-                .then(this._onQueryResult);
+            return this.executeRest(cmd)
+                .then(Agent._onQueryResult);
         }
 
         /**
@@ -265,8 +263,24 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, apacheIgnite
                 .addParam('cacheName', cacheName)
                 .addParam('pageSize', pageSize);
 
-            this.executeRest(cmd)
-                .then(this._onQueryResult);
+            return this.executeRest(cmd)
+                .then(Agent._onQueryResult);
+        }
+
+
+        /**
+         * @param {Boolean} demo Is need run command on demo node.
+         * @param {int} queryId Query Id.
+         * @param {int} pageSize Page size.
+         * @returns {Promise}
+         */
+        queryFetch(demo, queryId, pageSize) {
+            var cmd = new Command(demo, 'qryfetch')
+                .addParam('qryId', queryId)
+                .addParam('pageSize', pageSize);
+
+            return this.executeRest(cmd)
+                .then(Agent._onQueryResult);
         }
 
         /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/84f7557c/modules/control-center-web/src/main/js/serve/browser.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/browser.js b/modules/control-center-web/src/main/js/serve/browser.js
index 465f75f..c269d7d 100644
--- a/modules/control-center-web/src/main/js/serve/browser.js
+++ b/modules/control-center-web/src/main/js/serve/browser.js
@@ -78,7 +78,7 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                     agentMgr.findAgent(user._id)
                         .then((agent) => agent.topology(demo, attr, mtr))
                         .then((clusters) => cb(null, clusters))
-                        .catch((errMsg) => cb(errMsg));
+                        .catch((err) => cb(err));
                 });
 
                 // Close query on node.
@@ -90,7 +90,7 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                             return cache.__createPromise(cache._createCommand('qrycls').addParam('qryId', args.queryId));
                         })
                         .then(() => cb())
-                        .catch((errMsg) => cb(errMsg));
+                        .catch((err) => cb(err));
                 });
 
                 // Execute query on node and return first page to browser.
@@ -103,43 +103,47 @@ module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
                             return agent.fieldsQuery(args.demo, args.cacheName, args.query, args.pageSize);
                         })
                         .then((res) => cb(null, res))
-                        .catch((errMsg) => cb(errMsg));
+                        .catch((err) => cb(err));
                 });
 
                 // Fetch next page for query and return result to browser.
                 socket.on('node:query:fetch', (args, cb) => {
                     agentMgr.findAgent(user._id)
-                        .then((agent) => {
-                            const cache = agent.ignite(args.demo).cache(args.cacheName);
-
-                            const cmd = cache._createCommand('qryfetch')
-                                .addParam('qryId', args.queryId)
-                                .addParam('pageSize', args.pageSize);
-
-                            return cache.__createPromise(cmd);
-                        })
-                        .then((page) => cb(null, {
-                            rows: page.items,
-                            last: page === null || page.last
-                        }))
-                        .catch((errMsg) => cb(errMsg));
+                        .then((agent) => agent.queryFetch(args.demo, args.queryId, args.pageSize))
+                        .then((res) => cb(null, res))
+                        .catch((err) => cb(err));
                 });
 
                 // Execute query on node and return full result to browser.
                 socket.on('node:query:getAll', (args, cb) => {
+                    // Set page size for query.
+                    const pageSize = 1024;
+
                     agentMgr.findAgent(user._id)
                         .then((agent) => {
-                            // Create sql query.
-                            const qry = args.type === 'SCAN' ? new ScanQuery() : new SqlFieldsQuery(args.query);
+                            if (args.type === 'SCAN')
+                                return agent.scan(args.demo, args.cacheName, pageSize);
+
+                            return agent.fieldsQuery(args.demo, args.cacheName, args.query, pageSize);
+                        })
+                        .then((res) => {
+                            const fetchResult = (fullRes) => {
+                                if (fullRes.last)
+                                    return fullRes;
+
+                                return agent.queryFetch(args.demo, args.queryId, pageSize)
+                                    .then((res) => {
+                                        fullRes.rows = fullRes.rows.concat(res.rows);
 
-                            // Set page size for query.
-                            qry.setPageSize(1024);
+                                        fullRes.last = res.last;
 
-                            const cursor = agent.ignite(args.demo).cache(args.cacheName).query(qry);
+                                        return fetchResult(fullRes);
+                                    })
+                            };
 
-                            return cursor.getAll()
-                                .then((rows) => cb(null, {meta: cursor.fieldsMetadata(), rows}));
+                            return fetchResult(res);
                         })
+                        .then((res) => cb(null, res))
                         .catch((errMsg) => cb(errMsg));
                 });
 


[43/50] [abbrv] ignite git commit: IGNITE-843 Dropdown should be disabled if no options provided.

Posted by an...@apache.org.
 IGNITE-843 Dropdown should be disabled if no options provided.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e1a5dad7
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e1a5dad7
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e1a5dad7

Branch: refs/heads/ignite-2875
Commit: e1a5dad7c51601d7aa88d362bffbef29f1ef5d8c
Parents: e7dd846
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Mar 25 14:29:03 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Mar 25 14:29:03 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/app/modules/form/field/dropdown.jade             | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e1a5dad7/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.jade b/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.jade
index db607a1..fd8456c 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.jade
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/dropdown.jade
@@ -26,7 +26,7 @@
         data-multiple='1'
 
         ng-model='dropdown.value'
-        ng-disabled='dropdown.ngDisabled'
+        ng-disabled='dropdown.ngDisabled || !dropdown.options || !dropdown.options.length'
 
         data-ng-required='required || false'
 
@@ -45,7 +45,7 @@
         bs-options='item.value as item.label for item in dropdown.options' 
 
         ng-model='dropdown.value'
-        ng-disabled='dropdown.ngDisabled'
+        ng-disabled='dropdown.ngDisabled || !dropdown.options || !dropdown.options.length'
 
         data-ng-required='required || false'
 


[07/50] [abbrv] ignite git commit: IGNITE-2597 Refactored to websockets.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
index 8336afd..dd712f8 100644
--- a/modules/control-center-web/src/main/js/controllers/sql-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -17,15 +17,18 @@
 
 // Controller for SQL notebook screen.
 consoleModule.controller('sqlController', [
-    '$scope', '$http', '$timeout', '$interval', '$animate', '$location', '$anchorScroll', '$state', '$modal', '$popover', '$loading', '$common', '$confirm', '$agentDownload', 'QueryNotebooks', 'uiGridExporterConstants',
-    function ($scope, $http, $timeout, $interval, $animate, $location, $anchorScroll, $state, $modal, $popover, $loading, $common, $confirm, $agentDownload, QueryNotebooks, uiGridExporterConstants) {
+    '$scope', '$http', '$timeout', '$interval', '$animate', '$location', '$anchorScroll', '$state', '$modal', '$popover', '$loading', '$common', '$confirm', 'IgniteAgentMonitor', 'IgniteChartColors', 'QueryNotebooks', 'uiGridExporterConstants',
+    function ($scope, $http, $timeout, $interval, $animate, $location, $anchorScroll, $state, $modal, $popover, $loading, $common, $confirm, IgniteAgentMonitor, IgniteChartColors, QueryNotebooks, uiGridExporterConstants) {
+
+        var stopTopology = null;
+
         $scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
+            $interval.cancel(stopTopology);
+
             if ($scope.notebook && $scope.notebook.paragraphs)
                 $scope.notebook.paragraphs.forEach(function (paragraph) {
                     _tryStopRefresh(paragraph);
                 });
-
-            $agentDownload.stopAwaitAgent();
         });
 
         $scope.joinTip = $common.joinTip;
@@ -84,17 +87,12 @@ consoleModule.controller('sqlController', [
         // We need max 1800 items to hold history for 30 mins in case of refresh every second.
         var HISTORY_LENGTH = 1800;
 
-        var CHART_COLORS = [
-            '#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf',
-            '#ffbb78', '#98df8a', '#ff9896', '#c5b0d5', '#aec7e8', '#c49c94', '#f7b6d2', '#c7c7c7', '#dbdb8d', '#9edae5'
-        ];
-
-        var MAX_VAL_COLS = CHART_COLORS.length;
+        var MAX_VAL_COLS = IgniteChartColors.length;
 
         $anchorScroll.yOffset = 55;
 
         $scope.chartColor = function(index) {
-            return {"color": "white", "background-color": CHART_COLORS[index]};
+            return {"color": "white", "background-color": IgniteChartColors[index]};
         };
 
         $scope.chartRemoveKeyColumn = function (paragraph, index) {
@@ -256,6 +254,23 @@ consoleModule.controller('sqlController', [
                 });
         };
 
+        var _refreshFn = function() {
+            IgniteAgentMonitor.topology($scope.demo)
+                .then(function(clusters) {
+                    var caches = _.flattenDeep(clusters.map(function (cluster) { return cluster._caches; }));
+
+                    $scope.caches = _.sortBy(_.uniq(_.reject(caches, { mode: 'LOCAL' }), function (cache) {
+                        return _mask(cache.name);
+                    }), 'name');
+
+                    _setActiveCache();
+                })
+                .catch(_handleException)
+                .finally(function() {
+                    $loading.finish('loading');
+                });
+        };
+
         var loadNotebook = function (notebook) {
             $scope.notebook = notebook;
 
@@ -278,14 +293,28 @@ consoleModule.controller('sqlController', [
             else
                 $scope.rebuildScrollParagraphs();
 
-            $agentDownload.startTopologyListening(getTopology, _onConnect, $scope.demo);
-        };
+            IgniteAgentMonitor.startWatch({
+                    state: 'base.configuration.clusters',
+                    text: 'Back to Configuration',
+                    goal: 'execute sql statements'
+                }, function () {
+                    $state.go('base.sql.demo');
+                })
+                .then(function () {
+                    $loading.start('loading');
 
-        $loading.start('loading');
+                    _refreshFn();
+
+                    if ($scope.demo)
+                        _.forEach($scope.notebook.paragraphs, $scope.execute);
+
+                    stopTopology = $interval(_refreshFn, 5000, 0, false);
+                });
+        };
 
         QueryNotebooks.read($scope.demo, $state.params.noteId)
             .then(loadNotebook)
-            .catch(function(err) {
+            .catch(function() {
                 $scope.notebookLoadFailed = true;
 
                 $loading.finish('loading');
@@ -329,9 +358,7 @@ consoleModule.controller('sqlController', [
                     else
                         $state.go('base.configuration.clusters');
                 })
-                .catch(function (errMsg) {
-                    $common.showError(errMsg);
-                });
+                .catch(_handleException);
         };
 
         $scope.renameParagraph = function (paragraph, newName) {
@@ -441,27 +468,6 @@ consoleModule.controller('sqlController', [
             return panel_idx >= 0;
         };
 
-        function getTopology(clusters, onSuccess) {
-            onSuccess();
-
-            var caches = _.flattenDeep(clusters.map(function (cluster) { return cluster._caches; }));
-
-            $scope.caches = _.sortBy(_.uniq(_.reject(caches, { mode: 'LOCAL' }), function (cache) {
-                return _mask(cache.name);
-            }), 'name');
-
-            _setActiveCache();
-
-            $loading.finish('loading');
-        }
-
-        function _onConnect() {
-            if (!$scope.demo)
-                return;
-
-            _.forEach($scope.notebook.paragraphs, $scope.execute);
-        }
-
         var _columnFilter = function(paragraph) {
             return paragraph.disabledSystemColumns || paragraph.systemColumns ? _allColumn : _hideColumn;
         };
@@ -579,116 +585,113 @@ consoleModule.controller('sqlController', [
             return retainedCols;
         }
 
-        var _tryCloseQueryResult = function (queryId) {
-            if (queryId)
-                $http.post('/api/v1/agent/query/close', { demo: $scope.demo, queryId: queryId });
-        };
-
-        var _processQueryResult = function (paragraph, refreshMode) {
-            return function (res) {
-                var prevKeyCols = paragraph.chartKeyCols;
-                var prevValCols = paragraph.chartValCols;
+        var _processQueryResult = function (paragraph, res) {
+            var prevKeyCols = paragraph.chartKeyCols;
+            var prevValCols = paragraph.chartValCols;
 
-                if (res.meta && !refreshMode) {
-                    paragraph.meta = [];
+            if (!_.eq(paragraph.meta, res.meta)) {
+                paragraph.meta = [];
 
-                    paragraph.chartColumns = [];
+                paragraph.chartColumns = [];
 
-                    if (!$common.isDefined(paragraph.chartKeyCols))
-                        paragraph.chartKeyCols = [];
+                if (!$common.isDefined(paragraph.chartKeyCols))
+                    paragraph.chartKeyCols = [];
 
-                    if (!$common.isDefined(paragraph.chartValCols))
-                        paragraph.chartValCols = [];
+                if (!$common.isDefined(paragraph.chartValCols))
+                    paragraph.chartValCols = [];
 
-                    if (res.meta.length <= 2) {
-                        var _key = _.find(res.meta, {fieldName: '_KEY'});
-                        var _val = _.find(res.meta, {fieldName: '_VAL'});
+                if (res.meta.length <= 2) {
+                    var _key = _.find(res.meta, {fieldName: '_KEY'});
+                    var _val = _.find(res.meta, {fieldName: '_VAL'});
 
-                        paragraph.disabledSystemColumns = (res.meta.length == 2 && _key && _val) ||
-                            (res.meta.length == 1 && (_key || _val));
-                    }
+                    paragraph.disabledSystemColumns = (res.meta.length == 2 && _key && _val) ||
+                        (res.meta.length == 1 && (_key || _val));
+                }
 
-                    paragraph.columnFilter = _columnFilter(paragraph);
+                paragraph.columnFilter = _columnFilter(paragraph);
 
-                    paragraph.meta = res.meta;
+                paragraph.meta = res.meta;
 
-                    _rebuildColumns(paragraph);
-                }
+                _rebuildColumns(paragraph);
+            }
 
-                paragraph.page = 1;
+            paragraph.page = 1;
 
-                paragraph.total = 0;
+            paragraph.total = 0;
 
-                paragraph.queryId = res.queryId;
+            paragraph.queryId = res.queryId;
 
-                delete paragraph.errMsg;
+            delete paragraph.errMsg;
 
-                // Prepare explain results for display in table.
-                if (paragraph.queryArgs.type == "EXPLAIN" && res.rows) {
-                    paragraph.rows = [];
+            // Prepare explain results for display in table.
+            if (paragraph.queryArgs.type == "EXPLAIN" && res.rows) {
+                paragraph.rows = [];
 
-                    res.rows.forEach(function (row, i) {
-                        var line = res.rows.length - 1 == i ? row[0] : row[0] + '\n';
+                res.rows.forEach(function (row, i) {
+                    var line = res.rows.length - 1 == i ? row[0] : row[0] + '\n';
 
-                        line.replace(/\"/g, '').split('\n').forEach(function (line) {
-                            paragraph.rows.push([line]);
-                        });
+                    line.replace(/\"/g, '').split('\n').forEach(function (line) {
+                        paragraph.rows.push([line]);
                     });
-                }
-                else
-                    paragraph.rows = res.rows;
-
-                paragraph.gridOptions.setRows(paragraph.rows);
+                });
+            }
+            else
+                paragraph.rows = res.rows;
 
-                var chartHistory = paragraph.chartHistory;
+            paragraph.gridOptions.setRows(paragraph.rows);
 
-                // Clear history on query change.
-                var queryChanged = paragraph.prevQuery != paragraph.query;
+            var chartHistory = paragraph.chartHistory;
 
-                if (queryChanged) {
-                    paragraph.prevQuery = paragraph.query;
+            // Clear history on query change.
+            var queryChanged = paragraph.prevQuery != paragraph.query;
 
-                    chartHistory.length = 0;
+            if (queryChanged) {
+                paragraph.prevQuery = paragraph.query;
 
-                    _.forEach(paragraph.charts, function (chart) {
-                        chart.data.length = 0;
-                    })
-                }
+                chartHistory.length = 0;
 
-                // Add results to history.
-                chartHistory.push({tm: new Date(), rows: paragraph.rows});
+                _.forEach(paragraph.charts, function (chart) {
+                    chart.data.length = 0;
+                })
+            }
 
-                // Keep history size no more than max length.
-                while (chartHistory.length > HISTORY_LENGTH)
-                    chartHistory.shift();
+            // Add results to history.
+            chartHistory.push({tm: new Date(), rows: paragraph.rows});
 
-                _showLoading(paragraph, false);
+            // Keep history size no more than max length.
+            while (chartHistory.length > HISTORY_LENGTH)
+                chartHistory.shift();
 
-                if (paragraph.result == 'none' || paragraph.queryArgs.type != "QUERY")
-                    paragraph.result = 'table';
-                else if (paragraph.chart()) {
-                    var resetCharts = queryChanged;
+            _showLoading(paragraph, false);
 
-                    if (!resetCharts) {
-                        var curKeyCols = paragraph.chartKeyCols;
-                        var curValCols = paragraph.chartValCols;
+            if (paragraph.result == 'none' || paragraph.queryArgs.type != "QUERY")
+                paragraph.result = 'table';
+            else if (paragraph.chart()) {
+                var resetCharts = queryChanged;
 
-                        resetCharts = !prevKeyCols || !prevValCols ||
-                            prevKeyCols.length != curKeyCols.length ||
-                            prevValCols.length != curValCols.length;
-                    }
+                if (!resetCharts) {
+                    var curKeyCols = paragraph.chartKeyCols;
+                    var curValCols = paragraph.chartValCols;
 
-                    _chartApplySettings(paragraph, resetCharts);
+                    resetCharts = !prevKeyCols || !prevValCols ||
+                        prevKeyCols.length != curKeyCols.length ||
+                        prevValCols.length != curValCols.length;
                 }
+
+                _chartApplySettings(paragraph, resetCharts);
             }
         };
 
         var _executeRefresh = function (paragraph) {
-            _tryCloseQueryResult(paragraph.queryId);
-
-            $http.post('/api/v1/agent/query', paragraph.queryArgs)
-                .success(_processQueryResult(paragraph, true))
-                .error(function (errMsg) {
+            IgniteAgentMonitor.awaitAgent()
+                .then(function () {
+                    return IgniteAgentMonitor.queryClose(paragraph.queryArgs);
+                })
+                .then(function () {
+                    return IgniteAgentMonitor.query(paragraph.queryArgs);
+                })
+                .then(_processQueryResult.bind(this, paragraph))
+                .catch(function (errMsg) {
                     paragraph.errMsg = errMsg;
                 });
         };
@@ -705,31 +708,33 @@ consoleModule.controller('sqlController', [
 
             _showLoading(paragraph, true);
 
-            _tryCloseQueryResult(paragraph.queryId);
-
-            paragraph.queryArgs = {
-                demo: $scope.demo,
-                type: "QUERY",
-                query: paragraph.query,
-                pageSize: paragraph.pageSize,
-                cacheName: paragraph.cacheName || undefined
-            };
-
-            $http.post('/api/v1/agent/query', paragraph.queryArgs)
-                .success(function (res) {
-                    _processQueryResult(paragraph)(res);
+            IgniteAgentMonitor.queryClose(paragraph.queryArgs)
+                .then(function () {
+                    paragraph.queryArgs = {
+                        demo: $scope.demo,
+                        type: "QUERY",
+                        query: paragraph.query,
+                        pageSize: paragraph.pageSize,
+                        cacheName: paragraph.cacheName || undefined
+                    };
+
+                    return IgniteAgentMonitor.query(paragraph.queryArgs);
+                })
+                .then(function (res) {
+                    _processQueryResult(paragraph, res);
 
                     _tryStartRefresh(paragraph);
                 })
-                .error(function (errMsg) {
+                .catch(function (errMsg) {
                     paragraph.errMsg = errMsg;
 
-                    _showLoading(paragraph, false);
+                        _showLoading(paragraph, false);
 
                     $scope.stopRefresh(paragraph);
+                })
+                .finally(function () {
+                    paragraph.ace.focus();
                 });
-
-            paragraph.ace.focus();
         };
 
         $scope.queryExecuted = function(paragraph) {
@@ -744,25 +749,27 @@ consoleModule.controller('sqlController', [
 
             _showLoading(paragraph, true);
 
-            _tryCloseQueryResult(paragraph.queryId);
-
-            paragraph.queryArgs = {
-                demo: $scope.demo,
-                type: "EXPLAIN",
-                query: 'EXPLAIN ' + paragraph.query,
-                pageSize: paragraph.pageSize,
-                cacheName: paragraph.cacheName || undefined
-            };
-
-            $http.post('/api/v1/agent/query', paragraph.queryArgs)
-                .success(_processQueryResult(paragraph))
-                .error(function (errMsg) {
+            IgniteAgentMonitor.queryClose(paragraph.queryArgs)
+                .then(function () {
+                    paragraph.queryArgs = {
+                        demo: $scope.demo,
+                        type: "EXPLAIN",
+                        query: 'EXPLAIN ' + paragraph.query,
+                        pageSize: paragraph.pageSize,
+                        cacheName: paragraph.cacheName || undefined
+                    };
+
+                    return IgniteAgentMonitor.query(paragraph.queryArgs);
+                })
+                .then(_processQueryResult.bind(this, paragraph))
+                .catch(function (errMsg) {
                     paragraph.errMsg = errMsg;
 
                     _showLoading(paragraph, false);
+                })
+                .finally(function () {
+                    paragraph.ace.focus();
                 });
-
-            paragraph.ace.focus();
         };
 
         $scope.scan = function (paragraph) {
@@ -773,36 +780,40 @@ consoleModule.controller('sqlController', [
 
             _showLoading(paragraph, true);
 
-            _tryCloseQueryResult(paragraph.queryId);
-
-            paragraph.queryArgs = {
-                demo: $scope.demo,
-                type: "SCAN",
-                pageSize: paragraph.pageSize,
-                cacheName: paragraph.cacheName || undefined
-            };
-
-            $http.post('/api/v1/agent/scan', paragraph.queryArgs)
-                .success(_processQueryResult(paragraph))
-                .error(function (errMsg) {
+            IgniteAgentMonitor.queryClose(paragraph.queryArgs)
+                .then(function () {
+                    paragraph.queryArgs = {
+                        demo: $scope.demo,
+                        type: "SCAN",
+                        pageSize: paragraph.pageSize,
+                        cacheName: paragraph.cacheName || undefined
+                    };
+
+                    return IgniteAgentMonitor.query(paragraph.queryArgs);
+                })
+                .then(_processQueryResult.bind(this, paragraph))
+                .catch(function (errMsg) {
                     paragraph.errMsg = errMsg;
 
                     _showLoading(paragraph, false);
+                })
+                .finally(function () {
+                    paragraph.ace.focus();
                 });
-
-            paragraph.ace.focus();
         };
 
         $scope.nextPage = function(paragraph) {
             _showLoading(paragraph, true);
 
-            $http.post('/api/v1/agent/query/fetch', {
-                    demo: $scope.demo,
-                    queryId: paragraph.queryId,
-                    pageSize: paragraph.pageSize,
-                    cacheName: paragraph.queryArgs.cacheName
-                })
-                .success(function (res) {
+            paragraph.queryArgs = {
+                demo: $scope.demo,
+                queryId: paragraph.queryId,
+                pageSize: paragraph.pageSize,
+                cacheName: paragraph.queryArgs.cacheName
+            };
+
+            IgniteAgentMonitor.next(paragraph.queryArgs)
+                .then(function (res) {
                     paragraph.page++;
 
                     paragraph.total += paragraph.rows.length;
@@ -823,10 +834,13 @@ consoleModule.controller('sqlController', [
                     if (res.last)
                         delete paragraph.queryId;
                 })
-                .error(function (errMsg) {
+                .catch(function (errMsg) {
                     paragraph.errMsg = errMsg;
 
                     _showLoading(paragraph, false);
+                })
+                .finally(function () {
+                    paragraph.ace.focus();
                 });
         };
 
@@ -887,17 +901,18 @@ consoleModule.controller('sqlController', [
             paragraph.gridOptions.api.exporter.pdfExport(uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE);
         };
 
-        $scope.exportCsvAll = function(paragraph) {
-            $http.post('/api/v1/agent/query/getAll', {
+        $scope.exportCsvAll = function (paragraph) {
+            IgniteAgentMonitor.query({
                     demo: $scope.demo,
+                    type: paragraph.queryArgs.type,
                     query: paragraph.queryArgs.query,
                     cacheName: paragraph.queryArgs.cacheName
                 })
-                .success(function (response) {
-                    _export(paragraph.name + '-all.csv', response.meta, response.rows);
+                .then(function (res) {
+                    _export(paragraph.name + '-all.csv', res.meta, res.rows);
                 })
-                .error(function (errMsg) {
-                    $common.showError(errMsg);
+                .finally(function () {
+                    paragraph.ace.focus();
                 });
         };
 
@@ -1337,7 +1352,7 @@ consoleModule.controller('sqlController', [
                             axisLabel:  _yAxisLabel(paragraph),
                             tickFormat: _yAxisFormat
                         },
-                        color: CHART_COLORS,
+                        color: IgniteChartColors,
                         stacked: stacked,
                         showControls: true
                     }
@@ -1405,7 +1420,7 @@ consoleModule.controller('sqlController', [
                             axisLabel:  _yAxisLabel(paragraph),
                             tickFormat: _yAxisFormat
                         },
-                        color: CHART_COLORS,
+                        color: IgniteChartColors,
                         useInteractiveGuideline: true
                     }
                 };
@@ -1426,27 +1441,27 @@ consoleModule.controller('sqlController', [
                     ? paragraph.chartsOptions.areaChart.style
                     : 'stack';
 
-                var options = {
-                    chart: {
-                        type: 'stackedAreaChart',
-                        height: 400,
-                        margin: {left: 70},
-                        duration: 0,
-                        x: _xX,
-                        y: _yY,
-                        xAxis: {
-                            axisLabel: _xAxisLabel(paragraph),
-                            tickFormat: paragraph.chartTimeLineEnabled() ? _xAxisTimeFormat : _xAxisWithLabelFormat(paragraph),
-                            showMaxMin: false
-                        },
-                        yAxis: {
-                            axisLabel:  _yAxisLabel(paragraph),
-                            tickFormat: _yAxisFormat
-                        },
-                        color: CHART_COLORS,
-                        style: style
-                    }
-                };
+            var options = {
+                chart: {
+                    type: 'stackedAreaChart',
+                    height: 400,
+                    margin: {left: 70},
+                    duration: 0,
+                    x: _xX,
+                    y: _yY,
+                    xAxis: {
+                        axisLabel: _xAxisLabel(paragraph),
+                        tickFormat: paragraph.chartTimeLineEnabled() ? _xAxisTimeFormat : _xAxisWithLabelFormat(paragraph),
+                        showMaxMin: false
+                    },
+                    yAxis: {
+                        axisLabel:  _yAxisLabel(paragraph),
+                        tickFormat: _yAxisFormat
+                    },
+                    color: IgniteChartColors,
+                    style: style
+                }
+            };
 
                 paragraph.charts = [{options: options, data: datum}];
 
@@ -1487,10 +1502,10 @@ consoleModule.controller('sqlController', [
 
             $scope.metadata = [];
 
-            $http.post('/api/v1/agent/cache/metadata', {demo: $scope.demo})
-                .success(function (metadata) {
-                    $scope.metadata = _.sortBy(_.filter(metadata, function (meta) {
-                        var cache = _.find($scope.caches, { name: meta.cacheName });
+        IgniteAgentMonitor.metadata($scope.demo)
+            .then(function (metadata) {
+                $scope.metadata = _.sortBy(_.filter(metadata, function (meta) {
+                    var cache = _.find($scope.caches, { name: meta.cacheName });
 
                         if (cache) {
                             meta.name = (cache.sqlSchema ? cache.sqlSchema : '"' + meta.cacheName + '"') + '.' + meta.typeName;
@@ -1503,15 +1518,12 @@ consoleModule.controller('sqlController', [
                             meta.children.unshift({type: 'plain', name: 'mode: ' + cache.mode});
                         }
 
-                        return cache;
-                    }), 'name');
-                })
-                .error(function (errMsg) {
-                    $common.showError(errMsg);
-                })
-                .finally(function() {
-                    $loading.finish('loadingCacheMetadata');
-                });
+                    return cache;
+                }), 'name');
+            })
+            .finally(function () {
+                $loading.finish('loadingCacheMetadata');
+            });
         };
 
         $scope.showResultQuery = function (paragraph) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/gulpfile.js/tasks/bundle.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/gulpfile.js/tasks/bundle.js b/modules/control-center-web/src/main/js/gulpfile.js/tasks/bundle.js
index 8d0d2e9..ce15b34 100644
--- a/modules/control-center-web/src/main/js/gulpfile.js/tasks/bundle.js
+++ b/modules/control-center-web/src/main/js/gulpfile.js/tasks/bundle.js
@@ -39,19 +39,15 @@ var options = {
 	minify: true
 };
 
-gulp.task('bundle', function(cb) {
-	return sequence('bundle:ignite', 'bundle:legacy', cb);
-});
+gulp.task('bundle', ['eslint', 'bundle:ignite', 'bundle:legacy']);
 
 // Package all external dependencies and ignite-console.
-gulp.task('bundle:ignite', ['eslint'], function() {
-	if (util.env.debug) {
+gulp.task('bundle:ignite', function() {
+	if (util.env.debug)
 		delete options.minify;
-	}
 
-	if (util.env.debug || util.env.sourcemaps) {
+	if (util.env.debug || util.env.sourcemaps)
 		options.sourceMaps = true;
-	}
 
 	return jspm.bundleSFX('app/index', 'build/app.min.js', options);
 });

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/gulpfile.js/tasks/inject-plugins.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/gulpfile.js/tasks/inject-plugins.js b/modules/control-center-web/src/main/js/gulpfile.js/tasks/inject-plugins.js
index ce5b5cd..bdac24c 100644
--- a/modules/control-center-web/src/main/js/gulpfile.js/tasks/inject-plugins.js
+++ b/modules/control-center-web/src/main/js/gulpfile.js/tasks/inject-plugins.js
@@ -23,8 +23,7 @@ var common_options = {
 };
 
 var html_targets = [
-    './build/*.html',
-    './build/**/*.html'
+    './build/index.html'
 ];
 
 var js_targets = [

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/package.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/package.json b/modules/control-center-web/src/main/js/package.json
index 9766d61..02cdcd9 100644
--- a/modules/control-center-web/src/main/js/package.json
+++ b/modules/control-center-web/src/main/js/package.json
@@ -57,9 +57,10 @@
     "passport": "^0.3.2",
     "passport-local": "^1.0.0",
     "passport-local-mongoose": "3.1.0",
+    "passport.socketio": "^3.6.1",
     "require-dir": "^0.3.0",
     "serve-favicon": "~2.3.0",
-    "ws": "~0.8.0"
+    "socket.io": "^1.4.5"
   },
   "devDependencies": {
     "jspm": "^0.16.15",
@@ -77,10 +78,11 @@
       "angular-loading": "github:darthwade/angular-loading@^0.1.4",
       "angular-motion": "github:mgcrea/angular-motion@^0.4.3",
       "angular-nvd3": "github:krispo/angular-nvd3@^1.0.4",
-      "angular-retina": "github:jrief/angular-retina@^0.3.8",
+      "angular-retina": "github:jrief/angular-retina@0.3.8",
       "angular-sanitize": "github:angular/bower-angular-sanitize@^1.5.0",
       "angular-smart-table": "github:lorenzofox3/Smart-Table@^2.1.4",
-      "angular-strap": "github:akuznetsov-gridgain/angular-strap@fix-1852-2.3.6",
+      "angular-socket-io": "github:btford/angular-socket-io@^0.7.0",
+      "angular-strap": "github:mgcrea/angular-strap@2.3.7",
       "angular-tree-control": "github:wix/angular-tree-control@^0.2.23",
       "angular-ui-grid": "github:angular-ui/bower-ui-grid@^3.0.7",
       "angular-ui-router": "github:angular-ui/ui-router@^0.2.15",
@@ -97,6 +99,7 @@
       "lodash": "npm:lodash@^3.10.1",
       "pdfmake": "github:bpampuch/pdfmake@^0.1.20",
       "query-command-supported": "github:zenorocha/document.queryCommandSupported@^1.0.0",
+      "socket.io-client": "github:socketio/socket.io-client@1.4.5",
       "text": "github:systemjs/plugin-text@^0.0.7"
     },
     "devDependencies": {
@@ -119,6 +122,20 @@
           }
         }
       },
+      "github:btford/angular-socket-io@0.7.0": {
+        "dependencies": {
+          "socket.io-client": "github:socketio/socket.io-client@1.4.5"
+        }
+      },
+      "github:socketio/socket.io-client@1.4.5": {
+        "format": "global",
+        "main": "socket.io",
+        "shim": {
+          "socket.io": {
+            "exports": "io"
+          }
+        }
+      },
       "github:Stuk/jszip@2.5.0": {
         "format": "global",
         "main": "./dist/jszip"
@@ -141,14 +158,12 @@
       "github:krispo/angular-nvd3@1.0.4": {
         "main": "dist/angular-nvd3",
         "dependencies": {
-          "angular": "^1",
           "nvd3": "npm:nvd3@1.8.1",
           "d3": "npm:d3@3.5.14"
         },
         "shim": {
           "dist/angular-nvd3": {
             "deps": [
-              "angular",
               "d3",
               "nvd3"
             ]
@@ -218,18 +233,22 @@
           "pdfmake": "github:bpampuch/pdfmake@^0.1.20"
         }
       },
-      "github:akuznetsov-gridgain/angular-strap@fix-1852-2.3.6": {
-        "main": "dist/angular-strap.tpl",
+      "github:mgcrea/angular-strap@2.3.7": {
+        "directories": {
+          "lib": "dist"
+        },
+        "main": "angular-strap.tpl",
         "dependencies": {
-          "angular": "github:angular/bower-angular@^1.5.0",
+          "angular": "^1",
           "angular-animate": "github:angular/bower-angular-animate@^1.5.0",
           "angular-motion": "github:mgcrea/angular-motion@^0.4.3",
           "angular-sanitize": "github:angular/bower-angular-sanitize@^1.5.0"
         },
         "shim": {
-          "dist/angular-strap.tpl": {
+          "angular-strap.tpl": {
             "deps": [
-              "./angular-strap"
+              "./angular-strap",
+              "angular"
             ]
           }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve.js b/modules/control-center-web/src/main/js/serve.js
index 59ea9e8..74342a9 100644
--- a/modules/control-center-web/src/main/js/serve.js
+++ b/modules/control-center-web/src/main/js/serve.js
@@ -66,29 +66,23 @@ const fireUp = require('fire-up').newInjector({
     ]
 });
 
-Promise.all([fireUp('settings'), fireUp('app'), fireUp('agent')])
+Promise.all([fireUp('settings'), fireUp('app'), fireUp('agent'), fireUp('io')])
     .then((values) => {
-        const settings = values[0], app = values[1], agent = values[2];
+        const settings = values[0];
+        const app = values[1];
+        const agent = values[2];
+        const io = values[3];
 
-        // Create HTTP server.
-        const server = http.createServer(app);
-
-        app.set('port', settings.server.port);
+        // Start rest server.
+        const server = settings.server.SSLOptions
+            ? https.createServer(settings.server.SSLOptions) : http.createServer();
 
         server.listen(settings.server.port);
         server.on('error', _onError.bind(null, settings.server.port));
         server.on('listening', _onListening.bind(null, server.address()));
 
-        // Create HTTPS server if needed.
-        if (settings.server.SSLOptions) {
-            const httpsServer = https.createServer(settings.server.SSLOptions, app);
-
-            const httpsPort = settings.server.SSLOptions.port;
-
-            httpsServer.listen(httpsPort);
-            httpsServer.on('error', _onError.bind(null, httpsPort));
-            httpsServer.on('listening', _onListening.bind(null, httpsServer.address()));
-        }
+        app.listen(server);
+        io.listen(server);
 
         // Start agent server.
         const agentServer = settings.agent.SSLOptions
@@ -104,7 +98,7 @@ Promise.all([fireUp('settings'), fireUp('app'), fireUp('agent')])
         if (process.send)
             process.send('running');
     }).catch((err) => {
-        console.error(err);
+        console.error(error);
 
         process.exit(1);
     });

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/agent.js b/modules/control-center-web/src/main/js/serve/agent.js
index 6c54ae1..04d7ed6 100644
--- a/modules/control-center-web/src/main/js/serve/agent.js
+++ b/modules/control-center-web/src/main/js/serve/agent.js
@@ -21,10 +21,21 @@
 
 module.exports = {
     implements: 'agent',
-    inject: ['require(fs)', 'require(ws)', 'require(apache-ignite)', 'mongo']
+    inject: ['require(lodash)', 'require(fs)', 'require(path)', 'require(jszip)', 'require(socket.io)', 'require(apache-ignite)', 'settings', 'mongo']
 };
 
-module.exports.factory = function(fs, ws, apacheIgnite, mongo) {
+/**
+ * @param _
+ * @param fs
+ * @param path
+ * @param JSZip
+ * @param socketio
+ * @param apacheIgnite
+ * @param settings
+ * @param mongo
+ * @returns {AgentManager}
+ */
+module.exports.factory = function(_, fs, path, JSZip, socketio, apacheIgnite, settings, mongo) {
     /**
      * Creates an instance of server for Ignite.
      */
@@ -72,37 +83,39 @@ module.exports.factory = function(fs, ws, apacheIgnite, mongo) {
 
     class Agent {
         /**
+         * @param {socketIo.Socket} _wsSrv
          * @param {AgentManager} manager
-         * @param {WebSocket} _wsSrv
          */
         constructor(_wsSrv, manager) {
             const self = this;
 
             this._manager = manager;
 
-            this._wsSrv = _wsSrv;
+            /**
+             * @type {socketIo.Socket}
+             * @private
+             */
+            this._wsAgents = _wsSrv;
 
-            this._wsSrv.on('close', () => {
+            this._wsAgents.on('disconnect', () => {
                 if (self._user)
-                    self._manager._removeClient(self._user._id, self);
-            });
-
-            this._wsSrv.on('message', (msgStr) => {
-                const msg = JSON.parse(msgStr);
-
-                self['_rmt' + msg.type](msg);
+                    self._manager._removeAgent(self._user._id, self);
             });
 
-            this._reqCounter = 0;
-
-            this._cbMap = {};
+            this._wsAgents.on('agent:auth', (msg, cb) => self._processAuth(msg, cb));
         }
 
-        _runCommand(method, args) {
+        /**
+         *
+         * @param event
+         * @param data
+         * @returns {Promise}
+         */
+        _exec(event, data) {
             const self = this;
 
             return new Promise((resolve, reject) =>
-                self._invokeRmtMethod(method, args, (error, res) => {
+                self._emit(event, data, (error, res) => {
                     if (error)
                         return reject(error);
 
@@ -133,10 +146,7 @@ module.exports.factory = function(fs, ws, apacheIgnite, mongo) {
             if (headers && typeof (headers) !== 'object')
                 throw 'headers must be an object';
 
-            if (!method)
-                method = 'GET';
-            else
-                method = method.toUpperCase();
+            method = method ? method.toUpperCase() : 'GET';
 
             if (method !== 'GET' && method !== 'POST')
                 throw 'Unknown HTTP method: ' + method;
@@ -145,38 +155,32 @@ module.exports.factory = function(fs, ws, apacheIgnite, mongo) {
                 if (error)
                     return cb(error);
 
-                const restError = restResult.error;
-
-                if (restError)
-                    return cb(restError);
+                error = restResult.error;
 
-                const restCode = restResult.restCode;
+                const code = restResult.code;
 
-                if (restCode !== 200) {
-                    if (restCode === 401)
-                        return cb.call({code: restCode, message: 'Failed to authenticate on node.'});
+                if (code !== 200) {
+                    if (code === 401)
+                        return cb({code, message: 'Failed to authenticate on node.'});
 
-                    return cb.call({
-                        code: restCode,
-                        message: restError || 'Failed connect to node and execute REST command.'
-                    });
+                    return cb({code, message: error || 'Failed connect to node and execute REST command.'});
                 }
 
                 try {
-                    const nodeResponse = JSON.parse(restResult.response);
+                    const response = JSON.parse(restResult.data);
 
-                    if (nodeResponse.successStatus === 0)
-                        return cb(null, nodeResponse.response);
+                    if (response.successStatus === 0)
+                        return cb(null, response.response);
 
-                    switch (nodeResponse.successStatus) {
+                    switch (response.successStatus) {
                         case 1:
-                            return cb({code: 500, message: nodeResponse.error});
+                            return cb({code: 500, message: response.error});
                         case 2:
-                            return cb({code: 401, message: nodeResponse.error});
+                            return cb({code: 401, message: response.error});
                         case 3:
-                            return cb({code: 403, message: nodeResponse.error});
+                            return cb({code: 403, message: response.error});
                         default:
-                            return cb(nodeResponse.error);
+                            return cb(response.error);
                     }
                 }
                 catch (e) {
@@ -184,14 +188,7 @@ module.exports.factory = function(fs, ws, apacheIgnite, mongo) {
                 }
             };
 
-            this._invokeRmtMethod('executeRest', [uri, params, demo, method, headers, body], _cb);
-        }
-
-        /**
-         * @param {?String} error
-         */
-        authResult(error) {
-            return this._runCommand('authResult', [error]);
+            this._emit('node:rest', {uri, params, demo, method, headers, body}, _cb);
         }
 
         /**
@@ -202,7 +199,7 @@ module.exports.factory = function(fs, ws, apacheIgnite, mongo) {
          * @returns {Promise} Promise on list of tables (see org.apache.ignite.schema.parser.DbTable java class)
          */
         metadataSchemas(driverPath, driverClass, url, info) {
-            return this._runCommand('schemas', [driverPath, driverClass, url, info]);
+            return this._exec('schemaImport:schemas', {driverPath, driverClass, url, info});
         }
 
         /**
@@ -215,89 +212,74 @@ module.exports.factory = function(fs, ws, apacheIgnite, mongo) {
          * @returns {Promise} Promise on list of tables (see org.apache.ignite.schema.parser.DbTable java class)
          */
         metadataTables(driverPath, driverClass, url, info, schemas, tablesOnly) {
-            return this._runCommand('metadata', [driverPath, driverClass, url, info, schemas, tablesOnly]);
+            return this._exec('schemaImport:metadata', {driverPath, driverClass, url, info, schemas, tablesOnly});
         }
 
         /**
          * @returns {Promise} Promise on list of jars from driver folder.
          */
         availableDrivers() {
-            return this._runCommand('availableDrivers', []);
+            return this._exec('schemaImport:drivers');
         }
 
         /**
          * Run http request
          *
-         * @this {AgentServer}
-         * @param {String} method Command name.
-         * @param {Array} args Command params.
-         * @param {Function} callback on finish
+         * @this {Agent}
+         * @param {String} event Command name.
+         * @param {Object} data Command params.
+         * @param {Function} [callback] on finish
          */
-        _invokeRmtMethod(method, args, callback) {
-            if (this._wsSrv.readyState !== 1) {
+        _emit(event, data, callback) {
+            if (!this._wsAgents.connected) {
                 if (callback)
                     callback('org.apache.ignite.agent.AgentException: Connection is closed');
 
                 return;
             }
 
-            const msg = {method, args};
-
-            if (callback) {
-                const reqId = this._reqCounter++;
-
-                this._cbMap[reqId] = callback;
-
-                msg.reqId = reqId;
-            }
-
-            this._wsSrv.send(JSON.stringify(msg));
+            this._wsAgents.emit(event, data, callback);
         }
 
-        _rmtAuthMessage(msg) {
+        /**
+         * Process auth request.
+         *
+         * @param {Object} data
+         * @param {Function} cb
+         * @private
+         */
+        _processAuth(data, cb) {
             const self = this;
 
-            fs.stat('public/agent/ignite-web-agent-1.5.0.final.zip', (errFs, stats) => {
-                let relDate = 0;
-
-                if (!errFs)
-                    relDate = stats.birthtime.getTime();
+            if (!_.isEmpty(this._manager.supportedAgents)) {
+                const ver = data.ver;
+                const bt = data.bt;
 
-                if ((msg.relDate || 0) < relDate)
-                    self.authResult('You are using an older version of the agent. Please reload agent archive');
+                if (_.isEmpty(ver) || _.isEmpty(bt) || _.isEmpty(this._manager.supportedAgents[ver]) ||
+                    this._manager.supportedAgents[ver].buildTime > bt)
+                    return cb('You are using an older version of the agent. Please reload agent archive');
+            }
 
-                mongo.Account.findOne({token: msg.token}, (err, account) => {
-                    // TODO IGNITE-1379 send error to web master.
-                    if (err)
-                        self.authResult('Failed to authorize user');
-                    else if (!account)
-                        self.authResult('Invalid token, user not found');
-                    else {
-                        self.authResult(null);
+            mongo.Account.findOne({token: data.token}, (err, account) => {
+                // TODO IGNITE-1379 send error to web master.
+                if (err)
+                    cb('Failed to authorize user');
+                else if (!account)
+                    cb('Invalid token, user not found');
+                else {
+                    self._user = account;
 
-                        self._user = account;
+                    self._manager._addAgent(account._id, self);
 
-                        self._manager._addAgent(account._id, self);
+                    self._cluster = new apacheIgnite.Ignite(new AgentServer(self));
 
-                        self._cluster = new apacheIgnite.Ignite(new AgentServer(self));
+                    self._demo = new apacheIgnite.Ignite(new AgentServer(self, true));
 
-                        self._demo = new apacheIgnite.Ignite(new AgentServer(self, true));
-                    }
-                });
+                    cb();
+                }
             });
         }
 
-        _rmtCallRes(msg) {
-            const callback = this._cbMap[msg.reqId];
-
-            if (!callback)
-                return;
-
-            delete this._cbMap[msg.reqId];
-
-            callback(msg.error, msg.response);
-        }
-
         /**
          * @returns {Ignite}
          */
@@ -311,11 +293,79 @@ module.exports.factory = function(fs, ws, apacheIgnite, mongo) {
          * @constructor
          */
         constructor() {
+            /**
+             * @type {Object.<ObjectId, Array.<Agent>>}
+             */
             this._agents = {};
+
+            /**
+             * @type {Object.<ObjectId, Array.<Socket>>}
+             */
+            this._users = {};
+
+            const agentArchives = fs.readdirSync(settings.agent.dists)
+                .filter((file) => path.extname(file) === '.zip');
+
+            /**
+             * @type {Object.<String, String>}
+             */
+            this.supportedAgents = {};
+
+            const jarFilter = (file) => path.extname(file) === '.jar';
+
+            for (const archive of agentArchives) {
+                const filePath = path.join(settings.agent.dists, archive);
+
+                const zip = new JSZip(fs.readFileSync(filePath));
+
+                const jarPath = _.find(_.keys(zip.files), jarFilter);
+
+                const jar = new JSZip(zip.files[jarPath].asNodeBuffer());
+
+                const manifest = jar.files['META-INF/MANIFEST.MF']
+                    .asText()
+                    .trim()
+                    .split(/\s*\n+\s*/)
+                    .map((line, r) => {
+                        r = line.split(/\s*:\s*/);
+
+                        this[r[0]] = r[1];
+
+                        return this;
+                    }, {})[0];
+
+                const ver = manifest['Implementation-Version'];
+
+                if (ver) {
+                    this.supportedAgents[ver] = {
+                        fileName: archive,
+                        filePath,
+                        buildTime: manifest['Build-Time']
+                    };
+                }
+            }
+
+            const latest = _.first(Object.keys(this.supportedAgents).sort((a, b) => {
+                const aParts = a.split('.');
+                const bParts = b.split('.');
+
+                for (let i = 0; i < aParts.length; ++i) {
+                    if (bParts.length === i)
+                        return 1;
+
+                    if (aParts[i] === aParts[i])
+                        continue;
+
+                    return aParts[i] > bParts[i] ? 1 : -1;
+                }
+            }));
+
+            if (latest)
+                this.supportedAgents.latest = this.supportedAgents[latest];
         }
 
         /**
-         *
+         * @param {http.Server|https.Server} srv
          */
         listen(srv) {
             if (this._server)
@@ -323,58 +373,106 @@ module.exports.factory = function(fs, ws, apacheIgnite, mongo) {
 
             this._server = srv;
 
-            this._wsSrv = new ws.Server({server: this._server});
+            /**
+             * @type {WebSocketServer}
+             */
+            this._wsAgents = socketio(this._server);
 
             const self = this;
 
-            this._wsSrv.on('connection', (_wsSrv) => new Agent(_wsSrv, self));
+            this._wsAgents.on('connection', (_wsSrv) => new Agent(_wsSrv, self));
         }
 
         /**
-         * @param userId
-         * @param {Agent} client
+         * @param {ObjectId} userId
+         * @param {Socket} user
+         * @returns {int} connected agent count.
          */
-        _removeClient(userId, client) {
+        addAgentListener(userId, user) {
+            let users = this._users[userId];
+
+            if (!users)
+                this._users[userId] = users = [];
+
+            users.push(user);
+
             const agents = this._agents[userId];
 
-            if (agents) {
-                let idx;
+            return agents ? agents.length : 0;
+        }
 
-                while ((idx = agents.indexOf(client)) !== -1)
-                    agents.splice(idx, 1);
+        /**
+         * @param {ObjectId} userId
+         * @param {Socket} user
+         * @returns {int} connected agent count.
+         */
+        removeAgentListener(userId, user) {
+            const users = this._users[userId];
 
-                if (agents.length === 0)
-                    delete this._agents[userId];
-            }
+            _.remove(users, (_user) => _user === user);
         }
 
         /**
          * @param {ObjectId} userId
-         * @param {Agent} agent
+         * @returns {Promise.<Agent>}
          */
-        _addAgent(userId, agent) {
-            let agents = this._agents[userId];
+        findAgent(userId) {
+            if (!this._server)
+                return Promise.reject('Agent server not started yet!');
 
-            if (!agents) {
-                agents = [];
+            const agents = this._agents[userId];
 
-                this._agents[userId] = agents;
-            }
+            if (!agents || agents.length === 0)
+                return Promise.reject('Failed to connect to agent');
 
-            agents.push(agent);
+            return Promise.resolve(agents[0]);
         }
 
         /**
+         * Close connections for all user agents.
          * @param {ObjectId} userId
-         * @returns {Agent}
          */
-        findClient(userId) {
+        close(userId) {
+            if (!this._server)
+                throw 'Agent server not started yet!';
+
+            const agents = this._agents[userId];
+
+            this._agents[userId] = [];
+
+            for (const agent of agents)
+                agent._emit('agent:close', 'Security token was changed for user');
+        }
+
+        /**
+         * @param userId
+         * @param {Agent} agent
+         */
+        _removeAgent(userId, agent) {
             const agents = this._agents[userId];
 
-            if (!agents || agents.length === 0)
-                return null;
+            _.remove(agents, (_agent) => _agent === agent);
+
+            const users = this._users[userId];
+
+            _.forEach(users, (user) => user.emit('agent:count', {count: agents.length}));
+        }
+
+        /**
+         * @param {ObjectId} userId
+         * @param {Agent} agent
+         */
+        _addAgent(userId, agent) {
+            let agents = this._agents[userId];
+
+            if (!agents)
+                this._agents[userId] = agents = [];
+
+            agents.push(agent);
+
+            const users = this._users[userId];
 
-            return agents[0];
+            _.forEach(users, (user) => user.emit('agent:count', {count: agents.length}));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/agent_dists/README.txt
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/agent_dists/README.txt b/modules/control-center-web/src/main/js/serve/agent_dists/README.txt
new file mode 100644
index 0000000..d51bdf9
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/agent_dists/README.txt
@@ -0,0 +1,7 @@
+Ignite Web Console
+======================================
+
+This is default folder for agent distributives.
+
+Also, you could specify custom folder in `serve/config/settings.json`
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/app.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/app.js b/modules/control-center-web/src/main/js/serve/app.js
index 5f4e4fb..e4b5eca 100644
--- a/modules/control-center-web/src/main/js/serve/app.js
+++ b/modules/control-center-web/src/main/js/serve/app.js
@@ -21,15 +21,22 @@
 
 module.exports = {
     implements: 'app',
-    inject: ['require(express)', 'configure', 'routes']
+    inject: ['require(express)', 'configure', 'routes', 'io']
 };
 
 module.exports.factory = function(Express, configure, routes) {
-    const app = new Express();
+    return {
+        /**
+         * @param {Server} srv
+         */
+        listen: (srv) => {
+            const app = new Express();
 
-    configure(app);
+            configure.express(app);
 
-    routes.register(app);
+            routes.register(app);
 
-    return app;
+            srv.addListener('request', app);
+        }
+    };
 };

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/config/default.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/config/default.json b/modules/control-center-web/src/main/js/serve/config/default.json
deleted file mode 100644
index 3dcc5ca..0000000
--- a/modules/control-center-web/src/main/js/serve/config/default.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-    "server": {
-        "port": 3000,
-        "https-port": 8443,
-        "ssl": false,
-        "key": "serve/keys/test.key",
-        "cert": "serve/keys/test.crt",
-        "keyPassphrase": "password"
-    },
-    "mongoDB": {
-        "url": "mongodb://localhost/web-control-center"
-    },
-    "agent-server": {
-        "port": 3001,
-        "ssl": true,
-        "key": "serve/keys/test.key",
-        "cert": "serve/keys/test.crt",
-        "keyPassphrase": "password"
-    },
-    "smtp": {
-        "service": "",
-        "username": "Apache Ignite Web Console",
-        "email": "",
-        "password": ""
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/config/settings.json.sample
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/config/settings.json.sample b/modules/control-center-web/src/main/js/serve/config/settings.json.sample
new file mode 100644
index 0000000..94dd9f7
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/config/settings.json.sample
@@ -0,0 +1,26 @@
+{
+    "server": {
+        "port": 3000,
+        "ssl": false,
+        "key": "serve/keys/test.key",
+        "cert": "serve/keys/test.crt",
+        "keyPassphrase": "password"
+    },
+    "mongoDB": {
+        "url": "mongodb://localhost/console"
+    },
+    "agent-server": {
+        "port": 3001,
+        "ssl": false,
+        "key": "serve/keys/test.key",
+        "cert": "serve/keys/test.crt",
+        "keyPassphrase": "password"
+    },
+    "smtp": {
+        "service": "",
+        "username": "Apache Ignite Web Console",
+        "sign": "Kind regards,<br>Apache Ignite Team",
+        "email": "",
+        "password": ""
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/configure.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/configure.js b/modules/control-center-web/src/main/js/serve/configure.js
index 9d8b1d3..ac27751 100644
--- a/modules/control-center-web/src/main/js/serve/configure.js
+++ b/modules/control-center-web/src/main/js/serve/configure.js
@@ -21,46 +21,60 @@
 
 module.exports = {
     implements: 'configure',
-    inject: ['require(morgan)', 'require(cookie-parser)', 'require(body-parser)', 'require(express-force-ssl)',
-        'require(express-session)', 'require(connect-mongo)', 'require(passport)', 'settings', 'mongo']
+    inject: ['require(morgan)', 'require(cookie-parser)', 'require(body-parser)',
+        'require(express-session)', 'require(connect-mongo)', 'require(passport)', 'require(passport.socketio)', 'settings', 'mongo']
 };
 
-module.exports.factory = function(logger, cookieParser, bodyParser, forceSSL, session, connectMongo, Passport, settings, mongo) {
-    return (app) => {
-        app.use(logger('dev', {
-            skip: (req, res) => res.statusCode < 400
-        }));
+module.exports.factory = function(logger, cookieParser, bodyParser, session, connectMongo, passport, passportSocketIo, settings, mongo) {
+    const _sessionStore = new (connectMongo(session))({mongooseConnection: mongo.connection});
 
-        app.use(cookieParser(settings.sessionSecret));
+    return {
+        express: (app) => {
+            app.use(logger('dev', {
+                skip: (req, res) => res.statusCode < 400
+            }));
 
-        app.use(bodyParser.json({limit: '50mb'}));
-        app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
+            app.use(cookieParser(settings.sessionSecret));
 
-        const MongoStore = connectMongo(session);
+            app.use(bodyParser.json({limit: '50mb'}));
+            app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
 
-        app.use(session({
-            secret: settings.sessionSecret,
-            resave: false,
-            saveUninitialized: true,
-            cookie: {
-                expires: new Date(Date.now() + settings.cookieTTL),
-                maxAge: settings.cookieTTL
-            },
-            store: new MongoStore({mongooseConnection: mongo.connection})
-        }));
+            app.use(session({
+                secret: settings.sessionSecret,
+                resave: false,
+                saveUninitialized: true,
+                cookie: {
+                    expires: new Date(Date.now() + settings.cookieTTL),
+                    maxAge: settings.cookieTTL
+                },
+                store: _sessionStore
+            }));
 
-        app.use(Passport.initialize());
-        app.use(Passport.session());
+            app.use(passport.initialize());
+            app.use(passport.session());
 
-        Passport.serializeUser(mongo.Account.serializeUser());
-        Passport.deserializeUser(mongo.Account.deserializeUser());
+            passport.serializeUser(mongo.Account.serializeUser());
+            passport.deserializeUser(mongo.Account.deserializeUser());
 
-        Passport.use(mongo.Account.createStrategy());
+            passport.use(mongo.Account.createStrategy());
+        },
+        socketio: (io) => {
+            const _onAuthorizeSuccess = (data, accept) => {
+                accept(null, true);
+            };
 
-        if (settings.SSLOptions) {
-            app.set('forceSSLOptions', settings.SSLOptions);
+            const _onAuthorizeFail = (data, message, error, accept) => {
+                accept(null, false);
+            };
 
-            app.use(forceSSL);
+            io.use(passportSocketIo.authorize({
+                cookieParser,
+                key: 'connect.sid', // the name of the cookie where express/connect stores its session_id
+                secret: settings.sessionSecret, // the session_secret to parse the cookie
+                store: _sessionStore, // we NEED to use a sessionstore. no memorystore please
+                success: _onAuthorizeSuccess, // *optional* callback on success - read more below
+                fail: _onAuthorizeFail // *optional* callback on fail/error - read more below
+            }));
         }
     };
 };

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/io.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/io.js b/modules/control-center-web/src/main/js/serve/io.js
new file mode 100644
index 0000000..ded00fa
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/io.js
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+'use strict';
+
+// Fire me up!
+
+module.exports = {
+    implements: 'io',
+    inject: ['require(lodash)', 'require(socket.io)', 'require(apache-ignite)', 'agent', 'configure']
+};
+
+module.exports.factory = (_, socketio, apacheIgnite, agentMgr, configure) => {
+    const SqlFieldsQuery = apacheIgnite.SqlFieldsQuery;
+    const ScanQuery = apacheIgnite.ScanQuery;
+
+    return {
+        listen: (server) => {
+            const io = socketio(server);
+
+            configure.socketio(io);
+
+            io.sockets.on('connection', (socket) => {
+                const user = socket.client.request.user;
+
+                socket.on('schemaImport:drivers', (cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => agent.availableDrivers())
+                        .then((drivers) => cb(null, drivers))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                socket.on('schemaImport:schemas', (preset, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            const jdbcInfo = {user: preset.user, password: preset.password};
+
+                            return agent.metadataSchemas(preset.jdbcDriverJar, preset.jdbcDriverClass, preset.jdbcUrl, jdbcInfo);
+                        })
+                        .then((schemas) => cb(null, schemas))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                socket.on('schemaImport:tables', (preset, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            const jdbcInfo = {user: preset.user, password: preset.password};
+
+                            return agent.metadataTables(preset.jdbcDriverJar, preset.jdbcDriverClass, preset.jdbcUrl, jdbcInfo,
+                                preset.schemas, preset.tablesOnly);
+                        })
+                        .then((tables) => cb(null, tables))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                socket.on('node:topology', (demo, attr, mtr, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => agent.ignite(demo).cluster(attr, mtr))
+                        .then((clusters) => cb(null, clusters))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                socket.on('node:query:close', (args, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            const cache = agent.ignite(args.demo).cache(args.cacheName);
+
+                            return cache.__createPromise(cache._createCommand('qrycls').addParam('qryId', args.queryId));
+                        })
+                        .then(() => cb())
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                socket.on('node:query', (args, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            // Create sql query.
+                            const qry = args.type === 'SCAN' ? new ScanQuery() : new SqlFieldsQuery(args.query);
+
+                            // Set page size for query.
+                            qry.setPageSize(args.pageSize);
+
+                            return agent.ignite(args.demo).cache(args.cacheName).query(qry).nextPage();
+                        })
+                        .then((cursor) => cb(null, {
+                            meta: cursor.fieldsMetadata(),
+                            rows: cursor.page(),
+                            queryId: cursor.queryId()
+                        }))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                socket.on('node:query:fetch', (args, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            const cache = agent.ignite(args.demo).cache(args.cacheName);
+
+                            const cmd = cache._createCommand('qryfetch')
+                                .addParam('qryId', args.queryId)
+                                .addParam('pageSize', args.pageSize);
+
+                            return cache.__createPromise(cmd);
+                        })
+                        .then((page) => cb(null, {
+                            rows: page.items,
+                            last: page === null || page.last
+                        }))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                socket.on('node:query:getAll', (args, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => {
+                            // Create sql query.
+                            const qry = args.type === 'SCAN' ? new ScanQuery() : new SqlFieldsQuery(args.query);
+
+                            // Set page size for query.
+                            qry.setPageSize(args.pageSize);
+
+                            return agent.ignite(args.demo).cache(args.cacheName).query(qry).getAll();
+                        })
+                        .then((cursor) => cb(null, {
+                            meta: cursor.fieldsMetadata(),
+                            rows: cursor.page()
+                        }))
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                socket.on('node:cache:metadata', (args, cb) => {
+                    agentMgr.findAgent(user._id)
+                        .then((agent) => agent.ignite(args.demo).cache(args.cacheName).metadata())
+                        .then((caches) => {
+                            let types = [];
+
+                            const _compact = (className) => {
+                                return className.replace('java.lang.', '').replace('java.util.', '').replace('java.sql.', '');
+                            };
+
+                            const _typeMapper = (meta, typeName) => {
+                                let fields = meta.fields[typeName];
+
+                                let columns = [];
+
+                                for (const fieldName in fields) {
+                                    if (fields.hasOwnProperty(fieldName)) {
+                                        const fieldClass = _compact(fields[fieldName]);
+
+                                        columns.push({
+                                            type: 'field',
+                                            name: fieldName,
+                                            clazz: fieldClass,
+                                            system: fieldName === '_KEY' || fieldName === '_VAL',
+                                            cacheName: meta.cacheName,
+                                            typeName
+                                        });
+                                    }
+                                }
+
+                                const indexes = [];
+
+                                for (const index of meta.indexes[typeName]) {
+                                    fields = [];
+
+                                    for (const field of index.fields) {
+                                        fields.push({
+                                            type: 'index-field',
+                                            name: field,
+                                            order: index.descendings.indexOf(field) < 0,
+                                            unique: index.unique,
+                                            cacheName: meta.cacheName,
+                                            typeName
+                                        });
+                                    }
+
+                                    if (fields.length > 0) {
+                                        indexes.push({
+                                            type: 'index',
+                                            name: index.name,
+                                            children: fields,
+                                            cacheName: meta.cacheName,
+                                            typeName
+                                        });
+                                    }
+                                }
+
+                                columns = _.sortBy(columns, 'name');
+
+                                if (!_.isEmpty(indexes)) {
+                                    columns = columns.concat({
+                                        type: 'indexes',
+                                        name: 'Indexes',
+                                        cacheName: meta.cacheName,
+                                        typeName,
+                                        children: indexes
+                                    });
+                                }
+
+                                return {
+                                    type: 'type',
+                                    cacheName: meta.cacheName || '',
+                                    typeName,
+                                    children: columns
+                                };
+                            };
+
+                            for (const meta of caches) {
+                                const cacheTypes = meta.types.map(_typeMapper.bind(null, meta));
+
+                                if (!_.isEmpty(cacheTypes))
+                                    types = types.concat(cacheTypes);
+                            }
+
+                            return cb(null, types);
+                        })
+                        .catch((errMsg) => cb(errMsg));
+                });
+
+                const count = agentMgr.addAgentListener(user._id, socket);
+
+                socket.emit('agent:count', {count});
+            });
+
+            io.sockets.on('disconnect', (socket) =>
+                agentMgr.removeAgentListener(socket.client.request.user._id, socket)
+            );
+        }
+    };
+};

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/mail.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/mail.js b/modules/control-center-web/src/main/js/serve/mail.js
index 8ab3e7e..36b4fa7 100644
--- a/modules/control-center-web/src/main/js/serve/mail.js
+++ b/modules/control-center-web/src/main/js/serve/mail.js
@@ -28,11 +28,12 @@ module.exports.factory = function(nodemailer, settings) {
     return {
         /**
          * Send mail to user.
+         *
          * @param {Account} user
          * @param {String} subject
          * @param {String} html
          * @param {String} sendErr
-         *
+         * @throws {Error}
          * @return {Promise}
          */
         send: (user, subject, html, sendErr) => {
@@ -45,7 +46,7 @@ module.exports.factory = function(nodemailer, settings) {
             };
 
             if (transporter.service === '' || transporter.auth.user === '' || transporter.auth.pass === '')
-                return Promise.reject('Failed to send email. SMTP server is not configured . Please ask webmaster to setup SMTP server!');
+                throw new Error('Failed to send email. SMTP server is not configured. Please ask webmaster to setup SMTP server!');
 
             const mailer = nodemailer.createTransport(transporter);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/agent.js b/modules/control-center-web/src/main/js/serve/routes/agent.js
index 7bb05e7..4e123bf 100644
--- a/modules/control-center-web/src/main/js/serve/routes/agent.js
+++ b/modules/control-center-web/src/main/js/serve/routes/agent.js
@@ -21,7 +21,7 @@
 
 module.exports = {
     implements: 'agent-routes',
-    inject: ['require(lodash)', 'require(express)', 'require(apache-ignite)', 'require(fs)', 'require(jszip)', 'settings', 'agent']
+    inject: ['require(lodash)', 'require(express)', 'require(fs)', 'require(jszip)', 'require(apache-ignite)', 'settings', 'agent']
 };
 
 /**
@@ -34,302 +34,47 @@ module.exports = {
  * @param {AgentManager} agentMgr
  * @returns {Promise}
  */
-module.exports.factory = function(_, express, apacheIgnite, fs, JSZip, settings, agentMgr) {
+module.exports.factory = function(_, express, fs, JSZip, apacheIgnite, settings, agentMgr) {
     return new Promise((resolveFactory) => {
         const router = new express.Router();
 
-        const SqlFieldsQuery = apacheIgnite.SqlFieldsQuery;
-        const ScanQuery = apacheIgnite.ScanQuery;
-
-        const _client = (userId) => {
-            return new Promise((resolve, reject) => {
-                const agent = agentMgr.findClient(userId);
-
-                if (agent)
-                    return resolve(agent);
-
-                reject({code: 503, message: 'Connection to Ignite Web Agent is not established'});
-            });
-        };
-
-        const _compact = (className) => {
-            return className.replace('java.lang.', '').replace('java.util.', '').replace('java.sql.', '');
-        };
-
-        const _handleException = (res) => {
-            return (error) => {
-                if (_.isObject(error))
-                    return res.status(error.code).send(error.message);
-
-                return res.status(500).send(error);
-            };
-        };
-
         /* Get grid topology. */
         router.get('/download/zip', (req, res) => {
-            const agentFld = settings.agent.file;
-            const agentZip = agentFld + '.zip';
-            const agentPathZip = 'public/agent/' + agentFld + '.zip';
-
-            fs.stat(agentPathZip, (err, stats) => {
-                if (err)
-                    return res.download(agentPathZip, agentZip);
-
-                // Read a zip file.
-                fs.readFile(agentPathZip, (errFs, data) => {
-                    if (errFs)
-                        return res.download(agentPathZip, agentZip);
-
-                    const zip = new JSZip(data);
-
-                    const prop = [];
-
-                    const host = req.hostname.match(/:/g) ? req.hostname.slice(0, req.hostname.indexOf(':')) : req.hostname;
-
-                    prop.push('token=' + req.user.token);
-                    prop.push('server-uri=wss://' + host + ':' + settings.agent.port);
-                    prop.push('#Uncomment following options if needed:');
-                    prop.push('#node-uri=http://localhost:8080');
-                    prop.push('#driver-folder=./jdbc-drivers');
-                    prop.push('');
-                    prop.push('#Note: Do not change this auto generated line');
-                    prop.push('rel-date=' + stats.birthtime.getTime());
-
-                    zip.file(agentFld + '/default.properties', prop.join('\n'));
-
-                    const buffer = zip.generate({type: 'nodebuffer', platform: 'UNIX'});
-
-                    // Set the archive name.
-                    res.attachment(agentZip);
-
-                    res.send(buffer);
-                });
-            });
-        });
-
-        /* Get grid topology. */
-        router.post('/topology', (req, res) => {
-            _client(req.currentUserId())
-                .then((client) => client.ignite(req.body.demo).cluster(req.body.attr, req.body.mtr))
-                .then((clusters) => res.json(clusters))
-                .catch(_handleException(res));
-        });
-
-        /* Execute query. */
-        router.post('/query', (req, res) => {
-            _client(req.currentUserId())
-                .then((client) => {
-                    // Create sql query.
-                    const qry = new SqlFieldsQuery(req.body.query);
-
-                    // Set page size for query.
-                    qry.setPageSize(req.body.pageSize);
-
-                    return client.ignite(req.body.demo).cache(req.body.cacheName).query(qry).nextPage();
-                })
-                .then((cursor) => res.json({
-                    meta: cursor.fieldsMetadata(),
-                    rows: cursor.page(),
-                    queryId: cursor.queryId()
-                }))
-                .catch(_handleException(res));
-        });
-
-        /* Execute query getAll. */
-        router.post('/query/getAll', (req, res) => {
-            _client(req.currentUserId())
-                .then((client) => {
-                    // Create sql query.
-                    const qry = req.body.query ? new SqlFieldsQuery(req.body.query) : new ScanQuery();
-
-                    // Set page size for query.
-                    qry.setPageSize(1024);
-
-                    // Get query cursor.
-                    const cursor = client.ignite(req.body.demo).cache(req.body.cacheName).query(qry);
+            const latest = agentMgr.supportedAgents.latest;
 
-                    return cursor.getAll()
-                        .then((rows) => res.json({meta: cursor.fieldsMetadata(), rows}));
-                })
-                .catch(_handleException(res));
-        });
-
-        /* Execute query. */
-        router.post('/scan', (req, res) => {
-            _client(req.currentUserId())
-                .then((client) => {
-                    // Create sql query.
-                    const qry = new ScanQuery();
-
-                    // Set page size for query.
-                    qry.setPageSize(req.body.pageSize);
-
-                    // Get query cursor.
-                    return client.ignite(req.body.demo).cache(req.body.cacheName).query(qry).nextPage();
-                })
-                .then((cursor) => res.json({
-                    meta: cursor.fieldsMetadata(),
-                    rows: cursor.page(),
-                    queryId: cursor.queryId()
-                }))
-                .catch(_handleException(res));
-        });
-
-        /* Get next query page. */
-        router.post('/query/fetch', (req, res) => {
-            _client(req.currentUserId())
-                .then((client) => {
-                    const cache = client.ignite(req.body.demo).cache(req.body.cacheName);
-
-                    const cmd = cache._createCommand('qryfetch')
-                        .addParam('qryId', req.body.queryId)
-                        .addParam('pageSize', req.body.pageSize);
-
-                    return cache.__createPromise(cmd);
-                })
-                .then((page) => res.json({rows: page.items, last: page === null || page.last}))
-                .catch(_handleException(res));
-        });
-
-        /* Close query cursor by id. */
-        router.post('/query/close', (req, res) => {
-            _client(req.currentUserId())
-                .then((client) => {
-                    const cache = client.ignite(req.body.demo).cache(req.body.cacheName);
-
-                    return cache.__createPromise(cache._createCommand('qrycls').addParam('qryId', req.body.queryId));
-                })
-                .then(() => res.sendStatus(200))
-                .catch(_handleException(res));
-        });
-
-        /* Get metadata for cache. */
-        router.post('/cache/metadata', (req, res) => {
-            _client(req.currentUserId())
-                .then((client) => client.ignite(req.body.demo).cache(req.body.cacheName).metadata())
-                .then((caches) => {
-                    let types = [];
-
-                    const _typeMapper = (meta, typeName) => {
-                        let fields = meta.fields[typeName];
-
-                        let columns = [];
-
-                        for (const fieldName in fields) {
-                            if (fields.hasOwnProperty(fieldName)) {
-                                const fieldClass = _compact(fields[fieldName]);
+            if (_.isEmpty(latest))
+                return res.status(500).send('Missing agent zip on server. Please ask webmaster to upload agent zip!');
 
-                                columns.push({
-                                    type: 'field',
-                                    name: fieldName,
-                                    clazz: fieldClass,
-                                    system: fieldName === '_KEY' || fieldName === '_VAL',
-                                    cacheName: meta.cacheName,
-                                    typeName
-                                });
-                            }
-                        }
+            const agentFld = latest.fileName.substr(0, latest.fileName.length - 4);
+            const agentZip = latest.fileName;
+            const agentPathZip = latest.filePath;
 
-                        const indexes = [];
-
-                        for (const index of meta.indexes[typeName]) {
-                            fields = [];
-
-                            for (const field of index.fields) {
-                                fields.push({
-                                    type: 'index-field',
-                                    name: field,
-                                    order: index.descendings.indexOf(field) < 0,
-                                    unique: index.unique,
-                                    cacheName: meta.cacheName,
-                                    typeName
-                                });
-                            }
-
-                            if (fields.length > 0) {
-                                indexes.push({
-                                    type: 'index',
-                                    name: index.name,
-                                    children: fields,
-                                    cacheName: meta.cacheName,
-                                    typeName
-                                });
-                            }
-                        }
-
-                        columns = _.sortBy(columns, 'name');
-
-                        if (!_.isEmpty(indexes)) {
-                            columns = columns.concat({
-                                type: 'indexes',
-                                name: 'Indexes',
-                                cacheName: meta.cacheName,
-                                typeName,
-                                children: indexes
-                            });
-                        }
-
-                        return {
-                            type: 'type',
-                            cacheName: meta.cacheName || '',
-                            typeName,
-                            children: columns
-                        };
-                    };
-
-                    for (const meta of caches) {
-                        const cacheTypes = meta.types.map(_typeMapper.bind(null, meta));
-
-                        if (!_.isEmpty(cacheTypes))
-                            types = types.concat(cacheTypes);
-                    }
+            // Read a zip file.
+            fs.readFile(agentPathZip, (errFs, data) => {
+                if (errFs)
+                    return res.download(agentPathZip, agentZip);
 
-                    res.json(types);
-                })
-                .catch(_handleException(res));
-        });
+                const zip = new JSZip(data);
 
-        /* Ping client. */
-        router.post('/ping', (req, res) => {
-            _client(req.currentUserId())
-                .then(() => res.sendStatus(200))
-                .catch(_handleException(res));
-        });
+                const prop = [];
 
-        /* Get JDBC drivers list. */
-        router.post('/drivers', (req, res) => {
-            _client(req.currentUserId())
-                .then((client) => client.availableDrivers())
-                .then((arr) => res.json(arr))
-                .catch(_handleException(res));
-        });
+                const host = req.hostname.match(/:/g) ? req.hostname.slice(0, req.hostname.indexOf(':')) : req.hostname;
 
-        /** Get database schemas. */
-        router.post('/schemas', (req, res) => {
-            _client(req.currentUserId())
-                .then((client) => {
-                    const args = req.body;
+                prop.push('token=' + req.user.token);
+                prop.push('server-uri=' + (settings.agent.SSLOptions ? 'https' : 'http') + '://' + host + ':' + settings.agent.port);
+                prop.push('#Uncomment following options if needed:');
+                prop.push('#node-uri=http://localhost:8080');
+                prop.push('#driver-folder=./jdbc-drivers');
 
-                    args.jdbcInfo = {user: args.user, password: args.password};
+                zip.file(agentFld + '/default.properties', prop.join('\n'));
 
-                    return client.metadataSchemas(args.jdbcDriverJar, args.jdbcDriverClass, args.jdbcUrl, args.jdbcInfo);
-                })
-                .then((arr) => res.json(arr))
-                .catch(_handleException(res));
-        });
-
-        /** Get database tables. */
-        router.post('/tables', (req, res) => {
-            _client(req.currentUserId())
-                .then((client) => {
-                    const args = req.body;
+                const buffer = zip.generate({type: 'nodebuffer', platform: 'UNIX'});
 
-                    args.jdbcInfo = {user: args.user, password: args.password};
+                // Set the archive name.
+                res.attachment(agentZip);
 
-                    return client.metadataTables(args.jdbcDriverJar, args.jdbcDriverClass, args.jdbcUrl, args.jdbcInfo, args.schemas, args.tablesOnly);
-                })
-                .then((arr) => res.json(arr))
-                .catch(_handleException(res));
+                res.send(buffer);
+            });
         });
 
         resolveFactory(router);

http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-web/src/main/js/serve/routes/profile.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/profile.js b/modules/control-center-web/src/main/js/serve/routes/profile.js
index da6b599..9d24239 100644
--- a/modules/control-center-web/src/main/js/serve/routes/profile.js
+++ b/modules/control-center-web/src/main/js/serve/routes/profile.js
@@ -21,10 +21,18 @@
 
 module.exports = {
     implements: 'profile-routes',
-    inject: ['require(lodash)', 'require(express)', 'mongo']
+    inject: ['require(lodash)', 'require(express)', 'mongo', 'agent']
 };
 
-module.exports.factory = function(_, express, mongo) {
+/**
+ *
+ * @param _
+ * @param express
+ * @param mongo
+ * @param {AgentManager} agent
+ * @returns {Promise}
+ */
+module.exports.factory = function(_, express, mongo, agent) {
     return new Promise((resolveFactory) => {
         const router = new express.Router();
 
@@ -71,6 +79,9 @@ module.exports.factory = function(_, express, mongo) {
                     });
                 })
                 .then((user) => {
+                    if (!params.token || user.token !== params.token)
+                        agent.close(user._id);
+
                     for (const param in params) {
                         if (params.hasOwnProperty(param))
                             user[param] = params[param];


[23/50] [abbrv] ignite git commit: IGNITE-2840 Refactoring to mixins.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
index 1aca477..4e11cc6 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
@@ -14,65 +14,42 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.ZooKeeper';
 
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Curator:
-            ignite-form-field-tooltip
-                | The Curator framework in use #[br]
-                | By default generates curator of org.apache.curator. framework.imps.CuratorFrameworkImpl
-                | class with configured connect string, retry policy, and default session and connection timeouts
-            ignite-form-field-java-class(
-                data-id='curator'
-                data-name='curator'
-                data-ng-model='#{model}.curator'
-            )
+        +java-class('Curator:', model + '.curator', 'curator', 'true', 'false',
+            'The Curator framework in use<br/>\
+            By default generates curator of org.apache.curator. framework.imps.CuratorFrameworkImpl\
+            class with configured connect string, retry policy, and default session and connection timeouts')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Connect string:
-            ignite-form-field-tooltip
-                | When "IGNITE_ZK_CONNECTION_STRING" system property is not configured this property will be used
-            ignite-form-field-input-text(
-                data-id='zkConnectionString'
-                data-name='zkConnectionString'
-                data-ng-model='#{model}.zkConnectionString'
-                data-placeholder='host:port[chroot][,host:port[chroot]]'
-                data-ng-required='true'
-            )
+        +text('Connect string:', model + '.zkConnectionString', 'zkConnectionString', 'true', 'host:port[chroot][,host:port[chroot]]',
+            'When "IGNITE_ZK_CONNECTION_STRING" system property is not configured this property will be used')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Retry policy:
-            ignite-form-field-tooltip
-                | Available retry policies:
-                ul: li Exponential backoff - retries a set number of times with increasing sleep time between retries
-                   li Bounded exponential backoff - retries a set number of times with an increasing (up to a maximum bound) sleep time between retries
-                    li Until elapsed - retries until a given amount of time elapses
-                    li Max number of times - retries a max number of times
-                    li Only once - retries only once
-                    li Always allow retry - retries infinitely
-                    li Custom - custom retry policy implementation
-                    li Default - exponential backoff retry policy with configured base sleep time equal to 1000ms and max retry count equal to 10
-            ignite-form-field-dropdown(
-                data-id='retryPolicy'
-                data-name='retryPolicy'
-                data-options='[\
-                    {value: "ExponentialBackoff", label: "Exponential backoff"},\
-                    {value: "BoundedExponentialBackoff", label: "Bounded exponential backoff"},\
-                    {value: "UntilElapsed", label: "Until elapsed"},\
-                    {value: "NTimes", label: "Max number of times"},\
-                    {value: "OneTime", label: "Only once"},\
-                    {value: "Forever", label: "Always allow retry"},\
-                    {value: "Custom", label: "Custom"},\
-                    {value: undefined, label: "Default"}\
-                ]'
-                data-ng-model='#{model}.retryPolicy.kind'
-                data-multiple='false'
-            )
+        +dropdown('Retry policy:', model + '.retryPolicy.kind', 'retryPolicy', 'true', 'Default',
+            '[\
+                {value: "ExponentialBackoff", label: "Exponential backoff"},\
+                {value: "BoundedExponentialBackoff", label: "Bounded exponential backoff"},\
+                {value: "UntilElapsed", label: "Until elapsed"},\
+                {value: "NTimes", label: "Max number of times"},\
+                {value: "OneTime", label: "Only once"},\
+                {value: "Forever", label: "Always allow retry"},\
+                {value: "Custom", label: "Custom"},\
+                {value: undefined, label: "Default"}\
+            ]',
+            'Available retry policies:\
+            <ul>\
+                <li>Exponential backoff - retries a set number of times with increasing sleep time between retries</li>\
+                <li>Bounded exponential backoff - retries a set number of times with an increasing (up to a maximum bound) sleep time between retries</li>\
+                <li>Until elapsed - retries until a given amount of time elapses</li>\
+                <li>Max number of times - retries a max number of times</li>\
+                <li>Only once - retries only once</li>\
+                <li>Always allow retry - retries infinitely</li>\
+                <li>Custom - custom retry policy implementation</li>\
+                <li>Default - exponential backoff retry policy with configured base sleep time equal to 1000ms and max retry count equal to 10</li>\
+            </ul>')
     .details-row(ng-if='#{model}.retryPolicy.kind')
         .panel-details.col-sm-12
             div(ng-switch='#{model}.retryPolicy.kind')
@@ -84,40 +61,13 @@ div
                 ignite-configuration-clusters-general-discovery-zookeeper-forever(ng-switch-when='Forever')
                 ignite-configuration-clusters-general-discovery-zookeeper-custom(ng-switch-when='Custom')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Base path:
-            ignite-form-field-tooltip
-                | Base path for service registration
-            ignite-form-field-input-text(
-                data-id='basePath'
-                data-name='basePath'
-                data-ng-model='#{model}.basePath'
-                data-placeholder='/services'
-            )
+        +text('Base path:', model + '.basePath', 'basePath', 'false', '/services', 'Base path for service registration')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Service name:
-            ignite-form-field-tooltip
-                | Service name to use, as defined by Curator's ServiceDiscovery recipe#[br]
-                | In physical ZooKeeper terms, it represents the node under basePath, under which services will be registered
-            ignite-form-field-input-text(
-                data-id='serviceName'
-                data-name='serviceName'
-                data-ng-model='#{model}.serviceName'
-                data-placeholder='ignite'
-            )
+        +text('Service name:', model + '.serviceName', 'serviceName', 'false', 'ignite',
+            'Service name to use, as defined by Curator&#39;s ServiceDiscovery recipe<br/>\
+            In physical ZooKeeper terms, it represents the node under basePath, under which services will be registered')
     .details-row
-        ignite-form-field.checkbox
-            ignite-form-field-input-checkbox(
-                data-id='allowDuplicateRegistrations'
-                data-name='allowDuplicateRegistrations'
-                data-ng-model='#{model}.allowDuplicateRegistrations'
-            )
-            | Allow duplicate registrations
-            ignite-form-field-tooltip
-                | Whether to register each node only once, or if duplicate registrations are allowed#[br]
-                | Nodes will attempt to register themselves, plus those they know about#[br]
-                | By default, duplicate registrations are not allowed, but you might want to set this property
-                | to #[b true] if you have multiple network interfaces or if you are facing troubles
+        +checkbox('Allow duplicate registrations', model + '.allowDuplicateRegistrations', 'allowDuplicateRegistrations',
+            'Whether to register each node only once, or if duplicate registrations are allowed<br/>\
+            Nodes will attempt to register themselves, plus those they know about<br/>\
+            By default, duplicate registrations are not allowed, but you might want to set this property to <b>true</b> if you have multiple network interfaces or if you are facing troubles')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
index db6a9d6..9a03e75 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
@@ -14,43 +14,14 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.ZooKeeper.retryPolicy.BoundedExponentialBackoff';
 
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Base interval:
-            ignite-form-field-tooltip
-                | Initial amount of time in ms to wait between retries
-            ignite-form-field-input-number(
-                data-id='baseSleepTimeMs'
-                data-name='baseSleepTimeMs'
-                data-ng-model='#{model}.baseSleepTimeMs'
-                data-placeholder='1000'
-            )
+        +number('Base interval:', model + '.baseSleepTimeMs', 'baseSleepTimeMs', 'true', '1000', '0', 'Initial amount of time in ms to wait between retries')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Max interval:
-            ignite-form-field-tooltip
-                | Max time in ms to sleep on each retry
-            ignite-form-field-input-number(
-                data-id='maxSleepTimeMs'
-                data-name='maxSleepTimeMs'
-                data-ng-model='#{model}.maxSleepTimeMs'
-                data-placeholder='Integer.MAX_VALUE'
-            )
+        +number('Max interval:', model + '.maxSleepTimeMs', 'maxSleepTimeMs', 'true', 'Integer.MAX_VALUE', '0', 'Max time in ms to sleep on each retry')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Max retries:
-            ignite-form-field-tooltip
-                | Max number of times to retry
-            ignite-form-field-input-number(
-                data-id='maxRetries'
-                data-name='maxRetries'
-                data-ng-model='#{model}.maxRetries'
-                data-placeholder='10'
-                data-max='29'
-            )
+        +number-min-max('Max retries:', model + '.maxRetries', 'maxRetries', 'true', '10', '0', '29', 'Max number of times to retry')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
index 337f2f8..f0d5311 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
@@ -14,17 +14,9 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.ZooKeeper.retryPolicy.Custom';
 
 .details-row
-    ignite-form-field
-        ignite-form-field-label
-            | Class name:
-        ignite-form-field-tooltip
-            | Custom retry policy implementation class name
-        ignite-form-field-java-class(
-            data-id='className'
-            data-name='className'
-            data-ng-model='#{model}.className'
-            data-ng-required='true'
-        )
+    +java-class('Class name:', model + '.className', 'className', 'true', 'false', 'Custom retry policy implementation class name')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
index 0e89242..729d937 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
@@ -14,43 +14,14 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.ZooKeeper.retryPolicy.ExponentialBackoff';
 
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Base interval:
-            ignite-form-field-tooltip
-                | Initial amount of time in ms to wait between retries
-            ignite-form-field-input-number(
-                data-id='baseSleepTimeMs'
-                data-name='baseSleepTimeMs'
-                data-ng-model='#{model}.baseSleepTimeMs'
-                data-placeholder='1000'
-            )
+        +number('Base interval:', model + '.baseSleepTimeMs', 'baseSleepTimeMs', 'true', '1000', '0', 'Initial amount of time in ms to wait between retries')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Max retries:
-            ignite-form-field-tooltip
-                | Max number of times to retry
-            ignite-form-field-input-number(
-                data-id='maxRetries'
-                data-name='maxRetries'
-                data-ng-model='#{model}.maxRetries'
-                data-placeholder='10'
-                data-max='29'
-            )
+        +number-min-max('Max retries:', model + '.maxRetries', 'maxRetries', 'true', '10', '0', '29', 'Max number of times to retry')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Max interval:
-            ignite-form-field-tooltip
-                | Max time in ms to sleep on each retry
-            ignite-form-field-input-number(
-                data-id='maxSleepMs'
-                data-name='maxSleepMs'
-                data-ng-model='#{model}.maxSleepMs'
-                data-placeholder='Integer.MAX_VALUE'
-            )
+        +number('Max interval:', model + '.maxSleepMs', 'maxSleepMs', 'true', 'Integer.MAX_VALUE', '0', 'Max time in ms to sleep on each retry')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
index d14ff21..f3d0957 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
@@ -14,17 +14,9 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.ZooKeeper.retryPolicy.Forever';
 
 .details-row
-    ignite-form-field
-        ignite-form-field-label
-            | Interval:
-        ignite-form-field-tooltip
-            | Time in ms between retry attempts
-        ignite-form-field-input-number(
-            data-id='retryIntervalMs'
-            data-name='retryIntervalMs'
-            data-ng-model='#{model}.retryIntervalMs'
-            data-placeholder='1000'
-        )
+    +number('Interval:', model + '.retryIntervalMs', 'retryIntervalMs', 'true', '1000', '0', 'Time in ms between retry attempts')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
index 977a028..2cb6f90 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
@@ -14,30 +14,12 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.ZooKeeper.retryPolicy.NTimes';
 
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Retries:
-            ignite-form-field-tooltip
-                | Number of times to retry
-            ignite-form-field-input-number(
-                data-id='n'
-                data-name='n'
-                data-ng-model='#{model}.n'
-                data-placeholder='10'
-            )
+        +number('Retries:', model + '.n', 'n', 'true', '10', '0', 'Number of times to retry')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Interval:
-            ignite-form-field-tooltip
-                | Time in ms between retry attempts
-            ignite-form-field-input-number(
-                data-id='sleepMsBetweenRetries'
-                data-name='sleepMsBetweenRetries'
-                data-ng-model='#{model}.sleepMsBetweenRetries'
-                data-placeholder='1000'
-            )
+        +number('Interval:', model + '.sleepMsBetweenRetries', 'sleepMsBetweenRetries', 'true', '1000', '0', 'Time in ms between retry attempts')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
index f102f7e..d1c8607 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
@@ -14,18 +14,10 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.ZooKeeper.retryPolicy.OneTime';
 
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Interval:
-            ignite-form-field-tooltip
-                | Time in ms to retry attempt
-            ignite-form-field-input-number(
-                data-id='sleepMsBetweenRetry'
-                data-name='sleepMsBetweenRetry'
-                data-ng-model='#{model}.sleepMsBetweenRetry'
-                data-placeholder='1000'
-            )
+        +number('Interval:', model + '.sleepMsBetweenRetry', 'sleepMsBetweenRetry', 'true', '1000', '0', 'Time in ms to retry attempt')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
index b5cadc7..94850df 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
@@ -14,30 +14,12 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.ZooKeeper.retryPolicy.UntilElapsed';
 
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Total time:
-            ignite-form-field-tooltip
-                | Total time in ms for execution of retry attempt
-            ignite-form-field-input-number(
-                data-id='maxElapsedTimeMs'
-                data-name='maxElapsedTimeMs'
-                data-ng-model='#{model}.maxElapsedTimeMs'
-                data-placeholder='60000'
-            )
+        +number('Total time:', model + '.maxElapsedTimeMs', 'maxElapsedTimeMs', 'true', '60000', '0', 'Total time in ms for execution of retry attempt')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Interval:
-            ignite-form-field-tooltip
-                | Time in ms between retry attempts
-            ignite-form-field-input-number(
-                data-id='sleepMsBetweenRetries'
-                data-name='sleepMsBetweenRetries'
-                data-ng-model='#{model}.sleepMsBetweenRetries'
-                data-placeholder='1000'
-            )
+        +number('Interval:', model + '.sleepMsBetweenRetries', 'sleepMsBetweenRetries', 'true', '1000', '0', 'Time in ms between retry attempts')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/igfs.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/igfs.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/igfs.jade
index 5ce730e..f326607 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/igfs.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/igfs.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem'
 
 form.panel.panel-default(name='igfs' novalidate)
@@ -27,29 +29,9 @@ form.panel.panel-default(name='igfs' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | IGFS: #[a(ui-sref='base.configuration.igfs({id: #{model}._id})') (add)]
-                        ignite-form-field-tooltip
-                            | Select IGFS to start in cluster or add a new IGFS
-                        ignite-form-field-dropdown(
-                            data-id='igfss'
-                            data-name='igfss'
-                            data-options='igfss'
-                            data-multiple='true'
-                            data-ng-model='#{model}.igfss'
-                            data-ng-disabled='!igfss.length'
-                            data-placeholder='{{ igfss.length ? "Choose IGFS": "No IGFS configured" }}'
-                        )
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='igfss' data-detail='igfss' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='igfss' data-detail='igfss' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +dropdown-multiple('<span>IGFS:</span>' +
+                        '<a ui-sref="base.configuration.igfs({id: ' + model + '._id})"> (add)</a>',
+                        model + '.igfss', 'igfss', 'Choose IGFS', 'No IGFS configured', 'igfss',
+                        'Select IGFS to start in cluster or add a new IGFS')
+            .col-sm-6
+                +preview-xml-java(model, 'igfss')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/marshaller.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/marshaller.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/marshaller.jade
index dc28bdf..6f752ed 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/marshaller.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/marshaller.jade
@@ -14,7 +14,11 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-- var model = 'backupItem.marshaller'
+include ../../../../../app/helpers/jade/mixins.jade
+
+- var model = 'backupItem'
+- var marshaller = model + '.marshaller'
+- var optMarshaller = marshaller + '.OptimizedMarshaller'
 
 form.panel.panel-default(name='marshaller' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
@@ -28,106 +32,37 @@ form.panel.panel-default(name='marshaller' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Marshaller:
-                        ignite-form-field-tooltip
-                            | Instance of marshaller to use in grid#[br]
-                            | If not provided, BinaryMarshaller will be used
-                        ignite-form-field-dropdown(
-                            data-id='kind'
-                            data-name='kind'
-                            data-options='[\
-                                {value: "OptimizedMarshaller", label: "OptimizedMarshaller"},\
-                                {value: "JdkMarshaller", label: "JdkMarshaller"},\
-                                {value: undefined, label: "Not set"}\
-                            ]'
-                            data-ng-model='#{model}.kind'
-                            data-placeholder='Choose marshaller'
-                        )
-
+                    +dropdown('Marshaller:', marshaller + '.kind', 'kind', 'true', 'Choose marshaller',
+                        '[\
+                            {value: "OptimizedMarshaller", label: "OptimizedMarshaller"},\
+                            {value: "JdkMarshaller", label: "JdkMarshaller"},\
+                            {value: undefined, label: "Not set"}\
+                        ]',
+                        'Instance of marshaller to use in grid<br/>\
+                        If not provided, BinaryMarshaller will be used')
                     a.customize(
-                        ng-if='#{model}.kind && #{model}.kind === "OptimizedMarshaller"'
-                        ng-click='#{model}.expanded = !#{model}.expanded'
-                    ) {{ #{model}.expanded ? "Hide settings" : "Show settings"}}
-
+                        ng-if='#{marshaller}.kind && #{marshaller}.kind === "OptimizedMarshaller"'
+                        ng-click='#{marshaller}.expanded = !#{marshaller}.expanded'
+                    ) {{ #{marshaller}.expanded ? "Hide settings" : "Show settings"}}
                 .settings-row
-                    .panel-details.col-sm-12(ng-if='#{model}.expanded && #{model}.kind === "OptimizedMarshaller"')
+                    .panel-details.col-sm-12(ng-if='#{marshaller}.expanded && #{marshaller}.kind === "OptimizedMarshaller"')
                         .details-row
-                            ignite-form-field
-                                ignite-form-field-label
-                                    | Streams pool size:
-                                ignite-form-field-tooltip
-                                    | Specifies size of cached object streams used by marshaller#[br]
-                                    | Object streams are cached for performance reason to avoid costly recreation for every serialization routine#[br]
-                                    | If 0 (default), pool is not used and each thread has its own cached object stream which it keeps reusing#[br]
-                                    | Since each stream has an internal buffer, creating a stream for each thread can lead to high memory consumption if many large messages are marshalled or unmarshalled concurrently#[br]
-                                    | Consider using pool in this case. This will limit number of streams that can be created and, therefore, decrease memory consumption#[br]
-                                    | NOTE: Using streams pool can decrease performance since streams will be shared between different threads which will lead to more frequent context switching
-                                ignite-form-field-input-number(
-                                    data-id='poolSize'
-                                    data-name='poolSize'
-                                    data-ng-model='#{model}.OptimizedMarshaller.poolSize'
-                                    data-placeholder='0'
-                                )
-
+                            +number('Streams pool size:', optMarshaller + '.poolSize', 'poolSize', 'true', '0', '0',
+                                'Specifies size of cached object streams used by marshaller<br/>\
+                                Object streams are cached for performance reason to avoid costly recreation for every serialization routine<br/>\
+                                If 0 (default), pool is not used and each thread has its own cached object stream which it keeps reusing<br/>\
+                                Since each stream has an internal buffer, creating a stream for each thread can lead to high memory consumption if many large messages are marshalled or unmarshalled concurrently<br/>\
+                                Consider using pool in this case. This will limit number of streams that can be created and, therefore, decrease memory consumption<br/>\
+                                NOTE: Using streams pool can decrease performance since streams will be shared between different threads which will lead to more frequent context switching')
                         .details-row
-                            ignite-form-field.checkbox
-                                ignite-form-field-input-checkbox(
-                                    data-id='requireSerializable'
-                                    data-name='requireSerializable'
-                                    data-ng-model='#{model}.OptimizedMarshaller.requireSerializable'
-                                )
-                                | Require serializable
-                                ignite-form-field-tooltip
-                                    | Whether marshaller should require Serializable interface or not
-
+                            +checkbox('Require serializable', optMarshaller + '.requireSerializable', 'requireSerializable',
+                                'Whether marshaller should require Serializable interface or not')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='marshalLocalJobs'
-                            data-name='marshalLocalJobs'
-                            data-ng-model='backupItem.marshalLocalJobs'
-                        )
-                        | Marshal local jobs
-                        ignite-form-field-tooltip
-                            | If this flag is enabled, jobs mapped to local node will be marshalled as if it was remote node
-
+                    +checkbox('Marshal local jobs', model + '.marshalLocalJobs', 'marshalLocalJobs', 'If this flag is enabled, jobs mapped to local node will be marshalled as if it was remote node')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Keep alive time:
-                        ignite-form-field-tooltip
-                            | Keep alive time of thread pool that is in charge of processing marshaller messages
-                        ignite-form-field-input-number(
-                            data-id='marshallerCacheKeepAliveTime'
-                            data-name='marshallerCacheKeepAliveTime'
-                            data-ng-model='backupItem.marshallerCacheKeepAliveTime'
-                            data-placeholder='10000'
-                        )
-
+                    +number('Keep alive time:', model + '.marshallerCacheKeepAliveTime', 'marshallerCacheKeepAliveTime', 'true', '10000', '0')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Pool size:
-                        ignite-form-field-tooltip
-                            | Default size of thread pool that is in charge of processing marshaller messages
-                        ignite-form-field-input-number(
-                            data-id='marshallerCacheThreadPoolSize'
-                            data-name='marshallerCacheThreadPoolSize'
-                            data-ng-model='backupItem.marshallerCacheThreadPoolSize'
-                            data-placeholder='max(8, availableProcessors) * 2'
-                        )
-
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterMarshaller' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterMarshaller' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +number('Pool size:', model + '.marshallerCacheThreadPoolSize', 'marshallerCacheThreadPoolSize', 'true', 'max(8, availableProcessors) * 2', '0',
+                        'Default size of thread pool that is in charge of processing marshaller messages')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterMarshaller')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/metrics.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/metrics.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/metrics.jade
index 0ed99e6..bcfe977 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/metrics.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/metrics.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem'
 
 form.panel.panel-default(name='metrics' novalidate)
@@ -27,63 +29,21 @@ form.panel.panel-default(name='metrics' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field(data-label='Elapsed time')
-                        ignite-form-field-tooltip
-                            |Time in milliseconds after which a certain metric value is considered expired
-                        ignite-form-field-input-number(
-                            data-id='metricsExpireTime'
-                            data-name='metricsExpireTime'
-                            data-ng-model='#{model}.metricsExpireTime'
-                            data-min='1'
-                            data-placeholder='Long.MAX_VALUE'
-                        )
-
+                    +number('Elapsed time:', model + '.metricsExpireTime', 'metricsExpireTime', 'true', 'Long.MAX_VALUE', '1',
+                        'Time in milliseconds after which a certain metric value is considered expired')
                 .settings-row
-                    ignite-form-field(data-label='History size')
-                        ignite-form-field-tooltip
-                            | Number of metrics kept in history to compute totals and averages
-                        ignite-form-field-input-number(
-                            data-id='metricsHistorySize'
-                            data-name='metricsHistorySize'
-                            data-ng-model='#{model}.metricsHistorySize'
-                            data-placeholder='10000'
-                            data-min='1'
-                        )
-
+                    +number('History size:', model + '.metricsHistorySize', 'metricsHistorySize', 'true', '10000', '1',
+                        'Number of metrics kept in history to compute totals and averages')
                 .settings-row
-                    ignite-form-field(data-label='Log frequency')
-                        ignite-form-field-tooltip
-                            | Frequency of metrics log print out. To disable set to 0
-                        ignite-form-field-input-number(
-                            data-id='metricsLogFrequency'
-                            data-name='metricsLogFrequency'
-                            data-ng-model='#{model}.metricsLogFrequency'
-                            data-placeholder='60000'
-                        )
-
+                    +number('Log frequency:', model + '.metricsLogFrequency', 'metricsLogFrequency', 'true', '60000', '0',
+                        'Frequency of metrics log print out. To disable set to 0')
                 .settings-row
-                    ignite-form-field(data-label='Update frequency')
-                        ignite-form-field-tooltip
-                            | Job metrics update frequency in milliseconds
-                            ul
-                                li If set to -1 job metrics are never updated
-                                li If set to 0 job metrics are updated on each job start and finish
-                                li Positive value defines the actual update frequency
-                        ignite-form-field-input-number(
-                            data-id='metricsUpdateFrequency'
-                            data-name='metricsUpdateFrequency'
-                            data-ng-model='#{model}.metricsUpdateFrequency'
-                            data-placeholder='2000'
-                        )
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterMetrics' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterMetrics' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +number('Update frequency:', model + '.metricsUpdateFrequency', 'metricsUpdateFrequency', 'true', '2000', '0',
+                        'Job metrics update frequency in milliseconds\
+                        <ul>\
+                            <li>If set to -1 job metrics are never updated</li>\
+                            <li>If set to 0 job metrics are updated on each job start and finish</li>\
+                            <li>Positive value defines the actual update frequency</li>\
+                        </ul>')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterMetrics')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/preview-panel.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/preview-panel.directive.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/preview-panel.directive.js
deleted file mode 100644
index fb67326..0000000
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/preview-panel.directive.js
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-import ace from 'ace';
-
-export default ['previewPanel', ['$interval', '$timeout', ($interval, $timeout) => {
-    let animation = {editor: null, stage: 0, start: 0, stop: 0};
-    let prevContent = [];
-
-    const Range = ace.require('ace/range').Range;
-
-    const _clearSelection = (editor) => {
-        _.forEach(editor.session.getMarkers(false), (marker) => {
-            editor.session.removeMarker(marker.id);
-        });
-    };
-
-    /**
-     * Switch to next stage of animation.
-     */
-    const _animate = () => {
-        animation.stage += animation.step;
-
-        const stage = animation.stage;
-        const editor = animation.editor;
-
-        _clearSelection(editor);
-
-        animation.selections.forEach((selection) => {
-            editor.session.addMarker(new Range(selection.start, 0, selection.stop, 0),
-                'preview-highlight-' + stage, 'line', false);
-        });
-
-        if (stage === animation.finalStage) {
-            editor.animatePromise = null;
-
-            if (animation.clearOnFinal)
-                _clearSelection(editor);
-        }
-    };
-
-    /**
-     * Selection with animation.
-     *
-     * @param editor Editor to show selection animation.
-     * @param selections Array of selection intervals.
-     * @param step Step of animation (1 or -1).
-     * @param stage Start stage of animation.
-     * @param finalStage Final stage of animation.
-     * @param clearOnFinal Boolean flat to clear selection on animation finish.
-     */
-    const _fade = (editor, selections, step, stage, finalStage, clearOnFinal) => {
-        const promise = editor.animatePromise;
-
-        if (promise) {
-            $interval.cancel(promise);
-
-            _clearSelection(editor);
-        }
-
-        animation = {editor, selections, step, stage, finalStage, clearOnFinal};
-
-        editor.animatePromise = $interval(_animate, 100, 10, false);
-    };
-
-    /**
-     * Show selections with animation.
-     *
-     * @param editor Editor to show selection.
-     * @param selections Array of selection intervals.
-     */
-    const _fadeIn = (editor, selections) => {
-        _fade(editor, selections, 1, 0, 10, false);
-    };
-
-    /**
-     * Hide selections with animation.
-     *
-     * @param editor Editor to show selection.
-     * @param selections Array of selection intervals.
-     */
-    const _fadeOut = (editor, selections) => {
-        _fade(editor, selections, -1, 10, 0, true);
-    };
-
-    const onChange = ([content, editor]) => {
-        const {clearPromise} = editor;
-        const {lines} = content;
-
-        if (content.action === 'remove')
-            prevContent = lines;
-        else if (prevContent.length > 0 && lines.length > 0 && editor.attractAttention) {
-            if (clearPromise) {
-                $timeout.cancel(clearPromise);
-
-                _clearSelection(editor);
-            }
-
-            const selections = [];
-
-            let newIx = 0;
-            let prevIx = 0;
-
-            let prevLen = prevContent.length - (prevContent[prevContent.length - 1] === '' ? 1 : 0);
-            let newLen = lines.length - (lines[lines.length - 1] === '' ? 1 : 0);
-
-            const removed = newLen < prevLen;
-
-            let skipEnd = 0;
-
-            let selected = false;
-            let scrollTo = -1;
-
-            while (lines[newLen - 1] === prevContent[prevLen - 1] && newLen > 0 && prevLen > 0) {
-                prevLen -= 1;
-                newLen -= 1;
-
-                skipEnd += 1;
-            }
-
-            while (newIx < newLen || prevIx < prevLen) {
-                let start = -1;
-                let stop = -1;
-
-                // Find an index of a first line with different text.
-                for (; (newIx < newLen || prevIx < prevLen) && start < 0; newIx++, prevIx++) {
-                    if (newIx >= newLen || prevIx >= prevLen || lines[newIx] !== prevContent[prevIx]) {
-                        start = newIx;
-
-                        break;
-                    }
-                }
-
-                if (start >= 0) {
-                    // Find an index of a last line with different text by checking last string of old and new content in reverse order.
-                    for (let i = start; i < newLen && stop < 0; i++) {
-                        for (let j = prevIx; j < prevLen && stop < 0; j++) {
-                            if (lines[i] === prevContent[j] && lines[i] !== '') {
-                                stop = i;
-
-                                newIx = i;
-                                prevIx = j;
-
-                                break;
-                            }
-                        }
-                    }
-
-                    if (stop < 0) {
-                        stop = newLen;
-
-                        newIx = newLen;
-                        prevIx = prevLen;
-                    }
-
-                    if (start === stop) {
-                        if (removed)
-                            start = Math.max(0, start - 1);
-
-                        stop = Math.min(newLen + skipEnd, stop + 1);
-                    }
-
-                    if (start <= stop) {
-                        selections.push({start, stop});
-
-                        if (!selected)
-                            scrollTo = start;
-
-                        selected = true;
-                    }
-                }
-            }
-
-            // Run clear selection one time.
-            if (selected) {
-                _fadeIn(editor, selections);
-
-                editor.clearPromise = $timeout(() => {
-                    _fadeOut(editor, selections);
-
-                    editor.clearPromise = null;
-                }, 2000);
-
-                editor.scrollToRow(scrollTo);
-            }
-
-            prevContent = [];
-        }
-        else
-            editor.attractAttention = true;
-    };
-
-
-    const link = (scope, $element, $attrs, [igniteUiAceTabs1, igniteUiAceTabs2]) => {
-        const igniteUiAceTabs = igniteUiAceTabs1 || igniteUiAceTabs2;
-
-        if (!igniteUiAceTabs)
-            return;
-
-        igniteUiAceTabs.onLoad = (editor) => {
-            editor.setReadOnly(true);
-            editor.setOption('highlightActiveLine', false);
-            editor.setAutoScrollEditorIntoView(true);
-            editor.$blockScrolling = Infinity;
-            editor.attractAttention = false;
-
-            const renderer = editor.renderer;
-
-            renderer.setHighlightGutterLine(false);
-            renderer.setShowPrintMargin(false);
-            renderer.setOption('fontSize', '10px');
-            renderer.setOption('maxLines', '50');
-
-            editor.setTheme('ace/theme/chrome');
-        };
-
-        igniteUiAceTabs.onChange = onChange;
-    };
-
-    return {
-        restrict: 'C',
-        link,
-        require: ['?igniteUiAceTabs', '?^igniteUiAceTabs']
-    };
-}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
index 39387c3..cb4ed65 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
@@ -14,44 +14,14 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var cluster = 'backupItem'
 - var enabled = 'backupItem.sslEnabled'
 - var model = cluster + '.sslContextFactory'
 - var trust = model + '.trustManagers'
 - var form = 'trustManagers'
 
-mixin trstMgrField(field, save, newItem)
-    - var reset = (newItem ? 'group.add = []' : 'field.edit = false')
-    - var resetOnEnter = (newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)')
-    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
-
-    ignite-form-field-java-class(
-        data-name='#{field}'
-        data-ng-model='#{field}'
-        data-ng-required='true'
-        data-ignite-unique='#{trust}'
-        data-ignite-form-field-input-autofocus='true'
-        on-enter='#{valid} && (#{save}); #{valid} && #{resetOnEnter};'
-        on-escape='#{reset}'
-        ng-blur='#{valid} && (#{save}); #{resetOnBlur};'
-    )
-        block
-
-mixin trstMgrSaveBtn(valid, save, reset)
-    i.fa.fa-floppy-o(
-        ng-show='#{valid}'
-        ng-click='#{valid} && (#{save}); #{valid} && (#{reset});'
-        bs-tooltip
-        data-title='Click icon or press [Enter] to save item'
-    )
-
-mixin trstMgrFeedbackUnique(field)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='!#{form}.#{field}.$pristine && #{form}.#{field}.$error.igniteUnique'
-        bs-tooltip
-        data-title='Such trust manager already exists!'
-    )
-
 form.panel.panel-default(name='#{form}' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
         ignite-form-panel-chevron
@@ -63,80 +33,24 @@ form.panel.panel-default(name='#{form}' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='sslEnabled'
-                            data-name='sslEnabled'
-                            data-ng-model='#{enabled}'
-                        )
-                        | Enabled
-                        ignite-form-field-tooltip
-                            | Flag indicating whether to configure SSL configuration
-                
+                    +checkbox('Enabled', enabled, 'sslEnabled', 'Flag indicating whether to configure SSL configuration')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Algorithm to create a key manager:
-                        ignite-form-field-tooltip
-                            | Sets key manager algorithm that will be used to create a key manager,#[br]
-                            | Notice that in most cased default value suites well, however, on Android platform this value need to be set to X509
-                        ignite-form-field-input-datalist(
-                            data-id='keyAlgorithm'
-                            data-name='keyAlgorithm'
-                            data-options='["SumX509", "X509"]'
-                            data-ng-model='#{model}.keyAlgorithm'
-                            data-placeholder='SumX509'
-                            data-ng-disabled='!#{enabled}'
-                        )
-
+                    +text-options('Algorithm to create a key manager:', model + '.keyAlgorithm', 'keyAlgorithm', '["SumX509", "X509"]', enabled, 'SumX509',
+                        'Sets key manager algorithm that will be used to create a key manager<br/>\
+                        Notice that in most cased default value suites well, however, on Android platform this value need to be set to X509')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Key store file:
-                        ignite-form-field-tooltip
-                            | Path to the key store file,#[br]
-                            | This is a mandatory parameter since ssl context could not be initialized without key manager
-                        ignite-form-field-input-text(
-                            data-id='keyStoreFilePath'
-                            data-name='keyStoreFilePath'
-                            data-ng-model='#{model}.keyStoreFilePath'
-                            data-placeholder='Path to the key store file'
-                            data-ng-required='#{enabled}'
-                            data-ng-disabled='!#{enabled}'
-                        )
-
+                    +text-enabled('Key store file:', model + '.keyStoreFilePath', 'keyStoreFilePath', enabled, enabled, 'Path to the key store file',
+                        'Path to the key store file<br/>\
+                        This is a mandatory parameter since ssl context could not be initialized without key manager')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Key store type:
-                        ignite-form-field-tooltip
-                            | Key store type used in context initialization
-                        ignite-form-field-input-datalist(
-                            data-id='keyStoreType'
-                            data-name='keyStoreType'
-                            data-options='["JKS", "PCKS11", "PCKS12"]'
-                            data-ng-model='#{model}.keyStoreType'
-                            data-placeholder='JKS'
-                            data-ng-disabled='!#{enabled}'
-                        )
-
+                    +text-options('Key store type:', model + '.keyStoreType', 'keyStoreType', '["JKS", "PCKS11", "PCKS12"]', enabled, 'JKS',
+                        'Key store type used in context initialization')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Protocol:
-                        ignite-form-field-tooltip
-                            | Protocol for secure transport
-                        ignite-form-field-input-datalist(
-                            data-id='protocol'
-                            data-name='protocol'
-                            data-options='["TSL", "SSL"]'
-                            data-ng-model='#{model}.protocol'
-                            data-placeholder='TSL'
-                            data-ng-disabled='!#{enabled}'
-                        )
-
+                    +text-options('Protocol:', model + '.protocol', 'protocol', '["TSL", "SSL"]', enabled, 'TSL', 'Protocol for secure transport')
                 .settings-row
                     ignite-form-group(ng-form='trustManagers' ng-model='#{trust}')
+                        - var uniqueTip = 'Such trust manager already exists!'
+
                         ignite-form-field-label
                             | Trust managers
                         ignite-form-group-tooltip
@@ -152,72 +66,31 @@ form.panel.panel-default(name='#{form}' novalidate)
 
                             ignite-form-field(ng-repeat='model in #{trust} track by $index' type='internal' name='Trust manager')
                                 .indexField
-                                    | {{ $index+1 }}) 
-                                i.tipField.fa.fa-remove(
-                                    ng-show='#{enabled}'
-                                    ng-hide='field.edit'
-                                    bs-tooltip='"Remove trust manager"'
-                                    ng-click='#{enabled} && (#{trust}.splice(#{trust}.indexOf(model), 1))'
-                                )
+                                    | {{ $index+1 }})
+                                +table-remove-conditional-button(trust, enabled, 'Remove trust manager')
                                 span(ng-hide='field.edit')
                                     a.labelFormField(ng-click='#{enabled} && (field.edit = true)') {{ model }}
                                 span(ng-if='field.edit' ng-init='#{field} = model')
-                                    +trstMgrField(field, save, false)
-                                        +trstMgrSaveBtn(valid, save, reset)
-                                        +trstMgrFeedbackUnique(field)
+                                    +table-java-class-field(field, trust, save, false)
+                                        +table-save-button(valid, save, false)
+                                        +table-feedback-unique(form, field, uniqueTip)
 
                         .group-content(ng-repeat='field in group.add')
                             - var field = 'new'
                             - var valid = form + '.' + field + '.$valid'
                             - var save = trust + '.push(' + field + ')'
-                            - var reset = 'group.add = []'
 
                             ignite-form-field(type='internal' name='Trust manager')
-                                +trstMgrField(field, save, true)
-                                    +trstMgrSaveBtn(valid, save, reset)
-                                    +trstMgrFeedbackUnique(field)
+                                +table-java-class-field(field, trust, save, true)
+                                    +table-save-button(valid, save, true)
+                                    +table-feedback-unique(form, field, uniqueTip)
 
                         .group-content-empty(ng-if='!(#{trust}.length) && !group.add.length')
                             | Not defined
 
                 .settings-row(ng-if='!#{trust}.length')
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Trust store file:
-                        ignite-form-field-tooltip
-                            | Path to the trust store file
-                        ignite-form-field-input-text(
-                            data-id='trustStoreFilePath'
-                            data-name='trustStoreFilePath'
-                            data-ng-model='#{model}.trustStoreFilePath'
-                            data-placeholder='Path to the trust store file'
-                            data-ng-disabled='!#{enabled}'
-                        )
-
+                    +text-enabled('Trust store file:', model + '.trustStoreFilePath', 'trustStoreFilePath', enabled, 'false', 'Path to the trust store file', 'Path to the trust store file')
                 .settings-row(ng-if='!#{trust}.length')
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Trust store type:
-                        ignite-form-field-tooltip
-                            | Trust store type used in context initialization
-                        ignite-form-field-input-datalist(
-                            data-id='trustStoreType'
-                            data-name='trustStoreType'
-                            data-options='["JKS", "PCKS11", "PCKS12"]'
-                            data-ng-model='#{model}.trustStoreType'
-                            data-placeholder='JKS'
-                            data-ng-disabled='!#{enabled}'
-                        )                        
- 
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterSsl' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterSsl' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +text-options('Trust store type:', model + '.trustStoreType', 'trustStoreType', '["JKS", "PCKS11", "PCKS12"]', enabled, 'JKS', 'Trust store type used in context initialization')
+            .col-sm-6
+                +preview-xml-java(cluster, 'clusterSsl')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
index 22a3725..0672c22 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
@@ -14,7 +14,11 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-- var model = 'backupItem.swapSpaceSpi'
+include ../../../../../app/helpers/jade/mixins.jade
+
+- var model = 'backupItem'
+- var swapModel = model + '.swapSpaceSpi'
+- var fileSwapModel = swapModel + '.FileSwapSpaceSpi'
 
 form.panel.panel-default(name='swapSpaceSpi' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
@@ -27,106 +31,36 @@ form.panel.panel-default(name='swapSpaceSpi' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Swap space SPI:
-                        ignite-form-field-tooltip
-                            | Provides a mechanism in grid for storing data on disk#[br]
-                            | Ignite cache uses swap space to overflow data to disk if it cannot fit in memory
-                        ignite-form-field-dropdown(
-                            data-id='swapSpaceSpi'
-                            data-name='swapSpaceSpi'
-                            data-options='[\
-                                {value: "FileSwapSpaceSpi", label: "File-based swap"},\
-                                {value: undefined, label: "Not set"}\
-                            ]'
-                            data-ng-model='#{model}.kind'
-                            data-placeholder='Choose swap SPI'
-                        )
-                        
+                    +dropdown('Swap space SPI:', swapModel + '.kind', 'swapSpaceSpi', 'true', 'Choose swap SPI',
+                        '[\
+                            {value: "FileSwapSpaceSpi", label: "File-based swap"},\
+                            {value: undefined, label: "Not set"}\
+                        ]',
+                        'Provides a mechanism in grid for storing data on disk<br/>\
+                        Ignite cache uses swap space to overflow data to disk if it cannot fit in memory')
                     a.customize(
-                        ng-if='#{model}.kind'
-                        ng-click='#{model}.expanded = !#{model}.expanded'
-                    ) {{ #{model}.expanded ? "Hide settings" : "Show settings"}}
-
+                        ng-if='#{swapModel}.kind'
+                        ng-click='#{swapModel}.expanded = !#{swapModel}.expanded'
+                    ) {{ #{swapModel}.expanded ? "Hide settings" : "Show settings"}}
                 .settings-row
-                    .panel-details.col-sm-12(ng-if='#{model}.expanded && #{model}.kind')
+                    .panel-details.col-sm-12(ng-if='#{swapModel}.expanded && #{swapModel}.kind')
                         .details-row
-                            ignite-form-field
-                                ignite-form-field-label
-                                    | Base directory:
-                                ignite-form-field-tooltip
-                                    | Base directory where to write files
-                                ignite-form-field-input-text(
-                                    data-id='baseDirectory'
-                                    data-name='baseDirectory'
-                                    data-ng-model='#{model}.FileSwapSpaceSpi.baseDirectory'
-                                    data-placeholder='swapspace'
-                                )
+                            +text('Base directory:', fileSwapModel + '.baseDirectory', 'baseDirectory', 'false', 'swapspace',
+                                'Base directory where to write files')
                         .details-row
-                            ignite-form-field
-                                ignite-form-field-label
-                                    | Read stripe size:
-                                ignite-form-field-tooltip
-                                    | Read stripe size defines number of file channels to be used concurrently
-                                ignite-form-field-input-number(
-                                    data-id='readStripesNumber'
-                                    data-name='readStripesNumber'
-                                    data-ng-model='#{model}.FileSwapSpaceSpi.readStripesNumber'
-                                    data-placeholder='availableProcessors'
-                                )
+                            +number('Read stripe size:', fileSwapModel + '.readStripesNumber', 'readStripesNumber', 'true', 'availableProcessors', '0',
+                                'Read stripe size defines number of file channels to be used concurrently')
                         .details-row
-                            ignite-form-field
-                                ignite-form-field-label
-                                    | Maximum sparsity:
-                                ignite-form-field-tooltip
-                                    | This property defines maximum acceptable wasted file space to whole file size ratio#[br]
-                                    | When this ratio becomes higher than specified number compacting thread starts working
-                                ignite-form-field-input-number(
-                                    data-id='maximumSparsity'
-                                    data-name='maximumSparsity'
-                                    data-ng-model='#{model}.FileSwapSpaceSpi.maximumSparsity'
-                                    data-placeholder='0.5'
-                                    data-max='0.999'
-                                    data-min='0'
-                                )
+                            +number-min-max-step('Maximum sparsity:', fileSwapModel + '.maximumSparsity', maximumSparsity, 'true', '0.5', '0', '0.999', '0.05',
+                                'This property defines maximum acceptable wasted file space to whole file size ratio<br/>\
+                                When this ratio becomes higher than specified number compacting thread starts working')
                         .details-row
-                            ignite-form-field
-                                ignite-form-field-label
-                                    | Max write queue size:
-                                ignite-form-field-tooltip
-                                    | Max write queue size in bytes#[br]
-                                    | If there are more values are waiting for being written to disk then specified size, SPI will block on store operation
-                                ignite-form-field-input-number(
-                                    data-id='maxWriteQueueSize'
-                                    data-name='maxWriteQueueSize'
-                                    data-ng-model='#{model}.FileSwapSpaceSpi.maxWriteQueueSize'
-                                    data-placeholder='1024 * 1024'
-                                )
+                            +number('Max write queue size:', fileSwapModel + '.maxWriteQueueSize', 'maxWriteQueueSize', 'true', '1024 * 1024', '0',
+                                'Max write queue size in bytes<br/>\
+                                If there are more values are waiting for being written to disk then specified size, SPI will block on store operation')
                         .details-row
-                            ignite-form-field
-                                ignite-form-field-label
-                                    | Write buffer size:
-                                ignite-form-field-tooltip
-                                    | Write buffer size in bytes#[br]
-                                    | Write to disk occurs only when this buffer is full
-                                ignite-form-field-input-number(
-                                    data-id='writeBufferSize'
-                                    data-name='writeBufferSize'
-                                    data-ng-model='#{model}.FileSwapSpaceSpi.writeBufferSize'
-                                    data-placeholder='64 * 1024'
-                                )
-
-
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterSwap' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterSwap' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                            +number('Write buffer size:', fileSwapModel + '.writeBufferSize', 'writeBufferSize', 'true', '64 * 1024', '0',
+                                'Write buffer size in bytes<br/>\
+                                Write to disk occurs only when this buffer is full')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterSwap')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
index cabcab2..ad526ed 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem'
 
 form.panel.panel-default(name='thread' novalidate)
@@ -27,69 +29,19 @@ form.panel.panel-default(name='thread' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field(data-label='Public')
-                        ignite-form-field-tooltip
-                            | Thread pool that is in charge of processing ComputeJob, GridJobs and user messages sent to node
-                        ignite-form-field-input-number(
-                            data-id='publicThreadPoolSize'
-                            data-name='publicThreadPoolSize'
-                            data-ng-model='#{model}.publicThreadPoolSize'
-                            data-placeholder='max(8, availableProcessors) * 2'
-                            data-min='1'
-                        )
+                    +number('Public:', model + '.publicThreadPoolSize', 'publicThreadPoolSize', 'true', 'max(8, availableProcessors) * 2', '1',
+                        'Thread pool that is in charge of processing ComputeJob, GridJobs and user messages sent to node')
                 .settings-row
-                    ignite-form-field(data-label='System')
-                        ignite-form-field-tooltip
-                            | Thread pool that is in charge of processing internal system messages
-                        ignite-form-field-input-number(
-                            data-id='systemThreadPoolSize'
-                            data-name='systemThreadPoolSize'
-                            data-ng-model='#{model}.systemThreadPoolSize'
-                            data-placeholder='max(8, availableProcessors) * 2'
-                            data-min='1'
-                        )
+                    +number('System:', model + '.systemThreadPoolSize', 'systemThreadPoolSize', 'true', 'max(8, availableProcessors) * 2', '1',
+                        'Thread pool that is in charge of processing internal system messages')
                 .settings-row
-                    ignite-form-field(data-label='Management')
-                        ignite-form-field-tooltip
-                            | Thread pool that is in charge of processing internal and Visor ComputeJob, GridJobs
-                        ignite-form-field-input-number(
-                            data-id='managementThreadPoolSize'
-                            data-name='managementThreadPoolSize'
-                            data-ng-model='#{model}.managementThreadPoolSize'
-                            data-placeholder='4'
-                            data-min='1'
-                        )
+                    +number('Management:', model + '.managementThreadPoolSize', 'managementThreadPoolSize', 'true', '4', '1',
+                        'Thread pool that is in charge of processing internal and Visor ComputeJob, GridJobs')
                 .settings-row
-                    ignite-form-field(data-label='IGFS')
-                        ignite-form-field-tooltip
-                            | Thread pool that is in charge of processing outgoing IGFS messages
-                        ignite-form-field-input-number(
-                            data-id='igfsThreadPoolSize'
-                            data-name='igfsThreadPoolSize'
-                            data-ng-model='#{model}.igfsThreadPoolSize'
-                            data-placeholder='availableProcessors'
-                            data-min='1'
-                        )
+                    +number('IGFS:', model + '.igfsThreadPoolSize', 'igfsThreadPoolSize', 'true', 'availableProcessors', '1',
+                        'Thread pool that is in charge of processing outgoing IGFS messages')
                 .settings-row
-                    ignite-form-field(data-label='Rebalance')
-                        ignite-form-field-tooltip
-                            | Max count of threads can be used at rebalancing
-                        ignite-form-field-input-number(
-                            data-id='rebalanceThreadPoolSize'
-                            data-name='rebalanceThreadPoolSize'
-                            data-ng-model='#{model}.rebalanceThreadPoolSize'
-                            data-placeholder='1'
-                            data-min='1'
-                        )
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterPools' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterPools' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +number('Rebalance:', model + '.rebalanceThreadPoolSize', 'rebalanceThreadPoolSize', 'true', '1', '1',
+                        'Max count of threads can be used at rebalancing')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterPools')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/time.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/time.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/time.jade
index 239a820..cade190 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/time.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/time.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem'
 
 form.panel.panel-default(name='time' novalidate)
@@ -27,67 +29,18 @@ form.panel.panel-default(name='time' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Samples size
-                        ignite-form-field-tooltip
-                            | Number of samples used to synchronize clocks between different nodes#[br]
-                            | Clock synchronization is used for cache version assignment in CLOCK order mode
-                        ignite-form-field-input-number(
-                            data-id='clockSyncSamples'
-                            data-name='clockSyncSamples'
-                            data-ng-model='#{model}.clockSyncSamples'
-                            data-placeholder='8'
-                        )
+                    +number('Samples size:', model + '.clockSyncSamples', 'clockSyncSamples', 'true', '8', '0',
+                        'Number of samples used to synchronize clocks between different nodes<br/>\
+                        Clock synchronization is used for cache version assignment in CLOCK order mode')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Frequency
-                        ignite-form-field-tooltip
-                            | Frequency at which clock is synchronized between nodes, in milliseconds#[br]
-                            | Clock synchronization is used for cache version assignment in CLOCK order mode
-                        ignite-form-field-input-number(
-                            data-id='clockSyncFrequency'
-                            data-name='clockSyncFrequency'
-                            data-ng-model='#{model}.clockSyncFrequency'
-                            data-placeholder='120000'
-                        )
+                    +number('Frequency:', model + '.clockSyncFrequency', 'clockSyncFrequency', 'true', '120000', '0',
+                        'Frequency at which clock is synchronized between nodes, in milliseconds<br/>\
+                        Clock synchronization is used for cache version assignment in CLOCK order mode')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Port base
-                        ignite-form-field-tooltip
-                            | Time server provides clock synchronization between nodes#[br]
-                            | Base UPD port number for grid time server. Time server will be started on one of free ports in range
-                        ignite-form-field-input-number(
-                            data-id='timeServerPortBase'
-                            data-name='timeServerPortBase'
-                            data-ng-model='#{model}.timeServerPortBase'
-                            data-placeholder='31100'
-                            data-max='65535'
-                        )
+                    +number-min-max('Port base:', model + '.timeServerPortBase', 'timeServerPortBase', 'true', '31100', '0', '65535',
+                        'Time server provides clock synchronization between nodes<br/>\
+                        Base UPD port number for grid time server. Time server will be started on one of free ports in range')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Port range
-                        ignite-form-field-tooltip
-                            | Time server port range
-                        ignite-form-field-input-number(
-                            data-id='timeServerPortRange'
-                            data-name='timeServerPortRange'
-                            data-ng-model='#{model}.timeServerPortRange'
-                            data-placeholder='100'
-                            data-min='1'
-                        )
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterTime' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterTime' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +number('Port range:', model + '.timeServerPortRange', 'timeServerPortRange', 'true', '100', '1', 'Time server port range')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterTime')


[31/50] [abbrv] ignite git commit: IGNITE-2597 Minor fix.

Posted by an...@apache.org.
IGNITE-2597 Minor fix.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1c3c17c5
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1c3c17c5
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1c3c17c5

Branch: refs/heads/ignite-2875
Commit: 1c3c17c54bc3975339b86f77ea5df4844a30b106
Parents: 767529b
Author: Andrey <an...@gridgain.com>
Authored: Wed Mar 23 10:20:43 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Wed Mar 23 10:20:43 2016 +0700

----------------------------------------------------------------------
 .../ui-ace-pojos/ui-ace-pojos.controller.js           | 14 ++++++++++----
 .../src/main/js/app/filters/hasPojo.filter.js         |  2 +-
 .../src/main/js/app/modules/ace.module.js             |  5 ++++-
 3 files changed, 15 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1c3c17c5/modules/control-center-web/src/main/js/app/directives/ui-ace-pojos/ui-ace-pojos.controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/ui-ace-pojos/ui-ace-pojos.controller.js b/modules/control-center-web/src/main/js/app/directives/ui-ace-pojos/ui-ace-pojos.controller.js
index 1fe1c11..bc185b3 100644
--- a/modules/control-center-web/src/main/js/app/directives/ui-ace-pojos/ui-ace-pojos.controller.js
+++ b/modules/control-center-web/src/main/js/app/directives/ui-ace-pojos/ui-ace-pojos.controller.js
@@ -69,11 +69,17 @@ export default ['$scope', 'JavaTypes', 'GeneratorJava', function($scope, JavaTyp
             return;
 
         _.forEach(ctrl.pojos, (pojo) => {
-            if (pojo.keyType === ctrl.class)
-                return ctrl.data = pojo.keyClass;
+            if (pojo.keyType === ctrl.class) {
+                ctrl.data = pojo.keyClass;
 
-            if (pojo.valueType === ctrl.class)
-                return ctrl.data = pojo.valueClass;
+                return false;
+            }
+
+            if (pojo.valueType === ctrl.class) {
+                ctrl.data = pojo.valueClass;
+
+                return false;
+            }
         });
     };
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1c3c17c5/modules/control-center-web/src/main/js/app/filters/hasPojo.filter.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/filters/hasPojo.filter.js b/modules/control-center-web/src/main/js/app/filters/hasPojo.filter.js
index 3ccbf22..a179423 100644
--- a/modules/control-center-web/src/main/js/app/filters/hasPojo.filter.js
+++ b/modules/control-center-web/src/main/js/app/filters/hasPojo.filter.js
@@ -15,4 +15,4 @@
  * limitations under the License.
  */
 
-export default ['hasPojo', [() => ({caches}) => _.find(caches, (cache) => cache.domains && cache.domains.length)]];
+export default ['hasPojo', [() => ({caches} = []) => _.find(caches, (cache) => cache.domains && cache.domains.length)]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/1c3c17c5/modules/control-center-web/src/main/js/app/modules/ace.module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/ace.module.js b/modules/control-center-web/src/main/js/app/modules/ace.module.js
index 8a9024e..d747ccf 100644
--- a/modules/control-center-web/src/main/js/app/modules/ace.module.js
+++ b/modules/control-center-web/src/main/js/app/modules/ace.module.js
@@ -125,7 +125,10 @@ angular
             }
 
             // onLoad callbacks.
-            _.forEach(opts.callbacks, (cb) => angular.isFunction(cb) && cb(acee));
+            _.forEach(opts.callbacks, (cb) => {
+                if (angular.isFunction(cb))
+                    cb(acee)
+            });
         };
 
         return {


[25/50] [abbrv] ignite git commit: IGNITE-2840 Refactoring to mixins.

Posted by an...@apache.org.
 IGNITE-2840 Refactoring to mixins.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f8a690ec
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f8a690ec
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f8a690ec

Branch: refs/heads/ignite-2875
Commit: f8a690ece50012520ca5ff05da4741c19228d2c5
Parents: 94632f2
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Mon Mar 21 18:26:05 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Mar 21 18:26:05 2016 +0700

----------------------------------------------------------------------
 .../ui-ace-java/ui-ace-java.directive.js        |   5 -
 .../ui-ace-xml/ui-ace-xml.directive.js          |   5 -
 .../src/main/js/app/helpers/jade/mixins.jade    | 120 ++++++-
 .../form/field/input/number.directive.js        |   1 +
 .../js/app/modules/form/field/input/number.jade |   1 +
 .../app/modules/states/configuration.state.js   |   5 +-
 .../states/configuration/clusters/atomic.jade   |  74 ++---
 .../states/configuration/clusters/binary.jade   | 120 ++-----
 .../configuration/clusters/communication.jade   | 332 +++----------------
 .../configuration/clusters/connector.jade       | 314 +++---------------
 .../configuration/clusters/deployment.jade      | 181 +++-------
 .../configuration/clusters/discovery.jade       | 296 ++---------------
 .../states/configuration/clusters/events.jade   |  33 +-
 .../states/configuration/clusters/general.jade  |  89 ++---
 .../clusters/general/discovery/cloud.jade       | 229 ++++---------
 .../clusters/general/discovery/google.jade      |  59 +---
 .../clusters/general/discovery/jdbc.jade        |  13 +-
 .../clusters/general/discovery/multicast.jade   | 159 ++-------
 .../clusters/general/discovery/s3.jade          |  14 +-
 .../clusters/general/discovery/shared.jade      |  12 +-
 .../clusters/general/discovery/vm.jade          | 100 ++----
 .../clusters/general/discovery/zookeeper.jade   | 126 +++----
 .../bounded-exponential-backoff.jade            |  39 +--
 .../discovery/zookeeper/retrypolicy/custom.jade |  14 +-
 .../retrypolicy/exponential-backoff.jade        |  39 +--
 .../zookeeper/retrypolicy/forever.jade          |  14 +-
 .../zookeeper/retrypolicy/n-times.jade          |  26 +-
 .../zookeeper/retrypolicy/one-time.jade         |  14 +-
 .../zookeeper/retrypolicy/until-elapsed.jade    |  26 +-
 .../states/configuration/clusters/igfs.jade     |  34 +-
 .../configuration/clusters/marshaller.jade      | 129 ++-----
 .../states/configuration/clusters/metrics.jade  |  74 +----
 .../clusters/preview-panel.directive.js         | 239 -------------
 .../states/configuration/clusters/ssl.jade      | 179 ++--------
 .../states/configuration/clusters/swap.jade     | 128 ++-----
 .../states/configuration/clusters/thread.jade   |  76 +----
 .../states/configuration/clusters/time.jade     |  75 +----
 .../configuration/clusters/transactions.jade    | 111 ++-----
 .../configuration/preview-panel.directive.js    | 239 +++++++++++++
 .../main/js/controllers/clusters-controller.js  |   7 +-
 .../main/js/helpers/generator/generator-java.js | 110 +++---
 .../main/js/helpers/generator/generator-xml.js  |  92 +++--
 .../main/js/views/configuration/clusters.jade   |   2 +-
 43 files changed, 1063 insertions(+), 2892 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js b/modules/control-center-web/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
index 617cfbe..77cb774 100644
--- a/modules/control-center-web/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
@@ -64,11 +64,6 @@ export default ['igniteUiAceJava', ['GeneratorJava', (generator) => {
 
                     break;
 
-                case 'clusterDiscovery':
-                    ctrl.generator = (cluster) => generator.clusterDiscovery(cluster.discovery).asString();
-
-                    break;
-
                 case 'igfss':
                     ctrl.generator = (cluster) => {
                         const igfss = _.reduce(scope.detail, (acc, igfs) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js b/modules/control-center-web/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
index b379404..215c1b9 100644
--- a/modules/control-center-web/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
@@ -64,11 +64,6 @@ export default ['igniteUiAceXml', ['GeneratorXml', (generator) => {
 
                     break;
 
-                case 'clusterDiscovery':
-                    ctrl.generator = (cluster) => generator.clusterDiscovery(cluster.discovery).asString();
-
-                    break;
-
                 case 'igfss':
                     ctrl.generator = (cluster) => {
                         const igfss = _.reduce(scope.detail, (acc, igfs) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
index 0c4e140..2fd0270 100644
--- a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
+++ b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
@@ -55,6 +55,22 @@ mixin java-class(lbl, model, name, enabled, required, tip)
         )
 
 //- Mixin for text field.
+mixin text-ip-address(lbl, model, name, enabled, placeholder, tip)
+    ignite-form-field
+        ignite-form-field-label
+            | #{lbl}
+        ignite-form-field-tooltip
+            | !{tip}
+        ignite-form-field-input-text(
+            data-id=name
+            data-name=name
+            data-ng-model=model
+            data-ipaddress='true'
+            data-ng-disabled='!(#{enabled})'
+            data-placeholder=placeholder
+        )
+
+//- Mixin for text field.
 mixin text-enabled(lbl, model, name, enabled, required, placeholder, tip)
     ignite-form-field
         ignite-form-field-label
@@ -81,7 +97,7 @@ mixin text-options(lbl, model, name, options, enabled, placeholder, tip)
             | #{lbl}
         ignite-form-field-tooltip
             | !{tip}
-        ignite-form-field-input-text(
+        ignite-form-field-input-datalist(
             data-id=name
             data-name=name
             data-ng-model=model
@@ -109,6 +125,10 @@ mixin number-requited(lbl, model, name, required, enabled, placeholder, min, tip
 
 //- Mixin for required numeric field with maximum and minimum limit.
 mixin number-min-max(lbl, model, name, enabled, placeholder, min, max, tip)
+    +number-min-max-step(lbl, model, name, enabled, placeholder, min, max, '1', tip)
+
+//- Mixin for required numeric field with maximum and minimum limit.
+mixin number-min-max-step(lbl, model, name, enabled, placeholder, min, max, step, tip)
     ignite-form-field
         ignite-form-field-label
             | #{lbl}
@@ -122,6 +142,7 @@ mixin number-min-max(lbl, model, name, enabled, placeholder, min, max, tip)
             data-placeholder=placeholder
             data-min=min
             data-max=max
+            data-step=step
         )
 
 //- Mixin for numeric field.
@@ -169,11 +190,11 @@ mixin dropdown-multiple(lbl, model, name, placeholder, placeholderEmpty, options
 
 //- Mixin for table java class field.
 mixin table-java-class-field(field, items, save, newItem)
-    - var reset = (newItem ? 'group.add = []' : 'field.edit = false')
-
     - var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     - var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
+    - var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+
     - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
     - var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
@@ -184,15 +205,87 @@ mixin table-java-class-field(field, items, save, newItem)
         data-ignite-unique=items
         data-ignite-form-field-input-autofocus='true'
         on-enter=onEnter
+        on-escape=onEscape
+        ng-blur=onBlur
+    )
+        block
+
+//- Mixin for table java package field.
+mixin table-java-package-field(field, items, save, newItem)
+    - var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+    - var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+
+    - var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+
+    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    - var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+
+    ignite-form-field-input-text(
+        data-name=field
+        data-ng-model=field
+        data-ng-required='true'
+        data-placeholder='Enter package name'
+        data-java-keywords='true'
+        data-java-package-name='true'
+        data-ignite-unique=items
+        data-ignite-form-field-input-autofocus='true'
+        on-enter=onEnter
+        on-escape=onEscape
+        ng-blur=onBlur
+    )
+        block
+
+//- Mixin for table text field.
+mixin table-text-field(field, items, save, placeholder, newItem)
+    - var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+    - var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+
+    - var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+
+    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    - var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+
+    ignite-form-field-input-text(
+        data-name=field
+        data-ng-model=field
+        data-ng-required='true'
+        data-placeholder=placeholder
+        data-ignite-unique=items
+        data-ignite-form-field-input-autofocus='true'
+        on-enter=onEnter
+        on-escape=onEscape
+        ng-blur=onBlur
+    )
+        block
+
+//- Mixin for table address field.
+mixin table-address-field(field, items, save, newItem)
+    - var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+    - var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+
+    - var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+
+    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    - var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+
+    ignite-form-field-input-text(
+        data-name=field
+        data-ng-model=field
+        data-ng-required='true'
+        data-placeholder='IP address:port'
+        data-ipaddress='true'
+        data-ignite-unique=items
+        data-ignite-form-field-input-autofocus='true'
+        on-enter=onEnter
+        on-escape=onEscape
         ng-blur=onBlur
-        on-escape=reset
     )
         block
 
 //- Mixin for table save button.
 mixin table-save-button(valid, save, newItem)
     - var reset = (newItem ? 'group.add = []' : 'field.edit = false')
-    - var onClick = valid + ' && ' + save + '; ' + valid  + '&& (' + reset + ');'
+    - var onClick = valid + ' && ' + save + '; ' + valid  + ' && (' + reset + ');'
 
     i.fa.fa-floppy-o(
         ng-show=valid
@@ -202,19 +295,30 @@ mixin table-save-button(valid, save, newItem)
     )
 
 //- Mixin for table remove button.
-mixin table-remove-button(items, tip)
+mixin table-remove-conditional-button(items, show, tip)
     i.tipField.fa.fa-remove(
+        ng-show='#{show}'
         ng-hide='field.edit'
         bs-tooltip='"#{tip}"'
         ng-click='#{items}.splice(#{items}.indexOf(model), 1)'
     )
 
+//- Mixin for table remove button.
+mixin table-remove-button(items, tip)
+    +table-remove-conditional-button(items, 'true', tip)
+
 //- Mixin for table feedback for unique validator.
 mixin table-feedback-unique(from, field, tip)
-    - var formField = form + '.' + field
+    i.fa.fa-exclamation-triangle.form-control-feedback(
+        ng-show=form + '.' + field + '.$error.igniteUnique'
+        bs-tooltip
+        data-title=tip
+    )
 
+//- Mixin for table feedback for valid host name / IP address.
+mixin table-feedback-ip-address(from, field, tip)
     i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='!' + formField + '.$pristine && ' + formField + '.$error.igniteUnique'
+        ng-show=form + '.' + field + '.$error.ipaddress'
         bs-tooltip
         data-title=tip
     )

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/form/field/input/number.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/number.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/input/number.directive.js
index cc135b5..cc2dd31 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/number.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/number.directive.js
@@ -54,6 +54,7 @@ export default ['igniteFormFieldInputNumber', ['IgniteFormGUID', (guid) => {
 
             min: '@',
             max: '@',
+            step: '@',
             value: '=ngModel'
         },
         link,

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/form/field/input/number.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/number.jade b/modules/control-center-web/src/main/js/app/modules/form/field/input/number.jade
index 4429d30..3caf020 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/number.jade
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/number.jade
@@ -30,6 +30,7 @@ mixin feedback(error, message)
         type='number'
         min='{{ min || 0 }}'
         max='{{ max || Number.MAX_VALUE }}'
+        step='{{ step || 1 }}'
 
         data-ng-model='value'
         data-ng-required='required || false'

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration.state.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration.state.js b/modules/control-center-web/src/main/js/app/modules/states/configuration.state.js
index 0c32181..fa2f6fe 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration.state.js
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration.state.js
@@ -17,9 +17,10 @@
 
 import angular from 'angular';
 
-// Clusters screen.
-import previewPanel from './configuration/clusters/preview-panel.directive';
+// Common directives.
+import previewPanel from './configuration/preview-panel.directive.js';
 
+// Clusters screen.
 import clustersGeneral from './configuration/clusters/general.directive';
 
 import clustersGeneralDiscoveryCloud from './configuration/clusters/general/discovery/cloud.directive';

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/atomic.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/atomic.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/atomic.jade
index 8d108b8..4f27a0b 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/atomic.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/atomic.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.atomicConfiguration'
 
 form.panel.panel-default(name='atomics' novalidate)
@@ -28,59 +30,23 @@ form.panel.panel-default(name='atomics' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Cache mode:
-                        ignite-form-field-tooltip
-                            | Cache modes:
-                            ul: li Partitioned - in this mode the overall key set will be divided into partitions and all partitions will be split equally between participating nodes
-                                li Replicated - in this mode all the keys are distributed to all participating nodes
-                                li Local - in this mode caches residing on different grid nodes will not know about each other
-                        ignite-form-field-dropdown(
-                            data-id='cacheMode'
-                            data-name='cacheMode'
-                            data-options='[\
-                                {value: "LOCAL", label: "LOCAL"},\
-                                {value: "REPLICATED", label: "REPLICATED"},\
-                                {value: "PARTITIONED", label: "PARTITIONED"}\
-                            ]'
-                            data-ng-model='#{model}.cacheMode'
-                            data-placeholder='PARTITIONED'
-                        )
+                    +dropdown('Cache mode:', model + '.cacheMode', 'cacheMode', 'true', 'PARTITIONED',
+                        '[\
+                            {value: "LOCAL", label: "LOCAL"},\
+                            {value: "REPLICATED", label: "REPLICATED"},\
+                            {value: "PARTITIONED", label: "PARTITIONED"}\
+                        ]',
+                        'Cache modes:\
+                        <ul>\
+                            <li>Partitioned - in this mode the overall key set will be divided into partitions and all partitions will be split equally between participating nodes</li>\
+                            <li>Replicated - in this mode all the keys are distributed to all participating nodes</li>\
+                            <li>Local - in this mode caches residing on different grid nodes will not know about each other</li>\
+                        </ul>')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Sequence reserve:
-                        ignite-form-field-tooltip
-                            | Default number of sequence values reserved for IgniteAtomicSequence instances#[br]
-                            | After a certain number has been reserved, consequent increments of sequence will happen locally, without communication with other nodes, until the next reservation has to be made
-                        ignite-form-field-input-number(
-                            data-id='atomicSequenceReserveSize'
-                            data-name='atomicSequenceReserveSize'
-                            data-ng-model='#{model}.atomicSequenceReserveSize'
-                            data-placeholder='1000'
-                        )
+                    +number('Sequence reserve:', model + '.atomicSequenceReserveSize', 'atomicSequenceReserveSize', 'true', '1000', '0',
+                        'Default number of sequence values reserved for IgniteAtomicSequence instances<br/>\
+                        After a certain number has been reserved, consequent increments of sequence will happen locally, without communication with other nodes, until the next reservation has to be made')
                 .settings-row(ng-if='!(#{model}.cacheMode && #{model}.cacheMode != "PARTITIONED")')
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Backups:
-                        ignite-form-field-tooltip
-                            | Number of backup nodes
-                        ignite-form-field-input-number(
-                            data-id='backups'
-                            data-name='backups'
-                            data-ng-model='#{model}.backups'
-                            data-placeholder='0'
-                        )
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterAtomics' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterAtomics' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +number('Backups:', model + '.backups', 'backups', 'true', '0', '0', 'Number of backup nodes')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterAtomics')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/binary.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/binary.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/binary.jade
index bf9ba38..36f7960 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/binary.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/binary.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.binaryConfiguration'
 - var types = model + '.typeConfigurations'
 
@@ -28,41 +30,15 @@ form.panel.panel-default(name='binary' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | ID mapper:
-                        ignite-form-field-tooltip
-                            | Maps given from BinaryNameMapper type and filed name to ID that will be used by Ignite in internals#[br]
-                            | Ignite never writes full strings for field or type names. Instead, for performance reasons, Ignite writes integer hash codes for type/class and field names. It has been tested that hash code conflicts for the type/class names or the field names within the same type are virtually non-existent and, to gain performance, it is safe to work with hash codes. For the cases when hash codes for different types or fields actually do collide #[b BinaryIdMapper] allows to override the automatically generated hash code IDs for the type and field names
-                        ignite-form-field-java-class(
-                            data-id='idMapper'
-                            data-name='idMapper'
-                            data-ng-model='#{model}.idMapper'
-                        )
+                    +java-class('ID mapper:', model + '.idMapper', 'idMapper', 'true', 'false',
+                        'Maps given from BinaryNameMapper type and filed name to ID that will be used by Ignite in internals<br/>\
+                        Ignite never writes full strings for field or type names. Instead, for performance reasons, Ignite writes integer hash codes for type/class and field names. It has been tested that hash code conflicts for the type/class names or the field names within the same type are virtually non - existent and, to gain performance, it is safe to work with hash codes. For the cases when hash codes for different types or fields actually do collide <b>BinaryIdMapper</b> allows to override the automatically generated hash code IDs for the type and field names')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Name mapper:
-                        ignite-form-field-tooltip
-                            | Maps type/class and field names to different names#[br]
-                        ignite-form-field-java-class(
-                            data-id='nameMapper'
-                            data-name='nameMapper'
-                            data-ng-model='#{model}.nameMapper'
-                        )
+                    +java-class('Name mapper:', model + '.nameMapper', 'nameMapper', 'true', 'false', 'Maps type/class and field names to different names')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Serializer:
-                        ignite-form-field-tooltip
-                            | Class with custom serialization logic for binary objects
-                        ignite-form-field-java-class(
-                            data-id='serializer'
-                            data-name='serializer'
-                            data-ng-model='#{model}.serializer'
-                        )
+                    +java-class('Serializer:', model + '.serializer', 'serializer', 'true', 'false', 'Class with custom serialization logic for binary objects')
                 .settings-row
-                    ignite-form-group(ng-form='typeConfigurations' ng-model='#{types}')
+                    ignite-form-group(ng-form='typeConfigurations' ng-model=types)
                         ignite-form-field-label
                             | Type configurations
                         ignite-form-group-tooltip
@@ -79,81 +55,25 @@ form.panel.panel-default(name='binary' novalidate)
                                         | Type name:
                                     ignite-form-field-tooltip
                                         | Type name
-                                    i.tipField.fa.fa-remove(
-                                        bs-tooltip='"Remove type configuration"'
-                                        ng-click='#{types}.splice(#{types}.indexOf(model), 1)'
-                                    )
+                                    +table-remove-button(types, 'Remove type configuration')
                                     ignite-form-field-java-class(
-                                        data-id='typeName'
-                                        data-name='typeName'
+                                        data-id='typeName{{$index}}'
+                                        data-name='typeName{{$index}}'
                                         data-ng-model='model.typeName'
                                         data-ng-required='true'
                                     )
                             .settings-row
-                                ignite-form-field
-                                    ignite-form-field-label
-                                        | ID mapper:
-                                    ignite-form-field-tooltip
-                                        | Maps given from BinaryNameMapper type and filed name to ID that will be used by Ignite in internals#[br]
-                                        | Ignite never writes full strings for field or type/class names. Instead, for performance reasons, Ignite writes integer hash codes for type/class and field names. It has been tested that hash code conflicts for the type/class names or the field names within the same type are virtually non-existent and, to gain performance, it is safe to work with hash codes. For the cases when hash codes for different types or fields actually do collide #[b BinaryIdMapper] allows to override the automatically generated hash code IDs for the type and field names
-                                    ignite-form-field-java-class(
-                                        data-id='idMapper'
-                                        data-name='idMapper'
-                                        data-ng-model='model.idMapper'
-                                    )
+                                +java-class('ID mapper:', 'model.idMapper', 'idMapper{{$index}}', 'true', 'false',
+                                    'Maps given from BinaryNameMapper type and filed name to ID that will be used by Ignite in internals<br/>\
+                                    Ignite never writes full strings for field or type/class names. Instead, for performance reasons, Ignite writes integer hash codes for type/class and field names. It has been tested that hash code conflicts for the type/class names or the field names within the same type are virtually non - existent and, to gain performance, it is safe to work with hash codes. For the cases when hash codes for different types or fields actually do collide #[b BinaryIdMapper] allows to override the automatically generated hash code IDs for the type and field names')
                             .settings-row
-                                ignite-form-field
-                                    ignite-form-field-label
-                                        | Name mapper:
-                                    ignite-form-field-tooltip
-                                        | Maps type/class and field names to different names#[br]
-                                    ignite-form-field-java-class(
-                                        data-id='nameMapper'
-                                        data-name='nameMapper'
-                                        data-ng-model='model.nameMapper'
-                                    )
+                                +java-class('Name mapper:', 'model.nameMapper', 'nameMapper{{$index}}', 'true', 'false', 'Maps type/class and field names to different names')
                             .settings-row
-                                ignite-form-field
-                                    ignite-form-field-label
-                                        | Serializer:
-                                    ignite-form-field-tooltip
-                                        | Class with custom serialization logic for binary object
-                                    ignite-form-field-java-class(
-                                        data-id='serializer'
-                                        data-name='serializer'
-                                        data-ng-model='model.serializer'
-                                    )
+                                +java-class('Serializer:', 'model.serializer', 'serializer{{$index}}', 'true', 'false', 'Class with custom serialization logic for binary object')
                             .settings-row
-                                ignite-form-field.checkbox
-                                    ignite-form-field-input-checkbox(
-                                        data-id='enum'
-                                        data-name='enum'
-                                        data-ng-model='model.enum'
-                                    )
-                                    | Enum
-                                    ignite-form-field-tooltip
-                                        | Flag indicating that this type is the enum
-
+                                +checkbox('Enum', 'model.enum', 'enum{{$index}}', 'Flag indicating that this type is the enum')
 
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='compactFooter'
-                            data-name='compactFooter'
-                            data-ng-model='#{model}.compactFooter'
-                        )
-                        | Compact footer
-                        ignite-form-field-tooltip
-                            | When enabled, Ignite will not write fields metadata when serializing objects(this will increase serialization performance), because internally #[b BinaryMarshaller] already distribute metadata inside cluster
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterBinary' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterBinary' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +checkbox('Compact footer', model + '.compactFooter', 'compactFooter', 'When enabled, Ignite will not write fields metadata when serializing objects(this will increase serialization performance), because internally #[b BinaryMarshaller] already distribute metadata inside cluster')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterBinary')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
index 43c9ef3..d4c3b8c 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
@@ -14,7 +14,10 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-- var model = 'backupItem.communication'
+include ../../../../../app/helpers/jade/mixins.jade
+
+- var model = 'backupItem'
+- var communication = model + '.communication'
 
 form.panel.panel-default(name='communication' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
@@ -27,321 +30,60 @@ form.panel.panel-default(name='communication' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Timeout:
-                        ignite-form-field-tooltip
-                            | Maximum timeout in milliseconds for network requests
-                        ignite-form-field-input-number(
-                            data-id='commNetworkTimeout'
-                            data-name='commNetworkTimeout'
-                            data-ng-model='backupItem.networkTimeout'
-                            data-placeholder='5000'
-                            data-min='1'
-                        )
+                    +number('Timeout:', model + '.networkTimeout', 'commNetworkTimeout', 'true', '5000', '1', 'Maximum timeout in milliseconds for network requests')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Send retry delay:
-                        ignite-form-field-tooltip
-                            | Interval in milliseconds between message send retries
-                        ignite-form-field-input-number(
-                            data-id='networkSendRetryDelay'
-                            data-name='networkSendRetryDelay'
-                            data-ng-model='backupItem.networkSendRetryDelay'
-                            data-placeholder='1000'
-                            data-min='1'
-                        )
+                    +number('Send retry delay:', model + '.networkSendRetryDelay', 'networkSendRetryDelay', 'true', '1000', '1', 'Interval in milliseconds between message send retries')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Send retry count:
-                        ignite-form-field-tooltip
-                            | Message send retries count
-                        ignite-form-field-input-number(
-                            data-id='networkSendRetryCount'
-                            data-name='networkSendRetryCount'
-                            data-ng-model='backupItem.networkSendRetryCount'
-                            data-placeholder='3'
-                            data-min='1'
-                        )
+                    +number('Send retry count:', model + '.networkSendRetryCount', 'networkSendRetryCount', 'true', '3', '1', 'Message send retries count')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Discovery startup delay:
-                        ignite-form-field-tooltip
-                            | This value is used to expire messages from waiting list whenever node discovery discrepancies happen
-                        ignite-form-field-input-number(
-                            data-id='discoveryStartupDelay'
-                            data-name='discoveryStartupDelay'
-                            data-ng-model='backupItem.discoveryStartupDelay'
-                            data-placeholder='60000'
-                            data-min='1'
-                        )
+                    +number('Discovery startup delay:', model + '.discoveryStartupDelay', 'discoveryStartupDelay', 'true', '60000', '1', 'This value is used to expire messages from waiting list whenever node discovery discrepancies happen')
                 .settings-row
-                   ignite-form-field
-                        ignite-form-field-label
-                            | Communication listener:
-                        ignite-form-field-tooltip
-                            | Communication listener
-                        ignite-form-field-java-class(
-                            data-id='comListener'
-                            data-name='comListener'
-                            data-ng-model='#{model}.listener'
-                        )
+                    +java-class('Communication listener:', communication + '.listener', 'comListener', 'true', 'false', 'Communication listener')
                 .settings-row
-                   ignite-form-field
-                        ignite-form-field-label
-                            | Local IP address:
-                        ignite-form-field-tooltip
-                            | Local host address for socket binding
-                        ignite-form-field-input-text(
-                            data-id='comLocalAddress'
-                            data-name='comLocalAddress'
-                            data-ng-model='#{model}.localAddress'
-                            data-placeholder='228.1.2.4'
-                        )
+                    +text-ip-address('Local IP address:', communication + '.localAddress', 'comLocalAddress', 'true', '228.1.2.4', 'Local host address for socket binding')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Local port:
-                        ignite-form-field-tooltip
-                            | Local port for socket binding
-                        ignite-form-field-input-number(
-                            data-id='comLocalPort'
-                            data-name='comLocalPort'
-                            data-ng-model='#{model}.localPort'
-                            data-placeholder='47100'
-                            data-min='1024'
-                            data-max='65535'
-                        )
+                    +number-min-max('Local port:', communication + '.localPort', 'comLocalPort', 'true', '47100', '1024', '65535', 'Local port for socket binding')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Local port range:
-                        ignite-form-field-tooltip
-                            | Local port range for local host ports
-                        ignite-form-field-input-number(
-                            data-id='comLocalPortRange'
-                            data-name='comLocalPortRange'
-                            data-ng-model='#{model}.localPortRange'
-                            data-placeholder='100'
-                            data-min='1'
-                        )
+                    +number('Local port range:', communication + '.localPortRange', 'comLocalPortRange', 'true', '100', '1', 'Local port range for local host ports')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Shared memory port:
-                        ignite-form-field-tooltip
-                            | Local port to accept shared memory connections#[br]
-                            | If set to #[b -1] shared memory communication will be disabled
-                        ignite-form-field-input-number(
-                            data-id='sharedMemoryPort'
-                            data-name='sharedMemoryPort'
-                            data-ng-model='#{model}.sharedMemoryPort'
-                            data-placeholder='48100'
-                            data-min='-1'
-                            data-max='65535'
-                        )
+                    +number-min-max('Shared memory port:', communication + '.sharedMemoryPort', 'sharedMemoryPort', 'true', '48100', '-1', '65535',
+                        'Local port to accept shared memory connections<br/>\
+                        If set to #[b -1] shared memory communication will be disabled')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='directBuffer'
-                            data-name='directBuffer'
-                            data-ng-model='#{model}.directBuffer'
-                        )
-                        | Direct buffer
-                        ignite-form-field-tooltip
-                            | If value is true, then SPI will use ByteBuffer.allocateDirect(int) call#[br]
-                            | Otherwise, SPI will use ByteBuffer.allocate(int) call.
+                    +checkbox('Direct buffer', communication + '.directBuffer', 'directBuffer',
+                        'If value is true, then SPI will use ByteBuffer.allocateDirect(int) call<br/>\
+                        Otherwise, SPI will use ByteBuffer.allocate(int) call.')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='directSendBuffer'
-                            data-name='directSendBuffer'
-                            data-ng-model='#{model}.directSendBuffer'
-                        )
-                        | Direct send buffer
-                        ignite-form-field-tooltip
-                            | Flag defining whether direct send buffer should be used
+                    +checkbox('Direct send buffer', communication + '.directSendBuffer', 'directSendBuffer', 'Flag defining whether direct send buffer should be used')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Idle connection timeout:
-                        ignite-form-field-tooltip
-                            | Maximum idle connection timeout upon which a connection to client will be closed
-                        ignite-form-field-input-number(
-                            data-id='idleConnectionTimeout'
-                            data-name='idleConnectionTimeout'
-                            data-ng-model='#{model}.idleConnectionTimeout'
-                            data-placeholder='30000'
-                            data-min='1'
-                        )
+                    +number('Idle connection timeout:', communication + '.idleConnectionTimeout', 'idleConnectionTimeout', 'true', '30000', '1',
+                        'Maximum idle connection timeout upon which a connection to client will be closed')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Connect timeout:
-                        ignite-form-field-tooltip
-                            | Connect timeout used when establishing connection with remote nodes
-                        ignite-form-field-input-number(
-                            data-id='connectTimeout'
-                            data-name='connectTimeout'
-                            data-ng-model='#{model}.connectTimeout'
-                            data-placeholder='5000'
-                        )
+                    +number('Connect timeout:', communication + '.connectTimeout', 'connectTimeout', 'true', '5000', '0', 'Connect timeout used when establishing connection with remote nodes')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Maximum connect timeout:
-                        ignite-form-field-tooltip
-                            | Maximum connect timeout
-                        ignite-form-field-input-number(
-                            data-id='maxConnectTimeout'
-                            data-name='maxConnectTimeout'
-                            data-ng-model='#{model}.maxConnectTimeout'
-                            data-placeholder='600000'
-                        )
+                    +number('Maximum connect timeout:', communication + '.maxConnectTimeout', 'maxConnectTimeout', 'true', '600000', '0', 'Maximum connect timeout')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Reconnect count:
-                        ignite-form-field-tooltip
-                            | Maximum number of reconnect attempts used when establishing connection with remote nodes
-                        ignite-form-field-input-number(
-                            data-id='comReconnectCount'
-                            data-name='comReconnectCount'
-                            data-ng-model='#{model}.reconnectCount'
-                            data-placeholder='10'
-                            data-min='1'
-                        )
+                    +number('Reconnect count:', communication + '.reconnectCount', 'comReconnectCount', 'true', '10', '1',
+                        'Maximum number of reconnect attempts used when establishing connection with remote nodes')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Socket send buffer:
-                        ignite-form-field-tooltip
-                            | Send buffer size for sockets created or accepted by this SPI
-                        ignite-form-field-input-number(
-                            data-id='socketSendBuffer'
-                            data-name='socketSendBuffer'
-                            data-ng-model='#{model}.socketSendBuffer'
-                            data-placeholder='32768'
-                        )
+                    +number('Socket send buffer:', communication + '.socketSendBuffer', 'socketSendBuffer', 'true', '32768', '0', 'Send buffer size for sockets created or accepted by this SPI')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Socket receive buffer:
-                        ignite-form-field-tooltip
-                            | Receive buffer size for sockets created or accepted by this SPI
-                        ignite-form-field-input-number(
-                            data-id='socketReceiveBuffer'
-                            data-name='socketReceiveBuffer'
-                            data-ng-model='#{model}.socketReceiveBuffer'
-                            data-placeholder='32768'
-                        )
+                    +number('Socket receive buffer:', communication + '.socketReceiveBuffer', 'socketReceiveBuffer', 'true', '32768', '0', 'Receive buffer size for sockets created or accepted by this SPI')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Message queue limit:
-                        ignite-form-field-tooltip
-                            | Message queue limit for incoming and outgoing messages
-                        ignite-form-field-input-number(
-                            data-id='messageQueueLimit'
-                            data-name='messageQueueLimit'
-                            data-ng-model='#{model}.messageQueueLimit'
-                            data-placeholder='1024'
-                        )
+                    +number('Message queue limit:', communication + '.messageQueueLimit', 'messageQueueLimit', 'true', '1024', '0', 'Message queue limit for incoming and outgoing messages')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Slow client queue limit:
-                        ignite-form-field-tooltip
-                            | Slow client queue limit
-                        ignite-form-field-input-number(
-                            data-id='slowClientQueueLimit'
-                            data-name='slowClientQueueLimit'
-                            data-ng-model='#{model}.slowClientQueueLimit'
-                            data-placeholder='0'
-                        )
+                    +number('Slow client queue limit:', communication + '.slowClientQueueLimit', 'slowClientQueueLimit', 'true', '0', '0', 'Slow client queue limit')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='tcpNoDelay'
-                            data-name='tcpNoDelay'
-                            data-ng-model='#{model}.tcpNoDelay'
-                        )
-                        | TCP_NODELAY option
-                        ignite-form-field-tooltip
-                            | Value for TCP_NODELAY socket option
+                    +checkbox('TCP_NODELAY option', communication + '.tcpNoDelay', 'tcpNoDelay', 'Value for TCP_NODELAY socket option')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Ack send threshold:
-                        ignite-form-field-tooltip
-                            | Number of received messages per connection to node after which acknowledgment message is sent
-                        ignite-form-field-input-number(
-                            data-id='ackSendThreshold'
-                            data-name='ackSendThreshold'
-                            data-ng-model='#{model}.ackSendThreshold'
-                            data-placeholder='16'
-                            data-min='1'
-                        )
+                    +number('Ack send threshold:', communication + '.ackSendThreshold', 'ackSendThreshold', 'true', '16', '1', 'Number of received messages per connection to node after which acknowledgment message is sent')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Unacknowledged messages:
-                        ignite-form-field-tooltip
-                            | Maximum number of stored unacknowledged messages per connection to node
-                        ignite-form-field-input-number(
-                            data-id='unacknowledgedMessagesBufferSize'
-                            data-name='unacknowledgedMessagesBufferSize'
-                            data-ng-model='#{model}.unacknowledgedMessagesBufferSize'
-                            data-placeholder='0'
-                        )
+                    +number('Unacknowledged messages:', communication + '.unacknowledgedMessagesBufferSize', 'unacknowledgedMessagesBufferSize', 'true', '0', '0', 'Maximum number of stored unacknowledged messages per connection to node')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Socket write timeout:
-                        ignite-form-field-tooltip
-                            | Socket write timeout
-                        ignite-form-field-input-number(
-                            data-id='socketWriteTimeout'
-                            data-name='socketWriteTimeout'
-                            data-ng-model='#{model}.socketWriteTimeout'
-                            data-placeholder='2000'
-                        )
+                    +number('Socket write timeout:', communication + '.socketWriteTimeout', 'socketWriteTimeout', 'true', '2000', '0', 'Socket write timeout')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Selectors count:
-                        ignite-form-field-tooltip
-                            | Count of selectors te be used in TCP server
-                        ignite-form-field-input-number(
-                            data-id='selectorsCount'
-                            data-name='selectorsCount'
-                            data-ng-model='#{model}.selectorsCount'
-                            data-placeholder='min(4, availableProcessors)'
-                            data-min='1'
-                        )
+                    +number('Selectors count:', communication + '.selectorsCount', 'selectorsCount', 'true', 'min(4, availableProcessors)', '1', 'Count of selectors te be used in TCP server')
                 .settings-row
-                   ignite-form-field
-                        ignite-form-field-label
-                            | Address resolver:
-                        ignite-form-field-tooltip
-                            | Address resolver
-                        ignite-form-field-java-class(
-                            data-id='comAddressResolver'
-                            data-name='comAddressResolver'
-                            data-ng-model='#{model}.addressResolver'
-                        )
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterCommunication' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterCommunication' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +java-class('Address resolver:', communication + '.addressResolver', 'comAddressResolver', 'true', 'false', 'Address resolver')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterCommunication')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
index fe965a0..a1f6684 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
@@ -14,7 +14,11 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.connector'
+- var enabled = model + '.enabled'
+- var sslEnabled = enabled + ' && ' + model + '.sslEnabled'
 
 form.panel.panel-default(name='connector' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
@@ -27,282 +31,72 @@ form.panel.panel-default(name='connector' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='restEnabled'
-                            data-name='restEnabled'
-                            data-ng-model='#{model}.enabled'
-                        )
-                        | Enabled
-                        ignite-form-field-tooltip
-                            | Flag indicating whether to configure connector configuration
+                    +checkbox('Enabled', enabled, 'restEnabled', 'Flag indicating whether to configure connector configuration')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Jetty configuration path:
-                        ignite-form-field-tooltip
-                            | Path, either absolute or relative to IGNITE_HOME, to Jetty XML configuration file#[br]
-                            | Jetty is used to support REST over HTTP protocol for accessing Ignite APIs remotely#[br]
-                            | If not provided, Jetty instance with default configuration will be started picking IgniteSystemProperties.IGNITE_JETTY_HOST and IgniteSystemProperties.IGNITE_JETTY_PORT as host and port respectively
-                        ignite-form-field-input-text(
-                            data-id='connectorJettyPath'
-                            data-name='connectorJettyPath'
-                            data-ng-model='#{model}.jettyPath'
-                            data-ng-disabled='!#{model}.enabled'
-                        )
+                    +text-enabled('Jetty configuration path:', model + '.jettyPath', 'connectorJettyPath', enabled, 'false', 'Input path to Jetty configuration',
+                        'Path, either absolute or relative to IGNITE_HOME, to Jetty XML configuration file<br/>\
+                        Jetty is used to support REST over HTTP protocol for accessing Ignite APIs remotely<br/>\
+                        If not provided, Jetty instance with default configuration will be started picking IgniteSystemProperties.IGNITE_JETTY_HOST and IgniteSystemProperties.IGNITE_JETTY_PORT as host and port respectively')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | TCP host:
-                        ignite-form-field-tooltip
-                            | Host for TCP binary protocol server#[br]
-                            | This can be either an IP address or a domain name#[br]
-                            | If not defined, system-wide local address will be used IgniteConfiguration#getLocalHost()#[br]
-                            | You can also use '0.0.0.0' value to bind to all locally-available IP addresses
-                        ignite-form-field-input-text(
-                            data-id='connectorHost'
-                            data-name='connectorHost'
-                            data-ng-model='#{model}.host'
-                            data-ng-disabled='!#{model}.enabled'
-                            data-placeholder='IgniteConfiguration#getLocalHost()'
-                        )
+                    +text-ip-address('TCP host:', model + '.host', 'connectorHost', enabled, 'IgniteConfiguration#getLocalHost()',
+                        'Host for TCP binary protocol server<br/>\
+                        This can be either an IP address or a domain name<br/>\
+                        If not defined, system - wide local address will be used IgniteConfiguration#getLocalHost()<br/>\
+                        You can also use "0.0.0.0" value to bind to all locally - available IP addresses')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | TCP port:
-                        ignite-form-field-tooltip
-                            | Port for TCP binary protocol server
-                        ignite-form-field-input-number(
-                            data-id='connectorPort'
-                            data-name='connectorPort'
-                            data-ng-model='#{model}.port'
-                            data-ng-disabled='!#{model}.enabled'
-                            data-placeholder='11211'
-                            data-min='1024'
-                            data-max='65535'
-                        )
+                    +number-min-max('TCP port:', model + '.port', 'connectorPort', enabled, '11211', '1024', '65535', 'Port for TCP binary protocol server')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | TCP port range:
-                        ignite-form-field-tooltip
-                            | Number of ports for TCP binary protocol server to try if configured port is already in use
-                        ignite-form-field-input-number(
-                            data-id='connectorPortRange'
-                            data-name='connectorPortRange'
-                            data-ng-model='#{model}.portRange'
-                            data-placeholder='100'
-                            data-ng-disabled='!#{model}.enabled'
-                            data-min='1'
-                        )
+                    +number('TCP port range:', model + '.portRange', 'connectorPortRange', enabled, '100', '1', 'Number of ports for TCP binary protocol server to try if configured port is already in use')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Idle query cursor timeout:
-                        ignite-form-field-tooltip
-                            | Reject open query cursors that is not used timeout#[br]
-                            | If no fetch query request come within idle timeout, it will be removed on next check for old query cursors
-                        ignite-form-field-input-number(
-                        data-id='connectorIdleQueryCursorTimeout'
-                        data-name='connectorIdleQueryCursorTimeout'
-                        data-ng-model='#{model}.idleQueryCursorTimeout'
-                        data-placeholder='600000'
-                        data-ng-disabled='!#{model}.enabled'
-                        )
+                    +number('Idle query cursor timeout:', model + '.idleQueryCursorTimeout', 'connectorIdleQueryCursorTimeout', enabled, '600000', '0',
+                        'Reject open query cursors that is not used timeout<br/>\
+                        If no fetch query request come within idle timeout, it will be removed on next check for old query cursors')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Idle query cursor check frequency:
-                        ignite-form-field-tooltip
-                            | Idle query cursors check frequency#[br]
-                            | This setting is used to reject open query cursors that is not used
-                        ignite-form-field-input-number(
-                        data-id='connectorIdleQueryCursorCheckFrequency'
-                        data-name='connectorIdleQueryCursorCheckFrequency'
-                        data-ng-model='#{model}.idleQueryCursorCheckFrequency'
-                        data-placeholder='60000'
-                        data-ng-disabled='!#{model}.enabled'
-                        )
+                    +number('Idle query cursor check frequency:', model + '.idleQueryCursorCheckFrequency', 'connectorIdleQueryCursorCheckFrequency', enabled, '60000', '0',
+                        'Idle query cursors check frequency<br/>\
+                        This setting is used to reject open query cursors that is not used')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Idle timeout:
-                        ignite-form-field-tooltip
-                            | Idle timeout for REST server#[br]
-                            | This setting is used to reject half-opened sockets#[br]
-                            | If no packets come within idle timeout, the connection is closed
-                        ignite-form-field-input-number(
-                            data-id='connectorIdleTimeout'
-                            data-name='connectorIdleTimeout'
-                            data-ng-model='#{model}.idleTimeout'
-                            data-placeholder='7000'
-                            data-ng-disabled='!#{model}.enabled'
-                        )
+                    +number('Idle timeout:', model + '.idleTimeout', 'connectorIdleTimeout', enabled, '7000', '0',
+                        'Idle timeout for REST server<br/>\
+                        This setting is used to reject half - opened sockets<br/>\
+                        If no packets come within idle timeout, the connection is closed')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Receive buffer size:
-                        ignite-form-field-tooltip
-                            | REST TCP server receive buffer size
-                        ignite-form-field-input-number(
-                            data-id='connectorReceiveBufferSize'
-                            data-name='connectorReceiveBufferSize'
-                            data-ng-model='#{model}.receiveBufferSize'
-                            data-placeholder='32768'
-                            data-ng-disabled='!#{model}.enabled'
-                        )
+                    +number('Receive buffer size:', model + '.receiveBufferSize', 'connectorReceiveBufferSize', enabled, '32768', '0', 'REST TCP server receive buffer size')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Send buffer size:
-                        ignite-form-field-tooltip
-                            | REST TCP server send buffer size
-                        ignite-form-field-input-number(
-                            data-id='connectorSendBufferSize'
-                            data-name='connectorSendBufferSize'
-                            data-ng-model='#{model}.sendBufferSize'
-                            data-placeholder='32768'
-                            data-ng-disabled='!#{model}.enabled'
-                        )
+                    +number('Send buffer size:', model + '.sendBufferSize', 'connectorSendBufferSize', enabled, '32768', '0', 'REST TCP server send buffer size')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Send queue limit:
-                        ignite-form-field-tooltip
-                            | REST TCP server send queue limit#[br]
-                            | If the limit exceeds, all successive writes will block until the queue has enough capacity
-                        ignite-form-field-input-number(
-                            data-id='connectorSendQueueLimit'
-                            data-name='connectorSendQueueLimit'
-                            data-ng-model='#{model}.sendQueueLimit'
-                            data-placeholder='unlimited'
-                            data-ng-disabled='!#{model}.enabled'
-                        )
+                    +number('Send queue limit:', model + '.sendQueueLimit', 'connectorSendQueueLimit', enabled, 'unlimited', '0',
+                        'REST TCP server send queue limit<br/>\
+                        If the limit exceeds, all successive writes will block until the queue has enough capacity')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='connectorDirectBuffer'
-                            data-name='connectorDirectBuffer'
-                            data-ng-model='#{model}.directBuffer'
-                            data-ng-disabled='!#{model}.enabled'
-                        )
-                        | Direct buffer
-                        ignite-form-field-tooltip
-                            | Flag indicating whether REST TCP server should use direct buffers#[br]
-                            | A direct buffer is a buffer that is allocated and accessed using native system calls, without using JVM heap#[br]
-                            | Enabling direct buffer may improve performance and avoid memory issues (long GC pauses due to huge buffer size)
+                    +checkbox-enabled('Direct buffer', model + '.directBuffer', 'connectorDirectBuffer', enabled,
+                        'Flag indicating whether REST TCP server should use direct buffers<br/>\
+                        A direct buffer is a buffer that is allocated and accessed using native system calls, without using JVM heap<br/>\
+                        Enabling direct buffer may improve performance and avoid memory issues(long GC pauses due to huge buffer size)')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='connectorNoDelay'
-                            data-name='connectorNoDelay'
-                            data-ng-model='#{model}.noDelay'
-                            data-ng-disabled='!#{model}.enabled'
-                        )
-                        | TCP_NODELAY option
-                        ignite-form-field-tooltip
-                            | Flag indicating whether TCP_NODELAY option should be set for accepted client connections#[br]
-                            | Setting this option reduces network latency and should be enabled in majority of cases#[br]
-                            | For more information, see Socket#setTcpNoDelay(boolean)
+                    +checkbox-enabled('TCP_NODELAY option', model + '.noDelay', 'connectorNoDelay', enabled,
+                        'Flag indicating whether TCP_NODELAY option should be set for accepted client connections<br/>\
+                        Setting this option reduces network latency and should be enabled in majority of cases<br/>\
+                        For more information, see Socket#setTcpNoDelay(boolean)')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Selector count:
-                        ignite-form-field-tooltip
-                            | Number of selector threads in REST TCP server#[br]
-                            | Higher value for this parameter may increase throughput, but also increases context switching
-                        ignite-form-field-input-number(
-                            data-id='connectorSelectorCount'
-                            data-name='connectorSelectorCount'
-                            data-ng-model='#{model}.selectorCount'
-                            data-placeholder='min(4, availableProcessors)'
-                            data-ng-disabled='!#{model}.enabled'
-                            data-min='1'
-                        )
+                    +number('Selector count:', model + '.selectorCount', 'connectorSelectorCount', enabled, 'min(4, availableProcessors)', '1',
+                        'Number of selector threads in REST TCP server<br/>\
+                        Higher value for this parameter may increase throughput, but also increases context switching')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Thread pool size:
-                        ignite-form-field-tooltip
-                            | Thread pool size to use for processing of client messages (REST requests)
-                        ignite-form-field-input-number(
-                            data-id='connectorThreadPoolSize'
-                            data-name='connectorThreadPoolSize'
-                            data-ng-model='#{model}.threadPoolSize'
-                            data-placeholder='max(8, availableProcessors) * 2'
-                            data-ng-disabled='!#{model}.enabled'
-                            data-min='1'
-                        )
+                    +number('Thread pool size:', model + '.threadPoolSize', 'connectorThreadPoolSize', enabled, 'max(8, availableProcessors) * 2', '1',
+                        'Thread pool size to use for processing of client messages (REST requests)')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Message interceptor:
-                        ignite-form-field-tooltip
-                            | Interceptor allows to transform all objects exchanged via REST protocol#[br]
-                            | For example if you use custom serialisation on client you can write interceptor to transform binary representations received from client to Java objects and later access them from java code directly
-                        ignite-form-field-java-class(
-                            data-id='connectorMessageInterceptor'
-                            data-name='connectorMessageInterceptor'
-                            data-ng-model='#{model}.messageInterceptor'
-                            data-ng-disabled='!#{model}.enabled'
-                        )
+                    +java-class('Message interceptor:', model + '.messageInterceptor', 'connectorMessageInterceptor', enabled, 'false',
+                        'Interceptor allows to transform all objects exchanged via REST protocol<br/>\
+                        For example if you use custom serialisation on client you can write interceptor to transform binary representations received from client to Java objects and later access them from java code directly')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Secret key:
-                        ignite-form-field-tooltip
-                            | Secret key to authenticate REST requests
-                        ignite-form-field-input-text(
-                            data-id='connectorSecretKey'
-                            data-name='connectorSecretKey'
-                            data-ng-model='#{model}.secretKey'
-                            data-ng-disabled='!#{model}.enabled'
-                            data-placeholder='Specify to enable authentication'
-                        )
+                    +text-enabled('Secret key:', model + '.secretKey', 'connectorSecretKey', enabled, 'false', 'Specify to enable authentication', 'Secret key to authenticate REST requests')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='connectorSslEnabled'
-                            data-name='connectorSslEnabled'
-                            data-ng-model='#{model}.sslEnabled'
-                            data-ng-disabled='!#{model}.enabled'
-                        )
-                        | Enable SSL
-                        ignite-form-field-tooltip
-                            | Enables/disables SSL for REST TCP binary protocol
+                    +checkbox-enabled('Enable SSL', model + '.sslEnabled', 'connectorSslEnabled', enabled, 'Enables/disables SSL for REST TCP binary protocol')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='connectorSslClientAuth'
-                            data-name='connectorSslClientAuth'
-                            data-ng-model='#{model}.sslClientAuth'
-                            data-ng-disabled='!#{model}.enabled || !#{model}.sslEnabled'
-                        )
-                        | Enable SSL client auth
-                        ignite-form-field-tooltip
-                            | Flag indicating whether or not SSL client authentication is required
+                    +checkbox-enabled('Enable SSL client auth', model + '.sslClientAuth', 'connectorSslClientAuth', sslEnabled, 'Flag indicating whether or not SSL client authentication is required')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | SSL factory:
-                        ignite-form-field-tooltip
-                            | Instance of Factory that will be used to create an instance of SSLContext for Secure Socket Layer on TCP binary protocol
-                        ignite-form-field-java-class(
-                            data-id='connectorSslFactory'
-                            data-name='connectorSslFactory'
-                            data-ng-model='#{model}.sslFactory'
-                            data-ng-required='#{model}.sslEnabled'
-                            data-ng-disabled='!#{model}.enabled || !#{model}.sslEnabled'
-                        )
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterConnector' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterConnector' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +java-class('SSL factory:', model + '.sslFactory', 'connectorSslFactory', sslEnabled, sslEnabled,
+                        'Instance of Factory that will be used to create an instance of SSLContext for Secure Socket Layer on TCP binary protocol')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterConnector')


[32/50] [abbrv] ignite git commit: IGNITE-843 Fixed table mixins and added workaround for not escaping of "&&" to "& & ".

Posted by an...@apache.org.
IGNITE-843 Fixed table mixins and added workaround for not escaping of "&&" to "&amp;&amp;".


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/63819d66
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/63819d66
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/63819d66

Branch: refs/heads/ignite-2875
Commit: 63819d66efa202670b7bb4ab6169646e5b3b9c52
Parents: 1c3c17c
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Wed Mar 23 12:09:48 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Wed Mar 23 12:09:48 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/app/helpers/jade/mixins.jade    | 45 ++++++++++++--------
 .../src/main/js/app/modules/ace.module.js       |  2 +-
 .../states/configuration/caches/query.jade      |  8 ++--
 .../states/configuration/caches/store.jade      | 14 +++---
 .../configuration/clusters/deployment.jade      | 16 +++----
 .../clusters/general/discovery/cloud.jade       | 16 +++----
 .../clusters/general/discovery/multicast.jade   |  8 ++--
 .../clusters/general/discovery/vm.jade          |  8 ++--
 .../states/configuration/clusters/ssl.jade      |  8 ++--
 9 files changed, 67 insertions(+), 58 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/63819d66/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
index ed6083d..abe08a3 100644
--- a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
+++ b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
@@ -188,8 +188,8 @@ mixin dropdown-multiple(lbl, model, name, placeholder, placeholderEmpty, options
             data-disabled='!#{options}.length'
         )
 
-//- Mixin for table java class field.
-mixin table-java-class-field(field, items, save, newItem)
+//- Mixin for table text field.
+mixin table-text-field(field, items, valid, save, placeholder, newItem)
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
@@ -198,10 +198,11 @@ mixin table-java-class-field(field, items, save, newItem)
     -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
-    ignite-form-field-java-class(
+    ignite-form-field-input-text(
         data-name=field
         data-ng-model=field
         data-ng-required='true'
+        data-placeholder=placeholder
         data-ignite-unique=items
         data-ignite-form-field-input-autofocus='true'
         on-enter=onEnter
@@ -210,8 +211,8 @@ mixin table-java-class-field(field, items, save, newItem)
     )
         block
 
-//- Mixin for table java package field.
-mixin table-java-package-field(field, items, save, newItem)
+//- Mixin for table java class field.
+mixin table-java-class-field(field, items, valid, save, newItem)
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
@@ -220,13 +221,10 @@ mixin table-java-package-field(field, items, save, newItem)
     -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
-    ignite-form-field-input-text(
+    ignite-form-field-java-class(
         data-name=field
         data-ng-model=field
         data-ng-required='true'
-        data-placeholder='Enter package name'
-        data-java-keywords='true'
-        data-java-package-name='true'
         data-ignite-unique=items
         data-ignite-form-field-input-autofocus='true'
         on-enter=onEnter
@@ -235,8 +233,8 @@ mixin table-java-package-field(field, items, save, newItem)
     )
         block
 
-//- Mixin for table text field.
-mixin table-text-field(field, items, save, placeholder, newItem)
+//- Mixin for table java package field.
+mixin table-java-package-field(field, items, valid, save, newItem)
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
@@ -249,7 +247,9 @@ mixin table-text-field(field, items, save, placeholder, newItem)
         data-name=field
         data-ng-model=field
         data-ng-required='true'
-        data-placeholder=placeholder
+        data-placeholder='Enter package name'
+        data-java-keywords='true'
+        data-java-package-name='true'
         data-ignite-unique=items
         data-ignite-form-field-input-autofocus='true'
         on-enter=onEnter
@@ -259,7 +259,7 @@ mixin table-text-field(field, items, save, placeholder, newItem)
         block
 
 //- Mixin for table address field.
-mixin table-address-field(field, items, save, newItem)
+mixin table-address-field(field, items, valid, save, newItem)
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
@@ -282,14 +282,15 @@ mixin table-address-field(field, items, save, newItem)
     )
         block
 
-//- Mixin for table save button.
+//-
+    Mixin for table save button.
+    "||" used instead of "&&" to workaround escaping of "&&" to "&amp;&amp;"
 mixin table-save-button(valid, save, newItem)
     -var reset = (newItem ? 'group.add = []' : 'field.edit = false')
-    -var onClick = valid + ' && ' + save + '; ' + valid  + ' && (' + reset + ');'
 
     i.fa.fa-floppy-o(
         ng-show=valid
-        ng-click=onClick
+        ng-click="!#{valid} || (#{save}); !#{valid} || (#{reset});"
         bs-tooltip
         data-title='Click icon or press [Enter] to save item'
     )
@@ -307,8 +308,8 @@ mixin table-remove-conditional-button(items, show, tip)
 mixin table-remove-button(items, tip)
     +table-remove-conditional-button(items, 'true', tip)
 
-//- Mixin for table feedback for unique validator.
-mixin table-error-feedback(visible, error, errorMessage)
+//- Mixin for feedback on specified error.
+mixin error-feedback(visible, error, errorMessage)
     i.fa.fa-exclamation-triangle.form-control-feedback(
         ng-if=visible
         bs-tooltip='"#{errorMessage}"'
@@ -316,6 +317,14 @@ mixin table-error-feedback(visible, error, errorMessage)
         ignite-error-message=errorMessage
     )
 
+//- Mixin for feedback on unique violation.
+mixin unique-feedback(visible, errorMessage)
+    i.fa.fa-exclamation-triangle.form-control-feedback(
+        ng-if=visible
+        bs-tooltip='"#{errorMessage}"'
+        ignite-error='igniteUnique'
+        ignite-error-message=errorMessage
+    )
 
 //- Mixin for cache mode.
 mixin cacheMode(lbl, model, name, placeholder)

http://git-wip-us.apache.org/repos/asf/ignite/blob/63819d66/modules/control-center-web/src/main/js/app/modules/ace.module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/ace.module.js b/modules/control-center-web/src/main/js/app/modules/ace.module.js
index d747ccf..9be827d 100644
--- a/modules/control-center-web/src/main/js/app/modules/ace.module.js
+++ b/modules/control-center-web/src/main/js/app/modules/ace.module.js
@@ -127,7 +127,7 @@ angular
             // onLoad callbacks.
             _.forEach(opts.callbacks, (cb) => {
                 if (angular.isFunction(cb))
-                    cb(acee)
+                    cb(acee);
             });
         };
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/63819d66/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
index 6d8e0ee..5dbcab6 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
@@ -63,9 +63,9 @@ form.panel.panel-default(name='query' novalidate)
                                 span(ng-hide='field.edit')
                                     a.labelFormField(ng-click='field.edit = true') {{ model }}
                                 span(ng-if='field.edit' ng-init='#{field} = model')
-                                    +table-java-class-field(field, sqlFunctionClasses, save, false)
+                                    +table-java-class-field(field, sqlFunctionClasses, valid, save, false)
                                         +table-save-button(valid, save, false)
-                                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                                        +unique-feedback(unique, uniqueTip)
 
                         .group-content(ng-repeat='field in group.add')
                             -var field = 'new'
@@ -74,9 +74,9 @@ form.panel.panel-default(name='query' novalidate)
                             -var save = sqlFunctionClasses + '.push(' + field + ')'
 
                             ignite-form-field(type='internal' name='SQL function')
-                                +table-java-class-field(field, sqlFunctionClasses, save, true)
+                                +table-java-class-field(field, sqlFunctionClasses, valid, save, true)
                                     +table-save-button(valid, save, true)
-                                    +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                                    +unique-feedback(unique, uniqueTip)
 
                         .group-content-empty(ng-if='!(#{sqlFunctionClasses}.length) && !group.add.length')
                             | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/63819d66/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
index 84cc376..44ae665 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
@@ -50,7 +50,7 @@ mixin dialect(lbl, model, name, tipTitle, genericDialectName, placeholder)
             data-placeholder=placeholder
         )
 
-mixin hibernateField(items, field, save, newItem)
+mixin hibernateField(items, field, valid, save, newItem)
     -var reset = (newItem ? 'group.add = []' : 'field.edit = false')
 
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
@@ -196,10 +196,10 @@ form.panel.panel-default(name='store' novalidate)
                                                 span(ng-hide='field.edit')
                                                     a.labelFormField(ng-click='field.edit = true') {{ model }}
                                                 span(ng-if='field.edit' ng-init='#{field} = model')
-                                                    +hibernateField(hibernateProperties, field, save, false)
+                                                    +hibernateField(hibernateProperties, field, valid, save, false)
                                                         +table-save-button(valid, save, false)
-                                                        +table-error-feedback(unique, 'ignitePropertyUnique', tipUnique)
-                                                        +table-error-feedback(unique, 'ignitePropertyValueSpecified', tipPropertySpecified)
+                                                        +error-feedback(unique, 'ignitePropertyUnique', tipUnique)
+                                                        +error-feedback(unique, 'ignitePropertyValueSpecified', tipPropertySpecified)
 
                                         .group-content(ng-repeat='field in group.add')
                                             -var field = 'new'
@@ -209,10 +209,10 @@ form.panel.panel-default(name='store' novalidate)
                                             -var save = hibernateProperties + '.push(' + field + ')'
 
                                             ignite-form-field(type='internal' name='Hibernate property')
-                                                +hibernateField(hibernateProperties, field, save, true)
+                                                +hibernateField(hibernateProperties, field, valid, save, true)
                                                     +table-save-button(valid, save, true)
-                                                    +table-error-feedback(unique, 'ignitePropertyUnique', tipUnique)
-                                                    +table-error-feedback(unique, 'ignitePropertyValueSpecified', tipPropertySpecified)
+                                                    +error-feedback(unique, 'ignitePropertyUnique', tipUnique)
+                                                    +error-feedback(unique, 'ignitePropertyValueSpecified', tipPropertySpecified)
                                         .group-content-empty(ng-if='!(#{hibernateProperties}.length) && !group.add.length')
                                             | Not defined
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/63819d66/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
index 1c8d475..9c0391b 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
@@ -84,11 +84,11 @@ form.panel.panel-default(name='deployment' novalidate)
                                 span(ng-hide='field.edit')
                                     a.labelFormField(ng-click='#{enabled} && (field.edit = true)') {{ model }}
                                 span(ng-if='field.edit' ng-init='#{field} = model')
-                                    +table-java-package-field(field, exclude, save, false)
+                                    +table-java-package-field(field, exclude, valid, save, false)
                                         +table-save-button(valid, save, false)
-                                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
-                                        +table-error-feedback(javaPackageName, 'javaPackageName', tipJavaPackageName)
-                                        +table-error-feedback(javaKeywords, 'javaKeywords', tipJavaKeyWord)
+                                        +unique-feedback(unique, uniqueTip)
+                                        +error-feedback(javaPackageName, 'javaPackageName', tipJavaPackageName)
+                                        +error-feedback(javaKeywords, 'javaKeywords', tipJavaKeyWord)
 
                         .group-content(ng-repeat='field in group.add')
                             -var field = 'new'
@@ -99,11 +99,11 @@ form.panel.panel-default(name='deployment' novalidate)
                             -var save = exclude + '.push(' + field + ')'
 
                             ignite-form-field(type='internal' name='Package name')
-                                +table-java-package-field(field, exclude, save, true)
+                                +table-java-package-field(field, exclude, valid, save, true)
                                     +table-save-button(valid, save, true)
-                                    +table-error-feedback(unique, 'igniteUnique', uniqueTip)
-                                    +table-error-feedback(javaPackageName, 'javaPackageName', tipJavaPackageName)
-                                    +table-error-feedback(javaKeywords, 'javaKeywords', tipJavaKeyWord)
+                                    +unique-feedback(unique, uniqueTip)
+                                    +error-feedback(javaPackageName, 'javaPackageName', tipJavaPackageName)
+                                    +error-feedback(javaKeywords, 'javaKeywords', tipJavaKeyWord)
 
 
                         .group-content-empty(ng-if='!(#{exclude}.length) && !group.add.length')

http://git-wip-us.apache.org/repos/asf/ignite/blob/63819d66/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
index 704611d..c920fe8 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
@@ -63,9 +63,9 @@ div
                     span(ng-hide='field.edit')
                         a.labelFormField(ng-click='field.edit = true') {{ model }}
                     span(ng-if='field.edit' ng-init='#{field} = model')
-                        +table-text-field(field, regions, save, 'Region name', false)
+                        +table-text-field(field, regions, valid, save, 'Region name', false)
                             +table-save-button(valid, save, false)
-                            +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                            +unique-feedback(unique, uniqueTip)
 
             .group-content(ng-repeat='field in group.add')
                 -var field = 'new'
@@ -74,9 +74,9 @@ div
                 -var save = regions + '.push(' + field + ')'
 
                 ignite-form-field(type='internal' name='Region')
-                    +table-text-field(field, regions, save, 'Region name', true)
+                    +table-text-field(field, regions, valid, save, 'Region name', true)
                         +table-save-button(valid, save, true)
-                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                        +unique-feedback(unique, uniqueTip)
 
             .group-content-empty(ng-if='!(#{regions}.length) && !group.add.length')
                 | Not defined
@@ -106,9 +106,9 @@ div
                     span(ng-hide='field.edit')
                         a.labelFormField(ng-click='field.edit = true') {{ model }}
                     span(ng-if='field.edit' ng-init='#{field} = model')
-                        +table-text-field(field, zones, save, 'Zone name',false)
+                        +table-text-field(field, zones, valid, save, 'Zone name', false)
                             +table-save-button(valid, save, false)
-                            +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                            +unique-feedback(unique, uniqueTip)
 
             .group-content(ng-repeat='field in group.add')
                 -var field = 'new'
@@ -117,9 +117,9 @@ div
                 -var save = zones + '.push(' + field + ')'
 
                 ignite-form-field(type='internal' name='Zone')
-                    +table-text-field(field, zones, save, 'Zone name',true)
+                    +table-text-field(field, zones, valid, save, 'Zone name', true)
                         +table-save-button(valid, save, true)
-                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                        +unique-feedback(unique, uniqueTip)
 
             .group-content-empty(ng-if='!(#{zones}.length) && !group.add.length')
                 | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/63819d66/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
index 19c496c..61a0718 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
@@ -76,9 +76,9 @@ div
                     span(ng-hide='field.edit')
                         a.labelFormField(ng-click='field.edit = true') {{ model }}
                     span(ng-if='field.edit' ng-init='#{field} = model')
-                        +table-address-field(field, addresses, save, false)
+                        +table-address-field(field, addresses, valid, save, false)
                             +table-save-button(valid, save, false)
-                            +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                            +unique-feedback(unique, uniqueTip)
 
             .group-content(ng-repeat='field in group.add')
                 -var field = 'new'
@@ -87,9 +87,9 @@ div
                 -var save = addresses + '.push(' + field + ')'
 
                 ignite-form-field(type='internal' name='Address')
-                    +table-address-field(field, addresses, save, true)
+                    +table-address-field(field, addresses, valid, save, true)
                         +table-save-button(valid, save, true)
-                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                        +unique-feedback(unique, uniqueTip)
 
             .group-content-empty(ng-if='!(#{addresses}.length) && !group.add.length')
                 | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/63819d66/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
index cb7385c..a19adf7 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
@@ -59,9 +59,9 @@ include ../../../../../../../app/helpers/jade/mixins.jade
                 span(ng-hide='field.edit')
                     a.labelFormField(ng-click='field.edit = true') {{ model }}
                 span(ng-if='field.edit' ng-init='#{field} = model')
-                    +table-address-field(field, addresses, save, false)
+                    +table-address-field(field, addresses, valid, save, false)
                         +table-save-button(valid, save, false)
-                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                        +unique-feedback(unique, uniqueTip)
 
         .group-content(ng-repeat='field in group.add')
             -var field = 'new'
@@ -70,9 +70,9 @@ include ../../../../../../../app/helpers/jade/mixins.jade
             -var save = addresses + '.push(' + field + ')'
 
             ignite-form-field(type='internal' name='Address')
-                +table-address-field(field, addresses, save, true)
+                +table-address-field(field, addresses, valid, save, true)
                     +table-save-button(valid, save, true)
-                    +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                    +unique-feedback(unique, uniqueTip)
 
         .group-content-empty(id='addresses' ng-if='!(#{addresses}.length) && !group.add.length')
                 | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/63819d66/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
index 15a14cc..130a409 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
@@ -72,9 +72,9 @@ form.panel.panel-default(name='sslConfiguration' novalidate)
                                 span(ng-hide='field.edit')
                                     a.labelFormField(ng-click='#{enabled} && (field.edit = true)') {{ model }}
                                 span(ng-if='field.edit' ng-init='#{field} = model')
-                                    +table-java-class-field(field, trust, save, false)
+                                    +table-java-class-field(field, trust, valid, save, false)
                                         +table-save-button(valid, save, false)
-                                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                                        +unique-feedback(unique, uniqueTip)
 
                         .group-content(ng-repeat='field in group.add')
                             -var field = 'new'
@@ -83,9 +83,9 @@ form.panel.panel-default(name='sslConfiguration' novalidate)
                             -var save = trust + '.push(' + field + ')'
 
                             ignite-form-field(type='internal' name='Trust manager')
-                                +table-java-class-field(field, trust, save, true)
+                                +table-java-class-field(field, trust, valid, save, true)
                                     +table-save-button(valid, save, true)
-                                    +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                                    +unique-feedback(unique, uniqueTip)
 
                         .group-content-empty(ng-if='!(#{trust}.length) && !group.add.length')
                             | Not defined


[45/50] [abbrv] ignite git commit: Merge branch 'web-console-staging' of https://github.com/gridgain/apache-ignite into ignite-2875

Posted by an...@apache.org.
Merge branch 'web-console-staging' of https://github.com/gridgain/apache-ignite into ignite-2875


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4f6e72ec
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4f6e72ec
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4f6e72ec

Branch: refs/heads/ignite-2875
Commit: 4f6e72ec39458527b5123486ad33788260288c37
Parents: 8e08764 214c9b2
Author: Andrey <an...@gridgain.com>
Authored: Fri Mar 25 14:46:11 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Mar 25 14:46:11 2016 +0700

----------------------------------------------------------------------
 .../form-field-java-class.directive.js          |  30 +-
 .../form-field-java-class.jade                  |  26 +-
 .../src/main/js/app/helpers/jade/mixins.jade    |  20 +-
 .../modules/form/field/dropdown.directive.js    |  17 +-
 .../js/app/modules/form/field/dropdown.jade     |   8 +-
 .../form/field/input/number.directive.js        |  12 +-
 .../js/app/modules/form/field/input/text.css    |   2 +-
 .../modules/form/field/input/text.directive.js  |  26 +-
 .../js/app/modules/form/field/input/text.jade   |   6 +-
 .../src/main/js/app/modules/form/form.module.js |   2 +
 .../validator/igfs-path-unique.directive.js     |  46 +++
 .../form/validator/property-unique.directive.js |   9 +-
 .../modules/form/validator/unique.directive.js  |   3 +-
 .../app/modules/states/configuration.state.js   | 257 +++++++-------
 .../states/configuration/caches/query.jade      |   4 +-
 .../states/configuration/caches/store.jade      |  12 +-
 .../states/configuration/igfs/dual.directive.js |  27 ++
 .../modules/states/configuration/igfs/dual.jade |  41 +++
 .../igfs/fragmentizer.directive.js              |  27 ++
 .../states/configuration/igfs/fragmentizer.jade |  42 +++
 .../configuration/igfs/general.directive.js     |  27 ++
 .../states/configuration/igfs/general.jade      |  53 +++
 .../states/configuration/igfs/ipc.directive.js  |  27 ++
 .../modules/states/configuration/igfs/ipc.jade  |  56 +++
 .../states/configuration/igfs/misc.directive.js |  27 ++
 .../modules/states/configuration/igfs/misc.jade | 121 +++++++
 .../configuration/igfs/secondary.directive.js   |  27 ++
 .../states/configuration/igfs/secondary.jade    |  43 +++
 .../main/js/controllers/caches-controller.js    |  31 +-
 .../main/js/controllers/clusters-controller.js  |  31 +-
 .../src/main/js/controllers/common-module.js    |  16 +-
 .../src/main/js/controllers/igfs-controller.js  | 348 +++++++------------
 .../main/js/helpers/generator/generator-java.js |   6 +-
 .../helpers/generator/generator-properties.js   |   2 +-
 .../src/main/js/views/configuration/igfs.jade   |  24 +-
 .../src/main/js/views/settings/profile.jade     |   4 +-
 .../src/main/js/views/signin.jade               |   4 +-
 37 files changed, 997 insertions(+), 467 deletions(-)
----------------------------------------------------------------------



[22/50] [abbrv] ignite git commit: IGNITE-2840 Refactoring to mixins.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
index b241e45..872b46c 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.transactionConfiguration'
 
 form.panel.panel-default(name='transactionConfiguration' novalidate)
@@ -27,95 +29,30 @@ form.panel.panel-default(name='transactionConfiguration' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Concurrency
-                        ignite-form-field-tooltip
-                            | Cache transaction concurrency to use when one is not explicitly specified
-                        ignite-form-field-dropdown(
-                            data-id='defaultTxConcurrency'
-                            data-name='defaultTxConcurrency'
-                            data-options='[\
-                                {value: "OPTIMISTIC", label: "OPTIMISTIC"},\
-                                {value: "PESSIMISTIC", label: "PESSIMISTIC"}\
-                            ]'
-                            data-ng-model='#{model}.defaultTxConcurrency'
-                            data-placeholder='PESSIMISTIC'
-                        )
+                    +dropdown('Concurrency:', model + '.defaultTxConcurrency', 'defaultTxConcurrency', 'true', 'PESSIMISTIC',
+                        '[\
+                            {value: "OPTIMISTIC", label: "OPTIMISTIC"},\
+                            {value: "PESSIMISTIC", label: "PESSIMISTIC"}\
+                        ]',
+                        'Cache transaction concurrency to use when one is not explicitly specified')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Isolation
-                        ignite-form-field-tooltip
-                            | Default transaction isolation
-                        ignite-form-field-dropdown(
-                            data-id='defaultTxIsolation'
-                            data-name='defaultTxIsolation'
-                            data-options='[\
-                                {value: "READ_COMMITTED", label: "READ_COMMITTED"},\
-                                {value: "REPEATABLE_READ", label: "REPEATABLE_READ"},\
-                                {value: "SERIALIZABLE", label: "SERIALIZABLE"}\
-                            ]'
-                            data-ng-model='#{model}.defaultTxIsolation'
-                            data-placeholder='REPEATABLE_READ'
-                        )
+                    +dropdown('Isolation:', model + '.defaultTxIsolation', 'defaultTxIsolation', 'true', 'REPEATABLE_READ',
+                        '[\
+                            {value: "READ_COMMITTED", label: "READ_COMMITTED"},\
+                            {value: "REPEATABLE_READ", label: "REPEATABLE_READ"},\
+                            {value: "SERIALIZABLE", label: "SERIALIZABLE"}\
+                        ]',
+                        'Default transaction isolation')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Default timeout
-                        ignite-form-field-tooltip
-                            | Default transaction timeout
-                        ignite-form-field-input-number(
-                            data-id='defaultTxTimeout'
-                            data-name='defaultTxTimeout'
-                            data-ng-model='#{model}.defaultTxTimeout'
-                            data-placeholder='0'
-                        )
+                    +number('Default timeout:', model + '.defaultTxTimeout', 'defaultTxTimeout', 'true', '0', '0', 'Default transaction timeout')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Pessimistic log cleanup delay
-                        ignite-form-field-tooltip
-                            | Delay, in milliseconds, after which pessimistic recovery entries will be cleaned up for failed node
-                        ignite-form-field-input-number(
-                            data-id='pessimisticTxLogLinger'
-                            data-name='pessimisticTxLogLinger'
-                            data-ng-model='#{model}.pessimisticTxLogLinger'
-                            data-placeholder='10000'
-                        )
+                    +number('Pessimistic log cleanup delay:', model + '.pessimisticTxLogLinger', 'pessimisticTxLogLinger', 'true', '10000', '0',
+                        'Delay, in milliseconds, after which pessimistic recovery entries will be cleaned up for failed node')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Pessimistic log size
-                        ignite-form-field-tooltip
-                            | Size of pessimistic transactions log stored on node in order to recover transaction commit if originating node has left grid before it has sent all messages to transaction nodes
-                        ignite-form-field-input-number(
-                            data-id='pessimisticTxLogSize'
-                            data-name='pessimisticTxLogSize'
-                            data-ng-model='#{model}.pessimisticTxLogSize'
-                            data-placeholder='0'
-                        )
+                    +number('Pessimistic log size:', model + '.pessimisticTxLogSize', 'pessimisticTxLogSize', 'true', '0', '0',
+                        'Size of pessimistic transactions log stored on node in order to recover transaction commit if originating node has left grid before it has sent all messages to transaction nodes')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Manager factory
-                        ignite-form-field-tooltip 
-                            | Class name of transaction manager factory for integration with JEE app servers
-                        ignite-form-field-java-class(
-                            data-id='txManagerFactory'
-                            data-name='txManagerFactory'
-                            data-ng-model='#{model}.txManagerFactory'
-                            data-placeholder='Enter fully qualified class name'
-                        )
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterTransactions' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterTransactions' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +java-class('Manager factory:', model + '.txManagerFactory', 'txManagerFactory', 'true', 'false',
+                        'Class name of transaction manager factory for integration with JEE app servers')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterTransactions')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/preview-panel.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/preview-panel.directive.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/preview-panel.directive.js
new file mode 100644
index 0000000..fb67326
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/preview-panel.directive.js
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import ace from 'ace';
+
+export default ['previewPanel', ['$interval', '$timeout', ($interval, $timeout) => {
+    let animation = {editor: null, stage: 0, start: 0, stop: 0};
+    let prevContent = [];
+
+    const Range = ace.require('ace/range').Range;
+
+    const _clearSelection = (editor) => {
+        _.forEach(editor.session.getMarkers(false), (marker) => {
+            editor.session.removeMarker(marker.id);
+        });
+    };
+
+    /**
+     * Switch to next stage of animation.
+     */
+    const _animate = () => {
+        animation.stage += animation.step;
+
+        const stage = animation.stage;
+        const editor = animation.editor;
+
+        _clearSelection(editor);
+
+        animation.selections.forEach((selection) => {
+            editor.session.addMarker(new Range(selection.start, 0, selection.stop, 0),
+                'preview-highlight-' + stage, 'line', false);
+        });
+
+        if (stage === animation.finalStage) {
+            editor.animatePromise = null;
+
+            if (animation.clearOnFinal)
+                _clearSelection(editor);
+        }
+    };
+
+    /**
+     * Selection with animation.
+     *
+     * @param editor Editor to show selection animation.
+     * @param selections Array of selection intervals.
+     * @param step Step of animation (1 or -1).
+     * @param stage Start stage of animation.
+     * @param finalStage Final stage of animation.
+     * @param clearOnFinal Boolean flat to clear selection on animation finish.
+     */
+    const _fade = (editor, selections, step, stage, finalStage, clearOnFinal) => {
+        const promise = editor.animatePromise;
+
+        if (promise) {
+            $interval.cancel(promise);
+
+            _clearSelection(editor);
+        }
+
+        animation = {editor, selections, step, stage, finalStage, clearOnFinal};
+
+        editor.animatePromise = $interval(_animate, 100, 10, false);
+    };
+
+    /**
+     * Show selections with animation.
+     *
+     * @param editor Editor to show selection.
+     * @param selections Array of selection intervals.
+     */
+    const _fadeIn = (editor, selections) => {
+        _fade(editor, selections, 1, 0, 10, false);
+    };
+
+    /**
+     * Hide selections with animation.
+     *
+     * @param editor Editor to show selection.
+     * @param selections Array of selection intervals.
+     */
+    const _fadeOut = (editor, selections) => {
+        _fade(editor, selections, -1, 10, 0, true);
+    };
+
+    const onChange = ([content, editor]) => {
+        const {clearPromise} = editor;
+        const {lines} = content;
+
+        if (content.action === 'remove')
+            prevContent = lines;
+        else if (prevContent.length > 0 && lines.length > 0 && editor.attractAttention) {
+            if (clearPromise) {
+                $timeout.cancel(clearPromise);
+
+                _clearSelection(editor);
+            }
+
+            const selections = [];
+
+            let newIx = 0;
+            let prevIx = 0;
+
+            let prevLen = prevContent.length - (prevContent[prevContent.length - 1] === '' ? 1 : 0);
+            let newLen = lines.length - (lines[lines.length - 1] === '' ? 1 : 0);
+
+            const removed = newLen < prevLen;
+
+            let skipEnd = 0;
+
+            let selected = false;
+            let scrollTo = -1;
+
+            while (lines[newLen - 1] === prevContent[prevLen - 1] && newLen > 0 && prevLen > 0) {
+                prevLen -= 1;
+                newLen -= 1;
+
+                skipEnd += 1;
+            }
+
+            while (newIx < newLen || prevIx < prevLen) {
+                let start = -1;
+                let stop = -1;
+
+                // Find an index of a first line with different text.
+                for (; (newIx < newLen || prevIx < prevLen) && start < 0; newIx++, prevIx++) {
+                    if (newIx >= newLen || prevIx >= prevLen || lines[newIx] !== prevContent[prevIx]) {
+                        start = newIx;
+
+                        break;
+                    }
+                }
+
+                if (start >= 0) {
+                    // Find an index of a last line with different text by checking last string of old and new content in reverse order.
+                    for (let i = start; i < newLen && stop < 0; i++) {
+                        for (let j = prevIx; j < prevLen && stop < 0; j++) {
+                            if (lines[i] === prevContent[j] && lines[i] !== '') {
+                                stop = i;
+
+                                newIx = i;
+                                prevIx = j;
+
+                                break;
+                            }
+                        }
+                    }
+
+                    if (stop < 0) {
+                        stop = newLen;
+
+                        newIx = newLen;
+                        prevIx = prevLen;
+                    }
+
+                    if (start === stop) {
+                        if (removed)
+                            start = Math.max(0, start - 1);
+
+                        stop = Math.min(newLen + skipEnd, stop + 1);
+                    }
+
+                    if (start <= stop) {
+                        selections.push({start, stop});
+
+                        if (!selected)
+                            scrollTo = start;
+
+                        selected = true;
+                    }
+                }
+            }
+
+            // Run clear selection one time.
+            if (selected) {
+                _fadeIn(editor, selections);
+
+                editor.clearPromise = $timeout(() => {
+                    _fadeOut(editor, selections);
+
+                    editor.clearPromise = null;
+                }, 2000);
+
+                editor.scrollToRow(scrollTo);
+            }
+
+            prevContent = [];
+        }
+        else
+            editor.attractAttention = true;
+    };
+
+
+    const link = (scope, $element, $attrs, [igniteUiAceTabs1, igniteUiAceTabs2]) => {
+        const igniteUiAceTabs = igniteUiAceTabs1 || igniteUiAceTabs2;
+
+        if (!igniteUiAceTabs)
+            return;
+
+        igniteUiAceTabs.onLoad = (editor) => {
+            editor.setReadOnly(true);
+            editor.setOption('highlightActiveLine', false);
+            editor.setAutoScrollEditorIntoView(true);
+            editor.$blockScrolling = Infinity;
+            editor.attractAttention = false;
+
+            const renderer = editor.renderer;
+
+            renderer.setHighlightGutterLine(false);
+            renderer.setShowPrintMargin(false);
+            renderer.setOption('fontSize', '10px');
+            renderer.setOption('maxLines', '50');
+
+            editor.setTheme('ace/theme/chrome');
+        };
+
+        igniteUiAceTabs.onChange = onChange;
+    };
+
+    return {
+        restrict: 'C',
+        link,
+        require: ['?igniteUiAceTabs', '?^igniteUiAceTabs']
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/clusters-controller.js b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
index 9469305..e39be4f 100644
--- a/modules/control-center-web/src/main/js/controllers/clusters-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
@@ -263,7 +263,12 @@ consoleModule.controller('clustersController', [
                     msg = errors[firstErrorKey][0].$errorMessages[actualError.$name][firstErrorKey];
                 }
                 catch(ignored) {
-                    msg = 'Invalid value';
+                    try {
+                        msg = form[firstError.$name].$errorMessages[actualError.$name][firstErrorKey];
+                    }
+                    catch(ignited) {
+                        // No-op.
+                    }
                 }
 
                 return showPopoverMessage($scope.ui, firstError.$name, actualError.$name, msg);

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/helpers/generator/generator-java.js b/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
index 45fa410..fe65b45 100644
--- a/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
+++ b/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
@@ -631,12 +631,10 @@ $generatorJava.clusterGeneral = function (cluster, clientNearCfg, res) {
 };
 
 // Generate atomics group.
-$generatorJava.clusterAtomics = function (cluster, res) {
+$generatorJava.clusterAtomics = function (atomics, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    var atomics = cluster.atomicConfiguration;
-
     if ($commonUtils.hasAtLeastOneProperty(atomics, ['cacheMode', 'atomicSequenceReserveSize', 'backups'])) {
         res.startSafeBlock();
 
@@ -667,12 +665,10 @@ $generatorJava.clusterAtomics = function (cluster, res) {
 };
 
 // Generate binary group.
-$generatorJava.clusterBinary = function (cluster, res) {
+$generatorJava.clusterBinary = function (binary, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    var binary = cluster.binaryConfiguration;
-
     if ($generatorCommon.binaryIsDefined(binary)) {
         var varName = 'binary';
 
@@ -808,19 +804,19 @@ $generatorJava.clusterCommunication = function (cluster, res) {
 };
 
 // Generate REST access group.
-$generatorJava.clusterConnector = function (cluster, res) {
+$generatorJava.clusterConnector = function (connector, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    if ($commonUtils.isDefined(cluster.connector) && cluster.connector.enabled) {
+    if ($commonUtils.isDefined(connector) && connector.enabled) {
         var cfg = _.cloneDeep($generatorCommon.CONNECTOR_CONFIGURATION);
 
-        if (cluster.connector.sslEnabled) {
+        if (connector.sslEnabled) {
             cfg.fields.sslClientAuth = {dflt: false};
             cfg.fields.sslFactory = {type: 'bean'};
         }
 
-        $generatorJava.beanProperty(res, 'cfg', cluster.connector, 'connectorConfiguration', 'clientCfg',
+        $generatorJava.beanProperty(res, 'cfg', connector, 'connectorConfiguration', 'clientCfg',
             cfg.className, cfg.fields, true);
 
         res.needEmptyLine = true;
@@ -860,54 +856,56 @@ $generatorJava.clusterDiscovery = function (disco, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    $generatorJava.property(res, 'discovery', disco, 'localAddress');
-    $generatorJava.property(res, 'discovery', disco, 'localPort', null, null, 47500);
-    $generatorJava.property(res, 'discovery', disco, 'localPortRange', null, null, 100);
+    if (disco) {
+        $generatorJava.property(res, 'discovery', disco, 'localAddress');
+        $generatorJava.property(res, 'discovery', disco, 'localPort', null, null, 47500);
+        $generatorJava.property(res, 'discovery', disco, 'localPortRange', null, null, 100);
 
-    if ($commonUtils.isDefinedAndNotEmpty(disco.addressResolver)) {
-        $generatorJava.beanProperty(res, 'discovery', disco, 'addressResolver', 'addressResolver', disco.addressResolver, {}, true);
-        res.needEmptyLine = false;
-    }
+        if ($commonUtils.isDefinedAndNotEmpty(disco.addressResolver)) {
+            $generatorJava.beanProperty(res, 'discovery', disco, 'addressResolver', 'addressResolver', disco.addressResolver, {}, true);
+            res.needEmptyLine = false;
+        }
 
-    $generatorJava.property(res, 'discovery', disco, 'socketTimeout', null, null, 5000);
-    $generatorJava.property(res, 'discovery', disco, 'ackTimeout', null, null, 5000);
-    $generatorJava.property(res, 'discovery', disco, 'maxAckTimeout', null, null, 600000);
-    $generatorJava.property(res, 'discovery', disco, 'networkTimeout', null, null, 5000);
-    $generatorJava.property(res, 'discovery', disco, 'joinTimeout', null, null, 0);
-    $generatorJava.property(res, 'discovery', disco, 'threadPriority', null, null, 10);
-    $generatorJava.property(res, 'discovery', disco, 'heartbeatFrequency', null, null, 2000);
-    $generatorJava.property(res, 'discovery', disco, 'maxMissedHeartbeats', null, null, 1);
-    $generatorJava.property(res, 'discovery', disco, 'maxMissedClientHeartbeats', null, null, 5);
-    $generatorJava.property(res, 'discovery', disco, 'topHistorySize', null, null, 1000);
-
-    if ($commonUtils.isDefinedAndNotEmpty(disco.listener)) {
-        $generatorJava.beanProperty(res, 'discovery', disco, 'listener', 'listener', disco.listener, {}, true);
-        res.needEmptyLine = false;
-    }
+        $generatorJava.property(res, 'discovery', disco, 'socketTimeout', null, null, 5000);
+        $generatorJava.property(res, 'discovery', disco, 'ackTimeout', null, null, 5000);
+        $generatorJava.property(res, 'discovery', disco, 'maxAckTimeout', null, null, 600000);
+        $generatorJava.property(res, 'discovery', disco, 'networkTimeout', null, null, 5000);
+        $generatorJava.property(res, 'discovery', disco, 'joinTimeout', null, null, 0);
+        $generatorJava.property(res, 'discovery', disco, 'threadPriority', null, null, 10);
+        $generatorJava.property(res, 'discovery', disco, 'heartbeatFrequency', null, null, 2000);
+        $generatorJava.property(res, 'discovery', disco, 'maxMissedHeartbeats', null, null, 1);
+        $generatorJava.property(res, 'discovery', disco, 'maxMissedClientHeartbeats', null, null, 5);
+        $generatorJava.property(res, 'discovery', disco, 'topHistorySize', null, null, 1000);
+
+        if ($commonUtils.isDefinedAndNotEmpty(disco.listener)) {
+            $generatorJava.beanProperty(res, 'discovery', disco, 'listener', 'listener', disco.listener, {}, true);
+            res.needEmptyLine = false;
+        }
 
-    if ($commonUtils.isDefinedAndNotEmpty(disco.dataExchange)) {
-        $generatorJava.beanProperty(res, 'discovery', disco, 'dataExchange', 'dataExchange', disco.dataExchange, {}, true);
-        res.needEmptyLine = false;
-    }
+        if ($commonUtils.isDefinedAndNotEmpty(disco.dataExchange)) {
+            $generatorJava.beanProperty(res, 'discovery', disco, 'dataExchange', 'dataExchange', disco.dataExchange, {}, true);
+            res.needEmptyLine = false;
+        }
 
-    if ($commonUtils.isDefinedAndNotEmpty(disco.metricsProvider)) {
-        $generatorJava.beanProperty(res, 'discovery', disco, 'metricsProvider', 'metricsProvider', disco.metricsProvider, {}, true);
-        res.needEmptyLine = false;
-    }
+        if ($commonUtils.isDefinedAndNotEmpty(disco.metricsProvider)) {
+            $generatorJava.beanProperty(res, 'discovery', disco, 'metricsProvider', 'metricsProvider', disco.metricsProvider, {}, true);
+            res.needEmptyLine = false;
+        }
 
-    $generatorJava.property(res, 'discovery', disco, 'reconnectCount', null, null, 10);
-    $generatorJava.property(res, 'discovery', disco, 'statisticsPrintFrequency', null, null, 0);
-    $generatorJava.property(res, 'discovery', disco, 'ipFinderCleanFrequency', null, null, 60000);
+        $generatorJava.property(res, 'discovery', disco, 'reconnectCount', null, null, 10);
+        $generatorJava.property(res, 'discovery', disco, 'statisticsPrintFrequency', null, null, 0);
+        $generatorJava.property(res, 'discovery', disco, 'ipFinderCleanFrequency', null, null, 60000);
 
-    if ($commonUtils.isDefinedAndNotEmpty(disco.authenticator)) {
-        $generatorJava.beanProperty(res, 'discovery', disco, 'authenticator', 'authenticator', disco.authenticator, {}, true);
-        res.needEmptyLine = false;
-    }
+        if ($commonUtils.isDefinedAndNotEmpty(disco.authenticator)) {
+            $generatorJava.beanProperty(res, 'discovery', disco, 'authenticator', 'authenticator', disco.authenticator, {}, true);
+            res.needEmptyLine = false;
+        }
 
-    $generatorJava.property(res, 'discovery', disco, 'forceServerMode', null, null, false);
-    $generatorJava.property(res, 'discovery', disco, 'clientReconnectDisabled', null, null, false);
+        $generatorJava.property(res, 'discovery', disco, 'forceServerMode', null, null, false);
+        $generatorJava.property(res, 'discovery', disco, 'clientReconnectDisabled', null, null, false);
 
-    res.needEmptyLine = true;
+        res.needEmptyLine = true;
+    }
 
     return res;
 };
@@ -1059,11 +1057,11 @@ $generatorJava.clusterPools = function (cluster, res) {
 };
 
 // Generate transactions group.
-$generatorJava.clusterTransactions = function (cluster, res) {
+$generatorJava.clusterTransactions = function (transactionConfiguration, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    $generatorJava.beanProperty(res, 'cfg', cluster.transactionConfiguration, 'transactionConfiguration',
+    $generatorJava.beanProperty(res, 'cfg', transactionConfiguration, 'transactionConfiguration',
         'transactionConfiguration', $generatorCommon.TRANSACTION_CONFIGURATION.className,
         $generatorCommon.TRANSACTION_CONFIGURATION.fields, false);
 
@@ -2474,13 +2472,13 @@ $generatorJava.igfsMisc = function(igfs, varName, res) {
 $generatorJava.clusterConfiguration = function (cluster, clientNearCfg, res) {
     $generatorJava.clusterGeneral(cluster, clientNearCfg, res);
 
-    $generatorJava.clusterAtomics(cluster, res);
+    $generatorJava.clusterAtomics(cluster.atomicConfiguration, res);
 
-    $generatorJava.clusterBinary(cluster, res);
+    $generatorJava.clusterBinary(cluster.binaryConfiguration, res);
 
     $generatorJava.clusterCommunication(cluster, res);
 
-    $generatorJava.clusterConnector(cluster, res);
+    $generatorJava.clusterConnector(cluster.connector, res);
 
     $generatorJava.clusterDeployment(cluster, res);
 
@@ -2496,7 +2494,7 @@ $generatorJava.clusterConfiguration = function (cluster, clientNearCfg, res) {
 
     $generatorJava.clusterPools(cluster, res);
 
-    $generatorJava.clusterTransactions(cluster, res);
+    $generatorJava.clusterTransactions(cluster.transactionConfiguration, res);
 
     var isSrvCfg = !$commonUtils.isDefined(clientNearCfg);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/helpers/generator/generator-xml.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/helpers/generator/generator-xml.js b/modules/control-center-web/src/main/js/helpers/generator/generator-xml.js
index 3cb7ed2..64c5bd5 100644
--- a/modules/control-center-web/src/main/js/helpers/generator/generator-xml.js
+++ b/modules/control-center-web/src/main/js/helpers/generator/generator-xml.js
@@ -485,12 +485,10 @@ $generatorXml.clusterGeneral = function (cluster, res) {
 };
 
 // Generate atomics group.
-$generatorXml.clusterAtomics = function (cluster, res) {
+$generatorXml.clusterAtomics = function (atomics, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    var atomics = cluster.atomicConfiguration;
-
     if ($commonUtils.hasAtLeastOneProperty(atomics, ['cacheMode', 'atomicSequenceReserveSize', 'backups'])) {
         res.startSafeBlock();
 
@@ -523,19 +521,17 @@ $generatorXml.clusterAtomics = function (cluster, res) {
 };
 
 // Generate binary group.
-$generatorXml.clusterBinary = function (cluster, res) {
+$generatorXml.clusterBinary = function (binary, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    var binary = cluster.binaryConfiguration;
-
     if ($generatorCommon.binaryIsDefined(binary)) {
         res.startBlock('<property name="binaryConfiguration">');
         res.startBlock('<bean class="org.apache.ignite.configuration.BinaryConfiguration">');
 
         $generatorXml.simpleBeanProperty(res, binary, 'idMapper');
-        $generatorXml.simpleBeanProperty(res, binary, 'serializer');
         $generatorXml.simpleBeanProperty(res, binary, 'nameMapper');
+        $generatorXml.simpleBeanProperty(res, binary, 'serializer');
 
         if ($commonUtils.isDefinedAndNotEmpty(binary.typeConfigurations)) {
             res.startBlock('<property name="typeConfigurations">');
@@ -590,23 +586,23 @@ $generatorXml.clusterCommunication = function (cluster, res) {
 /**
  * XML generator for cluster's REST access configuration.
  *
- * @param cluster Cluster to get REST configuration.
+ * @param connector Cluster REST connector configuration.
  * @param res Optional configuration presentation builder object.
  * @returns Configuration presentation builder object
  */
-$generatorXml.clusterConnector = function(cluster, res) {
+$generatorXml.clusterConnector = function(connector, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    if ($commonUtils.isDefined(cluster.connector) && cluster.connector.enabled) {
+    if ($commonUtils.isDefined(connector) && connector.enabled) {
         var cfg = _.cloneDeep($generatorCommon.CONNECTOR_CONFIGURATION);
 
-        if (cluster.connector.sslEnabled) {
+        if (connector.sslEnabled) {
             cfg.fields.sslClientAuth = {dflt: false};
             cfg.fields.sslFactory = {type: 'bean'};
         }
 
-        $generatorXml.beanProperty(res, cluster.connector, 'connectorConfiguration', cfg, true);
+        $generatorXml.beanProperty(res, connector, 'connectorConfiguration', cfg, true);
 
         res.needEmptyLine = true;
     }
@@ -644,36 +640,38 @@ $generatorXml.clusterDiscovery = function (disco, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    $generatorXml.property(res, disco, 'localAddress');
-    $generatorXml.property(res, disco, 'localPort', null, 47500);
-    $generatorXml.property(res, disco, 'localPortRange', null, 100);
-    if ($commonUtils.isDefinedAndNotEmpty(disco.addressResolver))
-        $generatorXml.beanProperty(res, disco, 'addressResolver', {className: disco.addressResolver}, true);
-    $generatorXml.property(res, disco, 'socketTimeout', null, 5000);
-    $generatorXml.property(res, disco, 'ackTimeout', null, 5000);
-    $generatorXml.property(res, disco, 'maxAckTimeout', null, 600000);
-    $generatorXml.property(res, disco, 'networkTimeout', null, 5000);
-    $generatorXml.property(res, disco, 'joinTimeout', null, 0);
-    $generatorXml.property(res, disco, 'threadPriority', null, 10);
-    $generatorXml.property(res, disco, 'heartbeatFrequency', null, 2000);
-    $generatorXml.property(res, disco, 'maxMissedHeartbeats', null, 1);
-    $generatorXml.property(res, disco, 'maxMissedClientHeartbeats', null, 5);
-    $generatorXml.property(res, disco, 'topHistorySize', null, 1000);
-    if ($commonUtils.isDefinedAndNotEmpty(disco.listener))
-        $generatorXml.beanProperty(res, disco, 'listener', {className: disco.listener}, true);
-    if ($commonUtils.isDefinedAndNotEmpty(disco.dataExchange))
-        $generatorXml.beanProperty(res, disco, 'dataExchange', {className: disco.dataExchange}, true);
-    if ($commonUtils.isDefinedAndNotEmpty(disco.metricsProvider))
-        $generatorXml.beanProperty(res, disco, 'metricsProvider', {className: disco.metricsProvider}, true);
-    $generatorXml.property(res, disco, 'reconnectCount', null, 10);
-    $generatorXml.property(res, disco, 'statisticsPrintFrequency', null, 0);
-    $generatorXml.property(res, disco, 'ipFinderCleanFrequency', null, 60000);
-    if ($commonUtils.isDefinedAndNotEmpty(disco.authenticator))
-        $generatorXml.beanProperty(res, disco, 'authenticator', {className: disco.authenticator}, true);
-    $generatorXml.property(res, disco, 'forceServerMode', null, false);
-    $generatorXml.property(res, disco, 'clientReconnectDisabled', null, false);
+    if (disco) {
+        $generatorXml.property(res, disco, 'localAddress');
+        $generatorXml.property(res, disco, 'localPort', null, 47500);
+        $generatorXml.property(res, disco, 'localPortRange', null, 100);
+        if ($commonUtils.isDefinedAndNotEmpty(disco.addressResolver))
+            $generatorXml.beanProperty(res, disco, 'addressResolver', {className: disco.addressResolver}, true);
+        $generatorXml.property(res, disco, 'socketTimeout', null, 5000);
+        $generatorXml.property(res, disco, 'ackTimeout', null, 5000);
+        $generatorXml.property(res, disco, 'maxAckTimeout', null, 600000);
+        $generatorXml.property(res, disco, 'networkTimeout', null, 5000);
+        $generatorXml.property(res, disco, 'joinTimeout', null, 0);
+        $generatorXml.property(res, disco, 'threadPriority', null, 10);
+        $generatorXml.property(res, disco, 'heartbeatFrequency', null, 2000);
+        $generatorXml.property(res, disco, 'maxMissedHeartbeats', null, 1);
+        $generatorXml.property(res, disco, 'maxMissedClientHeartbeats', null, 5);
+        $generatorXml.property(res, disco, 'topHistorySize', null, 1000);
+        if ($commonUtils.isDefinedAndNotEmpty(disco.listener))
+            $generatorXml.beanProperty(res, disco, 'listener', {className: disco.listener}, true);
+        if ($commonUtils.isDefinedAndNotEmpty(disco.dataExchange))
+            $generatorXml.beanProperty(res, disco, 'dataExchange', {className: disco.dataExchange}, true);
+        if ($commonUtils.isDefinedAndNotEmpty(disco.metricsProvider))
+            $generatorXml.beanProperty(res, disco, 'metricsProvider', {className: disco.metricsProvider}, true);
+        $generatorXml.property(res, disco, 'reconnectCount', null, 10);
+        $generatorXml.property(res, disco, 'statisticsPrintFrequency', null, 0);
+        $generatorXml.property(res, disco, 'ipFinderCleanFrequency', null, 60000);
+        if ($commonUtils.isDefinedAndNotEmpty(disco.authenticator))
+            $generatorXml.beanProperty(res, disco, 'authenticator', {className: disco.authenticator}, true);
+        $generatorXml.property(res, disco, 'forceServerMode', null, false);
+        $generatorXml.property(res, disco, 'clientReconnectDisabled', null, false);
 
-    res.needEmptyLine = true;
+        res.needEmptyLine = true;
+    }
 
     return res;
 };
@@ -803,11 +801,11 @@ $generatorXml.clusterPools = function (cluster, res) {
 };
 
 // Generate transactions group.
-$generatorXml.clusterTransactions = function (cluster, res) {
+$generatorXml.clusterTransactions = function (transactionConfiguration, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    $generatorXml.beanProperty(res, cluster.transactionConfiguration, 'transactionConfiguration', $generatorCommon.TRANSACTION_CONFIGURATION, false);
+    $generatorXml.beanProperty(res, transactionConfiguration, 'transactionConfiguration', $generatorCommon.TRANSACTION_CONFIGURATION, false);
 
     res.needEmptyLine = true;
 
@@ -1663,13 +1661,13 @@ $generatorXml.clusterConfiguration = function (cluster, clientNearCfg, res) {
 
     $generatorXml.clusterGeneral(cluster, res);
 
-    $generatorXml.clusterAtomics(cluster, res);
+    $generatorXml.clusterAtomics(cluster.atomicConfiguration, res);
 
-    $generatorXml.clusterBinary(cluster, res);
+    $generatorXml.clusterBinary(cluster.binaryConfiguration, res);
 
     $generatorXml.clusterCommunication(cluster, res);
 
-    $generatorXml.clusterConnector(cluster, res);
+    $generatorXml.clusterConnector(cluster.connector, res);
 
     $generatorXml.clusterDeployment(cluster, res);
 
@@ -1685,7 +1683,7 @@ $generatorXml.clusterConfiguration = function (cluster, clientNearCfg, res) {
 
     $generatorXml.clusterPools(cluster, res);
 
-    $generatorXml.clusterTransactions(cluster, res);
+    $generatorXml.clusterTransactions(cluster.transactionConfiguration, res);
 
     $generatorXml.clusterCaches(cluster.caches, cluster.igfss, isSrvCfg, res);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/views/configuration/clusters.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/configuration/clusters.jade b/modules/control-center-web/src/main/js/views/configuration/clusters.jade
index 4c4fb52..3d15324 100644
--- a/modules/control-center-web/src/main/js/views/configuration/clusters.jade
+++ b/modules/control-center-web/src/main/js/views/configuration/clusters.jade
@@ -51,8 +51,8 @@ include ../includes/infos
                             ignite-configuration-clusters-metrics
                             ignite-configuration-clusters-ssl
                             ignite-configuration-clusters-swap
-                            ignite-configuration-clusters-time
                             ignite-configuration-clusters-thread
+                            ignite-configuration-clusters-time
                             ignite-configuration-clusters-transactions
 
                             ignite-advanced-options-toggle


[41/50] [abbrv] ignite git commit: IGNITE-843 Minor fix.

Posted by an...@apache.org.
IGNITE-843 Minor fix.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e7dd8467
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e7dd8467
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e7dd8467

Branch: refs/heads/ignite-2875
Commit: e7dd8467df032c6aff3285c60ecef4a500201da1
Parents: c9a39bc
Author: Andrey <an...@gridgain.com>
Authored: Fri Mar 25 13:32:46 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Mar 25 13:32:46 2016 +0700

----------------------------------------------------------------------
 .../control-center-web/src/main/js/views/settings/profile.jade   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e7dd8467/modules/control-center-web/src/main/js/views/settings/profile.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/settings/profile.jade b/modules/control-center-web/src/main/js/views/settings/profile.jade
index df8fd7d..f36f0b4 100644
--- a/modules/control-center-web/src/main/js/views/settings/profile.jade
+++ b/modules/control-center-web/src/main/js/views/settings/profile.jade
@@ -50,7 +50,7 @@ mixin lbl(txt)
                             i.fa(
                             ng-click='expandedToken = !expandedToken'
                             ng-class='expandedToken ? "fa-chevron-circle-down" : "fa-chevron-circle-right"')
-                            a(ng-click='expandedToken = !expandedToken') {{expandedToken ? 'Hide security token...' : 'Show security token...'}}
+                            a(ng-click='expandedToken = !expandedToken') {{expandedToken ? 'Cancel security token changing...' : 'Show security token...'}}
                         div(ng-show='expandedToken')
                             +lbl('Security token:')
                             label {{user.token}}
@@ -63,7 +63,7 @@ mixin lbl(txt)
                             ng-click='expandedPassword = !expandedPassword'
                             ng-class='expandedPassword ? "fa-chevron-circle-down" : "fa-chevron-circle-right"')
                             a(ng-click='expandedPassword = !expandedPassword') {{expandedPassword ? 'Cancel password changing...' : 'Change password...'}}
-                        div(ng-show='expandedPassword')
+                        div(ng-if='expandedPassword')
                             .details-row
                                 +lbl('New password:')
                                 .col-xs-5.col-sm-4


[24/50] [abbrv] ignite git commit: IGNITE-2840 Refactoring to mixins.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
index 842506f..20312e7 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem'
 - var exclude = model + '.peerClassLoadingLocalClassPathExclude'
 - var form = 'deployment'
@@ -21,9 +23,9 @@
 
 mixin feedback(name, error, message)
     i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='!#{form}.#{name}.$pristine && #{form}.#{name}.$error.#{error}'
+        ng-show=form + '.' + name +  '.$error.' + error
         bs-tooltip
-        data-title='#{message}'
+        data-title=message
     )
 
 form.panel.panel-default(name='#{form}' novalidate)
@@ -37,160 +39,71 @@ form.panel.panel-default(name='#{form}' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Deployment mode:
-                        ignite-form-field-tooltip
-                            | Task classes and resources sharing mode#[br]
-                            | The following deployment modes are supported:#[br]
-                            ul
-                                li PRIVATE - in this mode deployed classes do not share resources
-                                li ISOLATED - in this mode tasks or classes deployed within the same class loader will share the same instances of resources
-                                li SHARED - same as ISOLATED, but now tasks from different master nodes with the same user version and same class loader will share the same class loader on remote nodes
-                                li CONTINUOUS - same as SHARED deployment mode, but resources will not be undeployed even after all master nodes left grid
-                        ignite-form-field-dropdown(
-                            data-id='deploymentMode'
-                            data-name='deploymentMode'
-                            data-options='[\
-                                {value: "PRIVATE", label: "PRIVATE"},\
-                                {value: "ISOLATED", label: "ISOLATED"}, \
-                                {value: "SHARED", label: "SHARED"},\
-                                {value: "CONTINUOUS", label: "CONTINUOUS"}\
-                            ]'
-                            data-ng-model='#{model}.deploymentMode'
-                            data-placeholder='SHARED'
-                        )
+                    +dropdown('Deployment mode:', model + '.deploymentMode', 'deploymentMode', 'true', 'SHARED',
+                        '[\
+                            {value: "PRIVATE", label: "PRIVATE"},\
+                            {value: "ISOLATED", label: "ISOLATED"}, \
+                            {value: "SHARED", label: "SHARED"},\
+                            {value: "CONTINUOUS", label: "CONTINUOUS"}\
+                        ]',
+                        'Task classes and resources sharing mode<br/>\
+                        The following deployment modes are supported:\
+                        <ul>\
+                            <li>PRIVATE - in this mode deployed classes do not share resources</li>\
+                            <li>ISOLATED - in this mode tasks or classes deployed within the same class loader will share the same instances of resources</li>\
+                            <li>SHARED - same as ISOLATED, but now tasks from different master nodes with the same user version and same class loader will share the same class loader on remote nodes</li>\
+                            <li>CONTINUOUS - same as SHARED deployment mode, but resources will not be undeployed even after all master nodes left grid</li>\
+                        </ul>')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='peerClassLoadingEnabled'
-                            data-name='peerClassLoadingEnabled'
-                            data-ng-model='#{model}.peerClassLoadingEnabled'
-                        )
-                        | Enable peer class loading
-                        ignite-form-field-tooltip
-                            | Enables/disables peer class loading
+                    +checkbox('Enable peer class loading', model + '.peerClassLoadingEnabled', 'peerClassLoadingEnabled', 'Enables/disables peer class loading')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Missed resources cache size:
-                        ignite-form-field-tooltip
-                            | If size greater than 0, missed resources will be cached and next resource request ignored
-                            | If size is 0, then request for the resource will be sent to the remote node every time this resource is requested
-                        ignite-form-field-input-number(
-                            data-id='peerClassLoadingMissedResourcesCacheSize'
-                            data-name='peerClassLoadingMissedResourcesCacheSize'
-                            data-ng-model='#{model}.peerClassLoadingMissedResourcesCacheSize'
-                            data-placeholder='100'
-                            data-ng-disabled='!#{enabled}'
-                        )
+                    +number('Missed resources cache size:', model + '.peerClassLoadingMissedResourcesCacheSize', 'peerClassLoadingMissedResourcesCacheSize', enabled, '100', '0',
+                        'If size greater than 0, missed resources will be cached and next resource request ignored<br/>\
+                        If size is 0, then request for the resource will be sent to the remote node every time this resource is requested')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Pool size:
-                        ignite-form-field-tooltip
-                            | Thread pool size to use for peer class loading
-                        ignite-form-field-input-number(
-                            data-id='peerClassLoadingThreadPoolSize'
-                            data-name='peerClassLoadingThreadPoolSize'
-                            data-ng-model='#{model}.peerClassLoadingThreadPoolSize'
-                            data-placeholder='2'
-                            data-ng-disabled='!#{enabled}'
-                            data-min='1'
-                        )
+                    +number('Pool size:', model + '.peerClassLoadingThreadPoolSize', 'peerClassLoadingThreadPoolSize', enabled, '2', '1', 'Thread pool size to use for peer class loading')
                 .settings-row
-                    ignite-form-group(ng-model='#{exclude}' ng-form='#{form}' )
+                    ignite-form-group(ng-model=exclude ng-form=form)
                         ignite-form-field-label
                             | Local class path exclude
                         ignite-form-group-tooltip
-                            | List of packages from the system classpath that need to be peer-to-peer loaded from task originating node#[br]
+                            | List of packages from the system classpath that need to be peer-to-peer loaded from task originating node<br/>
                             | '*' is supported at the end of the package name which means that all sub-packages and their classes are included like in Java package import clause
                         ignite-form-group-add(ng-show='#{enabled}' ng-click='(group.add = [{}])')
                             | Add package name.
 
-                        - var field = 'edit'
-                        - var valid = form + '.' + field + '.$valid'
-                        - var save = exclude + '[$index] = ' + field
+                        .group-content(ng-if=exclude + '.length')
+                            - var field = 'edit'
+                            - var valid = form + '.' + field + '.$valid'
+                            - var save = exclude + '[$index] = ' + field
 
-                        .group-content(ng-if='#{exclude}.length')
-                            ignite-form-field(ng-repeat='model in #{exclude} track by $index' type='internal')
+                            ignite-form-field(ng-repeat='model in #{exclude} track by $index' type='internal' name='Package name')
                                 .indexField
-                                    | {{ $index+1 }}) 
-                                i.tipField.fa.fa-remove(
-                                    ng-hide='field.edit'
-                                    bs-tooltip='"Remove package name"'
-                                    ng-click='#{exclude}.splice(#{exclude}.indexOf(model), 1)'
-                                )
+                                    | {{ $index+1 }})
+                                +table-remove-button(exclude, 'Remove package name')
                                 span(ng-hide='field.edit')
                                     a.labelFormField(ng-click='#{enabled} && (field.edit = true)') {{ model }}
                                 span(ng-if='field.edit' ng-init='#{field} = model')
-                                    ignite-form-field-input-text(
-                                        data-name='#{field}'
-                                        data-ng-model='#{field}'
-                                        data-ng-required='true'
-                                        data-placeholder='Enter package name'
-                                        data-java-keywords='true'
-                                        data-java-package-name='true'
-                                        data-ignite-unique='#{exclude}'
-                                        data-ignite-form-field-input-autofocus='true'
-                                        on-enter='#{valid} && (#{save}); #{valid} && (field.edit = false);'
-                                        on-escape='field.edit = false'
-                                        ng-blur='#{valid} && (#{save}); (field.edit = false)'
-                                    )
-                                        i.fa.fa-floppy-o(
-                                            ng-show='#{valid}'
-                                            ng-click='#{valid} && (#{save}); #{valid} && (field.edit = false);'
-                                            bs-tooltip 
-                                            data-title='Click icon or press [Enter] to save item' 
-                                        )
-
-                                        +feedback(field, 'required', 'Package name could not be empty')
+                                    +table-java-package-field(field, exclude, save, false)
+                                        +table-save-button(valid, save, false)
+                                        +table-feedback-unique(form, field, 'Such package already exists')
                                         +feedback(field, 'javaPackageName', 'Package name is invalid')
                                         +feedback(field, 'javaKeywords', 'Package name could not contains reserved java keyword')
-                                        +feedback(field, 'igniteUnique', 'Such package already exists')
-
-                        - var field = 'new'
-                        - var valid = form + '.' + field + '.$valid'
-                        - var push = exclude + '.push(' + field + ')'
 
                         .group-content(ng-repeat='field in group.add')
-                            ignite-form-field(type='internal')
-                                ignite-form-field-input-text(
-                                    data-name='#{field}'
-                                    data-ng-model='#{field}'
-                                    data-ng-required='true'
-                                    data-placeholder='Enter package name'
-                                    data-java-keywords='true'
-                                    data-java-package-name='true'
-                                    data-ignite-unique='#{exclude}'
-                                    data-ignite-form-field-input-autofocus='true'
-                                    on-enter='#{valid} && #{push}; #{valid} && (stopblur = true) && (group.add = [{}])'
-                                    on-escape='group.add = []'
-                                    ng-blur='#{valid} && #{push}; !stopblur && (group.add = [])'
-                                )
-                                    i.fa.fa-floppy-o(
-                                        ng-show='#{valid}'
-                                        ng-click='#{valid} && #{push}; #{valid} && (group.add = [])'
-                                        bs-tooltip 
-                                        data-title='Click icon or press [Enter] to save item' 
-                                    )
+                            - var field = 'new'
+                            - var valid = form + '.' + field + '.$valid'
+                            - var save = exclude + '.push(' + field + ')'
 
-                                    +feedback(field, 'required', 'Package name could not be empty')
+                            ignite-form-field(type='internal' name='Package name')
+                                +table-java-package-field(field, exclude, save, true)
+                                    +table-save-button(valid, save, true)
+                                    +table-feedback-unique(form, field, 'Such package already exists')
                                     +feedback(field, 'javaPackageName', 'Package name is invalid')
                                     +feedback(field, 'javaKeywords', 'Package name could not contains reserved java keyword')
-                                    +feedback(field, 'igniteUnique', 'Such package already exists')
-            
+
+
                         .group-content-empty(ng-if='!(#{exclude}.length) && !group.add.length')
                             | Not defined
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterDeployment' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterDeployment' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+            .col-sm-6
+                +preview-xml-java(model, 'clusterDeployment')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
index 58959b6..6077ab5 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery'
 
 form.panel.panel-default(name='discovery' novalidate)
@@ -27,292 +29,52 @@ form.panel.panel-default(name='discovery' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                   ignite-form-field
-                        ignite-form-field-label
-                            | Local address:
-                        ignite-form-field-tooltip
-                            | Local address
-                        ignite-form-field-input-text(
-                            data-id='discoLocalAddress'
-                            data-name='discoLocalAddress'
-                            data-ng-model='#{model}.localAddress'
-                            data-placeholder='228.1.2.4'
-                        )
+                    +text-ip-address('Local address:', model + '.localAddress', 'discoLocalAddress', 'true', '228.1.2.4', 'Local address')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Local port:
-                        ignite-form-field-tooltip
-                            | Local port which node uses
-                        ignite-form-field-input-number(
-                            data-id='discoLocalPort'
-                            data-name='discoLocalPort'
-                            data-ng-model='#{model}.localPort'
-                            data-min='1024'
-                            data-max='65535'
-                            data-placeholder='47500'
-                        )
+                    +number-min-max('Local port:', model + '.localPort', 'discoLocalPort', 'true', '47500', '1024', '65535', 'Local port which node uses')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Local port range:
-                        ignite-form-field-tooltip
-                            | Local port range
-                        ignite-form-field-input-number(
-                            data-id='discoLocalPortRange'
-                            data-name='discoLocalPortRange'
-                            data-ng-model='#{model}.localPortRange'
-                            data-placeholder='100'
-                            data-min='1'
-                        )
+                    +number('Local port range:', model + '.localPortRange', 'discoLocalPortRange', 'true', '100', '1', 'Local port range')
                 .settings-row
-                   ignite-form-field
-                        ignite-form-field-label
-                            | Address resolver:
-                        ignite-form-field-tooltip
-                            | Class name of resolution between external and internal addresses provider
-                        ignite-form-field-java-class(
-                            data-id='discoAddressResolver'
-                            data-name='discoAddressResolver'
-                            data-ng-model='#{model}.addressResolver'
-                        )
+                    +java-class('Address resolver:', model + '.addressResolver', 'discoAddressResolver', 'true', 'false',
+                        'Class name of resolution between external and internal addresses provider')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Socket timeout:
-                        ignite-form-field-tooltip
-                            | Socket operations timeout
-                        ignite-form-field-input-number(
-                            data-id='socketTimeout'
-                            data-name='socketTimeout'
-                            data-ng-model='#{model}.socketTimeout'
-                            data-placeholder='5000'
-                        )
+                    +number('Socket timeout:', model + '.socketTimeout', 'socketTimeout', 'true', '5000', '0', 'Socket operations timeout')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Acknowledgement timeout:
-                        ignite-form-field-tooltip
-                            | Message acknowledgement timeout
-                        ignite-form-field-input-number(
-                            data-id='ackTimeout'
-                            data-name='ackTimeout'
-                            data-ng-model='#{model}.ackTimeout'
-                            data-placeholder='5000'
-                        )
+                    +number('Acknowledgement timeout:', model + '.ackTimeout', 'ackTimeout', 'true', '5000', '0', 'Message acknowledgement timeout')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Max acknowledgement timeout:
-                        ignite-form-field-tooltip
-                            | Maximum message acknowledgement timeout
-                        ignite-form-field-input-number(
-                            data-id='maxAckTimeout'
-                            data-name='maxAckTimeout'
-                            data-ng-model='#{model}.maxAckTimeout'
-                            data-placeholder='600000'
-                        )
+                    +number('Max acknowledgement timeout:', model + '.maxAckTimeout', 'maxAckTimeout', 'true', '600000', '0', 'Maximum message acknowledgement timeout')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Network timeout:
-                        ignite-form-field-tooltip
-                            | Network timeout
-                        ignite-form-field-input-number(
-                            data-id='discoNetworkTimeout'
-                            data-name='discoNetworkTimeout'
-                            data-ng-model='#{model}.networkTimeout'
-                            data-placeholder='5000'
-                            data-min='1'
-                        )
+                    +number('Network timeout:', model + '.networkTimeout', 'discoNetworkTimeout', 'true', '5000', '1', 'Network timeout')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Join timeout:
-                        ignite-form-field-tooltip
-                            | Join timeout
-                        ignite-form-field-input-number(
-                            data-id='joinTimeout'
-                            data-name='joinTimeout'
-                            data-ng-model='#{model}.joinTimeout'
-                            data-placeholder='0'
-                        )
+                    +number('Join timeout:', model + '.joinTimeout', 'joinTimeout', 'true', '0', '0', 'Join timeout')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Thread priority:
-                        ignite-form-field-tooltip
-                            | Thread priority for all threads started by SPI
-                        ignite-form-field-input-number(
-                            data-id='threadPriority'
-                            data-name='threadPriority'
-                            data-ng-model='#{model}.threadPriority'
-                            data-placeholder='10'
-                            data-min='1'
-                        )
+                    +number('Thread priority:', model + '.threadPriority', 'threadPriority', 'true', '10', '1', 'Thread priority for all threads started by SPI')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Heartbeat frequency:
-                        ignite-form-field-tooltip
-                            | Heartbeat messages issuing frequency
-                        ignite-form-field-input-number(
-                            data-id='heartbeatFrequency'
-                            data-name='heartbeatFrequency'
-                            data-ng-model='#{model}.heartbeatFrequency'
-                            data-placeholder='2000'
-                            data-min='1'
-                        )
+                    +number('Heartbeat frequency:', model + '.heartbeatFrequency', 'heartbeatFrequency', 'true', '2000', '1', 'Heartbeat messages issuing frequency')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Max heartbeats miss w/o init:
-                        ignite-form-field-tooltip
-                            | Max heartbeats count node can miss without initiating status check
-                        ignite-form-field-input-number(
-                            data-id='maxMissedHeartbeats'
-                            data-name='maxMissedHeartbeats'
-                            data-ng-model='#{model}.maxMissedHeartbeats'
-                            data-placeholder='1'
-                            data-min='1'
-                        )
+                    +number('Max heartbeats miss w/o init:', model + '.maxMissedHeartbeats', 'maxMissedHeartbeats', 'true', '1', '1',
+                        'Max heartbeats count node can miss without initiating status check')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Max heartbeats miss w/o failing client node:
-                        ignite-form-field-tooltip
-                            | Max heartbeats count node can miss without failing client node
-                        ignite-form-field-input-number(
-                            data-id='maxMissedClientHeartbeats'
-                            data-name='maxMissedClientHeartbeats'
-                            data-ng-model='#{model}.maxMissedClientHeartbeats'
-                            data-placeholder='5'
-                            data-min='1'
-                        )
+                    +number('Max heartbeats miss w/o failing client node:', model + '.maxMissedClientHeartbeats', 'maxMissedClientHeartbeats', 'true', '5', '1')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Topology history:
-                        ignite-form-field-tooltip
-                            | Size of topology snapshots history
-                        ignite-form-field-input-number(
-                            data-id='topHistorySize'
-                            data-name='topHistorySize'
-                            data-ng-model='#{model}.topHistorySize'
-                            data-placeholder='1000'
-                        )
+                    +number('Topology history:', model + '.topHistorySize', 'topHistorySize', 'true', '1000', '0', 'Size of topology snapshots history')
                 .settings-row
-                   ignite-form-field
-                        ignite-form-field-label
-                            | Discovery listener:
-                        ignite-form-field-tooltip
-                            | Grid discovery listener
-                        ignite-form-field-java-class(
-                            data-id='discoListener'
-                            data-name='discoListener'
-                            data-ng-model='#{model}.listener'
-                        )
+                    +java-class('Discovery listener:', model + '.listener', 'discoListener', 'true', 'false', 'Grid discovery listener')
                 .settings-row
-                   ignite-form-field
-                        ignite-form-field-label
-                            | Data exchange:
-                        ignite-form-field-tooltip
-                            | Class name of handler for initial data exchange between Ignite nodes
-                        ignite-form-field-java-class(
-                            data-id='dataExchange'
-                            data-name='dataExchange'
-                            data-ng-model='#{model}.dataExchange'
-                        )
+                    +java-class('Data exchange:', model + '.dataExchange', 'dataExchange', 'true', 'false', 'Class name of handler for initial data exchange between Ignite nodes')
                 .settings-row
-                   ignite-form-field
-                        ignite-form-field-label
-                            | Metrics provider:
-                        ignite-form-field-tooltip
-                            | Class name of metric provider to discovery SPI
-                        ignite-form-field-java-class(
-                            data-id='metricsProvider'
-                            data-name='metricsProvider'
-                            data-ng-model='#{model}.metricsProvider'
-                        )
+                    +java-class('Metrics provider:', model + '.metricsProvider', 'metricsProvider', 'true', 'false', 'Class name of metric provider to discovery SPI')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Reconnect count:
-                        ignite-form-field-tooltip
-                            | Reconnect attempts count
-                        ignite-form-field-input-number(
-                            data-id='discoReconnectCount'
-                            data-name='discoReconnectCount'
-                            data-ng-model='#{model}.reconnectCount'
-                            data-placeholder='10'
-                            data-min='1'
-                        )
+                    +number('Reconnect count:', model + '.reconnectCount', 'discoReconnectCount', 'true', '10', '1', 'Reconnect attempts count')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Statistics frequency:
-                        ignite-form-field-tooltip
-                            | Statistics print frequency
-                        ignite-form-field-input-number(
-                            data-id='statisticsPrintFrequency'
-                            data-name='statisticsPrintFrequency'
-                            data-ng-model='#{model}.statisticsPrintFrequency'
-                            data-placeholder='0'
-                            data-min='1'
-                        )
+                    +number('Statistics frequency:', model + '.statisticsPrintFrequency', 'statisticsPrintFrequency', 'true', '0', '1', 'Statistics print frequency')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | IP finder clean frequency:
-                        ignite-form-field-tooltip
-                            | IP finder clean frequency
-                        ignite-form-field-input-number(
-                            data-id='ipFinderCleanFrequency'
-                            data-name='ipFinderCleanFrequency'
-                            data-ng-model='#{model}.ipFinderCleanFrequency'
-                            data-placeholder='60000'
-                            data-min='1'
-                        )
+                    +number('IP finder clean frequency:', model + '.ipFinderCleanFrequency', 'ipFinderCleanFrequency', 'true', '60000', '1', 'IP finder clean frequency')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Node authenticator:
-                        ignite-form-field-tooltip
-                            | Node authenticator
-                        ignite-form-field-java-class(
-                            data-id='authenticator'
-                            data-name='authenticator'
-                            data-ng-model='#{model}.authenticator'
-                        )
+                    +java-class('Node authenticator:', model + '.authenticator', 'authenticator', 'true', 'false', 'Node authenticator')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='forceServerMode'
-                            data-name='forceServerMode'
-                            data-ng-model='#{model}.forceServerMode'
-                        )
-                        | Force server mode
-                        ignite-form-field-tooltip
-                            | Force server mode
+                    +checkbox('Force server mode', model + '.forceServerMode', 'forceServerMode', 'Force server mode')
                 .settings-row
-                    ignite-form-field.checkbox
-                        ignite-form-field-input-checkbox(
-                            data-id='clientReconnectDisabled'
-                            data-name='clientReconnectDisabled'
-                            data-ng-model='#{model}.clientReconnectDisabled'
-                        )
-                        | Client reconnect disabled
-                        ignite-form-field-tooltip
-                            | Client reconnect disabled
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterDiscovery' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterDiscovery' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +checkbox('Client reconnect disabled', model + '.clientReconnectDisabled', 'clientReconnectDisabled', 'Client reconnect disabled')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterDiscovery')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/events.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/events.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/events.jade
index d221cbc..edcde05 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/events.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/events.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem'
 
 form.panel.panel-default(name='events' novalidate)
@@ -27,29 +29,8 @@ form.panel.panel-default(name='events' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Include type:
-                        ignite-form-field-tooltip
-                            | Array of event types, which will be recorded by GridEventStorageManager#record(Event)#[br]
-                            | Note, that either the include event types or the exclude event types can be established
-                        ignite-form-field-dropdown(
-                            data-id='includeEventTypes'
-                            data-name='includeEventTypes'
-                            data-options='eventGroups'
-                            data-multiple='true'
-                            data-ng-model='#{model}.includeEventTypes'
-                            data-placeholder='Choose recorded event types'
-                        )
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterEvents' ng-model='$parent.data')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterEvents' ng-model='$parent.data')
-                    .preview-content-empty(ng-if='!data')
-                        label All Defaults
+                    +dropdown-multiple('Include type:', model + '.includeEventTypes', 'includeEventTypes', 'Choose recorded event types', '', 'eventGroups',
+                        'Array of event types, which will be recorded by GridEventStorageManager#record(Event)<br/>\
+                        Note, that either the include event types or the exclude event types can be established')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterEvents')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
index aa29382..2f5771d 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem'
 
 form.panel.panel-default(name='general' novalidate)
@@ -25,66 +27,27 @@ form.panel.panel-default(name='general' novalidate)
         .panel-body
             .col-sm-6
                 .settings-row
-                   ignite-form-field
-                        ignite-form-field-label
-                            | Name:
-                        ignite-form-field-tooltip
-                            | Grid name
-                        ignite-form-field-input-text(
-                            data-id='clusterName'
-                            data-name='clusterName'
-                            data-ng-model='#{model}.name'
-                            data-ng-required='true'
-                            data-placeholder='Input name'
-                        )
+                    +text('Name:', model + '.name', 'clusterName', 'true', 'Input name', 'Grid name')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Caches: #[a(ui-sref='base.configuration.caches({id: #{model}._id})') (add)]
-                        ignite-form-field-tooltip
-                            | Select caches to start in cluster or add a new cache
-                        ignite-form-field-dropdown(
-                            data-id='caches'
-                            data-name='caches'
-                            data-options='caches'
-                            data-multiple='true'
-                            data-ng-model='#{model}.caches'
-                            data-ng-disabled='!caches.length'
-                            data-placeholder='{{ caches.length ? "Choose caches": "No caches configured" }}'
-                        )
+                    +dropdown-multiple('<span>Caches:</span>' +
+                        '<a ui-sref="base.configuration.caches({id: ' + model + '._id})"> (add)</a>',
+                        model + '.caches', 'caches', 'Choose caches', 'No caches configured', 'caches',
+                        'Select caches to start in cluster or add a new cache')
                 .settings-row
-                   ignite-form-field
-                        ignite-form-field-label
-                            | Local host:
-                        ignite-form-field-tooltip
-                            | System-wide local address or host for all Ignite components to bind to
-                        ignite-form-field-input-text(
-                            data-id='localHost'
-                            data-name='localHost'
-                            data-ng-model='#{model}.localHost'
-                            data-placeholder='0.0.0.0'
-                        )
+                    +text-ip-address('Local host:', model + '.localHost', 'localHost', 'true', '0.0.0.0', 'System-wide local address or host for all Ignite components to bind to')
                 .settings-row
-                    ignite-form-field
-                        ignite-form-field-label
-                            | Discovery:
-                        ignite-form-field-tooltip
-                            | Discovery allows to discover remote nodes in grid
-                            ul: li Static IPs - IP Finder which works only with pre configured list of IP addresses specified
-                                li Multicast - Multicast based IP finder
-                                li AWS S3 - AWS S3 based IP finder
-                                li Apache jclouds - Apache jclouds multi cloud toolkit based IP finder
-                                li Google cloud storage - Google Cloud Storage based IP finder
-                                li JDBC - JDBC based IP finder
-                                li Shared filesystem - Shared filesystem based IP finder
-                                li Apache ZooKeeper - Apache ZooKeeper based IP finder
-                        ignite-form-field-dropdown(
-                            data-id='discovery'
-                            data-name='discovery'
-                            data-options='discoveries'
-                            data-ng-model='#{model}.discovery.kind'
-                            data-placeholder='Choose marshaller'
-                        )
+                    +dropdown('Discovery:', model + '.discovery.kind', 'discovery', 'true', 'Choose discovery', 'discoveries',
+                        'Discovery allows to discover remote nodes in grid\
+                        <ul>\
+                            <li>Static IPs - IP Finder which works only with pre configured list of IP addresses specified</li>\
+                            <li>Multicast - Multicast based IP finder</li>\
+                            <li>AWS S3 - AWS S3 based IP finder</li>\
+                            <li>Apache jclouds - Apache jclouds multi cloud toolkit based IP finder</li>\
+                            <li>Google cloud storage - Google Cloud Storage based IP finder</li>\
+                            <li>JDBC - JDBC based IP finder</li>\
+                            <li>Shared filesystem - Shared filesystem based IP finder</li>\
+                            <li>Apache ZooKeeper - Apache ZooKeeper based IP finder</li>\
+                        </ul>')
                 .settings-row
                     .panel-details.col-sm-12
                         ignite-configuration-clusters-general-discovery-cloud(
@@ -103,13 +66,5 @@ form.panel.panel-default(name='general' novalidate)
                             ng-if='#{model}.discovery.kind === "Vm"')
                         ignite-configuration-clusters-general-discovery-zookeeper(
                             ng-if='#{model}.discovery.kind === "ZooKeeper"')
-            ignite-ui-ace-tabs.col-sm-6
-                .preview-panel(ng-init='mode = false')
-                    .preview-legend
-                        a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                        | &nbsp;
-                        a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-                    .preview-content(ng-if='mode')
-                        ignite-ui-ace-java(data-master='backupItem' data-generator='clusterCaches' data-details='caches')
-                    .preview-content(ng-if='!mode')
-                        ignite-ui-ace-xml(data-master='backupItem' data-generator='clusterCaches' data-details='caches')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterCaches', 'caches')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
index 258524f..c880d8a 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.Cloud';
 - var regions = model + '.regions';
 - var zones = model + '.zones';
@@ -22,56 +24,23 @@
 
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Credential:
-            ignite-form-field-tooltip
-                | Credential that is used during authentication on the cloud#[br]
-                | Depending on a cloud platform it can be a password or access key
-            ignite-form-field-input-text(
-                data-id='credential'
-                data-name='credential'
-                data-ng-model='#{model}.credential'
-            )
+        +text('Credential:', model + '.credential', 'credential', 'false', 'Input cloud credential',
+            'Credential that is used during authentication on the cloud<br/>\
+            Depending on a cloud platform it can be a password or access key')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Path to credential:
-            ignite-form-field-tooltip
-                | Path to a credential that is used during authentication on the cloud#[br]
-                | Access key or private key should be stored in a plain or PEM file without a passphrase
-            ignite-form-field-input-text(
-                data-id='credentialPath'
-                data-name='credentialPath'
-                data-ng-model='#{model}.credentialPath'
-            )
+        +text('Path to credential:', model + '.credentialPath', 'credentialPath', 'false', 'Input pathto credential',
+            'Path to a credential that is used during authentication on the cloud<br/>\
+            Access key or private key should be stored in a plain or PEM file without a passphrase')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Identity:
-            ignite-form-field-tooltip
-                | Identity that is used as a user name during a connection to the cloud#[br]
-                | Depending on a cloud platform it can be an email address, user name, etc
-            ignite-form-field-input-text(
-                data-id='identity'
-                data-name='identity'
-                data-ng-model='#{model}.identity'
-                data-ng-required='true'
-            )
+        +text('Identity:', model + '.identity', 'identity', 'true', 'Input identity',
+            'Identity that is used as a user name during a connection to the cloud<br/>\
+            Depending on a cloud platform it can be an email address, user name, etc')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Provider:
-            ignite-form-field-tooltip
-                | Cloud provider to use
-            ignite-form-field-input-text(
-                data-id='provider'
-                data-name='provider'
-                data-ng-model='#{model}.provider'
-                data-ng-required='true'
-            )
+        +text('Provider:', model + '.provider', 'provider', 'true', 'Input provider', 'Cloud provider to use')
     .details-row
-        ignite-form-group(ng-model='#{regions}' ng-form='#{formRegions}')
+        ignite-form-group(ng-model=regions ng-form=formRegions)
+            - var uniqueTip = 'Such region already exists!'
+
             ignite-form-field-label
                 | Regions
             ignite-form-group-tooltip
@@ -81,80 +50,38 @@ div
             ignite-form-group-add(ng-click='group.add = [{}]')
                 | Add new region
 
-            - var field = 'edit'
-            - var valid = formRegions + '.' + field + '.$valid'
-            - var save = regions + '[$index] = ' + field
-
             .group-content(ng-if='#{regions}.length')
-                ignite-form-field(ng-repeat='model in #{regions} track by $index' type='internal')
+                - var field = 'edit'
+                - var valid = formRegions + '.' + field + '.$valid'
+                - var save = regions + '[$index] = ' + field
+
+                ignite-form-field(ng-repeat='model in #{regions} track by $index' type='internal' name='Region')
                     .indexField
-                        | {{ $index+1 }}) 
-                    i.tipField.fa.fa-remove(
-                        ng-hide='field.edit'
-                        bs-tooltip='"Remove region"'
-                        ng-click='#{regions}.splice(#{regions}.indexOf(model), 1)'
-                    )
+                        | {{ $index+1 }})
+                    +table-remove-button(regions, 'Remove region')
                     span(ng-hide='field.edit')
                         a.labelFormField(ng-click='field.edit = true') {{ model }}
                     span(ng-if='field.edit' ng-init='#{field} = model')
-                        ignite-form-field-input-text(
-                            data-name='#{field}'
-                            data-ng-model='#{field}'
-                            data-ng-required='true'
-                            data-placeholder='Region name'
-                            data-ignite-unique='#{regions}'
-                            data-ignite-form-field-input-autofocus='true'
-                            on-enter='#{valid} && (#{save}); #{valid} && (field.edit = false);'
-                            on-escape='field.edit = false'
-                            ng-blur='#{valid} && (#{save}); (field.edit = false)'
-                        )
-                            i.fa.fa-floppy-o(
-                                ng-show='#{valid}'
-                                ng-click='#{valid} && (#{save}); #{valid} && (field.edit = false);'
-                                bs-tooltip 
-                                data-title='Click icon or press [Enter] to save item' 
-                            )
-
-                            i.fa.fa-exclamation-triangle.form-control-feedback(
-                                ng-show='!#{formRegions}.#{field}.$pristine && #{formRegions}.#{field}.$error.igniteUnique'
-                                bs-tooltip
-                                data-title='Such region already exists!'
-                            )
-
-            - var field = 'new'
-            - var valid = formRegions + '.' + field + '.$valid'
-            - var push = regions + '.push(' + field + ')'
+                        +table-text-field(field, regions, save, 'Region name', false)
+                            +table-save-button(valid, save, false)
+                            +table-feedback-unique(formRegions, field, uniqueTip)
 
             .group-content(ng-repeat='field in group.add')
-                ignite-form-field(type='internal')
-                    ignite-form-field-input-text(
-                        data-name='#{field}'
-                        data-ng-model='#{field}'
-                        data-ng-required='true'
-                        data-placeholder='Region name'
-                        data-ignite-unique='#{regions}'
-                        data-ignite-form-field-input-autofocus='true'
-                        on-enter='#{valid} && #{push}; #{valid} && (stopblur = true) && (group.add = [{}])'
-                        on-escape='group.add = []'
-                        ng-blur='#{valid} && #{push}; !stopblur && (group.add = [])'
-                    )
-                        i.fa.fa-floppy-o(
-                            ng-show='#{valid}'
-                            ng-click='#{valid} && #{push}; #{valid} && (group.add = [])'
-                            bs-tooltip 
-                            data-title='Click icon or press [Enter] to save item' 
-                        )
-
-                        i.fa.fa-exclamation-triangle.form-control-feedback(
-                            ng-show='!#{formRegions}.#{field}.$pristine && #{formRegions}.#{field}.$error.igniteUnique'
-                            bs-tooltip
-                            data-title='Such region already exists!'
-                        )
-            
+                - var field = 'new'
+                - var valid = formRegions + '.' + field + '.$valid'
+                - var save = regions + '.push(' + field + ')'
+
+                ignite-form-field(type='internal' name='Region')
+                    +table-text-field(field, regions, save, 'Region name', true)
+                        +table-save-button(valid, save, true)
+                        +table-feedback-unique(formRegions, field, uniqueTip)
+
             .group-content-empty(ng-if='!(#{regions}.length) && !group.add.length')
                 | Not defined
     .details-row
-         ignite-form-group(ng-model='#{zones}' ng-form='#{formZones}')
+        ignite-form-group(ng-model=zones ng-form=formZones)
+            - var uniqueTip = 'Such zone already exists!'
+
             ignite-form-field-label
                 | Zones
             ignite-form-group-tooltip
@@ -164,75 +91,31 @@ div
             ignite-form-group-add(ng-click='group.add = [{}]')
                 | Add new zone
 
-            - var field = 'edit'
-            - var valid = formZones + '.' + field + '.$valid'
-            - var save = zones + '[$index] = ' + field
-
             .group-content(ng-if='#{zones}.length')
-                ignite-form-field(ng-repeat='model in #{zones} track by $index' type='internal')
+                - var field = 'edit'
+                - var valid = formZones + '.' + field + '.$valid'
+                - var save = zones + '[$index] = ' + field
+
+                ignite-form-field(ng-repeat='model in #{zones} track by $index' type='internal' name='Zone')
                     .indexField
-                        | {{ $index+1 }}) 
-                    i.tipField.fa.fa-remove(
-                        ng-hide='field.edit'
-                        bs-tooltip='"Remove zone"'
-                        ng-click='#{zones}.splice(#{zones}.indexOf(model), 1)'
-                    )
+                        | {{ $index+1 }})
+                    +table-remove-button(zones, 'Remove zone')
                     span(ng-hide='field.edit')
                         a.labelFormField(ng-click='field.edit = true') {{ model }}
                     span(ng-if='field.edit' ng-init='#{field} = model')
-                        ignite-form-field-input-text(
-                            data-name='#{field}'
-                            data-ng-model='#{field}'
-                            data-ng-required='true'
-                            data-placeholder='Zone name'
-                            data-ignite-unique='#{zones}'
-                            data-ignite-form-field-input-autofocus='true'
-                            on-enter='#{valid} && (#{save}); #{valid} && (field.edit = false);'
-                            on-escape='field.edit = false'
-                            ng-blur='#{valid} && (#{save}); (field.edit = false)'
-                        )
-                            i.fa.fa-floppy-o(
-                                ng-show='#{valid}'
-                                ng-click='#{valid} && (#{save}); #{valid} && (field.edit = false);'
-                                bs-tooltip 
-                                data-title='Click icon or press [Enter] to save item' 
-                            )
-
-                            i.fa.fa-exclamation-triangle.form-control-feedback(
-                                ng-show='!#{formZones}.#{field}.$pristine && #{formZones}.#{field}.$error.igniteUnique'
-                                bs-tooltip
-                                data-title='Such zone already exists!'
-                            )
-
-            - var field = 'new'
-            - var valid = formZones + '.' + field + '.$valid'
-            - var push = zones + '.push(' + field + ')'
+                        +table-text-field(field, zones, save, 'Zone name',false)
+                            +table-save-button(valid, save, false)
+                            +table-feedback-unique(formZones, field, uniqueTip)
 
             .group-content(ng-repeat='field in group.add')
-                ignite-form-field(type='internal')
-                    ignite-form-field-input-text(
-                        data-name='#{field}'
-                        data-ng-model='#{field}'
-                        data-ng-required='true'
-                        data-placeholder='Zone name'
-                        data-ignite-unique='#{zones}'
-                        data-ignite-form-field-input-autofocus='true'
-                        on-enter='#{valid} && #{push}; #{valid} && (stopblur = true) && (group.add = [{}])'
-                        on-escape='group.add = []'
-                        ng-blur='#{valid} && #{push}; !stopblur && (group.add = [])'
-                    )
-                        i.fa.fa-floppy-o(
-                            ng-show='#{valid}'
-                            ng-click='#{valid} && #{push}; #{valid} && (group.add = [])'
-                            bs-tooltip 
-                            data-title='Click icon or press [Enter] to save item' 
-                        )
-
-                        i.fa.fa-exclamation-triangle.form-control-feedback(
-                            ng-show='!#{formZones}.#{field}.$pristine && #{formZones}.#{field}.$error.igniteUnique'
-                            bs-tooltip
-                            data-title='Such zone already exists!'
-                        )
-            
+                - var field = 'new'
+                - var valid = formZones + '.' + field + '.$valid'
+                - var save = zones + '.push(' + field + ')'
+
+                ignite-form-field(type='internal' name='Zone')
+                    +table-text-field(field, zones, save, 'Zone name',true)
+                        +table-save-button(valid, save, true)
+                        +table-feedback-unique(formZones, field, uniqueTip)
+
             .group-content-empty(ng-if='!(#{zones}.length) && !group.add.length')
                 | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
index 79ae2f1..5dbe2c5 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
@@ -14,57 +14,22 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.GoogleStorage';
 
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Project name:
-            ignite-form-field-tooltip
-                | Google Cloud Platforms project name#[br]
-                | Usually this is an auto generated project number (ex. 208709979073) that can be found in 'Overview' section of Google Developer Console
-            ignite-form-field-input-text(
-                data-id='projectName'
-                data-name='projectName'
-                data-ng-model='#{model}.projectName'
-                data-ng-required='true'
-            )
+        +text('Project name:', model + '.projectName', 'projectName', 'true', 'Input project name', '' +
+            'Google Cloud Platforms project name<br/>\
+            Usually this is an auto generated project number(ex. 208709979073) that can be found in "Overview" section of Google Developer Console')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Bucket name:
-            ignite-form-field-tooltip
-                | Google Cloud Storage bucket name#[br]
-                | If the bucket doesn't exist Ignite will automatically create it#[br]
-                | However the name must be unique across whole Google Cloud Storage and Service Account Id must be authorized to perform this operation
-            ignite-form-field-input-text(
-                data-id='bucketName'
-                data-name='bucketName'
-                data-ng-model='#{model}.bucketName'
-                data-ng-required='true'
-            )
+        +text('Bucket name:', model + '.bucketName', 'bucketName', 'true', 'Input bucket name',
+            'Google Cloud Storage bucket name<br/>\
+            If the bucket does not exist Ignite will automatically create it<br/>\
+            However the name must be unique across whole Google Cloud Storage and Service Account Id must be authorized to perform this operation')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Private key path:
-            ignite-form-field-tooltip
-                | Full path to the private key in PKCS12 format of the Service Account
-            ignite-form-field-input-text(
-                data-id='serviceAccountP12FilePath'
-                data-name='serviceAccountP12FilePath'
-                data-ng-model='#{model}.serviceAccountP12FilePath'
-                data-ng-required='true'
-            )
+        +text('Private key path:', model + '.serviceAccountP12FilePath', 'serviceAccountP12FilePath', 'true', 'Input private key path',
+            'Full path to the private key in PKCS12 format of the Service Account')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Account id:
-            ignite-form-field-tooltip
-                | Service account ID (typically an e-mail address)
-            ignite-form-field-input-text(
-                data-id='serviceAccountId'
-                data-name='serviceAccountId'
-                data-ng-model='#{model}.serviceAccountId'
-                data-ng-required='true'
-            )
\ No newline at end of file
+        +text('Account id:', model + '.serviceAccountId', 'serviceAccountId', 'true', 'Input account id', 'Service account ID (typically an e-mail address)')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/jdbc.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
index e677392..b26a4ee 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
@@ -14,16 +14,11 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.Jdbc';
 
 div
     .details-row
-        ignite-form-field.checkbox
-            ignite-form-field-input-checkbox(
-                data-id='initSchema'
-                data-name='initSchema'
-                data-ng-model='#{model}.initSchema'
-            )
-            | DB schema should be initialized by Ignite
-            ignite-form-field-tooltip
-                | Flag indicating whether DB schema should be initialized by Ignite or was explicitly created by user
\ No newline at end of file
+        +checkbox('DB schema should be initialized by Ignite', model + '.initSchema', 'initSchema',
+            'Flag indicating whether DB schema should be initialized by Ignite or was explicitly created by user')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
index 63e46cc..acabab3 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
@@ -14,124 +14,34 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.Multicast';
 - var addresses = model + '.addresses';
 - var form = 'discoveryMulticastAddresses';
 
-mixin addressField(field, save, newItem)
-    - var reset = (newItem ? 'group.add = []' : 'field.edit = false')
-    - var resetOnEnter = (newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)')
-    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
-
-    ignite-form-field-input-text(
-        data-name='#{field}'
-        data-ng-model='#{field}'
-        data-ng-required='true'
-        data-placeholder='IP address:port'
-        data-ipaddress='true'
-        data-ignite-unique='#{addresses}'
-        data-ignite-form-field-input-autofocus='true'
-        on-enter='#{valid} && (#{save}); #{valid} && #{resetOnEnter};'
-        on-escape='#{reset}'
-        ng-blur='#{valid} && (#{save}); #{resetOnBlur};'
-    )
-        block
-
-mixin addressSaveBtn(valid, save, reset)
-    i.fa.fa-floppy-o(
-        ng-show='#{valid}'
-        ng-click='#{valid} && #{save}; #{valid} && (#{reset})'
-        bs-tooltip
-        data-title='Click icon or press [Enter] to save item'
-    )
-
-mixin addressFeedbackUnique(field)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='#{form}.#{field}.$error.igniteUnique'
-        bs-tooltip
-        data-title='Such IP address already exists!'
-    )
-
-mixin addressFeedbackValid(field)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='#{form}.#{field}.$error.ipadress'
-        bs-tooltip
-        data-title='Invalid IP address!'
-    )
-
-mixin addressFeedbackRequired(field)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='!#{form}.#{field}.$pristine && #{form}.#{field}.$error.required'
-        bs-tooltip
-        data-title='IP address should not be empty!'
-    )
-
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | IP address:
-            ignite-form-field-tooltip
-                | IP address of multicast group
-            ignite-form-field-input-text(
-                data-id='multicastGroup'
-                data-name='multicastGroup'
-                data-ng-model='#{model}.multicastGroup'
-                data-placeholder='228.1.2.4'
-            )
+        +text-ip-address('IP address:', model + '.multicastGroup', 'multicastGroup', 'true', '228.1.2.4', 'IP address of multicast group')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Port number:
-            ignite-form-field-tooltip
-                | Port number which multicast messages are sent to
-            ignite-form-field-input-number(
-                data-id='multicastPort'
-                data-name='multicastPort'
-                data-ng-model='#{model}.multicastPort'
-                data-max='65535'
-                data-placeholder='47400'
-            )
+        +number-min-max('Port number:', model + '.multicastPort', 'multicastPort', 'true', '47400', '0', '65535', 'Port number which multicast messages are sent to')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Waits for reply:
-            ignite-form-field-tooltip
-                | Time in milliseconds IP finder waits for reply to multicast address request
-            ignite-form-field-input-number(
-                data-id='responseWaitTime'
-                data-name='responseWaitTime'
-                data-ng-model='#{model}.responseWaitTime'
-                data-placeholder='500'
-            )
+        +number('Waits for reply:', model + '.responseWaitTime', 'responseWaitTime', 'true', '500', '0',
+            'Time in milliseconds IP finder waits for reply to multicast address request')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Attempts count:
-            ignite-form-field-tooltip
-                | Number of attempts to send multicast address request#[br]
-                | IP finder re-sends request only in case if no reply for previous request is received
-            ignite-form-field-input-number(
-                data-id='addressRequestAttempts'
-                data-name='addressRequestAttempts'
-                data-ng-model='#{model}.addressRequestAttempts'
-                data-placeholder='2'
-            )
+        +number('Attempts count:', model + '.addressRequestAttempts', 'addressRequestAttempts', 'true', '2', '0',
+            'Number of attempts to send multicast address request<br/>\
+            IP finder re - sends request only in case if no reply for previous request is received')
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Local address:
-            ignite-form-field-tooltip
-                | Local host address used by this IP finder#[br]
-                | If provided address is non-loopback then multicast socket is bound to this interface#[br]
-                | If local address is not set or is any local address then IP finder creates multicast sockets for all found non-loopback addresses
-            ignite-form-field-input-text(
-                data-id='localAddress'
-                data-name='localAddress'
-                data-ng-model='#{model}.localAddress'
-            )
+        +text-ip-address('Local address:', model + '.localAddress', 'localAddress', 'true', '0.0.0.0',
+            'Local host address used by this IP finder<br/>\
+            If provided address is non - loopback then multicast socket is bound to this interface<br/>\
+            If local address is not set or is any local address then IP finder creates multicast sockets for all found non - loopback addresses')
     .details-row
-        ignite-form-group(ng-model='#{addresses}' ng-form='discoveryMulticastAddresses')
+        ignite-form-group(ng-model=addresses ng-form=form)
+            - var uniqueTip = 'Such IP address already exists!'
+            - var ipAddressTip = 'Invalid IP address!'
+
             ignite-form-field-label
                 | Addresses
             ignite-form-group-tooltip
@@ -153,40 +63,33 @@ div
                 - var field = 'edit'
                 - var valid = form + '.' + field + '.$valid'
                 - var save = addresses + '[$index] = ' + field
-                - var reset = 'field.edit = false'
 
-                ignite-form-field(ng-repeat='model in #{addresses} track by $index' type='internal')
+                ignite-form-field(ng-repeat='model in #{addresses} track by $index' type='internal' name='Address')
                     .indexField
-                        | {{ $index+1 }}) 
-                    i.tipField.fa.fa-remove(
-                        ng-hide='field.edit'
-                        bs-tooltip='"Remove address"'
-                        ng-click='#{addresses}.splice(#{addresses}.indexOf(model), 1)'
-                    )
+                        | {{ $index+1 }})
+                    +table-remove-button(addresses, 'Remove address')
 
-                    ignite-form-field-down(ng-if='!$last' ng-hide='field.edit' data-ng-model='model' data-models='#{addresses}')
-                    ignite-form-field-up(ng-if='!$first' ng-hide='field.edit' data-ng-model='model' data-models='#{addresses}')
+                    ignite-form-field-down(ng-if='!$last' ng-hide='field.edit' data-ng-model='model' data-models=addresses)
+                    ignite-form-field-up(ng-if='!$first' ng-hide='field.edit' data-ng-model='model' data-models=addresses)
 
                     span(ng-hide='field.edit')
                         a.labelFormField(ng-click='field.edit = true') {{ model }}
                     span(ng-if='field.edit' ng-init='#{field} = model')
-                        +addressField(field, save, false)
-                            +addressSaveBtn(valid, save, reset)
-                            +addressFeedbackUnique(field)
-                            +addressFeedbackValid(field)
-                            +addressFeedbackRequired(field)
+                        +table-address-field(field, addresses, save, false)
+                            +table-save-button(valid, save, false)
+                            +table-feedback-unique(form, field, uniqueTip)
+                            +table-feedback-ip-address(form, field, ipAddressTip)
 
             .group-content(ng-repeat='field in group.add')
                 - var field = 'new'
                 - var valid = form + '.' + field + '.$valid'
                 - var save = addresses + '.push(' + field + ')'
-                - var reset = 'group.add = []'
 
-                ignite-form-field(type='internal')
-                    +addressField(field, save, true)
-                        +addressFeedbackUnique(field)
-                        +addressFeedbackValid(field)
-                        +addressFeedbackUnique(field)
+                ignite-form-field(type='internal' name='Address')
+                    +table-address-field(field, addresses, save, true)
+                        +table-save-button(valid, save, true)
+                        +table-feedback-unique(form, field, uniqueTip)
+                        +table-feedback-ip-address(form, field, ipAddressTip)
 
             .group-content-empty(ng-if='!(#{addresses}.length) && !group.add.length')
                 | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
index d6652ce..650d739 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
@@ -14,20 +14,12 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.S3';
 
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | Bucket name:
-            ignite-form-field-tooltip
-                | Bucket name for IP finder
-            ignite-form-field-input-text(
-                data-id='bucketName'
-                data-name='bucketName'
-                data-ng-model='#{model}.bucketName'
-                data-ng-required='true'
-            )
+        +text('Bucket name:', model + '.bucketName', 'bucketName', 'true', 'Input bucket name', 'Bucket name for IP finder')
     .details-row
         label Note, AWS credentials will be generated as stub

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/shared.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/shared.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/shared.jade
index 4f492d5..8f22568 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/shared.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/shared.jade
@@ -14,16 +14,10 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.SharedFs';
 
 div
     .details-row
-        ignite-form-field
-            ignite-form-field-label
-                | File path:
-            ignite-form-field-input-text(
-                data-id='path'
-                data-name='path'
-                data-ng-model='#{model}.path'
-                data-placeholder='disco/tcp'
-            )
\ No newline at end of file
+        +text('File path:', model + '.path', 'path', 'false', 'disco/tcp', 'Shared path')

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8a690ec/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
index a0071e6..313074d 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
@@ -14,60 +14,17 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../../../../../../app/helpers/jade/mixins.jade
+
 - var model = 'backupItem.discovery.Vm';
 - var addresses = model + '.addresses';
 - var form = 'discoveryVmAddresses';
 
-mixin addressField(field, save, newItem)
-    - var reset = (newItem ? 'group.add = []' : 'field.edit = false')
-    - var resetOnEnter = (newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)')
-    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
-
-    ignite-form-field-input-text(
-        data-name='#{field}'
-        data-ng-model='#{field}'
-        data-ng-required='true'
-        data-placeholder='IP address:port'
-        data-ipaddress='true'
-        data-ignite-unique='#{addresses}'
-        data-ignite-form-field-input-autofocus='true'
-        on-enter='#{valid} && (#{save}); #{valid} && #{resetOnEnter};'
-        on-escape='#{reset}'
-        ng-blur='#{valid} && (#{save}); #{resetOnBlur};'
-    )
-        block
-
-mixin addressSaveBtn(valid, save, reset)
-    i.fa.fa-floppy-o(
-        ng-show='#{valid}'
-        ng-click='#{valid} && #{save}; #{valid} && (#{reset})'
-        bs-tooltip
-        data-title='Click icon or press [Enter] to save item'
-    )
-
-mixin addressFeedbackUnique(field)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='#{form}.#{field}.$error.igniteUnique'
-        bs-tooltip
-        data-title='Such IP address already exists!'
-    )
-
-mixin addressFeedbackValid(field)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='#{form}.#{field}.$error.ipaddress'
-        bs-tooltip
-        data-title='Invalid IP address!'
-    )
-
-mixin addressFeedbackRequired(field)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='!#{form}.#{field}.$pristine && #{form}.#{field}.$error.required'
-        bs-tooltip
-        data-title='IP address should not be empty!'
-    )
-
 .details-row
-    ignite-form-group(ng-model='#{addresses}' ng-form='discoveryVmAddresses')
+    ignite-form-group(ng-model=addresses ng-form=form)
+        - var uniqueTip = 'Such IP address already exists!'
+        - var ipAddressTip = 'Invalid IP address!'
+
         ignite-form-field-label
             | Addresses
         ignite-form-group-tooltip
@@ -89,40 +46,33 @@ mixin addressFeedbackRequired(field)
             - var field = 'edit'
             - var valid = form + '.' + field + '.$valid'
             - var save = addresses + '[$index] = ' + field
-            - var reset = 'field.edit = false'
 
-            ignite-form-field(ng-repeat='model in #{addresses} track by $index' type='internal')
+            ignite-form-field(ng-repeat='model in #{addresses} track by $index' type='internal' name='Address')
                 .indexField
-                    | {{ $index+1 }}) 
-                i.tipField.fa.fa-remove(
-                    ng-hide='field.edit'
-                    bs-tooltip='"Remove address"'
-                    ng-click='#{addresses}.splice(#{addresses}.indexOf(model), 1)'
-                )
+                    | {{ $index+1 }})
+                +table-remove-button(addresses, 'Remove address')
 
-                ignite-form-field-down(ng-if='!$last' ng-hide='field.edit' data-ng-model='model' data-models='#{addresses}')
-                ignite-form-field-up(ng-if='!$first' ng-hide='field.edit' data-ng-model='model' data-models='#{addresses}')
+                ignite-form-field-down(ng-if='!$last' ng-hide='field.edit' data-ng-model='model' data-models=addresses)
+                ignite-form-field-up(ng-if='!$first' ng-hide='field.edit' data-ng-model='model' data-models=addresses)
                 
                 span(ng-hide='field.edit')
                     a.labelFormField(ng-click='field.edit = true') {{ model }}
                 span(ng-if='field.edit' ng-init='#{field} = model')
-                    +addressField(field, save, false)
-                        +addressSaveBtn(valid, save, reset)
-                        +addressFeedbackUnique(field)
-                        +addressFeedbackValid(field)
-                        +addressFeedbackRequired(field)
-
-        - var field = 'new'
-        - var valid = form + '.' + field + '.$valid'
-        - var save = addresses + '.push(' + field + ')'
-        - var reset = 'group.add = []'
+                    +table-address-field(field, addresses, save, false)
+                        +table-save-button(valid, save, false)
+                        +table-feedback-unique(form, field, uniqueTip)
+                        +table-feedback-ip-address(form, field, ipAddressTip)
 
         .group-content(ng-repeat='field in group.add')
-            ignite-form-field(type='internal')
-                +addressField(field, save, true)
-                    +addressSaveBtn(valid, save, reset)
-                    +addressFeedbackUnique(field)
-                    +addressFeedbackValid(field)
-        
+            - var field = 'new'
+            - var valid = form + '.' + field + '.$valid'
+            - var save = addresses + '.push(' + field + ')'
+
+            ignite-form-field(type='internal' name='Address')
+                +table-address-field(field, addresses, save, true)
+                    +table-save-button(valid, save, true)
+                    +table-feedback-unique(form, field, uniqueTip)
+                    +table-feedback-ip-address(form, field, ipAddressTip)
+
         .group-content-empty(id='addresses' ng-if='!(#{addresses}.length) && !group.add.length')
                 | Not defined


[38/50] [abbrv] ignite git commit: IGNITE-2676 Review

Posted by an...@apache.org.
IGNITE-2676 Review


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8e3de18a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8e3de18a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8e3de18a

Branch: refs/heads/ignite-2875
Commit: 8e3de18a1c0a56609674914e141b1d2c24678940
Parents: 8c79a57
Author: vsisko <vs...@gridgain.com>
Authored: Fri Mar 25 12:45:14 2016 +0700
Committer: vsisko <vs...@gridgain.com>
Committed: Fri Mar 25 12:45:14 2016 +0700

----------------------------------------------------------------------
 .../app/modules/states/configuration/igfs/dual.jade   |  3 ++-
 .../states/configuration/igfs/fragmentizer.jade       | 10 +++++-----
 .../js/app/modules/states/configuration/igfs/ipc.jade | 14 +++++++-------
 .../src/main/js/controllers/igfs-controller.js        |  4 ----
 .../src/main/js/views/configuration/igfs.jade         |  2 +-
 5 files changed, 15 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8e3de18a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.jade
index df8a7f68..64cccc9 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/dual.jade
@@ -23,7 +23,8 @@ form.panel.panel-default(name='dualMode' novalidate)
         ignite-form-panel-chevron
         label Dual mode
         ignite-form-field-tooltip.tipLabel
-            | Dual mode settings
+            | IGFS supports dual-mode that allows it to work as either a standalone file system in Hadoop cluster, or work in tandem with HDFS, providing a primary caching layer for the secondary HDFS#[br]
+            | As a caching layer it provides highly configurable read-through and write-through behaviour
         ignite-form-revert
     .panel-collapse(role='tabpanel' bs-collapse-target id='dualMode')
         .panel-body(ng-if='__show__')

http://git-wip-us.apache.org/repos/asf/ignite/blob/8e3de18a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.jade
index 9490726..b4f4125 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/fragmentizer.jade
@@ -28,15 +28,15 @@ form.panel.panel-default(name='fragmentizer' novalidate)
     .panel-collapse(role='tabpanel' bs-collapse-target id='fragmentizer')
         .panel-body(ng-if='__show__')
             .col-sm-6
-                -var fragmentizerEnabled = model + '.fragmentizerEnabled'
+                -var enabled = model + '.fragmentizerEnabled'
 
                 .settings-row
-                    +checkbox('Enabled', fragmentizerEnabled, 'fragmentizerEnabled', 'Fragmentizer enabled flag')
+                    +checkbox('Enabled', enabled, 'fragmentizerEnabled', 'Fragmentizer enabled flag')
                 .settings-row
-                    +number('Concurrent files:', model + '.fragmentizerConcurrentFiles', 'fragmentizerConcurrentFiles', fragmentizerEnabled, '0', '0', 'Number of files to process concurrently by fragmentizer')
+                    +number('Concurrent files:', model + '.fragmentizerConcurrentFiles', 'fragmentizerConcurrentFiles', enabled, '0', '0', 'Number of files to process concurrently by fragmentizer')
                 .settings-row
-                    +number('Throttling block length:', model + '.fragmentizerThrottlingBlockLength', 'fragmentizerThrottlingBlockLength', fragmentizerEnabled, '16777216', '1', 'Length of file chunk to transmit before throttling is delayed')
+                    +number('Throttling block length:', model + '.fragmentizerThrottlingBlockLength', 'fragmentizerThrottlingBlockLength', enabled, '16777216', '1', 'Length of file chunk to transmit before throttling is delayed')
                 .settings-row
-                    +number('Throttling delay:', model + '.fragmentizerThrottlingDelay', 'fragmentizerThrottlingDelay', fragmentizerEnabled, '200', '0', 'Delay in milliseconds for which fragmentizer is paused')
+                    +number('Throttling delay:', model + '.fragmentizerThrottlingDelay', 'fragmentizerThrottlingDelay', enabled, '200', '0', 'Delay in milliseconds for which fragmentizer is paused')
             .col-sm-6
                 +preview-xml-java(model, 'igfsFragmentizer')

http://git-wip-us.apache.org/repos/asf/ignite/blob/8e3de18a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
index 3db3d8c..5463c46 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/igfs/ipc.jade
@@ -29,12 +29,12 @@ form.panel.panel-default(name='ipc' novalidate)
         .panel-body(ng-if='__show__')
             .col-sm-6
                 -var ipcEndpointConfiguration = model + '.ipcEndpointConfiguration'
-                -var ipcEndpointEnabled = model + '.ipcEndpointEnabled'
+                -var enabled = model + '.ipcEndpointEnabled'
 
                 .settings-row
-                    +checkbox('Enabled', model + '.ipcEndpointEnabled', 'ipcEndpointEnabled', 'IPC endpoint enabled flag')
+                    +checkbox('Enabled', enabled, 'ipcEndpointEnabled', 'IPC endpoint enabled flag')
                 .settings-row
-                    +dropdown('Type:', ipcEndpointConfiguration + '.type', 'ipcEndpointConfigurationType', ipcEndpointEnabled, 'TCP',
+                    +dropdown('Type:', ipcEndpointConfiguration + '.type', 'ipcEndpointConfigurationType', enabled, 'TCP',
                         '[\
                             {value: "SHMEM", label: "SHMEM"},\
                             {value: "TCP", label: "TCP"}\
@@ -45,12 +45,12 @@ form.panel.panel-default(name='ipc' novalidate)
                             <li>TCP - TCP endpoint</li>\
                         </ul>')
                 .settings-row
-                    +text-ip-address('Host:', ipcEndpointConfiguration + '.host', 'ipcEndpointConfigurationHost', ipcEndpointEnabled, '127.0.0.1', 'Host name')
+                    +text-ip-address('Host:', ipcEndpointConfiguration + '.host', 'ipcEndpointConfigurationHost', enabled, '127.0.0.1', 'Host name')
                 .settings-row
-                    +number-min-max('Port:', ipcEndpointConfiguration + '.port', 'ipcEndpointConfigurationPort', ipcEndpointEnabled, '10500', '1', '65535', 'Port number')
+                    +number-min-max('Port:', ipcEndpointConfiguration + '.port', 'ipcEndpointConfigurationPort', enabled, '10500', '1', '65535', 'Port number')
                 .settings-row
-                    +number('Memory size:', ipcEndpointConfiguration + '.memorySize', 'ipcEndpointConfigurationMemorySize', ipcEndpointEnabled, '262144', '1', 'Shared memory size in bytes allocated for endpoint communication')
+                    +number('Memory size:', ipcEndpointConfiguration + '.memorySize', 'ipcEndpointConfigurationMemorySize', enabled, '262144', '1', 'Shared memory size in bytes allocated for endpoint communication')
                 .settings-row
-                    +text-enabled('Token directory:', ipcEndpointConfiguration + '.tokenDirectoryPath', 'ipcEndpointConfigurationTokenDirectoryPath', ipcEndpointEnabled, 'false', 'ipc/shmem', 'Directory where shared memory tokens are stored')
+                    +text-enabled('Token directory:', ipcEndpointConfiguration + '.tokenDirectoryPath', 'ipcEndpointConfigurationTokenDirectoryPath', enabled, 'false', 'ipc/shmem', 'Directory where shared memory tokens are stored')
             .col-sm-6
                 +preview-xml-java(model, 'igfsIPC')

http://git-wip-us.apache.org/repos/asf/ignite/blob/8e3de18a/modules/control-center-web/src/main/js/controllers/igfs-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/igfs-controller.js b/modules/control-center-web/src/main/js/controllers/igfs-controller.js
index 553fd4c..6781546 100644
--- a/modules/control-center-web/src/main/js/controllers/igfs-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/igfs-controller.js
@@ -221,10 +221,6 @@ consoleModule.controller('igfsController', [
                 return showPopoverMessage($scope.ui, firstError.$name, errNameFull, msg);
             }
 
-            if (!$common.isEmptyString(item.dualModePutExecutorService) &&
-                !$common.isValidJavaClass('Put executor service', item.dualModePutExecutorService, false, 'dualModePutExecutorService', false, $scope.ui, 'dualMode'))
-                return false;
-
             if (!item.secondaryFileSystemEnabled && (item.defaultMode === 'PROXY'))
                 return showPopoverMessage($scope.ui, 'secondaryFileSystem', 'secondaryFileSystem-title', 'Secondary file system should be configured for "PROXY" IGFS mode!');
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8e3de18a/modules/control-center-web/src/main/js/views/configuration/igfs.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/configuration/igfs.jade b/modules/control-center-web/src/main/js/views/configuration/igfs.jade
index 947cebe..602f863 100644
--- a/modules/control-center-web/src/main/js/views/configuration/igfs.jade
+++ b/modules/control-center-web/src/main/js/views/configuration/igfs.jade
@@ -39,10 +39,10 @@ include ../includes/infos
                         ignite-advanced-options-toggle
 
                         div(ng-show='ui.expanded')
+                            ignite-configuration-igfs-secondary
                             ignite-configuration-igfs-ipc
                             ignite-configuration-igfs-fragmentizer
                             ignite-configuration-igfs-dual
-                            ignite-configuration-igfs-secondary
                             ignite-configuration-igfs-misc
 
                             ignite-advanced-options-toggle


[21/50] [abbrv] ignite git commit: IGNITE-843 Merge with web-console-production.

Posted by an...@apache.org.
IGNITE-843 Merge with web-console-production.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/94632f28
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/94632f28
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/94632f28

Branch: refs/heads/ignite-2875
Commit: 94632f288e462279d6c5ebc4dea78083809bffc1
Parents: 767a2eb c4596e9
Author: Andrey <an...@gridgain.com>
Authored: Mon Mar 21 17:15:20 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 21 17:15:20 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/app/modules/states/signin.state.js               | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------



[18/50] [abbrv] ignite git commit: IGNITE-843 Minor fix. (cherry picked from commit 2651715)

Posted by an...@apache.org.
IGNITE-843 Minor fix.
(cherry picked from commit 2651715)


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/41e37997
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/41e37997
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/41e37997

Branch: refs/heads/ignite-2875
Commit: 41e379970bca300fe58d2da40aaa6cc84b9bb2cf
Parents: 72ba11c
Author: Andrey <an...@gridgain.com>
Authored: Mon Mar 21 11:26:45 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Mar 21 15:44:54 2016 +0700

----------------------------------------------------------------------
 modules/control-center-web/src/main/js/app/index.js             | 1 +
 .../src/main/js/app/modules/states/signin.state.js              | 5 +----
 2 files changed, 2 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/41e37997/modules/control-center-web/src/main/js/app/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/index.js b/modules/control-center-web/src/main/js/app/index.js
index f959d2d..e9739fd 100644
--- a/modules/control-center-web/src/main/js/app/index.js
+++ b/modules/control-center-web/src/main/js/app/index.js
@@ -171,6 +171,7 @@ angular
 }])
 .config(['UIRouterMetatagsProvider', (UIRouterMetatagsProvider) => {
     UIRouterMetatagsProvider
+        .setDefaultTitle('Apache Ignite Web Console - Management Tool and Configuration Wizard for Apache Ignite')
         .setTitleSuffix(' – Apache Ignite Web Console')
         .setDefaultDescription('The Apache Ignite Web Console is an interactive management tool and configuration wizard for Apache Ignite which walks you through the creation of configuration files. Try the tool now.');
 }])

http://git-wip-us.apache.org/repos/asf/ignite/blob/41e37997/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/signin.state.js b/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
index ba14be6..a12ef43 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
+++ b/modules/control-center-web/src/main/js/app/modules/states/signin.state.js
@@ -28,10 +28,7 @@ angular
     $stateProvider
     .state('signin', {
         url: '/',
-        templateUrl: '/signin.html',
-        metaTags: {
-            title: 'Management Tool and Configuration Wizard for Apache Ignite'
-        }
+        templateUrl: '/signin.html'
     });
 }])
 .run(['$rootScope', '$state', 'Auth', 'IgniteBranding', function($root, $state, Auth, branding) {


[27/50] [abbrv] ignite git commit: IGNITE-843 Fixed validation and code format.

Posted by an...@apache.org.
IGNITE-843 Fixed validation and code format.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/625dcefa
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/625dcefa
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/625dcefa

Branch: refs/heads/ignite-2875
Commit: 625dcefa777e95abf87adbbb8ddbd5c2d20cd11b
Parents: f8a690e
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Tue Mar 22 14:56:02 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Tue Mar 22 14:56:02 2016 +0700

----------------------------------------------------------------------
 .../form-field-java-class.directive.js          |  9 +++
 .../src/main/js/app/helpers/jade/mixins.jade    | 64 +++++++++-----------
 .../js/app/modules/form/field/input/number.jade | 20 +++---
 .../modules/form/field/input/text.directive.js  | 19 +++---
 .../js/app/modules/form/field/input/text.jade   | 16 +++--
 .../js/app/modules/form/group/add.directive.js  |  4 +-
 .../form/validator/property-unique.directive.js |  5 +-
 .../configuration/caches/concurrency.jade       |  2 +-
 .../states/configuration/caches/general.jade    |  2 +-
 .../states/configuration/caches/memory.jade     |  2 +-
 .../states/configuration/caches/query.jade      | 30 ++++-----
 .../states/configuration/caches/rebalance.jade  |  2 +-
 .../configuration/caches/server-near-cache.jade |  6 +-
 .../states/configuration/caches/statistics.jade |  2 +-
 .../states/configuration/caches/store.jade      | 57 ++++++++---------
 .../states/configuration/clusters/atomic.jade   |  2 +-
 .../states/configuration/clusters/binary.jade   |  4 +-
 .../configuration/clusters/communication.jade   |  4 +-
 .../configuration/clusters/connector.jade       |  6 +-
 .../configuration/clusters/deployment.jade      | 49 ++++++++-------
 .../configuration/clusters/discovery.jade       |  2 +-
 .../states/configuration/clusters/events.jade   |  2 +-
 .../states/configuration/clusters/general.jade  |  2 +-
 .../clusters/general/discovery/cloud.jade       | 50 ++++++++-------
 .../clusters/general/discovery/google.jade      |  2 +-
 .../clusters/general/discovery/jdbc.jade        |  2 +-
 .../clusters/general/discovery/multicast.jade   | 30 ++++-----
 .../clusters/general/discovery/s3.jade          |  2 +-
 .../clusters/general/discovery/shared.jade      |  2 +-
 .../clusters/general/discovery/vm.jade          | 30 ++++-----
 .../clusters/general/discovery/zookeeper.jade   |  2 +-
 .../bounded-exponential-backoff.jade            |  2 +-
 .../discovery/zookeeper/retrypolicy/custom.jade |  2 +-
 .../retrypolicy/exponential-backoff.jade        |  2 +-
 .../zookeeper/retrypolicy/forever.jade          |  2 +-
 .../zookeeper/retrypolicy/n-times.jade          |  2 +-
 .../zookeeper/retrypolicy/one-time.jade         |  2 +-
 .../zookeeper/retrypolicy/until-elapsed.jade    |  2 +-
 .../states/configuration/clusters/igfs.jade     |  2 +-
 .../configuration/clusters/marshaller.jade      |  6 +-
 .../states/configuration/clusters/metrics.jade  |  2 +-
 .../states/configuration/clusters/ssl.jade      | 32 +++++-----
 .../states/configuration/clusters/swap.jade     |  6 +-
 .../states/configuration/clusters/thread.jade   |  2 +-
 .../states/configuration/clusters/time.jade     |  2 +-
 .../configuration/clusters/transactions.jade    |  2 +-
 .../main/js/controllers/caches-controller.js    | 24 ++++----
 .../main/js/controllers/clusters-controller.js  | 44 +++++++-------
 .../main/js/views/configuration/summary.jade    |  4 +-
 .../src/main/js/views/includes/controls.jade    | 34 +++++------
 50 files changed, 311 insertions(+), 294 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
index f1f66c9..7e13b73 100644
--- a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
@@ -45,6 +45,13 @@ export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
         scope.$watch(() => form.$pristine, setAsDefault);
         scope.$watch('value', setAsDefault);
 
+        const checkValid = () => {
+            if (ngModel.$valid)
+                el.find('input').addClass('ng-valid').removeClass('ng-invalid');
+            else
+                el.find('input').removeClass('ng-valid').addClass('ng-invalid');
+        };
+
         scope.ngChange = function() {
             ngModel.$setViewValue(scope.value);
 
@@ -52,6 +59,8 @@ export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
                 ngModel.$setDirty();
             else
                 ngModel.$setPristine();
+
+            setTimeout(checkValid, 100);  // Use setTimeout() workaround of problem of two controllers.
         };
 
         ngModel.$render = function() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
index 2fd0270..ed6083d 100644
--- a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
+++ b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
@@ -190,13 +190,13 @@ mixin dropdown-multiple(lbl, model, name, placeholder, placeholderEmpty, options
 
 //- Mixin for table java class field.
 mixin table-java-class-field(field, items, save, newItem)
-    - var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
-    - var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+    -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+    -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
-    - var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
 
-    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
-    - var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+    -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-java-class(
         data-name=field
@@ -212,13 +212,13 @@ mixin table-java-class-field(field, items, save, newItem)
 
 //- Mixin for table java package field.
 mixin table-java-package-field(field, items, save, newItem)
-    - var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
-    - var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+    -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+    -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
-    - var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
 
-    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
-    - var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+    -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
         data-name=field
@@ -237,13 +237,13 @@ mixin table-java-package-field(field, items, save, newItem)
 
 //- Mixin for table text field.
 mixin table-text-field(field, items, save, placeholder, newItem)
-    - var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
-    - var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+    -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+    -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
-    - var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
 
-    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
-    - var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+    -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
         data-name=field
@@ -260,13 +260,13 @@ mixin table-text-field(field, items, save, placeholder, newItem)
 
 //- Mixin for table address field.
 mixin table-address-field(field, items, save, newItem)
-    - var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
-    - var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+    -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+    -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
-    - var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var onEscape = (newItem ? 'group.add = []' : 'field.edit = false')
 
-    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
-    - var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+    -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
         data-name=field
@@ -284,8 +284,8 @@ mixin table-address-field(field, items, save, newItem)
 
 //- Mixin for table save button.
 mixin table-save-button(valid, save, newItem)
-    - var reset = (newItem ? 'group.add = []' : 'field.edit = false')
-    - var onClick = valid + ' && ' + save + '; ' + valid  + ' && (' + reset + ');'
+    -var reset = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var onClick = valid + ' && ' + save + '; ' + valid  + ' && (' + reset + ');'
 
     i.fa.fa-floppy-o(
         ng-show=valid
@@ -308,20 +308,14 @@ mixin table-remove-button(items, tip)
     +table-remove-conditional-button(items, 'true', tip)
 
 //- Mixin for table feedback for unique validator.
-mixin table-feedback-unique(from, field, tip)
+mixin table-error-feedback(visible, error, errorMessage)
     i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show=form + '.' + field + '.$error.igniteUnique'
-        bs-tooltip
-        data-title=tip
+        ng-if=visible
+        bs-tooltip='"#{errorMessage}"'
+        ignite-error=error
+        ignite-error-message=errorMessage
     )
 
-//- Mixin for table feedback for valid host name / IP address.
-mixin table-feedback-ip-address(from, field, tip)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show=form + '.' + field + '.$error.ipaddress'
-        bs-tooltip
-        data-title=tip
-    )
 
 //- Mixin for cache mode.
 mixin cacheMode(lbl, model, name, placeholder)
@@ -341,8 +335,8 @@ mixin cacheMode(lbl, model, name, placeholder)
 
 //- Mixin for eviction policy.
 mixin evictionPolicy(model, name, required, enabled, tip)
-    - var kind = model + '.kind'
-    - var policy = model + '[' + kind + ']'
+    -var kind = model + '.kind'
+    -var policy = model + '[' + kind + ']'
 
     +dropdown-required('Eviction policy:', kind, name + 'Kind', required, enabled, 'Not set',
         '[\

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/form/field/input/number.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/number.jade b/modules/control-center-web/src/main/js/app/modules/form/field/input/number.jade
index 3caf020..eb5f040 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/number.jade
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/number.jade
@@ -14,12 +14,14 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-mixin feedback(error, message)
+mixin feedback(isCheckPristine, error, errorMessage)
+    -var checkPristine = isCheckPristine ? '!field.$pristine && ' : ''
+
     i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='!field.$pristine && field.$error.#{error}'
-        bs-tooltip='"#{message}"'
-        ignite-error='#{error}'
-        ignite-error-message='#{message}'
+        ng-show='#{checkPristine}field.$error.#{error}'
+        bs-tooltip='"#{errorMessage}"'
+        ignite-error=error
+        ignite-error-message=errorMessage
     )
 
 .input-tip
@@ -38,9 +40,9 @@ mixin feedback(error, message)
         data-ng-model-options='{debounce: 150}'
     )
 
-    +feedback('min', 'Value is less than allowable minimum: {{ min || 0 }}')
-    +feedback('max', 'Value is more than allowable maximum: {{ max }}')
-    +feedback('number', 'Only numbers allowed')
-    +feedback('required', 'This field could not be empty')
+    +feedback(true, 'required', 'This field could not be empty')
+    +feedback(false, 'min', 'Value is less than allowable minimum: {{ min || 0 }}')
+    +feedback(false, 'max', 'Value is more than allowable maximum: {{ max }}')
+    +feedback(false, 'number', 'Only numbers allowed')
 
     span(ng-transclude='')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
index 38b7994..93dc60c 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.directive.js
@@ -26,6 +26,7 @@ export default ['igniteFormFieldInputText', ['IgniteFormGUID', (guid) => {
 
         scope.ngModel = ngModel;
         scope.form = form;
+        scope.field = form[name];
         scope.label = label;
 
         scope.$watch('required', (required) => {
@@ -52,7 +53,14 @@ export default ['igniteFormFieldInputText', ['IgniteFormGUID', (guid) => {
         scope.$watch(() => form.$pristine, setAsDefault);
         scope.$watch('value', setAsDefault);
 
-        scope.ngChange = function() {
+        const checkValid = () => {
+            if (ngModel.$valid)
+                el.find('input').addClass('ng-valid').removeClass('ng-invalid');
+            else
+                el.find('input').removeClass('ng-valid').addClass('ng-invalid');
+        };
+
+        scope.ngChange = () => {
             ngModel.$setViewValue(scope.value);
 
             if (JSON.stringify(scope.value) !== JSON.stringify(form.$defaults[name]))
@@ -60,15 +68,10 @@ export default ['igniteFormFieldInputText', ['IgniteFormGUID', (guid) => {
             else
                 ngModel.$setPristine();
 
-            setTimeout(() => {
-                if (ngModel.$valid)
-                    el.find('input').addClass('ng-valid').removeClass('ng-invalid');
-                else
-                    el.find('input').removeClass('ng-valid').addClass('ng-invalid');
-            }, 100); // Use setTimeout() workaround of problem of two controllers.
+            setTimeout(checkValid, 100); // Use setTimeout() workaround of problem of two controllers.
         };
 
-        ngModel.$render = function() {
+        ngModel.$render = () => {
             scope.value = ngModel.$modelValue;
         };
     };

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
index 6c7bca4..14d4ed5 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
+++ b/modules/control-center-web/src/main/js/app/modules/form/field/input/text.jade
@@ -14,6 +14,16 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+mixin feedback(isCheckPristine, error, errorMessage)
+    -var checkPristine = isCheckPristine ? '!field.$pristine && ' : ''
+
+    i.fa.fa-exclamation-triangle.form-control-feedback(
+        ng-if='#{checkPristine}field.$error.#{error}'
+        bs-tooltip='"#{errorMessage}"'
+        ignite-error=error
+        ignite-error-message=errorMessage
+    )
+
 .input-tip
     input.form-control(
         id='{{ id }}'
@@ -33,9 +43,7 @@
         data-ignite-form-field-input-autofocus='autofocus || false'
     )
 
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-if='!form[name+"TextInput"].$pristine && form[name+"TextInput"].$error.required'
-        bs-tooltip='"{{ label.name }} could not be empty!"'
-    )
+    +feedback(true, 'required', '{{ label.name }} could not be empty!')
+    +feedback(false, 'ipaddress', 'Invalid address!')
 
     span(ng-transclude='')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/form/group/add.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/group/add.directive.js b/modules/control-center-web/src/main/js/app/modules/form/group/add.directive.js
index 6d79026..382790d 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/group/add.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/group/add.directive.js
@@ -20,8 +20,8 @@ const template = `<i class='group-legend-btn fa fa-plus'></i>`;
 export default ['igniteFormGroupAdd', ['$tooltip', ($tooltip) => {
     const link = ($scope, $element, $attrs, $ctrls, $transclude) => {
         const content = Array.prototype.slice
-        .apply($transclude($scope))
-        .reduce((html, el) => html += el.outerHTML, '');
+            .apply($transclude($scope))
+            .reduce((html, el) => html += el.outerHTML || el.textContent || el, '');
 
         $tooltip($element, { title: content });
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/form/validator/property-unique.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/validator/property-unique.directive.js b/modules/control-center-web/src/main/js/app/modules/form/validator/property-unique.directive.js
index edc5f29..3f06f7b 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/validator/property-unique.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/validator/property-unique.directive.js
@@ -31,9 +31,8 @@ export default ['ignitePropertyUnique', ['$parse', ($parse) => {
             const name = attrs.name;
 
             // Check for $index in case of editing in-place.
-            return _.isNumber(scope.$index) && !_.find(arr, function(checkedVal, ix) {
-                return (name === 'new' || scope.$index !== ix) && checkedVal.split('=')[0] === key;
-            });
+            return _.isNumber(scope.$index) &&
+                !_.find(arr, (checkedVal, ix) => (name === 'new' || scope.$index !== ix) && checkedVal.split('=')[0] === key);
         };
     };
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/concurrency.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/concurrency.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/concurrency.jade
index d7037e7..03c4d51 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/concurrency.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/concurrency.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='concurrency' novalidate)
     .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/general.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/general.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/general.jade
index 851f0e1..3e55811 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/general.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/general.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='general' novalidate)
     .panel-heading(bs-collapse-toggle)

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/memory.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/memory.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/memory.jade
index d6e3a88..648ea93 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/memory.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/memory.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='memory' novalidate)
     .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
index f3dc2a9..6d8e0ee 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/query.jade
@@ -16,12 +16,9 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
-- var form = 'querySqlFunctionClasses';
-- var sqlFunctionClasses = model + '.sqlFunctionClasses';
-
-mixin sqlFxFeedbackUnique(field)
-    +table-feedback-unique(form, field, 'SQL function with such class name already exists!')
+-var model = 'backupItem'
+-var form = 'querySqlFunctionClasses';
+-var sqlFunctionClasses = model + '.sqlFunctionClasses';
 
 form.panel.panel-default(name='query' novalidate)
     .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')
@@ -50,10 +47,13 @@ form.panel.panel-default(name='query' novalidate)
                         ignite-form-group-add(ng-click='group.add = [{}]')
                             | Add new user-defined functions for SQL queries
 
+                        -var uniqueTip = 'SQL function with such class name already exists!'
+
                         .group-content(ng-if='#{sqlFunctionClasses}.length')
-                            - var field = 'edit'
-                            - var valid = form + '.' + field + '.$valid'
-                            - var save = sqlFunctionClasses + '[$index] = ' + field
+                            -var field = 'edit'
+                            -var valid = form + '.' + field + '.$valid'
+                            -var unique = form + '.' + field + '.$error.igniteUnique'
+                            -var save = sqlFunctionClasses + '[$index] = ' + field
 
                             ignite-form-field(ng-repeat='model in #{sqlFunctionClasses} track by $index' type='internal' name='SQL function')
                                 .indexField
@@ -65,17 +65,19 @@ form.panel.panel-default(name='query' novalidate)
                                 span(ng-if='field.edit' ng-init='#{field} = model')
                                     +table-java-class-field(field, sqlFunctionClasses, save, false)
                                         +table-save-button(valid, save, false)
-                                        +sqlFxFeedbackUnique(field)
+                                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
                         .group-content(ng-repeat='field in group.add')
-                            - var field = 'new'
-                            - var valid = form + '.' + field + '.$valid'
-                            - var save = sqlFunctionClasses + '.push(' + field + ')'
+                            -var field = 'new'
+                            -var valid = form + '.' + field + '.$valid'
+                            -var unique = form + '.' + field + '.$error.igniteUnique'
+                            -var save = sqlFunctionClasses + '.push(' + field + ')'
 
                             ignite-form-field(type='internal' name='SQL function')
                                 +table-java-class-field(field, sqlFunctionClasses, save, true)
                                     +table-save-button(valid, save, true)
-                                    +sqlFxFeedbackUnique(field)
+                                    +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+
                         .group-content-empty(ng-if='!(#{sqlFunctionClasses}.length) && !group.add.length')
                             | Not defined
                 .settings-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/rebalance.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/rebalance.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/rebalance.jade
index ce8237b..11cdfa0 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/rebalance.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/rebalance.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='rebalance' novalidate ng-hide='#{model}.cacheMode === "LOCAL"')
     .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/server-near-cache.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/server-near-cache.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/server-near-cache.jade
index a4adc78..ba2bfbd 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/server-near-cache.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/server-near-cache.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='server-near-cache' novalidate ng-show='#{model}.cacheMode === "PARTITIONED"')
     .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')
@@ -30,8 +30,8 @@ form.panel.panel-default(name='server-near-cache' novalidate ng-show='#{model}.c
     .panel-collapse(role='tabpanel' bs-collapse-target id='server-near-cache')
         .panel-body(ng-if='__show__')
             .col-sm-6
-                - var enabled = model + '.nearCacheEnabled'
-                - var nearCfg = model + '.nearConfiguration'
+                -var enabled = model + '.nearCacheEnabled'
+                -var nearCfg = model + '.nearConfiguration'
 
                 .settings-row
                     +checkbox('Enabled', enabled, 'nearCacheEnabled', 'Flag indicating whether to configure near cache')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/statistics.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/statistics.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/statistics.jade
index a75df2b..c83dcb7 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/statistics.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/statistics.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='statistics' novalidate)
     .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
index da20d8e..84cc376 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/caches/store.jade
@@ -16,8 +16,8 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
-- var form = 'store'
+-var model = 'backupItem'
+-var form = 'store'
 
 //- Mixin for DB dialect.
 mixin dialect(lbl, model, name, tipTitle, genericDialectName, placeholder)
@@ -51,13 +51,13 @@ mixin dialect(lbl, model, name, tipTitle, genericDialectName, placeholder)
         )
 
 mixin hibernateField(items, field, save, newItem)
-    - var reset = (newItem ? 'group.add = []' : 'field.edit = false')
+    -var reset = (newItem ? 'group.add = []' : 'field.edit = false')
 
-    - var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
-    - var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+    -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+    -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
-    - var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
-    - var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+    -var resetOnBlur = (newItem ? '!stopblur && (group.add = [])' : 'field.edit = false')
+    -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
         data-name=field
@@ -73,22 +73,6 @@ mixin hibernateField(items, field, save, newItem)
     )
         block
 
-mixin hibernateFeedbackPropertyValueSpecified(field)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='!#{form}.#{field}.$pristine && #{form}.#{field}.$error.ignitePropertyValueSpecified'
-        bs-tooltip
-        data-title='Property should be present in format key=value!'
-    )
-
-mixin hibernateFeedbackUnique(field)
-    - var formField = form + '.' + field
-
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show='!' + formField + '.$pristine && ' + formField + '.$error.ignitePropertyUnique'
-        bs-tooltip
-        data-title='Property with such key already exists!'
-    )
-
 form.panel.panel-default(name='store' novalidate)
     .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')
         ignite-form-panel-chevron
@@ -194,10 +178,15 @@ form.panel.panel-default(name='store' novalidate)
                                         ignite-form-group-add(ng-click='group.add = [{}]')
                                             | Add new Hibernate property
 
+                                        -var tipUnique = 'Property with such key already exists!'
+                                        -var tipPropertySpecified = 'Property should be present in format key=value!'
+
                                         .group-content(ng-if='#{hibernateProperties}.length')
-                                            - var field = 'edit'
-                                            - var valid = form + '.' + field + '.$valid'
-                                            - var save = hibernateProperties + '[$index] = ' + field
+                                            -var field = 'edit'
+                                            -var valid = form + '.' + field + '.$valid'
+                                            -var unique = form + '.' + field + '.$error.ignitePropertyUnique'
+                                            -var prop = form + '.' + field + '.$error.ignitePropertyValueSpecified'
+                                            -var save = hibernateProperties + '[$index] = ' + field
 
                                             ignite-form-field(ng-repeat='model in #{hibernateProperties} track by $index' type='internal' name='Hibernate properties')
                                                 .indexField
@@ -209,19 +198,21 @@ form.panel.panel-default(name='store' novalidate)
                                                 span(ng-if='field.edit' ng-init='#{field} = model')
                                                     +hibernateField(hibernateProperties, field, save, false)
                                                         +table-save-button(valid, save, false)
-                                                        +hibernateFeedbackUnique(field)
-                                                        +hibernateFeedbackPropertyValueSpecified(field)
+                                                        +table-error-feedback(unique, 'ignitePropertyUnique', tipUnique)
+                                                        +table-error-feedback(unique, 'ignitePropertyValueSpecified', tipPropertySpecified)
 
                                         .group-content(ng-repeat='field in group.add')
-                                            - var field = 'new'
-                                            - var valid = form + '.' + field + '.$valid'
-                                            - var save = hibernateProperties + '.push(' + field + ')'
+                                            -var field = 'new'
+                                            -var valid = form + '.' + field + '.$valid'
+                                            -var unique = form + '.' + field + '.$error.ignitePropertyUnique'
+                                            -var prop = form + '.' + field + '.$error.ignitePropertyValueSpecified'
+                                            -var save = hibernateProperties + '.push(' + field + ')'
 
                                             ignite-form-field(type='internal' name='Hibernate property')
                                                 +hibernateField(hibernateProperties, field, save, true)
                                                     +table-save-button(valid, save, true)
-                                                    +hibernateFeedbackUnique(field)
-                                                    +hibernateFeedbackPropertyValueSpecified(field)
+                                                    +table-error-feedback(unique, 'ignitePropertyUnique', tipUnique)
+                                                    +table-error-feedback(unique, 'ignitePropertyValueSpecified', tipPropertySpecified)
                                         .group-content-empty(ng-if='!(#{hibernateProperties}.length) && !group.add.length')
                                             | Not defined
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/atomic.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/atomic.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/atomic.jade
index 4f27a0b..7ac818d 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/atomic.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/atomic.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.atomicConfiguration'
+-var model = 'backupItem.atomicConfiguration'
 
 form.panel.panel-default(name='atomics' novalidate)
     .panel-heading(bs-collapse-toggle='' ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/binary.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/binary.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/binary.jade
index 36f7960..e82161e 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/binary.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/binary.jade
@@ -16,8 +16,8 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.binaryConfiguration'
-- var types = model + '.typeConfigurations'
+-var model = 'backupItem.binaryConfiguration'
+-var types = model + '.typeConfigurations'
 
 form.panel.panel-default(name='binary' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
index d4c3b8c..cbb4010 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/communication.jade
@@ -16,8 +16,8 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
-- var communication = model + '.communication'
+-var model = 'backupItem'
+-var communication = model + '.communication'
 
 form.panel.panel-default(name='communication' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
index a1f6684..4319742 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/connector.jade
@@ -16,9 +16,9 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.connector'
-- var enabled = model + '.enabled'
-- var sslEnabled = enabled + ' && ' + model + '.sslEnabled'
+-var model = 'backupItem.connector'
+-var enabled = model + '.enabled'
+-var sslEnabled = enabled + ' && ' + model + '.sslEnabled'
 
 form.panel.panel-default(name='connector' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
index 20312e7..a7de09a 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/deployment.jade
@@ -16,17 +16,10 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
-- var exclude = model + '.peerClassLoadingLocalClassPathExclude'
-- var form = 'deployment'
-- var enabled = 'backupItem.peerClassLoadingEnabled'
-
-mixin feedback(name, error, message)
-    i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-show=form + '.' + name +  '.$error.' + error
-        bs-tooltip
-        data-title=message
-    )
+-var model = 'backupItem'
+-var exclude = model + '.peerClassLoadingLocalClassPathExclude'
+-var form = 'deployment'
+-var enabled = 'backupItem.peerClassLoadingEnabled'
 
 form.panel.panel-default(name='#{form}' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
@@ -72,10 +65,17 @@ form.panel.panel-default(name='#{form}' novalidate)
                         ignite-form-group-add(ng-show='#{enabled}' ng-click='(group.add = [{}])')
                             | Add package name.
 
+                        -var uniqueTip = 'Such package already exists'
+                        -var tipJavaPackageName = 'Package name is invalid'
+                        -var tipJavaKeyWord = 'Package name could not contains reserved java keyword'
+
                         .group-content(ng-if=exclude + '.length')
-                            - var field = 'edit'
-                            - var valid = form + '.' + field + '.$valid'
-                            - var save = exclude + '[$index] = ' + field
+                            -var field = 'edit'
+                            -var valid = form + '.' + field + '.$valid'
+                            -var unique = form + '.' + field + '.$error.igniteUnique'
+                            -var javaPackageName = form + '.' + field + '.$error.javaPackageName'
+                            -var javaKeywords = form + '.' + field + '.$error.javaKeywords'
+                            -var save = exclude + '[$index] = ' + field
 
                             ignite-form-field(ng-repeat='model in #{exclude} track by $index' type='internal' name='Package name')
                                 .indexField
@@ -86,21 +86,24 @@ form.panel.panel-default(name='#{form}' novalidate)
                                 span(ng-if='field.edit' ng-init='#{field} = model')
                                     +table-java-package-field(field, exclude, save, false)
                                         +table-save-button(valid, save, false)
-                                        +table-feedback-unique(form, field, 'Such package already exists')
-                                        +feedback(field, 'javaPackageName', 'Package name is invalid')
-                                        +feedback(field, 'javaKeywords', 'Package name could not contains reserved java keyword')
+                                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                                        +table-error-feedback(javaPackageName, 'javaPackageName', tipJavaPackageName)
+                                        +table-error-feedback(javaKeywords, 'javaKeywords', tipJavaKeyWord)
 
                         .group-content(ng-repeat='field in group.add')
-                            - var field = 'new'
-                            - var valid = form + '.' + field + '.$valid'
-                            - var save = exclude + '.push(' + field + ')'
+                            -var field = 'new'
+                            -var valid = form + '.' + field + '.$valid'
+                            -var unique = form + '.' + field + '.$error.igniteUnique'
+                            -var javaPackageName = form + '.' + field + '.$error.javaPackageName'
+                            -var javaKeywords = form + '.' + field + '.$error.javaKeywords'
+                            -var save = exclude + '.push(' + field + ')'
 
                             ignite-form-field(type='internal' name='Package name')
                                 +table-java-package-field(field, exclude, save, true)
                                     +table-save-button(valid, save, true)
-                                    +table-feedback-unique(form, field, 'Such package already exists')
-                                    +feedback(field, 'javaPackageName', 'Package name is invalid')
-                                    +feedback(field, 'javaKeywords', 'Package name could not contains reserved java keyword')
+                                    +table-error-feedback(unique, 'igniteUnique', uniqueTip)
+                                    +table-error-feedback(javaPackageName, 'javaPackageName', tipJavaPackageName)
+                                    +table-error-feedback(javaKeywords, 'javaKeywords', tipJavaKeyWord)
 
 
                         .group-content-empty(ng-if='!(#{exclude}.length) && !group.add.length')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
index 6077ab5..1ba04fa 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/discovery.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery'
+-var model = 'backupItem.discovery'
 
 form.panel.panel-default(name='discovery' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/events.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/events.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/events.jade
index edcde05..b872877 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/events.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/events.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='events' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
index 2f5771d..ec004ce 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='general' novalidate)
     .panel-heading(bs-collapse-toggle)

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
index c880d8a..704611d 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
@@ -16,11 +16,11 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.Cloud';
-- var regions = model + '.regions';
-- var zones = model + '.zones';
-- var formRegions = 'discoveryCloudRegions'
-- var formZones = 'discoveryCloudZones'
+-var model = 'backupItem.discovery.Cloud';
+-var regions = model + '.regions';
+-var zones = model + '.zones';
+-var formRegions = 'discoveryCloudRegions'
+-var formZones = 'discoveryCloudZones'
 
 div
     .details-row
@@ -39,7 +39,7 @@ div
         +text('Provider:', model + '.provider', 'provider', 'true', 'Input provider', 'Cloud provider to use')
     .details-row
         ignite-form-group(ng-model=regions ng-form=formRegions)
-            - var uniqueTip = 'Such region already exists!'
+            -var uniqueTip = 'Such region already exists!'
 
             ignite-form-field-label
                 | Regions
@@ -51,9 +51,10 @@ div
                 | Add new region
 
             .group-content(ng-if='#{regions}.length')
-                - var field = 'edit'
-                - var valid = formRegions + '.' + field + '.$valid'
-                - var save = regions + '[$index] = ' + field
+                -var field = 'edit'
+                -var valid = formRegions + '.' + field + '.$valid'
+                -var unique = formRegions + '.' + field + '.$error.igniteUnique'
+                -var save = regions + '[$index] = ' + field
 
                 ignite-form-field(ng-repeat='model in #{regions} track by $index' type='internal' name='Region')
                     .indexField
@@ -64,23 +65,24 @@ div
                     span(ng-if='field.edit' ng-init='#{field} = model')
                         +table-text-field(field, regions, save, 'Region name', false)
                             +table-save-button(valid, save, false)
-                            +table-feedback-unique(formRegions, field, uniqueTip)
+                            +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
             .group-content(ng-repeat='field in group.add')
-                - var field = 'new'
-                - var valid = formRegions + '.' + field + '.$valid'
-                - var save = regions + '.push(' + field + ')'
+                -var field = 'new'
+                -var valid = formRegions + '.' + field + '.$valid'
+                -var unique = formRegions + '.' + field + '.$error.igniteUnique'
+                -var save = regions + '.push(' + field + ')'
 
                 ignite-form-field(type='internal' name='Region')
                     +table-text-field(field, regions, save, 'Region name', true)
                         +table-save-button(valid, save, true)
-                        +table-feedback-unique(formRegions, field, uniqueTip)
+                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
             .group-content-empty(ng-if='!(#{regions}.length) && !group.add.length')
                 | Not defined
     .details-row
         ignite-form-group(ng-model=zones ng-form=formZones)
-            - var uniqueTip = 'Such zone already exists!'
+            -var uniqueTip = 'Such zone already exists!'
 
             ignite-form-field-label
                 | Zones
@@ -92,9 +94,10 @@ div
                 | Add new zone
 
             .group-content(ng-if='#{zones}.length')
-                - var field = 'edit'
-                - var valid = formZones + '.' + field + '.$valid'
-                - var save = zones + '[$index] = ' + field
+                -var field = 'edit'
+                -var valid = formZones + '.' + field + '.$valid'
+                -var unique = formZones + '.' + field + '.$error.igniteUnique'
+                -var save = zones + '[$index] = ' + field
 
                 ignite-form-field(ng-repeat='model in #{zones} track by $index' type='internal' name='Zone')
                     .indexField
@@ -105,17 +108,18 @@ div
                     span(ng-if='field.edit' ng-init='#{field} = model')
                         +table-text-field(field, zones, save, 'Zone name',false)
                             +table-save-button(valid, save, false)
-                            +table-feedback-unique(formZones, field, uniqueTip)
+                            +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
             .group-content(ng-repeat='field in group.add')
-                - var field = 'new'
-                - var valid = formZones + '.' + field + '.$valid'
-                - var save = zones + '.push(' + field + ')'
+                -var field = 'new'
+                -var valid = formZones + '.' + field + '.$valid'
+                -var unique = formZones + '.' + field + '.$error.igniteUnique'
+                -var save = zones + '.push(' + field + ')'
 
                 ignite-form-field(type='internal' name='Zone')
                     +table-text-field(field, zones, save, 'Zone name',true)
                         +table-save-button(valid, save, true)
-                        +table-feedback-unique(formZones, field, uniqueTip)
+                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
             .group-content-empty(ng-if='!(#{zones}.length) && !group.add.length')
                 | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
index 5dbe2c5..9bf84ea 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.GoogleStorage';
+-var model = 'backupItem.discovery.GoogleStorage';
 
 div
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/jdbc.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
index b26a4ee..adf2e8d 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.Jdbc';
+-var model = 'backupItem.discovery.Jdbc';
 
 div
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
index acabab3..19c496c 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/multicast.jade
@@ -16,9 +16,9 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.Multicast';
-- var addresses = model + '.addresses';
-- var form = 'discoveryMulticastAddresses';
+-var model = 'backupItem.discovery.Multicast';
+-var addresses = model + '.addresses';
+-var form = 'discoveryMulticastAddresses';
 
 div
     .details-row
@@ -39,8 +39,8 @@ div
             If local address is not set or is any local address then IP finder creates multicast sockets for all found non - loopback addresses')
     .details-row
         ignite-form-group(ng-model=addresses ng-form=form)
-            - var uniqueTip = 'Such IP address already exists!'
-            - var ipAddressTip = 'Invalid IP address!'
+            -var uniqueTip = 'Such IP address already exists!'
+            -var ipAddressTip = 'Invalid IP address!'
 
             ignite-form-field-label
                 | Addresses
@@ -60,9 +60,10 @@ div
                 | Add new address
 
             .group-content(ng-if='#{addresses}.length')
-                - var field = 'edit'
-                - var valid = form + '.' + field + '.$valid'
-                - var save = addresses + '[$index] = ' + field
+                -var field = 'edit'
+                -var valid = form + '.' + field + '.$valid'
+                -var unique = form + '.' + field + '.$error.igniteUnique'
+                -var save = addresses + '[$index] = ' + field
 
                 ignite-form-field(ng-repeat='model in #{addresses} track by $index' type='internal' name='Address')
                     .indexField
@@ -77,19 +78,18 @@ div
                     span(ng-if='field.edit' ng-init='#{field} = model')
                         +table-address-field(field, addresses, save, false)
                             +table-save-button(valid, save, false)
-                            +table-feedback-unique(form, field, uniqueTip)
-                            +table-feedback-ip-address(form, field, ipAddressTip)
+                            +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
             .group-content(ng-repeat='field in group.add')
-                - var field = 'new'
-                - var valid = form + '.' + field + '.$valid'
-                - var save = addresses + '.push(' + field + ')'
+                -var field = 'new'
+                -var valid = form + '.' + field + '.$valid'
+                -var unique = form + '.' + field + '.$error.igniteUnique'
+                -var save = addresses + '.push(' + field + ')'
 
                 ignite-form-field(type='internal' name='Address')
                     +table-address-field(field, addresses, save, true)
                         +table-save-button(valid, save, true)
-                        +table-feedback-unique(form, field, uniqueTip)
-                        +table-feedback-ip-address(form, field, ipAddressTip)
+                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
             .group-content-empty(ng-if='!(#{addresses}.length) && !group.add.length')
                 | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
index 650d739..a53cb6e 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.S3';
+-var model = 'backupItem.discovery.S3';
 
 div
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/shared.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/shared.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/shared.jade
index 8f22568..318d94c 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/shared.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/shared.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.SharedFs';
+-var model = 'backupItem.discovery.SharedFs';
 
 div
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
index 313074d..cb7385c 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/vm.jade
@@ -16,14 +16,14 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.Vm';
-- var addresses = model + '.addresses';
-- var form = 'discoveryVmAddresses';
+-var model = 'backupItem.discovery.Vm';
+-var addresses = model + '.addresses';
+-var form = 'discoveryVmAddresses';
 
 .details-row
     ignite-form-group(ng-model=addresses ng-form=form)
-        - var uniqueTip = 'Such IP address already exists!'
-        - var ipAddressTip = 'Invalid IP address!'
+        -var uniqueTip = 'Such IP address already exists!'
+        -var ipAddressTip = 'Invalid IP address!'
 
         ignite-form-field-label
             | Addresses
@@ -43,9 +43,10 @@ include ../../../../../../../app/helpers/jade/mixins.jade
             | Add new address
 
         .group-content(ng-if='#{addresses}.length')
-            - var field = 'edit'
-            - var valid = form + '.' + field + '.$valid'
-            - var save = addresses + '[$index] = ' + field
+            -var field = 'edit'
+            -var valid = form + '.' + field + '.$valid'
+            -var unique = form + '.' + field + '.$error.igniteUnique'
+            -var save = addresses + '[$index] = ' + field
 
             ignite-form-field(ng-repeat='model in #{addresses} track by $index' type='internal' name='Address')
                 .indexField
@@ -60,19 +61,18 @@ include ../../../../../../../app/helpers/jade/mixins.jade
                 span(ng-if='field.edit' ng-init='#{field} = model')
                     +table-address-field(field, addresses, save, false)
                         +table-save-button(valid, save, false)
-                        +table-feedback-unique(form, field, uniqueTip)
-                        +table-feedback-ip-address(form, field, ipAddressTip)
+                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
         .group-content(ng-repeat='field in group.add')
-            - var field = 'new'
-            - var valid = form + '.' + field + '.$valid'
-            - var save = addresses + '.push(' + field + ')'
+            -var field = 'new'
+            -var valid = form + '.' + field + '.$valid'
+            -var unique = form + '.' + field + '.$error.igniteUnique'
+            -var save = addresses + '.push(' + field + ')'
 
             ignite-form-field(type='internal' name='Address')
                 +table-address-field(field, addresses, save, true)
                     +table-save-button(valid, save, true)
-                    +table-feedback-unique(form, field, uniqueTip)
-                    +table-feedback-ip-address(form, field, ipAddressTip)
+                    +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
         .group-content-empty(id='addresses' ng-if='!(#{addresses}.length) && !group.add.length')
                 | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
index 4e11cc6..8e4257f 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.ZooKeeper';
+-var model = 'backupItem.discovery.ZooKeeper';
 
 div
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
index 9a03e75..bc039e6 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.ZooKeeper.retryPolicy.BoundedExponentialBackoff';
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.BoundedExponentialBackoff';
 
 div
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
index f0d5311..8cf2a18 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.ZooKeeper.retryPolicy.Custom';
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.Custom';
 
 .details-row
     +java-class('Class name:', model + '.className', 'className', 'true', 'false', 'Custom retry policy implementation class name')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
index 729d937..4c8bca7 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.ZooKeeper.retryPolicy.ExponentialBackoff';
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.ExponentialBackoff';
 
 div
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
index f3d0957..dc2a955 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.ZooKeeper.retryPolicy.Forever';
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.Forever';
 
 .details-row
     +number('Interval:', model + '.retryIntervalMs', 'retryIntervalMs', 'true', '1000', '0', 'Time in ms between retry attempts')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
index 2cb6f90..4d7eafb 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.ZooKeeper.retryPolicy.NTimes';
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.NTimes';
 
 div
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
index d1c8607..83426c5 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.ZooKeeper.retryPolicy.OneTime';
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.OneTime';
 
 div
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
index 94850df..61cab70 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.discovery.ZooKeeper.retryPolicy.UntilElapsed';
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.UntilElapsed';
 
 div
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/igfs.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/igfs.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/igfs.jade
index f326607..25003d3 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/igfs.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/igfs.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='igfs' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/marshaller.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/marshaller.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/marshaller.jade
index 6f752ed..daff659 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/marshaller.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/marshaller.jade
@@ -16,9 +16,9 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
-- var marshaller = model + '.marshaller'
-- var optMarshaller = marshaller + '.OptimizedMarshaller'
+-var model = 'backupItem'
+-var marshaller = model + '.marshaller'
+-var optMarshaller = marshaller + '.OptimizedMarshaller'
 
 form.panel.panel-default(name='marshaller' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/metrics.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/metrics.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/metrics.jade
index bcfe977..0b20b2e 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/metrics.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/metrics.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='metrics' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
index cb4ed65..f96cc4e 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/ssl.jade
@@ -16,11 +16,11 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var cluster = 'backupItem'
-- var enabled = 'backupItem.sslEnabled'
-- var model = cluster + '.sslContextFactory'
-- var trust = model + '.trustManagers'
-- var form = 'trustManagers'
+-var cluster = 'backupItem'
+-var enabled = 'backupItem.sslEnabled'
+-var model = cluster + '.sslContextFactory'
+-var trust = model + '.trustManagers'
+-var form = 'trustManagers'
 
 form.panel.panel-default(name='#{form}' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')
@@ -49,7 +49,7 @@ form.panel.panel-default(name='#{form}' novalidate)
                     +text-options('Protocol:', model + '.protocol', 'protocol', '["TSL", "SSL"]', enabled, 'TSL', 'Protocol for secure transport')
                 .settings-row
                     ignite-form-group(ng-form='trustManagers' ng-model='#{trust}')
-                        - var uniqueTip = 'Such trust manager already exists!'
+                        -var uniqueTip = 'Such trust manager already exists!'
 
                         ignite-form-field-label
                             | Trust managers
@@ -59,10 +59,11 @@ form.panel.panel-default(name='#{form}' novalidate)
                             | Add new trust manager.
 
                         .group-content(ng-if='#{trust}.length')
-                            - var field = 'edit'
-                            - var valid = form + '.' + field + '.$valid'
-                            - var save = trust + '[$index] = ' + field
-                            - var reset = 'field.edit = false'
+                            -var field = 'edit'
+                            -var valid = form + '.' + field + '.$valid'
+                            -var unique = form + '.' + field + '.$error.igniteUnique'
+                            -var save = trust + '[$index] = ' + field
+                            -var reset = 'field.edit = false'
 
                             ignite-form-field(ng-repeat='model in #{trust} track by $index' type='internal' name='Trust manager')
                                 .indexField
@@ -73,17 +74,18 @@ form.panel.panel-default(name='#{form}' novalidate)
                                 span(ng-if='field.edit' ng-init='#{field} = model')
                                     +table-java-class-field(field, trust, save, false)
                                         +table-save-button(valid, save, false)
-                                        +table-feedback-unique(form, field, uniqueTip)
+                                        +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
                         .group-content(ng-repeat='field in group.add')
-                            - var field = 'new'
-                            - var valid = form + '.' + field + '.$valid'
-                            - var save = trust + '.push(' + field + ')'
+                            -var field = 'new'
+                            -var valid = form + '.' + field + '.$valid'
+                            -var unique = form + '.' + field + '.$error.igniteUnique'
+                            -var save = trust + '.push(' + field + ')'
 
                             ignite-form-field(type='internal' name='Trust manager')
                                 +table-java-class-field(field, trust, save, true)
                                     +table-save-button(valid, save, true)
-                                    +table-feedback-unique(form, field, uniqueTip)
+                                    +table-error-feedback(unique, 'igniteUnique', uniqueTip)
 
                         .group-content-empty(ng-if='!(#{trust}.length) && !group.add.length')
                             | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
index 0672c22..015bdd9 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/swap.jade
@@ -16,9 +16,9 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
-- var swapModel = model + '.swapSpaceSpi'
-- var fileSwapModel = swapModel + '.FileSwapSpaceSpi'
+-var model = 'backupItem'
+-var swapModel = model + '.swapSpaceSpi'
+-var fileSwapModel = swapModel + '.FileSwapSpaceSpi'
 
 form.panel.panel-default(name='swapSpaceSpi' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
index ad526ed..1537696 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/thread.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='thread' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/time.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/time.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/time.jade
index cade190..3576273 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/time.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/time.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem'
+-var model = 'backupItem'
 
 form.panel.panel-default(name='time' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')

http://git-wip-us.apache.org/repos/asf/ignite/blob/625dcefa/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
index 872b46c..90a2e50 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/clusters/transactions.jade
@@ -16,7 +16,7 @@
 
 include ../../../../../app/helpers/jade/mixins.jade
 
-- var model = 'backupItem.transactionConfiguration'
+-var model = 'backupItem.transactionConfiguration'
 
 form.panel.panel-default(name='transactionConfiguration' novalidate)
     .panel-heading(bs-collapse-toggle ng-click='__show__ = true')


[03/50] [abbrv] ignite git commit: IGNITE-2840 Additional mixins, fixed disabled conditions, disable empty dropdown

Posted by an...@apache.org.
IGNITE-2840 Additional mixins, fixed disabled conditions, disable empty dropdown


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/51308e66
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/51308e66
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/51308e66

Branch: refs/heads/ignite-2875
Commit: 51308e66e14845ebc01281334bac19e9101cda6d
Parents: 6b017f0
Author: vsisko <vs...@gridgain.com>
Authored: Thu Mar 17 18:29:27 2016 +0700
Committer: vsisko <vs...@gridgain.com>
Committed: Thu Mar 17 18:29:27 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/app/helpers/jade/mixins.jade    | 52 ++++++++++++++++++--
 1 file changed, 49 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/51308e66/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
index e09d5ef..0c4e140 100644
--- a/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
+++ b/modules/control-center-web/src/main/js/app/helpers/jade/mixins.jade
@@ -26,6 +26,34 @@ mixin checkbox(lbl, model, name, tip)
         ignite-form-field-tooltip
             | !{tip}
 
+//- Mixin for checkbox with enabled condition.
+mixin checkbox-enabled(lbl, model, name, enabled, tip)
+    ignite-form-field.checkbox
+        ignite-form-field-input-checkbox(
+            data-id=name
+            data-name=name
+            data-ng-model=model
+            data-ng-disabled='!(#{enabled})'
+        )
+        | #{lbl}
+        ignite-form-field-tooltip
+            | !{tip}
+
+//- Mixin for java name field with enabled condition.
+mixin java-class(lbl, model, name, enabled, required, tip)
+    ignite-form-field
+        ignite-form-field-label
+            | #{lbl}
+        ignite-form-field-tooltip
+            | !{tip}
+        ignite-form-field-java-class(
+            data-id=name
+            data-name=name
+            data-ng-model=model
+            data-ng-disabled='!(#{enabled})'
+            data-ng-required=required
+        )
+
 //- Mixin for text field.
 mixin text-enabled(lbl, model, name, enabled, required, placeholder, tip)
     ignite-form-field
@@ -38,7 +66,7 @@ mixin text-enabled(lbl, model, name, enabled, required, placeholder, tip)
             data-name=name
             data-ng-model=model
             data-placeholder=placeholder
-            data-ng-disabled='!#{enabled}'
+            data-ng-disabled='!(#{enabled})'
             data-ng-required=required
         )
 
@@ -46,6 +74,22 @@ mixin text-enabled(lbl, model, name, enabled, required, placeholder, tip)
 mixin text(lbl, model, name, required, placeholder, tip)
     +text-enabled(lbl, model, name, 'true', required, placeholder, tip)
 
+//- Mixin for text field with enabled condition with options.
+mixin text-options(lbl, model, name, options, enabled, placeholder, tip)
+    ignite-form-field
+        ignite-form-field-label
+            | #{lbl}
+        ignite-form-field-tooltip
+            | !{tip}
+        ignite-form-field-input-text(
+            data-id=name
+            data-name=name
+            data-ng-model=model
+            data-options=options
+            data-placeholder=placeholder
+            data-ng-disabled='!(#{enabled})'
+        )
+
 //- Mixin for required numeric field.
 mixin number-requited(lbl, model, name, required, enabled, placeholder, min, tip)
     ignite-form-field
@@ -58,7 +102,7 @@ mixin number-requited(lbl, model, name, required, enabled, placeholder, min, tip
             data-name=name
             data-ng-model=model
             data-ng-required=required
-            data-ng-disabled='!#{enabled}'
+            data-ng-disabled='!(#{enabled})'
             data-placeholder=placeholder
             data-min=min
         )
@@ -79,6 +123,7 @@ mixin number-min-max(lbl, model, name, enabled, placeholder, min, max, tip)
             data-min=min
             data-max=max
         )
+
 //- Mixin for numeric field.
 mixin number(lbl, model, name, enabled, placeholder, min, tip)
     +number-requited(lbl, model, name, 'false', enabled, placeholder, min, tip)
@@ -96,7 +141,7 @@ mixin dropdown-required(lbl, model, name, required, enabled, placeholder, option
             data-options=options
             data-ng-model=model
             data-ng-required=required
-            data-ng-disabled='!#{enabled}'
+            data-ng-disabled='!(#{enabled})'
             data-placeholder=placeholder
         )
 
@@ -119,6 +164,7 @@ mixin dropdown-multiple(lbl, model, name, placeholder, placeholderEmpty, options
             data-options=options
             data-ng-model=model
             data-placeholder='{{ #{options}.length > 0 ? "#{placeholder}" : "#{placeholderEmpty}" }}'
+            data-disabled='!#{options}.length'
         )
 
 //- Mixin for table java class field.


[02/50] [abbrv] ignite git commit: IGNITE-843 Fixed validator for java classes.

Posted by an...@apache.org.
IGNITE-843 Fixed validator for java classes.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6b017f01
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6b017f01
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6b017f01

Branch: refs/heads/ignite-2875
Commit: 6b017f019a834c1b1ab8d8f705f3ef75d02967b2
Parents: ec3150d
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Thu Mar 17 18:06:24 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Thu Mar 17 18:06:24 2016 +0700

----------------------------------------------------------------------
 .../form-field-java-class/form-field-java-class.directive.js  | 3 ++-
 .../form-field-java-class/form-field-java-class.jade          | 6 +++---
 .../src/main/js/app/modules/form/group/group.directive.js     | 7 +++----
 3 files changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/6b017f01/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
index 8c857f0..f1f66c9 100644
--- a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
+++ b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.directive.js
@@ -26,6 +26,7 @@ export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
         scope.ngModel = ngModel;
         scope.form = form;
         scope.label = label;
+        scope.name = scope.ngModelName + 'JavaClass';
 
         scope.$watch('required', (required) => {
             label.required = required || false;
@@ -62,7 +63,7 @@ export default ['igniteFormFieldJavaClass', ['IgniteFormGUID', (guid) => {
         restrict: 'E',
         scope: {
             id: '@',
-            name: '@',
+            ngModelName: '@name',
             placeholder: '@',
             required: '=ngRequired',
             disabled: '=ngDisabled',

http://git-wip-us.apache.org/repos/asf/ignite/blob/6b017f01/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.jade b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.jade
index 6b56e6a..3078b80 100644
--- a/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.jade
+++ b/modules/control-center-web/src/main/js/app/directives/form-field-java-class/form-field-java-class.jade
@@ -16,7 +16,7 @@
 
 mixin feedback(error, message)
     i.fa.fa-exclamation-triangle.form-control-feedback(
-        ng-if='!form[name+"JavaClass"].$pristine && form[name+"JavaClass"].$error.#{error}'
+        ng-if='!form[name].$pristine && form[name].$error.#{error}'
         bs-tooltip='"{{ label.name }} #{message}"'
         ignite-error='#{error}'
         ignite-error-message='{{ label.name }} #{message}'
@@ -24,8 +24,8 @@ mixin feedback(error, message)
 
 .input-tip
     input.form-control(
-        id='{{ id }}'
-        name='{{ name }}JavaClass'
+        id='{{ id }}JavaClass'
+        name='{{ name }}'
         placeholder='Enter fully qualified class name'
         type='text'
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/6b017f01/modules/control-center-web/src/main/js/app/modules/form/group/group.directive.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/form/group/group.directive.js b/modules/control-center-web/src/main/js/app/modules/form/group/group.directive.js
index d5fedfd..5039d6f 100644
--- a/modules/control-center-web/src/main/js/app/modules/form/group/group.directive.js
+++ b/modules/control-center-web/src/main/js/app/modules/form/group/group.directive.js
@@ -34,7 +34,7 @@ export default ['igniteFormGroup', [() => {
         parentFormCtrl.$defaults = parentFormCtrl.$defaults || {};
 
         if (parentFormCtrl.$pristine) {
-            if (!(_.isNull(parentFormCtrl.$defaults[name]) || _.isUndefined(parentFormCtrl.$defaults[name]))) 
+            if (!(_.isNull(parentFormCtrl.$defaults[name]) || _.isUndefined(parentFormCtrl.$defaults[name])))
                 scope.ngModel = parentFormCtrl.$defaults[name];
             else
                 parentFormCtrl.$defaults[name] = _.cloneDeep(scope.ngModel);
@@ -50,11 +50,10 @@ export default ['igniteFormGroup', [() => {
         };
 
         const setAsDirty = () => {
-            if (JSON.stringify(scope.ngModel) !== JSON.stringify(parentFormCtrl.$defaults[name])){
+            if (JSON.stringify(scope.ngModel) !== JSON.stringify(parentFormCtrl.$defaults[name]))
                 ngModelCtrl.$setDirty();
-            }else{
+            else
                 ngModelCtrl.$setPristine();
-            }
         };
 
         scope.$watch(() => parentFormCtrl.$pristine, setAsDefault);