Jelajahi Sumber

AMBARI-13433. Issues with CSV download.

Alex Antonenko 9 tahun lalu
induk
melakukan
c877445e48

File diff ditekan karena terlalu besar
+ 0 - 0
ambari-web/app/assets/data/cluster_metrics/cpu_1hr.json


File diff ditekan karena terlalu besar
+ 0 - 0
ambari-web/app/assets/data/cluster_metrics/load_1hr.json


File diff ditekan karena terlalu besar
+ 0 - 0
ambari-web/app/assets/data/cluster_metrics/memory_1hr.json


File diff ditekan karena terlalu besar
+ 0 - 0
ambari-web/app/assets/data/cluster_metrics/network_1hr.json


+ 11 - 3
ambari-web/app/mixins/common/widgets/export_metrics_mixin.js

@@ -29,16 +29,24 @@ App.ExportMetricsMixin = Em.Mixin.create({
    */
    */
   exportToCSVArgument: true,
   exportToCSVArgument: true,
 
 
-  isMenuHidden: true,
+  isExportMenuHidden: true,
+
+  isExportButtonHidden: false,
 
 
   exportMetricsMenuView: App.ExportMetricsMenuView.extend(),
   exportMetricsMenuView: App.ExportMetricsMenuView.extend(),
 
 
+  hideMenuForNoData: function () {
+    if (this.get('isExportButtonHidden')) {
+      this.set('isExportMenuHidden', true);
+    }
+  }.observes('isExportButtonHidden'),
+
   toggleFormatsList: function () {
   toggleFormatsList: function () {
-    this.toggleProperty('isMenuHidden');
+    this.toggleProperty('isExportMenuHidden');
   },
   },
 
 
   exportGraphData: function () {
   exportGraphData: function () {
-    this.set('isMenuHidden', true);
+    this.set('isExportMenuHidden', true);
   },
   },
 
 
   exportGraphDataSuccessCallback: function (response, request, params) {
   exportGraphDataSuccessCallback: function (response, request, params) {

+ 3 - 1
ambari-web/app/styles/application.less

@@ -2306,9 +2306,11 @@ a:focus {
     z-index: 5;
     z-index: 5;
   }
   }
   .chart-title {
   .chart-title {
-    padding-right: 15px;
     text-align: center;
     text-align: center;
     font-size: small;
     font-size: small;
+    &.has-data {
+      padding-right: 15px;
+    }
   }
   }
   .corner-icon {
   .corner-icon {
     position: absolute;
     position: absolute;

+ 40 - 38
ambari-web/app/styles/enhanced_service_dashboard.less

@@ -27,9 +27,9 @@
     width: 98%;
     width: 98%;
     padding: 43px;
     padding: 43px;
     border: 1px solid @border-color;
     border: 1px solid @border-color;
-    border-radius: 0px;
-    -webkit-border-radius: 0px;
-    -moz-border-radius: 0px;
+    border-radius: 0;
+    -webkit-border-radius: 0;
+    -moz-border-radius: 0;
     background-image: none;
     background-image: none;
     .icon-plus {
     .icon-plus {
       font-size: 70px;
       font-size: 70px;
@@ -140,13 +140,13 @@
         background: url(/img/spinner.gif) no-repeat center center;
         background: url(/img/spinner.gif) no-repeat center center;
       }
       }
       .chart-container{
       .chart-container{
-        margin: -4px 8px 0px 8px;
+        margin: -4px 8px 0 8px;
         .chart-y-axis{
         .chart-y-axis{
           margin-top: 10px;
           margin-top: 10px;
         }
         }
         .chart-legend {
         .chart-legend {
           top: 110px;
           top: 110px;
-          left: 0px;
+          left: 0;
           padding: 3px;
           padding: 3px;
           min-width: 100%;
           min-width: 100%;
           text-align: left;
           text-align: left;
@@ -210,31 +210,33 @@
         display: none;
         display: none;
         .icon-remove-sign{
         .icon-remove-sign{
           color: #000000;
           color: #000000;
-          text-shadow: #fff 0px 0px 15px;
+          text-shadow: #fff 0 0 15px;
           position: absolute;
           position: absolute;
           left: -7px;
           left: -7px;
           top: -7px;
           top: -7px;
         }
         }
-        .icon-edit, .icon-copy, .icon-save {
-          color: #555555;
-          font-weight: bold;
-          text-shadow: #ffffff -8px 8px 10px;
-          background-color: rgba(255,255,255,0.6);
-          position: absolute;
-          padding: 5px 5px;
-        }
-        .icon-copy {
-          right: 45px;
-        }
-        .icon-edit {
-          right: 25px;
-        }
-        .icon-save {
-          right: 5px;
+      }
+      .widget-icons {
+        position: absolute;
+        right: 5px;
+        top: 6px;
+        .corner-icon {
+          i {
+            position: relative;
+            color: #555555;
+            font-weight: bold;
+            text-shadow: #fff -8px 8px 8px, #fff 8px 8px 8px, #fff -8px -8px 8px, #fff 8px -8px 8px;
+            background-color: rgba(255,255,255,0.6);
+            padding: 5px 5px 5px 2px;
+          }
+          &.hidden i {
+            display: none;
+          }
         }
         }
       }
       }
       .export-graph-list {
       .export-graph-list {
-        right: -1px;
+        right: -6px;
+        margin-top: -2px;
       }
       }
       &:hover {
       &:hover {
         cursor: move;
         cursor: move;
@@ -281,7 +283,7 @@
 }
 }
 
 
 .chart-legend .description-line {
 .chart-legend .description-line {
-  padding: 0px 3px 8px 8px;
+  padding: 0 3px 8px 8px;
   line-height: 16px;
   line-height: 16px;
   max-height: 45px;
   max-height: 45px;
   font-weight: bold;
   font-weight: bold;
@@ -440,7 +442,7 @@
         a {
         a {
           position: absolute;
           position: absolute;
           right: 3px;
           right: 3px;
-          top: 0px;
+          top: 0;
           text-decoration: none;
           text-decoration: none;
           display: none;
           display: none;
           .icon-remove {
           .icon-remove {
@@ -479,9 +481,9 @@
           -webkit-box-shadow: none;
           -webkit-box-shadow: none;
           -moz-box-shadow: none;
           -moz-box-shadow: none;
           box-shadow: none;
           box-shadow: none;
-          border-radius: 0px;
-          -webkit-border-radius: 0px;
-          -moz-border-radius: 0px;
+          border-radius: 0;
+          -webkit-border-radius: 0;
+          -moz-border-radius: 0;
           -webkit-transition: none;
           -webkit-transition: none;
           -moz-transition: none;
           -moz-transition: none;
           -o-transition: none;
           -o-transition: none;
@@ -528,7 +530,7 @@
         }
         }
         label.checkbox {
         label.checkbox {
           line-height: 20px;
           line-height: 20px;
-          margin-bottom: 0px;
+          margin-bottom: 0;
           margin-top: 5px;
           margin-top: 5px;
         }
         }
         .description-text-area {
         .description-text-area {
@@ -556,7 +558,7 @@
   .select-options-dropdown {
   .select-options-dropdown {
     width: 240px;
     width: 240px;
     max-height: 123px;
     max-height: 123px;
-    padding: 0px;
+    padding: 0;
     border-bottom: 200px transparent solid;
     border-bottom: 200px transparent solid;
     border-right: 150px transparent solid;
     border-right: 150px transparent solid;
     border-left: none;
     border-left: none;
@@ -567,13 +569,13 @@
   }
   }
   li.metric-select {
   li.metric-select {
     padding: 5px;
     padding: 5px;
-    padding-bottom: 0px;
+    padding-bottom: 0;
     border: 1px #ccc solid;
     border: 1px #ccc solid;
     border-bottom: none;
     border-bottom: none;
   }
   }
   li.aggregator-select {
   li.aggregator-select {
     padding: 5px;
     padding: 5px;
-    padding-bottom: 0px;
+    padding-bottom: 0;
     border: 1px #ccc solid;
     border: 1px #ccc solid;
     border-bottom: none;
     border-bottom: none;
     border-top: none;
     border-top: none;
@@ -629,9 +631,9 @@
       min-width: 300px;
       min-width: 300px;
       width: 300px;
       width: 300px;
       border: 1px solid rgba(0, 0, 0, 0.2);
       border: 1px solid rgba(0, 0, 0, 0.2);
-      -webkit-border-radius: 0px;
-      -moz-border-radius: 0px;
-      border-radius: 0px;
+      -webkit-border-radius: 0;
+      -moz-border-radius: 0;
+      border-radius: 0;
       -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
       -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
       -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
       -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
       box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
       box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
@@ -645,7 +647,7 @@
     max-height: 600px;
     max-height: 600px;
     position: fixed;
     position: fixed;
     .modal-body {
     .modal-body {
-      padding-top: 0px;
+      padding-top: 0;
       min-height: 290px;
       min-height: 290px;
       max-height: 460px;
       max-height: 460px;
     }
     }
@@ -717,7 +719,7 @@
           }
           }
           .is-shared-icon {
           .is-shared-icon {
             display: inline-block;
             display: inline-block;
-            margin-bottom: 0px;
+            margin-bottom: 0;
             margin-right: 5px;
             margin-right: 5px;
             color: #888;
             color: #888;
           }
           }
@@ -749,7 +751,7 @@
           }
           }
           .dropdown-menu {
           .dropdown-menu {
             min-width: 110px;
             min-width: 110px;
-            left: 0px;
+            left: 0;
           }
           }
         }
         }
       }
       }

+ 5 - 7
ambari-web/app/templates/common/chart/linear_time.hbs

@@ -19,12 +19,10 @@
 <div {{bindAttr class="view.isReady:hide:show :screensaver :no-borders :chart-container"}}></div>
 <div {{bindAttr class="view.isReady:hide:show :screensaver :no-borders :chart-container"}}></div>
 <div {{bindAttr class="view.isReady::hidden :time-label"}}>
 <div {{bindAttr class="view.isReady::hidden :time-label"}}>
   {{view.parentView.currentTimeState.name}}
   {{view.parentView.currentTimeState.name}}
-  {{#if view.parentView.graph.hasData}}
-    <a class="corner-icon pull-right" href="#" {{action toggleFormatsList target="view"}}>
-      <i class="icon-save"></i>
-    </a>
-    {{view view.exportMetricsMenuView}}
-  {{/if}}
+  <a {{bindAttr class="view.isExportButtonHidden:hidden :corner-icon :pull-right"}} href="#" {{action toggleFormatsList target="view"}}>
+    <i class="icon-save"></i>
+  </a>
+  {{view view.exportMetricsMenuView}}
 </div>
 </div>
 {{#if view.isTimePagingEnable}}
 {{#if view.isTimePagingEnable}}
   <div {{bindAttr class="view.leftArrowVisible:visibleArrow :arrow-left"}} {{action "switchTimeBack" target="view.parentView"}}></div>
   <div {{bindAttr class="view.leftArrowVisible:visibleArrow :arrow-left"}} {{action "switchTimeBack" target="view.parentView"}}></div>
@@ -34,7 +32,7 @@
   <div {{bindAttr id="view.xAxisId"}} {{bindAttr class="view.xAxisClass :chart-x-axis"}}></div>
   <div {{bindAttr id="view.xAxisId"}} {{bindAttr class="view.xAxisClass :chart-x-axis"}}></div>
   <div {{bindAttr id="view.legendId"}} {{bindAttr class="view.legendClass :chart-legend"}}></div>
   <div {{bindAttr id="view.legendId"}} {{bindAttr class="view.legendClass :chart-legend"}}></div>
   <div {{bindAttr id="view.chartId"}} {{bindAttr class="view.chartClass :chart"}}></div>
   <div {{bindAttr id="view.chartId"}} {{bindAttr class="view.chartClass :chart"}}></div>
-  <div {{bindAttr id="view.titleId"}} {{bindAttr class="view.titleClass :chart-title"}}>{{view.title}}</div>
+  <div {{bindAttr id="view.titleId"}} {{bindAttr class="view.titleClass view.isExportButtonHidden::has-data :chart-title"}}>{{view.title}}</div>
 </div>
 </div>
 {{#if view.isTimePagingEnable}}
 {{#if view.isTimePagingEnable}}
   <div {{bindAttr class="view.rightArrowVisible:visibleArrow :arrow-right"}} {{action "switchTimeForward" "forward" target="view.parentView"}}></div>
   <div {{bindAttr class="view.rightArrowVisible:visibleArrow :arrow-right"}} {{action "switchTimeForward" "forward" target="view.parentView"}}></div>

+ 8 - 6
ambari-web/app/templates/common/widget/gauge_widget.hbs

@@ -23,12 +23,14 @@
     </a>
     </a>
     <div class="caption title span11">{{view.content.widgetName}}</div>
     <div class="caption title span11">{{view.content.widgetName}}</div>
     {{#isAccessible ADMIN}}
     {{#isAccessible ADMIN}}
-      <a class="corner-icon pull-right" href="#" {{action cloneWidget target="view"}}>
-        <i class="icon-copy"></i>
-      </a>
-      <a class="corner-icon pull-right" href="#" {{action editWidget target="view"}}>
-        <i class="icon-edit"></i>
-      </a>
+      <div class="widget-icons">
+        <a class="corner-icon pull-right" href="#" {{action editWidget target="view"}}>
+          <i class="icon-edit"></i>
+        </a>
+        <a class="corner-icon pull-right" href="#" {{action cloneWidget target="view"}}>
+          <i class="icon-copy"></i>
+        </a>
+      </div>
     {{/isAccessible}}
     {{/isAccessible}}
     <div class="content">
     <div class="content">
       {{#if view.isUnavailable}}
       {{#if view.isUnavailable}}

+ 12 - 10
ambari-web/app/templates/common/widget/graph_widget.hbs

@@ -23,16 +23,18 @@
     </a>
     </a>
     <div class="caption title span11">{{view.content.widgetName}}</div>
     <div class="caption title span11">{{view.content.widgetName}}</div>
     {{#isAccessible ADMIN}}
     {{#isAccessible ADMIN}}
-      <a class="corner-icon pull-right" href="#" {{action cloneWidget target="view"}}>
-        <i class="icon-copy"></i>
-      </a>
-      <a class="corner-icon pull-right" href="#" {{action editWidget target="view"}}>
-        <i class="icon-edit"></i>
-      </a>
-      <a class="corner-icon pull-right" href="#" {{action toggleFormatsList target="view"}}>
-        <i class="icon-save"></i>
-      </a>
-      {{view view.exportMetricsMenuView}}
+      <div class="widget-icons">
+        <a {{bindAttr class="view.isExportButtonHidden:hidden :corner-icon :pull-right"}} href="#" {{action toggleFormatsList target="view"}}>
+          <i class="icon-save"></i>
+        </a>
+        <a class="corner-icon pull-right" href="#" {{action editWidget target="view"}}>
+          <i class="icon-edit"></i>
+        </a>
+        <a class="corner-icon pull-right" href="#" {{action cloneWidget target="view"}}>
+          <i class="icon-copy"></i>
+        </a>
+        {{view view.exportMetricsMenuView}}
+      </div>
     {{/isAccessible}}
     {{/isAccessible}}
     <div class="content"> {{view view.graphView}}</div>
     <div class="content"> {{view view.graphView}}</div>
 
 

+ 5 - 3
ambari-web/app/templates/common/widget/number_widget.hbs

@@ -23,12 +23,14 @@
     </a>
     </a>
     <div class="caption title span11">{{view.content.widgetName}}</div>
     <div class="caption title span11">{{view.content.widgetName}}</div>
     {{#isAccessible ADMIN}}
     {{#isAccessible ADMIN}}
-      <a class="corner-icon pull-right" href="#" {{action cloneWidget target="view"}}>
-        <i class="icon-copy"></i>
-      </a>
+    <div class="widget-icons">
       <a class="corner-icon pull-right" href="#" {{action editWidget target="view"}}>
       <a class="corner-icon pull-right" href="#" {{action editWidget target="view"}}>
         <i class="icon-edit"></i>
         <i class="icon-edit"></i>
       </a>
       </a>
+      <a class="corner-icon pull-right" href="#" {{action cloneWidget target="view"}}>
+        <i class="icon-copy"></i>
+      </a>
+      </div>
     {{/isAccessible}}
     {{/isAccessible}}
     <div {{bindAttr class="view.contentColor :content"}}>{{view.displayValue}}</div>
     <div {{bindAttr class="view.contentColor :content"}}>{{view.displayValue}}</div>
     {{#if view.content.description}}
     {{#if view.content.description}}

+ 8 - 6
ambari-web/app/templates/common/widget/template_widget.hbs

@@ -23,12 +23,14 @@
     </a>
     </a>
     <div class="caption title span11">{{view.content.widgetName}}</div>
     <div class="caption title span11">{{view.content.widgetName}}</div>
     {{#isAccessible ADMIN}}
     {{#isAccessible ADMIN}}
-      <a class="corner-icon pull-right" href="#" {{action cloneWidget target="view"}}>
-        <i class="icon-copy"></i>
-      </a>
-      <a class="corner-icon pull-right" href="#" {{action editWidget target="view"}}>
-        <i class="icon-edit"></i>
-      </a>
+      <div class="widget-icons">
+        <a class="corner-icon pull-right" href="#" {{action editWidget target="view"}}>
+          <i class="icon-edit"></i>
+        </a>
+        <a class="corner-icon pull-right" href="#" {{action cloneWidget target="view"}}>
+          <i class="icon-copy"></i>
+        </a>
+      </div>
     {{/isAccessible}}
     {{/isAccessible}}
     <div {{bindAttr class="view.contentColor :content"}}>{{{view.displayValue}}}</div>
     <div {{bindAttr class="view.contentColor :content"}}>{{{view.displayValue}}}</div>
     {{#if view.content.description}}
     {{#if view.content.description}}

+ 2 - 2
ambari-web/app/templates/main/charts/linear_time.hbs

@@ -26,11 +26,11 @@
   <div id="{{unbound view.id}}-chart" class="chart"  {{action showGraphInPopup target="view"}}></div>
   <div id="{{unbound view.id}}-chart" class="chart"  {{action showGraphInPopup target="view"}}></div>
   <div id="{{unbound view.id}}-timeline" class="timeline" {{action showGraphInPopup target="view"}}></div>
   <div id="{{unbound view.id}}-timeline" class="timeline" {{action showGraphInPopup target="view"}}></div>
   {{#unless view.noTitleUnderGraph}}
   {{#unless view.noTitleUnderGraph}}
-    <div id="{{unbound view.id}}-title" class="chart-title">
+    <div id="{{unbound view.id}}-title" {{bindAttr class="view.isExportButtonHidden::has-data :chart-title"}}>
       {{view.title}}
       {{view.title}}
     </div>
     </div>
     {{#if view.isReady}}
     {{#if view.isReady}}
-      <a class="corner-icon span1" href="#" {{action toggleFormatsList target="view"}}>
+      <a {{bindAttr class="view.isExportButtonHidden:hidden :corner-icon :span1"}} href="#" {{action toggleFormatsList target="view"}}>
         <i class="icon-save"></i>
         <i class="icon-save"></i>
       </a>
       </a>
       <div class="export-graph-list-top"></div>
       <div class="export-graph-list-top"></div>

+ 1 - 1
ambari-web/app/templates/main/dashboard/widgets/cluster_metrics.hbs

@@ -25,7 +25,7 @@
       <div class="caption span10">{{view.title}}</div>
       <div class="caption span10">{{view.title}}</div>
       {{#if view.isDataLoaded}}
       {{#if view.isDataLoaded}}
         {{#if view.childViews.lastObject.hasData}}
         {{#if view.childViews.lastObject.hasData}}
-          <a class="corner-icon span1" href="#" {{action toggleFormatsList target="view"}}>
+          <a {{bindAttr class="view.isExportButtonHidden:hidden :corner-icon :span1"}} href="#" {{action toggleFormatsList target="view"}}>
             <i class="icon-save"></i>
             <i class="icon-save"></i>
           </a>
           </a>
           {{view view.exportMetricsMenuView}}
           {{view view.exportMetricsMenuView}}

+ 16 - 6
ambari-web/app/views/common/chart/linear_time.js

@@ -165,7 +165,7 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
     this.loadData();
     this.loadData();
     this.registerGraph();
     this.registerGraph();
     this.$().parent().on('mouseleave', function () {
     this.$().parent().on('mouseleave', function () {
-      self.set('isMenuHidden', true);
+      self.set('isExportMenuHidden', true);
     });
     });
     App.tooltip(this.$("[rel='ZoomInTooltip']"), {
     App.tooltip(this.$("[rel='ZoomInTooltip']"), {
       placement: 'left',
       placement: 'left',
@@ -209,7 +209,7 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
         name: this.get('ajaxIndex'),
         name: this.get('ajaxIndex'),
         sender: this,
         sender: this,
         data: this.getDataForAjaxRequest(),
         data: this.getDataForAjaxRequest(),
-        success: '_refreshGraph',
+        success: 'loadDataSuccessCallback',
         error: 'loadDataErrorCallback'
         error: 'loadDataErrorCallback'
       });
       });
     }
     }
@@ -237,13 +237,20 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
     };
     };
   },
   },
 
 
+  loadDataSuccessCallback: function (response) {
+    this._refreshGraph(response);
+  },
+
   loadDataErrorCallback: function (xhr, textStatus, errorThrown) {
   loadDataErrorCallback: function (xhr, textStatus, errorThrown) {
     this.set('isReady', true);
     this.set('isReady', true);
     if (xhr.readyState == 4 && xhr.status) {
     if (xhr.readyState == 4 && xhr.status) {
       textStatus = xhr.status + " " + textStatus;
       textStatus = xhr.status + " " + textStatus;
     }
     }
     this._showMessage('warn', this.t('graphs.error.title'), this.t('graphs.error.message').format(textStatus, errorThrown));
     this._showMessage('warn', this.t('graphs.error.title'), this.t('graphs.error.message').format(textStatus, errorThrown));
-    this.set('hasData', false);
+    this.setProperties({
+      hasData: false,
+      isExportButtonHidden: true
+    });
   },
   },
 
 
   /**
   /**
@@ -390,7 +397,7 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
    *
    *
    * @type Function
    * @type Function
    */
    */
-  _refreshGraph: function (jsonData) {
+  _refreshGraph: function (jsonData, graphView) {
     if (this.get('isDestroyed')) {
     if (this.get('isDestroyed')) {
       return;
       return;
     }
     }
@@ -414,7 +421,10 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
         }
         }
       });
       });
     }
     }
-    if (this.checkSeries(seriesData)) {
+    var hasData = this.checkSeries(seriesData);
+    var view = graphView || this;
+    view.set('isExportButtonHidden', !hasData);
+    if (hasData) {
       // Check container exists (may be not, if we go to another page and wait while graphs loading)
       // Check container exists (may be not, if we go to another page and wait while graphs loading)
       if (graph_container.length) {
       if (graph_container.length) {
         container = $(this.get('_containerSelector'));
         container = $(this.get('_containerSelector'));
@@ -760,7 +770,7 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
           });
           });
           this.$().closest('.modal').on('click', function (event) {
           this.$().closest('.modal').on('click', function (event) {
             if (!($(event.target).is('.corner-icon, .icon-save, .export-graph-list-container, .export-graph-list-container *'))) {
             if (!($(event.target).is('.corner-icon, .icon-save, .export-graph-list-container, .export-graph-list-container *'))) {
-              popupBody.set('isMenuHidden', true);
+              popupBody.set('isExportMenuHidden', true);
             }
             }
           });
           });
           $('#modal').addClass('modal-graph-line');
           $('#modal').addClass('modal-graph-line');

+ 1 - 1
ambari-web/app/views/common/export_metrics_menu_view.js

@@ -20,7 +20,7 @@ var App = require('app');
 
 
 App.ExportMetricsMenuView = Em.View.extend({
 App.ExportMetricsMenuView = Em.View.extend({
 
 
-  classNameBindings: ['parentView.isMenuHidden::open', ':export-graph-list-container'],
+  classNameBindings: ['parentView.isExportMenuHidden::open', ':export-graph-list-container'],
 
 
   templateName: require('templates/common/export_metrics_menu')
   templateName: require('templates/common/export_metrics_menu')
 
 

+ 11 - 5
ambari-web/app/views/common/widget/graph_widget_view.js

@@ -281,16 +281,15 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, App.ExportMetricsMixin, {
     },
     },
 
 
     loadData: function () {
     loadData: function () {
-      var self = this;
-      Em.run.next(function () {
-        self._refreshGraph(self.get('parentView.data'))
+      Em.run.next(this, function () {
+        this._refreshGraph(this.get('parentView.data'), this.get('parentView'));
       });
       });
     },
     },
 
 
     didInsertElement: function () {
     didInsertElement: function () {
       var self = this;
       var self = this;
       this.$().closest('.graph-widget').on('mouseleave', function () {
       this.$().closest('.graph-widget').on('mouseleave', function () {
-        self.set('parentView.isMenuHidden', true);
+        self.set('parentView.isExportMenuHidden', true);
       });
       });
       this.setYAxisFormatter();
       this.setYAxisFormatter();
       this.loadData();
       this.loadData();
@@ -315,7 +314,14 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, App.ExportMetricsMixin, {
       fileType = isCSV ? 'csv' : 'json',
       fileType = isCSV ? 'csv' : 'json',
       fileName = 'data.' + fileType,
       fileName = 'data.' + fileType,
       metrics = this.get('content.metrics'),
       metrics = this.get('content.metrics'),
+      hasData = Em.isArray(metrics) && metrics.some(function (item) {
+        return Em.isArray(item.data);
+      });
+    if (hasData) {
       data = isCSV ? this.prepareCSV(metrics) : this.prepareJSON(metrics);
       data = isCSV ? this.prepareCSV(metrics) : this.prepareJSON(metrics);
-    fileUtils.downloadTextFile(data, fileType, fileName);
+      fileUtils.downloadTextFile(data, fileType, fileName);
+    } else {
+      App.showAlertPopup(Em.I18n.t('graphs.noData.title'), Em.I18n.t('graphs.noData.tooltip.title'));
+    }
   }
   }
 });
 });

+ 1 - 1
ambari-web/app/views/main/dashboard/widgets/cluster_metrics_widget.js

@@ -25,7 +25,7 @@ App.ClusterMetricsDashboardWidgetView = App.DashboardWidgetView.extend(App.Expor
   didInsertElement: function () {
   didInsertElement: function () {
     var self = this;
     var self = this;
     this.$().on('mouseleave', function () {
     this.$().on('mouseleave', function () {
-      self.set('isMenuHidden', true);
+      self.set('isExportMenuHidden', true);
     });
     });
     App.tooltip(this.$('.corner-icon > .icon-save'), {
     App.tooltip(this.$('.corner-icon > .icon-save'), {
       title: Em.I18n.t('common.export')
       title: Em.I18n.t('common.export')

+ 35 - 8
ambari-web/test/mixins/common/widgets/export_metrics_mixin_test.js

@@ -33,20 +33,20 @@ describe('App.ExportMetricsMixin', function () {
 
 
     var cases = [
     var cases = [
       {
       {
-        isMenuHidden: true,
+        isExportMenuHidden: true,
         title: 'menu should be visible'
         title: 'menu should be visible'
       },
       },
       {
       {
-        isMenuHidden: false,
+        isExportMenuHidden: false,
         title: 'menu should be hidden'
         title: 'menu should be hidden'
       }
       }
     ];
     ];
 
 
     cases.forEach(function (item) {
     cases.forEach(function (item) {
       it(item.title, function () {
       it(item.title, function () {
-        obj.set('isMenuHidden', !item.isMenuHidden);
+        obj.set('isExportMenuHidden', !item.isExportMenuHidden);
         obj.toggleFormatsList();
         obj.toggleFormatsList();
-        expect(obj.get('isMenuHidden')).to.equal(item.isMenuHidden);
+        expect(obj.get('isExportMenuHidden')).to.equal(item.isExportMenuHidden);
       });
       });
     });
     });
 
 
@@ -56,20 +56,20 @@ describe('App.ExportMetricsMixin', function () {
 
 
     var cases = [
     var cases = [
       {
       {
-        isMenuHidden: true,
+        isExportMenuHidden: true,
         title: 'menu should remain hidden'
         title: 'menu should remain hidden'
       },
       },
       {
       {
-        isMenuHidden: false,
+        isExportMenuHidden: false,
         title: 'menu should become hidden'
         title: 'menu should become hidden'
       }
       }
     ];
     ];
 
 
     cases.forEach(function (item) {
     cases.forEach(function (item) {
       it(item.title, function () {
       it(item.title, function () {
-        obj.set('isMenuHidden', item.isMenuHidden);
+        obj.set('isExportMenuHidden', item.isExportMenuHidden);
         obj.exportGraphData();
         obj.exportGraphData();
-        expect(obj.get('isMenuHidden')).to.be.true;
+        expect(obj.get('isExportMenuHidden')).to.be.true;
       });
       });
     });
     });
 
 
@@ -289,4 +289,31 @@ describe('App.ExportMetricsMixin', function () {
 
 
   });
   });
 
 
+  describe('#hideMenuForNoData', function () {
+
+    var cases = [
+      {
+        isExportButtonHidden: true,
+        isExportMenuHidden: true,
+        title: 'menu should be hidden'
+      },
+      {
+        isExportButtonHidden: false,
+        isExportMenuHidden: false,
+        title: 'menu should be visible'
+      }
+    ];
+
+    cases.forEach(function (item) {
+      it(item.title, function () {
+        obj.setProperties({
+          isExportButtonHidden: item.isExportButtonHidden,
+          isExportMenuHidden: false
+        });
+        expect(obj.get('isExportMenuHidden')).to.equal(item.isExportMenuHidden);
+      });
+    });
+
+  });
+
 });
 });

+ 20 - 0
ambari-web/test/views/common/chart/linear_time_test.js

@@ -266,6 +266,26 @@ describe('App.ChartLinearTimeView', function () {
 
 
   });
   });
 
 
+  describe('#loadDataSuccessCallback', function () {
+
+    beforeEach(function () {
+      sinon.stub(chartLinearTimeView, '_refreshGraph', Em.K);
+    });
+
+    afterEach(function () {
+      chartLinearTimeView._refreshGraph.restore();
+    });
+
+    it('should refresh graph', function () {
+      var response = {
+        key: 'value'
+      };
+      chartLinearTimeView.loadDataSuccessCallback(response);
+      expect(chartLinearTimeView._refreshGraph.calledOnce).to.be.true;
+      expect(chartLinearTimeView._refreshGraph.calledWith(response)).to.be.true;
+    });
+  });
+
 });
 });
 
 
 
 

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini