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:48:14 UTC

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

 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;