Browse Source

[spark] Show specific results when there is no datasets

Romain Rigaux 11 năm trước cách đây
mục cha
commit
a23c1fe

+ 4 - 1
apps/spark/src/spark/models.py

@@ -264,7 +264,10 @@ class SparkApi():
     session = _get_snippet_session(notebook, snippet)
     
     try:
-      return {'id': api.submit_statement(session['id'], snippet['statement']).split('cells/')[1]}
+      return {
+          'id': api.submit_statement(session['id'], snippet['statement']).split('cells/')[1],
+          'has_result_set': True,
+      }
     except Exception, e:
       message = force_unicode(str(e))
       if 'session not found' in message:

+ 40 - 16
apps/spark/src/spark/templates/editor.mako

@@ -304,33 +304,48 @@ ${_('Example: SELECT * FROM tablename, or press CTRL + space')}
             <textarea data-bind="value: statement_raw, codemirror: { 'id': id(), 'viewportMargin': Infinity, 'lineNumbers': true, 'matchBrackets': true, 'mode': editorMode(), 'enter': execute }"></textarea>
             <a href="javascript:void(0)" data-bind="click: execute, visible: status() != 'running'" class="btn codeMirror-overlaybtn">${ _('Go!') }</a>
             <a href="javascript:void(0)" data-bind="click: cancel, visible: status() == 'running'" class="btn codeMirror-overlaybtn">${ _('Cancel') }</a>
-            <div class="progress" data-bind="css:{'progress-neutral': progress() == 0, 'progress-warning': progress() > 0 && progress() < 100, 'progress-success': progress() == 100}" style="height: 1px">
+            <div class="progress" data-bind="css: {'progress-neutral': progress() == 0, 'progress-warning': progress() > 0 && progress() < 100, 'progress-success': progress() == 100}" style="height: 1px">
               <div class="bar" data-bind="style: {'width': progress() + '%'}"></div>
             </div>
           </div>
         </div>
 
         <div style="padding-top: 10px;">
-
-          <a data-bind="visible: result.meta().length > 0, click: function() { $data.showGrid(true); }, css: {'active': $data.showGrid}" href="javascript:void(0)" class="btn" title="${ _('Grid') }"><i class="fa fa-th"></i></a>
-          <div class="btn-group" data-bind="visible: result.meta().length > 0">
-            <button class="btn dropdown-toggle" style="height: 31px" data-bind="css: {'active': $data.showChart}" data-toggle="dropdown"><i class="hcha hcha-bar-chart" data-bind="visible: chartType() == ko.HUE_CHARTS.TYPES.BARCHART"></i><i class="hcha hcha-line-chart" data-bind="visible: chartType() == ko.HUE_CHARTS.TYPES.LINECHART"></i><i class="hcha hcha-pie-chart" data-bind="visible: chartType() == ko.HUE_CHARTS.TYPES.PIECHART"></i><i class="hcha hcha-map-chart" data-bind="visible: chartType() == ko.HUE_CHARTS.TYPES.MAP"></i> <i class="fa fa-caret-down"></i></button>
+          <a data-bind="visible: result.hasSomeResults(), click: function() { $data.showGrid(true); }, css: {'active': $data.showGrid}" href="javascript:void(0)" class="btn" title="${ _('Grid') }"><i class="fa fa-th"></i></a>
+          <div class="btn-group" data-bind="visible: result.hasSomeResults()">
+            <button class="btn dropdown-toggle" style="height: 31px" data-bind="css: {'active': $data.showChart}" data-toggle="dropdown">
+              <i class="hcha hcha-bar-chart" data-bind="visible: chartType() == ko.HUE_CHARTS.TYPES.BARCHART"></i>
+              <i class="hcha hcha-line-chart" data-bind="visible: chartType() == ko.HUE_CHARTS.TYPES.LINECHART"></i>
+              <i class="hcha hcha-pie-chart" data-bind="visible: chartType() == ko.HUE_CHARTS.TYPES.PIECHART"></i>
+              <i class="hcha hcha-map-chart" data-bind="visible: chartType() == ko.HUE_CHARTS.TYPES.MAP"></i>
+              <i class="fa fa-caret-down"></i>
+            </button>
             <ul class="dropdown-menu">
-              <li><a href="javascript:void(0)" data-bind="css: {'active': chartType() == ko.HUE_CHARTS.TYPES.BARCHART}, click: function(){ $data.showChart(true); chartType(ko.HUE_CHARTS.TYPES.BARCHART); }"><i class="hcha hcha-bar-chart"></i> ${_('Bars')}</a></li>
-              <li><a href="javascript:void(0)" data-bind="css: {'active': chartType() == ko.HUE_CHARTS.TYPES.LINECHART}, click: function(){ $data.showChart(true); chartType(ko.HUE_CHARTS.TYPES.LINECHART); }"><i class="hcha hcha-line-chart"></i> ${_('Lines')}</a></li>
-              <li><a href="javascript:void(0)" data-bind="css: {'active': chartType() == ko.HUE_CHARTS.TYPES.PIECHART}, click: function(){ $data.showChart(true); chartType(ko.HUE_CHARTS.TYPES.PIECHART); }"><i class="hcha hcha-pie-chart"></i> ${_('Pie')}</a></li>
-              <li><a href="javascript:void(0)" data-bind="css: {'active': chartType() == ko.HUE_CHARTS.TYPES.MAP}, click: function(){ $data.showChart(true); chartType(ko.HUE_CHARTS.TYPES.MAP); }"><i class="hcha hcha-map-chart"></i> ${_('Map')}</a></li>
+              <li><a href="javascript:void(0)" data-bind="css: {'active': chartType() == ko.HUE_CHARTS.TYPES.BARCHART}, click: function(){ $data.showChart(true); chartType(ko.HUE_CHARTS.TYPES.BARCHART); }">
+                <i class="hcha hcha-bar-chart"></i> ${_('Bars')}</a>
+              </li>
+              <li><a href="javascript:void(0)" data-bind="css: {'active': chartType() == ko.HUE_CHARTS.TYPES.LINECHART}, click: function(){ $data.showChart(true); chartType(ko.HUE_CHARTS.TYPES.LINECHART); }">
+                <i class="hcha hcha-line-chart"></i> ${_('Lines')}</a>
+              </li>
+              <li><a href="javascript:void(0)" data-bind="css: {'active': chartType() == ko.HUE_CHARTS.TYPES.PIECHART}, click: function(){ $data.showChart(true); chartType(ko.HUE_CHARTS.TYPES.PIECHART); }">
+                <i class="hcha hcha-pie-chart"></i> ${_('Pie')}</a>
+              </li>
+              <li><a href="javascript:void(0)" data-bind="css: {'active': chartType() == ko.HUE_CHARTS.TYPES.MAP}, click: function(){ $data.showChart(true); chartType(ko.HUE_CHARTS.TYPES.MAP); }">
+                <i class="hcha hcha-map-chart"></i> ${_('Map')}</a>
+              </li>
             </ul>
           </div>
 
           <div class="pull-right">
-              <a data-bind="visible: status() != 'ready', click: function() { $data.showLogs(! $data.showLogs()); window.setTimeout(redrawFixedHeaders, 100); }, css: {'active': $data.showLogs}" href="javascript:void(0)" class="btn" title="${ _('Logs') }"><i class="fa fa-file-text-o"></i></a>
-              &nbsp;
-              <a data-bind="visible: status() == 'available', click: function() { $data.showDownload(! $data.showDownload()); }" href="javascript:void(0)" class="btn" title="${ _('Logs') }">
-                <i class="fa fa-arrow-circle-o-down"></i>
-              </a>
+            <a data-bind="visible: status() != 'ready', click: function() { $data.showLogs(! $data.showLogs()); window.setTimeout(redrawFixedHeaders, 100); }, css: {'active': $data.showLogs}" href="javascript:void(0)" class="btn" title="${ _('Logs') }">
+              <i class="fa fa-file-text-o"></i>
+            </a>
+            &nbsp;
+            <a data-bind="visible: status() == 'available', click: function() { $data.showDownload(! $data.showDownload()); }" href="javascript:void(0)" class="btn" title="${ _('Logs') }">
+              <i class="fa fa-download"></i>
+            </a>
 
-            <span data-bind="visible: showDownload">
+            <span data-bind="visible: showDownload() && result.hasSomeResults()">
               <form method="POST" action="${ url('spark:download') }">
                 ${ csrf_token(request) | n,unicode }
                 <input type="hidden" name="notebook" data-bind="value: ko.mapping.toJSON($root.selectedNotebook)"/>
@@ -351,12 +366,21 @@ ${_('Example: SELECT * FROM tablename, or press CTRL + space')}
         <div data-bind="visible: result.errors().length > 0, css: resultsKlass">
           <span data-bind="text: result.errors"></span>
         </div>
+        
+        <div data-bind="visible: ! result.hasResultset() && status() == 'available', css: resultsKlass">
+          ${ _('Success.') }
+        </div>
+        
+        <div data-bind="visible: result.hasResultset() && status() == 'available' && result.data().length == 0, css: resultsKlass">
+          ${ _('Success but empty results.') }
+        </div>
 
-        <div class="row-fluid" data-bind="visible: result.meta().length > 0 && showGrid()" style="max-height: 400px; margin-top: 4px">
+        <div class="row-fluid" data-bind="visible: result.hasSomeResults() && showGrid()" style="max-height: 400px; margin-top: 4px">
           <div data-bind="visible: isLeftPanelVisible, css:{'span2': isLeftPanelVisible, 'hidden': !isLeftPanelVisible()}">
             <a title="${_('Toggle columns')}" class="pull-right pointer" style="margin:3px; margin-top:9px" data-bind="click: toggleLeftPanel">
               <i class="fa fa-chevron-left"></i>
             </a>
+
             <ul class="nav nav-list" style="border: none; background-color: #FFF">
               <li class="nav-header">${_('columns')}</li>
             </ul>

+ 9 - 4
apps/spark/static/js/spark.vm.js

@@ -20,6 +20,7 @@ var Result = function (snippet, result) {
 
   self.id = ko.observable(typeof result.id != "undefined" && result.id != null ? result.id : UUID());
   self.type = ko.observable(typeof result.type != "undefined" && result.type != null ? result.type : 'table');
+  self.hasResultset = ko.observable(typeof result.hasResultset != "undefined" && result.hasResultset != null ? result.hasResultset : true);
   self.handle = ko.observable({});
   self.meta = ko.observableArray(typeof result.meta != "undefined" && result.meta != null ? result.meta : []);
   self.meta.extend({ rateLimit: 50 });
@@ -32,7 +33,10 @@ var Result = function (snippet, result) {
   self.data.extend({ rateLimit: 50 });
   self.logs = ko.observable('');
   self.errors = ko.observable('');
-
+  self.hasSomeResults = ko.computed(function(){
+    return self.hasResultset() && self.data().length > 0; // status() == 'available'
+  });
+  
   if (typeof result.handle != "undefined" && result.handle != null) {
     $.each(result.handle, function(key, val) {
       self.handle()[key] = val;
@@ -167,7 +171,7 @@ var Snippet = function (notebook, snippet) {
     return "results " + self.type();
   });
 
-  self.chartType = ko.observable(typeof snippet.chartType != "undefined" && snippet.chartType != null ? snippet.chartType : '');
+  self.chartType = ko.observable(typeof snippet.chartType != "undefined" && snippet.chartType != null ? snippet.chartType : ko.HUE_CHARTS.TYPES.BARCHART);
   self.chartSorting = ko.observable(typeof snippet.chartSorting != "undefined" && snippet.chartSorting != null ? snippet.chartSorting : "none");
   self.chartX = ko.observable(typeof snippet.chartX != "undefined" && snippet.chartX != null ? snippet.chartX : null);
   self.chartYSingle = ko.observable(typeof snippet.chartYSingle != "undefined" && snippet.chartYSingle != null ? snippet.chartYSingle : null);
@@ -181,7 +185,7 @@ var Snippet = function (notebook, snippet) {
 
   self.tempChartOptions = {};
 
-  self.isLeftPanelVisible = ko.observable(typeof snippet.isLeftPanelVisible != "undefined" && snippet.isLeftPanelVisible != null ? snippet.isLeftPanelVisible : true);
+  self.isLeftPanelVisible = ko.observable(typeof snippet.isLeftPanelVisible != "undefined" && snippet.isLeftPanelVisible != null ? snippet.isLeftPanelVisible : false);
   self.toggleLeftPanel = function () {
     self.isLeftPanelVisible(! self.isLeftPanelVisible());
     $(document).trigger("toggleLeftPanel", self);
@@ -262,6 +266,7 @@ var Snippet = function (notebook, snippet) {
           self.result.handle()[key] = val;
         });
 
+        self.result.hasResultset(data.handle.has_result_set);
         self.checkStatus();
       } else {
         self._ajax_error(data);
@@ -500,7 +505,7 @@ function EditorViewModel(notebooks, options) {
   self.notebooks = ko.observableArray();
   self.selectedNotebook = ko.observable();
 
-  self.isEditing = ko.observable(true);
+  self.isEditing = ko.observable(false);
   self.isEditing.subscribe(function(newVal){
     $(document).trigger("editingToggled");
   });