You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2018/04/06 23:41:13 UTC

[ambari] branch trunk updated: AMBARI-23501 Fixes for NameNode widgets on dashboard. (ababiichuk)

This is an automated email from the ASF dual-hosted git repository.

ababiichuk pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 66c008b  AMBARI-23501 Fixes for NameNode widgets on dashboard. (ababiichuk)
66c008b is described below

commit 66c008b30f8982f36b9e22dcff816da49b05306c
Author: ababiichuk <ab...@hortonworks.com>
AuthorDate: Fri Apr 6 20:16:39 2018 +0300

    AMBARI-23501 Fixes for NameNode widgets on dashboard. (ababiichuk)
---
 .../main/dashboard/widgets/namenode_widget.js      |   4 +
 ambari-web/app/styles/dashboard.less               |   6 +-
 .../app/templates/main/dashboard/widgets.hbs       |  52 +++--
 ambari-web/app/views/main/dashboard/widget.js      |  19 +-
 ambari-web/app/views/main/dashboard/widgets.js     | 250 ++++++++++++++-------
 .../test/views/main/dashboard/widget_test.js       |   3 +-
 .../test/views/main/dashboard/widgets_test.js      |   2 +-
 7 files changed, 235 insertions(+), 101 deletions(-)

diff --git a/ambari-web/app/mixins/main/dashboard/widgets/namenode_widget.js b/ambari-web/app/mixins/main/dashboard/widgets/namenode_widget.js
index 7b81542..5283634 100644
--- a/ambari-web/app/mixins/main/dashboard/widgets/namenode_widget.js
+++ b/ambari-web/app/mixins/main/dashboard/widgets/namenode_widget.js
@@ -20,8 +20,12 @@ const App = require('app');
 
 App.NameNodeWidgetMixin = Em.Mixin.create({
 
+  groupId: 'nn',
+
   subGroupId: 'default',
 
+  isAllItemsSubGroup: false,
+
   componentGroup: Em.computed.findByKey('model.masterComponentGroups', 'name', 'subGroupId'),
 
   clusterId: Em.computed.alias('componentGroup.clusterId'),
diff --git a/ambari-web/app/styles/dashboard.less b/ambari-web/app/styles/dashboard.less
index b8b38c0..d4920f1 100644
--- a/ambari-web/app/styles/dashboard.less
+++ b/ambari-web/app/styles/dashboard.less
@@ -34,6 +34,9 @@
       float: left;
       width: 100%;
     }
+    .add-widgets-apply-button {
+      margin: 0px 20px 20px 0px;
+    }
   }
   #widgets-options-menu {
     .add-widgets-text.pull-left .dropdown-menu {
@@ -48,9 +51,6 @@
       width: 250px;
       left: -250px;
     }
-    .add-widgets-apply-button {
-      margin: 0px 20px 20px 0px;
-    }
     .nothing-to-add {
       padding: 5px 15px;
     }
diff --git a/ambari-web/app/templates/main/dashboard/widgets.hbs b/ambari-web/app/templates/main/dashboard/widgets.hbs
index a4e74dc..867ac94 100644
--- a/ambari-web/app/templates/main/dashboard/widgets.hbs
+++ b/ambari-web/app/templates/main/dashboard/widgets.hbs
@@ -56,31 +56,49 @@
       {{#if view.displayedWidgetGroups.length}}
         {{#each group in view.displayedWidgetGroups}}
           <div class="dashboard-widget-groups-container">
-            <div class="col-md-12">
-              <h5 class="widgets-group-title">{{group.title}}</h5>
-              {{#if group.subGroups.length}}
-                <div class="btn-group">
-                  <button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
-                    {{#if group.activeSubGroup}}
-                      {{group.activeSubGroup.title}}
-                    {{else}}
-                      {{t common.all}}
-                    {{/if}}
+            <div class="col-md-12 row">
+              <div class="col-md-6">
+                <h5 class="widgets-group-title">{{group.title}}</h5>
+                {{#if group.subGroups.length}}
+                  <div class="btn-group">
+                    <button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+                      {{#if group.activeSubGroup}}
+                        {{group.activeSubGroup.title}}
+                      {{else}}
+                        {{t common.all}}
+                      {{/if}}
+                      <span class="caret"></span>
+                    </button>
+                    <ul class="dropdown-menu">
+                      {{#each item in group.subGroups}}
+                        <li>
+                          <a href="#" {{action setActiveSubGroup group.subGroups item.name target="view"}}>
+                            {{item.title}}
+                          </a>
+                        </li>
+                      {{/each}}
+                    </ul>
+                  </div>
+                {{/if}}
+              </div>
+              <div class="col-md-6">
+                <div class="dropdown btn-group pull-right">
+                  <button class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">
+                    <span>{{t common.add}}</span>
                     <span class="caret"></span>
                   </button>
                   <ul class="dropdown-menu">
-                    {{#each item in group.subGroups}}
-                      <li>
-                        <a href="#" {{action setActiveSubGroup group.subGroups item.name target="view"}}>
-                          {{item.title}}
-                        </a>
+                    {{#each groupLayout in group.allWidgets}}
+                      <li class="dropdown-submenu pull-left">
+                        <a href="#">{{groupLayout.title}}</a>
+                        {{view view.groupWidgetsFilterView hiddenWidgetsBinding="groupLayout.hiddenWidgets"}}
                       </li>
                     {{/each}}
                   </ul>
                 </div>
-              {{/if}}
+              </div>
             </div>
-            <div class="thumbnails">
+            <div class="thumbnails sortable" {{bindAttr id="group.name"}}>
               {{#each groupLayout in group.allWidgets}}
                 {{#if groupLayout.isActive}}
                   {{#each widget in groupLayout.widgets}}
diff --git a/ambari-web/app/views/main/dashboard/widget.js b/ambari-web/app/views/main/dashboard/widget.js
index bb21e1f..efc1239 100644
--- a/ambari-web/app/views/main/dashboard/widget.js
+++ b/ambari-web/app/views/main/dashboard/widget.js
@@ -152,7 +152,7 @@ App.DashboardWidgetView = Em.View.extend({
    * delete widget
    */
   deleteWidget: function () {
-    this.get('parentView').hideWidget(this.get('id'));
+    this.get('parentView').hideWidget(this.get('id'), this.get('groupId'), this.get('subGroupId'), this.get('isAllItemsSubGroup'));
   },
 
   /**
@@ -161,11 +161,22 @@ App.DashboardWidgetView = Em.View.extend({
    * @param {number[]} preparedThresholds
    */
   saveWidgetThresholds(preparedThresholds) {
+    const widgetId = this.get('id');
+    const widgetIdToNumber = Number(widgetId);
     const widgetsView = this.get('widgetsView');
     const userPreferences = widgetsView.get('userPreferences');
-    const widgetId = Number(this.get('id'));
-    userPreferences.threshold[widgetId] = preparedThresholds;
-    this.set('widget.threshold', userPreferences.threshold[widgetId]);
+    const isGroupWidget = isNaN(widgetIdToNumber);
+    if (isGroupWidget) {
+      const parsedWidgetId = parseInt(widgetId);
+      if (this.get('isAllItemsSubGroup')) {
+        userPreferences.groups[this.get('groupId')]['*'].threshold[this.get('subGroupId')][parsedWidgetId] = preparedThresholds;
+      } else {
+        userPreferences.groups[this.get('groupId')][this.get('subGroupId')].threshold[parsedWidgetId] = preparedThresholds;
+      }
+    } else {
+      userPreferences.threshold[widgetIdToNumber] = preparedThresholds;
+      this.set('widget.threshold', userPreferences.threshold[widgetIdToNumber]);
+    }
     widgetsView.saveWidgetsSettings(userPreferences);
   },
 
diff --git a/ambari-web/app/views/main/dashboard/widgets.js b/ambari-web/app/views/main/dashboard/widgets.js
index 0eea55d..a412fbb 100644
--- a/ambari-web/app/views/main/dashboard/widgets.js
+++ b/ambari-web/app/views/main/dashboard/widgets.js
@@ -28,6 +28,26 @@ const WidgetObject = Em.Object.extend({
   isVisible: true
 });
 
+const plusButtonFilterView = Ember.View.extend({
+  tagName: 'ul',
+  classNames: ['dropdown-menu'],
+  templateName: require('templates/main/dashboard/plus_button_filter'),
+  valueBinding: '',
+  widgetCheckbox: App.CheckboxView.extend({
+    didInsertElement: function () {
+      $('.checkbox').click(function (event) {
+        event.stopPropagation();
+      });
+    }
+  }),
+  applyFilter: function () {
+    const parent = this.get('parentView'),
+      hiddenWidgets = this.get('hiddenWidgets');
+    hiddenWidgets.filterProperty('checked').setEach('isVisible', true);
+    parent.saveWidgetsSettings();
+  }
+});
+
 App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App.TimeRangeMixin, {
   name: 'mainDashboardWidgetsView',
   templateName: require('templates/main/dashboard/widgets'),
@@ -156,6 +176,9 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
         this.set('isDataLoaded', true);
         App.loadTimer.finish('Dashboard Metrics Page');
         Em.run.next(this, 'makeSortable');
+        if (this.get('displayedWidgetGroups.length')) {
+          Em.run.next(this, 'makeGroupedWidgetsSortable');
+        }
       });
     });
   },
@@ -186,11 +209,11 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
     }
     else {
       newSettings.threshold = userPreferences.threshold;
+      newSettings.groups = userPreferences.groups;
       this.get('allWidgets').forEach(widget => {
         let key = widget.get('isVisible') ? 'visible' : 'hidden';
         newSettings[key].push(widget.get('id'));
       });
-      //TODO handle grouped widgets
     }
     this.set('userPreferences', newSettings);
     this.setDBProperty(this.get('persistKey'), newSettings);
@@ -241,29 +264,33 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
 
     this.resolveConfigDependencies(widgetsDefinition);
     widgetsDefinition.forEach(widget => {
-      const {sourceName, id} = widget,
+      const {sourceName, id, groupName} = widget,
         widgetGroups = this.get('displayedWidgetGroups');
       if (App.Service.find(sourceName).get('isLoaded') || sourceName === 'HOST_METRICS') {
         const state = widget.isHiddenByDefault ? 'hidden' : 'visible',
           {threshold} = widget,
-          widgetGroup = widgetGroups.findProperty('serviceName', sourceName);
+          widgetGroup = widgetGroups.find(group => {
+            return group.get('serviceName') === sourceName && group.get('name') === groupName;
+          });
         if (widgetGroup) {
           const widgetGroupName = widgetGroup.get('name'),
             allSubGroups = widgetGroup.get('subGroups'),
             subGroupForAllItems = allSubGroups.findProperty('name', '*'),
             subGroups = allSubGroups.rejectProperty('name', '*'),
             existingEntry = preferences.groups[widgetGroupName],
-            currentEntry = existingEntry || this.getWidgetSubGroupsObject(subGroups);
-          if (subGroupForAllItems && !currentEntry['*']) {
-            currentEntry['*'] =this.getWidgetSubGroupsObject(subGroups);
-          }
+            currentEntry = existingEntry || this.getWidgetSubGroupsObject(allSubGroups);
           subGroups.forEach(subGroup => {
             const {name} = subGroup;
             currentEntry[name][state].push(id);
             currentEntry[name].threshold[id] = threshold;
             if (subGroupForAllItems) {
-              currentEntry['*'][name][state].push(id);
-              currentEntry['*'][name].threshold[id] = threshold;
+              currentEntry['*'][state].push({
+                id,
+                subGroup: name
+              });
+              currentEntry['*'].threshold[name] = Object.assign({}, currentEntry['*'].threshold[name], {
+                [id]: threshold
+              });
             }
           });
           if (!existingEntry) {
@@ -281,11 +308,24 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
   /**
    * Don't show widget on the Dashboard
    *
-   * @param {number} id
+   * @param {number|string} id
+   * @param {string} [groupId]
+   * @param {string} [subGroupId]
+   * @param {boolean} [isAllItemsSubGroup]
    */
-  hideWidget(id) {
-    // TODO handle grouped widgets
-    this.get('allWidgets').findProperty('id', id).set('isVisible', false);
+  hideWidget(id, groupId, subGroupId, isAllItemsSubGroup) {
+    const idToNumber = Number(id);
+    if (isNaN(idToNumber)) {
+      const subGroupToFilter = isAllItemsSubGroup ? '*' : subGroupId,
+        groupWidgets = this.get('displayedWidgetGroups').findProperty('name', groupId).get('allWidgets'),
+        subGroupWidgets = groupWidgets && groupWidgets.findProperty('subGroupName', subGroupToFilter).get('widgets'),
+        targetWidget = subGroupWidgets && subGroupWidgets.findProperty('id', id);
+      if (targetWidget) {
+        targetWidget.set('isVisible', false);
+      }
+    } else {
+      this.get('allWidgets').findProperty('id', id).set('isVisible', false);
+    }
     this.saveWidgetsSettings();
   },
 
@@ -325,12 +365,13 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
     const widget = this.get('widgetsDefinitionMap')[id];
     subGroupId = subGroupId || 'default';
     return WidgetObject.create({
-      id: `${id}-${groupId}-${subGroupId}`,
+      id: `${id}-${groupId}-${subGroupId}${isAllSubGroupsDisplay ? '-*' : ''}`,
       threshold: isAllSubGroupsDisplay ?
-        this.get('userPreferences.groups')[groupId]['*'][subGroupId].threshold[id] :
+        this.get('userPreferences.groups')[groupId]['*'].threshold[subGroupId][id] :
         this.get('userPreferences.groups')[groupId][subGroupId].threshold[id],
       viewClass: App[widget.viewName].extend({
-        subGroupId
+        subGroupId,
+        isAllItemsSubGroup: isAllSubGroupsDisplay
       }),
       sourceName: widget.sourceName,
       title: `${widget.title} - ${subGroupId}`,
@@ -338,6 +379,10 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
     });
   },
 
+  findWidgetInAllItemsSubGroup: function (id, subGroup) {
+    return widget => widget.id === id && widget.subGroup === subGroup;
+  },
+
   /**
    * set widgets to view in order to render
    */
@@ -362,9 +407,11 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
               existingSubGroup = allWidgets.findProperty('subGroupName', subGroupName),
               currentSubGroup = existingSubGroup || Em.Object.create({
                   subGroupName,
+                  title: subGroupName,
                   parentGroup: widgetGroup,
                   isActive: Em.computed.equal('parentGroup.activeSubGroup.name', subGroupName),
-                  widgets: []
+                  widgets: [],
+                  hiddenWidgets: Em.computed.filterBy('widgets', 'isVisible', false)
                 }),
               visibleIndex = subGroupPreferences.visible.indexOf(id),
               hiddenIndex = subGroupPreferences.hidden.indexOf(id),
@@ -384,31 +431,34 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
               existingSubGroup = allWidgets.findProperty('subGroupName', '*'),
               currentSubGroup = existingSubGroup || Em.Object.create({
                   subGroupName: '*',
+                  title: Em.I18n.t('common.all'),
                   parentGroup: widgetGroup,
                   isActive: Em.computed.equal('parentGroup.activeSubGroup.name', '*'),
-                  widgets: []
+                  widgets: [],
+                  hiddenWidgets: Em.computed.filterBy('widgets', 'isVisible', false)
                 });
             if (!existingSubGroup) {
               allWidgets.pushObject(currentSubGroup);
             }
-            Object.keys(subGroupPreferences).forEach(key => {
-              const existingWidgetsLength = currentSubGroup.get('widgets.length'),
-                preferences = subGroupPreferences[key],
-                visibleIndex = preferences.visible.indexOf(id),
-                hiddenIndex = preferences.hidden.indexOf(id),
-                visibleCount = preferences.visible.length;
-              let widgets = [];
-              if (visibleIndex > -1) {
-                currentSubGroup.get('widgets')[visibleIndex + existingWidgetsLength] = this._createGroupWidgetObj(id, true, groupName, key, true);
-              }
-              if (hiddenIndex > -1) {
-                currentSubGroup.get('widgets')[hiddenIndex + visibleCount + existingWidgetsLength] = this._createGroupWidgetObj(id, false, groupName, key, true);
-              }
+            const visibleItems = subGroupPreferences.visible.filterProperty('id', id),
+              hiddenItems = subGroupPreferences.hidden.filterProperty('id', id),
+              visibleCount = subGroupPreferences.visible.length;
+            let widgets = [];
+            visibleItems.forEach(widget => {
+              const subgroupName = widget.subGroup,
+                findFunction = this.findWidgetInAllItemsSubGroup(id, subgroupName),
+                index = subGroupPreferences.visible.findIndex(findFunction);
+              currentSubGroup.get('widgets')[index] = this._createGroupWidgetObj(id, true, groupName, subgroupName, true);
+            });
+            hiddenItems.forEach(widget => {
+              const subgroupName = widget.subGroup,
+                findFunction = this.findWidgetInAllItemsSubGroup(id, subgroupName),
+                index = subGroupPreferences.hidden.findIndex(findFunction);
+              currentSubGroup.get('widgets')[index + visibleCount] = this._createGroupWidgetObj(id, false, groupName, subgroupName, true);
             });
           }
           allWidgets.forEach(subGroup => {
             const widgets = subGroup.get('widgets');
-            subGroup.set('widgets', widgets.filter(widget => !Em.isNone(widget)));
           });
         }
       } else {
@@ -439,7 +489,7 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
         visible: userPreferences.visible.slice(0),
         hidden: userPreferences.hidden.slice(0),
         threshold: userPreferences.threshold,
-        groups: userPreferences.groups || {}
+        groups: $.extend(true, {}, userPreferences.groups)
       },
       isChanged = false;
 
@@ -462,7 +512,7 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
                   [subGroupName]: {
                     visible: [],
                     hidden: [],
-                    threshold: {}
+                    threshold: defaultPreferences.groups[groupName][subGroupName].threshold
                   }
                 }
               });
@@ -475,27 +525,28 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
           });
         });
         if (subGroupForAllItems) {
-          Object.keys(subGroupForAllItems).forEach(subGroupName => {
-            subGroupForAllItems[subGroupName][state].forEach(id => {
-              if (!newValue.groups[groupName]['*'] || !newValue.groups[groupName]['*'][subGroupName]) {
-                $.extend(true, newValue.groups, {
-                  [groupName]: {
-                    '*': {
-                      [subGroupName]: {
-                        visible: [],
-                        hidden: [],
-                        threshold: {}
-                      }
-                    }
+          subGroupForAllItems[state].forEach(item => {
+            const {id, subGroup} = item;
+            if (!newValue.groups[groupName]['*']) {
+              $.extend(true, newValue.groups, {
+                [groupName]: {
+                  '*': {
+                    visible: [],
+                    hidden: [],
+                    threshold: defaultPreferences.groups[groupName]['*'].threshold
                   }
-                });
-              }
-              const subGroupPreferences = newValue.groups[groupName]['*'][subGroupName];
-              if (!subGroupPreferences.visible.contains(id) && !subGroupPreferences.hidden.contains(id)) {
-                isChanged = true;
-                subGroupPreferences[state].push(id);
-              }
-            });
+                }
+              });
+            }
+            const preferences = newValue.groups[groupName]['*'],
+              checkFunction = this.findWidgetInAllItemsSubGroup(id, subGroup);
+            if (!preferences.visible.some(checkFunction) && !preferences.hidden.some(checkFunction)) {
+              isChanged = true;
+              preferences[state].push({
+                id,
+                subGroup
+              });
+            }
           });
         }
       });
@@ -531,13 +582,14 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
       tolerance: "pointer",
       scroll: false,
       update: function () {
-        var widgetsArray = $('div[viewid]');
+        var widgetsArray = $('#sortable div[viewid]');
 
         var userPreferences = self.get('userPreferences') || self.getDBProperty(self.get('persistKey'));
         var newValue = {
           visible: [],
           hidden: userPreferences.hidden,
-          threshold: userPreferences.threshold
+          threshold: userPreferences.threshold,
+          groups: userPreferences.groups
         };
         newValue.visible = userPreferences.visible.map((item, index) => {
           var viewID = widgetsArray.get(index).getAttribute('viewid');
@@ -554,32 +606,80 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, App.LocalStorage, App
     }).disableSelection();
   },
 
+  makeGroupedWidgetsSortable: function () {
+    this.get('displayedWidgetGroups').forEach(widgetGroup => {
+      const selector = `#${widgetGroup.get('name')}`;
+      $(selector).sortable({
+        items: '> div',
+        cursor: 'move',
+        tolerance: 'pointer',
+        scroll: false,
+        update: () => {
+          let isSubGroupForAllItems = false;
+          const widgetsArray = $(`${selector} div[viewid]`),
+            userPreferences = this.get('userPreferences') || this.getDBProperty(self.get('persistKey')),
+            currentWidgetsData = widgetsArray.toArray().map(widget => {
+              const viewId = widget.getAttribute('viewid'),
+                splittedViewId = viewId.split('-');
+              if (splittedViewId.length > 4) {
+                isSubGroupForAllItems = true;
+              }
+              return {
+                id: Number(splittedViewId[1]),
+                groupName: splittedViewId[2],
+                subGroupName: splittedViewId.slice(3, isSubGroupForAllItems ?
+                splittedViewId.length - 1 : splittedViewId.length).join('-')
+              };
+            }),
+            {groupName} = currentWidgetsData[0],
+            subGroupName = isSubGroupForAllItems ? '*' : currentWidgetsData[0].subGroupName,
+            groupPreferences = userPreferences.groups[groupName][subGroupName],
+            newSubGroupValue = {
+              visible: groupPreferences.visible.map((item, index) => {
+                const widget = currentWidgetsData[index];
+                if (isSubGroupForAllItems) {
+                  return {
+                    id: widget.id,
+                    subGroup: widget.subGroupName
+                  };
+                } else {
+                  return widget.id;
+                }
+              })
+            },
+            newValue = {
+              visible: userPreferences.visible,
+              hidden: userPreferences.hidden,
+              threshold: userPreferences.threshold,
+              groups: $.extend(true, userPreferences.groups, {
+                [groupName]: {
+                  [subGroupName]: newSubGroupValue
+                }
+              })
+            };
+          this.saveWidgetsSettings(newValue);
+        },
+        activate: () => {
+          this.set('isMoving', true);
+        },
+        deactivate: () => {
+          this.set('isMoving', false);
+        }
+      }).disableSelection();
+    });
+  },
+
   /**
    * Submenu view for New Dashboard style
    * @type {Ember.View}
    * @class
    */
-  plusButtonFilterView: Ember.View.extend({
-    tagName: 'ul',
-    classNames: ['dropdown-menu'],
-    templateName: require('templates/main/dashboard/plus_button_filter'),
-    hiddenWidgetsBinding: 'parentView.hiddenWidgets',
-    valueBinding: '',
-    widgetCheckbox: App.CheckboxView.extend({
-      didInsertElement: function () {
-        $('.checkbox').click(function (event) {
-          event.stopPropagation();
-        });
-      }
-    }),
-    applyFilter: function () {
-      var parent = this.get('parentView'),
-        hiddenWidgets = this.get('hiddenWidgets');
-      hiddenWidgets.filterProperty('checked').setEach('isVisible', true);
-      parent.saveWidgetsSettings();
-    }
+  plusButtonFilterView: plusButtonFilterView.extend({
+    hiddenWidgetsBinding: 'parentView.hiddenWidgets'
   }),
 
+  groupWidgetsFilterView: plusButtonFilterView.extend(),
+
   showAlertsPopup: Em.K,
 
   setActiveSubGroup: function (event) {
diff --git a/ambari-web/test/views/main/dashboard/widget_test.js b/ambari-web/test/views/main/dashboard/widget_test.js
index b45f88d..8a28d19 100644
--- a/ambari-web/test/views/main/dashboard/widget_test.js
+++ b/ambari-web/test/views/main/dashboard/widget_test.js
@@ -141,7 +141,8 @@ describe('App.DashboardWidgetView', function () {
       view.set('parentView.userPreferences', {
         visible: [1],
         hidden: [],
-        threshold: []
+        threshold: [],
+        groups: {}
       });
       view.deleteWidget();
     });
diff --git a/ambari-web/test/views/main/dashboard/widgets_test.js b/ambari-web/test/views/main/dashboard/widgets_test.js
index b1ae67c..ef48ae7 100644
--- a/ambari-web/test/views/main/dashboard/widgets_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets_test.js
@@ -94,7 +94,7 @@ describe('App.MainDashboardWidgetsView', function () {
 
   describe('#saveWidgetsSettings()', function() {
 
-    var userPreferences = {visible: [], hidden: [], threshold: {}};
+    var userPreferences = {visible: [], hidden: [], threshold: {}, groups: {}};
 
     beforeEach(function () {
       sinon.stub(view, 'setDBProperty', Em.K);

-- 
To stop receiving notification emails like this one, please contact
ababiichuk@apache.org.