You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2015/04/10 14:55:44 UTC
ambari git commit: AMBARI-10433 Create widget wizard -> Metrics &
Expression page: Implement preview for the created expression. (atkach)
Repository: ambari
Updated Branches:
refs/heads/trunk 7a8a7f71f -> 53da928ba
AMBARI-10433 Create widget wizard -> Metrics & Expression page: Implement preview for the created expression. (atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/53da928b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/53da928b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/53da928b
Branch: refs/heads/trunk
Commit: 53da928baa8f0e14b8d1545835e27ce4993c0225
Parents: 7a8a7f7
Author: Andrii Tkach <at...@hortonworks.com>
Authored: Fri Apr 10 14:58:21 2015 +0300
Committer: Andrii Tkach <at...@hortonworks.com>
Committed: Fri Apr 10 14:58:21 2015 +0300
----------------------------------------------------------------------
.../service/widgets/create/step2_controller.js | 164 ++++++++++++++++++-
ambari-web/app/messages.js | 20 ++-
ambari-web/app/mixins/common/widget_mixin.js | 36 ++++
.../app/styles/enhanced_service_dashboard.less | 40 ++++-
ambari-web/app/templates.js | 3 +
.../main/service/widgets/create/expression.hbs | 3 +
.../main/service/widgets/create/step2.hbs | 21 +--
.../main/service/widgets/create/step2_graph.hbs | 46 ++++++
.../service/widgets/create/step2_number.hbs | 29 ++++
.../service/widgets/create/step2_template.hbs | 46 ++++++
.../main/service/widgets/create/wizard.hbs | 8 +
.../views/common/widget/gauge_widget_view.js | 7 -
.../views/common/widget/graph_widget_view.js | 17 +-
.../views/common/widget/number_widget_view.js | 9 +-
.../views/common/widget/template_widget_view.js | 11 +-
.../service/widgets/create/expression_view.js | 1 +
.../main/service/widgets/create/step2_view.js | 100 ++++++++++-
.../main/service/widgets/create/wizard_view.js | 47 +++++-
.../widgets/create/expression_view_test.js | 5 +-
19 files changed, 557 insertions(+), 56 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/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 d0a28b1..cfa555f 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
@@ -21,14 +21,50 @@ var App = require('app');
App.WidgetWizardStep2Controller = Em.Controller.extend({
name: "widgetWizardStep2Controller",
+ /**
+ * @type {Array}
+ */
widgetProperties: [],
widgetValues: {},
+ expressionData: {
+ values: [],
+ metrics: []
+ },
+ widgetPropertiesData: {},
+
+ propertiesMap: {
+ "warning_threshold": {
+ name: 'threshold',
+ property: 'smallValue'
+ },
+ "error_threshold": {
+ name: 'threshold',
+ property: 'bigValue'
+ },
+ "display_unit": {
+ name: 'display-unit',
+ property: 'value'
+ },
+ "graph_type": {
+ name: 'graph_type',
+ property: 'value'
+ },
+ "time_range": {
+ name: 'time_range',
+ property: 'value'
+ }
+ },
+
//TODO: Following computed property needs to be implemented. Next button should be enabled when there is no validation error and all required fields are filled
isSubmitDisabled: function () {
return this.get('widgetProperties').someProperty('isValid', false);
}.property('widgetProperties.@each.isValid'),
+ /**
+ * metrics filtered by type
+ * @type {Array}
+ */
filteredMetrics: function () {
var type = this.get('content.widgetType');
return this.get('content.widgetMetrics').filter(function (metric) {
@@ -40,14 +76,140 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
}, this);
}.property('content.widgetMetrics'),
+ /**
+ * update preview widget with latest expression data
+ * @param {Em.View} view
+ */
+ updateExpressions: function (view) {
+ var widgetType = this.get('content.widgetType');
+ var expressionData = {
+ values: [],
+ metrics: []
+ };
+ if (view.get('expressions').length > 0 && view.get('dataSets').length > 0) {
+ switch (widgetType) {
+ case 'GAUGE':
+ case 'NUMBER':
+ expressionData = this.parseExpression(view.get('expressions')[0]);
+ expressionData.values = [
+ {
+ value: expressionData.value
+ }
+ ];
+ break;
+ case 'TEMPLATE':
+ expressionData = this.parseTemplateExpression(view);
+ break;
+ case 'GRAPH':
+ expressionData = this.parseGraphDataset(view);
+ break;
+ }
+ }
+ this.set('expressionData', expressionData);
+ },
+
+ /**
+ * parse Graph data set
+ * @param {Ember.View} view
+ * @returns {{metrics: Array, values: Array}}
+ */
+ parseGraphDataset: function (view) {
+ var metrics = [];
+ var values = [];
+
+ view.get('dataSets').forEach(function (dataSet) {
+ var result = this.parseExpression(dataSet.get('expression'));
+ metrics.pushObjects(result.metrics);
+ values.push({
+ name: dataSet.get('label'),
+ value: result.value
+ });
+ }, this);
+
+ return {
+ metrics: metrics,
+ values: values
+ };
+ },
+
+ /**
+ * parse expression from template
+ * @param {Ember.View} view
+ * @returns {{metrics: Array, values: {value: *}[]}}
+ */
+ parseTemplateExpression: function (view) {
+ var metrics = [];
+ var self = this;
+ var expression = view.get('templateValue').replace(/\{\{Expression[\d]\}\}/g, function (exp) {
+ var result;
+ if (view.get('expressions').someProperty('alias', exp)) {
+ result = self.parseExpression(view.get('expressions').findProperty('alias', exp));
+ metrics.pushObjects(result.metrics);
+ return result.value;
+ }
+ return exp;
+ });
+ return {
+ metrics: metrics,
+ values: [
+ {
+ value: expression
+ }
+ ]
+ };
+ },
+
+ /**
+ *
+ * @param {object} expression
+ * @returns {{metrics: Array, value: string}}
+ */
+ parseExpression: function (expression) {
+ var value = '';
+ var metrics = [];
+
+ if (expression.data.length > 0) {
+ value = '${';
+ expression.data.forEach(function (element) {
+ if (element.isMetric) {
+ metrics.push(element.name);
+ }
+ value += element.name;
+ }, this);
+ value += '}';
+ }
+
+ return {
+ metrics: metrics,
+ value: value
+ };
+ },
+
+ /**
+ * update properties of preview widget
+ */
+ updateProperties: function () {
+ var propertiesMap = this.get('propertiesMap');
+ var result = {};
+ var widgetProperty;
+
+ for (var i in propertiesMap) {
+ widgetProperty = this.get('widgetProperties').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'),
+
/*
* Generate the thresholds, unit, time range.etc object based on the widget type selected in previous step.
*/
renderProperties: function () {
var widgetType = this.get('content.widgetType');
- this.set("widgetProperties", {});
var widgetProperties = App.WidgetType.find().findProperty('name', widgetType).get('properties');
var properties = [];
+
switch (widgetType) {
case 'GAUGE':
properties = this.renderGaugeProperties(widgetProperties);
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 5233087..cf0f61e 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -258,6 +258,10 @@ Em.I18n.translations = {
'common.seconds': "Seconds",
'common.milliseconds': "Milliseconds",
'common.configGroup': 'Config Group',
+ 'common.expression': 'Expression',
+ 'common.dataSet': 'Data Set',
+ 'common.label': 'Label',
+ 'common.preview': 'Preview',
'models.alert_instance.tiggered.verbose': "Occured on {0} <br> Checked on {1}",
'models.alert_definition.triggered.verbose': "Occured on {0}",
@@ -2251,12 +2255,6 @@ Em.I18n.translations = {
'dashboard.widgets.create': 'Create New Widget',
'dashboard.widgets.layout.import': 'Import a layout',
'dashboard.widgets.layout.save': 'Save a layout',
- 'dashboard.widgets.wizard.step2.addMetrics': 'Add Metrics and operators here...',
- 'dashboard.widgets.wizard.step2.newMetric': '+ New Metric',
- 'dashboard.widgets.wizard.step2.newOperator': '+ New Operator',
- 'dashboard.widgets.wizard.step2.selectComponent': 'Select a Component',
- 'dashboard.widgets.wizard.step2.selectMetric': 'Select a Metric',
- 'dashboard.widgets.wizard.step2.addMetric': 'Add Metric',
'dashboard.widgets.NameNodeHeap': 'NameNode Heap',
'dashboard.widgets.NameNodeCpu': 'NameNode CPU WIO',
@@ -2488,8 +2486,18 @@ Em.I18n.translations = {
'widget.create.wizard.step1.body.text': 'What type of widget do you want to create?',
'widget.create.wizard.step2.header': 'Metrics and Expression',
'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',
+
+ 'dashboard.widgets.wizard.step2.addMetrics': 'Add Metrics and operators here...',
+ 'dashboard.widgets.wizard.step2.newMetric': '+ New Metric',
+ 'dashboard.widgets.wizard.step2.newOperator': '+ New Operator',
+ 'dashboard.widgets.wizard.step2.selectComponent': 'Select a Component',
+ 'dashboard.widgets.wizard.step2.selectMetric': 'Select a Metric',
+ 'dashboard.widgets.wizard.step2.addMetric': 'Add Metric',
'restart.service.all': 'Restart All',
'restart.service.all.affected': 'Restart All Affected',
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/ambari-web/app/mixins/common/widget_mixin.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/widget_mixin.js b/ambari-web/app/mixins/common/widget_mixin.js
index 5ed262c..0fe7958 100644
--- a/ambari-web/app/mixins/common/widget_mixin.js
+++ b/ambari-web/app/mixins/common/widget_mixin.js
@@ -60,6 +60,16 @@ App.WidgetMixin = Ember.Mixin.create({
},
/**
+ * draw widget
+ */
+ drawWidget: function () {
+ if (this.get('isLoaded')) {
+ this.calculateValues();
+ this.set('value', this.get('content.values')[0] && this.get('content.values')[0].computedValue);
+ }
+ },
+
+ /**
* callback on metrics loaded
*/
onMetricsLoaded: function () {
@@ -240,4 +250,30 @@ App.WidgetMixin = Ember.Mixin.create({
//TODO push data to metrics after response structure approved
}
+});
+
+App.WidgetPreviewMixin = Ember.Mixin.create({
+ beforeRender: Em.K,
+ isLoaded: true,
+ metrics: [],
+ content: Em.Object.create({
+ widgetName: 'mock-widget',
+ values: []
+ }),
+ drawWidget: function () {
+ this.loadMetrics();
+ this.set('content.values', this.get('controller.expressionData.values'));
+ this.set('content.properties', this.get('controller.widgetPropertiesData'));
+ this._super();
+ }.observes('controller.widgetPropertiesData', 'controller.expressionData'),
+ loadMetrics: function () {
+ var metrics = [];
+ this.get('controller.expressionData.metrics').forEach(function (metric) {
+ metrics.push({
+ name: metric,
+ data: this.get('MOCK_VALUE')
+ });
+ }, this);
+ this.set('metrics', metrics);
+ }
});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/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 b9a54bf..0578ee7 100644
--- a/ambari-web/app/styles/enhanced_service_dashboard.less
+++ b/ambari-web/app/styles/enhanced_service_dashboard.less
@@ -48,8 +48,10 @@
}
}
-#widget_layout {
+#widget_layout,
+#widget-preview {
.frame {
+ overflow: hidden;
height: 150px;
width: 90%;
}
@@ -111,6 +113,15 @@
}
}
+#widget-preview {
+ max-width: 200px;
+ .graph-widget {
+ .title {
+ height: 0;
+ }
+ }
+}
+
#add-widget-wizard {
.step2 {
.badge-container {
@@ -132,6 +143,14 @@
background-color: @health-status-red;
}
}
+ .remove-link {
+ padding: 5px;
+ cursor: pointer;
+ color: #555555;
+ right: 10px;
+ bottom: 10px;
+ position: absolute;
+ }
.icon-asterisk {
color: red;
font-size: 8px;
@@ -142,7 +161,7 @@
}
.metric-container {
position: relative;
- margin-bottom: 70px;
+ margin-bottom: 50px;
height: 200px;
border: 1px solid @border-color;
button,
@@ -189,6 +208,23 @@
border-color: red;
}
}
+ .template {
+ margin-bottom: 10px;
+ textarea {
+ width: ~"calc(100% - 10px)";
+ }
+ }
+ fieldset {
+ position: relative;
+ border: 2px groove #ddd;
+ padding: 0 1.4em 1.4em 1.4em;
+ margin: 0 0 1.5em 0;
+ }
+ legend {
+ width: inherit;
+ padding: 0 10px;
+ border-bottom: none;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/ambari-web/app/templates.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates.js b/ambari-web/app/templates.js
index 0157613..af5a2c0 100644
--- a/ambari-web/app/templates.js
+++ b/ambari-web/app/templates.js
@@ -22,4 +22,7 @@
require('templates/main/service/info/summary/base');
require('templates/common/progress');
+require("templates/main/service/widgets/create/step2_number");
+require("templates/main/service/widgets/create/step2_template");
+require("templates/main/service/widgets/create/step2_graph");
require('templates/common/configs/widgets/controls');
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/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 55a9537..e57942c 100644
--- a/ambari-web/app/templates/main/service/widgets/create/expression.hbs
+++ b/ambari-web/app/templates/main/service/widgets/create/expression.hbs
@@ -44,6 +44,9 @@
</div>
{{else}}
<a {{action startEdit target="view"}} class="edit-link"><i class="icon-edit"></i></a>
+ {{#if view.expression.isRemovable}}
+ <a {{action removeExpression view.expression target="view.parentView"}} class="remove-link"><i class="icon-trash"></i></a>
+ {{/if}}
{{#if view.expression.data.length}}
<div class="metric-field">
{{#each element in view.expression.data}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/ambari-web/app/templates/main/service/widgets/create/step2.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/widgets/create/step2.hbs b/ambari-web/app/templates/main/service/widgets/create/step2.hbs
index 5b39032..f8f3848 100644
--- a/ambari-web/app/templates/main/service/widgets/create/step2.hbs
+++ b/ambari-web/app/templates/main/service/widgets/create/step2.hbs
@@ -17,17 +17,18 @@
}}
<div class="step2">
- <h2>{{t widget.create.wizard.step2.header}}</h2>
- <div class="alert alert-info">
- {{t widget.create.wizard.step2.body.text}}
- <div class="alert alert-warning">
- {{t widget.create.wizard.step2.body.warning}}
- </div>
- </div>
- {{#each expression in view.expressions}}
- {{view App.WidgetWizardExpressionView expressionBinding="expression"}}
- {{/each}}
+ {{#if view.templateType.isNumber}}
+ {{template "templates/main/service/widgets/create/step2_number"}}
+ {{/if}}
+
+ {{#if view.templateType.isGraph}}
+ {{template "templates/main/service/widgets/create/step2_graph"}}
+ {{/if}}
+
+ {{#if view.templateType.isTemplate}}
+ {{template "templates/main/service/widgets/create/step2_template"}}
+ {{/if}}
<div>
<form class="form-horizontal">
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/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
new file mode 100644
index 0000000..b27c451
--- /dev/null
+++ b/ambari-web/app/templates/main/service/widgets/create/step2_graph.hbs
@@ -0,0 +1,46 @@
+{{!
+* 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.
+}}
+
+<h2>{{t widget.create.wizard.step2.header}}</h2>
+<div class="alert alert-info">
+ {{t widget.create.wizard.step2.body.text}}
+ <div class="alert alert-warning">
+ {{t widget.create.wizard.step2.body.warning}}
+ </div>
+</div>
+
+{{#each dataSet in view.dataSets}}
+ <fieldset>
+ <legend>{{t common.dataSet}} {{dataSet.id}}</legend>
+ <h5>
+ {{t common.label}}: {{view Ember.TextField valueBinding="dataSet.label"}}
+ </h5>
+ <h5>{{t common.expression}}:</h5>
+ {{view App.WidgetWizardExpressionView expressionBinding="dataSet.expression"}}
+ {{#if dataSet.isRemovable}}
+ <a {{action removeDataSet dataSet target="view"}} class="remove-link"><i class="icon-trash"></i></a>
+ {{/if}}
+ </fieldset>
+{{/each}}
+
+<div class="align-right">
+ <a href="#" {{action addDataSet target="view"}}>
+ <i class="icon-plus"></i>
+ {{t widget.create.wizard.step2.addDataset}}
+ </a>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/ambari-web/app/templates/main/service/widgets/create/step2_number.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/widgets/create/step2_number.hbs b/ambari-web/app/templates/main/service/widgets/create/step2_number.hbs
new file mode 100644
index 0000000..ec44798
--- /dev/null
+++ b/ambari-web/app/templates/main/service/widgets/create/step2_number.hbs
@@ -0,0 +1,29 @@
+{{!
+* 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.
+}}
+
+<h2>{{t widget.create.wizard.step2.header}}</h2>
+<div class="alert alert-info">
+ {{t widget.create.wizard.step2.body.text}}
+ <div class="alert alert-warning">
+ {{t widget.create.wizard.step2.body.warning}}
+ </div>
+</div>
+
+{{#each expression in view.expressions}}
+ {{view App.WidgetWizardExpressionView expressionBinding="expression"}}
+{{/each}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/ambari-web/app/templates/main/service/widgets/create/step2_template.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/widgets/create/step2_template.hbs b/ambari-web/app/templates/main/service/widgets/create/step2_template.hbs
new file mode 100644
index 0000000..6d82e9b
--- /dev/null
+++ b/ambari-web/app/templates/main/service/widgets/create/step2_template.hbs
@@ -0,0 +1,46 @@
+{{!
+* 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.
+}}
+
+<h2>{{t widget.create.wizard.step2.header}}</h2>
+
+<div class="alert alert-info">
+ {{t widget.create.wizard.step2.body.template}}
+</div>
+
+<div class="template">
+ {{view Ember.TextArea valueBinding="view.templateValue"}}
+</div>
+
+<div class="alert alert-info">
+ {{t widget.create.wizard.step2.body.text}}
+ <div class="alert alert-warning">
+ {{t widget.create.wizard.step2.body.warning}}
+ </div>
+</div>
+
+{{#each expression in view.expressions}}
+ <h5>{{view.EXPRESSION_PREFIX}}{{expression.id}}</h5>
+ {{view App.WidgetWizardExpressionView expressionBinding="expression"}}
+{{/each}}
+
+<div class="align-right">
+ <a href="#" {{action addExpression target="view"}}>
+ <i class="icon-plus"></i>
+ {{t widget.create.wizard.step2.addExpression}}
+ </a>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/ambari-web/app/templates/main/service/widgets/create/wizard.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/widgets/create/wizard.hbs b/ambari-web/app/templates/main/service/widgets/create/wizard.hbs
index 883d153..6d17b7f 100644
--- a/ambari-web/app/templates/main/service/widgets/create/wizard.hbs
+++ b/ambari-web/app/templates/main/service/widgets/create/wizard.hbs
@@ -30,6 +30,14 @@
<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}}
+ <div class="preview" id="widget-preview">
+ <h5>{{t common.preview}}:</h5>
+ <div class="widget">
+ {{view view.previewWidgetClass controllerBinding="App.router.widgetWizardStep2Controller"}}
+ </div>
+ </div>
+ {{/if}}
</div>
<div class="wizard-content well span9">
{{outlet}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/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 46d6966..25ec38e 100644
--- a/ambari-web/app/views/common/widget/gauge_widget_view.js
+++ b/ambari-web/app/views/common/widget/gauge_widget_view.js
@@ -32,13 +32,6 @@ App.GaugeWidgetView = Em.View.extend(App.WidgetMixin, {
*/
metrics: [],
- drawWidget: function () {
- if (this.get('isLoaded')) {
- this.calculateValues();
- this.set('value', this.get('content.values')[0].computedValue);
- }
- },
-
chartView: App.ChartPieView.extend({
stroke: '#D6DDDF', //light grey
innerR: 25,
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/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 b440984..e886b9b 100644
--- a/ambari-web/app/views/common/widget/graph_widget_view.js
+++ b/ambari-web/app/views/common/widget/graph_widget_view.js
@@ -58,11 +58,16 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, {
var seriesData = [];
this.get('content.values').forEach(function (value) {
- var computedExpressions = this.computeExpression(this.extractExpressions(value)[0], metrics);
- seriesData.push({
- name: value.name,
- data: computedExpressions[value.value.match(this.get('EXPRESSION_REGEX'))[0]]
- });
+ var expression = this.extractExpressions(value)[0];
+ var computedExpressions;
+
+ if (expression) {
+ computedExpressions = this.computeExpression(expression, metrics);
+ seriesData.push({
+ name: value.name,
+ data: computedExpressions[value.value.match(this.get('EXPRESSION_REGEX'))[0]]
+ });
+ }
}, this);
return seriesData;
},
@@ -201,4 +206,4 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, {
this._refreshGraph(this.get('parentView.data'));
}.observes('parentView.data')
})
-});
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/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 c0a85cb..2bab561 100644
--- a/ambari-web/app/views/common/widget/number_widget_view.js
+++ b/ambari-web/app/views/common/widget/number_widget_view.js
@@ -48,12 +48,5 @@ App.NumberWidgetView = Em.View.extend(App.WidgetMixin, {
} else {
return 'red';
}
- }.property('value', 'content.properties.warning_threshold', 'content.properties.error_threshold'),
-
- drawWidget: function () {
- if (this.get('isLoaded')) {
- this.calculateValues();
- this.set('value', this.get('content.values')[0].computedValue);
- }
- }
+ }.property('value', 'content.properties.warning_threshold', 'content.properties.error_threshold')
});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/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 62d043c..b7b54a6 100644
--- a/ambari-web/app/views/common/widget/template_widget_view.js
+++ b/ambari-web/app/views/common/widget/template_widget_view.js
@@ -30,12 +30,5 @@ App.TemplateWidgetView = Em.View.extend(App.WidgetMixin, {
* common metrics container
* @type {Array}
*/
- metrics: [],
-
- drawWidget: function () {
- if (this.get('isLoaded')) {
- this.calculateValues();
- this.set('value', this.get('content.values')[0].computedValue);
- }
- }
-});
\ No newline at end of file
+ metrics: []
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/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 9bc8427..ba4c47e 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
@@ -150,6 +150,7 @@ App.WidgetWizardExpressionView = Em.View.extend({
}
this.set('isInvalid', isInvalid);
+ if (!isInvalid) this.get('parentView').updatePreview();
}.observes('expression.data.length'),
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/ambari-web/app/views/main/service/widgets/create/step2_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/widgets/create/step2_view.js b/ambari-web/app/views/main/service/widgets/create/step2_view.js
index 0cf04a3..d6711c2 100644
--- a/ambari-web/app/views/main/service/widgets/create/step2_view.js
+++ b/ambari-web/app/views/main/service/widgets/create/step2_view.js
@@ -20,18 +20,108 @@ App.WidgetWizardStep2View = Em.View.extend({
templateName: require('templates/main/service/widgets/create/step2'),
+ EXPRESSION_PREFIX: 'Expression',
+
+ /**
+ * content of template of Template widget
+ * @type {string}
+ */
+ templateValue: '',
+
+ /**
+ * calculate template by widget type
+ */
+ templateType: function () {
+ switch (this.get('controller.content.widgetType')) {
+ case 'GAUGE':
+ case 'NUMBER':
+ return {
+ isNumber: true
+ };
+ case 'TEMPLATE':
+ return {
+ isTemplate: true
+ };
+ case 'GRAPH':
+ return {
+ isGraph: true
+ }
+ }
+ }.property('controller.content.widgetType'),
+
/**
* @type {Array}
*/
- expressions: [
- Em.Object.create({
- data: []
- })
- ],
+ expressions: [],
+
+ /**
+ * used only for GRAPH widget
+ * @type {Array}
+ */
+ dataSets: [],
+
+ /**
+ * Add data set
+ * @param {object|null} event
+ * @param {boolean} isDefault
+ */
+ addDataSet: function(event, isDefault) {
+ var id = (isDefault) ? 1 :(Math.max.apply(this, this.get('dataSets').mapProperty('id')) + 1);
+
+ this.get('dataSets').pushObject(Em.Object.create({
+ id: id,
+ label: '',
+ isRemovable: !isDefault,
+ expression: Em.Object.create({
+ data: []
+ })
+ }));
+ },
+
+ /**
+ * Remove data set
+ * @param {object} event
+ */
+ removeDataSet: function(event) {
+ this.get('dataSets').removeObject(event.context);
+ },
+
+ /**
+ * Add expression
+ * @param {object|null} event
+ * @param {boolean} isDefault
+ */
+ addExpression: function(event, isDefault) {
+ var id = (isDefault) ? 1 :(Math.max.apply(this, this.get('expressions').mapProperty('id')) + 1);
+
+ this.get('expressions').pushObject(Em.Object.create({
+ id: id,
+ isRemovable: !isDefault,
+ data: [],
+ alias: '{{' + this.get('EXPRESSION_PREFIX') + id + '}}'
+ }));
+ },
+
+ /**
+ * Remove expression
+ * @param {object} event
+ */
+ removeExpression: function(event) {
+ this.get('expressions').removeObject(event.context);
+ },
+
+ updatePreview: function() {
+ this.get('controller').updateExpressions(this);
+ }.observes('templateValue', 'dataSets.@each.label'),
didInsertElement: function () {
var controller = this.get('controller');
controller.renderProperties();
+ this.get('expressions').clear();
+ this.get('dataSets').clear();
+ this.addExpression(null, true);
+ this.addDataSet(null, true);
+ controller.updateExpressions(this);
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/ambari-web/app/views/main/service/widgets/create/wizard_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/widgets/create/wizard_view.js b/ambari-web/app/views/main/service/widgets/create/wizard_view.js
index 327c573..4283e82 100644
--- a/ambari-web/app/views/main/service/widgets/create/wizard_view.js
+++ b/ambari-web/app/views/main/service/widgets/create/wizard_view.js
@@ -20,5 +20,50 @@ var App = require('app');
App.WidgetWizardView = Em.View.extend(App.WizardMenuMixin, {
- templateName: require('templates/main/service/widgets/create/wizard')
+ templateName: require('templates/main/service/widgets/create/wizard'),
+
+ /**
+ * @type {App.Widget}
+ */
+ previewWidgetClass: function () {
+ switch (this.get('controller.content.widgetType')) {
+ case 'GRAPH':
+ return App.GraphWidgetView.extend(App.WidgetPreviewMixin, {
+ MOCK_VALUE: function () {
+ var nowTime = App.dateTime();
+ var mock = [];
+
+ for (var i = 0; i < 240; i++) {
+ mock.push([
+ 1,
+ (nowTime + (15 * i))
+ ])
+ }
+ return mock;
+ }.property()
+ });
+ case 'TEMPLATE':
+ return App.TemplateWidgetView.extend(App.WidgetPreviewMixin, {
+ MOCK_VALUE: 50
+ });
+ case 'NUMBER':
+ return App.NumberWidgetView.extend(App.WidgetPreviewMixin, {
+ MOCK_VALUE: 50
+ });
+ case 'GAUGE':
+ return App.GaugeWidgetView.extend(App.WidgetPreviewMixin, {
+ MOCK_VALUE: 0.5
+ });
+ default:
+ return Em.View;
+ }
+ }.property('controller.content.widgetType'),
+
+ /**
+ * Widget preview should be shown on 2nd step of wizard
+ * @type {boolean}
+ */
+ showPreview: function () {
+ return this.get('controller.currentStep') == "2";
+ }.property('controller.currentStep')
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/53da928b/ambari-web/test/views/main/service/widgets/create/expression_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/service/widgets/create/expression_view_test.js b/ambari-web/test/views/main/service/widgets/create/expression_view_test.js
index 768bac4..2dd0f73 100644
--- a/ambari-web/test/views/main/service/widgets/create/expression_view_test.js
+++ b/ambari-web/test/views/main/service/widgets/create/expression_view_test.js
@@ -23,7 +23,10 @@ describe('App.WidgetWizardExpressionView', function () {
var view = App.WidgetWizardExpressionView.create({
expression: {
data: []
- }
+ },
+ parentView: Em.Object.create({
+ updatePreview: Em.K
+ })
});
describe("#validate()", function() {