Repository: ambari Updated Branches: refs/heads/branch-1.6.0.slider 3e0750217 -> 0a70061c7
AMBARI-5959. Slider views UI flickering due to mapper always creating new objects. (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0a70061c Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0a70061c Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0a70061c Branch: refs/heads/branch-1.6.0.slider Commit: 0a70061c78c976db54eec01ecd381826a743ca4c Parents: 3e07502 Author: Oleg Nechiporenko <[email protected]> Authored: Fri May 30 17:59:50 2014 +0300 Committer: Oleg Nechiporenko <[email protected]> Committed: Fri May 30 17:59:50 2014 +0300 ---------------------------------------------------------------------- .../ui/app/templates/slider_app/summary.hbs | 34 ++++---- .../resources/ui/app/templates/slider_apps.hbs | 87 +++++++++----------- .../src/main/resources/ui/app/translations.js | 9 +- .../resources/ui/app/views/common/chart_view.js | 13 ++- .../views/slider_app/metrics/app_metric_view.js | 18 ++-- .../ui/app/views/slider_app/summary_view.js | 62 +++++++++++--- 6 files changed, 129 insertions(+), 94 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/0a70061c/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs b/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs index 2f68ab9..f9d8679 100644 --- a/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs +++ b/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs @@ -54,28 +54,28 @@ </div> <div class="col-md-6"> {{#bs-panel heading="Components"}} - <table class="table section-table table-condensed"> - <tbody> - {{#each controller.model.components}} - <tr> - <td><i {{bind-attr class="isRunning:icon-ok-sign:icon-warning-sign"}}></i><span> </span>{{componentName}}</td> - <td>{{host}}</td> - </tr> - {{/each}} - </tbody> - </table> + <table class="table section-table table-condensed"> + <tbody> + {{#each controller.model.components}} + <tr> + <td> + <i {{bind-attr class="isRunning:icon-ok-sign:icon-warning-sign"}}></i><span> </span>{{componentName}} + </td> + <td>{{host}}</td> + </tr> + {{/each}} + </tbody> + </table> {{/bs-panel}} </div> </div> {{#if controller.model.showMetrics}} {{#bs-panel heading="Metrics"}} - {{#each graphs in view.parentView.graphs}} - <div class="row"> - {{#each graph in graphs}} - <div class="col-md-3">{{view graph}}</div> - {{/each}} - </div> - {{/each}} + <div class="row"> + {{#each graph in view.parentView.graphs}} + <div class="col-md-3">{{view graph.view}}</div> + {{/each}} + </div> {{/bs-panel}} {{/if}} </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/0a70061c/contrib/views/slider/src/main/resources/ui/app/templates/slider_apps.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/templates/slider_apps.hbs b/contrib/views/slider/src/main/resources/ui/app/templates/slider_apps.hbs index f8b45ec..0a81379 100644 --- a/contrib/views/slider/src/main/resources/ui/app/templates/slider_apps.hbs +++ b/contrib/views/slider/src/main/resources/ui/app/templates/slider_apps.hbs @@ -19,44 +19,44 @@ <div id="slider-apps-table"> <div class="box-header"> <div class="pull-right create-app"> - <div class="btn-toolbar"> - <div class="btn-group"> - <a href="#" class="btn btn-primary" {{action createApp}}> - <i class="icon-plus"></i><span> {{t slider.apps.create}}</span> - </a> - </div> - <div class="btn-group"> - <button class="btn dropdown-toggle" data-toggle="dropdown" href="#"> - <i class="icon-cog"></i><span> </span> - <span class="caret"></span> - </button> - <ul class="dropdown-menu"> - {{#if view.yarnUi}} - <li> - <a {{bind-attr href="view.yarnUi"}} target="_blank">YARN UI</a> - </li> - {{/if}} - {{#if view.hdfsUi}} - <li> - <a {{bind-attr href="view.hdfsUi"}} href="" target="_blank">HDFS UI</a> - </li> - {{/if}} - </ul> - </div> + <div class="btn-toolbar"> + <div class="btn-group"> + <a href="#" class="btn btn-primary" {{action createApp}}> + <i class="icon-plus"></i><span> {{t slider.apps.create}}</span> + </a> + </div> + <div class="btn-group"> + <button class="btn dropdown-toggle" data-toggle="dropdown" href="#"> + <i class="icon-cog"></i><span> </span> + <span class="caret"></span> + </button> + <ul class="dropdown-menu"> + {{#if view.yarnUi}} + <li> + <a {{bind-attr href="view.yarnUi"}} target="_blank">YARN UI</a> + </li> + {{/if}} + {{#if view.hdfsUi}} + <li> + <a {{bind-attr href="view.hdfsUi"}} href="" target="_blank">HDFS UI</a> + </li> + {{/if}} + </ul> + </div> </div> </div> </div> <table class="datatable table table-bordered table-striped" id="slider-table"> <thead> - {{#view view.sortView classNames="label-row" contentBinding="view.filteredContent"}} - {{view view.parentView.nameSort}} - {{view view.parentView.statusSort}} - {{view view.parentView.typeSort}} - {{view view.parentView.userSort}} - {{view view.parentView.startSort}} - {{view view.parentView.endSort}} - {{/view}} + {{#view view.sortView classNames="label-row" contentBinding="view.filteredContent"}} + {{view view.parentView.nameSort}} + {{view view.parentView.statusSort}} + {{view view.parentView.typeSort}} + {{view view.parentView.userSort}} + {{view view.parentView.startSort}} + {{view view.parentView.endSort}} + {{/view}} <tr id="filter-row"> <th>{{view view.nameFilterView}}</th> <th>{{view view.statusFilterView}}</th> @@ -67,9 +67,9 @@ </tr> </thead> <tbody> - {{#if view.pageContent}} - {{#each slider in view.pageContent}} - {{#view view.SliderView contentBinding="slider"}} + {{#if view.pageContent}} + {{#each slider in view.pageContent}} + {{#view view.SliderView contentBinding="slider"}} <td> {{#link-to 'slider_app.summary' slider}} @@ -87,16 +87,16 @@ <td>{{slider.ended}}</td> - {{/view}} - {{/each}} - {{else}} + {{/view}} + {{/each}} + {{else}} <tr> <td class="first"></td> - <td colspan="11"> + <td colspan="5"> {{t tableView.filters.noItems}} </td> </tr> - {{/if}} + {{/if}} </tbody> </table> <div class="page-bar"> @@ -107,13 +107,6 @@ <div class="items-on-page"> <label>{{t common.show}} {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label> </div> - {{!-- - <div class="info">{{view.paginationInfo}}</div> - <div class="paging_two_button"> - {{view view.paginationLeft}} - {{view view.paginationRight}} - </div> - --}} </div> </div> {{outlet}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/0a70061c/contrib/views/slider/src/main/resources/ui/app/translations.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/translations.js b/contrib/views/slider/src/main/resources/ui/app/translations.js index c8f165c..84ac330 100644 --- a/contrib/views/slider/src/main/resources/ui/app/translations.js +++ b/contrib/views/slider/src/main/resources/ui/app/translations.js @@ -62,6 +62,8 @@ Em.I18n.translations = { 'slider.apps.create': 'Create App', 'sliderApps.filters.info': '{0} of {1} sliders showing', + 'slider.app.flexPopup.title': 'Allocate Resources', + 'wizard.name': 'Create Slider App', 'wizard.step1.name': 'Select Type', 'wizard.step1.header': 'Available Types', @@ -80,5 +82,10 @@ Em.I18n.translations = { 'wizard.step3.error': 'Only \"key\":\"value\" format allowed.', 'wizard.step4.name': 'Deploy', 'wizard.step4.appName': 'App Name', - 'wizard.step4.appType': 'App Type' + 'wizard.step4.appType': 'App Type', + + 'graphs.noData.title': 'No Data', + 'graphs.noData.message': 'There was no data available. Possible reasons include inaccessible Ganglia service.', + 'graphs.noDataAtTime.message': 'No available data for the time period.' + }; http://git-wip-us.apache.org/repos/asf/ambari/blob/0a70061c/contrib/views/slider/src/main/resources/ui/app/views/common/chart_view.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/views/common/chart_view.js b/contrib/views/slider/src/main/resources/ui/app/views/common/chart_view.js index 5af5241..1ab957e 100644 --- a/contrib/views/slider/src/main/resources/ui/app/views/common/chart_view.js +++ b/contrib/views/slider/src/main/resources/ui/app/views/common/chart_view.js @@ -252,7 +252,6 @@ App.ChartView = Ember.View.extend({ * */ transformData: function (seriesData, displayName) { - var seriesArray = []; if (seriesData != null) { // Is it a string? if ("string" == typeof seriesData) { @@ -298,14 +297,12 @@ App.ChartView = Ember.View.extend({ * series. * May be redefined in child views * - * @param series - * Series for which color is being requested * @return color String. Returning null allows this chart to pick a color * from palette. * @default null * @type Function */ - colorForSeries: function (series) { + colorForSeries: function () { return null; }, @@ -367,11 +364,11 @@ App.ChartView = Ember.View.extend({ this.set('isReady', true); //if Axis X time interval is default(60 minutes) if(this.get('timeUnitSeconds') === 3600){ - this._showMessage('info', this.t('graphs.noData.title'), this.t('graphs.noData.message')); + this._showMessage('info', Ember.I18n.t('graphs.noData.title'), Ember.I18n.t('graphs.noData.message')); this.set('hasData', false); } else { - this._showMessage('info', this.t('graphs.noData.title'), this.t('graphs.noDataAtTime.message')); + this._showMessage('info', Ember.I18n.t('graphs.noData.title'), Ember.I18n.t('graphs.noDataAtTime.message')); } this.set('isPopup', false); } @@ -442,7 +439,7 @@ App.ChartView = Ember.View.extend({ var palette = new Rickshaw.Color.Palette({ scheme: 'munin'}); // Format series for display var series_min_length = 100000000; - data.forEach(function (series, index) { + data.forEach(function (series) { var seriesColor = self.colorForSeries(series); if (seriesColor == null) { seriesColor = palette.color(); @@ -479,7 +476,7 @@ App.ChartView = Ember.View.extend({ }.bind(this)); // All series should have equal length - data.forEach(function(series, index) { + data.forEach(function(series) { if (series.data.length > series_min_length) { series.data.length = series_min_length; } http://git-wip-us.apache.org/repos/asf/ambari/blob/0a70061c/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/app_metric_view.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/app_metric_view.js b/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/app_metric_view.js index dbd012a..9d0806c 100644 --- a/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/app_metric_view.js +++ b/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/app_metric_view.js @@ -52,17 +52,19 @@ App.AppMetricView = App.ChartView.extend({ }, transformToSeries: function (jsonData) { - var seriesArray = []; - var metricName = this.get('metricName'); - if (jsonData && jsonData.metrics) { - for ( var name in jsonData.metrics) { - var displayName = metricName; - var seriesData = jsonData.metrics[metricName]; + var self = this, + seriesArray = [], + metricName = this.get('metricName'), + metrics = Ember.get(jsonData, 'metrics'); + + if (!Ember.isNone(metrics)) { + Ember.keys(metrics).forEach(function() { + var seriesData = metrics[metricName]; if (seriesData) { - var s = this.transformData(seriesData, displayName); + var s = self.transformData(seriesData, metricName); seriesArray.push(s); } - } + }); } return seriesArray; } http://git-wip-us.apache.org/repos/asf/ambari/blob/0a70061c/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js b/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js index abebb63..bd1e488 100644 --- a/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js +++ b/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js @@ -20,22 +20,58 @@ App.SliderAppSummaryView = Ember.View.extend({ classNames: ['app_summary'], - graphs : function() { - var app = this.get('controller.content'); - if (app) { - var supportedMetrics = app.get('supportedMetricNames'); + /** + * List of graphs shown on page + * Format: + * <code> + * [ + * { + * id: string, + * view: App.AppMetricView + * }, + * { + * id: string, + * view: App.AppMetricView + * }, + * .... + * ] + * </code> + * @type {{object}[][]} + */ + graphs: [], + + /** + * Update <code>graphs</code>-list when <code>model</code> is updated + * New metrics are pushed to <code>graphs</code> (not set new list to <code>graphs</code>!) to prevent page flickering + * @method updateGraphs + */ + updateGraphs: function() { + var model = this.get('controller.model'), + existingGraphs = this.get('graphs'); + if (model) { + var supportedMetrics = model.get('supportedMetricNames'); if (supportedMetrics && supportedMetrics.length > 0) { - var graphs = []; supportedMetrics.split(',').forEach(function(metricName) { - var graph = App.AppMetricView.extend({ - app: app, - metricName: metricName - }); - graphs.push(graph); + if (!existingGraphs.isAny('id', metricName)) { + var view = App.AppMetricView.extend({ + app: model, + metricName: metricName + }); + existingGraphs.push({id: metricName, view: view}); + } }); - return [graphs]; } + + // Delete not existed graphs + var toDeleteGraphs = []; + existingGraphs.forEach(function(existingGraph) { + if (supportedMetrics.indexOf(existingGraph) == -1) { + toDeleteGraphs.push(existingGraph); + } + }); + toDeleteGraphs.forEach(function(toDeleteGraph) { + existingGraphs = existingGraphs.without(toDeleteGraph); + }); } - return [[]]; - }.property('controller.content.supportedMetricNames') + }.observes('controller.model.supportedMetricNames') });
