Przeglądaj źródła

HUE-6077 [frontend] Switch to the common left-nav design

Johan Ahlen 8 lat temu
rodzic
commit
0e6e64a

Plik diff jest za duży
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue.css


+ 128 - 0
desktop/core/src/desktop/static/desktop/less/cui/sidebar.less

@@ -0,0 +1,128 @@
+
+
+@import (reference) "extra-variables.less";
+
+@sidebar-width: 180px;
+@collapsed-sidebar-width: 48px;
+@sidebar-animation-duration: 250ms;
+@sidebar-category-font-size: 13px;
+@sidebar-left-spacing: 16px;
+
+.sidebar {
+  position: fixed;
+  top: @navbar-height;
+  left: 0;
+  bottom: 0;
+  background-color: @cui-gray-050;
+  width: @sidebar-width;
+  transition: width @sidebar-animation-duration;
+  z-index: 1000;
+  overflow: hidden;
+  box-shadow: 0 1px 2px 0;
+
+
+  .fa:before {
+    font-size: 16px;
+    color: @cui-gray-600;
+  }
+
+  .sidebar-content {
+    top: 48px;
+    bottom: 36px;
+    position: absolute;
+    overflow-y: auto;
+    min-width: @sidebar-width;
+  }
+
+  .sidebar-item {
+    display: block;
+    padding-left: @sidebar-left-spacing;
+    line-height: 36px;
+    color: @text-color;
+
+    .fa {
+      margin-right: 14px;
+      width: 18px;
+      text-align: center;
+    }
+  }
+
+  .sidebar-item.active {
+    font-weight: bold;
+    background: @cui-gray-100;
+
+    .fa:before {
+      color: @cui-blue-500;
+    }
+  }
+
+  .sidebar-item:hover {
+    background: @cui-gray-100;
+  }
+
+  .sidebar-category-item {
+    margin: 20px 0 4px @sidebar-left-spacing;
+    font-size: @sidebar-category-font-size;
+    font-weight: bold;
+    color: @cui-gray-600;
+    transition: opacity @sidebar-animation-duration;
+  }
+
+  .sidebar-action-button {
+    background-color: inherit;
+    display: block;
+    position: absolute;
+    bottom: 0;
+    right: 0;
+    left: 0;
+    line-height: 36px;
+    width: 100%;
+    text-align: right;
+    padding-right: 16px;
+    color: @text-color;
+    box-shadow: 0 0px 2px 0;
+
+    &:hover {
+      background: @cui-gray-100;
+    }
+  }
+
+  .sidebar-item-name {
+    transition: opacity @sidebar-animation-duration;
+    opacity: 1;
+  }
+
+  .sidebar-footer-panel {
+    background-color: inherit;
+    position: absolute;
+    bottom: 0;
+    right: 0;
+    left: 0;
+    width: 100%;
+    color: @text-color;
+    box-shadow: 0 0 2px 0;
+  }
+}
+
+.sidebar.collapsed {
+  width: @collapsed-sidebar-width;
+
+  .sidebar-category-item, .sidebar-item-name {
+    opacity: 0;
+  }
+
+  .sidebar-action-button {
+    text-align: center;
+    padding: 0;
+  }
+}
+
+.sidebar-placeholder {
+  transition: width @sidebar-animation-duration;
+  width: @sidebar-width;
+  height: 100%;
+
+  &.collapsed {
+    width: @collapsed-sidebar-width;
+  }
+}

+ 10 - 78
desktop/core/src/desktop/static/desktop/less/hue.less

@@ -18,6 +18,7 @@
 @import (reference) "cui/colors.less";
 @import (reference) "hue-mixins.less";
 
+@import "cui/sidebar";
 @import "hue-assist";
 @import "hue-autocomplete";
 @import "hue-cui-overrides.less";
@@ -314,88 +315,19 @@ body {
   }
 }
 
-.left-nav {
-  position:absolute;
-  background-color: @hue-primary-color-dark;
-  color: @cui-gray-050;
-  z-index: 1048;
-  top: 0;
-  left: 0;
-  bottom: 0;
-  width: 0;
-  overflow-x: hidden;
-  white-space: nowrap;
-  .hue-ease-transition(width);
-}
-
-.left-nav-menu {
-  padding-bottom: 60px;
-  margin: 10px 0 0 0;
-}
-
-.left-nav-menu li.header {
-  text-transform: uppercase;
-  letter-spacing: 1px;
-}
-
-.left-nav-menu li {
-  padding-left: 15px;
-  list-style: none;
-  line-height: 33px;
-  height: 33px;
-}
-
-.left-nav-menu li:not(.header) {
-  background-color: transparent;
-  cursor: pointer;
-  .hue-ease-transition(background-color);
-}
-
-.left-nav-menu li:not(.header):hover {
-  background-color: rgba(240, 240, 240, 0.9);
-}
-
-.left-nav-menu li a {
-  font-size: 14px;
-  letter-spacing: 1px;
-  color: @cui-gray-050;
-  .hue-ease-transition(color);
-}
-
-.left-nav-menu li:not(.header):hover a {
-  color: @cui-blue-900;
-}
-
-.left-nav-menu li a:hover {
-  text-decoration: none;
-}
-
-.left-nav-visible {
-  width: 200px;
-  .hue-box-shadow-top;
-}
+.sidebar {
+  .sidebar-footer-panel div {
+    margin-top: 15px;
+    margin-bottom: 15px;
+    text-align: center;
+  }
 
-.left-nav-drop {
-  border-top: 1px solid rgba(240, 240, 240, 0.9);
-  position: absolute;
-  bottom: 0;
-  left: 0;
-  font-size: 16px;
-  background-color: @hue-primary-color-dark;
-  width: 0;
+  a {
+    .pointer
+  }
 }
 
-.left-nav-drop div {
-  margin-top: 15px;
-  margin-bottom: 15px;
-  text-align: center;
-}
 
-.left-nav-visible .left-nav-drop {
-  width: 200px;
-  position: fixed;
-  .hue-ease-transition(width);
-}
 
 .inactive-action,
 .inactive-action a {

+ 170 - 50
desktop/core/src/desktop/templates/hue.mako

@@ -217,55 +217,28 @@ ${ hueIcons.symbols() }
   </nav>
 
   <div class="content-wrapper">
-    <div class="left-nav" data-bind="css: { 'left-nav-visible': leftNavVisible }, niceScroll">
-      <ul class="left-nav-menu">
-        <li data-bind="click: function () { page('/home') }"><a href="javascript: void(0);">Documents</a></li>
-        <li class="header">&nbsp;</li>
-        <li class="header" style="padding-left: 4px; border-bottom: 1px solid #DDD; padding-bottom: 3px;">${ _('Analyse') }</li>
-        % if interpreters:
-        <li data-bind="click: function () { page('/editor'); onePageViewModel.changeEditorType('hive', true); }"><a href="javascript: void(0);">Editor</a></li>
-        % endif
-        % if IS_DASHBOARD_ENABLED.get():
-        <li data-bind="click: function () { page('/dashboard/new_search') }"><a href="javascript: void(0);">Dashboard</a></li>
-        % endif
-        % if 'oozie' in apps:
-        <li data-bind="click: function () { page('/oozie/editor/workflow/new/') }"><a href="javascript: void(0);">Workflows</a></li>
-        % endif
-        <li class="header">&nbsp;</li>
-        <li class="header" style="padding-left: 4px; border-bottom: 1px solid #DDD; padding-bottom: 3px;">${ _('Browse') }</li>
-        % if 'filebrowser' in apps:
-        <li data-bind="click: function () { page('/filebrowser/') }"><a href="javascript: void(0);">Files</a></li>
-        % endif
-        % if is_s3_enabled:
-        <li data-bind="click: function () { page('/filebrowser/view=S3A://') }"><a href="javascript: void(0);">S3</a></li>
-        % endif
-        % if 'metastore' in apps:
-        <li data-bind="click: function () { page('/metastore/tables/') }"><a href="javascript: void(0);">Tables</a></li>
-        % endif
-        % if 'search' in apps:
-        <li data-bind="click: function () { page('/indexer/') }"><a href="javascript: void(0);">Indexes</a></li>
-        % endif
-        % if 'jobbrowser' in apps:
-        <li data-bind="click: function () { page('/jobbrowser/') }"><a href="javascript: void(0);">Jobs</a></li>
-        % endif
-        % if 'hbase' in apps:
-        <li data-bind="click: function () { page('/hbase/') }"><a href="javascript: void(0);">HBase</a></li>
-        % endif
-        % if 'security' in apps:
-          <li data-bind="click: function () { page('/security/hive') }"><a href="javascript: void(0);">Security</a></li>
-        % endif
-        % if 'sqoop' in apps:
-        <li><a href="/${apps['sqoop'].display_name}">${_('Sqoop')}</a></li>
-        % endif
-        % if other_apps:
-        <li class="header">&nbsp;</li>
-        <li class="header" style="padding-left: 4px; border-bottom: 1px solid #DDD; padding-bottom: 3px;">${ _('Apps') }</li>
-        % for other in other_apps:
-        <li><a href="/${ other.display_name }">${ other.nice_name }</a></li>
-        % endfor
-        % endif
-      </ul>
-      <div class="left-nav-drop">
+
+
+    <script type="text/html" id="tmpl-sidebar-link">
+      <a role="button" class="sidebar-item" data-bind="click: item.click, attr: { title: item.displayName }">
+        <!-- ko if: item.icon --><i class="fa" data-bind="css: item.icon"></i><!-- /ko -->
+        <span class="sidebar-item-name" data-bind="text: item.displayName"></span>
+      </a>
+    </script>
+
+    <div class="sidebar" data-bind="visible: leftNavVisible" style="display:none;">
+      <div class="sidebar-content">
+        <!-- ko foreach: {data: items, as: 'item'} -->
+          <!-- ko if: item.isCategory -->
+             <h4 class="sidebar-category-item" data-bind="text: item.displayName"></h4>
+             <!-- ko template: {name: 'tmpl-sidebar-link', foreach: item.children, as: 'item'} --><!-- /ko -->
+          <!-- /ko -->
+          <!-- ko ifnot: item.isCategory -->
+             <!-- ko template: { name: 'tmpl-sidebar-link' } --><!-- /ko -->
+          <!-- /ko -->
+        <!-- /ko -->
+      </div>
+      <div class="sidebar-footer-panel">
         <div data-bind="dropzone: {
             clickable: false,
             url: '/filebrowser/upload/file?dest=' + DropzoneGlobals.homeDir,
@@ -1073,11 +1046,158 @@ ${ smart_unicode(login_modal(request).content) | n,unicode }
 
       var topNavViewModel = new TopNavViewModel();
       ko.applyBindings(topNavViewModel, $('.top-nav')[0]);
-      ko.applyBindings(topNavViewModel, $('.left-nav')[0]);
 
       return topNavViewModel;
     })(onePageViewModel);
 
+
+    (function (onePageViewModel, topNavViewModel) {
+      function SideBarViewModel () {
+        self.items = [];
+
+        self.leftNavVisible = topNavViewModel.leftNavVisible;
+        self.onePageViewModel = onePageViewModel;
+
+        self.items.push({
+          displayName: '${ _('Documents') }',
+          click: function () {
+            page('/home')
+          }
+        });
+
+        var analyzeItems = [];
+
+        % if interpreters:
+          analyzeItems.push({
+            displayName: '${ _('Editor') }',
+            click: function () {
+              page('/editor');
+              onePageViewModel.changeEditorType('hive', true);
+            }
+          });
+        % endif
+        % if IS_DASHBOARD_ENABLED.get():
+          analyzeItems.push({
+            displayName: '${ _('Dashboard') }',
+            click: function () {
+              page('/dashboard/new_search');
+            }
+          });
+        % endif
+        % if 'oozie' in apps:
+          analyzeItems.push({
+            displayName: '${ _('Workflows') }',
+            click: function () {
+              page('/oozie/editor/workflow/new/')
+            }
+          });
+        % endif
+
+        if (analyzeItems.length > 0) {
+          self.items.push({
+            isCategory: true,
+            displayName: '${ _('Analyze') }',
+            children: analyzeItems
+          })
+        }
+
+        var browseItems = [];
+
+        % if 'filebrowser' in apps:
+          browseItems.push({
+            displayName: '${ _('Files') }',
+            click: function () {
+              page('/filebrowser/')
+            }
+          });
+        % endif
+        % if is_s3_enabled:
+          browseItems.push({
+            displayName: '${ _('S3') }',
+            click: function () {
+              page('/filebrowser/view=S3A://')
+            }
+          });
+        % endif
+        % if 'metastore' in apps:
+          browseItems.push({
+            displayName: '${ _('Tables') }',
+            click: function () {
+              page('/metastore/tables/')
+            }
+          });
+        % endif
+        % if 'search' in apps:
+          browseItems.push({
+            displayName: '${ _('Indexes') }',
+            click: function () {
+              page('/indexer/')
+            }
+          });
+        % endif
+        % if 'jobbrowser' in apps:
+          browseItems.push({
+            displayName: '${ _('Jobs') }',
+            click: function () {
+              page('/jobbrowser/')
+            }
+          });
+        % endif
+        % if 'hbase' in apps:
+          browseItems.push({
+            displayName: '${ _('HBase') }',
+            click: function () {
+              page('/hbase/')
+            }
+          });
+        % endif
+        % if 'security' in apps:
+          browseItems.push({
+            displayName: '${ _('Security') }',
+            click: function () {
+              page('/security/hive')
+            }
+          });
+        % endif
+        % if 'sqoop' in apps:
+          browseItems.push({
+            displayName: '${ _('Sqoop') }',
+            click: function () {
+              page('/sqoop')
+            }
+          });
+        % endif
+
+        if (browseItems.length > 0) {
+          self.items.push({
+            isCategory: true,
+            displayName: '${ _('Browse') }',
+            children: browseItems
+          })
+        }
+
+        % if other_apps:
+          var otherApps = [];
+        % for other in other_apps:
+          otherApps.push({
+            displayName: '${ other.nice_name }',
+            click: function () {
+              window.location('/${ other.nice_name }')
+            }
+          });
+        % endfor
+          self.items.push({
+            isCategory: true,
+            displayName: '${ _('Apps') }',
+            children: otherApps
+          });
+        % endif
+      }
+
+      var sidebarViewModel = new SideBarViewModel();
+      ko.applyBindings(sidebarViewModel, $('.sidebar')[0]);
+    })(onePageViewModel, topNavViewModel);
+
     window.hueDebug = {
       viewModel: function (element) {
         return element ? ko.dataFor(element) : window.hueDebug.onePageViewModel;

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików