ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From alexantone...@apache.org
Subject [1/5] ambari git commit: AMBARI-10254. Provide original config controls in enhanced-configs (alexantonenko)
Date Fri, 27 Mar 2015 19:52:05 GMT
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 <hiveww@gmail.com>
Authored: Fri Mar 27 20:58:08 2015 +0200
Committer: Alex Antonenko <hiveww@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 () {


Mime
View raw message