Browse Source

[assist] Extract assist panel into separate mako file

Johan Ahlen 10 years ago
parent
commit
60282060cc

+ 2 - 2
apps/beeswax/src/beeswax/templates/execute.mako

@@ -23,7 +23,7 @@
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="dashboard" file="common_dashboard.mako" />
-<%namespace name="koComponents" file="/ko_components.mako" />
+<%namespace name="assist" file="/assist.mako" />
 
 ${ commonheader(_('Query'), app_name, user) | n,unicode }
 ${ layout.menubar(section='query') }
@@ -837,7 +837,7 @@ ${ commonshare() | n,unicode }
 <script src="${ static('desktop/ext/select2/select2.min.js') }" type="text/javascript" charset="utf-8"></script>
 
 
-${ koComponents.assistPanel() }
+${ assist.assistPanel() }
 
 <style type="text/css">
   h1 {

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

@@ -0,0 +1,348 @@
+## 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.
+
+<%!
+from desktop import conf
+from desktop.lib.i18n import smart_unicode
+from django.utils.translation import ugettext as _
+from desktop.views import _ko
+%>
+
+<%def name="assistPanel()">
+  <style>
+    .assist-tables {
+      overflow-y: hidden;
+      overflow-x: auto;
+      margin-left: 7px;
+    }
+
+    .assist-tables a {
+      text-decoration: none;
+    }
+
+    .assist-tables li {
+      list-style: none;
+    }
+
+    .assist-tables > li {
+      position: relative;
+      padding-top: 2px;
+      padding-bottom: 2px;
+    }
+
+    .assist-tables-counter {
+      color: #d1d1d1;
+      font-weight: normal;
+    }
+
+    .assist-table-link {
+      font-size: 13px;
+    }
+
+    .assist-field-link {
+      font-size: 12px;
+    }
+
+    .assist-table-link,
+    .assist-table-link:focus {
+      color: #444;
+    }
+
+    .assist-field-link,
+    .assist-field-link:focus {
+      white-space: nowrap;
+      color: #737373;
+    }
+
+    .assist-columns {
+      margin-left: 0px;
+    }
+
+    .assist-columns > li {
+      padding: 6px 5px;
+      white-space: nowrap;
+    }
+
+    .assist-actions  {
+      position:absolute;
+      right: 0px;
+      padding-right:4px;
+      padding-left:4px;
+      background-color: #FFF;
+    }
+
+    .assist .nav-header {
+      margin-right: 0 !important;
+      padding-right: 4px !important;
+    }
+  </style>
+
+  <script type="text/html" id="assist-panel-table-stats">
+    <div class="content">
+      <!-- ko if: statRows().length -->
+      <table class="table table-striped">
+        <tbody data-bind="foreach: statRows">
+          <tr><th data-bind="text: data_type"></th><td data-bind="text: comment"></td></tr>
+        </tbody>
+      </table>
+      <!-- /ko -->
+    </div>
+  </script>
+
+  <script type="text/html" id="assist-panel-column-stats">
+    <div class="pull-right filter" data-bind="visible: termsTabActive" style="display:none;">
+      <input type="text" data-bind="textInput: prefixFilter" placeholder="${ _('Prefix filter...') }"/>
+    </div>
+    <ul class="nav nav-tabs" role="tablist" style="margin-bottom: 0">
+      <li data-bind="click: function() { termsTabActive(false) }" class="active"><a href="#columnAnalysisStats" role="tab" data-toggle="tab">${ _('Stats') }</a></li>
+      <li data-bind="click: function() { termsTabActive(true) }"><a href="#columnAnalysisTerms" role="tab" data-toggle="tab">${ _('Terms') }</a></li>
+    </ul>
+    <div class="tab-content">
+      <div class="tab-pane active" id="columnAnalysisStats" style="text-align: left">
+        <div class="alert" data-bind="visible: isComplexType" style="margin: 5px">${ _('Column stats are currently not supported for columns of type:') } <span data-bind="text: type"></span></div>
+        <div class="content" data-bind="ifnot: isComplexType">
+          <table class="table table-striped">
+            <tbody data-bind="foreach: statRows">
+              <tr><th data-bind="text: Object.keys($data)[0]"></th><td data-bind="text: $data[Object.keys($data)[0]]"></td></tr>
+            </tbody>
+          </table>
+        </div>
+      </div>
+      <div class="tab-pane" id="columnAnalysisTerms" style="text-align: left">
+        <i style="margin: 5px;" data-bind="visible: loadingTerms" class='fa fa-spinner fa-spin'></i>
+        <div class="alert" data-bind="visible: ! loadingTerms() && terms().length == 0">${ _('There are no terms to be shown') }</div>
+        <div class="content">
+          <table class="table table-striped" data-bind="visible: ! loadingTerms()">
+            <tbody data-bind="foreach: terms">
+              <tr><td data-bind="text: name"></td><td style="width: 40px"><div class="progress"><div class="bar-label" data-bind="text: count"></div><div class="bar bar-info" style="margin-top: -20px;" data-bind="style: { 'width' : percent + '%' }"></div></div></td></tr>
+            </tbody>
+          </table>
+        </div>
+      </div>
+    </div>
+  </script>
+
+  <script type="text/html" id="assist-no-entries">
+    <ul class="assist-tables">
+      <li data-bind="visible: definition.isDatabase">
+        <span>${_('The selected database has no tables.')}</span>
+      </li>
+      <li data-bind="visible: definition.isTable">
+        <span>${_('The selected table has no columns.')}</span>
+      </li>
+    </ul>
+  </script>
+
+  <script type="text/html" id="assist-entry-actions">
+    <div class="assist-actions" data-bind="css: { 'table-actions' : definition.isTable, 'column-actions': definition.isColumn } " style="opacity: 0">
+      <a class="inactive-action" href="javascript:void(0)" data-bind="visible: definition.isTable, click: showPreview"><i class="fa fa-list" title="${_('Preview Sample data')}"></i></a>
+      <a class="inactive-action" href="javascript:void(0)" data-bind="visible: definition.isTable || definition.isColumn, click: showStats, css: { 'blue': statsVisible }"><i class='fa fa-bar-chart' title="${_('View statistics') }"></i></a>
+    </div>
+  </script>
+
+  <script type="text/html" id="assist-entries">
+    <ul data-bind="foreach: filteredEntries, css: { 'assist-tables': definition.isDatabase }, event: { 'scroll': assistSource.repositionActions }">
+      <li data-bind="visibleOnHover: { override: statsVisible, selector: definition.isTable ? '.table-actions' : '.column-actions' }, css: { 'assist-table': definition.isTable, 'assist-column': definition.isColumn }">
+        <!-- ko template: { if: definition.isTable || definition.isColumn, name: 'assist-entry-actions' } --><!-- /ko -->
+        <a class="assist-column-link" data-bind="multiClick: { click: toggleOpen, dblClick: dblClick }, attr: {'title': definition.title }, css: { 'assist-field-link': ! definition.isTable, 'assist-table-link': definition.isTable }" href="javascript:void(0)">
+          <span draggable="true" data-bind="text: definition.displayName, draggableText: { text: editorText }"></span>
+        </a>
+        <!-- ko template: { if: open(), name: 'assist-entries'  } --><!-- /ko -->
+      </li>
+    </ul>
+    <!-- ko template: { if: ! hasEntries() && ! loading(), name: 'assist-no-entries' } --><!-- /ko -->
+  </script>
+
+  <script type="text/html" id="assist-panel-template">
+    <ul class="nav nav-list" style="position:relative; border: none; padding: 0; background-color: #FFF; margin-bottom: 1px; width:100%;">
+      <!-- ko if: availableSourceTypes.length > 1 -->
+      <li class="nav-header">
+        ${_('source')}
+      </li>
+      <li>
+        <select data-bind="options: availableSourceTypes, select2: { width: '100%', placeholder: '${ _ko("Choose a source...") }', update: selectedSourceType }" class="input-medium" data-placeholder="${_('Choose a source...')}"></select>
+      </li>
+      <!-- /ko -->
+      <!-- ko with: selectedSource -->
+      <!-- ko template: { name: "assist-type-template" } --><!-- /ko -->
+      <!-- /ko -->
+    </ul>
+  </script>
+
+  <script type="text/html" id="assist-type-template">
+    <div data-bind="visibleOnHover: { selector: '.hover-actions' }" style="position: relative; width:100%">
+      <li class="nav-header">
+        ${_('database')}
+        <div class="pull-right" data-bind="css: { 'hover-actions' : ! reloading() }">
+          <a class="inactive-action" href="javascript:void(0)" data-bind="click: reloadAssist"><i class="pointer fa fa-refresh" data-bind="css: { 'fa-spin' : reloading }" title="${_('Manually refresh the table list')}"></i></a>
+        </div>
+      </li>
+
+      <li data-bind="visible: ! hasErrors() && ! assistHelper.loading()" >
+        <div data-bind="select2: { options: assistHelper.availableDatabases, value: assistHelper.activeDatabase, width: '100%', placeholder: '${ _ko("Choose a database...") }' }" class="input-medium" data-placeholder="${_('Choose a database...')}"></div>
+      </li>
+
+      <li class="center" data-bind="visible: assistHelper.loading()" >
+        <!--[if !IE]><!--><i class="fa fa-spinner fa-spin" style="font-size: 20px; color: #BBB"></i><!--<![endif]-->
+        <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }"/><![endif]-->
+      </li>
+
+      <li data-bind="visible: hasErrors">
+        <span>${ _('The database list cannot be loaded.') }</span>
+      </li>
+
+      <li class="nav-header" style="margin-top:10px;" data-bind="visible: ! assistHelper.loading() && ! hasErrors()">
+        ${_('tables')}
+        <div class="pull-right" data-bind="visible: selectedDatabase() != null && selectedDatabase().hasEntries(), css: { 'hover-actions': ! filter(), 'blue': filter }">
+          <!-- ko if: selectedDatabase() != null -->
+          <span class="assist-tables-counter">(<span data-bind="text: selectedDatabase().filteredEntries().length"></span>)</span>
+          <!-- /ko -->
+          <a class="inactive-action" href="javascript:void(0)" data-bind="click: toggleSearch"><i class="pointer fa fa-search" title="${_('Search')}"></i></a>
+        </div>
+      </li>
+
+      <!-- ko if: selectedDatabase() != null -->
+        <li data-bind="slideVisible: selectedDatabase() != null && selectedDatabase().hasEntries() && options.isSearchVisible()">
+          <div><input type="text" placeholder="${ _('Table name...') }" style="width:90%;" data-bind="value: filter, valueUpdate: 'afterkeydown'"/></div>
+        </li>
+
+      <div class="table-container">
+        <div class="center" data-bind="visible: selectedDatabase() != null && selectedDatabase().loading()">
+          <!--[if !IE]><!--><i class="fa fa-spinner fa-spin" style="font-size: 20px; color: #BBB"></i><!--<![endif]-->
+          <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }"/><![endif]-->
+        </div>
+        <!-- ko template: { if: selectedDatabase() != null, name: 'assist-entries', data: selectedDatabase } --><!-- /ko -->
+        </div>
+      <!-- /ko -->
+    </div>
+
+    <div id="assistQuickLook" class="modal hide fade">
+      <div class="modal-header">
+        <a href="#" class="close" data-dismiss="modal">&times;</a>
+        <a class="tableLink pull-right" href="#" target="_blank" style="margin-right: 20px;margin-top:6px">
+          <i class="fa fa-external-link"></i> ${ _('View in Metastore Browser') }
+        </a>
+        <h3>${_('Data sample for')} <span class="tableName"></span></h3>
+      </div>
+      <div class="modal-body" style="min-height: 100px">
+        <div class="loader">
+          <!--[if !IE]><!--><i class="fa fa-spinner fa-spin" style="font-size: 30px; color: #DDD"></i><!--<![endif]-->
+          <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }"/><![endif]-->
+        </div>
+        <div class="sample"></div>
+      </div>
+      <div class="modal-footer">
+        <button class="btn btn-primary disable-feedback" data-dismiss="modal">${_('Ok')}</button>
+      </div>
+    </div>
+
+    <div id="tableAnalysis" style="position: fixed; display: none;" class="popover show mega-popover right" data-bind="visible: analysisStats() != null, with: analysisStats">
+      <div class="arrow"></div>
+      <h3 class="popover-title" style="text-align: left">
+        <a class="pull-right pointer close-popover" style="margin-left: 8px" data-bind="click: function() { $parent.analysisStats(null) }"><i class="fa fa-times"></i></a>
+        <a class="pull-right pointer stats-refresh" style="margin-left: 8px" data-bind="visible: !isComplexType, click: refresh"><i class="fa fa-refresh" data-bind="css: { 'fa-spin' : refreshing }"></i></a>
+        <span class="pull-right stats-warning muted" data-bind="visible: inaccurate() && column == null" rel="tooltip" data-placement="top" title="${ _('The column stats for this table are not accurate') }" style="margin-left: 8px"><i class="fa fa-exclamation-triangle"></i></span>
+        <i data-bind="visible: loading" class='fa fa-spinner fa-spin'></i>
+        <!-- ko if: column == null -->
+        <strong class="table-name" data-bind="text: table"></strong> ${ _(' table analysis') }
+        <!-- /ko -->
+        <!-- ko ifnot: column == null -->
+        <strong class="table-name" data-bind="text: column"></strong> ${ _(' column analysis') }
+        <!-- /ko -->
+      </h3>
+      <div class="popover-content">
+        <div class="alert" style="text-align: left; display:none" data-bind="visible: hasError">${ _('There is no analysis available') }</div>
+        <!-- ko if: isComplexType && snippet.type() == 'impala' -->
+        <div class="alert" style="text-align: left">${ _('Column analysis is currently not supported for columns of type:') } <span data-bind="text: type"></span></div>
+        <!-- /ko -->
+        <!-- ko template: {if: column == null && ! hasError() && ! (isComplexType && snippet.type() == 'impala'), name: 'assist-panel-table-stats' } --><!-- /ko -->
+        <!-- ko template: {if: column != null && ! hasError() && ! (isComplexType && snippet.type() == 'impala'), name: 'assist-panel-column-stats' } --><!-- /ko -->
+      </div>
+    </div>
+  </script>
+
+  <script type="text/javascript" charset="utf-8">
+    (function (factory) {
+      if(typeof require === "function") {
+        require(['knockout', 'desktop/js/assist/assistSource'], factory);
+      } else {
+        factory(ko, AssistSource);
+      }
+    }(function (ko, AssistSource) {
+
+      function AssistPanel(params) {
+        var i18n = {
+          errorLoadingTablePreview: "${ _('There was a problem loading the table preview.') }",
+          errorLoadingStats: "${ _('There was a problem loading the stats.') }",
+          errorRefreshingStats: "${ _('There was a problem refreshing the stats.') }",
+          errorLoadingTerms: "${ _('There was a problem loading the terms.') }"
+        }
+        var notebookViewModel = params.notebookViewModel;
+        var notebook = notebookViewModel.selectedNotebook();
+
+        self.sourceIndex = {};
+        $.each(notebookViewModel.availableSnippets(), function (index, snippet) {
+          var settings = notebookViewModel.getSnippetViewSettings(snippet.type());
+
+          var fakeSnippet = {
+            type: snippet.type,
+            getContext: function() {
+              return {
+                type: snippet.type()
+              }
+            },
+            getAssistHelper: function() {
+              return notebook.getAssistHelper(snippet.type());
+            }
+          };
+
+          if (settings.sqlDialect) {
+            self.sourceIndex[snippet.name()] = new AssistSource(fakeSnippet, i18n);
+          }
+        });
+
+        self.availableSourceTypes = Object.keys(self.sourceIndex);
+
+        self.selectedSourceType = ko.observable();
+        self.selectedSource = ko.observable();
+
+        self.selectedSourceType.subscribe(function (newSourceType) {
+          var source = self.sourceIndex[newSourceType];
+          if (! source.assistHelper.loaded()) {
+            source.assistHelper.load(source.snippet);
+          }
+          self.selectedSource(source);
+        });
+
+        var lastSelectedSource =  $.totalStorage("hue.assist.lastSelectedSource." + notebookViewModel.user);
+        if ($.inArray(lastSelectedSource, self.availableSourceTypes) !== -1) {
+          self.selectedSourceType(lastSelectedSource);
+        } else {
+          self.selectedSourceType(self.availableSourceTypes[0]);
+        }
+
+        self.selectedSourceType.subscribe(function (newSourceType) {
+          $.totalStorage("hue.assist.lastSelectedSource." + notebookViewModel.user, newSourceType);
+        });
+      }
+
+      ko.components.register('assist-panel', {
+        viewModel: AssistPanel,
+        template: { element: 'assist-panel-template' }
+      });
+    }));
+  </script>
+</%def>

+ 0 - 326
desktop/core/src/desktop/templates/ko_components.mako

@@ -21,332 +21,6 @@ from django.utils.translation import ugettext as _
 from desktop.views import _ko
 %>
 
-<%def name="assistPanel()">
-  <style>
-    .assist-tables {
-      overflow-y: hidden;
-      overflow-x: auto;
-      margin-left: 7px;
-    }
-
-    .assist-tables a {
-      text-decoration: none;
-    }
-
-    .assist-tables li {
-      list-style: none;
-    }
-
-    .assist-tables > li {
-      position: relative;
-      padding-top: 2px;
-      padding-bottom: 2px;
-    }
-
-    .assist-tables-counter {
-      color: #d1d1d1;
-      font-weight: normal;
-    }
-
-    .assist-table-link {
-      font-size: 13px;
-    }
-
-    .assist-field-link {
-      font-size: 12px;
-    }
-
-    .assist-table-link,
-    .assist-table-link:focus {
-      color: #444;
-    }
-
-    .assist-field-link,
-    .assist-field-link:focus {
-      white-space: nowrap;
-      color: #737373;
-    }
-
-    .assist-columns {
-      margin-left: 0px;
-    }
-
-    .assist-columns > li {
-      padding: 6px 5px;
-      white-space: nowrap;
-    }
-
-    .assist-actions  {
-      position:absolute;
-      right: 0px;
-      padding-right:4px;
-      padding-left:4px;
-      background-color: #FFF;
-    }
-
-    .assist .nav-header {
-      margin-right: 0 !important;
-      padding-right: 4px !important;
-    }
-  </style>
-
-  <script type="text/html" id="assist-panel-table-stats">
-    <div class="content">
-      <!-- ko if: statRows().length -->
-      <table class="table table-striped">
-        <tbody data-bind="foreach: statRows">
-          <tr><th data-bind="text: data_type"></th><td data-bind="text: comment"></td></tr>
-        </tbody>
-      </table>
-      <!-- /ko -->
-    </div>
-  </script>
-
-  <script type="text/html" id="assist-panel-column-stats">
-    <div class="pull-right filter" data-bind="visible: termsTabActive" style="display:none;">
-      <input type="text" data-bind="textInput: prefixFilter" placeholder="${ _('Prefix filter...') }"/>
-    </div>
-    <ul class="nav nav-tabs" role="tablist" style="margin-bottom: 0">
-      <li data-bind="click: function() { termsTabActive(false) }" class="active"><a href="#columnAnalysisStats" role="tab" data-toggle="tab">${ _('Stats') }</a></li>
-      <li data-bind="click: function() { termsTabActive(true) }"><a href="#columnAnalysisTerms" role="tab" data-toggle="tab">${ _('Terms') }</a></li>
-    </ul>
-    <div class="tab-content">
-      <div class="tab-pane active" id="columnAnalysisStats" style="text-align: left">
-        <div class="alert" data-bind="visible: isComplexType" style="margin: 5px">${ _('Column stats are currently not supported for columns of type:') } <span data-bind="text: type"></span></div>
-        <div class="content" data-bind="ifnot: isComplexType">
-          <table class="table table-striped">
-            <tbody data-bind="foreach: statRows">
-              <tr><th data-bind="text: Object.keys($data)[0]"></th><td data-bind="text: $data[Object.keys($data)[0]]"></td></tr>
-            </tbody>
-          </table>
-        </div>
-      </div>
-      <div class="tab-pane" id="columnAnalysisTerms" style="text-align: left">
-        <i style="margin: 5px;" data-bind="visible: loadingTerms" class='fa fa-spinner fa-spin'></i>
-        <div class="alert" data-bind="visible: ! loadingTerms() && terms().length == 0">${ _('There are no terms to be shown') }</div>
-        <div class="content">
-          <table class="table table-striped" data-bind="visible: ! loadingTerms()">
-            <tbody data-bind="foreach: terms">
-              <tr><td data-bind="text: name"></td><td style="width: 40px"><div class="progress"><div class="bar-label" data-bind="text: count"></div><div class="bar bar-info" style="margin-top: -20px;" data-bind="style: { 'width' : percent + '%' }"></div></div></td></tr>
-            </tbody>
-          </table>
-        </div>
-      </div>
-    </div>
-  </script>
-
-  <script type="text/html" id="assist-no-entries">
-    <ul class="assist-tables">
-      <li data-bind="visible: definition.isDatabase">
-        <span>${_('The selected database has no tables.')}</span>
-      </li>
-      <li data-bind="visible: definition.isTable">
-        <span>${_('The selected table has no columns.')}</span>
-      </li>
-    </ul>
-  </script>
-
-  <script type="text/html" id="assist-entry-actions">
-    <div class="assist-actions" data-bind="css: { 'table-actions' : definition.isTable, 'column-actions': definition.isColumn } " style="opacity: 0">
-      <a class="inactive-action" href="javascript:void(0)" data-bind="visible: definition.isTable, click: showPreview"><i class="fa fa-list" title="${_('Preview Sample data')}"></i></a>
-      <a class="inactive-action" href="javascript:void(0)" data-bind="visible: definition.isTable || definition.isColumn, click: showStats, css: { 'blue': statsVisible }"><i class='fa fa-bar-chart' title="${_('View statistics') }"></i></a>
-    </div>
-  </script>
-
-  <script type="text/html" id="assist-entries">
-    <ul data-bind="foreach: filteredEntries, css: { 'assist-tables': definition.isDatabase }, event: { 'scroll': assistSource.repositionActions }">
-      <li data-bind="visibleOnHover: { override: statsVisible, selector: definition.isTable ? '.table-actions' : '.column-actions' }, css: { 'assist-table': definition.isTable, 'assist-column': definition.isColumn }">
-        <!-- ko template: { if: definition.isTable || definition.isColumn, name: 'assist-entry-actions' } --><!-- /ko -->
-        <a class="assist-column-link" data-bind="multiClick: { click: toggleOpen, dblClick: dblClick }, attr: {'title': definition.title }, css: { 'assist-field-link': ! definition.isTable, 'assist-table-link': definition.isTable }" href="javascript:void(0)">
-          <span draggable="true" data-bind="text: definition.displayName, draggableText: { text: editorText }"></span>
-        </a>
-        <!-- ko template: { if: open(), name: 'assist-entries'  } --><!-- /ko -->
-      </li>
-    </ul>
-    <!-- ko template: { if: ! hasEntries() && ! loading(), name: 'assist-no-entries' } --><!-- /ko -->
-  </script>
-
-  <script type="text/html" id="assist-panel-template">
-    <ul class="nav nav-list" style="position:relative; border: none; padding: 0; background-color: #FFF; margin-bottom: 1px; width:100%;">
-      <!-- ko if: availableSourceTypes.length > 1 -->
-      <li class="nav-header">
-        ${_('source')}
-      </li>
-      <li>
-        <select data-bind="options: availableSourceTypes, select2: { width: '100%', placeholder: '${ _ko("Choose a source...") }', update: selectedSourceType }" class="input-medium" data-placeholder="${_('Choose a source...')}"></select>
-      </li>
-      <!-- /ko -->
-      <!-- ko with: selectedSource -->
-      <!-- ko template: { name: "assist-type-template" } --><!-- /ko -->
-      <!-- /ko -->
-    </ul>
-  </script>
-
-  <script type="text/html" id="assist-type-template">
-    <div data-bind="visibleOnHover: { selector: '.hover-actions' }" style="position: relative; width:100%">
-      <li class="nav-header">
-        ${_('database')}
-        <div class="pull-right" data-bind="css: { 'hover-actions' : ! reloading() }">
-          <a class="inactive-action" href="javascript:void(0)" data-bind="click: reloadAssist"><i class="pointer fa fa-refresh" data-bind="css: { 'fa-spin' : reloading }" title="${_('Manually refresh the table list')}"></i></a>
-        </div>
-      </li>
-
-      <li data-bind="visible: ! hasErrors() && ! assistHelper.loading()" >
-        <div data-bind="select2: { options: assistHelper.availableDatabases, value: assistHelper.activeDatabase, width: '100%', placeholder: '${ _ko("Choose a database...") }' }" class="input-medium" data-placeholder="${_('Choose a database...')}"></div>
-      </li>
-
-      <li class="center" data-bind="visible: assistHelper.loading()" >
-        <!--[if !IE]><!--><i class="fa fa-spinner fa-spin" style="font-size: 20px; color: #BBB"></i><!--<![endif]-->
-        <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }"/><![endif]-->
-      </li>
-
-      <li data-bind="visible: hasErrors">
-        <span>${ _('The database list cannot be loaded.') }</span>
-      </li>
-
-      <li class="nav-header" style="margin-top:10px;" data-bind="visible: ! assistHelper.loading() && ! hasErrors()">
-        ${_('tables')}
-        <div class="pull-right" data-bind="visible: selectedDatabase() != null && selectedDatabase().hasEntries(), css: { 'hover-actions': ! filter(), 'blue': filter }">
-          <!-- ko if: selectedDatabase() != null -->
-          <span class="assist-tables-counter">(<span data-bind="text: selectedDatabase().filteredEntries().length"></span>)</span>
-          <!-- /ko -->
-          <a class="inactive-action" href="javascript:void(0)" data-bind="click: toggleSearch"><i class="pointer fa fa-search" title="${_('Search')}"></i></a>
-        </div>
-      </li>
-
-      <!-- ko if: selectedDatabase() != null -->
-        <li data-bind="slideVisible: selectedDatabase() != null && selectedDatabase().hasEntries() && options.isSearchVisible()">
-          <div><input type="text" placeholder="${ _('Table name...') }" style="width:90%;" data-bind="value: filter, valueUpdate: 'afterkeydown'"/></div>
-        </li>
-
-      <div class="table-container">
-        <div class="center" data-bind="visible: selectedDatabase() != null && selectedDatabase().loading()">
-          <!--[if !IE]><!--><i class="fa fa-spinner fa-spin" style="font-size: 20px; color: #BBB"></i><!--<![endif]-->
-          <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }"/><![endif]-->
-        </div>
-        <!-- ko template: { if: selectedDatabase() != null, name: 'assist-entries', data: selectedDatabase } --><!-- /ko -->
-        </div>
-      <!-- /ko -->
-    </div>
-
-    <div id="assistQuickLook" class="modal hide fade">
-      <div class="modal-header">
-        <a href="#" class="close" data-dismiss="modal">&times;</a>
-        <a class="tableLink pull-right" href="#" target="_blank" style="margin-right: 20px;margin-top:6px">
-          <i class="fa fa-external-link"></i> ${ _('View in Metastore Browser') }
-        </a>
-        <h3>${_('Data sample for')} <span class="tableName"></span></h3>
-      </div>
-      <div class="modal-body" style="min-height: 100px">
-        <div class="loader">
-          <!--[if !IE]><!--><i class="fa fa-spinner fa-spin" style="font-size: 30px; color: #DDD"></i><!--<![endif]-->
-          <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }"/><![endif]-->
-        </div>
-        <div class="sample"></div>
-      </div>
-      <div class="modal-footer">
-        <button class="btn btn-primary disable-feedback" data-dismiss="modal">${_('Ok')}</button>
-      </div>
-    </div>
-
-    <div id="tableAnalysis" style="position: fixed; display: none;" class="popover show mega-popover right" data-bind="visible: analysisStats() != null, with: analysisStats">
-      <div class="arrow"></div>
-      <h3 class="popover-title" style="text-align: left">
-        <a class="pull-right pointer close-popover" style="margin-left: 8px" data-bind="click: function() { $parent.analysisStats(null) }"><i class="fa fa-times"></i></a>
-        <a class="pull-right pointer stats-refresh" style="margin-left: 8px" data-bind="visible: !isComplexType, click: refresh"><i class="fa fa-refresh" data-bind="css: { 'fa-spin' : refreshing }"></i></a>
-        <span class="pull-right stats-warning muted" data-bind="visible: inaccurate() && column == null" rel="tooltip" data-placement="top" title="${ _('The column stats for this table are not accurate') }" style="margin-left: 8px"><i class="fa fa-exclamation-triangle"></i></span>
-        <i data-bind="visible: loading" class='fa fa-spinner fa-spin'></i>
-        <!-- ko if: column == null -->
-        <strong class="table-name" data-bind="text: table"></strong> ${ _(' table analysis') }
-        <!-- /ko -->
-        <!-- ko ifnot: column == null -->
-        <strong class="table-name" data-bind="text: column"></strong> ${ _(' column analysis') }
-        <!-- /ko -->
-      </h3>
-      <div class="popover-content">
-        <div class="alert" style="text-align: left; display:none" data-bind="visible: hasError">${ _('There is no analysis available') }</div>
-        <!-- ko if: isComplexType && snippet.type() == 'impala' -->
-        <div class="alert" style="text-align: left">${ _('Column analysis is currently not supported for columns of type:') } <span data-bind="text: type"></span></div>
-        <!-- /ko -->
-        <!-- ko template: {if: column == null && ! hasError() && ! (isComplexType && snippet.type() == 'impala'), name: 'assist-panel-table-stats' } --><!-- /ko -->
-        <!-- ko template: {if: column != null && ! hasError() && ! (isComplexType && snippet.type() == 'impala'), name: 'assist-panel-column-stats' } --><!-- /ko -->
-      </div>
-    </div>
-  </script>
-
-  <script type="text/javascript" charset="utf-8">
-    (function (factory) {
-      if(typeof require === "function") {
-        require(['knockout', 'desktop/js/assist/assistSource'], factory);
-      } else {
-        factory(ko, AssistSource);
-      }
-    }(function (ko, AssistSource) {
-
-      function AssistPanel(params) {
-        var i18n = {
-          errorLoadingTablePreview: "${ _('There was a problem loading the table preview.') }",
-          errorLoadingStats: "${ _('There was a problem loading the stats.') }",
-          errorRefreshingStats: "${ _('There was a problem refreshing the stats.') }",
-          errorLoadingTerms: "${ _('There was a problem loading the terms.') }"
-        }
-        var notebookViewModel = params.notebookViewModel;
-        var notebook = notebookViewModel.selectedNotebook();
-
-        self.sourceIndex = {};
-        $.each(notebookViewModel.availableSnippets(), function (index, snippet) {
-          var settings = notebookViewModel.getSnippetViewSettings(snippet.type());
-
-          var fakeSnippet = {
-            type: snippet.type,
-            getContext: function() {
-              return {
-                type: snippet.type()
-              }
-            },
-            getAssistHelper: function() {
-              return notebook.getAssistHelper(snippet.type());
-            }
-          };
-
-          if (settings.sqlDialect) {
-            self.sourceIndex[snippet.name()] = new AssistSource(fakeSnippet, i18n);
-          }
-        });
-
-        self.availableSourceTypes = Object.keys(self.sourceIndex);
-
-        self.selectedSourceType = ko.observable();
-        self.selectedSource = ko.observable();
-
-        self.selectedSourceType.subscribe(function (newSourceType) {
-          var source = self.sourceIndex[newSourceType];
-          if (! source.assistHelper.loaded()) {
-            source.assistHelper.load(source.snippet);
-          }
-          self.selectedSource(source);
-        });
-
-        var lastSelectedSource =  $.totalStorage("hue.assist.lastSelectedSource." + notebookViewModel.user);
-        if ($.inArray(lastSelectedSource, self.availableSourceTypes) !== -1) {
-          self.selectedSourceType(lastSelectedSource);
-        } else {
-          self.selectedSourceType(self.availableSourceTypes[0]);
-        }
-
-        self.selectedSourceType.subscribe(function (newSourceType) {
-          $.totalStorage("hue.assist.lastSelectedSource." + notebookViewModel.user, newSourceType);
-        });
-      }
-
-      ko.components.register('assist-panel', {
-        viewModel: AssistPanel,
-        template: { element: 'assist-panel-template' }
-      });
-    }));
-  </script>
-</%def>
-
 <%def name="jvmMemoryInput()">
   <script type="text/html" id="jvm-memory-input-template">
     <input type="text" class="input-small" data-bind="numericTextInput: { value: value, precision: 0, allowEmpty: true }" /> <select class="input-mini" data-bind="options: units, value: selectedUnit" />

+ 2 - 1
desktop/libs/notebook/src/notebook/templates/editor.mako

@@ -20,6 +20,7 @@
 %>
 
 <%namespace name="koComponents" file="/ko_components.mako" />
+<%namespace name="assist" file="/assist.mako" />
 <%namespace name="editorComponents" file="editor_components.mako" />
 
 ${ commonheader(_('Editor'), editor_type, user, "68px") | n,unicode }
@@ -38,9 +39,9 @@ ${ editorComponents.topBar('editor', editor_type) }
 ${ editorComponents.commonHTML() }
 
 
+${ assist.assistPanel() }
 ${ koComponents.csvListInput() }
 ${ koComponents.jvmMemoryInput() }
-${ koComponents.assistPanel() }
 ${ koComponents.downloadSnippetResults() }
 
 ${ editorComponents.commonJS() }

+ 2 - 1
desktop/libs/notebook/src/notebook/templates/notebook.mako

@@ -19,6 +19,7 @@
   from django.utils.translation import ugettext as _
 %>
 
+<%namespace name="assist" file="/assist.mako" />
 <%namespace name="koComponents" file="/ko_components.mako" />
 <%namespace name="editorComponents" file="editor_components.mako" />
 
@@ -53,9 +54,9 @@ ${ editorComponents.topBar('notebook') }
   </%def>
 </%editorComponents:commonHTML>
 
+${ assist.assistPanel() }
 ${ koComponents.csvListInput() }
 ${ koComponents.jvmMemoryInput() }
-${ koComponents.assistPanel() }
 ${ koComponents.addSnippetMenu() }
 ${ koComponents.downloadSnippetResults() }