Repository: ambari Updated Branches: refs/heads/trunk fbc69dce3 -> b119d1252
AMBARI-10314 Implement reordering of a widget on a section. (atkach) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b119d125 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b119d125 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b119d125 Branch: refs/heads/trunk Commit: b119d12529607a0a68fab8e179979fa2d25db509 Parents: fbc69dc Author: Andrii Tkach <[email protected]> Authored: Thu Apr 2 12:32:30 2015 +0300 Committer: Andrii Tkach <[email protected]> Committed: Thu Apr 2 12:48:07 2015 +0300 ---------------------------------------------------------------------- .../data/widget_layouts/HBASE/stack_layout.json | 87 ++++++++++++++++++++ .../controllers/main/service/info/summary.js | 22 ++++- .../app/styles/enhanced_service_dashboard.less | 25 +++++- .../templates/common/widget/gauge_widget.hbs | 2 +- .../templates/common/widget/graph_widget.hbs | 26 ++++++ .../templates/common/widget/number_widget.hbs | 2 +- .../templates/common/widget/template_widget.hbs | 2 +- .../app/templates/main/service/info/summary.hbs | 31 ++++--- ambari-web/app/utils/ajax/ajax.js | 11 +++ .../app/views/common/chart/linear_time.js | 9 +- .../views/common/widget/gauge_widget_view.js | 6 -- .../views/common/widget/graph_widget_view.js | 83 ++++++++++++------- .../views/common/widget/number_widget_view.js | 6 -- .../views/common/widget/template_widget_view.js | 6 -- .../app/views/main/service/info/summary.js | 46 ++++++++--- 15 files changed, 278 insertions(+), 86 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/assets/data/widget_layouts/HBASE/stack_layout.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/widget_layouts/HBASE/stack_layout.json b/ambari-web/app/assets/data/widget_layouts/HBASE/stack_layout.json index ae9a43f..0300401 100644 --- a/ambari-web/app/assets/data/widget_layouts/HBASE/stack_layout.json +++ b/ambari-web/app/assets/data/widget_layouts/HBASE/stack_layout.json @@ -78,6 +78,60 @@ } }, { + "widget_name": "FILES_LOCAL2", + "display_name": "Files Local", + "description": "This widget shows percentage of files local.", + "widget_type": "NUMBER", + "is_visible": "true", + "metrics":[ + { + "name": "regionserver.Server.percentFilesLocal", + "widget_id": "metrics/hbase/regionserver/percentFilesLocal", + "category": "", + "service_name": "HBASE", + "component_name": "HBASE_REGIONSERVER" + } + ], + "values": [ + { + "name": "Files Local", + "value": "${regionserver.Server.percentFilesLocal}" + } + ], + "properties": { + "display_unit": "%", + "warning_threshold": 70, + "error_threshold": 90 + } + }, + { + "widget_name": "FILES_LOCAL3", + "display_name": "Files Local", + "description": "This widget shows percentage of files local.", + "widget_type": "NUMBER", + "is_visible": "true", + "metrics":[ + { + "name": "regionserver.Server.percentFilesLocal", + "widget_id": "metrics/hbase/regionserver/percentFilesLocal", + "category": "", + "service_name": "HBASE", + "component_name": "HBASE_REGIONSERVER" + } + ], + "values": [ + { + "name": "Files Local", + "value": "${regionserver.Server.percentFilesLocal}" + } + ], + "properties": { + "display_unit": "%", + "warning_threshold": 70, + "error_threshold": 90 + } + }, + { "widget_name": "NAMENODE_HEAP", "display_name": "NameNode Heap", "widget_type": "GAUGE", @@ -109,6 +163,39 @@ "warning_threshold": 0.9, "error_threshold": 0.7 } + }, + { + "widget_name": "NAMENODE_HEAP2", + "display_name": "NameNode Heap", + "widget_type": "GAUGE", + "is_visible": "true", + "description": "", + "metrics":[ + { + "name": "java.lang:type=Memory.HeapMemoryUsage[used]", + "widget_id": "metrics/jvm/HeapMemoryUsed", + "category": "", + "service_name": "HBASE", + "component_name": "HBASE_REGIONSERVER" + }, + { + "name": "java.lang:type=Memory.HeapMemoryUsage[max]", + "widget_id": "metrics/jvm/HeapMemoryMax", + "category": "", + "service_name": "HBASE", + "component_name": "HBASE_REGIONSERVER" + } + ], + "values": [ + { + "name": "NameNode heap", + "value": "${java.lang:type=Memory.HeapMemoryUsage[used]/java.lang:type=Memory.HeapMemoryUsage[max]}" + } + ], + "properties": { + "warning_threshold": 0.9, + "error_threshold": 0.7 + } } ] } http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/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 3246781..f25ad56 100644 --- a/ambari-web/app/controllers/main/service/info/summary.js +++ b/ambari-web/app/controllers/main/service/info/summary.js @@ -320,7 +320,7 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({ * @type {Em.A} */ widgetLayouts: function() { - return App.WidgetLayout.find().filterProperty('serviceName', this.get('content.serviceName')); + return App.WidgetLayout.find(); }.property('isWidgetLayoutsLoaded'), /** @@ -417,9 +417,25 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({ /** * save layout + * return {$.ajax} */ - saveLayout: function () { - + saveLayout: function (widgets, layout) { + var data = { + "layout_name": layout.get('layoutName'), + "section_name": layout.get('sectionName'), + "scope": layout.get('scope'), + "widgetLayoutInfo": widgets.map(function (widget) { + return { + "widget_name": widget.get('widgetName'), + "id": widget.get('widgetId') + } + }) + }; + return App.ajax.send({ + name: 'widgets.layout.save', + sender: this, + data: data + }); }, /** http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/styles/enhanced_service_dashboard.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/enhanced_service_dashboard.less b/ambari-web/app/styles/enhanced_service_dashboard.less index cdc72ad..24e52a3 100644 --- a/ambari-web/app/styles/enhanced_service_dashboard.less +++ b/ambari-web/app/styles/enhanced_service_dashboard.less @@ -21,8 +21,8 @@ .service-metrics-block { #add-widget-action-box { - margin: 20px 10px 10px 10px; - padding: 40px 55px; + width: 96%; + padding: 43px; border: 1px solid #ddd; .icon-plus { font-size: 70px; @@ -51,6 +51,12 @@ height: 150px; width: 90%; } + .span2p4 { + width: 19.3%; + background-color: white; + margin: 5px 0 5px 5px; + cursor: move; + } .widget { .spinner { margin: 55px auto; @@ -68,11 +74,22 @@ font-weight: bold; font-size: 35px; } - .template-widget { + .template-widget, + .number-widget { .frame; } - .number-widget { + .graph-widget { .frame; + .content { + padding-top: 0; + } + .chart-legend { + min-width: 100%; + padding: 5px; + text-align: left; + top: 95px; + left: -15px; + } } .gauge-widget { .frame; http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/templates/common/widget/gauge_widget.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/widget/gauge_widget.hbs b/ambari-web/app/templates/common/widget/gauge_widget.hbs index 11e3565..823a567 100644 --- a/ambari-web/app/templates/common/widget/gauge_widget.hbs +++ b/ambari-web/app/templates/common/widget/gauge_widget.hbs @@ -18,7 +18,7 @@ <div class="gauge-widget thumbnail"> {{#if view.isLoaded}} - <div class="caption title">{{view.title}}</div> + <div class="caption title">{{view.content.displayName}}</div> <div class="content"> {{view view.chartView}}</div> {{else}} <div class="spinner"></div> http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/templates/common/widget/graph_widget.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/widget/graph_widget.hbs b/ambari-web/app/templates/common/widget/graph_widget.hbs new file mode 100644 index 0000000..58fb143 --- /dev/null +++ b/ambari-web/app/templates/common/widget/graph_widget.hbs @@ -0,0 +1,26 @@ +{{! +* 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="graph-widget thumbnail"> + {{#if view.isLoaded}} + <div class="caption title">{{view.content.displayName}}</div> + <div class="content"> {{view view.graphView}}</div> + {{else}} + <div class="spinner"></div> + {{/if}} +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/templates/common/widget/number_widget.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/widget/number_widget.hbs b/ambari-web/app/templates/common/widget/number_widget.hbs index f8998fd..711773e 100644 --- a/ambari-web/app/templates/common/widget/number_widget.hbs +++ b/ambari-web/app/templates/common/widget/number_widget.hbs @@ -18,7 +18,7 @@ <div class="number-widget thumbnail"> {{#if view.isLoaded}} - <div class="caption title">{{view.title}}</div> + <div class="caption title">{{view.content.displayName}}</div> <div {{bindAttr class="view.contentColor :content"}}>{{view.value}}</div> {{else}} <div class="spinner"></div> http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/templates/common/widget/template_widget.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/widget/template_widget.hbs b/ambari-web/app/templates/common/widget/template_widget.hbs index 02f7425..ed29d23 100644 --- a/ambari-web/app/templates/common/widget/template_widget.hbs +++ b/ambari-web/app/templates/common/widget/template_widget.hbs @@ -18,7 +18,7 @@ <div class="template-widget thumbnail"> {{#if view.isLoaded}} - <div class="caption title">{{view.title}}</div> + <div class="caption title">{{view.content.displayName}}</div> <div class="content"> {{view.value}}</div> {{else}} <div class="spinner"></div> http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/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 8e66441..bc18a24 100644 --- a/ambari-web/app/templates/main/service/info/summary.hbs +++ b/ambari-web/app/templates/main/service/info/summary.hbs @@ -75,7 +75,6 @@ </div> {{#if view.isServiceMetricLoaded}} - {{#if view.serviceMetricGraphs.length}} <div class="service-metrics-block"> <div class="box"> <div class="box-header"> @@ -140,21 +139,22 @@ </div> {{/if}} </div> - <div class=""> + <div> + {{#if App.supports.customizedWidgets}} + <div id="widget_layout" class="row-fluid"> + {{#each widget in controller.widgets}} + <div class="widget span2p4" {{bindAttr id="widget.id"}}> + {{view widget.viewClass contentBinding="widget"}} + </div> + {{/each}} + <div class="span2p4"> + <button id="add-widget-action-box" + class="btn btn-default" {{action "goToAddWidgetWizard" controller.content target="view"}}><i + class="icon-plus"></i></button> + </div> + </div> + {{/if}} <table class="graphs"> - {{#if App.supports.customizedWidgets}} - {{#if controller.isWidgetsLoaded}} - <tr id="widget_layout"> - {{#each widget in controller.widgets}} - <td> - <div class="widget"> - {{view widget.viewClass contentBinding="widget"}} - </div> - </td> - {{/each}} - </tr> - {{/if}} - {{/if}} {{#each graphs in view.serviceMetricGraphs}} <tr> {{#each graph in graphs}} @@ -170,7 +170,6 @@ </div> </div> </div> - {{/if}} {{/if}} </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/utils/ajax/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js index 22e5715..4fe1171 100644 --- a/ambari-web/app/utils/ajax/ajax.js +++ b/ambari-web/app/utils/ajax/ajax.js @@ -2419,6 +2419,17 @@ var urls = { mock: '/data/widget_layouts/HBASE/layouts.json' }, + 'widgets.layout.save': { + real: '/clusters/{clusterName}/widget_layouts/{layout_name}', + mock: '', + format: function (data) { + return { + type: 'PUT', + data: JSON.stringify(data.data) + } + } + }, + 'widgets.serviceComponent.metrics.get': { real: '/clusters/{clusterName}/services/{serviceName}/components/{componentName}?fields={widgetIds}', mock: '/data/metrics/{serviceName}/Append_num_ops_&_Delete_num_ops.json' http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/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 bf8ccad..25a0ff8 100644 --- a/ambari-web/app/views/common/chart/linear_time.js +++ b/ambari-web/app/views/common/chart/linear_time.js @@ -137,6 +137,13 @@ App.ChartLinearTimeView = Ember.View.extend({ */ hasData: true, + /** + * chart height + * @type {number} + * @default 150 + */ + height: 150, + didInsertElement: function () { this.loadData(); this.registerGraph(); @@ -508,7 +515,7 @@ App.ChartLinearTimeView = Ember.View.extend({ var yaxisElement = document.querySelector(yaxisElementId); var legendElement = document.querySelector(legendElementId); - var height = 150; + var height = this.get('height'); var width = 400; var diff = 32; http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/views/common/widget/gauge_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/widget/gauge_widget_view.js b/ambari-web/app/views/common/widget/gauge_widget_view.js index 7a31d14..46d6966 100644 --- a/ambari-web/app/views/common/widget/gauge_widget_view.js +++ b/ambari-web/app/views/common/widget/gauge_widget_view.js @@ -24,11 +24,6 @@ App.GaugeWidgetView = Em.View.extend(App.WidgetMixin, { /** * @type {string} */ - title: '', - - /** - * @type {string} - */ value: '', /** @@ -40,7 +35,6 @@ App.GaugeWidgetView = Em.View.extend(App.WidgetMixin, { drawWidget: function () { if (this.get('isLoaded')) { this.calculateValues(); - this.set('title', this.get('content.values')[0].name); this.set('value', this.get('content.values')[0].computedValue); } }, http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/views/common/widget/graph_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/widget/graph_widget_view.js b/ambari-web/app/views/common/widget/graph_widget_view.js index 9d2e4f5..b440984 100644 --- a/ambari-web/app/views/common/widget/graph_widget_view.js +++ b/ambari-web/app/views/common/widget/graph_widget_view.js @@ -18,28 +18,8 @@ var App = require('app'); -App.GraphWidgetView = App.ChartLinearTimeView.extend(App.WidgetMixin, { - - /** - * @type {string} - */ - id: function () { - return this.get('content.id'); - }.property('content.id'), - - /** - * @type {string} - */ - title: function () { - return this.get('content.displayName'); - }.property('content.displayName'), - - /** - * @type {string} - */ - renderer: function () { - return this.get('properties.graph_type') === 'STACK' ? 'area' : 'line'; - }.property('properties.graph_type'), +App.GraphWidgetView = Em.View.extend(App.WidgetMixin, { + templateName: require('templates/common/widget/graph_widget'), /** * common metrics container @@ -59,15 +39,14 @@ App.GraphWidgetView = App.ChartLinearTimeView.extend(App.WidgetMixin, { */ timeStep: 15, - didInsertElement: Em.K, - - transformToSeries: function (seriesData) { - return seriesData; - }, + /** + * @type {Array} + */ + data: [], drawWidget: function () { if (this.get('isLoaded')) { - this._refreshGraph(this.calculateValues()) + this.set('data', this.calculateValues()); } }, @@ -80,9 +59,11 @@ App.GraphWidgetView = App.ChartLinearTimeView.extend(App.WidgetMixin, { this.get('content.values').forEach(function (value) { var computedExpressions = this.computeExpression(this.extractExpressions(value)[0], metrics); - seriesData.push(this.transformData(computedExpressions[value.value.match(this.get('EXPRESSION_REGEX'))[0]], value.name)); + seriesData.push({ + name: value.name, + data: computedExpressions[value.value.match(this.get('EXPRESSION_REGEX'))[0]] + }); }, this); - return seriesData; }, @@ -179,5 +160,45 @@ App.GraphWidgetView = App.ChartLinearTimeView.extend(App.WidgetMixin, { }, this); return result; - } + }, + + /** + * @type {Em.View} + * @class + */ + graphView: App.ChartLinearTimeView.extend({ + + /** + * graph height + * @type {number} + */ + height: 95, + + /** + * @type {string} + */ + id: function () { + return this.get('parentView.content.id') + '_graph'; + }.property('parentView.content.id'), + + /** + * @type {string} + */ + renderer: function () { + return this.get('parentView.content.properties.graph_type') === 'STACK' ? 'area' : 'line'; + }.property('parentView.content.properties.graph_type'), + + transformToSeries: function (seriesData) { + var seriesArray = []; + + seriesData.forEach(function(_series){ + seriesArray.push(this.transformData(_series.data, _series.name)); + }, this); + return seriesArray; + }, + + didInsertElement: function () { + this._refreshGraph(this.get('parentView.data')); + }.observes('parentView.data') + }) }); http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/views/common/widget/number_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/widget/number_widget_view.js b/ambari-web/app/views/common/widget/number_widget_view.js index fd8a99e..c0a85cb 100644 --- a/ambari-web/app/views/common/widget/number_widget_view.js +++ b/ambari-web/app/views/common/widget/number_widget_view.js @@ -24,11 +24,6 @@ App.NumberWidgetView = Em.View.extend(App.WidgetMixin, { /** * @type {string} */ - title: '', - - /** - * @type {string} - */ value: '', /** @@ -59,7 +54,6 @@ App.NumberWidgetView = Em.View.extend(App.WidgetMixin, { if (this.get('isLoaded')) { this.calculateValues(); this.set('value', this.get('content.values')[0].computedValue); - this.set('title', this.get('content.values')[0].name); } } }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/ambari-web/app/views/common/widget/template_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/widget/template_widget_view.js b/ambari-web/app/views/common/widget/template_widget_view.js index 572e4fb..62d043c 100644 --- a/ambari-web/app/views/common/widget/template_widget_view.js +++ b/ambari-web/app/views/common/widget/template_widget_view.js @@ -24,11 +24,6 @@ App.TemplateWidgetView = Em.View.extend(App.WidgetMixin, { /** * @type {string} */ - title: '', - - /** - * @type {string} - */ value: '', /** @@ -41,7 +36,6 @@ App.TemplateWidgetView = Em.View.extend(App.WidgetMixin, { if (this.get('isLoaded')) { this.calculateValues(); this.set('value', this.get('content.values')[0].computedValue); - this.set('title', this.get('content.values')[0].name); } } }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/b119d125/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 ea06cf8..2a1c274 100644 --- a/ambari-web/app/views/main/service/info/summary.js +++ b/ambari-web/app/views/main/service/info/summary.js @@ -17,6 +17,7 @@ var App = require('app'); var batchUtils = require('utils/batch_scheduled_requests'); +var misc = require('utils/misc'); require('views/main/service/service'); require('data/service_graph_config'); @@ -330,16 +331,6 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, { })); }); - if (App.get('supports.customizedWidgets')) { - graphObjects.push(Ember.View.extend({ - classNames: ['last-child'], - template: Ember.Handlebars.compile('<button id="add-widget-action-box" class="btn btn-default" {{action "goToAddWidgetWizard" controller.content target="view"}}><i class="icon-plus"></i></button>'), - goToAddWidgetWizard: function(evt) { - App.router.send('addServiceWidget',evt.context); - } - })); - } - while(graphObjects.length) { result.push(graphObjects.splice(0, chunkSize)); } @@ -376,6 +367,15 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, { this.set('currentTimeRangeIndex', 0); } }, + + /** + * launch Add Widget wizard + * @param event + */ + goToAddWidgetWizard: function (event) { + App.router.send('addServiceWidget', event.context); + }, + /** * list of static actions of widget * @type {Array} @@ -569,5 +569,31 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, { } } } + this.makeSortable(); + }, + + /** + * Make widgets' list sortable on New Dashboard style + */ + makeSortable: function () { + var self = this; + $('html').on('DOMNodeInserted', '#widget_layout', function () { + $(this).sortable({ + items: "> div", + cursor: "move", + tolerance: "pointer", + scroll: false, + update: function () { + var widgets = misc.sortByOrder($("#widget_layout .widget").map(function () { + return this.id; + }), self.get('controller.widgets')); + //TODO bind to actual layout instance + var layout = self.get('controller.widgetLayouts').objectAt(0); + + self.get('controller').saveLayout(widgets, layout); + } + }).disableSelection(); + $('html').off('DOMNodeInserted', '#widget_layout'); + }); } });
