You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2015/03/24 14:06:52 UTC
ambari git commit: AMBARI-10191. YARN configs should show
slider-widgets when configured in theme (onechiporenko)
Repository: ambari
Updated Branches:
refs/heads/trunk ed231bead -> fd5e6e682
AMBARI-10191. YARN configs should show slider-widgets when configured in theme (onechiporenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/fd5e6e68
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fd5e6e68
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fd5e6e68
Branch: refs/heads/trunk
Commit: fd5e6e6823cec08ef3334286924e964638c9fa16
Parents: ed231be
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Tue Mar 24 14:59:18 2015 +0200
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Tue Mar 24 14:59:18 2015 +0200
----------------------------------------------------------------------
.../controllers/main/service/info/configs.js | 7 +-
ambari-web/app/styles/widgets.less | 9 +--
.../configs/service_config_layout_tab.hbs | 10 ++-
.../configs/widgets/slider_config_widget.hbs | 34 +++++----
.../configs/service_config_layout_tab_view.js | 48 ++++++++++++-
.../widgets/slider_config_widget_view.js | 76 +++++++++++++++-----
.../main/service/info/config_test.js | 7 +-
.../widgets/slider_config_widget_view_test.js | 48 ++++++++++---
8 files changed, 187 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/fd5e6e68/ambari-web/app/controllers/main/service/info/configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js
index 0314afc..be086ac 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -257,7 +257,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
var self = this;
if (App.get('supports.enhancedConfigs')) {
App.config.loadConfigTheme(this.get('content.serviceName')).then(function() {
- App.themesMapper.generateAdvancedTabs([self.get('content.serviceName')]);
+ self.loadDependentConfigs().done(function () {
+ App.themesMapper.generateAdvancedTabs([self.get('content.serviceName')]);
+ });
});
}
this.clearStep();
@@ -354,7 +356,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
* by serviceName that has dependent properties
*/
if (serviceConfigsToLoad.length > 0) {
- App.config.loadConfigCurrentVersions(serviceConfigsToLoad);
+ return App.config.loadConfigCurrentVersions(serviceConfigsToLoad);
}
},
@@ -988,7 +990,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
this.set('versionLoaded', true);
this.set('hash', this.getHash());
this.set('isInit', false);
- this.loadDependentConfigs();
},
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/fd5e6e68/ambari-web/app/styles/widgets.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/widgets.less b/ambari-web/app/styles/widgets.less
index 9746547..33f8b15 100644
--- a/ambari-web/app/styles/widgets.less
+++ b/ambari-web/app/styles/widgets.less
@@ -31,10 +31,6 @@
@slider-widget-border-color: #999;
- .ui-slider-wrapper {
- margin: 0 30px;
- }
-
.slider-track {
height: 20px !important;
border: 1px solid @slider-widget-border-color;
@@ -70,6 +66,11 @@
border-radius: 11px;
box-shadow: none;
}
+
+ .undo-button {
+ margin-left: 20px;
+ }
+
}
.spinner-input-widget {
http://git-wip-us.apache.org/repos/asf/ambari/blob/fd5e6e68/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs b/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs
index 9f3fb8e..3fd541d 100644
--- a/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs
+++ b/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs
@@ -22,12 +22,18 @@
<tr>
{{#each section in row}}
<td class="config-section" {{bindAttr colspan="section.columnSpan" rowspan="section.rowSpan"}}>
- {{section.displayName}}
+ <h3>{{section.displayName}}</h3>
<table class="config-subsection-table">
{{#each subRow in section.subsectionRows}}
<tr>
{{#each subsection in subRow}}
- <td class="config-subsection">{{subsection.name}}</td>
+ <td class="config-subsection">
+ {{#each config in subsection.configs}}
+ {{#if config.view}}
+ {{view config.widget configBinding="config"}}
+ {{/if}}
+ {{/each}}
+ </td>
{{/each}}
</tr>
{{/each}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fd5e6e68/ambari-web/app/templates/common/configs/widgets/slider_config_widget.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/widgets/slider_config_widget.hbs b/ambari-web/app/templates/common/configs/widgets/slider_config_widget.hbs
index 960bc72..c38e4b3 100644
--- a/ambari-web/app/templates/common/configs/widgets/slider_config_widget.hbs
+++ b/ambari-web/app/templates/common/configs/widgets/slider_config_widget.hbs
@@ -17,24 +17,30 @@
}}
<div class="widget slider-widget">
+ <p>{{view.config.name}}</p>
+
<p>{{view.config.description}}</p>
- <div {{bindAttr class="view.isMirrorValueValid::error :control-group :pull-left"}}>
- <div {{bindAttr class="view.config.stackConfigProperty.valueAttributes.unit:input-append"}}>
- {{view Ember.TextField valueBinding="view.mirrorValue" class="input-mini"}}
- {{#if view.config.stackConfigProperty.valueAttributes.unit}}
- <span class="add-on">{{view.config.stackConfigProperty.valueAttributes.unit}}</span>
- {{/if}}
+
+ <div>
+ <div {{bindAttr class="view.isMirrorValueValid::error :control-group :pull-left"}}>
+ <div {{bindAttr class="view.config.stackConfigProperty.valueAttributes.unit:input-append"}}>
+ {{view Ember.TextField valueBinding="view.mirrorValue" class="input-mini"}}
+ {{#if view.config.stackConfigProperty.valueAttributes.unit}}
+ <span class="add-on">{{view.config.stackConfigProperty.valueAttributes.unit}}</span>
+ {{/if}}
+ </div>
</div>
+ {{#if view.valueIsChanged}}
+ <div class="pull-left undo-button">
+ <a class="btn btn-small" href="#" {{action "restoreValue" target="view"}}>
+ <i class="icon-undo"></i>
+ </a>
+ </div>
+ {{/if}}
+ <div class="clearfix"></div>
</div>
- <div class="pull-left ui-slider-wrapper">
+ <div class="ui-slider-wrapper">
{{view Ember.TextField valueBinding="view.config.value" class="input-mini slider-input"}}
</div>
- {{#if view.valueIsChanged}}
- <div class="pull-left undo-button">
- <a class="btn btn-small" href="#" {{action "restoreValue" target="view"}}>
- <i class="icon-undo"></i>
- </a>
- </div>
- {{/if}}
<div class="clearfix"></div>
</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/fd5e6e68/ambari-web/app/views/common/configs/service_config_layout_tab_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/service_config_layout_tab_view.js b/ambari-web/app/views/common/configs/service_config_layout_tab_view.js
index 2fa35b6..9e93076 100644
--- a/ambari-web/app/views/common/configs/service_config_layout_tab_view.js
+++ b/ambari-web/app/views/common/configs/service_config_layout_tab_view.js
@@ -19,5 +19,51 @@
var App = require('app');
App.ServiceConfigLayoutTabView = Em.View.extend({
- templateName: require('templates/common/configs/service_config_layout_tab')
+
+ templateName: require('templates/common/configs/service_config_layout_tab'),
+
+ /**
+ * ConfigType-Widget map
+ * key - widget type
+ * value - widget view
+ * @type {object}
+ */
+ widgetTypeMap: {
+ slider: App.SliderConfigWidgetView
+ },
+
+ /**
+ * Prepare configs for render
+ * <code>subsection.configs</code> is an array of App.StackConfigProperty, but not App.ConfigProperty,
+ * so proper config-properties should be linked to the subsections.
+ * Also correct widget should be used for each config (it's selected according to <code>widget.type</code> and
+ * <code>widgetTypeMap</code>). It may throw an error if needed widget can't be found in the <code>widgetTypeMap</code>
+ * @method prepareConfigProperties
+ */
+ prepareConfigProperties: function () {
+ var widgetTypeMap = this.get('widgetTypeMap');
+ var self = this;
+ this.get('content.sectionRows').forEach(function (row) {
+ row.forEach(function (section) {
+ section.get('subsectionRows').forEach(function (subRow) {
+ subRow.forEach(function (subsection) {
+ subsection.set('configs', []);
+ subsection.get('configProperties').forEach(function (config) {
+ var c = App.ConfigProperty.find(config.get('id') + '_' + self.get('controller.selectedVersion'));
+ subsection.get('configs').pushObject(c);
+ var configWidgetType = config.get('widget.type');
+ var widget = widgetTypeMap[configWidgetType];
+ Em.assert('Unknown config widget view for config ' + c.get('id') + ' with type ' + configWidgetType, widget);
+ c.set('widget', widget);
+ });
+ });
+ });
+ });
+ });
+ },
+
+ beforeRender: function () {
+ this.prepareConfigProperties();
+ }
+
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fd5e6e68/ambari-web/app/views/common/configs/widgets/slider_config_widget_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/widgets/slider_config_widget_view.js b/ambari-web/app/views/common/configs/widgets/slider_config_widget_view.js
index 05306f5..f6c44c5 100644
--- a/ambari-web/app/views/common/configs/widgets/slider_config_widget_view.js
+++ b/ambari-web/app/views/common/configs/widgets/slider_config_widget_view.js
@@ -48,6 +48,24 @@ App.SliderConfigWidgetView = App.ConfigWidgetView.extend({
*/
isMirrorValueValid: true,
+ /**
+ * Function used to parse config value (based on <code>config.stackConfigProperty.valueAttributes.type</code>)
+ * For integer - parseInt, for float - parseFloat
+ * @type {Function}
+ */
+ parseFunction: function () {
+ return this.get('config.stackConfigProperty.valueAttributes.type') === 'int' ? parseInt : parseFloat;
+ }.property('config.stackConfigProperty.valueAttributes.type'),
+
+ /**
+ * Function used to validate config value (based on <code>config.stackConfigProperty.valueAttributes.type</code>)
+ * For integer - validator.isValidInt, for float - validator.isValidFloat
+ * @type {Function}
+ */
+ validateFunction: function () {
+ return this.get('config.stackConfigProperty.valueAttributes.type') === 'int' ? validator.isValidInt : validator.isValidFloat;
+ }.property('config.stackConfigProperty.valueAttributes.type'),
+
willInsertElement: function () {
this._super();
this.addObserver('mirrorValue', this, this.mirrorValueObs);
@@ -56,6 +74,7 @@ App.SliderConfigWidgetView = App.ConfigWidgetView.extend({
didInsertElement: function () {
this._super();
this.set('mirrorValue', this.get('config.value'));
+ this.prepareValueAttributes();
this.initSlider();
},
@@ -69,15 +88,15 @@ App.SliderConfigWidgetView = App.ConfigWidgetView.extend({
slider = this.get('slider'),
min = this.get('config.stackConfigProperty.valueAttributes.minimum'),
max = this.get('config.stackConfigProperty.valueAttributes.maximum'),
- validationFunction = this.get('config.stackConfigProperty.valueAttributes.type') == 'int' ? validator.isValidInt : validator.isValidFloat,
- parseFunction = this.get('config.stackConfigProperty.valueAttributes.type') == 'int' ? parseInt : parseFloat;
+ validationFunction = this.get('validateFunction'),
+ parseFunction = this.get('parseFunction');
if (validationFunction(mirrorValue)) {
var parsed = parseFunction(mirrorValue);
if (parsed >= min && parsed <=max) {
this.set('isMirrorValueValid', true);
this.set('config.value', parsed);
if (slider) {
- slider.setValue(this.get('config.value'));
+ slider.setValue(parsed);
}
}
else {
@@ -90,6 +109,19 @@ App.SliderConfigWidgetView = App.ConfigWidgetView.extend({
},
/**
+ * valueAttributes are strings, but should be numbers
+ * parse them using <code>parseFunction</code>
+ * @method prepareValueAttributes
+ */
+ prepareValueAttributes: function () {
+ var valueAttributes = this.get('config.stackConfigProperty.valueAttributes'),
+ parseFunction = this.get('parseFunction');
+ if (!valueAttributes) return;
+ Em.set(valueAttributes, 'maximum', parseFunction(valueAttributes.maximum));
+ Em.set(valueAttributes, 'minimum', parseFunction(valueAttributes.minimum));
+ },
+
+ /**
* Draw slider for current config
* @method initSlider
*/
@@ -97,30 +129,40 @@ App.SliderConfigWidgetView = App.ConfigWidgetView.extend({
var self = this,
config = this.get('config'),
valueAttributes = config.get('stackConfigProperty.valueAttributes'),
- unit = valueAttributes.get('unit'),
+ unit = Em.getWithDefault(valueAttributes, 'unit', ''),
+ parseFunction = this.get('parseFunction'),
ticks = [valueAttributes.minimum],
ticksLabels = [];
+
+ // ticks and labels
for (var i = 1; i <= 3; i++) {
- ticks.push(Math.round((valueAttributes.minimum + valueAttributes.maximum) / 4 * i));
+ var val = (valueAttributes.minimum + valueAttributes.maximum) / 4 * i;
+ // if value's type is float, ticks may be float too
+ ticks.push(valueAttributes.type === 'int' ? Math.round(val) : parseFloat(val.toFixed(1)));
}
ticks.push(valueAttributes.maximum);
- ticks.forEach(function (tick, indx) {
- ticksLabels.push(indx % 2===0 ? tick + ' ' + unit : '');
+ ticks.forEach(function (tick, index) {
+ ticksLabels.push(index % 2 === 0 ? tick + ' ' + unit : '');
});
+
var slider = new Slider('#' + this.get('elementId') + ' input.slider-input', {
- value: this.get('config.value'),
+ value: parseFunction(this.get('config.value')),
ticks: ticks,
tooltip: 'hide',
ticks_labels: ticksLabels,
- ticks_snap_bounds: valueAttributes.get('type') === 'int' ? 1 : 0.1,
- step: valueAttributes.get('type') === 'int' ? 1 : 0.1
+ ticks_snap_bounds: Em.get(valueAttributes, 'type') === 'int' ? 1 : 0.1,
+ step: Em.get(valueAttributes, 'type') === 'int' ? 1 : 0.1
});
- slider.on('slide', function (newValue) {
- self.set('config.value', newValue);
- self.set('mirrorValue', newValue);
+
+ slider.on('change', function (obj) {
+ var val = parseFunction(obj.newValue);
+ self.set('config.value', val);
+ self.set('mirrorValue', val);
});
+
this.set('slider', slider);
- this.$('.slider-tick:first, .slider-tick:last').hide(); // hide some ticks. can't do this via css
+ // hide some ticks. can't do this via css
+ this.$('.slider-tick:first, .slider-tick:last').hide();
},
/**
@@ -130,8 +172,10 @@ App.SliderConfigWidgetView = App.ConfigWidgetView.extend({
*/
restoreValue: function () {
this._super();
- this.get('slider').setValue(this.get('config.value'));
- this.set('mirrorValue', this.get('config.value'));
+ var parseFunction = this.get('parseFunction'),
+ val = parseFunction(this.get('config.value'));
+ this.get('slider').setValue(val);
+ this.set('mirrorValue', val);
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fd5e6e68/ambari-web/test/controllers/main/service/info/config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/info/config_test.js b/ambari-web/test/controllers/main/service/info/config_test.js
index a6785ee..9de9f39 100644
--- a/ambari-web/test/controllers/main/service/info/config_test.js
+++ b/ambari-web/test/controllers/main/service/info/config_test.js
@@ -25,7 +25,11 @@ describe("App.MainServiceInfoConfigsController", function () {
beforeEach(function () {
sinon.stub(App.config, 'loadConfigTheme').returns($.Deferred().resolve().promise());
sinon.stub(App.themesMapper, 'generateAdvancedTabs').returns(Em.K);
- mainServiceInfoConfigsController = App.MainServiceInfoConfigsController.create({});
+ mainServiceInfoConfigsController = App.MainServiceInfoConfigsController.create({
+ loadDependentConfigs: function () {
+ return {done: Em.K}
+ }
+ });
});
afterEach(function() {
@@ -1311,7 +1315,6 @@ describe("App.MainServiceInfoConfigsController", function () {
});
});
-
describe('#calculateDependentFileNames()', function() {
beforeEach(function() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/fd5e6e68/ambari-web/test/views/common/configs/widgets/slider_config_widget_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/configs/widgets/slider_config_widget_view_test.js b/ambari-web/test/views/common/configs/widgets/slider_config_widget_view_test.js
index f34fb8f..b6d9ba6 100644
--- a/ambari-web/test/views/common/configs/widgets/slider_config_widget_view_test.js
+++ b/ambari-web/test/views/common/configs/widgets/slider_config_widget_view_test.js
@@ -28,13 +28,13 @@ describe('App.SliderConfigWidgetView', function () {
config: Em.Object.create({
name: 'a.b.c',
description: 'A B C',
- value: 486,
- defaultValue: 486,
+ value: '486',
+ defaultValue: '486',
stackConfigProperty: Em.Object.create({
valueAttributes: Em.Object.create({
type: 'int',
- minimum: 0,
- maximum: 2096,
+ minimum: '0',
+ maximum: '2096',
unit: 'MB'
})
})
@@ -47,13 +47,13 @@ describe('App.SliderConfigWidgetView', function () {
config: Em.Object.create({
name: 'a.b.c2',
description: 'A B C 2',
- value: 72.2,
- defaultValue: 72.2,
+ value: '72.2',
+ defaultValue: '72.2',
stackConfigProperty: Em.Object.create({
valueAttributes: Em.Object.create({
type: 'float',
- minimum: 0,
- maximum: 100,
+ minimum: '0',
+ maximum: '100',
unit: '%'
})
})
@@ -65,8 +65,8 @@ describe('App.SliderConfigWidgetView', function () {
describe('#mirrorValue', function () {
it('should be equal to config.value after init', function () {
- expect(viewInt.get('mirrorValue')).to.equal(viewInt.get('config.value'));
- expect(viewFloat.get('mirrorValue')).to.equal(viewFloat.get('config.value'));
+ expect(viewInt.get('mirrorValue')).to.equal('' + viewInt.get('config.value'));
+ expect(viewFloat.get('mirrorValue')).to.equal('' + viewFloat.get('config.value'));
});
});
@@ -94,4 +94,32 @@ describe('App.SliderConfigWidgetView', function () {
});
+ describe('#prepareValueAttributes', function () {
+
+ it('should parse string to int', function () {
+
+ var max = viewInt.get('config.stackConfigProperty.valueAttributes.maximum'),
+ min = viewInt.get('config.stackConfigProperty.valueAttributes.minimum');
+ viewInt.set('config.stackConfigProperty.valueAttributes.maximum', '' + max);
+ viewInt.set('config.stackConfigProperty.valueAttributes.minimum', '' + min);
+ viewInt.prepareValueAttributes();
+ expect(viewInt.get('config.stackConfigProperty.valueAttributes.maximum')).to.equal(max);
+ expect(viewInt.get('config.stackConfigProperty.valueAttributes.minimum')).to.equal(min);
+
+ });
+
+ it('should parse string to float', function () {
+
+ var max = viewFloat.get('config.stackConfigProperty.valueAttributes.maximum'),
+ min = viewFloat.get('config.stackConfigProperty.valueAttributes.minimum');
+ viewFloat.set('config.stackConfigProperty.valueAttributes.maximum', '' + max);
+ viewFloat.set('config.stackConfigProperty.valueAttributes.minimum', '' + min);
+ viewFloat.prepareValueAttributes();
+ expect(viewFloat.get('config.stackConfigProperty.valueAttributes.maximum')).to.equal(max);
+ expect(viewFloat.get('config.stackConfigProperty.valueAttributes.minimum')).to.equal(min);
+
+ });
+
+ });
+
});
\ No newline at end of file