Przeglądaj źródła

[frontend] Switch to accordion menu for the user and help menu options

Johan Ahlen 4 lat temu
rodzic
commit
6a39695ea2

+ 37 - 5
desktop/core/src/desktop/js/components/sidebar/AccordionItem.vue

@@ -80,14 +80,19 @@
     <BaseNavigationItemTooltip
       v-if="tooltip"
       :visible="isCollapsed"
-      :style="{
-        top: tooltip.top + 'px',
-        left: tooltip.right + 'px',
-        'max-height': tooltip.maxHeight + 'px'
-      }"
+      :style="tooltipStyle"
       role="tooltip"
     >
       <div
+        v-if="isUserMenu"
+        class="sidebar-sidebar-item-tooltip-primary sidebar-tooltip-user-header"
+        :class="{ 'sidebar-active': isActive }"
+      >
+        <div class="sidebar-user-icon" role="img">{{ item.displayName[0].toUpperCase() }}</div>
+        <div class="sidebar-tooltip-username">{{ item.displayName }}</div>
+      </div>
+      <div
+        v-else
         class="sidebar-sidebar-item-tooltip-primary"
         :class="{ 'sidebar-active': isActive }"
         :style="{ height: tooltip.height + 'px' }"
@@ -157,6 +162,10 @@
       );
     }
 
+    get isUserMenu(): boolean {
+      return this.item.name === 'user';
+    }
+
     get accordionItemsHeight(): string {
       const el = <HTMLElement>this.$refs.accordionItems;
       if (this.isOpen && el) {
@@ -165,6 +174,29 @@
       return '0';
     }
 
+    get tooltipStyle(): CSSStyleDeclaration | undefined {
+      if (!this.tooltip) {
+        return {};
+      }
+
+      if (this.isCollapsed) {
+        // Prevent the menu from showing outside the window
+        const height = this.item.children.length * 32 + (this.isUserMenu ? 50 : 40);
+        const diff = this.tooltip.top + height - window.innerHeight;
+        if (diff > 0) {
+          return {
+            top: this.tooltip.top - diff - 5 + 'px',
+            left: this.tooltip.right + 'px'
+          };
+        }
+      }
+      return {
+        top: this.tooltip.top + 'px',
+        left: this.tooltip.right + 'px',
+        maxHeight: this.tooltip.maxHeight + 'px'
+      };
+    }
+
     mounted(): void {
       const containerEl = <HTMLElement>this.$refs.containerRef;
       if (containerEl) {

+ 9 - 0
desktop/core/src/desktop/js/components/sidebar/HueSidebar.vue

@@ -19,8 +19,10 @@
 <template>
   <Sidebar
     :sidebar-items="sidebarItems"
+    :use-drawer-for-user="false"
     :user-drawer-item="userDrawerItem"
     :user-drawer-children="userDrawerChildren"
+    :use-drawer-for-help="false"
     :help-drawer-item="helpDrawerItem"
     :help-drawer-children="helpDrawerChildren"
     :active-item-name="activeItemName"
@@ -147,6 +149,13 @@
     });
   }
 
+  USER_DRAWER_CHILDREN.push({
+    type: 'navigation',
+    name: 'logOut',
+    displayName: I18n('Log Out'),
+    handler: (event: Event) => onHueLinkClick(event, '/accounts/logout')
+  });
+
   const HELP_DRAWER_CHILDREN: Omit<SidebarNavigationItem, 'iconHtml'>[] = [
     {
       type: 'navigation',

+ 56 - 16
desktop/core/src/desktop/js/components/sidebar/Sidebar.vue

@@ -51,13 +51,25 @@
       />
       <div class="sidebar-footer">
         <NavigationItem
-          v-if="helpItem"
+          v-if="helpItem && useDrawerForHelp"
+          :item="helpItem"
+          :is-collapsed="isCollapsed"
+          :active-item-name="activeItemName"
+        />
+        <AccordionItem
+          v-if="helpItem && !useDrawerForHelp"
           :item="helpItem"
           :is-collapsed="isCollapsed"
           :active-item-name="activeItemName"
         />
         <NavigationItem
-          v-if="userItem"
+          v-if="userItem && useDrawerForUser"
+          :item="userItem"
+          :is-collapsed="isCollapsed"
+          :active-item-name="activeItemName"
+        />
+        <AccordionItem
+          v-if="userItem && !useDrawerForUser"
           :item="userItem"
           :is-collapsed="isCollapsed"
           :active-item-name="activeItemName"
@@ -91,6 +103,8 @@
   import Component from 'vue-class-component';
   import { Fragment } from 'vue-fragment';
   import { Prop } from 'vue-property-decorator';
+
+  import AccordionItem from './AccordionItem.vue';
   import BaseNavigationItem from './BaseNavigationItem.vue';
   import './drawer.scss';
   import HelpDrawerContent from './HelpDrawerContent.vue';
@@ -99,6 +113,7 @@
   import SidebarBody from './SidebarBody.vue';
   import SidebarDrawer from './SidebarDrawer.vue';
   import {
+    SidebarAccordionItem,
     SidebarAccordionSubItem,
     SidebarItem,
     SidebarNavigationItem,
@@ -108,6 +123,7 @@
 
   @Component({
     components: {
+      AccordionItem,
       HelpDrawerContent,
       UserDrawerContent,
       SidebarDrawer,
@@ -121,11 +137,15 @@
     @Prop()
     sidebarItems!: SidebarItem[];
 
+    @Prop({ required: false, default: true })
+    useDrawerForUser: boolean;
     @Prop({ required: false })
     userDrawerItem: UserDrawerItem | null = null;
     @Prop({ required: false })
     userDrawerChildren: SidebarAccordionSubItem[] = [];
 
+    @Prop({ required: false, default: true })
+    useDrawerForHelp: boolean;
     @Prop({ required: false })
     helpDrawerItem: HelpDrawerItem | null = null;
     @Prop({ required: false })
@@ -144,33 +164,53 @@
       }
     }
 
-    get helpItem(): SidebarNavigationItem | null {
+    get helpItem(): SidebarAccordionItem | SidebarNavigationItem | null {
       if (!this.helpDrawerItem) {
         return null;
       }
-      return {
-        type: 'navigation',
+      const sharedProps = {
         name: 'help',
         displayName: this.helpDrawerItem.displayName,
-        iconHtml: this.helpDrawerItem.iconHtml,
-        handler: () => {
-          this.drawerTopic = 'help';
-        }
+        iconHtml: this.helpDrawerItem.iconHtml
+      };
+      if (this.useDrawerForHelp) {
+        return {
+          type: 'navigation',
+          ...sharedProps,
+          handler: () => {
+            this.drawerTopic = 'help';
+          }
+        };
+      }
+      return {
+        type: 'accordion',
+        ...sharedProps,
+        children: this.helpDrawerChildren
       };
     }
 
-    get userItem(): SidebarNavigationItem | null {
+    get userItem(): SidebarAccordionItem | SidebarNavigationItem | null {
       if (!this.userDrawerItem) {
         return null;
       }
-      return {
-        type: 'navigation',
+      const sharedProps = {
         name: 'user',
         displayName: this.userDrawerItem.displayName,
-        iconHtml: `<div class="sidebar-user-icon" role="img">${this.userDrawerItem.displayName[0].toUpperCase()}</div>`,
-        handler: () => {
-          this.drawerTopic = 'user';
-        }
+        iconHtml: `<div class="sidebar-user-icon" role="img">${this.userDrawerItem.displayName[0].toUpperCase()}</div>`
+      };
+      if (this.useDrawerForUser) {
+        return {
+          type: 'navigation',
+          ...sharedProps,
+          handler: () => {
+            this.drawerTopic = 'user';
+          }
+        };
+      }
+      return {
+        type: 'accordion',
+        ...sharedProps,
+        children: this.userDrawerChildren
       };
     }
   }

+ 16 - 0
desktop/core/src/desktop/js/components/sidebar/sidebar.scss

@@ -266,6 +266,22 @@
     color: $sidebar-selection-color;
     font-weight: 500;
   }
+
+  &.sidebar-tooltip-user-header {
+    height: 40px;
+    padding-top: 10px;
+
+    .sidebar-tooltip-username,
+    .sidebar-user-icon {
+      margin-left: 10px;
+    }
+
+    .sidebar-user-icon {
+      width: 30px;
+      height: 30px;
+      font-size: 18px;
+    }
+  }
 }
 
 .sidebar-accordion-item {