Repository: ambari
Updated Branches:
  refs/heads/trunk 53dbf69f9 -> 5a2b89464


AMBARI-9625. Autoclosing of expanding elements on Hosts page (alexantonenko)


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

Branch: refs/heads/trunk
Commit: 5a2b894644334e06e3567f6936858db1873ecc5d
Parents: 53dbf69
Author: Alex Antonenko <hiv...@gmail.com>
Authored: Fri Feb 13 22:54:59 2015 +0200
Committer: Alex Antonenko <hiv...@gmail.com>
Committed: Fri Feb 13 22:54:59 2015 +0200

----------------------------------------------------------------------
 ambari-web/app/assets/test/tests.js     |   1 +
 ambari-web/app/controllers/main/host.js |   4 +
 ambari-web/app/styles/application.less  |   3 +-
 ambari-web/app/templates/main/host.hbs  |   4 +-
 ambari-web/app/views/main/host.js       |  43 ++++-
 ambari-web/test/views/main/host_test.js | 264 +++++++++++++++++++++++++++
 6 files changed, 306 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5a2b8946/ambari-web/app/assets/test/tests.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/test/tests.js 
b/ambari-web/app/assets/test/tests.js
index bd16cde..f9b3f18 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -166,6 +166,7 @@ var files = ['test/init_model_test',
   'test/views/common/progress_bar_view_test',
   'test/views/main/dashboard_test',
   'test/views/main/menu_test',
+  'test/views/main/host_test',
   'test/views/main/alert_definitions_view_test',
   'test/views/main/alerts/manage_alert_groups_view_test',
   'test/views/main/alerts/manage_alert_notifications_view_test',

http://git-wip-us.apache.org/repos/asf/ambari/blob/5a2b8946/ambari-web/app/controllers/main/host.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host.js 
b/ambari-web/app/controllers/main/host.js
index 9511be8..2ea463b 100644
--- a/ambari-web/app/controllers/main/host.js
+++ b/ambari-web/app/controllers/main/host.js
@@ -43,6 +43,10 @@ App.MainHostController = 
Em.ArrayController.extend(App.TableServerMixin, {
 
   startIndex: 1,
 
+  expandedComponentsSections: [],
+
+  expandedVersionsSections: [],
+
   /**
    * Components which will be shown in component filter
    * @returns {Array}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5a2b8946/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less 
b/ambari-web/app/styles/application.less
index ae5c756..11b310b 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -3222,7 +3222,6 @@ table.graphs {
     }
   }
   .collapsed-list {
-    display: none;
     padding-left: 10px;
   }
   .host-table-versions {
@@ -5525,4 +5524,4 @@ input[type="checkbox"].align-checkbox {
 
 .bottom-border {
   border-bottom: 1px solid #dddddd;
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5a2b8946/ambari-web/app/templates/main/host.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/host.hbs 
b/ambari-web/app/templates/main/host.hbs
index c76ab34..3474686 100644
--- a/ambari-web/app/templates/main/host.hbs
+++ b/ambari-web/app/templates/main/host.hbs
@@ -139,14 +139,14 @@
               {{/unless}}
               {{view.currentVersion}}
             </a>
-            <div class="stack-versions collapsed-list">
+            <div {{bindAttr class="view.isVersionsCollapsed:noDisplay:display 
:stack-versions :collapsed-list"}}>
               {{{view.versionlabels}}}
             </div>
           </td>
           <td class="host-table-components">
             <a href="#" class="expander" {{action toggleComponents 
target="view"}}> <span {{bindAttr 
class="view.isComponentsCollapsed:icon-caret-right:icon-caret-down"}}></span>
               {{view.content.hostComponents.length}} {{pluralize 
view.content.hostComponents.length singular="t:common.component" 
plural="t:common.components"}}</a>
-            <div class="host-components collapsed-list">
+            <div {{bindAttr 
class="view.isComponentsCollapsed:noDisplay:display :host-components 
:collapsed-list"}}>
               {{{view.labels}}}
             </div>
           </td>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5a2b8946/ambari-web/app/views/main/host.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host.js 
b/ambari-web/app/views/main/host.js
index f116e6c..79e3572 100644
--- a/ambari-web/app/views/main/host.js
+++ b/ambari-web/app/views/main/host.js
@@ -218,12 +218,26 @@ App.MainHostView = 
App.TableView.extend(App.TableServerViewMixin, {
     this.clearFiltersObs();
     this.addObserver('selectAllHosts', this, this.toggleAllHosts);
     this.addObserver('filteringComplete', this, this.overlayObserver);
-    this.addObserver('startIndex', this, 'updatePagination');
+    this.addObserver('startIndex', this, 'updateHostsPagination');
     this.addObserver('displayLength', this, 'updatePagination');
     this.addObserver('filteredCount', this, this.updatePaging);
     this.overlayObserver();
   },
 
+  updateHostsPagination: function () {
+    this.clearExpandedSections();
+    this.updatePagination();
+  },
+
+  willDestroyElement: function () {
+    this.clearExpandedSections();
+  },
+
+  clearExpandedSections: function () {
+    this.get('controller.expandedComponentsSections').clear();
+    this.get('controller.expandedVersionsSections').clear();
+  },
+
   onInitialLoad: function () {
     if (this.get('tableFilteringComplete')) {
       this.refresh();
@@ -526,19 +540,30 @@ App.MainHostView = 
App.TableView.extend(App.TableServerViewMixin, {
     content:null,
     tagName: 'tr',
     didInsertElement: function(){
+      var hostName = this.get('content.hostName');
       App.tooltip(this.$("[rel='HealthTooltip'], [rel='UsageTooltip'], 
[rel='ComponentsTooltip']"));
-      this.set('isComponentsCollapsed', true);
-      this.set('isVersionsCollapsed', true);
+      this.set('isComponentsCollapsed', 
!this.get('controller.expandedComponentsSections').contains(hostName));
+      this.set('isVersionsCollapsed', 
!this.get('controller.expandedVersionsSections').contains(hostName));
+    },
+
+    toggleList: function (flagName, arrayName) {
+      var arrayPropertyName = 'controller.' + arrayName;
+      var hostNameArray = this.get(arrayPropertyName);
+      var hostName = this.get('content.hostName');
+      this.toggleProperty(flagName);
+      if (this.get(flagName)) {
+        this.set(arrayPropertyName, hostNameArray.without(hostName));
+      } else {
+        hostNameArray.push(hostName);
+      }
     },
 
-    toggleComponents: function(event) {
-      this.toggleProperty('isComponentsCollapsed');
-      this.$('.host-components').toggle();
+    toggleComponents: function () {
+      this.toggleList('isComponentsCollapsed', 'expandedComponentsSections');
     },
 
-    toggleVersions: function(){
-      this.toggleProperty('isVersionsCollapsed');
-      this.$('.stack-versions').toggle();
+    toggleVersions: function () {
+      this.toggleList('isVersionsCollapsed', 'expandedVersionsSections');
     },
 
     /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/5a2b8946/ambari-web/test/views/main/host_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/host_test.js 
b/ambari-web/test/views/main/host_test.js
new file mode 100644
index 0000000..84579c2
--- /dev/null
+++ b/ambari-web/test/views/main/host_test.js
@@ -0,0 +1,264 @@
+/**
+ * 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.
+ */
+
+
+var App = require('app');
+require('views/main/host');
+
+describe('App.MainHostView', function () {
+
+  var view;
+
+  beforeEach(function () {
+    view = App.MainHostView.create({
+      controller: App.MainHostController.create()
+    });
+  });
+
+  describe('#didInsertElement', function () {
+
+    var cases = [
+        {
+          methodName: 'clearFiltersObs',
+          propertyToChange: 'controller.clearFilters',
+          callCount: 2
+        },
+        {
+          methodName: 'toggleAllHosts',
+          propertyToChange: 'selectAllHosts',
+          callCount: 1
+        },
+        {
+          methodName: 'overlayObserver',
+          propertyToChange: 'filteringComplete',
+          callCount: 2
+        },
+        {
+          methodName: 'updateHostsPagination',
+          propertyToChange: 'startIndex',
+          callCount: 1
+        },
+        {
+          methodName: 'updatePagination',
+          propertyToChange: 'displayLength',
+          callCount: 1
+        },
+        {
+          methodName: 'updatePaging',
+          propertyToChange: 'filteredCount',
+          callCount: 2
+        }
+      ],
+      title = '{0} changed';
+
+    beforeEach(function () {
+      cases.forEach(function (item) {
+        sinon.stub(view, item.methodName, Em.K);
+      });
+    });
+
+    afterEach(function () {
+      cases.forEach(function (item) {
+        view[item.methodName].restore();
+      });
+    });
+
+    cases.forEach(function (item) {
+      it(title.format(item.propertyToChange), function () {
+        view.didInsertElement();
+        view.propertyDidChange(item.propertyToChange);
+        expect(view[item.methodName].callCount).to.equal(item.callCount);
+      });
+    });
+
+  });
+
+  describe('#updateHostsPagination', function () {
+
+    beforeEach(function () {
+      sinon.stub(view, 'clearExpandedSections', Em.K);
+      sinon.stub(view, 'updatePagination', Em.K);
+    });
+
+    afterEach(function () {
+      view.clearExpandedSections.restore();
+      view.updatePagination.restore();
+    });
+
+    it('should execute clearExpandedSections and updatePagination', function 
() {
+      view.updateHostsPagination();
+      expect(view.clearExpandedSections.calledOnce).to.be.true;
+      expect(view.updatePagination.calledOnce).to.be.true;
+    });
+
+  });
+
+  describe('#willDestroyElement', function () {
+
+    beforeEach(function () {
+      sinon.stub(view, 'clearExpandedSections', Em.K);
+    });
+
+    afterEach(function () {
+      view.clearExpandedSections.restore();
+    });
+
+    it('should execute clearExpandedSections', function () {
+      view.willDestroyElement();
+      expect(view.clearExpandedSections.calledOnce).to.be.true;
+    });
+
+  });
+
+  describe('#clearExpandedSections', function () {
+
+    it('should clear expandedComponentsSections and expandedVersionsSections 
from controller', function () {
+      view.get('controller').setProperties({
+        expandedComponentsSections: [''],
+        expandedVersionsSections: ['']
+      });
+      view.clearExpandedSections();
+      
expect(view.get('controller.expandedComponentsSections')).to.have.length(0);
+      
expect(view.get('controller.expandedVersionsSections')).to.have.length(0);
+    });
+
+  });
+
+  describe('#HostView', function () {
+
+    var hostView;
+
+    beforeEach(function () {
+      hostView = view.HostView.create({
+        content: {
+          hostName: null
+        },
+        controller: App.MainHostController.create()
+      });
+    });
+
+    describe('#didInsertElement', function () {
+
+      var cases = [
+          {
+            expandedSections: ['h0'],
+            isCollapsed: false,
+            title: '{0} section should be expanded'
+          },
+          {
+            expandedSections: ['h1'],
+            isCollapsed: true,
+            title: '{0} section should be collapsed'
+          }
+        ],
+        testMethod = function (item, elementsName, arrayName, propertyName) {
+          it(item.title.format(elementsName), function () {
+            hostView.set('content.hostName', 'h0');
+            hostView.set('controller.' + arrayName, item.expandedSections);
+            hostView.didInsertElement();
+            expect(App.tooltip.calledOnce).to.be.true;
+            expect(hostView.get(propertyName)).to.equal(item.isCollapsed);
+          });
+        };
+
+      beforeEach(function () {
+        sinon.stub(App, 'tooltip', Em.K);
+      });
+
+      afterEach(function () {
+        App.tooltip.restore();
+      });
+
+      cases.forEach(function (item) {
+        testMethod(item, 'components', 'expandedComponentsSections', 
'isComponentsCollapsed');
+        testMethod(item, 'versions', 'expandedVersionsSections', 
'isVersionsCollapsed');
+      });
+
+    });
+
+    describe('#toggleList', function () {
+
+      var cases = [
+        {
+          isCollapsed: false,
+          isCollapsedAfter: true,
+          expandedSections: ['h0'],
+          expandedSectionsAfter: [],
+          title: 'section becomes collapsed'
+        },
+        {
+          isCollapsed: true,
+          isCollapsedAfter: false,
+          expandedSections: [],
+          expandedSectionsAfter: ['h0'],
+          title: 'section becomes expanded'
+        }
+      ];
+
+      cases.forEach(function (item) {
+        it(item.title, function () {
+          hostView.set('content.hostName', 'h0');
+          hostView.set('isComponentsCollapsed', item.isCollapsed);
+          hostView.set('controller.expandedComponentsSections', 
item.expandedSections);
+          hostView.toggleList('isComponentsCollapsed', 
'expandedComponentsSections');
+          
expect(hostView.get('isComponentsCollapsed')).to.equal(item.isCollapsedAfter);
+          
expect(hostView.get('controller.expandedComponentsSections')).to.eql(item.expandedSectionsAfter);
+        });
+      });
+
+    });
+
+    describe('#toggleComponents', function () {
+
+      beforeEach(function () {
+        sinon.stub(hostView, 'toggleList', Em.K);
+      });
+
+      afterEach(function () {
+        hostView.toggleList.restore();
+      });
+
+      it('should toggle components list', function () {
+        hostView.toggleComponents();
+        expect(hostView.toggleList.calledOnce).to.be.true;
+        expect(hostView.toggleList.calledWith('isComponentsCollapsed', 
'expandedComponentsSections')).to.be.true;
+      });
+
+    });
+
+    describe('#toggleVersions', function () {
+
+      beforeEach(function () {
+        sinon.stub(hostView, 'toggleList', Em.K);
+      });
+
+      afterEach(function () {
+        hostView.toggleList.restore();
+      });
+
+      it('should toggle components list', function () {
+        hostView.toggleVersions();
+        expect(hostView.toggleList.calledOnce).to.be.true;
+        expect(hostView.toggleList.calledWith('isVersionsCollapsed', 
'expandedVersionsSections')).to.be.true;
+      });
+
+    });
+
+  });
+
+});

Reply via email to