AMBARI-18991 Fix Flume agents table. (ababiichuk)

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

Branch: refs/heads/branch-feature-AMBARI-18634
Commit: 5c002c6408d74b9d7c1a7693f3d01761ed64265a
Parents: 549d7cc
Author: ababiichuk <ababiic...@hortonworks.com>
Authored: Fri Nov 25 18:34:52 2016 +0200
Committer: ababiichuk <ababiic...@hortonworks.com>
Committed: Fri Nov 25 19:00:10 2016 +0200

----------------------------------------------------------------------
 ambari-web/app/models/service/flume.js          |   8 +
 ambari-web/app/styles/application.less          | 112 ++++-------
 .../app/styles/theme/bootstrap-ambari.css       |  25 ++-
 .../templates/main/service/services/flume.hbs   | 196 ++++++++-----------
 .../app/views/main/service/services/flume.js    |  32 +--
 ambari-web/test/models/service/flume_test.js    |   6 +
 .../views/main/service/services/flume_test.js   |  17 +-
 7 files changed, 178 insertions(+), 218 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5c002c64/ambari-web/app/models/service/flume.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/service/flume.js 
b/ambari-web/app/models/service/flume.js
index d482ab6..37cfbb5 100644
--- a/ambari-web/app/models/service/flume.js
+++ b/ambari-web/app/models/service/flume.js
@@ -49,6 +49,14 @@ App.FlumeAgent = DS.Model.extend({
     UNKNOWN: App.healthIconClassYellow
   },
 
+  healthIconClass: Em.computed.getByKey('healthIconClassMap', 'status', ''),
+
+  healthIconClassMap: {
+    RUNNING: 'health-status-LIVE',
+    NOT_RUNNING: 'health-status-DEAD-RED',
+    UNKNOWN: 'health-status-DEAD-YELLOW'
+  },
+
   displayStatus: Em.computed.getByKey('displayStatusMap', 'status', 
Em.I18n.t('common.unknown')),
 
   displayStatusMap: {

http://git-wip-us.apache.org/repos/asf/ambari/blob/5c002c64/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less 
b/ambari-web/app/styles/application.less
index 7d93778..d449ccb 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -2180,86 +2180,60 @@ input[type="radio"].align-checkbox, 
input[type="checkbox"].align-checkbox {
 }
 
 #flume-summary {
-  text-align:left !important;
   max-height: 490px;
-  #flume-agents-table {
+  .table {
     margin: 0;
-    width: 100%;
-    .highlight {
-      td, th {
-        background-color: #BDC3C7 !important;
-        color: #666;
+    table-layout: fixed;
+  }
+  #flume-agents-table {
+    border-collapse: separate;
+    > tbody > tr > td {
+      &:last-of-type {
+        padding: 0;
+        &.empty-label {
+          padding: 8px;
+          text-align: center;
+        }
       }
     }
     th:first-child {
       width: 40%;
+      + th {
+        width: 30%;
+        ~ th {
+          width: 10%;
+        }
+      }
     }
-    th:first-child + th {
-      width: 30%;
-    }
-    th:first-child + th + th {
-      width: 10%;
-    }
-    th:first-child + th + th + th {
-      width: 10%;
-    }
-    th:first-child + th + th + th + th {
-      width: 10%;
-    }
-    td.agent-status {
-      width: 125px;
-    }
-    td.agent-name {
-      width: 20%;
-      overflow: hidden;
-    }
-    td.agent-host-name {
-      width: 20%;
-      overflow: hidden;
-      max-width: 90px;
-    }
-    .glyphicon-warning-sign {
-      color: @restart-indicator-color;
-    }
-    #flume-host-agent-row {
-      cursor: pointer;
-      text-align: left;
-      background-color: #fff;
-    }
-    .empty-label {
-      border-top: 1px solid #ddd;
-      text-align: center;
-    }
-  }
-  .wrapp-flume-status{
-    text-align: left;
-  }
-  .btn-wrapper {
-    margin: 0 5px 5px 0;
-    float: right;
-    width:60px;
-    position: static;
-  }
-  .flume-agents-actions {
-    .btn-group {
-      position: static;
-    }
-    a {
-      text-decoration: none;
-    }
-    a.dropdown-toggle {
-      padding: 2px 6px;
-      font-size: 11px;
-      line-height: 17px;
-    }
-    .dropdown-menu {
-      position: absolute;
+    td {
+      &.agent-host-name {
+        overflow: hidden;
+        border-bottom: 1px solid #eee;
+        cursor: pointer;
+      }
+      &.agent-status {
+        width: 50%;
+      }
+      &.flume-agent-sources-count, &.flume-agent-channels-count {
+        width: 16.667%;
+      }
+      &.flume-agent-sink-count {
+        width: 16.666%;
+      }
+      .flume-agents-actions {
+        .btn-group {
+          position: static;
+        }
+        a {
+          text-decoration: none;
+        }
+      }
     }
   }
   .scrollable-container {
+    position: static;
     max-height: 450px;
-    width: 100%;
-    overflow-y: scroll;
+    overflow-y: auto;
   }
 }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/5c002c64/ambari-web/app/styles/theme/bootstrap-ambari.css
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/theme/bootstrap-ambari.css 
b/ambari-web/app/styles/theme/bootstrap-ambari.css
index fd341a5..f427c0a 100644
--- a/ambari-web/app/styles/theme/bootstrap-ambari.css
+++ b/ambari-web/app/styles/theme/bootstrap-ambari.css
@@ -35,7 +35,6 @@
   outline: none;
   font-family: 'Roboto', sans-serif;
   text-transform: uppercase;
-  height: 34px;
   font-size: 14px;
   padding: 10px 20px;
   line-height: 14px;
@@ -213,6 +212,10 @@
   background-color: #429929;
   border: 1px solid #3FAE2A;
 }
+.navbar-btn {
+  margin-top: 7px;
+  margin-bottom: 7px;
+}
 .btn-regular-default-state {
   background-color: #FFF;
   color: #666;
@@ -374,8 +377,21 @@ h2.table-title {
   top: 4px;
   margin-bottom: 0;
 }
+.table thead > tr > th {
+  border-bottom-color: #EEE;
+}
 .table tfoot > tr:first-of-type > td {
   border-top-width: 2px;
+  border-top-color: #EEE;
+}
+.table > tbody > tr > td {
+  border-top-color: #EEE;
+}
+.table > tbody > tr.active {
+  background-color: #EEE;
+}
+.table > tbody > tr.active > td {
+  background-color: #EEE;
 }
 .table.table-hover .action {
   visibility: hidden;
@@ -393,13 +409,6 @@ h2.table-title {
 .table.table-hover > tbody > tr > td {
   border-width: 0;
 }
-.table.table-hover > tbody > tr.active {
-  border-color: #EEE;
-  background-color: #EEE;
-}
-.table.table-hover > tbody > tr.active > td {
-  background-color: #EEE;
-}
 .table.table-hover > tbody > tr:hover {
   border-color: #A7DFF2;
   background-color: #E7F6FC;

http://git-wip-us.apache.org/repos/asf/ambari/blob/5c002c64/ambari-web/app/templates/main/service/services/flume.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/services/flume.hbs 
b/ambari-web/app/templates/main/service/services/flume.hbs
index 1e57cd5..5b3a8e2 100644
--- a/ambari-web/app/templates/main/service/services/flume.hbs
+++ b/ambari-web/app/templates/main/service/services/flume.hbs
@@ -21,121 +21,89 @@
   <div class="col-md-12">
     <a href="#" {{action filterHosts 
view.flumeHandlerComponent}}>{{view.summaryHeader}}</a>
     <a href="#" class="pull-right" {{action gotoConfigs 
target="controller"}}>{{t dashboard.services.flume.summary.configure}}</a>
-    <div id="flume-agent-table-wrap" class="scrollable-container">
-      <table class="table table-hover advanced-header-table table-bordered 
table-striped" id="flume-agents-table">
-        <thead>
-          {{#view view.sortView contentBinding="view.filteredContent" 
class="label-row"}}
-            {{view view.parentView.hostSort}}
-            <th>{{t dashboard.services.flume.agent}}</th>
-            <th>
-              <i class="glyphicon glyphicon-signin" {{translateAttr 
title="dashboard.services.flume.sources"}}></i> {{t 
dashboard.services.flume.sources}}
-            </th>
-            <th>
-              <i class="glyphicon glyphicon-random" {{translateAttr 
title="dashboard.services.flume.channels"}}></i> {{t 
dashboard.services.flume.channels}}
-            </th>
-            <th>
-              <i class="glyphicon glyphicon-signout" {{translateAttr 
title="dashboard.services.flume.sinks"}}></i> {{t 
dashboard.services.flume.sinks}}
-            </th>
-          {{/view}}
-        </thead>
-        {{#if view.pageContent}}
-          {{#each host in view.pageContent}}
-            <tbody class="flume-agent-table-tbody">
-            {{#view view.agentView contentBinding="host"}}
-              <td {{bindAttr rowspan="host.rowspan"}} 
id="flume-host-agent-row" class="agent-host-name">
-                <a class="agent-host-link" href="javascript:void(null)" 
{{action click host target="view"}}>
-                  {{host.hostName}}
-                </a>
-              </td>
-              <td class="agent-status">
-                <div class="wrapp-flume-status">
-                  <div class="pull-left flume-agents-status">
-                    <span {{bindAttr 
class="host.firtstAgent.healthClass"}}></span> {{host.firtstAgent.name}}</div>
-                  <div class="btn-wrapper flume-agents-actions">
-                    <div class="btn-group display-inline-block">
-                      <a class="btn btn-default dropdown-toggle" 
data-toggle="dropdown"
-                         
href="javascript:void(null)">{{host.firtstAgent.displayStatus}}
-                        <span class="caret"></span>
-                      </a>
-                      <ul class="pull-left dropdown-menu">
-                        <li {{bindAttr 
class="host.firtstAgent.isStartAgentDisabled:disabled"}}>
-                          <a href="javascript:void(null)"
-                            {{bindAttr 
class="host.firtstAgent.isStartAgentDisabled:disabled :start-agent"}}
-                            {{action startFlumeAgent host.firtstAgent 
target="controller"}}>
-                            {{t services.service.summary.flume.startAgent}}</a>
-                        </li>
-                        <li {{bindAttr 
class="host.firtstAgent.isStopAgentDisabled:disabled"}}>
-                          <a href="javascript:void(null)"
-                            {{bindAttr 
class="host.firtstAgent.isStopAgentDisabled:disabled :stop-agent"}}
-                            {{action stopFlumeAgent host.firtstAgent 
target="controller"}}>
-                            {{t services.service.summary.flume.stopAgent}}</a>
-                        </li>
-                      </ul>
-                    </div>
-                  </div>
-                </div>
-              </td>
-              <td class="flume-sources-count">
-                {{host.firtstAgent.sourcesCount}}
-              </td>
-              <td class="flume-channels-count">
-                {{host.firtstAgent.channelsCount}}
-              </td>
-              <td class="flume-sinks-count">
-                {{host.firtstAgent.sinksCount}}
-              </td>
-            {{/view}}
-            {{#each agent in host.otherAgents}}
-              {{#view view.agentView contentBinding="host"}}
-                <td class="agent-status">
-                  <div class="wrapp-flume-status">
-                    <div class="pull-left flume-agents-status">
-                      <span {{bindAttr class="agent.healthClass"}}></span> 
{{agent.name}}</div>
-                    <div class="btn-wrapper flume-agents-actions">
-                      <div class="btn-group display-inline-block">
-                        <a class="btn btn-default dropdown-toggle" 
data-toggle="dropdown"
-                           href="javascript:void(null)">{{agent.displayStatus}}
-                          <span class="caret"></span>
-                        </a>
-                        <ul class="pull-left dropdown-menu">
-                          <li {{bindAttr 
class="agent.isStartAgentDisabled:disabled :start-agent"}}>
-                            <a href="javascript:void(null)"
-                              {{bindAttr 
class="agent.isStartAgentDisabled:disabled"}}
-                              {{action startFlumeAgent agent 
target="controller"}}>
-                              {{t 
services.service.summary.flume.startAgent}}</a>
-                          </li>
-                          <li {{bindAttr 
class="agent.isStopAgentDisabled:disabled"}}>
-                            <a href="javascript:void(null)"
-                              {{bindAttr 
class="agent.isStopAgentDisabled:disabled :stop-agent"}}
-                              {{action stopFlumeAgent agent 
target="controller"}}>
-                              {{t 
services.service.summary.flume.stopAgent}}</a>
-                          </li>
-                        </ul>
-                      </div>
-                    </div>
-                  </div>
-                </td>
-                <td class="flume-agent-sources-count">
-                  {{agent.sourcesCount}}
-                </td>
-                <td class="flume-agent-channels-count">
-                  {{agent.channelsCount}}
-                </td>
-                <td class="flume-agent-sink-count">
-                  {{agent.sinksCount}}
-                </td>
-              {{/view}}
-            {{/each}}
-            </tbody>
-          {{/each}}
-        {{else}}
-          <tr>
-            <td colspan="5" id="flume-agents-empty-label" class="empty-label">
-              {{t services.service.summary.flume.noAgents}}
+  </div>
+  <div id="flume-agent-table-wrap" class="scrollable-container col-md-12">
+    <table class="table advanced-header-table" id="flume-agents-table">
+      <thead>
+      {{#view view.sortView contentBinding="view.filteredContent" 
class="label-row"}}
+        {{view view.parentView.hostSort}}
+        <th>{{t dashboard.services.flume.agent}}</th>
+        <th>
+          <i class="icon icon-signin" {{translateAttr 
title="dashboard.services.flume.sources"}}></i> {{t 
dashboard.services.flume.sources}}
+        </th>
+        <th>
+          <i class="icon icon-random" {{translateAttr 
title="dashboard.services.flume.channels"}}></i> {{t 
dashboard.services.flume.channels}}
+        </th>
+        <th>
+          <i class="icon icon-signout" {{translateAttr 
title="dashboard.services.flume.sinks"}}></i> {{t 
dashboard.services.flume.sinks}}
+        </th>
+      {{/view}}
+      </thead>
+      <tbody>
+      {{#if view.pageContent}}
+        {{#each host in view.pageContent}}
+          <tr {{bindAttr class="host.isActive:active"}}>
+            <td class="agent-host-name" {{action selectHost host 
target="view"}}>
+              <a href="javascript:void(null)">
+                {{host.hostName}}
+              </a>
+            </td>
+            <td colspan="4">
+              <table class="table table-hover table-striped">
+                <tbody>
+                  {{#each agent in host.agents}}
+                    <tr {{bindAttr class="host.isActive:active"}}>
+                      <td class="agent-status">
+                        <div class="pull-left">
+                          <span {{bindAttr class="agent.healthClass 
agent.healthIconClass"}}></span> {{agent.name}}
+                        </div>
+                        <div class="flume-agents-actions pull-right">
+                          <div class="btn-group display-inline-block">
+                            <button type="button" class="btn btn-default 
dropdown-toggle" data-toggle="dropdown">
+                              {{agent.displayStatus}}
+                              <span class="caret"></span>
+                            </button>
+                            <ul class="pull-left dropdown-menu">
+                              <li {{bindAttr 
class="agent.isStartAgentDisabled:disabled :start-agent"}}>
+                                <a href="javascript:void(null)"
+                                  {{bindAttr 
class="agent.isStartAgentDisabled:disabled"}}
+                                  {{action startFlumeAgent agent 
target="controller"}}>
+                                  {{t 
services.service.summary.flume.startAgent}}</a>
+                              </li>
+                              <li {{bindAttr 
class="agent.isStopAgentDisabled:disabled"}}>
+                                <a href="javascript:void(null)"
+                                  {{bindAttr 
class="agent.isStopAgentDisabled:disabled :stop-agent"}}
+                                  {{action stopFlumeAgent agent 
target="controller"}}>
+                                  {{t 
services.service.summary.flume.stopAgent}}</a>
+                              </li>
+                            </ul>
+                          </div>
+                        </div>
+                      </td>
+                      <td class="flume-agent-sources-count">
+                        {{agent.sourcesCount}}
+                      </td>
+                      <td class="flume-agent-channels-count">
+                        {{agent.channelsCount}}
+                      </td>
+                      <td class="flume-agent-sink-count">
+                        {{agent.sinksCount}}
+                      </td>
+                    </tr>
+                  {{/each}}
+                </tbody>
+              </table>
             </td>
           </tr>
-        {{/if}}
-      </table>
-    </div>
+        {{/each}}
+      {{else}}
+        <tr>
+          <td colspan="5" class="empty-label">
+            {{t services.service.summary.flume.noAgents}}
+          </td>
+        </tr>
+      {{/if}}
+      </tbody>
+    </table>
   </div>
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/5c002c64/ambari-web/app/views/main/service/services/flume.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/services/flume.js 
b/ambari-web/app/views/main/service/services/flume.js
index 2db4583..15c61d6 100644
--- a/ambari-web/app/views/main/service/services/flume.js
+++ b/ambari-web/app/views/main/service/services/flume.js
@@ -37,10 +37,7 @@ App.MainDashboardServiceFlumeView = 
App.TableView.extend(App.MainDashboardServic
       content.push(
         Em.Object.create({
           hostName: hostName,
-          agents: agents,
-          rowspan: agents.length,
-          firtstAgent: agents[0],
-          otherAgents: agents.without(agents[0])
+          agents: agents
         })
       );
     });
@@ -58,24 +55,6 @@ App.MainDashboardServiceFlumeView = 
App.TableView.extend(App.MainDashboardServic
     componentName: 'FLUME_HANDLER'
   }),
 
-  agentView: Em.View.extend({
-    content: null,
-    tagName: 'tr',
-
-    click: function (e) {
-      var numberOfAgents = this.get('content.agents').length;
-      if ($(e.target).attr('class') === "agent-host-name" || 
$(e.target).attr('class') === "agent-host-link") {
-        var currentTargetRow = $(e.currentTarget);
-        if ($(e.target).attr('class') === "agent-host-link") {
-          currentTargetRow = 
currentTargetRow.parent(".agent-host-name").parent();
-        }
-        
currentTargetRow.parents("table:first").find('tr').removeClass('highlight');
-        currentTargetRow.addClass('highlight').nextAll("tr").slice(0, 
numberOfAgents - 1).addClass('highlight');
-        this.get('parentView').showAgentInfo(this.get('content'));
-      }
-    }
-  }),
-
   sortView: sort.wrapperView,
 
   hostSort: sort.fieldView.extend({
@@ -92,6 +71,14 @@ App.MainDashboardServiceFlumeView = 
App.TableView.extend(App.MainDashboardServic
     });
   },
 
+  selectHost: function (e) {
+    var host = e && e.context;
+    this.get('pageContent').setEach('isActive', false);
+    if (host) {
+      this.showAgentInfo(host);
+    }
+  },
+
   /**
    * Locate dropdown menu absolutely outside of scrollable block
    * @param element
@@ -131,6 +118,7 @@ App.MainDashboardServiceFlumeView = 
App.TableView.extend(App.MainDashboardServic
    * @param {object} host
    */
   showAgentInfo: function (host) {
+    Em.set(host, 'isActive', true);
     this.set('selectedHost', host);
     this.setAgentMetrics(host);
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/5c002c64/ambari-web/test/models/service/flume_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/service/flume_test.js 
b/ambari-web/test/models/service/flume_test.js
index 55fd135..d88f375 100644
--- a/ambari-web/test/models/service/flume_test.js
+++ b/ambari-web/test/models/service/flume_test.js
@@ -47,6 +47,12 @@ describe('App.FlumeAgent', function () {
     UNKNOWN: App.healthIconClassYellow
   }});
 
+  App.TestAliases.testAsComputedGetByKey(getModel(), 'healthIconClass', 
'healthIconClassMap', 'status', {defaultValue: '', map: {
+    RUNNING: 'health-status-LIVE',
+    NOT_RUNNING: 'health-status-DEAD-RED',
+    UNKNOWN: 'health-status-DEAD-YELLOW'
+  }});
+
   App.TestAliases.testAsComputedGetByKey(getModel(), 'displayStatus', 
'displayStatusMap', 'status', {defaultValue: Em.I18n.t('common.unknown'), map: {
     RUNNING: Em.I18n.t('common.running'),
     NOT_RUNNING: Em.I18n.t('common.stopped'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/5c002c64/ambari-web/test/views/main/service/services/flume_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/service/services/flume_test.js 
b/ambari-web/test/views/main/service/services/flume_test.js
index a19b5c9..dc2f99a 100644
--- a/ambari-web/test/views/main/service/services/flume_test.js
+++ b/ambari-web/test/views/main/service/services/flume_test.js
@@ -40,8 +40,6 @@ describe('App.MainDashboardServiceFlumeView', function () {
       ]);
       view.propertyDidChange('content');
       expect(view.get('content').mapProperty('hostName')).to.be.eql(['host1', 
'host2']);
-      expect(view.get('content').mapProperty('rowspan')).to.be.eql([1, 2]);
-      
expect(view.get('content').mapProperty('firtstAgent')).to.be.eql([{hostName: 
'host1'}, {hostName: 'host2'}]);
     });
   });
 
@@ -162,18 +160,27 @@ describe('App.MainDashboardServiceFlumeView', function () 
{
 
   describe("#showAgentInfo()", function() {
 
+    var host;
+
     beforeEach(function() {
+      host = {hostName: 'host1'};
       sinon.stub(view, 'setAgentMetrics');
+      view.showAgentInfo(host);
     });
     afterEach(function() {
       view.setAgentMetrics.restore();
     });
 
-    it("setAgentMetrics should be called", function() {
-      var host = {hostName: 'host1'};
-      view.showAgentInfo(host);
+    it('setAgentMetrics should be called', function() {
       expect(view.setAgentMetrics.calledWith(host)).to.be.true;
+    });
+
+    it('proper host should be selected', function() {
       expect(view.get('selectedHost')).to.be.eql(host);
     });
+
+    it('proper row should be highlighted', function() {
+      expect(Em.get(host, 'isActive')).to.be.true;
+    });
   });
 });
\ No newline at end of file

Reply via email to