Merge remote-tracking branch 'apache-github/master' into ZEPPELIN-1619-rebased

This commit is contained in:
Lee moon soo 2017-01-10 19:07:25 -08:00
commit 4c879837c9
47 changed files with 6340 additions and 6300 deletions

1
.gitignore vendored
View file

@ -46,6 +46,7 @@ zeppelin-web/src/fonts/patua-one*
zeppelin-web/src/fonts/google-fonts.css
zeppelin-web/.sass-cache
zeppelin-web/npm-debug.log
zeppelin-web/yarn-error.log
zeppelin-web/bower_components
zeppelin-web/yarn.lock
**nbproject/

File diff suppressed because it is too large Load diff

View file

@ -72,9 +72,9 @@ public class PythonInterpreter extends Interpreter {
// Add matplotlib display hook
InterpreterGroup intpGroup = getInterpreterGroup();
if (intpGroup != null && intpGroup.getInterpreterHookRegistry() != null) {
registerHook(HookType.POST_EXEC_DEV, "z._displayhook()");
registerHook(HookType.POST_EXEC_DEV, "\nz._displayhook()");
}
// Add zeppelin-bundled libs to PYTHONPATH
setPythonPath("../interpreter/lib/python:$PYTHONPATH");
LOG.info("Starting Python interpreter ---->");

View file

@ -45,6 +45,7 @@ import org.apache.zeppelin.interpreter.ClassloaderInterpreter;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterGroup;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
@ -62,6 +63,7 @@ import org.slf4j.LoggerFactory;
public class PythonInterpreterTest {
private static final Logger LOG = LoggerFactory.getLogger(PythonProcess.class);
PythonInterpreter zeppelinPythonInterpreter = null;
PythonInterpreter pythonInterpreter = null;
PythonProcess mockPythonProcess;
String cmdHistory;
@ -88,6 +90,7 @@ public class PythonInterpreterTest {
// python interpreter
pythonInterpreter = spy(new PythonInterpreter(getPythonTestProperties()));
zeppelinPythonInterpreter = new PythonInterpreter(getPythonTestProperties());
// create interpreter group
InterpreterGroup group = new InterpreterGroup();
@ -99,6 +102,12 @@ public class PythonInterpreterTest {
when(mockPythonProcess.sendAndGetResult(eq("\n\nimport py4j\n"))).thenReturn("ImportError");
}
@After
public void afterTest() throws IOException {
pythonInterpreter.close();
zeppelinPythonInterpreter.close();
}
@Test
public void testOpenInterpreter() {
pythonInterpreter.open();
@ -172,6 +181,18 @@ public class PythonInterpreterTest {
assertEquals("%text print a", result.message().get(0).toString());
}
@Test
public void testInterpretInvalidSyntax() {
zeppelinPythonInterpreter.open();
InterpreterResult result = zeppelinPythonInterpreter.interpret("for x in range(0,3): print (\"hi\")\n\nz._displayhook()", null);
assertEquals(InterpreterResult.Code.SUCCESS, result.code());
assertTrue(result.message().get(0).toString().contains("hi\nhi\nhi"));
result = zeppelinPythonInterpreter.interpret("for x in range(0,3): print (\"hi\")\nz._displayhook()", null);
assertEquals(InterpreterResult.Code.ERROR, result.code());
assertTrue(result.message().get(0).toString().contains("SyntaxError: invalid syntax"));
}
/**
* Checks if given port is open on 'localhost'
* @param port

View file

@ -11,52 +11,50 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('MainCtrl', MainCtrl);
angular.module('zeppelinWebApp').controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope', '$rootScope', '$window', 'arrayOrderingSrv'];
MainCtrl.$inject = ['$scope', '$rootScope', '$window', 'arrayOrderingSrv'];
function MainCtrl($scope, $rootScope, $window, arrayOrderingSrv) {
$scope.looknfeel = 'default';
function MainCtrl($scope, $rootScope, $window, arrayOrderingSrv) {
$scope.looknfeel = 'default';
var init = function() {
$scope.asIframe = (($window.location.href.indexOf('asIframe') > -1) ? true : false);
};
var init = function() {
$scope.asIframe = (($window.location.href.indexOf('asIframe') > -1) ? true : false);
};
init();
init();
$rootScope.$on('setIframe', function(event, data) {
if (!event.defaultPrevented) {
$scope.asIframe = data;
event.preventDefault();
}
});
$rootScope.$on('setIframe', function(event, data) {
if (!event.defaultPrevented) {
$scope.asIframe = data;
event.preventDefault();
}
});
$rootScope.$on('setLookAndFeel', function(event, data) {
if (!event.defaultPrevented && data && data !== '' && data !== $scope.looknfeel) {
$scope.looknfeel = data;
event.preventDefault();
}
});
$rootScope.$on('setLookAndFeel', function(event, data) {
if (!event.defaultPrevented && data && data !== '' && data !== $scope.looknfeel) {
$scope.looknfeel = data;
event.preventDefault();
}
});
// Set The lookAndFeel to default on every page
$rootScope.$on('$routeChangeStart', function(event, next, current) {
$rootScope.$broadcast('setLookAndFeel', 'default');
});
// Set The lookAndFeel to default on every page
$rootScope.$on('$routeChangeStart', function(event, next, current) {
$rootScope.$broadcast('setLookAndFeel', 'default');
});
$rootScope.noteName = function(note) {
if (!_.isEmpty(note)) {
return arrayOrderingSrv.getNoteName(note);
}
};
$rootScope.noteName = function(note) {
if (!_.isEmpty(note)) {
return arrayOrderingSrv.getNoteName(note);
}
};
BootstrapDialog.defaultOptions.onshown = function() {
angular.element('#' + this.id).find('.btn:last').focus();
};
BootstrapDialog.defaultOptions.onshown = function() {
angular.element('#' + this.id).find('.btn:last').focus();
};
// Remove BootstrapDialog animation
BootstrapDialog.configDefaultOptions({animate: false});
}
// Remove BootstrapDialog animation
BootstrapDialog.configDefaultOptions({animate: false});
}
})();

View file

@ -14,140 +14,142 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
var zeppelinWebApp = angular.module('zeppelinWebApp', [
'ngCookies',
'ngAnimate',
'ngRoute',
'ngSanitize',
'angular-websocket',
'ui.ace',
'ui.bootstrap',
'as.sortable',
'ngTouch',
'ngDragDrop',
'angular.filter',
'monospaced.elastic',
'puElasticInput',
'xeditable',
'ngToast',
'focus-if',
'ngResource',
'ngclipboard'
])
.filter('breakFilter', function() {
return function(text) {
if (!!text) {
return text.replace(/\n/g, '<br />');
}
};
})
.config(function($httpProvider, $routeProvider, ngToastProvider) {
// withCredentials when running locally via grunt
$httpProvider.defaults.withCredentials = true;
var visBundleLoad = {
load: ['heliumService', function(heliumService) {
return heliumService.load;
}]
};
$routeProvider
.when('/', {
templateUrl: 'app/home/home.html'
})
.when('/notebook/:noteId', {
templateUrl: 'app/notebook/notebook.html',
controller: 'NotebookCtrl',
resolve: visBundleLoad
})
.when('/notebook/:noteId/paragraph?=:paragraphId', {
templateUrl: 'app/notebook/notebook.html',
controller: 'NotebookCtrl'
})
.when('/notebook/:noteId/paragraph/:paragraphId?', {
templateUrl: 'app/notebook/notebook.html',
controller: 'NotebookCtrl'
})
.when('/notebook/:noteId/revision/:revisionId', {
templateUrl: 'app/notebook/notebook.html',
controller: 'NotebookCtrl'
})
.when('/jobmanager', {
templateUrl: 'app/jobmanager/jobmanager.html',
controller: 'JobmanagerCtrl'
})
.when('/interpreter', {
templateUrl: 'app/interpreter/interpreter.html',
controller: 'InterpreterCtrl'
})
.when('/notebookRepos', {
templateUrl: 'app/notebookRepos/notebookRepos.html',
controller: 'NotebookReposCtrl',
controllerAs: 'noterepo'
})
.when('/credential', {
templateUrl: 'app/credential/credential.html',
controller: 'CredentialCtrl'
})
.when('/helium', {
templateUrl: 'app/helium/helium.html',
controller: 'HeliumCtrl'
})
.when('/configuration', {
templateUrl: 'app/configuration/configuration.html',
controller: 'ConfigurationCtrl'
})
.when('/search/:searchTerm', {
templateUrl: 'app/search/result-list.html',
controller: 'SearchResultCtrl'
})
.otherwise({
redirectTo: '/'
});
ngToastProvider.configure({
dismissButton: true,
dismissOnClick: false,
combineDuplications: true,
timeout: 6000
});
})
.constant('TRASH_FOLDER_ID', '~Trash');
function auth() {
var $http = angular.injector(['ng']).get('$http');
var baseUrlSrv = angular.injector(['zeppelinWebApp']).get('baseUrlSrv');
var zeppelinWebApp = angular.module('zeppelinWebApp', [
'ngCookies',
'ngAnimate',
'ngRoute',
'ngSanitize',
'angular-websocket',
'ui.ace',
'ui.bootstrap',
'as.sortable',
'ngTouch',
'ngDragDrop',
'angular.filter',
'monospaced.elastic',
'puElasticInput',
'xeditable',
'ngToast',
'focus-if',
'ngResource',
'ngclipboard'
])
.filter('breakFilter', function() {
return function(text) {
if (!!text) {
return text.replace(/\n/g, '<br />');
}
};
})
.config(function($httpProvider, $routeProvider, ngToastProvider) {
// withCredentials when running locally via grunt
$http.defaults.withCredentials = true;
jQuery.ajaxSetup({
dataType: 'json',
xhrFields: {
withCredentials: true
},
crossDomain: true
});
return $http.get(baseUrlSrv.getRestApiBase() + '/security/ticket').then(function(response) {
zeppelinWebApp.run(function($rootScope) {
$rootScope.ticket = angular.fromJson(response.data).body;
});
}, function(errorResponse) {
// Handle error case
});
}
$httpProvider.defaults.withCredentials = true;
function bootstrapApplication() {
zeppelinWebApp.run(function($rootScope, $location) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
if (!$rootScope.ticket && next.$$route && !next.$$route.publicAccess) {
$location.path('/');
}
});
});
angular.bootstrap(document, ['zeppelinWebApp']);
}
var visBundleLoad = {
load: ['heliumService', function(heliumService) {
return heliumService.load;
}]
};
angular.element(document).ready(function() {
auth().then(bootstrapApplication);
$routeProvider
.when('/', {
templateUrl: 'app/home/home.html'
})
.when('/notebook/:noteId', {
templateUrl: 'app/notebook/notebook.html',
controller: 'NotebookCtrl',
resolve: visBundleLoad
})
.when('/notebook/:noteId/paragraph?=:paragraphId', {
templateUrl: 'app/notebook/notebook.html',
controller: 'NotebookCtrl',
resolve: visBundleLoad
})
.when('/notebook/:noteId/paragraph/:paragraphId?', {
templateUrl: 'app/notebook/notebook.html',
controller: 'NotebookCtrl',
resolve: visBundleLoad
})
.when('/notebook/:noteId/revision/:revisionId', {
templateUrl: 'app/notebook/notebook.html',
controller: 'NotebookCtrl',
resolve: visBundleLoad
})
.when('/jobmanager', {
templateUrl: 'app/jobmanager/jobmanager.html',
controller: 'JobmanagerCtrl'
})
.when('/interpreter', {
templateUrl: 'app/interpreter/interpreter.html',
controller: 'InterpreterCtrl'
})
.when('/notebookRepos', {
templateUrl: 'app/notebookRepos/notebookRepos.html',
controller: 'NotebookReposCtrl',
controllerAs: 'noterepo'
})
.when('/credential', {
templateUrl: 'app/credential/credential.html',
controller: 'CredentialCtrl'
})
.when('/helium', {
templateUrl: 'app/helium/helium.html',
controller: 'HeliumCtrl'
})
.when('/configuration', {
templateUrl: 'app/configuration/configuration.html',
controller: 'ConfigurationCtrl'
})
.when('/search/:searchTerm', {
templateUrl: 'app/search/result-list.html',
controller: 'SearchResultCtrl'
})
.otherwise({
redirectTo: '/'
});
ngToastProvider.configure({
dismissButton: true,
dismissOnClick: false,
combineDuplications: true,
timeout: 6000
});
})
.constant('TRASH_FOLDER_ID', '~Trash');
function auth() {
var $http = angular.injector(['ng']).get('$http');
var baseUrlSrv = angular.injector(['zeppelinWebApp']).get('baseUrlSrv');
// withCredentials when running locally via grunt
$http.defaults.withCredentials = true;
jQuery.ajaxSetup({
dataType: 'json',
xhrFields: {
withCredentials: true
},
crossDomain: true
});
}());
return $http.get(baseUrlSrv.getRestApiBase() + '/security/ticket').then(function(response) {
zeppelinWebApp.run(function($rootScope) {
$rootScope.ticket = angular.fromJson(response.data).body;
});
}, function(errorResponse) {
// Handle error case
});
}
function bootstrapApplication() {
zeppelinWebApp.run(function($rootScope, $location) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
if (!$rootScope.ticket && next.$$route && !next.$$route.publicAccess) {
$location.path('/');
}
});
});
angular.bootstrap(document, ['zeppelinWebApp']);
}
angular.element(document).ready(function() {
auth().then(bootstrapApplication);
});

View file

@ -11,41 +11,39 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('ConfigurationCtrl', ConfigurationCtrl);
angular.module('zeppelinWebApp').controller('ConfigurationCtrl', ConfigurationCtrl);
ConfigurationCtrl.$inject = ['$scope', '$rootScope', '$http', 'baseUrlSrv', 'ngToast'];
ConfigurationCtrl.$inject = ['$scope', '$rootScope', '$http', 'baseUrlSrv', 'ngToast'];
function ConfigurationCtrl($scope, $rootScope, $http, baseUrlSrv, ngToast) {
$scope.configrations = [];
$scope._ = _;
ngToast.dismiss();
function ConfigurationCtrl($scope, $rootScope, $http, baseUrlSrv, ngToast) {
$scope.configrations = [];
$scope._ = _;
ngToast.dismiss();
var getConfigurations = function() {
$http.get(baseUrlSrv.getRestApiBase() + '/configurations/all').
success(function(data, status, headers, config) {
$scope.configurations = data.body;
}).
error(function(data, status, headers, config) {
if (status === 401) {
ngToast.danger({
content: 'You don\'t have permission on this page',
verticalPosition: 'bottom',
timeout: '3000'
});
setTimeout(function() {
window.location.replace('/');
}, 3000);
}
console.log('Error %o %o', status, data.message);
});
};
var getConfigurations = function() {
$http.get(baseUrlSrv.getRestApiBase() + '/configurations/all').
success(function(data, status, headers, config) {
$scope.configurations = data.body;
}).
error(function(data, status, headers, config) {
if (status === 401) {
ngToast.danger({
content: 'You don\'t have permission on this page',
verticalPosition: 'bottom',
timeout: '3000'
});
setTimeout(function() {
window.location.replace('/');
}, 3000);
}
console.log('Error %o %o', status, data.message);
});
};
var init = function() {
getConfigurations();
};
var init = function() {
getConfigurations();
};
init();
}
})();
init();
}

View file

@ -11,88 +11,87 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('CredentialCtrl', CredentialCtrl);
angular.module('zeppelinWebApp').controller('CredentialCtrl', CredentialCtrl);
CredentialCtrl.$inject = ['$scope', '$rootScope', '$http', 'baseUrlSrv', 'ngToast'];
CredentialCtrl.$inject = ['$scope', '$rootScope', '$http', 'baseUrlSrv', 'ngToast'];
function CredentialCtrl($scope, $rootScope, $http, baseUrlSrv, ngToast) {
$scope._ = _;
ngToast.dismiss();
function CredentialCtrl($scope, $rootScope, $http, baseUrlSrv, ngToast) {
$scope._ = _;
ngToast.dismiss();
$scope.credentialInfo = [];
$scope.showAddNewCredentialInfo = false;
$scope.availableInterpreters = [];
$scope.credentialInfo = [];
$scope.showAddNewCredentialInfo = false;
$scope.availableInterpreters = [];
var getCredentialInfo = function() {
$http.get(baseUrlSrv.getRestApiBase() + '/credential').
success(function(data, status, headers, config) {
$scope.credentialInfo = _.map(data.body.userCredentials, function(value, prop) {
return {entity: prop, password: value.password, username: value.username};
});
console.log('Success %o %o', status, $scope.credentialInfo);
}).
error(function(data, status, headers, config) {
if (status === 401) {
ngToast.danger({
content: 'You don\'t have permission on this page',
verticalPosition: 'bottom',
timeout: '3000'
});
setTimeout(function() {
window.location.replace('/');
}, 3000);
}
console.log('Error %o %o', status, data.message);
var getCredentialInfo = function() {
$http.get(baseUrlSrv.getRestApiBase() + '/credential').
success(function(data, status, headers, config) {
$scope.credentialInfo = _.map(data.body.userCredentials, function(value, prop) {
return {entity: prop, password: value.password, username: value.username};
});
};
$scope.addNewCredentialInfo = function() {
if ($scope.entity && _.isEmpty($scope.entity.trim()) &&
$scope.username && _.isEmpty($scope.username.trim())) {
console.log('Success %o %o', status, $scope.credentialInfo);
}).
error(function(data, status, headers, config) {
if (status === 401) {
ngToast.danger({
content: 'Username \\ Entity can not be empty.',
content: 'You don\'t have permission on this page',
verticalPosition: 'bottom',
timeout: '3000'
});
return;
setTimeout(function() {
window.location.replace('/');
}, 3000);
}
console.log('Error %o %o', status, data.message);
});
};
var newCredential = {
'entity': $scope.entity,
'username': $scope.username,
'password': $scope.password
};
$http.put(baseUrlSrv.getRestApiBase() + '/credential', newCredential).
success(function(data, status, headers, config) {
ngToast.success({
content: 'Successfully saved credentials.',
verticalPosition: 'bottom',
timeout: '3000'
});
$scope.credentialInfo.push(newCredential);
resetCredentialInfo();
$scope.showAddNewCredentialInfo = false;
console.log('Success %o %o', status, data.message);
}).
error(function(data, status, headers, config) {
ngToast.danger({
content: 'Error saving credentials',
verticalPosition: 'bottom',
timeout: '3000'
});
console.log('Error %o %o', status, data.message);
$scope.addNewCredentialInfo = function() {
if ($scope.entity && _.isEmpty($scope.entity.trim()) &&
$scope.username && _.isEmpty($scope.username.trim())) {
ngToast.danger({
content: 'Username \\ Entity can not be empty.',
verticalPosition: 'bottom',
timeout: '3000'
});
return;
}
var newCredential = {
'entity': $scope.entity,
'username': $scope.username,
'password': $scope.password
};
var getAvailableInterpreters = function() {
$http.get(baseUrlSrv.getRestApiBase() + '/interpreter/setting')
$http.put(baseUrlSrv.getRestApiBase() + '/credential', newCredential).
success(function(data, status, headers, config) {
ngToast.success({
content: 'Successfully saved credentials.',
verticalPosition: 'bottom',
timeout: '3000'
});
$scope.credentialInfo.push(newCredential);
resetCredentialInfo();
$scope.showAddNewCredentialInfo = false;
console.log('Success %o %o', status, data.message);
}).
error(function(data, status, headers, config) {
ngToast.danger({
content: 'Error saving credentials',
verticalPosition: 'bottom',
timeout: '3000'
});
console.log('Error %o %o', status, data.message);
});
};
var getAvailableInterpreters = function() {
$http.get(baseUrlSrv.getRestApiBase() + '/interpreter/setting')
.success(function(data, status, headers, config) {
for (var setting = 0; setting < data.body.length; setting++) {
$scope.availableInterpreters.push(
data.body[setting].group + '.' + data.body[setting].name);
data.body[setting].group + '.' + data.body[setting].name);
}
angular.element('#entityname').autocomplete({
source: $scope.availableInterpreters,
@ -102,91 +101,90 @@
}
});
}).error(function(data, status, headers, config) {
console.log('Error %o %o', status, data.message);
});
};
console.log('Error %o %o', status, data.message);
});
};
$scope.toggleAddNewCredentialInfo = function() {
if ($scope.showAddNewCredentialInfo) {
$scope.showAddNewCredentialInfo = false;
} else {
$scope.showAddNewCredentialInfo = true;
}
};
$scope.cancelCredentialInfo = function() {
$scope.toggleAddNewCredentialInfo = function() {
if ($scope.showAddNewCredentialInfo) {
$scope.showAddNewCredentialInfo = false;
resetCredentialInfo();
} else {
$scope.showAddNewCredentialInfo = true;
}
};
$scope.cancelCredentialInfo = function() {
$scope.showAddNewCredentialInfo = false;
resetCredentialInfo();
};
var resetCredentialInfo = function() {
$scope.entity = '';
$scope.username = '';
$scope.password = '';
};
$scope.copyOriginCredentialsInfo = function() {
ngToast.info({
content: 'Since entity is a unique key, you can edit only username & password',
verticalPosition: 'bottom',
timeout: '3000'
});
};
$scope.updateCredentialInfo = function(form, data, entity) {
var request = {
entity: entity,
username: data.username,
password: data.password
};
var resetCredentialInfo = function() {
$scope.entity = '';
$scope.username = '';
$scope.password = '';
};
$scope.copyOriginCredentialsInfo = function() {
ngToast.info({
content: 'Since entity is a unique key, you can edit only username & password',
$http.put(baseUrlSrv.getRestApiBase() + '/credential/', request).
success(function(data, status, headers, config) {
var index = _.findIndex($scope.credentialInfo, {'entity': entity});
$scope.credentialInfo[index] = request;
return true;
}).
error(function(data, status, headers, config) {
console.log('Error %o %o', status, data.message);
ngToast.danger({
content: 'We couldn\'t save the credential',
verticalPosition: 'bottom',
timeout: '3000'
});
};
form.$show();
});
return false;
};
$scope.updateCredentialInfo = function(form, data, entity) {
var request = {
entity: entity,
username: data.username,
password: data.password
};
$http.put(baseUrlSrv.getRestApiBase() + '/credential/', request).
success(function(data, status, headers, config) {
var index = _.findIndex($scope.credentialInfo, {'entity': entity});
$scope.credentialInfo[index] = request;
return true;
}).
error(function(data, status, headers, config) {
console.log('Error %o %o', status, data.message);
ngToast.danger({
content: 'We couldn\'t save the credential',
verticalPosition: 'bottom',
timeout: '3000'
});
form.$show();
});
return false;
};
$scope.removeCredentialInfo = function(entity) {
BootstrapDialog.confirm({
closable: false,
closeByBackdrop: false,
closeByKeyboard: false,
title: '',
message: 'Do you want to delete this credential information?',
callback: function(result) {
if (result) {
$http.delete(baseUrlSrv.getRestApiBase() + '/credential/' + entity).
success(function(data, status, headers, config) {
var index = _.findIndex($scope.credentialInfo, {'entity': entity});
$scope.credentialInfo.splice(index, 1);
console.log('Success %o %o', status, data.message);
}).
error(function(data, status, headers, config) {
console.log('Error %o %o', status, data.message);
});
}
$scope.removeCredentialInfo = function(entity) {
BootstrapDialog.confirm({
closable: false,
closeByBackdrop: false,
closeByKeyboard: false,
title: '',
message: 'Do you want to delete this credential information?',
callback: function(result) {
if (result) {
$http.delete(baseUrlSrv.getRestApiBase() + '/credential/' + entity).
success(function(data, status, headers, config) {
var index = _.findIndex($scope.credentialInfo, {'entity': entity});
$scope.credentialInfo.splice(index, 1);
console.log('Success %o %o', status, data.message);
}).
error(function(data, status, headers, config) {
console.log('Error %o %o', status, data.message);
});
}
});
};
}
});
};
var init = function() {
getAvailableInterpreters();
getCredentialInfo();
};
var init = function() {
getAvailableInterpreters();
getCredentialInfo();
};
init();
}
init();
}
})();

View file

@ -11,126 +11,124 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('HomeCtrl', HomeCtrl);
angular.module('zeppelinWebApp').controller('HomeCtrl', HomeCtrl);
HomeCtrl.$inject = [
'$scope',
'noteListDataFactory',
'websocketMsgSrv',
'$rootScope',
'arrayOrderingSrv',
'ngToast',
'noteActionSrv',
'TRASH_FOLDER_ID'
];
HomeCtrl.$inject = [
'$scope',
'noteListDataFactory',
'websocketMsgSrv',
'$rootScope',
'arrayOrderingSrv',
'ngToast',
'noteActionSrv',
'TRASH_FOLDER_ID'
];
function HomeCtrl($scope, noteListDataFactory, websocketMsgSrv, $rootScope, arrayOrderingSrv,
ngToast, noteActionSrv, TRASH_FOLDER_ID) {
ngToast.dismiss();
var vm = this;
vm.notes = noteListDataFactory;
vm.websocketMsgSrv = websocketMsgSrv;
vm.arrayOrderingSrv = arrayOrderingSrv;
function HomeCtrl($scope, noteListDataFactory, websocketMsgSrv, $rootScope, arrayOrderingSrv,
ngToast, noteActionSrv, TRASH_FOLDER_ID) {
ngToast.dismiss();
var vm = this;
vm.notes = noteListDataFactory;
vm.websocketMsgSrv = websocketMsgSrv;
vm.arrayOrderingSrv = arrayOrderingSrv;
vm.notebookHome = false;
if ($rootScope.ticket !== undefined) {
vm.notebookHome = false;
if ($rootScope.ticket !== undefined) {
vm.staticHome = false;
} else {
vm.staticHome = true;
}
$scope.isReloading = false;
$scope.TRASH_FOLDER_ID = TRASH_FOLDER_ID;
var initHome = function() {
websocketMsgSrv.getHomeNote();
};
initHome();
$scope.reloadNoteList = function() {
websocketMsgSrv.reloadAllNotesFromRepo();
$scope.isReloadingNotes = true;
};
$scope.toggleFolderNode = function(node) {
node.hidden = !node.hidden;
};
angular.element('#loginModal').on('hidden.bs.modal', function(e) {
$rootScope.$broadcast('initLoginValues');
});
/*
** $scope.$on functions below
*/
$scope.$on('setNoteMenu', function(event, notes) {
$scope.isReloadingNotes = false;
});
$scope.$on('setNoteContent', function(event, note) {
if (note) {
vm.note = note;
// initialize look And Feel
$rootScope.$broadcast('setLookAndFeel', 'home');
// make it read only
vm.viewOnly = true;
vm.notebookHome = true;
vm.staticHome = false;
} else {
vm.staticHome = true;
vm.notebookHome = false;
}
});
$scope.isReloading = false;
$scope.TRASH_FOLDER_ID = TRASH_FOLDER_ID;
$scope.renameNote = function(node) {
noteActionSrv.renameNote(node.id, node.path);
};
var initHome = function() {
websocketMsgSrv.getHomeNote();
};
$scope.moveNoteToTrash = function(noteId) {
noteActionSrv.moveNoteToTrash(noteId, false);
};
initHome();
$scope.moveFolderToTrash = function(folderId) {
noteActionSrv.moveFolderToTrash(folderId);
};
$scope.reloadNoteList = function() {
websocketMsgSrv.reloadAllNotesFromRepo();
$scope.isReloadingNotes = true;
};
$scope.restoreNote = function(noteId) {
websocketMsgSrv.restoreNote(noteId);
};
$scope.toggleFolderNode = function(node) {
node.hidden = !node.hidden;
};
$scope.restoreFolder = function(folderId) {
websocketMsgSrv.restoreFolder(folderId);
};
angular.element('#loginModal').on('hidden.bs.modal', function(e) {
$rootScope.$broadcast('initLoginValues');
});
$scope.restoreAll = function() {
noteActionSrv.restoreAll();
};
/*
** $scope.$on functions below
*/
$scope.renameFolder = function(node) {
noteActionSrv.renameFolder(node.id);
};
$scope.$on('setNoteMenu', function(event, notes) {
$scope.isReloadingNotes = false;
});
$scope.removeNote = function(noteId) {
noteActionSrv.removeNote(noteId, false);
};
$scope.$on('setNoteContent', function(event, note) {
if (note) {
vm.note = note;
$scope.removeFolder = function(folderId) {
noteActionSrv.removeFolder(folderId);
};
// initialize look And Feel
$rootScope.$broadcast('setLookAndFeel', 'home');
$scope.emptyTrash = function() {
noteActionSrv.emptyTrash();
};
// make it read only
vm.viewOnly = true;
vm.notebookHome = true;
vm.staticHome = false;
} else {
vm.staticHome = true;
vm.notebookHome = false;
}
});
$scope.renameNote = function(node) {
noteActionSrv.renameNote(node.id, node.path);
};
$scope.moveNoteToTrash = function(noteId) {
noteActionSrv.moveNoteToTrash(noteId, false);
};
$scope.moveFolderToTrash = function(folderId) {
noteActionSrv.moveFolderToTrash(folderId);
};
$scope.restoreNote = function(noteId) {
websocketMsgSrv.restoreNote(noteId);
};
$scope.restoreFolder = function(folderId) {
websocketMsgSrv.restoreFolder(folderId);
};
$scope.restoreAll = function() {
noteActionSrv.restoreAll();
};
$scope.renameFolder = function(node) {
noteActionSrv.renameFolder(node.id);
};
$scope.removeNote = function(noteId) {
noteActionSrv.removeNote(noteId, false);
};
$scope.removeFolder = function(folderId) {
noteActionSrv.removeFolder(folderId);
};
$scope.emptyTrash = function() {
noteActionSrv.emptyTrash();
};
$scope.clearAllParagraphOutput = function(noteId) {
noteActionSrv.clearAllParagraphOutput(noteId);
};
}
})();
$scope.clearAllParagraphOutput = function(noteId) {
noteActionSrv.clearAllParagraphOutput(noteId);
};
}

File diff suppressed because it is too large Load diff

View file

@ -11,15 +11,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').filter('sortByKey', sortByKey);
angular.module('zeppelinWebApp').filter('sortByKey', sortByKey);
function sortByKey() {
return function(properties) {
var sortedKeys = properties ? Object.keys(properties) : [];
return sortedKeys.sort();
};
}
})();
function sortByKey() {
return function(properties) {
var sortedKeys = properties ? Object.keys(properties) : [];
return sortedKeys.sort();
};
}

View file

@ -11,167 +11,165 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp')
.controller('JobmanagerCtrl', JobmanagerCtrl);
angular.module('zeppelinWebApp')
.controller('JobmanagerCtrl', JobmanagerCtrl);
JobmanagerCtrl.$inject = ['$scope', 'websocketMsgSrv', '$interval', 'ngToast', '$q', '$timeout', 'jobManagerFilter'];
JobmanagerCtrl.$inject = ['$scope', 'websocketMsgSrv', '$interval', 'ngToast', '$q', '$timeout', 'jobManagerFilter'];
function JobmanagerCtrl($scope, websocketMsgSrv, $interval, ngToast, $q, $timeout, jobManagerFilter) {
ngToast.dismiss();
var asyncNotebookJobFilter = function(jobInfomations, filterConfig) {
return $q(function(resolve, reject) {
$scope.JobInfomationsByFilter = $scope.jobTypeFilter(jobInfomations, filterConfig);
resolve($scope.JobInfomationsByFilter);
function JobmanagerCtrl($scope, websocketMsgSrv, $interval, ngToast, $q, $timeout, jobManagerFilter) {
ngToast.dismiss();
var asyncNotebookJobFilter = function(jobInfomations, filterConfig) {
return $q(function(resolve, reject) {
$scope.JobInfomationsByFilter = $scope.jobTypeFilter(jobInfomations, filterConfig);
resolve($scope.JobInfomationsByFilter);
});
};
$scope.doFiltering = function(jobInfomations, filterConfig) {
asyncNotebookJobFilter(jobInfomations, filterConfig).then(
function() {
// success
$scope.isLoadingFilter = false;
},
function() {
// failed
});
};
};
$scope.doFiltering = function(jobInfomations, filterConfig) {
asyncNotebookJobFilter(jobInfomations, filterConfig).then(
function() {
// success
$scope.isLoadingFilter = false;
},
function() {
// failed
});
};
$scope.filterValueToName = function(filterValue, maxStringLength) {
if ($scope.activeInterpreters === undefined) {
return;
$scope.filterValueToName = function(filterValue, maxStringLength) {
if ($scope.activeInterpreters === undefined) {
return;
}
var index = _.findIndex($scope.activeInterpreters, {value: filterValue});
if ($scope.activeInterpreters[index].name !== undefined) {
if (maxStringLength !== undefined && maxStringLength > $scope.activeInterpreters[index].name) {
return $scope.activeInterpreters[index].name.substr(0, maxStringLength - 3) + '...';
}
var index = _.findIndex($scope.activeInterpreters, {value: filterValue});
if ($scope.activeInterpreters[index].name !== undefined) {
if (maxStringLength !== undefined && maxStringLength > $scope.activeInterpreters[index].name) {
return $scope.activeInterpreters[index].name.substr(0, maxStringLength - 3) + '...';
}
return $scope.activeInterpreters[index].name;
} else {
return 'Interpreter is not set';
}
};
return $scope.activeInterpreters[index].name;
} else {
return 'Interpreter is not set';
}
};
$scope.setFilterValue = function(filterValue) {
$scope.filterConfig.filterValueInterpreter = filterValue;
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig);
};
$scope.setFilterValue = function(filterValue) {
$scope.filterConfig.filterValueInterpreter = filterValue;
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig);
};
$scope.onChangeRunJobToAlwaysTopToggle = function() {
$scope.filterConfig.isRunningAlwaysTop = !$scope.filterConfig.isRunningAlwaysTop;
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig);
};
$scope.onChangeRunJobToAlwaysTopToggle = function() {
$scope.filterConfig.isRunningAlwaysTop = !$scope.filterConfig.isRunningAlwaysTop;
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig);
};
$scope.onChangeSortAsc = function() {
$scope.filterConfig.isSortByAsc = !$scope.filterConfig.isSortByAsc;
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig);
};
$scope.onChangeSortAsc = function() {
$scope.filterConfig.isSortByAsc = !$scope.filterConfig.isSortByAsc;
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig);
};
$scope.doFilterInputTyping = function(keyEvent, jobInfomations, filterConfig) {
var RETURN_KEY_CODE = 13;
$timeout.cancel($scope.dofilterTimeoutObject);
$scope.isActiveSearchTimer = true;
$scope.dofilterTimeoutObject = $timeout(function() {
$scope.doFiltering(jobInfomations, filterConfig);
$scope.isActiveSearchTimer = false;
}, 10000);
if (keyEvent.which === RETURN_KEY_CODE) {
$timeout.cancel($scope.dofilterTimeoutObject);
$scope.doFiltering(jobInfomations, filterConfig);
$scope.isActiveSearchTimer = false;
}
};
$scope.doForceFilterInputTyping = function(keyEvent, jobInfomations, filterConfig) {
$scope.doFilterInputTyping = function(keyEvent, jobInfomations, filterConfig) {
var RETURN_KEY_CODE = 13;
$timeout.cancel($scope.dofilterTimeoutObject);
$scope.isActiveSearchTimer = true;
$scope.dofilterTimeoutObject = $timeout(function() {
$scope.doFiltering(jobInfomations, filterConfig);
$scope.isActiveSearchTimer = false;
}, 10000);
if (keyEvent.which === RETURN_KEY_CODE) {
$timeout.cancel($scope.dofilterTimeoutObject);
$scope.doFiltering(jobInfomations, filterConfig);
$scope.isActiveSearchTimer = false;
}
};
$scope.doForceFilterInputTyping = function(keyEvent, jobInfomations, filterConfig) {
$timeout.cancel($scope.dofilterTimeoutObject);
$scope.doFiltering(jobInfomations, filterConfig);
$scope.isActiveSearchTimer = false;
};
$scope.init = function() {
$scope.isLoadingFilter = true;
$scope.jobInfomations = [];
$scope.JobInfomationsByFilter = $scope.jobInfomations;
$scope.filterConfig = {
isRunningAlwaysTop: true,
filterValueNotebookName: '',
filterValueInterpreter: '*',
isSortByAsc: true
};
$scope.jobTypeFilter = jobManagerFilter;
$scope.init = function() {
$scope.isLoadingFilter = true;
$scope.jobInfomations = [];
$scope.JobInfomationsByFilter = $scope.jobInfomations;
$scope.filterConfig = {
isRunningAlwaysTop: true,
filterValueNotebookName: '',
filterValueInterpreter: '*',
isSortByAsc: true
};
$scope.jobTypeFilter = jobManagerFilter;
websocketMsgSrv.getNoteJobsList();
websocketMsgSrv.getNoteJobsList();
$scope.$on('$destroy', function() {
websocketMsgSrv.unsubscribeJobManager();
});
};
$scope.$on('$destroy', function() {
websocketMsgSrv.unsubscribeJobManager();
});
};
/*
** $scope.$on functions below
*/
/*
** $scope.$on functions below
*/
$scope.$on('setNoteJobs', function(event, responseData) {
$scope.lastJobServerUnixTime = responseData.lastResponseUnixTime;
$scope.jobInfomations = responseData.jobs;
$scope.jobInfomationsIndexs = $scope.jobInfomations ? _.indexBy($scope.jobInfomations, 'noteId') : {};
$scope.jobTypeFilter($scope.jobInfomations, $scope.filterConfig);
$scope.activeInterpreters = [
{
name: 'ALL',
value: '*'
}
];
var interpreterLists = _.uniq(_.pluck($scope.jobInfomations, 'interpreter'), false);
for (var index = 0, length = interpreterLists.length; index < length; index++) {
$scope.activeInterpreters.push({
name: interpreterLists[index],
value: interpreterLists[index]
});
$scope.$on('setNoteJobs', function(event, responseData) {
$scope.lastJobServerUnixTime = responseData.lastResponseUnixTime;
$scope.jobInfomations = responseData.jobs;
$scope.jobInfomationsIndexs = $scope.jobInfomations ? _.indexBy($scope.jobInfomations, 'noteId') : {};
$scope.jobTypeFilter($scope.jobInfomations, $scope.filterConfig);
$scope.activeInterpreters = [
{
name: 'ALL',
value: '*'
}
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig);
});
$scope.$on('setUpdateNoteJobs', function(event, responseData) {
var jobInfomations = $scope.jobInfomations;
var indexStore = $scope.jobInfomationsIndexs;
$scope.lastJobServerUnixTime = responseData.lastResponseUnixTime;
var notes = responseData.jobs;
notes.map(function(changedItem) {
if (indexStore[changedItem.noteId] === undefined) {
var newItem = angular.copy(changedItem);
jobInfomations.push(newItem);
indexStore[changedItem.noteId] = newItem;
} else {
var changeOriginTarget = indexStore[changedItem.noteId];
if (changedItem.isRemoved !== undefined && changedItem.isRemoved === true) {
// remove Item.
var removeIndex = _.findIndex(indexStore, changedItem.noteId);
if (removeIndex > -1) {
indexStore.splice(removeIndex, 1);
}
removeIndex = _.findIndex(jobInfomations, {'noteId': changedItem.noteId});
if (removeIndex) {
jobInfomations.splice(removeIndex, 1);
}
} else {
// change value for item.
changeOriginTarget.isRunningJob = changedItem.isRunningJob;
changeOriginTarget.noteName = changedItem.noteName;
changeOriginTarget.noteType = changedItem.noteType;
changeOriginTarget.interpreter = changedItem.interpreter;
changeOriginTarget.unixTimeLastRun = changedItem.unixTimeLastRun;
changeOriginTarget.paragraphs = changedItem.paragraphs;
}
}
];
var interpreterLists = _.uniq(_.pluck($scope.jobInfomations, 'interpreter'), false);
for (var index = 0, length = interpreterLists.length; index < length; index++) {
$scope.activeInterpreters.push({
name: interpreterLists[index],
value: interpreterLists[index]
});
$scope.doFiltering(jobInfomations, $scope.filterConfig);
});
}
}
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig);
});
$scope.$on('setUpdateNoteJobs', function(event, responseData) {
var jobInfomations = $scope.jobInfomations;
var indexStore = $scope.jobInfomationsIndexs;
$scope.lastJobServerUnixTime = responseData.lastResponseUnixTime;
var notes = responseData.jobs;
notes.map(function(changedItem) {
if (indexStore[changedItem.noteId] === undefined) {
var newItem = angular.copy(changedItem);
jobInfomations.push(newItem);
indexStore[changedItem.noteId] = newItem;
} else {
var changeOriginTarget = indexStore[changedItem.noteId];
if (changedItem.isRemoved !== undefined && changedItem.isRemoved === true) {
// remove Item.
var removeIndex = _.findIndex(indexStore, changedItem.noteId);
if (removeIndex > -1) {
indexStore.splice(removeIndex, 1);
}
removeIndex = _.findIndex(jobInfomations, {'noteId': changedItem.noteId});
if (removeIndex) {
jobInfomations.splice(removeIndex, 1);
}
} else {
// change value for item.
changeOriginTarget.isRunningJob = changedItem.isRunningJob;
changeOriginTarget.noteName = changedItem.noteName;
changeOriginTarget.noteType = changedItem.noteType;
changeOriginTarget.interpreter = changedItem.interpreter;
changeOriginTarget.unixTimeLastRun = changedItem.unixTimeLastRun;
changeOriginTarget.paragraphs = changedItem.paragraphs;
}
}
});
$scope.doFiltering(jobInfomations, $scope.filterConfig);
});
}
})();

View file

@ -11,35 +11,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').filter('jobManager', jobManagerFilter);
angular.module('zeppelinWebApp').filter('jobManager', jobManagerFilter);
function jobManagerFilter() {
function filterContext(jobItems, filterConfig) {
var filterValueInterpreter = filterConfig.filterValueInterpreter;
var filterValueNotebookName = filterConfig.filterValueNotebookName;
var filterItems = jobItems;
function jobManagerFilter() {
function filterContext(jobItems, filterConfig) {
var filterValueInterpreter = filterConfig.filterValueInterpreter;
var filterValueNotebookName = filterConfig.filterValueNotebookName;
var filterItems = jobItems;
if (filterValueInterpreter === undefined) {
filterItems = _.filter(filterItems, function(jobItem) {
return jobItem.interpreter === undefined ? true : false;
});
} else if (filterValueInterpreter !== '*') {
filterItems = _.where(filterItems, {interpreter: filterValueInterpreter});
}
if (filterValueNotebookName !== '') {
filterItems = _.filter(filterItems, function(jobItem) {
var lowerFilterValue = filterValueNotebookName.toLocaleLowerCase();
var lowerNotebookName = jobItem.noteName.toLocaleLowerCase();
return lowerNotebookName.match(new RegExp('.*' + lowerFilterValue + '.*'));
});
}
return filterItems;
if (filterValueInterpreter === undefined) {
filterItems = _.filter(filterItems, function(jobItem) {
return jobItem.interpreter === undefined ? true : false;
});
} else if (filterValueInterpreter !== '*') {
filterItems = _.where(filterItems, {interpreter: filterValueInterpreter});
}
return filterContext;
}
})();
if (filterValueNotebookName !== '') {
filterItems = _.filter(filterItems, function(jobItem) {
var lowerFilterValue = filterValueNotebookName.toLocaleLowerCase();
var lowerNotebookName = jobItem.noteName.toLocaleLowerCase();
return lowerNotebookName.match(new RegExp('.*' + lowerFilterValue + '.*'));
});
}
return filterItems;
}
return filterContext;
}

View file

@ -11,99 +11,97 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('JobCtrl', JobCtrl);
angular.module('zeppelinWebApp').controller('JobCtrl', JobCtrl);
JobCtrl.$inject = ['$scope', '$http', 'baseUrlSrv'];
JobCtrl.$inject = ['$scope', '$http', 'baseUrlSrv'];
function JobCtrl($scope, $http, baseUrlSrv) {
$scope.init = function(jobInformation) {
$scope.progressValue = 0;
};
function JobCtrl($scope, $http, baseUrlSrv) {
$scope.init = function(jobInformation) {
$scope.progressValue = 0;
};
$scope.getProgress = function() {
var statusList = _.pluck($scope.notebookJob.paragraphs, 'status');
var runningJob = _.countBy(statusList, function(status) {
if (status === 'FINISHED' || status === 'RUNNING') {
return 'matchCount';
} else {
return 'none';
}
});
var totalCount = statusList.length;
var runningJobCount = runningJob.matchCount;
var result = Math.ceil(runningJobCount / totalCount * 100);
return isNaN(result) ? 0 : result;
};
$scope.getProgress = function() {
var statusList = _.pluck($scope.notebookJob.paragraphs, 'status');
var runningJob = _.countBy(statusList, function(status) {
if (status === 'FINISHED' || status === 'RUNNING') {
return 'matchCount';
} else {
return 'none';
}
});
var totalCount = statusList.length;
var runningJobCount = runningJob.matchCount;
var result = Math.ceil(runningJobCount / totalCount * 100);
return isNaN(result) ? 0 : result;
};
$scope.runNotebookJob = function(notebookId) {
BootstrapDialog.confirm({
closable: true,
title: '',
message: 'Run all paragraphs?',
callback: function(result) {
if (result) {
$http({
method: 'POST',
url: baseUrlSrv.getRestApiBase() + '/notebook/job/' + notebookId,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(function successCallback(response) {
// success
}, function errorCallback(errorResponse) {
var errorText = 'SERVER ERROR';
if (!!errorResponse.data.message) {
errorText = errorResponse.data.message;
}
BootstrapDialog.alert({
closable: true,
title: 'Execution Failure',
message: errorText
});
$scope.runNotebookJob = function(notebookId) {
BootstrapDialog.confirm({
closable: true,
title: '',
message: 'Run all paragraphs?',
callback: function(result) {
if (result) {
$http({
method: 'POST',
url: baseUrlSrv.getRestApiBase() + '/notebook/job/' + notebookId,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(function successCallback(response) {
// success
}, function errorCallback(errorResponse) {
var errorText = 'SERVER ERROR';
if (!!errorResponse.data.message) {
errorText = errorResponse.data.message;
}
BootstrapDialog.alert({
closable: true,
title: 'Execution Failure',
message: errorText
});
}
});
}
});
};
}
});
};
$scope.stopNotebookJob = function(notebookId) {
BootstrapDialog.confirm({
closable: true,
title: '',
message: 'Stop all paragraphs?',
callback: function(result) {
if (result) {
$http({
method: 'DELETE',
url: baseUrlSrv.getRestApiBase() + '/notebook/job/' + notebookId,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(function successCallback(response) {
// success
}, function errorCallback(errorResponse) {
var errorText = 'SERVER ERROR';
if (!!errorResponse.data.message) {
$scope.stopNotebookJob = function(notebookId) {
BootstrapDialog.confirm({
closable: true,
title: '',
message: 'Stop all paragraphs?',
callback: function(result) {
if (result) {
$http({
method: 'DELETE',
url: baseUrlSrv.getRestApiBase() + '/notebook/job/' + notebookId,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(function successCallback(response) {
// success
}, function errorCallback(errorResponse) {
var errorText = 'SERVER ERROR';
if (!!errorResponse.data.message) {
errorText = errorResponse.data.message;
}
BootstrapDialog.alert({
closable: true,
title: 'Stop Failure',
message: errorText
});
errorText = errorResponse.data.message;
}
BootstrapDialog.alert({
closable: true,
title: 'Stop Failure',
message: errorText
});
}
});
}
});
};
}
});
};
$scope.lastExecuteTime = function(unixtime) {
return moment.unix(unixtime / 1000).fromNow();
};
$scope.lastExecuteTime = function(unixtime) {
return moment.unix(unixtime / 1000).fromNow();
};
}
}
})();

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -11,80 +11,78 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('NotebookReposCtrl', NotebookReposCtrl);
angular.module('zeppelinWebApp').controller('NotebookReposCtrl', NotebookReposCtrl);
NotebookReposCtrl.$inject = ['$http', 'baseUrlSrv', 'ngToast'];
NotebookReposCtrl.$inject = ['$http', 'baseUrlSrv', 'ngToast'];
function NotebookReposCtrl($http, baseUrlSrv, ngToast) {
var vm = this;
vm.notebookRepos = [];
vm.showDropdownSelected = showDropdownSelected;
vm.saveNotebookRepo = saveNotebookRepo;
function NotebookReposCtrl($http, baseUrlSrv, ngToast) {
var vm = this;
vm.notebookRepos = [];
vm.showDropdownSelected = showDropdownSelected;
vm.saveNotebookRepo = saveNotebookRepo;
_init();
_init();
// Public functions
// Public functions
function saveNotebookRepo(valueform, repo, data) {
console.log('data %o', data);
$http.put(baseUrlSrv.getRestApiBase() + '/notebook-repositories', {
'name': repo.className,
'settings': data
}).success(function(data) {
var index = _.findIndex(vm.notebookRepos, {'className': repo.className});
if (index >= 0) {
vm.notebookRepos[index] = data.body;
console.log('repos %o, data %o', vm.notebookRepos, data.body);
}
valueform.$show();
}).error(function() {
ngToast.danger({
content: 'We couldn\'t save that NotebookRepo\'s settings',
verticalPosition: 'bottom',
timeout: '3000'
});
valueform.$show();
});
return 'manual';
}
function showDropdownSelected(setting) {
var index = _.findIndex(setting.value, {'value': setting.selected});
if (index < 0) {
return 'No value';
} else {
return setting.value[index].name;
function saveNotebookRepo(valueform, repo, data) {
console.log('data %o', data);
$http.put(baseUrlSrv.getRestApiBase() + '/notebook-repositories', {
'name': repo.className,
'settings': data
}).success(function(data) {
var index = _.findIndex(vm.notebookRepos, {'className': repo.className});
if (index >= 0) {
vm.notebookRepos[index] = data.body;
console.log('repos %o, data %o', vm.notebookRepos, data.body);
}
valueform.$show();
}).error(function() {
ngToast.danger({
content: 'We couldn\'t save that NotebookRepo\'s settings',
verticalPosition: 'bottom',
timeout: '3000'
});
valueform.$show();
});
return 'manual';
}
function showDropdownSelected(setting) {
var index = _.findIndex(setting.value, {'value': setting.selected});
if (index < 0) {
return 'No value';
} else {
return setting.value[index].name;
}
}
// Private functions
// Private functions
function _getInterpreterSettings() {
$http.get(baseUrlSrv.getRestApiBase() + '/notebook-repositories')
function _getInterpreterSettings() {
$http.get(baseUrlSrv.getRestApiBase() + '/notebook-repositories')
.success(function(data, status, headers, config) {
vm.notebookRepos = data.body;
console.log('ya notebookRepos %o', vm.notebookRepos);
}).error(function(data, status, headers, config) {
if (status === 401) {
ngToast.danger({
content: 'You don\'t have permission on this page',
verticalPosition: 'bottom',
timeout: '3000'
});
setTimeout(function() {
window.location.replace('/');
}, 3000);
}
console.log('Error %o %o', status, data.message);
});
}
function _init() {
_getInterpreterSettings();
};
if (status === 401) {
ngToast.danger({
content: 'You don\'t have permission on this page',
verticalPosition: 'bottom',
timeout: '3000'
});
setTimeout(function() {
window.location.replace('/');
}, 3000);
}
console.log('Error %o %o', status, data.message);
});
}
})();
function _init() {
_getInterpreterSettings();
};
}

View file

@ -11,148 +11,146 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('SearchResultCtrl', SearchResultCtrl);
angular.module('zeppelinWebApp').controller('SearchResultCtrl', SearchResultCtrl);
SearchResultCtrl.$inject = ['$scope', '$routeParams', 'searchService'];
SearchResultCtrl.$inject = ['$scope', '$routeParams', 'searchService'];
function SearchResultCtrl($scope, $routeParams, searchService) {
$scope.isResult = true ;
$scope.searchTerm = $routeParams.searchTerm;
var results = searchService.search({'q': $routeParams.searchTerm}).query();
results.$promise.then(function(result) {
$scope.notes = result.body.map(function(note) {
// redirect to notebook when search result is a notebook itself,
// not a paragraph
if (!/\/paragraph\//.test(note.id)) {
return note;
}
note.id = note.id.replace('paragraph/', '?paragraph=') +
'&term=' + $routeParams.searchTerm;
function SearchResultCtrl($scope, $routeParams, searchService) {
$scope.isResult = true ;
$scope.searchTerm = $routeParams.searchTerm;
var results = searchService.search({'q': $routeParams.searchTerm}).query();
results.$promise.then(function(result) {
$scope.notes = result.body.map(function(note) {
// redirect to notebook when search result is a notebook itself,
// not a paragraph
if (!/\/paragraph\//.test(note.id)) {
return note;
});
if ($scope.notes.length === 0) {
$scope.isResult = false;
} else {
$scope.isResult = true;
}
$scope.$on('$routeChangeStart', function(event, next, current) {
if (next.originalPath !== '/search/:searchTerm') {
searchService.searchTerm = '';
}
});
note.id = note.id.replace('paragraph/', '?paragraph=') +
'&term=' + $routeParams.searchTerm;
return note;
});
if ($scope.notes.length === 0) {
$scope.isResult = false;
} else {
$scope.isResult = true;
}
$scope.page = 0;
$scope.allResults = false;
$scope.$on('$routeChangeStart', function(event, next, current) {
if (next.originalPath !== '/search/:searchTerm') {
searchService.searchTerm = '';
}
});
});
$scope.highlightSearchResults = function(note) {
return function(_editor) {
function getEditorMode(text) {
var editorModes = {
'ace/mode/scala': /^%(\w*\.)?spark/,
'ace/mode/python': /^%(\w*\.)?(pyspark|python)/,
'ace/mode/r': /^%(\w*\.)?(r|sparkr|knitr)/,
'ace/mode/sql': /^%(\w*\.)?\wql/,
'ace/mode/markdown': /^%md/,
'ace/mode/sh': /^%sh/
};
$scope.page = 0;
$scope.allResults = false;
return Object.keys(editorModes).reduce(function(res, mode) {
return editorModes[mode].test(text) ? mode : res;
}, 'ace/mode/scala');
}
$scope.highlightSearchResults = function(note) {
return function(_editor) {
function getEditorMode(text) {
var editorModes = {
'ace/mode/scala': /^%(\w*\.)?spark/,
'ace/mode/python': /^%(\w*\.)?(pyspark|python)/,
'ace/mode/r': /^%(\w*\.)?(r|sparkr|knitr)/,
'ace/mode/sql': /^%(\w*\.)?\wql/,
'ace/mode/markdown': /^%md/,
'ace/mode/sh': /^%sh/
};
var Range = ace.require('ace/range').Range;
return Object.keys(editorModes).reduce(function(res, mode) {
return editorModes[mode].test(text) ? mode : res;
}, 'ace/mode/scala');
}
_editor.setOption('highlightActiveLine', false);
_editor.$blockScrolling = Infinity;
_editor.setReadOnly(true);
_editor.renderer.setShowGutter(false);
_editor.setTheme('ace/theme/chrome');
_editor.getSession().setMode(getEditorMode(note.text));
var Range = ace.require('ace/range').Range;
function getIndeces(term) {
return function(str) {
var indeces = [];
var i = -1;
while ((i = str.indexOf(term, i + 1)) >= 0) {
indeces.push(i);
_editor.setOption('highlightActiveLine', false);
_editor.$blockScrolling = Infinity;
_editor.setReadOnly(true);
_editor.renderer.setShowGutter(false);
_editor.setTheme('ace/theme/chrome');
_editor.getSession().setMode(getEditorMode(note.text));
function getIndeces(term) {
return function(str) {
var indeces = [];
var i = -1;
while ((i = str.indexOf(term, i + 1)) >= 0) {
indeces.push(i);
}
return indeces;
};
}
var result = '';
if (note.header !== '') {
result = note.header + '\n\n' + note.snippet;
} else {
result = note.snippet;
}
var lines = result
.split('\n')
.map(function(line, row) {
var match = line.match(/<B>(.+?)<\/B>/);
// return early if nothing to highlight
if (!match) {
return line;
}
var term = match[1];
var __line = line
.replace(/<B>/g, '')
.replace(/<\/B>/g, '');
var indeces = getIndeces(term)(__line);
indeces.forEach(function(start) {
var end = start + term.length;
if (note.header !== '' && row === 0) {
_editor
.getSession()
.addMarker(
new Range(row, 0, row, line.length),
'search-results-highlight-header',
'background'
);
_editor
.getSession()
.addMarker(
new Range(row, start, row, end),
'search-results-highlight',
'line'
);
} else {
_editor
.getSession()
.addMarker(
new Range(row, start, row, end),
'search-results-highlight',
'line'
);
}
return indeces;
};
}
var result = '';
if (note.header !== '') {
result = note.header + '\n\n' + note.snippet;
} else {
result = note.snippet;
}
var lines = result
.split('\n')
.map(function(line, row) {
var match = line.match(/<B>(.+?)<\/B>/);
// return early if nothing to highlight
if (!match) {
return line;
}
var term = match[1];
var __line = line
.replace(/<B>/g, '')
.replace(/<\/B>/g, '');
var indeces = getIndeces(term)(__line);
indeces.forEach(function(start) {
var end = start + term.length;
if (note.header !== '' && row === 0) {
_editor
.getSession()
.addMarker(
new Range(row, 0, row, line.length),
'search-results-highlight-header',
'background'
);
_editor
.getSession()
.addMarker(
new Range(row, start, row, end),
'search-results-highlight',
'line'
);
} else {
_editor
.getSession()
.addMarker(
new Range(row, start, row, end),
'search-results-highlight',
'line'
);
}
});
return __line;
});
return __line;
});
// resize editor based on content length
_editor.setOption(
'maxLines',
lines.reduce(function(len, line) {return len + line.length;}, 0)
);
// resize editor based on content length
_editor.setOption(
'maxLines',
lines.reduce(function(len, line) {return len + line.length;}, 0)
);
_editor.getSession().setValue(lines.join('\n'));
_editor.getSession().setValue(lines.join('\n'));
};
};
}
};
}
})();

View file

@ -11,29 +11,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').service('arrayOrderingSrv', arrayOrderingSrv);
angular.module('zeppelinWebApp').service('arrayOrderingSrv', arrayOrderingSrv);
arrayOrderingSrv.$inject = ['TRASH_FOLDER_ID'];
arrayOrderingSrv.$inject = ['TRASH_FOLDER_ID'];
function arrayOrderingSrv(TRASH_FOLDER_ID) {
var arrayOrderingSrv = this;
function arrayOrderingSrv(TRASH_FOLDER_ID) {
var arrayOrderingSrv = this;
this.noteListOrdering = function(note) {
if (note.id === TRASH_FOLDER_ID) {
return '\uFFFF';
}
return arrayOrderingSrv.getNoteName(note);
};
this.noteListOrdering = function(note) {
if (note.id === TRASH_FOLDER_ID) {
return '\uFFFF';
}
return arrayOrderingSrv.getNoteName(note);
};
this.getNoteName = function(note) {
if (note.name === undefined || note.name.trim() === '') {
return 'Note ' + note.id;
} else {
return note.name;
}
};
}
this.getNoteName = function(note) {
if (note.name === undefined || note.name.trim() === '') {
return 'Note ' + note.id;
} else {
return note.name;
}
};
}
})();

View file

@ -11,41 +11,39 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').service('baseUrlSrv', baseUrlSrv);
angular.module('zeppelinWebApp').service('baseUrlSrv', baseUrlSrv);
function baseUrlSrv() {
this.getPort = function() {
var port = Number(location.port);
if (!port) {
port = 80;
if (location.protocol === 'https:') {
port = 443;
}
function baseUrlSrv() {
this.getPort = function() {
var port = Number(location.port);
if (!port) {
port = 80;
if (location.protocol === 'https:') {
port = 443;
}
//Exception for when running locally via grunt
if (port === 3333 || port === 9000) {
port = 8080;
}
return port;
};
}
//Exception for when running locally via grunt
if (port === 3333 || port === 9000) {
port = 8080;
}
return port;
};
this.getWebsocketUrl = function() {
var wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
return wsProtocol + '//' + location.hostname + ':' + this.getPort() +
this.getWebsocketUrl = function() {
var wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
return wsProtocol + '//' + location.hostname + ':' + this.getPort() +
skipTrailingSlash(location.pathname) + '/ws';
};
};
this.getRestApiBase = function() {
return location.protocol + '//' + location.hostname + ':' +
this.getRestApiBase = function() {
return location.protocol + '//' + location.hostname + ':' +
this.getPort() + skipTrailingSlash(location.pathname) +
'/api';
};
'/api';
};
var skipTrailingSlash = function(path) {
return path.replace(/\/$/, '');
};
}
var skipTrailingSlash = function(path) {
return path.replace(/\/$/, '');
};
}
})();

View file

@ -11,32 +11,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').service('browserDetectService', browserDetectService);
angular.module('zeppelinWebApp').service('browserDetectService', browserDetectService);
function browserDetectService() {
this.detectIE = function() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
if (msie > 0) {
// IE 10 or older => return version number
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
}
var trident = ua.indexOf('Trident/');
if (trident > 0) {
// IE 11 => return version number
var rv = ua.indexOf('rv:');
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
}
var edge = ua.indexOf('Edge/');
if (edge > 0) {
// IE 12 (aka Edge) => return version number
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
}
// other browser
return false;
};
}
function browserDetectService() {
this.detectIE = function() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
if (msie > 0) {
// IE 10 or older => return version number
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
}
var trident = ua.indexOf('Trident/');
if (trident > 0) {
// IE 11 => return version number
var rv = ua.indexOf('rv:');
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
}
var edge = ua.indexOf('Edge/');
if (edge > 0) {
// IE 12 (aka Edge) => return version number
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
}
// other browser
return false;
};
}
})();

View file

@ -11,25 +11,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('clipboardCtrl', clipboardCtrl);
clipboardCtrl.$inject = ['$scope'];
angular.module('zeppelinWebApp').controller('clipboardCtrl', clipboardCtrl);
clipboardCtrl.$inject = ['$scope'];
function clipboardCtrl($scope) {
$scope.complete = function(e) {
$scope.copied = true;
$scope.tooltip = 'Copied!';
setTimeout(function() {
$scope.tooltip = 'Copy to clipboard';
}, 400);
};
$scope.$watch('input', function() {
$scope.copied = false;
function clipboardCtrl($scope) {
$scope.complete = function(e) {
$scope.copied = true;
$scope.tooltip = 'Copied!';
setTimeout(function() {
$scope.tooltip = 'Copy to clipboard';
});
$scope.clipError = function(e) {
console.log('Error: ' + e.name + ' - ' + e.message);
$scope.tooltip = 'Not supported browser';
};
}
})();
}, 400);
};
$scope.$watch('input', function() {
$scope.copied = false;
$scope.tooltip = 'Copy to clipboard';
});
$scope.clipError = function(e) {
console.log('Error: ' + e.name + ' - ' + e.message);
$scope.tooltip = 'Not supported browser';
};
}

View file

@ -11,19 +11,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').directive('dropdownInput', dropdownInput);
angular.module('zeppelinWebApp').directive('dropdownInput', dropdownInput);
function dropdownInput() {
return {
restrict: 'A',
link: function(scope, element) {
element.bind('click', function(event) {
event.stopPropagation();
});
}
};
}
function dropdownInput() {
return {
restrict: 'A',
link: function(scope, element) {
element.bind('click', function(event) {
event.stopPropagation();
});
}
};
}
})();

View file

@ -11,31 +11,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').directive('codeEditor', codeEditor);
angular.module('zeppelinWebApp').directive('codeEditor', codeEditor);
function codeEditor($templateRequest, $compile) {
return {
restrict: 'AE',
scope: {
paragraphId: '=paragraphId',
paragraph: '=paragraphContext',
dirtyText: '=dirtyText',
originalText: '=originalText',
onLoad: '=onLoad',
revisionView: '=revisionView'
},
link: function(scope, element, attrs, controller) {
$templateRequest('components/editor/ace.editor.directive.html').then(function(editorHtml) {
var editor = angular.element(editorHtml);
editor.attr('id', scope.paragraphId + '_editor');
element.append(editor);
$compile(editor)(scope);
console.log('codeEditor directive revision view is ' + scope.revisionView);
});
}
};
}
function codeEditor($templateRequest, $compile) {
return {
restrict: 'AE',
scope: {
paragraphId: '=paragraphId',
paragraph: '=paragraphContext',
dirtyText: '=dirtyText',
originalText: '=originalText',
onLoad: '=onLoad',
revisionView: '=revisionView'
},
link: function(scope, element, attrs, controller) {
$templateRequest('components/editor/ace.editor.directive.html').then(function(editorHtml) {
var editor = angular.element(editorHtml);
editor.attr('id', scope.paragraphId + '_editor');
element.append(editor);
$compile(editor)(scope);
console.log('codeEditor directive revision view is ' + scope.revisionView);
});
}
};
}
})();

View file

@ -11,14 +11,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('ElasticInputCtrl', ElasticInputCtrl);
angular.module('zeppelinWebApp').controller('ElasticInputCtrl', ElasticInputCtrl);
function ElasticInputCtrl() {
var vm = this;
vm.showEditor = false;
vm.value = '';
}
function ElasticInputCtrl() {
var vm = this;
vm.showEditor = false;
vm.value = '';
}
})();

View file

@ -11,30 +11,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').directive('expandCollapse', expandCollapse);
angular.module('zeppelinWebApp').directive('expandCollapse', expandCollapse);
function expandCollapse() {
return {
restrict: 'EA',
link: function(scope, element, attrs) {
angular.element(element).click(function(event) {
if (angular.element(element).find('.expandable:visible').length > 1) {
angular.element(element).find('.expandable:visible').slideUp('slow');
angular.element(element).find('i.icon-folder-alt').toggleClass('icon-folder icon-folder-alt');
} else {
angular.element(element).find('.expandable').first().slideToggle('200',function() {
// do not toggle trash folder
if (angular.element(element).find('.fa-trash-o').length === 0) {
angular.element(element).find('i').first().toggleClass('icon-folder icon-folder-alt');
}
});
}
event.stopPropagation();
});
}
};
}
function expandCollapse() {
return {
restrict: 'EA',
link: function(scope, element, attrs) {
angular.element(element).click(function(event) {
if (angular.element(element).find('.expandable:visible').length > 1) {
angular.element(element).find('.expandable:visible').slideUp('slow');
angular.element(element).find('i.icon-folder-alt').toggleClass('icon-folder icon-folder-alt');
} else {
angular.element(element).find('.expandable').first().slideToggle('200',function() {
// do not toggle trash folder
if (angular.element(element).find('.fa-trash-o').length === 0) {
angular.element(element).find('i').first().toggleClass('icon-folder icon-folder-alt');
}
});
}
event.stopPropagation();
});
}
};
}
})();

View file

@ -11,24 +11,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').directive('interpreterDirective', interpreterDirective);
angular.module('zeppelinWebApp').directive('interpreterDirective', interpreterDirective);
interpreterDirective.$inject = ['$timeout'];
interpreterDirective.$inject = ['$timeout'];
function interpreterDirective($timeout) {
return {
restrict: 'A',
link: function(scope, element, attr) {
if (scope.$last === true) {
$timeout(function() {
var id = 'ngRenderFinished';
scope.$emit(id);
});
}
function interpreterDirective($timeout) {
return {
restrict: 'A',
link: function(scope, element, attr) {
if (scope.$last === true) {
$timeout(function() {
var id = 'ngRenderFinished';
scope.$emit(id);
});
}
};
}
}
};
}
})();

View file

@ -11,53 +11,51 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('LoginCtrl', LoginCtrl);
angular.module('zeppelinWebApp').controller('LoginCtrl', LoginCtrl);
LoginCtrl.$inject = ['$scope', '$rootScope', '$http', '$httpParamSerializer', 'baseUrlSrv'];
function LoginCtrl($scope, $rootScope, $http, $httpParamSerializer, baseUrlSrv) {
$scope.SigningIn = false;
$scope.loginParams = {};
$scope.login = function() {
LoginCtrl.$inject = ['$scope', '$rootScope', '$http', '$httpParamSerializer', 'baseUrlSrv'];
function LoginCtrl($scope, $rootScope, $http, $httpParamSerializer, baseUrlSrv) {
$scope.SigningIn = false;
$scope.loginParams = {};
$scope.login = function() {
$scope.SigningIn = true;
$http({
method: 'POST',
url: baseUrlSrv.getRestApiBase() + '/login',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $httpParamSerializer({
'userName': $scope.loginParams.userName,
'password': $scope.loginParams.password
})
}).then(function successCallback(response) {
$rootScope.ticket = response.data.body;
angular.element('#loginModal').modal('toggle');
$rootScope.$broadcast('loginSuccess', true);
$rootScope.userName = $scope.loginParams.userName;
}, function errorCallback(errorResponse) {
$scope.loginParams.errorText = 'The username and password that you entered don\'t match.';
$scope.SigningIn = false;
});
};
var initValues = function() {
$scope.loginParams = {
userName: '',
password: ''
};
};
/*
** $scope.$on functions below
*/
$scope.$on('initLoginValues', function() {
initValues();
$scope.SigningIn = true;
$http({
method: 'POST',
url: baseUrlSrv.getRestApiBase() + '/login',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $httpParamSerializer({
'userName': $scope.loginParams.userName,
'password': $scope.loginParams.password
})
}).then(function successCallback(response) {
$rootScope.ticket = response.data.body;
angular.element('#loginModal').modal('toggle');
$rootScope.$broadcast('loginSuccess', true);
$rootScope.userName = $scope.loginParams.userName;
}, function errorCallback(errorResponse) {
$scope.loginParams.errorText = 'The username and password that you entered don\'t match.';
$scope.SigningIn = false;
});
}
})();
};
var initValues = function() {
$scope.loginParams = {
userName: '',
password: ''
};
};
/*
** $scope.$on functions below
*/
$scope.$on('initLoginValues', function() {
initValues();
});
}

View file

@ -11,135 +11,133 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('NavCtrl', NavCtrl);
angular.module('zeppelinWebApp').controller('NavCtrl', NavCtrl);
NavCtrl.$inject = [
'$scope',
'$rootScope',
'$http',
'$routeParams',
'$location',
'noteListDataFactory',
'baseUrlSrv',
'websocketMsgSrv',
'arrayOrderingSrv',
'searchService',
'TRASH_FOLDER_ID'
];
NavCtrl.$inject = [
'$scope',
'$rootScope',
'$http',
'$routeParams',
'$location',
'noteListDataFactory',
'baseUrlSrv',
'websocketMsgSrv',
'arrayOrderingSrv',
'searchService',
'TRASH_FOLDER_ID'
];
function NavCtrl($scope, $rootScope, $http, $routeParams, $location,
noteListDataFactory, baseUrlSrv, websocketMsgSrv,
arrayOrderingSrv, searchService, TRASH_FOLDER_ID) {
var vm = this;
vm.arrayOrderingSrv = arrayOrderingSrv;
vm.connected = websocketMsgSrv.isConnected();
vm.isActive = isActive;
vm.logout = logout;
vm.notes = noteListDataFactory;
vm.search = search;
vm.searchForm = searchService;
vm.showLoginWindow = showLoginWindow;
vm.TRASH_FOLDER_ID = TRASH_FOLDER_ID;
function NavCtrl($scope, $rootScope, $http, $routeParams, $location,
noteListDataFactory, baseUrlSrv, websocketMsgSrv,
arrayOrderingSrv, searchService, TRASH_FOLDER_ID) {
var vm = this;
vm.arrayOrderingSrv = arrayOrderingSrv;
vm.connected = websocketMsgSrv.isConnected();
vm.isActive = isActive;
vm.logout = logout;
vm.notes = noteListDataFactory;
vm.search = search;
vm.searchForm = searchService;
vm.showLoginWindow = showLoginWindow;
vm.TRASH_FOLDER_ID = TRASH_FOLDER_ID;
$scope.query = {q: ''};
$scope.query = {q: ''};
initController();
initController();
function getZeppelinVersion() {
$http.get(baseUrlSrv.getRestApiBase() + '/version').success(
function(data, status, headers, config) {
$rootScope.zeppelinVersion = data.body;
}).error(
function(data, status, headers, config) {
console.log('Error %o %o', status, data.message);
});
}
function initController() {
$scope.isDrawNavbarNoteList = false;
angular.element('#notebook-list').perfectScrollbar({suppressScrollX: true});
angular.element(document).click(function() {
$scope.query.q = '';
function getZeppelinVersion() {
$http.get(baseUrlSrv.getRestApiBase() + '/version').success(
function(data, status, headers, config) {
$rootScope.zeppelinVersion = data.body;
}).error(
function(data, status, headers, config) {
console.log('Error %o %o', status, data.message);
});
getZeppelinVersion();
loadNotes();
}
function isActive(noteId) {
return ($routeParams.noteId === noteId);
}
function loadNotes() {
websocketMsgSrv.getNoteList();
}
function logout() {
var logoutURL = baseUrlSrv.getRestApiBase() + '/login/logout';
//for firefox and safari
logoutURL = logoutURL.replace('//', '//false:false@');
$http.post(logoutURL).error(function() {
//force authcBasic (if configured) to logout
$http.post(logoutURL).error(function() {
$rootScope.userName = '';
$rootScope.ticket.principal = '';
$rootScope.ticket.ticket = '';
$rootScope.ticket.roles = '';
BootstrapDialog.show({
message: 'Logout Success'
});
setTimeout(function() {
window.location.replace('/');
}, 1000);
});
});
}
function search(searchTerm) {
$location.path('/search/' + searchTerm);
}
function showLoginWindow() {
setTimeout(function() {
angular.element('#userName').focus();
}, 500);
}
/*
** $scope.$on functions below
*/
$scope.$on('setNoteMenu', function(event, notes) {
noteListDataFactory.setNotes(notes);
initNotebookListEventListener();
});
$scope.$on('setConnectedStatus', function(event, param) {
vm.connected = param;
});
$scope.$on('loginSuccess', function(event, param) {
loadNotes();
});
/*
** Performance optimization for Browser Render.
*/
function initNotebookListEventListener() {
angular.element(document).ready(function() {
angular.element('.notebook-list-dropdown').on('show.bs.dropdown', function() {
$scope.isDrawNavbarNoteList = true;
});
angular.element('.notebook-list-dropdown').on('hide.bs.dropdown', function() {
$scope.isDrawNavbarNoteList = false;
});
});
}
}
})();
function initController() {
$scope.isDrawNavbarNoteList = false;
angular.element('#notebook-list').perfectScrollbar({suppressScrollX: true});
angular.element(document).click(function() {
$scope.query.q = '';
});
getZeppelinVersion();
loadNotes();
}
function isActive(noteId) {
return ($routeParams.noteId === noteId);
}
function loadNotes() {
websocketMsgSrv.getNoteList();
}
function logout() {
var logoutURL = baseUrlSrv.getRestApiBase() + '/login/logout';
//for firefox and safari
logoutURL = logoutURL.replace('//', '//false:false@');
$http.post(logoutURL).error(function() {
//force authcBasic (if configured) to logout
$http.post(logoutURL).error(function() {
$rootScope.userName = '';
$rootScope.ticket.principal = '';
$rootScope.ticket.ticket = '';
$rootScope.ticket.roles = '';
BootstrapDialog.show({
message: 'Logout Success'
});
setTimeout(function() {
window.location.replace('/');
}, 1000);
});
});
}
function search(searchTerm) {
$location.path('/search/' + searchTerm);
}
function showLoginWindow() {
setTimeout(function() {
angular.element('#userName').focus();
}, 500);
}
/*
** $scope.$on functions below
*/
$scope.$on('setNoteMenu', function(event, notes) {
noteListDataFactory.setNotes(notes);
initNotebookListEventListener();
});
$scope.$on('setConnectedStatus', function(event, param) {
vm.connected = param;
});
$scope.$on('loginSuccess', function(event, param) {
loadNotes();
});
/*
** Performance optimization for Browser Render.
*/
function initNotebookListEventListener() {
angular.element(document).ready(function() {
angular.element('.notebook-list-dropdown').on('show.bs.dropdown', function() {
$scope.isDrawNavbarNoteList = true;
});
angular.element('.notebook-list-dropdown').on('hide.bs.dropdown', function() {
$scope.isDrawNavbarNoteList = false;
});
});
}
}

View file

@ -11,23 +11,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').directive('ngEnter', ngEnter);
angular.module('zeppelinWebApp').directive('ngEnter', ngEnter);
function ngEnter() {
return function(scope, element, attrs) {
element.bind('keydown keypress', function(event) {
if (event.which === 13) {
if (!event.shiftKey) {
scope.$apply(function() {
scope.$eval(attrs.ngEnter);
});
}
event.preventDefault();
function ngEnter() {
return function(scope, element, attrs) {
element.bind('keydown keypress', function(event) {
if (event.which === 13) {
if (!event.shiftKey) {
scope.$apply(function() {
scope.$eval(attrs.ngEnter);
});
}
});
};
}
event.preventDefault();
}
});
};
}
})();

View file

@ -11,21 +11,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').directive('ngEscape', ngEscape);
angular.module('zeppelinWebApp').directive('ngEscape', ngEscape);
function ngEscape() {
return function(scope, element, attrs) {
element.bind('keydown keyup', function(event) {
if (event.which === 27) {
scope.$apply(function() {
scope.$eval(attrs.ngEscape);
});
event.preventDefault();
}
});
};
}
function ngEscape() {
return function(scope, element, attrs) {
element.bind('keydown keyup', function(event) {
if (event.which === 27) {
scope.$apply(function() {
scope.$eval(attrs.ngEscape);
});
event.preventDefault();
}
});
};
}
})();

View file

@ -11,175 +11,173 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').service('noteActionSrv', noteActionSrv);
angular.module('zeppelinWebApp').service('noteActionSrv', noteActionSrv);
noteActionSrv.$inject = ['websocketMsgSrv', '$location', 'renameSrv', 'noteListDataFactory'];
noteActionSrv.$inject = ['websocketMsgSrv', '$location', 'renameSrv', 'noteListDataFactory'];
function noteActionSrv(websocketMsgSrv, $location, renameSrv, noteListDataFactory) {
this.moveNoteToTrash = function(noteId, redirectToHome) {
BootstrapDialog.confirm({
closable: true,
title: 'Move this note to trash?',
message: 'This note will be moved to <strong>trash</strong>.',
callback: function(result) {
if (result) {
websocketMsgSrv.moveNoteToTrash(noteId);
if (redirectToHome) {
$location.path('/');
}
function noteActionSrv(websocketMsgSrv, $location, renameSrv, noteListDataFactory) {
this.moveNoteToTrash = function(noteId, redirectToHome) {
BootstrapDialog.confirm({
closable: true,
title: 'Move this note to trash?',
message: 'This note will be moved to <strong>trash</strong>.',
callback: function(result) {
if (result) {
websocketMsgSrv.moveNoteToTrash(noteId);
if (redirectToHome) {
$location.path('/');
}
}
});
};
}
});
};
this.moveFolderToTrash = function(folderId) {
BootstrapDialog.confirm({
closable: true,
title: 'Move this folder to trash?',
message: 'This folder will be moved to <strong>trash</strong>.',
callback: function(result) {
if (result) {
websocketMsgSrv.moveFolderToTrash(folderId);
this.moveFolderToTrash = function(folderId) {
BootstrapDialog.confirm({
closable: true,
title: 'Move this folder to trash?',
message: 'This folder will be moved to <strong>trash</strong>.',
callback: function(result) {
if (result) {
websocketMsgSrv.moveFolderToTrash(folderId);
}
}
});
};
this.removeNote = function(noteId, redirectToHome) {
BootstrapDialog.confirm({
type: BootstrapDialog.TYPE_WARNING,
closable: true,
title: 'WARNING! This note will be removed permanently',
message: 'This cannot be undone. Are you sure?',
callback: function(result) {
if (result) {
websocketMsgSrv.deleteNote(noteId);
if (redirectToHome) {
$location.path('/');
}
}
});
};
}
});
};
this.removeNote = function(noteId, redirectToHome) {
BootstrapDialog.confirm({
type: BootstrapDialog.TYPE_WARNING,
closable: true,
title: 'WARNING! This note will be removed permanently',
message: 'This cannot be undone. Are you sure?',
callback: function(result) {
if (result) {
websocketMsgSrv.deleteNote(noteId);
if (redirectToHome) {
$location.path('/');
}
}
this.removeFolder = function(folderId) {
BootstrapDialog.confirm({
type: BootstrapDialog.TYPE_WARNING,
closable: true,
title: 'WARNING! This folder will be removed permanently',
message: 'This cannot be undone. Are you sure?',
callback: function(result) {
if (result) {
websocketMsgSrv.removeFolder(folderId);
}
});
};
}
});
};
this.removeFolder = function(folderId) {
BootstrapDialog.confirm({
type: BootstrapDialog.TYPE_WARNING,
closable: true,
title: 'WARNING! This folder will be removed permanently',
message: 'This cannot be undone. Are you sure?',
callback: function(result) {
if (result) {
websocketMsgSrv.removeFolder(folderId);
}
this.restoreAll = function() {
BootstrapDialog.confirm({
closable: true,
title: 'Are you sure want to restore all notes in the trash?',
message: 'Folders and notes in the trash will be ' +
'<strong>merged</strong> into their original position.',
callback: function(result) {
if (result) {
websocketMsgSrv.restoreAll();
}
});
};
}
});
};
this.restoreAll = function() {
BootstrapDialog.confirm({
closable: true,
title: 'Are you sure want to restore all notes in the trash?',
message: 'Folders and notes in the trash will be ' +
'<strong>merged</strong> into their original position.',
callback: function(result) {
if (result) {
websocketMsgSrv.restoreAll();
}
this.emptyTrash = function() {
BootstrapDialog.confirm({
type: BootstrapDialog.TYPE_WARNING,
closable: true,
title: 'WARNING! Notes under trash will be removed permanently',
message: 'This cannot be undone. Are you sure?',
callback: function(result) {
if (result) {
websocketMsgSrv.emptyTrash();
}
});
};
}
});
};
this.emptyTrash = function() {
BootstrapDialog.confirm({
type: BootstrapDialog.TYPE_WARNING,
closable: true,
title: 'WARNING! Notes under trash will be removed permanently',
message: 'This cannot be undone. Are you sure?',
callback: function(result) {
if (result) {
websocketMsgSrv.emptyTrash();
}
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);
}
});
};
}
});
};
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);
}
}
});
};
this.renameNote = function(noteId, notePath) {
renameSrv.openRenameModal({
title: 'Rename note',
oldName: notePath,
callback: function(newName) {
websocketMsgSrv.renameNote(noteId, newName);
}
});
};
this.renameNote = function(noteId, notePath) {
renameSrv.openRenameModal({
title: 'Rename note',
oldName: notePath,
callback: function(newName) {
websocketMsgSrv.renameNote(noteId, newName);
}
});
};
this.renameFolder = function(folderId) {
renameSrv.openRenameModal({
title: 'Rename folder',
oldName: folderId,
callback: function(newName) {
var newFolderId = normalizeFolderId(newName);
if (_.has(noteListDataFactory.flatFolderMap, newFolderId)) {
BootstrapDialog.confirm({
type: BootstrapDialog.TYPE_WARNING,
closable: true,
title: 'WARNING! The folder will be MERGED',
message: 'The folder will be merged into <strong>' + newFolderId + '</strong>. Are you sure?',
callback: function(result) {
if (result) {
websocketMsgSrv.renameFolder(folderId, newFolderId);
}
this.renameFolder = function(folderId) {
renameSrv.openRenameModal({
title: 'Rename folder',
oldName: folderId,
callback: function(newName) {
var newFolderId = normalizeFolderId(newName);
if (_.has(noteListDataFactory.flatFolderMap, newFolderId)) {
BootstrapDialog.confirm({
type: BootstrapDialog.TYPE_WARNING,
closable: true,
title: 'WARNING! The folder will be MERGED',
message: 'The folder will be merged into <strong>' + newFolderId + '</strong>. Are you sure?',
callback: function(result) {
if (result) {
websocketMsgSrv.renameFolder(folderId, newFolderId);
}
});
} else {
websocketMsgSrv.renameFolder(folderId, newFolderId);
}
}
});
} else {
websocketMsgSrv.renameFolder(folderId, newFolderId);
}
});
};
function normalizeFolderId(folderId) {
folderId = folderId.trim();
while (folderId.indexOf('\\') > -1) {
folderId = folderId.replace('\\', '/');
}
});
};
while (folderId.indexOf('///') > -1) {
folderId = folderId.replace('///', '/');
}
function normalizeFolderId(folderId) {
folderId = folderId.trim();
folderId = folderId.replace('//', '/');
if (folderId === '/') {
return '/';
}
if (folderId[0] === '/') {
folderId = folderId.substring(1);
}
if (folderId.slice(-1) === '/') {
folderId = folderId.slice(0, -1);
}
return folderId;
while (folderId.indexOf('\\') > -1) {
folderId = folderId.replace('\\', '/');
}
while (folderId.indexOf('///') > -1) {
folderId = folderId.replace('///', '/');
}
folderId = folderId.replace('//', '/');
if (folderId === '/') {
return '/';
}
if (folderId[0] === '/') {
folderId = folderId.substring(1);
}
if (folderId.slice(-1) === '/') {
folderId = folderId.slice(0, -1);
}
return folderId;
}
})();
}

View file

@ -11,74 +11,72 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').factory('noteListDataFactory', noteListDataFactory);
angular.module('zeppelinWebApp').factory('noteListDataFactory', noteListDataFactory);
noteListDataFactory.$inject = ['TRASH_FOLDER_ID'];
noteListDataFactory.$inject = ['TRASH_FOLDER_ID'];
function noteListDataFactory(TRASH_FOLDER_ID) {
var notes = {
root: {children: []},
flatList: [],
flatFolderMap: {},
function noteListDataFactory(TRASH_FOLDER_ID) {
var notes = {
root: {children: []},
flatList: [],
flatFolderMap: {},
setNotes: function(notesList) {
// a flat list to boost searching
notes.flatList = _.map(notesList, (note) => {
note.isTrash = note.name ?
note.name.split('/')[0] === TRASH_FOLDER_ID : false;
return note;
});
setNotes: function(notesList) {
// a flat list to boost searching
notes.flatList = _.map(notesList, (note) => {
note.isTrash = note.name ?
note.name.split('/')[0] === TRASH_FOLDER_ID : false;
return note;
});
// construct the folder-based tree
notes.root = {children: []};
notes.flatFolderMap = {};
_.reduce(notesList, function(root, note) {
var noteName = note.name || note.id;
var nodes = noteName.match(/([^\/][^\/]*)/g);
// construct the folder-based tree
notes.root = {children: []};
notes.flatFolderMap = {};
_.reduce(notesList, function(root, note) {
var noteName = note.name || note.id;
var nodes = noteName.match(/([^\/][^\/]*)/g);
// recursively add nodes
addNode(root, nodes, note.id);
// recursively add nodes
addNode(root, nodes, note.id);
return root;
}, notes.root);
}
};
return root;
}, notes.root);
}
};
var addNode = function(curDir, nodes, noteId) {
if (nodes.length === 1) { // the leaf
curDir.children.push({
name: nodes[0],
id: noteId,
path: curDir.id ? curDir.id + '/' + nodes[0] : nodes[0],
var addNode = function(curDir, nodes, noteId) {
if (nodes.length === 1) { // the leaf
curDir.children.push({
name: nodes[0],
id: noteId,
path: curDir.id ? curDir.id + '/' + nodes[0] : nodes[0],
isTrash: curDir.id ? curDir.id.split('/')[0] === TRASH_FOLDER_ID : false
});
} else { // a folder node
var node = nodes.shift();
var dir = _.find(curDir.children,
function(c) {return c.name === node && c.children !== undefined;});
if (dir !== undefined) { // found an existing dir
addNode(dir, nodes, noteId);
} else {
var newDir = {
id: curDir.id ? curDir.id + '/' + node : node,
name: node,
hidden: true,
children: [],
isTrash: curDir.id ? curDir.id.split('/')[0] === TRASH_FOLDER_ID : false
});
} else { // a folder node
var node = nodes.shift();
var dir = _.find(curDir.children,
function(c) {return c.name === node && c.children !== undefined;});
if (dir !== undefined) { // found an existing dir
addNode(dir, nodes, noteId);
} else {
var newDir = {
id: curDir.id ? curDir.id + '/' + node : node,
name: node,
hidden: true,
children: [],
isTrash: curDir.id ? curDir.id.split('/')[0] === TRASH_FOLDER_ID : false
};
};
// add the folder to flat folder map
notes.flatFolderMap[newDir.id] = newDir;
// add the folder to flat folder map
notes.flatFolderMap[newDir.id] = newDir;
curDir.children.push(newDir);
addNode(newDir, nodes, noteId);
}
curDir.children.push(newDir);
addNode(newDir, nodes, noteId);
}
};
}
};
return notes;
}
return notes;
}
})();

View file

@ -11,104 +11,102 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('NotenameCtrl', NotenameCtrl);
angular.module('zeppelinWebApp').controller('NotenameCtrl', NotenameCtrl);
NotenameCtrl.$inject = [
'$scope',
'noteListDataFactory',
'$routeParams',
'websocketMsgSrv'
];
NotenameCtrl.$inject = [
'$scope',
'noteListDataFactory',
'$routeParams',
'websocketMsgSrv'
];
function NotenameCtrl($scope, noteListDataFactory, $routeParams, websocketMsgSrv) {
var vm = this;
vm.clone = false;
vm.notes = noteListDataFactory;
vm.websocketMsgSrv = websocketMsgSrv;
$scope.note = {};
$scope.interpreterSettings = {};
$scope.note.defaultInterpreter = null;
function NotenameCtrl($scope, noteListDataFactory, $routeParams, websocketMsgSrv) {
var vm = this;
vm.clone = false;
vm.notes = noteListDataFactory;
vm.websocketMsgSrv = websocketMsgSrv;
$scope.note = {};
$scope.interpreterSettings = {};
$scope.note.defaultInterpreter = null;
vm.createNote = function() {
if (!vm.clone) {
var defaultInterpreterId = '';
if ($scope.note.defaultInterpreter !== null) {
defaultInterpreterId = $scope.note.defaultInterpreter.id;
}
vm.websocketMsgSrv.createNotebook($scope.note.notename, defaultInterpreterId);
$scope.note.defaultInterpreter = $scope.interpreterSettings[0];
} else {
var noteId = $routeParams.noteId;
vm.websocketMsgSrv.cloneNote(noteId, $scope.note.notename);
vm.createNote = function() {
if (!vm.clone) {
var defaultInterpreterId = '';
if ($scope.note.defaultInterpreter !== null) {
defaultInterpreterId = $scope.note.defaultInterpreter.id;
}
};
vm.websocketMsgSrv.createNotebook($scope.note.notename, defaultInterpreterId);
$scope.note.defaultInterpreter = $scope.interpreterSettings[0];
} else {
var noteId = $routeParams.noteId;
vm.websocketMsgSrv.cloneNote(noteId, $scope.note.notename);
}
};
vm.handleNameEnter = function() {
angular.element('#noteNameModal').modal('toggle');
vm.createNote();
};
vm.handleNameEnter = function() {
angular.element('#noteNameModal').modal('toggle');
vm.createNote();
};
vm.preVisible = function(clone, sourceNoteName) {
vm.clone = clone;
vm.sourceNoteName = sourceNoteName;
$scope.note.notename = vm.clone ? vm.cloneNoteName() : vm.newNoteName();
$scope.$apply();
};
vm.preVisible = function(clone, sourceNoteName) {
vm.clone = clone;
vm.sourceNoteName = sourceNoteName;
$scope.note.notename = vm.clone ? vm.cloneNoteName() : vm.newNoteName();
$scope.$apply();
};
vm.newNoteName = function() {
var newCount = 1;
angular.forEach(vm.notes.flatList, function(noteName) {
noteName = noteName.name;
if (noteName.match(/^Untitled Note [0-9]*$/)) {
var lastCount = noteName.substr(14) * 1;
if (newCount <= lastCount) {
newCount = lastCount + 1;
}
vm.newNoteName = function() {
var newCount = 1;
angular.forEach(vm.notes.flatList, function(noteName) {
noteName = noteName.name;
if (noteName.match(/^Untitled Note [0-9]*$/)) {
var lastCount = noteName.substr(14) * 1;
if (newCount <= lastCount) {
newCount = lastCount + 1;
}
});
return 'Untitled Note ' + newCount;
};
vm.cloneNoteName = function() {
var copyCount = 1;
var newCloneName = '';
var lastIndex = vm.sourceNoteName.lastIndexOf(' ');
var endsWithNumber = !!vm.sourceNoteName.match('^.+?\\s\\d$');
var noteNamePrefix = endsWithNumber ? vm.sourceNoteName.substr(0, lastIndex) : vm.sourceNoteName;
var regexp = new RegExp('^' + noteNamePrefix + ' .+');
angular.forEach(vm.notes.flatList, function(noteName) {
noteName = noteName.name;
if (noteName.match(regexp)) {
var lastCopyCount = noteName.substr(lastIndex).trim();
newCloneName = noteNamePrefix;
lastCopyCount = parseInt(lastCopyCount);
if (copyCount <= lastCopyCount) {
copyCount = lastCopyCount + 1;
}
}
});
if (!newCloneName) {
newCloneName = vm.sourceNoteName;
}
return newCloneName + ' ' + copyCount;
};
});
return 'Untitled Note ' + newCount;
};
vm.getInterpreterSettings = function() {
vm.websocketMsgSrv.getInterpreterSettings();
};
vm.cloneNoteName = function() {
var copyCount = 1;
var newCloneName = '';
var lastIndex = vm.sourceNoteName.lastIndexOf(' ');
var endsWithNumber = !!vm.sourceNoteName.match('^.+?\\s\\d$');
var noteNamePrefix = endsWithNumber ? vm.sourceNoteName.substr(0, lastIndex) : vm.sourceNoteName;
var regexp = new RegExp('^' + noteNamePrefix + ' .+');
$scope.$on('interpreterSettings', function(event, data) {
$scope.interpreterSettings = data.interpreterSettings;
//initialize default interpreter with Spark interpreter
$scope.note.defaultInterpreter = data.interpreterSettings[0];
angular.forEach(vm.notes.flatList, function(noteName) {
noteName = noteName.name;
if (noteName.match(regexp)) {
var lastCopyCount = noteName.substr(lastIndex).trim();
newCloneName = noteNamePrefix;
lastCopyCount = parseInt(lastCopyCount);
if (copyCount <= lastCopyCount) {
copyCount = lastCopyCount + 1;
}
}
});
}
if (!newCloneName) {
newCloneName = vm.sourceNoteName;
}
return newCloneName + ' ' + copyCount;
};
vm.getInterpreterSettings = function() {
vm.websocketMsgSrv.getInterpreterSettings();
};
$scope.$on('interpreterSettings', function(event, data) {
$scope.interpreterSettings = data.interpreterSettings;
//initialize default interpreter with Spark interpreter
$scope.note.defaultInterpreter = data.interpreterSettings[0];
});
}
})();

View file

@ -11,37 +11,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').directive('modalvisible', modalvisible);
angular.module('zeppelinWebApp').directive('modalvisible', modalvisible);
function modalvisible() {
return {
restrict: 'A',
scope: {
preVisibleCallback: '&previsiblecallback',
postVisibleCallback: '&postvisiblecallback',
targetinput: '@targetinput'
},
link: function(scope, element, attrs) {
// Add some listeners
var previsibleMethod = scope.preVisibleCallback;
var postVisibleMethod = scope.postVisibleCallback;
element.on('show.bs.modal',function(e) {
var relatedTarget = angular.element(e.relatedTarget);
var clone = relatedTarget.data('clone');
var sourceNoteName = relatedTarget.data('source-note-name');
var cloneNote = clone ? true : false;
previsibleMethod()(cloneNote, sourceNoteName);
});
element.on('shown.bs.modal', function(e) {
if (scope.targetinput) {
angular.element(e.target).find('input#' + scope.targetinput).select();
}
postVisibleMethod();
});
}
};
}
function modalvisible() {
return {
restrict: 'A',
scope: {
preVisibleCallback: '&previsiblecallback',
postVisibleCallback: '&postvisiblecallback',
targetinput: '@targetinput'
},
link: function(scope, element, attrs) {
// Add some listeners
var previsibleMethod = scope.preVisibleCallback;
var postVisibleMethod = scope.postVisibleCallback;
element.on('show.bs.modal',function(e) {
var relatedTarget = angular.element(e.relatedTarget);
var clone = relatedTarget.data('clone');
var sourceNoteName = relatedTarget.data('source-note-name');
var cloneNote = clone ? true : false;
previsibleMethod()(cloneNote, sourceNoteName);
});
element.on('shown.bs.modal', function(e) {
if (scope.targetinput) {
angular.element(e.target).find('input#' + scope.targetinput).select();
}
postVisibleMethod();
});
}
};
}
})();

View file

@ -1,140 +1,138 @@
/*
* 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.
*/
(function() {
* 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.
*/
angular.module('zeppelinWebApp').controller('NoteImportCtrl', NoteImportCtrl);
angular.module('zeppelinWebApp').controller('NoteImportCtrl', NoteImportCtrl);
NoteImportCtrl.$inject = ['$scope', '$timeout', 'websocketMsgSrv'];
NoteImportCtrl.$inject = ['$scope', '$timeout', 'websocketMsgSrv'];
function NoteImportCtrl($scope, $timeout, websocketMsgSrv) {
var vm = this;
function NoteImportCtrl($scope, $timeout, websocketMsgSrv) {
var vm = this;
$scope.note = {};
$scope.note.step1 = true;
$scope.note.step2 = false;
$scope.maxLimit = '';
var limit = 0;
websocketMsgSrv.listConfigurations();
$scope.$on('configurationsInfo', function(scope, event) {
limit = event.configurations['zeppelin.websocket.max.text.message.size'];
$scope.maxLimit = Math.round(limit / 1048576);
});
vm.resetFlags = function() {
$scope.note = {};
$scope.note.step1 = true;
$scope.note.step2 = false;
$scope.maxLimit = '';
var limit = 0;
angular.element('#noteImportFile').val('');
};
websocketMsgSrv.listConfigurations();
$scope.$on('configurationsInfo', function(scope, event) {
limit = event.configurations['zeppelin.websocket.max.text.message.size'];
$scope.maxLimit = Math.round(limit / 1048576);
});
$scope.uploadFile = function() {
angular.element('#noteImportFile').click();
};
vm.resetFlags = function() {
$scope.note = {};
$scope.importFile = function(element) {
$scope.note.errorText = '';
$scope.note.importFile = element.files[0];
var file = $scope.note.importFile;
var reader = new FileReader();
if (file.size > limit) {
$scope.note.errorText = 'File size limit Exceeded!';
$scope.$apply();
return;
}
reader.onloadend = function() {
vm.processImportJson(reader.result);
};
if (file) {
reader.readAsText(file);
}
};
$scope.uploadURL = function() {
$scope.note.errorText = '';
$scope.note.step1 = false;
$timeout(function() {
$scope.note.step2 = true;
}, 400);
};
vm.importBack = function() {
$scope.note.errorText = '';
$timeout(function() {
$scope.note.step1 = true;
$scope.note.step2 = false;
angular.element('#noteImportFile').val('');
};
}, 400);
$scope.note.step2 = false;
};
$scope.uploadFile = function() {
angular.element('#noteImportFile').click();
};
vm.importNote = function() {
$scope.note.errorText = '';
if ($scope.note.importUrl) {
jQuery.ajax({
url: $scope.note.importUrl,
type: 'GET',
dataType: 'json',
jsonp: false,
xhrFields: {
withCredentials: false
},
error: function(xhr, ajaxOptions, thrownError) {
$scope.note.errorText = 'Unable to Fetch URL';
$scope.$apply();
}}).done(function(data) {
vm.processImportJson(data);
});
} else {
$scope.note.errorText = 'Enter URL';
$scope.$apply();
}
};
$scope.importFile = function(element) {
$scope.note.errorText = '';
$scope.note.importFile = element.files[0];
var file = $scope.note.importFile;
var reader = new FileReader();
if (file.size > limit) {
$scope.note.errorText = 'File size limit Exceeded!';
vm.processImportJson = function(result) {
if (typeof result !== 'object') {
try {
result = JSON.parse(result);
} catch (e) {
$scope.note.errorText = 'JSON parse exception';
$scope.$apply();
return;
}
reader.onloadend = function() {
vm.processImportJson(reader.result);
};
if (file) {
reader.readAsText(file);
}
};
$scope.uploadURL = function() {
$scope.note.errorText = '';
$scope.note.step1 = false;
$timeout(function() {
$scope.note.step2 = true;
}, 400);
};
vm.importBack = function() {
$scope.note.errorText = '';
$timeout(function() {
$scope.note.step1 = true;
}, 400);
$scope.note.step2 = false;
};
vm.importNote = function() {
$scope.note.errorText = '';
if ($scope.note.importUrl) {
jQuery.ajax({
url: $scope.note.importUrl,
type: 'GET',
dataType: 'json',
jsonp: false,
xhrFields: {
withCredentials: false
},
error: function(xhr, ajaxOptions, thrownError) {
$scope.note.errorText = 'Unable to Fetch URL';
$scope.$apply();
}}).done(function(data) {
vm.processImportJson(data);
});
}
if (result.paragraphs && result.paragraphs.length > 0) {
if (!$scope.note.noteImportName) {
$scope.note.noteImportName = result.name;
} else {
$scope.note.errorText = 'Enter URL';
$scope.$apply();
result.name = $scope.note.noteImportName;
}
};
websocketMsgSrv.importNote(result);
//angular.element('#noteImportModal').modal('hide');
} else {
$scope.note.errorText = 'Invalid JSON';
}
$scope.$apply();
};
vm.processImportJson = function(result) {
if (typeof result !== 'object') {
try {
result = JSON.parse(result);
} catch (e) {
$scope.note.errorText = 'JSON parse exception';
$scope.$apply();
return;
}
/*
** $scope.$on functions below
*/
}
if (result.paragraphs && result.paragraphs.length > 0) {
if (!$scope.note.noteImportName) {
$scope.note.noteImportName = result.name;
} else {
result.name = $scope.note.noteImportName;
}
websocketMsgSrv.importNote(result);
//angular.element('#noteImportModal').modal('hide');
} else {
$scope.note.errorText = 'Invalid JSON';
}
$scope.$apply();
};
$scope.$on('setNoteMenu', function(event, notes) {
vm.resetFlags();
angular.element('#noteImportModal').modal('hide');
});
}
/*
** $scope.$on functions below
*/
$scope.$on('setNoteMenu', function(event, notes) {
vm.resetFlags();
angular.element('#noteImportModal').modal('hide');
});
}
})();

View file

@ -11,31 +11,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').service('noteVarShareService', noteVarShareService);
angular.module('zeppelinWebApp').service('noteVarShareService', noteVarShareService);
noteVarShareService.$inject = [];
noteVarShareService.$inject = [];
function noteVarShareService() {
var store = {};
function noteVarShareService() {
var store = {};
this.clear = function() {
store = {};
};
this.put = function(key, value) {
store[key] = value;
};
this.get = function(key) {
return store[key];
};
this.del = function(key) {
var v = store[key];
delete store[key];
return v;
};
this.clear = function() {
store = {};
};
})();
this.put = function(key, value) {
store[key] = value;
};
this.get = function(key) {
return store[key];
};
this.del = function(key) {
var v = store[key];
delete store[key];
return v;
};
}

View file

@ -11,17 +11,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').directive('popoverHtmlUnsafePopup', popoverHtmlUnsafePopup);
angular.module('zeppelinWebApp').directive('popoverHtmlUnsafePopup', popoverHtmlUnsafePopup);
function popoverHtmlUnsafePopup() {
return {
restrict: 'EA',
replace: true,
scope: {title: '@', content: '@', placement: '@', animation: '&', isOpen: '&'},
templateUrl: 'components/popover-html-unsafe/popover-html-unsafe-popup.html'
};
}
function popoverHtmlUnsafePopup() {
return {
restrict: 'EA',
replace: true,
scope: {title: '@', content: '@', placement: '@', animation: '&', isOpen: '&'},
templateUrl: 'components/popover-html-unsafe/popover-html-unsafe-popup.html'
};
}
})();

View file

@ -11,14 +11,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').directive('popoverHtmlUnsafe', popoverHtmlUnsafe);
angular.module('zeppelinWebApp').directive('popoverHtmlUnsafe', popoverHtmlUnsafe);
popoverHtmlUnsafe.$inject = ['$tooltip'];
popoverHtmlUnsafe.$inject = ['$tooltip'];
function popoverHtmlUnsafe($tooltip) {
return $tooltip('popoverHtmlUnsafe', 'popover', 'click');
}
function popoverHtmlUnsafe($tooltip) {
return $tooltip('popoverHtmlUnsafe', 'popover', 'click');
}
})();

View file

@ -11,39 +11,37 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').controller('RenameCtrl', RenameCtrl);
angular.module('zeppelinWebApp').controller('RenameCtrl', RenameCtrl);
RenameCtrl.$inject = ['$scope'];
RenameCtrl.$inject = ['$scope'];
function RenameCtrl($scope) {
var self = this;
function RenameCtrl($scope) {
var self = this;
$scope.params = {newName: ''};
$scope.isValid = true;
$scope.params = {newName: ''};
$scope.isValid = true;
$scope.rename = function() {
angular.element('#renameModal').modal('hide');
self.callback($scope.params.newName);
$scope.rename = function() {
angular.element('#renameModal').modal('hide');
self.callback($scope.params.newName);
};
$scope.$on('openRenameModal', function(event, options) {
self.validator = options.validator || defaultValidator;
self.callback = options.callback || function() {};
$scope.title = options.title || 'Rename';
$scope.params.newName = options.oldName || '';
$scope.validate = function() {
$scope.isValid = self.validator($scope.params.newName);
};
$scope.$on('openRenameModal', function(event, options) {
self.validator = options.validator || defaultValidator;
self.callback = options.callback || function() {};
angular.element('#renameModal').modal('show');
});
$scope.title = options.title || 'Rename';
$scope.params.newName = options.oldName || '';
$scope.validate = function() {
$scope.isValid = self.validator($scope.params.newName);
};
angular.element('#renameModal').modal('show');
});
function defaultValidator(str) {
return !!str.trim();
}
function defaultValidator(str) {
return !!str.trim();
}
}
})();

View file

@ -11,24 +11,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').service('renameSrv', renameSrv);
angular.module('zeppelinWebApp').service('renameSrv', renameSrv);
renameSrv.$inject = ['$rootScope'];
renameSrv.$inject = ['$rootScope'];
function renameSrv($rootScope) {
var self = this;
function renameSrv($rootScope) {
var self = this;
/**
* <options schema>
* title: string - Modal title
* oldName: string - name to initialize input
* callback: (newName: string)=>void - callback onButtonClick
* validator: (str: string)=>boolean - input validator
*/
self.openRenameModal = function(options) {
$rootScope.$broadcast('openRenameModal', options);
};
}
})();
/**
* <options schema>
* title: string - Modal title
* oldName: string - name to initialize input
* callback: (newName: string)=>void - callback onButtonClick
* validator: (str: string)=>boolean - input validator
*/
self.openRenameModal = function(options) {
$rootScope.$broadcast('openRenameModal', options);
};
}

View file

@ -11,62 +11,60 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').directive('resizable', resizable);
angular.module('zeppelinWebApp').directive('resizable', resizable);
function resizable() {
var resizableConfig = {
autoHide: true,
handles: 'se',
helper: 'resizable-helper',
stop: function() {
angular.element(this).css({'width': '100%', 'height': '100%'});
}
};
function resizable() {
var resizableConfig = {
autoHide: true,
handles: 'se',
helper: 'resizable-helper',
stop: function() {
angular.element(this).css({'width': '100%', 'height': '100%'});
}
};
return {
restrict: 'A',
scope: {
callback: '&onResize'
},
link: function postLink(scope, elem, attrs) {
attrs.$observe('resize', function(resize) {
var resetResize = function(elem, resize) {
var colStep = window.innerWidth / 12;
elem.off('resizestop');
var conf = angular.copy(resizableConfig);
if (resize.graphType === 'TABLE' || resize.graphType === 'TEXT') {
conf.grid = [colStep, 10];
conf.minHeight = 100;
} else {
conf.grid = [colStep, 10000];
conf.minHeight = 0;
}
conf.maxWidth = window.innerWidth;
elem.resizable(conf);
elem.on('resizestop', function() {
if (scope.callback) {
var height = elem.height();
if (height < 50) {
height = 300;
}
scope.callback({width: Math.ceil(elem.width() / colStep), height: height});
}
});
};
resize = JSON.parse(resize);
if (resize.allowresize === 'true') {
resetResize(elem, resize);
angular.element(window).resize(function() {
resetResize(elem, resize);
});
return {
restrict: 'A',
scope: {
callback: '&onResize'
},
link: function postLink(scope, elem, attrs) {
attrs.$observe('resize', function(resize) {
var resetResize = function(elem, resize) {
var colStep = window.innerWidth / 12;
elem.off('resizestop');
var conf = angular.copy(resizableConfig);
if (resize.graphType === 'TABLE' || resize.graphType === 'TEXT') {
conf.grid = [colStep, 10];
conf.minHeight = 100;
} else {
conf.grid = [colStep, 10000];
conf.minHeight = 0;
}
});
}
};
}
conf.maxWidth = window.innerWidth;
elem.resizable(conf);
elem.on('resizestop', function() {
if (scope.callback) {
var height = elem.height();
if (height < 50) {
height = 300;
}
scope.callback({width: Math.ceil(elem.width() / colStep), height: height});
}
});
};
resize = JSON.parse(resize);
if (resize.allowresize === 'true') {
resetResize(elem, resize);
angular.element(window).resize(function() {
resetResize(elem, resize);
});
}
});
}
};
}
})();

View file

@ -11,44 +11,42 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').service('saveAsService', saveAsService);
angular.module('zeppelinWebApp').service('saveAsService', saveAsService);
saveAsService.$inject = ['browserDetectService'];
saveAsService.$inject = ['browserDetectService'];
function saveAsService(browserDetectService) {
this.saveAs = function(content, filename, extension) {
var BOM = '\uFEFF';
if (browserDetectService.detectIE()) {
angular.element('body').append('<iframe id="SaveAsId" style="display: none"></iframe>');
var frameSaveAs = angular.element('body > iframe#SaveAsId')[0].contentWindow;
content = BOM + content;
frameSaveAs.document.open('text/json', 'replace');
frameSaveAs.document.write(content);
frameSaveAs.document.close();
frameSaveAs.focus();
var t1 = Date.now();
frameSaveAs.document.execCommand('SaveAs', false, filename + '.' + extension);
var t2 = Date.now();
function saveAsService(browserDetectService) {
this.saveAs = function(content, filename, extension) {
var BOM = '\uFEFF';
if (browserDetectService.detectIE()) {
angular.element('body').append('<iframe id="SaveAsId" style="display: none"></iframe>');
var frameSaveAs = angular.element('body > iframe#SaveAsId')[0].contentWindow;
content = BOM + content;
frameSaveAs.document.open('text/json', 'replace');
frameSaveAs.document.write(content);
frameSaveAs.document.close();
frameSaveAs.focus();
var t1 = Date.now();
frameSaveAs.document.execCommand('SaveAs', false, filename + '.' + extension);
var t2 = Date.now();
//This means, this version of IE dosen't support auto download of a file with extension provided in param
//falling back to ".txt"
if (t1 === t2) {
frameSaveAs.document.execCommand('SaveAs', true, filename + '.txt');
}
angular.element('body > iframe#SaveAsId').remove();
} else {
content = 'data:image/svg;charset=utf-8,' + BOM + encodeURIComponent(content);
angular.element('body').append('<a id="SaveAsId"></a>');
var saveAsElement = angular.element('body > a#SaveAsId');
saveAsElement.attr('href', content);
saveAsElement.attr('download', filename + '.' + extension);
saveAsElement.attr('target', '_blank');
saveAsElement[0].click();
saveAsElement.remove();
//This means, this version of IE dosen't support auto download of a file with extension provided in param
//falling back to ".txt"
if (t1 === t2) {
frameSaveAs.document.execCommand('SaveAs', true, filename + '.txt');
}
};
}
angular.element('body > iframe#SaveAsId').remove();
} else {
content = 'data:image/svg;charset=utf-8,' + BOM + encodeURIComponent(content);
angular.element('body').append('<a id="SaveAsId"></a>');
var saveAsElement = angular.element('body > a#SaveAsId');
saveAsElement.attr('href', content);
saveAsElement.attr('download', filename + '.' + extension);
saveAsElement.attr('target', '_blank');
saveAsElement[0].click();
saveAsElement.remove();
}
};
}
})();

View file

@ -11,26 +11,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').service('searchService', searchService);
angular.module('zeppelinWebApp').service('searchService', searchService);
searchService.$inject = ['$resource', 'baseUrlSrv'];
searchService.$inject = ['$resource', 'baseUrlSrv'];
function searchService($resource, baseUrlSrv) {
this.search = function(term) {
this.searchTerm = term.q;
console.log('Searching for: %o', term.q);
if (!term.q) { //TODO(bzz): empty string check
return;
}
var encQuery = window.encodeURIComponent(term.q);
return $resource(baseUrlSrv.getRestApiBase() + '/notebook/search?q=' + encQuery, {}, {
query: {method: 'GET'}
});
};
function searchService($resource, baseUrlSrv) {
this.search = function(term) {
this.searchTerm = term.q;
console.log('Searching for: %o', term.q);
if (!term.q) { //TODO(bzz): empty string check
return;
}
var encQuery = window.encodeURIComponent(term.q);
return $resource(baseUrlSrv.getRestApiBase() + '/notebook/search?q=' + encQuery, {}, {
query: {method: 'GET'}
});
};
this.searchTerm = '';
}
this.searchTerm = '';
}
})();

View file

@ -11,176 +11,174 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').factory('websocketEvents', websocketEvents);
angular.module('zeppelinWebApp').factory('websocketEvents', websocketEvents);
websocketEvents.$inject = ['$rootScope', '$websocket', '$location', 'baseUrlSrv'];
websocketEvents.$inject = ['$rootScope', '$websocket', '$location', 'baseUrlSrv'];
function websocketEvents($rootScope, $websocket, $location, baseUrlSrv) {
var websocketCalls = {};
var pingIntervalId;
function websocketEvents($rootScope, $websocket, $location, baseUrlSrv) {
var websocketCalls = {};
var pingIntervalId;
websocketCalls.ws = $websocket(baseUrlSrv.getWebsocketUrl());
websocketCalls.ws.reconnectIfNotNormalClose = true;
websocketCalls.ws = $websocket(baseUrlSrv.getWebsocketUrl());
websocketCalls.ws.reconnectIfNotNormalClose = true;
websocketCalls.ws.onOpen(function() {
console.log('Websocket created');
$rootScope.$broadcast('setConnectedStatus', true);
pingIntervalId = setInterval(function() {
websocketCalls.sendNewEvent({op: 'PING'});
}, 10000);
});
websocketCalls.ws.onOpen(function() {
console.log('Websocket created');
$rootScope.$broadcast('setConnectedStatus', true);
pingIntervalId = setInterval(function() {
websocketCalls.sendNewEvent({op: 'PING'});
}, 10000);
});
websocketCalls.sendNewEvent = function(data) {
if ($rootScope.ticket !== undefined) {
data.principal = $rootScope.ticket.principal;
data.ticket = $rootScope.ticket.ticket;
data.roles = $rootScope.ticket.roles;
websocketCalls.sendNewEvent = function(data) {
if ($rootScope.ticket !== undefined) {
data.principal = $rootScope.ticket.principal;
data.ticket = $rootScope.ticket.ticket;
data.roles = $rootScope.ticket.roles;
} else {
data.principal = '';
data.ticket = '';
data.roles = '';
}
console.log('Send >> %o, %o, %o, %o, %o', data.op, data.principal, data.ticket, data.roles, data);
websocketCalls.ws.send(JSON.stringify(data));
};
websocketCalls.isConnected = function() {
return (websocketCalls.ws.socket.readyState === 1);
};
websocketCalls.ws.onMessage(function(event) {
var payload;
if (event.data) {
payload = angular.fromJson(event.data);
}
console.log('Receive << %o, %o', payload.op, payload);
var op = payload.op;
var data = payload.data;
if (op === 'NOTE') {
$rootScope.$broadcast('setNoteContent', data.note);
} else if (op === 'NEW_NOTE') {
$location.path('/notebook/' + data.note.id);
} else if (op === 'NOTES_INFO') {
$rootScope.$broadcast('setNoteMenu', data.notes);
} else if (op === 'LIST_NOTE_JOBS') {
$rootScope.$broadcast('setNoteJobs', data.noteJobs);
} else if (op === 'LIST_UPDATE_NOTE_JOBS') {
$rootScope.$broadcast('setUpdateNoteJobs', data.noteRunningJobs);
} else if (op === 'AUTH_INFO') {
var btn = [];
if ($rootScope.ticket.roles === '[]') {
btn = [{
label: 'Close',
action: function(dialog) {
dialog.close();
}
}];
} else {
data.principal = '';
data.ticket = '';
data.roles = '';
btn = [{
label: 'Login',
action: function(dialog) {
dialog.close();
angular.element('#loginModal').modal({
show: 'true'
});
}
}, {
label: 'Cancel',
action: function(dialog) {
dialog.close();
$location.path('/');
}
}];
}
console.log('Send >> %o, %o, %o, %o, %o', data.op, data.principal, data.ticket, data.roles, data);
websocketCalls.ws.send(JSON.stringify(data));
};
websocketCalls.isConnected = function() {
return (websocketCalls.ws.socket.readyState === 1);
};
BootstrapDialog.show({
closable: false,
closeByBackdrop: false,
closeByKeyboard: false,
title: 'Insufficient privileges',
message: data.info.toString(),
buttons: btn
});
websocketCalls.ws.onMessage(function(event) {
var payload;
if (event.data) {
payload = angular.fromJson(event.data);
}
console.log('Receive << %o, %o', payload.op, payload);
var op = payload.op;
var data = payload.data;
if (op === 'NOTE') {
$rootScope.$broadcast('setNoteContent', data.note);
} else if (op === 'NEW_NOTE') {
$location.path('/notebook/' + data.note.id);
} else if (op === 'NOTES_INFO') {
$rootScope.$broadcast('setNoteMenu', data.notes);
} else if (op === 'LIST_NOTE_JOBS') {
$rootScope.$broadcast('setNoteJobs', data.noteJobs);
} else if (op === 'LIST_UPDATE_NOTE_JOBS') {
$rootScope.$broadcast('setUpdateNoteJobs', data.noteRunningJobs);
} else if (op === 'AUTH_INFO') {
var btn = [];
if ($rootScope.ticket.roles === '[]') {
btn = [{
label: 'Close',
action: function(dialog) {
dialog.close();
}
}];
} else {
btn = [{
label: 'Login',
action: function(dialog) {
dialog.close();
angular.element('#loginModal').modal({
show: 'true'
});
}
}, {
label: 'Cancel',
action: function(dialog) {
dialog.close();
$location.path('/');
}
}];
}
} else if (op === 'PARAGRAPH') {
$rootScope.$broadcast('updateParagraph', data);
} else if (op === 'PARAGRAPH_APPEND_OUTPUT') {
$rootScope.$broadcast('appendParagraphOutput', data);
} else if (op === 'PARAGRAPH_UPDATE_OUTPUT') {
$rootScope.$broadcast('updateParagraphOutput', data);
} else if (op === 'PROGRESS') {
$rootScope.$broadcast('updateProgress', data);
} else if (op === 'COMPLETION_LIST') {
$rootScope.$broadcast('completionList', data);
} else if (op === 'EDITOR_SETTING') {
$rootScope.$broadcast('editorSetting', data);
} else if (op === 'ANGULAR_OBJECT_UPDATE') {
$rootScope.$broadcast('angularObjectUpdate', data);
} else if (op === 'ANGULAR_OBJECT_REMOVE') {
$rootScope.$broadcast('angularObjectRemove', data);
} else if (op === 'APP_APPEND_OUTPUT') {
$rootScope.$broadcast('appendAppOutput', data);
} else if (op === 'APP_UPDATE_OUTPUT') {
$rootScope.$broadcast('updateAppOutput', data);
} else if (op === 'APP_LOAD') {
$rootScope.$broadcast('appLoad', data);
} else if (op === 'APP_STATUS_CHANGE') {
$rootScope.$broadcast('appStatusChange', data);
} else if (op === 'LIST_REVISION_HISTORY') {
$rootScope.$broadcast('listRevisionHistory', data);
} else if (op === 'NOTE_REVISION') {
$rootScope.$broadcast('noteRevision', data);
} else if (op === 'INTERPRETER_BINDINGS') {
$rootScope.$broadcast('interpreterBindings', data);
} else if (op === 'ERROR_INFO') {
BootstrapDialog.show({
closable: false,
closeByBackdrop: false,
closeByKeyboard: false,
title: 'Details',
message: data.info.toString(),
buttons: [{
// close all the dialogs when there are error on running all paragraphs
label: 'Close',
action: function() {
BootstrapDialog.closeAll();
}
}]
});
} else if (op === 'CONFIGURATIONS_INFO') {
$rootScope.$broadcast('configurationsInfo', data);
} else if (op === 'INTERPRETER_SETTINGS') {
$rootScope.$broadcast('interpreterSettings', data);
} else if (op === 'PARAGRAPH_ADDED') {
$rootScope.$broadcast('addParagraph', data.paragraph, data.index);
} else if (op === 'PARAGRAPH_REMOVED') {
$rootScope.$broadcast('removeParagraph', data.id);
} else if (op === 'PARAGRAPH_MOVED') {
$rootScope.$broadcast('moveParagraph', data.id, data.index);
} else if (op === 'NOTE_UPDATED') {
$rootScope.$broadcast('updateNote', data.name, data.config, data.info);
} else if (op === 'SET_NOTE_REVISION') {
$rootScope.$broadcast('setNoteRevisionResult', data);
}
});
BootstrapDialog.show({
closable: false,
closeByBackdrop: false,
closeByKeyboard: false,
title: 'Insufficient privileges',
message: data.info.toString(),
buttons: btn
});
websocketCalls.ws.onError(function(event) {
console.log('error message: ', event);
$rootScope.$broadcast('setConnectedStatus', false);
});
} else if (op === 'PARAGRAPH') {
$rootScope.$broadcast('updateParagraph', data);
} else if (op === 'PARAGRAPH_APPEND_OUTPUT') {
$rootScope.$broadcast('appendParagraphOutput', data);
} else if (op === 'PARAGRAPH_UPDATE_OUTPUT') {
$rootScope.$broadcast('updateParagraphOutput', data);
} else if (op === 'PROGRESS') {
$rootScope.$broadcast('updateProgress', data);
} else if (op === 'COMPLETION_LIST') {
$rootScope.$broadcast('completionList', data);
} else if (op === 'EDITOR_SETTING') {
$rootScope.$broadcast('editorSetting', data);
} else if (op === 'ANGULAR_OBJECT_UPDATE') {
$rootScope.$broadcast('angularObjectUpdate', data);
} else if (op === 'ANGULAR_OBJECT_REMOVE') {
$rootScope.$broadcast('angularObjectRemove', data);
} else if (op === 'APP_APPEND_OUTPUT') {
$rootScope.$broadcast('appendAppOutput', data);
} else if (op === 'APP_UPDATE_OUTPUT') {
$rootScope.$broadcast('updateAppOutput', data);
} else if (op === 'APP_LOAD') {
$rootScope.$broadcast('appLoad', data);
} else if (op === 'APP_STATUS_CHANGE') {
$rootScope.$broadcast('appStatusChange', data);
} else if (op === 'LIST_REVISION_HISTORY') {
$rootScope.$broadcast('listRevisionHistory', data);
} else if (op === 'NOTE_REVISION') {
$rootScope.$broadcast('noteRevision', data);
} else if (op === 'INTERPRETER_BINDINGS') {
$rootScope.$broadcast('interpreterBindings', data);
} else if (op === 'ERROR_INFO') {
BootstrapDialog.show({
closable: false,
closeByBackdrop: false,
closeByKeyboard: false,
title: 'Details',
message: data.info.toString(),
buttons: [{
// close all the dialogs when there are error on running all paragraphs
label: 'Close',
action: function() {
BootstrapDialog.closeAll();
}
}]
});
} else if (op === 'CONFIGURATIONS_INFO') {
$rootScope.$broadcast('configurationsInfo', data);
} else if (op === 'INTERPRETER_SETTINGS') {
$rootScope.$broadcast('interpreterSettings', data);
} else if (op === 'PARAGRAPH_ADDED') {
$rootScope.$broadcast('addParagraph', data.paragraph, data.index);
} else if (op === 'PARAGRAPH_REMOVED') {
$rootScope.$broadcast('removeParagraph', data.id);
} else if (op === 'PARAGRAPH_MOVED') {
$rootScope.$broadcast('moveParagraph', data.id, data.index);
} else if (op === 'NOTE_UPDATED') {
$rootScope.$broadcast('updateNote', data.name, data.config, data.info);
} else if (op === 'SET_NOTE_REVISION') {
$rootScope.$broadcast('setNoteRevisionResult', data);
}
});
websocketCalls.ws.onClose(function(event) {
console.log('close message: ', event);
if (pingIntervalId !== undefined) {
clearInterval(pingIntervalId);
pingIntervalId = undefined;
}
$rootScope.$broadcast('setConnectedStatus', false);
});
websocketCalls.ws.onError(function(event) {
console.log('error message: ', event);
$rootScope.$broadcast('setConnectedStatus', false);
});
return websocketCalls;
}
websocketCalls.ws.onClose(function(event) {
console.log('close message: ', event);
if (pingIntervalId !== undefined) {
clearInterval(pingIntervalId);
pingIntervalId = undefined;
}
$rootScope.$broadcast('setConnectedStatus', false);
});
return websocketCalls;
}
})();

View file

@ -11,308 +11,306 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
angular.module('zeppelinWebApp').service('websocketMsgSrv', websocketMsgSrv);
angular.module('zeppelinWebApp').service('websocketMsgSrv', websocketMsgSrv);
websocketMsgSrv.$inject = ['$rootScope', 'websocketEvents'];
websocketMsgSrv.$inject = ['$rootScope', 'websocketEvents'];
function websocketMsgSrv($rootScope, websocketEvents) {
return {
function websocketMsgSrv($rootScope, websocketEvents) {
return {
getHomeNote: function() {
websocketEvents.sendNewEvent({op: 'GET_HOME_NOTE'});
},
getHomeNote: function() {
websocketEvents.sendNewEvent({op: 'GET_HOME_NOTE'});
},
createNotebook: function(noteName, defaultInterpreterId) {
websocketEvents.sendNewEvent({
op: 'NEW_NOTE',
data: {
name: noteName,
defaultInterpreterId: defaultInterpreterId
}
});
},
createNotebook: function(noteName, defaultInterpreterId) {
websocketEvents.sendNewEvent({
op: 'NEW_NOTE',
data: {
name: noteName,
defaultInterpreterId: defaultInterpreterId
}
});
},
moveNoteToTrash: function(noteId) {
websocketEvents.sendNewEvent({op: 'MOVE_NOTE_TO_TRASH', data: {id: noteId}});
},
moveNoteToTrash: function(noteId) {
websocketEvents.sendNewEvent({op: 'MOVE_NOTE_TO_TRASH', data: {id: noteId}});
},
moveFolderToTrash: function(folderId) {
websocketEvents.sendNewEvent({op: 'MOVE_FOLDER_TO_TRASH', data: {id: folderId}});
},
moveFolderToTrash: function(folderId) {
websocketEvents.sendNewEvent({op: 'MOVE_FOLDER_TO_TRASH', data: {id: folderId}});
},
restoreNote: function(noteId) {
websocketEvents.sendNewEvent({op: 'RESTORE_NOTE', data: {id: noteId}});
},
restoreNote: function(noteId) {
websocketEvents.sendNewEvent({op: 'RESTORE_NOTE', data: {id: noteId}});
},
restoreFolder: function(folderId) {
websocketEvents.sendNewEvent({op: 'RESTORE_FOLDER', data: {id: folderId}});
},
restoreFolder: function(folderId) {
websocketEvents.sendNewEvent({op: 'RESTORE_FOLDER', data: {id: folderId}});
},
restoreAll: function() {
websocketEvents.sendNewEvent({op: 'RESTORE_ALL'});
},
restoreAll: function() {
websocketEvents.sendNewEvent({op: 'RESTORE_ALL'});
},
deleteNote: function(noteId) {
websocketEvents.sendNewEvent({op: 'DEL_NOTE', data: {id: noteId}});
},
deleteNote: function(noteId) {
websocketEvents.sendNewEvent({op: 'DEL_NOTE', data: {id: noteId}});
},
removeFolder: function(folderId) {
websocketEvents.sendNewEvent({op: 'REMOVE_FOLDER', data: {id: folderId}});
},
removeFolder: function(folderId) {
websocketEvents.sendNewEvent({op: 'REMOVE_FOLDER', data: {id: folderId}});
},
emptyTrash: function() {
websocketEvents.sendNewEvent({op: 'EMPTY_TRASH'});
},
emptyTrash: function() {
websocketEvents.sendNewEvent({op: 'EMPTY_TRASH'});
},
cloneNote: function(noteIdToClone, newNoteName) {
websocketEvents.sendNewEvent({op: 'CLONE_NOTE', data: {id: noteIdToClone, name: newNoteName}});
},
cloneNote: function(noteIdToClone, newNoteName) {
websocketEvents.sendNewEvent({op: 'CLONE_NOTE', data: {id: noteIdToClone, name: newNoteName}});
},
getNoteList: function() {
websocketEvents.sendNewEvent({op: 'LIST_NOTES'});
},
getNoteList: function() {
websocketEvents.sendNewEvent({op: 'LIST_NOTES'});
},
reloadAllNotesFromRepo: function() {
websocketEvents.sendNewEvent({op: 'RELOAD_NOTES_FROM_REPO'});
},
reloadAllNotesFromRepo: function() {
websocketEvents.sendNewEvent({op: 'RELOAD_NOTES_FROM_REPO'});
},
getNote: function(noteId) {
websocketEvents.sendNewEvent({op: 'GET_NOTE', data: {id: noteId}});
},
getNote: function(noteId) {
websocketEvents.sendNewEvent({op: 'GET_NOTE', data: {id: noteId}});
},
updateNote: function(noteId, noteName, noteConfig) {
websocketEvents.sendNewEvent({op: 'NOTE_UPDATE', data: {id: noteId, name: noteName, config: noteConfig}});
},
updateNote: function(noteId, noteName, noteConfig) {
websocketEvents.sendNewEvent({op: 'NOTE_UPDATE', data: {id: noteId, name: noteName, config: noteConfig}});
},
updatePersonalizedMode: function(noteId, modeValue) {
websocketEvents.sendNewEvent({op: 'UPDATE_PERSONALIZED_MODE', data: {id: noteId, personalized: modeValue}});
},
updatePersonalizedMode: function(noteId, modeValue) {
websocketEvents.sendNewEvent({op: 'UPDATE_PERSONALIZED_MODE', data: {id: noteId, personalized: modeValue}});
},
renameNote: function(noteId, noteName) {
websocketEvents.sendNewEvent({op: 'NOTE_RENAME', data: {id: noteId, name: noteName}});
},
renameNote: function(noteId, noteName) {
websocketEvents.sendNewEvent({op: 'NOTE_RENAME', data: {id: noteId, name: noteName}});
},
renameFolder: function(folderId, folderName) {
websocketEvents.sendNewEvent({op: 'FOLDER_RENAME', data: {id: folderId, name: folderName}});
},
renameFolder: function(folderId, folderName) {
websocketEvents.sendNewEvent({op: 'FOLDER_RENAME', data: {id: folderId, name: folderName}});
},
moveParagraph: function(paragraphId, newIndex) {
websocketEvents.sendNewEvent({op: 'MOVE_PARAGRAPH', data: {id: paragraphId, index: newIndex}});
},
moveParagraph: function(paragraphId, newIndex) {
websocketEvents.sendNewEvent({op: 'MOVE_PARAGRAPH', data: {id: paragraphId, index: newIndex}});
},
insertParagraph: function(newIndex) {
websocketEvents.sendNewEvent({op: 'INSERT_PARAGRAPH', data: {index: newIndex}});
},
insertParagraph: function(newIndex) {
websocketEvents.sendNewEvent({op: 'INSERT_PARAGRAPH', data: {index: newIndex}});
},
copyParagraph: function(newIndex, paragraphTitle, paragraphData,
paragraphConfig, paragraphParams) {
websocketEvents.sendNewEvent({
op: 'COPY_PARAGRAPH',
data: {
index: newIndex,
title: paragraphTitle,
paragraph: paragraphData,
config: paragraphConfig,
params: paragraphParams
}
});
},
copyParagraph: function(newIndex, paragraphTitle, paragraphData,
paragraphConfig, paragraphParams) {
websocketEvents.sendNewEvent({
op: 'COPY_PARAGRAPH',
data: {
index: newIndex,
title: paragraphTitle,
paragraph: paragraphData,
config: paragraphConfig,
params: paragraphParams
}
});
},
updateAngularObject: function(noteId, paragraphId, name, value, interpreterGroupId) {
websocketEvents.sendNewEvent({
op: 'ANGULAR_OBJECT_UPDATED',
data: {
noteId: noteId,
paragraphId: paragraphId,
name: name,
value: value,
interpreterGroupId: interpreterGroupId
}
});
},
updateAngularObject: function(noteId, paragraphId, name, value, interpreterGroupId) {
websocketEvents.sendNewEvent({
op: 'ANGULAR_OBJECT_UPDATED',
data: {
noteId: noteId,
paragraphId: paragraphId,
name: name,
value: value,
interpreterGroupId: interpreterGroupId
}
});
},
clientBindAngularObject: function(noteId, name, value, paragraphId) {
websocketEvents.sendNewEvent({
op: 'ANGULAR_OBJECT_CLIENT_BIND',
data: {
noteId: noteId,
name: name,
value: value,
paragraphId: paragraphId
}
});
},
clientBindAngularObject: function(noteId, name, value, paragraphId) {
websocketEvents.sendNewEvent({
op: 'ANGULAR_OBJECT_CLIENT_BIND',
data: {
noteId: noteId,
name: name,
value: value,
paragraphId: paragraphId
}
});
},
clientUnbindAngularObject: function(noteId, name, paragraphId) {
websocketEvents.sendNewEvent({
op: 'ANGULAR_OBJECT_CLIENT_UNBIND',
data: {
noteId: noteId,
name: name,
paragraphId: paragraphId
}
});
},
clientUnbindAngularObject: function(noteId, name, paragraphId) {
websocketEvents.sendNewEvent({
op: 'ANGULAR_OBJECT_CLIENT_UNBIND',
data: {
noteId: noteId,
name: name,
paragraphId: paragraphId
}
});
},
cancelParagraphRun: function(paragraphId) {
websocketEvents.sendNewEvent({op: 'CANCEL_PARAGRAPH', data: {id: paragraphId}});
},
cancelParagraphRun: function(paragraphId) {
websocketEvents.sendNewEvent({op: 'CANCEL_PARAGRAPH', data: {id: paragraphId}});
},
runParagraph: function(paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
websocketEvents.sendNewEvent({
op: 'RUN_PARAGRAPH',
data: {
id: paragraphId,
title: paragraphTitle,
paragraph: paragraphData,
config: paragraphConfig,
params: paragraphParams
}
});
},
runParagraph: function(paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
websocketEvents.sendNewEvent({
op: 'RUN_PARAGRAPH',
data: {
id: paragraphId,
title: paragraphTitle,
paragraph: paragraphData,
config: paragraphConfig,
params: paragraphParams
}
});
},
runAllParagraphs: function(noteId, paragraphs) {
websocketEvents.sendNewEvent({
op: 'RUN_ALL_PARAGRAPHS',
data: {
noteId: noteId,
paragraphs: JSON.stringify(paragraphs)
}
});
},
runAllParagraphs: function(noteId, paragraphs) {
websocketEvents.sendNewEvent({
op: 'RUN_ALL_PARAGRAPHS',
data: {
noteId: noteId,
paragraphs: JSON.stringify(paragraphs)
}
});
},
removeParagraph: function(paragraphId) {
websocketEvents.sendNewEvent({op: 'PARAGRAPH_REMOVE', data: {id: paragraphId}});
},
removeParagraph: function(paragraphId) {
websocketEvents.sendNewEvent({op: 'PARAGRAPH_REMOVE', data: {id: paragraphId}});
},
clearParagraphOutput: function(paragraphId) {
websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_OUTPUT', data: {id: paragraphId}});
},
clearParagraphOutput: function(paragraphId) {
websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_OUTPUT', data: {id: paragraphId}});
},
clearAllParagraphOutput: function(noteId) {
websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_ALL_OUTPUT', data: {id: noteId}});
},
clearAllParagraphOutput: function(noteId) {
websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_ALL_OUTPUT', data: {id: noteId}});
},
completion: function(paragraphId, buf, cursor) {
websocketEvents.sendNewEvent({
op: 'COMPLETION',
data: {
id: paragraphId,
buf: buf,
cursor: cursor
}
});
},
completion: function(paragraphId, buf, cursor) {
websocketEvents.sendNewEvent({
op: 'COMPLETION',
data: {
id: paragraphId,
buf: buf,
cursor: cursor
}
});
},
commitParagraph: function(paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
websocketEvents.sendNewEvent({
op: 'COMMIT_PARAGRAPH',
data: {
id: paragraphId,
title: paragraphTitle,
paragraph: paragraphData,
config: paragraphConfig,
params: paragraphParams
}
});
},
commitParagraph: function(paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
websocketEvents.sendNewEvent({
op: 'COMMIT_PARAGRAPH',
data: {
id: paragraphId,
title: paragraphTitle,
paragraph: paragraphData,
config: paragraphConfig,
params: paragraphParams
}
});
},
importNote: function(note) {
websocketEvents.sendNewEvent({
op: 'IMPORT_NOTE',
data: {
note: note
}
});
},
importNote: function(note) {
websocketEvents.sendNewEvent({
op: 'IMPORT_NOTE',
data: {
note: note
}
});
},
checkpointNote: function(noteId, commitMessage) {
websocketEvents.sendNewEvent({
op: 'CHECKPOINT_NOTE',
data: {
noteId: noteId,
commitMessage: commitMessage
}
});
},
checkpointNote: function(noteId, commitMessage) {
websocketEvents.sendNewEvent({
op: 'CHECKPOINT_NOTE',
data: {
noteId: noteId,
commitMessage: commitMessage
}
});
},
setNoteRevision: function(noteId, revisionId) {
websocketEvents.sendNewEvent({
op: 'SET_NOTE_REVISION',
data: {
noteId: noteId,
revisionId: revisionId
}
});
},
setNoteRevision: function(noteId, revisionId) {
websocketEvents.sendNewEvent({
op: 'SET_NOTE_REVISION',
data: {
noteId: noteId,
revisionId: revisionId
}
});
},
listRevisionHistory: function(noteId) {
websocketEvents.sendNewEvent({
op: 'LIST_REVISION_HISTORY',
data: {
noteId: noteId
}
});
},
listRevisionHistory: function(noteId) {
websocketEvents.sendNewEvent({
op: 'LIST_REVISION_HISTORY',
data: {
noteId: noteId
}
});
},
getNoteByRevision: function(noteId, revisionId) {
websocketEvents.sendNewEvent({
op: 'NOTE_REVISION',
data: {
noteId: noteId,
revisionId: revisionId
}
});
},
getNoteByRevision: function(noteId, revisionId) {
websocketEvents.sendNewEvent({
op: 'NOTE_REVISION',
data: {
noteId: noteId,
revisionId: revisionId
}
});
},
getEditorSetting: function(paragraphId, replName) {
websocketEvents.sendNewEvent({
op: 'EDITOR_SETTING',
data: {
paragraphId: paragraphId,
magic: replName
}
});
},
getEditorSetting: function(paragraphId, replName) {
websocketEvents.sendNewEvent({
op: 'EDITOR_SETTING',
data: {
paragraphId: paragraphId,
magic: replName
}
});
},
isConnected: function() {
return websocketEvents.isConnected();
},
isConnected: function() {
return websocketEvents.isConnected();
},
getNoteJobsList: function() {
websocketEvents.sendNewEvent({op: 'LIST_NOTE_JOBS'});
},
getNoteJobsList: function() {
websocketEvents.sendNewEvent({op: 'LIST_NOTE_JOBS'});
},
getUpdateNoteJobsList: function(lastUpdateServerUnixTime) {
websocketEvents.sendNewEvent(
{op: 'LIST_UPDATE_NOTE_JOBS', data: {lastUpdateUnixTime: lastUpdateServerUnixTime * 1}}
);
},
getUpdateNoteJobsList: function(lastUpdateServerUnixTime) {
websocketEvents.sendNewEvent(
{op: 'LIST_UPDATE_NOTE_JOBS', data: {lastUpdateUnixTime: lastUpdateServerUnixTime * 1}}
);
},
unsubscribeJobManager: function() {
websocketEvents.sendNewEvent({op: 'UNSUBSCRIBE_UPDATE_NOTE_JOBS'});
},
unsubscribeJobManager: function() {
websocketEvents.sendNewEvent({op: 'UNSUBSCRIBE_UPDATE_NOTE_JOBS'});
},
getInterpreterBindings: function(noteId) {
websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_BINDINGS', data: {noteId: noteId}});
},
getInterpreterBindings: function(noteId) {
websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_BINDINGS', data: {noteId: noteId}});
},
saveInterpreterBindings: function(noteId, selectedSettingIds) {
websocketEvents.sendNewEvent({op: 'SAVE_INTERPRETER_BINDINGS',
data: {noteId: noteId, selectedSettingIds: selectedSettingIds}});
},
saveInterpreterBindings: function(noteId, selectedSettingIds) {
websocketEvents.sendNewEvent({op: 'SAVE_INTERPRETER_BINDINGS',
data: {noteId: noteId, selectedSettingIds: selectedSettingIds}});
},
listConfigurations: function() {
websocketEvents.sendNewEvent({op: 'LIST_CONFIGURATIONS'});
},
listConfigurations: function() {
websocketEvents.sendNewEvent({op: 'LIST_CONFIGURATIONS'});
},
getInterpreterSettings: function() {
websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_SETTINGS'});
}
getInterpreterSettings: function() {
websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_SETTINGS'});
}
};
}
};
}
})();