mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
Merge remote-tracking branch 'upstream/master' into ZEPPELIN-2403
This commit is contained in:
commit
07160e00eb
25 changed files with 216 additions and 73 deletions
|
|
@ -64,7 +64,7 @@ fi
|
|||
|
||||
. "${bin}/common.sh"
|
||||
|
||||
ZEPPELIN_INTP_CLASSPATH=""
|
||||
ZEPPELIN_INTP_CLASSPATH="${CLASSPATH}"
|
||||
|
||||
# construct classpath
|
||||
if [[ -d "${ZEPPELIN_HOME}/zeppelin-interpreter/target/classes" ]]; then
|
||||
|
|
@ -190,8 +190,6 @@ fi
|
|||
|
||||
addJarInDirForIntp "${LOCAL_INTERPRETER_REPO}"
|
||||
|
||||
CLASSPATH+=":${ZEPPELIN_INTP_CLASSPATH}"
|
||||
|
||||
if [[ ! -z "$ZEPPELIN_IMPERSONATE_USER" ]]; then
|
||||
suid="$(id -u ${ZEPPELIN_IMPERSONATE_USER})"
|
||||
if [[ -n "${suid}" || -z "${SPARK_SUBMIT}" ]]; then
|
||||
|
|
@ -204,12 +202,12 @@ fi
|
|||
|
||||
if [[ -n "${SPARK_SUBMIT}" ]]; then
|
||||
if [[ -n "$ZEPPELIN_IMPERSONATE_USER" ]] && [[ "$ZEPPELIN_IMPERSONATE_SPARK_PROXY_USER" != "false" ]]; then
|
||||
INTERPRETER_RUN_COMMAND+=' '` echo ${SPARK_SUBMIT} --class ${ZEPPELIN_SERVER} --driver-class-path \"${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${CLASSPATH}\" --driver-java-options \"${JAVA_INTP_OPTS}\" ${SPARK_SUBMIT_OPTIONS} --proxy-user ${ZEPPELIN_IMPERSONATE_USER} ${SPARK_APP_JAR} ${PORT}`
|
||||
INTERPRETER_RUN_COMMAND+=' '` echo ${SPARK_SUBMIT} --class ${ZEPPELIN_SERVER} --driver-class-path \"${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${ZEPPELIN_INTP_CLASSPATH}\" --driver-java-options \"${JAVA_INTP_OPTS}\" ${SPARK_SUBMIT_OPTIONS} --proxy-user ${ZEPPELIN_IMPERSONATE_USER} ${SPARK_APP_JAR} ${PORT}`
|
||||
else
|
||||
INTERPRETER_RUN_COMMAND+=' '` echo ${SPARK_SUBMIT} --class ${ZEPPELIN_SERVER} --driver-class-path \"${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${CLASSPATH}\" --driver-java-options \"${JAVA_INTP_OPTS}\" ${SPARK_SUBMIT_OPTIONS} ${SPARK_APP_JAR} ${PORT}`
|
||||
INTERPRETER_RUN_COMMAND+=' '` echo ${SPARK_SUBMIT} --class ${ZEPPELIN_SERVER} --driver-class-path \"${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${ZEPPELIN_INTP_CLASSPATH}\" --driver-java-options \"${JAVA_INTP_OPTS}\" ${SPARK_SUBMIT_OPTIONS} ${SPARK_APP_JAR} ${PORT}`
|
||||
fi
|
||||
else
|
||||
INTERPRETER_RUN_COMMAND+=' '` echo ${ZEPPELIN_RUNNER} ${JAVA_INTP_OPTS} ${ZEPPELIN_INTP_MEM} -cp ${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${CLASSPATH} ${ZEPPELIN_SERVER} ${PORT} `
|
||||
INTERPRETER_RUN_COMMAND+=' '` echo ${ZEPPELIN_RUNNER} ${JAVA_INTP_OPTS} ${ZEPPELIN_INTP_MEM} -cp ${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${ZEPPELIN_INTP_CLASSPATH} ${ZEPPELIN_SERVER} ${PORT} `
|
||||
fi
|
||||
|
||||
if [[ ! -z "$ZEPPELIN_IMPERSONATE_USER" ]] && [[ -n "${suid}" || -z "${SPARK_SUBMIT}" ]]; then
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ addJarInDir "${ZEPPELIN_HOME}/zeppelin-zengine/target/lib"
|
|||
addJarInDir "${ZEPPELIN_HOME}/zeppelin-server/target/lib"
|
||||
addJarInDir "${ZEPPELIN_HOME}/zeppelin-web/target/lib"
|
||||
|
||||
CLASSPATH+=":${ZEPPELIN_CLASSPATH}"
|
||||
ZEPPELIN_CLASSPATH="$CLASSPATH:$ZEPPELIN_CLASSPATH"
|
||||
|
||||
if [[ ! -d "${ZEPPELIN_LOG_DIR}" ]]; then
|
||||
echo "Log dir doesn't exist, create ${ZEPPELIN_LOG_DIR}"
|
||||
|
|
@ -83,4 +83,4 @@ if [[ ! -d "${ZEPPELIN_PID_DIR}" ]]; then
|
|||
$(mkdir -p "${ZEPPELIN_PID_DIR}")
|
||||
fi
|
||||
|
||||
exec $ZEPPELIN_RUNNER $JAVA_OPTS -cp $ZEPPELIN_CLASSPATH_OVERRIDES:$CLASSPATH $ZEPPELIN_SERVER "$@"
|
||||
exec $ZEPPELIN_RUNNER $JAVA_OPTS -cp $ZEPPELIN_CLASSPATH_OVERRIDES:${ZEPPELIN_CLASSPATH} $ZEPPELIN_SERVER "$@"
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ public class JDBCInterpreter extends Interpreter {
|
|||
logger.debug("propertyKey: {}", propertyKey);
|
||||
String[] keyValue = propertyKey.split("\\.", 2);
|
||||
if (2 == keyValue.length) {
|
||||
logger.info("key: {}, value: {}", keyValue[0], keyValue[1]);
|
||||
logger.debug("key: {}, value: {}", keyValue[0], keyValue[1]);
|
||||
|
||||
Properties prefixProperties;
|
||||
if (basePropretiesMap.containsKey(keyValue[0])) {
|
||||
|
|
@ -249,6 +249,7 @@ public class JDBCInterpreter extends Interpreter {
|
|||
|
||||
private boolean existAccountInBaseProperty(String propertyKey) {
|
||||
return basePropretiesMap.get(propertyKey).containsKey(USER_KEY) &&
|
||||
!isEmpty((String) basePropretiesMap.get(propertyKey).get(USER_KEY)) &&
|
||||
basePropretiesMap.get(propertyKey).containsKey(PASSWORD_KEY);
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +296,6 @@ public class JDBCInterpreter extends Interpreter {
|
|||
}
|
||||
}
|
||||
jdbcUserConfigurations.setPropertyMap(propertyKey, basePropretiesMap.get(propertyKey));
|
||||
|
||||
if (existAccountInBaseProperty(propertyKey)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -576,7 +576,7 @@ public class JDBCInterpreter extends Interpreter {
|
|||
String precode = getProperty(String.format(PRECODE_KEY_TEMPLATE, propertyKey));
|
||||
if (StringUtils.isNotBlank(precode)) {
|
||||
precode = StringUtils.trim(precode);
|
||||
logger.info("Run SQL precode '{}'", precode);
|
||||
logger.debug("Run SQL precode '{}'", precode);
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute(precode);
|
||||
if (!connection.getAutoCommit()) {
|
||||
|
|
@ -720,7 +720,7 @@ public class JDBCInterpreter extends Interpreter {
|
|||
|
||||
@Override
|
||||
public InterpreterResult interpret(String cmd, InterpreterContext contextInterpreter) {
|
||||
logger.info("Run SQL command '{}'", cmd);
|
||||
logger.debug("Run SQL command '{}'", cmd);
|
||||
String propertyKey = getPropertyKey(cmd);
|
||||
|
||||
if (null != propertyKey && !propertyKey.equals(DEFAULT_KEY)) {
|
||||
|
|
@ -728,8 +728,7 @@ public class JDBCInterpreter extends Interpreter {
|
|||
}
|
||||
|
||||
cmd = cmd.trim();
|
||||
|
||||
logger.info("PropertyKey: {}, SQL command: '{}'", propertyKey, cmd);
|
||||
logger.debug("PropertyKey: {}, SQL command: '{}'", propertyKey, cmd);
|
||||
return executeSql(propertyKey, cmd, contextInterpreter);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -339,18 +339,18 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter {
|
|||
* 'jdbc1' interpreter has user('dbuser')/password('dbpassword') property
|
||||
* 'jdbc2' interpreter doesn't have user/password property
|
||||
* 'user1' doesn't have Credential information.
|
||||
* 'user2' has 'jdbc2' Credential information that is same with database account.
|
||||
* 'user2' has 'jdbc2' Credential information that is 'user2Id' / 'user2Pw' as id and password
|
||||
*/
|
||||
|
||||
JDBCInterpreter jdbc1 = new JDBCInterpreter(getDBProperty("dbuser", "dbpassword"));
|
||||
JDBCInterpreter jdbc2 = new JDBCInterpreter(getDBProperty(null, null));
|
||||
JDBCInterpreter jdbc2 = new JDBCInterpreter(getDBProperty("", ""));
|
||||
|
||||
AuthenticationInfo user1Credential = getUserAuth("user1", null, null, null);
|
||||
AuthenticationInfo user2Credential = getUserAuth("user2", "jdbc.jdbc2", "dbuser", "dbpassword");
|
||||
AuthenticationInfo user2Credential = getUserAuth("user2", "jdbc.jdbc2", "user2Id","user2Pw");
|
||||
|
||||
// user1 runs jdbc1
|
||||
jdbc1.open();
|
||||
InterpreterContext ctx1 = new InterpreterContext("", "1", "jdbc.jdbc1", "", "", user1Credential,
|
||||
InterpreterContext ctx1 = new InterpreterContext("", "1", "jdbc1", "", "", user1Credential,
|
||||
null, null, null, null, null, null);
|
||||
jdbc1.interpret("", ctx1);
|
||||
|
||||
|
|
@ -361,7 +361,7 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter {
|
|||
|
||||
// user1 runs jdbc2
|
||||
jdbc2.open();
|
||||
InterpreterContext ctx2 = new InterpreterContext("", "1", "jdbc.jdbc2", "", "", user1Credential,
|
||||
InterpreterContext ctx2 = new InterpreterContext("", "1", "jdbc2", "", "", user1Credential,
|
||||
null, null, null, null, null, null);
|
||||
jdbc2.interpret("", ctx2);
|
||||
|
||||
|
|
@ -372,7 +372,7 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter {
|
|||
|
||||
// user2 runs jdbc1
|
||||
jdbc1.open();
|
||||
InterpreterContext ctx3 = new InterpreterContext("", "1", "jdbc.jdbc1", "", "", user2Credential,
|
||||
InterpreterContext ctx3 = new InterpreterContext("", "1", "jdbc1", "", "", user2Credential,
|
||||
null, null, null, null, null, null);
|
||||
jdbc1.interpret("", ctx3);
|
||||
|
||||
|
|
@ -383,13 +383,13 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter {
|
|||
|
||||
// user2 runs jdbc2
|
||||
jdbc2.open();
|
||||
InterpreterContext ctx4 = new InterpreterContext("", "1", "jdbc.jdbc2", "", "", user2Credential,
|
||||
InterpreterContext ctx4 = new InterpreterContext("", "1", "jdbc2", "", "", user2Credential,
|
||||
null, null, null, null, null, null);
|
||||
jdbc2.interpret("", ctx4);
|
||||
|
||||
JDBCUserConfigurations user2JDBC2Conf = jdbc2.getJDBCConfiguration("user2");
|
||||
assertNull(user2JDBC2Conf.getPropertyMap("default").get("user"));
|
||||
assertNull(user2JDBC2Conf.getPropertyMap("default").get("password"));
|
||||
assertEquals("user2Id", user2JDBC2Conf.getPropertyMap("default").get("user"));
|
||||
assertEquals("user2Pw", user2JDBC2Conf.getPropertyMap("default").get("password"));
|
||||
jdbc2.close();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -252,5 +252,10 @@ public class AngularObjectRegistry {
|
|||
|
||||
public void setRegistry(Map<String, Map<String, AngularObject>> registry) {
|
||||
this.registry = registry;
|
||||
for (Map<String, AngularObject> map : registry.values()) {
|
||||
for (AngularObject ao : map.values()) {
|
||||
ao.setListener(angularObjectListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ import java.util.Map;
|
|||
* RemoteInterpreterEventPoller is counter part in ZeppelinServer
|
||||
*/
|
||||
public class RemoteInterpreterEventClient implements ResourcePoolConnector {
|
||||
private final Logger logger = LoggerFactory.getLogger(RemoteInterpreterEvent.class);
|
||||
private final Logger logger = LoggerFactory.getLogger(RemoteInterpreterEventClient.class);
|
||||
private final List<RemoteInterpreterEvent> eventQueue = new LinkedList<>();
|
||||
private final List<ResourceSet> getAllResourceResponse = new LinkedList<>();
|
||||
private final Map<ResourceId, Object> getResourceResponse = new HashMap<>();
|
||||
|
|
@ -415,6 +415,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
|
|||
}
|
||||
|
||||
private void sendEvent(RemoteInterpreterEvent event) {
|
||||
logger.debug("Send Event: " + event);
|
||||
synchronized (eventQueue) {
|
||||
eventQueue.add(event);
|
||||
eventQueue.notifyAll();
|
||||
|
|
@ -446,7 +447,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
|
|||
appendOutput.put("appId", appId);
|
||||
appendOutput.put("type", type);
|
||||
appendOutput.put("data", output);
|
||||
logger.info("onAppoutputUpdate = {}", output);
|
||||
logger.debug("onAppoutputUpdate = {}", output);
|
||||
sendEvent(new RemoteInterpreterEvent(
|
||||
RemoteInterpreterEventType.OUTPUT_UPDATE,
|
||||
gson.toJson(appendOutput)));
|
||||
|
|
|
|||
|
|
@ -124,6 +124,9 @@ public class RemoteInterpreterEventPoller extends Thread {
|
|||
AngularObjectRegistry angularObjectRegistry = interpreterGroup.getAngularObjectRegistry();
|
||||
|
||||
try {
|
||||
if (event.getType() != RemoteInterpreterEventType.NO_OP) {
|
||||
logger.debug("Receive message from RemoteInterpreter Process: " + event.toString());
|
||||
}
|
||||
if (event.getType() == RemoteInterpreterEventType.NO_OP) {
|
||||
continue;
|
||||
} else if (event.getType() == RemoteInterpreterEventType.ANGULAR_OBJECT_ADD) {
|
||||
|
|
@ -263,11 +266,20 @@ public class RemoteInterpreterEventPoller extends Thread {
|
|||
logger.error("Can't handle event " + event, e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
clearUnreadEvents(interpreterProcess.getClient());
|
||||
} catch (Exception e1) {
|
||||
logger.error("Can't get RemoteInterpreterEvent", e1);
|
||||
}
|
||||
if (appendFuture != null) {
|
||||
appendFuture.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearUnreadEvents(Client client) throws TException {
|
||||
while (client.getEvent().getType() != RemoteInterpreterEventType.NO_OP) {}
|
||||
}
|
||||
|
||||
private void progressRemoteZeppelinControlEvent(
|
||||
RemoteZeppelinServerResource.Type resourceType,
|
||||
RemoteInterpreterProcessListener remoteWorksEventListener,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
*/
|
||||
|
||||
package org.apache.zeppelin.interpreter.remote;
|
||||
|
||||
import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterEvent;
|
||||
import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.apache.zeppelin.interpreter.thrift.RemoteInterpreterEventType.NO_OP;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class RemoteInterpreterEventPollerTest {
|
||||
|
||||
@Test
|
||||
public void shouldClearUnreadEventsOnShutdown() throws Exception {
|
||||
RemoteInterpreterProcess interpreterProc = getMockEventsInterpreterProcess();
|
||||
RemoteInterpreterEventPoller eventPoller = new RemoteInterpreterEventPoller(null, null);
|
||||
|
||||
eventPoller.setInterpreterProcess(interpreterProc);
|
||||
eventPoller.shutdown();
|
||||
eventPoller.start();
|
||||
eventPoller.join();
|
||||
|
||||
assertEquals(NO_OP, interpreterProc.getClient().getEvent().getType());
|
||||
}
|
||||
|
||||
private RemoteInterpreterProcess getMockEventsInterpreterProcess() throws Exception {
|
||||
RemoteInterpreterEvent fakeEvent = new RemoteInterpreterEvent();
|
||||
RemoteInterpreterEvent noMoreEvents = new RemoteInterpreterEvent(NO_OP, "");
|
||||
RemoteInterpreterService.Client client = mock(RemoteInterpreterService.Client.class);
|
||||
RemoteInterpreterProcess intProc = mock(RemoteInterpreterProcess.class);
|
||||
|
||||
when(client.getEvent()).thenReturn(fakeEvent, fakeEvent, noMoreEvents);
|
||||
when(intProc.getClient()).thenReturn(client);
|
||||
|
||||
return intProc;
|
||||
}
|
||||
}
|
||||
|
|
@ -494,7 +494,7 @@ public class NotebookServer extends WebSocketServlet
|
|||
if (socketLists == null || socketLists.size() == 0) {
|
||||
return;
|
||||
}
|
||||
LOG.debug("SEND >> " + m.op);
|
||||
LOG.debug("SEND >> " + m);
|
||||
for (NotebookSocket conn : socketLists) {
|
||||
try {
|
||||
conn.send(serializeMessage(m));
|
||||
|
|
@ -512,7 +512,7 @@ public class NotebookServer extends WebSocketServlet
|
|||
if (socketLists == null || socketLists.size() == 0) {
|
||||
return;
|
||||
}
|
||||
LOG.debug("SEND >> " + m.op);
|
||||
LOG.debug("SEND >> " + m);
|
||||
for (NotebookSocket conn : socketLists) {
|
||||
if (exclude.equals(conn)) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
{
|
||||
|
||||
"plugins": ["transform-object-rest-spread"],
|
||||
"presets": ["es2015"]
|
||||
"presets": [
|
||||
[
|
||||
"env",
|
||||
{
|
||||
"debug": true,
|
||||
"targets": {
|
||||
"browsers": ["last 5 version", "> 5%", "edge >= 12", "ie >= 9", "safari 7", "chrome 47", "firefox 31"]
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@
|
|||
"name": "zeppelin-web",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"angular": "1.5.0",
|
||||
"angular": "1.5.7",
|
||||
"json3": "~3.3.1",
|
||||
"es5-shim": "~3.1.0",
|
||||
"bootstrap": "~3.2.0",
|
||||
"angular-cookies": "1.5.0",
|
||||
"angular-sanitize": "1.5.0",
|
||||
"angular-animate": "1.5.0",
|
||||
"angular-touch": "1.5.0",
|
||||
"angular-route": "1.5.0",
|
||||
"angular-resource": "1.5.0",
|
||||
"angular-cookies": "1.5.7",
|
||||
"angular-sanitize": "1.5.7",
|
||||
"angular-animate": "1.5.7",
|
||||
"angular-touch": "1.5.7",
|
||||
"angular-route": "1.5.7",
|
||||
"angular-resource": "1.5.7",
|
||||
"angular-bootstrap": "~2.5.0",
|
||||
"angular-websocket": "~1.0.13",
|
||||
"ace-builds": "1.2.6",
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
"ngclipboard": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"angular-mocks": "1.5.0"
|
||||
"angular-mocks": "1.5.7"
|
||||
},
|
||||
"appPath": "src",
|
||||
"overrides": {
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@
|
|||
"babel-cli": "^6.18.0",
|
||||
"babel-core": "^6.21.0",
|
||||
"babel-loader": "^6.2.10",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.16.0",
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"babel-preset-env": "^1.4.0",
|
||||
"bower": "^1.8.0",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.26.1",
|
||||
|
|
|
|||
|
|
@ -143,4 +143,8 @@ function HomeCtrl ($scope, noteListDataFactory, websocketMsgSrv, $rootScope, arr
|
|||
$scope.getNoteName = function (note) {
|
||||
return arrayOrderingSrv.getNoteName(note)
|
||||
}
|
||||
|
||||
$scope.noteComparator = function (note1, note2) {
|
||||
return arrayOrderingSrv.noteComparator(note1, note2)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,16 +40,16 @@ limitations under the License.
|
|||
<i style="font-size: 15px;" class="icon-notebook"></i> Create new note</a></h5>
|
||||
<ul id="notebook-names">
|
||||
<li class="filter-names" ng-include="'components/filterNoteNames/filter-note-names.html'"></li>
|
||||
<li ng-repeat="note in home.notes.list | filter:query.q | orderBy:home.arrayOrderingSrv.noteListOrdering track by $index">
|
||||
<li ng-repeat="note in home.notes.list | filter:query.q | orderBy:node:false:home.arrayOrderingSrv.noteComparator track by $index">
|
||||
<i style="font-size: 10px;" class="icon-doc"></i>
|
||||
<a style="text-decoration: none;" href="#/notebook/{{note.id}}">{{noteName(note)}}</a>
|
||||
</li>
|
||||
<div ng-if="!query.q || query.q === ''">
|
||||
<li ng-repeat="node in home.notes.root.children | orderBy:home.arrayOrderingSrv.noteListOrdering track by $index"
|
||||
<li ng-repeat="node in home.notes.root.children | orderBy:node:false:home.arrayOrderingSrv.noteComparator track by $index"
|
||||
ng-include src="'app/home/notebook-template.html'" ng-class="note_folder_renderer"></li>
|
||||
</div>
|
||||
<div ng-if="query.q">
|
||||
<li ng-repeat="node in home.notes.flatList| filter:query.q | orderBy:home.arrayOrderingSrv.noteListOrdering track by $index"
|
||||
<li ng-repeat="node in home.notes.flatList| filter:query.q | orderBy:home.arrayOrderingSrv.noteFlatListOrdering track by $index"
|
||||
ng-include src="'app/home/notebook-template.html'" ng-class="note_folder_renderer"></li>
|
||||
</div>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ limitations under the License.
|
|||
</div>
|
||||
<div ng-if="!node.hidden">
|
||||
<ul style="list-style-type: none; padding-left:15px;">
|
||||
<li ng-repeat="node in node.children" ng-include="'app/home/notebook-template.html'" ng-class="'note_folder_renderer'"></li>
|
||||
<li ng-repeat="node in node.children | orderBy:node:false:noteComparator" ng-include="'app/home/notebook-template.html'" ng-class="'note_folder_renderer'"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -116,7 +116,7 @@ limitations under the License.
|
|||
</div>
|
||||
<div ng-if="!node.hidden">
|
||||
<ul style="list-style-type: none; padding-left:15px;">
|
||||
<li ng-repeat="node in node.children" ng-include="'app/home/notebook-template.html'" ng-class="'note_folder_renderer'"></li>
|
||||
<li ng-repeat="node in node.children | orderBy:node:false:noteComparator" ng-include="'app/home/notebook-template.html'" ng-class="'note_folder_renderer'"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ limitations under the License.
|
|||
<ul id="notebook-names">
|
||||
<li class="filter-names" ng-include="'components/filterNoteNames/filter-note-names.html'"></li>
|
||||
<div ng-if="!query.q || query.q === ''">
|
||||
<li ng-repeat="node in home.notes.root.children | orderBy:home.arrayOrderingSrv.noteListOrdering track by $index"
|
||||
<li ng-repeat="node in home.notes.root.children | orderBy:node:false:home.arrayOrderingSrv.noteComparator track by $index"
|
||||
ng-include src="'app/home/notebook-template.html'" ng-class="note_folder_renderer"></li>
|
||||
</div>
|
||||
<div ng-if="query.q">
|
||||
<li ng-repeat="node in home.notes.flatList | filter:query.q | orderBy:home.arrayOrderingSrv.noteListOrdering track by $index"
|
||||
<li ng-repeat="node in home.notes.flatList | filter:query.q | orderBy:home.arrayOrderingSrv.noteFlatListOrdering track by $index"
|
||||
ng-include src="'app/home/notebook-template.html'" ng-class="note_folder_renderer"></li>
|
||||
</div>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -138,6 +138,15 @@ function ResultCtrl ($scope, $rootScope, $route, $window, $routeParams, $locatio
|
|||
// queue for append output
|
||||
const textResultQueueForAppend = []
|
||||
|
||||
// prevent body area scrollbar from blocking due to scroll in paragraph results
|
||||
$scope.mouseOver = false
|
||||
$scope.onMouseOver = function() { $scope.mouseOver = true }
|
||||
$scope.onMouseOut = function() { $scope.mouseOver = false }
|
||||
$scope.getPointerEvent = function() {
|
||||
return ($scope.mouseOver) ? {'pointer-events': 'auto' }
|
||||
: {'pointer-events': 'none' }
|
||||
}
|
||||
|
||||
$scope.init = function (result, config, paragraph, index) {
|
||||
// register helium plugin vis
|
||||
let visBundles = heliumService.getVisualizationBundles()
|
||||
|
|
|
|||
|
|
@ -15,17 +15,19 @@ limitations under the License.
|
|||
<div>
|
||||
<div ng-include src="'app/notebook/paragraph/result/result-chart-selector.html'"></div>
|
||||
<div
|
||||
ng-mouseout="onMouseOut()"
|
||||
ng-mouseover="onMouseOver()"
|
||||
id="p{{id}}_resize"
|
||||
ng-if="!config.helium.activeApp"
|
||||
style="padding-bottom: 5px;"
|
||||
resize='{"allowresize": "{{!asIframe && !viewOnly}}", "graphType": "{{type}}"}'
|
||||
resizable on-resize="resize(width, height);">
|
||||
resizable on-resize="resize(width, height);">
|
||||
|
||||
<div ng-if="type=='TABLE'">
|
||||
<div ng-if="type=='TABLE'"
|
||||
ng-style="getPointerEvent()">
|
||||
<!-- graph setting -->
|
||||
<div class="option lightBold" style="overflow: visible;"
|
||||
ng-show="graphMode!='table'
|
||||
&& config.graph.optionOpen && !asIframe && !viewOnly">
|
||||
ng-show="graphMode!='table' && config.graph.optionOpen && !asIframe && !viewOnly">
|
||||
<div ng-repeat="viz in builtInTableDataVisualizationList track by $index"
|
||||
id="trsetting{{id}}_{{viz.id}}"
|
||||
ng-show="graphMode == viz.id"></div>
|
||||
|
|
@ -52,7 +54,8 @@ limitations under the License.
|
|||
</div>
|
||||
|
||||
<div ng-if="type == 'TEXT'"
|
||||
class="plainTextContainer">
|
||||
class="plainTextContainer"
|
||||
ng-style="getPointerEvent()">
|
||||
<div class="fa fa-level-down scroll-paragraph-down"
|
||||
ng-show="showScrollDownIcon()"
|
||||
ng-click="scrollParagraphDown()"
|
||||
|
|
@ -66,30 +69,40 @@ limitations under the License.
|
|||
uib-tooltip="Scroll Top"></div>
|
||||
</div>
|
||||
|
||||
<div id="p{{id}}_custom" class="resultContained"
|
||||
ng-if="!isDefaultDisplay()">
|
||||
<div id="p{{id}}_custom"
|
||||
class="resultContained"
|
||||
ng-if="!isDefaultDisplay()"
|
||||
ng-style="getPointerEvent()">
|
||||
</div>
|
||||
|
||||
<div id="p{{id}}_elem" class="resultContained"
|
||||
ng-if="type == 'ELEMENT'">
|
||||
<div id="p{{id}}_elem"
|
||||
class="resultContained"
|
||||
ng-if="type == 'ELEMENT'"
|
||||
ng-style="getPointerEvent()">
|
||||
</div>
|
||||
|
||||
<div id="p{{id}}_html" class="resultContained"
|
||||
ng-if="type == 'HTML'">
|
||||
<div id="p{{id}}_html"
|
||||
class="resultContained"
|
||||
ng-if="type == 'HTML'"
|
||||
ng-style="getPointerEvent()">
|
||||
</div>
|
||||
|
||||
<div id="p{{id}}_angular" class="resultContained"
|
||||
ng-if="type == 'ANGULAR'">
|
||||
<div id="p{{id}}_angular"
|
||||
class="resultContained"
|
||||
ng-if="type == 'ANGULAR'"
|
||||
ng-style="getPointerEvent()">
|
||||
</div>
|
||||
|
||||
<img id="{{id}}_img"
|
||||
ng-if="type == 'IMG'"
|
||||
ng-src="{{getBase64ImageSrc(result.data)}}" />
|
||||
ng-src="{{getBase64ImageSrc(result.data)}}"
|
||||
ng-style="getPointerEvent()" />
|
||||
</div>
|
||||
|
||||
<div ng-repeat="app in apps">
|
||||
<div id="p{{app.id}}"
|
||||
ng-show="config.helium.activeApp == app.id">
|
||||
ng-show="config.helium.activeApp == app.id"
|
||||
ng-style="getPointerEvent()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -33,4 +33,30 @@ function arrayOrderingSrv (TRASH_FOLDER_ID) {
|
|||
return note.name
|
||||
}
|
||||
}
|
||||
|
||||
this.noteComparator = function (v1, v2) {
|
||||
let note1 = v1.value
|
||||
let note2 = v2.value
|
||||
|
||||
if (note1.id === TRASH_FOLDER_ID) {
|
||||
return 1
|
||||
}
|
||||
|
||||
if (note2.id === TRASH_FOLDER_ID) {
|
||||
return -1
|
||||
}
|
||||
|
||||
if (note1.children === undefined && note2.children !== undefined) {
|
||||
return 1
|
||||
}
|
||||
|
||||
if (note1.children !== undefined && note2.children === undefined) {
|
||||
return -1
|
||||
}
|
||||
|
||||
let noteName1 = arrayOrderingSrv.getNoteName(note1)
|
||||
let noteName2 = arrayOrderingSrv.getNoteName(note2)
|
||||
|
||||
return noteName1.localeCompare(noteName2)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ limitations under the License.
|
|||
</div>
|
||||
<div class="expandable" style="color: black;">
|
||||
<ul>
|
||||
<li ng-repeat="note in note.children | orderBy:navbar.arrayOrderingSrv.noteListOrdering track by $index"
|
||||
<li ng-repeat="note in note.children | orderBy:node:false:navbar.arrayOrderingSrv.noteComparator track by $index"
|
||||
ng-class="{'active' : navbar.isActive(note.id)}"
|
||||
ng-include="'components/navbar/navbar-noteList-elem.html'">
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -25,20 +25,20 @@ limitations under the License.
|
|||
|
||||
<div class="collapse navbar-collapse" ng-controller="NavCtrl as navbar">
|
||||
<ul class="nav navbar-nav" ng-if="ticket">
|
||||
<li class="dropdown notebook-list-dropdown" dropdown>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" dropdown-toggle>Notebook <span class="caret"></span></a>
|
||||
<li class="dropdown notebook-list-dropdown" uib-dropdown>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" uib-dropdown-toggle>Notebook <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li ng-controller="NotenameCtrl as notenamectrl"><a href="" data-toggle="modal" data-target="#noteNameModal" ng-click="notenamectrl.getInterpreterSettings()"><i class="fa fa-plus"></i> Create new note</a></li>
|
||||
<li class="divider"></li>
|
||||
<div id="notebook-list" class="scrollbar-container" ng-if="isDrawNavbarNoteList">
|
||||
<li class="filter-names" ng-include="'components/filterNoteNames/filter-note-names.html'"></li>
|
||||
<div ng-if="!query.q || query.q === ''">
|
||||
<li ng-repeat="note in navbar.notes.root.children | orderBy:navbar.arrayOrderingSrv.noteListOrdering track by note.id"
|
||||
<li ng-repeat="note in navbar.notes.root.children | orderBy:node:false:navbar.arrayOrderingSrv.noteComparator track by note.id"
|
||||
ng-class="{'active' : navbar.isActive(note.id)}" ng-include="'components/navbar/navbar-noteList-elem.html'">
|
||||
</li>
|
||||
</div>
|
||||
<div ng-if="query.q">
|
||||
<li ng-repeat="note in navbar.notes.flatList | filter : query.q | orderBy:navbar.arrayOrderingSrv.noteListOrdering track by note.id"
|
||||
<li ng-repeat="note in navbar.notes.flatList | filter : query.q | orderBy:navbar.arrayOrderingSrv.noteFlatListOrdering track by note.id"
|
||||
ng-class="{'active' : navbar.isActive(note.id)}" ng-include="'components/navbar/navbar-noteList-elem.html'">
|
||||
</li>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
angular.module('zeppelinWebApp').directive('popoverHtmlUnsafe', popoverHtmlUnsafe)
|
||||
|
||||
function popoverHtmlUnsafe ($tooltip) {
|
||||
function popoverHtmlUnsafe ($uibTooltip) {
|
||||
'ngInject'
|
||||
|
||||
return $tooltip('popoverHtmlUnsafe', 'popover', 'click')
|
||||
return $uibTooltip('popoverHtmlUnsafe', 'popover', 'click')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import java.net.URL;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* This registry reads helium package json data
|
||||
|
|
@ -55,7 +56,10 @@ public class HeliumOnlineRegistry extends HeliumRegistry {
|
|||
public HeliumOnlineRegistry(String name, String uri, File registryCacheDir) {
|
||||
super(name, uri);
|
||||
registryCacheDir.mkdirs();
|
||||
this.registryCacheFile = new File(registryCacheDir, name);
|
||||
|
||||
UUID registryCacheFileUuid = UUID.nameUUIDFromBytes(uri.getBytes());
|
||||
this.registryCacheFile = new File(registryCacheDir, registryCacheFileUuid.toString());
|
||||
|
||||
gson = new Gson();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ DEPENDENCIES
|
|||
"webpack": "^1.12.2",
|
||||
"babel-core": "^6.23.1",
|
||||
"babel-loader": "^6.3.2",
|
||||
"babel-preset-es2015": "^6.22.0",
|
||||
"babel-preset-stage-0": "^6.22.0",
|
||||
"babel-preset-env": "^1.4.0",
|
||||
"css-loader": "^0.26.2",
|
||||
"style-loader": "^0.13.2",
|
||||
"url-loader": "^0.5.8",
|
||||
|
|
|
|||
|
|
@ -24,7 +24,18 @@ module.exports = {
|
|||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules\/(?!(zeppelin-spell|zeppelin-vis|zeppelin-tabledata)\/).*/,
|
||||
query: { presets: ['es2015', 'stage-0'] },
|
||||
query: {
|
||||
presets: [
|
||||
[
|
||||
"env",
|
||||
{
|
||||
"targets": {
|
||||
"browsers": ["last 5 version", "> 5%", "edge >= 12", "ie >= 9", "safari 7", "chrome 47", "firefox 31"]
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
},
|
||||
{ test: /(\.css)$/, loaders: ['style', 'css?sourceMap&importLoaders=1'], },
|
||||
{ test: /\.woff(\?\S*)?$/, loader: 'url-loader?limit=10000&minetype=application/font-woff', },
|
||||
|
|
|
|||
Loading…
Reference in a new issue