Pārlūkot izejas kodu

HUE-8893 [assist] Move the remaining assist subpanels into webpack

Johan Ahlen 6 gadi atpakaļ
vecāks
revīzija
1e000cd3c8

+ 81 - 0
desktop/core/src/desktop/js/assist/assistAdlsPanel.js

@@ -0,0 +1,81 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import ko from 'knockout';
+
+import apiHelper from 'api/apiHelper';
+import AssistStorageEntry from 'assist/assistStorageEntry';
+import huePubSub from 'utils/huePubSub';
+
+class AssistAdlsPanel {
+  constructor(options) {
+    const self = this;
+    self.selectedAdlsEntry = ko.observable();
+    self.loading = ko.observable();
+    self.initialized = false;
+
+    const loadPath = path => {
+      self.loading(true);
+      const parts = path.split('/');
+      parts.shift();
+
+      const currentEntry = new AssistStorageEntry({
+        type: 'adls',
+        definition: {
+          name: '/',
+          type: 'dir'
+        },
+        parent: null
+      });
+
+      currentEntry.loadDeep(parts, entry => {
+        self.selectedAdlsEntry(entry);
+        entry.open(true);
+        self.loading(false);
+      });
+    };
+
+    self.reload = () => {
+      loadPath(apiHelper.getFromTotalStorage('assist', 'currentAdlsPath', '/'));
+    };
+
+    huePubSub.subscribe('assist.adls.go.home', () => {
+      loadPath(window.USER_HOME_DIR);
+      apiHelper.setInTotalStorage('assist', 'currentAdlsPath', window.USER_HOME_DIR);
+    });
+
+    huePubSub.subscribe('assist.selectAdlsEntry', entry => {
+      self.selectedAdlsEntry(entry);
+      apiHelper.setInTotalStorage('assist', 'currentAdlsPath', entry.path);
+    });
+
+    huePubSub.subscribe('assist.adls.refresh', () => {
+      huePubSub.publish('assist.clear.adls.cache');
+      self.reload();
+    });
+  }
+
+  init() {
+    const self = this;
+    if (self.initialized) {
+      return;
+    }
+    self.reload();
+    self.initialized = true;
+  }
+}
+
+export default AssistAdlsPanel;

+ 209 - 0
desktop/core/src/desktop/js/assist/assistDocumentsPanel.js

@@ -0,0 +1,209 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import $ from 'jquery';
+import ko from 'knockout';
+
+import apiHelper from 'api/apiHelper';
+import huePubSub from 'utils/huePubSub';
+import HueFileEntry from 'doc/hueFileEntry';
+import { DOCUMENT_TYPES } from 'doc/docSupport';
+
+class AssistDocumentsPanel {
+  /**
+   * @param {Object} options
+   * @param {string} options.user
+   * @constructor
+   **/
+  constructor(options) {
+    const self = this;
+    self.user = options.user;
+
+    self.activeEntry = ko.observable();
+    self.activeSort = ko.observable('defaultAsc');
+    self.typeFilter = ko.observable(DOCUMENT_TYPES[0]); // all is first
+
+    self.highlightTypeFilter = ko.observable(false);
+
+    const lastOpenedUuid = apiHelper.getFromTotalStorage('assist', 'last.opened.assist.doc.uuid');
+
+    if (lastOpenedUuid) {
+      self.activeEntry(
+        new HueFileEntry({
+          activeEntry: self.activeEntry,
+          trashEntry: ko.observable(),
+          app: 'documents',
+          user: self.user,
+          activeSort: self.activeSort,
+          typeFilter: self.typeFilter,
+          definition: {
+            uuid: lastOpenedUuid,
+            type: 'directory'
+          }
+        })
+      );
+    } else {
+      self.fallbackToRoot();
+    }
+
+    self.activeEntry.subscribe(newEntry => {
+      if (!newEntry.loaded()) {
+        const loadedSub = newEntry.loaded.subscribe(loaded => {
+          if (
+            loaded &&
+            !newEntry.hasErrors() &&
+            newEntry.definition() &&
+            newEntry.definition().uuid
+          ) {
+            apiHelper.setInTotalStorage(
+              'assist',
+              'last.opened.assist.doc.uuid',
+              newEntry.definition().uuid
+            );
+          }
+          loadedSub.dispose();
+        });
+      } else if (!newEntry.hasErrors() && newEntry.definition() && newEntry.definition().uuid) {
+        apiHelper.setInTotalStorage(
+          'assist',
+          'last.opened.assist.doc.uuid',
+          newEntry.definition().uuid
+        );
+      }
+    });
+
+    self.reload = () => {
+      self.activeEntry().load(
+        () => {},
+        () => {
+          self.fallbackToRoot();
+        }
+      );
+    };
+
+    huePubSub.subscribe('assist.document.refresh', () => {
+      huePubSub.publish('assist.clear.document.cache');
+      self.reload();
+    });
+
+    huePubSub.subscribe('assist.doc.highlight', details => {
+      huePubSub.publish('assist.show.documents');
+      huePubSub.publish('context.popover.hide');
+      const whenLoaded = $.Deferred().done(() => {
+        self.activeEntry().highlightInside(details.docUuid);
+      });
+      if (
+        self.activeEntry() &&
+        self.activeEntry().definition() &&
+        self.activeEntry().definition().uuid === details.parentUuid
+      ) {
+        if (self.activeEntry().loaded() && !self.activeEntry().hasErrors()) {
+          whenLoaded.resolve();
+        } else {
+          const loadedSub = self.activeEntry().loaded.subscribe(newVal => {
+            if (newVal) {
+              if (!self.activeEntry().hasErrors()) {
+                whenLoaded.resolve();
+              }
+              whenLoaded.reject();
+              loadedSub.remove();
+            }
+          });
+        }
+        self.activeEntry().highlight(details.docUuid);
+      } else {
+        self.activeEntry(
+          new HueFileEntry({
+            activeEntry: self.activeEntry,
+            trashEntry: ko.observable(),
+            app: 'documents',
+            user: self.user,
+            activeSort: self.activeSort,
+            typeFilter: self.typeFilter,
+            definition: {
+              uuid: details.parentUuid,
+              type: 'directory'
+            }
+          })
+        );
+        self.activeEntry().load(
+          () => {
+            whenLoaded.resolve();
+          },
+          () => {
+            whenLoaded.reject();
+            self.fallbackToRoot();
+          }
+        );
+      }
+    });
+  }
+
+  setTypeFilter(newType) {
+    const self = this;
+    DOCUMENT_TYPES.some(docType => {
+      if (docType.type === newType) {
+        self.typeFilter(docType);
+        return true;
+      }
+    });
+    self.highlightTypeFilter(true);
+    window.setTimeout(() => {
+      self.highlightTypeFilter(false);
+    }, 600);
+  }
+
+  fallbackToRoot() {
+    const self = this;
+    if (
+      !self.activeEntry() ||
+      (self.activeEntry().definition() &&
+        (self.activeEntry().definition().path !== '/' || self.activeEntry().definition().uuid))
+    ) {
+      apiHelper.setInTotalStorage('assist', 'last.opened.assist.doc.uuid', null);
+      self.activeEntry(
+        new HueFileEntry({
+          activeEntry: self.activeEntry,
+          trashEntry: ko.observable(),
+          app: 'documents',
+          user: self.user,
+          activeSort: self.activeSort,
+          typeFilter: self.typeFilter,
+          definition: {
+            name: '/',
+            type: 'directory'
+          }
+        })
+      );
+      self.activeEntry().load();
+    }
+  }
+
+  init() {
+    const self = this;
+    if (!self.activeEntry().loaded()) {
+      self.activeEntry().load(
+        () => {},
+        () => {
+          self.fallbackToRoot();
+        },
+        true
+      );
+    }
+  }
+}
+
+export default AssistDocumentsPanel;

+ 71 - 0
desktop/core/src/desktop/js/assist/assistGitPanel.js

@@ -0,0 +1,71 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import ko from 'knockout';
+
+import apiHelper from 'api/apiHelper';
+import AssistGitEntry from 'assist/assistGitEntry';
+import huePubSub from 'utils/huePubSub';
+
+class AssistGitPanel {
+  /**
+   * @param {Object} options
+   * @constructor
+   **/
+  constructor(options) {
+    const self = this;
+
+    self.selectedGitEntry = ko.observable();
+    self.reload = function() {
+      const lastKnownPath = apiHelper.getFromTotalStorage(
+        'assist',
+        'currentGitPath',
+        window.USER_HOME_DIR
+      );
+      const parts = lastKnownPath.split('/');
+      parts.shift();
+
+      const currentEntry = new AssistGitEntry({
+        definition: {
+          name: '/',
+          type: 'dir'
+        },
+        parent: null
+      });
+
+      currentEntry.loadDeep(parts, entry => {
+        self.selectedGitEntry(entry);
+        entry.open(true);
+      });
+    };
+
+    huePubSub.subscribe('assist.selectGitEntry', entry => {
+      self.selectedGitEntry(entry);
+      apiHelper.setInTotalStorage('assist', 'currentGitPath', entry.path);
+    });
+
+    huePubSub.subscribe('assist.git.refresh', () => {
+      huePubSub.publish('assist.clear.git.cache');
+      self.reload();
+    });
+  }
+
+  init() {
+    this.reload();
+  }
+}
+
+export default AssistGitPanel;

+ 131 - 0
desktop/core/src/desktop/js/assist/assistHBasePanel.js

@@ -0,0 +1,131 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import ko from 'knockout';
+
+import apiHelper from 'api/apiHelper';
+import AssistHBaseEntry from 'assist/assistHBaseEntry';
+import huePubSub from 'utils/huePubSub';
+
+class AssistHBasePanel {
+  /**
+   * @param {Object} options
+   * @constructor
+   **/
+  constructor(options) {
+    const self = this;
+    self.initialized = false;
+
+    const root = new AssistHBaseEntry({
+      definition: {
+        host: '',
+        name: '',
+        port: 0
+      }
+    });
+
+    self.selectedHBaseEntry = ko.observable();
+    self.reload = () => {
+      self.selectedHBaseEntry(root);
+      root.loadEntries(() => {
+        const lastOpenendPath = apiHelper.getFromTotalStorage(
+          'assist',
+          'last.opened.hbase.entry',
+          null
+        );
+        if (lastOpenendPath) {
+          root.entries().every(entry => {
+            if (entry.path === lastOpenendPath) {
+              entry.open();
+              return false;
+            }
+            return true;
+          });
+        }
+      });
+    };
+
+    self.selectedHBaseEntry.subscribe(newEntry => {
+      if (newEntry !== root || (newEntry === root && newEntry.loaded)) {
+        apiHelper.setInTotalStorage('assist', 'last.opened.hbase.entry', newEntry.path);
+      }
+    });
+
+    huePubSub.subscribe('assist.clickHBaseItem', entry => {
+      if (entry.definition.host) {
+        entry.loadEntries();
+        self.selectedHBaseEntry(entry);
+      } else {
+        huePubSub.publish('assist.dblClickHBaseItem', entry);
+      }
+    });
+
+    huePubSub.subscribe('assist.clickHBaseRootItem', () => {
+      self.reload();
+    });
+
+    const delayChangeHash = hash => {
+      window.setTimeout(() => {
+        window.location.hash = hash;
+      }, 0);
+    };
+
+    self.lastClickeHBaseEntry = null;
+    self.HBaseLoaded = false;
+
+    huePubSub.subscribeOnce('hbase.app.loaded', () => {
+      if (self.selectedHBaseEntry() && self.lastClickeHBaseEntry) {
+        delayChangeHash(
+          self.selectedHBaseEntry().definition.name +
+            '/' +
+            self.lastClickeHBaseEntry.definition.name
+        );
+      }
+      self.HBaseLoaded = true;
+    });
+
+    huePubSub.subscribe('assist.dblClickHBaseItem', entry => {
+      const hash = self.selectedHBaseEntry().definition.name + '/' + entry.definition.name;
+      if (window.location.pathname.startsWith('/hue/hbase')) {
+        window.location.hash = hash;
+      } else {
+        self.lastClickeHBaseEntry = entry;
+        huePubSub.subscribeOnce('app.gained.focus', app => {
+          if (app === 'hbase' && self.HBaseLoaded) {
+            delayChangeHash(hash);
+          }
+        });
+        huePubSub.publish('open.link', '/hbase');
+      }
+    });
+
+    huePubSub.subscribe('assist.hbase.refresh', () => {
+      huePubSub.publish('assist.clear.hbase.cache');
+      self.reload();
+    });
+  }
+
+  init() {
+    const self = this;
+    if (self.initialized) {
+      return;
+    }
+    self.reload();
+    self.initialized = true;
+  }
+}
+
+export default AssistHBasePanel;

+ 85 - 0
desktop/core/src/desktop/js/assist/assistHdfsPanel.js

@@ -0,0 +1,85 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import ko from 'knockout';
+
+import apiHelper from 'api/apiHelper';
+import AssistStorageEntry from 'assist/assistStorageEntry';
+import huePubSub from 'utils/huePubSub';
+
+class AssistHdfsPanel {
+  /**
+   * @param {Object} options
+   * @constructor
+   **/
+  constructor(options) {
+    const self = this;
+    self.selectedHdfsEntry = ko.observable();
+    self.loading = ko.observable();
+    self.initialized = false;
+
+    const loadPath = path => {
+      self.loading(true);
+      const parts = path.split('/');
+      parts.shift();
+
+      const currentEntry = new AssistStorageEntry({
+        type: 'hdfs',
+        definition: {
+          name: '/',
+          type: 'dir'
+        },
+        parent: null
+      });
+
+      currentEntry.loadDeep(parts, entry => {
+        self.selectedHdfsEntry(entry);
+        entry.open(true);
+        self.loading(false);
+      });
+    };
+
+    self.reload = () => {
+      loadPath(apiHelper.getFromTotalStorage('assist', 'currentHdfsPath', window.USER_HOME_DIR));
+    };
+
+    huePubSub.subscribe('assist.hdfs.go.home', () => {
+      loadPath(window.USER_HOME_DIR);
+      apiHelper.setInTotalStorage('assist', 'currentHdfsPath', window.USER_HOME_DIR);
+    });
+
+    huePubSub.subscribe('assist.selectHdfsEntry', entry => {
+      self.selectedHdfsEntry(entry);
+      apiHelper.setInTotalStorage('assist', 'currentHdfsPath', entry.path);
+    });
+
+    huePubSub.subscribe('assist.hdfs.refresh', () => {
+      huePubSub.publish('assist.clear.hdfs.cache');
+      self.reload();
+    });
+  }
+
+  init() {
+    const self = this;
+    if (self.initialized) {
+      return;
+    }
+    self.reload();
+    self.initialized = true;
+  }
+}
+
+export default AssistHdfsPanel;

+ 81 - 0
desktop/core/src/desktop/js/assist/assistPanel.js

@@ -0,0 +1,81 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import ko from 'knockout';
+
+import apiHelper from 'api/apiHelper';
+import AssistStorageEntry from 'assist/assistStorageEntry';
+import huePubSub from 'utils/huePubSub';
+
+class AssistAdlsPanel {
+  constructor(options) {
+    const self = this;
+    self.selectedAdlsEntry = ko.observable();
+    self.loading = ko.observable();
+    self.initialized = false;
+
+    const loadPath = path => {
+      self.loading(true);
+      const parts = path.split('/');
+      parts.shift();
+
+      const currentEntry = new AssistStorageEntry({
+        type: 'adls',
+        definition: {
+          name: '/',
+          type: 'dir'
+        },
+        parent: null
+      });
+
+      currentEntry.loadDeep(parts, entry => {
+        self.selectedAdlsEntry(entry);
+        entry.open(true);
+        self.loading(false);
+      });
+    };
+
+    self.reload = () => {
+      loadPath(apiHelper.getFromTotalStorage('assist', 'currentAdlsPath', '/'));
+    };
+
+    huePubSub.subscribe('assist.adls.go.home', () => {
+      loadPath(window.USER_HOME_DIR);
+      apiHelper.setInTotalStorage('assist', 'currentAdlsPath', window.USER_HOME_DIR);
+    });
+
+    huePubSub.subscribe('assist.selectAdlsEntry', entry => {
+      self.selectedAdlsEntry(entry);
+      apiHelper.setInTotalStorage('assist', 'currentAdlsPath', entry.path);
+    });
+
+    huePubSub.subscribe('assist.adls.refresh', () => {
+      huePubSub.publish('assist.clear.adls.cache');
+      self.reload();
+    });
+  }
+
+  init() {
+    const self = this;
+    if (self.initialized) {
+      return;
+    }
+    self.reload();
+    self.initialized = true;
+  }
+}
+
+export default AssistAdlsPanel;

+ 78 - 0
desktop/core/src/desktop/js/assist/assistS3Panel.js

@@ -0,0 +1,78 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import ko from 'knockout';
+
+import apiHelper from 'api/apiHelper';
+import AssistStorageEntry from 'assist/assistStorageEntry';
+import huePubSub from 'utils/huePubSub';
+
+class AssistS3Panel {
+  /**
+   * @param {Object} options
+   * @constructor
+   **/
+  constructor(options) {
+    const self = this;
+
+    self.selectedS3Entry = ko.observable();
+    self.loading = ko.observable();
+    self.initialized = false;
+
+    self.reload = () => {
+      self.loading(true);
+      const lastKnownPath = apiHelper.getFromTotalStorage('assist', 'currentS3Path', '/');
+      const parts = lastKnownPath.split('/');
+      parts.shift();
+
+      const currentEntry = new AssistStorageEntry({
+        type: 's3',
+        definition: {
+          name: '/',
+          type: 'dir'
+        },
+        parent: null
+      });
+
+      currentEntry.loadDeep(parts, entry => {
+        self.selectedS3Entry(entry);
+        entry.open(true);
+        self.loading(false);
+      });
+    };
+
+    huePubSub.subscribe('assist.selectS3Entry', entry => {
+      self.selectedS3Entry(entry);
+      apiHelper.setInTotalStorage('assist', 'currentS3Path', entry.path);
+    });
+
+    huePubSub.subscribe('assist.s3.refresh', () => {
+      huePubSub.publish('assist.clear.s3.cache');
+      self.reload();
+    });
+  }
+
+  init() {
+    const self = this;
+    if (self.initialized) {
+      return;
+    }
+    self.reload();
+    self.initialized = true;
+  }
+}
+
+export default AssistS3Panel;

+ 150 - 0
desktop/core/src/desktop/js/assist/ko/ko.assistPanel.js

@@ -0,0 +1,150 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import ko from 'knockout';
+
+import componentUtils from 'ko/components/componentUtils';
+
+const TEMPLATE = `
+  <ul class="cui-app-switcher nav navbar-nav">
+    <li class="dropdown">
+      <button class="btn btn-flat" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true" role="button">
+        <i class="fa fa-th"></i>
+      </button>
+
+      <ul class="dropdown-menu pull-right" role="menu">
+        <!-- ko foreach: links -->
+        <li class="nav-item">
+          <!-- ko if: $data.divider -->
+          <div class="divider"></div>
+          <!-- /ko -->
+          <!-- ko ifnot: $data.divider -->
+          <a role="button" class="nav-link" data-bind="attr: { href: link }">
+            <span class="app-switcher-app-icon">
+              <!-- ko if: $data.icon -->
+              <i data-bind="attr: { class: icon }"></i>
+              <!-- /ko -->
+              <!-- ko if: $data.img -->
+              <!-- ko template: 'app-switcher-icon-template' --><!-- /ko -->
+              <!-- /ko -->
+            </span>
+            <span class="app-switcher-app-name" data-bind="text: label"></span>
+          </a>
+          <!-- /ko -->
+        </li>
+        <!-- /ko -->
+      </ul>
+    </li>
+  </ul>
+`;
+
+const apps = {
+  hue: {
+    label: 'Data Warehouse',
+    icon: 'altus-icon altus-adb-query'
+  },
+  cdsw: {
+    label: 'Data Science',
+    icon: 'altus-icon altus-ds'
+  },
+  dataFlow: {
+    label: 'Data Engineering',
+    icon: 'altus-icon altus-workload'
+  },
+  navigator: {
+    label: 'Data Stewart',
+    icon: 'altus-icon altus-adb'
+  },
+  navopt: {
+    label: 'Admin',
+    icon: 'altus-icon altus-iam'
+  }
+};
+
+const AppSwitcher = function AppSwitcher(params) {
+  const self = this;
+
+  self.links = ko.observableArray([]);
+
+  const altusLinks = [
+    {
+      product: 'hue',
+      link: 'https://sso.staging.aem.cloudera.com'
+    },
+    {
+      product: 'cdsw',
+      link: 'https://sso.staging.aem.cloudera.com'
+    },
+    {
+      product: 'dataFlow',
+      link: 'https://sso.staging.aem.cloudera.com'
+    },
+    {
+      product: 'navigator',
+      link: 'https://sso.staging.aem.cloudera.com'
+    },
+    {
+      product: 'navopt',
+      link: 'https://sso.staging.aem.cloudera.com'
+    }
+  ];
+
+  const onPremLinks = [
+    {
+      product: 'cdsw',
+      link: '/'
+    },
+    {
+      divider: true
+    },
+    {
+      product: 'cm',
+      link: '/'
+    },
+    {
+      product: 'navigator',
+      link: '/'
+    }
+  ];
+
+  const applyLinks = function(links) {
+    const newLinks = [];
+    links.forEach(link => {
+      if (link.product) {
+        const lookup = apps[link.product];
+        if (lookup) {
+          lookup.link = link.link;
+          newLinks.push(lookup);
+        }
+      } else {
+        newLinks.push(link);
+      }
+    });
+    self.links(newLinks);
+  };
+
+  params.onPrem.subscribe(newValue => {
+    if (newValue) {
+      applyLinks(onPremLinks);
+    } else {
+      applyLinks(altusLinks);
+    }
+  });
+
+  applyLinks(altusLinks);
+};
+
+componentUtils.registerComponent('hue-app-switcher', AppSwitcher, TEMPLATE);

+ 12 - 0
desktop/core/src/desktop/js/hue.js

@@ -77,9 +77,21 @@ import 'assist/ko/ko.assistFileDraggable';
 import 'assist/ko/ko.assistFileDroppable';
 import AssistDbPanel from 'assist/assistDbPanel';
 import AssistInnerPanel from 'assist/assistInnerPanel';
+import AssistDocumentsPanel from 'assist/assistDocumentsPanel';
+import AssistHdfsPanel from 'assist/assistHdfsPanel';
+import AssistAdlsPanel from 'assist/assistAdlsPanel';
+import AssistGitPanel from 'assist/assistGitPanel';
+import AssistS3Panel from 'assist/assistS3Panel';
+import AssistHBasePanel from 'assist/assistHBasePanel';
 
 window.AssistDbPanel = AssistDbPanel;
 window.AssistInnerPanel = AssistInnerPanel;
+window.AssistDocumentsPanel = AssistDocumentsPanel;
+window.AssistHdfsPanel = AssistHdfsPanel;
+window.AssistAdlsPanel = AssistAdlsPanel;
+window.AssistGitPanel = AssistGitPanel;
+window.AssistS3Panel = AssistS3Panel;
+window.AssistHBasePanel = AssistHBasePanel;
 
 // TODO: Migrate away
 window._ = _;

+ 0 - 456
desktop/core/src/desktop/templates/assist.mako

@@ -1068,462 +1068,6 @@ from desktop.views import _ko
 
     (function () {
 
-
-      /**
-       * @param {Object} options
-       * @param {string} options.user
-       * @constructor
-       **/
-      function AssistDocumentsPanel (options) {
-        var self = this;
-        self.user = options.user;
-
-        self.activeEntry = ko.observable();
-        self.activeSort = ko.observable('defaultAsc');
-        self.typeFilter = ko.observable(DOCUMENT_TYPES[0]); // all is first
-
-        self.highlightTypeFilter = ko.observable(false);
-
-        var lastOpenedUuid = window.apiHelper.getFromTotalStorage('assist', 'last.opened.assist.doc.uuid');
-
-        if (lastOpenedUuid) {
-          self.activeEntry(new HueFileEntry({
-            activeEntry: self.activeEntry,
-            trashEntry: ko.observable(),
-            app: 'documents',
-            user: self.user,
-            activeSort: self.activeSort,
-            typeFilter: self.typeFilter,
-            definition: {
-              uuid: lastOpenedUuid,
-              type: 'directory'
-            }
-          }))
-        } else {
-          self.fallbackToRoot();
-        }
-
-        self.activeEntry.subscribe(function (newEntry) {
-          if (!newEntry.loaded()) {
-            var loadedSub = newEntry.loaded.subscribe(function (loaded) {
-              if (loaded && !newEntry.hasErrors() && newEntry.definition() && newEntry.definition().uuid) {
-                window.apiHelper.setInTotalStorage('assist', 'last.opened.assist.doc.uuid', newEntry.definition().uuid);
-              }
-              loadedSub.dispose();
-            })
-          } else if (!newEntry.hasErrors() && newEntry.definition() && newEntry.definition().uuid) {
-            window.apiHelper.setInTotalStorage('assist', 'last.opened.assist.doc.uuid', newEntry.definition().uuid);
-          }
-        });
-
-        self.reload = function () {
-          self.activeEntry().load(function () {}, function () {
-            self.fallbackToRoot();
-          });
-        };
-
-        huePubSub.subscribe('assist.document.refresh', function () {
-          huePubSub.publish('assist.clear.document.cache');
-          self.reload();
-        });
-
-        huePubSub.subscribe('assist.doc.highlight', function (details) {
-          huePubSub.publish('assist.show.documents');
-          huePubSub.publish('context.popover.hide');
-          var whenLoaded = $.Deferred().done(function () {
-            self.activeEntry().highlightInside(details.docUuid);
-          });
-          if (self.activeEntry() && self.activeEntry().definition() && self.activeEntry().definition().uuid === details.parentUuid) {
-            if (self.activeEntry().loaded() && !self.activeEntry().hasErrors()) {
-              whenLoaded.resolve();
-            } else {
-              var loadedSub = self.activeEntry().loaded.subscribe(function (newVal) {
-                if (newVal) {
-                  if (!self.activeEntry().hasErrors()) {
-                    whenLoaded.resolve();
-                  }
-                  whenLoaded.reject();
-                  loadedSub.remove();
-                }
-              })
-            }
-            self.activeEntry().highlight(details.docUuid);
-          } else {
-            self.activeEntry(new HueFileEntry({
-              activeEntry: self.activeEntry,
-              trashEntry: ko.observable(),
-              app: 'documents',
-              user: self.user,
-              activeSort: self.activeSort,
-              typeFilter: self.typeFilter,
-              definition: {
-                uuid: details.parentUuid,
-                type: 'directory'
-              }
-            }));
-            self.activeEntry().load(function() {
-              whenLoaded.resolve();
-            }, function () {
-              whenLoaded.reject();
-              self.fallbackToRoot();
-            });
-          }
-        });
-      }
-
-      AssistDocumentsPanel.prototype.setTypeFilter = function (newType) {
-        var self = this;
-        DOCUMENT_TYPES.some(function (docType) {
-          if (docType.type === newType) {
-            self.typeFilter(docType);
-            return true;
-          }
-        });
-        self.highlightTypeFilter(true);
-        window.setTimeout(function () {
-          self.highlightTypeFilter(false);
-        }, 600)
-      };
-
-      AssistDocumentsPanel.prototype.fallbackToRoot = function () {
-        var self = this;
-        if (!self.activeEntry() || self.activeEntry().definition() && (self.activeEntry().definition().path !== '/' || self.activeEntry().definition().uuid)) {
-          window.apiHelper.setInTotalStorage('assist', 'last.opened.assist.doc.uuid', null);
-          self.activeEntry(new HueFileEntry({
-            activeEntry: self.activeEntry,
-            trashEntry: ko.observable(),
-            app: 'documents',
-            user: self.user,
-            activeSort: self.activeSort,
-            typeFilter: self.typeFilter,
-            definition: {
-              name: '/',
-              type: 'directory'
-            }
-          }));
-          self.activeEntry().load();
-        }
-      };
-
-      AssistDocumentsPanel.prototype.init = function () {
-        var self = this;
-        if (! self.activeEntry().loaded()) {
-          self.activeEntry().load(function () {}, function () {
-            self.fallbackToRoot();
-          }, true);
-        }
-      };
-
-      /**
-       * @param {Object} options
-       * @constructor
-       **/
-      function AssistHdfsPanel (options) {
-        var self = this;
-        self.selectedHdfsEntry = ko.observable();
-        self.loading = ko.observable();
-        self.initialized = false;
-
-        var loadPath = function (path) {
-          self.loading(true);
-          var parts = path.split('/');
-          parts.shift();
-
-          var currentEntry = new AssistStorageEntry({
-            type: 'hdfs',
-            definition: {
-              name: '/',
-              type: 'dir'
-            },
-            parent: null
-          });
-
-          currentEntry.loadDeep(parts, function (entry) {
-            self.selectedHdfsEntry(entry);
-            entry.open(true);
-            self.loading(false);
-          });
-        };
-
-        self.reload = function () {
-          loadPath(window.apiHelper.getFromTotalStorage('assist', 'currentHdfsPath', window.USER_HOME_DIR));
-        };
-
-        huePubSub.subscribe('assist.hdfs.go.home', function () {
-          loadPath(window.USER_HOME_DIR);
-          window.apiHelper.setInTotalStorage('assist', 'currentHdfsPath', window.USER_HOME_DIR);
-        });
-
-        huePubSub.subscribe('assist.selectHdfsEntry', function (entry) {
-          self.selectedHdfsEntry(entry);
-          window.apiHelper.setInTotalStorage('assist', 'currentHdfsPath', entry.path);
-        });
-
-        huePubSub.subscribe('assist.hdfs.refresh', function () {
-          huePubSub.publish('assist.clear.hdfs.cache');
-          self.reload();
-        });
-      }
-
-      AssistHdfsPanel.prototype.init = function () {
-        var self = this;
-        if (self.initialized) {
-          return;
-        }
-        self.reload();
-        self.initialized = true;
-      };
-
-      function AssistAdlsPanel (options) {
-        var self = this;
-        self.selectedAdlsEntry = ko.observable();
-        self.loading = ko.observable();
-        self.initialized = false;
-
-        var loadPath = function (path) {
-          self.loading(true);
-          var parts = path.split('/');
-          parts.shift();
-
-          var currentEntry = new AssistStorageEntry({
-            type: 'adls',
-            definition: {
-              name: '/',
-              type: 'dir'
-            },
-            parent: null
-          });
-
-          currentEntry.loadDeep(parts, function (entry) {
-            self.selectedAdlsEntry(entry);
-            entry.open(true);
-            self.loading(false);
-          });
-        };
-
-        self.reload = function () {
-          loadPath(window.apiHelper.getFromTotalStorage('assist', 'currentAdlsPath', '/'));
-        };
-
-        huePubSub.subscribe('assist.adls.go.home', function () {
-          loadPath(window.USER_HOME_DIR);
-          window.apiHelper.setInTotalStorage('assist', 'currentAdlsPath', window.USER_HOME_DIR);
-        });
-
-        huePubSub.subscribe('assist.selectAdlsEntry', function (entry) {
-          self.selectedAdlsEntry(entry);
-          window.apiHelper.setInTotalStorage('assist', 'currentAdlsPath', entry.path);
-        });
-
-        huePubSub.subscribe('assist.adls.refresh', function () {
-          huePubSub.publish('assist.clear.adls.cache');
-          self.reload();
-        });
-      }
-
-      AssistAdlsPanel.prototype.init = function () {
-        var self = this;
-        if (self.initialized) {
-          return;
-        }
-        self.reload();
-        self.initialized = true;
-      };
-
-      /**
-       * @param {Object} options
-       * @constructor
-       **/
-      function AssistGitPanel (options) {
-        var self = this;
-
-        self.selectedGitEntry = ko.observable();
-        self.reload = function () {
-          var lastKnownPath = window.apiHelper.getFromTotalStorage('assist', 'currentGitPath', window.USER_HOME_DIR);
-          var parts = lastKnownPath.split('/');
-          parts.shift();
-
-          var currentEntry = new AssistGitEntry({
-            definition: {
-              name: '/',
-              type: 'dir'
-            },
-            parent: null
-          });
-
-          currentEntry.loadDeep(parts, function (entry) {
-            self.selectedGitEntry(entry);
-            entry.open(true);
-          });
-        };
-
-        huePubSub.subscribe('assist.selectGitEntry', function (entry) {
-          self.selectedGitEntry(entry);
-          window.apiHelper.setInTotalStorage('assist', 'currentGitPath', entry.path);
-        });
-
-        huePubSub.subscribe('assist.git.refresh', function () {
-          huePubSub.publish('assist.clear.git.cache');
-          self.reload();
-        });
-      }
-
-      AssistGitPanel.prototype.init = function () {
-        this.reload();
-      };
-
-      /**
-       * @param {Object} options
-       * @constructor
-       **/
-      function AssistS3Panel (options) {
-        var self = this;
-
-        self.selectedS3Entry = ko.observable();
-        self.loading = ko.observable();
-        self.initialized = false;
-
-        self.reload = function () {
-          self.loading(true);
-          var lastKnownPath = window.apiHelper.getFromTotalStorage('assist', 'currentS3Path', '/');
-          var parts = lastKnownPath.split('/');
-          parts.shift();
-
-          var currentEntry = new AssistStorageEntry({
-            type: 's3',
-            definition: {
-              name: '/',
-              type: 'dir'
-            },
-            parent: null
-          });
-
-          currentEntry.loadDeep(parts, function (entry) {
-            self.selectedS3Entry(entry);
-            entry.open(true);
-            self.loading(false);
-          });
-        };
-
-        huePubSub.subscribe('assist.selectS3Entry', function (entry) {
-          self.selectedS3Entry(entry);
-          window.apiHelper.setInTotalStorage('assist', 'currentS3Path', entry.path);
-        });
-
-        huePubSub.subscribe('assist.s3.refresh', function () {
-          huePubSub.publish('assist.clear.s3.cache');
-          self.reload();
-        });
-      }
-
-      AssistS3Panel.prototype.init = function () {
-        var self = this;
-        if (self.initialized) {
-          return;
-        }
-        self.reload();
-        self.initialized = true;
-      };
-
-      /**
-       * @param {Object} options
-       * @constructor
-       **/
-      function AssistHBasePanel(options) {
-        var self = this;
-        self.initialized = false;
-
-        var root = new AssistHBaseEntry({
-          definition: {
-            host: '',
-            name: '',
-            port: 0
-          }
-        });
-
-        self.selectedHBaseEntry = ko.observable();
-        self.reload = function () {
-          self.selectedHBaseEntry(root);
-          root.loadEntries(function () {
-            var lastOpenendPath = window.apiHelper.getFromTotalStorage('assist', 'last.opened.hbase.entry', null);
-            if (lastOpenendPath) {
-              root.entries().every(function (entry) {
-                if (entry.path === lastOpenendPath) {
-                  entry.open();
-                  return false;
-                }
-                return true;
-              })
-            }
-          });
-        };
-
-        self.selectedHBaseEntry.subscribe(function (newEntry) {
-          if (newEntry !== root || (newEntry === root && newEntry.loaded)) {
-            window.apiHelper.setInTotalStorage('assist', 'last.opened.hbase.entry', newEntry.path);
-          }
-        });
-
-        huePubSub.subscribe('assist.clickHBaseItem', function (entry) {
-          if (entry.definition.host) {
-            entry.loadEntries();
-            self.selectedHBaseEntry(entry);
-          }
-          else {
-            huePubSub.publish('assist.dblClickHBaseItem', entry);
-          }
-        });
-
-        huePubSub.subscribe('assist.clickHBaseRootItem', function (entry) {
-          self.reload();
-        });
-
-        var delayChangeHash = function (hash) {
-          window.setTimeout(function () {
-            window.location.hash = hash;
-          }, 0);
-        };
-
-        self.lastClickeHBaseEntry = null;
-        self.HBaseLoaded = false;
-
-        huePubSub.subscribeOnce('hbase.app.loaded', function() {
-          if (self.selectedHBaseEntry() && self.lastClickeHBaseEntry) {
-            delayChangeHash(self.selectedHBaseEntry().definition.name + '/' + self.lastClickeHBaseEntry.definition.name);
-          }
-          self.HBaseLoaded = true;
-        });
-
-        huePubSub.subscribe('assist.dblClickHBaseItem', function (entry) {
-          var hash = self.selectedHBaseEntry().definition.name + '/' + entry.definition.name;
-          if (window.location.pathname.startsWith('/hue/hbase')) {
-            window.location.hash = hash;
-          } else {
-            self.lastClickeHBaseEntry = entry;
-            huePubSub.subscribeOnce('app.gained.focus', function (app) {
-              if (app === 'hbase' && self.HBaseLoaded) {
-                delayChangeHash(hash);
-              }
-            });
-            huePubSub.publish('open.link', '/hbase');
-          }
-        });
-
-        huePubSub.subscribe('assist.hbase.refresh', function () {
-          huePubSub.publish('assist.clear.hbase.cache');
-          self.reload();
-        });
-      }
-
-      AssistHBasePanel.prototype.init = function () {
-        var self = this;
-        if (self.initialized) {
-          return;
-        }
-        self.reload();
-        self.initialized = true;
-      };
-
       var NAV_FACET_ICON = 'fa-tags';
       var NAV_TYPE_ICONS = {
         'DATABASE': 'fa-database',