mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
fix: semi
This commit is contained in:
parent
d4a8082639
commit
cc874d26cd
79 changed files with 3968 additions and 3965 deletions
|
|
@ -31,7 +31,6 @@
|
|||
"process": false
|
||||
},
|
||||
"rules": {
|
||||
"semi": 0,
|
||||
"array-bracket-spacing": 0,
|
||||
"space-before-function-paren": 0,
|
||||
"no-unneeded-ternary": 0,
|
||||
|
|
|
|||
|
|
@ -12,48 +12,48 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('MainCtrl', MainCtrl);
|
||||
angular.module('zeppelinWebApp').controller('MainCtrl', MainCtrl)
|
||||
|
||||
function MainCtrl ($scope, $rootScope, $window, arrayOrderingSrv) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
$scope.looknfeel = 'default';
|
||||
$scope.looknfeel = 'default'
|
||||
|
||||
let init = function () {
|
||||
$scope.asIframe = (($window.location.href.indexOf('asIframe') > -1) ? true : false);
|
||||
};
|
||||
$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();
|
||||
$scope.asIframe = data
|
||||
event.preventDefault()
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
$rootScope.$on('setLookAndFeel', function (event, data) {
|
||||
if (!event.defaultPrevented && data && data !== '' && data !== $scope.looknfeel) {
|
||||
$scope.looknfeel = data;
|
||||
event.preventDefault();
|
||||
$scope.looknfeel = data
|
||||
event.preventDefault()
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// Set The lookAndFeel to default on every page
|
||||
$rootScope.$on('$routeChangeStart', function (event, next, current) {
|
||||
$rootScope.$broadcast('setLookAndFeel', 'default');
|
||||
});
|
||||
$rootScope.$broadcast('setLookAndFeel', 'default')
|
||||
})
|
||||
|
||||
$rootScope.noteName = function (note) {
|
||||
if (!_.isEmpty(note)) {
|
||||
return arrayOrderingSrv.getNoteName(note);
|
||||
return arrayOrderingSrv.getNoteName(note)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
BootstrapDialog.defaultOptions.onshown = function () {
|
||||
angular.element('#' + this.id).find('.btn:last').focus();
|
||||
};
|
||||
angular.element('#' + this.id).find('.btn:last').focus()
|
||||
}
|
||||
|
||||
// Remove BootstrapDialog animation
|
||||
BootstrapDialog.configDefaultOptions({animate: false});
|
||||
BootstrapDialog.configDefaultOptions({animate: false})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
describe('Controller: MainCtrl', function () {
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'));
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'))
|
||||
|
||||
let scope;
|
||||
let rootScope;
|
||||
let scope
|
||||
let rootScope
|
||||
|
||||
beforeEach(inject(function ($controller, $rootScope) {
|
||||
rootScope = $rootScope;
|
||||
scope = $rootScope.$new();
|
||||
rootScope = $rootScope
|
||||
scope = $rootScope.$new()
|
||||
$controller('MainCtrl', {
|
||||
$scope: scope
|
||||
});
|
||||
}));
|
||||
})
|
||||
}))
|
||||
|
||||
it('should attach "asIframe" to the scope and the default value should be false', function () {
|
||||
expect(scope.asIframe).toBeDefined();
|
||||
expect(scope.asIframe).toEqual(false);
|
||||
});
|
||||
expect(scope.asIframe).toBeDefined()
|
||||
expect(scope.asIframe).toEqual(false)
|
||||
})
|
||||
|
||||
it('should set the default value of "looknfeel to "default"', function () {
|
||||
expect(scope.looknfeel).toEqual('default');
|
||||
});
|
||||
expect(scope.looknfeel).toEqual('default')
|
||||
})
|
||||
|
||||
it('should set "asIframe" flag to true when a controller broadcasts setIframe event', function () {
|
||||
rootScope.$broadcast('setIframe', true);
|
||||
expect(scope.asIframe).toEqual(true);
|
||||
});
|
||||
});
|
||||
rootScope.$broadcast('setIframe', true)
|
||||
expect(scope.asIframe).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -39,19 +39,19 @@ let zeppelinWebApp = angular.module('zeppelinWebApp', [
|
|||
return function (text) {
|
||||
// eslint-disable-next-line no-extra-boolean-cast
|
||||
if (!!text) {
|
||||
return text.replace(/\n/g, '<br />');
|
||||
return text.replace(/\n/g, '<br />')
|
||||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
.config(function ($httpProvider, $routeProvider, ngToastProvider) {
|
||||
// withCredentials when running locally via grunt
|
||||
$httpProvider.defaults.withCredentials = true;
|
||||
$httpProvider.defaults.withCredentials = true
|
||||
|
||||
let visBundleLoad = {
|
||||
load: ['heliumService', function (heliumService) {
|
||||
return heliumService.load;
|
||||
return heliumService.load
|
||||
}]
|
||||
};
|
||||
}
|
||||
|
||||
$routeProvider
|
||||
.when('/', {
|
||||
|
|
@ -108,14 +108,14 @@ let zeppelinWebApp = angular.module('zeppelinWebApp', [
|
|||
})
|
||||
.otherwise({
|
||||
redirectTo: '/'
|
||||
});
|
||||
})
|
||||
|
||||
ngToastProvider.configure({
|
||||
dismissButton: true,
|
||||
dismissOnClick: false,
|
||||
combineDuplications: true,
|
||||
timeout: 6000
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
// handel logout on API failure
|
||||
|
|
@ -124,51 +124,51 @@ let zeppelinWebApp = angular.module('zeppelinWebApp', [
|
|||
return {
|
||||
'responseError': function (rejection) {
|
||||
if (rejection.status === 405) {
|
||||
let data = {};
|
||||
data.info = '';
|
||||
$rootScope.$broadcast('session_logout', data);
|
||||
let data = {}
|
||||
data.info = ''
|
||||
$rootScope.$broadcast('session_logout', data)
|
||||
}
|
||||
$rootScope.$broadcast('httpResponseError', rejection);
|
||||
return $q.reject(rejection);
|
||||
$rootScope.$broadcast('httpResponseError', rejection)
|
||||
return $q.reject(rejection)
|
||||
}
|
||||
};
|
||||
});
|
||||
$httpProvider.interceptors.push('httpInterceptor');
|
||||
}
|
||||
})
|
||||
$httpProvider.interceptors.push('httpInterceptor')
|
||||
})
|
||||
.constant('TRASH_FOLDER_ID', '~Trash');
|
||||
.constant('TRASH_FOLDER_ID', '~Trash')
|
||||
|
||||
function auth () {
|
||||
let $http = angular.injector(['ng']).get('$http');
|
||||
let baseUrlSrv = angular.injector(['zeppelinWebApp']).get('baseUrlSrv');
|
||||
let $http = angular.injector(['ng']).get('$http')
|
||||
let baseUrlSrv = angular.injector(['zeppelinWebApp']).get('baseUrlSrv')
|
||||
// withCredentials when running locally via grunt
|
||||
$http.defaults.withCredentials = true;
|
||||
$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;
|
||||
});
|
||||
$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('/');
|
||||
$location.path('/')
|
||||
}
|
||||
});
|
||||
});
|
||||
angular.bootstrap(document, ['zeppelinWebApp']);
|
||||
})
|
||||
})
|
||||
angular.bootstrap(document, ['zeppelinWebApp'])
|
||||
}
|
||||
|
||||
angular.element(document).ready(function () {
|
||||
auth().then(bootstrapApplication);
|
||||
});
|
||||
auth().then(bootstrapApplication)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -12,19 +12,19 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('ConfigurationCtrl', ConfigurationCtrl);
|
||||
angular.module('zeppelinWebApp').controller('ConfigurationCtrl', ConfigurationCtrl)
|
||||
|
||||
function ConfigurationCtrl ($scope, $rootScope, $http, baseUrlSrv, ngToast) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
$scope.configrations = [];
|
||||
$scope._ = _;
|
||||
ngToast.dismiss();
|
||||
$scope.configrations = []
|
||||
$scope._ = _
|
||||
ngToast.dismiss()
|
||||
|
||||
let getConfigurations = function () {
|
||||
$http.get(baseUrlSrv.getRestApiBase() + '/configurations/all')
|
||||
.success(function (data, status, headers, config) {
|
||||
$scope.configurations = data.body;
|
||||
$scope.configurations = data.body
|
||||
})
|
||||
.error(function (data, status, headers, config) {
|
||||
if (status === 401) {
|
||||
|
|
@ -32,18 +32,18 @@ function ConfigurationCtrl ($scope, $rootScope, $http, baseUrlSrv, ngToast) {
|
|||
content: 'You don\'t have permission on this page',
|
||||
verticalPosition: 'bottom',
|
||||
timeout: '3000'
|
||||
});
|
||||
})
|
||||
setTimeout(function () {
|
||||
window.location.replace('/');
|
||||
}, 3000);
|
||||
window.location.replace('/')
|
||||
}, 3000)
|
||||
}
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
|
||||
let init = function () {
|
||||
getConfigurations();
|
||||
};
|
||||
getConfigurations()
|
||||
}
|
||||
|
||||
init();
|
||||
init()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,25 +12,25 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('CredentialCtrl', CredentialCtrl);
|
||||
angular.module('zeppelinWebApp').controller('CredentialCtrl', CredentialCtrl)
|
||||
|
||||
function CredentialCtrl ($scope, $rootScope, $http, baseUrlSrv, ngToast) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
$scope._ = _;
|
||||
ngToast.dismiss();
|
||||
$scope._ = _
|
||||
ngToast.dismiss()
|
||||
|
||||
$scope.credentialInfo = [];
|
||||
$scope.showAddNewCredentialInfo = false;
|
||||
$scope.availableInterpreters = [];
|
||||
$scope.credentialInfo = []
|
||||
$scope.showAddNewCredentialInfo = false
|
||||
$scope.availableInterpreters = []
|
||||
|
||||
let 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);
|
||||
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) {
|
||||
|
|
@ -38,14 +38,14 @@ function CredentialCtrl ($scope, $rootScope, $http, baseUrlSrv, ngToast) {
|
|||
content: 'You don\'t have permission on this page',
|
||||
verticalPosition: 'bottom',
|
||||
timeout: '3000'
|
||||
});
|
||||
})
|
||||
setTimeout(function () {
|
||||
window.location.replace('/');
|
||||
}, 3000);
|
||||
window.location.replace('/')
|
||||
}, 3000)
|
||||
}
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
|
||||
$scope.addNewCredentialInfo = function () {
|
||||
if ($scope.entity && _.isEmpty($scope.entity.trim()) &&
|
||||
|
|
@ -54,15 +54,15 @@ function CredentialCtrl ($scope, $rootScope, $http, baseUrlSrv, ngToast) {
|
|||
content: 'Username \\ Entity can not be empty.',
|
||||
verticalPosition: 'bottom',
|
||||
timeout: '3000'
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
let newCredential = {
|
||||
'entity': $scope.entity,
|
||||
'username': $scope.username,
|
||||
'password': $scope.password
|
||||
};
|
||||
}
|
||||
|
||||
$http.put(baseUrlSrv.getRestApiBase() + '/credential', newCredential)
|
||||
.success(function (data, status, headers, config) {
|
||||
|
|
@ -70,92 +70,92 @@ function CredentialCtrl ($scope, $rootScope, $http, baseUrlSrv, ngToast) {
|
|||
content: 'Successfully saved credentials.',
|
||||
verticalPosition: 'bottom',
|
||||
timeout: '3000'
|
||||
});
|
||||
$scope.credentialInfo.push(newCredential);
|
||||
resetCredentialInfo();
|
||||
$scope.showAddNewCredentialInfo = false;
|
||||
console.log('Success %o %o', status, data.message);
|
||||
})
|
||||
$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);
|
||||
});
|
||||
};
|
||||
})
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
|
||||
let getAvailableInterpreters = function () {
|
||||
$http.get(baseUrlSrv.getRestApiBase() + '/interpreter/setting')
|
||||
.success(function (data, status, headers, config) {
|
||||
for (let 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,
|
||||
select: function (event, selected) {
|
||||
$scope.entity = selected.item.value;
|
||||
return false;
|
||||
$scope.entity = selected.item.value
|
||||
return false
|
||||
}
|
||||
});
|
||||
})
|
||||
}).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;
|
||||
$scope.showAddNewCredentialInfo = false
|
||||
} else {
|
||||
$scope.showAddNewCredentialInfo = true;
|
||||
$scope.showAddNewCredentialInfo = true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.cancelCredentialInfo = function () {
|
||||
$scope.showAddNewCredentialInfo = false;
|
||||
resetCredentialInfo();
|
||||
};
|
||||
$scope.showAddNewCredentialInfo = false
|
||||
resetCredentialInfo()
|
||||
}
|
||||
|
||||
const resetCredentialInfo = function () {
|
||||
$scope.entity = '';
|
||||
$scope.username = '';
|
||||
$scope.password = '';
|
||||
};
|
||||
$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) {
|
||||
let request = {
|
||||
entity: entity,
|
||||
username: data.username,
|
||||
password: data.password
|
||||
};
|
||||
}
|
||||
|
||||
$http.put(baseUrlSrv.getRestApiBase() + '/credential/', request)
|
||||
.success(function (data, status, headers, config) {
|
||||
let index = _.findIndex($scope.credentialInfo, {'entity': entity});
|
||||
$scope.credentialInfo[index] = request;
|
||||
return true;
|
||||
let 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);
|
||||
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;
|
||||
};
|
||||
})
|
||||
form.$show()
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
$scope.removeCredentialInfo = function (entity) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -168,22 +168,22 @@ function CredentialCtrl ($scope, $rootScope, $http, baseUrlSrv, ngToast) {
|
|||
if (result) {
|
||||
$http.delete(baseUrlSrv.getRestApiBase() + '/credential/' + entity)
|
||||
.success(function (data, status, headers, config) {
|
||||
let index = _.findIndex($scope.credentialInfo, {'entity': entity});
|
||||
$scope.credentialInfo.splice(index, 1);
|
||||
console.log('Success %o %o', status, data.message);
|
||||
let 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);
|
||||
});
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
let init = function () {
|
||||
getAvailableInterpreters();
|
||||
getCredentialInfo();
|
||||
};
|
||||
getAvailableInterpreters()
|
||||
getCredentialInfo()
|
||||
}
|
||||
|
||||
init();
|
||||
init()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@
|
|||
*/
|
||||
export default class HandsonHelper {
|
||||
constructor (columns, rows, comment) {
|
||||
this.columns = columns || [];
|
||||
this.rows = rows || [];
|
||||
this.comment = comment || '';
|
||||
this._numericValidator = this._numericValidator.bind(this);
|
||||
this.columns = columns || []
|
||||
this.rows = rows || []
|
||||
this.comment = comment || ''
|
||||
this._numericValidator = this._numericValidator.bind(this)
|
||||
}
|
||||
|
||||
getHandsonTableConfig (columns, columnNames, resultRows) {
|
||||
let self = this;
|
||||
let self = this
|
||||
return {
|
||||
colHeaders: columnNames,
|
||||
data: resultRows,
|
||||
|
|
@ -42,32 +42,32 @@ export default class HandsonHelper {
|
|||
fragmentSelection: true,
|
||||
disableVisualSelection: true,
|
||||
cells: function (ro, co, pro) {
|
||||
let cellProperties = {};
|
||||
let colType = columns[co].type;
|
||||
let cellProperties = {}
|
||||
let colType = columns[co].type
|
||||
cellProperties.renderer = function (instance, td, row, col, prop, value, cellProperties) {
|
||||
self._cellRenderer(instance, td, row, col, prop, value, cellProperties, colType);
|
||||
};
|
||||
return cellProperties;
|
||||
self._cellRenderer(instance, td, row, col, prop, value, cellProperties, colType)
|
||||
}
|
||||
return cellProperties
|
||||
},
|
||||
afterGetColHeader: function (col, TH) {
|
||||
let instance = this;
|
||||
let menu = self._buildDropDownMenu(columns[col].type);
|
||||
let button = self._buildTypeSwitchButton();
|
||||
let instance = this
|
||||
let menu = self._buildDropDownMenu(columns[col].type)
|
||||
let button = self._buildTypeSwitchButton()
|
||||
|
||||
self._addButtonMenuEvent(button, menu);
|
||||
self._addButtonMenuEvent(button, menu)
|
||||
|
||||
Handsontable.Dom.addEvent(menu, 'click', function (event) {
|
||||
if (event.target.nodeName === 'LI') {
|
||||
self._setColumnType(columns, event.target.data.colType, instance, col);
|
||||
self._setColumnType(columns, event.target.data.colType, instance, col)
|
||||
}
|
||||
});
|
||||
})
|
||||
if (TH.firstChild.lastChild.nodeName === 'BUTTON') {
|
||||
TH.firstChild.removeChild(TH.firstChild.lastChild);
|
||||
TH.firstChild.removeChild(TH.firstChild.lastChild)
|
||||
}
|
||||
TH.firstChild.appendChild(button);
|
||||
TH.style['white-space'] = 'normal';
|
||||
TH.firstChild.appendChild(button)
|
||||
TH.style['white-space'] = 'normal'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -76,126 +76,126 @@ export default class HandsonHelper {
|
|||
|
||||
_addButtonMenuEvent (button, menu) {
|
||||
Handsontable.Dom.addEvent(button, 'click', function (event) {
|
||||
let changeTypeMenu;
|
||||
let position;
|
||||
let removeMenu;
|
||||
let changeTypeMenu
|
||||
let position
|
||||
let removeMenu
|
||||
|
||||
document.body.appendChild(menu);
|
||||
document.body.appendChild(menu)
|
||||
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault()
|
||||
event.stopImmediatePropagation()
|
||||
|
||||
changeTypeMenu = document.querySelectorAll('.changeTypeMenu');
|
||||
changeTypeMenu = document.querySelectorAll('.changeTypeMenu')
|
||||
|
||||
for (let i = 0, len = changeTypeMenu.length; i < len; i++) {
|
||||
changeTypeMenu[i].style.display = 'none';
|
||||
changeTypeMenu[i].style.display = 'none'
|
||||
}
|
||||
menu.style.display = 'block';
|
||||
position = button.getBoundingClientRect();
|
||||
menu.style.display = 'block'
|
||||
position = button.getBoundingClientRect()
|
||||
|
||||
menu.style.top = (position.top + (window.scrollY || window.pageYOffset)) + 2 + 'px';
|
||||
menu.style.left = (position.left) + 'px';
|
||||
menu.style.top = (position.top + (window.scrollY || window.pageYOffset)) + 2 + 'px'
|
||||
menu.style.left = (position.left) + 'px'
|
||||
|
||||
removeMenu = function (event) {
|
||||
if (menu.parentNode) {
|
||||
menu.parentNode.removeChild(menu);
|
||||
menu.parentNode.removeChild(menu)
|
||||
}
|
||||
};
|
||||
Handsontable.Dom.removeEvent(document, 'click', removeMenu);
|
||||
Handsontable.Dom.addEvent(document, 'click', removeMenu);
|
||||
});
|
||||
}
|
||||
Handsontable.Dom.removeEvent(document, 'click', removeMenu)
|
||||
Handsontable.Dom.addEvent(document, 'click', removeMenu)
|
||||
})
|
||||
}
|
||||
|
||||
_buildDropDownMenu (activeCellType) {
|
||||
let menu = document.createElement('UL');
|
||||
let types = ['text', 'numeric', 'date'];
|
||||
let item;
|
||||
let menu = document.createElement('UL')
|
||||
let types = ['text', 'numeric', 'date']
|
||||
let item
|
||||
|
||||
menu.className = 'changeTypeMenu';
|
||||
menu.className = 'changeTypeMenu'
|
||||
|
||||
for (let i = 0, len = types.length; i < len; i++) {
|
||||
item = document.createElement('LI');
|
||||
item = document.createElement('LI')
|
||||
if ('innerText' in item) {
|
||||
item.innerText = types[i];
|
||||
item.innerText = types[i]
|
||||
} else {
|
||||
item.textContent = types[i];
|
||||
item.textContent = types[i]
|
||||
}
|
||||
|
||||
item.data = {'colType': types[i]};
|
||||
item.data = {'colType': types[i]}
|
||||
|
||||
if (activeCellType === types[i]) {
|
||||
item.className = 'active';
|
||||
item.className = 'active'
|
||||
}
|
||||
menu.appendChild(item);
|
||||
menu.appendChild(item)
|
||||
}
|
||||
|
||||
return menu;
|
||||
return menu
|
||||
}
|
||||
|
||||
_buildTypeSwitchButton () {
|
||||
let button = document.createElement('BUTTON');
|
||||
let button = document.createElement('BUTTON')
|
||||
|
||||
button.innerHTML = '\u25BC';
|
||||
button.className = 'changeType';
|
||||
button.innerHTML = '\u25BC'
|
||||
button.className = 'changeType'
|
||||
|
||||
return button;
|
||||
return button
|
||||
}
|
||||
|
||||
_isNumeric (value) {
|
||||
if (!isNaN(value)) {
|
||||
if (value.length !== 0) {
|
||||
if (Number(value) <= Number.MAX_SAFE_INTEGER && Number(value) >= Number.MIN_SAFE_INTEGER) {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
_cellRenderer (instance, td, row, col, prop, value, cellProperties, colType) {
|
||||
if (colType === 'numeric' && this._isNumeric(value)) {
|
||||
cellProperties.format = '0,0.[00000]';
|
||||
td.style.textAlign = 'left';
|
||||
cellProperties.format = '0,0.[00000]'
|
||||
td.style.textAlign = 'left'
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
Handsontable.renderers.NumericRenderer.apply(this, arguments);
|
||||
Handsontable.renderers.NumericRenderer.apply(this, arguments)
|
||||
} else if (value.length > '%html'.length && value.substring(0, '%html '.length) === '%html ') {
|
||||
td.innerHTML = value.substring('%html'.length);
|
||||
td.innerHTML = value.substring('%html'.length)
|
||||
} else {
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
Handsontable.renderers.TextRenderer.apply(this, arguments);
|
||||
Handsontable.renderers.TextRenderer.apply(this, arguments)
|
||||
}
|
||||
}
|
||||
|
||||
_dateValidator (value, callback) {
|
||||
let d = moment(value);
|
||||
return callback(d.isValid());
|
||||
let d = moment(value)
|
||||
return callback(d.isValid())
|
||||
}
|
||||
|
||||
_numericValidator (value, callback) {
|
||||
return callback(this._isNumeric(value));
|
||||
return callback(this._isNumeric(value))
|
||||
}
|
||||
|
||||
_setColumnType (columns, type, instance, col) {
|
||||
columns[col].type = type;
|
||||
this._setColumnValidator(columns, col);
|
||||
instance.updateSettings({columns: columns});
|
||||
instance.validateCells(null);
|
||||
columns[col].type = type
|
||||
this._setColumnValidator(columns, col)
|
||||
instance.updateSettings({columns: columns})
|
||||
instance.validateCells(null)
|
||||
if (this._isColumnSorted(instance, col)) {
|
||||
instance.sort(col, instance.sortOrder);
|
||||
instance.sort(col, instance.sortOrder)
|
||||
}
|
||||
}
|
||||
|
||||
_isColumnSorted (instance, col) {
|
||||
return instance.sortingEnabled && instance.sortColumn === col;
|
||||
return instance.sortingEnabled && instance.sortColumn === col
|
||||
}
|
||||
|
||||
_setColumnValidator (columns, col) {
|
||||
if (columns[col].type === 'numeric') {
|
||||
columns[col].validator = this._numericValidator;
|
||||
columns[col].validator = this._numericValidator
|
||||
} else if (columns[col].type === 'date') {
|
||||
columns[col].validator = this._dateValidator;
|
||||
columns[col].validator = this._dateValidator
|
||||
} else {
|
||||
columns[col].validator = null;
|
||||
columns[col].validator = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,73 +16,73 @@ export const HeliumConfFieldType = {
|
|||
NUMBER: 'number',
|
||||
JSON: 'json',
|
||||
STRING: 'string',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param persisted <Object> including `type`, `description`, `defaultValue` for each conf key
|
||||
* @param spec <Object> including `value` for each conf key
|
||||
*/
|
||||
export function mergePersistedConfWithSpec (persisted, spec) {
|
||||
const confs = [];
|
||||
const confs = []
|
||||
|
||||
for (let name in spec) {
|
||||
const specField = spec[name];
|
||||
const persistedValue = persisted[name];
|
||||
const specField = spec[name]
|
||||
const persistedValue = persisted[name]
|
||||
|
||||
const value = (persistedValue) ? persistedValue : specField.defaultValue;
|
||||
const value = (persistedValue) ? persistedValue : specField.defaultValue
|
||||
const merged = {
|
||||
name: name,
|
||||
type: specField.type,
|
||||
description: specField.description,
|
||||
value: value,
|
||||
defaultValue: specField.defaultValue,
|
||||
};
|
||||
}
|
||||
|
||||
confs.push(merged);
|
||||
confs.push(merged)
|
||||
}
|
||||
|
||||
return confs;
|
||||
return confs
|
||||
}
|
||||
|
||||
export function createPackageConf (defaultPackages, persistedPackacgeConfs) {
|
||||
let packageConfs = {};
|
||||
let packageConfs = {}
|
||||
|
||||
for (let name in defaultPackages) {
|
||||
const pkgInfo = defaultPackages[name];
|
||||
const pkgInfo = defaultPackages[name]
|
||||
|
||||
const configSpec = pkgInfo.pkg.config;
|
||||
if (!configSpec) { continue; }
|
||||
const configSpec = pkgInfo.pkg.config
|
||||
if (!configSpec) { continue }
|
||||
|
||||
const version = pkgInfo.pkg.version;
|
||||
if (!version) { continue; }
|
||||
const version = pkgInfo.pkg.version
|
||||
if (!version) { continue }
|
||||
|
||||
let config = {};
|
||||
let config = {}
|
||||
if (persistedPackacgeConfs[name] && persistedPackacgeConfs[name][version]) {
|
||||
config = persistedPackacgeConfs[name][version];
|
||||
config = persistedPackacgeConfs[name][version]
|
||||
}
|
||||
|
||||
const confs = mergePersistedConfWithSpec(config, configSpec);
|
||||
packageConfs[name] = confs;
|
||||
const confs = mergePersistedConfWithSpec(config, configSpec)
|
||||
packageConfs[name] = confs
|
||||
}
|
||||
|
||||
return packageConfs;
|
||||
return packageConfs
|
||||
}
|
||||
|
||||
export function parseConfigValue (type, stringified) {
|
||||
let value = stringified;
|
||||
let value = stringified
|
||||
|
||||
try {
|
||||
if (HeliumConfFieldType.NUMBER === type) {
|
||||
value = parseFloat(stringified);
|
||||
value = parseFloat(stringified)
|
||||
} else if (HeliumConfFieldType.JSON === type) {
|
||||
value = JSON.parse(stringified);
|
||||
value = JSON.parse(stringified)
|
||||
}
|
||||
} catch (error) {
|
||||
// return just the stringified one
|
||||
console.error(`Failed to parse conf type ${type}, value ${value}`);
|
||||
console.error(`Failed to parse conf type ${type}, value ${value}`)
|
||||
}
|
||||
|
||||
return value;
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -92,10 +92,10 @@ export function createPersistableConfig (currentConf) {
|
|||
// persist key-value only
|
||||
// since other info (e.g type, desc) can be provided by default config
|
||||
const filtered = currentConf.reduce((acc, c) => {
|
||||
let value = parseConfigValue(c.type, c.value);
|
||||
acc[c.name] = value;
|
||||
return acc;
|
||||
}, {});
|
||||
let value = parseConfigValue(c.type, c.value)
|
||||
acc[c.name] = value
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return filtered;
|
||||
return filtered
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,17 +12,17 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { HeliumType, } from '../../components/helium/helium-type';
|
||||
import { HeliumType, } from '../../components/helium/helium-type'
|
||||
|
||||
export default function HeliumCtrl ($scope, $rootScope, $sce,
|
||||
baseUrlSrv, ngToast, heliumService) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
$scope.pkgSearchResults = {};
|
||||
$scope.defaultPackages = {};
|
||||
$scope.showVersions = {};
|
||||
$scope.bundleOrder = [];
|
||||
$scope.bundleOrderChanged = false;
|
||||
$scope.pkgSearchResults = {}
|
||||
$scope.defaultPackages = {}
|
||||
$scope.showVersions = {}
|
||||
$scope.bundleOrder = []
|
||||
$scope.bundleOrderChanged = false
|
||||
$scope.vizTypePkg = {}
|
||||
$scope.spellTypePkg = {}
|
||||
$scope.intpTypePkg = {}
|
||||
|
|
@ -30,34 +30,34 @@ export default function HeliumCtrl ($scope, $rootScope, $sce,
|
|||
$scope.numberOfEachPackageByType = {}
|
||||
$scope.allPackageTypes = [HeliumType][0]
|
||||
$scope.pkgListByType = 'VISUALIZATION'
|
||||
$scope.defaultPackageConfigs = {}; // { pkgName, [{name, type, desc, value, defaultValue}] }
|
||||
$scope.intpDefaultIcon = $sce.trustAsHtml('<img src="../assets/images/maven_default_icon.png" style="width: 12px"/>');
|
||||
$scope.defaultPackageConfigs = {} // { pkgName, [{name, type, desc, value, defaultValue}] }
|
||||
$scope.intpDefaultIcon = $sce.trustAsHtml('<img src="../assets/images/maven_default_icon.png" style="width: 12px"/>')
|
||||
|
||||
function init () {
|
||||
// get all package info and set config
|
||||
heliumService.getAllPackageInfoAndDefaultPackages()
|
||||
.then(({ pkgSearchResults, defaultPackages }) => {
|
||||
// pagination
|
||||
$scope.itemsPerPage = 10;
|
||||
$scope.currentPage = 1;
|
||||
$scope.maxSize = 5;
|
||||
$scope.itemsPerPage = 10
|
||||
$scope.currentPage = 1
|
||||
$scope.maxSize = 5
|
||||
|
||||
$scope.pkgSearchResults = pkgSearchResults;
|
||||
$scope.defaultPackages = defaultPackages;
|
||||
classifyPkgType($scope.defaultPackages);
|
||||
$scope.pkgSearchResults = pkgSearchResults
|
||||
$scope.defaultPackages = defaultPackages
|
||||
classifyPkgType($scope.defaultPackages)
|
||||
|
||||
return heliumService.getAllPackageConfigs()
|
||||
})
|
||||
.then(defaultPackageConfigs => {
|
||||
$scope.defaultPackageConfigs = defaultPackageConfigs;
|
||||
});
|
||||
$scope.defaultPackageConfigs = defaultPackageConfigs
|
||||
})
|
||||
|
||||
// 2. get vis package order
|
||||
heliumService.getVisualizationPackageOrder()
|
||||
.then(visPackageOrder => {
|
||||
$scope.bundleOrder = visPackageOrder;
|
||||
$scope.bundleOrderChanged = false;
|
||||
});
|
||||
$scope.bundleOrder = visPackageOrder
|
||||
$scope.bundleOrderChanged = false
|
||||
})
|
||||
}
|
||||
|
||||
let orderPackageByPubDate = function (a, b) {
|
||||
|
|
@ -66,36 +66,36 @@ export default function HeliumCtrl ($scope, $rootScope, $sce,
|
|||
a.pkg.published = new Date().getTime()
|
||||
}
|
||||
|
||||
return new Date(a.pkg.published).getTime() - new Date(b.pkg.published).getTime();
|
||||
};
|
||||
return new Date(a.pkg.published).getTime() - new Date(b.pkg.published).getTime()
|
||||
}
|
||||
|
||||
const classifyPkgType = function (packageInfo) {
|
||||
let allTypesOfPkg = {};
|
||||
let vizTypePkg = [];
|
||||
let spellTypePkg = [];
|
||||
let intpTypePkg = [];
|
||||
let appTypePkg = [];
|
||||
let allTypesOfPkg = {}
|
||||
let vizTypePkg = []
|
||||
let spellTypePkg = []
|
||||
let intpTypePkg = []
|
||||
let appTypePkg = []
|
||||
|
||||
let packageInfoArr = Object.keys(packageInfo).map(key => packageInfo[key])
|
||||
packageInfoArr = packageInfoArr.sort(orderPackageByPubDate).reverse();
|
||||
packageInfoArr = packageInfoArr.sort(orderPackageByPubDate).reverse()
|
||||
|
||||
for (let name in packageInfoArr) {
|
||||
let pkgs = packageInfoArr[name];
|
||||
let pkgType = pkgs.pkg.type;
|
||||
let pkgs = packageInfoArr[name]
|
||||
let pkgType = pkgs.pkg.type
|
||||
|
||||
switch (pkgType) {
|
||||
case HeliumType.VISUALIZATION:
|
||||
vizTypePkg.push(pkgs);
|
||||
break;
|
||||
vizTypePkg.push(pkgs)
|
||||
break
|
||||
case HeliumType.SPELL:
|
||||
spellTypePkg.push(pkgs);
|
||||
break;
|
||||
spellTypePkg.push(pkgs)
|
||||
break
|
||||
case HeliumType.INTERPRETER:
|
||||
intpTypePkg.push(pkgs);
|
||||
break;
|
||||
intpTypePkg.push(pkgs)
|
||||
break
|
||||
case HeliumType.APPLICATION:
|
||||
appTypePkg.push(pkgs);
|
||||
break;
|
||||
appTypePkg.push(pkgs)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,19 +106,19 @@ export default function HeliumCtrl ($scope, $rootScope, $sce,
|
|||
appTypePkg
|
||||
]
|
||||
for (let idx in _.keys(HeliumType)) {
|
||||
allTypesOfPkg[_.keys(HeliumType)[idx]] = pkgsArr[idx];
|
||||
allTypesOfPkg[_.keys(HeliumType)[idx]] = pkgsArr[idx]
|
||||
}
|
||||
|
||||
$scope.allTypesOfPkg = allTypesOfPkg;
|
||||
};
|
||||
$scope.allTypesOfPkg = allTypesOfPkg
|
||||
}
|
||||
|
||||
$scope.bundleOrderListeners = {
|
||||
accept: function (sourceItemHandleScope, destSortableScope) { return true; },
|
||||
accept: function (sourceItemHandleScope, destSortableScope) { return true },
|
||||
itemMoved: function (event) {},
|
||||
orderChanged: function (event) {
|
||||
$scope.bundleOrderChanged = true;
|
||||
$scope.bundleOrderChanged = true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.saveBundleOrder = function () {
|
||||
const confirm = BootstrapDialog.confirm({
|
||||
|
|
@ -129,67 +129,67 @@ export default function HeliumCtrl ($scope, $rootScope, $sce,
|
|||
message: 'Save changes?',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
confirm.$modalFooter.find('button').addClass('disabled');
|
||||
confirm.$modalFooter.find('button').addClass('disabled')
|
||||
confirm.$modalFooter.find('button:contains("OK")')
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Enabling');
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Enabling')
|
||||
heliumService.setVisualizationPackageOrder($scope.bundleOrder)
|
||||
.success(function (data, status) {
|
||||
init();
|
||||
confirm.close();
|
||||
init()
|
||||
confirm.close()
|
||||
})
|
||||
.error(function (data, status) {
|
||||
confirm.close();
|
||||
console.log('Failed to save order');
|
||||
confirm.close()
|
||||
console.log('Failed to save order')
|
||||
BootstrapDialog.show({
|
||||
title: 'Error on saving order ',
|
||||
message: data.message
|
||||
});
|
||||
});
|
||||
return false;
|
||||
})
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
let getLicense = function (name, artifact) {
|
||||
let filteredPkgSearchResults = _.filter($scope.defaultPackages[name], function (p) {
|
||||
return p.artifact === artifact;
|
||||
});
|
||||
return p.artifact === artifact
|
||||
})
|
||||
|
||||
let license;
|
||||
let license
|
||||
if (filteredPkgSearchResults.length === 0) {
|
||||
filteredPkgSearchResults = _.filter($scope.pkgSearchResults[name], function (p) {
|
||||
return p.pkg.artifact === artifact;
|
||||
});
|
||||
return p.pkg.artifact === artifact
|
||||
})
|
||||
|
||||
if (filteredPkgSearchResults.length > 0) {
|
||||
license = filteredPkgSearchResults[0].pkg.license;
|
||||
license = filteredPkgSearchResults[0].pkg.license
|
||||
}
|
||||
} else {
|
||||
license = filteredPkgSearchResults[0].license;
|
||||
license = filteredPkgSearchResults[0].license
|
||||
}
|
||||
|
||||
if (!license) {
|
||||
license = 'Unknown';
|
||||
license = 'Unknown'
|
||||
}
|
||||
return license;
|
||||
return license
|
||||
}
|
||||
|
||||
const getHeliumTypeText = function (type) {
|
||||
if (type === HeliumType.VISUALIZATION) {
|
||||
return `<a target="_blank" href="https://zeppelin.apache.org/docs/${$rootScope.zeppelinVersion}/development/writingzeppelinvisualization.html">${type}</a>`; // eslint-disable-line max-len
|
||||
return `<a target="_blank" href="https://zeppelin.apache.org/docs/${$rootScope.zeppelinVersion}/development/writingzeppelinvisualization.html">${type}</a>` // eslint-disable-line max-len
|
||||
} else if (type === HeliumType.SPELL) {
|
||||
return `<a target="_blank" href="https://zeppelin.apache.org/docs/${$rootScope.zeppelinVersion}/development/writingzeppelinspell.html">${type}</a>`; // eslint-disable-line max-len
|
||||
return `<a target="_blank" href="https://zeppelin.apache.org/docs/${$rootScope.zeppelinVersion}/development/writingzeppelinspell.html">${type}</a>` // eslint-disable-line max-len
|
||||
} else {
|
||||
return type;
|
||||
return type
|
||||
}
|
||||
}
|
||||
|
||||
$scope.enable = function (name, artifact, type, groupId, description) {
|
||||
let license = getLicense(name, artifact);
|
||||
let mavenArtifactInfoToHTML = groupId + ':' + artifact.split('@')[0] + ':' + artifact.split('@')[1];
|
||||
let zeppelinVersion = $rootScope.zeppelinVersion;
|
||||
let url = 'https://zeppelin.apache.org/docs/' + zeppelinVersion + '/manual/interpreterinstallation.html';
|
||||
let license = getLicense(name, artifact)
|
||||
let mavenArtifactInfoToHTML = groupId + ':' + artifact.split('@')[0] + ':' + artifact.split('@')[1]
|
||||
let zeppelinVersion = $rootScope.zeppelinVersion
|
||||
let url = 'https://zeppelin.apache.org/docs/' + zeppelinVersion + '/manual/interpreterinstallation.html'
|
||||
|
||||
let confirm = ''
|
||||
if (type === HeliumType.INTERPRETER) {
|
||||
|
|
@ -205,7 +205,7 @@ export default function HeliumCtrl ($scope, $rootScope, $sce,
|
|||
'<p>After restart Zeppelin, create interpreter setting and bind it with your note. ' +
|
||||
'For more detailed information, see <a target="_blank" href=' +
|
||||
url + '>Interpreter Installation.</a></p>'
|
||||
});
|
||||
})
|
||||
} else {
|
||||
confirm = BootstrapDialog.confirm({
|
||||
closable: false,
|
||||
|
|
@ -226,26 +226,26 @@ export default function HeliumCtrl ($scope, $rootScope, $sce,
|
|||
`<div style="color:gray">${license}</div>`,
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
confirm.$modalFooter.find('button').addClass('disabled');
|
||||
confirm.$modalFooter.find('button').addClass('disabled')
|
||||
confirm.$modalFooter.find('button:contains("OK")')
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Enabling');
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Enabling')
|
||||
heliumService.enable(name, artifact, type).success(function (data, status) {
|
||||
init();
|
||||
confirm.close();
|
||||
init()
|
||||
confirm.close()
|
||||
}).error(function (data, status) {
|
||||
confirm.close();
|
||||
console.log('Failed to enable package %o %o. %o', name, artifact, data);
|
||||
confirm.close()
|
||||
console.log('Failed to enable package %o %o. %o', name, artifact, data)
|
||||
BootstrapDialog.show({
|
||||
title: 'Error on enabling ' + name,
|
||||
message: data.message
|
||||
});
|
||||
});
|
||||
return false;
|
||||
})
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.disable = function (name, artifact) {
|
||||
const confirm = BootstrapDialog.confirm({
|
||||
|
|
@ -256,52 +256,52 @@ export default function HeliumCtrl ($scope, $rootScope, $sce,
|
|||
message: artifact,
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
confirm.$modalFooter.find('button').addClass('disabled');
|
||||
confirm.$modalFooter.find('button').addClass('disabled')
|
||||
confirm.$modalFooter.find('button:contains("OK")')
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Disabling');
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Disabling')
|
||||
heliumService.disable(name)
|
||||
.success(function (data, status) {
|
||||
init();
|
||||
confirm.close();
|
||||
init()
|
||||
confirm.close()
|
||||
})
|
||||
.error(function (data, status) {
|
||||
confirm.close();
|
||||
console.log('Failed to disable package %o. %o', name, data);
|
||||
confirm.close()
|
||||
console.log('Failed to disable package %o. %o', name, data)
|
||||
BootstrapDialog.show({
|
||||
title: 'Error on disabling ' + name,
|
||||
message: data.message
|
||||
});
|
||||
});
|
||||
return false;
|
||||
})
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
$scope.toggleVersions = function (pkgName) {
|
||||
if ($scope.showVersions[pkgName]) {
|
||||
$scope.showVersions[pkgName] = false;
|
||||
$scope.showVersions[pkgName] = false
|
||||
} else {
|
||||
$scope.showVersions[pkgName] = true;
|
||||
$scope.showVersions[pkgName] = true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.isLocalPackage = function (pkgSearchResult) {
|
||||
const pkg = pkgSearchResult.pkg;
|
||||
return pkg.artifact && !pkg.artifact.includes('@');
|
||||
};
|
||||
const pkg = pkgSearchResult.pkg
|
||||
return pkg.artifact && !pkg.artifact.includes('@')
|
||||
}
|
||||
|
||||
$scope.hasNpmLink = function (pkgSearchResult) {
|
||||
const pkg = pkgSearchResult.pkg;
|
||||
const pkg = pkgSearchResult.pkg
|
||||
return (pkg.type === HeliumType.SPELL || pkg.type === HeliumType.VISUALIZATION) &&
|
||||
!$scope.isLocalPackage(pkgSearchResult);
|
||||
};
|
||||
!$scope.isLocalPackage(pkgSearchResult)
|
||||
}
|
||||
|
||||
$scope.hasMavenLink = function (pkgSearchResult) {
|
||||
const pkg = pkgSearchResult.pkg;
|
||||
const pkg = pkgSearchResult.pkg
|
||||
return (pkg.type === HeliumType.APPLICATION || pkg.type === HeliumType.INTERPRETER) &&
|
||||
!$scope.isLocalPackage(pkgSearchResult);
|
||||
};
|
||||
!$scope.isLocalPackage(pkgSearchResult)
|
||||
}
|
||||
|
||||
$scope.getPackageSize = function (pkgSearchResult, targetPkgType) {
|
||||
let result = []
|
||||
|
|
@ -313,49 +313,49 @@ export default function HeliumCtrl ($scope, $rootScope, $sce,
|
|||
|
||||
$scope.configExists = function (pkgSearchResult) {
|
||||
// helium package config is persisted per version
|
||||
return pkgSearchResult.pkg.config && pkgSearchResult.pkg.artifact;
|
||||
};
|
||||
return pkgSearchResult.pkg.config && pkgSearchResult.pkg.artifact
|
||||
}
|
||||
|
||||
$scope.configOpened = function (pkgSearchResult) {
|
||||
return pkgSearchResult.configOpened && !pkgSearchResult.configFetching;
|
||||
};
|
||||
return pkgSearchResult.configOpened && !pkgSearchResult.configFetching
|
||||
}
|
||||
|
||||
$scope.getConfigButtonClass = function (pkgSearchResult) {
|
||||
return (pkgSearchResult.configOpened && pkgSearchResult.configFetching)
|
||||
? 'disabled' : '';
|
||||
? 'disabled' : ''
|
||||
}
|
||||
|
||||
$scope.toggleConfigButton = function (pkgSearchResult) {
|
||||
if (pkgSearchResult.configOpened) {
|
||||
pkgSearchResult.configOpened = false;
|
||||
return;
|
||||
pkgSearchResult.configOpened = false
|
||||
return
|
||||
}
|
||||
|
||||
const pkg = pkgSearchResult.pkg;
|
||||
const pkgName = pkg.name;
|
||||
pkgSearchResult.configFetching = true;
|
||||
pkgSearchResult.configOpened = true;
|
||||
const pkg = pkgSearchResult.pkg
|
||||
const pkgName = pkg.name
|
||||
pkgSearchResult.configFetching = true
|
||||
pkgSearchResult.configOpened = true
|
||||
|
||||
heliumService.getSinglePackageConfigs(pkg)
|
||||
.then(confs => {
|
||||
$scope.defaultPackageConfigs[pkgName] = confs;
|
||||
pkgSearchResult.configFetching = false;
|
||||
});
|
||||
};
|
||||
$scope.defaultPackageConfigs[pkgName] = confs
|
||||
pkgSearchResult.configFetching = false
|
||||
})
|
||||
}
|
||||
|
||||
$scope.saveConfig = function (pkgSearchResult) {
|
||||
const pkgName = pkgSearchResult.pkg.name;
|
||||
const currentConf = $scope.defaultPackageConfigs[pkgName];
|
||||
const pkgName = pkgSearchResult.pkg.name
|
||||
const currentConf = $scope.defaultPackageConfigs[pkgName]
|
||||
|
||||
heliumService.saveConfig(pkgSearchResult.pkg, currentConf, () => {
|
||||
// close after config is saved
|
||||
pkgSearchResult.configOpened = false;
|
||||
});
|
||||
};
|
||||
pkgSearchResult.configOpened = false
|
||||
})
|
||||
}
|
||||
|
||||
$scope.getDescriptionText = function (pkgSearchResult) {
|
||||
return $sce.trustAsHtml(pkgSearchResult.pkg.description);
|
||||
};
|
||||
return $sce.trustAsHtml(pkgSearchResult.pkg.description)
|
||||
}
|
||||
|
||||
init();
|
||||
init()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import HeliumController from './helium.controller';
|
||||
import HeliumController from './helium.controller'
|
||||
|
||||
angular.module('zeppelinWebApp')
|
||||
.controller('HeliumCtrl', HeliumController);
|
||||
.controller('HeliumCtrl', HeliumController)
|
||||
|
|
|
|||
|
|
@ -12,135 +12,135 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('HomeCtrl', HomeCtrl);
|
||||
angular.module('zeppelinWebApp').controller('HomeCtrl', HomeCtrl)
|
||||
|
||||
function HomeCtrl ($scope, noteListDataFactory, websocketMsgSrv, $rootScope, arrayOrderingSrv,
|
||||
ngToast, noteActionSrv, TRASH_FOLDER_ID) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
ngToast.dismiss();
|
||||
let vm = this;
|
||||
vm.notes = noteListDataFactory;
|
||||
vm.websocketMsgSrv = websocketMsgSrv;
|
||||
vm.arrayOrderingSrv = arrayOrderingSrv;
|
||||
ngToast.dismiss()
|
||||
let vm = this
|
||||
vm.notes = noteListDataFactory
|
||||
vm.websocketMsgSrv = websocketMsgSrv
|
||||
vm.arrayOrderingSrv = arrayOrderingSrv
|
||||
|
||||
vm.notebookHome = false;
|
||||
vm.noteCustomHome = true;
|
||||
vm.notebookHome = false
|
||||
vm.noteCustomHome = true
|
||||
if ($rootScope.ticket !== undefined) {
|
||||
vm.staticHome = false;
|
||||
vm.staticHome = false
|
||||
} else {
|
||||
vm.staticHome = true;
|
||||
vm.staticHome = true
|
||||
}
|
||||
|
||||
$scope.isReloading = false;
|
||||
$scope.TRASH_FOLDER_ID = TRASH_FOLDER_ID;
|
||||
$scope.query = {q: ''};
|
||||
$scope.isReloading = false
|
||||
$scope.TRASH_FOLDER_ID = TRASH_FOLDER_ID
|
||||
$scope.query = {q: ''}
|
||||
|
||||
$scope.initHome = function () {
|
||||
websocketMsgSrv.getHomeNote();
|
||||
vm.noteCustomHome = false;
|
||||
};
|
||||
websocketMsgSrv.getHomeNote()
|
||||
vm.noteCustomHome = false
|
||||
}
|
||||
|
||||
$scope.reloadNoteList = function () {
|
||||
websocketMsgSrv.reloadAllNotesFromRepo();
|
||||
$scope.isReloadingNotes = true;
|
||||
};
|
||||
websocketMsgSrv.reloadAllNotesFromRepo()
|
||||
$scope.isReloadingNotes = true
|
||||
}
|
||||
|
||||
$scope.toggleFolderNode = function (node) {
|
||||
node.hidden = !node.hidden;
|
||||
};
|
||||
node.hidden = !node.hidden
|
||||
}
|
||||
|
||||
angular.element('#loginModal').on('hidden.bs.modal', function (e) {
|
||||
$rootScope.$broadcast('initLoginValues');
|
||||
});
|
||||
$rootScope.$broadcast('initLoginValues')
|
||||
})
|
||||
|
||||
/*
|
||||
** $scope.$on functions below
|
||||
*/
|
||||
|
||||
$scope.$on('setNoteMenu', function (event, notes) {
|
||||
$scope.isReloadingNotes = false;
|
||||
});
|
||||
$scope.isReloadingNotes = false
|
||||
})
|
||||
|
||||
$scope.$on('setNoteContent', function (event, note) {
|
||||
if (vm.noteCustomHome) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
if (note) {
|
||||
vm.note = note;
|
||||
vm.note = note
|
||||
|
||||
// initialize look And Feel
|
||||
$rootScope.$broadcast('setLookAndFeel', 'home');
|
||||
$rootScope.$broadcast('setLookAndFeel', 'home')
|
||||
|
||||
// make it read only
|
||||
vm.viewOnly = true;
|
||||
vm.viewOnly = true
|
||||
|
||||
vm.notebookHome = true;
|
||||
vm.staticHome = false;
|
||||
vm.notebookHome = true
|
||||
vm.staticHome = false
|
||||
} else {
|
||||
vm.staticHome = true;
|
||||
vm.notebookHome = false;
|
||||
vm.staticHome = true
|
||||
vm.notebookHome = false
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
$scope.renameNote = function (nodeId, nodePath) {
|
||||
noteActionSrv.renameNote(nodeId, nodePath);
|
||||
};
|
||||
noteActionSrv.renameNote(nodeId, nodePath)
|
||||
}
|
||||
|
||||
$scope.moveNoteToTrash = function (noteId) {
|
||||
noteActionSrv.moveNoteToTrash(noteId, false);
|
||||
};
|
||||
noteActionSrv.moveNoteToTrash(noteId, false)
|
||||
}
|
||||
|
||||
$scope.moveFolderToTrash = function (folderId) {
|
||||
noteActionSrv.moveFolderToTrash(folderId);
|
||||
};
|
||||
noteActionSrv.moveFolderToTrash(folderId)
|
||||
}
|
||||
|
||||
$scope.restoreNote = function (noteId) {
|
||||
websocketMsgSrv.restoreNote(noteId);
|
||||
};
|
||||
websocketMsgSrv.restoreNote(noteId)
|
||||
}
|
||||
|
||||
$scope.restoreFolder = function (folderId) {
|
||||
websocketMsgSrv.restoreFolder(folderId);
|
||||
};
|
||||
websocketMsgSrv.restoreFolder(folderId)
|
||||
}
|
||||
|
||||
$scope.restoreAll = function () {
|
||||
noteActionSrv.restoreAll();
|
||||
};
|
||||
noteActionSrv.restoreAll()
|
||||
}
|
||||
|
||||
$scope.renameFolder = function (node) {
|
||||
noteActionSrv.renameFolder(node.id);
|
||||
};
|
||||
noteActionSrv.renameFolder(node.id)
|
||||
}
|
||||
|
||||
$scope.removeNote = function (noteId) {
|
||||
noteActionSrv.removeNote(noteId, false);
|
||||
};
|
||||
noteActionSrv.removeNote(noteId, false)
|
||||
}
|
||||
|
||||
$scope.removeFolder = function (folderId) {
|
||||
noteActionSrv.removeFolder(folderId);
|
||||
};
|
||||
noteActionSrv.removeFolder(folderId)
|
||||
}
|
||||
|
||||
$scope.emptyTrash = function () {
|
||||
noteActionSrv.emptyTrash();
|
||||
};
|
||||
noteActionSrv.emptyTrash()
|
||||
}
|
||||
|
||||
$scope.clearAllParagraphOutput = function (noteId) {
|
||||
noteActionSrv.clearAllParagraphOutput(noteId);
|
||||
};
|
||||
noteActionSrv.clearAllParagraphOutput(noteId)
|
||||
}
|
||||
|
||||
$scope.isFilterNote = function (note) {
|
||||
if (!$scope.query.q) {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
let noteName = note.name;
|
||||
let noteName = note.name
|
||||
if (noteName.toLowerCase().indexOf($scope.query.q.toLowerCase()) > -1) {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return false
|
||||
}
|
||||
|
||||
$scope.getNoteName = function (note) {
|
||||
return arrayOrderingSrv.getNoteName(note);
|
||||
};
|
||||
return arrayOrderingSrv.getNoteName(note)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,29 +12,29 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ParagraphStatus, } from '../notebook/paragraph/paragraph.status';
|
||||
import { ParagraphStatus, } from '../notebook/paragraph/paragraph.status'
|
||||
|
||||
angular.module('zeppelinWebApp').controller('InterpreterCtrl', InterpreterCtrl);
|
||||
angular.module('zeppelinWebApp').controller('InterpreterCtrl', InterpreterCtrl)
|
||||
|
||||
function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeout, $route) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let interpreterSettingsTmp = [];
|
||||
$scope.interpreterSettings = [];
|
||||
$scope.availableInterpreters = {};
|
||||
$scope.showAddNewSetting = false;
|
||||
$scope.showRepositoryInfo = false;
|
||||
$scope.searchInterpreter = '';
|
||||
$scope._ = _;
|
||||
ngToast.dismiss();
|
||||
let interpreterSettingsTmp = []
|
||||
$scope.interpreterSettings = []
|
||||
$scope.availableInterpreters = {}
|
||||
$scope.showAddNewSetting = false
|
||||
$scope.showRepositoryInfo = false
|
||||
$scope.searchInterpreter = ''
|
||||
$scope._ = _
|
||||
ngToast.dismiss()
|
||||
|
||||
$scope.openPermissions = function () {
|
||||
$scope.showInterpreterAuth = true;
|
||||
};
|
||||
$scope.showInterpreterAuth = true
|
||||
}
|
||||
|
||||
$scope.closePermissions = function () {
|
||||
$scope.showInterpreterAuth = false;
|
||||
};
|
||||
$scope.showInterpreterAuth = false
|
||||
}
|
||||
|
||||
let getSelectJson = function () {
|
||||
let selectJson = {
|
||||
|
|
@ -45,19 +45,19 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
ajax: {
|
||||
url: function (params) {
|
||||
if (!params.term) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
return baseUrlSrv.getRestApiBase() + '/security/userlist/' + params.term;
|
||||
return baseUrlSrv.getRestApiBase() + '/security/userlist/' + params.term
|
||||
},
|
||||
delay: 250,
|
||||
processResults: function (data, params) {
|
||||
let users = [];
|
||||
let users = []
|
||||
if (data.body.users.length !== 0) {
|
||||
for (let i = 0; i < data.body.users.length; i++) {
|
||||
users.push({
|
||||
'id': data.body.users[i],
|
||||
'text': data.body.users[i]
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
|
|
@ -65,55 +65,55 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
pagination: {
|
||||
more: false
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
cache: false
|
||||
}
|
||||
};
|
||||
return selectJson;
|
||||
};
|
||||
}
|
||||
return selectJson
|
||||
}
|
||||
|
||||
$scope.togglePermissions = function (intpName) {
|
||||
angular.element('#' + intpName + 'Users').select2(getSelectJson());
|
||||
angular.element('#' + intpName + 'Users').select2(getSelectJson())
|
||||
if ($scope.showInterpreterAuth) {
|
||||
$scope.closePermissions();
|
||||
$scope.closePermissions()
|
||||
} else {
|
||||
$scope.openPermissions();
|
||||
$scope.openPermissions()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.$on('ngRenderFinished', function (event, data) {
|
||||
for (let setting = 0; setting < $scope.interpreterSettings.length; setting++) {
|
||||
angular.element('#' + $scope.interpreterSettings[setting].name + 'Users').select2(getSelectJson());
|
||||
angular.element('#' + $scope.interpreterSettings[setting].name + 'Users').select2(getSelectJson())
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
let getInterpreterSettings = function () {
|
||||
$http.get(baseUrlSrv.getRestApiBase() + '/interpreter/setting')
|
||||
.success(function (data, status, headers, config) {
|
||||
$scope.interpreterSettings = data.body;
|
||||
checkDownloadingDependencies();
|
||||
$scope.interpreterSettings = data.body
|
||||
checkDownloadingDependencies()
|
||||
}).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);
|
||||
window.location.replace('/')
|
||||
}, 3000)
|
||||
}
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
|
||||
const checkDownloadingDependencies = function () {
|
||||
let isDownloading = false;
|
||||
let isDownloading = false
|
||||
for (let index = 0; index < $scope.interpreterSettings.length; index++) {
|
||||
let setting = $scope.interpreterSettings[index];
|
||||
let setting = $scope.interpreterSettings[index]
|
||||
if (setting.status === 'DOWNLOADING_DEPENDENCIES') {
|
||||
isDownloading = true;
|
||||
isDownloading = true
|
||||
}
|
||||
|
||||
if (setting.status === ParagraphStatus.ERROR || setting.errorReason) {
|
||||
|
|
@ -121,186 +121,186 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
setting.group + '.' + setting.name + '\': ' + setting.errorReason,
|
||||
verticalPosition: 'top',
|
||||
dismissOnTimeout: false
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (isDownloading) {
|
||||
$timeout(function () {
|
||||
if ($route.current.$$route.originalPath === '/interpreter') {
|
||||
getInterpreterSettings();
|
||||
getInterpreterSettings()
|
||||
}
|
||||
}, 2000);
|
||||
}, 2000)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let getAvailableInterpreters = function () {
|
||||
$http.get(baseUrlSrv.getRestApiBase() + '/interpreter').success(function (data, status, headers, config) {
|
||||
$scope.availableInterpreters = data.body;
|
||||
$scope.availableInterpreters = data.body
|
||||
}).error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
|
||||
let emptyNewProperty = function (object) {
|
||||
angular.extend(object, {propertyValue: '', propertyKey: ''});
|
||||
};
|
||||
angular.extend(object, {propertyValue: '', propertyKey: ''})
|
||||
}
|
||||
|
||||
let emptyNewDependency = function (object) {
|
||||
angular.extend(object, {depArtifact: '', depExclude: ''});
|
||||
};
|
||||
angular.extend(object, {depArtifact: '', depExclude: ''})
|
||||
}
|
||||
|
||||
let removeTMPSettings = function (index) {
|
||||
interpreterSettingsTmp.splice(index, 1);
|
||||
};
|
||||
interpreterSettingsTmp.splice(index, 1)
|
||||
}
|
||||
|
||||
$scope.copyOriginInterpreterSettingProperties = function (settingId) {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
interpreterSettingsTmp[index] = angular.copy($scope.interpreterSettings[index]);
|
||||
};
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
interpreterSettingsTmp[index] = angular.copy($scope.interpreterSettings[index])
|
||||
}
|
||||
|
||||
$scope.setPerNoteOption = function (settingId, sessionOption) {
|
||||
let option;
|
||||
let option
|
||||
if (settingId === undefined) {
|
||||
option = $scope.newInterpreterSetting.option;
|
||||
option = $scope.newInterpreterSetting.option
|
||||
} else {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let setting = $scope.interpreterSettings[index];
|
||||
option = setting.option;
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
let setting = $scope.interpreterSettings[index]
|
||||
option = setting.option
|
||||
}
|
||||
|
||||
if (sessionOption === 'isolated') {
|
||||
option.perNote = sessionOption;
|
||||
option.session = false;
|
||||
option.process = true;
|
||||
option.perNote = sessionOption
|
||||
option.session = false
|
||||
option.process = true
|
||||
} else if (sessionOption === 'scoped') {
|
||||
option.perNote = sessionOption;
|
||||
option.session = true;
|
||||
option.process = false;
|
||||
option.perNote = sessionOption
|
||||
option.session = true
|
||||
option.process = false
|
||||
} else {
|
||||
option.perNote = 'shared';
|
||||
option.session = false;
|
||||
option.process = false;
|
||||
option.perNote = 'shared'
|
||||
option.session = false
|
||||
option.process = false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.setPerUserOption = function (settingId, sessionOption) {
|
||||
let option;
|
||||
let option
|
||||
if (settingId === undefined) {
|
||||
option = $scope.newInterpreterSetting.option;
|
||||
option = $scope.newInterpreterSetting.option
|
||||
} else {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let setting = $scope.interpreterSettings[index];
|
||||
option = setting.option;
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
let setting = $scope.interpreterSettings[index]
|
||||
option = setting.option
|
||||
}
|
||||
|
||||
if (sessionOption === 'isolated') {
|
||||
option.perUser = sessionOption;
|
||||
option.session = false;
|
||||
option.process = true;
|
||||
option.perUser = sessionOption
|
||||
option.session = false
|
||||
option.process = true
|
||||
} else if (sessionOption === 'scoped') {
|
||||
option.perUser = sessionOption;
|
||||
option.session = true;
|
||||
option.process = false;
|
||||
option.perUser = sessionOption
|
||||
option.session = true
|
||||
option.process = false
|
||||
} else {
|
||||
option.perUser = 'shared';
|
||||
option.session = false;
|
||||
option.process = false;
|
||||
option.perUser = 'shared'
|
||||
option.session = false
|
||||
option.process = false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.getPerNoteOption = function (settingId) {
|
||||
let option;
|
||||
let option
|
||||
if (settingId === undefined) {
|
||||
option = $scope.newInterpreterSetting.option;
|
||||
option = $scope.newInterpreterSetting.option
|
||||
} else {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let setting = $scope.interpreterSettings[index];
|
||||
option = setting.option;
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
let setting = $scope.interpreterSettings[index]
|
||||
option = setting.option
|
||||
}
|
||||
|
||||
if (option.perNote === 'scoped') {
|
||||
return 'scoped';
|
||||
return 'scoped'
|
||||
} else if (option.perNote === 'isolated') {
|
||||
return 'isolated';
|
||||
return 'isolated'
|
||||
} else {
|
||||
return 'shared';
|
||||
return 'shared'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.getPerUserOption = function (settingId) {
|
||||
let option;
|
||||
let option
|
||||
if (settingId === undefined) {
|
||||
option = $scope.newInterpreterSetting.option;
|
||||
option = $scope.newInterpreterSetting.option
|
||||
} else {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let setting = $scope.interpreterSettings[index];
|
||||
option = setting.option;
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
let setting = $scope.interpreterSettings[index]
|
||||
option = setting.option
|
||||
}
|
||||
|
||||
if (option.perUser === 'scoped') {
|
||||
return 'scoped';
|
||||
return 'scoped'
|
||||
} else if (option.perUser === 'isolated') {
|
||||
return 'isolated';
|
||||
return 'isolated'
|
||||
} else {
|
||||
return 'shared';
|
||||
return 'shared'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.getInterpreterRunningOption = function (settingId) {
|
||||
let sharedModeName = 'shared';
|
||||
let sharedModeName = 'shared'
|
||||
|
||||
let globallyModeName = 'Globally';
|
||||
let perNoteModeName = 'Per Note';
|
||||
let perUserModeName = 'Per User';
|
||||
let globallyModeName = 'Globally'
|
||||
let perNoteModeName = 'Per Note'
|
||||
let perUserModeName = 'Per User'
|
||||
|
||||
let option;
|
||||
let option
|
||||
if (settingId === undefined) {
|
||||
option = $scope.newInterpreterSetting.option;
|
||||
option = $scope.newInterpreterSetting.option
|
||||
} else {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let setting = $scope.interpreterSettings[index];
|
||||
option = setting.option;
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
let setting = $scope.interpreterSettings[index]
|
||||
option = setting.option
|
||||
}
|
||||
|
||||
let perNote = option.perNote;
|
||||
let perUser = option.perUser;
|
||||
let perNote = option.perNote
|
||||
let perUser = option.perUser
|
||||
|
||||
// Globally == shared_perNote + shared_perUser
|
||||
if (perNote === sharedModeName && perUser === sharedModeName) {
|
||||
return globallyModeName;
|
||||
return globallyModeName
|
||||
}
|
||||
|
||||
if ($rootScope.ticket.ticket === 'anonymous' && $rootScope.ticket.roles === '[]') {
|
||||
if (perNote !== undefined && typeof perNote === 'string' && perNote !== '') {
|
||||
return perNoteModeName;
|
||||
return perNoteModeName
|
||||
}
|
||||
} else if ($rootScope.ticket.ticket !== 'anonymous') {
|
||||
if (perNote !== undefined && typeof perNote === 'string' && perNote !== '') {
|
||||
if (perUser !== undefined && typeof perUser === 'string' && perUser !== '') {
|
||||
return perUserModeName;
|
||||
return perUserModeName
|
||||
}
|
||||
return perNoteModeName;
|
||||
return perNoteModeName
|
||||
}
|
||||
}
|
||||
|
||||
option.perNote = sharedModeName;
|
||||
option.perUser = sharedModeName;
|
||||
return globallyModeName;
|
||||
};
|
||||
option.perNote = sharedModeName
|
||||
option.perUser = sharedModeName
|
||||
return globallyModeName
|
||||
}
|
||||
|
||||
$scope.setInterpreterRunningOption = function (settingId, isPerNoteMode, isPerUserMode) {
|
||||
let option;
|
||||
let option
|
||||
if (settingId === undefined) {
|
||||
option = $scope.newInterpreterSetting.option;
|
||||
option = $scope.newInterpreterSetting.option
|
||||
} else {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let setting = $scope.interpreterSettings[index];
|
||||
option = setting.option;
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
let setting = $scope.interpreterSettings[index]
|
||||
option = setting.option
|
||||
}
|
||||
option.perNote = isPerNoteMode;
|
||||
option.perUser = isPerUserMode;
|
||||
};
|
||||
option.perNote = isPerNoteMode
|
||||
option.perUser = isPerUserMode
|
||||
}
|
||||
|
||||
$scope.updateInterpreterSetting = function (form, settingId) {
|
||||
const thisConfirm = BootstrapDialog.confirm({
|
||||
|
|
@ -311,75 +311,75 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
message: 'Do you want to update this interpreter and restart with new settings?',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let setting = $scope.interpreterSettings[index];
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
let setting = $scope.interpreterSettings[index]
|
||||
if (setting.propertyKey !== '' || setting.propertyKey) {
|
||||
$scope.addNewInterpreterProperty(settingId);
|
||||
$scope.addNewInterpreterProperty(settingId)
|
||||
}
|
||||
if (setting.depArtifact !== '' || setting.depArtifact) {
|
||||
$scope.addNewInterpreterDependency(settingId);
|
||||
$scope.addNewInterpreterDependency(settingId)
|
||||
}
|
||||
// add missing field of option
|
||||
if (!setting.option) {
|
||||
setting.option = {};
|
||||
setting.option = {}
|
||||
}
|
||||
if (setting.option.isExistingProcess === undefined) {
|
||||
setting.option.isExistingProcess = false;
|
||||
setting.option.isExistingProcess = false
|
||||
}
|
||||
if (setting.option.setPermission === undefined) {
|
||||
setting.option.setPermission = false;
|
||||
setting.option.setPermission = false
|
||||
}
|
||||
if (setting.option.isUserImpersonate === undefined) {
|
||||
setting.option.isUserImpersonate = false;
|
||||
setting.option.isUserImpersonate = false
|
||||
}
|
||||
if (!($scope.getInterpreterRunningOption(settingId) === 'Per User' &&
|
||||
$scope.getPerUserOption(settingId) === 'isolated')) {
|
||||
setting.option.isUserImpersonate = false;
|
||||
setting.option.isUserImpersonate = false
|
||||
}
|
||||
if (setting.option.remote === undefined) {
|
||||
// remote always true for now
|
||||
setting.option.remote = true;
|
||||
setting.option.remote = true
|
||||
}
|
||||
setting.option.users = angular.element('#' + setting.name + 'Users').val();
|
||||
setting.option.users = angular.element('#' + setting.name + 'Users').val()
|
||||
|
||||
let request = {
|
||||
option: angular.copy(setting.option),
|
||||
properties: angular.copy(setting.properties),
|
||||
dependencies: angular.copy(setting.dependencies)
|
||||
};
|
||||
}
|
||||
|
||||
thisConfirm.$modalFooter.find('button').addClass('disabled');
|
||||
thisConfirm.$modalFooter.find('button').addClass('disabled')
|
||||
thisConfirm.$modalFooter.find('button:contains("OK")')
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Saving Setting');
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Saving Setting')
|
||||
|
||||
$http.put(baseUrlSrv.getRestApiBase() + '/interpreter/setting/' + settingId, request)
|
||||
.success(function (data, status, headers, config) {
|
||||
$scope.interpreterSettings[index] = data.body;
|
||||
removeTMPSettings(index);
|
||||
checkDownloadingDependencies();
|
||||
thisConfirm.close();
|
||||
$scope.interpreterSettings[index] = data.body
|
||||
removeTMPSettings(index)
|
||||
checkDownloadingDependencies()
|
||||
thisConfirm.close()
|
||||
})
|
||||
.error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
ngToast.danger({content: data.message, verticalPosition: 'bottom'});
|
||||
form.$show();
|
||||
thisConfirm.close();
|
||||
});
|
||||
return false;
|
||||
console.log('Error %o %o', status, data.message)
|
||||
ngToast.danger({content: data.message, verticalPosition: 'bottom'})
|
||||
form.$show()
|
||||
thisConfirm.close()
|
||||
})
|
||||
return false
|
||||
} else {
|
||||
form.$show();
|
||||
form.$show()
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
$scope.resetInterpreterSetting = function (settingId) {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
|
||||
// Set the old settings back
|
||||
$scope.interpreterSettings[index] = angular.copy(interpreterSettingsTmp[index]);
|
||||
removeTMPSettings(index);
|
||||
};
|
||||
$scope.interpreterSettings[index] = angular.copy(interpreterSettingsTmp[index])
|
||||
removeTMPSettings(index)
|
||||
}
|
||||
|
||||
$scope.removeInterpreterSetting = function (settingId) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -390,31 +390,31 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
if (result) {
|
||||
$http.delete(baseUrlSrv.getRestApiBase() + '/interpreter/setting/' + settingId)
|
||||
.success(function (data, status, headers, config) {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
$scope.interpreterSettings.splice(index, 1);
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
$scope.interpreterSettings.splice(index, 1)
|
||||
}).error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
$scope.newInterpreterGroupChange = function () {
|
||||
let el = _.pluck(_.filter($scope.availableInterpreters, {'name': $scope.newInterpreterSetting.group}),
|
||||
'properties');
|
||||
let properties = {};
|
||||
'properties')
|
||||
let properties = {}
|
||||
for (let i = 0; i < el.length; i++) {
|
||||
let intpInfo = el[i];
|
||||
let intpInfo = el[i]
|
||||
for (let key in intpInfo) {
|
||||
properties[key] = {
|
||||
value: intpInfo[key].defaultValue,
|
||||
description: intpInfo[key].description
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
$scope.newInterpreterSetting.properties = properties;
|
||||
};
|
||||
$scope.newInterpreterSetting.properties = properties
|
||||
}
|
||||
|
||||
$scope.restartInterpreterSetting = function (settingId) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -425,18 +425,18 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
if (result) {
|
||||
$http.put(baseUrlSrv.getRestApiBase() + '/interpreter/setting/restart/' + settingId)
|
||||
.success(function (data, status, headers, config) {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
$scope.interpreterSettings[index] = data.body;
|
||||
ngToast.info('Interpreter stopped. Will be lazily started on next run.');
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
$scope.interpreterSettings[index] = data.body
|
||||
ngToast.info('Interpreter stopped. Will be lazily started on next run.')
|
||||
}).error(function (data, status, headers, config) {
|
||||
let errorMsg = (data !== null) ? data.message : 'Could not connect to server.';
|
||||
console.log('Error %o %o', status, errorMsg);
|
||||
ngToast.danger(errorMsg);
|
||||
});
|
||||
let errorMsg = (data !== null) ? data.message : 'Could not connect to server.'
|
||||
console.log('Error %o %o', status, errorMsg)
|
||||
ngToast.danger(errorMsg)
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
$scope.addNewInterpreterSetting = function () {
|
||||
// user input validation on interpreter creation
|
||||
|
|
@ -446,8 +446,8 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
closable: true,
|
||||
title: 'Add interpreter',
|
||||
message: 'Please fill in interpreter name and choose a group'
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if ($scope.newInterpreterSetting.name.indexOf('.') >= 0) {
|
||||
|
|
@ -455,8 +455,8 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
closable: true,
|
||||
title: 'Add interpreter',
|
||||
message: '\'.\' is invalid for interpreter name'
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (_.findIndex($scope.interpreterSettings, {'name': $scope.newInterpreterSetting.name}) >= 0) {
|
||||
|
|
@ -464,47 +464,47 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
closable: true,
|
||||
title: 'Add interpreter',
|
||||
message: 'Name ' + $scope.newInterpreterSetting.name + ' already exists'
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
let newSetting = $scope.newInterpreterSetting;
|
||||
let newSetting = $scope.newInterpreterSetting
|
||||
if (newSetting.propertyKey !== '' || newSetting.propertyKey) {
|
||||
$scope.addNewInterpreterProperty();
|
||||
$scope.addNewInterpreterProperty()
|
||||
}
|
||||
if (newSetting.depArtifact !== '' || newSetting.depArtifact) {
|
||||
$scope.addNewInterpreterDependency();
|
||||
$scope.addNewInterpreterDependency()
|
||||
}
|
||||
if (newSetting.option.setPermission === undefined) {
|
||||
newSetting.option.setPermission = false;
|
||||
newSetting.option.setPermission = false
|
||||
}
|
||||
newSetting.option.users = angular.element('#newInterpreterUsers').val();
|
||||
newSetting.option.users = angular.element('#newInterpreterUsers').val()
|
||||
|
||||
let request = angular.copy($scope.newInterpreterSetting);
|
||||
let request = angular.copy($scope.newInterpreterSetting)
|
||||
|
||||
// Change properties to proper request format
|
||||
let newProperties = {};
|
||||
let newProperties = {}
|
||||
for (let p in newSetting.properties) {
|
||||
newProperties[p] = newSetting.properties[p].value;
|
||||
newProperties[p] = newSetting.properties[p].value
|
||||
}
|
||||
request.properties = newProperties;
|
||||
request.properties = newProperties
|
||||
|
||||
$http.post(baseUrlSrv.getRestApiBase() + '/interpreter/setting', request)
|
||||
.success(function (data, status, headers, config) {
|
||||
$scope.resetNewInterpreterSetting();
|
||||
getInterpreterSettings();
|
||||
$scope.showAddNewSetting = false;
|
||||
checkDownloadingDependencies();
|
||||
$scope.resetNewInterpreterSetting()
|
||||
getInterpreterSettings()
|
||||
$scope.showAddNewSetting = false
|
||||
checkDownloadingDependencies()
|
||||
}).error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
ngToast.danger({content: data.message, verticalPosition: 'bottom'});
|
||||
});
|
||||
};
|
||||
console.log('Error %o %o', status, data.message)
|
||||
ngToast.danger({content: data.message, verticalPosition: 'bottom'})
|
||||
})
|
||||
}
|
||||
|
||||
$scope.cancelInterpreterSetting = function () {
|
||||
$scope.showAddNewSetting = false;
|
||||
$scope.resetNewInterpreterSetting();
|
||||
};
|
||||
$scope.showAddNewSetting = false
|
||||
$scope.resetNewInterpreterSetting()
|
||||
}
|
||||
|
||||
$scope.resetNewInterpreterSetting = function () {
|
||||
$scope.newInterpreterSetting = {
|
||||
|
|
@ -520,88 +520,88 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
process: false
|
||||
|
||||
}
|
||||
};
|
||||
emptyNewProperty($scope.newInterpreterSetting);
|
||||
};
|
||||
}
|
||||
emptyNewProperty($scope.newInterpreterSetting)
|
||||
}
|
||||
|
||||
$scope.removeInterpreterProperty = function (key, settingId) {
|
||||
if (settingId === undefined) {
|
||||
delete $scope.newInterpreterSetting.properties[key];
|
||||
delete $scope.newInterpreterSetting.properties[key]
|
||||
} else {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
delete $scope.interpreterSettings[index].properties[key];
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
delete $scope.interpreterSettings[index].properties[key]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.removeInterpreterDependency = function (artifact, settingId) {
|
||||
if (settingId === undefined) {
|
||||
$scope.newInterpreterSetting.dependencies = _.reject($scope.newInterpreterSetting.dependencies,
|
||||
function (el) {
|
||||
return el.groupArtifactVersion === artifact;
|
||||
});
|
||||
return el.groupArtifactVersion === artifact
|
||||
})
|
||||
} else {
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
$scope.interpreterSettings[index].dependencies = _.reject($scope.interpreterSettings[index].dependencies,
|
||||
function (el) {
|
||||
return el.groupArtifactVersion === artifact;
|
||||
});
|
||||
return el.groupArtifactVersion === artifact
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.addNewInterpreterProperty = function (settingId) {
|
||||
if (settingId === undefined) {
|
||||
// Add new property from create form
|
||||
if (!$scope.newInterpreterSetting.propertyKey || $scope.newInterpreterSetting.propertyKey === '') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
$scope.newInterpreterSetting.properties[$scope.newInterpreterSetting.propertyKey] = {
|
||||
value: $scope.newInterpreterSetting.propertyValue
|
||||
};
|
||||
emptyNewProperty($scope.newInterpreterSetting);
|
||||
}
|
||||
emptyNewProperty($scope.newInterpreterSetting)
|
||||
} else {
|
||||
// Add new property from edit form
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let setting = $scope.interpreterSettings[index];
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
let setting = $scope.interpreterSettings[index]
|
||||
|
||||
if (!setting.propertyKey || setting.propertyKey === '') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
setting.properties[setting.propertyKey] = setting.propertyValue;
|
||||
emptyNewProperty(setting);
|
||||
setting.properties[setting.propertyKey] = setting.propertyValue
|
||||
emptyNewProperty(setting)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.addNewInterpreterDependency = function (settingId) {
|
||||
if (settingId === undefined) {
|
||||
// Add new dependency from create form
|
||||
if (!$scope.newInterpreterSetting.depArtifact || $scope.newInterpreterSetting.depArtifact === '') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// overwrite if artifact already exists
|
||||
let newSetting = $scope.newInterpreterSetting;
|
||||
let newSetting = $scope.newInterpreterSetting
|
||||
for (let d in newSetting.dependencies) {
|
||||
if (newSetting.dependencies[d].groupArtifactVersion === newSetting.depArtifact) {
|
||||
newSetting.dependencies[d] = {
|
||||
'groupArtifactVersion': newSetting.depArtifact,
|
||||
'exclusions': newSetting.depExclude
|
||||
};
|
||||
newSetting.dependencies.splice(d, 1);
|
||||
}
|
||||
newSetting.dependencies.splice(d, 1)
|
||||
}
|
||||
}
|
||||
|
||||
newSetting.dependencies.push({
|
||||
'groupArtifactVersion': newSetting.depArtifact,
|
||||
'exclusions': (newSetting.depExclude === '') ? [] : newSetting.depExclude
|
||||
});
|
||||
emptyNewDependency(newSetting);
|
||||
})
|
||||
emptyNewDependency(newSetting)
|
||||
} else {
|
||||
// Add new dependency from edit form
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
let setting = $scope.interpreterSettings[index];
|
||||
let index = _.findIndex($scope.interpreterSettings, {'id': settingId})
|
||||
let setting = $scope.interpreterSettings[index]
|
||||
if (!setting.depArtifact || setting.depArtifact === '') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// overwrite if artifact already exists
|
||||
|
|
@ -610,18 +610,18 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
setting.dependencies[dep] = {
|
||||
'groupArtifactVersion': setting.depArtifact,
|
||||
'exclusions': setting.depExclude
|
||||
};
|
||||
setting.dependencies.splice(dep, 1);
|
||||
}
|
||||
setting.dependencies.splice(dep, 1)
|
||||
}
|
||||
}
|
||||
|
||||
setting.dependencies.push({
|
||||
'groupArtifactVersion': setting.depArtifact,
|
||||
'exclusions': (setting.depExclude === '') ? [] : setting.depExclude
|
||||
});
|
||||
emptyNewDependency(setting);
|
||||
})
|
||||
emptyNewDependency(setting)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.resetNewRepositorySetting = function () {
|
||||
$scope.newRepoSetting = {
|
||||
|
|
@ -635,30 +635,30 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
proxyPort: null,
|
||||
proxyLogin: '',
|
||||
proxyPassword: ''
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let getRepositories = function () {
|
||||
$http.get(baseUrlSrv.getRestApiBase() + '/interpreter/repository')
|
||||
.success(function (data, status, headers, config) {
|
||||
$scope.repositories = data.body;
|
||||
$scope.repositories = data.body
|
||||
}).error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
|
||||
$scope.addNewRepository = function () {
|
||||
let request = angular.copy($scope.newRepoSetting);
|
||||
let request = angular.copy($scope.newRepoSetting)
|
||||
|
||||
$http.post(baseUrlSrv.getRestApiBase() + '/interpreter/repository', request)
|
||||
.success(function (data, status, headers, config) {
|
||||
getRepositories();
|
||||
$scope.resetNewRepositorySetting();
|
||||
angular.element('#repoModal').modal('hide');
|
||||
getRepositories()
|
||||
$scope.resetNewRepositorySetting()
|
||||
angular.element('#repoModal').modal('hide')
|
||||
}).error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', headers, config);
|
||||
});
|
||||
};
|
||||
console.log('Error %o %o', headers, config)
|
||||
})
|
||||
}
|
||||
|
||||
$scope.removeRepository = function (repoId) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -669,55 +669,55 @@ function InterpreterCtrl ($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeo
|
|||
if (result) {
|
||||
$http.delete(baseUrlSrv.getRestApiBase() + '/interpreter/repository/' + repoId)
|
||||
.success(function (data, status, headers, config) {
|
||||
let index = _.findIndex($scope.repositories, {'id': repoId});
|
||||
$scope.repositories.splice(index, 1);
|
||||
let index = _.findIndex($scope.repositories, {'id': repoId})
|
||||
$scope.repositories.splice(index, 1)
|
||||
}).error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
$scope.isDefaultRepository = function (repoId) {
|
||||
if (repoId === 'central' || repoId === 'local') {
|
||||
return true;
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.showErrorMessage = function (setting) {
|
||||
BootstrapDialog.show({
|
||||
title: 'Error downloading dependencies',
|
||||
message: setting.errorReason
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
let init = function () {
|
||||
$scope.resetNewInterpreterSetting();
|
||||
$scope.resetNewRepositorySetting();
|
||||
$scope.resetNewInterpreterSetting()
|
||||
$scope.resetNewRepositorySetting()
|
||||
|
||||
getInterpreterSettings();
|
||||
getAvailableInterpreters();
|
||||
getRepositories();
|
||||
};
|
||||
getInterpreterSettings()
|
||||
getAvailableInterpreters()
|
||||
getRepositories()
|
||||
}
|
||||
|
||||
$scope.showSparkUI = function (settingId) {
|
||||
$http.get(baseUrlSrv.getRestApiBase() + '/interpreter/getmetainfos/' + settingId + '?propName=url')
|
||||
.success(function (data, status, headers, config) {
|
||||
let url = data.body.url;
|
||||
let url = data.body.url
|
||||
if (!url) {
|
||||
BootstrapDialog.alert({
|
||||
message: 'No spark application running'
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
window.open(url, '_blank');
|
||||
window.open(url, '_blank')
|
||||
}).error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
|
||||
init();
|
||||
init()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').filter('sortByKey', sortByKey);
|
||||
angular.module('zeppelinWebApp').filter('sortByKey', sortByKey)
|
||||
|
||||
function sortByKey () {
|
||||
return function (properties) {
|
||||
let sortedKeys = properties ? Object.keys(properties) : [];
|
||||
return sortedKeys.sort();
|
||||
};
|
||||
let sortedKeys = properties ? Object.keys(properties) : []
|
||||
return sortedKeys.sort()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,169 +13,169 @@
|
|||
*/
|
||||
|
||||
angular.module('zeppelinWebApp')
|
||||
.controller('JobmanagerCtrl', JobmanagerCtrl);
|
||||
.controller('JobmanagerCtrl', JobmanagerCtrl)
|
||||
|
||||
function JobmanagerCtrl ($scope, websocketMsgSrv, $interval, ngToast, $q, $timeout, jobManagerFilter) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
ngToast.dismiss();
|
||||
ngToast.dismiss()
|
||||
let asyncNotebookJobFilter = function (jobInfomations, filterConfig) {
|
||||
return $q(function (resolve, reject) {
|
||||
$scope.JobInfomationsByFilter = $scope.jobTypeFilter(jobInfomations, filterConfig);
|
||||
resolve($scope.JobInfomationsByFilter);
|
||||
});
|
||||
};
|
||||
$scope.JobInfomationsByFilter = $scope.jobTypeFilter(jobInfomations, filterConfig)
|
||||
resolve($scope.JobInfomationsByFilter)
|
||||
})
|
||||
}
|
||||
|
||||
$scope.doFiltering = function (jobInfomations, filterConfig) {
|
||||
asyncNotebookJobFilter(jobInfomations, filterConfig).then(
|
||||
function () {
|
||||
// success
|
||||
$scope.isLoadingFilter = false;
|
||||
$scope.isLoadingFilter = false
|
||||
},
|
||||
function () {
|
||||
// failed
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
$scope.filterValueToName = function (filterValue, maxStringLength) {
|
||||
if ($scope.activeInterpreters === undefined) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
let index = _.findIndex($scope.activeInterpreters, {value: filterValue});
|
||||
let 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.substr(0, maxStringLength - 3) + '...'
|
||||
}
|
||||
return $scope.activeInterpreters[index].name;
|
||||
return $scope.activeInterpreters[index].name
|
||||
} else {
|
||||
return 'Interpreter is not set';
|
||||
return 'Interpreter is not set'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.setFilterValue = function (filterValue) {
|
||||
$scope.filterConfig.filterValueInterpreter = filterValue;
|
||||
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig);
|
||||
};
|
||||
$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.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.filterConfig.isSortByAsc = !$scope.filterConfig.isSortByAsc
|
||||
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig)
|
||||
}
|
||||
|
||||
$scope.doFilterInputTyping = function (keyEvent, jobInfomations, filterConfig) {
|
||||
let RETURN_KEY_CODE = 13;
|
||||
$timeout.cancel($scope.dofilterTimeoutObject);
|
||||
$scope.isActiveSearchTimer = true;
|
||||
let RETURN_KEY_CODE = 13
|
||||
$timeout.cancel($scope.dofilterTimeoutObject)
|
||||
$scope.isActiveSearchTimer = true
|
||||
$scope.dofilterTimeoutObject = $timeout(function () {
|
||||
$scope.doFiltering(jobInfomations, filterConfig);
|
||||
$scope.isActiveSearchTimer = false;
|
||||
}, 10000);
|
||||
$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;
|
||||
$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;
|
||||
};
|
||||
$timeout.cancel($scope.dofilterTimeoutObject)
|
||||
$scope.doFiltering(jobInfomations, filterConfig)
|
||||
$scope.isActiveSearchTimer = false
|
||||
}
|
||||
|
||||
$scope.init = function () {
|
||||
$scope.isLoadingFilter = true;
|
||||
$scope.jobInfomations = [];
|
||||
$scope.JobInfomationsByFilter = $scope.jobInfomations;
|
||||
$scope.isLoadingFilter = true
|
||||
$scope.jobInfomations = []
|
||||
$scope.JobInfomationsByFilter = $scope.jobInfomations
|
||||
$scope.filterConfig = {
|
||||
isRunningAlwaysTop: true,
|
||||
filterValueNotebookName: '',
|
||||
filterValueInterpreter: '*',
|
||||
isSortByAsc: true
|
||||
};
|
||||
$scope.sortTooltipMsg = 'Switch to sort by desc';
|
||||
$scope.jobTypeFilter = jobManagerFilter;
|
||||
}
|
||||
$scope.sortTooltipMsg = 'Switch to sort by desc'
|
||||
$scope.jobTypeFilter = jobManagerFilter
|
||||
|
||||
websocketMsgSrv.getNoteJobsList();
|
||||
websocketMsgSrv.getNoteJobsList()
|
||||
|
||||
$scope.$watch('filterConfig.isSortByAsc', function (value) {
|
||||
if (value) {
|
||||
$scope.sortTooltipMsg = 'Switch to sort by desc';
|
||||
$scope.sortTooltipMsg = 'Switch to sort by desc'
|
||||
} else {
|
||||
$scope.sortTooltipMsg = 'Switch to sort by asc';
|
||||
$scope.sortTooltipMsg = 'Switch to sort by asc'
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
websocketMsgSrv.unsubscribeJobManager();
|
||||
});
|
||||
};
|
||||
websocketMsgSrv.unsubscribeJobManager()
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
** $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.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: '*'
|
||||
}
|
||||
];
|
||||
let interpreterLists = _.uniq(_.pluck($scope.jobInfomations, 'interpreter'), false);
|
||||
]
|
||||
let interpreterLists = _.uniq(_.pluck($scope.jobInfomations, 'interpreter'), false)
|
||||
for (let index = 0, length = interpreterLists.length; index < length; index++) {
|
||||
$scope.activeInterpreters.push({
|
||||
name: interpreterLists[index],
|
||||
value: interpreterLists[index]
|
||||
});
|
||||
})
|
||||
}
|
||||
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig);
|
||||
});
|
||||
$scope.doFiltering($scope.jobInfomations, $scope.filterConfig)
|
||||
})
|
||||
|
||||
$scope.$on('setUpdateNoteJobs', function (event, responseData) {
|
||||
let jobInfomations = $scope.jobInfomations;
|
||||
let indexStore = $scope.jobInfomationsIndexs;
|
||||
$scope.lastJobServerUnixTime = responseData.lastResponseUnixTime;
|
||||
let notes = responseData.jobs;
|
||||
let jobInfomations = $scope.jobInfomations
|
||||
let indexStore = $scope.jobInfomationsIndexs
|
||||
$scope.lastJobServerUnixTime = responseData.lastResponseUnixTime
|
||||
let notes = responseData.jobs
|
||||
notes.map(function (changedItem) {
|
||||
if (indexStore[changedItem.noteId] === undefined) {
|
||||
let newItem = angular.copy(changedItem);
|
||||
jobInfomations.push(newItem);
|
||||
indexStore[changedItem.noteId] = newItem;
|
||||
let newItem = angular.copy(changedItem)
|
||||
jobInfomations.push(newItem)
|
||||
indexStore[changedItem.noteId] = newItem
|
||||
} else {
|
||||
let changeOriginTarget = indexStore[changedItem.noteId];
|
||||
let changeOriginTarget = indexStore[changedItem.noteId]
|
||||
|
||||
if (changedItem.isRemoved !== undefined && changedItem.isRemoved === true) {
|
||||
// remove Item.
|
||||
let removeIndex = _.findIndex(indexStore, changedItem.noteId);
|
||||
let removeIndex = _.findIndex(indexStore, changedItem.noteId)
|
||||
if (removeIndex > -1) {
|
||||
indexStore.splice(removeIndex, 1);
|
||||
indexStore.splice(removeIndex, 1)
|
||||
}
|
||||
|
||||
removeIndex = _.findIndex(jobInfomations, {'noteId': changedItem.noteId});
|
||||
removeIndex = _.findIndex(jobInfomations, {'noteId': changedItem.noteId})
|
||||
if (removeIndex) {
|
||||
jobInfomations.splice(removeIndex, 1);
|
||||
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;
|
||||
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);
|
||||
});
|
||||
})
|
||||
$scope.doFiltering(jobInfomations, $scope.filterConfig)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,36 +12,36 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').filter('jobManager', jobManagerFilter);
|
||||
angular.module('zeppelinWebApp').filter('jobManager', jobManagerFilter)
|
||||
|
||||
function jobManagerFilter () {
|
||||
function filterContext (jobItems, filterConfig) {
|
||||
let filterValueInterpreter = filterConfig.filterValueInterpreter;
|
||||
let filterValueNotebookName = filterConfig.filterValueNotebookName;
|
||||
let isSortByAsc = filterConfig.isSortByAsc;
|
||||
let filterItems = jobItems;
|
||||
let filterValueInterpreter = filterConfig.filterValueInterpreter
|
||||
let filterValueNotebookName = filterConfig.filterValueNotebookName
|
||||
let isSortByAsc = filterConfig.isSortByAsc
|
||||
let filterItems = jobItems
|
||||
|
||||
if (filterValueInterpreter === undefined) {
|
||||
filterItems = _.filter(filterItems, function (jobItem) {
|
||||
return jobItem.interpreter === undefined ? true : false;
|
||||
});
|
||||
return jobItem.interpreter === undefined ? true : false
|
||||
})
|
||||
} else if (filterValueInterpreter !== '*') {
|
||||
filterItems = _.where(filterItems, {interpreter: filterValueInterpreter});
|
||||
filterItems = _.where(filterItems, {interpreter: filterValueInterpreter})
|
||||
}
|
||||
|
||||
if (filterValueNotebookName !== '') {
|
||||
filterItems = _.filter(filterItems, function (jobItem) {
|
||||
let lowerFilterValue = filterValueNotebookName.toLocaleLowerCase();
|
||||
let lowerNotebookName = jobItem.noteName.toLocaleLowerCase();
|
||||
return lowerNotebookName.match(new RegExp('.*' + lowerFilterValue + '.*'));
|
||||
});
|
||||
let lowerFilterValue = filterValueNotebookName.toLocaleLowerCase()
|
||||
let lowerNotebookName = jobItem.noteName.toLocaleLowerCase()
|
||||
return lowerNotebookName.match(new RegExp('.*' + lowerFilterValue + '.*'))
|
||||
})
|
||||
}
|
||||
|
||||
filterItems = _.sortBy(filterItems, function (sortItem) {
|
||||
return sortItem.noteName.toLowerCase();
|
||||
});
|
||||
return sortItem.noteName.toLowerCase()
|
||||
})
|
||||
|
||||
return isSortByAsc ? filterItems : filterItems.reverse();
|
||||
return isSortByAsc ? filterItems : filterItems.reverse()
|
||||
}
|
||||
return filterContext;
|
||||
return filterContext
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,31 +12,31 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ParagraphStatus, } from '../../notebook/paragraph/paragraph.status';
|
||||
import { ParagraphStatus, } from '../../notebook/paragraph/paragraph.status'
|
||||
|
||||
angular.module('zeppelinWebApp').controller('JobCtrl', JobCtrl);
|
||||
angular.module('zeppelinWebApp').controller('JobCtrl', JobCtrl)
|
||||
|
||||
function JobCtrl ($scope, $http, baseUrlSrv) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
$scope.init = function (jobInformation) {
|
||||
$scope.progressValue = 0;
|
||||
};
|
||||
$scope.progressValue = 0
|
||||
}
|
||||
|
||||
$scope.getProgress = function () {
|
||||
let statusList = _.pluck($scope.notebookJob.paragraphs, 'status');
|
||||
let statusList = _.pluck($scope.notebookJob.paragraphs, 'status')
|
||||
let runningJob = _.countBy(statusList, function (status) {
|
||||
if (status === ParagraphStatus.RUNNING || status === ParagraphStatus.FINISHED) {
|
||||
return 'matchCount';
|
||||
return 'matchCount'
|
||||
} else {
|
||||
return 'none';
|
||||
return 'none'
|
||||
}
|
||||
});
|
||||
let totalCount = statusList.length;
|
||||
let runningJobCount = runningJob.matchCount;
|
||||
let result = Math.ceil(runningJobCount / totalCount * 100);
|
||||
return isNaN(result) ? 0 : result;
|
||||
};
|
||||
})
|
||||
let totalCount = statusList.length
|
||||
let runningJobCount = runningJob.matchCount
|
||||
let result = Math.ceil(runningJobCount / totalCount * 100)
|
||||
return isNaN(result) ? 0 : result
|
||||
}
|
||||
|
||||
$scope.runNotebookJob = function (notebookId) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -54,21 +54,21 @@ function JobCtrl ($scope, $http, baseUrlSrv) {
|
|||
}).then(function successCallback (response) {
|
||||
// success
|
||||
}, function errorCallback (errorResponse) {
|
||||
let errorText = 'SERVER ERROR';
|
||||
let errorText = 'SERVER ERROR'
|
||||
// eslint-disable-next-line no-extra-boolean-cast
|
||||
if (!!errorResponse.data.message) {
|
||||
errorText = errorResponse.data.message;
|
||||
errorText = errorResponse.data.message
|
||||
}
|
||||
BootstrapDialog.alert({
|
||||
closable: true,
|
||||
title: 'Execution Failure',
|
||||
message: errorText
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
$scope.stopNotebookJob = function (notebookId) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -86,23 +86,23 @@ function JobCtrl ($scope, $http, baseUrlSrv) {
|
|||
}).then(function successCallback (response) {
|
||||
// success
|
||||
}, function errorCallback (errorResponse) {
|
||||
let errorText = 'SERVER ERROR';
|
||||
let errorText = 'SERVER ERROR'
|
||||
// eslint-disable-next-line no-extra-boolean-cast
|
||||
if (!!errorResponse.data.message) {
|
||||
errorText = errorResponse.data.message;
|
||||
errorText = errorResponse.data.message
|
||||
}
|
||||
BootstrapDialog.alert({
|
||||
closable: true,
|
||||
title: 'Stop Failure',
|
||||
message: errorText
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
$scope.lastExecuteTime = function (unixtime) {
|
||||
return moment.unix(unixtime / 1000).fromNow();
|
||||
};
|
||||
return moment.unix(unixtime / 1000).fromNow()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
describe('Controller: NotebookCtrl', function () {
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'));
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'))
|
||||
|
||||
let scope;
|
||||
let scope
|
||||
|
||||
let websocketMsgSrvMock = {
|
||||
getNote: function () {},
|
||||
|
|
@ -9,131 +9,131 @@ describe('Controller: NotebookCtrl', function () {
|
|||
getInterpreterBindings: function () {},
|
||||
updateNote: function () {},
|
||||
renameNote: function () {}
|
||||
};
|
||||
}
|
||||
|
||||
let baseUrlSrvMock = {
|
||||
getRestApiBase: function () {
|
||||
return 'http://localhost:8080';
|
||||
return 'http://localhost:8080'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let noteMock = {
|
||||
id: 1,
|
||||
name: 'my note',
|
||||
config: {},
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(inject(function ($controller, $rootScope) {
|
||||
scope = $rootScope.$new();
|
||||
scope = $rootScope.$new()
|
||||
$controller('NotebookCtrl', {
|
||||
$scope: scope,
|
||||
websocketMsgSrv: websocketMsgSrvMock,
|
||||
baseUrlSrv: baseUrlSrvMock
|
||||
});
|
||||
}));
|
||||
})
|
||||
}))
|
||||
|
||||
beforeEach(function () {
|
||||
scope.note = noteMock;
|
||||
});
|
||||
scope.note = noteMock
|
||||
})
|
||||
|
||||
let functions = ['getCronOptionNameFromValue', 'removeNote', 'runAllParagraphs', 'saveNote', 'toggleAllEditor',
|
||||
'showAllEditor', 'hideAllEditor', 'toggleAllTable', 'hideAllTable', 'showAllTable', 'isNoteRunning',
|
||||
'killSaveTimer', 'startSaveTimer', 'setLookAndFeel', 'setCronScheduler', 'setConfig', 'updateNoteName',
|
||||
'openSetting', 'closeSetting', 'saveSetting', 'toggleSetting'];
|
||||
'openSetting', 'closeSetting', 'saveSetting', 'toggleSetting']
|
||||
|
||||
functions.forEach(function (fn) {
|
||||
it('check for scope functions to be defined : ' + fn, function () {
|
||||
expect(scope[fn]).toBeDefined();
|
||||
});
|
||||
});
|
||||
expect(scope[fn]).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
it('should set default value of "editorToggled" to false', function () {
|
||||
expect(scope.editorToggled).toEqual(false);
|
||||
});
|
||||
expect(scope.editorToggled).toEqual(false)
|
||||
})
|
||||
|
||||
it('should set "showSetting" to true when openSetting() is called', function () {
|
||||
scope.openSetting();
|
||||
expect(scope.showSetting).toEqual(true);
|
||||
});
|
||||
scope.openSetting()
|
||||
expect(scope.showSetting).toEqual(true)
|
||||
})
|
||||
|
||||
it('should set "showSetting" to false when closeSetting() is called', function () {
|
||||
scope.closeSetting();
|
||||
expect(scope.showSetting).toEqual(false);
|
||||
});
|
||||
scope.closeSetting()
|
||||
expect(scope.showSetting).toEqual(false)
|
||||
})
|
||||
|
||||
it('should return the correct value for getCronOptionNameFromValue()', function () {
|
||||
let none = scope.getCronOptionNameFromValue();
|
||||
let oneMin = scope.getCronOptionNameFromValue('0 0/1 * * * ?');
|
||||
let fiveMin = scope.getCronOptionNameFromValue('0 0/5 * * * ?');
|
||||
let oneHour = scope.getCronOptionNameFromValue('0 0 0/1 * * ?');
|
||||
let threeHours = scope.getCronOptionNameFromValue('0 0 0/3 * * ?');
|
||||
let sixHours = scope.getCronOptionNameFromValue('0 0 0/6 * * ?');
|
||||
let twelveHours = scope.getCronOptionNameFromValue('0 0 0/12 * * ?');
|
||||
let oneDay = scope.getCronOptionNameFromValue('0 0 0 * * ?');
|
||||
let none = scope.getCronOptionNameFromValue()
|
||||
let oneMin = scope.getCronOptionNameFromValue('0 0/1 * * * ?')
|
||||
let fiveMin = scope.getCronOptionNameFromValue('0 0/5 * * * ?')
|
||||
let oneHour = scope.getCronOptionNameFromValue('0 0 0/1 * * ?')
|
||||
let threeHours = scope.getCronOptionNameFromValue('0 0 0/3 * * ?')
|
||||
let sixHours = scope.getCronOptionNameFromValue('0 0 0/6 * * ?')
|
||||
let twelveHours = scope.getCronOptionNameFromValue('0 0 0/12 * * ?')
|
||||
let oneDay = scope.getCronOptionNameFromValue('0 0 0 * * ?')
|
||||
|
||||
expect(none).toEqual('');
|
||||
expect(oneMin).toEqual('1m');
|
||||
expect(fiveMin).toEqual('5m');
|
||||
expect(oneHour).toEqual('1h');
|
||||
expect(threeHours).toEqual('3h');
|
||||
expect(sixHours).toEqual('6h');
|
||||
expect(twelveHours).toEqual('12h');
|
||||
expect(oneDay).toEqual('1d');
|
||||
});
|
||||
expect(none).toEqual('')
|
||||
expect(oneMin).toEqual('1m')
|
||||
expect(fiveMin).toEqual('5m')
|
||||
expect(oneHour).toEqual('1h')
|
||||
expect(threeHours).toEqual('3h')
|
||||
expect(sixHours).toEqual('6h')
|
||||
expect(twelveHours).toEqual('12h')
|
||||
expect(oneDay).toEqual('1d')
|
||||
})
|
||||
|
||||
it('should have "isNoteDirty" as null by default', function () {
|
||||
expect(scope.isNoteDirty).toEqual(null);
|
||||
});
|
||||
expect(scope.isNoteDirty).toEqual(null)
|
||||
})
|
||||
|
||||
it('should first call killSaveTimer() when calling startSaveTimer()', function () {
|
||||
expect(scope.saveTimer).toEqual(null);
|
||||
spyOn(scope, 'killSaveTimer');
|
||||
scope.startSaveTimer();
|
||||
expect(scope.killSaveTimer).toHaveBeenCalled();
|
||||
});
|
||||
expect(scope.saveTimer).toEqual(null)
|
||||
spyOn(scope, 'killSaveTimer')
|
||||
scope.startSaveTimer()
|
||||
expect(scope.killSaveTimer).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should set "saveTimer" when saveTimer() and killSaveTimer() are called', function () {
|
||||
expect(scope.saveTimer).toEqual(null);
|
||||
scope.startSaveTimer();
|
||||
expect(scope.saveTimer).toBeTruthy();
|
||||
scope.killSaveTimer();
|
||||
expect(scope.saveTimer).toEqual(null);
|
||||
});
|
||||
expect(scope.saveTimer).toEqual(null)
|
||||
scope.startSaveTimer()
|
||||
expect(scope.saveTimer).toBeTruthy()
|
||||
scope.killSaveTimer()
|
||||
expect(scope.saveTimer).toEqual(null)
|
||||
})
|
||||
|
||||
it('should NOT update note name when updateNoteName() is called with an invalid name', function () {
|
||||
spyOn(websocketMsgSrvMock, 'renameNote');
|
||||
scope.updateNoteName('');
|
||||
expect(scope.note.name).toEqual(noteMock.name);
|
||||
expect(websocketMsgSrvMock.renameNote).not.toHaveBeenCalled();
|
||||
scope.updateNoteName(' ');
|
||||
expect(scope.note.name).toEqual(noteMock.name);
|
||||
expect(websocketMsgSrvMock.renameNote).not.toHaveBeenCalled();
|
||||
scope.updateNoteName(scope.note.name);
|
||||
expect(scope.note.name).toEqual(noteMock.name);
|
||||
expect(websocketMsgSrvMock.renameNote).not.toHaveBeenCalled();
|
||||
});
|
||||
spyOn(websocketMsgSrvMock, 'renameNote')
|
||||
scope.updateNoteName('')
|
||||
expect(scope.note.name).toEqual(noteMock.name)
|
||||
expect(websocketMsgSrvMock.renameNote).not.toHaveBeenCalled()
|
||||
scope.updateNoteName(' ')
|
||||
expect(scope.note.name).toEqual(noteMock.name)
|
||||
expect(websocketMsgSrvMock.renameNote).not.toHaveBeenCalled()
|
||||
scope.updateNoteName(scope.note.name)
|
||||
expect(scope.note.name).toEqual(noteMock.name)
|
||||
expect(websocketMsgSrvMock.renameNote).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should update note name when updateNoteName() is called with a valid name', function () {
|
||||
spyOn(websocketMsgSrvMock, 'renameNote');
|
||||
let newName = 'Your Note';
|
||||
scope.updateNoteName(newName);
|
||||
expect(scope.note.name).toEqual(newName);
|
||||
expect(websocketMsgSrvMock.renameNote).toHaveBeenCalled();
|
||||
});
|
||||
spyOn(websocketMsgSrvMock, 'renameNote')
|
||||
let newName = 'Your Note'
|
||||
scope.updateNoteName(newName)
|
||||
expect(scope.note.name).toEqual(newName)
|
||||
expect(websocketMsgSrvMock.renameNote).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should reload note info once per one "setNoteMenu" event', function () {
|
||||
spyOn(websocketMsgSrvMock, 'getNote');
|
||||
spyOn(websocketMsgSrvMock, 'listRevisionHistory');
|
||||
spyOn(websocketMsgSrvMock, 'getNote')
|
||||
spyOn(websocketMsgSrvMock, 'listRevisionHistory')
|
||||
|
||||
scope.$broadcast('setNoteMenu');
|
||||
expect(websocketMsgSrvMock.getNote.calls.count()).toEqual(0);
|
||||
expect(websocketMsgSrvMock.listRevisionHistory.calls.count()).toEqual(0);
|
||||
scope.$broadcast('setNoteMenu')
|
||||
expect(websocketMsgSrvMock.getNote.calls.count()).toEqual(0)
|
||||
expect(websocketMsgSrvMock.listRevisionHistory.calls.count()).toEqual(0)
|
||||
|
||||
websocketMsgSrvMock.getNote.calls.reset();
|
||||
websocketMsgSrvMock.listRevisionHistory.calls.reset();
|
||||
websocketMsgSrvMock.getNote.calls.reset()
|
||||
websocketMsgSrvMock.listRevisionHistory.calls.reset()
|
||||
|
||||
scope.$broadcast('setNoteMenu');
|
||||
expect(websocketMsgSrvMock.getNote.calls.count()).toEqual(0);
|
||||
expect(websocketMsgSrvMock.listRevisionHistory.calls.count()).toEqual(0);
|
||||
});
|
||||
});
|
||||
scope.$broadcast('setNoteMenu')
|
||||
expect(websocketMsgSrvMock.getNote.calls.count()).toEqual(0)
|
||||
expect(websocketMsgSrvMock.listRevisionHistory.calls.count()).toEqual(0)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,53 +1,53 @@
|
|||
describe('Controller: ParagraphCtrl', function () {
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'));
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'))
|
||||
|
||||
let scope;
|
||||
let websocketMsgSrvMock = {};
|
||||
let scope
|
||||
let websocketMsgSrvMock = {}
|
||||
let paragraphMock = {
|
||||
config: {},
|
||||
settings: {
|
||||
forms: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
let route = {
|
||||
current: {
|
||||
pathParams: {
|
||||
noteId: 'noteId'
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(inject(function ($controller, $rootScope) {
|
||||
scope = $rootScope.$new();
|
||||
$rootScope.notebookScope = $rootScope.$new(true, $rootScope);
|
||||
scope = $rootScope.$new()
|
||||
$rootScope.notebookScope = $rootScope.$new(true, $rootScope)
|
||||
|
||||
$controller('ParagraphCtrl', {
|
||||
$scope: scope,
|
||||
websocketMsgSrv: websocketMsgSrvMock,
|
||||
$element: {},
|
||||
$route: route
|
||||
});
|
||||
})
|
||||
|
||||
scope.init(paragraphMock);
|
||||
}));
|
||||
scope.init(paragraphMock)
|
||||
}))
|
||||
|
||||
let functions = ['isRunning', 'getIframeDimensions', 'cancelParagraph', 'runParagraph', 'saveParagraph',
|
||||
'moveUp', 'moveDown', 'insertNew', 'removeParagraph', 'toggleEditor', 'closeEditor', 'openEditor',
|
||||
'closeTable', 'openTable', 'showTitle', 'hideTitle', 'setTitle', 'showLineNumbers', 'hideLineNumbers',
|
||||
'changeColWidth', 'columnWidthClass', 'toggleOutput', 'loadForm',
|
||||
'aceChanged', 'aceLoaded', 'getEditorValue', 'getProgress', 'getExecutionTime', 'isResultOutdated'];
|
||||
'aceChanged', 'aceLoaded', 'getEditorValue', 'getProgress', 'getExecutionTime', 'isResultOutdated']
|
||||
|
||||
functions.forEach(function (fn) {
|
||||
it('check for scope functions to be defined : ' + fn, function () {
|
||||
expect(scope[fn]).toBeDefined();
|
||||
});
|
||||
});
|
||||
expect(scope[fn]).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
it('should have this array of values for "colWidthOption"', function () {
|
||||
expect(scope.colWidthOption).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
|
||||
});
|
||||
expect(scope.colWidthOption).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
|
||||
})
|
||||
|
||||
it('should set default value of "paragraphFocused" as false', function () {
|
||||
expect(scope.paragraphFocused).toEqual(false);
|
||||
});
|
||||
});
|
||||
expect(scope.paragraphFocused).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@ export const ParagraphStatus = {
|
|||
FINISHED: 'FINISHED',
|
||||
ABORT: 'ABORT',
|
||||
ERROR: 'ERROR',
|
||||
};
|
||||
}
|
||||
|
||||
export function isParagraphRunning (paragraph) {
|
||||
if (!paragraph) { return false; }
|
||||
const status = paragraph.status;
|
||||
if (!status) { return false; }
|
||||
if (!paragraph) { return false }
|
||||
const status = paragraph.status
|
||||
if (!status) { return false }
|
||||
|
||||
return status === ParagraphStatus.PENDING || status === ParagraphStatus.RUNNING;
|
||||
return status === ParagraphStatus.PENDING || status === ParagraphStatus.RUNNING
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -12,50 +12,50 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('NotebookReposCtrl', NotebookReposCtrl);
|
||||
angular.module('zeppelinWebApp').controller('NotebookReposCtrl', NotebookReposCtrl)
|
||||
|
||||
function NotebookReposCtrl ($http, baseUrlSrv, ngToast) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let vm = this;
|
||||
vm.notebookRepos = [];
|
||||
vm.showDropdownSelected = showDropdownSelected;
|
||||
vm.saveNotebookRepo = saveNotebookRepo;
|
||||
let vm = this
|
||||
vm.notebookRepos = []
|
||||
vm.showDropdownSelected = showDropdownSelected
|
||||
vm.saveNotebookRepo = saveNotebookRepo
|
||||
|
||||
_init();
|
||||
_init()
|
||||
|
||||
// Public functions
|
||||
|
||||
function saveNotebookRepo (valueform, repo, data) {
|
||||
console.log('data %o', data);
|
||||
console.log('data %o', data)
|
||||
$http.put(baseUrlSrv.getRestApiBase() + '/notebook-repositories', {
|
||||
'name': repo.className,
|
||||
'settings': data
|
||||
}).success(function (data) {
|
||||
let index = _.findIndex(vm.notebookRepos, {'className': repo.className});
|
||||
let 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);
|
||||
vm.notebookRepos[index] = data.body
|
||||
console.log('repos %o, data %o', vm.notebookRepos, data.body)
|
||||
}
|
||||
valueform.$show();
|
||||
valueform.$show()
|
||||
}).error(function () {
|
||||
ngToast.danger({
|
||||
content: 'We couldn\'t save that NotebookRepo\'s settings',
|
||||
verticalPosition: 'bottom',
|
||||
timeout: '3000'
|
||||
});
|
||||
valueform.$show();
|
||||
});
|
||||
})
|
||||
valueform.$show()
|
||||
})
|
||||
|
||||
return 'manual';
|
||||
return 'manual'
|
||||
}
|
||||
|
||||
function showDropdownSelected (setting) {
|
||||
let index = _.findIndex(setting.value, {'value': setting.selected});
|
||||
let index = _.findIndex(setting.value, {'value': setting.selected})
|
||||
if (index < 0) {
|
||||
return 'No value';
|
||||
return 'No value'
|
||||
} else {
|
||||
return setting.value[index].name;
|
||||
return setting.value[index].name
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,24 +64,24 @@ function NotebookReposCtrl ($http, baseUrlSrv, ngToast) {
|
|||
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);
|
||||
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);
|
||||
window.location.replace('/')
|
||||
}, 3000)
|
||||
}
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
|
||||
function _init () {
|
||||
_getInterpreterSettings();
|
||||
_getInterpreterSettings()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,43 +12,43 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('SearchResultCtrl', SearchResultCtrl);
|
||||
angular.module('zeppelinWebApp').controller('SearchResultCtrl', SearchResultCtrl)
|
||||
|
||||
function SearchResultCtrl ($scope, $routeParams, searchService) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
$scope.isResult = true;
|
||||
$scope.searchTerm = $routeParams.searchTerm;
|
||||
let results = searchService.search({'q': $routeParams.searchTerm}).query();
|
||||
$scope.isResult = true
|
||||
$scope.searchTerm = $routeParams.searchTerm
|
||||
let 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;
|
||||
return note
|
||||
}
|
||||
|
||||
note.id = note.id.replace('paragraph/', '?paragraph=') +
|
||||
'&term=' + $routeParams.searchTerm;
|
||||
'&term=' + $routeParams.searchTerm
|
||||
|
||||
return note;
|
||||
});
|
||||
return note
|
||||
})
|
||||
if ($scope.notes.length === 0) {
|
||||
$scope.isResult = false;
|
||||
$scope.isResult = false
|
||||
} else {
|
||||
$scope.isResult = true;
|
||||
$scope.isResult = true
|
||||
}
|
||||
|
||||
$scope.$on('$routeChangeStart', function (event, next, current) {
|
||||
if (next.originalPath !== '/search/:searchTerm') {
|
||||
searchService.searchTerm = '';
|
||||
searchService.searchTerm = ''
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
$scope.page = 0;
|
||||
$scope.allResults = false;
|
||||
$scope.page = 0
|
||||
$scope.allResults = false
|
||||
|
||||
$scope.highlightSearchResults = function (note) {
|
||||
return function (_editor) {
|
||||
|
|
@ -60,59 +60,59 @@ function SearchResultCtrl ($scope, $routeParams, searchService) {
|
|||
'ace/mode/sql': /^%(\w*\.)?\wql/,
|
||||
'ace/mode/markdown': /^%md/,
|
||||
'ace/mode/sh': /^%sh/
|
||||
};
|
||||
}
|
||||
|
||||
return Object.keys(editorModes).reduce(function (res, mode) {
|
||||
return editorModes[mode].test(text) ? mode : res;
|
||||
}, 'ace/mode/scala');
|
||||
return editorModes[mode].test(text) ? mode : res
|
||||
}, 'ace/mode/scala')
|
||||
}
|
||||
|
||||
let Range = ace.require('ace/range').Range;
|
||||
let Range = ace.require('ace/range').Range
|
||||
|
||||
_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));
|
||||
_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) {
|
||||
let indeces = [];
|
||||
let i = -1;
|
||||
let indeces = []
|
||||
let i = -1
|
||||
while ((i = str.indexOf(term, i + 1)) >= 0) {
|
||||
indeces.push(i);
|
||||
indeces.push(i)
|
||||
}
|
||||
return indeces;
|
||||
};
|
||||
return indeces
|
||||
}
|
||||
}
|
||||
|
||||
let result = '';
|
||||
let result = ''
|
||||
if (note.header !== '') {
|
||||
result = note.header + '\n\n' + note.snippet;
|
||||
result = note.header + '\n\n' + note.snippet
|
||||
} else {
|
||||
result = note.snippet;
|
||||
result = note.snippet
|
||||
}
|
||||
|
||||
let lines = result
|
||||
.split('\n')
|
||||
.map(function (line, row) {
|
||||
let match = line.match(/<B>(.+?)<\/B>/);
|
||||
let match = line.match(/<B>(.+?)<\/B>/)
|
||||
|
||||
// return early if nothing to highlight
|
||||
if (!match) {
|
||||
return line;
|
||||
return line
|
||||
}
|
||||
|
||||
let term = match[1];
|
||||
let term = match[1]
|
||||
let __line = line
|
||||
.replace(/<B>/g, '')
|
||||
.replace(/<\/B>/g, '');
|
||||
.replace(/<\/B>/g, '')
|
||||
|
||||
let indeces = getIndeces(term)(__line);
|
||||
let indeces = getIndeces(term)(__line)
|
||||
|
||||
indeces.forEach(function (start) {
|
||||
let end = start + term.length;
|
||||
let end = start + term.length
|
||||
if (note.header !== '' && row === 0) {
|
||||
_editor
|
||||
.getSession()
|
||||
|
|
@ -120,14 +120,14 @@ function SearchResultCtrl ($scope, $routeParams, searchService) {
|
|||
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()
|
||||
|
|
@ -135,19 +135,19 @@ function SearchResultCtrl ($scope, $routeParams, searchService) {
|
|||
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)
|
||||
);
|
||||
lines.reduce(function (len, line) { return len + line.length }, 0)
|
||||
)
|
||||
|
||||
_editor.getSession().setValue(lines.join('\n'));
|
||||
};
|
||||
};
|
||||
_editor.getSession().setValue(lines.join('\n'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
export {
|
||||
DefaultDisplayType,
|
||||
SpellResult,
|
||||
} from './spell-result';
|
||||
} from './spell-result'
|
||||
|
||||
export {
|
||||
SpellBase,
|
||||
} from './spell-base';
|
||||
} from './spell-base'
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@
|
|||
import {
|
||||
DefaultDisplayType,
|
||||
SpellResult,
|
||||
} from './spell-result';
|
||||
} from './spell-result'
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
export class SpellBase {
|
||||
constructor (magic) {
|
||||
this.magic = magic;
|
||||
this.magic = magic
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -35,7 +35,7 @@ export class SpellBase {
|
|||
* @return {SpellResult}
|
||||
*/
|
||||
interpret (paragraphText, config) {
|
||||
throw new Error('SpellBase.interpret() should be overrided');
|
||||
throw new Error('SpellBase.interpret() should be overrided')
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -44,6 +44,6 @@ export class SpellBase {
|
|||
* @return {string}
|
||||
*/
|
||||
getMagic () {
|
||||
return this.magic;
|
||||
return this.magic
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export const DefaultDisplayType = {
|
|||
HTML: 'HTML',
|
||||
ANGULAR: 'ANGULAR',
|
||||
TEXT: 'TEXT',
|
||||
};
|
||||
}
|
||||
|
||||
export const DefaultDisplayMagic = {
|
||||
'%element': DefaultDisplayType.ELEMENT,
|
||||
|
|
@ -29,12 +29,12 @@ export const DefaultDisplayMagic = {
|
|||
'%html': DefaultDisplayType.HTML,
|
||||
'%angular': DefaultDisplayType.ANGULAR,
|
||||
'%text': DefaultDisplayType.TEXT,
|
||||
};
|
||||
}
|
||||
|
||||
export class DataWithType {
|
||||
constructor (data, type, magic, text) {
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.data = data
|
||||
this.type = type
|
||||
|
||||
/**
|
||||
* keep for `DefaultDisplayType.ELEMENT` (function data type)
|
||||
|
|
@ -44,29 +44,29 @@ export class DataWithType {
|
|||
* since they don't have context where they are created.
|
||||
*/
|
||||
|
||||
this.magic = magic;
|
||||
this.text = text;
|
||||
this.magic = magic
|
||||
this.text = text
|
||||
}
|
||||
|
||||
static handleDefaultMagic (m) {
|
||||
// let's use default display type instead of magic in case of default
|
||||
// to keep consistency with backend interpreter
|
||||
if (DefaultDisplayMagic[m]) {
|
||||
return DefaultDisplayMagic[m];
|
||||
return DefaultDisplayMagic[m]
|
||||
} else {
|
||||
return m;
|
||||
return m
|
||||
}
|
||||
}
|
||||
|
||||
static createPropagable (dataWithType) {
|
||||
if (!SpellResult.isFunction(dataWithType.data)) {
|
||||
return dataWithType;
|
||||
return dataWithType
|
||||
}
|
||||
|
||||
const data = dataWithType.getText();
|
||||
const type = dataWithType.getMagic();
|
||||
const data = dataWithType.getText()
|
||||
const type = dataWithType.getMagic()
|
||||
|
||||
return new DataWithType(data, type);
|
||||
return new DataWithType(data, type)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -77,43 +77,43 @@ export class DataWithType {
|
|||
*/
|
||||
static parseStringData (data, customDisplayMagic) {
|
||||
function availableMagic (magic) {
|
||||
return magic && (DefaultDisplayMagic[magic] || customDisplayMagic[magic]);
|
||||
return magic && (DefaultDisplayMagic[magic] || customDisplayMagic[magic])
|
||||
}
|
||||
|
||||
const splited = data.split('\n');
|
||||
const splited = data.split('\n')
|
||||
|
||||
const gensWithTypes = [];
|
||||
let mergedGens = [];
|
||||
let previousMagic = DefaultDisplayType.TEXT;
|
||||
const gensWithTypes = []
|
||||
let mergedGens = []
|
||||
let previousMagic = DefaultDisplayType.TEXT
|
||||
|
||||
// create `DataWithType` whenever see available display type.
|
||||
for (let i = 0; i < splited.length; i++) {
|
||||
const g = splited[i];
|
||||
const magic = SpellResult.extractMagic(g);
|
||||
const g = splited[i]
|
||||
const magic = SpellResult.extractMagic(g)
|
||||
|
||||
// create `DataWithType` only if see new magic
|
||||
if (availableMagic(magic) && mergedGens.length > 0) {
|
||||
gensWithTypes.push(new DataWithType(mergedGens.join(''), previousMagic));
|
||||
mergedGens = [];
|
||||
gensWithTypes.push(new DataWithType(mergedGens.join(''), previousMagic))
|
||||
mergedGens = []
|
||||
}
|
||||
|
||||
// accumulate `data` to mergedGens
|
||||
if (availableMagic(magic)) {
|
||||
const withoutMagic = g.split(magic)[1];
|
||||
mergedGens.push(`${withoutMagic}\n`);
|
||||
previousMagic = DataWithType.handleDefaultMagic(magic);
|
||||
const withoutMagic = g.split(magic)[1]
|
||||
mergedGens.push(`${withoutMagic}\n`)
|
||||
previousMagic = DataWithType.handleDefaultMagic(magic)
|
||||
} else {
|
||||
mergedGens.push(`${g}\n`);
|
||||
mergedGens.push(`${g}\n`)
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup the last `DataWithType`
|
||||
if (mergedGens.length > 0) {
|
||||
previousMagic = DataWithType.handleDefaultMagic(previousMagic);
|
||||
gensWithTypes.push(new DataWithType(mergedGens.join(''), previousMagic));
|
||||
previousMagic = DataWithType.handleDefaultMagic(previousMagic)
|
||||
gensWithTypes.push(new DataWithType(mergedGens.join(''), previousMagic))
|
||||
}
|
||||
|
||||
return gensWithTypes;
|
||||
return gensWithTypes
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -128,42 +128,42 @@ export class DataWithType {
|
|||
*/
|
||||
static produceMultipleData (dataWithType, customDisplayType,
|
||||
magic, textWithoutMagic) {
|
||||
const data = dataWithType.getData();
|
||||
const type = dataWithType.getType();
|
||||
const data = dataWithType.getData()
|
||||
const type = dataWithType.getType()
|
||||
|
||||
// if the type is specified, just return it
|
||||
// handle non-specified dataWithTypes only
|
||||
if (type) {
|
||||
return new Promise((resolve) => { resolve([dataWithType]); });
|
||||
return new Promise((resolve) => { resolve([dataWithType]) })
|
||||
}
|
||||
|
||||
let wrapped;
|
||||
let wrapped
|
||||
|
||||
if (SpellResult.isFunction(data)) {
|
||||
// if data is a function, we consider it as ELEMENT type.
|
||||
wrapped = new Promise((resolve) => {
|
||||
const dt = new DataWithType(
|
||||
data, DefaultDisplayType.ELEMENT, magic, textWithoutMagic);
|
||||
const result = [dt];
|
||||
return resolve(result);
|
||||
});
|
||||
data, DefaultDisplayType.ELEMENT, magic, textWithoutMagic)
|
||||
const result = [dt]
|
||||
return resolve(result)
|
||||
})
|
||||
} else if (SpellResult.isPromise(data)) {
|
||||
// if data is a promise,
|
||||
wrapped = data.then(generated => {
|
||||
const result =
|
||||
DataWithType.parseStringData(generated, customDisplayType);
|
||||
return result;
|
||||
DataWithType.parseStringData(generated, customDisplayType)
|
||||
return result
|
||||
})
|
||||
} else {
|
||||
// if data is a object, parse it to multiples
|
||||
wrapped = new Promise((resolve) => {
|
||||
const result =
|
||||
DataWithType.parseStringData(data, customDisplayType);
|
||||
return resolve(result);
|
||||
});
|
||||
DataWithType.parseStringData(data, customDisplayType)
|
||||
return resolve(result)
|
||||
})
|
||||
}
|
||||
|
||||
return wrapped;
|
||||
return wrapped
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -176,7 +176,7 @@ export class DataWithType {
|
|||
* @returns {*} `data` which can be object, function or promise.
|
||||
*/
|
||||
getData () {
|
||||
return this.data;
|
||||
return this.data
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -186,65 +186,65 @@ export class DataWithType {
|
|||
* @returns {string}
|
||||
*/
|
||||
getType () {
|
||||
return this.type;
|
||||
return this.type
|
||||
}
|
||||
|
||||
getMagic () {
|
||||
return this.magic;
|
||||
return this.magic
|
||||
}
|
||||
|
||||
getText () {
|
||||
return this.text;
|
||||
return this.text
|
||||
}
|
||||
}
|
||||
|
||||
export class SpellResult {
|
||||
constructor (resultData, resultType) {
|
||||
this.dataWithTypes = [];
|
||||
this.add(resultData, resultType);
|
||||
this.dataWithTypes = []
|
||||
this.add(resultData, resultType)
|
||||
}
|
||||
|
||||
static isFunction (data) {
|
||||
return (data && typeof data === 'function');
|
||||
return (data && typeof data === 'function')
|
||||
}
|
||||
|
||||
static isPromise (data) {
|
||||
return (data && typeof data.then === 'function');
|
||||
return (data && typeof data.then === 'function')
|
||||
}
|
||||
|
||||
static isObject (data) {
|
||||
return (data &&
|
||||
!SpellResult.isFunction(data) &&
|
||||
!SpellResult.isPromise(data));
|
||||
!SpellResult.isPromise(data))
|
||||
}
|
||||
|
||||
static extractMagic (allParagraphText) {
|
||||
const pattern = /^\s*%(\S+)\s*/g;
|
||||
const pattern = /^\s*%(\S+)\s*/g
|
||||
try {
|
||||
let match = pattern.exec(allParagraphText);
|
||||
let match = pattern.exec(allParagraphText)
|
||||
if (match) {
|
||||
return `%${match[1].trim()}`;
|
||||
return `%${match[1].trim()}`
|
||||
}
|
||||
} catch (error) {
|
||||
// failed to parse, ignore
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
|
||||
static createPropagable (resultMsg) {
|
||||
return resultMsg.map(dt => {
|
||||
return DataWithType.createPropagable(dt);
|
||||
return DataWithType.createPropagable(dt)
|
||||
})
|
||||
}
|
||||
|
||||
add (resultData, resultType) {
|
||||
if (resultData) {
|
||||
this.dataWithTypes.push(
|
||||
new DataWithType(resultData, resultType));
|
||||
new DataWithType(resultData, resultType))
|
||||
}
|
||||
|
||||
return this;
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -255,20 +255,20 @@ export class SpellResult {
|
|||
getAllParsedDataWithTypes (customDisplayType, magic, textWithoutMagic) {
|
||||
const promises = this.dataWithTypes.map(dt => {
|
||||
return DataWithType.produceMultipleData(
|
||||
dt, customDisplayType, magic, textWithoutMagic);
|
||||
});
|
||||
dt, customDisplayType, magic, textWithoutMagic)
|
||||
})
|
||||
|
||||
// some promises can include an array so we need to flatten them
|
||||
const flatten = Promise.all(promises).then(values => {
|
||||
return values.reduce((acc, cur) => {
|
||||
if (Array.isArray(cur)) {
|
||||
return acc.concat(cur);
|
||||
return acc.concat(cur)
|
||||
} else {
|
||||
return acc.concat([cur]);
|
||||
return acc.concat([cur])
|
||||
}
|
||||
})
|
||||
});
|
||||
})
|
||||
|
||||
return flatten;
|
||||
return flatten
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
*/
|
||||
|
||||
export function getCurrentChart(config) {
|
||||
return config.chart.current;
|
||||
return config.chart.current
|
||||
}
|
||||
|
||||
export function getCurrentChartTransform(config) {
|
||||
|
|
@ -43,7 +43,7 @@ export function useSharedAxis(config, chart) {
|
|||
export function serializeSharedAxes(config) {
|
||||
const availableCharts = getAvailableChartNames(config.spec.charts)
|
||||
for (let i = 0; i < availableCharts.length; i++) {
|
||||
const chartName = availableCharts[i];
|
||||
const chartName = availableCharts[i]
|
||||
if (useSharedAxis(config, chartName)) {
|
||||
/** use reference :) in case of sharedAxis */
|
||||
config.axis[chartName] = config.sharedAxis
|
||||
|
|
@ -59,19 +59,19 @@ export const Widget = {
|
|||
}
|
||||
|
||||
export function isInputWidget(paramSpec) {
|
||||
return (paramSpec && !paramSpec.widget) || (paramSpec && paramSpec.widget === Widget.INPUT);
|
||||
return (paramSpec && !paramSpec.widget) || (paramSpec && paramSpec.widget === Widget.INPUT)
|
||||
}
|
||||
|
||||
export function isOptionWidget(paramSpec) {
|
||||
return paramSpec && paramSpec.widget === Widget.OPTION;
|
||||
return paramSpec && paramSpec.widget === Widget.OPTION
|
||||
}
|
||||
|
||||
export function isCheckboxWidget(paramSpec) {
|
||||
return paramSpec && paramSpec.widget === Widget.CHECKBOX;
|
||||
return paramSpec && paramSpec.widget === Widget.CHECKBOX
|
||||
}
|
||||
|
||||
export function isTextareaWidget(paramSpec) {
|
||||
return paramSpec && paramSpec.widget === Widget.TEXTAREA;
|
||||
return paramSpec && paramSpec.widget === Widget.TEXTAREA
|
||||
}
|
||||
|
||||
export const ParameterValueType = {
|
||||
|
|
@ -92,23 +92,23 @@ export function parseParameter(paramSpecs, param) {
|
|||
|
||||
if (paramSpec.valueType === ParameterValueType.INT &&
|
||||
typeof parsed[name] !== 'number') {
|
||||
try { parsed[name] = parseInt(parsed[name]); } catch (error) { parsed[name] = paramSpec.defaultValue; }
|
||||
try { parsed[name] = parseInt(parsed[name]) } catch (error) { parsed[name] = paramSpec.defaultValue }
|
||||
} else if (paramSpec.valueType === ParameterValueType.FLOAT &&
|
||||
typeof parsed[name] !== 'number') {
|
||||
try { parsed[name] = parseFloat(parsed[name]); } catch (error) { parsed[name] = paramSpec.defaultValue; }
|
||||
try { parsed[name] = parseFloat(parsed[name]) } catch (error) { parsed[name] = paramSpec.defaultValue }
|
||||
} else if (paramSpec.valueType === ParameterValueType.BOOLEAN) {
|
||||
if (parsed[name] === 'false') {
|
||||
parsed[name] = false;
|
||||
parsed[name] = false
|
||||
} else if (parsed[name] === 'true') {
|
||||
parsed[name] = true;
|
||||
parsed[name] = true
|
||||
} else if (typeof parsed[name] !== 'boolean') {
|
||||
parsed[name] = paramSpec.defaultValue;
|
||||
parsed[name] = paramSpec.defaultValue
|
||||
}
|
||||
} else if (paramSpec.valueType === ParameterValueType.JSON) {
|
||||
if (parsed[name] !== null && typeof parsed[name] !== 'object') {
|
||||
try { parsed[name] = JSON.parse(parsed[name]); } catch (error) { parsed[name] = paramSpec.defaultValue; }
|
||||
try { parsed[name] = JSON.parse(parsed[name]) } catch (error) { parsed[name] = paramSpec.defaultValue }
|
||||
} else if (parsed[name] === null) {
|
||||
parsed[name] = paramSpec.defaultValue;
|
||||
parsed[name] = paramSpec.defaultValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -142,12 +142,12 @@ export function isSingleDimensionAxis(axisSpec) {
|
|||
* add the `name` field while converting to array to easily manipulate
|
||||
*/
|
||||
export function getSpecs(specObject) {
|
||||
const specs = [];
|
||||
const specs = []
|
||||
for (let name in specObject) {
|
||||
const singleSpec = specObject[name];
|
||||
const singleSpec = specObject[name]
|
||||
if (!singleSpec) { continue }
|
||||
singleSpec.name = name;
|
||||
specs.push(singleSpec);
|
||||
singleSpec.name = name
|
||||
specs.push(singleSpec)
|
||||
}
|
||||
|
||||
return specs
|
||||
|
|
@ -164,11 +164,11 @@ export function getAvailableChartNames(charts) {
|
|||
|
||||
export function applyMaxAxisCount(config, axisSpec) {
|
||||
if (isSingleDimensionAxis(axisSpec) || typeof axisSpec.maxAxisCount === 'undefined') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
const columns = getCurrentChartAxis(config)[axisSpec.name]
|
||||
if (columns.length <= axisSpec.maxAxisCount) { return; }
|
||||
if (columns.length <= axisSpec.maxAxisCount) { return }
|
||||
|
||||
const sliced = columns.slice(1)
|
||||
getCurrentChartAxis(config)[axisSpec.name] = sliced
|
||||
|
|
@ -205,23 +205,23 @@ export function initAxisConfig(config) {
|
|||
const spec = config.spec
|
||||
const availableCharts = getAvailableChartNames(spec.charts)
|
||||
|
||||
if (!config.axisSpecs) { config.axisSpecs = {}; }
|
||||
if (!config.axisSpecs) { config.axisSpecs = {} }
|
||||
for (let i = 0; i < availableCharts.length; i++) {
|
||||
const chartName = availableCharts[i];
|
||||
const chartName = availableCharts[i]
|
||||
|
||||
if (!config.axis[chartName]) {
|
||||
config.axis[chartName] = {};
|
||||
config.axis[chartName] = {}
|
||||
}
|
||||
const axisSpecs = getSpecs(spec.charts[chartName].axis)
|
||||
if (!config.axisSpecs[chartName]) {
|
||||
config.axisSpecs[chartName] = axisSpecs;
|
||||
config.axisSpecs[chartName] = axisSpecs
|
||||
}
|
||||
|
||||
/** initialize multi-dimension axes */
|
||||
for (let i = 0; i < axisSpecs.length; i++) {
|
||||
const axisSpec = axisSpecs[i]
|
||||
if (isSingleDimensionAxis(axisSpec)) {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
|
||||
/** intentionally nested if-stmt is used because order of conditions matter here */
|
||||
|
|
@ -260,18 +260,18 @@ export function initParameterConfig(config) {
|
|||
const spec = config.spec
|
||||
const availableCharts = getAvailableChartNames(spec.charts)
|
||||
|
||||
if (!config.paramSpecs) { config.paramSpecs = {}; }
|
||||
if (!config.paramSpecs) { config.paramSpecs = {} }
|
||||
for (let i = 0; i < availableCharts.length; i++) {
|
||||
const chartName = availableCharts[i];
|
||||
const chartName = availableCharts[i]
|
||||
|
||||
if (!config.parameter[chartName]) { config.parameter[chartName] = {}; }
|
||||
if (!config.parameter[chartName]) { config.parameter[chartName] = {} }
|
||||
const paramSpecs = getSpecs(spec.charts[chartName].parameter)
|
||||
if (!config.paramSpecs[chartName]) { config.paramSpecs[chartName] = paramSpecs; }
|
||||
if (!config.paramSpecs[chartName]) { config.paramSpecs[chartName] = paramSpecs }
|
||||
|
||||
for (let i = 0; i < paramSpecs.length; i++) {
|
||||
const paramSpec = paramSpecs[i];
|
||||
const paramSpec = paramSpecs[i]
|
||||
if (!config.parameter[chartName][paramSpec.name]) {
|
||||
config.parameter[chartName][paramSpec.name] = paramSpec.defaultValue;
|
||||
config.parameter[chartName][paramSpec.name] = paramSpec.defaultValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -287,7 +287,7 @@ export function getSpecVersion(availableCharts, spec) {
|
|||
const paramHash = {}
|
||||
|
||||
for (let i = 0; i < availableCharts.length; i++) {
|
||||
const chartName = availableCharts[i];
|
||||
const chartName = availableCharts[i]
|
||||
const axisSpecs = getSpecs(spec.charts[chartName].axis)
|
||||
axisHash[chartName] = axisSpecs
|
||||
|
||||
|
|
@ -333,12 +333,12 @@ export function initializeConfig(config, spec) {
|
|||
spec.version.axis = axisVersion
|
||||
spec.version.parameter = paramVersion
|
||||
|
||||
if (!config.spec || updated) { config.spec = spec; }
|
||||
if (!config.spec || updated) { config.spec = spec }
|
||||
|
||||
if (!config.chart) {
|
||||
config.chart = {};
|
||||
config.chart.current = availableCharts[0];
|
||||
config.chart.available = availableCharts;
|
||||
config.chart = {}
|
||||
config.chart.current = availableCharts[0]
|
||||
config.chart.available = availableCharts
|
||||
}
|
||||
|
||||
/** initialize config.axis, config.axisSpecs for each chart */
|
||||
|
|
@ -354,7 +354,7 @@ export function getColumnsForMultipleAxes(axisType, axisSpecs, axis) {
|
|||
let column = {}
|
||||
|
||||
for (let i = 0; i < axisSpecs.length; i++) {
|
||||
const axisSpec = axisSpecs[i];
|
||||
const axisSpec = axisSpecs[i]
|
||||
|
||||
if (axisType === AxisType.KEY && isKeyAxis(axisSpec)) {
|
||||
axisNames.push(axisSpec.name)
|
||||
|
|
@ -366,7 +366,7 @@ export function getColumnsForMultipleAxes(axisType, axisSpecs, axis) {
|
|||
}
|
||||
|
||||
for (let axisName of axisNames) {
|
||||
const columns = axis[axisName];
|
||||
const columns = axis[axisName]
|
||||
if (typeof axis[axisName] === 'undefined') { continue }
|
||||
if (!column[axisName]) { column[axisName] = [] }
|
||||
column[axisName] = column[axisName].concat(columns)
|
||||
|
|
@ -376,35 +376,39 @@ export function getColumnsForMultipleAxes(axisType, axisSpecs, axis) {
|
|||
}
|
||||
|
||||
export function getColumnsFromAxis(axisSpecs, axis) {
|
||||
const keyAxisNames = [];
|
||||
const groupAxisNames = [];
|
||||
const aggrAxisNames = [];
|
||||
const keyAxisNames = []
|
||||
const groupAxisNames = []
|
||||
const aggrAxisNames = []
|
||||
|
||||
for (let i = 0; i < axisSpecs.length; i++) {
|
||||
const axisSpec = axisSpecs[i];
|
||||
const axisSpec = axisSpecs[i]
|
||||
|
||||
if (isKeyAxis(axisSpec)) { keyAxisNames.push(axisSpec.name); }
|
||||
else if (isGroupAxis(axisSpec)) { groupAxisNames.push(axisSpec.name); }
|
||||
else if (isAggregatorAxis(axisSpec)) { aggrAxisNames.push(axisSpec.name); }
|
||||
if (isKeyAxis(axisSpec)) {
|
||||
keyAxisNames.push(axisSpec.name)
|
||||
} else if (isGroupAxis(axisSpec)) {
|
||||
groupAxisNames.push(axisSpec.name)
|
||||
} else if (isAggregatorAxis(axisSpec)) {
|
||||
aggrAxisNames.push(axisSpec.name)
|
||||
}
|
||||
}
|
||||
|
||||
let keyColumns = [];
|
||||
let groupColumns = [];
|
||||
let aggregatorColumns = [];
|
||||
let customColumn = {};
|
||||
let keyColumns = []
|
||||
let groupColumns = []
|
||||
let aggregatorColumns = []
|
||||
let customColumn = {}
|
||||
|
||||
for (let axisName in axis) {
|
||||
const columns = axis[axisName];
|
||||
const columns = axis[axisName]
|
||||
if (keyAxisNames.includes(axisName)) {
|
||||
keyColumns = keyColumns.concat(columns);
|
||||
keyColumns = keyColumns.concat(columns)
|
||||
} else if (groupAxisNames.includes(axisName)) {
|
||||
groupColumns = groupColumns.concat(columns);
|
||||
groupColumns = groupColumns.concat(columns)
|
||||
} else if (aggrAxisNames.includes(axisName)) {
|
||||
aggregatorColumns = aggregatorColumns.concat(columns);
|
||||
aggregatorColumns = aggregatorColumns.concat(columns)
|
||||
} else {
|
||||
const axisType = axisSpecs.filter(s => s.name === axisName)[0].axisType
|
||||
if (!customColumn[axisType]) { customColumn[axisType] = []; }
|
||||
customColumn[axisType] = customColumn[axisType].concat(columns);
|
||||
if (!customColumn[axisType]) { customColumn[axisType] = [] }
|
||||
customColumn[axisType] = customColumn[axisType].concat(columns)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -456,10 +460,10 @@ export function getTransformer(conf, rows, axisSpecs, axis) {
|
|||
|
||||
const method = transformSpec.method
|
||||
|
||||
const columns = getColumnsFromAxis(axisSpecs, axis);
|
||||
const keyColumns = columns.key;
|
||||
const groupColumns = columns.group;
|
||||
const aggregatorColumns = columns.aggregator;
|
||||
const columns = getColumnsFromAxis(axisSpecs, axis)
|
||||
const keyColumns = columns.key
|
||||
const groupColumns = columns.group
|
||||
const aggregatorColumns = columns.aggregator
|
||||
const customColumns = columns.custom
|
||||
|
||||
let column = {
|
||||
|
|
@ -467,7 +471,7 @@ export function getTransformer(conf, rows, axisSpecs, axis) {
|
|||
}
|
||||
|
||||
if (method === TransformMethod.RAW) {
|
||||
transformer = () => { return rows; }
|
||||
transformer = () => { return rows }
|
||||
} else if (method === TransformMethod.OBJECT) {
|
||||
transformer = () => {
|
||||
const { cube, schema, keyColumnName, keyNames, groupNameSet, selectorNameWithIndex, } =
|
||||
|
|
@ -569,31 +573,31 @@ export function getTransformer(conf, rows, axisSpecs, axis) {
|
|||
|
||||
const AggregatorFunctions = {
|
||||
sum: function(a, b) {
|
||||
const varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0;
|
||||
const varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0;
|
||||
return varA + varB;
|
||||
const varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0
|
||||
const varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0
|
||||
return varA + varB
|
||||
},
|
||||
count: function(a, b) {
|
||||
const varA = (a !== undefined) ? parseInt(a) : 0;
|
||||
const varB = (b !== undefined) ? 1 : 0;
|
||||
return varA + varB;
|
||||
const varA = (a !== undefined) ? parseInt(a) : 0
|
||||
const varB = (b !== undefined) ? 1 : 0
|
||||
return varA + varB
|
||||
},
|
||||
min: function(a, b) {
|
||||
const varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0;
|
||||
const varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0;
|
||||
return Math.min(varA, varB);
|
||||
const varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0
|
||||
const varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0
|
||||
return Math.min(varA, varB)
|
||||
},
|
||||
max: function(a, b) {
|
||||
const varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0;
|
||||
const varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0;
|
||||
return Math.max(varA, varB);
|
||||
const varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0
|
||||
const varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0
|
||||
return Math.max(varA, varB)
|
||||
},
|
||||
avg: function(a, b, c) {
|
||||
const varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0;
|
||||
const varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0;
|
||||
return varA + varB;
|
||||
const varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0
|
||||
const varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0
|
||||
return varA + varB
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const AggregatorFunctionDiv = {
|
||||
sum: false,
|
||||
|
|
@ -601,7 +605,7 @@ const AggregatorFunctionDiv = {
|
|||
max: false,
|
||||
count: false,
|
||||
avg: true
|
||||
};
|
||||
}
|
||||
|
||||
/** nested cube `(key) -> (group) -> aggregator` */
|
||||
export function getKGACube(rows, keyColumns, groupColumns, aggrColumns) {
|
||||
|
|
@ -609,7 +613,7 @@ export function getKGACube(rows, keyColumns, groupColumns, aggrColumns) {
|
|||
key: keyColumns.length !== 0,
|
||||
group: groupColumns.length !== 0,
|
||||
aggregator: aggrColumns.length !== 0,
|
||||
};
|
||||
}
|
||||
|
||||
let cube = {}
|
||||
const entry = {}
|
||||
|
|
@ -621,9 +625,9 @@ export function getKGACube(rows, keyColumns, groupColumns, aggrColumns) {
|
|||
let indexCounter = 0
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const row = rows[i];
|
||||
let e = entry;
|
||||
let c = cube;
|
||||
const row = rows[i]
|
||||
let e = entry
|
||||
let c = cube
|
||||
|
||||
// key: add to entry
|
||||
let mergedKeyName
|
||||
|
|
@ -716,7 +720,7 @@ export function getKAGCube(rows, keyColumns, groupColumns, aggrColumns) {
|
|||
key: keyColumns.length !== 0,
|
||||
group: groupColumns.length !== 0,
|
||||
aggregator: aggrColumns.length !== 0,
|
||||
};
|
||||
}
|
||||
|
||||
let cube = {}
|
||||
|
||||
|
|
@ -727,8 +731,8 @@ export function getKAGCube(rows, keyColumns, groupColumns, aggrColumns) {
|
|||
let indexCounter = 0
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const row = rows[i];
|
||||
let c = cube;
|
||||
const row = rows[i]
|
||||
let c = cube
|
||||
|
||||
// key: add to entry
|
||||
let mergedKeyName
|
||||
|
|
@ -826,7 +830,7 @@ export function getKKGACube(rows, key1Columns, key2Columns, groupColumns, aggrCo
|
|||
key2: key2Columns.length !== 0,
|
||||
group: groupColumns.length !== 0,
|
||||
aggregator: aggrColumns.length !== 0,
|
||||
};
|
||||
}
|
||||
|
||||
let cube = {}
|
||||
const entry = {}
|
||||
|
|
@ -840,9 +844,9 @@ export function getKKGACube(rows, key1Columns, key2Columns, groupColumns, aggrCo
|
|||
let indexCounter = 0
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const row = rows[i];
|
||||
let e = entry;
|
||||
let c = cube;
|
||||
const row = rows[i]
|
||||
let e = entry
|
||||
let c = cube
|
||||
|
||||
// key1: add to entry
|
||||
let mergedKey1Name
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Transformation from './transformation';
|
||||
import Transformation from './transformation'
|
||||
|
||||
import {
|
||||
getCurrentChart, getCurrentChartAxis, getCurrentChartParam,
|
||||
|
|
@ -23,19 +23,19 @@ import {
|
|||
removeDuplicatedColumnsInMultiDimensionAxis, applyMaxAxisCount,
|
||||
isInputWidget, isOptionWidget, isCheckboxWidget, isTextareaWidget, parseParameter,
|
||||
getTransformer,
|
||||
} from './advanced-transformation-util';
|
||||
} from './advanced-transformation-util'
|
||||
|
||||
const SETTING_TEMPLATE = 'app/tabledata/advanced-transformation-setting.html';
|
||||
const SETTING_TEMPLATE = 'app/tabledata/advanced-transformation-setting.html'
|
||||
|
||||
export default class AdvancedTransformation extends Transformation {
|
||||
constructor(config, spec) {
|
||||
super(config);
|
||||
super(config)
|
||||
|
||||
this.columns = []; /** [{ name, index, comment }] */
|
||||
this.props = {};
|
||||
this.columns = [] /** [{ name, index, comment }] */
|
||||
this.props = {}
|
||||
this.spec = spec
|
||||
|
||||
initializeConfig(config, spec);
|
||||
initializeConfig(config, spec)
|
||||
}
|
||||
|
||||
emitConfigChange(conf) {
|
||||
|
|
@ -57,8 +57,8 @@ export default class AdvancedTransformation extends Transformation {
|
|||
}
|
||||
|
||||
getSetting() {
|
||||
const self = this; /** for closure */
|
||||
const configInstance = self.config; /** for closure */
|
||||
const self = this /** for closure */
|
||||
const configInstance = self.config /** for closure */
|
||||
|
||||
if (self.spec.initialized) {
|
||||
self.spec.initialized = false
|
||||
|
|
@ -123,13 +123,13 @@ export default class AdvancedTransformation extends Transformation {
|
|||
|
||||
getAxisTypeAnnotationColor: (axisSpec) => {
|
||||
if (isAggregatorAxis(axisSpec)) {
|
||||
return { 'background-color': '#5782bd' };
|
||||
return { 'background-color': '#5782bd' }
|
||||
} else if (isGroupAxis(axisSpec)) {
|
||||
return { 'background-color': '#cd5c5c' };
|
||||
return { 'background-color': '#cd5c5c' }
|
||||
} else if (isKeyAxis(axisSpec)) {
|
||||
return { 'background-color': '#906ebd' };
|
||||
return { 'background-color': '#906ebd' }
|
||||
} else {
|
||||
return { 'background-color': '#62bda9' };
|
||||
return { 'background-color': '#62bda9' }
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ export default class AdvancedTransformation extends Transformation {
|
|||
},
|
||||
|
||||
parameterOnKeyDown: function(event, paramSpec) {
|
||||
const code = event.keyCode || event.which;
|
||||
const code = event.keyCode || event.which
|
||||
if (code === 13 && isInputWidget(paramSpec)) {
|
||||
self.emitParameterChange(configInstance)
|
||||
} else if (code === 13 && event.shiftKey && isTextareaWidget(paramSpec)) {
|
||||
|
|
@ -200,7 +200,7 @@ export default class AdvancedTransformation extends Transformation {
|
|||
}
|
||||
|
||||
transform(tableData) {
|
||||
this.columns = tableData.columns; /** used in `getSetting` */
|
||||
this.columns = tableData.columns /** used in `getSetting` */
|
||||
/** initialize in `transform` instead of `getSetting` because this method is called before */
|
||||
serializeSharedAxes(this.config)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Transformation from './transformation';
|
||||
import Transformation from './transformation'
|
||||
|
||||
/**
|
||||
* select columns
|
||||
|
|
@ -27,13 +27,13 @@ import Transformation from './transformation';
|
|||
*/
|
||||
export default class ColumnselectorTransformation extends Transformation {
|
||||
constructor (config, columnSelectorProp) {
|
||||
super(config);
|
||||
this.props = columnSelectorProp;
|
||||
super(config)
|
||||
this.props = columnSelectorProp
|
||||
}
|
||||
|
||||
getSetting () {
|
||||
let self = this;
|
||||
let configObj = self.config;
|
||||
let self = this
|
||||
let configObj = self.config
|
||||
return {
|
||||
template: 'app/tabledata/columnselector_settings.html',
|
||||
scope: {
|
||||
|
|
@ -41,40 +41,40 @@ export default class ColumnselectorTransformation extends Transformation {
|
|||
props: self.props,
|
||||
tableDataColumns: self.tableDataColumns,
|
||||
save: function () {
|
||||
self.emitConfig(configObj);
|
||||
self.emitConfig(configObj)
|
||||
},
|
||||
remove: function (selectorName) {
|
||||
configObj[selectorName] = null;
|
||||
self.emitConfig(configObj);
|
||||
configObj[selectorName] = null
|
||||
self.emitConfig(configObj)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method will be invoked when tableData or config changes
|
||||
*/
|
||||
transform (tableData) {
|
||||
this.tableDataColumns = tableData.columns;
|
||||
this.removeUnknown();
|
||||
return tableData;
|
||||
this.tableDataColumns = tableData.columns
|
||||
this.removeUnknown()
|
||||
return tableData
|
||||
}
|
||||
|
||||
removeUnknown () {
|
||||
let fields = this.config;
|
||||
let fields = this.config
|
||||
for (let f in fields) {
|
||||
if (fields[f]) {
|
||||
let found = false;
|
||||
let found = false
|
||||
for (let i = 0; i < this.tableDataColumns.length; i++) {
|
||||
let a = fields[f];
|
||||
let b = this.tableDataColumns[i];
|
||||
let a = fields[f]
|
||||
let b = this.tableDataColumns[i]
|
||||
if (a.index === b.index && a.name === b.name) {
|
||||
found = true;
|
||||
break;
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!found && (fields[f] instanceof Object) && !(fields[f] instanceof Array)) {
|
||||
fields[f] = null;
|
||||
fields[f] = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Transformation from './transformation';
|
||||
import Transformation from './transformation'
|
||||
|
||||
/**
|
||||
* passthough the data
|
||||
|
|
@ -20,13 +20,13 @@ import Transformation from './transformation';
|
|||
export default class PassthroughTransformation extends Transformation {
|
||||
// eslint-disable-next-line no-useless-constructor
|
||||
constructor (config) {
|
||||
super(config);
|
||||
super(config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method will be invoked when tableData or config changes
|
||||
*/
|
||||
transform (tableData) {
|
||||
return tableData;
|
||||
return tableData
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Transformation from './transformation';
|
||||
import Transformation from './transformation'
|
||||
|
||||
/**
|
||||
* pivot table data and return d3 chart data
|
||||
|
|
@ -20,116 +20,116 @@ import Transformation from './transformation';
|
|||
export default class PivotTransformation extends Transformation {
|
||||
// eslint-disable-next-line no-useless-constructor
|
||||
constructor (config) {
|
||||
super(config);
|
||||
super(config)
|
||||
}
|
||||
|
||||
getSetting () {
|
||||
let self = this;
|
||||
let self = this
|
||||
|
||||
let configObj = self.config;
|
||||
console.log('getSetting', configObj);
|
||||
let configObj = self.config
|
||||
console.log('getSetting', configObj)
|
||||
return {
|
||||
template: 'app/tabledata/pivot_settings.html',
|
||||
scope: {
|
||||
config: configObj.common.pivot,
|
||||
tableDataColumns: self.tableDataColumns,
|
||||
save: function () {
|
||||
self.emitConfig(configObj);
|
||||
self.emitConfig(configObj)
|
||||
},
|
||||
removeKey: function (idx) {
|
||||
configObj.common.pivot.keys.splice(idx, 1);
|
||||
self.emitConfig(configObj);
|
||||
configObj.common.pivot.keys.splice(idx, 1)
|
||||
self.emitConfig(configObj)
|
||||
},
|
||||
removeGroup: function (idx) {
|
||||
configObj.common.pivot.groups.splice(idx, 1);
|
||||
self.emitConfig(configObj);
|
||||
configObj.common.pivot.groups.splice(idx, 1)
|
||||
self.emitConfig(configObj)
|
||||
},
|
||||
removeValue: function (idx) {
|
||||
configObj.common.pivot.values.splice(idx, 1);
|
||||
self.emitConfig(configObj);
|
||||
configObj.common.pivot.values.splice(idx, 1)
|
||||
self.emitConfig(configObj)
|
||||
},
|
||||
setValueAggr: function (idx, aggr) {
|
||||
configObj.common.pivot.values[idx].aggr = aggr;
|
||||
self.emitConfig(configObj);
|
||||
configObj.common.pivot.values[idx].aggr = aggr
|
||||
self.emitConfig(configObj)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method will be invoked when tableData or config changes
|
||||
*/
|
||||
transform (tableData) {
|
||||
this.tableDataColumns = tableData.columns;
|
||||
this.config.common = this.config.common || {};
|
||||
this.config.common.pivot = this.config.common.pivot || {};
|
||||
let config = this.config.common.pivot;
|
||||
let firstTime = (!config.keys && !config.groups && !config.values);
|
||||
this.tableDataColumns = tableData.columns
|
||||
this.config.common = this.config.common || {}
|
||||
this.config.common.pivot = this.config.common.pivot || {}
|
||||
let config = this.config.common.pivot
|
||||
let firstTime = (!config.keys && !config.groups && !config.values)
|
||||
|
||||
config.keys = config.keys || [];
|
||||
config.groups = config.groups || [];
|
||||
config.values = config.values || [];
|
||||
config.keys = config.keys || []
|
||||
config.groups = config.groups || []
|
||||
config.values = config.values || []
|
||||
|
||||
this.removeUnknown();
|
||||
this.removeUnknown()
|
||||
if (firstTime) {
|
||||
this.selectDefault();
|
||||
this.selectDefault()
|
||||
}
|
||||
return this.pivot(
|
||||
tableData,
|
||||
config.keys,
|
||||
config.groups,
|
||||
config.values);
|
||||
config.values)
|
||||
}
|
||||
|
||||
removeUnknown () {
|
||||
let config = this.config.common.pivot;
|
||||
let tableDataColumns = this.tableDataColumns;
|
||||
let config = this.config.common.pivot
|
||||
let tableDataColumns = this.tableDataColumns
|
||||
let unique = function (list) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
for (let j = i + 1; j < list.length; j++) {
|
||||
if (angular.equals(list[i], list[j])) {
|
||||
list.splice(j, 1);
|
||||
list.splice(j, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let removeUnknown = function (list) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
// remove non existing column
|
||||
let found = false;
|
||||
let found = false
|
||||
for (let j = 0; j < tableDataColumns.length; j++) {
|
||||
let a = list[i];
|
||||
let b = tableDataColumns[j];
|
||||
let a = list[i]
|
||||
let b = tableDataColumns[j]
|
||||
if (a.index === b.index && a.name === b.name) {
|
||||
found = true;
|
||||
break;
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
list.splice(i, 1);
|
||||
list.splice(i, 1)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
unique(config.keys);
|
||||
removeUnknown(config.keys);
|
||||
unique(config.groups);
|
||||
removeUnknown(config.groups);
|
||||
removeUnknown(config.values);
|
||||
unique(config.keys)
|
||||
removeUnknown(config.keys)
|
||||
unique(config.groups)
|
||||
removeUnknown(config.groups)
|
||||
removeUnknown(config.values)
|
||||
}
|
||||
|
||||
selectDefault () {
|
||||
let config = this.config.common.pivot;
|
||||
let config = this.config.common.pivot
|
||||
if (config.keys.length === 0 &&
|
||||
config.groups.length === 0 &&
|
||||
config.values.length === 0) {
|
||||
if (config.keys.length === 0 && this.tableDataColumns.length > 0) {
|
||||
config.keys.push(this.tableDataColumns[0]);
|
||||
config.keys.push(this.tableDataColumns[0])
|
||||
}
|
||||
|
||||
if (config.values.length === 0 && this.tableDataColumns.length > 1) {
|
||||
config.values.push(this.tableDataColumns[1]);
|
||||
config.values.push(this.tableDataColumns[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -137,31 +137,31 @@ export default class PivotTransformation extends Transformation {
|
|||
pivot (data, keys, groups, values) {
|
||||
let aggrFunc = {
|
||||
sum: function (a, b) {
|
||||
let varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0;
|
||||
let varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0;
|
||||
return varA + varB;
|
||||
let varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0
|
||||
let varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0
|
||||
return varA + varB
|
||||
},
|
||||
count: function (a, b) {
|
||||
let varA = (a !== undefined) ? parseInt(a) : 0;
|
||||
let varB = (b !== undefined) ? 1 : 0;
|
||||
return varA + varB;
|
||||
let varA = (a !== undefined) ? parseInt(a) : 0
|
||||
let varB = (b !== undefined) ? 1 : 0
|
||||
return varA + varB
|
||||
},
|
||||
min: function (a, b) {
|
||||
let varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0;
|
||||
let varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0;
|
||||
return Math.min(varA, varB);
|
||||
let varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0
|
||||
let varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0
|
||||
return Math.min(varA, varB)
|
||||
},
|
||||
max: function (a, b) {
|
||||
let varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0;
|
||||
let varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0;
|
||||
return Math.max(varA, varB);
|
||||
let varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0
|
||||
let varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0
|
||||
return Math.max(varA, varB)
|
||||
},
|
||||
avg: function (a, b, c) {
|
||||
let varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0;
|
||||
let varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0;
|
||||
return varA + varB;
|
||||
let varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0
|
||||
let varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0
|
||||
return varA + varB
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let aggrFuncDiv = {
|
||||
sum: false,
|
||||
|
|
@ -169,18 +169,18 @@ export default class PivotTransformation extends Transformation {
|
|||
min: false,
|
||||
max: false,
|
||||
avg: true
|
||||
};
|
||||
}
|
||||
|
||||
let schema = {};
|
||||
let rows = {};
|
||||
let schema = {}
|
||||
let rows = {}
|
||||
|
||||
for (let i = 0; i < data.rows.length; i++) {
|
||||
let row = data.rows[i];
|
||||
let s = schema;
|
||||
let p = rows;
|
||||
let row = data.rows[i]
|
||||
let s = schema
|
||||
let p = rows
|
||||
|
||||
for (let k = 0; k < keys.length; k++) {
|
||||
let key = keys[k];
|
||||
let key = keys[k]
|
||||
|
||||
// add key to schema
|
||||
if (!s[key.name]) {
|
||||
|
|
@ -189,21 +189,21 @@ export default class PivotTransformation extends Transformation {
|
|||
index: key.index,
|
||||
type: 'key',
|
||||
children: {}
|
||||
};
|
||||
}
|
||||
}
|
||||
s = s[key.name].children;
|
||||
s = s[key.name].children
|
||||
|
||||
// add key to row
|
||||
let keyKey = row[key.index];
|
||||
let keyKey = row[key.index]
|
||||
if (!p[keyKey]) {
|
||||
p[keyKey] = {};
|
||||
p[keyKey] = {}
|
||||
}
|
||||
p = p[keyKey];
|
||||
p = p[keyKey]
|
||||
}
|
||||
|
||||
for (let g = 0; g < groups.length; g++) {
|
||||
let group = groups[g];
|
||||
let groupKey = row[group.index];
|
||||
let group = groups[g]
|
||||
let groupKey = row[group.index]
|
||||
|
||||
// add group to schema
|
||||
if (!s[groupKey]) {
|
||||
|
|
@ -212,20 +212,20 @@ export default class PivotTransformation extends Transformation {
|
|||
index: group.index,
|
||||
type: 'group',
|
||||
children: {}
|
||||
};
|
||||
}
|
||||
}
|
||||
s = s[groupKey].children;
|
||||
s = s[groupKey].children
|
||||
|
||||
// add key to row
|
||||
if (!p[groupKey]) {
|
||||
p[groupKey] = {};
|
||||
p[groupKey] = {}
|
||||
}
|
||||
p = p[groupKey];
|
||||
p = p[groupKey]
|
||||
}
|
||||
|
||||
for (let v = 0; v < values.length; v++) {
|
||||
let value = values[v];
|
||||
let valueKey = value.name + '(' + value.aggr + ')';
|
||||
let value = values[v]
|
||||
let valueKey = value.name + '(' + value.aggr + ')'
|
||||
|
||||
// add value to schema
|
||||
if (!s[valueKey]) {
|
||||
|
|
@ -233,7 +233,7 @@ export default class PivotTransformation extends Transformation {
|
|||
type: 'value',
|
||||
order: v,
|
||||
index: value.index
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// add value to row
|
||||
|
|
@ -241,12 +241,12 @@ export default class PivotTransformation extends Transformation {
|
|||
p[valueKey] = {
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -258,6 +258,6 @@ export default class PivotTransformation extends Transformation {
|
|||
values: values,
|
||||
schema: schema,
|
||||
rows: rows
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,57 +17,57 @@
|
|||
*/
|
||||
export default class TableData {
|
||||
constructor (columns, rows, comment) {
|
||||
this.columns = columns || [];
|
||||
this.rows = rows || [];
|
||||
this.comment = comment || '';
|
||||
this.columns = columns || []
|
||||
this.rows = rows || []
|
||||
this.comment = comment || ''
|
||||
}
|
||||
|
||||
loadParagraphResult (paragraphResult) {
|
||||
if (!paragraphResult || paragraphResult.type !== 'TABLE') {
|
||||
console.log('Can not load paragraph result');
|
||||
return;
|
||||
console.log('Can not load paragraph result')
|
||||
return
|
||||
}
|
||||
|
||||
let columnNames = [];
|
||||
let rows = [];
|
||||
let array = [];
|
||||
let textRows = paragraphResult.msg.split('\n');
|
||||
let comment = '';
|
||||
let commentRow = false;
|
||||
let columnNames = []
|
||||
let rows = []
|
||||
let array = []
|
||||
let textRows = paragraphResult.msg.split('\n')
|
||||
let comment = ''
|
||||
let commentRow = false
|
||||
|
||||
for (let i = 0; i < textRows.length; i++) {
|
||||
let textRow = textRows[i];
|
||||
let textRow = textRows[i]
|
||||
|
||||
if (commentRow) {
|
||||
comment += textRow;
|
||||
continue;
|
||||
comment += textRow
|
||||
continue
|
||||
}
|
||||
|
||||
if (textRow === '' || textRow === '<!--TABLE_COMMENT-->') {
|
||||
if (rows.length > 0) {
|
||||
commentRow = true;
|
||||
commentRow = true
|
||||
}
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
let textCols = textRow.split('\t');
|
||||
let cols = [];
|
||||
let cols2 = [];
|
||||
let textCols = textRow.split('\t')
|
||||
let cols = []
|
||||
let cols2 = []
|
||||
for (let j = 0; j < textCols.length; j++) {
|
||||
let col = textCols[j];
|
||||
let col = textCols[j]
|
||||
if (i === 0) {
|
||||
columnNames.push({name: col, index: j, aggr: 'sum'});
|
||||
columnNames.push({name: col, index: j, aggr: 'sum'})
|
||||
} else {
|
||||
cols.push(col);
|
||||
cols2.push({key: (columnNames[i]) ? columnNames[i].name : undefined, value: col});
|
||||
cols.push(col)
|
||||
cols2.push({key: (columnNames[i]) ? columnNames[i].name : undefined, value: col})
|
||||
}
|
||||
}
|
||||
if (i !== 0) {
|
||||
rows.push(cols);
|
||||
array.push(cols2);
|
||||
rows.push(cols)
|
||||
array.push(cols2)
|
||||
}
|
||||
}
|
||||
this.comment = comment;
|
||||
this.columns = columnNames;
|
||||
this.rows = rows;
|
||||
this.comment = comment
|
||||
this.columns = columnNames
|
||||
this.rows = rows
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,30 +12,30 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import TableData from './tabledata.js';
|
||||
import TableData from './tabledata.js'
|
||||
|
||||
describe('TableData build', function () {
|
||||
let td;
|
||||
let td
|
||||
|
||||
beforeEach(function () {
|
||||
console.log(TableData);
|
||||
td = new TableData();
|
||||
});
|
||||
console.log(TableData)
|
||||
td = new TableData()
|
||||
})
|
||||
|
||||
it('should initialize the default value', function () {
|
||||
expect(td.columns.length).toBe(0);
|
||||
expect(td.rows.length).toBe(0);
|
||||
expect(td.comment).toBe('');
|
||||
});
|
||||
expect(td.columns.length).toBe(0)
|
||||
expect(td.rows.length).toBe(0)
|
||||
expect(td.comment).toBe('')
|
||||
})
|
||||
|
||||
it('should able to create Tabledata from paragraph result', function () {
|
||||
td.loadParagraphResult({
|
||||
type: 'TABLE',
|
||||
msg: 'key\tvalue\na\t10\nb\t20\n\nhello'
|
||||
});
|
||||
})
|
||||
|
||||
expect(td.columns.length).toBe(2);
|
||||
expect(td.rows.length).toBe(2);
|
||||
expect(td.comment).toBe('hello');
|
||||
});
|
||||
});
|
||||
expect(td.columns.length).toBe(2)
|
||||
expect(td.rows.length).toBe(2)
|
||||
expect(td.comment).toBe('hello')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
*/
|
||||
export default class Transformation {
|
||||
constructor (config) {
|
||||
this.config = config;
|
||||
this._emitter = () => {};
|
||||
this.config = config
|
||||
this._emitter = () => {}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -42,62 +42,62 @@ export default class Transformation {
|
|||
* render setting
|
||||
*/
|
||||
renderSetting (targetEl) {
|
||||
let setting = this.getSetting();
|
||||
let setting = this.getSetting()
|
||||
if (!setting) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// already readered
|
||||
if (this._scope) {
|
||||
let self = this;
|
||||
let self = this
|
||||
this._scope.$apply(function () {
|
||||
for (let k in setting.scope) {
|
||||
self._scope[k] = setting.scope[k];
|
||||
self._scope[k] = setting.scope[k]
|
||||
}
|
||||
|
||||
for (let k in self._prevSettingScope) {
|
||||
if (!setting.scope[k]) {
|
||||
self._scope[k] = setting.scope[k];
|
||||
self._scope[k] = setting.scope[k]
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
} else {
|
||||
this._prevSettingScope = setting.scope;
|
||||
this._prevSettingScope = setting.scope
|
||||
}
|
||||
|
||||
let scope = this._createNewScope();
|
||||
let scope = this._createNewScope()
|
||||
for (let k in setting.scope) {
|
||||
scope[k] = setting.scope[k];
|
||||
scope[k] = setting.scope[k]
|
||||
}
|
||||
let template = setting.template;
|
||||
let template = setting.template
|
||||
|
||||
if (template.split('\n').length === 1 &&
|
||||
template.endsWith('.html')) { // template is url
|
||||
let self = this;
|
||||
let self = this
|
||||
this._templateRequest(template).then(function (t) {
|
||||
self._render(targetEl, t, scope);
|
||||
});
|
||||
self._render(targetEl, t, scope)
|
||||
})
|
||||
} else {
|
||||
this._render(targetEl, template, scope);
|
||||
this._render(targetEl, template, scope)
|
||||
}
|
||||
}
|
||||
|
||||
_render (targetEl, template, scope) {
|
||||
this._targetEl = targetEl;
|
||||
targetEl.html(template);
|
||||
this._compile(targetEl.contents())(scope);
|
||||
this._scope = scope;
|
||||
this._targetEl = targetEl
|
||||
targetEl.html(template)
|
||||
this._compile(targetEl.contents())(scope)
|
||||
this._scope = scope
|
||||
}
|
||||
|
||||
setConfig (config) {
|
||||
this.config = config;
|
||||
this.config = config
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit config. config will sent to server and saved.
|
||||
*/
|
||||
emitConfig (config) {
|
||||
this._emitter(config);
|
||||
this._emitter(config)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,25 +12,25 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Nvd3ChartVisualization from './visualization-nvd3chart';
|
||||
import PivotTransformation from '../../tabledata/pivot';
|
||||
import Nvd3ChartVisualization from './visualization-nvd3chart'
|
||||
import PivotTransformation from '../../tabledata/pivot'
|
||||
|
||||
/**
|
||||
* Visualize data in area chart
|
||||
*/
|
||||
export default class AreachartVisualization extends Nvd3ChartVisualization {
|
||||
constructor (targetEl, config) {
|
||||
super(targetEl, config);
|
||||
super(targetEl, config)
|
||||
|
||||
this.pivot = new PivotTransformation(config);
|
||||
this.pivot = new PivotTransformation(config)
|
||||
}
|
||||
|
||||
type () {
|
||||
return 'stackedAreaChart';
|
||||
return 'stackedAreaChart'
|
||||
}
|
||||
|
||||
getTransformation () {
|
||||
return this.pivot;
|
||||
return this.pivot
|
||||
}
|
||||
|
||||
render (pivot) {
|
||||
|
|
@ -42,36 +42,36 @@ export default class AreachartVisualization extends Nvd3ChartVisualization {
|
|||
pivot.values,
|
||||
false,
|
||||
true,
|
||||
false);
|
||||
false)
|
||||
|
||||
this.xLabels = d3Data.xLabels;
|
||||
super.render(d3Data);
|
||||
this.xLabels = d3Data.xLabels
|
||||
super.render(d3Data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new config
|
||||
*/
|
||||
setConfig (config) {
|
||||
super.setConfig(config);
|
||||
this.pivot.setConfig(config);
|
||||
super.setConfig(config)
|
||||
this.pivot.setConfig(config)
|
||||
}
|
||||
|
||||
configureChart (chart) {
|
||||
let self = this;
|
||||
chart.xAxis.tickFormat(function (d) { return self.xAxisTickFormat(d, self.xLabels); });
|
||||
chart.yAxis.tickFormat(function (d) { return self.yAxisTickFormat(d); });
|
||||
chart.yAxis.axisLabelDistance(50);
|
||||
chart.useInteractiveGuideline(true); // for better UX and performance issue. (https://github.com/novus/nvd3/issues/691)
|
||||
let self = this
|
||||
chart.xAxis.tickFormat(function (d) { return self.xAxisTickFormat(d, self.xLabels) })
|
||||
chart.yAxis.tickFormat(function (d) { return self.yAxisTickFormat(d) })
|
||||
chart.yAxis.axisLabelDistance(50)
|
||||
chart.useInteractiveGuideline(true) // for better UX and performance issue. (https://github.com/novus/nvd3/issues/691)
|
||||
|
||||
this.chart.style(this.config.style || 'stack');
|
||||
this.chart.style(this.config.style || 'stack')
|
||||
|
||||
this.chart.dispatch.on('stateChange', function (s) {
|
||||
self.config.style = s.style;
|
||||
self.config.style = s.style
|
||||
|
||||
// give some time to animation finish
|
||||
setTimeout(function () {
|
||||
self.emitConfig(self.config);
|
||||
}, 500);
|
||||
});
|
||||
self.emitConfig(self.config)
|
||||
}, 500)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,25 +12,25 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Nvd3ChartVisualization from './visualization-nvd3chart';
|
||||
import PivotTransformation from '../../tabledata/pivot';
|
||||
import Nvd3ChartVisualization from './visualization-nvd3chart'
|
||||
import PivotTransformation from '../../tabledata/pivot'
|
||||
|
||||
/**
|
||||
* Visualize data in bar char
|
||||
*/
|
||||
export default class BarchartVisualization extends Nvd3ChartVisualization {
|
||||
constructor (targetEl, config) {
|
||||
super(targetEl, config);
|
||||
super(targetEl, config)
|
||||
|
||||
this.pivot = new PivotTransformation(config);
|
||||
this.pivot = new PivotTransformation(config)
|
||||
}
|
||||
|
||||
type () {
|
||||
return 'multiBarChart';
|
||||
return 'multiBarChart'
|
||||
}
|
||||
|
||||
getTransformation () {
|
||||
return this.pivot;
|
||||
return this.pivot
|
||||
}
|
||||
|
||||
render (pivot) {
|
||||
|
|
@ -42,7 +42,7 @@ export default class BarchartVisualization extends Nvd3ChartVisualization {
|
|||
pivot.values,
|
||||
true,
|
||||
true,
|
||||
true);
|
||||
true)
|
||||
|
||||
super.render(d3Data);
|
||||
this.config.changeXLabel(this.config.xLabelStatus);
|
||||
|
|
@ -52,8 +52,8 @@ export default class BarchartVisualization extends Nvd3ChartVisualization {
|
|||
* Set new config
|
||||
*/
|
||||
setConfig (config) {
|
||||
super.setConfig(config);
|
||||
this.pivot.setConfig(config);
|
||||
super.setConfig(config)
|
||||
this.pivot.setConfig(config)
|
||||
}
|
||||
|
||||
configureChart (chart) {
|
||||
|
|
|
|||
|
|
@ -12,29 +12,29 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Nvd3ChartVisualization from './visualization-nvd3chart';
|
||||
import PivotTransformation from '../../tabledata/pivot';
|
||||
import Nvd3ChartVisualization from './visualization-nvd3chart'
|
||||
import PivotTransformation from '../../tabledata/pivot'
|
||||
|
||||
/**
|
||||
* Visualize data in line chart
|
||||
*/
|
||||
export default class LinechartVisualization extends Nvd3ChartVisualization {
|
||||
constructor (targetEl, config) {
|
||||
super(targetEl, config);
|
||||
super(targetEl, config)
|
||||
|
||||
this.pivot = new PivotTransformation(config);
|
||||
this.pivot = new PivotTransformation(config)
|
||||
}
|
||||
|
||||
type () {
|
||||
if (this.config.lineWithFocus) {
|
||||
return 'lineWithFocusChart';
|
||||
return 'lineWithFocusChart'
|
||||
} else {
|
||||
return 'lineChart';
|
||||
return 'lineChart'
|
||||
}
|
||||
}
|
||||
|
||||
getTransformation () {
|
||||
return this.pivot;
|
||||
return this.pivot
|
||||
}
|
||||
|
||||
render (pivot) {
|
||||
|
|
@ -46,49 +46,49 @@ export default class LinechartVisualization extends Nvd3ChartVisualization {
|
|||
pivot.values,
|
||||
false,
|
||||
true,
|
||||
false);
|
||||
false)
|
||||
|
||||
this.xLabels = d3Data.xLabels;
|
||||
super.render(d3Data);
|
||||
this.xLabels = d3Data.xLabels
|
||||
super.render(d3Data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new config
|
||||
*/
|
||||
setConfig (config) {
|
||||
super.setConfig(config);
|
||||
this.pivot.setConfig(config);
|
||||
super.setConfig(config)
|
||||
this.pivot.setConfig(config)
|
||||
|
||||
// change mode
|
||||
if (this.currentMode !== config.lineWithFocus) {
|
||||
super.destroy();
|
||||
this.currentMode = config.lineWithFocus;
|
||||
super.destroy()
|
||||
this.currentMode = config.lineWithFocus
|
||||
}
|
||||
}
|
||||
|
||||
configureChart (chart) {
|
||||
let self = this;
|
||||
chart.xAxis.tickFormat(function (d) { return self.xAxisTickFormat(d, self.xLabels); });
|
||||
let self = this
|
||||
chart.xAxis.tickFormat(function (d) { return self.xAxisTickFormat(d, self.xLabels) })
|
||||
chart.yAxis.tickFormat(function (d) {
|
||||
if (d === undefined) {
|
||||
return 'N/A';
|
||||
return 'N/A'
|
||||
}
|
||||
return self.yAxisTickFormat(d, self.xLabels);
|
||||
});
|
||||
chart.yAxis.axisLabelDistance(50);
|
||||
return self.yAxisTickFormat(d, self.xLabels)
|
||||
})
|
||||
chart.yAxis.axisLabelDistance(50)
|
||||
if (chart.useInteractiveGuideline) { // lineWithFocusChart hasn't got useInteractiveGuideline
|
||||
chart.useInteractiveGuideline(true); // for better UX and performance issue. (https://github.com/novus/nvd3/issues/691)
|
||||
chart.useInteractiveGuideline(true) // for better UX and performance issue. (https://github.com/novus/nvd3/issues/691)
|
||||
}
|
||||
if (this.config.forceY) {
|
||||
chart.forceY([0]); // force y-axis minimum to 0 for line chart.
|
||||
chart.forceY([0]) // force y-axis minimum to 0 for line chart.
|
||||
} else {
|
||||
chart.forceY([]);
|
||||
chart.forceY([])
|
||||
}
|
||||
}
|
||||
|
||||
getSetting (chart) {
|
||||
let self = this;
|
||||
let configObj = self.config;
|
||||
let self = this
|
||||
let configObj = self.config
|
||||
|
||||
return {
|
||||
template: `<div>
|
||||
|
|
@ -110,13 +110,13 @@ export default class LinechartVisualization extends Nvd3ChartVisualization {
|
|||
scope: {
|
||||
config: configObj,
|
||||
save: function () {
|
||||
self.emitConfig(configObj);
|
||||
self.emitConfig(configObj)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
defaultY () {
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,42 +12,42 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Visualization from '../visualization';
|
||||
import Visualization from '../visualization'
|
||||
|
||||
/**
|
||||
* Visualize data in table format
|
||||
*/
|
||||
export default class Nvd3ChartVisualization extends Visualization {
|
||||
constructor (targetEl, config) {
|
||||
super(targetEl, config);
|
||||
this.targetEl.append('<svg></svg>');
|
||||
super(targetEl, config)
|
||||
this.targetEl.append('<svg></svg>')
|
||||
}
|
||||
|
||||
refresh () {
|
||||
if (this.chart) {
|
||||
this.chart.update();
|
||||
this.chart.update()
|
||||
}
|
||||
}
|
||||
|
||||
render (data) {
|
||||
let type = this.type();
|
||||
let d3g = data.d3g;
|
||||
let type = this.type()
|
||||
let d3g = data.d3g
|
||||
|
||||
if (!this.chart) {
|
||||
this.chart = nv.models[type]();
|
||||
this.chart = nv.models[type]()
|
||||
}
|
||||
|
||||
this.configureChart(this.chart);
|
||||
this.configureChart(this.chart)
|
||||
|
||||
let animationDuration = 300;
|
||||
let numberOfDataThreshold = 150;
|
||||
let height = this.targetEl.height();
|
||||
let animationDuration = 300
|
||||
let numberOfDataThreshold = 150
|
||||
let height = this.targetEl.height()
|
||||
|
||||
// turn off animation when dataset is too large. (for performance issue)
|
||||
// still, since dataset is large, the chart content sequentially appears like animated
|
||||
try {
|
||||
if (d3g[0].values.length > numberOfDataThreshold) {
|
||||
animationDuration = 0;
|
||||
animationDuration = 0
|
||||
}
|
||||
} catch (err) { /** ignore */ }
|
||||
|
||||
|
|
@ -56,8 +56,8 @@ export default class Nvd3ChartVisualization extends Visualization {
|
|||
.datum(d3g)
|
||||
.transition()
|
||||
.duration(animationDuration)
|
||||
.call(this.chart);
|
||||
d3.select('#' + this.targetEl[0].id + ' svg').style.height = height + 'px';
|
||||
.call(this.chart)
|
||||
d3.select('#' + this.targetEl[0].id + ' svg').style.height = height + 'px'
|
||||
}
|
||||
|
||||
type () {
|
||||
|
|
@ -69,175 +69,175 @@ export default class Nvd3ChartVisualization extends Visualization {
|
|||
}
|
||||
|
||||
groupedThousandsWith3DigitsFormatter (x) {
|
||||
return d3.format(',')(d3.round(x, 3));
|
||||
return d3.format(',')(d3.round(x, 3))
|
||||
}
|
||||
|
||||
customAbbrevFormatter (x) {
|
||||
let s = d3.format('.3s')(x);
|
||||
let s = d3.format('.3s')(x)
|
||||
switch (s[s.length - 1]) {
|
||||
case 'G': return s.slice(0, -1) + 'B';
|
||||
case 'G': return s.slice(0, -1) + 'B'
|
||||
}
|
||||
return s;
|
||||
return s
|
||||
}
|
||||
|
||||
defaultY () {
|
||||
return 0;
|
||||
return 0
|
||||
}
|
||||
|
||||
xAxisTickFormat (d, xLabels) {
|
||||
if (xLabels[d] && (isNaN(parseFloat(xLabels[d])) || !isFinite(xLabels[d]))) { // to handle string type xlabel
|
||||
return xLabels[d];
|
||||
return xLabels[d]
|
||||
} else {
|
||||
return d;
|
||||
return d
|
||||
}
|
||||
}
|
||||
|
||||
yAxisTickFormat (d) {
|
||||
if (Math.abs(d) >= Math.pow(10, 6)) {
|
||||
return this.customAbbrevFormatter(d);
|
||||
return this.customAbbrevFormatter(d)
|
||||
}
|
||||
return this.groupedThousandsWith3DigitsFormatter(d);
|
||||
return this.groupedThousandsWith3DigitsFormatter(d)
|
||||
}
|
||||
|
||||
d3DataFromPivot (
|
||||
schema, rows, keys, groups, values, allowTextXAxis, fillMissingValues, multiBarChart) {
|
||||
let self = this;
|
||||
let self = this
|
||||
// construct table data
|
||||
let d3g = [];
|
||||
let d3g = []
|
||||
|
||||
let concat = function (o, n) {
|
||||
if (!o) {
|
||||
return n;
|
||||
return n
|
||||
} else {
|
||||
return o + '.' + n;
|
||||
return o + '.' + n
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const getSchemaUnderKey = function (key, s) {
|
||||
for (let c in key.children) {
|
||||
s[c] = {};
|
||||
getSchemaUnderKey(key.children[c], s[c]);
|
||||
s[c] = {}
|
||||
getSchemaUnderKey(key.children[c], s[c])
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const traverse = function (sKey, s, rKey, r, func, rowName, rowValue, colName) {
|
||||
// console.log("TRAVERSE sKey=%o, s=%o, rKey=%o, r=%o, rowName=%o, rowValue=%o, colName=%o", sKey, s, rKey, r, rowName, rowValue, colName);
|
||||
|
||||
if (s.type === 'key') {
|
||||
rowName = concat(rowName, sKey);
|
||||
rowValue = concat(rowValue, rKey);
|
||||
rowName = concat(rowName, sKey)
|
||||
rowValue = concat(rowValue, rKey)
|
||||
} else if (s.type === 'group') {
|
||||
colName = concat(colName, rKey);
|
||||
colName = concat(colName, rKey)
|
||||
} else if (s.type === 'value' && sKey === rKey || valueOnly) {
|
||||
colName = concat(colName, rKey);
|
||||
func(rowName, rowValue, colName, r);
|
||||
colName = concat(colName, rKey)
|
||||
func(rowName, rowValue, colName, r)
|
||||
}
|
||||
|
||||
for (let c in s.children) {
|
||||
if (fillMissingValues && s.children[c].type === 'group' && r[c] === undefined) {
|
||||
let cs = {};
|
||||
getSchemaUnderKey(s.children[c], cs);
|
||||
traverse(c, s.children[c], c, cs, func, rowName, rowValue, colName);
|
||||
continue;
|
||||
let cs = {}
|
||||
getSchemaUnderKey(s.children[c], cs)
|
||||
traverse(c, s.children[c], c, cs, func, rowName, rowValue, colName)
|
||||
continue
|
||||
}
|
||||
|
||||
for (let j in r) {
|
||||
if (s.children[c].type === 'key' || c === j) {
|
||||
traverse(c, s.children[c], j, r[j], func, rowName, rowValue, colName);
|
||||
traverse(c, s.children[c], j, r[j], func, rowName, rowValue, colName)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const valueOnly = (keys.length === 0 && groups.length === 0 && values.length > 0);
|
||||
let noKey = (keys.length === 0);
|
||||
let isMultiBarChart = multiBarChart;
|
||||
const valueOnly = (keys.length === 0 && groups.length === 0 && values.length > 0)
|
||||
let noKey = (keys.length === 0)
|
||||
let isMultiBarChart = multiBarChart
|
||||
|
||||
let sKey = Object.keys(schema)[0];
|
||||
let sKey = Object.keys(schema)[0]
|
||||
|
||||
let rowNameIndex = {};
|
||||
let rowIdx = 0;
|
||||
let colNameIndex = {};
|
||||
let colIdx = 0;
|
||||
let rowIndexValue = {};
|
||||
let rowNameIndex = {}
|
||||
let rowIdx = 0
|
||||
let colNameIndex = {}
|
||||
let colIdx = 0
|
||||
let rowIndexValue = {}
|
||||
|
||||
for (let k in rows) {
|
||||
traverse(sKey, schema[sKey], k, rows[k], function (rowName, rowValue, colName, value) {
|
||||
// console.log("RowName=%o, row=%o, col=%o, value=%o", rowName, rowValue, colName, value);
|
||||
if (rowNameIndex[rowValue] === undefined) {
|
||||
rowIndexValue[rowIdx] = rowValue;
|
||||
rowNameIndex[rowValue] = rowIdx++;
|
||||
rowIndexValue[rowIdx] = rowValue
|
||||
rowNameIndex[rowValue] = rowIdx++
|
||||
}
|
||||
|
||||
if (colNameIndex[colName] === undefined) {
|
||||
colNameIndex[colName] = colIdx++;
|
||||
colNameIndex[colName] = colIdx++
|
||||
}
|
||||
let i = colNameIndex[colName];
|
||||
let i = colNameIndex[colName]
|
||||
if (noKey && isMultiBarChart) {
|
||||
i = 0;
|
||||
i = 0
|
||||
}
|
||||
|
||||
if (!d3g[i]) {
|
||||
d3g[i] = {
|
||||
values: [],
|
||||
key: (noKey && isMultiBarChart) ? 'values' : colName
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let xVar = isNaN(rowValue) ? ((allowTextXAxis) ? rowValue : rowNameIndex[rowValue]) : parseFloat(rowValue);
|
||||
let yVar = self.defaultY();
|
||||
if (xVar === undefined) { xVar = colName; }
|
||||
let xVar = isNaN(rowValue) ? ((allowTextXAxis) ? rowValue : rowNameIndex[rowValue]) : parseFloat(rowValue)
|
||||
let yVar = self.defaultY()
|
||||
if (xVar === undefined) { xVar = colName }
|
||||
if (value !== undefined) {
|
||||
yVar = isNaN(value.value) ? self.defaultY() : parseFloat(value.value) / parseFloat(value.count);
|
||||
yVar = isNaN(value.value) ? self.defaultY() : parseFloat(value.value) / parseFloat(value.count)
|
||||
}
|
||||
d3g[i].values.push({
|
||||
x: xVar,
|
||||
y: yVar
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// clear aggregation name, if possible
|
||||
let namesWithoutAggr = {};
|
||||
let colName;
|
||||
let withoutAggr;
|
||||
let namesWithoutAggr = {}
|
||||
let colName
|
||||
let withoutAggr
|
||||
// TODO - This part could use som refactoring - Weird if/else with similar actions and variable names
|
||||
for (colName in colNameIndex) {
|
||||
withoutAggr = colName.substring(0, colName.lastIndexOf('('));
|
||||
withoutAggr = colName.substring(0, colName.lastIndexOf('('))
|
||||
if (!namesWithoutAggr[withoutAggr]) {
|
||||
namesWithoutAggr[withoutAggr] = 1;
|
||||
namesWithoutAggr[withoutAggr] = 1
|
||||
} else {
|
||||
namesWithoutAggr[withoutAggr]++;
|
||||
namesWithoutAggr[withoutAggr]++
|
||||
}
|
||||
}
|
||||
|
||||
if (valueOnly) {
|
||||
for (let valueIndex = 0; valueIndex < d3g[0].values.length; valueIndex++) {
|
||||
colName = d3g[0].values[valueIndex].x;
|
||||
colName = d3g[0].values[valueIndex].x
|
||||
if (!colName) {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
|
||||
withoutAggr = colName.substring(0, colName.lastIndexOf('('));
|
||||
withoutAggr = colName.substring(0, colName.lastIndexOf('('))
|
||||
if (namesWithoutAggr[withoutAggr] <= 1) {
|
||||
d3g[0].values[valueIndex].x = withoutAggr;
|
||||
d3g[0].values[valueIndex].x = withoutAggr
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let d3gIndex = 0; d3gIndex < d3g.length; d3gIndex++) {
|
||||
colName = d3g[d3gIndex].key;
|
||||
withoutAggr = colName.substring(0, colName.lastIndexOf('('));
|
||||
colName = d3g[d3gIndex].key
|
||||
withoutAggr = colName.substring(0, colName.lastIndexOf('('))
|
||||
if (namesWithoutAggr[withoutAggr] <= 1) {
|
||||
d3g[d3gIndex].key = withoutAggr;
|
||||
d3g[d3gIndex].key = withoutAggr
|
||||
}
|
||||
}
|
||||
|
||||
// use group name instead of group.value as a column name, if there're only one group and one value selected.
|
||||
if (groups.length === 1 && values.length === 1) {
|
||||
for (let d3gIndex = 0; d3gIndex < d3g.length; d3gIndex++) {
|
||||
colName = d3g[d3gIndex].key;
|
||||
colName = colName.split('.').slice(0, -1).join('.');
|
||||
d3g[d3gIndex].key = colName;
|
||||
colName = d3g[d3gIndex].key
|
||||
colName = colName.split('.').slice(0, -1).join('.')
|
||||
d3g[d3gIndex].key = colName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -245,7 +245,7 @@ export default class Nvd3ChartVisualization extends Visualization {
|
|||
return {
|
||||
xLabels: rowIndexValue,
|
||||
d3g: d3g
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -254,8 +254,8 @@ export default class Nvd3ChartVisualization extends Visualization {
|
|||
*/
|
||||
destroy () {
|
||||
if (this.chart) {
|
||||
d3.selectAll('#' + this.targetEl[0].id + ' svg > *').remove();
|
||||
this.chart = undefined;
|
||||
d3.selectAll('#' + this.targetEl[0].id + ' svg > *').remove()
|
||||
this.chart = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,29 +12,29 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Nvd3ChartVisualization from './visualization-nvd3chart';
|
||||
import PivotTransformation from '../../tabledata/pivot';
|
||||
import Nvd3ChartVisualization from './visualization-nvd3chart'
|
||||
import PivotTransformation from '../../tabledata/pivot'
|
||||
|
||||
/**
|
||||
* Visualize data in pie chart
|
||||
*/
|
||||
export default class PiechartVisualization extends Nvd3ChartVisualization {
|
||||
constructor (targetEl, config) {
|
||||
super(targetEl, config);
|
||||
this.pivot = new PivotTransformation(config);
|
||||
super(targetEl, config)
|
||||
this.pivot = new PivotTransformation(config)
|
||||
}
|
||||
|
||||
type () {
|
||||
return 'pieChart';
|
||||
return 'pieChart'
|
||||
}
|
||||
|
||||
getTransformation () {
|
||||
return this.pivot;
|
||||
return this.pivot
|
||||
}
|
||||
|
||||
render (pivot) {
|
||||
// [ZEPPELIN-2253] New chart function will be created each time inside super.render()
|
||||
this.chart = null;
|
||||
this.chart = null
|
||||
const d3Data = this.d3DataFromPivot(
|
||||
pivot.schema,
|
||||
pivot.rows,
|
||||
|
|
@ -43,41 +43,41 @@ export default class PiechartVisualization extends Nvd3ChartVisualization {
|
|||
pivot.values,
|
||||
true,
|
||||
false,
|
||||
false);
|
||||
const d = d3Data.d3g;
|
||||
false)
|
||||
const d = d3Data.d3g
|
||||
|
||||
let generateLabel;
|
||||
let generateLabel
|
||||
// data is grouped
|
||||
if (pivot.groups && pivot.groups.length > 0) {
|
||||
generateLabel = (suffix, prefix) => `${prefix}.${suffix}`;
|
||||
generateLabel = (suffix, prefix) => `${prefix}.${suffix}`
|
||||
} else { // data isn't grouped
|
||||
generateLabel = suffix => suffix;
|
||||
generateLabel = suffix => suffix
|
||||
}
|
||||
|
||||
let d3g = d.map(group => {
|
||||
return group.values.map(row => ({
|
||||
label: generateLabel(row.x, group.key),
|
||||
value: row.y
|
||||
}));
|
||||
});
|
||||
}))
|
||||
})
|
||||
// the map function returns d3g as a nested array
|
||||
// [].concat flattens it, http://stackoverflow.com/a/10865042/5154397
|
||||
d3g = [].concat.apply([], d3g); // eslint-disable-line prefer-spread
|
||||
super.render({d3g: d3g});
|
||||
d3g = [].concat.apply([], d3g) // eslint-disable-line prefer-spread
|
||||
super.render({d3g: d3g})
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new config
|
||||
*/
|
||||
setConfig (config) {
|
||||
super.setConfig(config);
|
||||
this.pivot.setConfig(config);
|
||||
super.setConfig(config)
|
||||
this.pivot.setConfig(config)
|
||||
}
|
||||
|
||||
configureChart (chart) {
|
||||
chart.x(function (d) { return d.label; })
|
||||
.y(function (d) { return d.value; })
|
||||
chart.x(function (d) { return d.label })
|
||||
.y(function (d) { return d.value })
|
||||
.showLabels(false)
|
||||
.showTooltipPercent(true);
|
||||
.showTooltipPercent(true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Nvd3ChartVisualization from './visualization-nvd3chart';
|
||||
import ColumnselectorTransformation from '../../tabledata/columnselector';
|
||||
import Nvd3ChartVisualization from './visualization-nvd3chart'
|
||||
import ColumnselectorTransformation from '../../tabledata/columnselector'
|
||||
|
||||
/**
|
||||
* Visualize data in scatter char
|
||||
*/
|
||||
export default class ScatterchartVisualization extends Nvd3ChartVisualization {
|
||||
constructor (targetEl, config) {
|
||||
super(targetEl, config);
|
||||
super(targetEl, config)
|
||||
|
||||
this.columnselectorProps = [
|
||||
{
|
||||
|
|
@ -41,196 +41,196 @@ export default class ScatterchartVisualization extends Nvd3ChartVisualization {
|
|||
or the number of distinct values are bigger than 5% of total number of values.</li>
|
||||
<li>Size field button turns to grey when the option you chose is not valid.</li>`
|
||||
}
|
||||
];
|
||||
this.columnselector = new ColumnselectorTransformation(config, this.columnselectorProps);
|
||||
]
|
||||
this.columnselector = new ColumnselectorTransformation(config, this.columnselectorProps)
|
||||
}
|
||||
|
||||
type () {
|
||||
return 'scatterChart';
|
||||
return 'scatterChart'
|
||||
}
|
||||
|
||||
getTransformation () {
|
||||
return this.columnselector;
|
||||
return this.columnselector
|
||||
}
|
||||
|
||||
render (tableData) {
|
||||
this.tableData = tableData;
|
||||
this.selectDefault();
|
||||
let d3Data = this.setScatterChart(tableData, true);
|
||||
this.xLabels = d3Data.xLabels;
|
||||
this.yLabels = d3Data.yLabels;
|
||||
this.tableData = tableData
|
||||
this.selectDefault()
|
||||
let d3Data = this.setScatterChart(tableData, true)
|
||||
this.xLabels = d3Data.xLabels
|
||||
this.yLabels = d3Data.yLabels
|
||||
|
||||
super.render(d3Data);
|
||||
super.render(d3Data)
|
||||
}
|
||||
|
||||
configureChart (chart) {
|
||||
let self = this;
|
||||
let self = this
|
||||
|
||||
chart.xAxis.tickFormat(function (d) { // TODO remove round after bump to nvd3 > 1.8.5
|
||||
return self.xAxisTickFormat(Math.round(d * 1e3) / 1e3, self.xLabels);
|
||||
});
|
||||
return self.xAxisTickFormat(Math.round(d * 1e3) / 1e3, self.xLabels)
|
||||
})
|
||||
|
||||
chart.yAxis.tickFormat(function (d) { // TODO remove round after bump to nvd3 > 1.8.5
|
||||
return self.yAxisTickFormat(Math.round(d * 1e3) / 1e3, self.yLabels);
|
||||
});
|
||||
return self.yAxisTickFormat(Math.round(d * 1e3) / 1e3, self.yLabels)
|
||||
})
|
||||
|
||||
chart.showDistX(true).showDistY(true);
|
||||
chart.showDistX(true).showDistY(true)
|
||||
// handle the problem of tooltip not showing when muliple points have same value.
|
||||
}
|
||||
|
||||
yAxisTickFormat (d, yLabels) {
|
||||
if (yLabels[d] && (isNaN(parseFloat(yLabels[d])) || !isFinite(yLabels[d]))) { // to handle string type xlabel
|
||||
return yLabels[d];
|
||||
return yLabels[d]
|
||||
} else {
|
||||
return super.yAxisTickFormat(d);
|
||||
return super.yAxisTickFormat(d)
|
||||
}
|
||||
}
|
||||
|
||||
selectDefault () {
|
||||
if (!this.config.xAxis && !this.config.yAxis) {
|
||||
if (this.tableData.columns.length > 1) {
|
||||
this.config.xAxis = this.tableData.columns[0];
|
||||
this.config.yAxis = this.tableData.columns[1];
|
||||
this.config.xAxis = this.tableData.columns[0]
|
||||
this.config.yAxis = this.tableData.columns[1]
|
||||
} else if (this.tableData.columns.length === 1) {
|
||||
this.config.xAxis = this.tableData.columns[0];
|
||||
this.config.xAxis = this.tableData.columns[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setScatterChart (data, refresh) {
|
||||
let xAxis = this.config.xAxis;
|
||||
let yAxis = this.config.yAxis;
|
||||
let group = this.config.group;
|
||||
let size = this.config.size;
|
||||
let xAxis = this.config.xAxis
|
||||
let yAxis = this.config.yAxis
|
||||
let group = this.config.group
|
||||
let size = this.config.size
|
||||
|
||||
let xValues = [];
|
||||
let yValues = [];
|
||||
let rows = {};
|
||||
let d3g = [];
|
||||
let xValues = []
|
||||
let yValues = []
|
||||
let rows = {}
|
||||
let d3g = []
|
||||
|
||||
let rowNameIndex = {};
|
||||
let colNameIndex = {};
|
||||
let grpNameIndex = {};
|
||||
let rowIndexValue = {};
|
||||
let colIndexValue = {};
|
||||
let grpIndexValue = {};
|
||||
let rowIdx = 0;
|
||||
let colIdx = 0;
|
||||
let grpIdx = 0;
|
||||
let grpName = '';
|
||||
let rowNameIndex = {}
|
||||
let colNameIndex = {}
|
||||
let grpNameIndex = {}
|
||||
let rowIndexValue = {}
|
||||
let colIndexValue = {}
|
||||
let grpIndexValue = {}
|
||||
let rowIdx = 0
|
||||
let colIdx = 0
|
||||
let grpIdx = 0
|
||||
let grpName = ''
|
||||
|
||||
let xValue;
|
||||
let yValue;
|
||||
let row;
|
||||
let xValue
|
||||
let yValue
|
||||
let row
|
||||
|
||||
if (!xAxis && !yAxis) {
|
||||
return {
|
||||
d3g: []
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < data.rows.length; i++) {
|
||||
row = data.rows[i];
|
||||
row = data.rows[i]
|
||||
if (xAxis) {
|
||||
xValue = row[xAxis.index];
|
||||
xValues[i] = xValue;
|
||||
xValue = row[xAxis.index]
|
||||
xValues[i] = xValue
|
||||
}
|
||||
if (yAxis) {
|
||||
yValue = row[yAxis.index];
|
||||
yValues[i] = yValue;
|
||||
yValue = row[yAxis.index]
|
||||
yValues[i] = yValue
|
||||
}
|
||||
}
|
||||
|
||||
let isAllDiscrete = ((xAxis && yAxis && this.isDiscrete(xValues) && this.isDiscrete(yValues)) ||
|
||||
(!xAxis && this.isDiscrete(yValues)) ||
|
||||
(!yAxis && this.isDiscrete(xValues)));
|
||||
(!yAxis && this.isDiscrete(xValues)))
|
||||
|
||||
if (isAllDiscrete) {
|
||||
rows = this.setDiscreteScatterData(data);
|
||||
rows = this.setDiscreteScatterData(data)
|
||||
} else {
|
||||
rows = data.rows;
|
||||
rows = data.rows
|
||||
}
|
||||
|
||||
if (!group && isAllDiscrete) {
|
||||
grpName = 'count';
|
||||
grpName = 'count'
|
||||
} else if (!group && !size) {
|
||||
if (xAxis && yAxis) {
|
||||
grpName = '(' + xAxis.name + ', ' + yAxis.name + ')';
|
||||
grpName = '(' + xAxis.name + ', ' + yAxis.name + ')'
|
||||
} else if (xAxis && !yAxis) {
|
||||
grpName = xAxis.name;
|
||||
grpName = xAxis.name
|
||||
} else if (!xAxis && yAxis) {
|
||||
grpName = yAxis.name;
|
||||
grpName = yAxis.name
|
||||
}
|
||||
} else if (!group && size) {
|
||||
grpName = size.name;
|
||||
grpName = size.name
|
||||
}
|
||||
|
||||
let epsilon = 1e-4; // TODO remove after bump to nvd3 > 1.8.5
|
||||
let epsilon = 1e-4 // TODO remove after bump to nvd3 > 1.8.5
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
row = rows[i];
|
||||
row = rows[i]
|
||||
if (xAxis) {
|
||||
xValue = row[xAxis.index];
|
||||
xValue = row[xAxis.index]
|
||||
}
|
||||
if (yAxis) {
|
||||
yValue = row[yAxis.index];
|
||||
yValue = row[yAxis.index]
|
||||
}
|
||||
if (group) {
|
||||
grpName = row[group.index];
|
||||
grpName = row[group.index]
|
||||
}
|
||||
let sz = (isAllDiscrete) ? row[row.length - 1] : ((size) ? row[size.index] : 1);
|
||||
let sz = (isAllDiscrete) ? row[row.length - 1] : ((size) ? row[size.index] : 1)
|
||||
|
||||
if (grpNameIndex[grpName] === undefined) {
|
||||
grpIndexValue[grpIdx] = grpName;
|
||||
grpNameIndex[grpName] = grpIdx++;
|
||||
grpIndexValue[grpIdx] = grpName
|
||||
grpNameIndex[grpName] = grpIdx++
|
||||
}
|
||||
|
||||
if (xAxis && rowNameIndex[xValue] === undefined) {
|
||||
rowIndexValue[rowIdx] = xValue;
|
||||
rowNameIndex[xValue] = rowIdx++;
|
||||
rowIndexValue[rowIdx] = xValue
|
||||
rowNameIndex[xValue] = rowIdx++
|
||||
}
|
||||
|
||||
if (yAxis && colNameIndex[yValue] === undefined) {
|
||||
colIndexValue[colIdx] = yValue;
|
||||
colNameIndex[yValue] = colIdx++;
|
||||
colIndexValue[colIdx] = yValue
|
||||
colNameIndex[yValue] = colIdx++
|
||||
}
|
||||
|
||||
if (!d3g[grpNameIndex[grpName]]) {
|
||||
d3g[grpNameIndex[grpName]] = {
|
||||
key: grpName,
|
||||
values: []
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// TODO remove epsilon jitter after bump to nvd3 > 1.8.5
|
||||
let xval = 0
|
||||
let yval = 0;
|
||||
let yval = 0
|
||||
if (xAxis) {
|
||||
xval = (isNaN(xValue) ? rowNameIndex[xValue] : parseFloat(xValue)) + Math.random() * epsilon;
|
||||
xval = (isNaN(xValue) ? rowNameIndex[xValue] : parseFloat(xValue)) + Math.random() * epsilon
|
||||
}
|
||||
if (yAxis) {
|
||||
yval = (isNaN(yValue) ? colNameIndex[yValue] : parseFloat(yValue)) + Math.random() * epsilon;
|
||||
yval = (isNaN(yValue) ? colNameIndex[yValue] : parseFloat(yValue)) + Math.random() * epsilon
|
||||
}
|
||||
|
||||
d3g[grpNameIndex[grpName]].values.push({
|
||||
x: xval,
|
||||
y: yval,
|
||||
size: isNaN(parseFloat(sz)) ? 1 : parseFloat(sz)
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// TODO remove sort and dedup after bump to nvd3 > 1.8.5
|
||||
let d3gvalues = d3g[grpNameIndex[grpName]].values;
|
||||
let d3gvalues = d3g[grpNameIndex[grpName]].values
|
||||
d3gvalues.sort(function (a, b) {
|
||||
return ((a['x'] - b['x']) || (a['y'] - b['y']))
|
||||
});
|
||||
})
|
||||
|
||||
for (let i = 0; i < d3gvalues.length - 1;) {
|
||||
if ((Math.abs(d3gvalues[i]['x'] - d3gvalues[i + 1]['x']) < epsilon) &&
|
||||
(Math.abs(d3gvalues[i]['y'] - d3gvalues[i + 1]['y']) < epsilon)) {
|
||||
d3gvalues.splice(i + 1, 1);
|
||||
d3gvalues.splice(i + 1, 1)
|
||||
} else {
|
||||
i++;
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -238,33 +238,33 @@ export default class ScatterchartVisualization extends Nvd3ChartVisualization {
|
|||
xLabels: rowIndexValue,
|
||||
yLabels: colIndexValue,
|
||||
d3g: d3g
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
setDiscreteScatterData (data) {
|
||||
let xAxis = this.config.xAxis;
|
||||
let yAxis = this.config.yAxis;
|
||||
let group = this.config.group;
|
||||
let xAxis = this.config.xAxis
|
||||
let yAxis = this.config.yAxis
|
||||
let group = this.config.group
|
||||
|
||||
let xValue;
|
||||
let yValue;
|
||||
let grp;
|
||||
let xValue
|
||||
let yValue
|
||||
let grp
|
||||
|
||||
let rows = {};
|
||||
let rows = {}
|
||||
|
||||
for (let i = 0; i < data.rows.length; i++) {
|
||||
let row = data.rows[i];
|
||||
let row = data.rows[i]
|
||||
if (xAxis) {
|
||||
xValue = row[xAxis.index];
|
||||
xValue = row[xAxis.index]
|
||||
}
|
||||
if (yAxis) {
|
||||
yValue = row[yAxis.index];
|
||||
yValue = row[yAxis.index]
|
||||
}
|
||||
if (group) {
|
||||
grp = row[group.index];
|
||||
grp = row[group.index]
|
||||
}
|
||||
|
||||
let key = xValue + ',' + yValue + ',' + grp;
|
||||
let key = xValue + ',' + yValue + ',' + grp
|
||||
|
||||
if (!rows[key]) {
|
||||
rows[key] = {
|
||||
|
|
@ -272,89 +272,89 @@ export default class ScatterchartVisualization extends Nvd3ChartVisualization {
|
|||
y: yValue,
|
||||
group: grp,
|
||||
size: 1
|
||||
};
|
||||
}
|
||||
} else {
|
||||
rows[key].size++;
|
||||
rows[key].size++
|
||||
}
|
||||
}
|
||||
|
||||
// change object into array
|
||||
let newRows = [];
|
||||
let newRows = []
|
||||
for (let r in rows) {
|
||||
let newRow = [];
|
||||
if (xAxis) { newRow[xAxis.index] = rows[r].x; }
|
||||
if (yAxis) { newRow[yAxis.index] = rows[r].y; }
|
||||
if (group) { newRow[group.index] = rows[r].group; }
|
||||
newRow[data.rows[0].length] = rows[r].size;
|
||||
newRows.push(newRow);
|
||||
let newRow = []
|
||||
if (xAxis) { newRow[xAxis.index] = rows[r].x }
|
||||
if (yAxis) { newRow[yAxis.index] = rows[r].y }
|
||||
if (group) { newRow[group.index] = rows[r].group }
|
||||
newRow[data.rows[0].length] = rows[r].size
|
||||
newRows.push(newRow)
|
||||
}
|
||||
return newRows;
|
||||
return newRows
|
||||
}
|
||||
|
||||
isDiscrete (field) {
|
||||
let getUnique = function (f) {
|
||||
let uniqObj = {};
|
||||
let uniqArr = [];
|
||||
let j = 0;
|
||||
let uniqObj = {}
|
||||
let uniqArr = []
|
||||
let j = 0
|
||||
for (let i = 0; i < f.length; i++) {
|
||||
let item = f[i];
|
||||
let item = f[i]
|
||||
if (uniqObj[item] !== 1) {
|
||||
uniqObj[item] = 1;
|
||||
uniqArr[j++] = item;
|
||||
uniqObj[item] = 1
|
||||
uniqArr[j++] = item
|
||||
}
|
||||
}
|
||||
return uniqArr;
|
||||
};
|
||||
return uniqArr
|
||||
}
|
||||
|
||||
for (let i = 0; i < field.length; i++) {
|
||||
if (isNaN(parseFloat(field[i])) &&
|
||||
(typeof field[i] === 'string' || field[i] instanceof String)) {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
let threshold = 0.05;
|
||||
let unique = getUnique(field);
|
||||
let threshold = 0.05
|
||||
let unique = getUnique(field)
|
||||
if (unique.length / field.length < threshold) {
|
||||
return true;
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
isValidSizeOption (options) {
|
||||
let xValues = [];
|
||||
let yValues = [];
|
||||
let rows = this.tableData.rows;
|
||||
let xValues = []
|
||||
let yValues = []
|
||||
let rows = this.tableData.rows
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i];
|
||||
let size = row[options.size.index];
|
||||
let row = rows[i]
|
||||
let size = row[options.size.index]
|
||||
|
||||
// check if the field is numeric
|
||||
if (isNaN(parseFloat(size)) || !isFinite(size)) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
if (options.xAxis) {
|
||||
let x = row[options.xAxis.index];
|
||||
xValues[i] = x;
|
||||
let x = row[options.xAxis.index]
|
||||
xValues[i] = x
|
||||
}
|
||||
if (options.yAxis) {
|
||||
let y = row[options.yAxis.index];
|
||||
yValues[i] = y;
|
||||
let y = row[options.yAxis.index]
|
||||
yValues[i] = y
|
||||
}
|
||||
}
|
||||
|
||||
// check if all existing fields are discrete
|
||||
let isAllDiscrete = ((options.xAxis && options.yAxis && this.isDiscrete(xValues) && this.isDiscrete(yValues)) ||
|
||||
(!options.xAxis && this.isDiscrete(yValues)) ||
|
||||
(!options.yAxis && this.isDiscrete(xValues)));
|
||||
(!options.yAxis && this.isDiscrete(xValues)))
|
||||
|
||||
if (isAllDiscrete) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,52 +12,52 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Visualization from '../visualization';
|
||||
import PassthroughTransformation from '../../tabledata/passthrough';
|
||||
import HandsonHelper from '../../handsontable/handsonHelper';
|
||||
import Visualization from '../visualization'
|
||||
import PassthroughTransformation from '../../tabledata/passthrough'
|
||||
import HandsonHelper from '../../handsontable/handsonHelper'
|
||||
|
||||
/**
|
||||
* Visualize data in table format
|
||||
*/
|
||||
export default class TableVisualization extends Visualization {
|
||||
constructor (targetEl, config) {
|
||||
super(targetEl, config);
|
||||
console.log('Init table viz');
|
||||
targetEl.addClass('table');
|
||||
this.passthrough = new PassthroughTransformation(config);
|
||||
super(targetEl, config)
|
||||
console.log('Init table viz')
|
||||
targetEl.addClass('table')
|
||||
this.passthrough = new PassthroughTransformation(config)
|
||||
}
|
||||
|
||||
refresh () {
|
||||
this.hot.render();
|
||||
this.hot.render()
|
||||
}
|
||||
|
||||
render (tableData) {
|
||||
let height = this.targetEl.height();
|
||||
let container = this.targetEl.css('height', height).get(0);
|
||||
let resultRows = tableData.rows;
|
||||
let columnNames = _.pluck(tableData.columns, 'name');
|
||||
let height = this.targetEl.height()
|
||||
let container = this.targetEl.css('height', height).get(0)
|
||||
let resultRows = tableData.rows
|
||||
let columnNames = _.pluck(tableData.columns, 'name')
|
||||
// eslint-disable-next-line prefer-spread
|
||||
let columns = Array.apply(null, Array(tableData.columns.length)).map(function () {
|
||||
return {type: 'text'};
|
||||
});
|
||||
return {type: 'text'}
|
||||
})
|
||||
|
||||
if (this.hot) {
|
||||
this.hot.destroy();
|
||||
this.hot.destroy()
|
||||
}
|
||||
|
||||
let handsonHelper = new HandsonHelper();
|
||||
let handsonHelper = new HandsonHelper()
|
||||
this.hot = new Handsontable(container, handsonHelper.getHandsonTableConfig(
|
||||
columns, columnNames, resultRows));
|
||||
this.hot.validateCells(null);
|
||||
columns, columnNames, resultRows))
|
||||
this.hot.validateCells(null)
|
||||
}
|
||||
|
||||
destroy () {
|
||||
if (this.hot) {
|
||||
this.hot.destroy();
|
||||
this.hot.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
getTransformation () {
|
||||
return this.passthrough;
|
||||
return this.passthrough
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@
|
|||
*/
|
||||
export default class Visualization {
|
||||
constructor (targetEl, config) {
|
||||
this.targetEl = targetEl;
|
||||
this.config = config;
|
||||
this._dirty = false;
|
||||
this._active = false;
|
||||
this._emitter = () => {};
|
||||
this.targetEl = targetEl
|
||||
this.config = config
|
||||
this._dirty = false
|
||||
this._active = false
|
||||
this._emitter = () => {}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -68,24 +68,24 @@ export default class Visualization {
|
|||
*/
|
||||
activate () {
|
||||
if (!this._active || this._dirty) {
|
||||
this.refresh();
|
||||
this._dirty = false;
|
||||
this.refresh()
|
||||
this._dirty = false
|
||||
}
|
||||
this._active = true;
|
||||
this._active = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate. invoked when visualization is de selected
|
||||
*/
|
||||
deactivate () {
|
||||
this._active = false;
|
||||
this._active = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Is active
|
||||
*/
|
||||
isActive () {
|
||||
return this._active;
|
||||
return this._active
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -93,9 +93,9 @@ export default class Visualization {
|
|||
*/
|
||||
resize () {
|
||||
if (this.isActive()) {
|
||||
this.refresh();
|
||||
this.refresh()
|
||||
} else {
|
||||
this._dirty = true;
|
||||
this._dirty = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -103,11 +103,11 @@ export default class Visualization {
|
|||
* Set new config
|
||||
*/
|
||||
setConfig (config) {
|
||||
this.config = config;
|
||||
this.config = config
|
||||
if (this.isActive()) {
|
||||
this.refresh();
|
||||
this.refresh()
|
||||
} else {
|
||||
this._dirty = true;
|
||||
this._dirty = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -115,57 +115,57 @@ export default class Visualization {
|
|||
* Emit config. config will sent to server and saved.
|
||||
*/
|
||||
emitConfig (config) {
|
||||
this._emitter(config);
|
||||
this._emitter(config)
|
||||
}
|
||||
|
||||
/**
|
||||
* render setting
|
||||
*/
|
||||
renderSetting (targetEl) {
|
||||
let setting = this.getSetting();
|
||||
let setting = this.getSetting()
|
||||
if (!setting) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// already readered
|
||||
if (this._scope) {
|
||||
let self = this;
|
||||
let self = this
|
||||
this._scope.$apply(function () {
|
||||
for (let k in setting.scope) {
|
||||
self._scope[k] = setting.scope[k];
|
||||
self._scope[k] = setting.scope[k]
|
||||
}
|
||||
|
||||
for (let k in self._prevSettingScope) {
|
||||
if (!setting.scope[k]) {
|
||||
self._scope[k] = setting.scope[k];
|
||||
self._scope[k] = setting.scope[k]
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
} else {
|
||||
this._prevSettingScope = setting.scope;
|
||||
this._prevSettingScope = setting.scope
|
||||
}
|
||||
|
||||
let scope = this._createNewScope();
|
||||
let scope = this._createNewScope()
|
||||
for (let k in setting.scope) {
|
||||
scope[k] = setting.scope[k];
|
||||
scope[k] = setting.scope[k]
|
||||
}
|
||||
let template = setting.template;
|
||||
let template = setting.template
|
||||
|
||||
if (template.split('\n').length === 1 &&
|
||||
template.endsWith('.html')) { // template is url
|
||||
this._templateRequest(template).then(t =>
|
||||
_renderSetting(this, targetEl, t, scope)
|
||||
);
|
||||
)
|
||||
} else {
|
||||
_renderSetting(this, targetEl, template, scope);
|
||||
_renderSetting(this, targetEl, template, scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _renderSetting (instance, targetEl, template, scope) {
|
||||
instance._targetEl = targetEl;
|
||||
targetEl.html(template);
|
||||
instance._compile(targetEl.contents())(scope);
|
||||
instance._scope = scope;
|
||||
instance._targetEl = targetEl
|
||||
targetEl.html(template)
|
||||
instance._compile(targetEl.contents())(scope)
|
||||
instance._scope = scope
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,25 +12,25 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').service('arrayOrderingSrv', arrayOrderingSrv);
|
||||
angular.module('zeppelinWebApp').service('arrayOrderingSrv', arrayOrderingSrv)
|
||||
|
||||
function arrayOrderingSrv (TRASH_FOLDER_ID) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let arrayOrderingSrv = this;
|
||||
let arrayOrderingSrv = this
|
||||
|
||||
this.noteListOrdering = function (note) {
|
||||
if (note.id === TRASH_FOLDER_ID) {
|
||||
return '\uFFFF';
|
||||
return '\uFFFF'
|
||||
}
|
||||
return arrayOrderingSrv.getNoteName(note);
|
||||
};
|
||||
return arrayOrderingSrv.getNoteName(note)
|
||||
}
|
||||
|
||||
this.getNoteName = function (note) {
|
||||
if (note.name === undefined || note.name.trim() === '') {
|
||||
return 'Note ' + note.id;
|
||||
return 'Note ' + note.id
|
||||
} else {
|
||||
return note.name;
|
||||
return note.name
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,37 +12,37 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').service('baseUrlSrv', baseUrlSrv);
|
||||
angular.module('zeppelinWebApp').service('baseUrlSrv', baseUrlSrv)
|
||||
|
||||
function baseUrlSrv () {
|
||||
this.getPort = function () {
|
||||
let port = Number(location.port);
|
||||
let port = Number(location.port)
|
||||
if (!port) {
|
||||
port = 80;
|
||||
port = 80
|
||||
if (location.protocol === 'https:') {
|
||||
port = 443;
|
||||
port = 443
|
||||
}
|
||||
}
|
||||
// Exception for when running locally via grunt
|
||||
if (port === process.env.WEB_PORT) {
|
||||
port = process.env.SERVER_PORT;
|
||||
port = process.env.SERVER_PORT
|
||||
}
|
||||
return port;
|
||||
};
|
||||
return port
|
||||
}
|
||||
|
||||
this.getWebsocketUrl = function () {
|
||||
let wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
let wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
return wsProtocol + '//' + location.hostname + ':' + this.getPort() +
|
||||
skipTrailingSlash(location.pathname) + '/ws';
|
||||
};
|
||||
skipTrailingSlash(location.pathname) + '/ws'
|
||||
}
|
||||
|
||||
this.getRestApiBase = function () {
|
||||
return location.protocol + '//' + location.hostname + ':' +
|
||||
this.getPort() + skipTrailingSlash(location.pathname) +
|
||||
'/api';
|
||||
};
|
||||
'/api'
|
||||
}
|
||||
|
||||
const skipTrailingSlash = function (path) {
|
||||
return path.replace(/\/$/, '');
|
||||
};
|
||||
return path.replace(/\/$/, '')
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,28 +12,28 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').service('browserDetectService', browserDetectService);
|
||||
angular.module('zeppelinWebApp').service('browserDetectService', browserDetectService)
|
||||
|
||||
function browserDetectService () {
|
||||
this.detectIE = function () {
|
||||
let ua = window.navigator.userAgent;
|
||||
let msie = ua.indexOf('MSIE ');
|
||||
let ua = window.navigator.userAgent
|
||||
let msie = ua.indexOf('MSIE ')
|
||||
if (msie > 0) {
|
||||
// IE 10 or older => return version number
|
||||
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
|
||||
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10)
|
||||
}
|
||||
let trident = ua.indexOf('Trident/');
|
||||
let trident = ua.indexOf('Trident/')
|
||||
if (trident > 0) {
|
||||
// IE 11 => return version number
|
||||
let rv = ua.indexOf('rv:');
|
||||
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
|
||||
let rv = ua.indexOf('rv:')
|
||||
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10)
|
||||
}
|
||||
let edge = ua.indexOf('Edge/');
|
||||
let edge = ua.indexOf('Edge/')
|
||||
if (edge > 0) {
|
||||
// IE 12 (aka Edge) => return version number
|
||||
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
|
||||
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10)
|
||||
}
|
||||
// other browser
|
||||
return false;
|
||||
};
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,24 +11,24 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
angular.module('zeppelinWebApp').controller('clipboardCtrl', clipboardCtrl);
|
||||
angular.module('zeppelinWebApp').controller('clipboardCtrl', clipboardCtrl)
|
||||
|
||||
function clipboardCtrl ($scope) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
$scope.complete = function (e) {
|
||||
$scope.copied = true;
|
||||
$scope.tooltip = 'Copied!';
|
||||
$scope.copied = true
|
||||
$scope.tooltip = 'Copied!'
|
||||
setTimeout(function () {
|
||||
$scope.tooltip = 'Copy to clipboard';
|
||||
}, 400);
|
||||
};
|
||||
$scope.tooltip = 'Copy to clipboard'
|
||||
}, 400)
|
||||
}
|
||||
$scope.$watch('input', function () {
|
||||
$scope.copied = false;
|
||||
$scope.tooltip = 'Copy to clipboard';
|
||||
});
|
||||
$scope.copied = false
|
||||
$scope.tooltip = 'Copy to clipboard'
|
||||
})
|
||||
$scope.clipError = function (e) {
|
||||
console.log('Error: ' + e.name + ' - ' + e.message);
|
||||
$scope.tooltip = 'Not supported browser';
|
||||
};
|
||||
console.log('Error: ' + e.name + ' - ' + e.message)
|
||||
$scope.tooltip = 'Not supported browser'
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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();
|
||||
});
|
||||
event.stopPropagation()
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').directive('codeEditor', codeEditor);
|
||||
angular.module('zeppelinWebApp').directive('codeEditor', codeEditor)
|
||||
|
||||
function codeEditor ($templateRequest, $compile) {
|
||||
return {
|
||||
|
|
@ -27,12 +27,12 @@ function codeEditor ($templateRequest, $compile) {
|
|||
},
|
||||
link: function (scope, element, attrs, controller) {
|
||||
$templateRequest('components/editor/ace.editor.directive.html').then(function (editorHtml) {
|
||||
let 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);
|
||||
});
|
||||
let 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)
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('ElasticInputCtrl', ElasticInputCtrl);
|
||||
angular.module('zeppelinWebApp').controller('ElasticInputCtrl', ElasticInputCtrl)
|
||||
|
||||
function ElasticInputCtrl () {
|
||||
let vm = this;
|
||||
vm.showEditor = false;
|
||||
vm.value = '';
|
||||
let vm = this
|
||||
vm.showEditor = false
|
||||
vm.value = ''
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').directive('expandCollapse', expandCollapse);
|
||||
angular.module('zeppelinWebApp').directive('expandCollapse', expandCollapse)
|
||||
|
||||
function expandCollapse () {
|
||||
return {
|
||||
|
|
@ -20,18 +20,18 @@ function expandCollapse () {
|
|||
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');
|
||||
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');
|
||||
angular.element(element).find('i').first().toggleClass('icon-folder icon-folder-alt')
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
event.stopPropagation();
|
||||
});
|
||||
event.stopPropagation()
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,73 +16,73 @@ export const HeliumConfFieldType = {
|
|||
NUMBER: 'number',
|
||||
JSON: 'json',
|
||||
STRING: 'string',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param persisted <Object> including `type`, `description`, `defaultValue` for each conf key
|
||||
* @param spec <Object> including `value` for each conf key
|
||||
*/
|
||||
export function mergePersistedConfWithSpec (persisted, spec) {
|
||||
const confs = [];
|
||||
const confs = []
|
||||
|
||||
for (let name in spec) {
|
||||
const specField = spec[name];
|
||||
const persistedValue = persisted[name];
|
||||
const specField = spec[name]
|
||||
const persistedValue = persisted[name]
|
||||
|
||||
const value = (persistedValue) ? persistedValue : specField.defaultValue;
|
||||
const value = (persistedValue) ? persistedValue : specField.defaultValue
|
||||
const merged = {
|
||||
name: name,
|
||||
type: specField.type,
|
||||
description: specField.description,
|
||||
value: value,
|
||||
defaultValue: specField.defaultValue,
|
||||
};
|
||||
}
|
||||
|
||||
confs.push(merged);
|
||||
confs.push(merged)
|
||||
}
|
||||
|
||||
return confs;
|
||||
return confs
|
||||
}
|
||||
|
||||
export function createAllPackageConfigs (defaultPackages, persistedConfs) {
|
||||
let packageConfs = {};
|
||||
let packageConfs = {}
|
||||
|
||||
for (let name in defaultPackages) {
|
||||
const pkgSearchResult = defaultPackages[name];
|
||||
const pkgSearchResult = defaultPackages[name]
|
||||
|
||||
const spec = pkgSearchResult.pkg.config;
|
||||
if (!spec) { continue; }
|
||||
const spec = pkgSearchResult.pkg.config
|
||||
if (!spec) { continue }
|
||||
|
||||
const artifact = pkgSearchResult.pkg.artifact;
|
||||
if (!artifact) { continue; }
|
||||
const artifact = pkgSearchResult.pkg.artifact
|
||||
if (!artifact) { continue }
|
||||
|
||||
let persistedConf = {};
|
||||
let persistedConf = {}
|
||||
if (persistedConfs[artifact]) {
|
||||
persistedConf = persistedConfs[artifact];
|
||||
persistedConf = persistedConfs[artifact]
|
||||
}
|
||||
|
||||
const confs = mergePersistedConfWithSpec(persistedConf, spec);
|
||||
packageConfs[name] = confs;
|
||||
const confs = mergePersistedConfWithSpec(persistedConf, spec)
|
||||
packageConfs[name] = confs
|
||||
}
|
||||
|
||||
return packageConfs;
|
||||
return packageConfs
|
||||
}
|
||||
|
||||
export function parseConfigValue (type, stringified) {
|
||||
let value = stringified;
|
||||
let value = stringified
|
||||
|
||||
try {
|
||||
if (HeliumConfFieldType.NUMBER === type) {
|
||||
value = parseFloat(stringified);
|
||||
value = parseFloat(stringified)
|
||||
} else if (HeliumConfFieldType.JSON === type) {
|
||||
value = JSON.parse(stringified);
|
||||
value = JSON.parse(stringified)
|
||||
}
|
||||
} catch (error) {
|
||||
// return just the stringified one
|
||||
console.error(`Failed to parse conf type ${type}, value ${value}`);
|
||||
console.error(`Failed to parse conf type ${type}, value ${value}`)
|
||||
}
|
||||
|
||||
return value;
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -91,9 +91,9 @@ export function parseConfigValue (type, stringified) {
|
|||
*/
|
||||
export function createPersistableConfig (currentConfs) {
|
||||
const filtered = currentConfs.reduce((acc, c) => {
|
||||
acc[c.name] = parseConfigValue(c.type, c.value);
|
||||
return acc;
|
||||
}, {});
|
||||
acc[c.name] = parseConfigValue(c.type, c.value)
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return filtered;
|
||||
return filtered
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,18 +14,18 @@
|
|||
|
||||
export function createDefaultPackage (pkgSearchResult, sce) {
|
||||
for (let pkgIdx in pkgSearchResult) {
|
||||
const pkg = pkgSearchResult[pkgIdx];
|
||||
pkg.pkg.icon = sce.trustAsHtml(pkg.pkg.icon);
|
||||
const pkg = pkgSearchResult[pkgIdx]
|
||||
pkg.pkg.icon = sce.trustAsHtml(pkg.pkg.icon)
|
||||
if (pkg.enabled) {
|
||||
pkgSearchResult.splice(pkgIdx, 1);
|
||||
return pkg;
|
||||
pkgSearchResult.splice(pkgIdx, 1)
|
||||
return pkg
|
||||
}
|
||||
}
|
||||
|
||||
// show first available version if package is not enabled
|
||||
const result = pkgSearchResult[0];
|
||||
pkgSearchResult.splice(0, 1);
|
||||
return result;
|
||||
const result = pkgSearchResult[0]
|
||||
pkgSearchResult.splice(0, 1)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -36,12 +36,12 @@ export function createDefaultPackage (pkgSearchResult, sce) {
|
|||
* @returns {Object} including {name, pkgInfo}
|
||||
*/
|
||||
export function createDefaultPackages (pkgSearchResults, sce) {
|
||||
const defaultPackages = {};
|
||||
const defaultPackages = {}
|
||||
// show enabled version if any version of package is enabled
|
||||
for (let name in pkgSearchResults) {
|
||||
const pkgSearchResult = pkgSearchResults[name];
|
||||
const pkgSearchResult = pkgSearchResults[name]
|
||||
defaultPackages[name] = createDefaultPackage(pkgSearchResult, sce)
|
||||
}
|
||||
|
||||
return defaultPackages;
|
||||
return defaultPackages
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,26 +12,26 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { HeliumType, } from './helium-type';
|
||||
import { HeliumType, } from './helium-type'
|
||||
import {
|
||||
createAllPackageConfigs,
|
||||
createPersistableConfig,
|
||||
mergePersistedConfWithSpec,
|
||||
} from './helium-conf';
|
||||
} from './helium-conf'
|
||||
import {
|
||||
createDefaultPackages,
|
||||
} from './helium-package';
|
||||
} from './helium-package'
|
||||
|
||||
angular.module('zeppelinWebApp').service('heliumService', heliumService);
|
||||
angular.module('zeppelinWebApp').service('heliumService', heliumService)
|
||||
|
||||
export default function heliumService ($http, $sce, baseUrlSrv) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let visualizationBundles = [];
|
||||
let visualizationBundles = []
|
||||
// name `heliumBundles` should be same as `HeliumBundleFactory.HELIUM_BUNDLES_VAR`
|
||||
let heliumBundles = [];
|
||||
let heliumBundles = []
|
||||
// map for `{ magic: interpreter }`
|
||||
let spellPerMagic = {};
|
||||
let spellPerMagic = {}
|
||||
// map for `{ magic: package-name }`
|
||||
let pkgNamePerMagic = {}
|
||||
|
||||
|
|
@ -40,39 +40,39 @@ export default function heliumService ($http, $sce, baseUrlSrv) {
|
|||
* @returns {SpellBase} undefined if magic is not registered
|
||||
*/
|
||||
this.getSpellByMagic = function (magic) {
|
||||
return spellPerMagic[magic];
|
||||
};
|
||||
return spellPerMagic[magic]
|
||||
}
|
||||
|
||||
this.executeSpell = function (magic, textWithoutMagic) {
|
||||
const promisedConf = this.getSinglePackageConfigUsingMagic(magic)
|
||||
.then(confs => createPersistableConfig(confs));
|
||||
.then(confs => createPersistableConfig(confs))
|
||||
|
||||
return promisedConf.then(conf => {
|
||||
const spell = this.getSpellByMagic(magic);
|
||||
const spellResult = spell.interpret(textWithoutMagic, conf);
|
||||
const spell = this.getSpellByMagic(magic)
|
||||
const spellResult = spell.interpret(textWithoutMagic, conf)
|
||||
const parsed = spellResult.getAllParsedDataWithTypes(
|
||||
spellPerMagic, magic, textWithoutMagic);
|
||||
spellPerMagic, magic, textWithoutMagic)
|
||||
|
||||
return parsed;
|
||||
});
|
||||
};
|
||||
return parsed
|
||||
})
|
||||
}
|
||||
|
||||
this.executeSpellAsDisplaySystem = function (magic, textWithoutMagic) {
|
||||
const promisedConf = this.getSinglePackageConfigUsingMagic(magic)
|
||||
.then(confs => createPersistableConfig(confs));
|
||||
.then(confs => createPersistableConfig(confs))
|
||||
|
||||
return promisedConf.then(conf => {
|
||||
const spell = this.getSpellByMagic(magic);
|
||||
const spellResult = spell.interpret(textWithoutMagic.trim(), conf);
|
||||
const parsed = spellResult.getAllParsedDataWithTypes(spellPerMagic);
|
||||
const spell = this.getSpellByMagic(magic)
|
||||
const spellResult = spell.interpret(textWithoutMagic.trim(), conf)
|
||||
const parsed = spellResult.getAllParsedDataWithTypes(spellPerMagic)
|
||||
|
||||
return parsed;
|
||||
});
|
||||
};
|
||||
return parsed
|
||||
})
|
||||
}
|
||||
|
||||
this.getVisualizationBundles = function () {
|
||||
return visualizationBundles;
|
||||
};
|
||||
return visualizationBundles
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise} which returns bundleOrder
|
||||
|
|
@ -80,45 +80,45 @@ export default function heliumService ($http, $sce, baseUrlSrv) {
|
|||
this.getVisualizationPackageOrder = function () {
|
||||
return $http.get(baseUrlSrv.getRestApiBase() + '/helium/order/visualization')
|
||||
.then(function (response, status) {
|
||||
return response.data.body;
|
||||
return response.data.body
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error('Can not get bundle order', error);
|
||||
});
|
||||
};
|
||||
console.error('Can not get bundle order', error)
|
||||
})
|
||||
}
|
||||
|
||||
this.setVisualizationPackageOrder = function (list) {
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/order/visualization', list);
|
||||
};
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/order/visualization', list)
|
||||
}
|
||||
|
||||
this.enable = function (name, artifact) {
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/enable/' + name, artifact);
|
||||
};
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/enable/' + name, artifact)
|
||||
}
|
||||
|
||||
this.disable = function (name) {
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/disable/' + name);
|
||||
};
|
||||
return $http.post(baseUrlSrv.getRestApiBase() + '/helium/disable/' + name)
|
||||
}
|
||||
|
||||
this.saveConfig = function (pkg, defaultPackageConfig, closeConfigPanelCallback) {
|
||||
// in case of local package, it will include `/`
|
||||
const pkgArtifact = encodeURIComponent(pkg.artifact);
|
||||
const pkgName = pkg.name;
|
||||
const filtered = createPersistableConfig(defaultPackageConfig);
|
||||
const pkgArtifact = encodeURIComponent(pkg.artifact)
|
||||
const pkgName = pkg.name
|
||||
const filtered = createPersistableConfig(defaultPackageConfig)
|
||||
|
||||
if (!pkgName || !pkgArtifact || !filtered) {
|
||||
console.error(
|
||||
`Can't save config for helium package '${pkgArtifact}'`, filtered);
|
||||
return;
|
||||
`Can't save config for helium package '${pkgArtifact}'`, filtered)
|
||||
return
|
||||
}
|
||||
|
||||
const url = `${baseUrlSrv.getRestApiBase()}/helium/config/${pkgName}/${pkgArtifact}`;
|
||||
const url = `${baseUrlSrv.getRestApiBase()}/helium/config/${pkgName}/${pkgArtifact}`
|
||||
return $http.post(url, filtered)
|
||||
.then(() => {
|
||||
if (closeConfigPanelCallback) { closeConfigPanelCallback(); }
|
||||
if (closeConfigPanelCallback) { closeConfigPanelCallback() }
|
||||
}).catch((error) => {
|
||||
console.error(`Failed to save config for ${pkgArtifact}`, error);
|
||||
});
|
||||
};
|
||||
console.error(`Failed to save config for ${pkgArtifact}`, error)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<Object>} which including {name, Array<package info for artifact>}
|
||||
|
|
@ -126,50 +126,50 @@ export default function heliumService ($http, $sce, baseUrlSrv) {
|
|||
this.getAllPackageInfo = function () {
|
||||
return $http.get(`${baseUrlSrv.getRestApiBase()}/helium/package`)
|
||||
.then(function (response, status) {
|
||||
return response.data.body;
|
||||
return response.data.body
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error('Failed to get all package infos', error);
|
||||
});
|
||||
};
|
||||
console.error('Failed to get all package infos', error)
|
||||
})
|
||||
}
|
||||
|
||||
this.getAllEnabledPackages = function () {
|
||||
return $http.get(`${baseUrlSrv.getRestApiBase()}/helium/enabledPackage`)
|
||||
.then(function (response, status) {
|
||||
return response.data.body;
|
||||
return response.data.body
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error('Failed to get all enabled package infos', error);
|
||||
});
|
||||
};
|
||||
console.error('Failed to get all enabled package infos', error)
|
||||
})
|
||||
}
|
||||
|
||||
this.getSingleBundle = function (pkgName) {
|
||||
let url = `${baseUrlSrv.getRestApiBase()}/helium/bundle/load/${pkgName}`
|
||||
if (process.env.HELIUM_BUNDLE_DEV) {
|
||||
url = url + '?refresh=true';
|
||||
url = url + '?refresh=true'
|
||||
}
|
||||
|
||||
return $http.get(url)
|
||||
.then(function (response, status) {
|
||||
const bundle = response.data
|
||||
if (bundle.substring(0, 'ERROR:'.length) === 'ERROR:') {
|
||||
console.error(`Failed to get bundle: ${pkgName}`, bundle);
|
||||
console.error(`Failed to get bundle: ${pkgName}`, bundle)
|
||||
return '' // empty bundle will be filtered later
|
||||
}
|
||||
|
||||
return bundle
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error(`Failed to get single bundle: ${pkgName}`, error);
|
||||
});
|
||||
console.error(`Failed to get single bundle: ${pkgName}`, error)
|
||||
})
|
||||
}
|
||||
|
||||
this.getDefaultPackages = function () {
|
||||
return this.getAllPackageInfo()
|
||||
.then(pkgSearchResults => {
|
||||
return createDefaultPackages(pkgSearchResults, $sce);
|
||||
});
|
||||
};
|
||||
return createDefaultPackages(pkgSearchResults, $sce)
|
||||
})
|
||||
}
|
||||
|
||||
this.getAllPackageInfoAndDefaultPackages = function () {
|
||||
return this.getAllPackageInfo()
|
||||
|
|
@ -177,73 +177,73 @@ export default function heliumService ($http, $sce, baseUrlSrv) {
|
|||
return {
|
||||
pkgSearchResults: pkgSearchResults,
|
||||
defaultPackages: createDefaultPackages(pkgSearchResults, $sce),
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* get all package configs.
|
||||
* @return { Promise<{name, Array<Object>}> }
|
||||
*/
|
||||
this.getAllPackageConfigs = function () {
|
||||
const promisedDefaultPackages = this.getDefaultPackages();
|
||||
const promisedDefaultPackages = this.getDefaultPackages()
|
||||
const promisedPersistedConfs =
|
||||
$http.get(`${baseUrlSrv.getRestApiBase()}/helium/config`)
|
||||
.then(function (response, status) {
|
||||
return response.data.body;
|
||||
});
|
||||
return response.data.body
|
||||
})
|
||||
|
||||
return Promise.all([promisedDefaultPackages, promisedPersistedConfs])
|
||||
.then(values => {
|
||||
const defaultPackages = values[0];
|
||||
const persistedConfs = values[1];
|
||||
const defaultPackages = values[0]
|
||||
const persistedConfs = values[1]
|
||||
|
||||
return createAllPackageConfigs(defaultPackages, persistedConfs);
|
||||
return createAllPackageConfigs(defaultPackages, persistedConfs)
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error('Failed to get all package configs', error);
|
||||
});
|
||||
};
|
||||
console.error('Failed to get all package configs', error)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* get the package config which is persisted in server.
|
||||
* @return { Promise<Array<Object>> }
|
||||
*/
|
||||
this.getSinglePackageConfigs = function (pkg) {
|
||||
const pkgName = pkg.name;
|
||||
const pkgName = pkg.name
|
||||
// in case of local package, it will include `/`
|
||||
const pkgArtifact = encodeURIComponent(pkg.artifact);
|
||||
const pkgArtifact = encodeURIComponent(pkg.artifact)
|
||||
|
||||
if (!pkgName || !pkgArtifact) {
|
||||
console.error('Failed to fetch config for\n', pkg);
|
||||
return Promise.resolve([]);
|
||||
console.error('Failed to fetch config for\n', pkg)
|
||||
return Promise.resolve([])
|
||||
}
|
||||
|
||||
const confUrl = `${baseUrlSrv.getRestApiBase()}/helium/config/${pkgName}/${pkgArtifact}`;
|
||||
const confUrl = `${baseUrlSrv.getRestApiBase()}/helium/config/${pkgName}/${pkgArtifact}`
|
||||
const promisedConf = $http.get(confUrl)
|
||||
.then(function (response, status) {
|
||||
return response.data.body;
|
||||
});
|
||||
return response.data.body
|
||||
})
|
||||
|
||||
return promisedConf.then(({confSpec, confPersisted}) => {
|
||||
const merged = mergePersistedConfWithSpec(confPersisted, confSpec)
|
||||
return merged;
|
||||
});
|
||||
};
|
||||
return merged
|
||||
})
|
||||
}
|
||||
|
||||
this.getSinglePackageConfigUsingMagic = function (magic) {
|
||||
const pkgName = pkgNamePerMagic[magic];
|
||||
const pkgName = pkgNamePerMagic[magic]
|
||||
|
||||
const confUrl = `${baseUrlSrv.getRestApiBase()}/helium/spell/config/${pkgName}`;
|
||||
const confUrl = `${baseUrlSrv.getRestApiBase()}/helium/spell/config/${pkgName}`
|
||||
const promisedConf = $http.get(confUrl)
|
||||
.then(function (response, status) {
|
||||
return response.data.body;
|
||||
});
|
||||
return response.data.body
|
||||
})
|
||||
|
||||
return promisedConf.then(({confSpec, confPersisted}) => {
|
||||
const merged = mergePersistedConfWithSpec(confPersisted, confSpec)
|
||||
return merged;
|
||||
});
|
||||
return merged
|
||||
})
|
||||
}
|
||||
|
||||
const p = this.getAllEnabledPackages()
|
||||
|
|
@ -260,7 +260,7 @@ export default function heliumService ($http, $sce, baseUrlSrv) {
|
|||
// filter out empty bundle
|
||||
if (b === '') { return acc }
|
||||
acc.push(b)
|
||||
return acc;
|
||||
return acc
|
||||
}, [])
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -12,20 +12,20 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').directive('interpreterDirective', interpreterDirective);
|
||||
angular.module('zeppelinWebApp').directive('interpreterDirective', interpreterDirective)
|
||||
|
||||
function interpreterDirective ($timeout) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attr) {
|
||||
if (scope.$last === true) {
|
||||
$timeout(function () {
|
||||
let id = 'ngRenderFinished';
|
||||
scope.$emit(id);
|
||||
});
|
||||
let id = 'ngRenderFinished'
|
||||
scope.$emit(id)
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('LoginCtrl', LoginCtrl);
|
||||
angular.module('zeppelinWebApp').controller('LoginCtrl', LoginCtrl)
|
||||
|
||||
function LoginCtrl ($scope, $rootScope, $http, $httpParamSerializer, baseUrlSrv, $location, $timeout) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
$scope.SigningIn = false;
|
||||
$scope.loginParams = {};
|
||||
$scope.SigningIn = false
|
||||
$scope.loginParams = {}
|
||||
$scope.login = function () {
|
||||
$scope.SigningIn = true;
|
||||
$scope.SigningIn = true
|
||||
$http({
|
||||
method: 'POST',
|
||||
url: baseUrlSrv.getRestApiBase() + '/login',
|
||||
|
|
@ -32,53 +32,53 @@ function LoginCtrl ($scope, $rootScope, $http, $httpParamSerializer, baseUrlSrv,
|
|||
'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;
|
||||
$scope.SigningIn = false;
|
||||
$rootScope.ticket = response.data.body
|
||||
angular.element('#loginModal').modal('toggle')
|
||||
$rootScope.$broadcast('loginSuccess', true)
|
||||
$rootScope.userName = $scope.loginParams.userName
|
||||
$scope.SigningIn = false
|
||||
|
||||
// redirect to the page from where the user originally was
|
||||
if ($location.search() && $location.search()['ref']) {
|
||||
$timeout(function () {
|
||||
let redirectLocation = $location.search()['ref'];
|
||||
$location.$$search = {};
|
||||
$location.path(redirectLocation);
|
||||
}, 100);
|
||||
let redirectLocation = $location.search()['ref']
|
||||
$location.$$search = {}
|
||||
$location.path(redirectLocation)
|
||||
}, 100)
|
||||
}
|
||||
}, function errorCallback (errorResponse) {
|
||||
$scope.loginParams.errorText = 'The username and password that you entered don\'t match.';
|
||||
$scope.SigningIn = false;
|
||||
});
|
||||
};
|
||||
$scope.loginParams.errorText = 'The username and password that you entered don\'t match.'
|
||||
$scope.SigningIn = false
|
||||
})
|
||||
}
|
||||
|
||||
let initValues = function () {
|
||||
$scope.loginParams = {
|
||||
userName: '',
|
||||
password: ''
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// handle session logout message received from WebSocket
|
||||
$rootScope.$on('session_logout', function (event, data) {
|
||||
if ($rootScope.userName !== '') {
|
||||
$rootScope.userName = '';
|
||||
$rootScope.ticket = undefined;
|
||||
$rootScope.userName = ''
|
||||
$rootScope.ticket = undefined
|
||||
|
||||
setTimeout(function () {
|
||||
$scope.loginParams = {};
|
||||
$scope.loginParams.errorText = data.info;
|
||||
angular.element('.nav-login-btn').click();
|
||||
}, 1000);
|
||||
let locationPath = $location.path();
|
||||
$location.path('/').search('ref', locationPath);
|
||||
$scope.loginParams = {}
|
||||
$scope.loginParams.errorText = data.info
|
||||
angular.element('.nav-login-btn').click()
|
||||
}, 1000)
|
||||
let locationPath = $location.path()
|
||||
$location.path('/').search('ref', locationPath)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
/*
|
||||
** $scope.$on functions below
|
||||
*/
|
||||
$scope.$on('initLoginValues', function () {
|
||||
initValues();
|
||||
});
|
||||
initValues()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,109 +12,109 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('NavCtrl', NavCtrl);
|
||||
angular.module('zeppelinWebApp').controller('NavCtrl', NavCtrl)
|
||||
|
||||
function NavCtrl ($scope, $rootScope, $http, $routeParams, $location,
|
||||
noteListDataFactory, baseUrlSrv, websocketMsgSrv,
|
||||
arrayOrderingSrv, searchService, TRASH_FOLDER_ID) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let 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;
|
||||
vm.isFilterNote = isFilterNote;
|
||||
let 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
|
||||
vm.isFilterNote = isFilterNote
|
||||
|
||||
$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;
|
||||
$rootScope.zeppelinVersion = data.body
|
||||
}).error(
|
||||
function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
console.log('Error %o %o', status, data.message)
|
||||
})
|
||||
}
|
||||
|
||||
function initController () {
|
||||
$scope.isDrawNavbarNoteList = false;
|
||||
angular.element('#notebook-list').perfectScrollbar({suppressScrollX: true});
|
||||
$scope.isDrawNavbarNoteList = false
|
||||
angular.element('#notebook-list').perfectScrollbar({suppressScrollX: true})
|
||||
|
||||
angular.element(document).click(function () {
|
||||
$scope.query.q = '';
|
||||
});
|
||||
$scope.query.q = ''
|
||||
})
|
||||
|
||||
getZeppelinVersion();
|
||||
loadNotes();
|
||||
getZeppelinVersion()
|
||||
loadNotes()
|
||||
}
|
||||
|
||||
function isFilterNote (note) {
|
||||
if (!$scope.query.q) {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
let noteName = note.name;
|
||||
let noteName = note.name
|
||||
if (noteName.toLowerCase().indexOf($scope.query.q.toLowerCase()) > -1) {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
function isActive (noteId) {
|
||||
return ($routeParams.noteId === noteId);
|
||||
return ($routeParams.noteId === noteId)
|
||||
}
|
||||
|
||||
function listConfigurations () {
|
||||
websocketMsgSrv.listConfigurations();
|
||||
websocketMsgSrv.listConfigurations()
|
||||
}
|
||||
|
||||
function loadNotes () {
|
||||
websocketMsgSrv.getNoteList();
|
||||
websocketMsgSrv.getNoteList()
|
||||
}
|
||||
|
||||
function getHomeNote () {
|
||||
websocketMsgSrv.getHomeNote();
|
||||
websocketMsgSrv.getHomeNote()
|
||||
}
|
||||
|
||||
function logout () {
|
||||
let logoutURL = baseUrlSrv.getRestApiBase() + '/login/logout';
|
||||
let logoutURL = baseUrlSrv.getRestApiBase() + '/login/logout'
|
||||
|
||||
// for firefox and safari
|
||||
logoutURL = logoutURL.replace('//', '//false:false@');
|
||||
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 = '';
|
||||
$rootScope.userName = ''
|
||||
$rootScope.ticket.principal = ''
|
||||
$rootScope.ticket.ticket = ''
|
||||
$rootScope.ticket.roles = ''
|
||||
BootstrapDialog.show({
|
||||
message: 'Logout Success'
|
||||
});
|
||||
})
|
||||
setTimeout(function () {
|
||||
window.location.replace('/');
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
window.location.replace('/')
|
||||
}, 1000)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function search (searchTerm) {
|
||||
$location.path('/search/' + searchTerm);
|
||||
$location.path('/search/' + searchTerm)
|
||||
}
|
||||
|
||||
function showLoginWindow () {
|
||||
setTimeout(function () {
|
||||
angular.element('#userName').focus();
|
||||
}, 500);
|
||||
angular.element('#userName').focus()
|
||||
}, 500)
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -122,19 +122,19 @@ function NavCtrl ($scope, $rootScope, $http, $routeParams, $location,
|
|||
*/
|
||||
|
||||
$scope.$on('setNoteMenu', function (event, notes) {
|
||||
noteListDataFactory.setNotes(notes);
|
||||
initNotebookListEventListener();
|
||||
});
|
||||
noteListDataFactory.setNotes(notes)
|
||||
initNotebookListEventListener()
|
||||
})
|
||||
|
||||
$scope.$on('setConnectedStatus', function (event, param) {
|
||||
vm.connected = param;
|
||||
});
|
||||
vm.connected = param
|
||||
})
|
||||
|
||||
$scope.$on('loginSuccess', function (event, param) {
|
||||
listConfigurations();
|
||||
loadNotes();
|
||||
getHomeNote();
|
||||
});
|
||||
listConfigurations()
|
||||
loadNotes()
|
||||
getHomeNote()
|
||||
})
|
||||
|
||||
/*
|
||||
** Performance optimization for Browser Render.
|
||||
|
|
@ -142,12 +142,12 @@ function NavCtrl ($scope, $rootScope, $http, $routeParams, $location,
|
|||
function initNotebookListEventListener () {
|
||||
angular.element(document).ready(function () {
|
||||
angular.element('.notebook-list-dropdown').on('show.bs.dropdown', function () {
|
||||
$scope.isDrawNavbarNoteList = true;
|
||||
});
|
||||
$scope.isDrawNavbarNoteList = true
|
||||
})
|
||||
|
||||
angular.element('.notebook-list-dropdown').on('hide.bs.dropdown', function () {
|
||||
$scope.isDrawNavbarNoteList = false;
|
||||
});
|
||||
});
|
||||
$scope.isDrawNavbarNoteList = false
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
describe('Controller: NavCtrl', function () {
|
||||
// load the controller's module
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'));
|
||||
let NavCtrl;
|
||||
let scope;
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'))
|
||||
let NavCtrl
|
||||
let scope
|
||||
// Initialize the controller and a mock scope
|
||||
beforeEach(inject(function ($controller, $rootScope) {
|
||||
scope = $rootScope.$new();
|
||||
scope = $rootScope.$new()
|
||||
NavCtrl = $controller('NavCtrl', {
|
||||
$scope: scope
|
||||
});
|
||||
})
|
||||
|
||||
it('NavCtrl to toBeDefined', function () {
|
||||
expect(NavCtrl).toBeDefined();
|
||||
expect(NavCtrl.loadNotes).toBeDefined();
|
||||
});
|
||||
}));
|
||||
});
|
||||
expect(NavCtrl).toBeDefined()
|
||||
expect(NavCtrl.loadNotes).toBeDefined()
|
||||
})
|
||||
}))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').directive('ngEnter', ngEnter);
|
||||
angular.module('zeppelinWebApp').directive('ngEnter', ngEnter)
|
||||
|
||||
function ngEnter () {
|
||||
return function (scope, element, attrs) {
|
||||
|
|
@ -20,11 +20,11 @@ function ngEnter () {
|
|||
if (event.which === 13) {
|
||||
if (!event.shiftKey) {
|
||||
scope.$apply(function () {
|
||||
scope.$eval(attrs.ngEnter);
|
||||
});
|
||||
scope.$eval(attrs.ngEnter)
|
||||
})
|
||||
}
|
||||
event.preventDefault();
|
||||
event.preventDefault()
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
describe('Directive: ngEnter', function () {
|
||||
// load the directive's module
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'));
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'))
|
||||
|
||||
let element;
|
||||
let scope;
|
||||
let element
|
||||
let scope
|
||||
|
||||
beforeEach(inject(function ($rootScope) {
|
||||
scope = $rootScope.$new();
|
||||
}));
|
||||
scope = $rootScope.$new()
|
||||
}))
|
||||
|
||||
it('should be define', inject(function ($compile) {
|
||||
element = angular.element('<ng-enter></ng-enter>');
|
||||
element = $compile(element)(scope);
|
||||
expect(element.text()).toBeDefined();
|
||||
}));
|
||||
element = angular.element('<ng-enter></ng-enter>')
|
||||
element = $compile(element)(scope)
|
||||
expect(element.text()).toBeDefined()
|
||||
}))
|
||||
|
||||
// Test the rest of function in ngEnter
|
||||
/* it('should make hidden element visible', inject(function ($compile) {
|
||||
|
|
@ -21,4 +21,4 @@ describe('Directive: ngEnter', function () {
|
|||
element = $compile(element)(scope);
|
||||
expect(element.text()).toBe('this is the ngEnter directive');
|
||||
})); */
|
||||
});
|
||||
})
|
||||
|
|
|
|||
|
|
@ -12,17 +12,17 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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();
|
||||
scope.$eval(attrs.ngEscape)
|
||||
})
|
||||
event.preventDefault()
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').service('noteActionSrv', noteActionSrv);
|
||||
angular.module('zeppelinWebApp').service('noteActionSrv', noteActionSrv)
|
||||
|
||||
function noteActionSrv (websocketMsgSrv, $location, renameSrv, noteListDataFactory) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
this.moveNoteToTrash = function (noteId, redirectToHome) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -24,14 +24,14 @@ function noteActionSrv (websocketMsgSrv, $location, renameSrv, noteListDataFacto
|
|||
message: 'This note will be moved to <strong>trash</strong>.',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
websocketMsgSrv.moveNoteToTrash(noteId);
|
||||
websocketMsgSrv.moveNoteToTrash(noteId)
|
||||
if (redirectToHome) {
|
||||
$location.path('/');
|
||||
$location.path('/')
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
this.moveFolderToTrash = function (folderId) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -40,11 +40,11 @@ function noteActionSrv (websocketMsgSrv, $location, renameSrv, noteListDataFacto
|
|||
message: 'This folder will be moved to <strong>trash</strong>.',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
websocketMsgSrv.moveFolderToTrash(folderId);
|
||||
websocketMsgSrv.moveFolderToTrash(folderId)
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
this.removeNote = function (noteId, redirectToHome) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -54,14 +54,14 @@ function noteActionSrv (websocketMsgSrv, $location, renameSrv, noteListDataFacto
|
|||
message: 'This cannot be undone. Are you sure?',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
websocketMsgSrv.deleteNote(noteId);
|
||||
websocketMsgSrv.deleteNote(noteId)
|
||||
if (redirectToHome) {
|
||||
$location.path('/');
|
||||
$location.path('/')
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
this.removeFolder = function (folderId) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -71,11 +71,11 @@ function noteActionSrv (websocketMsgSrv, $location, renameSrv, noteListDataFacto
|
|||
message: 'This cannot be undone. Are you sure?',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
websocketMsgSrv.removeFolder(folderId);
|
||||
websocketMsgSrv.removeFolder(folderId)
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
this.restoreAll = function () {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -85,11 +85,11 @@ function noteActionSrv (websocketMsgSrv, $location, renameSrv, noteListDataFacto
|
|||
'<strong>merged</strong> into their original position.',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
websocketMsgSrv.restoreAll();
|
||||
websocketMsgSrv.restoreAll()
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
this.emptyTrash = function () {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -99,11 +99,11 @@ function noteActionSrv (websocketMsgSrv, $location, renameSrv, noteListDataFacto
|
|||
message: 'This cannot be undone. Are you sure?',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
websocketMsgSrv.emptyTrash();
|
||||
websocketMsgSrv.emptyTrash()
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
this.clearAllParagraphOutput = function (noteId) {
|
||||
BootstrapDialog.confirm({
|
||||
|
|
@ -112,28 +112,28 @@ function noteActionSrv (websocketMsgSrv, $location, renameSrv, noteListDataFacto
|
|||
message: 'Do you want to clear all output?',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
websocketMsgSrv.clearAllParagraphOutput(noteId);
|
||||
websocketMsgSrv.clearAllParagraphOutput(noteId)
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
this.renameNote = function (noteId, notePath) {
|
||||
renameSrv.openRenameModal({
|
||||
title: 'Rename note',
|
||||
oldName: notePath,
|
||||
callback: function (newName) {
|
||||
websocketMsgSrv.renameNote(noteId, newName);
|
||||
websocketMsgSrv.renameNote(noteId, newName)
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
this.renameFolder = function (folderId) {
|
||||
renameSrv.openRenameModal({
|
||||
title: 'Rename folder',
|
||||
oldName: folderId,
|
||||
callback: function (newName) {
|
||||
let newFolderId = normalizeFolderId(newName);
|
||||
let newFolderId = normalizeFolderId(newName)
|
||||
if (_.has(noteListDataFactory.flatFolderMap, newFolderId)) {
|
||||
BootstrapDialog.confirm({
|
||||
type: BootstrapDialog.TYPE_WARNING,
|
||||
|
|
@ -142,42 +142,42 @@ function noteActionSrv (websocketMsgSrv, $location, renameSrv, noteListDataFacto
|
|||
message: 'The folder will be merged into <strong>' + newFolderId + '</strong>. Are you sure?',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
websocketMsgSrv.renameFolder(folderId, newFolderId);
|
||||
websocketMsgSrv.renameFolder(folderId, newFolderId)
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
} else {
|
||||
websocketMsgSrv.renameFolder(folderId, newFolderId);
|
||||
websocketMsgSrv.renameFolder(folderId, newFolderId)
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
function normalizeFolderId (folderId) {
|
||||
folderId = folderId.trim();
|
||||
folderId = folderId.trim()
|
||||
|
||||
while (folderId.indexOf('\\') > -1) {
|
||||
folderId = folderId.replace('\\', '/');
|
||||
folderId = folderId.replace('\\', '/')
|
||||
}
|
||||
|
||||
while (folderId.indexOf('///') > -1) {
|
||||
folderId = folderId.replace('///', '/');
|
||||
folderId = folderId.replace('///', '/')
|
||||
}
|
||||
|
||||
folderId = folderId.replace('//', '/');
|
||||
folderId = folderId.replace('//', '/')
|
||||
|
||||
if (folderId === '/') {
|
||||
return '/';
|
||||
return '/'
|
||||
}
|
||||
|
||||
if (folderId[0] === '/') {
|
||||
folderId = folderId.substring(1);
|
||||
folderId = folderId.substring(1)
|
||||
}
|
||||
|
||||
if (folderId.slice(-1) === '/') {
|
||||
folderId = folderId.slice(0, -1);
|
||||
folderId = folderId.slice(0, -1)
|
||||
}
|
||||
|
||||
return folderId;
|
||||
return folderId
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').factory('noteListDataFactory', noteListDataFactory);
|
||||
angular.module('zeppelinWebApp').factory('noteListDataFactory', noteListDataFactory)
|
||||
|
||||
function noteListDataFactory (TRASH_FOLDER_ID) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
const notes = {
|
||||
root: {children: []},
|
||||
|
|
@ -26,24 +26,24 @@ function noteListDataFactory (TRASH_FOLDER_ID) {
|
|||
// 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;
|
||||
});
|
||||
? note.name.split('/')[0] === TRASH_FOLDER_ID : false
|
||||
return note
|
||||
})
|
||||
|
||||
// construct the folder-based tree
|
||||
notes.root = {children: []};
|
||||
notes.flatFolderMap = {};
|
||||
notes.root = {children: []}
|
||||
notes.flatFolderMap = {}
|
||||
_.reduce(notesList, function (root, note) {
|
||||
let noteName = note.name || note.id;
|
||||
let nodes = noteName.match(/([^\/][^\/]*)/g);
|
||||
let noteName = note.name || note.id
|
||||
let nodes = noteName.match(/([^\/][^\/]*)/g)
|
||||
|
||||
// recursively add nodes
|
||||
addNode(root, nodes, note.id);
|
||||
addNode(root, nodes, note.id)
|
||||
|
||||
return root;
|
||||
}, notes.root);
|
||||
return root
|
||||
}, notes.root)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const addNode = function (curDir, nodes, noteId) {
|
||||
if (nodes.length === 1) { // the leaf
|
||||
|
|
@ -52,13 +52,13 @@ function noteListDataFactory (TRASH_FOLDER_ID) {
|
|||
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
|
||||
let node = nodes.shift();
|
||||
let node = nodes.shift()
|
||||
let dir = _.find(curDir.children,
|
||||
function (c) { return c.name === node && c.children !== undefined; });
|
||||
function (c) { return c.name === node && c.children !== undefined })
|
||||
if (dir !== undefined) { // found an existing dir
|
||||
addNode(dir, nodes, noteId);
|
||||
addNode(dir, nodes, noteId)
|
||||
} else {
|
||||
let newDir = {
|
||||
id: curDir.id ? curDir.id + '/' + node : node,
|
||||
|
|
@ -66,16 +66,16 @@ function noteListDataFactory (TRASH_FOLDER_ID) {
|
|||
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;
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
describe('Factory: NoteList', function () {
|
||||
let noteList;
|
||||
let noteList
|
||||
|
||||
beforeEach(function () {
|
||||
angular.mock.module('zeppelinWebApp');
|
||||
angular.mock.module('zeppelinWebApp')
|
||||
|
||||
inject(function ($injector) {
|
||||
noteList = $injector.get('noteListDataFactory');
|
||||
});
|
||||
});
|
||||
noteList = $injector.get('noteListDataFactory')
|
||||
})
|
||||
})
|
||||
|
||||
it('should generate both flat list and folder-based list properly', function () {
|
||||
let notesList = [
|
||||
|
|
@ -20,56 +20,56 @@ describe('Factory: NoteList', function () {
|
|||
{name: '/C/CB/CBA', id: '000007'}, // same name with another note
|
||||
{name: 'C///CB//CBB', id: '000008'},
|
||||
{name: 'D/D[A/DA]B', id: '000009'} // check if '[' and ']' considered as folder seperator
|
||||
];
|
||||
noteList.setNotes(notesList);
|
||||
]
|
||||
noteList.setNotes(notesList)
|
||||
|
||||
let flatList = noteList.flatList;
|
||||
expect(flatList.length).toBe(9);
|
||||
expect(flatList[0].name).toBe('A');
|
||||
expect(flatList[0].id).toBe('000001');
|
||||
expect(flatList[1].name).toBe('B');
|
||||
expect(flatList[2].name).toBeUndefined();
|
||||
expect(flatList[3].name).toBe('/C/CA');
|
||||
expect(flatList[4].name).toBe('/C/CB');
|
||||
expect(flatList[5].name).toBe('/C/CB/CBA');
|
||||
expect(flatList[6].name).toBe('/C/CB/CBA');
|
||||
expect(flatList[7].name).toBe('C///CB//CBB');
|
||||
expect(flatList[8].name).toBe('D/D[A/DA]B');
|
||||
let flatList = noteList.flatList
|
||||
expect(flatList.length).toBe(9)
|
||||
expect(flatList[0].name).toBe('A')
|
||||
expect(flatList[0].id).toBe('000001')
|
||||
expect(flatList[1].name).toBe('B')
|
||||
expect(flatList[2].name).toBeUndefined()
|
||||
expect(flatList[3].name).toBe('/C/CA')
|
||||
expect(flatList[4].name).toBe('/C/CB')
|
||||
expect(flatList[5].name).toBe('/C/CB/CBA')
|
||||
expect(flatList[6].name).toBe('/C/CB/CBA')
|
||||
expect(flatList[7].name).toBe('C///CB//CBB')
|
||||
expect(flatList[8].name).toBe('D/D[A/DA]B')
|
||||
|
||||
let folderList = noteList.root.children;
|
||||
expect(folderList.length).toBe(5);
|
||||
expect(folderList[0].name).toBe('A');
|
||||
expect(folderList[0].id).toBe('000001');
|
||||
expect(folderList[1].name).toBe('B');
|
||||
expect(folderList[2].name).toBe('000003');
|
||||
expect(folderList[3].name).toBe('C');
|
||||
expect(folderList[3].id).toBe('C');
|
||||
expect(folderList[3].children.length).toBe(3);
|
||||
expect(folderList[3].children[0].name).toBe('CA');
|
||||
expect(folderList[3].children[0].id).toBe('000004');
|
||||
expect(folderList[3].children[0].children).toBeUndefined();
|
||||
expect(folderList[3].children[1].name).toBe('CB');
|
||||
expect(folderList[3].children[1].id).toBe('000005');
|
||||
expect(folderList[3].children[1].children).toBeUndefined();
|
||||
expect(folderList[3].children[2].name).toBe('CB');
|
||||
expect(folderList[3].children[2].id).toBe('C/CB');
|
||||
expect(folderList[3].children[2].children.length).toBe(3);
|
||||
expect(folderList[3].children[2].children[0].name).toBe('CBA');
|
||||
expect(folderList[3].children[2].children[0].id).toBe('000006');
|
||||
expect(folderList[3].children[2].children[0].children).toBeUndefined();
|
||||
expect(folderList[3].children[2].children[1].name).toBe('CBA');
|
||||
expect(folderList[3].children[2].children[1].id).toBe('000007');
|
||||
expect(folderList[3].children[2].children[1].children).toBeUndefined();
|
||||
expect(folderList[3].children[2].children[2].name).toBe('CBB');
|
||||
expect(folderList[3].children[2].children[2].id).toBe('000008');
|
||||
expect(folderList[3].children[2].children[2].children).toBeUndefined();
|
||||
expect(folderList[4].name).toBe('D');
|
||||
expect(folderList[4].id).toBe('D');
|
||||
expect(folderList[4].children.length).toBe(1);
|
||||
expect(folderList[4].children[0].name).toBe('D[A');
|
||||
expect(folderList[4].children[0].id).toBe('D/D[A');
|
||||
expect(folderList[4].children[0].children[0].name).toBe('DA]B');
|
||||
expect(folderList[4].children[0].children[0].id).toBe('000009');
|
||||
expect(folderList[4].children[0].children[0].children).toBeUndefined();
|
||||
});
|
||||
});
|
||||
let folderList = noteList.root.children
|
||||
expect(folderList.length).toBe(5)
|
||||
expect(folderList[0].name).toBe('A')
|
||||
expect(folderList[0].id).toBe('000001')
|
||||
expect(folderList[1].name).toBe('B')
|
||||
expect(folderList[2].name).toBe('000003')
|
||||
expect(folderList[3].name).toBe('C')
|
||||
expect(folderList[3].id).toBe('C')
|
||||
expect(folderList[3].children.length).toBe(3)
|
||||
expect(folderList[3].children[0].name).toBe('CA')
|
||||
expect(folderList[3].children[0].id).toBe('000004')
|
||||
expect(folderList[3].children[0].children).toBeUndefined()
|
||||
expect(folderList[3].children[1].name).toBe('CB')
|
||||
expect(folderList[3].children[1].id).toBe('000005')
|
||||
expect(folderList[3].children[1].children).toBeUndefined()
|
||||
expect(folderList[3].children[2].name).toBe('CB')
|
||||
expect(folderList[3].children[2].id).toBe('C/CB')
|
||||
expect(folderList[3].children[2].children.length).toBe(3)
|
||||
expect(folderList[3].children[2].children[0].name).toBe('CBA')
|
||||
expect(folderList[3].children[2].children[0].id).toBe('000006')
|
||||
expect(folderList[3].children[2].children[0].children).toBeUndefined()
|
||||
expect(folderList[3].children[2].children[1].name).toBe('CBA')
|
||||
expect(folderList[3].children[2].children[1].id).toBe('000007')
|
||||
expect(folderList[3].children[2].children[1].children).toBeUndefined()
|
||||
expect(folderList[3].children[2].children[2].name).toBe('CBB')
|
||||
expect(folderList[3].children[2].children[2].id).toBe('000008')
|
||||
expect(folderList[3].children[2].children[2].children).toBeUndefined()
|
||||
expect(folderList[4].name).toBe('D')
|
||||
expect(folderList[4].id).toBe('D')
|
||||
expect(folderList[4].children.length).toBe(1)
|
||||
expect(folderList[4].children[0].name).toBe('D[A')
|
||||
expect(folderList[4].children[0].id).toBe('D/D[A')
|
||||
expect(folderList[4].children[0].children[0].name).toBe('DA]B')
|
||||
expect(folderList[4].children[0].children[0].id).toBe('000009')
|
||||
expect(folderList[4].children[0].children[0].children).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -12,37 +12,37 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('NotenameCtrl', NotenameCtrl);
|
||||
angular.module('zeppelinWebApp').controller('NotenameCtrl', NotenameCtrl)
|
||||
|
||||
function NotenameCtrl ($scope, noteListDataFactory, $routeParams, websocketMsgSrv) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let vm = this;
|
||||
vm.clone = false;
|
||||
vm.notes = noteListDataFactory;
|
||||
vm.websocketMsgSrv = websocketMsgSrv;
|
||||
$scope.note = {};
|
||||
$scope.interpreterSettings = {};
|
||||
$scope.note.defaultInterpreter = null;
|
||||
let 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) {
|
||||
let defaultInterpreterId = '';
|
||||
let defaultInterpreterId = ''
|
||||
if ($scope.note.defaultInterpreter !== null) {
|
||||
defaultInterpreterId = $scope.note.defaultInterpreter.id;
|
||||
defaultInterpreterId = $scope.note.defaultInterpreter.id
|
||||
}
|
||||
vm.websocketMsgSrv.createNotebook($scope.note.notename, defaultInterpreterId);
|
||||
$scope.note.defaultInterpreter = $scope.interpreterSettings[0];
|
||||
vm.websocketMsgSrv.createNotebook($scope.note.notename, defaultInterpreterId)
|
||||
$scope.note.defaultInterpreter = $scope.interpreterSettings[0]
|
||||
} else {
|
||||
let noteId = $routeParams.noteId;
|
||||
vm.websocketMsgSrv.cloneNote(noteId, $scope.note.notename);
|
||||
let noteId = $routeParams.noteId
|
||||
vm.websocketMsgSrv.cloneNote(noteId, $scope.note.notename)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
vm.handleNameEnter = function () {
|
||||
angular.element('#noteNameModal').modal('toggle');
|
||||
vm.createNote();
|
||||
};
|
||||
angular.element('#noteNameModal').modal('toggle')
|
||||
vm.createNote()
|
||||
}
|
||||
|
||||
vm.preVisible = function(clone, sourceNoteName, path) {
|
||||
vm.clone = clone;
|
||||
|
|
@ -54,11 +54,11 @@ function NotenameCtrl ($scope, noteListDataFactory, $routeParams, websocketMsgSr
|
|||
vm.newNoteName = function(path) {
|
||||
var newCount = 1;
|
||||
angular.forEach(vm.notes.flatList, function (noteName) {
|
||||
noteName = noteName.name;
|
||||
noteName = noteName.name
|
||||
if (noteName.match(/^Untitled Note [0-9]*$/)) {
|
||||
let lastCount = noteName.substr(14) * 1;
|
||||
let lastCount = noteName.substr(14) * 1
|
||||
if (newCount <= lastCount) {
|
||||
newCount = lastCount + 1;
|
||||
newCount = lastCount + 1
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -66,39 +66,39 @@ function NotenameCtrl ($scope, noteListDataFactory, $routeParams, websocketMsgSr
|
|||
};
|
||||
|
||||
vm.cloneNoteName = function () {
|
||||
let copyCount = 1;
|
||||
let newCloneName = '';
|
||||
let lastIndex = vm.sourceNoteName.lastIndexOf(' ');
|
||||
let endsWithNumber = !!vm.sourceNoteName.match('^.+?\\s\\d$');
|
||||
let noteNamePrefix = endsWithNumber ? vm.sourceNoteName.substr(0, lastIndex) : vm.sourceNoteName;
|
||||
let regexp = new RegExp('^' + noteNamePrefix + ' .+');
|
||||
let copyCount = 1
|
||||
let newCloneName = ''
|
||||
let lastIndex = vm.sourceNoteName.lastIndexOf(' ')
|
||||
let endsWithNumber = !!vm.sourceNoteName.match('^.+?\\s\\d$')
|
||||
let noteNamePrefix = endsWithNumber ? vm.sourceNoteName.substr(0, lastIndex) : vm.sourceNoteName
|
||||
let regexp = new RegExp('^' + noteNamePrefix + ' .+')
|
||||
|
||||
angular.forEach(vm.notes.flatList, function (noteName) {
|
||||
noteName = noteName.name;
|
||||
noteName = noteName.name
|
||||
if (noteName.match(regexp)) {
|
||||
let lastCopyCount = noteName.substr(lastIndex).trim();
|
||||
newCloneName = noteNamePrefix;
|
||||
lastCopyCount = parseInt(lastCopyCount);
|
||||
let lastCopyCount = noteName.substr(lastIndex).trim()
|
||||
newCloneName = noteNamePrefix
|
||||
lastCopyCount = parseInt(lastCopyCount)
|
||||
if (copyCount <= lastCopyCount) {
|
||||
copyCount = lastCopyCount + 1;
|
||||
copyCount = lastCopyCount + 1
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
if (!newCloneName) {
|
||||
newCloneName = vm.sourceNoteName;
|
||||
newCloneName = vm.sourceNoteName
|
||||
}
|
||||
return newCloneName + ' ' + copyCount;
|
||||
};
|
||||
return newCloneName + ' ' + copyCount
|
||||
}
|
||||
|
||||
vm.getInterpreterSettings = function () {
|
||||
vm.websocketMsgSrv.getInterpreterSettings();
|
||||
};
|
||||
vm.websocketMsgSrv.getInterpreterSettings()
|
||||
}
|
||||
|
||||
$scope.$on('interpreterSettings', function (event, data) {
|
||||
$scope.interpreterSettings = data.interpreterSettings;
|
||||
$scope.interpreterSettings = data.interpreterSettings
|
||||
|
||||
// initialize default interpreter with Spark interpreter
|
||||
$scope.note.defaultInterpreter = data.interpreterSettings[0];
|
||||
});
|
||||
$scope.note.defaultInterpreter = data.interpreterSettings[0]
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
describe('Controller: NotenameCtrl', function () {
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'));
|
||||
beforeEach(angular.mock.module('zeppelinWebApp'))
|
||||
|
||||
let scope;
|
||||
let ctrl;
|
||||
let noteList;
|
||||
let scope
|
||||
let ctrl
|
||||
let noteList
|
||||
|
||||
beforeEach(inject(function ($injector, $rootScope, $controller) {
|
||||
noteList = $injector.get('noteListDataFactory');
|
||||
scope = $rootScope.$new();
|
||||
noteList = $injector.get('noteListDataFactory')
|
||||
scope = $rootScope.$new()
|
||||
ctrl = $controller('NotenameCtrl', {
|
||||
$scope: scope,
|
||||
noteListDataFactory: noteList
|
||||
});
|
||||
}));
|
||||
})
|
||||
}))
|
||||
|
||||
it('should create a new name from current name when cloneNoteName is called', function () {
|
||||
let notesList = [
|
||||
|
|
@ -21,19 +21,19 @@ describe('Controller: NotenameCtrl', function () {
|
|||
{name: 'test name', id: '3'},
|
||||
{name: 'aa bb cc', id: '4'},
|
||||
{name: 'Untitled Note 6', id: '4'}
|
||||
];
|
||||
]
|
||||
|
||||
noteList.setNotes(notesList);
|
||||
noteList.setNotes(notesList)
|
||||
|
||||
ctrl.sourceNoteName = 'test name';
|
||||
expect(ctrl.cloneNoteName()).toEqual('test name 1');
|
||||
ctrl.sourceNoteName = 'aa bb cc';
|
||||
expect(ctrl.cloneNoteName()).toEqual('aa bb cc 1');
|
||||
ctrl.sourceNoteName = 'Untitled Note 6';
|
||||
expect(ctrl.cloneNoteName()).toEqual('Untitled Note 7');
|
||||
ctrl.sourceNoteName = 'My_note';
|
||||
expect(ctrl.cloneNoteName()).toEqual('My_note 1');
|
||||
ctrl.sourceNoteName = 'dsds 2';
|
||||
expect(ctrl.cloneNoteName()).toEqual('dsds 3');
|
||||
});
|
||||
});
|
||||
ctrl.sourceNoteName = 'test name'
|
||||
expect(ctrl.cloneNoteName()).toEqual('test name 1')
|
||||
ctrl.sourceNoteName = 'aa bb cc'
|
||||
expect(ctrl.cloneNoteName()).toEqual('aa bb cc 1')
|
||||
ctrl.sourceNoteName = 'Untitled Note 6'
|
||||
expect(ctrl.cloneNoteName()).toEqual('Untitled Note 7')
|
||||
ctrl.sourceNoteName = 'My_note'
|
||||
expect(ctrl.cloneNoteName()).toEqual('My_note 1')
|
||||
ctrl.sourceNoteName = 'dsds 2'
|
||||
expect(ctrl.cloneNoteName()).toEqual('dsds 3')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').directive('modalvisible', modalvisible);
|
||||
angular.module('zeppelinWebApp').directive('modalvisible', modalvisible)
|
||||
|
||||
function modalvisible () {
|
||||
return {
|
||||
|
|
@ -24,8 +24,8 @@ function modalvisible () {
|
|||
},
|
||||
link: function (scope, element, attrs) {
|
||||
// Add some listeners
|
||||
let previsibleMethod = scope.preVisibleCallback;
|
||||
let postVisibleMethod = scope.postVisibleCallback;
|
||||
let previsibleMethod = scope.preVisibleCallback
|
||||
let postVisibleMethod = scope.postVisibleCallback
|
||||
element.on('show.bs.modal', function (e) {
|
||||
var relatedTarget = angular.element(e.relatedTarget);
|
||||
var clone = relatedTarget.data('clone');
|
||||
|
|
@ -36,10 +36,10 @@ function modalvisible () {
|
|||
});
|
||||
element.on('shown.bs.modal', function (e) {
|
||||
if (scope.targetinput) {
|
||||
angular.element(e.target).find('input#' + scope.targetinput).select();
|
||||
angular.element(e.target).find('input#' + scope.targetinput).select()
|
||||
}
|
||||
postVisibleMethod();
|
||||
});
|
||||
postVisibleMethod()
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,74 +12,74 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('NoteImportCtrl', NoteImportCtrl);
|
||||
angular.module('zeppelinWebApp').controller('NoteImportCtrl', NoteImportCtrl)
|
||||
|
||||
function NoteImportCtrl ($scope, $timeout, websocketMsgSrv) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let vm = this;
|
||||
$scope.note = {};
|
||||
$scope.note.step1 = true;
|
||||
$scope.note.step2 = false;
|
||||
$scope.maxLimit = '';
|
||||
let limit = 0;
|
||||
let vm = this
|
||||
$scope.note = {}
|
||||
$scope.note.step1 = true
|
||||
$scope.note.step2 = false
|
||||
$scope.maxLimit = ''
|
||||
let limit = 0
|
||||
|
||||
websocketMsgSrv.listConfigurations();
|
||||
websocketMsgSrv.listConfigurations()
|
||||
$scope.$on('configurationsInfo', function (scope, event) {
|
||||
limit = event.configurations['zeppelin.websocket.max.text.message.size'];
|
||||
$scope.maxLimit = Math.round(limit / 1048576);
|
||||
});
|
||||
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;
|
||||
angular.element('#noteImportFile').val('');
|
||||
};
|
||||
$scope.note = {}
|
||||
$scope.note.step1 = true
|
||||
$scope.note.step2 = false
|
||||
angular.element('#noteImportFile').val('')
|
||||
}
|
||||
|
||||
$scope.uploadFile = function () {
|
||||
angular.element('#noteImportFile').click();
|
||||
};
|
||||
angular.element('#noteImportFile').click()
|
||||
}
|
||||
|
||||
$scope.importFile = function (element) {
|
||||
$scope.note.errorText = '';
|
||||
$scope.note.importFile = element.files[0];
|
||||
let file = $scope.note.importFile;
|
||||
let reader = new FileReader();
|
||||
$scope.note.errorText = ''
|
||||
$scope.note.importFile = element.files[0]
|
||||
let file = $scope.note.importFile
|
||||
let reader = new FileReader()
|
||||
|
||||
if (file.size > limit) {
|
||||
$scope.note.errorText = 'File size limit Exceeded!';
|
||||
$scope.$apply();
|
||||
return;
|
||||
$scope.note.errorText = 'File size limit Exceeded!'
|
||||
$scope.$apply()
|
||||
return
|
||||
}
|
||||
|
||||
reader.onloadend = function () {
|
||||
vm.processImportJson(reader.result);
|
||||
};
|
||||
vm.processImportJson(reader.result)
|
||||
}
|
||||
|
||||
if (file) {
|
||||
reader.readAsText(file);
|
||||
reader.readAsText(file)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.uploadURL = function () {
|
||||
$scope.note.errorText = '';
|
||||
$scope.note.step1 = false;
|
||||
$scope.note.errorText = ''
|
||||
$scope.note.step1 = false
|
||||
$timeout(function () {
|
||||
$scope.note.step2 = true;
|
||||
}, 400);
|
||||
};
|
||||
$scope.note.step2 = true
|
||||
}, 400)
|
||||
}
|
||||
|
||||
vm.importBack = function () {
|
||||
$scope.note.errorText = '';
|
||||
$scope.note.errorText = ''
|
||||
$timeout(function () {
|
||||
$scope.note.step1 = true;
|
||||
}, 400);
|
||||
$scope.note.step2 = false;
|
||||
};
|
||||
$scope.note.step1 = true
|
||||
}, 400)
|
||||
$scope.note.step2 = false
|
||||
}
|
||||
|
||||
vm.importNote = function () {
|
||||
$scope.note.errorText = '';
|
||||
$scope.note.errorText = ''
|
||||
if ($scope.note.importUrl) {
|
||||
jQuery.ajax({
|
||||
url: $scope.note.importUrl,
|
||||
|
|
@ -90,47 +90,47 @@ function NoteImportCtrl ($scope, $timeout, websocketMsgSrv) {
|
|||
withCredentials: false
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
$scope.note.errorText = 'Unable to Fetch URL';
|
||||
$scope.$apply();
|
||||
$scope.note.errorText = 'Unable to Fetch URL'
|
||||
$scope.$apply()
|
||||
}}).done(function (data) {
|
||||
vm.processImportJson(data);
|
||||
});
|
||||
vm.processImportJson(data)
|
||||
})
|
||||
} else {
|
||||
$scope.note.errorText = 'Enter URL';
|
||||
$scope.$apply();
|
||||
$scope.note.errorText = 'Enter URL'
|
||||
$scope.$apply()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
vm.processImportJson = function (result) {
|
||||
if (typeof result !== 'object') {
|
||||
try {
|
||||
result = JSON.parse(result);
|
||||
result = JSON.parse(result)
|
||||
} catch (e) {
|
||||
$scope.note.errorText = 'JSON parse exception';
|
||||
$scope.$apply();
|
||||
return;
|
||||
$scope.note.errorText = 'JSON parse exception'
|
||||
$scope.$apply()
|
||||
return
|
||||
}
|
||||
}
|
||||
if (result.paragraphs && result.paragraphs.length > 0) {
|
||||
if (!$scope.note.noteImportName) {
|
||||
$scope.note.noteImportName = result.name;
|
||||
$scope.note.noteImportName = result.name
|
||||
} else {
|
||||
result.name = $scope.note.noteImportName;
|
||||
result.name = $scope.note.noteImportName
|
||||
}
|
||||
websocketMsgSrv.importNote(result);
|
||||
websocketMsgSrv.importNote(result)
|
||||
// angular.element('#noteImportModal').modal('hide');
|
||||
} else {
|
||||
$scope.note.errorText = 'Invalid JSON';
|
||||
$scope.note.errorText = 'Invalid JSON'
|
||||
}
|
||||
$scope.$apply();
|
||||
};
|
||||
$scope.$apply()
|
||||
}
|
||||
|
||||
/*
|
||||
** $scope.$on functions below
|
||||
*/
|
||||
|
||||
$scope.$on('setNoteMenu', function (event, notes) {
|
||||
vm.resetFlags();
|
||||
angular.element('#noteImportModal').modal('hide');
|
||||
});
|
||||
vm.resetFlags()
|
||||
angular.element('#noteImportModal').modal('hide')
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,28 +12,28 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').service('noteVarShareService', noteVarShareService);
|
||||
angular.module('zeppelinWebApp').service('noteVarShareService', noteVarShareService)
|
||||
|
||||
function noteVarShareService () {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let store = {};
|
||||
let store = {}
|
||||
|
||||
this.clear = function () {
|
||||
store = {};
|
||||
};
|
||||
store = {}
|
||||
}
|
||||
|
||||
this.put = function (key, value) {
|
||||
store[key] = value;
|
||||
};
|
||||
store[key] = value
|
||||
}
|
||||
|
||||
this.get = function (key) {
|
||||
return store[key];
|
||||
};
|
||||
return store[key]
|
||||
}
|
||||
|
||||
this.del = function (key) {
|
||||
let v = store[key];
|
||||
delete store[key];
|
||||
return v;
|
||||
};
|
||||
let v = store[key]
|
||||
delete store[key]
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').directive('popoverHtmlUnsafePopup', popoverHtmlUnsafePopup);
|
||||
angular.module('zeppelinWebApp').directive('popoverHtmlUnsafePopup', popoverHtmlUnsafePopup)
|
||||
|
||||
function popoverHtmlUnsafePopup () {
|
||||
return {
|
||||
|
|
@ -20,5 +20,5 @@ function popoverHtmlUnsafePopup () {
|
|||
replace: true,
|
||||
scope: {title: '@', content: '@', placement: '@', animation: '&', isOpen: '&'},
|
||||
templateUrl: 'components/popover-html-unsafe/popover-html-unsafe-popup.html'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').directive('popoverHtmlUnsafe', popoverHtmlUnsafe);
|
||||
angular.module('zeppelinWebApp').directive('popoverHtmlUnsafe', popoverHtmlUnsafe)
|
||||
|
||||
function popoverHtmlUnsafe ($tooltip) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
return $tooltip('popoverHtmlUnsafe', 'popover', 'click');
|
||||
return $tooltip('popoverHtmlUnsafe', 'popover', 'click')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,35 +12,35 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').controller('RenameCtrl', RenameCtrl);
|
||||
angular.module('zeppelinWebApp').controller('RenameCtrl', RenameCtrl)
|
||||
|
||||
function RenameCtrl ($scope) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let self = this;
|
||||
let 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);
|
||||
};
|
||||
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 () {};
|
||||
self.validator = options.validator || defaultValidator
|
||||
self.callback = options.callback || function () {}
|
||||
|
||||
$scope.title = options.title || 'Rename';
|
||||
$scope.params.newName = options.oldName || '';
|
||||
$scope.title = options.title || 'Rename'
|
||||
$scope.params.newName = options.oldName || ''
|
||||
$scope.validate = function () {
|
||||
$scope.isValid = self.validator($scope.params.newName);
|
||||
};
|
||||
$scope.isValid = self.validator($scope.params.newName)
|
||||
}
|
||||
|
||||
angular.element('#renameModal').modal('show');
|
||||
});
|
||||
angular.element('#renameModal').modal('show')
|
||||
})
|
||||
|
||||
function defaultValidator (str) {
|
||||
return !!str.trim();
|
||||
return !!str.trim()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').service('renameSrv', renameSrv);
|
||||
angular.module('zeppelinWebApp').service('renameSrv', renameSrv)
|
||||
|
||||
function renameSrv ($rootScope) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let self = this;
|
||||
let self = this
|
||||
|
||||
/**
|
||||
* <options schema>
|
||||
|
|
@ -27,6 +27,6 @@ function renameSrv ($rootScope) {
|
|||
* validator: (str: string)=>boolean - input validator
|
||||
*/
|
||||
self.openRenameModal = function (options) {
|
||||
$rootScope.$broadcast('openRenameModal', options);
|
||||
};
|
||||
$rootScope.$broadcast('openRenameModal', options)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').directive('resizable', resizable);
|
||||
angular.module('zeppelinWebApp').directive('resizable', resizable)
|
||||
|
||||
function resizable () {
|
||||
let resizableConfig = {
|
||||
|
|
@ -20,9 +20,9 @@ function resizable () {
|
|||
handles: 'se',
|
||||
helper: 'resizable-helper',
|
||||
stop: function () {
|
||||
angular.element(this).css({'width': '100%', 'height': '100%'});
|
||||
angular.element(this).css({'width': '100%', 'height': '100%'})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
|
|
@ -32,38 +32,38 @@ function resizable () {
|
|||
link: function postLink (scope, elem, attrs) {
|
||||
attrs.$observe('resize', function (resize) {
|
||||
let resetResize = function (elem, resize) {
|
||||
let colStep = window.innerWidth / 12;
|
||||
elem.off('resizestop');
|
||||
let conf = angular.copy(resizableConfig);
|
||||
let colStep = window.innerWidth / 12
|
||||
elem.off('resizestop')
|
||||
let conf = angular.copy(resizableConfig)
|
||||
if (resize.graphType === 'TABLE' || resize.graphType === 'TEXT') {
|
||||
conf.grid = [colStep, 10];
|
||||
conf.minHeight = 100;
|
||||
conf.grid = [colStep, 10]
|
||||
conf.minHeight = 100
|
||||
} else {
|
||||
conf.grid = [colStep, 10000];
|
||||
conf.minHeight = 0;
|
||||
conf.grid = [colStep, 10000]
|
||||
conf.minHeight = 0
|
||||
}
|
||||
conf.maxWidth = window.innerWidth;
|
||||
conf.maxWidth = window.innerWidth
|
||||
|
||||
elem.resizable(conf);
|
||||
elem.resizable(conf)
|
||||
elem.on('resizestop', function () {
|
||||
if (scope.callback) {
|
||||
let height = elem.height();
|
||||
let height = elem.height()
|
||||
if (height < 50) {
|
||||
height = 300;
|
||||
height = 300
|
||||
}
|
||||
scope.callback({width: Math.ceil(elem.width() / colStep), height: height});
|
||||
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);
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
resize = JSON.parse(resize)
|
||||
if (resize.allowresize === 'true') {
|
||||
resetResize(elem, resize)
|
||||
angular.element(window).resize(function () {
|
||||
resetResize(elem, resize)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,40 +12,40 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').service('saveAsService', saveAsService);
|
||||
angular.module('zeppelinWebApp').service('saveAsService', saveAsService)
|
||||
|
||||
function saveAsService (browserDetectService) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
this.saveAs = function (content, filename, extension) {
|
||||
let BOM = '\uFEFF';
|
||||
let BOM = '\uFEFF'
|
||||
if (browserDetectService.detectIE()) {
|
||||
angular.element('body').append('<iframe id="SaveAsId" style="display: none"></iframe>');
|
||||
let 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();
|
||||
let t1 = Date.now();
|
||||
frameSaveAs.document.execCommand('SaveAs', false, filename + '.' + extension);
|
||||
let t2 = Date.now();
|
||||
angular.element('body').append('<iframe id="SaveAsId" style="display: none"></iframe>')
|
||||
let 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()
|
||||
let t1 = Date.now()
|
||||
frameSaveAs.document.execCommand('SaveAs', false, filename + '.' + extension)
|
||||
let 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');
|
||||
frameSaveAs.document.execCommand('SaveAs', true, filename + '.txt')
|
||||
}
|
||||
angular.element('body > iframe#SaveAsId').remove();
|
||||
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>');
|
||||
let saveAsElement = angular.element('body > a#SaveAsId');
|
||||
saveAsElement.attr('href', content);
|
||||
saveAsElement.attr('download', filename + '.' + extension);
|
||||
saveAsElement.attr('target', '_blank');
|
||||
saveAsElement[0].click();
|
||||
saveAsElement.remove();
|
||||
content = 'data:image/svg;charset=utf-8,' + BOM + encodeURIComponent(content)
|
||||
angular.element('body').append('<a id="SaveAsId"></a>')
|
||||
let saveAsElement = angular.element('body > a#SaveAsId')
|
||||
saveAsElement.attr('href', content)
|
||||
saveAsElement.attr('download', filename + '.' + extension)
|
||||
saveAsElement.attr('target', '_blank')
|
||||
saveAsElement[0].click()
|
||||
saveAsElement.remove()
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,22 +12,22 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').service('searchService', searchService);
|
||||
angular.module('zeppelinWebApp').service('searchService', searchService)
|
||||
|
||||
function searchService ($resource, baseUrlSrv) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
this.search = function (term) {
|
||||
this.searchTerm = term.q;
|
||||
console.log('Searching for: %o', term.q);
|
||||
this.searchTerm = term.q
|
||||
console.log('Searching for: %o', term.q)
|
||||
if (!term.q) { // TODO(bzz): empty string check
|
||||
return;
|
||||
return
|
||||
}
|
||||
let encQuery = window.encodeURIComponent(term.q);
|
||||
let encQuery = window.encodeURIComponent(term.q)
|
||||
return $resource(baseUrlSrv.getRestApiBase() + '/notebook/search?q=' + encQuery, {}, {
|
||||
query: {method: 'GET'}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
this.searchTerm = '';
|
||||
this.searchTerm = ''
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,91 +12,91 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').factory('websocketEvents', websocketEvents);
|
||||
angular.module('zeppelinWebApp').factory('websocketEvents', websocketEvents)
|
||||
|
||||
function websocketEvents ($rootScope, $websocket, $location, baseUrlSrv) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
let websocketCalls = {};
|
||||
let pingIntervalId;
|
||||
let websocketCalls = {}
|
||||
let 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);
|
||||
console.log('Websocket created')
|
||||
$rootScope.$broadcast('setConnectedStatus', true)
|
||||
pingIntervalId = setInterval(function () {
|
||||
websocketCalls.sendNewEvent({op: 'PING'});
|
||||
}, 10000);
|
||||
});
|
||||
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;
|
||||
data.principal = $rootScope.ticket.principal
|
||||
data.ticket = $rootScope.ticket.ticket
|
||||
data.roles = $rootScope.ticket.roles
|
||||
} else {
|
||||
data.principal = '';
|
||||
data.ticket = '';
|
||||
data.roles = '';
|
||||
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));
|
||||
};
|
||||
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);
|
||||
};
|
||||
return (websocketCalls.ws.socket.readyState === 1)
|
||||
}
|
||||
|
||||
websocketCalls.ws.onMessage(function (event) {
|
||||
let payload;
|
||||
let payload
|
||||
if (event.data) {
|
||||
payload = angular.fromJson(event.data);
|
||||
payload = angular.fromJson(event.data)
|
||||
}
|
||||
console.log('Receive Json << %o', event.data)
|
||||
console.log('Receive << %o, %o', payload.op, payload);
|
||||
let op = payload.op;
|
||||
let data = payload.data;
|
||||
if (op === 'NOTE') {
|
||||
$rootScope.$broadcast('setNoteContent', data.note);
|
||||
$rootScope.$broadcast('setNoteContent', data.note)
|
||||
} else if (op === 'NEW_NOTE') {
|
||||
$location.path('/notebook/' + data.note.id);
|
||||
$location.path('/notebook/' + data.note.id)
|
||||
} else if (op === 'NOTES_INFO') {
|
||||
$rootScope.$broadcast('setNoteMenu', data.notes);
|
||||
$rootScope.$broadcast('setNoteMenu', data.notes)
|
||||
} else if (op === 'LIST_NOTE_JOBS') {
|
||||
$rootScope.$broadcast('setNoteJobs', data.noteJobs);
|
||||
$rootScope.$broadcast('setNoteJobs', data.noteJobs)
|
||||
} else if (op === 'LIST_UPDATE_NOTE_JOBS') {
|
||||
$rootScope.$broadcast('setUpdateNoteJobs', data.noteRunningJobs);
|
||||
$rootScope.$broadcast('setUpdateNoteJobs', data.noteRunningJobs)
|
||||
} else if (op === 'AUTH_INFO') {
|
||||
let btn = [];
|
||||
let btn = []
|
||||
if ($rootScope.ticket.roles === '[]') {
|
||||
btn = [{
|
||||
label: 'Close',
|
||||
action: function (dialog) {
|
||||
dialog.close();
|
||||
dialog.close()
|
||||
}
|
||||
}];
|
||||
}]
|
||||
} else {
|
||||
btn = [{
|
||||
label: 'Login',
|
||||
action: function (dialog) {
|
||||
dialog.close();
|
||||
dialog.close()
|
||||
angular.element('#loginModal').modal({
|
||||
show: 'true'
|
||||
});
|
||||
})
|
||||
}
|
||||
}, {
|
||||
label: 'Cancel',
|
||||
action: function (dialog) {
|
||||
dialog.close();
|
||||
dialog.close()
|
||||
// using $rootScope.apply to trigger angular digest cycle
|
||||
// changing $location.path inside bootstrap modal wont trigger digest
|
||||
$rootScope.$apply(function () {
|
||||
$location.path('/');
|
||||
});
|
||||
$location.path('/')
|
||||
})
|
||||
}
|
||||
}];
|
||||
}]
|
||||
}
|
||||
|
||||
BootstrapDialog.show({
|
||||
|
|
@ -106,39 +106,39 @@ function websocketEvents ($rootScope, $websocket, $location, baseUrlSrv) {
|
|||
title: 'Insufficient privileges',
|
||||
message: data.info.toString(),
|
||||
buttons: btn
|
||||
});
|
||||
})
|
||||
} else if (op === 'PARAGRAPH') {
|
||||
$rootScope.$broadcast('updateParagraph', data);
|
||||
$rootScope.$broadcast('updateParagraph', data)
|
||||
} else if (op === 'RUN_PARAGRAPH_USING_SPELL') {
|
||||
$rootScope.$broadcast('runParagraphUsingSpell', data);
|
||||
$rootScope.$broadcast('runParagraphUsingSpell', data)
|
||||
} else if (op === 'PARAGRAPH_APPEND_OUTPUT') {
|
||||
$rootScope.$broadcast('appendParagraphOutput', data);
|
||||
$rootScope.$broadcast('appendParagraphOutput', data)
|
||||
} else if (op === 'PARAGRAPH_UPDATE_OUTPUT') {
|
||||
$rootScope.$broadcast('updateParagraphOutput', data);
|
||||
$rootScope.$broadcast('updateParagraphOutput', data)
|
||||
} else if (op === 'PROGRESS') {
|
||||
$rootScope.$broadcast('updateProgress', data);
|
||||
$rootScope.$broadcast('updateProgress', data)
|
||||
} else if (op === 'COMPLETION_LIST') {
|
||||
$rootScope.$broadcast('completionList', data);
|
||||
$rootScope.$broadcast('completionList', data)
|
||||
} else if (op === 'EDITOR_SETTING') {
|
||||
$rootScope.$broadcast('editorSetting', data);
|
||||
$rootScope.$broadcast('editorSetting', data)
|
||||
} else if (op === 'ANGULAR_OBJECT_UPDATE') {
|
||||
$rootScope.$broadcast('angularObjectUpdate', data);
|
||||
$rootScope.$broadcast('angularObjectUpdate', data)
|
||||
} else if (op === 'ANGULAR_OBJECT_REMOVE') {
|
||||
$rootScope.$broadcast('angularObjectRemove', data);
|
||||
$rootScope.$broadcast('angularObjectRemove', data)
|
||||
} else if (op === 'APP_APPEND_OUTPUT') {
|
||||
$rootScope.$broadcast('appendAppOutput', data);
|
||||
$rootScope.$broadcast('appendAppOutput', data)
|
||||
} else if (op === 'APP_UPDATE_OUTPUT') {
|
||||
$rootScope.$broadcast('updateAppOutput', data);
|
||||
$rootScope.$broadcast('updateAppOutput', data)
|
||||
} else if (op === 'APP_LOAD') {
|
||||
$rootScope.$broadcast('appLoad', data);
|
||||
$rootScope.$broadcast('appLoad', data)
|
||||
} else if (op === 'APP_STATUS_CHANGE') {
|
||||
$rootScope.$broadcast('appStatusChange', data);
|
||||
$rootScope.$broadcast('appStatusChange', data)
|
||||
} else if (op === 'LIST_REVISION_HISTORY') {
|
||||
$rootScope.$broadcast('listRevisionHistory', data);
|
||||
$rootScope.$broadcast('listRevisionHistory', data)
|
||||
} else if (op === 'NOTE_REVISION') {
|
||||
$rootScope.$broadcast('noteRevision', data);
|
||||
$rootScope.$broadcast('noteRevision', data)
|
||||
} else if (op === 'INTERPRETER_BINDINGS') {
|
||||
$rootScope.$broadcast('interpreterBindings', data);
|
||||
$rootScope.$broadcast('interpreterBindings', data)
|
||||
} else if (op === 'ERROR_INFO') {
|
||||
BootstrapDialog.show({
|
||||
closable: false,
|
||||
|
|
@ -150,46 +150,46 @@ function websocketEvents ($rootScope, $websocket, $location, baseUrlSrv) {
|
|||
// close all the dialogs when there are error on running all paragraphs
|
||||
label: 'Close',
|
||||
action: function () {
|
||||
BootstrapDialog.closeAll();
|
||||
BootstrapDialog.closeAll()
|
||||
}
|
||||
}]
|
||||
});
|
||||
})
|
||||
} else if (op === 'SESSION_LOGOUT') {
|
||||
$rootScope.$broadcast('session_logout', data);
|
||||
$rootScope.$broadcast('session_logout', data)
|
||||
} else if (op === 'CONFIGURATIONS_INFO') {
|
||||
$rootScope.$broadcast('configurationsInfo', data);
|
||||
$rootScope.$broadcast('configurationsInfo', data)
|
||||
} else if (op === 'INTERPRETER_SETTINGS') {
|
||||
$rootScope.$broadcast('interpreterSettings', data);
|
||||
$rootScope.$broadcast('interpreterSettings', data)
|
||||
} else if (op === 'PARAGRAPH_ADDED') {
|
||||
$rootScope.$broadcast('addParagraph', data.paragraph, data.index);
|
||||
$rootScope.$broadcast('addParagraph', data.paragraph, data.index)
|
||||
} else if (op === 'PARAGRAPH_REMOVED') {
|
||||
$rootScope.$broadcast('removeParagraph', data.id);
|
||||
$rootScope.$broadcast('removeParagraph', data.id)
|
||||
} else if (op === 'PARAGRAPH_MOVED') {
|
||||
$rootScope.$broadcast('moveParagraph', data.id, data.index);
|
||||
$rootScope.$broadcast('moveParagraph', data.id, data.index)
|
||||
} else if (op === 'NOTE_UPDATED') {
|
||||
$rootScope.$broadcast('updateNote', data.name, data.config, data.info);
|
||||
$rootScope.$broadcast('updateNote', data.name, data.config, data.info)
|
||||
} else if (op === 'SET_NOTE_REVISION') {
|
||||
$rootScope.$broadcast('setNoteRevisionResult', data);
|
||||
$rootScope.$broadcast('setNoteRevisionResult', data)
|
||||
} else if (op === 'PARAS_INFO') {
|
||||
$rootScope.$broadcast('updateParaInfos', data);
|
||||
$rootScope.$broadcast('updateParaInfos', data)
|
||||
} else {
|
||||
console.error(`unknown websocket op: ${op}`);
|
||||
console.error(`unknown websocket op: ${op}`)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
websocketCalls.ws.onError(function (event) {
|
||||
console.log('error message: ', event);
|
||||
$rootScope.$broadcast('setConnectedStatus', false);
|
||||
});
|
||||
console.log('error message: ', event)
|
||||
$rootScope.$broadcast('setConnectedStatus', false)
|
||||
})
|
||||
|
||||
websocketCalls.ws.onClose(function (event) {
|
||||
console.log('close message: ', event);
|
||||
console.log('close message: ', event)
|
||||
if (pingIntervalId !== undefined) {
|
||||
clearInterval(pingIntervalId);
|
||||
pingIntervalId = undefined;
|
||||
clearInterval(pingIntervalId)
|
||||
pingIntervalId = undefined
|
||||
}
|
||||
$rootScope.$broadcast('setConnectedStatus', false);
|
||||
});
|
||||
$rootScope.$broadcast('setConnectedStatus', false)
|
||||
})
|
||||
|
||||
return websocketCalls;
|
||||
return websocketCalls
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('zeppelinWebApp').service('websocketMsgSrv', websocketMsgSrv);
|
||||
angular.module('zeppelinWebApp').service('websocketMsgSrv', websocketMsgSrv)
|
||||
|
||||
function websocketMsgSrv ($rootScope, websocketEvents) {
|
||||
'ngInject';
|
||||
'ngInject'
|
||||
|
||||
return {
|
||||
|
||||
getHomeNote: function () {
|
||||
websocketEvents.sendNewEvent({op: 'GET_HOME_NOTE'});
|
||||
websocketEvents.sendNewEvent({op: 'GET_HOME_NOTE'})
|
||||
},
|
||||
|
||||
createNotebook: function (noteName, defaultInterpreterId) {
|
||||
|
|
@ -30,79 +30,79 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
name: noteName,
|
||||
defaultInterpreterId: defaultInterpreterId
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
moveNoteToTrash: function (noteId) {
|
||||
websocketEvents.sendNewEvent({op: 'MOVE_NOTE_TO_TRASH', data: {id: noteId}});
|
||||
websocketEvents.sendNewEvent({op: 'MOVE_NOTE_TO_TRASH', data: {id: noteId}})
|
||||
},
|
||||
|
||||
moveFolderToTrash: function (folderId) {
|
||||
websocketEvents.sendNewEvent({op: 'MOVE_FOLDER_TO_TRASH', data: {id: folderId}});
|
||||
websocketEvents.sendNewEvent({op: 'MOVE_FOLDER_TO_TRASH', data: {id: folderId}})
|
||||
},
|
||||
|
||||
restoreNote: function (noteId) {
|
||||
websocketEvents.sendNewEvent({op: 'RESTORE_NOTE', data: {id: noteId}});
|
||||
websocketEvents.sendNewEvent({op: 'RESTORE_NOTE', data: {id: noteId}})
|
||||
},
|
||||
|
||||
restoreFolder: function (folderId) {
|
||||
websocketEvents.sendNewEvent({op: 'RESTORE_FOLDER', data: {id: folderId}});
|
||||
websocketEvents.sendNewEvent({op: 'RESTORE_FOLDER', data: {id: folderId}})
|
||||
},
|
||||
|
||||
restoreAll: function () {
|
||||
websocketEvents.sendNewEvent({op: 'RESTORE_ALL'});
|
||||
websocketEvents.sendNewEvent({op: 'RESTORE_ALL'})
|
||||
},
|
||||
|
||||
deleteNote: function (noteId) {
|
||||
websocketEvents.sendNewEvent({op: 'DEL_NOTE', data: {id: noteId}});
|
||||
websocketEvents.sendNewEvent({op: 'DEL_NOTE', data: {id: noteId}})
|
||||
},
|
||||
|
||||
removeFolder: function (folderId) {
|
||||
websocketEvents.sendNewEvent({op: 'REMOVE_FOLDER', data: {id: folderId}});
|
||||
websocketEvents.sendNewEvent({op: 'REMOVE_FOLDER', data: {id: folderId}})
|
||||
},
|
||||
|
||||
emptyTrash: function () {
|
||||
websocketEvents.sendNewEvent({op: 'EMPTY_TRASH'});
|
||||
websocketEvents.sendNewEvent({op: 'EMPTY_TRASH'})
|
||||
},
|
||||
|
||||
cloneNote: function (noteIdToClone, newNoteName) {
|
||||
websocketEvents.sendNewEvent({op: 'CLONE_NOTE', data: {id: noteIdToClone, name: newNoteName}});
|
||||
websocketEvents.sendNewEvent({op: 'CLONE_NOTE', data: {id: noteIdToClone, name: newNoteName}})
|
||||
},
|
||||
|
||||
getNoteList: function () {
|
||||
websocketEvents.sendNewEvent({op: 'LIST_NOTES'});
|
||||
websocketEvents.sendNewEvent({op: 'LIST_NOTES'})
|
||||
},
|
||||
|
||||
reloadAllNotesFromRepo: function () {
|
||||
websocketEvents.sendNewEvent({op: 'RELOAD_NOTES_FROM_REPO'});
|
||||
websocketEvents.sendNewEvent({op: 'RELOAD_NOTES_FROM_REPO'})
|
||||
},
|
||||
|
||||
getNote: function (noteId) {
|
||||
websocketEvents.sendNewEvent({op: 'GET_NOTE', data: {id: 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}});
|
||||
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}});
|
||||
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}});
|
||||
websocketEvents.sendNewEvent({op: 'NOTE_RENAME', data: {id: noteId, name: noteName}})
|
||||
},
|
||||
|
||||
renameFolder: function (folderId, folderName) {
|
||||
websocketEvents.sendNewEvent({op: 'FOLDER_RENAME', data: {id: folderId, name: 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}});
|
||||
websocketEvents.sendNewEvent({op: 'MOVE_PARAGRAPH', data: {id: paragraphId, index: newIndex}})
|
||||
},
|
||||
|
||||
insertParagraph: function (newIndex) {
|
||||
websocketEvents.sendNewEvent({op: 'INSERT_PARAGRAPH', data: {index: newIndex}});
|
||||
websocketEvents.sendNewEvent({op: 'INSERT_PARAGRAPH', data: {index: newIndex}})
|
||||
},
|
||||
|
||||
copyParagraph: function (newIndex, paragraphTitle, paragraphData,
|
||||
|
|
@ -116,7 +116,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
config: paragraphConfig,
|
||||
params: paragraphParams
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
updateAngularObject: function (noteId, paragraphId, name, value, interpreterGroupId) {
|
||||
|
|
@ -129,7 +129,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
value: value,
|
||||
interpreterGroupId: interpreterGroupId
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
clientBindAngularObject: function (noteId, name, value, paragraphId) {
|
||||
|
|
@ -141,7 +141,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
value: value,
|
||||
paragraphId: paragraphId
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
clientUnbindAngularObject: function (noteId, name, paragraphId) {
|
||||
|
|
@ -152,11 +152,11 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
name: name,
|
||||
paragraphId: paragraphId
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
cancelParagraphRun: function (paragraphId) {
|
||||
websocketEvents.sendNewEvent({op: 'CANCEL_PARAGRAPH', data: {id: paragraphId}});
|
||||
websocketEvents.sendNewEvent({op: 'CANCEL_PARAGRAPH', data: {id: paragraphId}})
|
||||
},
|
||||
|
||||
paragraphExecutedBySpell: function (paragraphId, paragraphTitle,
|
||||
|
|
@ -172,8 +172,8 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
results: {
|
||||
code: paragraphStatus,
|
||||
msg: paragraphResultsMsg.map(dataWithType => {
|
||||
let serializedData = dataWithType.data;
|
||||
return { type: dataWithType.type, data: serializedData, };
|
||||
let serializedData = dataWithType.data
|
||||
return { type: dataWithType.type, data: serializedData, }
|
||||
})
|
||||
},
|
||||
status: paragraphStatus,
|
||||
|
|
@ -181,7 +181,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
config: paragraphConfig,
|
||||
params: paragraphParams
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
runParagraph: function (paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
|
||||
|
|
@ -194,7 +194,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
config: paragraphConfig,
|
||||
params: paragraphParams
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
runAllParagraphs: function (noteId, paragraphs) {
|
||||
|
|
@ -204,19 +204,19 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
noteId: noteId,
|
||||
paragraphs: JSON.stringify(paragraphs)
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
removeParagraph: function (paragraphId) {
|
||||
websocketEvents.sendNewEvent({op: 'PARAGRAPH_REMOVE', data: {id: paragraphId}});
|
||||
websocketEvents.sendNewEvent({op: 'PARAGRAPH_REMOVE', data: {id: paragraphId}})
|
||||
},
|
||||
|
||||
clearParagraphOutput: function (paragraphId) {
|
||||
websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_OUTPUT', data: {id: paragraphId}});
|
||||
websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_OUTPUT', data: {id: paragraphId}})
|
||||
},
|
||||
|
||||
clearAllParagraphOutput: function (noteId) {
|
||||
websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_ALL_OUTPUT', data: {id: noteId}});
|
||||
websocketEvents.sendNewEvent({op: 'PARAGRAPH_CLEAR_ALL_OUTPUT', data: {id: noteId}})
|
||||
},
|
||||
|
||||
completion: function (paragraphId, buf, cursor) {
|
||||
|
|
@ -227,7 +227,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
buf: buf,
|
||||
cursor: cursor
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
commitParagraph: function (paragraphId, paragraphTitle, paragraphData, paragraphConfig, paragraphParams) {
|
||||
|
|
@ -240,7 +240,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
config: paragraphConfig,
|
||||
params: paragraphParams
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
importNote: function (note) {
|
||||
|
|
@ -249,7 +249,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
data: {
|
||||
note: note
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
checkpointNote: function (noteId, commitMessage) {
|
||||
|
|
@ -259,7 +259,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
noteId: noteId,
|
||||
commitMessage: commitMessage
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
setNoteRevision: function (noteId, revisionId) {
|
||||
|
|
@ -269,7 +269,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
noteId: noteId,
|
||||
revisionId: revisionId
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
listRevisionHistory: function (noteId) {
|
||||
|
|
@ -278,7 +278,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
data: {
|
||||
noteId: noteId
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
getNoteByRevision: function (noteId, revisionId) {
|
||||
|
|
@ -288,7 +288,7 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
noteId: noteId,
|
||||
revisionId: revisionId
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
getEditorSetting: function (paragraphId, replName) {
|
||||
|
|
@ -298,43 +298,43 @@ function websocketMsgSrv ($rootScope, websocketEvents) {
|
|||
paragraphId: paragraphId,
|
||||
magic: replName
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
isConnected: function () {
|
||||
return websocketEvents.isConnected();
|
||||
return websocketEvents.isConnected()
|
||||
},
|
||||
|
||||
getNoteJobsList: function () {
|
||||
websocketEvents.sendNewEvent({op: 'LIST_NOTE_JOBS'});
|
||||
websocketEvents.sendNewEvent({op: 'LIST_NOTE_JOBS'})
|
||||
},
|
||||
|
||||
getUpdateNoteJobsList: function (lastUpdateServerUnixTime) {
|
||||
websocketEvents.sendNewEvent(
|
||||
{op: 'LIST_UPDATE_NOTE_JOBS', data: {lastUpdateUnixTime: lastUpdateServerUnixTime * 1}}
|
||||
);
|
||||
)
|
||||
},
|
||||
|
||||
unsubscribeJobManager: function () {
|
||||
websocketEvents.sendNewEvent({op: 'UNSUBSCRIBE_UPDATE_NOTE_JOBS'});
|
||||
websocketEvents.sendNewEvent({op: 'UNSUBSCRIBE_UPDATE_NOTE_JOBS'})
|
||||
},
|
||||
|
||||
getInterpreterBindings: function (noteId) {
|
||||
websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_BINDINGS', data: {noteId: 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}});
|
||||
data: {noteId: noteId, selectedSettingIds: selectedSettingIds}})
|
||||
},
|
||||
|
||||
listConfigurations: function () {
|
||||
websocketEvents.sendNewEvent({op: 'LIST_CONFIGURATIONS'});
|
||||
websocketEvents.sendNewEvent({op: 'LIST_CONFIGURATIONS'})
|
||||
},
|
||||
|
||||
getInterpreterSettings: function () {
|
||||
websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_SETTINGS'});
|
||||
websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_SETTINGS'})
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,65 +12,65 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import './app/app.js';
|
||||
import './app/app.controller.js';
|
||||
import './app/home/home.controller.js';
|
||||
import './app/handsontable/handsonHelper.js';
|
||||
import './app/notebook/notebook.controller.js';
|
||||
import './app/app.js'
|
||||
import './app/app.controller.js'
|
||||
import './app/home/home.controller.js'
|
||||
import './app/handsontable/handsonHelper.js'
|
||||
import './app/notebook/notebook.controller.js'
|
||||
|
||||
import './app/tabledata/tabledata.js';
|
||||
import './app/tabledata/transformation.js';
|
||||
import './app/tabledata/pivot.js';
|
||||
import './app/tabledata/passthrough.js';
|
||||
import './app/tabledata/columnselector.js';
|
||||
import './app/tabledata/advanced-transformation.js';
|
||||
import './app/visualization/visualization.js';
|
||||
import './app/visualization/builtins/visualization-table.js';
|
||||
import './app/visualization/builtins/visualization-nvd3chart.js';
|
||||
import './app/visualization/builtins/visualization-barchart.js';
|
||||
import './app/visualization/builtins/visualization-piechart.js';
|
||||
import './app/visualization/builtins/visualization-areachart.js';
|
||||
import './app/visualization/builtins/visualization-linechart.js';
|
||||
import './app/visualization/builtins/visualization-scatterchart.js';
|
||||
import './app/tabledata/tabledata.js'
|
||||
import './app/tabledata/transformation.js'
|
||||
import './app/tabledata/pivot.js'
|
||||
import './app/tabledata/passthrough.js'
|
||||
import './app/tabledata/columnselector.js'
|
||||
import './app/tabledata/advanced-transformation.js'
|
||||
import './app/visualization/visualization.js'
|
||||
import './app/visualization/builtins/visualization-table.js'
|
||||
import './app/visualization/builtins/visualization-nvd3chart.js'
|
||||
import './app/visualization/builtins/visualization-barchart.js'
|
||||
import './app/visualization/builtins/visualization-piechart.js'
|
||||
import './app/visualization/builtins/visualization-areachart.js'
|
||||
import './app/visualization/builtins/visualization-linechart.js'
|
||||
import './app/visualization/builtins/visualization-scatterchart.js'
|
||||
|
||||
import './app/jobmanager/jobmanager.controller.js';
|
||||
import './app/jobmanager/jobs/job.controller.js';
|
||||
import './app/jobmanager/jobmanager.filter.js';
|
||||
import './app/interpreter/interpreter.controller.js';
|
||||
import './app/interpreter/interpreter.filter.js';
|
||||
import './app/credential/credential.controller.js';
|
||||
import './app/configuration/configuration.controller.js';
|
||||
import './app/notebook/paragraph/paragraph.controller.js';
|
||||
import './app/notebook/paragraph/result/result.controller.js';
|
||||
import './app/search/result-list.controller.js';
|
||||
import './app/notebookRepos/notebookRepos.controller.js';
|
||||
import './app/helium';
|
||||
import './components/arrayOrderingSrv/arrayOrdering.service.js';
|
||||
import './components/clipboard/clipboard.controller.js';
|
||||
import './components/navbar/navbar.controller.js';
|
||||
import './components/ngescape/ngescape.directive.js';
|
||||
import './components/interpreter/interpreter.directive.js';
|
||||
import './components/expandCollapse/expandCollapse.directive.js';
|
||||
import './components/noteName-create/notename.controller.js';
|
||||
import './components/noteName-import/notenameImport.controller.js';
|
||||
import './components/popover-html-unsafe/popover-html-unsafe.directive.js';
|
||||
import './components/popover-html-unsafe/popover-html-unsafe-popup.directive.js';
|
||||
import './components/editor/codeEditor.directive.js';
|
||||
import './components/ngenter/ngenter.directive.js';
|
||||
import './components/dropdowninput/dropdowninput.directive.js';
|
||||
import './components/resizable/resizable.directive.js';
|
||||
import './components/noteName-create/visible.directive.js';
|
||||
import './components/websocketEvents/websocketMsg.service.js';
|
||||
import './components/websocketEvents/websocketEvents.factory.js';
|
||||
import './components/noteListDataFactory/noteList.datafactory.js';
|
||||
import './components/baseUrl/baseUrl.service.js';
|
||||
import './components/browser-detect/browserDetect.service.js';
|
||||
import './components/saveAs/saveAs.service.js';
|
||||
import './components/searchService/search.service.js';
|
||||
import './components/login/login.controller.js';
|
||||
import './components/elasticInputCtrl/elasticInput.controller.js';
|
||||
import './components/noteAction/noteAction.service.js';
|
||||
import './components/notevarshareService/notevarshare.service.js';
|
||||
import './components/rename/rename.controller.js';
|
||||
import './components/rename/rename.service.js';
|
||||
import './components/helium/helium.service.js';
|
||||
import './app/jobmanager/jobmanager.controller.js'
|
||||
import './app/jobmanager/jobs/job.controller.js'
|
||||
import './app/jobmanager/jobmanager.filter.js'
|
||||
import './app/interpreter/interpreter.controller.js'
|
||||
import './app/interpreter/interpreter.filter.js'
|
||||
import './app/credential/credential.controller.js'
|
||||
import './app/configuration/configuration.controller.js'
|
||||
import './app/notebook/paragraph/paragraph.controller.js'
|
||||
import './app/notebook/paragraph/result/result.controller.js'
|
||||
import './app/search/result-list.controller.js'
|
||||
import './app/notebookRepos/notebookRepos.controller.js'
|
||||
import './app/helium'
|
||||
import './components/arrayOrderingSrv/arrayOrdering.service.js'
|
||||
import './components/clipboard/clipboard.controller.js'
|
||||
import './components/navbar/navbar.controller.js'
|
||||
import './components/ngescape/ngescape.directive.js'
|
||||
import './components/interpreter/interpreter.directive.js'
|
||||
import './components/expandCollapse/expandCollapse.directive.js'
|
||||
import './components/noteName-create/notename.controller.js'
|
||||
import './components/noteName-import/notenameImport.controller.js'
|
||||
import './components/popover-html-unsafe/popover-html-unsafe.directive.js'
|
||||
import './components/popover-html-unsafe/popover-html-unsafe-popup.directive.js'
|
||||
import './components/editor/codeEditor.directive.js'
|
||||
import './components/ngenter/ngenter.directive.js'
|
||||
import './components/dropdowninput/dropdowninput.directive.js'
|
||||
import './components/resizable/resizable.directive.js'
|
||||
import './components/noteName-create/visible.directive.js'
|
||||
import './components/websocketEvents/websocketMsg.service.js'
|
||||
import './components/websocketEvents/websocketEvents.factory.js'
|
||||
import './components/noteListDataFactory/noteList.datafactory.js'
|
||||
import './components/baseUrl/baseUrl.service.js'
|
||||
import './components/browser-detect/browserDetect.service.js'
|
||||
import './components/saveAs/saveAs.service.js'
|
||||
import './components/searchService/search.service.js'
|
||||
import './components/login/login.controller.js'
|
||||
import './components/elasticInputCtrl/elasticInput.controller.js'
|
||||
import './components/noteAction/noteAction.service.js'
|
||||
import './components/notevarshareService/notevarshare.service.js'
|
||||
import './components/rename/rename.controller.js'
|
||||
import './components/rename/rename.service.js'
|
||||
import './components/helium/helium.service.js'
|
||||
|
|
|
|||
Loading…
Reference in a new issue