Repository: incubator-zeppelin
Updated Branches:
  refs/heads/master d549165ca -> fa40d567f


ZEPPELIN-299 Support clearing output for paragraph

add an option to clear output/result for paragraph on UI and necessary backend 
changes

<img width="569" alt="clear-output-notebook" 
src="https://cloud.githubusercontent.com/assets/2031306/10750542/9d4a246c-7c9c-11e5-953e-53036d7da109.png";>
--
<img width="560" alt="clear-output-paragraph" 
src="https://cloud.githubusercontent.com/assets/2031306/10750543/9d4c1754-7c9c-11e5-87a8-fa35b8457dfa.png";>

Author: Renjith Kamath <[email protected]>

Closes #372 from r-kamath/ZEPPELIN-299 and squashes the following commits:

a311fce [Renjith Kamath] remove unused param from clearAllParagraphOutput
d349102 [Renjith Kamath] remove duplicate function def
7f59ba4 [Renjith Kamath] ZEPPELIN-299 Support clearing output for paragraph


Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/fa40d567
Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/fa40d567
Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/fa40d567

Branch: refs/heads/master
Commit: fa40d567f0915c6372bd1792c776d485a129fd26
Parents: d549165
Author: Renjith Kamath <[email protected]>
Authored: Tue Oct 27 12:30:00 2015 +0530
Committer: Lee moon soo <[email protected]>
Committed: Wed Nov 11 18:16:19 2015 +0900

----------------------------------------------------------------------
 .../java/org/apache/zeppelin/socket/Message.java |  1 +
 .../apache/zeppelin/socket/NotebookServer.java   | 15 +++++++++++++++
 .../src/app/notebook/notebook.controller.js      |  9 +++++++++
 zeppelin-web/src/app/notebook/notebook.html      |  8 ++++++++
 .../notebook/paragraph/paragraph.controller.js   |  6 +++++-
 .../src/app/notebook/paragraph/paragraph.html    |  4 ++++
 .../websocketEvents/websocketMsg.service.js      |  4 ++++
 .../java/org/apache/zeppelin/notebook/Note.java  | 19 +++++++++++++++++++
 .../apache/zeppelin/notebook/NotebookTest.java   | 15 +++++++++++++++
 9 files changed, 80 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/fa40d567/zeppelin-server/src/main/java/org/apache/zeppelin/socket/Message.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/Message.java 
b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/Message.java
index f2b34aa..c51cfe3 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/Message.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/Message.java
@@ -95,6 +95,7 @@ public class Message {
                 // @param notes serialized List<NoteInfo> object
 
     PARAGRAPH_REMOVE,
+    PARAGRAPH_CLEAR_OUTPUT,
     PING,
 
     ANGULAR_OBJECT_UPDATE,  // [s-c] add/update angular object

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/fa40d567/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java 
b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
index 421e9a2..644639f 100644
--- 
a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
+++ 
b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
@@ -137,6 +137,9 @@ public class NotebookServer extends WebSocketServlet 
implements
           case PARAGRAPH_REMOVE:
             removeParagraph(conn, notebook, messagereceived);
             break;
+          case PARAGRAPH_CLEAR_OUTPUT:
+            clearParagraphOutput(conn, notebook, messagereceived);
+            break;
           case NOTE_UPDATE:
             updateNote(conn, notebook, messagereceived);
             break;
@@ -457,6 +460,18 @@ public class NotebookServer extends WebSocketServlet 
implements
     }
   }
 
+  private void clearParagraphOutput(NotebookSocket conn, Notebook notebook,
+      Message fromMessage) throws IOException {
+    final String paragraphId = (String) fromMessage.get("id");
+    if (paragraphId == null) {
+      return;
+    }
+
+    final Note note = notebook.getNote(getOpenNoteId(conn));
+    note.clearParagraphOutput(paragraphId);
+    broadcastNote(note);
+  }
+
   private void completion(NotebookSocket conn, Notebook notebook,
       Message fromMessage) throws IOException {
     String paragraphId = (String) fromMessage.get("id");

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/fa40d567/zeppelin-web/src/app/notebook/notebook.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js 
b/zeppelin-web/src/app/notebook/notebook.controller.js
index ff993cb..b671ead 100644
--- a/zeppelin-web/src/app/notebook/notebook.controller.js
+++ b/zeppelin-web/src/app/notebook/notebook.controller.js
@@ -116,6 +116,15 @@ 
angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
     }
   };
 
+  $scope.clearAllParagraphOutput = function() {
+    var result = confirm('Do you want to clear all output?');
+    if (result) {
+      _.forEach($scope.note.paragraphs, function(n, key) {
+        angular.element('#' + n.id + 
'_paragraphColumn_main').scope().clearParagraphOutput();
+      });
+    }
+  };
+
   $scope.toggleAllEditor = function() {
     if ($scope.editorToggled) {
       $scope.$broadcast('openEditor');

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/fa40d567/zeppelin-web/src/app/notebook/notebook.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook.html 
b/zeppelin-web/src/app/notebook/notebook.html
index 7898249..9c5440d 100644
--- a/zeppelin-web/src/app/notebook/notebook.html
+++ b/zeppelin-web/src/app/notebook/notebook.html
@@ -40,6 +40,14 @@ limitations under the License.
       </button>
       <button type="button"
               class="btn btn-default btn-xs"
+              ng-click="clearAllParagraphOutput()"
+              ng-hide="viewOnly"
+              ng-class="{'disabled':isNoteRunning()}"
+              tooltip-placement="bottom" tooltip="Clear output">
+        <i class="fa fa-eraser"></i>
+      </button>
+      <button type="button"
+              class="btn btn-default btn-xs"
               ng-click="removeNote(note.id)"
               ng-hide="viewOnly"
               tooltip-placement="bottom" tooltip="Remove the notebook">

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/fa40d567/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js 
b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
index 0ba155f..e9de91c 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
@@ -281,6 +281,10 @@ angular.module('zeppelinWebApp')
     }
   };
 
+  $scope.clearParagraphOutput = function() {
+    websocketMsgSrv.clearParagraphOutput($scope.paragraph.id);
+  };
+
   $scope.toggleEditor = function() {
     if ($scope.paragraph.config.editorHide) {
       $scope.openEditor();
@@ -698,7 +702,7 @@ angular.module('zeppelinWebApp')
       desc += ' (outdated)';
     }
     return desc;
-  };  
+  };
 
   $scope.isResultOutdated = function() {
     var pdata = $scope.paragraph;

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/fa40d567/zeppelin-web/src/app/notebook/paragraph/paragraph.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.html 
b/zeppelin-web/src/app/notebook/paragraph/paragraph.html
index 78c240f..25ac584 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.html
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.html
@@ -470,6 +470,10 @@ limitations under the License.
                ng-click="goToSingleParagraph()"> Link this paragraph</a>
         </li>
         <li>
+          <a class="fa fa-eraser" style="cursor:pointer"
+             ng-click="clearParagraphOutput()"> Clear output</a>
+        </li>
+        <li>
           <!-- remove paragraph -->
           <a class="fa fa-times" style="cursor:pointer"
              ng-click="removeParagraph()"> Remove</a>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/fa40d567/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
----------------------------------------------------------------------
diff --git 
a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js 
b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
index e74cfd0..6022543 100644
--- a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
+++ b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js
@@ -85,6 +85,10 @@ angular.module('zeppelinWebApp').service('websocketMsgSrv', 
function($rootScope,
       websocketEvents.sendNewEvent({op: 'PARAGRAPH_REMOVE', data: {id: 
paragraphId}});
     },
 
+    clearParagraphOutput: function(paragraphId) {
+      websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_OUTPUT', data: {id: 
paragraphId}});
+    },
+
     completion: function(paragraphId, buf, cursor) {
       websocketEvents.sendNewEvent({
         op : 'COMPLETION',

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/fa40d567/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java 
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
index b725177..033039c 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
@@ -188,6 +188,25 @@ public class Note implements Serializable, JobListener {
   }
 
   /**
+   * Clear paragraph output by id.
+   *
+   * @param paragraphId
+   * @return
+   */
+  public Paragraph clearParagraphOutput(String paragraphId) {
+    synchronized (paragraphs) {
+      for (int i = 0; i < paragraphs.size(); i++) {
+        Paragraph p = paragraphs.get(i);
+        if (p.getId().equals(paragraphId)) {
+          p.setReturn(null, null);
+          return p;
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
    * Move paragraph into the new index (order from 0 ~ n-1).
    *
    * @param paragraphId

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/fa40d567/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java 
b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
index 883dc64..dad7384 100644
--- 
a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
+++ 
b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
@@ -161,6 +161,21 @@ public class NotebookTest implements JobListenerFactory{
   }
 
   @Test
+  public void testClearParagraphOutput() throws IOException, 
SchedulerException{
+    Note note = notebook.createNote();
+    Paragraph p1 = note.addParagraph();
+    p1.setText("hello world");
+    note.run(p1.getId());
+
+    while(p1.isTerminated()==false || p1.getResult()==null) Thread.yield();
+    assertEquals("repl1: hello world", p1.getResult().message());
+
+    // clear paragraph output/result
+    note.clearParagraphOutput(p1.getId());
+    assertNull(p1.getResult());
+  }
+
+  @Test
   public void testRunAll() throws IOException {
     Note note = notebook.createNote();
     
note.getNoteReplLoader().setInterpreters(factory.getDefaultInterpreterSettingList());

Reply via email to