Просмотр исходного кода

HUE-9013 [editor] Extract grid component for notebook 2

Johan Ahlen 6 лет назад
Родитель
Сommit
b32dbe3fe2

+ 146 - 0
desktop/core/src/desktop/js/apps/notebook2/components/resultGrid/ko.resultGrid.js

@@ -0,0 +1,146 @@
+// 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';
+import DisposableComponent from 'ko/components/DisposableComponent';
+import I18n from 'utils/i18n';
+
+export const NAME = 'result-grid';
+
+// prettier-ignore
+const TEMPLATE = `
+<div>
+  <div class="column-side" style="position: relative; white-space: nowrap;" data-bind="
+      visible: isResultSettingsVisible,
+      css: { 'span3 result-settings': isResultSettingsVisible, 'hidden': !isResultSettingsVisible() }">
+    <div class="snippet-grid-settings" data-bind="delayedOverflow">
+      <table class="table table-condensed margin-top-10 no-border">
+        <thead>
+        <tr>
+          <th width="16">
+            <input class="all-meta-checked no-margin-top" type="checkbox" data-bind="
+                enable: !isMetaFilterVisible() && filteredMeta().length,
+                event: {
+                  change: function() { toggleAllResultColumns($element); clickFilteredMetaCheck() }
+                },
+                checked: filteredMetaChecked
+              "/>
+          </th>
+          <th colspan="2" class="nav-header-like">
+            <span class="meta-title pointer" data-bind="toggle: isMetaFilterVisible, attr: { title: filteredColumnCount }">${ I18n('columns')}</span>
+            (<span class="meta-title pointer" data-bind="toggle: isMetaFilterVisible, text: filteredColumnCount"></span>)
+            <span class="inactive-action" href="javascript:void(0)" data-bind="toggle: isMetaFilterVisible, css: { 'blue' : isMetaFilterVisible }"><i class="pointer fa fa-search" title="${ I18n('Search') }"></i></span>
+          </th>
+        </tr>
+        <tr data-bind="visible: isMetaFilterVisible">
+          <td colspan="3">
+            <div class="context-popover-inline-autocomplete" style="display: block;">
+              <!-- ko component: {
+                name: 'inline-autocomplete',
+                params: {
+                  placeHolder: '${ I18n('Filter columns...') }',
+                  querySpec: metaFilter,
+                  facets: Object.keys(SQL_COLUMNS_KNOWN_FACET_VALUES),
+                  knownFacetValues: SQL_COLUMNS_KNOWN_FACET_VALUES,
+                  autocompleteFromEntries: autocompleteFromEntries
+                }
+              } --><!-- /ko -->
+            </div>
+          </td>
+        </tr>
+        </thead>
+        <tbody class="unstyled filtered-meta" data-bind="foreach: filteredMeta">
+        <tr data-bind="visible: name !== ''">
+          <td><input class="no-margin-top" type="checkbox" data-bind="
+              event: {
+                change: function() { $parent.toggleResultColumn($element, originalIndex);}
+              },
+              checked: checked
+            "/></td>
+          <td><a class="pointer" data-bind="
+              click: function() { $parent.scrollToResultColumn($element); },
+              attr: { title: name + ' - ' + type }
+            "><span data-bind="text: name"></span></a></td>
+          <td><span data-bind="text: type" class="muted margin-left-20"></span></td>
+        </tr>
+        </tbody>
+        <tfoot>
+        <tr>
+          <td colspan="3">
+            <div class="margin-top-10 muted meta-noresults" data-bind="visible: !filteredMeta().length">
+              ${ I18n('No results found') }
+            </div>
+          </td>
+        </tr>
+        </tfoot>
+      </table>
+    </div>
+    <div class="resize-bar" style="top: 0; right: -10px; cursor: col-resize;"></div>
+  </div>
+  <div class="grid-side" data-bind="css: { 'span9': isResultSettingsVisible, 'span12 nomargin': !isResultSettingsVisible() }">
+    <div data-bind="delayedOverflow: 'slow', css: resultsKlass">
+      <table class="table table-condensed resultTable">
+        <thead>
+        <tr data-bind="foreach: meta">
+          <th class="sorting" data-bind="
+              text: ($index() == 0 ? '&nbsp;' : $data.name),
+              css: typeof cssClass != 'undefined' ? cssClass : 'sort-string',
+              attr: { title: $data.type },
+              style: { 
+                'width': $index() == 0 ? '1%' : '',
+                'height': $index() == 0 ? '32px' : ''
+              },
+              click: function(obj, e) { $(e.target).parents('table').trigger('sort', obj); }
+            "></th>
+        </tr>
+        </thead>
+        <tbody>
+        </tbody>
+      </table>
+      <div style="display:none;" data-bind="
+          visible: status() == 'expired' && data() && data().length > 99,
+          css: resultsKlass
+        ">
+        <pre class="margin-top-10"><i class="fa fa-check muted"></i> ${ I18n("Results have expired, rerun the query if needed.") }</pre>
+      </div>
+    </div>
+  </div>
+</div>
+`;
+
+class ResultGrid extends DisposableComponent {
+  constructor(params) {
+    super();
+    this.status = params.status;
+    this.isResultSettingsVisible = params.isResultSettingsVisible;
+    this.isMetaFilterVisible = params.isMetaFilterVisible; // result
+    this.filteredMeta = params.filteredMeta; // result
+    this.filteredMetaChecked = params.filteredMetaChecked; // result
+    this.clickFilteredMetaCheck = params.clickFilteredMetaCheck; // result
+    this.filteredColumnCount = params.filteredColumnCount; // result
+    this.metaFilter = params.metaFilter; // result
+    this.autocompleteFromEntries = params.autocompleteFromEntries; // result
+    this.toggleResultColumn = params.toggleResultColumn;
+    this.scrollToResultColumn = params.scrollToResultColumn;
+    this.resultsKlass = params.resultsKlass;
+    this.meta = params.meta; // result
+    this.data = params.data; // result
+  }
+}
+
+componentUtils.registerComponent(NAME, ResultGrid, TEMPLATE);

+ 2 - 0
desktop/core/src/desktop/js/apps/notebook2/snippet.js

@@ -22,6 +22,8 @@ import { markdown } from 'markdown';
 import 'apps/notebook2/components/ko.executableProgressBar';
 import 'apps/notebook2/components/ko.snippetEditorActions';
 import 'apps/notebook2/components/ko.snippetExecuteActions';
+import 'apps/notebook2/components/resultChart/ko.resultChart';
+import 'apps/notebook2/components/resultGrid/ko.resultGrid';
 
 import AceAutocompleteWrapper from 'apps/notebook/aceAutocompleteWrapper';
 import apiHelper from 'api/apiHelper';

+ 4 - 0
desktop/core/src/desktop/templates/global_js_constants.mako

@@ -189,6 +189,7 @@
     'column name...': '${_('column name...')}',
     'Column': '${ _('Column') }',
     'Columns': '${ _('Columns') }',
+    'columns': '${ _('columns') }',
     'Compilation': '${ _('Compilation') }',
     'Compute': '${ _('Compute') }',
     'condition': '${ _('condition') }',
@@ -265,6 +266,7 @@
     'Fields': '${ _('Fields') }',
     'File Browser': '${ _('File Browser') }',
     'Files': '${ _('Files') }',
+    'Filter columns...': '${ _('Filter columns...') }',
     'Filter databases...': '${ _('Filter databases...') }',
     'Filter sources...': '${ _('Filter sources...') }',
     'filter': '${ _('filter') }',
@@ -442,6 +444,7 @@
     'Result available': '${ _('Result available') }',
     'Result expired': '${ _('Result expired') }',
     'result(s) copied to the clipboard' : '${ _('result(s) copied to the clipboard') }',
+    'Results have expired, rerun the query if needed.': '${ _('Results have expired, rerun the query if needed.') }',
     'Risks': '${ _('Risks') }',
     'Running': '${ _('Running') }',
     'sample query': '${ _('sample query') }',
@@ -458,6 +461,7 @@
     'Search Dashboard': '${_('Search Dashboard')}',
     'Search data and saved documents...': '${ _('Search data and saved documents...') }',
     'Search saved documents...': '${_('Search saved documents...')}',
+    'Search': '${ _('Search') }',
     'Select a query or start typing to get optimization hints.': '${_('Select a query or start typing to get optimization hints')}',
     'Select json file': '${ _('Select json file') }',
     'Select the chart parameters on the left': '${ _('Select the chart parameters on the left') }',

+ 17 - 75
desktop/libs/notebook/src/notebook/templates/editor_components2.mako

@@ -1305,58 +1305,6 @@
     </div>
   </script>
 
-  <script type="text/html" id="snippet-grid-settings${ suffix }">
-    <div class="snippet-grid-settings" data-bind="delayedOverflow">
-      <table class="table table-condensed margin-top-10 no-border">
-        <thead>
-        <tr>
-          <th width="16">
-            <input class="all-meta-checked no-margin-top" type="checkbox" data-bind="enable: !result.isMetaFilterVisible() && result.filteredMeta().length > 0, event: { change: function(){ toggleAllResultColumns($element); result.clickFilteredMetaCheck() } }, checked: result.filteredMetaChecked" />
-          </th>
-          <th colspan="2" class="nav-header-like">
-            <span class="meta-title pointer" data-bind="click: function() { result.isMetaFilterVisible(true); }, attr: { title: result.filteredColumnCount() }">${_('columns')}</span>
-            (<span class="meta-title pointer" data-bind="click: function() { result.isMetaFilterVisible(true); }, text: result.filteredColumnCount()"></span>)
-            <span class="inactive-action" href="javascript:void(0)" data-bind="click: function(){ result.isMetaFilterVisible(true); }, css: { 'blue' : result.isMetaFilterVisible }"><i class="pointer fa fa-search" title="${ _('Search') }"></i></span>
-          </th>
-        </tr>
-        <tr data-bind="visible: result.isMetaFilterVisible">
-          <td colspan="3">
-            <div class="context-popover-inline-autocomplete" style="display: block;">
-              <!-- ko component: {
-                name: 'inline-autocomplete',
-                params: {
-                  placeHolder: '${ _ko('Filter columns...') }',
-                  querySpec: result.metaFilter,
-                  facets: Object.keys(SQL_COLUMNS_KNOWN_FACET_VALUES),
-                  knownFacetValues: SQL_COLUMNS_KNOWN_FACET_VALUES,
-                  autocompleteFromEntries: result.autocompleteFromEntries
-                }
-              } --><!-- /ko -->
-              ##<input class="meta-filter" type="text" data-bind="blurHide: result.isMetaFilterVisible, clearable: result.metaFilter, valueUpdate:'afterkeydown'" placeholder="${ _('Filter columns...') }" title="${ _('Type column:xxx or type:yyy for specific filters.') }" style="width: 257px" />
-            </div>
-          </td>
-        </tr>
-        </thead>
-        <tbody class="unstyled filtered-meta" data-bind="foreach: result.filteredMeta">
-        <tr data-bind="visible: name != ''">
-          <td><input class="no-margin-top" type="checkbox" data-bind="event: { change: function() { $parent.toggleResultColumn($element, originalIndex);} }, checked: checked" /></td>
-          <td><a class="pointer" data-bind="click: function(){ $parent.scrollToResultColumn($element); }, attr: { title: name + ' - ' + type}"><span data-bind="text: name"></span></a></td>
-          <td><span data-bind="text: type" class="muted margin-left-20"></span></td>
-        </tr>
-        </tbody>
-        <tfoot>
-        <tr>
-          <td colspan="3">
-            <div class="margin-top-10 muted meta-noresults" data-bind="visible: result.filteredMeta().length === 0">
-              ${ _('No results found') }
-            </div>
-          </td>
-        </tr>
-        </tfoot>
-      </table>
-    </div>
-  </script>
-
   <script type="text/html" id="snippet-explain${ suffix }">
     <pre class="no-margin-bottom" data-bind="text: result.explanation"></pre>
   </script>
@@ -1383,30 +1331,24 @@
           <!-- /ko -->
         </div>
 
-        <div class="row-fluid table-results" data-bind="visible: result.type() == 'table'" style="display: none; max-height: 400px; min-height: 290px;">
+        <div class="row-fluid table-results" data-bind="visible: result.type() === 'table'" style="display: none; max-height: 400px; min-height: 290px;">
           <!-- ko if: showGrid -->
-          <div>
-            <div class="column-side" data-bind="visible: isResultSettingsVisible, css:{'span3 result-settings': isResultSettingsVisible, 'hidden': ! isResultSettingsVisible()}" style="position:relative;white-space: nowrap;">
-              <!-- ko template: { name: 'snippet-grid-settings${ suffix }' } --><!-- /ko -->
-              <div class="resize-bar" style="top: 0; right: -10px; cursor: col-resize;"></div>
-            </div>
-            <div class="grid-side" data-bind="css: {'span9': isResultSettingsVisible, 'span12 nomargin': ! isResultSettingsVisible() }">
-              <div data-bind="delayedOverflow: 'slow', css: resultsKlass">
-                <table class="table table-condensed resultTable">
-                  <thead>
-                  <tr data-bind="foreach: result.meta">
-                    <th class="sorting" data-bind="text: ($index() == 0 ? '&nbsp;' : $data.name), css: typeof cssClass != 'undefined' ? cssClass : 'sort-string', attr: {title: $data.type }, style:{'width': $index() == 0 ? '1%' : '', 'height': $index() == 0 ? '32px' : ''}, click: function(obj, e){ $(e.target).parents('table').trigger('sort', obj); }"></th>
-                  </tr>
-                  </thead>
-                  <tbody>
-                  </tbody>
-                </table>
-                <div data-bind="visible: status() == 'expired' && result.data() && result.data().length > 99, css: resultsKlass" style="display:none;">
-                  <pre class="margin-top-10"><i class="fa fa-check muted"></i> ${ _("Results have expired, rerun the query if needed.") }</pre>
-                </div>
-              </div>
-            </div>
-          </div>
+            <!-- ko component: { name: 'result-grid', params: {
+              status: status,
+              isResultSettingsVisible: isResultSettingsVisible,
+              isMetaFilterVisible: result.isMetaFilterVisible,
+              filteredMeta: result.filteredMeta,
+              filteredMetaChecked: result.filteredMetaChecked,
+              clickFilteredMetaCheck: result.clickFilteredMetaCheck,
+              filteredColumnCount: result.filteredColumnCount,
+              metaFilter: result.metaFilter,
+              autocompleteFromEntries: result.autocompleteFromEntries,
+              toggleResultColumn: toggleResultColumn,
+              scrollToResultColumn: scrollToResultColumn,
+              resultsKlass: resultsKlass,
+              meta: result.meta,
+              data: result.data
+            } } --><!-- /ko -->
           <!-- /ko -->
           <!-- ko if: showChart-->
             <!-- ko component: { name: 'result-chart', params: {