| /* jshint loopfunc: true */ |
| /* global $: false */ |
| /* |
| * 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. |
| */ |
| 'use strict'; |
| |
| angular.module('zeppelinWebApp').controller('NotebookCtrl', |
| function($scope, $route, $routeParams, $location, $rootScope, $http, $window, |
| websocketMsgSrv, baseUrlSrv, $timeout, SaveAsService) { |
| $scope.note = null; |
| $scope.showEditor = false; |
| $scope.editorToggled = false; |
| $scope.tableToggled = false; |
| $scope.viewOnly = false; |
| $scope.showSetting = false; |
| $scope.looknfeelOption = [ 'default', 'simple', 'report']; |
| $scope.cronOption = [ |
| {name: 'None', value : undefined}, |
| {name: '1m', value: '0 0/1 * * * ?'}, |
| {name: '5m', value: '0 0/5 * * * ?'}, |
| {name: '1h', value: '0 0 0/1 * * ?'}, |
| {name: '3h', value: '0 0 0/3 * * ?'}, |
| {name: '6h', value: '0 0 0/6 * * ?'}, |
| {name: '12h', value: '0 0 0/12 * * ?'}, |
| {name: '1d', value: '0 0 0 * * ?'} |
| ]; |
| |
| $scope.interpreterSettings = []; |
| $scope.interpreterBindings = []; |
| $scope.isNoteDirty = null; |
| $scope.saveTimer = null; |
| |
| var connectedOnce = false; |
| |
| // user auto complete related |
| $scope.suggestions = []; |
| $scope.selectIndex = -1; |
| var selectedUser = ''; |
| var selectedUserIndex = 0; |
| var previousSelectedList = []; |
| var previousSelectedListOwners = []; |
| var previousSelectedListReaders = []; |
| var previousSelectedListWriters = []; |
| var searchText = []; |
| $scope.role = ''; |
| |
| $scope.$on('setConnectedStatus', function(event, param) { |
| if(connectedOnce && param){ |
| initNotebook(); |
| } |
| connectedOnce = true; |
| }); |
| |
| $scope.getCronOptionNameFromValue = function(value) { |
| if (!value) { |
| return ''; |
| } |
| |
| for (var o in $scope.cronOption) { |
| if ($scope.cronOption[o].value===value) { |
| return $scope.cronOption[o].name; |
| } |
| } |
| return value; |
| }; |
| |
| /** Init the new controller */ |
| var initNotebook = function() { |
| websocketMsgSrv.getNotebook($routeParams.noteId); |
| |
| var currentRoute = $route.current; |
| |
| if (currentRoute) { |
| setTimeout( |
| function() { |
| var routeParams = currentRoute.params; |
| var $id = $('#' + routeParams.paragraph + '_container'); |
| |
| if ($id.length > 0) { |
| // adjust for navbar |
| var top = $id.offset().top - 103; |
| $('html, body').scrollTo({top: top, left: 0}); |
| } |
| |
| // force notebook reload on user change |
| $scope.$on('setNoteMenu', function(event, note) { |
| initNotebook(); |
| }); |
| }, |
| 1000 |
| ); |
| } |
| }; |
| |
| initNotebook(); |
| |
| |
| $scope.focusParagraphOnClick = function(clickEvent) { |
| if (!$scope.note) { |
| return; |
| } |
| for (var i=0; i<$scope.note.paragraphs.length; i++) { |
| var paragraphId = $scope.note.paragraphs[i].id; |
| if (jQuery.contains(angular.element('#' + paragraphId + '_container')[0], clickEvent.target)) { |
| $scope.$broadcast('focusParagraph', paragraphId, 0, true); |
| break; |
| } |
| } |
| }; |
| |
| // register mouseevent handler for focus paragraph |
| document.addEventListener('click', $scope.focusParagraphOnClick); |
| |
| $scope.keyboardShortcut = function(keyEvent) { |
| // handle keyevent |
| if (!$scope.viewOnly) { |
| $scope.$broadcast('keyEvent', keyEvent); |
| } |
| }; |
| |
| // register mouseevent handler for focus paragraph |
| document.addEventListener('keydown', $scope.keyboardShortcut); |
| |
| |
| /** Remove the note and go back tot he main page */ |
| /** TODO(anthony): In the nearly future, go back to the main page and telle to the dude that the note have been remove */ |
| $scope.removeNote = function(noteId) { |
| BootstrapDialog.confirm({ |
| closable: true, |
| title: '', |
| message: 'Do you want to delete this notebook?', |
| callback: function(result) { |
| if (result) { |
| websocketMsgSrv.deleteNotebook(noteId); |
| $location.path('/#'); |
| } |
| } |
| }); |
| }; |
| |
| //Export notebook |
| $scope.exportNotebook = function() { |
| var jsonContent = JSON.stringify($scope.note); |
| SaveAsService.SaveAs(jsonContent, $scope.note.name, 'json'); |
| }; |
| |
| //Clone note |
| $scope.cloneNote = function(noteId) { |
| BootstrapDialog.confirm({ |
| closable: true, |
| title: '', |
| message: 'Do you want to clone this notebook?', |
| callback: function(result) { |
| if (result) { |
| websocketMsgSrv.cloneNotebook(noteId); |
| $location.path('/#'); |
| } |
| } |
| }); |
| }; |
| |
| // checkpoint/commit notebook |
| $scope.checkpointNotebook = function(commitMessage) { |
| BootstrapDialog.confirm({ |
| closable: true, |
| title: '', |
| message: 'Commit notebook to current repository?', |
| callback: function(result) { |
| if (result) { |
| websocketMsgSrv.checkpointNotebook($routeParams.noteId, commitMessage); |
| } |
| } |
| }); |
| document.getElementById('note.checkpoint.message').value=''; |
| }; |
| |
| $scope.runNote = function() { |
| BootstrapDialog.confirm({ |
| closable: true, |
| title: '', |
| message: 'Run all paragraphs?', |
| callback: function(result) { |
| if (result) { |
| _.forEach($scope.note.paragraphs, function (n, key) { |
| angular.element('#' + n.id + '_paragraphColumn_main').scope().runParagraph(n.text); |
| }); |
| } |
| } |
| }); |
| }; |
| |
| $scope.saveNote = function() { |
| if ($scope.note && $scope.note.paragraphs) { |
| _.forEach($scope.note.paragraphs, function(n, key) { |
| angular.element('#' + n.id + '_paragraphColumn_main').scope().saveParagraph(); |
| }); |
| $scope.isNoteDirty = null; |
| } |
| }; |
| |
| $scope.clearAllParagraphOutput = function() { |
| BootstrapDialog.confirm({ |
| closable: true, |
| title: '', |
| message: 'Do you want to clear all output?', |
| callback: function(result) { |
| if (result) { |
| _.forEach($scope.note.paragraphs, function(n, key) { |
| angular.element('#' + n.id + '_paragraphColumn_main').scope().clearParagraphOutput(); |
| }); |
| } |
| } |
| }); |
| }; |
| |
| $scope.toggleAllEditor = function() { |
| if ($scope.editorToggled) { |
| $scope.$broadcast('openEditor'); |
| } else { |
| $scope.$broadcast('closeEditor'); |
| } |
| $scope.editorToggled = !$scope.editorToggled; |
| }; |
| |
| $scope.showAllEditor = function() { |
| $scope.$broadcast('openEditor'); |
| }; |
| |
| $scope.hideAllEditor = function() { |
| $scope.$broadcast('closeEditor'); |
| }; |
| |
| $scope.toggleAllTable = function() { |
| if ($scope.tableToggled) { |
| $scope.$broadcast('openTable'); |
| } else { |
| $scope.$broadcast('closeTable'); |
| } |
| $scope.tableToggled = !$scope.tableToggled; |
| }; |
| |
| $scope.showAllTable = function() { |
| $scope.$broadcast('openTable'); |
| }; |
| |
| $scope.hideAllTable = function() { |
| $scope.$broadcast('closeTable'); |
| }; |
| |
| $scope.isNoteRunning = function() { |
| var running = false; |
| if(!$scope.note){ return false; } |
| for (var i=0; i<$scope.note.paragraphs.length; i++) { |
| if ( $scope.note.paragraphs[i].status === 'PENDING' || $scope.note.paragraphs[i].status === 'RUNNING') { |
| running = true; |
| break; |
| } |
| } |
| return running; |
| }; |
| |
| $scope.killSaveTimer = function() { |
| if ($scope.saveTimer) { |
| $timeout.cancel($scope.saveTimer); |
| $scope.saveTimer = null; |
| } |
| }; |
| |
| $scope.startSaveTimer = function() { |
| $scope.killSaveTimer(); |
| $scope.isNoteDirty = true; |
| //console.log('startSaveTimer called ' + $scope.note.id); |
| $scope.saveTimer = $timeout(function(){ |
| $scope.saveNote(); |
| }, 10000); |
| }; |
| |
| angular.element(window).on('beforeunload', function(e) { |
| $scope.killSaveTimer(); |
| $scope.saveNote(); |
| }); |
| |
| $scope.$on('$destroy', function() { |
| angular.element(window).off('beforeunload'); |
| $scope.killSaveTimer(); |
| $scope.saveNote(); |
| |
| document.removeEventListener('click', $scope.focusParagraphOnClick); |
| document.removeEventListener('keydown', $scope.keyboardShortcut); |
| }); |
| |
| $scope.setLookAndFeel = function(looknfeel) { |
| $scope.note.config.looknfeel = looknfeel; |
| $scope.setConfig(); |
| }; |
| |
| /** Set cron expression for this note **/ |
| $scope.setCronScheduler = function(cronExpr) { |
| $scope.note.config.cron = cronExpr; |
| $scope.setConfig(); |
| }; |
| |
| /** Set the username of the user to be used to execute all notes in notebook **/ |
| $scope.setCronExecutingUser = function(cronExecutingUser) { |
| $scope.note.config.cronExecutingUser = cronExecutingUser; |
| $scope.setConfig(); |
| }; |
| |
| /** Set release resource for this note **/ |
| $scope.setReleaseResource = function(value) { |
| $scope.note.config.releaseresource = value; |
| $scope.setConfig(); |
| }; |
| |
| /** Update note config **/ |
| $scope.setConfig = function(config) { |
| if(config) { |
| $scope.note.config = config; |
| } |
| websocketMsgSrv.updateNotebook($scope.note.id, $scope.note.name, $scope.note.config); |
| }; |
| |
| /** Update the note name */ |
| $scope.sendNewName = function() { |
| if ($scope.note.name) { |
| websocketMsgSrv.updateNotebook($scope.note.id, $scope.note.name, $scope.note.config); |
| } |
| }; |
| |
| /** update the current note */ |
| $scope.$on('setNoteContent', function(event, note) { |
| $scope.paragraphUrl = $routeParams.paragraphId; |
| $scope.asIframe = $routeParams.asIframe; |
| if ($scope.paragraphUrl) { |
| note = cleanParagraphExcept($scope.paragraphUrl, note); |
| $rootScope.$broadcast('setIframe', $scope.asIframe); |
| } |
| |
| if ($scope.note === null) { |
| $scope.note = note; |
| } else { |
| updateNote(note); |
| } |
| initializeLookAndFeel(); |
| //open interpreter binding setting when there're none selected |
| getInterpreterBindings(getInterpreterBindingsCallBack); |
| }); |
| |
| |
| var initializeLookAndFeel = function() { |
| if (!$scope.note.config.looknfeel) { |
| $scope.note.config.looknfeel = 'default'; |
| } else { |
| $scope.viewOnly = $scope.note.config.looknfeel === 'report' ? true : false; |
| } |
| $rootScope.$broadcast('setLookAndFeel', $scope.note.config.looknfeel); |
| }; |
| |
| var cleanParagraphExcept = function(paragraphId, note) { |
| var noteCopy = {}; |
| noteCopy.id = note.id; |
| noteCopy.name = note.name; |
| noteCopy.config = note.config; |
| noteCopy.info = note.info; |
| noteCopy.paragraphs = []; |
| for (var i=0; i<note.paragraphs.length; i++) { |
| if (note.paragraphs[i].id === paragraphId) { |
| noteCopy.paragraphs[0] = note.paragraphs[i]; |
| if (!noteCopy.paragraphs[0].config) { |
| noteCopy.paragraphs[0].config = {}; |
| } |
| noteCopy.paragraphs[0].config.editorHide = true; |
| noteCopy.paragraphs[0].config.tableHide = false; |
| break; |
| } |
| } |
| return noteCopy; |
| }; |
| |
| // create new paragraph on current position |
| $scope.$on('insertParagraph', function(event, paragraphId, position) { |
| var newIndex = -1; |
| for (var i=0; i<$scope.note.paragraphs.length; i++) { |
| if ( $scope.note.paragraphs[i].id === paragraphId ) { |
| //determine position of where to add new paragraph; default is below |
| if ( position === 'above' ) { |
| newIndex = i; |
| } else { |
| newIndex = i+1; |
| } |
| break; |
| } |
| } |
| |
| if (newIndex < 0 || newIndex > $scope.note.paragraphs.length) { |
| return; |
| } |
| websocketMsgSrv.insertParagraph(newIndex); |
| }); |
| |
| $scope.$on('moveParagraphUp', function(event, paragraphId) { |
| var newIndex = -1; |
| for (var i=0; i<$scope.note.paragraphs.length; i++) { |
| if ($scope.note.paragraphs[i].id === paragraphId) { |
| newIndex = i-1; |
| break; |
| } |
| } |
| if (newIndex<0 || newIndex>=$scope.note.paragraphs.length) { |
| return; |
| } |
| // save dirtyText of moving paragraphs. |
| var prevParagraphId = $scope.note.paragraphs[newIndex].id; |
| angular.element('#' + paragraphId + '_paragraphColumn_main').scope().saveParagraph(); |
| angular.element('#' + prevParagraphId + '_paragraphColumn_main').scope().saveParagraph(); |
| websocketMsgSrv.moveParagraph(paragraphId, newIndex); |
| }); |
| |
| $scope.$on('moveParagraphDown', function(event, paragraphId) { |
| var newIndex = -1; |
| for (var i=0; i<$scope.note.paragraphs.length; i++) { |
| if ($scope.note.paragraphs[i].id === paragraphId) { |
| newIndex = i+1; |
| break; |
| } |
| } |
| |
| if (newIndex<0 || newIndex>=$scope.note.paragraphs.length) { |
| return; |
| } |
| // save dirtyText of moving paragraphs. |
| var nextParagraphId = $scope.note.paragraphs[newIndex].id; |
| angular.element('#' + paragraphId + '_paragraphColumn_main').scope().saveParagraph(); |
| angular.element('#' + nextParagraphId + '_paragraphColumn_main').scope().saveParagraph(); |
| websocketMsgSrv.moveParagraph(paragraphId, newIndex); |
| }); |
| |
| $scope.$on('moveFocusToPreviousParagraph', function(event, currentParagraphId){ |
| var focus = false; |
| for (var i=$scope.note.paragraphs.length-1; i>=0; i--) { |
| if (focus === false ) { |
| if ($scope.note.paragraphs[i].id === currentParagraphId) { |
| focus = true; |
| continue; |
| } |
| } else { |
| $scope.$broadcast('focusParagraph', $scope.note.paragraphs[i].id, -1); |
| break; |
| } |
| } |
| }); |
| |
| $scope.$on('moveFocusToNextParagraph', function(event, currentParagraphId){ |
| var focus = false; |
| for (var i=0; i<$scope.note.paragraphs.length; i++) { |
| if (focus === false ) { |
| if ($scope.note.paragraphs[i].id === currentParagraphId) { |
| focus = true; |
| continue; |
| } |
| } else { |
| $scope.$broadcast('focusParagraph', $scope.note.paragraphs[i].id, 0); |
| break; |
| } |
| } |
| }); |
| |
| var updateNote = function(note) { |
| /** update Note name */ |
| if (note.name !== $scope.note.name) { |
| console.log('change note name: %o to %o', $scope.note.name, note.name); |
| $scope.note.name = note.name; |
| } |
| |
| $scope.note.config = note.config; |
| $scope.note.info = note.info; |
| |
| var newParagraphIds = note.paragraphs.map(function(x) {return x.id;}); |
| var oldParagraphIds = $scope.note.paragraphs.map(function(x) {return x.id;}); |
| |
| var numNewParagraphs = newParagraphIds.length; |
| var numOldParagraphs = oldParagraphIds.length; |
| |
| var paragraphToBeFocused; |
| var focusedParagraph; |
| for (var i=0; i<$scope.note.paragraphs.length; i++) { |
| var paragraphId = $scope.note.paragraphs[i].id; |
| if (angular.element('#' + paragraphId + '_paragraphColumn_main').scope().paragraphFocused) { |
| focusedParagraph = paragraphId; |
| break; |
| } |
| } |
| |
| /** add a new paragraph */ |
| if (numNewParagraphs > numOldParagraphs) { |
| for (var index in newParagraphIds) { |
| if (oldParagraphIds[index] !== newParagraphIds[index]) { |
| $scope.note.paragraphs.splice(index, 0, note.paragraphs[index]); |
| paragraphToBeFocused = note.paragraphs[index].id; |
| break; |
| } |
| $scope.$broadcast('updateParagraph', { |
| note: $scope.note, // pass the note object to paragraph scope |
| paragraph: note.paragraphs[index]}); |
| } |
| } |
| |
| /** update or move paragraph */ |
| if (numNewParagraphs === numOldParagraphs) { |
| for (var idx in newParagraphIds) { |
| var newEntry = note.paragraphs[idx]; |
| if (oldParagraphIds[idx] === newParagraphIds[idx]) { |
| $scope.$broadcast('updateParagraph', { |
| note: $scope.note, // pass the note object to paragraph scope |
| paragraph: newEntry}); |
| } else { |
| // move paragraph |
| var oldIdx = oldParagraphIds.indexOf(newParagraphIds[idx]); |
| $scope.note.paragraphs.splice(oldIdx, 1); |
| $scope.note.paragraphs.splice(idx, 0, newEntry); |
| // rebuild id list since paragraph has moved. |
| oldParagraphIds = $scope.note.paragraphs.map(function(x) {return x.id;}); |
| } |
| |
| if (focusedParagraph === newParagraphIds[idx]) { |
| paragraphToBeFocused = focusedParagraph; |
| } |
| } |
| } |
| |
| /** remove paragraph */ |
| if (numNewParagraphs < numOldParagraphs) { |
| for (var oldidx in oldParagraphIds) { |
| if(oldParagraphIds[oldidx] !== newParagraphIds[oldidx]) { |
| $scope.note.paragraphs.splice(oldidx, 1); |
| break; |
| } |
| } |
| } |
| |
| // restore focus of paragraph |
| for (var f=0; f<$scope.note.paragraphs.length; f++) { |
| if (paragraphToBeFocused === $scope.note.paragraphs[f].id) { |
| $scope.note.paragraphs[f].focus = true; |
| } |
| } |
| }; |
| |
| var getInterpreterBindings = function(callback) { |
| $http.get(baseUrlSrv.getRestApiBase()+ '/notebook/interpreter/bind/' +$scope.note.id). |
| success(function(data, status, headers, config) { |
| $scope.interpreterBindings = data.body; |
| $scope.interpreterBindingsOrig = angular.copy($scope.interpreterBindings); // to check dirty |
| if (callback) { |
| callback(); |
| } |
| }). |
| error(function(data, status, headers, config) { |
| if (status !== 0) { |
| console.log('Error %o %o', status, data.message); |
| } |
| }); |
| }; |
| |
| var getInterpreterBindingsCallBack = function() { |
| var selected = false; |
| var key; |
| var setting; |
| |
| for (key in $scope.interpreterBindings) { |
| setting = $scope.interpreterBindings[key]; |
| if (setting.selected) { |
| selected = true; |
| break; |
| } |
| } |
| |
| if (!selected) { |
| // make default selection |
| var selectedIntp = {}; |
| for (key in $scope.interpreterBindings) { |
| setting = $scope.interpreterBindings[key]; |
| if (!selectedIntp[setting.group]) { |
| setting.selected = true; |
| selectedIntp[setting.group] = true; |
| } |
| } |
| $scope.showSetting = true; |
| } |
| }; |
| |
| $scope.interpreterSelectionListeners = { |
| accept : function(sourceItemHandleScope, destSortableScope) {return true;}, |
| itemMoved: function (event) {}, |
| orderChanged: function(event) {} |
| }; |
| |
| $scope.openSetting = function() { |
| $scope.showSetting = true; |
| getInterpreterBindings(); |
| }; |
| |
| $scope.closeSetting = function() { |
| if (isSettingDirty()) { |
| BootstrapDialog.confirm({ |
| closable: true, |
| title: '', |
| message: 'Interpreter setting changes will be discarded.', |
| callback: function(result) { |
| if (result) { |
| $scope.$apply(function() { |
| $scope.showSetting = false; |
| }); |
| } |
| } |
| }); |
| } else { |
| $scope.showSetting = false; |
| } |
| }; |
| |
| $scope.saveSetting = function() { |
| var selectedSettingIds = []; |
| for (var no in $scope.interpreterBindings) { |
| var setting = $scope.interpreterBindings[no]; |
| if (setting.selected) { |
| selectedSettingIds.push(setting.id); |
| } |
| } |
| |
| $http.put(baseUrlSrv.getRestApiBase() + '/notebook/interpreter/bind/' + $scope.note.id, |
| selectedSettingIds). |
| success(function(data, status, headers, config) { |
| console.log('Interpreter binding %o saved', selectedSettingIds); |
| $scope.showSetting = false; |
| }). |
| error(function(data, status, headers, config) { |
| console.log('Error %o %o', status, data.message); |
| }); |
| }; |
| |
| $scope.toggleSetting = function() { |
| if ($scope.showSetting) { |
| $scope.closeSetting(); |
| } else { |
| $scope.openSetting(); |
| $scope.closePermissions(); |
| } |
| }; |
| |
| var getPermissions = function(callback) { |
| $http.get(baseUrlSrv.getRestApiBase()+ '/notebook/' +$scope.note.id + '/permissions'). |
| success(function(data, status, headers, config) { |
| $scope.permissions = data.body; |
| $scope.permissionsOrig = angular.copy($scope.permissions); // to check dirty |
| if (callback) { |
| callback(); |
| } |
| }). |
| error(function(data, status, headers, config) { |
| if (status !== 0) { |
| console.log('Error %o %o', status, data.message); |
| } |
| }); |
| }; |
| |
| $scope.openPermissions = function() { |
| $scope.showPermissions = true; |
| getPermissions(); |
| }; |
| |
| |
| $scope.closePermissions = function() { |
| if (isPermissionsDirty()) { |
| BootstrapDialog.confirm({ |
| closable: true, |
| title: '', |
| message: 'Changes will be discarded.', |
| callback: function(result) { |
| if (result) { |
| $scope.$apply(function() { |
| $scope.showPermissions = false; |
| }); |
| } |
| } |
| }); |
| } else { |
| $scope.showPermissions = false; |
| } |
| }; |
| |
| function convertPermissionsToArray() { |
| if (!angular.isArray($scope.permissions.owners)) { |
| $scope.permissions.owners = $scope.permissions.owners.split(','); |
| } |
| if (!angular.isArray($scope.permissions.readers)) { |
| $scope.permissions.readers = $scope.permissions.readers.split(','); |
| } |
| if (!angular.isArray($scope.permissions.writers)) { |
| $scope.permissions.writers = $scope.permissions.writers.split(','); |
| } |
| } |
| |
| $scope.savePermissions = function () { |
| convertPermissionsToArray(); |
| $http.put(baseUrlSrv.getRestApiBase() + '/notebook/' + $scope.note.id + '/permissions', |
| $scope.permissions, {withCredentials: true}). |
| success(function (data, status, headers, config) { |
| getPermissions(function() { |
| console.log('Note permissions %o saved', $scope.permissions); |
| BootstrapDialog.alert({ |
| closable: true, |
| title: 'Permissions Saved Successfully!!!', |
| message: 'Owners : ' + $scope.permissions.owners + '\n\n' + 'Readers : ' + |
| $scope.permissions.readers + '\n\n' + 'Writers : ' + $scope.permissions.writers |
| }); |
| $scope.showPermissions = false; |
| }); |
| }). |
| error(function (data, status, headers, config) { |
| console.log('Error %o %o', status, data.message); |
| BootstrapDialog.show({ |
| closable: false, |
| closeByBackdrop: false, |
| closeByKeyboard: false, |
| title: 'Insufficient privileges', |
| message: data.message, |
| buttons: [ |
| { |
| label: 'Login', |
| action: function (dialog) { |
| dialog.close(); |
| angular.element('#loginModal').modal({ |
| show: 'true' |
| }); |
| } |
| }, |
| { |
| label: 'Cancel', |
| action: function (dialog) { |
| dialog.close(); |
| $window.location.replace('/'); |
| } |
| } |
| ] |
| }); |
| }); |
| }; |
| |
| $scope.togglePermissions = function() { |
| if ($scope.showPermissions) { |
| $scope.closePermissions(); |
| } else { |
| $scope.openPermissions(); |
| $scope.closeSetting(); |
| } |
| }; |
| |
| |
| var isSettingDirty = function() { |
| if (angular.equals($scope.interpreterBindings, $scope.interpreterBindingsOrig)) { |
| return false; |
| } else { |
| return true; |
| } |
| }; |
| |
| var isPermissionsDirty = function() { |
| if (angular.equals($scope.permissions, $scope.permissionsOrig)) { |
| return false; |
| } else { |
| return true; |
| } |
| }; |
| |
| function checkPreviousRole(role) { |
| var i = 0; |
| if (role !== $scope.role) { |
| if ($scope.role === 'owners') { |
| previousSelectedListOwners = []; |
| for (i = 0; i < previousSelectedList.length; i++) { |
| previousSelectedListOwners[i] = previousSelectedList[i]; |
| } |
| } |
| if ($scope.role === 'readers') { |
| previousSelectedListReaders = []; |
| for (i = 0; i < previousSelectedList.length; i++) { |
| previousSelectedListReaders[i] = previousSelectedList[i]; |
| } |
| } |
| if ($scope.role === 'writers') { |
| previousSelectedListWriters = []; |
| for (i = 0; i < previousSelectedList.length; i++) { |
| previousSelectedListWriters[i] = previousSelectedList[i]; |
| } |
| } |
| |
| $scope.role = role; |
| previousSelectedList = []; |
| if (role === 'owners') { |
| for (i = 0; i < previousSelectedListOwners.length; i++) { |
| previousSelectedList[i] = previousSelectedListOwners[i]; |
| } |
| } |
| if (role === 'readers') { |
| for (i = 0; i < previousSelectedListReaders.length; i++) { |
| previousSelectedList[i] = previousSelectedListReaders[i]; |
| } |
| } |
| if (role === 'writers') { |
| for (i = 0; i < previousSelectedListWriters.length; i++) { |
| previousSelectedList[i] = previousSelectedListWriters[i]; |
| } |
| } |
| } |
| } |
| |
| |
| function convertToArray(role) { |
| if (!$scope.permissions) { |
| return; |
| } else if (role === 'owners' && typeof $scope.permissions.owners === 'string') { |
| searchText = $scope.permissions.owners.split(','); |
| } else if (role === 'readers' && typeof $scope.permissions.readers === 'string') { |
| searchText = $scope.permissions.readers.split(','); |
| } else if (role === 'writers' && typeof $scope.permissions.writers === 'string') { |
| searchText = $scope.permissions.writers.split(','); |
| } |
| |
| for (var i = 0; i < searchText.length; i++) { |
| searchText[i] = searchText[i].trim(); |
| } |
| } |
| |
| |
| function convertToString(role) { |
| if (role === 'owners') { |
| $scope.permissions.owners = searchText.join(); |
| } |
| else if (role === 'readers') { |
| $scope.permissions.readers = searchText.join(); |
| } |
| else if (role === 'writers') { |
| $scope.permissions.writers = searchText.join(); |
| } |
| } |
| |
| function getSuggestions (searchQuery) { |
| $scope.suggestions =[]; |
| $http.get(baseUrlSrv.getRestApiBase() + '/security/userlist/' + searchQuery ).then(function |
| (response) { |
| var userlist = angular.fromJson(response.data).body; |
| for (var k in userlist) { |
| $scope.suggestions.push(userlist[k]); |
| } |
| }); |
| } |
| |
| function updatePreviousList() { |
| for (var i = 0; i < searchText.length; i++) { |
| previousSelectedList[i] = searchText[i]; |
| } |
| } |
| |
| |
| var getChangedIndex = function() { |
| if (previousSelectedList.length === 0) { |
| selectedUserIndex = searchText.length - 1; |
| } |
| else { |
| for (var i = 0; i < searchText.length; i++) { |
| if (previousSelectedList[i] !== searchText[i]) { |
| selectedUserIndex = i; |
| previousSelectedList = []; |
| break; |
| } |
| } |
| } |
| updatePreviousList(); |
| }; |
| |
| $scope.$watch('permissions.owners', _.debounce(function(readers) { |
| $scope.$apply(function() { |
| $scope.search('owners'); |
| }); |
| }, 350)); |
| $scope.$watch('permissions.readers', _.debounce(function(readers) { |
| $scope.$apply(function() { |
| $scope.search('readers'); |
| }); |
| }, 350)); |
| $scope.$watch('permissions.writers', _.debounce(function(readers) { |
| $scope.$apply(function() { |
| $scope.search('writers'); |
| }); |
| }, 350)); |
| |
| // function to find suggestion list on change |
| $scope.search = function(role) { |
| convertToArray(role); |
| checkPreviousRole(role); |
| getChangedIndex(); |
| $scope.selectIndex = -1; |
| $scope.suggestions = []; |
| selectedUser = searchText[selectedUserIndex]; |
| if (selectedUser !== '') { |
| getSuggestions(selectedUser); |
| } else { |
| $scope.suggestions = []; |
| } |
| }; |
| |
| |
| var checkIfSelected = function() { |
| if (($scope.suggestions.length === 0) && ($scope.selectIndex < 0 || $scope.selectIndex >= $scope.suggestions.length) || ( $scope.suggestions.length !== 0 && ( $scope.selectIndex < 0 || $scope.selectIndex >= $scope.suggestions.length ))) { |
| searchText[selectedUserIndex] = selectedUser; |
| $scope.suggestions = []; |
| return true; |
| } |
| else { |
| return false; |
| } |
| }; |
| |
| |
| $scope.checkKeyDown = function(event, role) { |
| if (event.keyCode === 40) { |
| event.preventDefault(); |
| if ($scope.selectIndex + 1 !== $scope.suggestions.length) { |
| $scope.selectIndex++; |
| } |
| } |
| else if (event.keyCode === 38) { |
| event.preventDefault(); |
| |
| if ($scope.selectIndex - 1 !== -1) { |
| $scope.selectIndex--; |
| |
| } |
| } |
| else if (event.keyCode === 13) { |
| event.preventDefault(); |
| if (!checkIfSelected()) { |
| selectedUser = $scope.suggestions[$scope.selectIndex]; |
| searchText[selectedUserIndex] = $scope.suggestions[$scope.selectIndex]; |
| updatePreviousList(); |
| convertToString(role); |
| $scope.suggestions = []; |
| } |
| } |
| }; |
| |
| $scope.checkKeyUp = function(event) { |
| if (event.keyCode !== 8 || event.keyCode !== 46) { |
| if (searchText[selectedUserIndex] === '') { |
| $scope.suggestions = []; |
| } |
| } |
| }; |
| |
| |
| $scope.assignValueAndHide = function(index, role) { |
| searchText[selectedUserIndex] = $scope.suggestions[index]; |
| updatePreviousList(); |
| convertToString(role); |
| $scope.suggestions = []; |
| }; |
| |
| angular.element(document).click(function(){ |
| angular.element('.userlist').hide(); |
| angular.element('.ace_autocomplete').hide(); |
| }); |
| |
| }); |