Repository: ambari Updated Branches: refs/heads/trunk 0f4aea149 -> 92f07a92a
AMBARI-11005. Widgets: UI changes v4-PART 1. (xiwang) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/92f07a92 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/92f07a92 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/92f07a92 Branch: refs/heads/trunk Commit: 92f07a92a044b4da396ddf5cf3ae060924470fcf Parents: 0f4aea1 Author: Xi Wang <[email protected]> Authored: Wed May 6 11:12:44 2015 -0700 Committer: Xi Wang <[email protected]> Committed: Fri May 8 17:07:02 2015 -0700 ---------------------------------------------------------------------- .../service/widgets/create/step2_controller.js | 2 +- .../service/widgets/create/step3_controller.js | 7 +- ambari-web/app/messages.js | 2 + .../app/styles/enhanced_service_dashboard.less | 127 +++--- .../main/service/widgets/create/expression.hbs | 33 +- .../service/widgets/create/step2_add_metric.hbs | 102 +++-- .../main/service/widgets/create/step2_graph.hbs | 5 +- .../service/widgets/create/expression_view.js | 391 +++++++++---------- 8 files changed, 305 insertions(+), 364 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/92f07a92/ambari-web/app/controllers/main/service/widgets/create/step2_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/service/widgets/create/step2_controller.js b/ambari-web/app/controllers/main/service/widgets/create/step2_controller.js index 28a86d5..b6a3782 100644 --- a/ambari-web/app/controllers/main/service/widgets/create/step2_controller.js +++ b/ambari-web/app/controllers/main/service/widgets/create/step2_controller.js @@ -177,7 +177,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({ this.get('dataSets').pushObject(Em.Object.create({ id: id, - label: '', + label: Em.I18n.t('dashboard.widgets.wizard.step2.dataSeries').format(id), isRemovable: !isDefault, expression: Em.Object.create({ data: [], http://git-wip-us.apache.org/repos/asf/ambari/blob/92f07a92/ambari-web/app/controllers/main/service/widgets/create/step3_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/service/widgets/create/step3_controller.js b/ambari-web/app/controllers/main/service/widgets/create/step3_controller.js index d8281c7..43bd968 100644 --- a/ambari-web/app/controllers/main/service/widgets/create/step3_controller.js +++ b/ambari-web/app/controllers/main/service/widgets/create/step3_controller.js @@ -106,7 +106,8 @@ App.WidgetWizardStep3Controller = Em.Controller.extend({ }, isSubmitDisabled: function () { - return !(this.get('widgetName').trim()); + var widgetName = this.get('widgetName')? this.get('widgetName').trim(): null; + return !(widgetName); }.property('widgetName'), /** @@ -148,7 +149,9 @@ App.WidgetWizardStep3Controller = Em.Controller.extend({ App.router.send('complete', this.collectWidgetData()); var editController = App.router.get('widgetEditController'); editController.finish(); - editController.get('popup').hide(); + if (editController.get('popup')) { + editController.get('popup').hide(); + } var serviceName = editController.get('content.widgetService'); var service = App.Service.find().findProperty('serviceName', serviceName); App.router.transitionTo('main.services.service', service); http://git-wip-us.apache.org/repos/asf/ambari/blob/92f07a92/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 2cf9615..90d43e2 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -2560,6 +2560,7 @@ Em.I18n.translations = { 'widget.edit.button.primary': 'Edit Shared', 'widget.edit.button.secondary': 'Clone and Edit', + 'dashboard.widgets.wizard.step2.dataSeries': 'Data Series {0}', 'dashboard.widgets.wizard.step2.addMetrics': 'Add Metrics and operators here...', 'dashboard.widgets.wizard.step2.newMetric': '+ Add Metric', 'dashboard.widgets.wizard.step2.newOperator': '+ Add Operator', @@ -2569,6 +2570,7 @@ Em.I18n.translations = { 'dashboard.widgets.wizard.step2.selectMetric': 'Select a Metric', 'dashboard.widgets.wizard.step2.addMetric': 'Add Metric', 'dashboard.widgets.wizard.step2.aggregateFunction': 'Aggregator Function', + 'dashboard.widgets.wizard.step2.aggregateFunction.scanOps': 'Select Aggregation', 'dashboard.widgets.wizard.step2.aggregateTooltip': 'This mathematical function will be applied to compute single value for selected metric across all host components', 'dashboard.widgets.wizard.step2.threshold.ok.tooltip': 'This is the threshold value at which the widget color changes from green (OK) to orange (Warning)', 'dashboard.widgets.wizard.step2.threshold.warning.tooltip': 'This is the threshold value at which the widget color changes from orange (Warning) to red (Critical)', http://git-wip-us.apache.org/repos/asf/ambari/blob/92f07a92/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 464f4df..f95bdec 100644 --- a/ambari-web/app/styles/enhanced_service_dashboard.less +++ b/ambari-web/app/styles/enhanced_service_dashboard.less @@ -318,25 +318,31 @@ } .is-invalid.controls, .metric-container.is-invalid { - border-color: red; + .metric-field { + border-color: red; + } } .metric-container { position: relative; - margin-bottom: 50px; - height: 200px; - border: 1px solid @border-color; - button, - div.btn-group { - margin: 5px; - } + margin-top: 10px; + margin-bottom: 15px; + height: 250px; .placeholder { color: #999999; padding: 50px; } + .actions-field { + margin-bottom: 5px; + height: 14%; + .add-operator { + margin-left: 25px; + } + } .metric-field { - height: 100%; + height: 85%; background-color: #f5f5f5; overflow: scroll; + border: 1px solid @border-color; } .metric-instance { font-weight: bold; @@ -421,79 +427,46 @@ } } -.add-metric-modal.modal-690px-width { - .modal { - max-height: 600px; - .modal-body { - min-height: 380px;; - } +#add-metric-menu{ + .select-options-dropdown { + width: 240px; + max-height: 123px; + padding: 0px; + border-bottom: 200px transparent solid; + border-right: 150px transparent solid; + border-left: none; + border-top: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; } -} -#add-metric-popup { - min-height: 200px; - div.row-fluid { - margin: 20px 10px; - div { - line-height: 30px; - } + li.metric-select { + padding: 5px; + padding-bottom: 0px; + border: 1px #ccc solid; + border-bottom: none; } - .aggregator-select, - .component-select { - .btn.dropdown-toggle { - border-radius: 4px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - width: 220px; - text-align: left; - white-space: normal; - } - ul.dropdown-menu { - overflow: auto; - max-height: 280px; - } - .accordion-group { - border: none; - } - .accordion-toggle { - text-decoration: none; - padding: 3px 15px; - .icon-caret-down { - width: 10px; - display: inline-block; - } - .icon-caret-right { - display: none; - } - } - .accordion-toggle.collapsed { - text-decoration: none; - .icon-caret-down { - display: none; - } - .icon-caret-right { - width: 10px; - display: inline-block; - } - } - .accordion-inner { - padding: 0 15px; - border-top: none; - li { - list-style: none; - } - } - .link { - cursor: pointer; - color: #0088cc; - } - .link:hover { - background: transparent; + li.aggregator-select { + padding: 5px; + padding-bottom: 0px; + border: 1px #ccc solid; + border-bottom: none; + border-top: none; + } + li.actions-buttons{ + padding: 5px; + padding-left: 8px; + border: 1px #ccc solid; + border-top: none; + button { + margin-right: 5px; } } - .chosen-container-single { - width: 250px; + .chosen-container.chosen-container-single { + margin: 3px; .chosen-single { height: 30px; + width: 220px; line-height: 20px; color: #333333; font-size: 14px; @@ -529,7 +502,7 @@ margin-top: 2px; overflow: auto; width: 300px; - max-height: 280px; + max-height: 260px; border: 1px solid rgba(0, 0, 0, 0.2); -webkit-border-radius: 0px; -moz-border-radius: 0px; http://git-wip-us.apache.org/repos/asf/ambari/blob/92f07a92/ambari-web/app/templates/main/service/widgets/create/expression.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/service/widgets/create/expression.hbs b/ambari-web/app/templates/main/service/widgets/create/expression.hbs index a4b988f..353ddff 100644 --- a/ambari-web/app/templates/main/service/widgets/create/expression.hbs +++ b/ambari-web/app/templates/main/service/widgets/create/expression.hbs @@ -16,7 +16,20 @@ * limitations under the License. }} - +<div class="actions-field row-fluid"> + {{view App.AddMetricExpressionView}} + <div class="btn-group span2 add-operator"> + <a class="btn dropdown-toggle" data-toggle="dropdown" href="#"> + {{t dashboard.widgets.wizard.step2.newOperator}} + <span class="caret"></span> + </a> + <ul class="dropdown-menu"> + {{#each operator in view.OPERATORS}} + <li><a href="#" {{action addOperator operator target="view"}}>{{operator}}</a></li> + {{/each}} + </ul> + </div> +</div> <div class="metric-field"> {{#if view.expression.isRemovable}} <a {{action removeExpression view.expression target="controller"}} class="remove-link"><i class="icon-trash"></i></a> @@ -31,20 +44,4 @@ <div class="placeholder">{{t dashboard.widgets.wizard.step2.addMetrics}}</div> {{/if}} </div> -<div class="pull-left"> - <button class="btn" {{action addMetric target="view"}}>{{t dashboard.widgets.wizard.step2.newMetric}}</button> - <div class="btn-group pull-right"> - <a class="btn dropdown-toggle" data-toggle="dropdown" href="#"> - {{t dashboard.widgets.wizard.step2.newOperator}} - <span class="caret"></span> - </a> - <ul class="dropdown-menu"> - {{#each operator in view.OPERATORS}} - <li><a href="#" {{action addOperator operator target="view"}}>{{operator}}</a></li> - {{/each}} - </ul> - </div> -</div> -<div {{bindAttr class="view.isInvalid:is-invalid :controls"}}> - <button class="btn" {{action cancelEdit target="view"}}>{{t common.reset}}</button> -</div> \ No newline at end of file + http://git-wip-us.apache.org/repos/asf/ambari/blob/92f07a92/ambari-web/app/templates/main/service/widgets/create/step2_add_metric.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/service/widgets/create/step2_add_metric.hbs b/ambari-web/app/templates/main/service/widgets/create/step2_add_metric.hbs index 5eee49e..c88e6f8 100644 --- a/ambari-web/app/templates/main/service/widgets/create/step2_add_metric.hbs +++ b/ambari-web/app/templates/main/service/widgets/create/step2_add_metric.hbs @@ -16,64 +16,50 @@ * limitations under the License. }} -<div class="row-fluid"> - <div class="span3">{{t dashboard.widgets.wizard.step2.Component}}</div> - <div class="btn-group component-select span5"> - {{#if view.selectedComponent}} - <button class="btn dropdown-toggle" data-toggle="dropdown"> - {{view.selectedComponent.displayName}}<span class="caret pull-right"></span> - </button> - {{else}} - <button class="btn dropdown-toggle" data-toggle="dropdown"> - {{t dashboard.widgets.wizard.step2.selectComponent}}<span class="caret pull-right"></span> - </button> - {{/if}} - <ul class="dropdown-menu accordion" id="accordion2"> - {{#each service in view.componentMap}} - <li class="accordion-group keep-open"> - <div class="accordion-heading"> - <a class="accordion-toggle collapsed" data-toggle="collapse" {{bindAttr href="service.href"}}> - <i class="icon-caret-down"></i><i class="icon-caret-right"></i>{{service.displayName}} - </a> - </div> - <div {{bindAttr id="service.serviceName"}} class="accordion-body collapse"> - <ul class="accordion-inner"> - {{#each component in service.components}} - <li> - <a href="#" {{action selectComponents component target="view"}}> {{component.displayName}}</a> - </li> - {{/each}} +<div class="btn-group dropdown span2"> + <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">{{t dashboard.widgets.wizard.step2.newMetric}} <span class="caret"></span></a> + <ul class="dropdown-menu service-level-dropdown"> + <!--service level--> + {{#each service in view.componentMap}} + <li class="dropdown-submenu keep-open"> + <a class="" tabindex="-1" href="javascript:void(null);">{{service.displayName}}</a> + <ul class="dropdown-menu"> + {{#each component in service.components}} + <!--component level--> + <li class="dropdown-submenu keep-open"> + <a href="javascript:void(null);">{{component.displayName}}</a> + <ul class="dropdown-menu select-options-dropdown"> + <!--metrics level--> + <li class="keep-open metric-select" {{action selectComponents component target="view"}}> + <select class="metrics-select chosen-select" > + <option value="" disabled selected>{{t dashboard.widgets.wizard.step2.selectMetric}}</option> + {{#each metric in component.metrics}} + <option>{{unbound metric}}</option> + {{/each}} + </select> + </li> + <!--select aggregare function --> + <li {{bindAttr class=":keep-open :aggregator-select component.showAggregateSelect::hidden"}} + {{action selectComponents component target="view"}} + {{translateAttr data-original-title="dashboard.widgets.wizard.step2.aggregateTooltip"}}> + <select class="aggregate-function-select chosen-select" > + <option value="" disabled selected>{{t dashboard.widgets.wizard.step2.aggregateFunction.scanOps}}</option> + {{#each function in view.parentView.AGGREGATE_FUNCTIONS}} + <option>{{unbound function}}</option> + {{/each}} + </select> + </li> + <li class="actions-buttons"> + <button class="btn" href="#" {{action cancel target="view"}}>{{t common.cancel}}</button> + <button {{bindAttr class=":btn :btn-primary component.isAddEnabled::disabled"}} href="#" + {{action addMetric component target="view"}}>{{t common.add}}</button> + </li> </ul> - </div> - </li> - {{/each}} - </ul> - </div> + </li> + {{/each}} + </ul> + </li> + {{/each}} + </ul> </div> -<div class="row-fluid"> - <div class="span3">{{t dashboard.widgets.wizard.step2.Metric}}</div> - <div class="span9"> - <select class="chosen-select"> - <option value="" disabled selected>{{t dashboard.widgets.wizard.step2.selectMetric}}</option> - {{#each metric in view.selectedComponent.metrics}} - <option>{{unbound metric}}</option> - {{/each}} - </select> - </div> -</div> - -<div class="row-fluid" {{bindAttr class=":row-fluid view.showAggregateSelect::hidden"}}> - <div class="span3">{{t dashboard.widgets.wizard.step2.aggregateFunction}}</div> - <div class="btn-group aggregator-select span5" {{translateAttr data-original-title="dashboard.widgets.wizard.step2.aggregateTooltip"}}> - <button class="btn dropdown-toggle" data-toggle="dropdown"> - {{view.parentView.aggregateFunction}} - <span class="caret pull-right"></span> - </button> - <ul class="dropdown-menu"> - {{#each aggregation in view.parentView.AGGREGATE_FUNCTIONS}} - <li><a href="#" {{action selectAggregation aggregation target="view"}}>{{aggregation}}</a></li> - {{/each}} - </ul> - </div> -</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/92f07a92/ambari-web/app/templates/main/service/widgets/create/step2_graph.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/service/widgets/create/step2_graph.hbs b/ambari-web/app/templates/main/service/widgets/create/step2_graph.hbs index affc783..17e4790 100644 --- a/ambari-web/app/templates/main/service/widgets/create/step2_graph.hbs +++ b/ambari-web/app/templates/main/service/widgets/create/step2_graph.hbs @@ -23,10 +23,7 @@ {{#each dataSet in dataSets}} <fieldset> - <legend>{{t common.dataSet}} {{dataSet.id}}</legend> - <h5> - {{t common.label}}: {{view Ember.TextField valueBinding="dataSet.label"}} - </h5> + <h5>{{view Ember.TextField valueBinding="dataSet.label"}}</h5> <h5>{{t common.expression}}:</h5> {{view App.WidgetWizardExpressionView expressionBinding="dataSet.expression"}} {{#if dataSet.isRemovable}} http://git-wip-us.apache.org/repos/asf/ambari/blob/92f07a92/ambari-web/app/views/main/service/widgets/create/expression_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/widgets/create/expression_view.js b/ambari-web/app/views/main/service/widgets/create/expression_view.js index 8e8b8ce..1a11577 100644 --- a/ambari-web/app/views/main/service/widgets/create/expression_view.js +++ b/ambari-web/app/views/main/service/widgets/create/expression_view.js @@ -97,14 +97,6 @@ App.WidgetWizardExpressionView = Em.View.extend({ }, /** - * discard changes and disable metric edit area - */ - cancelEdit: function () { - this.set('expression.data', []); - this.propertyDidChange('expression'); - }, - - /** * remove metric or operator from expression * @param {object} event */ @@ -145,209 +137,200 @@ App.WidgetWizardExpressionView = Em.View.extend({ }.observes('expression.data.length'), /** - * show popup that provide ability to add metric + * @type {Array} + * @const */ - addMetric: function () { - return App.ModalPopup.show({ - header: Em.I18n.t('dashboard.widgets.wizard.step2.addMetric'), - classNames: ['modal-690px-width', 'add-metric-modal'], - disablePrimary: function () { - return Em.isNone(this.get('selectedMetric')); - }.property('selectedMetric'), - isHideBodyScroll: true, - expression: this.get('expression'), - - /** - * @type {Array} - * @const - */ - AGGREGATE_FUNCTIONS: ['avg', 'sum', 'min', 'max'], - - /** - * @type {object|null} - */ - selectedMetric: null, - - /** - * @type {string|null} - */ - aggregateFunction: null, - - /** - * @type {Ember.View} - * @class - */ - bodyClass: Em.View.extend({ - templateName: require('templates/main/service/widgets/create/step2_add_metric'), - controller: this.get('controller'), - elementId: 'add-metric-popup', - didInsertElement: function () { - var self = this; - - //prevent dropdown closing on checkbox click - $('html').on('click.dropdown', '.dropdown-menu li', function (e) { - $(this).hasClass('keep-open') && e.stopPropagation(); - }); - App.tooltip($('#' + this.get('elementId') + ' .aggregator-select')); - this.propertyDidChange('selectedComponent'); - - $(".chosen-select").chosen({ - placeholder_text: Em.I18n.t('dashboard.widgets.wizard.step2.selectMetric'), - no_results_text: Em.I18n.t('widget.create.wizard.step2.noMetricFound') - }).change(function (event, obj) { - var filteredComponentMetrics = self.get('controller.filteredMetrics').filterProperty('component_name', self.get('selectedComponent.componentName')).filterProperty('level',self.get('selectedComponent.level')); - var filteredMetric = filteredComponentMetrics.findProperty('name', obj.selected); - var selectedMetric = Em.Object.create({ - name: obj.selected, - componentName: self.get('selectedComponent.componentName'), - serviceName: self.get('selectedComponent.serviceName'), - metricPath: filteredMetric.widget_id, - isMetric: true - }); - if (self.get('selectedComponent.hostComponentCriteria')) { - selectedMetric.hostComponentCriteria = self.get('selectedComponent.hostComponentCriteria'); - } - self.set('parentView.selectedMetric', selectedMetric); + AGGREGATE_FUNCTIONS: ['avg', 'sum', 'min', 'max'] +}); + + +/** + * show menu view that provide ability to add metric + */ +App.AddMetricExpressionView = Em.View.extend({ + templateName: require('templates/main/service/widgets/create/step2_add_metric'), + controller: function () { + return this.get('parentView.controller'); + }.property('parentView.controller'), + elementId: 'add-metric-menu', + didInsertElement: function () { + //prevent dropdown closing on click select + $('html').on('click.dropdown', '.dropdown-menu li', function (e) { + $(this).hasClass('keep-open') && e.stopPropagation(); + }); + $('html').on('click.dropdown', '.dropdown-menu chosen-drop', function (e) { + $(this).hasClass('keep-open') && e.stopPropagation(); + }); + var self = this; + Em.run.later(this, function () { + $(".metrics-select.chosen-select").chosen({ + placeholder_text: Em.I18n.t('dashboard.widgets.wizard.step2.selectMetric'), + no_results_text: Em.I18n.t('widget.create.wizard.step2.noMetricFound') + }).change(function (event, obj) { + var filteredComponentMetrics = self.get('controller.filteredMetrics').filterProperty('component_name', self.get('currentSelectedComponent.componentName')).filterProperty('level',self.get('currentSelectedComponent.level')); + var filteredMetric = filteredComponentMetrics.findProperty('name', obj.selected); + var selectedMetric = Em.Object.create({ + name: obj.selected, + componentName: self.get('selectedComponent.componentName'), + serviceName: self.get('selectedComponent.serviceName'), + metricPath: filteredMetric.widget_id, + isMetric: true }); - }, - - /** - * @type {Ember.Object} - * @default null - */ - selectedComponent: null, - - /** - * @type {boolean} - */ - showAggregateSelect: function () { - return Boolean(this.get('selectedComponent') && this.get('selectedComponent.level') === 'COMPONENT'); - }.property('selectedComponent.level'), - - /** - * select component - * @param {object} event - */ - selectComponents: function (event) { - var component = this.get('componentMap').findProperty('serviceName', event.context.get('serviceName')) - .get('components').findProperty('id', event.context.get('id')); - $('#add-metric-popup .component-select').removeClass('open'); - - this.set('selectedComponent', component); - if (this.get('showAggregateSelect')) { - this.set('parentView.aggregateFunction', this.get('parentView.AGGREGATE_FUNCTIONS').objectAt(0)); + if (self.get('currentSelectedComponent.hostComponentCriteria')) { + selectedMetric.hostComponentCriteria = self.get('currentSelectedComponent.hostComponentCriteria'); + } + self.set('currentSelectedComponent.selectedMetric', selectedMetric); + }); + + $(".aggregate-function-select.chosen-select").chosen({ + placeholder_text: Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps') + }).change(function (event, obj) { + self.set('currentSelectedComponent.selectedAggregation', obj.selected); + }); + }, 1000); + + }, + + /** + * @type {Ember.Object} + * @default null + */ + currentSelectedComponent: null, + + /** + * select component + * @param {object} event + */ + selectComponents: function (event) { + var component = this.get('componentMap').findProperty('serviceName', event.context.get('serviceName')) + .get('components').findProperty('id', event.context.get('id')); + this.set('currentSelectedComponent', component); + }, + + /** + * add current metrics and aggregation to expression + * @param event + */ + addMetric: function (event) { + var selectedMetric = event.context.get('selectedMetric'), + aggregateFunction = event.context.get('selectedAggregation'); + var isAddEnabled = event.context.get('isAddEnabled'); + var result = jQuery.extend(true, {}, selectedMetric); + if (isAddEnabled) { + var data = this.get('parentView').get('expression.data'), + id = (data.length > 0) ? Math.max.apply(this.get('parentView'), data.mapProperty('id')) + 1 : 1; + result.set('id', id); + if (event.context.get('showAggregateSelect') && aggregateFunction !== 'avg') { + result.set('metricPath', result.get('metricPath') + '._' + aggregateFunction); + result.set('name', result.get('name') + '._' + aggregateFunction); + } + data.pushObject(result); + this.cancel(); + } + }, + + /** + * cancel adding metric, close add metric menu + */ + cancel: function () { + $(".service-level-dropdown").parent().removeClass('open'); + }, + + + /** + * map of components + * has following hierarchy: service -> component -> metrics + */ + componentMap: function () { + var servicesMap = {}; + var result = []; + var components = []; + var masterNames = App.StackServiceComponent.find().filterProperty('isMaster').mapProperty('componentName'); + var parentView = this.get('parentView'); + + if (this.get('controller.filteredMetrics')) { + this.get('controller.filteredMetrics').forEach(function (metric) { + var service = servicesMap[metric.service_name]; + var componentId = masterNames.contains(metric.component_name) ? metric.component_name + '_' + metric.level : metric.component_name; + if (service) { + service.count++; + if (service.components[componentId]) { + service.components[componentId].count++; + service.components[componentId].metrics.push(metric.name); } else { - this.set('parentView.aggregateFunction', null); + service.components[componentId] = { + component_name: metric.component_name, + level: metric.level, + count: 1, + hostComponentCriteria: metric.host_component_criteria, + metrics: [metric.name] + }; } - this.set('parentView.selectedMetric', null); - Em.run.next(function () { - $('.chosen-select option').first().attr('selected','selected'); - $('.chosen-select').trigger('chosen:updated'); - }); - }, - - /** - * select aggregation function - * @param {object} event - */ - selectAggregation: function(event) { - this.set('parentView.aggregateFunction', event.context); - }, - - /** - * map of components - * has following hierarchy: service -> component -> metrics - */ - componentMap: function () { - var servicesMap = {}; - var result = []; - var components = []; - var masterNames = App.StackServiceComponent.find().filterProperty('isMaster').mapProperty('componentName'); - - this.get('controller.filteredMetrics').forEach(function (metric) { - var service = servicesMap[metric.service_name]; - var componentId = masterNames.contains(metric.component_name) ? metric.component_name + '_' + metric.level : metric.component_name; - if (service) { - service.count++; - if (service.components[componentId]) { - service.components[componentId].count++; - service.components[componentId].metrics.push(metric.name); - } else { - service.components[componentId] = { - component_name: metric.component_name, - level: metric.level, - count: 1, - hostComponentCriteria: metric.host_component_criteria, - metrics: [metric.name] - }; + } else { + servicesMap[metric.service_name] = { + count: 1, + components: {} + }; + } + }, this); + } + + for (var serviceName in servicesMap) { + components = []; + for (var componentId in servicesMap[serviceName].components) { + + //HBase service should not show "Active HBase master" + if (servicesMap[serviceName].components[componentId].component_name === 'HBASE_MASTER' && + servicesMap[serviceName].components[componentId].level === 'HOSTCOMPONENT') continue; + + var component = Em.Object.create({ + componentName: servicesMap[serviceName].components[componentId].component_name, + level: servicesMap[serviceName].components[componentId].level, + displayName: function() { + var stackComponent = App.StackServiceComponent.find(this.get('componentName')); + if (stackComponent.get('isMaster')) { + if (this.get('level') === 'HOSTCOMPONENT') { + return Em.I18n.t('widget.create.wizard.step2.activeComponents').format(stackComponent.get('displayName')); } - } else { - servicesMap[metric.service_name] = { - count: 1, - components: {} - }; } - }, this); - - for (var serviceName in servicesMap) { - components = []; - for (var componentId in servicesMap[serviceName].components) { - - //HBase service should not show "Active HBase master" - if (servicesMap[serviceName].components[componentId].component_name === 'HBASE_MASTER' && - servicesMap[serviceName].components[componentId].level === 'HOSTCOMPONENT') continue; - - var component = Em.Object.create({ - componentName: servicesMap[serviceName].components[componentId].component_name, - level: servicesMap[serviceName].components[componentId].level, - displayName: function() { - var stackComponent = App.StackServiceComponent.find(this.get('componentName')); - if (stackComponent.get('isMaster')) { - if (this.get('level') === 'HOSTCOMPONENT') { - return Em.I18n.t('widget.create.wizard.step2.activeComponents').format(stackComponent.get('displayName')); - } - } - return Em.I18n.t('widget.create.wizard.step2.allComponents').format(stackComponent.get('displayName')); - }.property('componentName', 'level'), - count: servicesMap[serviceName].components[componentId].count, - metrics: servicesMap[serviceName].components[componentId].metrics.uniq().sort(), - selected: false, - id: componentId, - serviceName: serviceName - }); - if (component.get('level') === 'HOSTCOMPONENT') { - component.set('hostComponentCriteria', servicesMap[serviceName].components[componentId].hostComponentCriteria); - } - components.push(component); + return Em.I18n.t('widget.create.wizard.step2.allComponents').format(stackComponent.get('displayName')); + }.property('componentName', 'level'), + count: servicesMap[serviceName].components[componentId].count, + metrics: servicesMap[serviceName].components[componentId].metrics.uniq().sort(), + selected: false, + id: componentId, + serviceName: serviceName, + showAggregateSelect: function () { + return this.get('level') === 'COMPONENT'; + }.property('level'), + selectedMetric: null, + selectedAggregation: Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps'), + isAddEnabled: function () { + var selectedMetric = this.get('selectedMetric'), + aggregateFunction = this.get('selectedAggregation'); + if (this.get('showAggregateSelect')) { + return (!!selectedMetric && !!aggregateFunction && + aggregateFunction != Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps')); + } else { + return (!!selectedMetric); } - result.push(Em.Object.create({ - serviceName: serviceName, - //in order to support accordion lists - href: '#' + serviceName, - displayName: App.StackService.find(serviceName).get('displayName'), - count: servicesMap[serviceName].count, - components: components - })); - } - - return result; - }.property('controller.filteredMetrics') - }), - primary: Em.I18n.t('common.add'), - onPrimary: function () { - var data = this.get('expression.data'), - id = (data.length > 0) ? Math.max.apply(this, data.mapProperty('id')) + 1 : 1, - selectedMetric = this.get('selectedMetric'), - aggregateFunction = this.get('aggregateFunction'); - - selectedMetric.set('id', id); - if (aggregateFunction && aggregateFunction !== 'avg') { - selectedMetric.set('metricPath', selectedMetric.get('metricPath') + '._' + aggregateFunction); - selectedMetric.set('name', selectedMetric.get('name') + '._' + aggregateFunction); + }.property('selectedMetric', 'selectedAggregation') + }); + if (component.get('level') === 'HOSTCOMPONENT') { + component.set('hostComponentCriteria', servicesMap[serviceName].components[componentId].hostComponentCriteria); } - data.pushObject(selectedMetric); - this.hide(); + components.push(component); } - }) - } + result.push(Em.Object.create({ + serviceName: serviceName, + //in order to support accordion lists + href: '#' + serviceName, + displayName: App.StackService.find(serviceName).get('displayName'), + count: servicesMap[serviceName].count, + components: components + })); + } + + return result; + }.property('controller.filteredMetrics') });
