From a7e8fd8ee07cc61ad744acebdc9166d5cbaabe27 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Mon, 4 Jul 2016 16:57:07 +0900 Subject: [PATCH 01/16] initial impl --- .../org/apache/zeppelin/socket/NotebookServer.java | 14 ++++++++++++++ .../src/app/notebook/notebook-actionBar.html | 12 ++++++++++++ .../src/app/notebook/notebook.controller.js | 11 +++++++++++ .../websocketEvents/websocketEvents.factory.js | 2 ++ .../websocketEvents/websocketMsg.service.js | 11 ++++++++++- .../org/apache/zeppelin/notebook/Notebook.java | 5 +++++ .../zeppelin/notebook/repo/NotebookRepoSync.java | 10 ++++++++-- .../apache/zeppelin/notebook/socket/Message.java | 2 ++ 8 files changed, 64 insertions(+), 3 deletions(-) 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 853c0d5c524..147c9a3d557 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 @@ -45,6 +45,7 @@ import org.apache.zeppelin.interpreter.InterpreterSetting; import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener; import org.apache.zeppelin.notebook.*; +import org.apache.zeppelin.notebook.repo.NotebookRepo; import org.apache.zeppelin.notebook.socket.Message; import org.apache.zeppelin.notebook.socket.Message.OP; import org.apache.zeppelin.scheduler.Job; @@ -220,6 +221,9 @@ public void onMessage(NotebookSocket conn, String msg) { case CHECKPOINT_NOTEBOOK: checkpointNotebook(conn, notebook, messagereceived); break; + case LIST_REVISION_HISTORY: + listRevisionHistory(conn, notebook, messagereceived); + break; case LIST_NOTEBOOK_JOBS: unicastNotebookJobInfo(conn, messagereceived); break; @@ -1129,6 +1133,16 @@ private void checkpointNotebook(NotebookSocket conn, Notebook notebook, notebook.checkpointNote(noteId, commitMessage, subject); } + private void listRevisionHistory(NotebookSocket conn, Notebook notebook, + Message fromMessage) throws IOException { + String noteId = (String) fromMessage.get("noteId"); + AuthenticationInfo subject = new AuthenticationInfo(fromMessage.principal); + List revisions = notebook.listRevisionHistory(noteId, subject); + + conn.send(serializeMessage(new Message(OP.LIST_REVISION_HISTORY) + .put("revisionList", revisions))); + } + /** * This callback is for the paragraph that runs on ZeppelinServer * @param noteId diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html index 170d56d66ef..3344772155c 100644 --- a/zeppelin-web/src/app/notebook/notebook-actionBar.html +++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html @@ -91,6 +91,18 @@

+
  • +
    + + table +
    +
  • diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js index 7d58e463634..049c939ca43 100644 --- a/zeppelin-web/src/app/notebook/notebook.controller.js +++ b/zeppelin-web/src/app/notebook/notebook.controller.js @@ -175,6 +175,17 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro document.getElementById('note.checkpoint.message').value = ''; }; + $scope.listRevisionHistory = function() { + websocketMsgSrv.listRevisionHistory($routeParams.noteId); + }; + + $scope.$on('listRevisionHistory', function(event, data) { + console.log(data); + if (data === '{}') { + console.log('empty data'); + } + }); + $scope.runNote = function() { BootstrapDialog.confirm({ closable: true, diff --git a/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js b/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js index 2fb5003ba15..b0a59431c3f 100644 --- a/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js +++ b/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js @@ -109,6 +109,8 @@ angular.module('zeppelinWebApp').factory('websocketEvents', $rootScope.$broadcast('appLoad', data); } else if (op === 'APP_STATUS_CHANGE') { $rootScope.$broadcast('appStatusChange', data); + } else if (op === 'LIST_REVISION_HISTORY') { + $rootScope.$broadcast('listRevisionHistory', data); } }); diff --git a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js index 698b8ff8100..e2708a941c6 100644 --- a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js +++ b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js @@ -161,7 +161,16 @@ angular.module('zeppelinWebApp').service('websocketMsgSrv', function($rootScope, }); }, - isConnected: function() { + listRevisionHistory: function(noteId) { + websocketEvents.sendNewEvent({ + op: 'LIST_REVISION_HISTORY', + data: { + noteId: noteId + } + }); + }, + + isConnected: function(){ return websocketEvents.isConnected(); }, diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java index c56c4eed36e..e8c21ee1a2a 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java @@ -357,6 +357,11 @@ public void checkpointNote(String noteId, String checkpointMessage, Authenticati notebookRepo.checkpoint(noteId, checkpointMessage, subject); } + public List listRevisionHistory(String noteId, + AuthenticationInfo subject) { + return notebookRepo.revisionHistory(noteId, subject); + } + @SuppressWarnings("rawtypes") private Note loadNoteFromRepo(String id, AuthenticationInfo subject) { Note note = null; diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java index ab53f5f33c4..83ff9ecedff 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java @@ -21,6 +21,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -361,7 +362,12 @@ public Note get(String noteId, Revision rev, AuthenticationInfo subject) throws @Override public List revisionHistory(String noteId, AuthenticationInfo subject) { - // Auto-generated method stub - return null; + List revisions = Collections.emptyList(); + try { + revisions = getRepo(0).revisionHistory(noteId, subject); + } catch (IOException e) { + LOG.error("Failed to list revision history", e); + } + return revisions; } } diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java index 08b32359226..f0aac236fae 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java @@ -114,6 +114,8 @@ public static enum OP { CHECKPOINT_NOTEBOOK, // [c-s] checkpoint notebook to storage repository // @param noteId // @param checkpointName + LIST_REVISION_HISTORY, // [c-s] list revision history of the notebook + // @param noteId APP_APPEND_OUTPUT, // [s-c] append output APP_UPDATE_OUTPUT, // [s-c] update (replace) output From d8f42828bb2c55eb6fa51586c6e044eb1b88bba1 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Sun, 10 Jul 2016 13:49:28 +0900 Subject: [PATCH 02/16] add new note resource for tests with multiple notes --- .../src/test/resources/2A94M5J2Z/note.json | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 zeppelin-zengine/src/test/resources/2A94M5J2Z/note.json diff --git a/zeppelin-zengine/src/test/resources/2A94M5J2Z/note.json b/zeppelin-zengine/src/test/resources/2A94M5J2Z/note.json new file mode 100644 index 00000000000..79fe35cada9 --- /dev/null +++ b/zeppelin-zengine/src/test/resources/2A94M5J2Z/note.json @@ -0,0 +1,87 @@ +{ + "paragraphs": [ + { + "text": "%md\n## Congratulations, it\u0027s done.\n##### You can create your own notebook in \u0027Notebook\u0027 menu. Good luck!", + "config": { + "colWidth": 12.0, + "graph": { + "mode": "table", + "height": 300.0, + "optionOpen": false, + "keys": [], + "values": [], + "groups": [], + "scatter": {} + }, + "editorHide": true + }, + "settings": { + "params": {}, + "forms": {} + }, + "jobName": "paragraph_1423836268492_216498320", + "id": "20150213-230428_1231780373", + "result": { + "code": "SUCCESS", + "type": "HTML", + "msg": "\u003ch2\u003eCongratulations, it\u0027s done.\u003c/h2\u003e\n\u003ch5\u003eYou can create your own notebook in \u0027Notebook\u0027 menu. Good luck!\u003c/h5\u003e\n" + }, + "dateCreated": "Feb 13, 2015 11:04:28 PM", + "dateStarted": "Apr 1, 2015 9:12:18 PM", + "dateFinished": "Apr 1, 2015 9:12:18 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%md\n\nAbout bank data\n\n```\nCitation Request:\n This dataset is public available for research. The details are described in [Moro et al., 2011]. \n Please include this citation if you plan to use this database:\n\n [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, GuimarĂ£es, Portugal, October, 2011. EUROSIS.\n\n Available at: [pdf] http://hdl.handle.net/1822/14838\n [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n```", + "config": { + "colWidth": 12.0, + "graph": { + "mode": "table", + "height": 300.0, + "optionOpen": false, + "keys": [], + "values": [], + "groups": [], + "scatter": {} + }, + "editorHide": true + }, + "settings": { + "params": {}, + "forms": {} + }, + "jobName": "paragraph_1427420818407_872443482", + "id": "20150326-214658_12335843", + "result": { + "code": "SUCCESS", + "type": "HTML", + "msg": "\u003cp\u003eAbout bank data\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eCitation Request:\n This dataset is public available for research. The details are described in [Moro et al., 2011]. \n Please include this citation if you plan to use this database:\n\n [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, GuimarĂ£es, Portugal, October, 2011. EUROSIS.\n\n Available at: [pdf] http://hdl.handle.net/1822/14838\n [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n\u003c/code\u003e\u003c/pre\u003e\n" + }, + "dateCreated": "Mar 26, 2015 9:46:58 PM", + "dateStarted": "Jul 3, 2015 1:44:56 PM", + "dateFinished": "Jul 3, 2015 1:44:56 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "config": {}, + "settings": { + "params": {}, + "forms": {} + }, + "jobName": "paragraph_1435955447812_-158639899", + "id": "20150703-133047_853701097", + "dateCreated": "Jul 3, 2015 1:30:47 PM", + "status": "READY", + "progressUpdateIntervalMs": 500 + } + ], + "name": "Sample note - excerpt from Zeppelin Tutorial", + "id": "2A94M5J2Z", + "angularObjects": {}, + "config": { + "looknfeel": "default" + }, + "info": {} +} \ No newline at end of file From b4c69dfab3ab1b00295551502df79cc3ed6ef2c3 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Sun, 10 Jul 2016 14:43:53 +0900 Subject: [PATCH 03/16] add test: revision history, multiple notes --- .../notebook/repo/GitNotebookRepoTest.java | 55 +++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java index 8e787a2fdc5..b1d4b384e01 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java @@ -46,6 +46,7 @@ public class GitNotebookRepoTest { private static final String TEST_NOTE_ID = "2A94M5J1Z"; + private static final String TEST_NOTE_ID2 = "2A94M5J2Z"; private File zeppelinDir; private String notebooksDir; @@ -54,7 +55,7 @@ public class GitNotebookRepoTest { @Before public void setUp() throws Exception { - String zpath = System.getProperty("java.io.tmpdir")+"/ZeppelinTest_"+System.currentTimeMillis(); + String zpath = System.getProperty("java.io.tmpdir") + "/ZeppelinTest_" + System.currentTimeMillis(); zeppelinDir = new File(zpath); zeppelinDir.mkdirs(); new File(zeppelinDir, "conf").mkdirs(); @@ -64,8 +65,11 @@ public void setUp() throws Exception { notebookDir.mkdirs(); String testNoteDir = Joiner.on(File.separator).join(notebooksDir, TEST_NOTE_ID); + String testNoteDir2 = Joiner.on(File.separator).join(notebooksDir, TEST_NOTE_ID2); FileUtils.copyDirectory(new File(Joiner.on(File.separator).join("src", "test", "resources", TEST_NOTE_ID)), - new File(testNoteDir) + new File(testNoteDir)); + FileUtils.copyDirectory(new File(Joiner.on(File.separator).join("src", "test", "resources", TEST_NOTE_ID2)), + new File(testNoteDir2) ); System.setProperty(ConfVars.ZEPPELIN_HOME.getVarName(), zeppelinDir.getAbsolutePath()); @@ -106,7 +110,7 @@ public void initNonemptyNotebookDir() throws IOException, GitAPIException { } @Test - public void showNotebookHistory() throws GitAPIException, IOException { + public void showNotebookHistoryEmptyTest() throws GitAPIException, IOException { //given notebookRepo = new GitNotebookRepo(conf); assertThat(notebookRepo.list(null)).isNotEmpty(); @@ -120,7 +124,50 @@ public void showNotebookHistory() throws GitAPIException, IOException { } @Test - public void addCheckpoint() throws IOException { + public void showNotebookHistoryMultipleNotesTest() throws IOException { + //initial checks + notebookRepo = new GitNotebookRepo(conf); + assertThat(notebookRepo.list(null)).isNotEmpty(); + assertThat(containsNote(notebookRepo.list(null), TEST_NOTE_ID)).isTrue(); + assertThat(containsNote(notebookRepo.list(null), TEST_NOTE_ID2)).isTrue(); + assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID, null)).isEmpty(); + assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID2, null)).isEmpty(); + + //add commit to both notes + notebookRepo.checkpoint(TEST_NOTE_ID, "first commit, note1", null); + assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID, null).size()).isEqualTo(1); + notebookRepo.checkpoint(TEST_NOTE_ID2, "first commit, note2", null); + assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID2, null).size()).isEqualTo(1); + + //modify, save and checkpoint first note + Note note = notebookRepo.get(TEST_NOTE_ID, null); + Paragraph p = note.addParagraph(); + Map config = p.getConfig(); + config.put("enabled", true); + p.setConfig(config); + p.setText("%md note1 test text"); + notebookRepo.save(note, null); + assertThat(notebookRepo.checkpoint(TEST_NOTE_ID, "second commit, note1", null)).isNotNull(); + assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID, null).size()).isEqualTo(2); + assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID2, null).size()).isEqualTo(1); + assertThat(notebookRepo.checkpoint(TEST_NOTE_ID2, "first commit, note2", null)).isNull(); + assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID2, null).size()).isEqualTo(1); + + //modify, save and checkpoint second note + note = notebookRepo.get(TEST_NOTE_ID2, null); + p = note.addParagraph(); + config = p.getConfig(); + config.put("enabled", false); + p.setConfig(config); + p.setText("%md note2 test text"); + notebookRepo.save(note, null); + assertThat(notebookRepo.checkpoint(TEST_NOTE_ID2, "second commit, note2", null)).isNotNull(); + assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID, null).size()).isEqualTo(2); + assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID2, null).size()).isEqualTo(2); + } + + @Test + public void addCheckpointTest() throws IOException { // initial checks notebookRepo = new GitNotebookRepo(conf); assertThat(notebookRepo.list(null)).isNotEmpty(); From 18d430a2cc3124f0951fa923ccd24d6f4cbf3499 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Mon, 11 Jul 2016 15:26:49 +0900 Subject: [PATCH 04/16] add initial listing --- .../src/app/notebook/notebook-actionBar.html | 12 +++--------- .../src/app/notebook/notebook.controller.js | 18 +++++++++++------- .../websocketEvents/websocketMsg.service.js | 2 +- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html index 3344772155c..575eeb694a5 100644 --- a/zeppelin-web/src/app/notebook/notebook-actionBar.html +++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html @@ -91,16 +91,10 @@

    -
  • +
  • - - table + message: {{revision[$index].message}} + time: {{revision[$index].time}}
  • diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js index 049c939ca43..996aa574150 100644 --- a/zeppelin-web/src/app/notebook/notebook.controller.js +++ b/zeppelin-web/src/app/notebook/notebook.controller.js @@ -55,6 +55,16 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro var searchText = []; $scope.role = ''; + $scope.noteRevisions = websocketMsgSrv.listRevisionHistory($routeParams.noteId); + + + $scope.$on('setConnectedStatus', function(event, param) { + if (connectedOnce && param) { + initNotebook(); + } + connectedOnce = true; + }); + $scope.getCronOptionNameFromValue = function(value) { if (!value) { return ''; @@ -175,15 +185,9 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro document.getElementById('note.checkpoint.message').value = ''; }; - $scope.listRevisionHistory = function() { - websocketMsgSrv.listRevisionHistory($routeParams.noteId); - }; - $scope.$on('listRevisionHistory', function(event, data) { console.log(data); - if (data === '{}') { - console.log('empty data'); - } + $scope.noteRevisions = data; }); $scope.runNote = function() { diff --git a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js index e2708a941c6..653255d9dbe 100644 --- a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js +++ b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js @@ -170,7 +170,7 @@ angular.module('zeppelinWebApp').service('websocketMsgSrv', function($rootScope, }); }, - isConnected: function(){ + isConnected: function() { return websocketEvents.isConnected(); }, From bcf6cf1d3bdeee628d634924cf44bcb87f8b3183 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Mon, 11 Jul 2016 16:15:24 +0900 Subject: [PATCH 05/16] return list on successful commit --- .../java/org/apache/zeppelin/socket/NotebookServer.java | 8 +++++++- .../main/java/org/apache/zeppelin/notebook/Notebook.java | 7 ++++--- 2 files changed, 11 insertions(+), 4 deletions(-) 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 147c9a3d557..0cadabeab84 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 @@ -46,6 +46,7 @@ import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener; import org.apache.zeppelin.notebook.*; import org.apache.zeppelin.notebook.repo.NotebookRepo; +import org.apache.zeppelin.notebook.repo.NotebookRepo.Revision; import org.apache.zeppelin.notebook.socket.Message; import org.apache.zeppelin.notebook.socket.Message.OP; import org.apache.zeppelin.scheduler.Job; @@ -1130,7 +1131,12 @@ private void checkpointNotebook(NotebookSocket conn, Notebook notebook, String noteId = (String) fromMessage.get("noteId"); String commitMessage = (String) fromMessage.get("commitMessage"); AuthenticationInfo subject = new AuthenticationInfo(fromMessage.principal); - notebook.checkpointNote(noteId, commitMessage, subject); + Revision revision = notebook.checkpointNote(noteId, commitMessage, subject); + if (revision != null) { + List revisions = notebook.listRevisionHistory(noteId, subject); + conn.send(serializeMessage(new Message(OP.LIST_REVISION_HISTORY) + .put("revisionList", revisions))); + } } private void listRevisionHistory(NotebookSocket conn, Notebook notebook, diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java index e8c21ee1a2a..7285988e0de 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java @@ -55,6 +55,7 @@ import org.apache.zeppelin.interpreter.InterpreterSetting; import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry; import org.apache.zeppelin.notebook.repo.NotebookRepo; +import org.apache.zeppelin.notebook.repo.NotebookRepo.Revision; import org.apache.zeppelin.notebook.repo.NotebookRepoSync; import org.apache.zeppelin.resource.ResourcePoolUtils; import org.apache.zeppelin.scheduler.Job; @@ -352,9 +353,9 @@ public void removeNote(String id, AuthenticationInfo subject) { } } - public void checkpointNote(String noteId, String checkpointMessage, AuthenticationInfo subject) - throws IOException { - notebookRepo.checkpoint(noteId, checkpointMessage, subject); + public Revision checkpointNote(String noteId, String checkpointMessage, + AuthenticationInfo subject) throws IOException { + return notebookRepo.checkpoint(noteId, checkpointMessage, subject); } public List listRevisionHistory(String noteId, From 660139b91e7416ffd975e6bb58914664e7d97a2c Mon Sep 17 00:00:00 2001 From: Damien CORNEAU Date: Tue, 12 Jul 2016 15:03:25 +0900 Subject: [PATCH 06/16] fix the jscs error --- zeppelin-web/src/app/notebook/notebook.controller.js | 1 - 1 file changed, 1 deletion(-) diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js index 996aa574150..6b3e18e6c03 100644 --- a/zeppelin-web/src/app/notebook/notebook.controller.js +++ b/zeppelin-web/src/app/notebook/notebook.controller.js @@ -57,7 +57,6 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro $scope.noteRevisions = websocketMsgSrv.listRevisionHistory($routeParams.noteId); - $scope.$on('setConnectedStatus', function(event, param) { if (connectedOnce && param) { initNotebook(); From 9523b481a1254ab9fbb51834f5e61660a7528eab Mon Sep 17 00:00:00 2001 From: Damien CORNEAU Date: Tue, 12 Jul 2016 17:48:43 +0900 Subject: [PATCH 07/16] Add dropdown of revisions --- .../src/app/notebook/notebook-actionBar.html | 82 +++++++++++-------- .../src/app/notebook/notebook.controller.js | 9 +- zeppelin-web/src/app/notebook/notebook.css | 32 ++++++++ 3 files changed, 86 insertions(+), 37 deletions(-) diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html index 575eeb694a5..a11dad60986 100644 --- a/zeppelin-web/src/app/notebook/notebook-actionBar.html +++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html @@ -64,40 +64,56 @@

    tooltip-placement="bottom" tooltip="Export the notebook"> - - + + + + diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js index 6b3e18e6c03..673d766c658 100644 --- a/zeppelin-web/src/app/notebook/notebook.controller.js +++ b/zeppelin-web/src/app/notebook/notebook.controller.js @@ -19,6 +19,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro $rootScope, $http, websocketMsgSrv, baseUrlSrv, $timeout, SaveAsService) { $scope.note = null; + $scope.moment = moment; $scope.showEditor = false; $scope.editorToggled = false; $scope.tableToggled = false; @@ -54,8 +55,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro var previousSelectedListWriters = []; var searchText = []; $scope.role = ''; - - $scope.noteRevisions = websocketMsgSrv.listRevisionHistory($routeParams.noteId); + $scope.noteRevisions = []; $scope.$on('setConnectedStatus', function(event, param) { if (connectedOnce && param) { @@ -80,6 +80,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro /** Init the new controller */ var initNotebook = function() { websocketMsgSrv.getNotebook($routeParams.noteId); + websocketMsgSrv.listRevisionHistory($routeParams.noteId); var currentRoute = $route.current; if (currentRoute) { @@ -185,8 +186,8 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro }; $scope.$on('listRevisionHistory', function(event, data) { - console.log(data); - $scope.noteRevisions = data; + console.log("We got the revisions yeahh %o", data); + $scope.noteRevisions = data.revisionList; }); $scope.runNote = function() { diff --git a/zeppelin-web/src/app/notebook/notebook.css b/zeppelin-web/src/app/notebook/notebook.css index 59f756168f5..10b0538e18d 100644 --- a/zeppelin-web/src/app/notebook/notebook.css +++ b/zeppelin-web/src/app/notebook/notebook.css @@ -14,6 +14,38 @@ .notebookContent { padding-top: 36px; + +.revision { + max-width: 250px; + margin-bottom: 0 !important; +} + +.revision a { + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + padding: 2px 10px !important; +} + +.revisionName { + cursor: default; + padding: 1px 10px !important; + max-width: 150px; +} + +.revisionName:hover, +.revisionName:focus, +.revisionName:active { + background: transparent; + border-color: #ccc; +} + +.caretSeparator { + height: 22px; + line-height: 9px; + width: 16px; + padding-left: 3px !important; } .paragraph-col { From ee7b94fc501f939dc09b5fd2e595add8e466e4ee Mon Sep 17 00:00:00 2001 From: Damien CORNEAU Date: Tue, 12 Jul 2016 17:53:16 +0900 Subject: [PATCH 08/16] Reverse revisions order to have the latest first --- zeppelin-web/src/app/notebook/notebook-actionBar.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html index a11dad60986..0496722c256 100644 --- a/zeppelin-web/src/app/notebook/notebook-actionBar.html +++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html @@ -109,7 +109,7 @@

    From 1d20aeb7f573cf3fadeb6be0a28a8ca37a7d8f21 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Wed, 13 Jul 2016 18:00:45 +0900 Subject: [PATCH 09/16] fix jshint checkstyle --- zeppelin-web/src/app/notebook/notebook.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js index 673d766c658..89878389a1c 100644 --- a/zeppelin-web/src/app/notebook/notebook.controller.js +++ b/zeppelin-web/src/app/notebook/notebook.controller.js @@ -186,7 +186,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro }; $scope.$on('listRevisionHistory', function(event, data) { - console.log("We got the revisions yeahh %o", data); + console.log('We got the revisions %o', data); $scope.noteRevisions = data.revisionList; }); From 2090d60bd36d38477e8cb2b59917d2c9a3ed08f7 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Thu, 14 Jul 2016 13:19:44 +0900 Subject: [PATCH 10/16] mock listRevisionHistory --- zeppelin-web/test/spec/controllers/notebook.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zeppelin-web/test/spec/controllers/notebook.js b/zeppelin-web/test/spec/controllers/notebook.js index 317a905b4f1..f4f6e46dbe0 100644 --- a/zeppelin-web/test/spec/controllers/notebook.js +++ b/zeppelin-web/test/spec/controllers/notebook.js @@ -7,7 +7,8 @@ describe('Controller: NotebookCtrl', function() { var scope; var websocketMsgSrvMock = { - getNotebook: function() {} + getNotebook: function() {}, + listRevisionHistory: function() {} }; var baseUrlSrvMock = { From e6bafdec84cd4e5a42d07f04abc696941b6e81bd Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Tue, 19 Jul 2016 03:06:22 +0900 Subject: [PATCH 11/16] change time format --- zeppelin-web/src/app/notebook/notebook-actionBar.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html index 0496722c256..247140329fe 100644 --- a/zeppelin-web/src/app/notebook/notebook-actionBar.html +++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html @@ -110,7 +110,7 @@

    From 4607c0309d9e3a37b33e648e8512155b870e6293 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Tue, 19 Jul 2016 15:16:52 +0900 Subject: [PATCH 12/16] fix css fix rebase --- zeppelin-web/src/app/notebook/notebook.css | 1 + 1 file changed, 1 insertion(+) diff --git a/zeppelin-web/src/app/notebook/notebook.css b/zeppelin-web/src/app/notebook/notebook.css index 10b0538e18d..cc88c5052ef 100644 --- a/zeppelin-web/src/app/notebook/notebook.css +++ b/zeppelin-web/src/app/notebook/notebook.css @@ -14,6 +14,7 @@ .notebookContent { padding-top: 36px; +} .revision { max-width: 250px; From 0445b42de01acea8dccc0843de714de91926b5a2 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Tue, 19 Jul 2016 22:26:40 +0900 Subject: [PATCH 13/16] move date to right, add time --- zeppelin-web/src/app/notebook/notebook-actionBar.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html index 247140329fe..02e55204cab 100644 --- a/zeppelin-web/src/app/notebook/notebook-actionBar.html +++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html @@ -110,7 +110,7 @@

    From bd068fdf43a9177fd16bc7a3c23ee74aaab81212 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Tue, 19 Jul 2016 22:35:42 +0900 Subject: [PATCH 14/16] add css class with smaller font for revision date --- zeppelin-web/src/app/notebook/notebook-actionBar.html | 6 +++++- zeppelin-web/src/app/notebook/notebook.css | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html index 02e55204cab..41b40a4bb6a 100644 --- a/zeppelin-web/src/app/notebook/notebook-actionBar.html +++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html @@ -110,7 +110,11 @@

    diff --git a/zeppelin-web/src/app/notebook/notebook.css b/zeppelin-web/src/app/notebook/notebook.css index cc88c5052ef..600a9eeff14 100644 --- a/zeppelin-web/src/app/notebook/notebook.css +++ b/zeppelin-web/src/app/notebook/notebook.css @@ -35,6 +35,10 @@ max-width: 150px; } +.revisionDate { + font-size:80%; +} + .revisionName:hover, .revisionName:focus, .revisionName:active { From 614ed61ab1b47bd5276d64d477983b605a25f6b8 Mon Sep 17 00:00:00 2001 From: Khalid Huseynov Date: Wed, 20 Jul 2016 17:26:10 +0900 Subject: [PATCH 15/16] date: smaller font and spacing --- zeppelin-web/src/app/notebook/notebook-actionBar.html | 2 +- zeppelin-web/src/app/notebook/notebook.css | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html index 41b40a4bb6a..0e725f81119 100644 --- a/zeppelin-web/src/app/notebook/notebook-actionBar.html +++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html @@ -110,7 +110,7 @@