Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 88 additions & 2 deletions zeppelin-web/src/app/notebook/notebook.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
for (let i = 0; i < $scope.note.paragraphs.length; i++) {
let paragraphId = $scope.note.paragraphs[i].id
if (jQuery.contains(angular.element('#' + paragraphId + '_container')[0], clickEvent.target)) {
$scope.$broadcast('focusParagraph', paragraphId, 0, true)
$scope.$broadcast('focusParagraph', paragraphId, 0, null, true)
break
}
}
Expand Down Expand Up @@ -504,7 +504,7 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
para.focus = true

// we need `$timeout` since angular DOM might not be initialized
$timeout(() => { $scope.$broadcast('focusParagraph', para.id, 0, false) })
$timeout(() => { $scope.$broadcast('focusParagraph', para.id, 0, null, false) })
}
})
}
Expand Down Expand Up @@ -1180,6 +1180,92 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
** $scope.$on functions below
*/

$scope.$on('runAllAbove', function (event, paragraph, isNeedConfirm) {
let allParagraphs = $scope.note.paragraphs
let toRunParagraphs = []

for (let i = 0; allParagraphs[i] !== paragraph; i++) {
if (i === allParagraphs.length - 1) { return } // if paragraph not in array of all paragraphs
toRunParagraphs.push(allParagraphs[i])
}

const paragraphs = toRunParagraphs.map(p => {
return {
id: p.id,
title: p.title,
paragraph: p.text,
config: p.config,
params: p.settings.params
}
})

if (!isNeedConfirm) {
websocketMsgSrv.runAllParagraphs($scope.note.id, paragraphs)
} else {
BootstrapDialog.confirm({
closable: true,
title: '',
message: 'Run all above?',
callback: function (result) {
if (result) {
websocketMsgSrv.runAllParagraphs($scope.note.id, paragraphs)
}
}
})
}

$scope.saveCursorPosition(paragraph)
})

$scope.$on('runAllBelowAndCurrent', function (event, paragraph, isNeedConfirm) {
let allParagraphs = $scope.note.paragraphs
let toRunParagraphs = []

for (let i = allParagraphs.length - 1; allParagraphs[i] !== paragraph; i--) {
if (i < 0) { return } // if paragraph not in array of all paragraphs
toRunParagraphs.push(allParagraphs[i])
}

toRunParagraphs.push(paragraph)
toRunParagraphs.reverse()

const paragraphs = toRunParagraphs.map(p => {
return {
id: p.id,
title: p.title,
paragraph: p.text,
config: p.config,
params: p.settings.params
}
})

if (!isNeedConfirm) {
websocketMsgSrv.runAllParagraphs($scope.note.id, paragraphs)
} else {
BootstrapDialog.confirm({
closable: true,
title: '',
message: 'Run current and all below?',
callback: function (result) {
if (result) {
websocketMsgSrv.runAllParagraphs($scope.note.id, paragraphs)
}
}
})
}

$scope.saveCursorPosition(paragraph)
})

$scope.saveCursorPosition = function (paragraph) {
let angParagEditor = angular
.element('#' + paragraph.id + '_paragraphColumn_main')
.scope().editor
let col = angParagEditor.selection.lead.column
let row = angParagEditor.selection.lead.row
$scope.$broadcast('focusParagraph', paragraph.id, row + 1, col)
}

$scope.$on('setConnectedStatus', function (event, param) {
if (connectedOnce && param) {
initNotebook()
Expand Down
18 changes: 18 additions & 0 deletions zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,24 @@
Insert new
</a>
</li>
<li>
<a ng-click="runAllToThis(paragraph)" ng-hide="$first">
<span class="icon-action-redo shortcut-icon"
style="position: relative; transform: rotate(-90deg); left: -4px;">
</span>
<span class="shortcut-keys">Ctrl+Shift+Enter</span>
Run all above
</a>
</li>
<li>
<a ng-click="runAllFromThis(paragraph)" ng-hide="$last">
<span class="icon-action-undo shortcut-icon"
style="position: relative; transform: rotate(-90deg); left: -4px;">
</span>
<span class="shortcut-keys">Ctrl+Shift+Enter</span>
Run all below
</a>
</li>
<li>
<a ng-click="copyParagraph(getEditorValue())"><span class="fa fa-copy shortcut-icon"></span>
<span class="shortcut-keys">Ctrl+Shift+C</span>
Expand Down
56 changes: 49 additions & 7 deletions zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,43 @@ function ParagraphCtrl ($scope, $rootScope, $route, $window, $routeParams, $loca
$scope.runParagraph($scope.getEditorValue(), false, false)
}

$scope.runAllToThis = function(paragraph) {
$scope.$emit('runAllAbove', paragraph, true)
}

$scope.runAllFromThis = function(paragraph) {
$scope.$emit('runAllBelowAndCurrent', paragraph, true)
}

$scope.runAllToOrFromThis = function (paragraph) {
BootstrapDialog.show({
message: 'Run paragraphs:',
title: '',
buttons: [{
label: 'Close',
action: function(dialog) {
dialog.close()
}
},
{
label: 'Run all above',
cssClass: 'btn-primary',
action: function(dialog) {
$scope.$emit('runAllAbove', paragraph, false)
dialog.close()
}
},
{
label: 'Run current and all below',
cssClass: 'btn-primary',
action: function(dialog) {
$scope.$emit('runAllBelowAndCurrent', paragraph, false)
dialog.close()
}
}]
})
}

$scope.turnOnAutoRun = function (paragraph) {
paragraph.config.runOnSelectionChange = !paragraph.config.runOnSelectionChange
commitParagraph(paragraph)
Expand Down Expand Up @@ -1446,8 +1483,10 @@ function ParagraphCtrl ($scope, $rootScope, $route, $window, $routeParams, $loca
// move focus to next paragraph
// $timeout stops chaining effect of focus propogation
$timeout(() => $scope.$emit('moveFocusToNextParagraph', paragraphId))
} else if (keyEvent.shiftKey && keyCode === 13) { // Shift + Enter
} else if (!keyEvent.ctrlKey && keyEvent.shiftKey && keyCode === 13) { // Shift + Enter
$scope.runParagraphFromShortcut($scope.getEditorValue())
} else if (keyEvent.ctrlKey && keyEvent.shiftKey && keyCode === 13) { // Ctrl + Shift + Enter
$scope.runAllToOrFromThis($scope.paragraph)
} else if (keyEvent.ctrlKey && keyEvent.altKey && keyCode === 67) { // Ctrl + Alt + c
$scope.cancelParagraph($scope.paragraph)
} else if (keyEvent.ctrlKey && keyEvent.altKey && keyCode === 68) { // Ctrl + Alt + d
Expand Down Expand Up @@ -1500,22 +1539,25 @@ function ParagraphCtrl ($scope, $rootScope, $route, $window, $routeParams, $loca
}
})

$scope.$on('focusParagraph', function (event, paragraphId, cursorPos, mouseEvent) {
$scope.$on('focusParagraph', function (event, paragraphId, cursorPosRow, cursorPosCol, mouseEvent) {
if (cursorPosCol === null || cursorPosCol === undefined) {
cursorPosCol = 0
}
if ($scope.paragraph.id === paragraphId) {
// focus editor
if (!$scope.paragraph.config.editorHide) {
if (!mouseEvent) {
$scope.editor.focus()
// move cursor to the first row (or the last row)
let row
if (cursorPos >= 0) {
row = cursorPos
$scope.editor.gotoLine(row, 0)
if (cursorPosRow >= 0) {
row = cursorPosRow
$scope.editor.gotoLine(row, cursorPosCol)
} else {
row = $scope.editor.session.getLength()
$scope.editor.gotoLine(row, 0)
$scope.editor.gotoLine(row, cursorPosCol)
}
$scope.scrollToCursor($scope.paragraph.id, 0)
$scope.scrollToCursor($scope.paragraph.id, cursorPosCol)
}
}
handleFocus(true)
Expand Down
11 changes: 11 additions & 0 deletions zeppelin-web/src/app/notebook/shortcut.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ <h4 class="shortcut-modal-title" id="myModalLabel">Keyboard shortcuts</h4>
</td>
</tr>

<tr>
<td>
<div class="col-md-8">Run all above/below paragraphs</div>
</td>
<td>
<div class="keys">
<kbd class="kbd-default">Ctrl</kbd> + <kbd class="kbd-default">Shift</kbd> + <kbd class="kbd-default">Enter</kbd>
</div>
</td>
</tr>

<tr>
<td>
<div class="col-md-8">Cancel</div>
Expand Down