Ver Fonte

HUE-9114 [frontend] Move the top quick action button with dropdown into left nav submenus

Johan Ahlen há 5 anos atrás
pai
commit
e571cae3cb

+ 83 - 29
desktop/core/src/desktop/js/ko/components/__snapshots__/ko.sidebar.test.js.snap

@@ -8,20 +8,62 @@ exports[`ko.sidebar.js should render component 1`] = `
     <!-- ko ifnot: iconHtml -->
     <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>
+              <!-- /ko -->
+              <!-- ko if: !children && href -->
+                <a href=\\"javascript:void(0);\\" target=\\"_blank\\" data-bind=\\"attr: { 'href': href }, text: displayName\\"></a>
+              <!-- /ko -->
+            <!-- /ko -->
+          </li>
+        </ul>
+      </div>
+    </div>
   </script><script type=\\"text/html\\" id=\\"sidebar-item\\">
     <div class=\\"item-wrapper\\" data-bind=\\"css: itemClass\\">
-      <!-- ko if: click -->
-      <a href=\\"javascript: void(0);\\" data-bind=\\"click: click, attr: { 'aria-label': displayName, 'data-tooltip': displayName }, css: { 'active': active }\\" class=\\"item\\">
-        <!-- ko template: 'sidebar-inner-item' --><!-- /ko -->
-      </a>
-      <!-- /ko -->
-      <!-- ko ifnot: click -->
-      <a href=\\"javascript: void(0);\\" data-bind=\\"hueLink: url, publish: 'hue.sidebar.update.active', attr: { 'aria-label': displayName, 'data-tooltip': displayName }, css: { 'active': active }\\" class=\\"item\\">
-        <!-- ko template: 'sidebar-inner-item' --><!-- /ko -->
-      </a>
+      <!-- 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>
+          <!-- ko template: 'sidebar-sub-menu' --><!-- /ko -->
       <!-- /ko -->
-      <!-- ko if: subMenuTemplate -->
-      <!-- ko template: subMenuTemplate --><!-- /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\\"></a>
+        <!-- /ko -->
+        <!-- ko ifnot: click -->
+          <a href=\\"javascript: void(0);\\" data-bind=\\"
+              hueLink: url,
+              publish: 'hue.sidebar.update.active',
+              attr: { 'aria-label': displayName, 'data-tooltip': displayName },
+              css: { 'active': active },
+              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\\">
@@ -70,19 +112,24 @@ exports[`ko.sidebar.js should render component 1`] = `
     <!-- ko foreach: footerItems -->
     <!-- ko template: { name: 'sidebar-item' } -->
     <div class=\\"item-wrapper\\" data-bind=\\"css: itemClass\\">
-      <!-- ko if: click -->
-      <a href=\\"javascript: void(0);\\" data-bind=\\"click: click, attr: { 'aria-label': displayName, 'data-tooltip': displayName }, css: { 'active': active }\\" class=\\"item\\" aria-label=\\"Support\\" data-tooltip=\\"Support\\">
-        <!-- ko template: 'sidebar-inner-item' -->
+      <!-- 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\\">
     <!-- ko if: iconHtml --><!-- /ko -->
     <!-- ko ifnot: iconHtml -->
     <div class=\\"icon\\" data-bind=\\"hueAppIcon: icon\\"></div><span data-bind=\\"text: displayName\\">Support</span>
     <!-- /ko -->
-  <!-- /ko -->
-      </a>
-      <!-- /ko -->
-      <!-- ko ifnot: click --><!-- /ko -->
-      <!-- ko if: subMenuTemplate -->
-      <!-- ko template: subMenuTemplate -->
+  </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\\">
@@ -93,25 +140,31 @@ exports[`ko.sidebar.js should render component 1`] = `
       </div>
     </div>
   <!-- /ko -->
+        <!-- /ko -->
       <!-- /ko -->
     </div>
   <!-- /ko -->
     
     <!-- ko template: { name: 'sidebar-item' } -->
     <div class=\\"item-wrapper shepherd-user-menu\\" data-bind=\\"css: itemClass\\">
-      <!-- ko if: click -->
-      <a href=\\"javascript: void(0);\\" data-bind=\\"click: click, attr: { 'aria-label': displayName, 'data-tooltip': displayName }, css: { 'active': active }\\" class=\\"item\\" aria-label=\\"foo\\" data-tooltip=\\"foo\\">
-        <!-- ko template: 'sidebar-inner-item' -->
+      <!-- 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\\">
     <!-- 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 -->
-  <!-- /ko -->
-      </a>
-      <!-- /ko -->
-      <!-- ko ifnot: click --><!-- /ko -->
-      <!-- ko if: subMenuTemplate -->
-      <!-- ko template: subMenuTemplate -->
+  </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\\">
@@ -128,6 +181,7 @@ exports[`ko.sidebar.js should render component 1`] = `
       </div>
     </div>
   <!-- /ko -->
+        <!-- /ko -->
       <!-- /ko -->
     </div>
   <!-- /ko -->

+ 152 - 118
desktop/core/src/desktop/js/ko/components/ko.sidebar.js

@@ -36,20 +36,64 @@ const TEMPLATE = `
     <!-- /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>
+              <!-- /ko -->
+              <!-- ko if: !children && href -->
+                <a href="javascript:void(0);" target="_blank" data-bind="attr: { 'href': href }, text: displayName"></a>
+              <!-- /ko -->
+            <!-- /ko -->
+          </li>
+        </ul>
+      </div>
+    </div>
+  </script>
+
   <script type="text/html" id="sidebar-item">
     <div class="item-wrapper" data-bind="css: itemClass">
-      <!-- ko if: click -->
-      <a href="javascript: void(0);" data-bind="click: click, attr: { 'aria-label': displayName, 'data-tooltip': displayName }, css: { 'active': active }" class="item">
-        <!-- ko template: 'sidebar-inner-item' --><!-- /ko -->
-      </a>
+      <!-- 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>
+          <!-- ko template: 'sidebar-sub-menu' --><!-- /ko -->
       <!-- /ko -->
-      <!-- ko ifnot: click -->
-      <a href="javascript: void(0);" data-bind="hueLink: url, publish: 'hue.sidebar.update.active', attr: { 'aria-label': displayName, 'data-tooltip': displayName }, css: { 'active': active }" class="item">
-        <!-- ko template: 'sidebar-inner-item' --><!-- /ko -->
-      </a>
-      <!-- /ko -->
-      <!-- ko if: subMenuTemplate -->
-      <!-- ko template: subMenuTemplate --><!-- /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"></a>
+        <!-- /ko -->
+        <!-- ko ifnot: click -->
+          <a href="javascript: void(0);" data-bind="
+              hueLink: url,
+              publish: 'hue.sidebar.update.active',
+              attr: { 'aria-label': displayName, 'data-tooltip': displayName },
+              css: { 'active': active },
+              template: 'sidebar-inner-item'
+            " class="item"></a>
+        <!-- /ko -->
+        <!-- ko if: subMenuTemplate -->
+        <!-- ko template: subMenuTemplate --><!-- /ko -->
+        <!-- /ko -->
       <!-- /ko -->
     </div>
   </script>
@@ -135,20 +179,39 @@ const TEMPLATE = `
   </div>
 `;
 
+const trackCloseOnClick = (observable, id) => {
+  observable.subscribe(newVal => {
+    if (newVal) {
+      window.setTimeout(() => {
+        $(document).on('click.' + id, () => {
+          observable(false);
+        });
+      }, 0);
+    } else {
+      $(document).off('click.' + id);
+    }
+  });
+};
+
 class SidebarItem {
   constructor(options) {
     this.isCategory = !!options.isCategory;
     this.displayName = options.displayName;
+    this.isDivider = !!options.isDivider;
+    this.href = options.href;
     this.url = options.url;
     this.icon = options.icon;
     this.children = options.children;
     this.name = options.name;
     this.type = options.type;
     this.active = ko.observable(false);
+    this.open = ko.observable(false);
     this.click = options.click;
     this.subMenuTemplate = options.subMenuTemplate;
     this.iconHtml = options.iconHtml;
     this.itemClass = options.itemClass;
+
+    trackCloseOnClick(this.open, 'sidebar-sub');
   }
 }
 
@@ -160,31 +223,9 @@ class Sidebar {
     this.userMenuOpen = ko.observable(false);
     this.supportMenuOpen = ko.observable(false);
 
-    this.userMenuOpen.subscribe(newVal => {
-      if (newVal) {
-        window.setTimeout(() => {
-          $(document).on('click.userMenu', () => {
-            this.userMenuOpen(false);
-          });
-        }, 0);
-        this.supportMenuOpen(false);
-      } else {
-        $(document).off('click.userMenu');
-      }
-    });
+    trackCloseOnClick(this.userMenuOpen, 'userMenuOpen');
 
-    this.supportMenuOpen.subscribe(newVal => {
-      if (newVal) {
-        window.setTimeout(() => {
-          $(document).on('click.supportMenu', () => {
-            this.supportMenuOpen(false);
-          });
-        }, 0);
-        this.userMenuOpen(false);
-      } else {
-        $(document).off('click.supportMenu');
-      }
-    });
+    trackCloseOnClick(this.supportMenuOpen, 'supportMenuOpen');
 
     this.collapsed.subscribe(newVal => {
       if (newVal) {
@@ -233,7 +274,7 @@ class Sidebar {
               active = child.type === 'hdfs';
             }
           } else {
-            active = location.pathname == '/hue' + child.url;
+            active = location.pathname === '/hue' + child.url;
           }
           child.active(active);
         });
@@ -242,66 +283,81 @@ class Sidebar {
 
     const configUpdated = clusterConfig => {
       const items = [];
-      if (clusterConfig && clusterConfig['app_config']) {
+      if (clusterConfig && clusterConfig.app_config) {
         const appsItems = [];
-        const appConfig = clusterConfig['app_config'];
-        if (appConfig['editor']) {
-          let editor = null;
-          if (
-            clusterConfig['main_button_action'] &&
-            clusterConfig['main_button_action'].page.indexOf('/editor') === 0
-          ) {
-            editor = clusterConfig['main_button_action'];
-          }
+        const appConfig = clusterConfig.app_config;
 
-          if (!editor) {
-            const defaultEditor = appConfig['editor']['default_sql_interpreter'];
-            if (defaultEditor) {
-              const foundEditor = appConfig['editor']['interpreters'].filter(interpreter => {
-                return interpreter.type === defaultEditor;
+        ['editor', 'dashboard', 'scheduler', 'sdkapps'].forEach(appName => {
+          const config = appConfig[appName];
+          if (config && config.interpreters.length) {
+            if (config.interpreters.length === 1) {
+              appsItems.push(
+                new SidebarItem({
+                  displayName: config.displayName,
+                  url: config.interpreters[0].page,
+                  icon: config.name,
+                  type: config.name
+                })
+              );
+            } else {
+              const subApps = [];
+              const favourite = clusterConfig.main_button_action;
+
+              let lastWasSql = false;
+              let dividerAdded = false;
+              let favouriteFound = false;
+              config.interpreters.forEach(interpreter => {
+                if (!dividerAdded && lastWasSql && !interpreter.is_sql) {
+                  subApps.push(new SidebarItem({ isDivider: true }));
+                  dividerAdded = true;
+                }
+                if (!favourite || favourite.page !== interpreter.page) {
+                  subApps.push(
+                    new SidebarItem({
+                      displayName: interpreter.displayName,
+                      url: interpreter.page,
+                      icon: interpreter.dialect || interpreter.name,
+                      type: interpreter.dialect || interpreter.name
+                    })
+                  );
+                } else {
+                  favouriteFound = true;
+                }
+                lastWasSql = interpreter.is_sql;
               });
-              if (foundEditor.length === 1) {
-                editor = foundEditor[0];
+
+              if (favouriteFound) {
+                // Put the favourite on top
+                subApps.unshift(
+                  new SidebarItem({
+                    displayName: favourite.displayName,
+                    url: favourite.page,
+                    icon: favourite.dialect || favourite.name,
+                    type: favourite.dialect || favourite.name
+                  })
+                );
+              }
+              if (appName === 'editor' && window.SHOW_ADD_MORE_EDITORS) {
+                subApps.push(new SidebarItem({ isDivider: true }));
+                subApps.push(
+                  new SidebarItem({
+                    displayName: I18n('Add more...'),
+                    href: 'https://docs.gethue.com/administrator/configuration/connectors/'
+                  })
+                );
               }
+              appsItems.push(
+                new SidebarItem({
+                  displayName: config.displayName,
+                  icon: config.name,
+                  type: config.name,
+                  children: subApps
+                })
+              );
             }
           }
-
-          if (!editor && appConfig['editor']['interpreters'].length > 1) {
-            editor = appConfig['editor']['interpreters'][1];
-          }
-
-          if (editor) {
-            appsItems.push(
-              new SidebarItem({
-                displayName: I18n('Editor'),
-                url: editor['page'],
-                icon: 'editor',
-                type: 'editor'
-              })
-            );
-          } else {
-            appsItems.push(
-              new SidebarItem({
-                displayName: appConfig['editor']['displayName'],
-                url: appConfig['editor']['page'],
-                icon: 'editor',
-                type: 'editor'
-              })
-            );
-          }
-        }
-        ['dashboard', 'scheduler'].forEach(appName => {
-          if (appConfig[appName]) {
-            appsItems.push(
-              new SidebarItem({
-                displayName: appConfig[appName]['displayName'],
-                url: appConfig[appName]['page'],
-                icon: appName,
-                type: appName
-              })
-            );
-          }
         });
+
         if (appsItems.length > 0) {
           items.push(
             new SidebarItem({
@@ -313,18 +369,18 @@ class Sidebar {
         }
 
         const browserItems = [];
-        if (appConfig['home']) {
+        if (appConfig.home) {
           browserItems.push(
             new SidebarItem({
-              displayName: appConfig['home']['buttonName'],
-              url: appConfig['home']['page'],
+              displayName: appConfig.home.buttonName,
+              url: appConfig.home.page,
               icon: 'documents',
-              type: appConfig['home']['name']
+              type: appConfig.home.name
             })
           );
         }
-        if (appConfig['browser'] && appConfig['browser']['interpreters']) {
-          appConfig['browser']['interpreters'].forEach(browser => {
+        if (appConfig.browser && appConfig.browser.interpreters) {
+          appConfig.browser.interpreters.forEach(browser => {
             browserItems.push(
               new SidebarItem({
                 displayName: browser.displayName,
@@ -339,33 +395,11 @@ class Sidebar {
           items.push(
             new SidebarItem({
               isCategory: true,
-              displayName: I18n('Browsers'),
+              displayName: appConfig.browser.displayName,
               children: browserItems
             })
           );
         }
-
-        const sdkItems = [];
-        if (appConfig['sdkapps'] && appConfig['sdkapps']['interpreters']) {
-          appConfig['sdkapps']['interpreters'].forEach(sdkInterpreter => {
-            sdkItems.push(
-              new SidebarItem({
-                displayName: sdkInterpreter['displayName'],
-                url: sdkInterpreter['page'],
-                type: sdkInterpreter.type
-              })
-            );
-          });
-        }
-        if (sdkItems.length > 0) {
-          items.push(
-            new SidebarItem({
-              isCategory: true,
-              displayName: appConfig['sdkapps']['displayName'],
-              children: sdkItems
-            })
-          );
-        }
       }
 
       this.items(items);

+ 7 - 96
desktop/core/src/desktop/js/topNavViewModel.js

@@ -14,13 +14,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import $ from 'jquery';
 import * as ko from 'knockout';
 
 import apiHelper from 'api/apiHelper';
-import hueAnalytics from 'utils/hueAnalytics';
 import huePubSub from 'utils/huePubSub';
-import I18n from 'utils/i18n';
 import {
   CONFIG_REFRESHED_EVENT,
   GET_KNOWN_CONFIG_EVENT,
@@ -31,114 +28,28 @@ class TopNavViewModel {
   constructor(onePageViewModel) {
     const self = this;
     self.onePageViewModel = onePageViewModel;
-    self.leftNavVisible = ko.observable(false);
-    self.leftNavVisible.subscribe(val => {
-      huePubSub.publish('left.nav.open.toggle', val);
-      hueAnalytics.convert('hue', 'leftNavVisible/' + val);
-      if (val) {
-        // Defer or it will be triggered by the open click
-        window.setTimeout(() => {
-          $(document).one('click', () => {
-            if (self.leftNavVisible()) {
-              self.leftNavVisible(false);
-            }
-          });
-        }, 0);
-      }
-    });
-
-    huePubSub.subscribe('hue.toggle.left.nav', self.leftNavVisible);
 
     // TODO: Drop. Just for PoC
     self.pocClusterMode = ko.observable();
     apiHelper.withTotalStorage('topNav', 'multiCluster', self.pocClusterMode, 'dw');
     huePubSub.subscribe('set.multi.cluster.mode', self.pocClusterMode);
 
-    self.onePageViewModel.currentApp.subscribe(() => {
-      self.leftNavVisible(false);
-    });
-
-    self.mainQuickCreateAction = ko.observable();
-    self.quickCreateActions = ko.observableArray();
-
     self.hasJobBrowser = ko.observable(window.HAS_JOB_BROWSER);
     self.clusters = ko.observableArray();
 
     const configUpdated = config => {
-      if (config && config['main_button_action']) {
-        const topApp = config['main_button_action'];
-        self.mainQuickCreateAction({
-          displayName: topApp.buttonName,
-          icon: topApp.type,
-          tooltip: topApp.tooltip,
-          url: topApp.page
-        });
-      } else {
-        self.mainQuickCreateAction(undefined);
-      }
-
-      if (config && config['button_actions']) {
-        const apps = [];
-        const buttonActions = config['button_actions'];
-        buttonActions.forEach(app => {
-          const interpreters = [];
-          let toAddDivider = false;
-          let dividerAdded = false;
-          let lastInterpreter = null;
-          $.each(app['interpreters'], (index, interpreter) => {
-            // Promote the first catagory of interpreters
-            if (!dividerAdded) {
-              toAddDivider =
-                (app.name === 'editor' || app.name === 'dashboard') &&
-                (lastInterpreter != null && lastInterpreter.is_sql != interpreter.is_sql);
-            }
-            interpreters.push({
-              displayName: interpreter.displayName,
-              dividerAbove: toAddDivider,
-              icon: interpreter.type,
-              url: interpreter.page
-            });
-            lastInterpreter = interpreter;
-            if (toAddDivider) {
-              dividerAdded = true;
-              toAddDivider = false;
-            }
-          });
-
-          if (window.SHOW_ADD_MORE_EDITORS && app.name === 'editor' && interpreters.length > 1) {
-            interpreters.push({
-              displayName: I18n('Add more...'),
-              dividerAbove: true,
-              href: 'https://docs.gethue.com/administrator/configuration/connectors/'
-            });
-          }
-
-          apps.push({
-            displayName: app.displayName,
-            icon: app.name,
-            isCategory: interpreters.length > 0,
-            children: interpreters,
-            url: app.page
-          });
-        });
-
-        self.quickCreateActions(apps);
-      } else {
-        self.quickCreateActions([]);
-      }
-
-      if (config && config['clusters']) {
-        self.clusters(config['clusters']);
+      if (config && config.clusters) {
+        self.clusters(config.clusters);
       }
 
       self.hasJobBrowser(
         window.HAS_JOB_BROWSER &&
           config &&
-          config['app_config'] &&
-          config['app_config']['browser'] &&
-          (config['app_config']['browser']['interpreter_names'].indexOf('yarn') !== -1 ||
-            config['app_config']['editor']['interpreter_names'].indexOf('impala') !== -1 ||
-            config['app_config']['browser']['interpreter_names'].indexOf('dataeng') !== -1)
+          config.app_config &&
+          config.app_config.browser &&
+          (config.app_config.browser.interpreter_names.indexOf('yarn') !== -1 ||
+            config.app_config.editor.interpreter_names.indexOf('impala') !== -1 ||
+            config.app_config.browser.interpreter_names.indexOf('dataeng') !== -1)
       );
     };
 

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue.css


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue3-extra.css


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

@@ -392,9 +392,9 @@
   }
 
   .sidebar-menu {
-    z-index: 1010;
+    z-index: 1011;
+    position: absolute;
     display: none;
-    position: fixed;
     background-color: @cui-gray-800;
     color: @cui-white;
     font-size: 14px;
@@ -402,10 +402,16 @@
     box-shadow: rgba(0, 0, 0, 0.2) 0 2px 4px 0;
     white-space: nowrap;
     padding: 4px 8px;
-    top: auto;
     height: auto;
-    bottom: 20px;
     transition: none;
+    margin-top: -40px;
+
+    &.user-menu {
+      margin-top: 0;
+      top: auto;
+      bottom: 20px;
+      position: fixed;
+    }
 
     &.open {
       display: block;
@@ -453,6 +459,12 @@
         li {
           margin-left: -8px;
           margin-right: -8px;
+
+          &.divider {
+            height: 2px;
+            margin: 4px -8px;
+            background-color: #3e4b56;
+          }
         }
 
         li a {

+ 3 - 3
desktop/core/src/desktop/static/desktop/less/hue4.less

@@ -79,7 +79,7 @@
 
 .top-nav-left {
   padding-top: 3px;
-  .flex(0 0 340px);
+  .flex(0 0 275px);
 }
 
 .top-nav-middle {
@@ -90,7 +90,7 @@
 }
 
 .top-nav-right {
-  .flex(0 0 340px);
+  .flex(0 0 275px);
 }
 
 .top-nav-left .btn-group {
@@ -288,7 +288,7 @@
   position: relative;
   margin-left: auto;
   margin-right: auto;
-  max-width: 700px;
+  max-width: 1000px;
 }
 
 .search-container-top-old,

+ 1 - 51
desktop/core/src/desktop/templates/hue.mako

@@ -127,57 +127,7 @@ ${ hueIcons.symbols() }
 
     <nav class="navbar navbar-default">
       <div class="navbar-inner top-nav">
-        <div class="top-nav-left">
-          % if not (IS_MULTICLUSTER_ONLY.get() and get_cluster_config(user)['has_computes']):
-          <a class="hamburger hamburger-hue pull-left" data-bind="toggle: leftNavVisible, css: { 'is-active': leftNavVisible }">
-            <span class="hamburger-box"><span class="hamburger-inner"></span></span>
-          </a>
-          % endif
-
-          % if not IS_MULTICLUSTER_ONLY.get():
-          <div class="btn-group" data-bind="visible: true" style="display:none; margin-top: 8px">
-            <!-- ko if: mainQuickCreateAction -->
-            <!-- ko with: mainQuickCreateAction -->
-            <a class="btn btn-primary disable-feedback hue-main-create-btn" data-bind="hueLink: url, attr: {title: tooltip}, style: { borderBottomRightRadius: $parent.quickCreateActions().length > 1 ? '0px' : '4px', borderTopRightRadius: $parent.quickCreateActions().length > 1 ? '0px' : '4px' }">
-              <span data-bind="text: displayName"></span>
-            </a>
-            <!-- /ko -->
-            <!-- /ko -->
-            <button class="btn btn-primary dropdown-toggle hue-main-create-btn-dropdown" data-toggle="dropdown" data-bind="visible: quickCreateActions().length > 1 || (quickCreateActions().length == 1 && quickCreateActions()[0].children && quickCreateActions()[0].children.length > 1)">
-              <!-- ko ifnot: mainQuickCreateAction -->${ _('More') } <!-- /ko -->
-              <span class="caret"></span>
-            </button>
-            <ul class="dropdown-menu hue-main-create-dropdown" data-bind="foreach: { data: quickCreateActions, as: 'item' }">
-              <!-- ko template: 'quick-create-item-template' --><!-- /ko -->
-            </ul>
-          </div>
-          % endif
-
-          <script type="text/html" id="quick-create-item-template">
-            <!-- ko if: item.dividerAbove -->
-            <li class="divider"></li>
-            <!-- /ko -->
-            <li data-bind="css: { 'dropdown-submenu': item.isCategory && item.children.length > 1 }">
-              <!-- ko if: item.url -->
-                <a href="javascript: void(0);" data-bind="hueLink: item.url">
-                  <!-- ko if: item.icon -->
-                  <!-- ko template: { name: 'app-icon-template', data: item } --><!-- /ko -->
-                  <!-- /ko -->
-                  <span data-bind="css: { 'dropdown-no-icon': !item.icon }, text: item.displayName"></span>
-                </a>
-              <!-- /ko -->
-              <!-- ko if: item.href -->
-                <a data-bind="attr: { href: item.href }, text: item.displayName" target="_blank"></a>
-              <!-- /ko -->
-              <!-- ko if: item.isCategory && item.children.length > 1 -->
-              <ul class="dropdown-menu" data-bind="foreach: { data: item.children, as: 'item' }">
-                <!-- ko template: 'quick-create-item-template' --><!-- /ko -->
-              </ul>
-              <!-- /ko -->
-            </li>
-          </script>
-        </div>
-
+        <div class="top-nav-left"></div>
 
         <div class="top-nav-middle">
           <div class="search-container-top" data-bind="component: 'hue-global-search'"></div>

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff