Browse Source

HUE-9114 [frontend] Show sidebar user and help sub menus on hover

Johan Ahlen 5 years ago
parent
commit
79bbcbc562

+ 143 - 108
desktop/core/src/desktop/js/ko/components/__snapshots__/ko.sidebar.test.js.snap

@@ -9,35 +9,51 @@ exports[`ko.sidebar.js should render component 1`] = `
     <div class=\\"icon\\" data-bind=\\"hueAppIcon: icon\\"></div><span data-bind=\\"text: displayName\\"></span>
     <!-- /ko -->
   </script><script type=\\"text/html\\" id=\\"sidebar-sub-menu\\">
-    <div class=\\"sidebar-menu\\" data-bind=\\"css: { 'open' : open }\\">
-      <div class=\\"menu\\">
-        <ul class=\\"sidebar-nav-list\\" data-bind=\\"foreach: children\\">
-          <li data-bind=\\"css: { 'divider': isDivider }\\">
-            <!-- ko if: isDivider -->
-              &nbsp;
-            <!-- /ko -->
-            <!-- ko ifnot: isDivider -->
-              <!-- ko if: children && children.length -->
-                <a href=\\"javascript:void(0);\\" data-bind=\\"toggle: open, text: displayName\\"></a>
-                <!-- ko template: { name: 'sidebar-sub-menu' } --><!-- /ko -->
-              <!-- /ko -->
-              <!-- ko if: !children && url -->
-                <a href=\\"javascript:void(0);\\" data-bind=\\"hueLink: url, text: displayName\\"></a>
+    <div class=\\"sidebar-menu\\" data-bind=\\"
+        css: {
+          'open' : open() || hoverOpen(),
+          'fixed-bottom': fixedBottom
+        },
+        event: {
+          mouseenter: mouseEnter
+        }
+      \\">
+      <div class=\\"inner\\">
+        <div class=\\"menu\\">
+          <!-- ko if: headerTemplate -->
+          <div class=\\"menu-header\\" data-bind=\\"template: headerTemplate\\"></div>
+          <!-- /ko -->
+
+          <ul class=\\"sidebar-nav-list\\" data-bind=\\"foreach: children\\">
+            <li data-bind=\\"css: { 'divider': isDivider }\\">
+              <!-- ko if: isDivider -->
+                &nbsp;
               <!-- /ko -->
-              <!-- ko if: !children && href -->
-                <a href=\\"javascript:void(0);\\" target=\\"_blank\\" data-bind=\\"attr: { 'href': href }, text: displayName\\"></a>
+              <!-- ko ifnot: isDivider -->
+                <!-- ko if: children && children.length -->
+                  <a href=\\"javascript:void(0);\\" data-bind=\\"toggle: open, text: displayName\\"></a>
+                  <!-- ko template: { name: 'sidebar-sub-menu' } --><!-- /ko -->
+                <!-- /ko -->
+                <!-- ko if: !children && url -->
+                  <a href=\\"javascript:void(0);\\" data-bind=\\"hueLink: url, text: displayName\\"></a>
+                <!-- /ko -->
+                <!-- ko if: !children && href -->
+                  <a href=\\"javascript:void(0);\\" target=\\"_blank\\" data-bind=\\"attr: { 'href': href }, text: displayName\\"></a>
+                <!-- /ko -->
+                <!-- ko if: !children && click -->
+                  <a href=\\"javascript:void(0);\\" target=\\"_blank\\" data-bind=\\"click: click.bind($data), text: displayName\\"></a>
+                <!-- /ko -->
               <!-- /ko -->
-            <!-- /ko -->
-          </li>
-        </ul>
+            </li>
+          </ul>
+        </div>
       </div>
     </div>
   </script><script type=\\"text/html\\" id=\\"sidebar-item\\">
-    <div class=\\"item-wrapper\\" data-bind=\\"css: itemClass\\">
+    <div class=\\"item-wrapper\\" data-bind=\\"css: itemClass, event: { mouseenter: mouseEnter, mouseleave: mouseLeave }\\">
       <!-- ko if: children && children.length -->
         <a href=\\"javascript: void(0);\\" data-bind=\\"
             toggle: open,
-            attr: { 'aria-label': displayName, 'data-tooltip': displayName },
             css: { 'active': active },
             template: 'sidebar-inner-item'
           \\" class=\\"item\\"></a>
@@ -61,46 +77,12 @@ exports[`ko.sidebar.js should render component 1`] = `
               template: 'sidebar-inner-item'
             \\" class=\\"item\\"></a>
         <!-- /ko -->
-        <!-- ko if: subMenuTemplate -->
-        <!-- ko template: subMenuTemplate --><!-- /ko -->
-        <!-- /ko -->
       <!-- /ko -->
     </div>
-  </script><script type=\\"text/html\\" id=\\"user-sub-menu-template\\">
-    <div class=\\"sidebar-menu user-menu\\" data-bind=\\"css: { 'open' : $component.userMenuOpen }\\">
-      <div class=\\"menu\\">
-        <div class=\\"menu-header\\">
-          <div class=\\"user-icon\\" style=\\"background-color: #fff\\">F</div>
-          <div>
-            <div>foo</div>
-          </div>
-        </div>
-        <ul class=\\"sidebar-nav-list\\">
-          <!-- ko if: window.USER_VIEW_EDIT_USER_ENABLED -->
-          <li><a href=\\"javascript:void(0);\\" data-bind=\\"
-              hueLink: '/useradmin/users/edit/foo',
-              attr: {
-                'title': window.IS_LDAP_SETUP ? 'View Profile' : 'Edit Profile'
-              }
-            \\">My Profile</a></li>
-          <!-- /ko -->
-          <!-- ko if: window.USER_IS_ADMIN || window.USER_IS_ORG_ADMIN -->
-          <li><a href=\\"javascript: void(0);\\" data-bind=\\"hueLink: '/useradmin/users/'\\">Manage Users</a></li>
-          <li><a href=\\"javascript: void(0);\\" data-bind=\\"hueLink: '/about/'\\">Administration</a></li>
-          <!-- /ko -->
-          <li><a href=\\"javascript: void(0);\\" data-bind=\\"hueLink: '/accounts/logout'\\" title=\\"Sign out\\" >Sign out</a></li>
-        </ul>
-      </div>
-    </div>
-  </script><script type=\\"text/html\\" id=\\"support-sub-menu-template\\">
-    <div class=\\"sidebar-menu support-menu\\" data-bind=\\"css: { 'open' : $component.supportMenuOpen }\\">
-      <div class=\\"menu\\">
-        <ul class=\\"sidebar-nav-list\\">
-          <li><a href=\\"https://docs.gethue.com\\" target=\\"_blank\\">Documentation</a></li>
-          <li><a href=\\"javascript:void(0)\\" data-bind=\\"publish: 'show.welcome.tour'\\">Welcome Tour</a></li>
-          <li><a href=\\"http://gethue.com\\" target=\\"_blank\\">Gethue.com</a></li>
-        </ul>
-      </div>
+  </script><script type=\\"text/html\\" id=\\"user-header-template\\">
+    <div class=\\"user-icon\\" style=\\"background-color: #fff\\">F</div>
+    <div>
+      <div>foo</div>
     </div>
   </script><div class=\\"hue-sidebar-header\\" data-bind=\\"css: { 'hue-sidebar-custom-logo' : window.CUSTOM_LOGO }\\">
     <a data-bind=\\"hueLink: '/home/'\\" href=\\"javascript: void(0);\\" title=\\"Documents\\">
@@ -111,78 +93,131 @@ exports[`ko.sidebar.js should render component 1`] = `
   </div><div class=\\"hue-sidebar-footer\\">
     <!-- ko foreach: footerItems -->
     <!-- ko template: { name: 'sidebar-item' } -->
-    <div class=\\"item-wrapper\\" data-bind=\\"css: itemClass\\">
-      <!-- ko if: children && children.length --><!-- /ko -->
-      <!-- ko if: !children || !children.length -->
-        <!-- ko if: click -->
-          <a href=\\"javascript: void(0);\\" data-bind=\\"
-              click: click,
-              attr: { 'aria-label': displayName, 'data-tooltip': displayName },
-              css: { 'active': active },
-              template: 'sidebar-inner-item'
-            \\" class=\\"item\\" aria-label=\\"Support\\" data-tooltip=\\"Support\\">
+    <div class=\\"item-wrapper\\" data-bind=\\"css: itemClass, event: { mouseenter: mouseEnter, mouseleave: mouseLeave }\\">
+      <!-- ko if: children && children.length -->
+        <a href=\\"javascript: void(0);\\" data-bind=\\"
+            toggle: open,
+            css: { 'active': active },
+            template: 'sidebar-inner-item'
+          \\" class=\\"item\\">
     <!-- ko if: iconHtml --><!-- /ko -->
     <!-- ko ifnot: iconHtml -->
     <div class=\\"icon\\" data-bind=\\"hueAppIcon: icon\\"></div><span data-bind=\\"text: displayName\\">Support</span>
     <!-- /ko -->
   </a>
-        <!-- /ko -->
-        <!-- ko ifnot: click --><!-- /ko -->
-        <!-- ko if: subMenuTemplate -->
-        <!-- ko template: subMenuTemplate -->
-    <div class=\\"sidebar-menu support-menu\\" data-bind=\\"css: { 'open' : $component.supportMenuOpen }\\">
-      <div class=\\"menu\\">
-        <ul class=\\"sidebar-nav-list\\">
-          <li><a href=\\"https://docs.gethue.com\\" target=\\"_blank\\">Documentation</a></li>
-          <li><a href=\\"javascript:void(0)\\" data-bind=\\"publish: 'show.welcome.tour'\\">Welcome Tour</a></li>
-          <li><a href=\\"http://gethue.com\\" target=\\"_blank\\">Gethue.com</a></li>
-        </ul>
+          <!-- ko template: 'sidebar-sub-menu' -->
+    <div class=\\"sidebar-menu fixed-bottom\\" data-bind=\\"
+        css: {
+          'open' : open() || hoverOpen(),
+          'fixed-bottom': fixedBottom
+        },
+        event: {
+          mouseenter: mouseEnter
+        }
+      \\">
+      <div class=\\"inner\\">
+        <div class=\\"menu\\">
+          <!-- ko if: headerTemplate --><!-- /ko -->
+
+          <ul class=\\"sidebar-nav-list\\" data-bind=\\"foreach: children\\">
+            <li data-bind=\\"css: { 'divider': isDivider }\\">
+              <!-- ko if: isDivider --><!-- /ko -->
+              <!-- ko ifnot: isDivider -->
+                <!-- ko if: children && children.length --><!-- /ko -->
+                <!-- ko if: !children && url --><!-- /ko -->
+                <!-- ko if: !children && href -->
+                  <a href=\\"https://docs.gethue.com\\" target=\\"_blank\\" data-bind=\\"attr: { 'href': href }, text: displayName\\">Documentation</a>
+                <!-- /ko -->
+                <!-- ko if: !children && click --><!-- /ko -->
+              <!-- /ko -->
+            </li>
+          
+            <li data-bind=\\"css: { 'divider': isDivider }\\">
+              <!-- ko if: isDivider --><!-- /ko -->
+              <!-- ko ifnot: isDivider -->
+                <!-- ko if: children && children.length --><!-- /ko -->
+                <!-- ko if: !children && url --><!-- /ko -->
+                <!-- ko if: !children && href --><!-- /ko -->
+                <!-- ko if: !children && click -->
+                  <a href=\\"javascript:void(0);\\" target=\\"_blank\\" data-bind=\\"click: click.bind($data), text: displayName\\">Welcome Tour</a>
+                <!-- /ko -->
+              <!-- /ko -->
+            </li>
+          
+            <li data-bind=\\"css: { 'divider': isDivider }\\">
+              <!-- ko if: isDivider --><!-- /ko -->
+              <!-- ko ifnot: isDivider -->
+                <!-- ko if: children && children.length --><!-- /ko -->
+                <!-- ko if: !children && url --><!-- /ko -->
+                <!-- ko if: !children && href -->
+                  <a href=\\"https://gethue.com\\" target=\\"_blank\\" data-bind=\\"attr: { 'href': href }, text: displayName\\">Gethue.com</a>
+                <!-- /ko -->
+                <!-- ko if: !children && click --><!-- /ko -->
+              <!-- /ko -->
+            </li>
+          </ul>
+        </div>
       </div>
     </div>
   <!-- /ko -->
-        <!-- /ko -->
       <!-- /ko -->
+      <!-- ko if: !children || !children.length --><!-- /ko -->
     </div>
   <!-- /ko -->
     
     <!-- ko template: { name: 'sidebar-item' } -->
-    <div class=\\"item-wrapper shepherd-user-menu\\" data-bind=\\"css: itemClass\\">
-      <!-- ko if: children && children.length --><!-- /ko -->
-      <!-- ko if: !children || !children.length -->
-        <!-- ko if: click -->
-          <a href=\\"javascript: void(0);\\" data-bind=\\"
-              click: click,
-              attr: { 'aria-label': displayName, 'data-tooltip': displayName },
-              css: { 'active': active },
-              template: 'sidebar-inner-item'
-            \\" class=\\"item\\" aria-label=\\"foo\\" data-tooltip=\\"foo\\">
+    <div class=\\"item-wrapper shepherd-user-menu\\" data-bind=\\"css: itemClass, event: { mouseenter: mouseEnter, mouseleave: mouseLeave }\\">
+      <!-- ko if: children && children.length -->
+        <a href=\\"javascript: void(0);\\" data-bind=\\"
+            toggle: open,
+            css: { 'active': active },
+            template: 'sidebar-inner-item'
+          \\" class=\\"item\\">
     <!-- ko if: iconHtml -->
     <div class=\\"icon\\" data-bind=\\"html: iconHtml\\"><div class=\\"user-icon\\">F</div></div><span data-bind=\\"text: displayName\\">foo</span>
     <!-- /ko -->
     <!-- ko ifnot: iconHtml --><!-- /ko -->
   </a>
-        <!-- /ko -->
-        <!-- ko ifnot: click --><!-- /ko -->
-        <!-- ko if: subMenuTemplate -->
-        <!-- ko template: subMenuTemplate -->
-    <div class=\\"sidebar-menu user-menu\\" data-bind=\\"css: { 'open' : $component.userMenuOpen }\\">
-      <div class=\\"menu\\">
-        <div class=\\"menu-header\\">
-          <div class=\\"user-icon\\" style=\\"background-color: #fff\\">F</div>
-          <div>
-            <div>foo</div>
-          </div>
+          <!-- ko template: 'sidebar-sub-menu' -->
+    <div class=\\"sidebar-menu fixed-bottom\\" data-bind=\\"
+        css: {
+          'open' : open() || hoverOpen(),
+          'fixed-bottom': fixedBottom
+        },
+        event: {
+          mouseenter: mouseEnter
+        }
+      \\">
+      <div class=\\"inner\\">
+        <div class=\\"menu\\">
+          <!-- ko if: headerTemplate -->
+          <div class=\\"menu-header\\" data-bind=\\"template: headerTemplate\\">
+    <div class=\\"user-icon\\" style=\\"background-color: #fff\\">F</div>
+    <div>
+      <div>foo</div>
+    </div>
+  </div>
+          <!-- /ko -->
+
+          <ul class=\\"sidebar-nav-list\\" data-bind=\\"foreach: children\\">
+            <li data-bind=\\"css: { 'divider': isDivider }\\">
+              <!-- ko if: isDivider --><!-- /ko -->
+              <!-- ko ifnot: isDivider -->
+                <!-- ko if: children && children.length --><!-- /ko -->
+                <!-- ko if: !children && url -->
+                  <a href=\\"javascript:void(0);\\" data-bind=\\"hueLink: url, text: displayName\\">Sign out</a>
+                <!-- /ko -->
+                <!-- ko if: !children && href --><!-- /ko -->
+                <!-- ko if: !children && click --><!-- /ko -->
+              <!-- /ko -->
+            </li>
+          </ul>
         </div>
-        <ul class=\\"sidebar-nav-list\\">
-          <!-- ko if: window.USER_VIEW_EDIT_USER_ENABLED --><!-- /ko -->
-          <!-- ko if: window.USER_IS_ADMIN || window.USER_IS_ORG_ADMIN --><!-- /ko -->
-          <li><a href=\\"javascript: void(0);\\" data-bind=\\"hueLink: '/accounts/logout'\\" title=\\"Sign out\\">Sign out</a></li>
-        </ul>
       </div>
     </div>
   <!-- /ko -->
-        <!-- /ko -->
       <!-- /ko -->
+      <!-- ko if: !children || !children.length --><!-- /ko -->
     </div>
   <!-- /ko -->
     <!-- /ko -->

+ 64 - 56
desktop/core/src/desktop/js/ko/components/ko.sidebar.js

@@ -39,9 +39,21 @@ const TEMPLATE = `
   </script>
 
   <script type="text/html" id="sidebar-sub-menu">
-    <div class="sidebar-menu" data-bind="css: { 'open' : open() || hoverOpen() }, event: { mouseenter: mouseEnter  }">
+    <div class="sidebar-menu" data-bind="
+        css: {
+          'open' : open() || hoverOpen(),
+          'fixed-bottom': fixedBottom
+        },
+        event: {
+          mouseenter: mouseEnter
+        }
+      ">
       <div class="inner">
         <div class="menu">
+          <!-- ko if: headerTemplate -->
+          <div class="menu-header" data-bind="template: headerTemplate"></div>
+          <!-- /ko -->
+
           <ul class="sidebar-nav-list" data-bind="foreach: children">
             <li data-bind="css: { 'divider': isDivider }">
               <!-- ko if: isDivider -->
@@ -58,6 +70,9 @@ const TEMPLATE = `
                 <!-- ko if: !children && href -->
                   <a href="javascript:void(0);" target="_blank" data-bind="attr: { 'href': href }, text: displayName"></a>
                 <!-- /ko -->
+                <!-- ko if: !children && click -->
+                  <a href="javascript:void(0);" target="_blank" data-bind="click: click.bind($data), text: displayName"></a>
+                <!-- /ko -->
               <!-- /ko -->
             </li>
           </ul>
@@ -71,7 +86,6 @@ const TEMPLATE = `
       <!-- ko if: children && children.length -->
         <a href="javascript: void(0);" data-bind="
             toggle: open,
-            attr: { 'aria-label': displayName, 'data-tooltip': displayName },
             css: { 'active': active },
             template: 'sidebar-inner-item'
           " class="item"></a>
@@ -95,58 +109,14 @@ const TEMPLATE = `
               template: 'sidebar-inner-item'
             " class="item"></a>
         <!-- /ko -->
-        <!-- ko if: subMenuTemplate -->
-        <!-- ko template: subMenuTemplate --><!-- /ko -->
-        <!-- /ko -->
       <!-- /ko -->
     </div>
   </script>
 
-  <script type="text/html" id="user-sub-menu-template">
-    <div class="sidebar-menu user-menu" data-bind="css: { 'open' : $component.userMenuOpen }">
-      <div class="menu">
-        <div class="menu-header">
-          <div class="user-icon" style="background-color: #fff">${window.LOGGED_USERNAME[0].toUpperCase()}</div>
-          <div>
-            <div>${window.LOGGED_USERNAME}</div>
-          </div>
-        </div>
-        <ul class="sidebar-nav-list">
-          <!-- ko if: window.USER_VIEW_EDIT_USER_ENABLED -->
-          <li><a href="javascript:void(0);" data-bind="
-              hueLink: '/useradmin/users/edit/${window.LOGGED_USERNAME}',
-              attr: {
-                'title': window.IS_LDAP_SETUP ? '${I18n('View Profile')}' : '${I18n('Edit Profile')}'
-              }
-            ">${I18n('My Profile')}</a></li>
-          <!-- /ko -->
-          <!-- ko if: window.USER_IS_ADMIN || window.USER_IS_ORG_ADMIN -->
-          <li><a href="javascript: void(0);" data-bind="hueLink: '/useradmin/users/'">${I18n(
-            'Manage Users'
-          )}</a></li>
-          <li><a href="javascript: void(0);" data-bind="hueLink: '/about/'">${I18n(
-            'Administration'
-          )}</a></li>
-          <!-- /ko -->
-          <li><a href="javascript: void(0);" data-bind="hueLink: '/accounts/logout'" title="${I18n(
-            'Sign out'
-          )}" >${I18n('Sign out')}</a></li>
-        </ul>
-      </div>
-    </div>
-  </script>
-
-  <script type="text/html" id="support-sub-menu-template">
-    <div class="sidebar-menu support-menu" data-bind="css: { 'open' : $component.supportMenuOpen }">
-      <div class="menu">
-        <ul class="sidebar-nav-list">
-          <li><a href="https://docs.gethue.com" target="_blank">${I18n('Documentation')}</a></li>
-          <li><a href="javascript:void(0)" data-bind="publish: 'show.welcome.tour'">${I18n(
-            'Welcome Tour'
-          )}</a></li>
-          <li><a href="http://gethue.com" target="_blank">Gethue.com</a></li>
-        </ul>
-      </div>
+  <script type="text/html" id="user-header-template">
+    <div class="user-icon" style="background-color: #fff">${ window.LOGGED_USERNAME[0].toUpperCase() }</div>
+    <div>
+      <div>${ window.LOGGED_USERNAME }</div>
     </div>
   </script>
 
@@ -199,7 +169,6 @@ const trackCloseOnClick = (observable, id) => {
 
 class SidebarItem {
   constructor(options) {
-    this.id = Math.random();
     this.isCategory = !!options.isCategory;
     this.displayName = options.displayName;
     this.isDivider = !!options.isDivider;
@@ -213,11 +182,13 @@ class SidebarItem {
     this.open = ko.observable(false);
     this.hoverOpen = ko.observable(false);
     this.click = options.click;
-    this.subMenuTemplate = options.subMenuTemplate;
     this.iconHtml = options.iconHtml;
     this.itemClass = options.itemClass;
+    this.headerTemplate = options.headerTemplate;
+    this.fixedBottom = !!options.fixedBottom;
 
     trackCloseOnClick(this.open, 'sidebar-sub');
+    trackCloseOnClick(this.hoverOpen, 'sidebar-sub');
     this.hoverdelay = -1;
 
     this.open.subscribe(() => {
@@ -275,19 +246,56 @@ class Sidebar {
     apiHelper.withTotalStorage('hue.sidebar', 'collabse', this.collapsed, true);
 
     this.items = ko.observableArray();
+
+    const userChildren = [];
+
+    if (window.USER_VIEW_EDIT_USER_ENABLED) {
+      userChildren.push(
+        new SidebarItem({
+          url: '/useradmin/users/edit/' + window.LOGGED_USERNAME,
+          displayName: I18n('My Profile')
+        })
+      );
+    }
+
+    if (window.USER_IS_ADMIN || window.USER_IS_ORG_ADMIN) {
+      userChildren.push(
+        new SidebarItem({ url: '/useradmin/users/', displayName: I18n('Manage Users') })
+      );
+      userChildren.push(new SidebarItem({ url: '/about/', displayName: I18n('Administration') }));
+    }
+
+    userChildren.push(new SidebarItem({ url: '/accounts/logout', displayName: I18n('Sign out') }));
+
     this.footerItems = [
       new SidebarItem({
         displayName: 'Support',
         icon: 'support',
-        click: () => this.supportMenuOpen(!this.supportMenuOpen()),
-        subMenuTemplate: 'support-sub-menu-template'
+        children: [
+          new SidebarItem({
+            displayName: I18n('Documentation'),
+            href: 'https://docs.gethue.com'
+          }),
+          new SidebarItem({
+            displayName: I18n('Welcome Tour'),
+            click: () => {
+              huePubSub.publish('show.welcome.tour');
+            }
+          }),
+          new SidebarItem({
+            displayName: 'Gethue.com',
+            href: 'https://gethue.com'
+          })
+        ],
+        fixedBottom: true
       }),
       new SidebarItem({
         displayName: window.LOGGED_USERNAME,
         itemClass: 'shepherd-user-menu',
         iconHtml: '<div class="user-icon">' + window.LOGGED_USERNAME[0].toUpperCase() + '</div>',
-        click: () => this.userMenuOpen(!this.userMenuOpen()),
-        subMenuTemplate: 'user-sub-menu-template'
+        headerTemplate: 'user-header-template',
+        children: userChildren,
+        fixedBottom: true
       })
     ];
     this.lastAppName = undefined;

File diff suppressed because it is too large
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue.css


File diff suppressed because it is too large
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue3-extra.css


+ 1 - 1
desktop/core/src/desktop/static/desktop/less/components/hue-sidebar.less

@@ -410,7 +410,7 @@
       transition: none;
     }
 
-    &.user-menu {
+    &.fixed-bottom {
       margin-top: 0;
       top: auto;
       bottom: 20px;

Some files were not shown because too many files changed in this diff