IGNITE-8200 Web Console: Override clonedCluster in cluster-edit-form if caches 
or models have changed.
    This improves interop with "import from DB" feature, which might update 
caches/models of cluster currently opened for editing.
    The import dialog works as a separate state, so the form change detection 
mechanism ensures that any changes to the original
    cluster are safe and won't interfere with changes made by user in cluster 
edit form.


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

Branch: refs/heads/ignite-7708
Commit: 77316692f14d083138d7515affd2d3f225b709e0
Parents: 3cebf91
Author: Ilya Borisov <klast...@gmail.com>
Authored: Tue Apr 17 17:15:57 2018 +0700
Committer: Alexey Kuznetsov <akuznet...@apache.org>
Committed: Tue Apr 17 17:15:57 2018 +0700

----------------------------------------------------------------------
 .../components/cluster-edit-form/controller.js  | 24 +++++-
 .../cluster-edit-form/controller.spec.js        | 81 ++++++++++++++++++++
 2 files changed, 102 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/77316692/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 35b43e0..0207729 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
@@ -17,6 +17,7 @@
 
 import cloneDeep from 'lodash/cloneDeep';
 import get from 'lodash/get';
+import isEqual from 'lodash/isEqual';
 import _ from 'lodash';
 
 export default class ClusterEditFormController {
@@ -29,9 +30,11 @@ export default class ClusterEditFormController {
     constructor(IgniteLegacyUtils, IgniteEventGroups, IgniteConfirm, 
IgniteVersion, $scope, Clusters, IgniteFormUtils) {
         Object.assign(this, {IgniteLegacyUtils, IgniteEventGroups, 
IgniteConfirm, IgniteVersion, $scope, Clusters, IgniteFormUtils});
     }
+
     $onDestroy() {
         this.subscription.unsubscribe();
     }
+
     $onInit() {
         this.available = this.IgniteVersion.available.bind(this.IgniteVersion);
 
@@ -87,10 +90,9 @@ export default class ClusterEditFormController {
         this.$scope.ui = this.IgniteFormUtils.formUI();
         this.$scope.ui.loadedPanels = ['checkpoint', 'serviceConfiguration', 
'odbcConfiguration'];
     }
+
     $onChanges(changes) {
-        if (
-            'cluster' in changes && get(this.clonedCluster, '_id') !== 
get(this.cluster, '_id')
-        ) {
+        if ('cluster' in changes && this.shouldOverwriteValue(this.cluster, 
this.clonedCluster)) {
             this.clonedCluster = cloneDeep(changes.cluster.currentValue);
             if (this.$scope.ui && this.$scope.ui.inputForm) {
                 this.$scope.ui.inputForm.$setPristine();
@@ -100,14 +102,30 @@ export default class ClusterEditFormController {
         if ('caches' in changes)
             this.cachesMenu = (changes.caches.currentValue || []).map((c) => 
({label: c.name, value: c._id}));
     }
+
+    /**
+     * The form should accept incoming cluster value if:
+     * 1. It has different _id ("new" to real id).
+     * 2. Different caches or models (imported from DB).
+     * @param {Object} a Incoming value.
+     * @param {Object} b Current value.
+     */
+    shouldOverwriteValue(a, b) {
+        return get(a, '_id') !== get(b, '_id') ||
+            !isEqual(get(a, 'caches'), get(b, 'caches')) ||
+            !isEqual(get(a, 'models'), get(b, 'models'));
+    }
+
     getValuesToCompare() {
         return [this.cluster, this.clonedCluster].map(this.Clusters.normalize);
     }
+
     save() {
         if (this.$scope.ui.inputForm.$invalid)
             return 
this.IgniteFormUtils.triggerValidation(this.$scope.ui.inputForm, this.$scope);
         this.onSave({$event: cloneDeep(this.clonedCluster)});
     }
+
     reset = () => this.clonedCluster = cloneDeep(this.cluster);
     confirmAndReset() {
         return this.IgniteConfirm.confirm('Are you sure you want to undo all 
changes for current cluster?')

http://git-wip-us.apache.org/repos/asf/ignite/blob/77316692/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/controller.spec.js
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/controller.spec.js
 
b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/controller.spec.js
new file mode 100644
index 0000000..cac888f
--- /dev/null
+++ 
b/modules/web-console/frontend/app/components/page-configure-advanced/components/cluster-edit-form/controller.spec.js
@@ -0,0 +1,81 @@
+/*
+ * 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 'mocha';
+import {assert} from 'chai';
+import {spy} from 'sinon';
+import Controller from './controller';
+
+suite('cluster-edit-form controller', () => {
+    test('cluster binding changes', () => {
+        const $scope = {
+            ui: {
+                inputForm: {
+                    $setPristine: spy(),
+                    $setUntouched: spy()
+                }
+            }
+        };
+
+        const mocks = Controller.$inject.map((token) => {
+            switch (token) {
+                case '$scope': return $scope;
+                default: return null;
+            }
+        });
+
+        const changeBoundCluster = ($ctrl, cluster) => {
+            $ctrl.cluster = cluster;
+            $ctrl.$onChanges({
+                cluster: {
+                    currentValue: cluster
+                }
+            });
+        };
+
+        const $ctrl = new Controller(...mocks);
+
+        const cluster1 = {_id: 1, caches: [1, 2, 3]};
+        const cluster2 = {_id: 1, caches: [1, 2, 3, 4, 5, 6], models: [1, 2, 
3]};
+        const cluster3 = {_id: 1, caches: [1, 2, 3, 4, 5, 6], models: [1, 2, 
3], name: 'Foo'};
+
+        changeBoundCluster($ctrl, cluster1);
+
+        assert.notEqual($ctrl.clonedCluster, cluster1, 'Cloned cluster is 
really cloned');
+        assert.deepEqual($ctrl.clonedCluster, cluster1, 'Cloned cluster is 
really a clone of incloming value');
+        assert.equal(1, $scope.ui.inputForm.$setPristine.callCount, 'Sets form 
pristine when cluster value changes');
+        assert.equal(1, $scope.ui.inputForm.$setUntouched.callCount, 'Sets 
form untouched when cluster value changes');
+
+        changeBoundCluster($ctrl, cluster2);
+
+        assert.deepEqual(
+            $ctrl.clonedCluster,
+            cluster2,
+            'Overrides clonedCluster if incoming cluster has same id but 
different caches or models'
+        );
+        assert.equal(2, $scope.ui.inputForm.$setPristine.callCount, 'Sets form 
pristine when bound cluster caches/models change');
+        assert.equal(2, $scope.ui.inputForm.$setUntouched.callCount, 'Sets 
form untouched when bound cluster caches/models change');
+
+        changeBoundCluster($ctrl, cluster3);
+
+        assert.deepEqual(
+            $ctrl.clonedCluster,
+            cluster2,
+            'Does not change cloned cluster value if fields other than id, 
chaches and models change'
+        );
+    });
+});

Reply via email to