Clear all paragraphs and remove note from main page

This commit is contained in:
Mina Lee 2016-10-27 16:50:18 +09:00
parent 2f79852d34
commit 4adddb49d9
11 changed files with 127 additions and 36 deletions

View file

@ -215,6 +215,9 @@ public class NotebookServer extends WebSocketServlet implements
case PARAGRAPH_CLEAR_OUTPUT:
clearParagraphOutput(conn, userAndRoles, notebook, messagereceived);
break;
case PARAGRAPH_CLEAR_ALL_OUTPUT:
clearAllParagraphOutput(conn, userAndRoles, notebook, messagereceived);
break;
case NOTE_UPDATE:
updateNote(conn, userAndRoles, notebook, messagereceived);
break;
@ -780,6 +783,25 @@ public class NotebookServer extends WebSocketServlet implements
broadcastNoteList(subject, userAndRoles);
}
private void clearAllParagraphOutput(NotebookSocket conn, HashSet<String> userAndRoles,
Notebook notebook, Message fromMessage)
throws IOException {
final String noteId = (String) fromMessage.get("id");
if (StringUtils.isBlank(noteId)) {
return;
}
Note note = notebook.getNote(noteId);
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (!notebookAuthorization.isOwner(noteId, userAndRoles)) {
permissionError(conn, "clear output", fromMessage.principal,
userAndRoles, notebookAuthorization.getOwners(noteId));
return;
}
note.clearAllParagraphOutput();
broadcastNote(note);
}
protected Note importNote(NotebookSocket conn, HashSet<String> userAndRoles,
Notebook notebook, Message fromMessage)
throws IOException {

View file

@ -22,10 +22,12 @@
'websocketMsgSrv',
'$rootScope',
'arrayOrderingSrv',
'ngToast'
'ngToast',
'noteActionSrv'
];
function HomeCtrl($scope, noteListDataFactory, websocketMsgSrv, $rootScope, arrayOrderingSrv, ngToast) {
function HomeCtrl($scope, noteListDataFactory, websocketMsgSrv, $rootScope, arrayOrderingSrv,
ngToast, noteActionSrv) {
ngToast.dismiss();
var vm = this;
vm.notes = noteListDataFactory;
@ -85,6 +87,13 @@
vm.notebookHome = false;
}
});
}
$scope.removeNote = function(noteId) {
noteActionSrv.removeNote(noteId, false);
};
$scope.clearAllParagraphOutput = function(noteId) {
noteActionSrv.clearAllParagraphOutput(noteId);
};
}
})();

View file

@ -13,10 +13,24 @@ limitations under the License.
-->
<script type="text/ng-template" id="notebook_folder_renderer.html">
<div ng-if="node.children == null">
<div ng-if="node.children == null"
ng-mouseenter="showButton=true"
ng-mouseleave="showButton=false">
<a style="text-decoration: none;" href="#/notebook/{{node.id}}">
<i style="font-size: 10px;" class="icon-doc"/> {{noteName(node)}}
</a>
<a style="text-decoration: none;">
<i style="font-size: 13px; margin-left: 10px; cursor: pointer; text-decoration: none;"
class="fa fa-eraser" ng-show="showButton" ng-click="clearAllParagraphOutput(node.id)"
tooltip-placement="bottom" tooltip="Clear output">
</i>
</a>
<a style="text-decoration: none;">
<i style="font-size: 13px; margin-left: 2px; cursor: pointer; text-decoration: none;"
class="fa fa-trash-o" ng-show="showButton" ng-click="removeNote(node.id)"
tooltip-placement="bottom" tooltip="Remove note">
</i>
</a>
</div>
<div ng-if="node.children != null">
<a style="text-decoration: none; cursor: pointer;" ng-click="toggleFolderNode(node)">

View file

@ -43,7 +43,7 @@ limitations under the License.
</button>
<button type="button"
class="btn btn-default btn-xs"
ng-click="clearAllParagraphOutput()"
ng-click="clearAllParagraphOutput(note.id)"
ng-hide="viewOnly"
ng-class="{'disabled':isNoteRunning()}"
tooltip-placement="bottom" tooltip="Clear output">

View file

@ -27,12 +27,13 @@
'baseUrlSrv',
'$timeout',
'saveAsService',
'ngToast'
'ngToast',
'noteActionSrv'
];
function NotebookCtrl($scope, $route, $routeParams, $location, $rootScope,
$http, websocketMsgSrv, baseUrlSrv, $timeout, saveAsService,
ngToast) {
ngToast, noteActionSrv) {
ngToast.dismiss();
@ -143,20 +144,9 @@
$scope.$broadcast('doubleClickParagraph', paragraphId);
};
/** Remove the note and go back tot he main page */
/** TODO(anthony): In the nearly future, go back to the main page and telle to the dude that the note have been remove */
// Remove the note and go back to the main page
$scope.removeNote = function(noteId) {
BootstrapDialog.confirm({
closable: true,
title: '',
message: 'Do you want to delete this note?',
callback: function(result) {
if (result) {
websocketMsgSrv.deleteNote(noteId);
$location.path('/');
}
}
});
noteActionSrv.removeNote(noteId, true);
};
//Export notebook
@ -230,19 +220,8 @@
}
};
$scope.clearAllParagraphOutput = function() {
BootstrapDialog.confirm({
closable: true,
title: '',
message: 'Do you want to clear all output?',
callback: function(result) {
if (result) {
_.forEach($scope.note.paragraphs, function(n, key) {
angular.element('#' + n.id + '_paragraphColumn_main').scope().clearParagraphOutput();
});
}
}
});
$scope.clearAllParagraphOutput = function(noteId) {
noteActionSrv.clearAllParagraphOutput(noteId);
};
$scope.toggleAllEditor = function() {

View file

@ -0,0 +1,51 @@
/*
* Licensed 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.
*/
'use strict';
(function() {
angular.module('zeppelinWebApp').service('noteActionSrv', noteActionSrv);
noteActionSrv.$inject = ['websocketMsgSrv', '$location'];
function noteActionSrv(websocketMsgSrv, $location) {
this.removeNote = function(noteId, redirectToHome) {
BootstrapDialog.confirm({
closable: true,
title: '',
message: 'Do you want to delete this note?',
callback: function(result) {
if (result) {
websocketMsgSrv.deleteNote(noteId);
if (redirectToHome) {
$location.path('/');
}
}
}
});
};
this.clearAllParagraphOutput = function(noteId) {
BootstrapDialog.confirm({
closable: true,
title: '',
message: 'Do you want to clear all output?',
callback: function(result) {
if (result) {
websocketMsgSrv.clearAllParagraphOutput(noteId);
}
}
});
};
}
})();

View file

@ -122,6 +122,10 @@
websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_OUTPUT', data: {id: paragraphId}});
},
clearAllParagraphOutput: function(noteId) {
websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_ALL_OUTPUT', data: {id: noteId}});
},
completion: function(paragraphId, buf, cursor) {
websocketEvents.sendNewEvent({
op: 'COMPLETION',

View file

@ -185,6 +185,7 @@ limitations under the License.
<script src="components/searchService/search.service.js"></script>
<script src="components/login/login.controller.js"></script>
<script src="components/elasticInputCtrl/elasticInput.controller.js"></script>
<script src="components/noteAction/noteAction.service.js"></script>
<!-- endbuild -->
</body>
</html>

View file

@ -326,6 +326,17 @@ public class Note implements Serializable, ParagraphJobListener {
return null;
}
/**
* Clear all paragraph output of note
*/
public void clearAllParagraphOutput() {
synchronized (paragraphs) {
for (Paragraph p : paragraphs) {
p.setReturn(null, null);
}
}
}
/**
* Move paragraph into the new index (order from 0 ~ n-1).
*

View file

@ -48,7 +48,7 @@ public class Message {
// @param id note id
CLONE_NOTE, // [c-s] clone new notebook
// @param id id of note to clone
// @param name name fpor the cloned note
// @param name name for the cloned note
IMPORT_NOTE, // [c-s] import notebook
// @param object notebook
NOTE_UPDATE,
@ -96,7 +96,8 @@ public class Message {
// @param notes serialized List<NoteInfo> object
PARAGRAPH_REMOVE,
PARAGRAPH_CLEAR_OUTPUT,
PARAGRAPH_CLEAR_OUTPUT, // [c-s] clear output of paragraph
PARAGRAPH_CLEAR_ALL_OUTPUT, // [c-s] clear output of all paragraphs
PARAGRAPH_APPEND_OUTPUT, // [s-c] append output
PARAGRAPH_UPDATE_OUTPUT, // [s-c] update (replace) output
PING,

View file

@ -33,7 +33,6 @@ import org.apache.zeppelin.dep.Dependency;
import org.apache.zeppelin.dep.DependencyResolver;
import org.apache.zeppelin.interpreter.mock.MockInterpreter1;
import org.apache.zeppelin.interpreter.mock.MockInterpreter2;
import org.apache.zeppelin.notebook.repo.zeppelinhub.security.Authentication;
import org.apache.zeppelin.user.AuthenticationInfo;
import org.apache.zeppelin.interpreter.remote.RemoteInterpreter;
import org.apache.zeppelin.notebook.JobListenerFactory;