ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anovi...@apache.org
Subject ignite git commit: IGNITE-5466 Minor UI changes & improvements.
Date Wed, 06 Jun 2018 08:51:19 GMT
Repository: ignite
Updated Branches:
  refs/heads/master e8ecb1dd5 -> c47e30487


IGNITE-5466 Minor UI changes & improvements.


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

Branch: refs/heads/master
Commit: c47e304876d4827048f38068ced725429d8a23ad
Parents: e8ecb1d
Author: Ilya Borisov <iborisov@gridgain.com>
Authored: Wed Jun 6 15:51:04 2018 +0700
Committer: Andrey Novikov <anovikov@gridgain.com>
Committed: Wed Jun 6 15:51:04 2018 +0700

----------------------------------------------------------------------
 .../testcafe/fixtures/configuration/basic.js    |  1 -
 .../page-models/PageConfigurationBasic.js       | 23 +++++-----
 .../app/components/bs-select-menu/style.scss    |  2 +-
 .../list-editable-cols/cols.directive.js        |  3 +-
 .../list-editable-cols/cols.style.scss          |  6 +++
 .../list-editable-cols/cols.template.pug        |  1 +
 .../components/cache-edit-form/controller.js    | 11 ++++-
 .../components/cache-edit-form/template.tpl.pug |  6 +--
 .../components/cluster-edit-form/controller.js  | 11 ++++-
 .../cluster-edit-form/template.tpl.pug          |  8 +---
 .../cluster-edit-form/templates/binary.pug      |  2 +-
 .../templates/cache-key-cfg.pug                 |  2 +-
 .../cluster-edit-form/templates/checkpoint.pug  |  2 +-
 .../templates/data-storage.pug                  |  5 ++-
 .../cluster-edit-form/templates/failover.pug    | 15 +++----
 .../templates/load-balancing.pug                |  5 ++-
 .../cluster-edit-form/templates/memory.pug      |  2 +-
 .../cluster-edit-form/templates/service.pug     | 26 +++++------
 .../components/igfs-edit-form/controller.js     | 12 +++++-
 .../components/igfs-edit-form/template.tpl.pug  |  7 +--
 .../components/model-edit-form/controller.js    | 12 +++++-
 .../components/model-edit-form/template.tpl.pug |  7 +--
 .../controller.js                               |  4 +-
 .../controller.js                               |  4 +-
 .../page-configure-advanced-igfs/controller.js  |  4 +-
 .../controller.js                               |  4 +-
 .../page-configure-basic/controller.js          |  4 +-
 .../components/page-configure-basic/style.scss  | 25 -----------
 .../page-configure-basic/template.pug           | 15 +------
 .../components/pc-split-button/component.js     | 27 ++++++++++++
 .../components/pc-split-button/controller.js    | 45 ++++++++++++++++++++
 .../components/pc-split-button/index.js         | 23 ++++++++++
 .../components/pc-split-button/template.pug     | 28 ++++++++++++
 .../app/components/page-configure/index.js      |  4 +-
 .../page-configure/store/actionCreators.js      |  8 ++--
 .../components/page-configure/store/effects.js  | 22 +++++++---
 .../app/components/page-configure/style.scss    | 16 +++++++
 37 files changed, 269 insertions(+), 133 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/e2e/testcafe/fixtures/configuration/basic.js
----------------------------------------------------------------------
diff --git a/modules/web-console/e2e/testcafe/fixtures/configuration/basic.js b/modules/web-console/e2e/testcafe/fixtures/configuration/basic.js
index 090fd0a..0522fe2 100644
--- a/modules/web-console/e2e/testcafe/fixtures/configuration/basic.js
+++ b/modules/web-console/e2e/testcafe/fixtures/configuration/basic.js
@@ -62,7 +62,6 @@ test('Basic editing', async(t) => {
 
     await t
         .expect(page.buttonPreviewProject.visible).notOk('Preview project button is hidden for new cluster configs')
-        .expect(page.buttonDownloadProject.visible).notOk('Download project button is hidden for new cluster configs')
         .typeText(page.clusterNameInput.control, clusterName, {replace: true});
     await page.cachesList.addItem();
     await page.cachesList.addItem();

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/e2e/testcafe/page-models/PageConfigurationBasic.js
----------------------------------------------------------------------
diff --git a/modules/web-console/e2e/testcafe/page-models/PageConfigurationBasic.js b/modules/web-console/e2e/testcafe/page-models/PageConfigurationBasic.js
index 38610bc..2c13cc3 100644
--- a/modules/web-console/e2e/testcafe/page-models/PageConfigurationBasic.js
+++ b/modules/web-console/e2e/testcafe/page-models/PageConfigurationBasic.js
@@ -15,13 +15,13 @@
  * limitations under the License.
  */
 
-import {Selector, t} from 'testcafe'
-import {FormField} from '../components/FormField'
-import {ListEditable} from '../components/ListEditable'
+import {Selector, t} from 'testcafe';
+import {FormField} from '../components/FormField';
+import {ListEditable} from '../components/ListEditable';
 
 class VersionPicker {
     constructor() {
-        this._selector = Selector('version-picker')
+        this._selector = Selector('version-picker');
     }
     /**
      * @param {string} label Version label
@@ -29,24 +29,23 @@ class VersionPicker {
     pickVersion(label) {
         return t
             .hover(this._selector)
-            .click(this._selector.find('[role="menuitem"]').withText(label))
+            .click(this._selector.find('[role="menuitem"]').withText(label));
     }
 }
 
 export class PageConfigurationBasic {
-    static SAVE_CHANGES_AND_DOWNLOAD_LABEL = 'Save changes and download project';
-    static SAVE_CHANGES_LABEL = 'Save changes';
+    static SAVE_CHANGES_AND_DOWNLOAD_LABEL = 'Save and Download';
+    static SAVE_CHANGES_LABEL = 'Save';
 
     constructor() {
         this._selector = Selector('page-configure-basic');
-        this.versionPicker = new VersionPicker;
+        this.versionPicker = new VersionPicker();
         this.totalOffheapSizeInput = Selector('pc-form-field-size#memory');
         this.mainFormAction = Selector('.pc-form-actions-panel .btn-ignite-group .btn-ignite:nth-of-type(1)');
         this.contextFormActionsButton = Selector('.pc-form-actions-panel .btn-ignite-group .btn-ignite:nth-of-type(2)');
         this.contextSaveButton = Selector('a[role=menuitem]').withText(new RegExp(`^${PageConfigurationBasic.SAVE_CHANGES_LABEL}$`));
         this.contextSaveAndDownloadButton = Selector('a[role=menuitem]').withText(PageConfigurationBasic.SAVE_CHANGES_AND_DOWNLOAD_LABEL);
         this.buttonPreviewProject = Selector('button-preview-project');
-        this.buttonDownloadProject = Selector('button-download-project');
         this.clusterNameInput = new FormField({id: 'clusterNameInput'});
         this.clusterDiscoveryInput = new FormField({id: 'discoveryInput'});
         this.cachesList = new ListEditable(Selector('.pcb-caches-list'), {
@@ -55,14 +54,14 @@ export class PageConfigurationBasic {
             atomicityMode: {id: 'atomicityModeInput'},
             backups: {id: 'backupsInput'}
         });
-        this.pageHeader = Selector('.pc-page-header')
+        this.pageHeader = Selector('.pc-page-header');
     }
 
     async save() {
-        await t.click(this.mainFormAction)
+        await t.click(this.mainFormAction);
     }
 
     async saveWithoutDownload() {
-        return await t.click(this.contextFormActionsButton).click(this.contextSaveButton)
+        return await t.click(this.contextFormActionsButton).click(this.contextSaveButton);
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/bs-select-menu/style.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/bs-select-menu/style.scss b/modules/web-console/frontend/app/components/bs-select-menu/style.scss
index 02f9b5c..bfa0063 100644
--- a/modules/web-console/frontend/app/components/bs-select-menu/style.scss
+++ b/modules/web-console/frontend/app/components/bs-select-menu/style.scss
@@ -69,7 +69,7 @@
             }
         }
 
-        &:last-child > .bssm-item-button {
+        &:last-of-type > .bssm-item-button {
             border-bottom: none;
             padding-bottom: 10px;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.directive.js b/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.directive.js
index b38cb7a..e166402 100644
--- a/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.directive.js
+++ b/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.directive.js
@@ -70,7 +70,8 @@ export default function listEditableCols() {
         },
         bindToController: {
             colDefs: '<listEditableCols',
-            rowClass: '@?listEditableColsRowClass'
+            rowClass: '@?listEditableColsRowClass',
+            ngDisabled: '<?'
         }
     };
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.style.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.style.scss b/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.style.scss
index 12c9ba6..f5759fd 100644
--- a/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.style.scss
+++ b/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.style.scss
@@ -21,6 +21,7 @@
 
     margin-left: 10px;
     margin-right: $remove-column-width;
+    transition: 0.2s opacity;
 
     &__multiple-cols {
         margin-left: $index-column-width;
@@ -48,4 +49,9 @@
             display: none;
         }
     }
+
+    &[disabled] {
+        opacity: 0.5;
+        cursor: default;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.template.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.template.pug b/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.template.pug
index 6541c92..d060f45 100644
--- a/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.template.pug
+++ b/modules/web-console/frontend/app/components/list-editable/components/list-editable-cols/cols.template.pug
@@ -16,6 +16,7 @@
 
 .list-editable-cols__header(
     ng-class='::[$ctrl.rowClass, {"list-editable-cols__header__multiple-cols": $ctrl.colDefs.length > 1}]'
+    ng-disabled='$ctrl.ngDisabled'
 )
     .list-editable-cols__header-cell(ng-repeat='col in ::$ctrl.colDefs' ng-class='::col.cellClass')
         span.ignite-form-field__label

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cache-edit-form/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cache-edit-form/controller.js b/modules/web-console/frontend/app/components/page-configure-advanced/components/cache-edit-form/controller.js
index f1bba1f..e044a70 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cache-edit-form/controller.js
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cache-edit-form/controller.js
@@ -28,6 +28,8 @@ export default class CacheEditFormController {
      * @type {Array<string>}
      */
     igfsIDs;
+    /** @type {ng.ICompiledExpression} */
+    onSave;
 
     static $inject = ['IgniteConfirm', 'IgniteVersion', '$scope', 'Caches', 'IgniteFormUtils'];
     constructor(IgniteConfirm, IgniteVersion, $scope, Caches, IgniteFormUtils) {
@@ -66,6 +68,11 @@ export default class CacheEditFormController {
 
         // TODO: Do we really need this?
         this.$scope.ui = this.IgniteFormUtils.formUI();
+
+        this.formActions = [
+            {text: 'Save', icon: 'checkmark', click: () => this.save()},
+            {text: 'Save and Download', icon: 'download', click: () => this.save(true)}
+        ];
     }
     $onDestroy() {
         this.subscription.unsubscribe();
@@ -90,10 +97,10 @@ export default class CacheEditFormController {
     getValuesToCompare() {
         return [this.cache, this.clonedCache].map(this.Caches.normalize);
     }
-    save() {
+    save(download) {
         if (this.$scope.ui.inputForm.$invalid)
             return this.IgniteFormUtils.triggerValidation(this.$scope.ui.inputForm, this.$scope);
-        this.onSave({$event: cloneDeep(this.clonedCache)});
+        this.onSave({$event: {cache: cloneDeep(this.clonedCache), download}});
     }
     reset = (forReal) => forReal ? this.clonedCache = cloneDeep(this.cache) : void 0;
     confirmAndReset() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cache-edit-form/template.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cache-edit-form/template.tpl.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/cache-edit-form/template.tpl.pug
index a8ae2f2..7305a39 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cache-edit-form/template.tpl.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cache-edit-form/template.tpl.pug
@@ -18,7 +18,6 @@ form(
     name='ui.inputForm'
     id='cache'
     novalidate
-    ng-submit='$ctrl.save($ctrl.clonedCache)'
 )
     include ./templates/general
     include ./templates/memory
@@ -40,7 +39,4 @@ form(
         ng-click='$ctrl.confirmAndReset()'
     )
         | Cancel
-    button.btn-ignite.btn-ignite--success(
-        form='cache'
-        type='submit'
-    ) Save
+    pc-split-button(actions=`::$ctrl.formActions`)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/controller.js b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/controller.js
index 0207729..8459cdd 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/controller.js
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/controller.js
@@ -25,6 +25,8 @@ export default class ClusterEditFormController {
     caches;
     /** @type {ig.menu<string>} */
     cachesMenu;
+    /** @type {ng.ICompiledExpression} */
+    onSave;
 
     static $inject = ['IgniteLegacyUtils', 'IgniteEventGroups', 'IgniteConfirm', 'IgniteVersion', '$scope', 'Clusters', 'IgniteFormUtils'];
     constructor(IgniteLegacyUtils, IgniteEventGroups, IgniteConfirm, IgniteVersion, $scope, Clusters, IgniteFormUtils) {
@@ -89,6 +91,11 @@ export default class ClusterEditFormController {
 
         this.$scope.ui = this.IgniteFormUtils.formUI();
         this.$scope.ui.loadedPanels = ['checkpoint', 'serviceConfiguration', 'odbcConfiguration'];
+
+        this.formActions = [
+            {text: 'Save', icon: 'checkmark', click: () => this.save()},
+            {text: 'Save and Download', icon: 'download', click: () => this.save(true)}
+        ];
     }
 
     $onChanges(changes) {
@@ -120,10 +127,10 @@ export default class ClusterEditFormController {
         return [this.cluster, this.clonedCluster].map(this.Clusters.normalize);
     }
 
-    save() {
+    save(download) {
         if (this.$scope.ui.inputForm.$invalid)
             return this.IgniteFormUtils.triggerValidation(this.$scope.ui.inputForm, this.$scope);
-        this.onSave({$event: cloneDeep(this.clonedCluster)});
+        this.onSave({$event: {cluster: cloneDeep(this.clonedCluster), download}});
     }
 
     reset = () => this.clonedCluster = cloneDeep(this.cluster);

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/template.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/template.tpl.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/template.tpl.pug
index c2bfd68..d5cb909 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/template.tpl.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/template.tpl.pug
@@ -16,7 +16,7 @@
 
 include /app/helpers/jade/mixins
 
-form(id='cluster' name='ui.inputForm' novalidate ng-submit='$ctrl.save()')
+form(id='cluster' name='ui.inputForm' novalidate)
     .panel-group
         include ./templates/general
 
@@ -72,7 +72,6 @@ form(id='cluster' name='ui.inputForm' novalidate ng-submit='$ctrl.save()')
 
 .pc-form-actions-panel(n_g-show='$ctrl.$scope.selectedItem')
     button-preview-project(cluster='$ctrl.cluster' ng-hide='$ctrl.isNew')
-    button-download-project(cluster='$ctrl.cluster' ng-hide='$ctrl.isNew')
 
     .pc-form-actions-panel__right-after
 
@@ -81,7 +80,4 @@ form(id='cluster' name='ui.inputForm' novalidate ng-submit='$ctrl.save()')
         ng-click='$ctrl.confirmAndReset()'
     )
         | Cancel
-    button.btn-ignite.btn-ignite--success(
-        form='cluster'
-        type='submit'
-    ) Save
\ No newline at end of file
+    pc-split-button(actions=`::$ctrl.formActions`)

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/binary.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/binary.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/binary.pug
index 6c1b246..75f6756 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/binary.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/binary.pug
@@ -40,7 +40,7 @@ panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`)
                         +tooltip(`Configuration properties for binary types`)
                     .ignite-form-field__control
                         -var items = model + '.typeConfigurations'
-                        list-editable(ng-model=items name='typeŠ”onfigurations')
+                        list-editable.pc-list-editable-with-form-grid(ng-model=items name='typeŠ”onfigurations')
                             list-editable-item-edit.pc-form-grid-row
                                 - form = '$parent.form'
                                 .pc-form-grid-col-60

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/cache-key-cfg.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/cache-key-cfg.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/cache-key-cfg.pug
index abc8ff1..0b34ce4 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/cache-key-cfg.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/cache-key-cfg.pug
@@ -30,7 +30,7 @@ panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`)
                     +ignite-form-field__label('Cache key configuration:', '"cacheKeyConfiguration"')
                     .ignite-form-field__control
                         -let items = model
-                        list-editable(ng-model=items name='cacheKeyConfiguration')
+                        list-editable.pc-list-editable-with-form-grid(ng-model=items name='cacheKeyConfiguration')
                             list-editable-item-edit.pc-form-grid-row
                                 - form = '$parent.form'
                                 .pc-form-grid-col-60

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/checkpoint.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/checkpoint.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/checkpoint.pug
index b00c98c..7d56f14 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/checkpoint.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/checkpoint.pug
@@ -32,7 +32,7 @@ panel-collapsible(ng-form=form)
                 .ignite-form-field
                     +ignite-form-field__label('Checkpoint SPI configurations:', '"checkpointSPIConfigurations"')
                     .ignite-form-field__control
-                        list-editable(ng-model=model name='checkpointSPIConfigurations')
+                        list-editable.pc-list-editable-with-form-grid(ng-model=model name='checkpointSPIConfigurations')
                             list-editable-item-edit(item-name='$checkpointSPI').pc-form-grid-row
                                 .pc-form-grid-col-60
                                     +dropdown-required('Checkpoint SPI:', '$checkpointSPI.kind', '"checkpointKind"', 'true', 'true', 'Choose checkpoint configuration variant', '[\

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/data-storage.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/data-storage.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/data-storage.pug
index 06a5a4a..ea27c3c 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/data-storage.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/data-storage.pug
@@ -188,7 +188,10 @@ panel-collapsible(ng-show='$ctrl.available("2.3.0")' ng-form=form on-open=`ui.lo
                 .ignite-form-field
                     .ignite-form-field__label Data region configurations
                     .ignite-form-field__control
-                        list-editable(name='dataRegionConfigurations' ng-model=dataRegionConfigurations)
+                        list-editable.pc-list-editable-with-form-grid(
+                            name='dataRegionConfigurations'
+                            ng-model=dataRegionConfigurations
+                        )
                             list-editable-item-edit.pc-form-grid-row
                                 - form = '$parent.form'
                                 +data-region-form({

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/failover.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/failover.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/failover.pug
index 2e92f83..85c441e 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/failover.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/failover.pug
@@ -36,7 +36,7 @@ panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`)
                 +number('Client failure detection timeout:', model + '.clientFailureDetectionTimeout', '"clientFailureDetectionTimeout"', 'true',
                     '30000', '1', 'Failure detection timeout is used to determine how long the communication or discovery SPIs should wait before considering a remote connection failed')
 
-            .pc-form-grid-col-60(ng-init='failoverSpiTbl={type: "failoverSpi", model: "failoverSpi", focusId: "kind", ui: "failover-table"}')
+            .pc-form-grid-col-60
                 mixin clusters-failover-spi
                     .ignite-form-field
                         +ignite-form-field__label('Failover SPI configurations:', '"failoverSpi"')
@@ -44,10 +44,9 @@ panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`)
                         .ignite-form-field__control
                             -let items = failoverSpi
 
-                            list-editable(ng-model=items name='failoverSpi')
-                                list-editable-item-edit
-                                    - form = '$parent.form'
-                                    .settings-row
+                            list-editable.pc-list-editable-with-form-grid(ng-model=items name='failoverSpi')
+                                list-editable-item-edit.pc-form-grid-row
+                                    .pc-form-grid-col-60
                                         +sane-ignite-form-field-dropdown({
                                             required: true,
                                             label: 'Failover SPI:',
@@ -66,13 +65,13 @@ panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`)
                                             </ul>`
                                         })
 
-                                    .settings-row(ng-show='$item.kind === "JobStealing"')
+                                    .pc-form-grid-col-60(ng-show='$item.kind === "JobStealing"')
                                         +number('Maximum failover attempts:', '$item.JobStealing.maximumFailoverAttempts', '"jsMaximumFailoverAttempts"', 'true', '5', '0',
                                             'Maximum number of attempts to execute a failed job on another node')
-                                    .settings-row(ng-show='$item.kind === "Always"')
+                                    .pc-form-grid-col-60(ng-show='$item.kind === "Always"')
                                         +number('Maximum failover attempts:', '$item.Always.maximumFailoverAttempts', '"alwaysMaximumFailoverAttempts"', 'true', '5', '0',
                                             'Maximum number of attempts to execute a failed job on another node')
-                                    .settings-row(ng-show=failoverCustom)
+                                    .pc-form-grid-col-60(ng-show=failoverCustom)
                                         +java-class('SPI implementation', '$item.Custom.class', '"failoverSpiClass"', 'true', failoverCustom,
                                             'Custom FailoverSpi implementation class name.', failoverCustom)
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/load-balancing.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/load-balancing.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/load-balancing.pug
index ff817e1..f3b4dfe 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/load-balancing.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/load-balancing.pug
@@ -36,7 +36,10 @@ panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`)
                     .ignite-form-field__control
                         -let items = loadBalancingSpi
 
-                        list-editable(ng-model=items name='loadBalancingConfigurations')
+                        list-editable.pc-list-editable-with-legacy-settings-rows(
+                            ng-model=items
+                            name='loadBalancingConfigurations'
+                        )
                             list-editable-item-edit
                                 - form = '$parent.form'
                                 .settings-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/memory.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/memory.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/memory.pug
index 831adea..bc355d1 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/memory.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/memory.pug
@@ -98,7 +98,7 @@ panel-collapsible(
                             .ignite-form-field__control
                                 -let items = memoryPolicies
 
-                                list-editable(ng-model=items name='memoryPolicies')
+                                list-editable.pc-list-editable-with-form-grid(ng-model=items name='memoryPolicies')
                                     list-editable-item-edit.pc-form-grid-row
                                         - form = '$parent.form'
                                         .pc-form-grid-col-60

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/service.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/service.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/service.pug
index a244602..b37067b 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/service.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/templates/service.pug
@@ -32,15 +32,9 @@ panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`)
                     .ignite-form-field__control
                         -let items = model
 
-                        list-editable(ng-model=items name='serviceConfigurations')
-                            list-editable-item-edit
-                                - form = '$parent.form'
-                    
-                                -var nodeFilter = '$item.nodeFilter';
-                                -var nodeFilterKind = nodeFilter + '.kind';
-                                -var customFilter = nodeFilterKind + ' === "Custom"'
-
-                                .settings-row
+                        list-editable.pc-list-editable-with-form-grid(ng-model=items name='serviceConfigurations')
+                            list-editable-item-edit.pc-form-grid-row
+                                .pc-form-grid-col-60
                                     +sane-ignite-form-field-text({
                                         label: 'Name:',
                                         model: '$item.name',
@@ -56,23 +50,23 @@ panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`)
                                         ng-model-options='{allowInvalid: true}'
                                     )
                                         +form-field-feedback('"serviceName', 'uniqueName', 'Service with that name is already configured')
-                                .settings-row
+                                .pc-form-grid-col-60
                                     +java-class('Service class', '$item.service', '"serviceService"', 'true', 'true', 'Service implementation class name')
-                                .settings-row
+                                .pc-form-grid-col-60
                                     +number('Max per node count:', '$item.maxPerNodeCount', '"ServiceMaxPerNodeCount"', 'true', 'Unlimited', '0',
                                         'Maximum number of deployed service instances on each node.<br/>' +
                                         'Zero for unlimited')
-                                .settings-row
+                                .pc-form-grid-col-60
                                     +number('Total count:', '$item.totalCount', '"serviceTotalCount"', 'true', 'Unlimited', '0',
                                         'Total number of deployed service instances in the cluster.<br/>' +
                                         'Zero for unlimited')
-                                .settings-row
+                                .pc-form-grid-col-60
                                     +dropdown-required-empty('Cache:', '$item.cache', '"serviceCache"', 'true', 'false',
                                         'Choose cache', 'No caches configured for current cluster', '$ctrl.cachesMenu', 'Cache name used for key-to-node affinity calculation')(
                                         pc-is-in-collection='$ctrl.clonedCluster.caches'
-                                    ).settings-row
-                                        +form-field-feedback(form, 'isInCollection', `Cluster doesn't have such a cache`)
-                                .settings-row
+                                    )
+                                        +form-field-feedback(_, 'isInCollection', `Cluster doesn't have such a cache`)
+                                .pc-form-grid-col-60
                                     +text('Affinity key:', '$item.affinityKey', '"serviceAffinityKey"', 'false', 'Input affinity key',
                                         'Affinity key used for key-to-node affinity calculation')
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/igfs-edit-form/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/igfs-edit-form/controller.js b/modules/web-console/frontend/app/components/page-configure-advanced/components/igfs-edit-form/controller.js
index 6812002..b787ce8 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/igfs-edit-form/controller.js
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/igfs-edit-form/controller.js
@@ -19,6 +19,9 @@ import cloneDeep from 'lodash/cloneDeep';
 import get from 'lodash/get';
 
 export default class IgfsEditFormController {
+    /** @type {ng.ICompiledExpression} */
+    onSave;
+
     static $inject = ['IgniteConfirm', 'IgniteVersion', '$scope', 'IGFSs', 'IgniteFormUtils'];
     constructor( IgniteConfirm, IgniteVersion, $scope, IGFSs, IgniteFormUtils) {
         Object.assign(this, { IgniteConfirm, IgniteVersion, $scope, IGFSs, IgniteFormUtils});
@@ -28,6 +31,11 @@ export default class IgfsEditFormController {
 
         this.$scope.ui = this.IgniteFormUtils.formUI();
         this.$scope.ui.loadedPanels = ['general', 'secondaryFileSystem', 'misc'];
+
+        this.formActions = [
+            {text: 'Save', icon: 'checkmark', click: () => this.save()},
+            {text: 'Save and Download', icon: 'download', click: () => this.save(true)}
+        ];
     }
 
     $onChanges(changes) {
@@ -44,10 +52,10 @@ export default class IgfsEditFormController {
     getValuesToCompare() {
         return [this.igfs, this.$scope.backupItem].map(this.IGFSs.normalize);
     }
-    save() {
+    save(download) {
         if (this.$scope.ui.inputForm.$invalid)
             return this.IgniteFormUtils.triggerValidation(this.$scope.ui.inputForm, this.$scope);
-        this.onSave({$event: cloneDeep(this.$scope.backupItem)});
+        this.onSave({$event: {igfs: cloneDeep(this.$scope.backupItem), download}});
     }
     reset = (forReal) => forReal ? this.$scope.backupItem = cloneDeep(this.igfs) : void 0;
     confirmAndReset() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/igfs-edit-form/template.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/igfs-edit-form/template.tpl.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/igfs-edit-form/template.tpl.pug
index f505e58..a85a33c 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/igfs-edit-form/template.tpl.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/igfs-edit-form/template.tpl.pug
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-form(id='igfs' name='ui.inputForm' novalidate ng-submit='$ctrl.save()')
+form(id='igfs' name='ui.inputForm' novalidate)
     include ./templates/general
 
     include ./templates/secondary
@@ -32,7 +32,4 @@ form(id='igfs' name='ui.inputForm' novalidate ng-submit='$ctrl.save()')
         ng-click='$ctrl.confirmAndReset()'
     )
         | Cancel
-    button.btn-ignite.btn-ignite--success(
-        form='igfs'
-        type='submit'
-    ) Save
\ No newline at end of file
+    pc-split-button(actions=`::$ctrl.formActions`)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/model-edit-form/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/model-edit-form/controller.js b/modules/web-console/frontend/app/components/page-configure-advanced/components/model-edit-form/controller.js
index 20384d5..60cb95f 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/model-edit-form/controller.js
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/model-edit-form/controller.js
@@ -28,6 +28,9 @@ import {Confirm} from 'app/services/Confirm.service';
 export default class ModelEditFormController {
     /** @type {ig.config.model.DomainModel} */
     model;
+    /** @type {ng.ICompiledExpression} */
+    onSave;
+
     static $inject = ['ModalImportModels', 'IgniteErrorPopover', 'IgniteLegacyUtils', Confirm.name, 'ConfigChangesGuard', IgniteVersion.name, '$scope', Models.name, 'IgniteFormUtils'];
     /**
      * @param {ModalImportModels} ModalImportModels
@@ -54,6 +57,11 @@ export default class ModelEditFormController {
         this.$scope.javaBuiltInClasses = this.LegacyUtils.javaBuiltInClasses;
         this.$scope.supportedJdbcTypes = this.LegacyUtils.mkOptions(this.LegacyUtils.SUPPORTED_JDBC_TYPES);
         this.$scope.supportedJavaTypes = this.LegacyUtils.mkOptions(this.LegacyUtils.javaBuiltInTypes);
+
+        this.formActions = [
+            {text: 'Save', icon: 'checkmark', click: () => this.save()},
+            {text: 'Save and Download', icon: 'download', click: () => this.save(true)}
+        ];
     }
 
     /**
@@ -172,11 +180,11 @@ export default class ModelEditFormController {
     getValuesToCompare() {
         return [this.model, this.$scope.backupItem].map(this.Models.normalize);
     }
-    save() {
+    save(download) {
         if (this.$scope.ui.inputForm.$invalid)
             return this.IgniteFormUtils.triggerValidation(this.$scope.ui.inputForm, this.$scope);
         if (!this.validate(this.$scope.backupItem)) return;
-        this.onSave({$event: cloneDeep(this.$scope.backupItem)});
+        this.onSave({$event: {model: cloneDeep(this.$scope.backupItem), download}});
     }
     reset = (forReal) => forReal ? this.$scope.backupItem = cloneDeep(this.model) : void 0;
     confirmAndReset() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/model-edit-form/template.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/model-edit-form/template.tpl.pug b/modules/web-console/frontend/app/components/page-configure-advanced/components/model-edit-form/template.tpl.pug
index 78ae769..4751861 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/model-edit-form/template.tpl.pug
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/model-edit-form/template.tpl.pug
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-form(id='model' name='ui.inputForm' novalidate ng-submit='$ctrl.save()')
+form(id='model' name='ui.inputForm' novalidate)
     include ./templates/general
     include ./templates/query
     include ./templates/store
@@ -26,7 +26,4 @@ form(id='model' name='ui.inputForm' novalidate ng-submit='$ctrl.save()')
         ng-click='$ctrl.confirmAndReset()'
     )
         | Cancel
-    button.btn-ignite.btn-ignite--success(
-        form='model'
-        type='submit'
-    ) Save
+    pc-split-button(actions=`::$ctrl.formActions`)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-caches/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-caches/controller.js b/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-caches/controller.js
index 60244e5..ecb7a15 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-caches/controller.js
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-caches/controller.js
@@ -168,7 +168,7 @@ export default class Controller {
         this.$state.go('base.configuration.edit.advanced.caches.cache', {cacheID});
     }
 
-    save(cache) {
-        this.ConfigureState.dispatchAction(advancedSaveCache(cache));
+    save({cache, download}) {
+        this.ConfigureState.dispatchAction(advancedSaveCache(cache, download));
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-cluster/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-cluster/controller.js b/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-cluster/controller.js
index ad2eed4..2b05940 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-cluster/controller.js
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-cluster/controller.js
@@ -45,7 +45,7 @@ export default class PageConfigureAdvancedCluster {
         this.isBlocked$ = clusterID$;
     }
 
-    save(cluster) {
-        this.ConfigureState.dispatchAction(advancedSaveCluster(cluster));
+    save({cluster, download}) {
+        this.ConfigureState.dispatchAction(advancedSaveCluster(cluster, download));
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-igfs/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-igfs/controller.js b/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-igfs/controller.js
index 09d139d..dd0e5da 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-igfs/controller.js
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-igfs/controller.js
@@ -128,8 +128,8 @@ export default class PageConfigureAdvancedIGFS {
     edit(igfsID) {
         this.$state.go('base.configuration.edit.advanced.igfs.igfs', {igfsID});
     }
-    save(igfs) {
-        this.ConfigureState.dispatchAction(advancedSaveIGFS(igfs));
+    save({igfs, download}) {
+        this.ConfigureState.dispatchAction(advancedSaveIGFS(igfs, download));
     }
     remove(itemIDs) {
         this.ConfigureState.dispatchAction(

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-models/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-models/controller.js b/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-models/controller.js
index 7771735..d2a07e8 100644
--- a/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-models/controller.js
+++ b/modules/web-console/frontend/app/components/page-configure-advanced/components/page-configure-advanced-models/controller.js
@@ -156,8 +156,8 @@ export default class PageConfigureAdvancedModels {
         this.$state.go('base.configuration.edit.advanced.models.model', {modelID});
     }
 
-    save(model) {
-        this.ConfigureState.dispatchAction(advancedSaveModel(model));
+    save({model, download}) {
+        this.ConfigureState.dispatchAction(advancedSaveModel(model, download));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-basic/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-basic/controller.js b/modules/web-console/frontend/app/components/page-configure-basic/controller.js
index e764ac6..255bbe5 100644
--- a/modules/web-console/frontend/app/components/page-configure-basic/controller.js
+++ b/modules/web-console/frontend/app/components/page-configure-basic/controller.js
@@ -136,12 +136,12 @@ export default class PageConfigureBasicController {
 
         this.formActionsMenu = [
             {
-                text: 'Save changes and download project',
+                text: 'Save and Download',
                 click: () => this.save(true),
                 icon: 'download'
             },
             {
-                text: 'Save changes',
+                text: 'Save',
                 click: () => this.save(),
                 icon: 'checkmark'
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-basic/style.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-basic/style.scss b/modules/web-console/frontend/app/components/page-configure-basic/style.scss
index 64d1f2f..7c2108a 100644
--- a/modules/web-console/frontend/app/components/page-configure-basic/style.scss
+++ b/modules/web-console/frontend/app/components/page-configure-basic/style.scss
@@ -46,31 +46,6 @@ page-configure-basic {
         }
     }
 
-    .pcb-buttons-group {
-        display: flex;
-        flex-direction: row;
-
-        &>*+* {
-            margin-left: 10px;
-        }
-
-        .link-primary + .link-primary {
-            margin-left: 40px;
-        }
-    }
-
-    .pcb-select-existing-cache {
-        position: relative;
-
-        button {
-            background: none;
-            border: none;
-            padding: 0;
-            margin: 0;
-            outline: none !important;
-        }
-    }
-
     .pcb-section-notification {
         font-size: 14px;
         color: #757575;

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure-basic/template.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure-basic/template.pug b/modules/web-console/frontend/app/components/page-configure-basic/template.pug
index 3bcb216..e85b3d8 100644
--- a/modules/web-console/frontend/app/components/page-configure-basic/template.pug
+++ b/modules/web-console/frontend/app/components/page-configure-basic/template.pug
@@ -171,7 +171,6 @@ form(novalidate name=form)
         
     .pc-form-actions-panel
         button-preview-project(ng-hide='$ctrl.isNew$|async:this' cluster=model)
-        button-download-project(ng-hide='$ctrl.isNew$|async:this' cluster=model)
 
         .pc-form-actions-panel__right-after
         button.btn-ignite.btn-ignite--link-success(
@@ -179,16 +178,4 @@ form(novalidate name=form)
             ng-click='$ctrl.confirmAndReset()'
         )
             | Cancel
-        .btn-ignite-group
-            button.btn-ignite.btn-ignite--success(
-                ng-click='::$ctrl.formActionsMenu[0].click()'
-                type='button'
-            )
-                svg(ignite-icon='{{ ::$ctrl.formActionsMenu[0].icon }}').icon-left
-                | {{ ::$ctrl.formActionsMenu[0].text }}
-            button.btn-ignite.btn-ignite--success(
-                bs-dropdown='$ctrl.formActionsMenu'
-                data-placement='top-right'
-                type='button'
-            )
-                span.icon.fa.fa-caret-up
\ No newline at end of file
+        pc-split-button(actions=`::$ctrl.formActionsMenu`)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/component.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/component.js b/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/component.js
new file mode 100644
index 0000000..c891f1c
--- /dev/null
+++ b/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/component.js
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import template from './template.pug';
+import controller from './controller';
+
+export default {
+    controller,
+    template,
+    bindings: {
+        actions: '<'
+    }
+};

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/controller.js b/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/controller.js
new file mode 100644
index 0000000..8aa9495
--- /dev/null
+++ b/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/controller.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * @typedef {{icon: string, text: string, click: ng.ICompiledExpression}} ActionMenuItem
+ */
+
+/**
+ * @typedef {Array<ActionMenuItem>} ActionsMenu
+ */
+
+/**
+ * Groups multiple buttons into a single button with all but first buttons in a dropdown
+ */
+export default class SplitButton {
+    /** @type {ActionsMenu} */
+    actions = [];
+
+    static $inject = ['$element'];
+
+    /**
+     * @param {JQLite} $element Component root element
+     */
+    constructor($element, $transclude) {
+        this.$element = $element;
+    }
+
+    $onInit() {
+        this.$element[0].classList.add('btn-ignite-group');
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/index.js b/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/index.js
new file mode 100644
index 0000000..4b4b816
--- /dev/null
+++ b/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/index.js
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import angular from 'angular';
+import component from './component';
+
+export default angular
+    .module('ignite-console.page-configure.pc-split-button', [])
+    .component('pcSplitButton', component);

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/template.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/template.pug b/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/template.pug
new file mode 100644
index 0000000..d44d543
--- /dev/null
+++ b/modules/web-console/frontend/app/components/page-configure/components/pc-split-button/template.pug
@@ -0,0 +1,28 @@
+//-
+    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.
+
+button.btn-ignite.btn-ignite--success(
+    ng-click='$ctrl.actions[0].click()'
+    type='button'
+)
+    svg(ignite-icon='{{ ::$ctrl.actions[0].icon }}').icon-left
+    | {{ ::$ctrl.actions[0].text }}
+button.btn-ignite.btn-ignite--success(
+    bs-dropdown='$ctrl.actions'
+    data-placement='top-right'
+    type='button'
+)
+    span.icon.fa.fa-caret-down
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/index.js b/modules/web-console/frontend/app/components/page-configure/index.js
index 34b8cfe..0b254a0 100644
--- a/modules/web-console/frontend/app/components/page-configure/index.js
+++ b/modules/web-console/frontend/app/components/page-configure/index.js
@@ -46,6 +46,7 @@ import buttonImportModels from './components/button-import-models';
 import buttonDownloadProject from './components/button-download-project';
 import buttonPreviewProject from './components/button-preview-project';
 import previewPanel from './components/preview-panel';
+import pcSplitButton from './components/pc-split-button';
 
 import {errorState} from './transitionHooks/errorState';
 import {default as ActivitiesData} from 'app/core/activities/Activities.data';
@@ -106,7 +107,8 @@ export default angular
         buttonImportModels.name,
         buttonDownloadProject.name,
         buttonPreviewProject.name,
-        previewPanel.name
+        previewPanel.name,
+        pcSplitButton.name
     ])
     .config(registerStates)
     .config(['DefaultStateProvider', (DefaultState) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure/store/actionCreators.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/store/actionCreators.js b/modules/web-console/frontend/app/components/page-configure/store/actionCreators.js
index c911426..d6b1749 100644
--- a/modules/web-console/frontend/app/components/page-configure/store/actionCreators.js
+++ b/modules/web-console/frontend/app/components/page-configure/store/actionCreators.js
@@ -153,10 +153,10 @@ export const completeConfiguration = (configuration) => ({
     configuration
 });
 
-export const advancedSaveCluster = (cluster) => ({type: ADVANCED_SAVE_CLUSTER, cluster});
-export const advancedSaveCache = (cache) => ({type: ADVANCED_SAVE_CACHE, cache});
-export const advancedSaveIGFS = (igfs) => ({type: ADVANCED_SAVE_IGFS, igfs});
-export const advancedSaveModel = (model) => ({type: ADVANCED_SAVE_MODEL, model});
+export const advancedSaveCluster = (cluster, download = false) => ({type: ADVANCED_SAVE_CLUSTER, cluster, download});
+export const advancedSaveCache = (cache, download = false) => ({type: ADVANCED_SAVE_CACHE, cache, download});
+export const advancedSaveIGFS = (igfs, download = false) => ({type: ADVANCED_SAVE_IGFS, igfs, download});
+export const advancedSaveModel = (model, download = false) => ({type: ADVANCED_SAVE_MODEL, model, download});
 
 export const basicSave = (cluster) => ({type: BASIC_SAVE, cluster});
 export const basicSaveAndDownload = (cluster) => ({type: BASIC_SAVE_AND_DOWNLOAD, cluster});

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure/store/effects.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/store/effects.js b/modules/web-console/frontend/app/components/page-configure/store/effects.js
index 3ab216a..42c4023 100644
--- a/modules/web-console/frontend/app/components/page-configure/store/effects.js
+++ b/modules/web-console/frontend/app/components/page-configure/store/effects.js
@@ -23,7 +23,6 @@ import {merge} from 'rxjs/observable/merge';
 import {empty} from 'rxjs/observable/empty';
 import {of} from 'rxjs/observable/of';
 import {fromPromise} from 'rxjs/observable/fromPromise';
-import {uniqueName} from 'app/utils/uniqueName';
 import uniq from 'lodash/uniq';
 
 import {
@@ -35,7 +34,7 @@ import {
     shortIGFSsActionTypes,
     modelsActionTypes,
     igfssActionTypes
-} from './../reducer';
+} from '../reducer';
 
 import {
     REMOVE_CLUSTER_ITEMS,
@@ -43,6 +42,7 @@ import {
     CONFIRM_CLUSTERS_REMOVAL,
     CONFIRM_CLUSTERS_REMOVAL_OK,
     COMPLETE_CONFIGURATION,
+    ADVANCED_SAVE_COMPLETE_CONFIGURATION,
     ADVANCED_SAVE_CLUSTER,
     ADVANCED_SAVE_CACHE,
     ADVANCED_SAVE_IGFS,
@@ -141,7 +141,7 @@ export default class ConfigEffects {
             ].filter((v) => v)));
 
         this.saveCompleteConfigurationEffect$ = this.ConfigureState.actions$
-            .let(ofType('ADVANCED_SAVE_COMPLETE_CONFIGURATION'))
+            .let(ofType(ADVANCED_SAVE_COMPLETE_CONFIGURATION))
             .switchMap((action) => {
                 const actions = [
                     {
@@ -427,9 +427,21 @@ export default class ConfigEffects {
             .do((a) => this.configurationDownload.downloadClusterConfiguration(a.changedItems.cluster))
             .ignoreElements();
 
+        this.advancedDownloadAfterSaveEffect$ = merge(
+            this.ConfigureState.actions$.let(ofType(ADVANCED_SAVE_CLUSTER)),
+            this.ConfigureState.actions$.let(ofType(ADVANCED_SAVE_CACHE)),
+            this.ConfigureState.actions$.let(ofType(ADVANCED_SAVE_IGFS)),
+            this.ConfigureState.actions$.let(ofType(ADVANCED_SAVE_MODEL)),
+        )
+            .filter((a) => a.download)
+            .zip(this.ConfigureState.actions$.let(ofType('ADVANCED_SAVE_COMPLETE_CONFIGURATION_OK')))
+            .pluck('1')
+            .do((a) => this.configurationDownload.downloadClusterConfiguration(a.changedItems.cluster))
+            .ignoreElements();
+
         this.advancedSaveRedirectEffect$ = this.ConfigureState.actions$
             .let(ofType('ADVANCED_SAVE_COMPLETE_CONFIGURATION_OK'))
-            .withLatestFrom(this.ConfigureState.actions$.let(ofType('ADVANCED_SAVE_COMPLETE_CONFIGURATION')))
+            .withLatestFrom(this.ConfigureState.actions$.let(ofType(ADVANCED_SAVE_COMPLETE_CONFIGURATION)))
             .pluck('1', 'changedItems')
             .map((req) => {
                 const firstChangedItem = Object.keys(req).filter((k) => k !== 'cluster')
@@ -577,7 +589,7 @@ export default class ConfigEffects {
         )
             .withLatestFrom(this.ConfigureState.state$.pluck('edit'))
             .map(([action, edit]) => ({
-                type: 'ADVANCED_SAVE_COMPLETE_CONFIGURATION',
+                type: ADVANCED_SAVE_COMPLETE_CONFIGURATION,
                 changedItems: _applyChangedIDs(edit, action)
             }));
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/c47e3048/modules/web-console/frontend/app/components/page-configure/style.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/style.scss b/modules/web-console/frontend/app/components/page-configure/style.scss
index 94a3ebc..03b50fb 100644
--- a/modules/web-console/frontend/app/components/page-configure/style.scss
+++ b/modules/web-console/frontend/app/components/page-configure/style.scss
@@ -186,6 +186,22 @@ list-editable .pc-form-group__text-title {
     }
 }
 
+// Add this class to list-editable when a pc-form-grid is used inside list-editable-item-edit
+.pc-list-editable-with-form-grid > .le-body > .le-row {
+    & > .le-row-index,
+    & > .le-row-cross {
+        margin-top: 28px;
+    }
+}
+
+// Add this class to list-editable when legacy settings-row classes are used inside list-editable-item-edit
+.pc-list-editable-with-legacy-settings-rows > .le-body > .le-row {
+    & > .le-row-index,
+    & > .le-row-cross {
+        margin-top: 18px;
+    }
+}
+
 .pc-form-grid-row {
     &>.pc-form-grid-col-10 {
         flex-basis: calc(100% / 6);


Mime
View raw message