ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From agoncha...@apache.org
Subject [26/34] ignite git commit: IGNITE-5388 Added support to configuration of Ignite 2.x and Ignite 1.x.
Date Mon, 05 Jun 2017 09:06:02 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js
index 5933f6c..6bf1182 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js
+++ b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js
@@ -59,19 +59,20 @@ spec:\n\
 
 // eslint-disable-next-line no-undef
 onmessage = function(e) {
-    const {cluster, data, demo} = e.data;
+    const {cluster, data, demo, targetVer} = e.data;
 
     const zip = new JSZip();
 
     if (!data.docker)
-        data.docker = docker.generate(cluster, 'latest');
+        data.docker = docker.generate(cluster, targetVer);
 
     zip.file('Dockerfile', data.docker);
     zip.file('.dockerignore', docker.ignoreFile());
 
-    const cfg = generator.igniteConfiguration(cluster, false);
-    const clientCfg = generator.igniteConfiguration(cluster, true);
-    const clientNearCaches = _.filter(cluster.caches, (cache) => _.get(cache, 'clientNearConfiguration.enabled'));
+    const cfg = generator.igniteConfiguration(cluster, targetVer.ignite, false);
+    const clientCfg = generator.igniteConfiguration(cluster, targetVer.ignite, true);
+    const clientNearCaches = _.filter(cluster.caches, (cache) =>
+        cache.mode === 'PARTITIONED' && _.get(cache, 'clientNearConfiguration.enabled'));
 
     const secProps = properties.generate(cfg);
 
@@ -118,7 +119,7 @@ onmessage = function(e) {
     zip.file(`${startupPath}/ClientNodeCodeStartup.java`, java.nodeStartup(cluster, 'startup.ClientNodeCodeStartup',
         'ClientConfigurationFactory.createConfiguration()', 'config.ClientConfigurationFactory', clientNearCaches));
 
-    zip.file('pom.xml', maven.generate(cluster));
+    zip.file('pom.xml', maven.generate(cluster, targetVer));
 
     zip.file('README.txt', readme.generate());
     zip.file('jdbc-drivers/README.txt', readme.generateJDBC());

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/app/primitives/btn-group/index.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/btn-group/index.pug b/modules/web-console/frontend/app/primitives/btn-group/index.pug
index c047b25..702da60 100644
--- a/modules/web-console/frontend/app/primitives/btn-group/index.pug
+++ b/modules/web-console/frontend/app/primitives/btn-group/index.pug
@@ -14,19 +14,23 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-mixin btn-group(actions, tip)
+mixin btn-group(disabled, options, tip)
     .btn-group.panel-tip-container&attributes(attributes)
         button.btn.btn-primary(
-            ng-click=`${actions[0].click}`
+            ng-click=`${options[0].click}`
+
+            data-ng-disabled=disabled && `${disabled}`
 
             bs-tooltip=''
             data-title=tip
 
             data-trigger='hover'
             data-placement='bottom'
-        ) #{actions[0].text}
+        ) #{options[0].text}
         button.btn.dropdown-toggle.btn-primary(
-            bs-dropdown=`${JSON.stringify(actions)}`
+            data-ng-disabled=disabled && `${disabled}` || `!${JSON.stringify(options)}.length`
+
+            bs-dropdown=`${JSON.stringify(options)}`
 
             data-toggle='dropdown'
             data-container='body'

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/app/primitives/btn/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/btn/index.scss b/modules/web-console/frontend/app/primitives/btn/index.scss
index e10bef6..bba4ecc 100644
--- a/modules/web-console/frontend/app/primitives/btn/index.scss
+++ b/modules/web-console/frontend/app/primitives/btn/index.scss
@@ -58,6 +58,7 @@
     font-size: 14px;
     line-height: 16px;
     text-decoration: none;
+    cursor: pointer;
 
     .icon {
         &, &-right, &-left {
@@ -82,6 +83,11 @@
         line-height: inherit !important;
         font-size: 16px;
     }
+
+    &[disabled] {
+        -webkit-pointer-events: none;
+        pointer-events: none;
+    }
 }
 
 .btn-ignite--primary {

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/app/primitives/dropdown/index.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/dropdown/index.pug b/modules/web-console/frontend/app/primitives/dropdown/index.pug
index 7015433..3a5f1b1 100644
--- a/modules/web-console/frontend/app/primitives/dropdown/index.pug
+++ b/modules/web-console/frontend/app/primitives/dropdown/index.pug
@@ -16,7 +16,7 @@
 
 mixin ignite-form-field-bsdropdown(label, model, name, disabled, required, options, tip)
     .dropdown--ignite.ignite-form-field
-        button.btn-ignite.btn-ignite--primary-outline(
+        .btn-ignite.btn-ignite--primary-outline(
             data-ng-model=model
 
             data-ng-required=required && `${required}`
@@ -27,7 +27,6 @@ mixin ignite-form-field-bsdropdown(label, model, name, disabled, required, optio
             data-trigger='hover focus'
             data-placement='bottom-right'
             data-container='self'
-            data-animation=''
 
             tabindex='0'
             aria-haspopup='true'

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/app/primitives/dropdown/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/dropdown/index.scss b/modules/web-console/frontend/app/primitives/dropdown/index.scss
index 443324c..a3252cc 100644
--- a/modules/web-console/frontend/app/primitives/dropdown/index.scss
+++ b/modules/web-console/frontend/app/primitives/dropdown/index.scss
@@ -17,10 +17,12 @@
 
 @import '../../../public/stylesheets/variables';
 
-.dropdown--ignite {
+.ignite-form-field {
     font-style: normal;
 
     ul.dropdown-menu {
+        z-index: 1;
+        min-width: calc(100% + 2px);
         margin-top: 2px;
         padding: 0;
 
@@ -44,3 +46,18 @@
         }
     }
 }
+
+.dropdown--ignite {
+    button, .btn-ignite {
+        position: relative;
+
+        &::after {
+            content: '';
+            position: absolute;
+            bottom: -4px;
+            display: block;
+            height: 4px;
+            width: 100%;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/controllers/caches-controller.js b/modules/web-console/frontend/controllers/caches-controller.js
index bf97692..23a0608 100644
--- a/modules/web-console/frontend/controllers/caches-controller.js
+++ b/modules/web-console/frontend/controllers/caches-controller.js
@@ -18,9 +18,40 @@
 import infoMessageTemplateUrl from 'views/templates/message.tpl.pug';
 
 // Controller for Caches screen.
-export default ['cachesController', [
-    '$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'IgniteLegacyTable',
-    function($scope, $http, $state, $filter, $timeout, $modal, LegacyUtils, Messages, Confirm, Input, Loading, ModelNormalizer, UnsavedChangesGuard, Resource, ErrorPopover, FormUtils, LegacyTable) {
+export default ['$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'IgniteLegacyTable', 'IgniteVersion',
+    function($scope, $http, $state, $filter, $timeout, $modal, LegacyUtils, Messages, Confirm, Input, Loading, ModelNormalizer, UnsavedChangesGuard, Resource, ErrorPopover, FormUtils, LegacyTable, Version) {
+        this.available = Version.available.bind(Version);
+
+        const rebuildDropdowns = () => {
+            $scope.affinityFunction = [
+                {value: 'Rendezvous', label: 'Rendezvous'},
+                {value: 'Custom', label: 'Custom'},
+                {value: null, label: 'Default'}
+            ];
+
+            if (this.available(['1.0.0', '2.0.0']))
+                $scope.affinityFunction.splice(1, 0, {value: 'Fair', label: 'Fair'});
+        };
+
+        rebuildDropdowns();
+
+        const filterModel = () => {
+            if ($scope.backupItem) {
+                if (this.available('2.0.0')) {
+                    if (_.get($scope.backupItem, 'affinity.kind') === 'Fair')
+                        $scope.backupItem.affinity.kind = null;
+                }
+            }
+        };
+
+        Version.currentSbj.subscribe({
+            next: () => {
+                rebuildDropdowns();
+
+                filterModel();
+            }
+        });
+
         UnsavedChangesGuard.install($scope);
 
         const emptyCache = {empty: true};
@@ -34,6 +65,7 @@ export default ['cachesController', [
                     hibernateProperties: []
                 }
             },
+            writeBehindCoalescing: true,
             nearConfiguration: {},
             sqlFunctionClasses: []
         };
@@ -82,6 +114,22 @@ export default ['cachesController', [
             }, []);
         }
 
+        const setOffHeapMode = (item) => {
+            if (_.isNil(item.offHeapMaxMemory))
+                return;
+
+            return item.offHeapMode = Math.sign(item.offHeapMaxMemory);
+        };
+
+        const setOffHeapMaxMemory = (value) => {
+            const item = $scope.backupItem;
+
+            if (_.isNil(value) || value <= 0)
+                return item.offHeapMaxMemory = value;
+
+            item.offHeapMaxMemory = item.offHeapMaxMemory > 0 ? item.offHeapMaxMemory : null;
+        };
+
         $scope.tablePairSave = LegacyTable.tablePairSave;
         $scope.tablePairSaveVisible = LegacyTable.tablePairSaveVisible;
         $scope.tableNewItem = LegacyTable.tableNewItem;
@@ -220,6 +268,8 @@ export default ['cachesController', [
                         form.$setDirty();
                 }, true);
 
+                $scope.$watch('backupItem.offHeapMode', setOffHeapMaxMemory);
+
                 $scope.$watch('ui.activePanels.length', () => {
                     ErrorPopover.hide();
                 });
@@ -263,8 +313,12 @@ export default ['cachesController', [
                     $scope.ui.inputForm.$setPristine();
                 }
 
+                setOffHeapMode($scope.backupItem);
+
                 __original_value = ModelNormalizer.normalize($scope.backupItem);
 
+                filterModel();
+
                 if (LegacyUtils.getQueryVariable('new'))
                     $state.go('base.configuration.caches');
             }
@@ -416,9 +470,18 @@ export default ['cachesController', [
             if (LegacyUtils.isEmptyString(item.name))
                 return ErrorPopover.show('cacheNameInput', 'Cache name should not be empty!', $scope.ui, 'general');
 
+            if (item.memoryMode === 'ONHEAP_TIERED' && item.offHeapMaxMemory > 0 && !LegacyUtils.isDefined(item.evictionPolicy.kind))
+                return ErrorPopover.show('evictionPolicyKindInput', 'Eviction policy should be configured!', $scope.ui, 'memory');
+
             if (!LegacyUtils.checkFieldValidators($scope.ui))
                 return false;
 
+            if (item.memoryMode === 'OFFHEAP_VALUES' && !_.isEmpty(item.domains))
+                return ErrorPopover.show('memoryModeInput', 'Query indexing could not be enabled while values are stored off-heap!', $scope.ui, 'memory');
+
+            if (item.memoryMode === 'OFFHEAP_TIERED' && item.offHeapMaxMemory === -1)
+                return ErrorPopover.show('offHeapModeInput', 'Invalid value!', $scope.ui, 'memory');
+
             if (!checkEvictionPolicy(item.evictionPolicy))
                 return false;
 
@@ -587,4 +650,4 @@ export default ['cachesController', [
                 });
         };
     }
-]];
+];

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/controllers/clusters-controller.js b/modules/web-console/frontend/controllers/clusters-controller.js
index dba56fc..6861fe7 100644
--- a/modules/web-console/frontend/controllers/clusters-controller.js
+++ b/modules/web-console/frontend/controllers/clusters-controller.js
@@ -16,16 +16,68 @@
  */
 
 // Controller for Clusters screen.
-export default ['clustersController', [
-    '$rootScope', '$scope', '$http', '$state', '$timeout', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteEventGroups', 'DemoInfo', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils',
-    function($root, $scope, $http, $state, $timeout, LegacyUtils, Messages, Confirm, Input, Loading, ModelNormalizer, UnsavedChangesGuard, igniteEventGroups, DemoInfo, LegacyTable, Resource, ErrorPopover, FormUtils) {
+export default ['$rootScope', '$scope', '$http', '$state', '$timeout', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteEventGroups', 'DemoInfo', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'IgniteVersion',
+    function($root, $scope, $http, $state, $timeout, LegacyUtils, Messages, Confirm, Input, Loading, ModelNormalizer, UnsavedChangesGuard, igniteEventGroups, DemoInfo, LegacyTable, Resource, ErrorPopover, FormUtils, Version) {
+        let __original_value;
+
+        this.available = Version.available.bind(Version);
+
+        const rebuildDropdowns = () => {
+            $scope.eventStorage = [
+                {value: 'Memory', label: 'Memory'},
+                {value: 'Custom', label: 'Custom'}
+            ];
+
+            $scope.marshallerVariant = [
+                {value: 'JdkMarshaller', label: 'JdkMarshaller'},
+                {value: null, label: 'Default'}
+            ];
+
+            if (this.available('2.0.0')) {
+                $scope.eventStorage.push({value: null, label: 'Disabled'});
+
+                $scope.eventGroups = _.filter(igniteEventGroups, ({value}) => value !== 'EVTS_SWAPSPACE');
+            }
+            else {
+                $scope.eventGroups = igniteEventGroups;
+
+                $scope.marshallerVariant.splice(0, 0, {value: 'OptimizedMarshaller', label: 'OptimizedMarshaller'});
+            }
+        };
+
+        rebuildDropdowns();
+
+        const filterModel = () => {
+            if ($scope.backupItem) {
+                if (this.available('2.0.0')) {
+                    const evtGrps = _.map($scope.eventGroups, 'value');
+
+                    _.remove(__original_value, (evtGrp) => !_.includes(evtGrps, evtGrp));
+                    _.remove($scope.backupItem.includeEventTypes, (evtGrp) => !_.includes(evtGrps, evtGrp));
+
+                    if (_.get($scope.backupItem, 'marshaller.kind') === 'OptimizedMarshaller')
+                        $scope.backupItem.marshaller.kind = null;
+                }
+                else if ($scope.backupItem && !_.get($scope.backupItem, 'eventStorage.kind'))
+                    _.set($scope.backupItem, 'eventStorage.kind', 'Memory');
+            }
+        };
+
+        Version.currentSbj.subscribe({
+            next: () => {
+                rebuildDropdowns();
+
+                filterModel();
+            }
+        });
+
         UnsavedChangesGuard.install($scope);
 
         const emptyCluster = {empty: true};
 
-        let __original_value;
-
         const blank = {
+            activeOnStart: true,
+            cacheSanityCheckEnabled: true,
             atomicConfiguration: {},
             binaryConfiguration: {},
             cacheKeyConfiguration: [],
@@ -48,8 +100,17 @@ export default ['clustersController', [
             sslContextFactory: {
                 trustManagers: []
             },
+            swapSpaceSpi: {},
             transactionConfiguration: {},
-            collision: {}
+            collision: {},
+            memoryConfiguration: {
+                memoryPolicies: []
+            },
+            hadoopConfiguration: {
+                nativeLibraryNames: []
+            },
+            serviceConfigurations: [],
+            executorConfiguration: []
         };
 
         const pairFields = {
@@ -149,6 +210,12 @@ export default ['clustersController', [
                     else
                         $scope.backupItem.checkpointSpi = [newCheckpointCfg];
                 }
+                else if (field.type === 'memoryPolicies')
+                    $scope.backupItem.memoryConfiguration.memoryPolicies.push({});
+                else if (field.type === 'serviceConfigurations')
+                    $scope.backupItem.serviceConfigurations.push({});
+                else if (field.type === 'executorConfigurations')
+                    $scope.backupItem.executorConfiguration.push({});
                 else
                     LegacyTable.tableNewItem(field);
             }
@@ -231,7 +298,10 @@ export default ['clustersController', [
             {value: 'Kubernetes', label: 'Kubernetes'}
         ];
 
-        $scope.eventGroups = igniteEventGroups;
+        $scope.swapSpaceSpis = [
+            {value: 'FileSwapSpaceSpi', label: 'File-based swap'},
+            {value: null, label: 'Not set'}
+        ];
 
         $scope.clusters = [];
 
@@ -285,6 +355,18 @@ export default ['clustersController', [
                             scanners: []
                         }};
                     }
+
+                    if (!cluster.memoryConfiguration)
+                        cluster.memoryConfiguration = { memoryPolicies: [] };
+
+                    if (!cluster.hadoopConfiguration)
+                        cluster.hadoopConfiguration = { nativeLibraryNames: [] };
+
+                    if (!cluster.serviceConfigurations)
+                        cluster.serviceConfigurations = [];
+
+                    if (!cluster.executorConfiguration)
+                        cluster.executorConfiguration = [];
                 });
 
                 if ($state.params.linkId)
@@ -328,6 +410,9 @@ export default ['clustersController', [
                             (selCache) => selCache === cache.value
                         )
                     );
+
+                    $scope.clusterCachesEmpty = _.clone($scope.clusterCaches);
+                    $scope.clusterCachesEmpty.push({label: 'Not set'});
                 }, true);
 
                 $scope.$watch('ui.activePanels.length', () => {
@@ -349,6 +434,7 @@ export default ['clustersController', [
             });
 
         $scope.clusterCaches = [];
+        $scope.clusterCachesEmpty = [];
 
         $scope.selectItem = function(item, backup) {
             function selectItem() {
@@ -380,6 +466,8 @@ export default ['clustersController', [
 
                 __original_value = ModelNormalizer.normalize($scope.backupItem);
 
+                filterModel();
+
                 if (LegacyUtils.getQueryVariable('new'))
                     $state.go('base.configuration.clusters');
             }
@@ -602,6 +690,36 @@ export default ['clustersController', [
             }));
         }
 
+        function checkMemoryConfiguration(item) {
+            const memory = item.memoryConfiguration;
+
+            if ((memory.systemCacheMaxSize || 104857600) < (memory.systemCacheInitialSize || 41943040))
+                return ErrorPopover.show('systemCacheMaxSize', 'System cache maximum size should be greater than initial size', $scope.ui, 'memoryConfiguration');
+
+            const pageSize = memory.pageSize;
+
+            if (pageSize > 0 && (pageSize & (pageSize - 1) !== 0)) {
+                ErrorPopover.show('MemoryConfigurationPageSize', 'Page size must be power of 2', $scope.ui, 'memoryConfiguration');
+
+                return false;
+            }
+
+            const dfltPlc = memory.defaultMemoryPolicyName;
+
+            if (!_.isEmpty(dfltPlc) && !_.find(memory.memoryPolicies, (plc) => plc.name === dfltPlc))
+                return ErrorPopover.show('defaultMemoryPolicyName', 'Memory policy with that name should be configured', $scope.ui, 'memoryConfiguration');
+
+            return _.isNil(_.find(memory.memoryPolicies, (curPlc, curIx) => {
+                if (_.find(memory.memoryPolicies, (plc, ix) => curIx > ix && (curPlc.name || 'default') === (plc.name || 'default'))) {
+                    ErrorPopover.show('MemoryPolicyName' + curIx, 'Memory policy with that name is already configured', $scope.ui, 'memoryConfiguration');
+
+                    return true;
+                }
+
+                return false;
+            }));
+        }
+
         function checkODBC(item) {
             if (_.get(item, 'odbc.odbcEnabled') && _.get(item, 'marshaller.kind'))
                 return ErrorPopover.show('odbcEnabledInput', 'ODBC can only be used with BinaryMarshaller', $scope.ui, 'odbcConfiguration');
@@ -609,6 +727,38 @@ export default ['clustersController', [
             return true;
         }
 
+        function checkSwapConfiguration(item) {
+            const swapKind = item.swapSpaceSpi && item.swapSpaceSpi.kind;
+
+            if (swapKind && item.swapSpaceSpi[swapKind]) {
+                const swap = item.swapSpaceSpi[swapKind];
+
+                const sparsity = swap.maximumSparsity;
+
+                if (LegacyUtils.isDefined(sparsity) && (sparsity < 0 || sparsity >= 1))
+                    return ErrorPopover.show('maximumSparsityInput', 'Maximum sparsity should be more or equal 0 and less than 1!', $scope.ui, 'swap');
+
+                const readStripesNumber = swap.readStripesNumber;
+
+                if (readStripesNumber && !(readStripesNumber === -1 || (readStripesNumber & (readStripesNumber - 1)) === 0))
+                    return ErrorPopover.show('readStripesNumberInput', 'Read stripe size must be positive and power of two!', $scope.ui, 'swap');
+            }
+
+            return true;
+        }
+
+        function checkServiceConfiguration(item) {
+            return _.isNil(_.find(_.get(item, 'serviceConfigurations'), (curSrv, curIx) => {
+                if (_.find(item.serviceConfigurations, (srv, ix) => curIx > ix && curSrv.name === srv.name)) {
+                    ErrorPopover.show('ServiceName' + curIx, 'Service configuration with that name is already configured', $scope.ui, 'serviceConfiguration');
+
+                    return true;
+                }
+
+                return false;
+            }));
+        }
+
         function checkSslConfiguration(item) {
             const r = item.connector;
 
@@ -632,7 +782,15 @@ export default ['clustersController', [
             if (item.rebalanceThreadPoolSize && item.systemThreadPoolSize && item.systemThreadPoolSize <= item.rebalanceThreadPoolSize)
                 return ErrorPopover.show('rebalanceThreadPoolSizeInput', 'Rebalance thread pool size exceed or equals System thread pool size!', $scope.ui, 'pools');
 
-            return true;
+            return _.isNil(_.find(_.get(item, 'executorConfiguration'), (curExec, curIx) => {
+                if (_.find(item.executorConfiguration, (srv, ix) => curIx > ix && curExec.name === srv.name)) {
+                    ErrorPopover.show('ExecutorName' + curIx, 'Executor configuration with that name is already configured', $scope.ui, 'pools');
+
+                    return true;
+                }
+
+                return false;
+            }));
         }
 
         // Check cluster logical consistency.
@@ -669,9 +827,18 @@ export default ['clustersController', [
             if (!checkLoadBalancingConfiguration(item))
                 return false;
 
+            if (!checkMemoryConfiguration(item))
+                return false;
+
             if (!checkODBC(item))
                 return false;
 
+            if (!checkSwapConfiguration(item))
+                return false;
+
+            if (!checkServiceConfiguration(item))
+                return false;
+
             if (!checkSslConfiguration(item))
                 return false;
 
@@ -726,6 +893,11 @@ export default ['clustersController', [
         $scope.saveItem = function() {
             const item = $scope.backupItem;
 
+            const swapConfigured = item.swapSpaceSpi && item.swapSpaceSpi.kind;
+
+            if (!swapConfigured && _.find(clusterCaches(item), (cache) => cache.swapEnabled))
+                _.merge(item, {swapSpaceSpi: {kind: 'FileSwapSpaceSpi'}});
+
             if (validate(item))
                 save(item);
         };
@@ -812,4 +984,4 @@ export default ['clustersController', [
                 });
         };
     }
-]];
+];

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/controllers/domains-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/controllers/domains-controller.js b/modules/web-console/frontend/controllers/domains-controller.js
index 3c8830b..992c829 100644
--- a/modules/web-console/frontend/controllers/domains-controller.js
+++ b/modules/web-console/frontend/controllers/domains-controller.js
@@ -18,8 +18,7 @@
 import templateUrl from 'views/configuration/domains-import.tpl.pug';
 
 // Controller for Domain model screen.
-export default ['domainsController', [
-    '$rootScope', '$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteConfirmBatch', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'AgentManager', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'JavaTypes', 'SqlTypes', 'IgniteActivitiesData',
+export default ['$rootScope', '$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteConfirmBatch', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'AgentManager', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'JavaTypes', 'SqlTypes', 'IgniteActivitiesData',
     function($root, $scope, $http, $state, $filter, $timeout, $modal, LegacyUtils, Messages, Focus, Confirm, ConfirmBatch, Input, Loading, ModelNormalizer, UnsavedChangesGuard, agentMgr, LegacyTable, Resource, ErrorPopover, FormUtils, JavaTypes, SqlTypes, ActivitiesData) {
         UnsavedChangesGuard.install($scope);
 
@@ -462,7 +461,7 @@ export default ['domainsController', [
 
                 $scope.importDomain.loadingOptions = LOADING_JDBC_DRIVERS;
 
-                agentMgr.startAgentWatch('Back to Domain models', 'import domain model from database')
+                agentMgr.startAgentWatch('Back to Domain models')
                     .then(() => {
                         ActivitiesData.post({
                             group: 'configuration',
@@ -1875,4 +1874,4 @@ export default ['domainsController', [
                 });
         };
     }
-]];
+];

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/controllers/igfs-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/controllers/igfs-controller.js b/modules/web-console/frontend/controllers/igfs-controller.js
index 504e28d..5d9f4a2 100644
--- a/modules/web-console/frontend/controllers/igfs-controller.js
+++ b/modules/web-console/frontend/controllers/igfs-controller.js
@@ -16,9 +16,10 @@
  */
 
 // Controller for IGFS screen.
-export default ['igfsController', [
-    '$scope', '$http', '$state', '$filter', '$timeout', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils',
-    function($scope, $http, $state, $filter, $timeout, LegacyUtils, Messages, Confirm, Input, Loading, ModelNormalizer, UnsavedChangesGuard, LegacyTable, Resource, ErrorPopover, FormUtils) {
+export default ['$scope', '$http', '$state', '$filter', '$timeout', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'IgniteVersion',
+    function($scope, $http, $state, $filter, $timeout, LegacyUtils, Messages, Confirm, Input, Loading, ModelNormalizer, UnsavedChangesGuard, LegacyTable, Resource, ErrorPopover, FormUtils, Version) {
+        this.available = Version.available.bind(Version);
+
         UnsavedChangesGuard.install($scope);
 
         const emptyIgfs = {empty: true};
@@ -411,4 +412,4 @@ export default ['igfsController', [
                 });
         };
     }
-]];
+];

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/public/stylesheets/style.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/public/stylesheets/style.scss b/modules/web-console/frontend/public/stylesheets/style.scss
index 4054fb1..3ecb300 100644
--- a/modules/web-console/frontend/public/stylesheets/style.scss
+++ b/modules/web-console/frontend/public/stylesheets/style.scss
@@ -73,6 +73,16 @@ hr {
         cursor: default;
         pointer-events: none;
     }
+
+    version-picker {
+        margin-top: 10px;
+
+        & + hr {
+            margin-top: 10px;
+            margin-bottom: 10px;
+            margin-right: 20px;
+        }
+    }
 }
 
 .theme-line .sidebar-nav {
@@ -319,15 +329,6 @@ h1, h2, h3, h4, h5, h6 {
     }
 }
 
-.greedy {
-    min-height: 100%;
-    height: #{"calc(100vh - 270px)"};
-}
-
-.signin-greedy {
-    height: #{"calc(100vh - 300px)"};
-}
-
 body {
     overflow-x: hidden;
     display: flex;

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/test/unit/Version.test.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/test/unit/Version.test.js b/modules/web-console/frontend/test/unit/Version.test.js
index d8c8f65..b8477bf 100644
--- a/modules/web-console/frontend/test/unit/Version.test.js
+++ b/modules/web-console/frontend/test/unit/Version.test.js
@@ -23,39 +23,72 @@ import { suite, test } from 'mocha';
 import { assert } from 'chai';
 
 suite('VersionServiceTestsSuite', () => {
+    test('Parse 1.7.0-SNAPSHOT', () => {
+        const version = INSTANCE.parse('1.7.0-SNAPSHOT');
+        assert.equal(version.major, 1);
+        assert.equal(version.minor, 7);
+        assert.equal(version.maintenance, 0);
+        assert.equal(version.stage, 'SNAPSHOT');
+        assert.equal(version.revTs, 0);
+        assert.isNull(version.revHash);
+    });
+
+    test('Parse strip -DEV 1.7.0-DEV', () => {
+        const version = INSTANCE.parse('1.7.0-DEV');
+        assert.equal(version.major, 1);
+        assert.equal(version.minor, 7);
+        assert.equal(version.maintenance, 0);
+        assert.equal(version.stage, '');
+    });
+
+    test('Parse strip -n/a 1.7.0-n/a', () => {
+        const version = INSTANCE.parse('1.7.0-n/a');
+        assert.equal(version.major, 1);
+        assert.equal(version.minor, 7);
+        assert.equal(version.maintenance, 0);
+        assert.equal(version.stage, '');
+    });
+
     test('Check patch version', () => {
-        assert.equal(INSTANCE.compare('1.7.2', '1.7.1'), 1);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('1.7.2'), INSTANCE.parse('1.7.1')), 1);
     });
 
     test('Check minor version', () => {
-        assert.equal(INSTANCE.compare('1.8.1', '1.7.1'), 1);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('1.8.1'), INSTANCE.parse('1.7.1')), 1);
     });
 
     test('Check major version', () => {
-        assert.equal(INSTANCE.compare('2.7.1', '1.7.1'), 1);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('2.7.1'), INSTANCE.parse('1.7.1')), 1);
     });
 
     test('Version a > b', () => {
-        assert.equal(INSTANCE.compare('1.7.0', '1.5.0'), 1);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('1.7.0'), INSTANCE.parse('1.5.0')), 1);
     });
 
     test('Version a = b', () => {
-        assert.equal(INSTANCE.compare('1.0.0', '1.0.0'), 0);
-        assert.equal(INSTANCE.compare('1.2.0', '1.2.0'), 0);
-        assert.equal(INSTANCE.compare('1.2.3', '1.2.3'), 0);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('1.0.0'), INSTANCE.parse('1.0.0')), 0);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('1.2.0'), INSTANCE.parse('1.2.0')), 0);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('1.2.3'), INSTANCE.parse('1.2.3')), 0);
 
-        assert.equal(INSTANCE.compare('1.0.0-1', '1.0.0-1'), 0);
-        assert.equal(INSTANCE.compare('1.2.0-1', '1.2.0-1'), 0);
-        assert.equal(INSTANCE.compare('1.2.3-1', '1.2.3-1'), 0);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('1.0.0-1'), INSTANCE.parse('1.0.0-1')), 0);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('1.2.0-1'), INSTANCE.parse('1.2.0-1')), 0);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('1.2.3-1'), INSTANCE.parse('1.2.3-1')), 0);
     });
 
     test('Version a < b', () => {
-        assert.equal(INSTANCE.compare('1.5.1', '1.5.2'), -1);
+        assert.equal(INSTANCE.compare(INSTANCE.parse('1.5.1'), INSTANCE.parse('1.5.2')), -1);
     });
 
     test('Check since call', () => {
         assert.equal(INSTANCE.since('1.5.0', '1.5.0'), true);
         assert.equal(INSTANCE.since('1.6.0', '1.5.0'), true);
+        assert.equal(INSTANCE.since('1.5.4', ['1.5.5', '1.6.0'], ['1.6.2']), false);
+        assert.equal(INSTANCE.since('1.5.5', ['1.5.5', '1.6.0'], ['1.6.2']), true);
+        assert.equal(INSTANCE.since('1.5.11', ['1.5.5', '1.6.0'], ['1.6.2']), true);
+        assert.equal(INSTANCE.since('1.6.0', ['1.5.5', '1.6.0'], ['1.6.2']), false);
+        assert.equal(INSTANCE.since('1.6.1', ['1.5.5', '1.6.0'], '1.6.2'), false);
+        assert.equal(INSTANCE.since('1.6.2', ['1.5.5', '1.6.0'], ['1.6.2']), true);
+        assert.equal(INSTANCE.since('1.6.3', ['1.5.5', '1.6.0'], '1.6.2'), true);
     });
 
     test('Check wrong since call', () => {
@@ -70,44 +103,4 @@ suite('VersionServiceTestsSuite', () => {
     test('Check wrong before call', () => {
         assert.equal(INSTANCE.before('1.5.0', '1.3.0'), false);
     });
-
-    test('Check includes call', () => {
-        assert.equal(INSTANCE.includes('1.5.4', ['1.5.5', '1.6.0'], ['1.6.2']), false);
-        assert.equal(INSTANCE.includes('1.5.5', ['1.5.5', '1.6.0'], ['1.6.2']), true);
-        assert.equal(INSTANCE.includes('1.5.11', ['1.5.5', '1.6.0'], ['1.6.2']), true);
-        assert.equal(INSTANCE.includes('1.6.0', ['1.5.5', '1.6.0'], ['1.6.2']), false);
-        assert.equal(INSTANCE.includes('1.6.1', ['1.5.5', '1.6.0'], ['1.6.2']), false);
-        assert.equal(INSTANCE.includes('1.6.2', ['1.5.5', '1.6.0'], ['1.6.2']), true);
-        assert.equal(INSTANCE.includes('1.6.3', ['1.5.5', '1.6.0'], ['1.6.2']), true);
-    });
-
-    test('Check wrong before call', () => {
-        assert.equal(INSTANCE.before('1.5.0', '1.3.0'), false);
-    });
-
-    test('Parse 1.7.0-SNAPSHOT', () => {
-        const version = INSTANCE.parse('1.7.0-SNAPSHOT');
-        assert.equal(version.major, 1);
-        assert.equal(version.minor, 7);
-        assert.equal(version.maintenance, 0);
-        assert.equal(version.stage, 'SNAPSHOT');
-        assert.equal(version.revTs, 0);
-        assert.isNull(version.revHash);
-    });
-
-    test('Parse strip -DEV 1.7.0-DEV', () => {
-        const version = INSTANCE.parse('1.7.0-DEV');
-        assert.equal(version.major, 1);
-        assert.equal(version.minor, 7);
-        assert.equal(version.maintenance, 0);
-        assert.equal(version.stage, '');
-    });
-
-    test('Parse strip -n/a 1.7.0-n/a', () => {
-        const version = INSTANCE.parse('1.7.0-n/a');
-        assert.equal(version.major, 1);
-        assert.equal(version.minor, 7);
-        assert.equal(version.maintenance, 0);
-        assert.equal(version.stage, '');
-    });
 });

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/configuration/caches.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/configuration/caches.tpl.pug b/modules/web-console/frontend/views/configuration/caches.tpl.pug
index fca41a8..43b5d57 100644
--- a/modules/web-console/frontend/views/configuration/caches.tpl.pug
+++ b/modules/web-console/frontend/views/configuration/caches.tpl.pug
@@ -18,7 +18,7 @@ include /app/helpers/jade/mixins
 
 .docs-header
     h1 Configure Ignite Caches
-.docs-body(ng-controller='cachesController')
+.docs-body
     ignite-information
         ul
             li Configure #[a(href='https://apacheignite.readme.io/docs/data-grid' target='_blank') memory] settings

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/configuration/clusters.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/configuration/clusters.tpl.pug b/modules/web-console/frontend/views/configuration/clusters.tpl.pug
index 4a1df33..744ec7c 100644
--- a/modules/web-console/frontend/views/configuration/clusters.tpl.pug
+++ b/modules/web-console/frontend/views/configuration/clusters.tpl.pug
@@ -18,7 +18,7 @@ include /app/helpers/jade/mixins
 
 .docs-header
     h1 Configure Ignite Clusters
-.docs-body(ng-controller='clustersController')
+.docs-body
     ignite-information
         ul
             li Configure #[a(href='https://apacheignite.readme.io/docs/clustering' target='_blank') clusters] properties
@@ -52,13 +52,24 @@ include /app/helpers/jade/mixins
                             include /app/modules/states/configuration/clusters/discovery
                             include /app/modules/states/configuration/clusters/events
                             include /app/modules/states/configuration/clusters/failover
+                            include /app/modules/states/configuration/clusters/hadoop
                             include /app/modules/states/configuration/clusters/igfs
                             include /app/modules/states/configuration/clusters/load-balancing
                             include /app/modules/states/configuration/clusters/logger
                             include /app/modules/states/configuration/clusters/marshaller
+
+                            //- Since ignite 2.0
+                            include /app/modules/states/configuration/clusters/memory
+
+                            include /app/modules/states/configuration/clusters/misc
                             include /app/modules/states/configuration/clusters/metrics
                             include /app/modules/states/configuration/clusters/odbc
+                            include /app/modules/states/configuration/clusters/service
                             include /app/modules/states/configuration/clusters/ssl
+
+                            //- Removed in ignite 2.0
+                            include /app/modules/states/configuration/clusters/swap
+                                
                             include /app/modules/states/configuration/clusters/thread
                             include /app/modules/states/configuration/clusters/time
                             include /app/modules/states/configuration/clusters/transactions

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/configuration/domains.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/configuration/domains.tpl.pug b/modules/web-console/frontend/views/configuration/domains.tpl.pug
index a8f9b5c..9e3e297 100644
--- a/modules/web-console/frontend/views/configuration/domains.tpl.pug
+++ b/modules/web-console/frontend/views/configuration/domains.tpl.pug
@@ -18,7 +18,7 @@ include /app/helpers/jade/mixins
 
 .docs-header
     h1 Configure Domain Model And SQL Queries
-.docs-body(ng-controller='domainsController')
+.docs-body
     ignite-information
         ul: li Import database schemas
             li Configure indexed types

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/configuration/igfs.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/configuration/igfs.tpl.pug b/modules/web-console/frontend/views/configuration/igfs.tpl.pug
index dfc9ed2..46ee4c0 100644
--- a/modules/web-console/frontend/views/configuration/igfs.tpl.pug
+++ b/modules/web-console/frontend/views/configuration/igfs.tpl.pug
@@ -18,7 +18,7 @@ include /app/helpers/jade/mixins
 
 .docs-header
     h1 Configure Ignite In-memory File Systems
-.docs-body(ng-controller='igfsController')
+.docs-body
     ignite-information(data-title='Configure IGFS only if you are going to use In-memory File System')
         ul
             li Ignite File System (#[a(href='https://apacheignite-fs.readme.io/docs/in-memory-file-system' target='_blank') IGFS]) is an in-memory file system allowing work with files and directories over existing cache infrastructure
@@ -45,6 +45,10 @@ include /app/helpers/jade/mixins
                             include /app/modules/states/configuration/igfs/secondary
                             include /app/modules/states/configuration/igfs/ipc
                             include /app/modules/states/configuration/igfs/fragmentizer
+
+                            //- Removed in ignite 2.0
+                            include /app/modules/states/configuration/igfs/dual
+
                             include /app/modules/states/configuration/igfs/misc
 
                             +advanced-options-toggle-default

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/configuration/sidebar.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/configuration/sidebar.tpl.pug b/modules/web-console/frontend/views/configuration/sidebar.tpl.pug
index bba6b25..1442331 100644
--- a/modules/web-console/frontend/views/configuration/sidebar.tpl.pug
+++ b/modules/web-console/frontend/views/configuration/sidebar.tpl.pug
@@ -15,8 +15,10 @@
     limitations under the License.
 
 .row
-    .col-xs-3.col-sm-3.col-md-2.border-right.section-left.greedy
+    .col-xs-3.col-sm-3.col-md-2.border-right.section-left
         .sidebar-nav(bs-affix)
+            version-picker
+            hr
             ul.menu(ignite-sidebar)
                 li(ng-repeat='item in sidebar.items')
                     a(ui-sref-active='active' ui-sref='{{::item.sref}}')

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/includes/header-left.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/includes/header-left.pug b/modules/web-console/frontend/views/includes/header-left.pug
index 4dda1cc..deba568 100644
--- a/modules/web-console/frontend/views/includes/header-left.pug
+++ b/modules/web-console/frontend/views/includes/header-left.pug
@@ -21,7 +21,6 @@
         data-placement='bottom-left'
         data-trigger='hover focus'
         data-container='self'
-        data-animation=''
     )
         span Configure
             span.caret
@@ -41,7 +40,6 @@
             data-placement='bottom-left'
             data-trigger='hover focus'
             data-container='self'
-            data-animation=''
             aria-haspopup='true'
             aria-expanded='false'
         )
@@ -56,7 +54,6 @@
         data-placement='bottom-left'
         data-trigger='hover focus'
         data-container='self'
-        data-animation=''
         aria-haspopup='true'
         aria-expanded='false'
     )

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/includes/header-right.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/includes/header-right.pug b/modules/web-console/frontend/views/includes/header-right.pug
index 62227e9..de67445 100644
--- a/modules/web-console/frontend/views/includes/header-right.pug
+++ b/modules/web-console/frontend/views/includes/header-right.pug
@@ -34,7 +34,6 @@ ignite-cluster-select.wch-nav-item(ng-if='!IgniteDemoMode')
         data-placement='bottom-right'
         data-trigger='hover focus'
         data-container='self'
-        data-animation=''
     )
         span {{$root.user.firstName}} {{$root.user.lastName}}
             span.caret

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/settings/admin.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/settings/admin.tpl.pug b/modules/web-console/frontend/views/settings/admin.tpl.pug
index a8df240..3c49eb6 100644
--- a/modules/web-console/frontend/views/settings/admin.tpl.pug
+++ b/modules/web-console/frontend/views/settings/admin.tpl.pug
@@ -15,7 +15,7 @@
     limitations under the License.
 
 .admin-page.row
-    .docs-content.greedy
+    .docs-content
         header
             h1 Admin panel
         .docs-body

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/settings/profile.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/settings/profile.tpl.pug b/modules/web-console/frontend/views/settings/profile.tpl.pug
index 6f91f8f..54c8105 100644
--- a/modules/web-console/frontend/views/settings/profile.tpl.pug
+++ b/modules/web-console/frontend/views/settings/profile.tpl.pug
@@ -18,7 +18,7 @@ mixin lbl(txt)
     label.col-sm-2.required.labelFormField #{txt}
 
 .row(ng-controller='profileController')
-    .docs-content.greedy
+    .docs-content
         .docs-header
             h1 User profile
             hr

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/signin.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/signin.tpl.pug b/modules/web-console/frontend/views/signin.tpl.pug
index a32733d..c7e2027 100644
--- a/modules/web-console/frontend/views/signin.tpl.pug
+++ b/modules/web-console/frontend/views/signin.tpl.pug
@@ -97,7 +97,7 @@ web-console-header
                         ignite-features
                 .col-xs-12.col-md-6
                     #carousel.carousel.slide
-                        // Indicators
+                        //- Indicators
                         ol.carousel-indicators
                             li.active(data-target='#carousel', data-slide-to='0')
                             li(data-target='#carousel', data-slide-to='1')
@@ -106,7 +106,7 @@ web-console-header
                             li(data-target='#carousel', data-slide-to='4')
                             li(data-target='#carousel', data-slide-to='5')
                             li(data-target='#carousel', data-slide-to='6')
-                        // Wrapper for slides
+                        //- Wrapper for slides
                         .carousel-inner(role='listbox')
                             .item.active
                                 img(src='/images/cluster.png', alt='Clusters screen')
@@ -143,7 +143,7 @@ web-console-header
                                 .carousel-caption
                                     h3 Query chart
                                     p View data in tabular form and as charts
-                        // Controls
+                        //- Controls
                         a.left.carousel-control(href='#carousel', ng-click='$event.preventDefault()', role='button', data-slide='prev')
                             span.fa.fa-chevron-left(aria-hidden='true')
                             span.sr-only Previous

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/views/sql/sql.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/sql/sql.tpl.pug b/modules/web-console/frontend/views/sql/sql.tpl.pug
index dd2754d..65597a3 100644
--- a/modules/web-console/frontend/views/sql/sql.tpl.pug
+++ b/modules/web-console/frontend/views/sql/sql.tpl.pug
@@ -133,8 +133,8 @@ mixin table-result-heading-query
                 +result-toolbar
         .col-xs-4
             .pull-right
-                -var actions = [{ text: "Export", click: 'exportCsv(paragraph)' }, { text: 'Export all', click: 'exportCsvAll(paragraph)' }]
-                +btn-group(actions, '{{ actionTooltip(paragraph, "export", false) }}')(ng-disabled='paragraph.loading')
+                -var options = [{ text: "Export", click: 'exportCsv(paragraph)' }, { text: 'Export all', click: 'exportCsvAll(paragraph)' }]
+                +btn-group('paragraph.loading', options, '{{ actionTooltip(paragraph, "export", false) }}')
 
 mixin table-result-heading-scan
     .total.row
@@ -148,8 +148,8 @@ mixin table-result-heading-scan
                 +result-toolbar
         .col-xs-4
             .pull-right
-                -var actions = [{ text: "Export", click: 'exportCsv(paragraph)' }, { text: 'Export all', click: 'exportCsvAll(paragraph)' }]
-                +btn-group(actions, '{{ actionTooltip(paragraph, "export", false) }}')(ng-disabled='paragraph.loading')
+                -var options = [{ text: "Export", click: 'exportCsv(paragraph)' }, { text: 'Export all', click: 'exportCsvAll(paragraph)' }]
+                +btn-group('paragraph.loading', options, '{{ actionTooltip(paragraph, "export", false) }}')
 
 mixin table-result-body
     .grid(ui-grid='paragraph.gridOptions' ui-grid-resize-columns ui-grid-exporter)

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/webpack/webpack.common.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/webpack/webpack.common.js b/modules/web-console/frontend/webpack/webpack.common.js
index 5fefd59..a303d6e 100644
--- a/modules/web-console/frontend/webpack/webpack.common.js
+++ b/modules/web-console/frontend/webpack/webpack.common.js
@@ -52,8 +52,7 @@ export default {
     output: {
         path: path.resolve('build'),
         filename: '[name].[chunkhash].js',
-        publicPath: '/',
-        sourceMapFilename: '[name].[chunkhash].map'
+        publicPath: '/'
     },
 
     // Resolves modules.
@@ -62,8 +61,9 @@ export default {
         // A list of module source folders.
         alias: {
             app,
-            images: path.resolve('public/images'),
-            views: path.resolve('views'),
+            images: path.join(basedir, 'public/images'),
+            views: path.join(basedir, 'views'),
+            Controllers: path.join(basedir, 'controllers'),
             IgniteModules
         }
     },

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/frontend/webpack/webpack.dev.babel.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/webpack/webpack.dev.babel.js b/modules/web-console/frontend/webpack/webpack.dev.babel.js
index dc5cd41..56371cda 100644
--- a/modules/web-console/frontend/webpack/webpack.dev.babel.js
+++ b/modules/web-console/frontend/webpack/webpack.dev.babel.js
@@ -87,10 +87,7 @@ export default merge(commonCfg, {
             aggregateTimeout: 1000,
             poll: 2000
         },
-        stats: {
-            colors: true,
-            chunks: false
-        },
+        stats: 'errors-only',
         host: devServerHost,
         port: devServerPort
     },

http://git-wip-us.apache.org/repos/asf/ignite/blob/e04df7d1/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
index 27f5317..0da4469 100644
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
@@ -219,11 +219,11 @@ public class ClusterListener {
         }
 
         /**  */
-        boolean isSameCluster(TopologySnapshot snapshot) {
-            if (snapshot == null || F.isEmpty(snapshot.nids))
-                return false;
+        boolean differentCluster(TopologySnapshot old) {
+            if (old == null || F.isEmpty(old.nids))
+                return true;
 
-            return Collections.disjoint(nids, snapshot.nids);
+            return Collections.disjoint(nids, old.nids);
         }
     }
 
@@ -241,7 +241,7 @@ public class ClusterListener {
 
                         TopologySnapshot newTop = new TopologySnapshot(nodes);
 
-                        if (newTop.isSameCluster(top))
+                        if (newTop.differentCluster(top))
                             log.info("Connection successfully established to cluster with nodes: {}", newTop.nid8());
 
                         top = newTop;
@@ -276,7 +276,7 @@ public class ClusterListener {
 
                         TopologySnapshot newTop = new TopologySnapshot(nodes);
 
-                        if (top == null || top.isSameCluster(newTop)) {
+                        if (top.differentCluster(newTop)) {
                             clusterDisconnect();
 
                             log.info("Connection successfully established to cluster with nodes: {}", newTop.nid8());


Mime
View raw message