Repository: ambari Updated Branches: refs/heads/trunk e2ea86f4f -> e0a810734
AMBARI-10254. Provide original config controls in enhanced-configs (alexantonenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e0a81073 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e0a81073 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e0a81073 Branch: refs/heads/trunk Commit: e0a8107346dee966219b71361add0b88bb3404bc Parents: 5f7de77 Author: Alex Antonenko <hiv...@gmail.com> Authored: Fri Mar 27 20:58:08 2015 +0200 Committer: Alex Antonenko <hiv...@gmail.com> Committed: Fri Mar 27 21:51:59 2015 +0200 ---------------------------------------------------------------------- ambari-web/app/mappers/configs/themes_mapper.js | 167 ++++++++++--------- ambari-web/app/models/service_config.js | 2 +- .../configs/widgets/string_config_widget.hbs | 26 --- .../configs/widgets/textfield_config_widget.hbs | 27 +++ ambari-web/app/utils/ajax/ajax.js | 4 +- ambari-web/app/utils/config.js | 6 +- ambari-web/app/views.js | 2 + .../configs/service_config_layout_tab_view.js | 2 +- .../widgets/directory_config_widget_view.js | 5 +- .../widgets/number_config_widget_view.js | 37 ++++ .../widgets/password_config_widget_view.js | 35 ++++ .../widgets/string_config_widget_view.js | 10 +- .../test/mappers/configs/themes_mapper_test.js | 164 +++++++++--------- 13 files changed, 293 insertions(+), 194 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/mappers/configs/themes_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/configs/themes_mapper.js b/ambari-web/app/mappers/configs/themes_mapper.js index 48ee991..7fde958 100644 --- a/ambari-web/app/mappers/configs/themes_mapper.js +++ b/ambari-web/app/mappers/configs/themes_mapper.js @@ -60,87 +60,102 @@ App.themesMapper = App.QuickDataMapper.create({ map: function (json) { var tabs = []; - if (Em.get(json, "artifact_data.Theme.configuration.layouts")) { - var serviceName = Em.get(json, "Artifacts.service_name"); - Em.get(json, "artifact_data.Theme.configuration.layouts").forEach(function(layout) { - - if (layout.tabs) { - layout.tabs.forEach(function(tab) { - var parsedTab = this.parseIt(tab, this.get("tabConfig")); - parsedTab.id = serviceName + "_" + tab.name; - parsedTab.service_name = serviceName; - - if (Em.get(tab, "layout.sections")) { - var sections = []; - Em.get(tab, "layout.sections").forEach(function(section) { - var parsedSection = this.parseIt(section, this.get("sectionConfig")); - parsedSection.tab_id = parsedTab.id; - - if (section.subsections) { - var subSections = []; - section.subsections.forEach(function(subSection) { - var parsedSubSection = this.parseIt(subSection, this.get("subSectionConfig")); - parsedSubSection.section_id = parsedSection.id; - - subSections.push(parsedSubSection); - }, this); - App.store.loadMany(this.get("subSectionModel"), subSections); - parsedSection.sub_sections = subSections.mapProperty("id"); - } - - sections.push(parsedSection); - }, this); - - App.store.loadMany(this.get("sectionModel"), sections); - parsedTab.sections = sections.mapProperty("id"); - } - - tabs.push(parsedTab); - }, this); - } - - }, this); - } - // TODO Foreign key reference below throw some unclear error - /** - * create tie between <code>stackConfigProperty<code> and <code>subSection<code> - */ - if (Em.get(json, "artifact_data.Theme.placement.configs")) { - Em.get(json, "artifact_data.Theme.placement.configs").forEach(function(configLink) { - - var configId = this.getConfigId(configLink); - var subSectionId = configLink["subsection-name"]; - - var subSection = App.SubSection.find(subSectionId); - var configProperty = App.StackConfigProperty.find(configId); - if (configProperty && subSection) { - subSection.get('configProperties').pushObject(configProperty); - configProperty.set('subSection', subSection); - } else { - console.warn('there is no such property: ' + configId + '. Or subsection: ' + subSectionId); - } - }, this); - } + json.items.forEach(function(item) { + this.mapThemeLayouts(item, tabs); + this.mapThemeConfigs(item); + this.mapThemeWidgets(item); + }, this); - /** - * add widget object to <code>stackConfigProperty<code> - */ - if (Em.get(json, "artifact_data.Theme.widgets")) { - Em.get(json, "artifact_data.Theme.widgets").forEach(function(widget) { - var configId = this.getConfigId(widget); - - var configProperty = App.StackConfigProperty.find(configId); - if (configProperty) { - configProperty.set('widget', widget.widget); - } else { - console.warn('there is no such property: ' + configId); - } - }, this); - } App.store.loadMany(this.get("tabModel"), tabs); }, /** + * Bootstrap tab objects and link sections with subsections. + * + * @param {Object} json - json to parse + * @param {Object[]} tabs - tabs list + */ + mapThemeLayouts: function(json, tabs) { + var serviceName = Em.get(json, "ThemeInfo.service_name"); + Em.getWithDefault(json, "ThemeInfo.theme_data.Theme.configuration.layouts", []).forEach(function(layout) { + if (layout.tabs) { + layout.tabs.forEach(function(tab) { + var parsedTab = this.parseIt(tab, this.get("tabConfig")); + parsedTab.id = serviceName + "_" + tab.name; + parsedTab.service_name = serviceName; + + if (Em.get(tab, "layout.sections")) { + var sections = []; + Em.get(tab, "layout.sections").forEach(function(section) { + var parsedSection = this.parseIt(section, this.get("sectionConfig")); + parsedSection.tab_id = parsedTab.id; + + if (section.subsections) { + var subSections = []; + section.subsections.forEach(function(subSection) { + var parsedSubSection = this.parseIt(subSection, this.get("subSectionConfig")); + parsedSubSection.section_id = parsedSection.id; + + subSections.push(parsedSubSection); + }, this); + App.store.loadMany(this.get("subSectionModel"), subSections); + parsedSection.sub_sections = subSections.mapProperty("id"); + } + + sections.push(parsedSection); + }, this); + + App.store.loadMany(this.get("sectionModel"), sections); + parsedTab.sections = sections.mapProperty("id"); + } + + tabs.push(parsedTab); + }, this); + } + + }, this); + }, + + /** + * create tie between <code>stackConfigProperty<code> and <code>subSection<code> + * + * @param {Object} json - json to parse + */ + mapThemeConfigs: function(json) { + Em.getWithDefault(json, "ThemeInfo.theme_data.Theme.placement.configs", []).forEach(function(configLink) { + var configId = this.getConfigId(configLink); + var subSectionId = configLink["subsection-name"]; + var subSection = App.SubSection.find(subSectionId); + var configProperty = App.StackConfigProperty.find(configId); + + if (configProperty && subSection) { + subSection.get('configProperties').pushObject(configProperty); + configProperty.set('subSection', subSection); + } else { + console.warn('there is no such property: ' + configId + '. Or subsection: ' + subSectionId); + } + }, this); + }, + + /** + * add widget object to <code>stackConfigProperty<code> + * + * @param {Object} json - json to parse + */ + mapThemeWidgets: function(json) { + Em.getWithDefault(json, "ThemeInfo.theme_data.Theme.widgets", []).forEach(function(widget) { + var configId = this.getConfigId(widget); + var configProperty = App.StackConfigProperty.find(configId); + + if (configProperty) { + configProperty.set('widget', widget.widget); + } else { + console.warn('there is no such property: ' + configId); + } + }, this); + }, + + /** * transform info from json to config id * @param {Object} json * @returns {string|null} http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/models/service_config.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/service_config.js b/ambari-web/app/models/service_config.js index 8f4889f..1966d12 100644 --- a/ambari-web/app/models/service_config.js +++ b/ambari-web/app/models/service_config.js @@ -1079,7 +1079,7 @@ App.ServiceConfigProperty = Em.Object.extend({ } else { this.set('warn', true); } - + if (!isError) { this.set('errorMessage', ''); this.set('error', false); http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/templates/common/configs/widgets/string_config_widget.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/configs/widgets/string_config_widget.hbs b/ambari-web/app/templates/common/configs/widgets/string_config_widget.hbs deleted file mode 100644 index bdb1992..0000000 --- a/ambari-web/app/templates/common/configs/widgets/string_config_widget.hbs +++ /dev/null @@ -1,26 +0,0 @@ -{{! -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -}} - -<div class="pull-left"> - <p class="widget-config-label">{{view.configLabel}}</p> - {{view view.configView}} -</div> -{{view App.RestoreConfigView}} -{{#if view.configErrorMessage}} - <p class="text-error">{{view.configErrorMessage}}</p> -{{/if}} http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/templates/common/configs/widgets/textfield_config_widget.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/configs/widgets/textfield_config_widget.hbs b/ambari-web/app/templates/common/configs/widgets/textfield_config_widget.hbs new file mode 100644 index 0000000..4bd5c20 --- /dev/null +++ b/ambari-web/app/templates/common/configs/widgets/textfield_config_widget.hbs @@ -0,0 +1,27 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +<div class="pull-left"> + <p class="widget-config-label">{{view.configLabel}}</p> + {{view view.configView}} +</div> +{{view App.RestoreConfigView}} +<div class="clearfix"></div> +{{#if view.configErrorMessage}} + <p class="text-error">{{view.configErrorMessage}}</p> +{{/if}} http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/utils/ajax/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js index adc2ed7..1118d37 100644 --- a/ambari-web/app/utils/ajax/ajax.js +++ b/ambari-web/app/utils/ajax/ajax.js @@ -606,12 +606,12 @@ var urls = { /*************************CONFIG THEME****************************************/ 'configs.theme': { - 'real': '{stackVersionUrl}/services/{serviceName}/artifacts/theme', + 'real': '{stackVersionUrl}/services/{serviceName}/themes?ThemeInfo/default=true&fields=*', 'mock': '/data/configurations/theme.json' }, 'configs.theme.services': { - 'real': '{stackVersionUrl}/services?StackServices/service_name.in({serviceNames})&artifacts/Artifacts/artifact_name=theme&fields=artifacts/*', + 'real': '{stackVersionUrl}/services?StackServices/service_name.in({serviceNames})&themes/ThemeInfo/default=true&fields=themes/*', 'mock': '/data/configurations/theme_services.json' }, http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/utils/config.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js index 2b6769c..0ad7de4 100644 --- a/ambari-web/app/utils/config.js +++ b/ambari-web/app/utils/config.js @@ -1674,8 +1674,10 @@ App.config = Em.Object.create({ loadConfigThemeForServicesSuccess: function(data) { if (!data.items.length) return; - data.items.mapProperty('artifacts.firstObject').forEach(function(item) { - App.themesMapper.map(item); + App.themesMapper.map({ + items: data.items.mapProperty('themes').reduce(function(p,c) { + return p.concat(c); + }) }); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/views.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js index cb121ec..472d2a5 100644 --- a/ambari-web/app/views.js +++ b/ambari-web/app/views.js @@ -56,6 +56,8 @@ require('views/common/configs/widgets/config_widget_view'); require('views/common/configs/widgets/checkbox_config_widget_view'); require('views/common/configs/widgets/directory_config_widget_view'); require('views/common/configs/widgets/combo_config_widget_view'); +require('views/common/configs/widgets/number_config_widget_view'); +require('views/common/configs/widgets/password_config_widget_view'); require('views/common/configs/widgets/list_config_widget_view'); require('views/common/configs/widgets/slider_config_widget_view'); require('views/common/configs/widgets/string_config_widget_view'); http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/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 5f11f44f..e1fbb4e 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 @@ -51,7 +51,7 @@ App.ServiceConfigLayoutTabView = Em.View.extend(App.ConfigOverridable, { prepareConfigProperties: function () { var widgetTypeMap = this.get('widgetTypeMap'); var self = this; - var serviceName = self.get('controller.content.serviceName'); + var serviceName = self.get('controller.selectedService.serviceName'); this.get('content.sectionRows').forEach(function (row) { row.forEach(function (section) { section.get('subsectionRows').forEach(function (subRow) { http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/views/common/configs/widgets/directory_config_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/configs/widgets/directory_config_widget_view.js b/ambari-web/app/views/common/configs/widgets/directory_config_widget_view.js index 4701960..8d562f5 100644 --- a/ambari-web/app/views/common/configs/widgets/directory_config_widget_view.js +++ b/ambari-web/app/views/common/configs/widgets/directory_config_widget_view.js @@ -21,7 +21,7 @@ require('views/common/controls_view'); var App = require('app'); App.DirectoryConfigWidgetView = App.ConfigWidgetView.extend({ - templateName: require('templates/common/configs/widgets/directory_config_widget'), + templateName: require('templates/common/configs/widgets/textfield_config_widget'), classNames: ['widget-config', 'directory-widget'], /** @@ -37,8 +37,7 @@ App.DirectoryConfigWidgetView = App.ConfigWidgetView.extend({ }), didInsertElement: function() { - this.set('config.displayType', 'directories'); + this.set('config.displayType', this.get('config.stackConfigProperty.widget.type')); } - }); http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/views/common/configs/widgets/number_config_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/configs/widgets/number_config_widget_view.js b/ambari-web/app/views/common/configs/widgets/number_config_widget_view.js new file mode 100644 index 0000000..abe87c7 --- /dev/null +++ b/ambari-web/app/views/common/configs/widgets/number_config_widget_view.js @@ -0,0 +1,37 @@ +/** + * 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. + */ + +require('views/common/controls_view'); + +var App = require('app'); + +App.NumberConfigWidgetView = App.ConfigWidgetView.extend({ + templateName: require('templates/common/configs/widgets/textfield_config_widget'), + classNames: ['widget', 'number-widget'], + + configView: App.ServiceConfigTextField.extend({ + popoverPlacement: 'top', + serviceConfigBinding: 'parentView.config', + focusIn: function() {} + }), + + didInsertElement: function() { + this.set('config.displayType', this.get('config.stackConfigProperty.widget.type')); + } + +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/views/common/configs/widgets/password_config_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/configs/widgets/password_config_widget_view.js b/ambari-web/app/views/common/configs/widgets/password_config_widget_view.js new file mode 100644 index 0000000..d33cd13 --- /dev/null +++ b/ambari-web/app/views/common/configs/widgets/password_config_widget_view.js @@ -0,0 +1,35 @@ +/** + * 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. + */ + +require('views/common/controls_view'); + +var App = require('app'); + +App.PasswordConfigWidgetView = App.ConfigWidgetView.extend({ + templateName: require('templates/common/configs/widgets/textfield_config_widget'), + classNames: ['widget-config', 'password-widget'], + + configView: App.ServiceConfigPasswordField.extend({ + serviceConfigBinding: 'parentView.config', + popoverPlacement: 'top' + }), + + didInsertElement: function() { + this.set('config.displayType', this.get('config.stackConfigProperty.widget.type')); + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/app/views/common/configs/widgets/string_config_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/configs/widgets/string_config_widget_view.js b/ambari-web/app/views/common/configs/widgets/string_config_widget_view.js index adf014e..69c0c18 100644 --- a/ambari-web/app/views/common/configs/widgets/string_config_widget_view.js +++ b/ambari-web/app/views/common/configs/widgets/string_config_widget_view.js @@ -21,8 +21,8 @@ require('views/common/controls_view'); var App = require('app'); App.StringConfigWidgetView = App.ConfigWidgetView.extend({ - templateName: require('templates/common/configs/widgets/string_config_widget'), - classNames: ['widget-config', 'string-widget'], + templateName: require('templates/common/configs/widgets/textfield_config_widget'), + classNames: ['widget', 'string-widget'], /** * Control to edit value. @@ -34,5 +34,9 @@ App.StringConfigWidgetView = App.ConfigWidgetView.extend({ widthClass: 'span12', serviceConfigBinding: 'parentView.config', popoverPlacement: 'top' - }) + }), + + didInsertElement: function() { + this.set('config.displayType', this.get('config.stackConfigProperty.widget.type')); + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/e0a81073/ambari-web/test/mappers/configs/themes_mapper_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mappers/configs/themes_mapper_test.js b/ambari-web/test/mappers/configs/themes_mapper_test.js index 1dc901a..abe7751 100644 --- a/ambari-web/test/mappers/configs/themes_mapper_test.js +++ b/ambari-web/test/mappers/configs/themes_mapper_test.js @@ -40,101 +40,105 @@ describe('App.themeMapper', function () { describe("#map", function () { var json = { - "Artifacts": { - "service_name": "HDFS" - }, - "artifact_data": { - "Theme": { - "name": "default", - "description": "Default theme for HDFS service", - "configuration": { - "layouts": [ - { + items: [ + { + ThemeInfo: { + service_name: "HDFS", + theme_data: { + "Theme": { "name": "default", - "tabs": [ + "description": "Default theme for HDFS service", + "configuration": { + "layouts": [ + { + "name": "default", + "tabs": [ + { + "name": "settings", + "display-name": "Settings", + "layout": { + "tab-columns": "2", + "tab-rows": "1", + "sections": [ + { + "name": "Section-1", + "display-name": "Section One", + "row-index": "0", + "column-index": "0", + "row-span": "1", + "column-span": "1", + "section-columns": "2", + "section-rows": "3", + "subsections": [ + { + "name": "subsection1", + "display-name": "Storage", + "border": "false", + "row-index": "0", + "column-index": "0", + "column-span": "1", + "row-span": "1" + } + ] + }, + { + "name": "Section-2", + "display-name": "Section Two", + "row-index": "0", + "column-index": "1" + } + ] + } + } + ] + } + ], + }, + "widgets": [ { - "name": "settings", - "display-name": "Settings", - "layout": { - "tab-columns": "2", - "tab-rows": "1", - "sections": [ + "config": "c1/p1", + "widget": { + "type": "slider", + "units": [ { - "name": "Section-1", - "display-name": "Section One", - "row-index": "0", - "column-index": "0", - "row-span": "1", - "column-span": "1", - "section-columns": "2", - "section-rows": "3", - "subsections": [ - { - "name": "subsection1", - "display-name": "Storage", - "border": "false", - "row-index": "0", - "column-index": "0", - "column-span": "1", - "row-span": "1" - } - ] + "unit-name": "MB" }, { - "name": "Section-2", - "display-name": "Section Two", - "row-index": "0", - "column-index": "1" + "unit-name": "GB" } ] } - } - ] - } - ], - }, - "widgets": [ - { - "config": "c1/p1", - "widget": { - "type": "slider", - "units": [ - { - "unit-name": "MB" }, { - "unit-name": "GB" - } - ] - } - }, - { - "config": "c1/p2", - "widget": { - "type": "slider", - "units": [ - { - "unit-name": "percent" + "config": "c1/p2", + "widget": { + "type": "slider", + "units": [ + { + "unit-name": "percent" + } + ] + } } - ] + ], + "placement": { + "configuration-layout": "default", + "configs": [ + { + "config": "c1/p1", + "subsection-name": "subsection1" + }, + { + "config": "c1/p2", + "subsection-name": "subsection1" + } + ] + } } } - ], - "placement": { - "configuration-layout": "default", - "configs": [ - { - "config": "c1/p1", - "subsection-name": "subsection1" - }, - { - "config": "c1/p2", - "subsection-name": "subsection1" - } - ] } } - } + ] }; it('should map theme data', function () {