Move all websocket calls to a service

This commit is contained in:
Damien Corneau 2015-06-11 16:49:47 +09:00
parent b21cc69267
commit a36adf9839
5 changed files with 182 additions and 135 deletions

View file

@ -300,7 +300,7 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope,
var init = function() {
// when interpreter page opened after seeing non-default looknfeel note, the css remains unchanged. that's what interpreter page want. Force set default looknfeel.
$rootScope.$emit('setLookAndFeel', 'default');
$rootScope.$broadcast('setLookAndFeel', 'default');
$scope.interpreterSettings = [];
$scope.availableInterpreters = {};
$scope.resetNewInterpreterSetting();

View file

@ -23,7 +23,7 @@
* Controller of notes, manage the note (update)
*
*/
angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $route, $routeParams, $location, $rootScope, $http) {
angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $route, $routeParams, $location, $rootScope, $http, websocketMsgSrv) {
$scope.note = null;
$scope.showEditor = false;
$scope.editorToggled = false;
@ -61,7 +61,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
/** Init the new controller */
var initNotebook = function() {
$rootScope.$emit('sendNewEvent', {op: 'GET_NOTE', data: {id: $routeParams.noteId}});
websocketMsgSrv.getNotebook($routeParams.noteId);
};
initNotebook();
@ -71,7 +71,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
$scope.removeNote = function(noteId) {
var result = confirm('Do you want to delete this notebook?');
if (result) {
$rootScope.$emit('sendNewEvent', {op: 'DEL_NOTE', data: {id: noteId}});
websocketMsgSrv.deleteNotebook(noteId);
$location.path('/#');
}
};
@ -145,14 +145,14 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
if(config) {
$scope.note.config = config;
}
$rootScope.$emit('sendNewEvent', {op: 'NOTE_UPDATE', data: {id: $scope.note.id, name: $scope.note.name, config : $scope.note.config}});
websocketMsgSrv.updateNotebook($scope.note.id, $scope.note.name, $scope.note.config);
};
/** Update the note name */
$scope.sendNewName = function() {
$scope.showEditor = false;
if ($scope.note.name) {
$rootScope.$emit('sendNewEvent', {op: 'NOTE_UPDATE', data: {id: $scope.note.id, name: $scope.note.name, config : $scope.note.config}});
websocketMsgSrv.updateNotebook($scope.note.id, $scope.note.name, $scope.note.config);
}
};
@ -162,7 +162,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
$scope.asIframe = $routeParams.asIframe;
if ($scope.paragraphUrl) {
note = cleanParagraphExcept($scope.paragraphUrl, note);
$rootScope.$emit('setIframe', $scope.asIframe);
$rootScope.$broadcast('setIframe', $scope.asIframe);
}
if ($scope.note === null) {
@ -182,7 +182,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
} else {
$scope.viewOnly = $scope.note.config.looknfeel === 'report' ? true : false;
}
$rootScope.$emit('setLookAndFeel', $scope.note.config.looknfeel);
$rootScope.$broadcast('setLookAndFeel', $scope.note.config.looknfeel);
};
@ -222,7 +222,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
if (newIndex<0 || newIndex>=$scope.note.paragraphs.length) {
return;
}
$rootScope.$emit('sendNewEvent', { op: 'MOVE_PARAGRAPH', data : {id: paragraphId, index: newIndex}});
websocketMsgSrv.moveParagraph(paragraphId, newIndex);
});
// create new paragraph on current position
@ -242,7 +242,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
if (newIndex < 0 || newIndex > $scope.note.paragraphs.length) {
return;
}
$rootScope.$emit('sendNewEvent', { op: 'INSERT_PARAGRAPH', data : {index: newIndex}});
websocketMsgSrv.insertParagraph(newIndex);
});
$scope.$on('moveParagraphDown', function(event, paragraphId) {
@ -257,7 +257,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
if (newIndex<0 || newIndex>=$scope.note.paragraphs.length) {
return;
}
$rootScope.$emit('sendNewEvent', { op: 'MOVE_PARAGRAPH', data : {id: paragraphId, index: newIndex}});
websocketMsgSrv.moveParagraph(paragraphId, newIndex);
});
$scope.$on('moveFocusToPreviousParagraph', function(event, currentParagraphId){
@ -458,7 +458,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
if (!angularObjectRegistry[varName]) {
angularObjectRegistry[varName] = {
interpreterGroupId : data.interpreterGroupId,
}
};
}
angularObjectRegistry[varName].skipEmit = true;
@ -469,16 +469,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
angularObjectRegistry[varName].skipEmit = false;
return;
}
$rootScope.$emit('sendNewEvent', {
op: 'ANGULAR_OBJECT_UPDATED',
data: {
noteId: $routeParams.noteId,
name:varName,
value:newValue,
interpreterGroupId:angularObjectRegistry[varName].interpreterGroupId
}
});
websocketMsgSrv.updateAngularObject($routeParams.noteId, varName, newValue, angularObjectRegistry[varName].interpreterGroupId);
});
}
scope[varName] = data.angularObject.object;
@ -489,6 +480,6 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
var isFunction = function(functionToCheck) {
var getType = {};
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}
};
});

View file

@ -25,7 +25,8 @@
* @author anthonycorbacho
*/
angular.module('zeppelinWebApp')
.controller('ParagraphCtrl', function($scope, $rootScope, $route, $window, $element, $routeParams, $location, $timeout, $compile) {
.controller('ParagraphCtrl', function($scope,$rootScope, $route, $window, $element, $routeParams, $location,
$timeout, $compile, websocketMsgSrv) {
$scope.paragraph = null;
$scope.editor = null;
@ -67,7 +68,7 @@ angular.module('zeppelinWebApp')
try {
$('#p'+$scope.paragraph.id+'_html').html($scope.paragraph.result.msg);
$('#p'+$scope.paragraph.id+'_html').find('pre code').each(function(i, e) { hljs.highlightBlock(e) });
$('#p'+$scope.paragraph.id+'_html').find('pre code').each(function(i, e) { hljs.highlightBlock(e); });
} catch(err) {
console.log('HTML rendering error %o', err);
}
@ -159,17 +160,17 @@ angular.module('zeppelinWebApp')
// TODO: this may have impact on performance when there are many paragraphs in a note.
$scope.$on('updateParagraph', function(event, data) {
if (data.paragraph.id === $scope.paragraph.id &&
(
data.paragraph.dateCreated !== $scope.paragraph.dateCreated ||
data.paragraph.dateFinished !== $scope.paragraph.dateFinished ||
data.paragraph.dateStarted !== $scope.paragraph.dateStarted ||
data.paragraph.status !== $scope.paragraph.status ||
data.paragraph.jobName !== $scope.paragraph.jobName ||
data.paragraph.title !== $scope.paragraph.title ||
data.paragraph.errorMessage !== $scope.paragraph.errorMessage ||
!angular.equals(data.paragraph.settings, $scope.lastData.settings) ||
!angular.equals(data.paragraph.config, $scope.lastData.config)
)
(
data.paragraph.dateCreated !== $scope.paragraph.dateCreated ||
data.paragraph.dateFinished !== $scope.paragraph.dateFinished ||
data.paragraph.dateStarted !== $scope.paragraph.dateStarted ||
data.paragraph.status !== $scope.paragraph.status ||
data.paragraph.jobName !== $scope.paragraph.jobName ||
data.paragraph.title !== $scope.paragraph.title ||
data.paragraph.errorMessage !== $scope.paragraph.errorMessage ||
!angular.equals(data.paragraph.settings, $scope.lastData.settings) ||
!angular.equals(data.paragraph.config, $scope.lastData.config)
)
) {
// store original data for comparison
$scope.lastData.settings = angular.copy(data.paragraph.settings);
@ -247,22 +248,13 @@ angular.module('zeppelinWebApp')
$scope.cancelParagraph = function() {
console.log('Cancel %o', $scope.paragraph.id);
var data = {op: 'CANCEL_PARAGRAPH', data: {id: $scope.paragraph.id }};
$rootScope.$emit('sendNewEvent', data);
websocketMsgSrv.cancelParagraphRun($scope.paragraph.id);
};
$scope.runParagraph = function(data) {
var parapgraphData = {op: 'RUN_PARAGRAPH',
data: {
id: $scope.paragraph.id,
title: $scope.paragraph.title,
paragraph: data,
config: $scope.paragraph.config,
params: $scope.paragraph.settings.params
}
};
$rootScope.$emit('sendNewEvent', parapgraphData);
websocketMsgSrv.runParagraph($scope.paragraph.id, $scope.paragraph.title,
data, $scope.paragraph.config, $scope.paragraph.settings.params);
};
$scope.moveUp = function() {
@ -281,8 +273,7 @@ angular.module('zeppelinWebApp')
var result = confirm('Do you want to delete this paragraph?');
if (result) {
console.log('Remove paragraph');
var paragraphData = {op: 'PARAGRAPH_REMOVE', data: {id: $scope.paragraph.id}};
$rootScope.$emit('sendNewEvent', paragraphData);
websocketMsgSrv.removeParagraph($scope.paragraph.id);
}
};
@ -433,39 +424,32 @@ angular.module('zeppelinWebApp')
}
$scope.editor.setOptions({
enableBasicAutocompletion: true,
enableSnippets: false,
enableLiveAutocompletion:false
enableBasicAutocompletion: true,
enableSnippets: false,
enableLiveAutocompletion:false
});
var remoteCompleter = {
getCompletions : function(editor, session, pos, prefix, callback) {
if (!$scope.editor.isFocused() ){ return;}
getCompletions : function(editor, session, pos, prefix, callback) {
if (!$scope.editor.isFocused() ){ return;}
var buf = session.getTextRange(new Range(0, 0, pos.row, pos.column));
$rootScope.$emit('sendNewEvent', {
op : 'COMPLETION',
data : {
id : $scope.paragraph.id,
buf : buf,
cursor : buf.length
}
});
var buf = session.getTextRange(new Range(0, 0, pos.row, pos.column));
websocketMsgSrv.completion($scope.paragraph.id, buf, buf.length);
$scope.$on('completionList', function(event, data) {
if (data.completions) {
var completions = [];
for (var c in data.completions) {
var v = data.completions[c];
completions.push({
name:v,
value:v,
score:300
});
}
callback(null, completions);
}
});
}
$scope.$on('completionList', function(event, data) {
if (data.completions) {
var completions = [];
for (var c in data.completions) {
var v = data.completions[c];
completions.push({
name:v,
value:v,
score:300
});
}
callback(null, completions);
}
});
}
};
langTools.addCompleter(remoteCompleter);
@ -536,23 +520,23 @@ angular.module('zeppelinWebApp')
$scope.editor.keyBinding.onCommandKey = function(e, hashId, keyCode) {
if ($scope.editor.completer && $scope.editor.completer.activated) { // if autocompleter is active
} else {
var numRows;
var currentRow;
if (keyCode === 38 || (keyCode === 80 && e.ctrlKey)) { // UP
numRows = $scope.editor.getSession().getLength();
currentRow = $scope.editor.getCursorPosition().row;
if (currentRow === 0) {
// move focus to previous paragraph
$scope.$emit('moveFocusToPreviousParagraph', $scope.paragraph.id);
}
} else if (keyCode === 40 || (keyCode === 78 && e.ctrlKey)) { // DOWN
numRows = $scope.editor.getSession().getLength();
currentRow = $scope.editor.getCursorPosition().row;
if (currentRow === numRows-1) {
// move focus to next paragraph
$scope.$emit('moveFocusToNextParagraph', $scope.paragraph.id);
}
var numRows;
var currentRow;
if (keyCode === 38 || (keyCode === 80 && e.ctrlKey)) { // UP
numRows = $scope.editor.getSession().getLength();
currentRow = $scope.editor.getCursorPosition().row;
if (currentRow === 0) {
// move focus to previous paragraph
$scope.$emit('moveFocusToPreviousParagraph', $scope.paragraph.id);
}
} else if (keyCode === 40 || (keyCode === 78 && e.ctrlKey)) { // DOWN
numRows = $scope.editor.getSession().getLength();
currentRow = $scope.editor.getCursorPosition().row;
if (currentRow === numRows-1) {
// move focus to next paragraph
$scope.$emit('moveFocusToNextParagraph', $scope.paragraph.id);
}
}
}
this.origOnCommandKey(e, hashId, keyCode);
};
@ -713,16 +697,7 @@ angular.module('zeppelinWebApp')
};
var commitParagraph = function(title, text, config, params) {
var parapgraphData = {
op: 'COMMIT_PARAGRAPH',
data: {
id: $scope.paragraph.id,
title : title,
paragraph: text,
params: params,
config: config
}};
$rootScope.$emit('sendNewEvent', parapgraphData);
websocketMsgSrv.commitParagraph($scope.paragraph.id, title, text, config, params);
};
var setTable = function(type, data, refresh) {
@ -776,7 +751,7 @@ angular.module('zeppelinWebApp')
var v = row[index].value;
if (getTableContentFormat(v) !== 'html') {
v = v.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
return '&#'+i.charCodeAt(0)+';';
return '&#'+i.charCodeAt(0)+';';
});
}
html += ' <td>'+formatTableContent(v)+'</td>';
@ -845,23 +820,23 @@ angular.module('zeppelinWebApp')
var tooltipContent = '<h3>' + key + '</h3>';
if ($scope.paragraph.config.graph.scatter.size &&
$scope.isValidSizeOption($scope.paragraph.config.graph.scatter, $scope.paragraph.result.rows)) {
tooltipContent += '<p>' + data.point.size + '</p>';
tooltipContent += '<p>' + data.point.size + '</p>';
}
return tooltipContent;
});
$scope.chart[type].showDistX(true)
.showDistY(true)
//handle the problem of tooltip not showing when muliple points have same value.
.scatter.useVoronoi(false);
.showDistY(true)
//handle the problem of tooltip not showing when muliple points have same value.
.scatter.useVoronoi(false);
} else {
var p = pivot(data);
if (type === 'pieChart') {
var d = pivotDataToD3ChartFormat(p, true).d3g;
$scope.chart[type].x(function(d) { return d.label;})
.y(function(d) { return d.value;});
.y(function(d) { return d.value;});
if ( d.length > 0 ) {
for ( var i=0; i<d[0].values.length ; i++) {
@ -911,11 +886,11 @@ angular.module('zeppelinWebApp')
}
var chartEl = d3.select('#p'+$scope.paragraph.id+'_'+type+' svg')
.attr('height', $scope.paragraph.config.graph.height)
.datum(d3g)
.transition()
.duration(animationDuration)
.call($scope.chart[type]);
.attr('height', $scope.paragraph.config.graph.height)
.datum(d3g)
.transition()
.duration(animationDuration)
.call($scope.chart[type]);
d3.select('#p'+$scope.paragraph.id+'_'+type+' svg').style.height = height+'px';
nv.utils.windowResize($scope.chart[type].update);
};
@ -1132,10 +1107,10 @@ angular.module('zeppelinWebApp')
// add key to schema
if (!s[key.name]) {
s[key.name] = {
order : k,
index : key.index,
type : 'key',
children : {}
order : k,
index : key.index,
type : 'key',
children : {}
};
}
s = s[key.name].children;
@ -1155,10 +1130,10 @@ angular.module('zeppelinWebApp')
// add group to schema
if (!s[groupKey]) {
s[groupKey] = {
order : g,
index : group.index,
type : 'group',
children : {}
order : g,
index : group.index,
type : 'group',
children : {}
};
}
s = s[groupKey].children;
@ -1186,13 +1161,13 @@ angular.module('zeppelinWebApp')
// add value to row
if (!p[valueKey]) {
p[valueKey] = {
value : (value.aggr !== 'count') ? row[value.index] : 1,
count: 1
value : (value.aggr !== 'count') ? row[value.index] : 1,
count: 1
};
} else {
p[valueKey] = {
value : aggrFunc[value.aggr](p[valueKey].value, row[value.index], p[valueKey].count+1),
count : (aggrFuncDiv[value.aggr]) ? p[valueKey].count+1 : p[valueKey].count
value : aggrFunc[value.aggr](p[valueKey].value, row[value.index], p[valueKey].count+1),
count : (aggrFuncDiv[value.aggr]) ? p[valueKey].count+1 : p[valueKey].count
};
}
}
@ -1387,10 +1362,10 @@ angular.module('zeppelinWebApp')
if(!rows[key]) {
rows[key] = {
x : xValue,
y : yValue,
group : grp,
size : 1
x : xValue,
y : yValue,
group : grp,
size : 1
};
} else {
rows[key].size++;
@ -1583,8 +1558,8 @@ angular.module('zeppelinWebApp')
//check if all existing fields are discrete
var isAllDiscrete = ((options.xAxis && options.yAxis && isDiscrete(xValues) && isDiscrete(yValues)) ||
(!options.xAxis && isDiscrete(yValues)) ||
(!options.yAxis && isDiscrete(xValues)));
(!options.xAxis && isDiscrete(yValues)) ||
(!options.yAxis && isDiscrete(xValues)));
if (isAllDiscrete) {
return false;

View file

@ -39,7 +39,7 @@ angular.module('zeppelinWebApp').controller('NavCtrl', function($scope, $rootSco
});
function loadNotes() {
$rootScope.$broadcast('sendNewEvent', {op: 'LIST_NOTES'});
websocketMsgSrv.getNotebookList();
}
function isActive(noteId) {

View file

@ -19,4 +19,85 @@ angular.module('zeppelinWebApp').service('websocketMsgSrv', function($rootScope)
$rootScope.$broadcast('sendNewEvent', {op: 'NEW_NOTE'});
};
this.deleteNotebook = function(noteId) {
$rootScope.$broadcast('sendNewEvent', {op: 'DEL_NOTE', data: {id: noteId}});
};
this.getNotebookList = function() {
$rootScope.$broadcast('sendNewEvent', {op: 'LIST_NOTES'});
};
this.getNotebook = function(noteId) {
$rootScope.$broadcast('sendNewEvent', {op: 'GET_NOTE', data: {id: noteId}});
};
this.updateNotebook = function(noteId, noteName, noteConfig) {
$rootScope.$broadcast('sendNewEvent', {op: 'NOTE_UPDATE', data: {id: noteId, name: noteName, config : noteConfig}});
};
this.moveParagraph = function(paragraphId, newIndex) {
$rootScope.$broadcast('sendNewEvent', { op: 'MOVE_PARAGRAPH', data : {id: paragraphId, index: newIndex}});
};
this.insertParagraph = function(newIndex) {
$rootScope.$broadcast('sendNewEvent', { op: 'INSERT_PARAGRAPH', data : {index: newIndex}});
};
this.updateAngularObject = function(noteId, name, value, interpreterGroupId) {
$rootScope.$broadcast('sendNewEvent', {
op: 'ANGULAR_OBJECT_UPDATED',
data: {
noteId: noteId,
name: name,
value: value,
interpreterGroupId: interpreterGroupId
}
});
};
this.cancelParagraphRun = function(paragraphId) {
$rootScope.$broadcast('sendNewEvent', {op: 'CANCEL_PARAGRAPH', data: {id: paragraphId}});
};
this.runParagraph = function(paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
$rootScope.$broadcast('sendNewEvent', {
op: 'RUN_PARAGRAPH',
data: {
id: paragraphId,
title: paragraphTitle,
paragraph: paragraphData,
config: paragraphConfig,
params: paragraphParams
}
});
};
this.removeParagraph = function(paragraphId) {
$rootScope.$broadcast('sendNewEvent', {op: 'PARAGRAPH_REMOVE', data: {id: paragraphId}});
};
this.completion = function(paragraphId, buf, cursor) {
$rootScope.$broadcast('sendNewEvent', {
op : 'COMPLETION',
data : {
id : paragraphId,
buf : buf,
cursor : cursor
}
});
};
this.commitParagraph = function(paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
$rootScope.$broadcast('sendNewEvent', {
op: 'COMMIT_PARAGRAPH',
data: {
id: paragraphId,
title : paragraphTitle,
paragraph: paragraphData,
config: paragraphConfig,
params: paragraphParams
}
});
};
});