ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From xiw...@apache.org
Subject ambari git commit: AMBARI-8589. Service page layout changes in Ambari Web for Alerts + Metrics.(XIWANG)
Date Mon, 08 Dec 2014 20:13:06 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk 9053513f6 -> 8a322603d


AMBARI-8589. Service page layout changes in Ambari Web for Alerts + Metrics.(XIWANG)


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

Branch: refs/heads/trunk
Commit: 8a322603de3cdc01d296226cd98d0965948fcd44
Parents: 9053513
Author: Xi Wang <xiwang@apache.org>
Authored: Sun Dec 7 16:30:45 2014 -0800
Committer: Xi Wang <xiwang@apache.org>
Committed: Mon Dec 8 12:11:18 2014 -0800

----------------------------------------------------------------------
 .../controllers/main/service/info/summary.js    |  35 ++++-
 ambari-web/app/messages.js                      |   8 +-
 ambari-web/app/models/alert_definition.js       |  21 +++
 ambari-web/app/styles/alerts.less               |  37 ++++--
 .../main/service/info/service_alert_popup.hbs   |  40 ++++++
 .../app/templates/main/service/info/summary.hbs |  85 ++++++------
 .../main/service/info/summary_alert.hbs         |  49 -------
 .../app/views/common/chart/linear_time.js       |  34 ++---
 .../info/metrics/flume/flume_metric_graphs.js   |   2 +-
 .../app/views/main/service/info/summary.js      | 133 ++++++++++++++-----
 .../test/views/common/chart/linear_time_test.js |  11 +-
 .../views/main/service/info/summary_test.js     |  21 ---
 12 files changed, 293 insertions(+), 183 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/app/controllers/main/service/info/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/summary.js b/ambari-web/app/controllers/main/service/info/summary.js
index ab4770f..fff7628 100644
--- a/ambari-web/app/controllers/main/service/info/summary.js
+++ b/ambari-web/app/controllers/main/service/info/summary.js
@@ -102,7 +102,36 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
     return App.router.get('clusterController.isNagiosInstalled');
   }.property('App.router.clusterController.isNagiosInstalled'),
 
-  isGangliaInstalled: function(){
-    return App.router.get('clusterController.isGangliaInstalled');
-  }.property('App.router.clusterController.isGangliaInstalled')
+  showServiceAlertsPopup: function (event) {
+    var service = event.context;
+    return App.ModalPopup.show({
+      header: Em.I18n.t('services.service.summary.alerts.popup.header').format(service.get('displayName')),
+      bodyClass: Em.View.extend({
+        templateName: require('templates/main/service/info/service_alert_popup'),
+        controllerBinding: 'App.router.mainAlertDefinitionsController',
+        didInsertElement: function () {
+          Em.run.next(this, function () {
+            App.tooltip($(".timeago"));
+          });
+        },
+        alerts: function () {
+          var serviceDefinitions = this.get('controller.content').filterProperty('service',
service);
+          return serviceDefinitions.filterProperty('isCriticalOrWarning');
+        }.property('controller.content'),
+        gotoAlertDetails: function (event) {
+          if (event && event.context) {
+            this.get('parentView').hide();
+            App.router.transitionTo('main.alerts.alertDetails', event.context);
+          }
+        },
+        closePopup: function () {
+          this.get('parentView').hide();
+        }
+      }),
+      isHideBodyScroll: true,
+      primary: Em.I18n.t('common.close'),
+      secondary: null
+    });
+  }
+
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index de6b78a..27c34f3 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -244,6 +244,7 @@ Em.I18n.translations = {
   'common.severity': "Severity",
 
   'models.alert_instance.tiggered.verbose': "Occured on {0} <br> Checked on {1}",
+  'models.alert_definition.triggered.verbose': "Occured on {0}",
 
   'passiveState.turnOn':'Turn On Maintenance Mode',
   'passiveState.turnOff':'Turn Off Maintenance Mode',
@@ -326,6 +327,7 @@ Em.I18n.translations = {
   'graphs.timeRange.week': 'Last 1 week',
   'graphs.timeRange.month': 'Last 1 month',
   'graphs.timeRange.year': 'Last 1 year',
+  'graphs.timeRangeControl.label': 'Time range: ',
 
   'users.userName.validationFail': 'Only lowercase letters and numbers are recommended; must
start with a letter',
   'host.spacesValidation': 'Cannot contain whitespace',
@@ -1310,7 +1312,7 @@ Em.I18n.translations = {
 
   'services.service.start':'Start',
   'services.service.stop':'Stop',
-  'services.service.metrics':'Service Metrics',
+  'services.service.metrics':'Metrics',
   'services.nothingToAdd':'Nothing to add',
   'services.service.summary.version':'Version',
   'services.service.summary.viewHost':'View Host',
@@ -1408,6 +1410,10 @@ Em.I18n.translations = {
   'services.service.summary.flume.start.context': 'Start Flume {0}',
   'services.service.summary.flume.noAgents': 'No Flume to display',
 
+  'services.service.summary.alerts.noAlerts': 'No alerts',
+  'services.service.summary.alerts.alertsExist': '{0} alerts',
+  'services.service.summary.alerts.popup.header': 'Critical or Warning Alerts for {0}',
+
   'services.service.info.metrics.flume.channelFillPercent':'Channel Fill Percentage',
   'services.service.info.metrics.flume.channelSize':'Channel Size',
   'services.service.info.metrics.flume.sinkDrainSuccess':'Sink Event Drain Count',

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/app/models/alert_definition.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/alert_definition.js b/ambari-web/app/models/alert_definition.js
index 9e22153..92f395a 100644
--- a/ambari-web/app/models/alert_definition.js
+++ b/ambari-web/app/models/alert_definition.js
@@ -73,6 +73,27 @@ App.AlertDefinition = DS.Model.extend({
     return lastTriggered ? $.timeago(new Date(lastTriggered)): '';
   }.property('lastTriggered'),
 
+  lastTriggeredVerboseDisplay : function() {
+    var lastTriggered = this.get('lastTriggered');
+    return Em.I18n.t('models.alert_definition.triggered.verbose').format(dateUtils.dateFormat(lastTriggered));
+  }.property('lastTriggered'),
+
+  /**
+   * Formatted timestamp in format: for 4 days
+   * @type {string}
+   */
+  lastTriggeredForFormatted: function () {
+    var lastTriggered = this.get('lastTriggered');
+    var previousSuffixAgo = $.timeago.settings.strings.suffixAgo;
+    var previousPrefixAgo = $.timeago.settings.strings.prefixAgo;
+    $.timeago.settings.strings.suffixAgo = null;
+    $.timeago.settings.strings.prefixAgo = 'for';
+    var triggeredFor = lastTriggered ? $.timeago(new Date(lastTriggered)): '';
+    $.timeago.settings.strings.suffixAgo = previousSuffixAgo;
+    $.timeago.settings.strings.prefixAgo = previousPrefixAgo;
+    return triggeredFor;
+  }.property('lastTriggered'),
+
   /**
    * Formatted displayName for <code>componentName</code>
    * @type {String}

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/app/styles/alerts.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/alerts.less b/ambari-web/app/styles/alerts.less
index feee82b..02ac2fa 100644
--- a/ambari-web/app/styles/alerts.less
+++ b/ambari-web/app/styles/alerts.less
@@ -422,6 +422,31 @@
   }
 }
 
+.service-block .summary-box-header {
+  .alerts-count-label,.no-alerts-label {
+    padding: 2px 4px;
+    margin-right: 5px;
+    margin-top: 5px;
+    cursor: pointer;
+  }
+  .alerts-count-label {
+    background: #953B39;
+  }
+  .no-alerts-label {
+    background: #006400;
+  }
+}
+
+#summary-alerts-popup {
+  .alert-list-wrap {
+    padding: 10px 5px;
+    .status-icon {
+      padding-right: 5px;
+      min-width: 20px;
+    }
+  }
+}
+
 /*****start styles for manage alerts popup*****/
 .sixty-percent-width-modal.manage-alert-group-popup {
   .modal{
@@ -461,7 +486,7 @@
     min-width: 600px;
   }
   #alert-info {
-    .log-list-wrap:hover {
+    .alert-list-wrap:hover {
       background-color: #e6e6e6;
     }
   }
@@ -474,11 +499,6 @@
     font-size: 15px;
     padding: 0px 0px 20px 0px;
     height: 20px;
-    .status-top {
-      width: 12%;
-      padding-left: 5px;
-      min-width: 20px;
-    }
     .name-top {
       width: 32%;
       padding-left: 10px;
@@ -507,11 +527,6 @@
     .alert-list-line-cursor{
       width: 100%;
       min-height: 20px;
-      .status {
-        padding-left: 5px;
-        float: left;
-        width: 12%;
-      }
       .status-icon {
         padding-right: 5px;
         min-width: 20px;

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/app/templates/main/service/info/service_alert_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/service_alert_popup.hbs b/ambari-web/app/templates/main/service/info/service_alert_popup.hbs
new file mode 100644
index 0000000..403be5d
--- /dev/null
+++ b/ambari-web/app/templates/main/service/info/service_alert_popup.hbs
@@ -0,0 +1,40 @@
+{{!
+* 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.
+}}
+
+{{#if view.alerts.length}}
+  <ul id='summary-alerts-popup' class="alerts">
+    {{#each alert in view.alerts}}
+      <li class="alert-list-wrap">
+        <div class="row-fluid">
+          <div class="span6 name-text">
+            <a href="#" {{action "gotoAlertDetails" alert target="view"}}>{{alert.label}}</a>
+          </div>
+          <div class="span5 status-col" rel="alert-status-tooltip" {{bindAttr title="alert.lastTriggered"}}>
+            <span class="timeago" {{bindAttr data-original-title="alert.lastTriggeredVerboseDisplay"}}>
+              <span class="status-icon">{{{alert.status}}}</span>
+              <time>{{alert.lastTriggeredForFormatted}}</time>
+            </span>
+          </div>
+        </div>
+      </li>
+    {{/each}}
+  </ul>
+{{else}}
+  {{t services.service.summary.alerts.noAlerts}}
+{{/if}}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/app/templates/main/service/info/summary.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary.hbs b/ambari-web/app/templates/main/service/info/summary.hbs
index 1d28340..8ba06fc 100644
--- a/ambari-web/app/templates/main/service/info/summary.hbs
+++ b/ambari-web/app/templates/main/service/info/summary.hbs
@@ -47,8 +47,9 @@
 <div class="row-fluid service-block">
   <div class="span6">
     <div class="box">
-      <div class="box-header">
+      <div class="box-header summary-box-header">
         <h4>{{controller.content.label}} {{t services.service.info.menu.summary}}</h4>
+        <span {{action "showServiceAlertsPopup" controller.content target="controller"}}{{bindAttr
class=":pull-right view.alertsCount:alerts-count-label:no-alerts-label :label"}}>{{view.alertsCountLabel}}</span>
       </div>
       <div class="service-content">
         <table id="summary-info" class="table no-borders table-condensed">
@@ -62,8 +63,43 @@
     </div>
   </div>
 
-  <div class="span6">
-  </div>
+  {{#if view.isServiceMetricLoaded}}
+    {{#if view.serviceMetricGraphs.length}}
+      <div class="span6 service-metrics-block">
+        <div class="box">
+          <div class="box-header">
+            <h4>{{t services.service.metrics}}</h4>
+            <div class="btn-group pull-right">
+              <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+                {{t graphs.timeRangeControl.label}} {{view.currentTimeRange.name}}
+                  <span class="caret"></span>
+              </button>
+              <ul class="dropdown-menu">
+                {{#each option in view.timeRangeOptions}}
+                    <li><a href="#" {{action setTimeRange option target="view"}}>{{option.name}}</a></li>
+                {{/each}}
+              </ul>
+            </div>
+          </div>
+          <div class="">
+            <table class="graphs">
+              {{#each graphs in view.serviceMetricGraphs}}
+                <tr>
+                  {{#each graph in graphs}}
+                    <td>
+                        <div class="">
+                          {{view graph}}
+                        </div>
+                    </td>
+                  {{/each}}
+                </tr>
+              {{/each}}
+            </table>
+          </div>
+        </div>
+      </div>
+    {{/if}}
+  {{/if}}
 
 </div>
 
@@ -99,42 +135,7 @@
   </div>
 {{/if}}
 
-{{!todo: Enable service metrics check once MetricsSink is deployed as a service}}
-{{!#unless view.isNoServiceMetricsService}}
-  {{#if view.serviceMetricGraphs.length}}
-  <div class="row-fluid">
-    <div class="span12">
-      <div class="box">
-        <div class="box-header">
-          <h4>{{controller.content.displayName}} {{t services.service.metrics}}</h4>
-          {{#if controller.isGangliaInstalled}}
-            <div class="btn-group">
-              {{#if App.router.clusterController.isGangliaUrlLoaded}}
-                <a class="btn" target="_blank" rel="tooltip"
-                   title="Go to Ganglia" {{bindAttr href="view.gangliaUrl"}}><i class="icon-link"></i></a>
-              {{else}}
-                <div class="spinner"></div>
-              {{/if}}
-            </div>
-          {{/if}}
-        </div>
-        <div class="">
-          <table class="graphs">
-            {{#each graphs in view.serviceMetricGraphs}}
-              <tr>
-                {{#each graph in graphs}}
-                  <td>
-                    <div class="">
-                      {{view graph}}
-                    </div>
-                  </td>
-                {{/each}}
-              </tr>
-            {{/each}}
-          </table>
-        </div>
-      </div>
-      </div>
-    </div>
-  {{/if}}
-{{!/unless}}
+
+
+
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/app/templates/main/service/info/summary_alert.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary_alert.hbs b/ambari-web/app/templates/main/service/info/summary_alert.hbs
deleted file mode 100644
index cfa8171..0000000
--- a/ambari-web/app/templates/main/service/info/summary_alert.hbs
+++ /dev/null
@@ -1,49 +0,0 @@
-{{!
-* 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.
-}}
-
-<div class="container-fluid">
-    <div class="row-fluid">
-        <div class="span1 status-icon">
-          {{#if isOk}}
-              <i class="icon-ok icon-large"></i>
-          {{else}}
-	          {{#if isWarning}}
-	              <i class="icon-warning-sign icon-large"></i>
-	          {{else}}
-              {{#if isCritical}}
-                  <i class="icon-remove icon-large"></i>
-              {{else}}
-                {{#if isPassive}}
-                    <i class="icon-medkit icon-large"></i>
-                {{else}}
-                    <i class="icon-question-sign icon-large"></i>
-                {{/if}}
-              {{/if}}
-	          {{/if}}
-          {{/if}}
-        </div>
-        <div class="span11">
-            <div class="row-fluid">
-                <div class="span7 title">{{title}}
-                </div>
-                <div rel="tooltip" {{bindAttr data-title="timeSinceAlertDetails"}} data-placement="right"
class="span5 date-time">{{timeSinceAlert}}</div>
-            </div>
-            <div class="row-fluid message">{{message}}</div>
-        </div>
-    </div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/app/views/common/chart/linear_time.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/chart/linear_time.js b/ambari-web/app/views/common/chart/linear_time.js
index f76bc72..e2032b1 100644
--- a/ambari-web/app/views/common/chart/linear_time.js
+++ b/ambari-web/app/views/common/chart/linear_time.js
@@ -739,7 +739,6 @@ App.ChartLinearTimeView = Ember.View.extend({
       onPrimary: function() {
         this.hide();
         self.set('isPopup', false);
-        self.set('timeUnitSeconds', 3600);
       },
       onClose: function() {
         this.onPrimary();
@@ -771,22 +770,12 @@ App.ChartLinearTimeView = Ember.View.extend({
        */
       reloadGraphByTime: function(index) {
         this.set('currentTimeIndex', index);
-        self.set('timeUnitSeconds', this.get('timeStates')[index].seconds);
+        self.set('currentTimeIndex', index);
         self.loadData();
       },
-      timeStates: [
-        {name: Em.I18n.t('graphs.timeRange.hour'), seconds: 3600},
-        {name: Em.I18n.t('graphs.timeRange.twoHours'), seconds: 7200},
-        {name: Em.I18n.t('graphs.timeRange.fourHours'), seconds: 14400},
-        {name: Em.I18n.t('graphs.timeRange.twelveHours'), seconds: 43200},
-        {name: Em.I18n.t('graphs.timeRange.day'), seconds: 86400},
-        {name: Em.I18n.t('graphs.timeRange.week'), seconds: 604800},
-        {name: Em.I18n.t('graphs.timeRange.month'), seconds: 2592000},
-        {name: Em.I18n.t('graphs.timeRange.year'), seconds: 31104000}
-      ],
-      currentTimeIndex: 0,
+      currentTimeIndex: self.get('currentTimeIndex'),
       currentTimeState: function() {
-        return this.get('timeStates').objectAt(this.get('currentTimeIndex'));
+        return self.get('timeStates').objectAt(this.get('currentTimeIndex'));
       }.property('currentTimeIndex')
     });
     Ember.run.next(function() {
@@ -794,8 +783,21 @@ App.ChartLinearTimeView = Ember.View.extend({
       self.set('isPopupReady', false);
     });
   },
-  //60 minute interval on X axis.
-  timeUnitSeconds: 3600
+  timeStates: [
+    {name: Em.I18n.t('graphs.timeRange.hour'), seconds: 3600},
+    {name: Em.I18n.t('graphs.timeRange.twoHours'), seconds: 7200},
+    {name: Em.I18n.t('graphs.timeRange.fourHours'), seconds: 14400},
+    {name: Em.I18n.t('graphs.timeRange.twelveHours'), seconds: 43200},
+    {name: Em.I18n.t('graphs.timeRange.day'), seconds: 86400},
+    {name: Em.I18n.t('graphs.timeRange.week'), seconds: 604800},
+    {name: Em.I18n.t('graphs.timeRange.month'), seconds: 2592000},
+    {name: Em.I18n.t('graphs.timeRange.year'), seconds: 31104000}
+  ],
+  // should be set by time range control dropdown list when create current graph
+  currentTimeIndex: 0,
+  timeUnitSeconds: function() {
+    return this.get('timeStates').objectAt(this.get('currentTimeIndex')).seconds;
+  }.property('currentTimeIndex')
 });
 
 /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/app/views/main/service/info/metrics/flume/flume_metric_graphs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/metrics/flume/flume_metric_graphs.js b/ambari-web/app/views/main/service/info/metrics/flume/flume_metric_graphs.js
index 3c4efb0..d38074e 100644
--- a/ambari-web/app/views/main/service/info/metrics/flume/flume_metric_graphs.js
+++ b/ambari-web/app/views/main/service/info/metrics/flume/flume_metric_graphs.js
@@ -61,7 +61,7 @@ App.MainServiceInfoFlumeGraphsView = App.MainServiceInfoSummaryMetricGraphsView.
     graphRows.push([]);
     var graphs = graphRows[0];
     for (var metricName in metricNames) {
-      if (graphs.length > 3) {
+      if (graphs.length > 1) {
         graphRows.push([]);
         graphs = graphRows[graphRows.length - 1];
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/app/views/main/service/info/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/summary.js b/ambari-web/app/views/main/service/info/summary.js
index 4e9e36c..5d568c9 100644
--- a/ambari-web/app/views/main/service/info/summary.js
+++ b/ambari-web/app/views/main/service/info/summary.js
@@ -20,21 +20,7 @@ var batchUtils = require('utils/batch_scheduled_requests');
 require('views/main/service/service');
 require('data/service_graph_config');
 
-App.AlertItemView = Em.View.extend({
-  tagName:"li",
-  templateName: require('templates/main/service/info/summary_alert'),
-  classNameBindings: ["status"],
-  status: function () {
-    return "status-" + this.get("content.status");
-  }.property('content'),
-  didInsertElement: function () {
-    // Tooltips for alerts need to be enabled.
-    App.tooltip($("div[rel=tooltip]"));
-    $(".tooltip").remove();
-  }
-});
-
-App.MainServiceInfoSummaryView = Em.View.extend({
+App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, {
   templateName: require('templates/main/service/info/summary'),
   attributes:null,
 
@@ -258,6 +244,18 @@ App.MainServiceInfoSummaryView = Em.View.extend({
   componentsCount: null,
   hostsCount: null,
 
+  /*
+   * alerts label on summary box header. no alerts/ {cnt} alerts
+   */
+  alertsCountLabel: function () {
+    var cnt = this.get('controller.content.criticalAlertsCount');
+    return cnt? Em.I18n.t('services.service.summary.alerts.alertsExist').format(cnt) :
+      Em.I18n.t('services.service.summary.alerts.noAlerts');
+  }.property('controller.content.criticalAlertsCount'),
+  alertsCount: function () {
+    return !!this.get('controller.content.criticalAlertsCount');
+  }.property('controller.content.criticalAlertsCount'),
+
   restartRequiredHostsAndComponents:function () {
     return this.get('controller.content.restartRequiredHostsAndComponents');
   }.property('controller.content.restartRequiredHostsAndComponents'),
@@ -315,40 +313,105 @@ App.MainServiceInfoSummaryView = Em.View.extend({
 
    /*
    * Find the graph class associated with the graph name, and split
-   * the array into sections of 4 for displaying on the page
-   * (will only display rows with 4 items)
+   * the array into sections of 2 for displaying on the page
+   * (will only display rows with 2 items)
    */
   constructGraphObjects: function(graphNames) {
-    var result = [], graphObjects = [], chunkSize = 4;
+    var result = [], graphObjects = [], chunkSize = 2;
+    var self = this;
 
     if (!graphNames) {
-      return [];
+      self.set('serviceMetricGraphs', []);
+      self.set('isServiceMetricLoaded', true);
+      return;
     }
+    // load time range for current service from server
+    self.getUserPref(self.get('persistKey')).complete(function () {
+      var index = self.get('currentTimeRangeIndex');
+      graphNames.forEach(function(graphName) {
+        graphObjects.push(App["ChartServiceMetrics" + graphName].extend({
+          currentTimeIndex : index
+        }));
+      });
 
-    graphNames.forEach(function(graphName) {
-      graphObjects.push(App["ChartServiceMetrics" + graphName].extend());
+      while(graphObjects.length) {
+        result.push(graphObjects.splice(0, chunkSize));
+      }
+      self.set('serviceMetricGraphs', result);
+      self.set('isServiceMetricLoaded', true);
     });
+  },
+
+  /**
+   * Contains graphs for this particular service
+   */
+  serviceMetricGraphs: [],
+  isServiceMetricLoaded: false,
 
-    while(graphObjects.length) {
-      result.push(graphObjects.splice(0, chunkSize));
+  /**
+   * Key-name to store time range in Persist
+   * @type {string}
+   */
+  persistKey: function () {
+    return 'time-range-service-' + this.get('service.serviceName');
+  }.property(),
+
+  getUserPrefSuccessCallback: function (response, request, data) {
+    if (response) {
+      console.log('Got persist value from server with key ' + data.key + '. Value is: ' +
response);
+      this.set('currentTimeRangeIndex', response);
     }
+  },
 
-    return result;
+  getUserPrefErrorCallback: function (request) {
+    if (request.status == 404) {
+      console.log('Persist did NOT find the key');
+    }
   },
 
   /**
-   * Contains graphs for this particular service
+   * time range options for service metrics, a dropdown will list all options
    */
-  serviceMetricGraphs:function() {
-    var svcName = this.get('service.serviceName');
-    var graphs = [];
+  timeRangeOptions: [
+    {index: 0, name: Em.I18n.t('graphs.timeRange.hour'), seconds: 3600},
+    {index: 1, name: Em.I18n.t('graphs.timeRange.twoHours'), seconds: 7200},
+    {index: 2, name: Em.I18n.t('graphs.timeRange.fourHours'), seconds: 14400},
+    {index: 3, name: Em.I18n.t('graphs.timeRange.twelveHours'), seconds: 43200},
+    {index: 4, name: Em.I18n.t('graphs.timeRange.day'), seconds: 86400},
+    {index: 5, name: Em.I18n.t('graphs.timeRange.week'), seconds: 604800},
+    {index: 6, name: Em.I18n.t('graphs.timeRange.month'), seconds: 2592000},
+    {index: 7, name: Em.I18n.t('graphs.timeRange.year'), seconds: 31104000}
+  ],
+
+  currentTimeRangeIndex: 0,
+  currentTimeRange: function() {
+    return this.get('timeRangeOptions').objectAt(this.get('currentTimeRangeIndex'));
+  }.property('currentTimeRangeIndex'),
 
-    if (svcName) {
-      graphs = this.constructGraphObjects(App.service_graph_config[svcName.toLowerCase()]);
+  /**
+   * onclick handler for a time range option
+   */
+  setTimeRange: function (event) {
+    var self = this;
+    if (event && event.context) {
+      self.postUserPref(self.get('persistKey'), event.context.index);
+      self.set('currentTimeRangeIndex', event.context.index);
+      var svcName = self.get('service.serviceName');
+      if (svcName) {
+        var result = [], graphObjects = [], chunkSize = 2;
+        App.service_graph_config[svcName.toLowerCase()].forEach(function(graphName) {
+          graphObjects.push(App["ChartServiceMetrics" + graphName].extend({
+            currentTimeIndex : event.context.index
+          }));
+        });
+        while(graphObjects.length) {
+          result.push(graphObjects.splice(0, chunkSize));
+        }
+        self.set('serviceMetricGraphs', result);
+        self.set('isServiceMetricLoaded', true);
+      }
     }
-
-    return graphs;
-  }.property(''),
+  },
 
   loadServiceSummary: function () {
     var serviceName = this.get('serviceName');
@@ -409,6 +472,10 @@ App.MainServiceInfoSummaryView = Em.View.extend({
   }.property('App.router.clusterController.gangliaUrl', 'service.serviceName'),
 
   didInsertElement:function () {
+    var svcName = this.get('service.serviceName');
+    if (svcName) {
+      this.constructGraphObjects(App.service_graph_config[svcName.toLowerCase()]);
+    }
     // adjust the summary table height
     var summaryTable = document.getElementById('summary-info');
     if (summaryTable) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/test/views/common/chart/linear_time_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/chart/linear_time_test.js b/ambari-web/test/views/common/chart/linear_time_test.js
index 15a0d9a..d581a6f 100644
--- a/ambari-web/test/views/common/chart/linear_time_test.js
+++ b/ambari-web/test/views/common/chart/linear_time_test.js
@@ -140,7 +140,6 @@ describe('App.ChartLinearTimeView', function () {
       sinon.stub(App.YARNService, 'find', function(){return services.yarnService});
       sinon.stub(App.MapReduceService, 'find', function(){return services.mapreduceService});
       sinon.stub(App, 'dateTime').returns(1000);
-      chartLinearTimeView.set('timeUnitSeconds', 1);
       chartLinearTimeView.set('content', null);
     });
     afterEach(function(){
@@ -156,7 +155,7 @@ describe('App.ChartLinearTimeView', function () {
       }));
       expect(chartLinearTimeView.getDataForAjaxRequest()).to.be.eql({
         toSeconds: 1,
-        fromSeconds: 0,
+        fromSeconds: -3599,
         stepSeconds: 15,
         hostName: 'host1',
         nameNodeName: '',
@@ -172,7 +171,7 @@ describe('App.ChartLinearTimeView', function () {
       ];
       expect(chartLinearTimeView.getDataForAjaxRequest()).to.be.eql({
         toSeconds: 1,
-        fromSeconds: 0,
+        fromSeconds: -3599,
         stepSeconds: 15,
         hostName: '',
         nameNodeName: 'host1',
@@ -189,7 +188,7 @@ describe('App.ChartLinearTimeView', function () {
       ];
       expect(chartLinearTimeView.getDataForAjaxRequest()).to.be.eql({
         toSeconds: 1,
-        fromSeconds: 0,
+        fromSeconds: -3599,
         stepSeconds: 15,
         hostName: '',
         nameNodeName: 'host1',
@@ -206,7 +205,7 @@ describe('App.ChartLinearTimeView', function () {
       ];
       expect(chartLinearTimeView.getDataForAjaxRequest()).to.be.eql({
         toSeconds: 1,
-        fromSeconds: 0,
+        fromSeconds: -3599,
         stepSeconds: 15,
         hostName: '',
         nameNodeName: '',
@@ -223,7 +222,7 @@ describe('App.ChartLinearTimeView', function () {
       ];
       expect(chartLinearTimeView.getDataForAjaxRequest()).to.be.eql({
         toSeconds: 1,
-        fromSeconds: 0,
+        fromSeconds: -3599,
         stepSeconds: 15,
         hostName: '',
         nameNodeName: '',

http://git-wip-us.apache.org/repos/asf/ambari/blob/8a322603/ambari-web/test/views/main/service/info/summary_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/service/info/summary_test.js b/ambari-web/test/views/main/service/info/summary_test.js
index 42909f4..be377b5 100644
--- a/ambari-web/test/views/main/service/info/summary_test.js
+++ b/ambari-web/test/views/main/service/info/summary_test.js
@@ -104,25 +104,4 @@ describe('App.MainServiceInfoSummaryView', function() {
 
   });
 
-  describe("#constructGraphObjects", function() {
-    it("should return a single array with the items in the fom of '<name>.extend()'
when the number of items is less than 4", function() {
-      var graphs = ['HDFS_SpaceUtilization'];
-
-      expect(view.constructGraphObjects(graphs).length).to.equal(1);
-      expect(view.constructGraphObjects(graphs)[0].length).to.equal(1);
-    });
-
-    it("should return an array with arrays that are grouped into sizes of 4 or less when
number of items is greater than 4", function() {
-      var graphs = ['HDFS_SpaceUtilization', 'YARN_AllocatedMemory', 'MapReduce_JobsStatus',

-      'HBASE_ClusterRequests', 'Flume_ChannelSizeMMA'];
-
-      expect(view.constructGraphObjects(graphs).length).to.equal(2);
-      expect(view.constructGraphObjects(graphs)[0].length).to.equal(4);
-      expect(view.constructGraphObjects(graphs)[1].length).to.equal(1);
-    });
-
-    it("should return an empty array if the graphs array provided is empty", function() {
-      expect(view.constructGraphObjects([])).to.be.empty;
-    });
-  });
 });
\ No newline at end of file


Mime
View raw message