Repository: incubator-zeppelin Updated Branches: refs/heads/master d5ab911bf -> 014696197
ZEPPELIN-210 Show notebook in a homescreen https://issues.apache.org/jira/browse/ZEPPELIN-210 This patch lets user specify a notebook id by `ZEPPELIN_NOTEBOOK_HOMESCREEN` environment variable or `zeppelin.notebook.homescreen` property. Then Zeppelin default homescreen will be replaced by the notebook. Here's an example of home screen  Author: Lee moon soo <[email protected]> This patch had conflicts when merged, resolved by Committer: Lee moon soo <[email protected]> Closes #191 from Leemoonsoo/homenotebook and squashes the following commits: 1a30e48 [Lee moon soo] Add ZEPPELIN_NOTEBOOK_HOMESCREEN, ZEPPELIN_NOTEBOOK_HOMESCREEN_HIDE to zeppelin-env.sh.template e14fdb6 [Lee moon soo] add zeppelin.notebook.homescreen.hide option 7e88ee4 [Lee moon soo] Add zeppelin.notebook.homescreen to zeppelin-site.xml.tempate 10d4665 [Lee moon soo] Add home screen theme 6ea2318 [Lee moon soo] show notebook in a homescreen Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/01469619 Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/01469619 Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/01469619 Branch: refs/heads/master Commit: 014696197be71ff1186e3075b3e2f25cffbaccd7 Parents: d5ab911 Author: Lee moon soo <[email protected]> Authored: Sun Aug 9 15:00:29 2015 -0700 Committer: Lee moon soo <[email protected]> Committed: Sun Aug 16 08:17:38 2015 -0700 ---------------------------------------------------------------------- conf/zeppelin-env.sh.template | 2 + conf/zeppelin-site.xml.template | 13 +++ .../org/apache/zeppelin/socket/Message.java | 2 + .../apache/zeppelin/socket/NotebookServer.java | 33 +++++++ zeppelin-web/src/app/home/home.controller.js | 26 +++++- zeppelin-web/src/app/home/home.css | 3 +- zeppelin-web/src/app/home/home.html | 21 ++++- .../src/assets/styles/looknfeel/home.css | 97 ++++++++++++++++++++ .../websocketEvents/websocketMsg.service.js | 4 + .../zeppelin/conf/ZeppelinConfiguration.java | 4 + .../org/apache/zeppelin/notebook/Notebook.java | 3 + 11 files changed, 204 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/conf/zeppelin-env.sh.template ---------------------------------------------------------------------- diff --git a/conf/zeppelin-env.sh.template b/conf/zeppelin-env.sh.template index bfaf436..a5beda7 100644 --- a/conf/zeppelin-env.sh.template +++ b/conf/zeppelin-env.sh.template @@ -26,6 +26,8 @@ # export ZEPPELIN_LOG_DIR # Where log files are stored. PWD by default. # export ZEPPELIN_PID_DIR # The pid files are stored. /tmp by default. # export ZEPPELIN_NOTEBOOK_DIR # Where notebook saved +# export ZEPPELIN_NOTEBOOK_HOMESCREEN # Id of notebook to be displayed in homescreen. ex) 2A94M5J1Z +# export ZEPPELIN_NOTEBOOK_HOMESCREEN_HIDE # hide homescreen notebook from list when this value set to "true". default "false" # export ZEPPELIN_NOTEBOOK_S3_BUCKET # Bucket where notebook saved # export ZEPPELIN_NOTEBOOK_S3_USER # User in bucket where notebook saved. For example bucket/user/notebook/2A94M5J1Z/note.json # export ZEPPELIN_IDENT_STRING # A string representing this instance of zeppelin. $USER by default. http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/conf/zeppelin-site.xml.template ---------------------------------------------------------------------- diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template index 6d03f6e..57d1b23 100644 --- a/conf/zeppelin-site.xml.template +++ b/conf/zeppelin-site.xml.template @@ -37,6 +37,19 @@ <description>path or URI for notebook persist</description> </property> +<property> + <name>zeppelin.notebook.homescreen</name> + <value></value> + <description>id of notebook to be displayed in homescreen. ex) 2A94M5J1Z Empty value displays default home screen</description> +</property> + +<property> + <name>zeppelin.notebook.homescreen.hide</name> + <value>false</value> + <description>hide homescreen notebook from list when this value set to true</description> +</property> + + <!-- If used S3 to storage the notebooks, it is necessary the following folder structure bucketname/username/notebook/ --> <!-- <property> http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/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 d78f202..1784c53 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 @@ -34,6 +34,8 @@ public class Message { * */ public static enum OP { + GET_HOME_NOTE, // [c-s] load note for home screen + GET_NOTE, // [c-s] client load note // @param id note id http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/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 8c8b600..8a02b53 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 @@ -25,6 +25,9 @@ import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; + +import org.apache.zeppelin.conf.ZeppelinConfiguration; +import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; import org.apache.zeppelin.display.AngularObject; import org.apache.zeppelin.display.AngularObjectRegistry; import org.apache.zeppelin.display.AngularObjectRegistryListener; @@ -110,6 +113,9 @@ public class NotebookServer extends WebSocketServlet implements case LIST_NOTES: broadcastNoteList(); break; + case GET_HOME_NOTE: + sendHomeNote(conn, notebook); + break; case GET_NOTE: sendNote(conn, notebook, messagereceived); break; @@ -279,10 +285,20 @@ public class NotebookServer extends WebSocketServlet implements private void broadcastNoteList() { Notebook notebook = notebook(); + + ZeppelinConfiguration conf = notebook.getConf(); + String homescreenNotebookId = conf.getString(ConfVars.ZEPPELIN_NOTEBOOK_HOMESCREEN); + boolean hideHomeScreenNotebookFromList = conf + .getBoolean(ConfVars.ZEPPELIN_NOTEBOOK_HOMESCREEN_HIDE); + List<Note> notes = notebook.getAllNotes(); List<Map<String, String>> notesInfo = new LinkedList<>(); for (Note note : notes) { Map<String, String> info = new HashMap<>(); + if (hideHomeScreenNotebookFromList && note.id().equals(homescreenNotebookId)) { + continue; + } + info.put("id", note.id()); info.put("name", note.getName()); notesInfo.add(info); @@ -306,6 +322,23 @@ public class NotebookServer extends WebSocketServlet implements } } + private void sendHomeNote(NotebookSocket conn, Notebook notebook) throws IOException { + String noteId = notebook.getConf().getString(ConfVars.ZEPPELIN_NOTEBOOK_HOMESCREEN); + + Note note = null; + if (noteId != null) { + note = notebook.getNote(noteId); + } + + if (note != null) { + addConnectionToNote(note.id(), conn); + conn.send(serializeMessage(new Message(OP.NOTE).put("note", note))); + sendAllAngularObjects(note, conn); + } else { + conn.send(serializeMessage(new Message(OP.NOTE).put("note", null))); + } + } + private void updateNote(WebSocket conn, Notebook notebook, Message fromMessage) throws SchedulerException, IOException { String noteId = (String) fromMessage.get("id"); http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/zeppelin-web/src/app/home/home.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/home/home.controller.js b/zeppelin-web/src/app/home/home.controller.js index e66201c..d3fba0f 100644 --- a/zeppelin-web/src/app/home/home.controller.js +++ b/zeppelin-web/src/app/home/home.controller.js @@ -13,10 +13,34 @@ */ 'use strict'; -angular.module('zeppelinWebApp').controller('HomeCtrl', function($scope, notebookListDataFactory, websocketMsgSrv) { +angular.module('zeppelinWebApp').controller('HomeCtrl', function($scope, notebookListDataFactory, websocketMsgSrv, $rootScope) { var vm = this; vm.notes = notebookListDataFactory; vm.websocketMsgSrv = websocketMsgSrv; + + $scope.notebookHome = false; + $scope.staticHome = false; + var initHome = function() { + websocketMsgSrv.getHomeNotebook(); + } + + initHome(); + + $scope.$on('setNoteContent', function(event, note) { + if (note) { + $scope.note = note; + + // initialize look And Feel + $rootScope.$broadcast('setLookAndFeel', 'home'); + + // make it read only + $scope.viewOnly = true; + + $scope.notebookHome = true; + } else { + $scope.staticHome = true; + } + }); }); http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/zeppelin-web/src/app/home/home.css ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/home/home.css b/zeppelin-web/src/app/home/home.css index 9bf1e7b..5d5e115 100644 --- a/zeppelin-web/src/app/home/home.css +++ b/zeppelin-web/src/app/home/home.css @@ -293,5 +293,4 @@ This part should be removed when new version of bootstrap handles this issue. .btn-group > .tooltip + .btn, .btn-group > .popover + .btn { margin-left:-1px; -} - +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/zeppelin-web/src/app/home/home.html ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/home/home.html b/zeppelin-web/src/app/home/home.html index b3991ae..f437d61 100644 --- a/zeppelin-web/src/app/home/home.html +++ b/zeppelin-web/src/app/home/home.html @@ -12,7 +12,7 @@ See the License for the specific language governing permissions and limitations under the License. --> -<div class="box width-full home" ng-controller="HomeCtrl as home"> +<div ng-show="staticHome" class="box width-full home" ng-controller="HomeCtrl as home"> <div class="zeppelin"> <div class="zeppelin2"></div> </div> @@ -51,3 +51,22 @@ limitations under the License. </div> <br/><br/><br/> </div> + + +<!-- Load notebook --> +<div id="{{currentParagraph.id}}_paragraphColumn_main" + ng-show="notebookHome" + ng-repeat="currentParagraph in note.paragraphs" + ng-controller="ParagraphCtrl" + ng-Init="init(currentParagraph)" + ng-class="columnWidthClass(currentParagraph.config.colWidth)" + class="paragraph-col"> + <div id="{{currentParagraph.id}}_paragraphColumn" + ng-if="currentParagraph.result" + ng-include src="'app/notebook/paragraph/paragraph.html'" + ng-class="{'paragraph-space box paragraph-margin': !asIframe, 'focused': paragraphFocused}" + ng-hide="currentParagraph.config.tableHide && viewOnly"> + </div> +</div> + +<div style="clear:both;height:10px"></div> http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/zeppelin-web/src/assets/styles/looknfeel/home.css ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/assets/styles/looknfeel/home.css b/zeppelin-web/src/assets/styles/looknfeel/home.css new file mode 100644 index 0000000..b25d37a --- /dev/null +++ b/zeppelin-web/src/assets/styles/looknfeel/home.css @@ -0,0 +1,97 @@ +/* + * 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. + */ + + +/** + * Theme for homescreen + */ + + +body { + background: #ecf0f1; +} + +/** + * Box and well + */ +.box{ + border-style: solid; + min-height: 20px; + padding: 19px; + margin-bottom: 20px; +} + +.box, +.well { + background-color: #ffffff; + border-color: #e5e5e5; + border-width: 1px 1px 2px; + border-radius: 3px; + -webkit-box-shadow: none; + box-shadow: none; +} + +.paragraph { + min-height: 32px; +} + +.noteAction { + background-color: white; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); + color: #2c3e50; + border-bottom: 1px solid #E5E5E5; +} + +.control span { + margin-left: 4px; +} + +.control { + padding: 4px; +} + +.paragraph-space { + margin-bottom: 5px; + padding: 10px !important; +} + +.editor, +.executionTime, +.nv-controlsWrap { + display:block; +} + + +.paragraph .control { + visibility : hidden; + right:15px; + top: 6px; +} + +.paragraph:hover .control { + visibility : hidden; +} + +.noteAction span, .noteAction button, .noteAction form { + visibility : hidden; +} + +.noteAction:hover span, .noteAction:hover button, .noteAction:hover form { + visibility : visible; +} + +.executionTime, +.nv-controlsWrap { + display:none; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/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 fcdc51f..a30905c 100644 --- a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js +++ b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js @@ -17,6 +17,10 @@ angular.module('zeppelinWebApp').service('websocketMsgSrv', function($rootScope, return { + getHomeNotebook: function() { + websocketEvents.sendNewEvent({op: 'GET_HOME_NOTE'}); + }, + createNotebook: function(noteName) { websocketEvents.sendNewEvent({op: 'NEW_NOTE',data: {name: noteName}}); }, http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java index 0d2eb58..6fda2b2 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java @@ -401,6 +401,10 @@ public class ZeppelinConfiguration extends XMLConfiguration { ZEPPELIN_INTERPRETER_CONNECT_TIMEOUT("zeppelin.interpreter.connect.timeout", 30000), ZEPPELIN_ENCODING("zeppelin.encoding", "UTF-8"), ZEPPELIN_NOTEBOOK_DIR("zeppelin.notebook.dir", "notebook"), + // use specified notebook (id) as homescreen + ZEPPELIN_NOTEBOOK_HOMESCREEN("zeppelin.notebook.homescreen", null), + // whether homescreen notebook will be hidden from notebook list or not + ZEPPELIN_NOTEBOOK_HOMESCREEN_HIDE("zeppelin.notebook.homescreen.hide", false), ZEPPELIN_NOTEBOOK_S3_BUCKET("zeppelin.notebook.s3.bucket", "zeppelin"), ZEPPELIN_NOTEBOOK_S3_USER("zeppelin.notebook.s3.user", "user"), ZEPPELIN_NOTEBOOK_STORAGE("zeppelin.notebook.storage", VFSNotebookRepo.class.getName()), http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/01469619/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java ---------------------------------------------------------------------- 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 5383d27..03c9638 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 @@ -399,5 +399,8 @@ public class Notebook { return replFactory; } + public ZeppelinConfiguration getConf() { + return conf; + } }
