http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration.state.js
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration.state.js 
b/modules/web-console/frontend/app/modules/states/configuration.state.js
index 0ce936c..1a0a598 100644
--- a/modules/web-console/frontend/app/modules/states/configuration.state.js
+++ b/modules/web-console/frontend/app/modules/states/configuration.state.js
@@ -17,136 +17,281 @@
 
 import angular from 'angular';
 
+import {default as ActivitiesData} from 'app/core/activities/Activities.data';
+
 // Common directives.
 import previewPanel from './configuration/preview-panel.directive.js';
 
 // Summary screen.
-import ConfigurationSummaryCtrl from 
'./configuration/summary/summary.controller';
 import ConfigurationResource from './configuration/Configuration.resource';
-import summaryTabs from './configuration/summary/summary-tabs.directive';
 import IgniteSummaryZipper from 
'./configuration/summary/summary-zipper.service';
 
-import clustersTpl from 'views/configuration/clusters.tpl.pug';
-import cachesTpl from 'views/configuration/caches.tpl.pug';
-import domainsTpl from 'views/configuration/domains.tpl.pug';
-import igfsTpl from 'views/configuration/igfs.tpl.pug';
-import summaryTpl from 'views/configuration/summary.tpl.pug';
-import summaryTabsTemplateUrl from 'views/configuration/summary-tabs.pug';
+import base2 from 'views/base2.pug';
+import pageConfigureAdvancedClusterComponent from 
'app/components/page-configure-advanced/components/page-configure-advanced-cluster/component';
+import pageConfigureAdvancedModelsComponent from 
'app/components/page-configure-advanced/components/page-configure-advanced-models/component';
+import pageConfigureAdvancedCachesComponent from 
'app/components/page-configure-advanced/components/page-configure-advanced-caches/component';
+import pageConfigureAdvancedIGFSComponent from 
'app/components/page-configure-advanced/components/page-configure-advanced-igfs/component';
 
-import clustersCtrl from 'Controllers/clusters-controller';
-import domainsCtrl from 'Controllers/domains-controller';
-import cachesCtrl from 'Controllers/caches-controller';
-import igfsCtrl from 'Controllers/igfs-controller';
+import get from 'lodash/get';
+import {Observable} from 'rxjs/Observable';
 
-import base2 from 'views/base2.pug';
+const idRegex = `new|[a-z0-9]+`;
+
+const shortCachesResolve = ['ConfigSelectors', 'ConfigureState', 
'ConfigEffects', '$transition$', (ConfigSelectors, ConfigureState, {etp}, 
$transition$) => {
+    if ($transition$.params().clusterID === 'new') return Promise.resolve();
+    return Observable.fromPromise($transition$.injector().getAsync('_cluster'))
+    .switchMap(() => 
ConfigureState.state$.let(ConfigSelectors.selectCluster($transition$.params().clusterID)).take(1))
+    .switchMap((cluster) => {
+        return etp('LOAD_SHORT_CACHES', {ids: cluster.caches, clusterID: 
cluster._id});
+    })
+    .toPromise();
+}];
+
+/**
+ * @param {ActivitiesData} ActivitiesData
+ * @param {uirouter.UIRouter} $uiRouter
+ */
+function initConfiguration(ActivitiesData, $uiRouter) {
+    $uiRouter.transitionService.onSuccess({to: 'base.configuration.**'}, 
(transition) => {
+        ActivitiesData.post({group: 'configuration', action: 
transition.targetState().name()});
+    });
+}
+
+initConfiguration.$inject = ['IgniteActivitiesData', '$uiRouter'];
 
 angular.module('ignite-console.states.configuration', ['ui.router'])
     .directive(...previewPanel)
-    // Summary screen
-    .directive(...summaryTabs)
     // Services.
     .service('IgniteSummaryZipper', IgniteSummaryZipper)
     .service('IgniteConfigurationResource', ConfigurationResource)
-    .run(['$templateCache', ($templateCache) => {
-        $templateCache.put('summary-tabs.html', summaryTabsTemplateUrl);
-    }])
+    .run(initConfiguration)
     // Configure state provider.
     .config(['$stateProvider', ($stateProvider) => {
         // Setup the states.
         $stateProvider
             .state('base.configuration', {
                 abstract: true,
+                permission: 'configuration',
+                url: '/configuration',
+                onEnter: ['ConfigureState', (ConfigureState) => 
ConfigureState.dispatchAction({type: 'PRELOAD_STATE', state: {}})],
                 views: {
                     '@': {
                         template: base2
                     }
+                },
+                resolve: {
+                    _shortClusters: ['ConfigEffects', ({etp}) => {
+                        return etp('LOAD_USER_CLUSTERS');
+                    }]
+                },
+                resolvePolicy: {
+                    async: 'NOWAIT'
                 }
             })
-            .state('base.configuration.tabs', {
-                url: '/configuration',
+            .state('base.configuration.overview', {
+                url: '/overview',
+                component: 'pageConfigureOverview',
                 permission: 'configuration',
-                template: '<page-configure></page-configure>',
-                redirectTo: (trans) => {
-                    const PageConfigure = 
trans.injector().get('PageConfigure');
-
-                    return PageConfigure.onStateEnterRedirect(trans.to());
+                tfMetaTags: {
+                    title: 'Configuration'
+                }
+            })
+            .state('base.configuration.edit', {
+                url: `/{clusterID:${idRegex}}`,
+                permission: 'configuration',
+                component: 'pageConfigure',
+                resolve: {
+                    _cluster: ['ConfigEffects', '$transition$', ({etp}, 
$transition$) => {
+                        return 
$transition$.injector().getAsync('_shortClusters').then(() => {
+                            return etp('LOAD_AND_EDIT_CLUSTER', {clusterID: 
$transition$.params().clusterID});
+                        });
+                    }]
+                },
+                data: {
+                    errorState: 'base.configuration.overview'
+                },
+                redirectTo: ($transition$) => {
+                    const [ConfigureState, ConfigSelectors] = 
['ConfigureState', 'ConfigSelectors'].map((t) => 
$transition$.injector().get(t));
+                    const waitFor = ['_cluster', '_shortClusters'].map((t) => 
$transition$.injector().getAsync(t));
+                    return 
Observable.fromPromise(Promise.all(waitFor)).switchMap(() => {
+                        return Observable.combineLatest(
+                            
ConfigureState.state$.let(ConfigSelectors.selectCluster($transition$.params().clusterID)).take(1),
+                            
ConfigureState.state$.let(ConfigSelectors.selectShortClusters()).take(1)
+                        );
+                    })
+                    .map(([cluster = {caches: []}, clusters]) => {
+                        return (clusters.value.size > 10 || 
cluster.caches.length > 5)
+                            ? 'base.configuration.edit.advanced'
+                            : 'base.configuration.edit.basic';
+                    })
+                    .toPromise();
                 },
                 failState: 'signin',
                 tfMetaTags: {
                     title: 'Configuration'
                 }
             })
-            .state('base.configuration.tabs.basic', {
+            .state('base.configuration.edit.basic', {
                 url: '/basic',
+                component: 'pageConfigureBasic',
                 permission: 'configuration',
-                template: '<page-configure-basic></page-configure-basic>',
+                resolve: {
+                    _shortCaches: shortCachesResolve
+                },
+                resolvePolicy: {
+                    async: 'NOWAIT'
+                },
                 tfMetaTags: {
                     title: 'Basic Configuration'
-                },
-                resolve: {
-                    list: ['IgniteConfigurationResource', 'PageConfigure', 
(configuration, pageConfigure) => {
-                        // TODO IGNITE-5271: remove when advanced config is 
hooked into ConfigureState too.
-                        // This resolve ensures that basic always has fresh 
data, i.e. after going back from advanced
-                        // after adding a cluster.
-                        return configuration.read().then((data) => {
-                            pageConfigure.loadList(data);
-                        });
-                    }]
                 }
             })
-            .state('base.configuration.tabs.advanced', {
+            .state('base.configuration.edit.advanced', {
                 url: '/advanced',
-                template: 
'<page-configure-advanced></page-configure-advanced>',
-                redirectTo: 'base.configuration.tabs.advanced.clusters'
+                component: 'pageConfigureAdvanced',
+                permission: 'configuration',
+                redirectTo: 'base.configuration.edit.advanced.cluster'
             })
-            .state('base.configuration.tabs.advanced.clusters', {
-                url: '/clusters',
-                templateUrl: clustersTpl,
+            .state('base.configuration.edit.advanced.cluster', {
+                url: '/cluster',
+                component: pageConfigureAdvancedClusterComponent.name,
                 permission: 'configuration',
-                tfMetaTags: {
-                    title: 'Configure Clusters'
+                resolve: {
+                    _shortCaches: shortCachesResolve
                 },
-                controller: clustersCtrl,
-                controllerAs: '$ctrl'
+                resolvePolicy: {
+                    async: 'NOWAIT'
+                },
+                tfMetaTags: {
+                    title: 'Configure Cluster'
+                }
             })
-            .state('base.configuration.tabs.advanced.caches', {
+            .state('base.configuration.edit.advanced.caches', {
                 url: '/caches',
-                templateUrl: cachesTpl,
                 permission: 'configuration',
+                component: pageConfigureAdvancedCachesComponent.name,
+                resolve: {
+                    _shortCachesAndModels: ['ConfigSelectors', 
'ConfigureState', 'ConfigEffects', '$transition$', (ConfigSelectors, 
ConfigureState, {etp}, $transition$) => {
+                        if ($transition$.params().clusterID === 'new') return 
Promise.resolve();
+                        return 
Observable.fromPromise($transition$.injector().getAsync('_cluster'))
+                        .switchMap(() => 
ConfigureState.state$.let(ConfigSelectors.selectCluster($transition$.params().clusterID)).take(1))
+                        .map((cluster) => {
+                            return Promise.all([
+                                etp('LOAD_SHORT_CACHES', {ids: cluster.caches, 
clusterID: cluster._id}),
+                                etp('LOAD_SHORT_MODELS', {ids: cluster.models, 
clusterID: cluster._id}),
+                                etp('LOAD_SHORT_IGFSS', {ids: cluster.igfss, 
clusterID: cluster._id})
+                            ]);
+                        })
+                        .toPromise();
+                    }]
+                },
+                resolvePolicy: {
+                    async: 'NOWAIT'
+                },
                 tfMetaTags: {
                     title: 'Configure Caches'
+                }
+            })
+            .state('base.configuration.edit.advanced.caches.cache', {
+                url: `/{cacheID:${idRegex}}`,
+                permission: 'configuration',
+                resolve: {
+                    _cache: ['ConfigEffects', '$transition$', ({etp}, 
$transition$) => {
+                        const {clusterID, cacheID} = $transition$.params();
+                        if (cacheID === 'new') return Promise.resolve();
+                        return etp('LOAD_CACHE', {cacheID});
+                    }]
                 },
-                controller: cachesCtrl,
-                controllerAs: '$ctrl'
+                data: {
+                    errorState: 'base.configuration.edit.advanced.caches'
+                },
+                resolvePolicy: {
+                    async: 'NOWAIT'
+                },
+                tfMetaTags: {
+                    title: 'Configure Caches'
+                }
             })
-            .state('base.configuration.tabs.advanced.domains', {
-                url: '/domains',
-                templateUrl: domainsTpl,
+            .state('base.configuration.edit.advanced.models', {
+                url: '/models',
+                component: pageConfigureAdvancedModelsComponent.name,
                 permission: 'configuration',
+                resolve: {
+                    _shortCachesAndModels: ['ConfigSelectors', 
'ConfigureState', 'ConfigEffects', '$transition$', (ConfigSelectors, 
ConfigureState, {etp}, $transition$) => {
+                        if ($transition$.params().clusterID === 'new') return 
Promise.resolve();
+                        return 
Observable.fromPromise($transition$.injector().getAsync('_cluster'))
+                        .switchMap(() => 
ConfigureState.state$.let(ConfigSelectors.selectCluster($transition$.params().clusterID)).take(1))
+                        .map((cluster) => {
+                            return Promise.all([
+                                etp('LOAD_SHORT_CACHES', {ids: cluster.caches, 
clusterID: cluster._id}),
+                                etp('LOAD_SHORT_MODELS', {ids: cluster.models, 
clusterID: cluster._id})
+                            ]);
+                        })
+                        .toPromise();
+                    }]
+                },
+                resolvePolicy: {
+                    async: 'NOWAIT'
+                },
                 tfMetaTags: {
-                    title: 'Configure Domain Model'
+                    title: 'Configure SQL Schemes'
+                }
+            })
+            .state('base.configuration.edit.advanced.models.model', {
+                url: `/{modelID:${idRegex}}`,
+                resolve: {
+                    _cache: ['ConfigEffects', '$transition$', ({etp}, 
$transition$) => {
+                        const {clusterID, modelID} = $transition$.params();
+                        if (modelID === 'new') return Promise.resolve();
+                        return etp('LOAD_MODEL', {modelID});
+                    }]
+                },
+                data: {
+                    errorState: 'base.configuration.edit.advanced.models'
                 },
-                controller: domainsCtrl,
-                controllerAs: '$ctrl'
+                permission: 'configuration',
+                resolvePolicy: {
+                    async: 'NOWAIT'
+                }
             })
-            .state('base.configuration.tabs.advanced.igfs', {
+            .state('base.configuration.edit.advanced.igfs', {
                 url: '/igfs',
-                templateUrl: igfsTpl,
+                component: pageConfigureAdvancedIGFSComponent.name,
                 permission: 'configuration',
+                resolve: {
+                    _shortIGFSs: ['ConfigSelectors', 'ConfigureState', 
'ConfigEffects', '$transition$', (ConfigSelectors, ConfigureState, {etp}, 
$transition$) => {
+                        if ($transition$.params().clusterID === 'new') return 
Promise.resolve();
+                        return 
Observable.fromPromise($transition$.injector().getAsync('_cluster'))
+                        .switchMap(() => 
ConfigureState.state$.let(ConfigSelectors.selectCluster($transition$.params().clusterID)).take(1))
+                        .map((cluster) => {
+                            return Promise.all([
+                                etp('LOAD_SHORT_IGFSS', {ids: cluster.igfss, 
clusterID: cluster._id})
+                            ]);
+                        })
+                        .toPromise();
+                    }]
+                },
+                resolvePolicy: {
+                    async: 'NOWAIT'
+                },
                 tfMetaTags: {
                     title: 'Configure IGFS'
-                },
-                controller: igfsCtrl,
-                controllerAs: '$ctrl'
+                }
             })
-            .state('base.configuration.tabs.advanced.summary', {
-                url: '/summary',
-                templateUrl: summaryTpl,
+            .state('base.configuration.edit.advanced.igfs.igfs', {
+                url: `/{igfsID:${idRegex}}`,
                 permission: 'configuration',
-                controller: ConfigurationSummaryCtrl,
-                controllerAs: 'ctrl',
-                tfMetaTags: {
-                    title: 'Configurations Summary'
+                resolve: {
+                    _igfs: ['ConfigEffects', '$transition$', ({etp}, 
$transition$) => {
+                        const {clusterID, igfsID} = $transition$.params();
+                        if (igfsID === 'new') return Promise.resolve();
+                        return etp('LOAD_IGFS', {igfsID});
+                    }]
+                },
+                data: {
+                    errorState: 'base.configuration.edit.advanced.igfs'
+                },
+                resolvePolicy: {
+                    async: 'NOWAIT'
                 }
             });
     }]);

http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration/caches/affinity.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration/caches/affinity.pug
 
b/modules/web-console/frontend/app/modules/states/configuration/caches/affinity.pug
index e622694..ca781da 100644
--- 
a/modules/web-console/frontend/app/modules/states/configuration/caches/affinity.pug
+++ 
b/modules/web-console/frontend/app/modules/states/configuration/caches/affinity.pug
@@ -17,7 +17,7 @@
 include /app/helpers/jade/mixins
 
 -var form = 'affinity'
--var model = 'backupItem'
+-var model = '$ctrl.clonedCache'
 -var affModel = model + '.affinity'
 -var affMapModel = model + '.affinityMapper'
 -var rendezvousAff = affModel + '.kind === "Rendezvous"'
@@ -27,18 +27,17 @@ include /app/helpers/jade/mixins
 -var rendPartitionsRequired = rendezvousAff + ' && ' + affModel + 
'.Rendezvous.affinityBackupFilter'
 -var fairPartitionsRequired = fairAff + ' && ' + affModel + 
'.Fair.affinityBackupFilter'
 
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+.pca-panel(ng-form=form novalidate)
+    .pca-panel-heading(bs-collapse-toggle='' 
ng-click=`ui.loadPanel('${form}')`)
         ignite-form-panel-chevron
-        label Affinity Collocation
-        ignite-form-field-tooltip.tipLabel
-            | Collocate data with data to improve performance and scalability 
of your application#[br]
-            | 
#[a(href="https://apacheignite.readme.io/docs/affinity-collocation"; 
target="_blank") More info]
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
-        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
-            .col-sm-6
-                .settings-row(ng-if='$ctrl.available(["1.0.0", "2.0.0"])')
+        .pca-panel-heading-title Affinity Collocation
+        .pca-panel-heading-description
+            | Collocate data with data to improve performance and scalability 
of your application. 
+            
a.link-success(href="https://apacheignite.readme.io/docs/affinity-collocation"; 
target="_blank") More info
+    .pca-panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .pca-panel-body.pca-form-row(ng-if=`ui.isPanelLoaded('${form}')`)
+            .pca-form-column-6.pc-form-grid-row
+                .pc-form-grid-col-60(ng-if='$ctrl.available(["1.0.0", 
"2.0.0"])')
                     +dropdown('Function:', `${affModel}.kind`, 
'"AffinityKind"', 'true', 'Default', 'affinityFunction',
                         'Key topology resolver to provide mapping from keys to 
nodes<br/>\
                         <ul>\
@@ -47,7 +46,7 @@ include /app/helpers/jade/mixins
                             <li>Custom - Custom implementation of key affinity 
fynction</li>\
                             <li>Default - By default rendezvous affinity 
function  with 1024 partitions is used</li>\
                         </ul>')
-                .settings-row(ng-if='$ctrl.available("2.0.0")')
+                .pc-form-grid-col-60(ng-if='$ctrl.available("2.0.0")')
                     +dropdown('Function:', `${affModel}.kind`, 
'"AffinityKind"', 'true', 'Default', 'affinityFunction',
                         'Key topology resolver to provide mapping from keys to 
nodes<br/>\
                         <ul>\
@@ -55,35 +54,36 @@ include /app/helpers/jade/mixins
                             <li>Custom - Custom implementation of key affinity 
fynction</li>\
                             <li>Default - By default rendezvous affinity 
function  with 1024 partitions is used</li>\
                         </ul>')
-                .panel-details(ng-if=rendezvousAff)
-                    .details-row
-                        +number-required('Partitions', 
`${affModel}.Rendezvous.partitions`, '"RendPartitions"', 'true', 
rendPartitionsRequired, '1024', '1', 'Number of partitions')
-                    .details-row
-                        +java-class('Backup filter', 
`${affModel}.Rendezvous.affinityBackupFilter`, '"RendAffinityBackupFilter"', 
'true', 'false',
-                            'Backups will be selected from all nodes that pass 
this filter')
-                    .details-row
-                        +checkbox('Exclude neighbors', 
`${affModel}.Rendezvous.excludeNeighbors`, '"RendExcludeNeighbors"',
-                            'Exclude same - host - neighbors from being 
backups of each other and specified number of backups')
-                .panel-details(ng-if=fairAff)
-                    .details-row
-                        +number-required('Partitions', 
`${affModel}.Fair.partitions`, '"FairPartitions"', 'true', 
fairPartitionsRequired, '256', '1', 'Number of partitions')
-                    .details-row
-                        +java-class('Backup filter', 
`${affModel}.Fair.affinityBackupFilter`, '"FairAffinityBackupFilter"', 'true', 
'false',
-                            'Backups will be selected from all nodes that pass 
this filter')
-                    .details-row
-                        +checkbox('Exclude neighbors', 
`${affModel}.Fair.excludeNeighbors`, '"FairExcludeNeighbors"',
-                            'Exclude same - host - neighbors from being 
backups of each other and specified number of backups')
-                .panel-details(ng-if=customAff)
-                    .details-row
-                        +java-class('Class name:', 
`${affModel}.Custom.className`, '"AffCustomClassName"', 'true', customAff,
-                            'Custom key affinity function implementation class 
name')
-                .settings-row
+                .pc-form-group
+                    .pc-form-grid-row(ng-if=rendezvousAff)
+                        .pc-form-grid-col-60
+                            +number-required('Partitions', 
`${affModel}.Rendezvous.partitions`, '"RendPartitions"', 'true', 
rendPartitionsRequired, '1024', '1', 'Number of partitions')
+                        .pc-form-grid-col-60
+                            +java-class('Backup filter', 
`${affModel}.Rendezvous.affinityBackupFilter`, '"RendAffinityBackupFilter"', 
'true', 'false',
+                                'Backups will be selected from all nodes that 
pass this filter')
+                        .pc-form-grid-col-60
+                            +checkbox('Exclude neighbors', 
`${affModel}.Rendezvous.excludeNeighbors`, '"RendExcludeNeighbors"',
+                                'Exclude same - host - neighbors from being 
backups of each other and specified number of backups')
+                    .pc-form-grid-row(ng-if=fairAff)
+                        .pc-form-grid-col-60
+                            +number-required('Partitions', 
`${affModel}.Fair.partitions`, '"FairPartitions"', 'true', 
fairPartitionsRequired, '256', '1', 'Number of partitions')
+                        .pc-form-grid-col-60
+                            +java-class('Backup filter', 
`${affModel}.Fair.affinityBackupFilter`, '"FairAffinityBackupFilter"', 'true', 
'false',
+                                'Backups will be selected from all nodes that 
pass this filter')
+                        .pc-form-grid-col-60
+                            +checkbox('Exclude neighbors', 
`${affModel}.Fair.excludeNeighbors`, '"FairExcludeNeighbors"',
+                                'Exclude same - host - neighbors from being 
backups of each other and specified number of backups')
+                    .pc-form-grid-row(ng-if=customAff)
+                        .pc-form-grid-col-60
+                            +java-class('Class name:', 
`${affModel}.Custom.className`, '"AffCustomClassName"', 'true', customAff,
+                                'Custom key affinity function implementation 
class name')
+                .pc-form-grid-col-60
                     +java-class('Mapper:', model + '.affinityMapper', 
'"AffMapCustomClassName"', 'true', 'false',
                         'Provide custom affinity key for any given key')
 
                 //- Since ignite 2.0
-                .settings-row(ng-if='$ctrl.available("2.0.0")')
-                    +java-class('Topology validator:', model + 
'.topologyValidator', '"topologyValidator"', 'true', 'false', 'Topology 
validator')
+                .pc-form-grid-col-60(ng-if='$ctrl.available("2.0.0")')
+                    +java-class('Topology validator:', model + 
'.topologyValidator', '"topologyValidator"', 'true', 'false')
 
-            .col-sm-6
+            .pca-form-column-6
                 +preview-xml-java(model, 'cacheAffinity')

http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration/caches/client-near-cache.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration/caches/client-near-cache.pug
 
b/modules/web-console/frontend/app/modules/states/configuration/caches/client-near-cache.pug
deleted file mode 100644
index cd5bcc8..0000000
--- 
a/modules/web-console/frontend/app/modules/states/configuration/caches/client-near-cache.pug
+++ /dev/null
@@ -1,50 +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.
-
-include /app/helpers/jade/mixins
-
--var form = 'clientNearCache'
--var model = 'backupItem.clientNearConfiguration'
-
-.panel.panel-default(ng-form=form novalidate ng-show='backupItem.cacheMode === 
"PARTITIONED"')
-    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
-        ignite-form-panel-chevron
-        label Client near cache
-        ignite-form-field-tooltip.tipLabel
-            | Near cache settings for client nodes#[br]
-            | Near cache is a small local cache that stores most recently or 
most frequently accessed data#[br]
-            | Should be used in case when it is impossible to send 
computations to remote nodes
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
-        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
-            .col-sm-6
-                -var enabled = `${model}.clientNearCacheEnabled`
-
-                .settings-row
-                    +checkbox('Enabled', enabled, '"clientNacheEnabled"', 
'Flag indicating whether to configure near cache')
-                .settings-row
-                    +number('Start size:', `${model}.nearStartSize`, 
'"clientNearStartSize"', enabled, '375000', '0',
-                        'Initial cache size for near cache which will be used 
to pre-create internal hash table after start')
-                .settings-row
-                    +evictionPolicy(`${model}.nearEvictionPolicy`, 
'"clientNearCacheEvictionPolicy"', enabled, 'false',
-                        'Near cache eviction policy\
-                        <ul>\
-                            <li>Least Recently Used (LRU) - Eviction policy 
based on LRU algorithm and supports batch eviction</li>\
-                            <li>First In First Out (FIFO) - Eviction policy 
based on FIFO algorithm and supports batch eviction</li>\
-                            <li>SORTED - Eviction policy which will select the 
minimum cache entry for eviction</li>\
-                        </ul>')
-            .col-sm-6
-                +preview-xml-java('backupItem', 'cacheClientNearCache')

http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration/caches/concurrency.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration/caches/concurrency.pug
 
b/modules/web-console/frontend/app/modules/states/configuration/caches/concurrency.pug
index b24bf47..2902f21 100644
--- 
a/modules/web-console/frontend/app/modules/states/configuration/caches/concurrency.pug
+++ 
b/modules/web-console/frontend/app/modules/states/configuration/caches/concurrency.pug
@@ -17,29 +17,28 @@
 include /app/helpers/jade/mixins
 
 -var form = 'concurrency'
--var model = 'backupItem'
+-var model = '$ctrl.clonedCache'
 
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+.pca-panel(ng-form=form novalidate)
+    .pca-panel-heading(bs-collapse-toggle='' 
ng-click=`ui.loadPanel('${form}')`)
         ignite-form-panel-chevron
-        label Concurrency control
-        ignite-form-field-tooltip.tipLabel
-            | Cache concurrent asynchronous operations settings
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
-        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
-            .col-sm-6
-                .settings-row
+        .pca-panel-heading-title Concurrency control
+        .pca-panel-heading-description
+            | Cache concurrent asynchronous operations settings.
+    .pca-panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .pca-panel-body.pca-form-row(ng-if=`ui.isPanelLoaded('${form}')`)
+            .pca-form-column-6.pc-form-grid-row
+                .pc-form-grid-col-30
                     +number('Max async operations:', 
`${model}.maxConcurrentAsyncOperations`, '"maxConcurrentAsyncOperations"', 
'true', '500', '0',
                         'Maximum number of allowed concurrent asynchronous 
operations<br/>\
                         If <b>0</b> then number of concurrent asynchronous 
operations is unlimited')
-                .settings-row
+                .pc-form-grid-col-30
                     +number('Default lock timeout:', 
`${model}.defaultLockTimeout`, '"defaultLockTimeout"', 'true', '0', '0',
                         'Default lock acquisition timeout in milliseconds<br/>\
                         If <b>0</b> then lock acquisition will never timeout')
 
                 //- Removed in ignite 2.0
-                .settings-row(ng-if='$ctrl.available(["1.0.0", "2.0.0"])' 
ng-hide=`${model}.atomicityMode === 'TRANSACTIONAL'`)
+                .pc-form-grid-col-60(ng-if='$ctrl.available(["1.0.0", 
"2.0.0"])' ng-hide=`${model}.atomicityMode === 'TRANSACTIONAL'`)
                     +dropdown('Entry versioning:', 
`${model}.atomicWriteOrderMode`, '"atomicWriteOrderMode"', 'true', 'Choose 
versioning',
                         '[\
                             {value: "CLOCK", label: "CLOCK"},\
@@ -51,7 +50,7 @@ include /app/helpers/jade/mixins
                             <li>PRIMARY - in this mode version is assigned 
only on primary node. This means that sender will only send write request to 
primary node, which in turn will assign write version and forward it to 
backups</li>\
                         </ul>')
 
-                .settings-row
+                .pc-form-grid-col-60
                     +dropdown('Write synchronization mode:', 
`${model}.writeSynchronizationMode`, '"writeSynchronizationMode"', 'true', 
'PRIMARY_SYNC',
                         '[\
                             {value: "FULL_SYNC", label: "FULL_SYNC"},\
@@ -64,5 +63,5 @@ include /app/helpers/jade/mixins
                             <li>FULL_ASYNC - Ignite will not wait for write or 
commit responses from participating nodes</li>\
                             <li>PRIMARY_SYNC - Makes sense for PARTITIONED 
mode. Ignite will wait for write or commit to complete on primary node</li>\
                         </ul>')
-            .col-sm-6
+            .pca-form-column-6
                 +preview-xml-java(model, 'cacheConcurrency')

http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration/caches/general.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration/caches/general.pug
 
b/modules/web-console/frontend/app/modules/states/configuration/caches/general.pug
index 50f39e6..df4d3f8 100644
--- 
a/modules/web-console/frontend/app/modules/states/configuration/caches/general.pug
+++ 
b/modules/web-console/frontend/app/modules/states/configuration/caches/general.pug
@@ -17,35 +17,51 @@
 include /app/helpers/jade/mixins
 
 -var form = 'general'
--var model = 'backupItem'
+-var model = '$ctrl.clonedCache'
 
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle)
+.pca-panel(ng-form=form novalidate)
+    .pca-panel-heading(bs-collapse-toggle)
         ignite-form-panel-chevron
-        label General
-        ignite-form-field-tooltip.tipLabel
-            | Common cache configuration#[br]
-            | #[a(href="https://apacheignite.readme.io/docs/data-grid"; 
target="_blank") More info]
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id='general')
-        .panel-body
-            .col-sm-6
-                .settings-row
-                    +text('Name:', `${model}.name`, '"cacheName"', 'true', 
'Input name', 'Cache name')
-                .settings-row(ng-if='$ctrl.available("2.1.0")')
+        .pca-panel-heading-title General
+        .pca-panel-heading-description
+            | Common cache configuration. 
+            
a.link-success(href="https://apacheignite.readme.io/docs/data-grid"; 
target="_blank") More info
+    .pca-panel-collapse(role='tabpanel' bs-collapse-target id='general')
+        .pca-panel-body.pca-form-row
+            .pca-form-column-6.pc-form-grid-row
+                
+                .pc-form-grid-col-60
+                    +sane-ignite-form-field-text({
+                        label: 'Name:',
+                        model: `${model}.name`,
+                        name: '"cacheName"',
+                        placeholder: 'Input name',
+                        required: true
+                    })(
+                        ignite-unique='$ctrl.caches'
+                        ignite-unique-property='name'
+                        ignite-unique-skip=`["_id", ${model}]`
+                    )
+                        +unique-feedback(`${model}.name`, 'Cache name should 
be unique')
+                .pc-form-grid-col-60
+                    +sane-ignite-form-field-dropdown({
+                        label: 'Domain models:',
+                        model: `${model}.domains`,
+                        name: '"domains"',
+                        multiple: true,
+                        placeholder: 'Choose domain models',
+                        placeholderEmpty: 'No valid domain models configured',
+                        options: '$ctrl.modelsMenu',
+                        tip: 'Select domain models to describe types in cache'
+                    })
+                .pc-form-grid-col-60(ng-if='$ctrl.available("2.1.0")')
                     +text('Group:', `${model}.groupName`, '"groupName"', 
'false', 'Input group name',
                         'Cache group name.<br/>\
                         Caches with the same group name share single 
underlying "physical" cache (partition set), but are logically isolated.')
-                .settings-row
-                    +clusters(model, 'Associate clusters with the current 
cache')
-                .settings-row
-                    +dropdown-multiple('<span>Domain models:</span><a 
ui-sref="base.configuration.tabs.advanced.domains({linkId: linkId()})"> 
(add)</a>',
-                        `${model}.domains`, '"domains"', true, 'Choose domain 
models', 'No valid domain models configured', 'domains',
-                        'Select domain models to describe types in cache')
-                .settings-row
+                .pc-form-grid-col-30
                     +cacheMode('Mode:', `${model}.cacheMode`, '"cacheMode"', 
'PARTITIONED')
 
-                .settings-row
+                .pc-form-grid-col-30
                     +dropdown('Atomicity:', `${model}.atomicityMode`, 
'"atomicityMode"', 'true', 'ATOMIC',
                         '[\
                             {value: "ATOMIC", label: "ATOMIC"},\
@@ -56,14 +72,10 @@ include /app/helpers/jade/mixins
                             <li>ATOMIC - in this mode distributed transactions 
and distributed locking are not supported</li>\
                             <li>TRANSACTIONAL - in this mode specified fully 
ACID-compliant transactional cache behavior</li>\
                         </ul>')
-                .settings-row(data-ng-show=`${model}.cacheMode === 
'PARTITIONED'`)
+                .pc-form-grid-col-30(ng-is=`${model}.cacheMode === 
'PARTITIONED'`)
                     +number('Backups:', `${model}.backups`, '"backups"', 
'true', '0', '0', 'Number of nodes used to back up single partition for 
partitioned cache')
-                .settings-row(data-ng-show=`${model}.cacheMode === 
'PARTITIONED' && ${model}.backups`)
-                    +checkbox('Read from backup', `${model}.readFromBackup`, 
'"readFromBackup"',
-                        'Flag indicating whether data can be read from 
backup<br/>\
-                        If not set then always get data from primary node 
(never from backup)')
                 //- Since ignite 2.0
-                .settings-row(ng-if='$ctrl.available("2.0.0")')
+                .pc-form-grid-col-30(ng-if='$ctrl.available("2.0.0")')
                     +dropdown('Partition loss policy:', 
`${model}.partitionLossPolicy`, '"partitionLossPolicy"', 'true', 'IGNORE',
                     '[\
                         {value: "READ_ONLY_SAFE", label: "READ_ONLY_SAFE"},\
@@ -88,13 +100,18 @@ include /app/helpers/jade/mixins
                             The result of reading from a previously lost and 
not cleared partition is undefined and may be different\
                             on different nodes in the cluster.</li>\
                     </ul>')
-                .settings-row
+                .pc-form-grid-col-60(ng-show=`${model}.cacheMode === 
'PARTITIONED' && ${model}.backups`)
+                    +checkbox('Read from backup', `${model}.readFromBackup`, 
'"readFromBackup"',
+                        'Flag indicating whether data can be read from 
backup<br/>\
+                        If not set then always get data from primary node 
(never from backup)')
+                .pc-form-grid-col-60
                     +checkbox('Copy on read', `${model}.copyOnRead`, 
'"copyOnRead"',
                         'Flag indicating whether copy of the value stored in 
cache should be created for cache operation implying return value<br/>\
                         Also if this flag is set copies are created for values 
passed to CacheInterceptor and to CacheEntryProcessor')
-                .settings-row(ng-show=`${model}.cacheMode === 'PARTITIONED' && 
${model}.atomicityMode === 'TRANSACTIONAL'`)
-                    +checkbox('Invalidate near cache', `${model}.invalidate`, 
'"invalidate"',
+                .pc-form-grid-col-60(ng-show=`${model}.cacheMode === 
'PARTITIONED' && ${model}.atomicityMode === 'TRANSACTIONAL'`)
+                    +checkbox('Invalidate near cache', 
`${model}.isInvalidate`, '"isInvalidate"',
                         'Invalidation flag for near cache entries in 
transaction<br/>\
                         If set then values will be invalidated (nullified) 
upon commit in near cache')
-            .col-sm-6
+
+            .pca-form-column-6
                 +preview-xml-java(model, 'cacheGeneral')

http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration/caches/memory.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration/caches/memory.pug
 
b/modules/web-console/frontend/app/modules/states/configuration/caches/memory.pug
index e00f2a6..bcb8cda 100644
--- 
a/modules/web-console/frontend/app/modules/states/configuration/caches/memory.pug
+++ 
b/modules/web-console/frontend/app/modules/states/configuration/caches/memory.pug
@@ -17,120 +17,145 @@
 include /app/helpers/jade/mixins
 
 -var form = 'memory'
--var model = 'backupItem'
+-var model = '$ctrl.clonedCache'
 
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+.pca-panel(ng-form=form novalidate)
+    .pca-panel-heading(bs-collapse-toggle='' 
ng-click=`ui.loadPanel('${form}')`)
         ignite-form-panel-chevron
-        label Memory
-        ignite-form-field-tooltip.tipLabel(ng-show='$ctrl.available(["1.0.0", 
"2.0.0"])')
-            | Cache memory settings#[br]
-            | 
#[a(href="https://apacheignite.readme.io/v1.9/docs/off-heap-memory"; 
target="_blank") More info]
-        ignite-form-field-tooltip.tipLabel(ng-show='$ctrl.available("2.0.0")')
-            | Cache memory settings#[br]
-            | #[a(href="https://apacheignite.readme.io/docs/evictions"; 
target="_blank") More info]
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
-        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
-            .col-sm-6
+        .pca-panel-heading-title Memory
+        .pca-panel-heading-description
+            | Cache memory settings. 
+            a.link-success(
+                href="https://apacheignite.readme.io/v1.9/docs/off-heap-memory";
+                target="_blank"
+                ng-show='$ctrl.available(["1.0.0", "2.0.0"])'
+            ) More info
+            a.link-success(
+                href="https://apacheignite.readme.io/docs/evictions";
+                target="_blank"
+                ng-show='$ctrl.available("2.0.0")'
+            ) More info
+    .pca-panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .pca-panel-body.pca-form-row(ng-if=`ui.isPanelLoaded('${form}')`)
+            .pca-form-column-6.pc-form-grid-row
                 //- Since ignite 2.0
-                .settings-row(ng-if='$ctrl.available("2.0.0")')
-                        +checkbox('Onheap cache enabled', model + 
'.onheapCacheEnabled', '"OnheapCacheEnabled"', 'Checks if the on-heap cache is 
enabled for the off-heap based page memory')
+                .pc-form-grid-col-60(ng-if='$ctrl.available("2.0.0")')
+                    +checkbox('Onheap cache enabled', model + 
'.onheapCacheEnabled', '"OnheapCacheEnabled"', 'Checks if the on-heap cache is 
enabled for the off-heap based page memory')
 
                 //- Since ignite 2.0 deprecated in ignite 2.3
-                .settings-row(ng-if='$ctrl.available(["2.0.0", "2.3.0"])')
+                .pc-form-grid-col-60(ng-if='$ctrl.available(["2.0.0", 
"2.3.0"])')
                     +text('Memory policy name:', model + '.memoryPolicyName', 
'"MemoryPolicyName"', 'false', 'default',
                         'Name of memory policy configuration for this cache')
 
                 //- Since ignite 2.3
-                .settings-row(ng-if='$ctrl.available("2.3.0")')
+                .pc-form-grid-col-60(ng-if='$ctrl.available("2.3.0")')
                     +text('Data region name:', model + '.dataRegionName', 
'"DataRegionName"', 'false', 'default',
                         'Name of data region configuration for this cache')
 
                 //- Removed in ignite 2.0
-                div(ng-if='$ctrl.available(["1.0.0", "2.0.0"])')
-                    .settings-row
-                        +dropdown('Mode:', `${model}.memoryMode`, 
'"memoryMode"', 'true', 'ONHEAP_TIERED',
-                            '[\
-                                {value: "ONHEAP_TIERED", label: 
"ONHEAP_TIERED"},\
-                                {value: "OFFHEAP_TIERED", label: 
"OFFHEAP_TIERED"},\
-                                {value: "OFFHEAP_VALUES", label: 
"OFFHEAP_VALUES"}\
-                            ]',
-                            'Memory modes control whether value is stored in 
on-heap memory, off-heap memory, or swap space\
-                            <ul>\
-                                <li>\
-                                    ONHEAP_TIERED - entries are cached on heap 
memory first<br/>\
-                                    <ul>\
-                                        <li>\
-                                            If offheap memory is enabled and 
eviction policy evicts an entry from heap memory, entry will be moved to 
offheap memory<br/>\
-                                            If offheap memory is disabled, 
then entry is simply discarded\
-                                        </li>\
-                                        <li>\
-                                            If swap space is enabled and 
offheap memory fills up, then entry will be evicted into swap space<br/>\
-                                            If swap space is disabled, then 
entry will be discarded. If swap is enabled and offheap memory is disabled, 
then entry will be evicted directly from heap memory into swap\
-                                        </li>\
-                                    </ul>\
-                                </li>\
-                                <li>\
-                                    OFFHEAP_TIERED - works the same as 
ONHEAP_TIERED, except that entries never end up in heap memory and get stored 
in offheap memory right away<br/>\
-                                    Entries get cached in offheap memory first 
and then get evicted to swap, if one is configured\
-                                </li>\
-                                <li>\
-                                    OFFHEAP_VALUES - entry keys will be stored 
on heap memory, and values will be stored in offheap memory<br/>\
-                                    Note that in this mode entries can be 
evicted only to swap\
-                                </li>\
-                            </ul>')
-                    .settings-row(ng-show=`${model}.memoryMode !== 
'OFFHEAP_VALUES'`)
-                        +dropdown-required('Off-heap memory:', 
`${model}.offHeapMode`, '"offHeapMode"', 'true', `${model}.memoryMode === 
'OFFHEAP_TIERED'`,
-                            'Disabled',
-                            '[\
-                                {value: -1, label: "Disabled"},\
-                                {value: 1, label: "Limited"},\
-                                {value: 0, label: "Unlimited"}\
-                            ]',
-                            'Off-heap storage mode\
-                            <ul>\
-                                <li>Disabled - Off-heap storage is 
disabled</li>\
-                                <li>Limited - Off-heap storage has limited 
size</li>\
-                                <li>Unlimited - Off-heap storage grow 
infinitely (it is up to user to properly add and remove entries from cache to 
ensure that off-heap storage does not grow infinitely)</li>\
-                            </ul>')
-                    .settings-row(ng-if=`${model}.offHeapMode === 1 && 
${model}.memoryMode !== 'OFFHEAP_VALUES'`)
-                        +number-required('Off-heap memory max size:', 
`${model}.offHeapMaxMemory`, '"offHeapMaxMemory"', 'true',
-                            `${model}.offHeapMode === 1`, 'Enter off-heap 
memory size', '1',
-                            'Maximum amount of memory available to off-heap 
storage in bytes')
-
-                .settings-row
-                    -var onHeapTired = model + '.memoryMode === 
"ONHEAP_TIERED"'
-                    -var swapEnabled = model + '.swapEnabled'
-                    -var offHeapMaxMemory = model + '.offHeapMaxMemory'
-
-                    +evictionPolicy(`${model}.evictionPolicy`, 
'"evictionPolicy"', 'true',
-                        onHeapTired  + ' && (' + swapEnabled + '|| 
_.isNumber(' + offHeapMaxMemory + ') &&' + offHeapMaxMemory + ' >= 0)',
-                        'Optional cache eviction policy<br/>\
-                        Must be set for entries to be evicted from on-heap to 
off-heap or swap\
-                        <ul>\
-                            <li>Least Recently Used(LRU) - Eviction policy 
based on LRU algorithm and supports batch eviction</li>\
-                            <li>First In First Out (FIFO) - Eviction policy 
based on FIFO algorithm and supports batch eviction</li>\
-                            <li>SORTED - Eviction policy which will select the 
minimum cache entry for eviction</li>\
-                        </ul>')
+                .pc-form-grid-col-60(ng-if-start='$ctrl.available(["1.0.0", 
"2.0.0"])')
+                    +sane-ignite-form-field-dropdown({
+                        label: 'Mode:',
+                        model: `${model}.memoryMode`,
+                        name: '"memoryMode"',
+                        placeholder: '{{ ::$ctrl.Caches.memoryMode.default }}',
+                        options: '::$ctrl.Caches.memoryModes',
+                        tip: `Memory modes control whether value is stored in 
on-heap memory, off-heap memory, or swap space
+                        <ul>
+                            <li>
+                                ONHEAP_TIERED - entries are cached on heap 
memory first<br/>
+                                <ul>
+                                    <li>
+                                        If offheap memory is enabled and 
eviction policy evicts an entry from heap memory, entry will be moved to 
offheap memory<br/>
+                                        If offheap memory is disabled, then 
entry is simply discarded
+                                    </li>
+                                    <li>
+                                        If swap space is enabled and offheap 
memory fills up, then entry will be evicted into swap space<br/>
+                                        If swap space is disabled, then entry 
will be discarded. If swap is enabled and offheap memory is disabled, then 
entry will be evicted directly from heap memory into swap
+                                    </li>
+                                </ul>
+                            </li>
+                            <li>
+                                OFFHEAP_TIERED - works the same as 
ONHEAP_TIERED, except that entries never end up in heap memory and get stored 
in offheap memory right away<br/>
+                                Entries get cached in offheap memory first and 
then get evicted to swap, if one is configured
+                            </li>
+                            <li>
+                                OFFHEAP_VALUES - entry keys will be stored on 
heap memory, and values will be stored in offheap memory<br/>
+                                Note that in this mode entries can be evicted 
only to swap
+                            </li>
+                        </ul>`
+                    })(
+                        ui-validate=`{
+                            offheapAndDomains: 
'$ctrl.Caches.memoryMode.offheapAndDomains(${model})'
+                        }`
+                        ui-validate-watch=`"${model}.domains.length"`
+                        ng-model-options='{allowInvalid: true}'
+                    )
+                        +form-field-feedback(null, 'offheapAndDomains', 'Query 
indexing could not be enabled while values are stored off-heap')
+                .pc-form-grid-col-60(ng-if=`${model}.memoryMode !== 
'OFFHEAP_VALUES'`)
+                    +sane-ignite-form-field-dropdown({
+                        label: 'Off-heap memory:',
+                        model: `${model}.offHeapMode`,
+                        name: '"offHeapMode"',
+                        required: 
`$ctrl.Caches.offHeapMode.required(${model})`,
+                        placeholder: '{{::$ctrl.Caches.offHeapMode.default}}',
+                        options: '{{::$ctrl.Caches.offHeapModes}}',
+                        tip: `Off-heap storage mode
+                        <ul>
+                            <li>Disabled - Off-heap storage is disabled</li>
+                            <li>Limited - Off-heap storage has limited 
size</li>
+                            <li>Unlimited - Off-heap storage grow infinitely 
(it is up to user to properly add and remove entries from cache to ensure that 
off-heap storage does not grow infinitely)</li>
+                        </ul>`
+                    })(
+                        ng-change=`$ctrl.Caches.offHeapMode.onChange(${model})`
+                        ui-validate=`{
+                            offheapDisabled: 
'$ctrl.Caches.offHeapMode.offheapDisabled(${model})'
+                        }`
+                        ui-validate-watch=`'${model}.memoryMode'`
+                        ng-model-options='{allowInvalid: true}'
+                    )
+                        +form-field-feedback(null, 'offheapDisabled', 
'Off-heap storage can\'t be disabled when memory mode is OFFHEAP_TIERED')
+                .pc-form-grid-col-60(
+                    ng-if=`${model}.offHeapMode === 1 && ${model}.memoryMode 
!== 'OFFHEAP_VALUES'`
+                    ng-if-end
+                )
+                    pc-form-field-size(
+                        label='Off-heap memory max size:'
+                        ng-model=`${model}.offHeapMaxMemory`
+                        name='offHeapMaxMemory'
+                        placeholder='Enter off-heap memory size'
+                        min='{{ ::$ctrl.Caches.offHeapMaxMemory.min }}'
+                        tip='Maximum amount of memory available to off-heap 
storage'
+                        size-scale-label='mb'
+                        size-type='bytes'
+                        required='true'
+                    )
+                +evictionPolicy(`${model}.evictionPolicy`, '"evictionPolicy"', 
'true',
+                    `$ctrl.Caches.evictionPolicy.required(${model})`,
+                    'Optional cache eviction policy<br/>\
+                    Must be set for entries to be evicted from on-heap to 
off-heap or swap\
+                    <ul>\
+                        <li>Least Recently Used(LRU) - Eviction policy based 
on LRU algorithm and supports batch eviction</li>\
+                        <li>First In First Out (FIFO) - Eviction policy based 
on FIFO algorithm and supports batch eviction</li>\
+                        <li>SORTED - Eviction policy which will select the 
minimum cache entry for eviction</li>\
+                    </ul>')
 
                 //- Since ignite 2.0
-                .settings-row(ng-if='$ctrl.available("2.0.0")')
+                .pc-form-grid-col-60(ng-if='$ctrl.available("2.0.0")')
                     +java-class('Eviction filter:', model + '.evictionFilter', 
'"EvictionFilter"', 'true', 'false', 'Eviction filter to specify which entries 
should not be evicted')
 
                 //- Removed in ignite 2.0
-                div(ng-if='$ctrl.available(["1.0.0", "2.0.0"])')
-                    .settings-row
-                        +number('Start size:', `${model}.startSize`, 
'"startSize"', 'true', '1500000', '0',
-                            'In terms of size and capacity, Ignite internal 
cache map acts exactly like a normal Java HashMap: it has some initial capacity\
-                            (which is pretty small by default), which doubles 
as data arrives. The process of internal cache map resizing is CPU-intensive\
-                            and time-consuming, and if you load a huge dataset 
into cache (which is a normal use case), the map will have to resize a lot of 
times.\
-                            To avoid that, you can specify the initial cache 
map capacity, comparable to the expected size of your dataset.\
-                            This will save a lot of CPU resources during the 
load time, because the map would not have to resize.\
-                            For example, if you expect to load 10 million 
entries into cache, you can set this property to 10 000 000.\
-                            This will save you from cache internal map 
resizes.')
-                    .settings-row
-                        +checkbox('Swap enabled', `${model}.swapEnabled`, 
'"swapEnabled"', 'Flag indicating whether swap storage is enabled or not for 
this cache')
+                .pc-form-grid-col-60(ng-if-start='$ctrl.available(["1.0.0", 
"2.0.0"])')
+                    +number('Start size:', `${model}.startSize`, 
'"startSize"', 'true', '1500000', '0',
+                        'In terms of size and capacity, Ignite internal cache 
map acts exactly like a normal Java HashMap: it has some initial capacity\
+                        (which is pretty small by default), which doubles as 
data arrives. The process of internal cache map resizing is CPU-intensive\
+                        and time-consuming, and if you load a huge dataset 
into cache (which is a normal use case), the map will have to resize a lot of 
times.\
+                        To avoid that, you can specify the initial cache map 
capacity, comparable to the expected size of your dataset.\
+                        This will save a lot of CPU resources during the load 
time, because the map would not have to resize.\
+                        For example, if you expect to load 10 million entries 
into cache, you can set this property to 10 000 000.\
+                        This will save you from cache internal map resizes.')
+                .pc-form-grid-col-60(ng-if-end)
+                    +checkbox('Swap enabled', `${model}.swapEnabled`, 
'"swapEnabled"', 'Flag indicating whether swap storage is enabled or not for 
this cache')
 
-            .col-sm-6
+            .pca-form-column-6
                 +preview-xml-java(model, 'cacheMemory')

http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-client.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-client.pug
 
b/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-client.pug
index aeae30d..ff51361 100644
--- 
a/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-client.pug
+++ 
b/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-client.pug
@@ -17,35 +17,33 @@
 include /app/helpers/jade/mixins
 
 -var form = 'clientNearCache'
--var model = 'backupItem'
+-var model = '$ctrl.clonedCache'
 
-.panel.panel-default(ng-form=form novalidate ng-show=`${model}.cacheMode === 
'PARTITIONED'`)
-    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+.pca-panel(ng-form=form novalidate ng-show=`${model}.cacheMode === 
'PARTITIONED'`)
+    .pca-panel-heading(bs-collapse-toggle='' 
ng-click=`ui.loadPanel('${form}')`)
         ignite-form-panel-chevron
-        label Near cache on client node
-        ignite-form-field-tooltip.tipLabel
-            | Near cache settings for client nodes#[br]
-            | Near cache is a small local cache that stores most recently or 
most frequently accessed data#[br]
-            | Should be used in case when it is impossible to send 
computations to remote nodes
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
-        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
-            .col-sm-6
+        .pca-panel-heading-title Near cache on client node
+        .pca-panel-heading-description
+            | Near cache settings for client nodes. 
+            | Near cache is a small local cache that stores most recently or 
most frequently accessed data. 
+            | Should be used in case when it is impossible to send 
computations to remote nodes.
+    .pca-panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .pca-panel-body.pca-form-row(ng-if=`ui.isPanelLoaded('${form}')`)
+            .pca-form-column-6.pc-form-grid-row
                 -var nearCfg = `${model}.clientNearConfiguration`
                 -var enabled = `${nearCfg}.enabled`
 
-                .settings-row
+                .pc-form-grid-col-60
                     +checkbox('Enabled', enabled, '"clientNearEnabled"', 'Flag 
indicating whether to configure near cache')
-                .settings-row
+                .pc-form-grid-col-60
                     +number('Start size:', `${nearCfg}.nearStartSize`, 
'"clientNearStartSize"', enabled, '375000', '0',
                         'Initial cache size for near cache which will be used 
to pre-create internal hash table after start')
-                .settings-row
-                    +evictionPolicy(`${nearCfg}.nearEvictionPolicy`, 
'"clientNearCacheEvictionPolicy"', enabled, 'false',
-                        'Near cache eviction policy\
-                        <ul>\
-                            <li>Least Recently Used (LRU) - Eviction policy 
based on LRU algorithm and supports batch eviction</li>\
-                            <li>First In First Out (FIFO) - Eviction policy 
based on FIFO algorithm and supports batch eviction</li>\
-                            <li>SORTED - Eviction policy which will select the 
minimum cache entry for eviction</li>\
-                        </ul>')
-            .col-sm-6
+                +evictionPolicy(`${nearCfg}.nearEvictionPolicy`, 
'"clientNearCacheEvictionPolicy"', enabled, 'false',
+                    'Near cache eviction policy\
+                    <ul>\
+                        <li>Least Recently Used (LRU) - Eviction policy based 
on LRU algorithm and supports batch eviction</li>\
+                        <li>First In First Out (FIFO) - Eviction policy based 
on FIFO algorithm and supports batch eviction</li>\
+                        <li>SORTED - Eviction policy which will select the 
minimum cache entry for eviction</li>\
+                    </ul>')
+            .pca-form-column-6
                 +preview-xml-java(model, 'cacheNearClient')

http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-server.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-server.pug
 
b/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-server.pug
index 2efe43a..40f7024 100644
--- 
a/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-server.pug
+++ 
b/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-server.pug
@@ -17,36 +17,34 @@
 include /app/helpers/jade/mixins
 
 -var form = 'serverNearCache'
--var model = 'backupItem'
+-var model = '$ctrl.clonedCache'
 
-.panel.panel-default(ng-form=form novalidate ng-show=`${model}.cacheMode === 
'PARTITIONED'`)
-    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+.pca-panel(ng-form=form novalidate ng-show=`${model}.cacheMode === 
'PARTITIONED'`)
+    .pca-panel-heading(bs-collapse-toggle='' 
ng-click=`ui.loadPanel('${form}')`)
         ignite-form-panel-chevron
-        label Near cache on server node
-        ignite-form-field-tooltip.tipLabel
-            | Near cache settings#[br]
-            | Near cache is a small local cache that stores most recently or 
most frequently accessed data#[br]
-            | Should be used in case when it is impossible to send 
computations to remote nodes#[br]
-            | #[a(href="https://apacheignite.readme.io/docs/near-caches"; 
target="_blank") More info]
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
-        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
-            .col-sm-6
+        .pca-panel-heading-title Near cache on server node
+        .pca-panel-heading-description
+            | Near cache settings. 
+            | Near cache is a small local cache that stores most recently or 
most frequently accessed data. 
+            | Should be used in case when it is impossible to send 
computations to remote nodes. 
+            
a.link-success(href="https://apacheignite.readme.io/docs/near-caches"; 
target="_blank") More info
+    .pca-panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .pca-panel-body.pca-form-row(ng-if=`ui.isPanelLoaded('${form}')`)
+            .pca-form-column-6.pc-form-grid-row
                 -var nearCfg = `${model}.nearConfiguration`
                 -var enabled = `${nearCfg}.enabled`
 
-                .settings-row
+                .pc-form-grid-col-60
                     +checkbox('Enabled', enabled, '"nearCacheEnabled"', 'Flag 
indicating whether to configure near cache')
-                .settings-row
+                .pc-form-grid-col-60
                     +number('Start size:', `${nearCfg}.nearStartSize`, 
'"nearStartSize"', enabled, '375000', '0',
                         'Initial cache size for near cache which will be used 
to pre-create internal hash table after start')
-                .settings-row
-                    
+evictionPolicy(`${model}.nearConfiguration.nearEvictionPolicy`, 
'"nearCacheEvictionPolicy"', enabled, 'false',
-                        'Near cache eviction policy\
-                        <ul>\
-                            <li>Least Recently Used (LRU) - Eviction policy 
based on LRU algorithm and supports batch eviction</li>\
-                            <li>First In First Out (FIFO) - Eviction policy 
based on FIFO algorithm and supports batch eviction</li>\
-                            <li>SORTED - Eviction policy which will select the 
minimum cache entry for eviction</li>\
-                        </ul>')
-            .col-sm-6
+                
+evictionPolicy(`${model}.nearConfiguration.nearEvictionPolicy`, 
'"nearCacheEvictionPolicy"', enabled, 'false',
+                    'Near cache eviction policy\
+                    <ul>\
+                        <li>Least Recently Used (LRU) - Eviction policy based 
on LRU algorithm and supports batch eviction</li>\
+                        <li>First In First Out (FIFO) - Eviction policy based 
on FIFO algorithm and supports batch eviction</li>\
+                        <li>SORTED - Eviction policy which will select the 
minimum cache entry for eviction</li>\
+                    </ul>')
+            .pca-form-column-6
                 +preview-xml-java(model, 'cacheNearServer')

http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration/caches/node-filter.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration/caches/node-filter.pug
 
b/modules/web-console/frontend/app/modules/states/configuration/caches/node-filter.pug
index e184941..c40ea59 100644
--- 
a/modules/web-console/frontend/app/modules/states/configuration/caches/node-filter.pug
+++ 
b/modules/web-console/frontend/app/modules/states/configuration/caches/node-filter.pug
@@ -17,36 +17,41 @@
 include /app/helpers/jade/mixins
 
 -var form = 'nodeFilter'
--var model = 'backupItem'
+-var model = '$ctrl.clonedCache'
 -var nodeFilter = model + '.nodeFilter';
 -var nodeFilterKind = nodeFilter + '.kind';
 -var igfsFilter = nodeFilterKind + ' === "IGFS"'
 -var customFilter = nodeFilterKind + ' === "Custom"'
 
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+.pca-panel(ng-form=form novalidate)
+    .pca-panel-heading(bs-collapse-toggle='' 
ng-click=`ui.loadPanel('${form}')`)
         ignite-form-panel-chevron
-        label(id='nodeFilter-title') Node filter
-        ignite-form-field-tooltip.tipLabel
-            | Determines on what nodes the cache should be started
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
-        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
-            .col-sm-6
-                .settings-row
-                    +dropdown('Node filter:', nodeFilterKind, '"nodeFilter"', 
'true', 'Not set',
-                        '[\
-                            {value: "IGFS", label: "IGFS nodes"},\
-                            {value: "Custom", label: "Custom"},\
-                            {value: null, label: "Not set"}\
-                        ]',
-                        'Node filter variant'
+        .pca-panel-heading-title(id='nodeFilter-title') Node filter
+        .pca-panel-heading-description
+            | Determines on what nodes the cache should be started.
+    .pca-panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .pca-panel-body.pca-form-row(ng-if=`ui.isPanelLoaded('${form}')`)
+            .pca-form-column-6.pc-form-grid-row
+                .pc-form-grid-col-60
+                    +dropdown('Node filter:', nodeFilterKind, '"nodeFilter"', 
'true', 'Not set', '::$ctrl.Caches.nodeFilterKinds', 'Node filter variant')
+                .pc-form-grid-col-60(
+                    ng-if=igfsFilter
+                )
+                    +sane-ignite-form-field-dropdown({
+                        label: 'IGFS:',
+                        model: `${nodeFilter}.IGFS.igfs`,
+                        name: '"igfsNodeFilter"',
+                        required: true,
+                        placeholder: 'Choose IGFS',
+                        placeholderEmpty: 'No IGFS configured',
+                        options: '$ctrl.igfssMenu',
+                        tip: 'Select IGFS to filter nodes'
+                    })(
+                        pc-is-in-collection='$ctrl.igfsIDs'
                     )
-                .settings-row(ng-show=igfsFilter)
-                    +dropdown-required-empty('IGFS:', 
`${nodeFilter}.IGFS.igfs`, '"igfsNodeFilter"', 'true', igfsFilter,
-                        'Choose IGFS', 'No IGFS configured', 'igfss', 'Select 
IGFS to filter nodes')
-                .settings-row(ng-show=customFilter)
+                        +form-field-feedback(_, 'isInCollection', `Cluster 
doesn't have such an IGFS`)
+                .pc-form-grid-col-60(ng-show=customFilter)
                     +java-class('Class name:', 
`${nodeFilter}.Custom.className`, '"customNodeFilter"',
                         'true', customFilter, 'Class name of custom node 
filter implementation', customFilter)
-            .col-sm-6
+            .pca-form-column-6
                 +preview-xml-java(model, 'cacheNodeFilter', 'igfss')

http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration/caches/query.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration/caches/query.pug
 
b/modules/web-console/frontend/app/modules/states/configuration/caches/query.pug
index 46f2cc7..471b011 100644
--- 
a/modules/web-console/frontend/app/modules/states/configuration/caches/query.pug
+++ 
b/modules/web-console/frontend/app/modules/states/configuration/caches/query.pug
@@ -17,20 +17,19 @@
 include /app/helpers/jade/mixins
 
 -var form = 'query'
--var model = 'backupItem'
+-var model = '$ctrl.clonedCache'
 
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+.pca-panel(ng-form=form novalidate)
+    .pca-panel-heading(bs-collapse-toggle='' 
ng-click=`ui.loadPanel('${form}')`)
         ignite-form-panel-chevron
-        label Queries & Indexing
-        ignite-form-field-tooltip.tipLabel
-            | Cache queries settings#[br]
-            | #[a(href="https://apacheignite-sql.readme.io/docs/select"; 
target="_blank") More info]
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
-        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
-            .col-sm-6
-                .settings-row
+        .pca-panel-heading-title Queries & Indexing
+        .pca-panel-heading-description
+            | Cache queries settings. 
+            
a.link-success(href="https://apacheignite-sql.readme.io/docs/select"; 
target="_blank") More info
+    .pca-panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .pca-panel-body.pca-form-row(ng-if=`ui.isPanelLoaded('${form}')`)
+            .pca-form-column-6.pc-form-grid-row
+                .pc-form-grid-col-60
                     +text('SQL schema name:', `${model}.sqlSchema`, 
'"sqlSchema"', 'false', 'Input schema name',
                         'Specify any custom name to be used as SQL schema for 
current cache. This name will correspond to SQL ANSI-99 standard.\
                         Nonquoted identifiers are not case sensitive. Quoted 
identifiers are case sensitive.\
@@ -48,84 +47,71 @@ include /app/helpers/jade/mixins
                         </ul>')
 
                 //- Removed in ignite 2.0
-                .settings-row(ng-if='$ctrl.available(["1.0.0", "2.0.0"])')
+                .pc-form-grid-col-60(ng-if='$ctrl.available(["1.0.0", 
"2.0.0"])')
                     +number('On-heap cache for off-heap indexes:', 
`${model}.sqlOnheapRowCacheSize`, '"sqlOnheapRowCacheSize"', 'true', '10240', 
'1',
                         'Number of SQL rows which will be cached onheap to 
avoid deserialization on each SQL index access')
 
                 //- Deprecated in ignite 2.1
-                .settings-row(ng-if='$ctrl.available(["1.0.0", "2.1.0"])')
+                .pc-form-grid-col-60(ng-if='$ctrl.available(["1.0.0", 
"2.1.0"])')
                     +number('Long query timeout:', 
`${model}.longQueryWarningTimeout`, '"longQueryWarningTimeout"', 'true', 
'3000', '0',
                         'Timeout in milliseconds after which long query 
warning will be printed')
-                .settings-row
+                .pc-form-grid-col-60
                     +number('History size:', 
`${model}.queryDetailMetricsSize`, '"queryDetailMetricsSize"', 'true', '0', '0',
                         'Size of queries detail metrics that will be stored in 
memory for monitoring purposes')
-                .settings-row
-                    -var form = 'querySqlFunctionClasses';
-                    -var sqlFunctionClasses = `${model}.sqlFunctionClasses`;
-
-                    +ignite-form-group(ng-form=form 
ng-model=`${sqlFunctionClasses}`)
-                        ignite-form-field-label
-                            | SQL functions
-                        ignite-form-group-tooltip
-                            | Collections of classes with user-defined 
functions for SQL queries
-                        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 model = 'obj.model';
-                            -var name = '"edit" + $index'
-                            -var valid = `${form}[${name}].$valid`
-                            -var save = `${sqlFunctionClasses}[$index] = 
${model}`
-
-                            div(ng-repeat=`model in ${sqlFunctionClasses} 
track by $index` ng-init='obj = {}')
-                                label.col-xs-12.col-sm-12.col-md-12
-                                    .indexField
-                                        | {{ $index+1 }})
-                                    +table-remove-button(sqlFunctionClasses, 
'Remove user-defined function')
-
-                                    span(ng-hide='field.edit')
-                                        a.labelFormField(ng-click=`field.edit 
= true; ${model} = model;`) {{ model }}
-                                    span(ng-if='field.edit')
-                                        +table-java-class-field('SQL 
function', name, model, sqlFunctionClasses, valid, save, false)
-                                            +table-save-button(valid, save, 
false)
-                                            +unique-feedback(name, uniqueTip)
-
-                        .group-content(ng-repeat='field in group.add')
-                            -var model = 'new';
-                            -var name = '"new"'
-                            -var valid = `${form}[${name}].$valid`
-                            -var save = `${sqlFunctionClasses}.push(${model})`
-
-                            div
-                                label.col-xs-12.col-sm-12.col-md-12
-                                    +table-java-class-field('SQL function', 
name, model, sqlFunctionClasses, valid, save, true)
-                                        +table-save-button(valid, save, true)
-                                        +unique-feedback(name, uniqueTip)
-
-                        
.group-content-empty(ng-if=`!(${sqlFunctionClasses}.length) && 
!group.add.length`)
-                            | Not defined
+                .pc-form-grid-col-60
+                    mixin caches-query-list-sql-functions()
+                        .ignite-form-field
+                            -let items = `${model}.sqlFunctionClasses`;
+                            -let uniqueTip = 'SQL function with such class 
name already exists!'
+
+                            list-editable(
+                                ng-model=items
+                                list-editable-cols=`::[{
+                                    name: 'SQL functions:',
+                                    tip: 'Collections of classes with 
user-defined functions for SQL queries'
+                                }]`
+                            )
+                                list-editable-item-view {{ $item }}
+
+                                list-editable-item-edit
+                                    +list-java-class-field('SQL function', 
'$item', '"sqlFunction"', items)
+                                        +unique-feedback('"sqlFunction"', 
uniqueTip)
+
+                                list-editable-no-items
+                                    list-editable-add-item-button(
+                                        add-item=`$editLast((${items} = 
${items} || []).push(""))`
+                                        label-single='SQL function'
+                                        label-multiple='SQL functions'
+                                    )
+
+                    - var form = '$parent.form'
+                    +caches-query-list-sql-functions
+                    - var form = 'query'
 
                 //- Removed in ignite 2.0
-                .settings-row(ng-if='$ctrl.available(["1.0.0", "2.0.0"])')
+                .pc-form-grid-col-60(ng-if='$ctrl.available(["1.0.0", 
"2.0.0"])')
                     +checkbox('Snapshotable index', 
`${model}.snapshotableIndex`, '"snapshotableIndex"',
                         'Flag indicating whether SQL indexes should support 
snapshots')
 
-                .settings-row
+                .pc-form-grid-col-60
                     +checkbox('Escape table and filed names', 
`${model}.sqlEscapeAll`, '"sqlEscapeAll"',
                         'If enabled than all schema, table and field names 
will be escaped with double quotes (for example: "tableName"."fieldName").<br/>\
                         This enforces case sensitivity for field names and 
also allows having special characters in table and field names.<br/>\
                         Escaped names will be used for creation internal 
structures in Ignite SQL engine.')
 
                 //- Since ignite 2.0
-                div(ng-if='$ctrl.available("2.0.0")')
-                    .settings-row
-                        +number('Query parallelism', model + 
'.queryParallelism', '"queryParallelism"', 'true', '1', '1',
-                            'A hint to query execution engine on desired 
degree of parallelism within a single node')
-                    .settings-row
-                        +number('SQL index max inline size:', model + 
'.sqlIndexMaxInlineSize', '"sqlIndexMaxInlineSize"', 'true', '-1', '-1',
-                            'Maximum inline size for sql indexes')
-
-            .col-sm-6
+                .pc-form-grid-col-30(ng-if-start='$ctrl.available("2.0.0")')
+                    +number('Query parallelism', model + '.queryParallelism', 
'"queryParallelism"', 'true', '1', '1',
+                        'A hint to query execution engine on desired degree of 
parallelism within a single node')
+                .pc-form-grid-col-30(ng-if-end)
+                    +sane-ignite-form-field-number({
+                        label: 'SQL index max inline size:',
+                        model: `${model}.sqlIndexMaxInlineSize`,
+                        name: '"sqlIndexMaxInlineSize"',
+                        placeholder: '-1',
+                        min: '-1',
+                        tip: 'Maximum inline size for sql indexes'
+                    })
+
+            .pca-form-column-6
                 +preview-xml-java(model, 'cacheQuery', 'domains')

http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/modules/states/configuration/caches/rebalance.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/modules/states/configuration/caches/rebalance.pug
 
b/modules/web-console/frontend/app/modules/states/configuration/caches/rebalance.pug
index 9850d17..79ed803e 100644
--- 
a/modules/web-console/frontend/app/modules/states/configuration/caches/rebalance.pug
+++ 
b/modules/web-console/frontend/app/modules/states/configuration/caches/rebalance.pug
@@ -17,20 +17,19 @@
 include /app/helpers/jade/mixins
 
 -var form = 'rebalance'
--var model = 'backupItem'
+-var model = '$ctrl.clonedCache'
 
-.panel.panel-default(ng-form=form novalidate ng-hide=`${model}.cacheMode === 
"LOCAL"`)
-    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+.pca-panel(ng-form=form novalidate ng-hide=`${model}.cacheMode === "LOCAL"`)
+    .pca-panel-heading(bs-collapse-toggle='' 
ng-click=`ui.loadPanel('${form}')`)
         ignite-form-panel-chevron
-        label Rebalance
-        ignite-form-field-tooltip.tipLabel
-            | Cache rebalance settings#[br]
-            | #[a(href="https://apacheignite.readme.io/docs/rebalancing"; 
target="_blank") More info]
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
-        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
-            .col-sm-6
-                .settings-row
+        .pca-panel-heading-title Rebalance
+        .pca-panel-heading-description
+            | Cache rebalance settings. 
+            
a.link-success(href="https://apacheignite.readme.io/docs/rebalancing"; 
target="_blank") More info
+    .pca-panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .pca-panel-body.pca-form-row(ng-if=`ui.isPanelLoaded('${form}')`)
+            .pca-form-column-6.pc-form-grid-row
+                .pc-form-grid-col-30
                     +dropdown('Mode:', `${model}.rebalanceMode`, 
'"rebalanceMode"', 'true', 'ASYNC',
                         '[\
                             {value: "SYNC", label: "SYNC"},\
@@ -43,24 +42,24 @@ include /app/helpers/jade/mixins
                             <li>Asynchronous - in this mode distributed caches 
will start immediately and will load all necessary data from other available 
grid nodes in the background</li>\
                             <li>None - in this mode no rebalancing will take 
place which means that caches will be either loaded on demand from persistent 
store whenever data is accessed, or will be populated explicitly</li>\
                         </ul>')
-                    .settings-row
-                        +number('Batch size:', `${model}.rebalanceBatchSize`, 
'"rebalanceBatchSize"', 'true', '512 * 1024', '1',
-                            'Size (in bytes) to be loaded within a single 
rebalance message<br/>\
-                            Rebalancing algorithm will split total data set on 
every node into multiple batches prior to sending data')
-                    .settings-row
-                        +number('Batches prefetch count:', 
`${model}.rebalanceBatchesPrefetchCount`, '"rebalanceBatchesPrefetchCount"', 
'true', '2', '1',
-                            'Number of batches generated by supply node at 
rebalancing start')
-                    .settings-row
-                        +number('Order:', `${model}.rebalanceOrder`, 
'"rebalanceOrder"', 'true', '0', Number.MIN_SAFE_INTEGER,
-                            'If cache rebalance order is positive, rebalancing 
for this cache will be started only when rebalancing for all caches with 
smaller rebalance order (except caches with rebalance order 0) will be 
completed')
-                    .settings-row
-                        +number('Delay:', `${model}.rebalanceDelay`, 
'"rebalanceDelay"', 'true', '0', '0',
-                            'Delay in milliseconds upon a node joining or 
leaving topology (or crash) after which rebalancing should be started 
automatically')
-                    .settings-row
-                        +number('Timeout:', `${model}.rebalanceTimeout`, 
'"rebalanceTimeout"', 'true', '10000', '0',
-                            'Rebalance timeout in milliseconds')
-                    .settings-row
-                        +number('Throttle:', `${model}.rebalanceThrottle`, 
'"rebalanceThrottle"', 'true', '0', '0',
-                            'Time in milliseconds to wait between rebalance 
messages to avoid overloading of CPU or network')
-            .col-sm-6
+                .pc-form-grid-col-30
+                    +number('Batch size:', `${model}.rebalanceBatchSize`, 
'"rebalanceBatchSize"', 'true', '512 * 1024', '1',
+                        'Size (in bytes) to be loaded within a single 
rebalance message<br/>\
+                        Rebalancing algorithm will split total data set on 
every node into multiple batches prior to sending data')
+                .pc-form-grid-col-30
+                    +number('Batches prefetch count:', 
`${model}.rebalanceBatchesPrefetchCount`, '"rebalanceBatchesPrefetchCount"', 
'true', '2', '1',
+                        'Number of batches generated by supply node at 
rebalancing start')
+                .pc-form-grid-col-30
+                    +number('Order:', `${model}.rebalanceOrder`, 
'"rebalanceOrder"', 'true', '0', Number.MIN_SAFE_INTEGER,
+                        'If cache rebalance order is positive, rebalancing for 
this cache will be started only when rebalancing for all caches with smaller 
rebalance order (except caches with rebalance order 0) will be completed')
+                .pc-form-grid-col-20
+                    +number('Delay:', `${model}.rebalanceDelay`, 
'"rebalanceDelay"', 'true', '0', '0',
+                        'Delay in milliseconds upon a node joining or leaving 
topology (or crash) after which rebalancing should be started automatically')
+                .pc-form-grid-col-20
+                    +number('Timeout:', `${model}.rebalanceTimeout`, 
'"rebalanceTimeout"', 'true', '10000', '0',
+                        'Rebalance timeout in milliseconds')
+                .pc-form-grid-col-20
+                    +number('Throttle:', `${model}.rebalanceThrottle`, 
'"rebalanceThrottle"', 'true', '0', '0',
+                        'Time in milliseconds to wait between rebalance 
messages to avoid overloading of CPU or network')
+            .pca-form-column-6
                 +preview-xml-java(model, 'cacheRebalance')

Reply via email to