Forráskód Böngészése

AMBARI-10498 Create widget wizard: Implement step-3 "Name and Description". (atkach)

Andrii Tkach 10 éve
szülő
commit
ecb141f9e6

+ 3 - 3
ambari-web/app/controllers/main/service/widgets/create/step1_controller.js

@@ -34,7 +34,7 @@ App.WidgetWizardStep1Controller = Em.Controller.extend({
   /**
    * @type {boolean}
    */
-  isSubmitDisabled: function() {
+  isSubmitDisabled: function () {
     return !this.get('widgetType');
   }.property('widgetType'),
 
@@ -43,11 +43,11 @@ App.WidgetWizardStep1Controller = Em.Controller.extend({
    */
   options: App.WidgetType.find(),
 
-  loadStep: function() {
+  loadStep: function () {
     this.clearStep();
   },
 
-  clearStep: function() {
+  clearStep: function () {
     this.set('widgetType', '');
   },
 

+ 40 - 34
ambari-web/app/controllers/main/service/widgets/create/step2_controller.js

@@ -22,16 +22,26 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
   name: "widgetWizardStep2Controller",
 
   /**
+   * views of properties
    * @type {Array}
    */
-  widgetProperties: [],
-  widgetValues: {},
+  widgetPropertiesViews: [],
 
-  expressionData: {
-    values: [],
-    metrics: []
-  },
-  widgetPropertiesData: {},
+  /**
+   * actual values of properties in API format
+   * @type {object}
+   */
+  widgetProperties: {},
+
+  /**
+   * @type {Array}
+   */
+  widgetValues: [],
+
+  /**
+   * @type {Array}
+   */
+  widgetMetrics: [],
 
   propertiesMap: {
     "warning_threshold": {
@@ -62,14 +72,14 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
    */
   filteredMetrics: function () {
     var type = this.get('content.widgetType');
-    return this.get('content.widgetMetrics').filter(function (metric) {
+    return this.get('content.allMetrics').filter(function (metric) {
       if (type === 'GRAPH') {
         return metric.temporal;
       } else {
         return metric.point_in_time;
       }
     }, this);
-  }.property('content.widgetMetrics'),
+  }.property('content.allMetrics'),
 
   /**
    * update preview widget with latest expression data
@@ -100,7 +110,8 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
           break;
       }
     }
-    this.set('expressionData', expressionData);
+    this.set('widgetValues', expressionData.values);
+    this.set('widgetMetrics', expressionData.metrics);
   },
 
   /**
@@ -167,7 +178,11 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
       value = '${';
       expression.data.forEach(function (element) {
         if (element.isMetric) {
-          metrics.push(element.name);
+          metrics.push({
+            name: element.name,
+            componentName: element.componentName,
+            serviceName: element.serviceName
+          });
         }
         value += element.name;
       }, this);
@@ -189,13 +204,13 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
     var widgetProperty;
 
     for (var i in propertiesMap) {
-      widgetProperty = this.get('widgetProperties').findProperty('name', propertiesMap[i].name);
+      widgetProperty = this.get('widgetPropertiesViews').findProperty('name', propertiesMap[i].name);
       if (widgetProperty && widgetProperty.get('isValid')) {
         result[i] = widgetProperty.get(propertiesMap[i].property);
       }
     }
-    this.set('widgetPropertiesData', result);
-  }.observes('widgetProperties.@each.value', 'widgetProperties.@each.bigValue', 'widgetProperties.@each.smallValue'),
+    this.set('widgetProperties', result);
+  }.observes('widgetPropertiesViews.@each.value', 'widgetPropertiesViews.@each.bigValue', 'widgetPropertiesViews.@each.smallValue'),
 
   /*
    * Generate the thresholds, unit, time range.etc object based on the widget type selected in previous step.
@@ -221,7 +236,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
       default:
         console.error('Incorrect Widget Type: ', widgetType);
     }
-    this.set('widgetProperties', properties);
+    this.set('widgetPropertiesViews', properties);
   },
 
   /**
@@ -229,16 +244,14 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
    * @method renderGaugeProperties
    * @returns {App.WidgetProperties[]}
    */
-  renderGaugeProperties: function (widgetProperties) {
-    var result = [];
-    result = result.concat([
+  renderGaugeProperties: function () {
+    return [
       App.WidgetProperties.Thresholds.PercentageThreshold.create({
         smallValue: '0.7',
         bigValue: '0.9',
         isRequired: true
       })
-    ]);
-    return result;
+    ];
   },
 
   /**
@@ -246,10 +259,8 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
    * @method renderNumberProperties
    * @returns {App.WidgetProperties[]}
    */
-  renderNumberProperties: function (widgetProperties) {
-    var result = [];
-
-    result = result.concat([
+  renderNumberProperties: function () {
+    return [
       App.WidgetProperties.Threshold.create({
         smallValue: '10',
         bigValue: '20',
@@ -259,8 +270,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
         value: 'MB',
         isRequired: false
       })
-    ]);
-    return result;
+    ];
   },
 
   /**
@@ -269,14 +279,12 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
    * @returns {App.WidgetProperties[]}
    */
   renderTemplateProperties: function (widgetProperties) {
-    var result = [];
-    result = result.concat([
+    return [
       App.WidgetProperties.Unit.create({
         value: 'MB',
         isRequired: false
       })
-    ]);
-    return result;
+    ];
   },
 
   /**
@@ -285,8 +293,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
    * @returns {App.WidgetProperties[]}
    */
   renderGraphProperties: function (widgetProperties) {
-    var result = [];
-    result = result.concat([
+    return [
       App.WidgetProperties.GraphType.create({
         value: 'LINE',
         isRequired: true
@@ -299,8 +306,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
         value: 'MB',
         isRequired: false
       })
-    ]);
-    return result;
+    ];
   },
 
   next: function () {

+ 65 - 3
ambari-web/app/controllers/main/service/widgets/create/step3_controller.js

@@ -21,8 +21,70 @@ var App = require('app');
 App.WidgetWizardStep3Controller = Em.Controller.extend({
   name: "widgetWizardStep3Controller",
 
+  /**
+   * @type {Array}
+   */
+  scopes: [
+    Em.Object.create({
+      name: 'User',
+      checked: true
+    }),
+    Em.Object.create({
+      name: 'Cluster',
+      checked: false
+    })
+  ],
+
+  /**
+   * @type {string}
+   */
+  widgetName: '',
+
+  /**
+   * @type {string}
+   */
+  widgetAuthor: '',
+
+  /**
+   * @type {string}
+   */
+  widgetScope: function () {
+    return this.get('scopes').findProperty('checked');
+  }.property('scopes.@each.checked'),
+
+  /**
+   * @type {string}
+   */
+  widgetDescription: '',
+
+  /**
+   * actual values of properties in API format
+   * @type {object}
+   */
+  widgetProperties: {},
+
+  /**
+   * @type {Array}
+   */
+  widgetValues: [],
+
+  /**
+   * @type {Array}
+   */
+  widgetMetrics: [],
+
+  /**
+   * restore widget data set on 2nd step
+   */
+  initPreviewData: function () {
+    this.set('widgetProperties', this.get('content.widgetProperties'));
+    this.set('widgetValues', this.get('content.widgetValues'));
+    this.set('widgetMetrics', this.get('content.widgetMetrics'));
+    this.set('widgetAuthor', App.router.get('loginName'));
+  },
+
   //TODO: Following computed propert needs to be implemented. Next button should be enabled when there is no validation error and all required fields are filled
-  isSubmitDisabled: function() {
-    return false;
-  }.property('')
+  isSubmitDisabled: function () {
+    return !this.get('widgetName');
+  }.property('widgetName')
 });

+ 70 - 35
ambari-web/app/controllers/main/service/widgets/create/wizard_controller.js

@@ -35,24 +35,51 @@ App.WidgetWizardController = App.WizardController.extend({
     controllerName: 'widgetWizardController',
     widgetService: null,
     widgetType: '',
-    widgetProperties: [],
 
     /**
-     * widgetMetric schema:
+     * Example:
      * {
-     *  widget_id: DS.attr('string'), //example: "metrics/rpc/closeRegion_num_ops",
-     *  name: DS.attr('string'),       //example: "rpc.rpc.closeRegion_num_ops",
+     *  "display_unit": "%",
+     *  "warning_threshold": 70,
+     *  "error_threshold": 90
+     * }
+     */
+    widgetProperties: {},
+
+    /**
+     * Example:
+     * [{
+     *  widget_id: "metrics/rpc/closeRegion_num_ops",
+     *  name: "rpc.rpc.closeRegion_num_ops",
      *  pointInTime: true,
      *  temporal: true,
-     *  category: DS.attr('string'),                 //example: default
-     *  serviceName: DS.attr('string'),          //example: HBASE
-     *  componentName: DS.attr('string'),    //example: HBASE_CLIENT
-     *  type: DS.attr('string'),                        //options: GANGLIA | JMX
-     *  level: DS.attr('string'),                         //options: COMPONENT | HOSTCOMPONENT
-     * }
+     *  category: "default"
+     *  serviceName: "HBASE"
+     *  componentName: "HBASE_CLIENT"
+     *  type: "GANGLIA"//or JMX
+     *  level: "COMPONENT"//or HOSTCOMPONENT
+     * }]
      * @type {Array}
      */
+    allMetrics: [],
+
+    /**
+     * Example:
+     * [{
+     *  "name": "regionserver.Server.percentFilesLocal",
+     *  "serviceName": "HBASE",
+     *  "componentName": "HBASE_REGIONSERVER"
+     * }]
+     */
     widgetMetrics: [],
+
+    /**
+     * Example:
+     * [{
+     *  "name": "Files Local",
+     *  "value": "${regionserver.Server.percentFilesLocal}"
+     * }]
+     */
     widgetValues: [],
     widgetName: null,
     widgetDescription: null,
@@ -90,7 +117,6 @@ App.WidgetWizardController = App.WizardController.extend({
   }.observes('currentStep', 'App.router.clusterController.isLoaded'),
 
 
-
   /**
    * save status of the cluster.
    * @param clusterStatus object with status,requestId fields.
@@ -109,15 +135,15 @@ App.WidgetWizardController = App.WizardController.extend({
     this.save('cluster');
   },
 
-  loadWidgetService: function() {
+  loadWidgetService: function () {
     this.set('content.widgetService', this.getDBProperty('widgetService'));
   },
 
-  loadWidgetType: function() {
+  loadWidgetType: function () {
     this.set('content.widgetType', this.getDBProperty('widgetType'));
   },
 
-  loadWidgetProperties: function() {
+  loadWidgetProperties: function () {
     this.set('content.widgetProperties', this.getDBProperty('widgetProperties'));
   },
 
@@ -126,17 +152,17 @@ App.WidgetWizardController = App.WizardController.extend({
    * on resolve deferred return array of widget metrics
    * @returns {$.Deferred}
    */
-  loadWidgetMetrics: function () {
-    var widgetMetrics = this.getDBProperty('widgetMetrics');
+  loadAllMetrics: function () {
+    var widgetMetrics = this.getDBProperty('allMetrics');
     var self = this;
     var dfd = $.Deferred();
 
     if (widgetMetrics.length === 0) {
-      this.loadWidgetMetricsFromServer(function () {
-        dfd.resolve(self.get('content.widgetMetrics'));
+      this.loadAllMetricsFromServer(function () {
+        dfd.resolve(self.get('content.allMetrics'));
       });
     } else {
-      this.set('content.widgetMetrics', widgetMetrics);
+      this.set('content.allMetrics', widgetMetrics);
       dfd.resolve(widgetMetrics);
     }
     return dfd.promise();
@@ -147,7 +173,7 @@ App.WidgetWizardController = App.WizardController.extend({
    * @param {function} callback
    * @returns {$.ajax}
    */
-  loadWidgetMetricsFromServer: function (callback) {
+  loadAllMetricsFromServer: function (callback) {
     return App.ajax.send({
       name: 'widgets.wizard.metrics.get',
       sender: this,
@@ -156,7 +182,7 @@ App.WidgetWizardController = App.WizardController.extend({
         serviceNames: App.Service.find().mapProperty('serviceName').join(',')
       },
       callback: callback,
-      success: 'loadWidgetMetricsFromServerCallback'
+      success: 'loadAllMetricsFromServerCallback'
     })
   },
 
@@ -164,7 +190,7 @@ App.WidgetWizardController = App.WizardController.extend({
    *
    * @param {object} json
    */
-  loadWidgetMetricsFromServerCallback: function (json) {
+  loadAllMetricsFromServerCallback: function (json) {
     var result = [];
     var metrics = {};
 
@@ -191,36 +217,44 @@ App.WidgetWizardController = App.WizardController.extend({
         }
       }
     }
-    this.saveWidgetMetrics(result);
+    this.saveAllMetrics(result);
   },
 
-  loadWidgetValues: function() {
+  loadWidgetValues: function () {
     this.set('content.widgetValues', this.getDBProperty('widgetValues'));
   },
 
+  loadWidgetMetrics: function () {
+    this.set('content.widgetMetrics', this.getDBProperty('widgetMetrics'));
+  },
 
-  saveWidgetService: function(widgetService) {
-    this.setDBProperty('widgetService',widgetService);
+  saveWidgetService: function (widgetService) {
+    this.setDBProperty('widgetService', widgetService);
     this.set('content.widgetService', widgetService);
   },
 
-  saveWidgetType: function(widgetType) {
-    this.setDBProperty('widgetType',widgetType);
+  saveWidgetType: function (widgetType) {
+    this.setDBProperty('widgetType', widgetType);
     this.set('content.widgetType', widgetType);
   },
 
-  saveWidgetProperties: function(widgetProperties) {
-    this.setDBProperty('widgetProperties',widgetProperties);
+  saveWidgetProperties: function (widgetProperties) {
+    this.setDBProperty('widgetProperties', widgetProperties);
     this.set('content.widgetProperties', widgetProperties);
   },
 
-  saveWidgetMetrics: function(widgetMetrics) {
-    this.setDBProperty('widgetMetrics',widgetMetrics);
+  saveAllMetrics: function (allMetrics) {
+    this.setDBProperty('allMetrics', allMetrics);
+    this.set('content.allMetrics', allMetrics);
+  },
+
+  saveWidgetMetrics: function (widgetMetrics) {
+    this.setDBProperty('widgetMetrics', widgetMetrics);
     this.set('content.widgetMetrics', widgetMetrics);
   },
 
-  saveWidgetValues: function(widgetValues) {
-    this.setDBProperty('widgetValues',widgetValues);
+  saveWidgetValues: function (widgetValues) {
+    this.setDBProperty('widgetValues', widgetValues);
     this.set('content.widgetValues', widgetValues);
   },
 
@@ -240,12 +274,13 @@ App.WidgetWizardController = App.WizardController.extend({
         callback: function () {
           this.loadWidgetProperties();
           this.loadWidgetValues();
+          this.loadWidgetMetrics();
         }
       },
       {
         type: 'async',
         callback: function () {
-          return this.loadWidgetMetrics();
+          return this.loadAllMetrics();
         }
       }
     ]

+ 3 - 1
ambari-web/app/messages.js

@@ -262,6 +262,7 @@ Em.I18n.translations = {
   'common.dataSet': 'Data Set',
   'common.label': 'Label',
   'common.preview': 'Preview',
+  'common.scope': 'Scope',
 
   'models.alert_instance.tiggered.verbose': "Occured on {0} <br> Checked on {1}",
   'models.alert_definition.triggered.verbose': "Occured on {0}",
@@ -2502,12 +2503,13 @@ Em.I18n.translations = {
   'widget.create.wizard.step2.body.text':'Define the expression with any metrics and valid operators. </br>Use parentheses when necessary.',
   'widget.create.wizard.step2.body.template':'Define the template first, a template can have any number of {{expression}} and any string.',
   'widget.create.wizard.step2.body.warning':'Note: Valid operators are +, -, *, /',
-  'widget.create.wizard.step3.header': 'Name and Description',
   'widget.create.wizard.step2.addExpression': 'Add Expression',
   'widget.create.wizard.step2.addDataset': 'Add data set',
   'widget.create.wizard.step2.allComponents': 'All {0}',
   'widget.create.wizard.step2.activeComponents': 'Active {0}',
   'widget.create.wizard.step2.noMetricFound': 'No metric found',
+  'widget.create.wizard.step3.widgetName': 'Widget Name',
+  'widget.create.wizard.step3.header': 'Name and Description',
 
   'dashboard.widgets.wizard.step2.addMetrics': 'Add Metrics and operators here...',
   'dashboard.widgets.wizard.step2.newMetric': '+ New Metric',

+ 8 - 5
ambari-web/app/mixins/common/widget_mixin.js

@@ -281,15 +281,18 @@ App.WidgetPreviewMixin = Ember.Mixin.create({
   }),
   drawWidget: function () {
     this.loadMetrics();
-    this.set('content.values', this.get('controller.expressionData.values'));
-    this.set('content.properties', this.get('controller.widgetPropertiesData'));
+    this.get('content').setProperties({
+      'values': this.get('controller.widgetValues'),
+      'properties': this.get('controller.widgetProperties'),
+      'displayName': this.get('controller.widgetName')
+    });
     this._super();
-  }.observes('controller.widgetPropertiesData', 'controller.expressionData'),
+  }.observes('controller.widgetProperties', 'controller.widgetValues', 'controller.widgetMetrics', 'controller.widgetName'),
   loadMetrics: function () {
     var metrics = [];
-    this.get('controller.expressionData.metrics').forEach(function (metric) {
+    this.get('controller.widgetMetrics').forEach(function (metric) {
       metrics.push({
-        name: metric,
+        name: metric.name,
         data: this.get('MOCK_VALUE')
       });
     }, this);

+ 1 - 17
ambari-web/app/models/widget_property.js

@@ -18,7 +18,6 @@
 
 var App = require('app');
 var validator = require('utils/validator');
-var numericUtils = require('utils/number_utils');
 
 App.WidgetProperty = Ember.Object.extend({
 
@@ -92,20 +91,6 @@ App.WidgetProperty = Ember.Object.extend({
 
 App.WidgetProperties = {
 
-  WidgetName: App.WidgetProperty.extend({
-    name: 'widget_name',
-    label: 'Widget Name',
-    displayType: 'textField',
-    classNames: 'widget-property-text-input'
-  }),
-
-  Description: App.WidgetProperty.extend({
-    name: 'description',
-    label: 'Description',
-    displayType: 'textArea',
-    classNames: 'widget-property-text-area'
-  }),
-
   Unit: App.WidgetProperty.extend({
     name: 'display-unit',
     label: 'Unit',
@@ -245,5 +230,4 @@ App.WidgetProperties.Thresholds = {
     }.property('bigValue', 'smallValue')
 
   })
-}
-
+};

+ 2 - 1
ambari-web/app/routes/add_widget.js

@@ -100,6 +100,7 @@ module.exports = App.WizardRoute.extend({
       widgetWizardController.saveWidgetType(widgetStep1controller.get('widgetType'));
       widgetWizardController.setDBProperty('widgetProperties', []);
       widgetWizardController.setDBProperty('widgetMetrics', []);
+      widgetWizardController.setDBProperty('allMetrics', []);
       widgetWizardController.setDBProperty('widgetValues', []);
       router.transitionTo('step2');
     }
@@ -152,7 +153,7 @@ module.exports = App.WizardRoute.extend({
     complete: function (router, context) {
       var controller = router.get('widgetWizardStep3Controller');
       if (!controller.get('isSubmitDisabled')) {
-        $(context.currentTarget).parents("#modal").find(".close").trigger('click');
+        router.get('widgetWizardController.popup').onClose();
       }
     }
   })

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

@@ -5267,7 +5267,7 @@ i.icon-asterisks {
   }
 }
 
-input[type="checkbox"].align-checkbox {
+input[type="radio"].align-checkbox, input[type="checkbox"].align-checkbox {
   margin: -2px 5px 0 0;
 }
 

+ 21 - 0
ambari-web/app/styles/enhanced_service_dashboard.less

@@ -276,6 +276,27 @@
       border-bottom: none;
     }
   }
+  .step3 {
+    form {
+      margin: 50px 0;
+      .row-fluid {
+        line-height: 30px;
+        margin: 10px 0;
+        .title {
+          text-align: right;
+        }
+      }
+      .radio-group {
+        line-height: 20px;
+        .checkbox {
+          padding-left: 0;
+        }
+        label {
+          margin-bottom: 0;
+        }
+      }
+    }
+  }
 }
 
 #add-metric-popup {

+ 1 - 1
ambari-web/app/templates/main/service/widgets/create/step2.hbs

@@ -32,7 +32,7 @@
 
   <div>
     <form class="form-horizontal">
-      {{#each property in controller.widgetProperties}}
+      {{#each property in controller.widgetPropertiesViews}}
         <div {{bindAttr class=":control-group property.name property.isValid::error"}}>
           <label class="control-label">{{property.label}}
             {{#if property.isRequired }}

+ 1 - 1
ambari-web/app/templates/main/service/widgets/create/step2_add_metric.hbs

@@ -55,7 +55,7 @@
   <div class="span3">{{t dashboard.widgets.wizard.step2.selectMetric}}</div>
   <div class="span9">
     <select class="chosen-select">
-      {{#each metric in view.componentMetrics}}
+      {{#each metric in view.selectedComponent.metrics}}
         <option>{{unbound metric}}</option>
       {{/each}}
     </select>

+ 29 - 1
ambari-web/app/templates/main/service/widgets/create/step3.hbs

@@ -16,9 +16,37 @@
 * limitations under the License.
 }}
 
-<div id="add-widget-step3">
+<div class="step3">
   <h2>{{t widget.create.wizard.step3.header}}</h2>
 
+  <form>
+    <div class="row-fluid">
+      <div class="span2 title">{{t widget.create.wizard.step3.widgetName}}</div>
+      <div class="span10">{{view Ember.TextField valueBinding="widgetName"}}</div>
+    </div>
+
+    <div class="row-fluid">
+      <div class="span2 title">{{t common.author}}</div>
+      <div class="span10">{{widgetAuthor}}</div>
+    </div>
+
+    <div class="row-fluid">
+      <div class="span2 title">{{t common.scope}}</div>
+      <div class="span10 radio-group">
+        {{#each scope in scopes}}
+          <label class="checkbox">
+            {{view view.scopeRadioButtonView checkedBinding="scope.checked" class="align-checkbox"}}
+            {{scope.name}}
+          </label>
+        {{/each}}
+      </div>
+    </div>
+
+    <div class="row-fluid">
+      <div class="span2 title">{{t common.description}}</div>
+      <div class="span10">{{view Ember.TextArea valueBinding="widgetDescription"}}</div>
+    </div>
+  </form>
 
   <div class="btn-area">
     <button id="add-widget-step3-back" class="btn" {{action back}}>&larr; {{t common.back}}</button>

+ 9 - 1
ambari-web/app/templates/main/service/widgets/create/wizard.hbs

@@ -30,7 +30,7 @@
               <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep3 target="controller"}}>{{t widget.create.wizard.step3.header}}</a></li>
             </ul>
           </div>
-          {{#if view.showPreview}}
+          {{#if view.isStep2}}
             <div class="preview" id="widget-preview">
               <h5>{{t common.preview}}:</h5>
               <div class="widget">
@@ -38,6 +38,14 @@
               </div>
             </div>
           {{/if}}
+          {{#if view.isStep3}}
+            <div class="preview" id="widget-preview">
+              <h5>{{t common.preview}}:</h5>
+              <div class="widget">
+                {{view view.previewWidgetClass controllerBinding="App.router.widgetWizardStep3Controller"}}
+              </div>
+            </div>
+          {{/if}}
         </div>
         <div class="wizard-content well span9">
           {{outlet}}

+ 17 - 12
ambari-web/app/views/main/service/widgets/create/expression_view.js

@@ -164,8 +164,7 @@ App.WidgetWizardExpressionView = Em.View.extend({
       expression: this.get('expression'),
 
       /**
-       * @type {string}
-       * @default null
+       * @type {object|null}
        */
       selectedMetric: null,
 
@@ -189,22 +188,25 @@ App.WidgetWizardExpressionView = Em.View.extend({
             placeholder_text: Em.I18n.t('widget.create.wizard.step2.noMetricFound'),
             no_results_text: Em.I18n.t('widget.create.wizard.step2.noMetricFound')
           }).change(function (event, obj) {
-            self.set('parentView.selectedMetric', obj.selected);
+            self.set('parentView.selectedMetric', {
+              name: obj.selected,
+              componentName: self.get('selectedComponent.componentName'),
+              serviceName: self.get('selectedComponent.serviceName')
+            });
           });
         },
 
         /**
-         * @type {Array}
+         * @type {Ember.Object}
+         * @default null
          */
-        componentMetrics: [],
+        selectedComponent: null,
 
         selectComponents: function (event) {
-          var componentMetrics = [];
+          var component = this.get('componentMap').findProperty('serviceName', event.context.get('serviceName'))
+            .get('components').findProperty('id', event.context.get('id'));
 
-          this.get('componentMap').forEach(function (service) {
-            componentMetrics = service.get('components').findProperty('id', event.context.get('id')).get('metrics');
-          }, this);
-          this.set('componentMetrics', componentMetrics);
+          this.set('selectedComponent', component);
           this.set('parentView.selectedMetric', null);
           Em.run.next(function () {
             $('.chosen-select').trigger('chosen:updated');
@@ -264,7 +266,8 @@ App.WidgetWizardExpressionView = Em.View.extend({
                 count: servicesMap[serviceName].components[componentId].count,
                 metrics: servicesMap[serviceName].components[componentId].metrics.uniq().sort(),
                 selected: false,
-                id: componentId
+                id: componentId,
+                serviceName: serviceName
               }));
             }
             result.push(Em.Object.create({
@@ -284,7 +287,9 @@ App.WidgetWizardExpressionView = Em.View.extend({
         var lastId = (data.length > 0) ? Math.max.apply(this, data.mapProperty('id')) : 0;
         data.pushObject(Em.Object.create({
           id: ++lastId,
-          name: this.get('selectedMetric'),
+          name: this.get('selectedMetric.name'),
+          componentName: this.get('selectedMetric.componentName'),
+          serviceName: this.get('selectedMetric.serviceName'),
           isMetric: true
         }));
         this.hide();

+ 1 - 2
ambari-web/app/views/main/service/widgets/create/step2_view.js

@@ -64,7 +64,7 @@ App.WidgetWizardStep2View = Em.View.extend({
    * @type {boolean}
    */
   isSubmitDisabled: function() {
-    if (this.get('controller.widgetProperties').someProperty('isValid', false)) {
+    if (this.get('controller.widgetPropertiesViews').someProperty('isValid', false)) {
       return true;
     }
     switch (this.get('controller.content.widgetType')) {
@@ -142,7 +142,6 @@ App.WidgetWizardStep2View = Em.View.extend({
 
   updatePreview: function() {
     this.get('controller').updateExpressions(this);
-    this.propertyDidChange('isSubmitDisabled');
   }.observes('templateValue', 'dataSets.@each.label'),
 
   didInsertElement: function () {

+ 13 - 0
ambari-web/app/views/main/service/widgets/create/step3_view.js

@@ -20,8 +20,21 @@ App.WidgetWizardStep3View = Em.View.extend({
 
   templateName: require('templates/main/service/widgets/create/step3'),
 
+  /**
+   * @type {Ember.Checkbox}
+   */
+  scopeRadioButtonView: Em.Checkbox.extend({
+    attributeBindings: ['type', 'value', 'checked'],
+    type: 'radio',
+
+    change: function () {
+      this.get('controller.scopes').setEach('checked', false);
+    }
+  }),
+
   didInsertElement: function () {
     var controller = this.get('controller');
+    controller.initPreviewData();
   }
 
 });

+ 9 - 1
ambari-web/app/views/main/service/widgets/create/wizard_view.js

@@ -63,7 +63,15 @@ App.WidgetWizardView = Em.View.extend(App.WizardMenuMixin, {
    * Widget preview should be shown on 2nd step of wizard
    * @type {boolean}
    */
-  showPreview: function () {
+  isStep2: function () {
     return this.get('controller.currentStep') == "2";
+  }.property('controller.currentStep'),
+
+  /**
+   * Widget preview should be shown on 3rd step of wizard
+   * @type {boolean}
+   */
+  isStep3: function () {
+    return this.get('controller.currentStep') == "3";
   }.property('controller.currentStep')
 });