Change Zeppelin Folder Structure and its GruntFile
|
|
@ -63,7 +63,7 @@ module.exports = function (grunt) {
|
|||
tasks: ['wiredep']
|
||||
},
|
||||
js: {
|
||||
files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
|
||||
files: ['<%= yeoman.app %>/{app, components}/**/*.js'],
|
||||
tasks: ['newer:jshint:all'],
|
||||
options: {
|
||||
livereload: '<%= connect.options.livereload %>'
|
||||
|
|
@ -74,7 +74,7 @@ module.exports = function (grunt) {
|
|||
tasks: ['newer:jshint:test', 'karma']
|
||||
},
|
||||
styles: {
|
||||
files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
|
||||
files: ['<%= yeoman.app %>/{app, components, assets/styles}/**/*.css'],
|
||||
tasks: ['newer:copy:styles', 'autoprefixer']
|
||||
},
|
||||
gruntfile: {
|
||||
|
|
@ -85,9 +85,9 @@ module.exports = function (grunt) {
|
|||
livereload: '<%= connect.options.livereload %>'
|
||||
},
|
||||
files: [
|
||||
'<%= yeoman.app %>/{,*/}*.html',
|
||||
'<%= yeoman.app %>/{app, components}/**/*.html',
|
||||
'.tmp/styles/{,*/}*.css',
|
||||
'<%= yeoman.app %>/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
|
||||
'<%= yeoman.app %>/assets/images/**/*.{png,jpg,jpeg,gif,webp,svg}'
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
@ -148,7 +148,7 @@ module.exports = function (grunt) {
|
|||
all: {
|
||||
src: [
|
||||
'Gruntfile.js',
|
||||
'<%= yeoman.app %>/scripts/{,*/}*.js'
|
||||
'<%= yeoman.app %>/{app, components}/**/*.js'
|
||||
]
|
||||
},
|
||||
test: {
|
||||
|
|
@ -199,18 +199,6 @@ module.exports = function (grunt) {
|
|||
}
|
||||
},
|
||||
|
||||
// Renames files for browser caching purposes
|
||||
filerev: {
|
||||
dist: {
|
||||
src: [
|
||||
'<%= yeoman.dist %>/scripts/{,*/}*.js',
|
||||
'<%= yeoman.dist %>/styles/*.css',
|
||||
'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
|
||||
'<%= yeoman.dist %>/styles/fonts/*'
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// Reads HTML for usemin blocks to enable smart builds that automatically
|
||||
// concat, minify and revision files. Creates configurations in memory so
|
||||
// additional tasks can operate on them
|
||||
|
|
@ -235,7 +223,7 @@ module.exports = function (grunt) {
|
|||
html: ['<%= yeoman.dist %>/{,*/}*.html'],
|
||||
css: ['<%= yeoman.dist %>/styles/*.css'],
|
||||
options: {
|
||||
assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/images']
|
||||
assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/assets']
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -243,15 +231,15 @@ module.exports = function (grunt) {
|
|||
// By default, your `index.html`'s <!-- Usemin block --> will take care of
|
||||
// minification. These next options are pre-configured if you do not wish
|
||||
// to use the Usemin blocks.
|
||||
// cssmin: {
|
||||
// dist: {
|
||||
// files: {
|
||||
// '<%= yeoman.dist %>/styles/main.css': [
|
||||
// '.tmp/styles/{,*/}*.css'
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
cssmin: {
|
||||
dist: {
|
||||
files: {
|
||||
'<%= yeoman.dist %>/styles/main.css': [
|
||||
'.tmp/styles/{,*/}*.css'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
// uglify: {
|
||||
// dist: {
|
||||
// files: {
|
||||
|
|
@ -269,9 +257,9 @@ module.exports = function (grunt) {
|
|||
dist: {
|
||||
files: [{
|
||||
expand: true,
|
||||
cwd: '<%= yeoman.app %>/images',
|
||||
cwd: '<%= yeoman.app %>/assets/images',
|
||||
src: '{,*/}*.svg',
|
||||
dest: '<%= yeoman.dist %>/images'
|
||||
dest: '<%= yeoman.dist %>/assets/images'
|
||||
}]
|
||||
}
|
||||
},
|
||||
|
|
@ -288,7 +276,7 @@ module.exports = function (grunt) {
|
|||
files: [{
|
||||
expand: true,
|
||||
cwd: '<%= yeoman.dist %>',
|
||||
src: ['*.html', 'views/{,*/}*.html'],
|
||||
src: ['*.html', '{app, components}/**/*.html'],
|
||||
dest: '<%= yeoman.dist %>'
|
||||
}]
|
||||
}
|
||||
|
|
@ -306,18 +294,21 @@ module.exports = function (grunt) {
|
|||
'*.{ico,png,txt}',
|
||||
'.htaccess',
|
||||
'*.html',
|
||||
'views/{,*/}*.html',
|
||||
'images/*',
|
||||
'fonts/*',
|
||||
'assets/styles/**/*',
|
||||
'assets/images/**/*',
|
||||
'WEB-INF/*',
|
||||
'scripts/ace/{,*/}/{,*/}/*'
|
||||
]
|
||||
}, {
|
||||
expand : true,
|
||||
dot : true,
|
||||
cwd: '<%= yeoman.app %>',
|
||||
dest: '<%= yeoman.dist %>',
|
||||
src: ['styles/looknfeel/*']
|
||||
src: ['app/**/*.html', 'components/**/*.html']
|
||||
}, {
|
||||
expand : true,
|
||||
flatten: true,
|
||||
cwd: '<%= yeoman.app %>',
|
||||
dest: '<%= yeoman.dist %>/fonts/',
|
||||
src: ['assets/fonts/**/*']
|
||||
}, {
|
||||
expand: true,
|
||||
cwd: '.tmp/images',
|
||||
|
|
@ -337,9 +328,10 @@ module.exports = function (grunt) {
|
|||
},
|
||||
styles: {
|
||||
expand: true,
|
||||
cwd: '<%= yeoman.app %>/styles',
|
||||
flatten: true,
|
||||
cwd: '<%= yeoman.app %>',
|
||||
dest: '.tmp/styles/',
|
||||
src: '{,*/}*.css'
|
||||
src: '{app, components}/**/*.css'
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -378,7 +370,6 @@ module.exports = function (grunt) {
|
|||
'concurrent:server',
|
||||
'autoprefixer',
|
||||
'connect:livereload',
|
||||
/*'newer:jshint'*/
|
||||
'watch'
|
||||
]);
|
||||
});
|
||||
|
|
@ -407,7 +398,6 @@ module.exports = function (grunt) {
|
|||
'copy:dist',
|
||||
'cssmin',
|
||||
'uglify',
|
||||
/*'filerev',*/
|
||||
'usemin',
|
||||
'htmlmin'
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -112,18 +112,18 @@ angular
|
|||
|
||||
$routeProvider
|
||||
.when('/', {
|
||||
templateUrl: 'views/main.html'
|
||||
templateUrl: 'app/home/home.html'
|
||||
})
|
||||
.when('/notebook/:noteId', {
|
||||
templateUrl: 'views/notebooks.html',
|
||||
templateUrl: 'app/notebook/notebooks.html',
|
||||
controller: 'NotebookCtrl'
|
||||
})
|
||||
.when('/notebook/:noteId/paragraph/:paragraphId?', {
|
||||
templateUrl: 'views/notebooks.html',
|
||||
templateUrl: 'app/notebook/notebooks.html',
|
||||
controller: 'NotebookCtrl'
|
||||
})
|
||||
.when('/interpreter', {
|
||||
templateUrl: 'views/interpreter.html',
|
||||
templateUrl: 'app/interpreter/interpreter.html',
|
||||
controller: 'InterpreterCtrl'
|
||||
})
|
||||
.otherwise({
|
||||
|
|
@ -184,7 +184,7 @@ a.navbar-brand:hover {
|
|||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.box,
|
||||
.box,
|
||||
.well {
|
||||
background-color: #ffffff;
|
||||
border-color: #e5e5e5;
|
||||
|
|
@ -228,7 +228,7 @@ h6.box-heading{
|
|||
|
||||
|
||||
.zeppelin {
|
||||
background-image: url('../images/zepLogo.png');
|
||||
background-image: url('/assets/images/zepLogo.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: right;
|
||||
height: 380px;
|
||||
|
|
@ -236,7 +236,7 @@ h6.box-heading{
|
|||
}
|
||||
|
||||
.zeppelin2 {
|
||||
background-image: url('../images/zepLogo.png');
|
||||
background-image: url('/assets/images/zepLogo.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: right;
|
||||
background-position-y: 12px;
|
||||
|
|
@ -277,9 +277,9 @@ kbd {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
temporary fix for bootstrap issue (https://github.com/twbs/bootstrap/issues/5865)
|
||||
This part should be removed when new version of bootstrap handles this issue.
|
||||
/*
|
||||
temporary fix for bootstrap issue (https://github.com/twbs/bootstrap/issues/5865)
|
||||
This part should be removed when new version of bootstrap handles this issue.
|
||||
*/
|
||||
.btn-group > .tooltip + .btn,
|
||||
.btn-group > .popover + .btn {
|
||||
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 175 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 280 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
|
@ -19,10 +19,10 @@ angular.module('zeppelinWebApp')
|
|||
restrict: 'EA',
|
||||
replace: true,
|
||||
scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' },
|
||||
templateUrl: 'views/popover-html-unsafe-popup.html'
|
||||
templateUrl: 'components/popover-html-unsafe/popover-html-unsafe-popup.html'
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
.directive('popoverHtmlUnsafe', ['$tooltip', function($tooltip) {
|
||||
return $tooltip('popoverHtmlUnsafe', 'popover', 'click');
|
||||
}]);
|
||||
|
|
@ -3,7 +3,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
|
|||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
|
@ -40,20 +40,20 @@ limitations under the License.
|
|||
<!-- endbuild -->
|
||||
<!-- build:css(.tmp) styles/main.css -->
|
||||
<link href='https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" href="styles/main.css">
|
||||
<link rel="stylesheet" href="styles/typography.css">
|
||||
<link rel="stylesheet" href="styles/notebook.css">
|
||||
<link rel="stylesheet" href="styles/interpreter.css">
|
||||
<link rel="stylesheet" href="styles/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="styles/simple-line-icons.css">
|
||||
<link rel="stylesheet" href="styles/custom-font.css">
|
||||
<link rel="stylesheet" href="app/home/home.css">
|
||||
<link rel="stylesheet" href="app/typography.css">
|
||||
<link rel="stylesheet" href="app/notebook/notebook.css">
|
||||
<link rel="stylesheet" href="app/interpreter/interpreter.css">
|
||||
<link rel="stylesheet" href="app/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="app/simple-line-icons.css">
|
||||
<link rel="stylesheet" href="app/custom-font.css">
|
||||
<!-- endbuild -->
|
||||
<link rel="stylesheet" ng-href="styles/looknfeel/{{looknfeel}}.css">
|
||||
<link rel="stylesheet" ng-href="assets/styles/looknfeel/{{looknfeel}}.css">
|
||||
</head>
|
||||
<body ng-class="{'bodyAsIframe': asIframe}" >
|
||||
<!--[if lt IE 7]>
|
||||
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
|
||||
<![endif]-->
|
||||
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
|
||||
<![endif]-->
|
||||
<div class="navbar navbar-inverse navbar-fixed-top" style="display: none;" role="navigation" ng-class="{'displayNavBar': !asIframe}">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
|
|
@ -62,7 +62,7 @@ limitations under the License.
|
|||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#/"><img style="margin-top: -7px;s" src="images/zepLogoW.png" width="50" alt="I'm zeppelin"> Zeppelin</a>
|
||||
<a class="navbar-brand" href="#/"><img style="margin-top: -7px;s" src="assets/images/zepLogoW.png" width="50" alt="I'm zeppelin"> Zeppelin</a>
|
||||
</div>
|
||||
|
||||
<div class="collapse navbar-collapse" ng-controller="NavCtrl">
|
||||
|
|
@ -73,19 +73,21 @@ limitations under the License.
|
|||
<li><a href="javascript:void(0);" ng-click="createNewNote()"><i class="fa fa-plus"></i> Create new note</a></li>
|
||||
<li class="divider"></li>
|
||||
<div id="notebook-list" class="scrollbar-container">
|
||||
<li ng-repeat="note in notes track by $index" ng-class="{'active' : isActive(note.id)}"><a href="#/notebook/{{note.id}}">{{note.name || 'Note ' + note.id}} </a></li>
|
||||
</div>
|
||||
<li ng-repeat="note in notes track by $index" ng-class="{'active' : isActive(note.id)}">
|
||||
<a href="#/notebook/{{note.id}}">{{note.name || 'Note ' + note.id}} </a>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#/interpreter">Interpreter</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right" style="margin-top:10px; margin-right:5px;">
|
||||
<ul class="nav navbar-nav navbar-right" style="margin-top:10px; margin-right:5px;">
|
||||
<li class="server-status">
|
||||
<i class="fa fa-circle" ng-class="{'server-connected':connected, 'server-disconnected':!connected }"></i>
|
||||
<span ng-show="connected">Connected</span>
|
||||
<span ng-show="!connected">Disconnected</span>
|
||||
<i class="fa fa-circle" ng-class="{'server-connected':connected, 'server-disconnected':!connected }"></i>
|
||||
<span ng-show="connected">Connected</span>
|
||||
<span ng-show="!connected">Disconnected</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -96,12 +98,12 @@ limitations under the License.
|
|||
<div ng-view></div>
|
||||
</div>
|
||||
<!-- Modal :: Keyboard shortcuts -->
|
||||
<div ng-include src="'views/modal-shortcut.html'"></div>
|
||||
<div ng-include src="'components/modal-shortcut/modal-shortcut.html'"></div>
|
||||
<!-- build:js(.) scripts/oldieshim.js -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="bower_components/es5-shim/es5-shim.js"></script>
|
||||
<script src="bower_components/json3/lib/json3.min.js"></script>
|
||||
<![endif]-->
|
||||
<script src="bower_components/es5-shim/es5-shim.js"></script>
|
||||
<script src="bower_components/json3/lib/json3.min.js"></script>
|
||||
<![endif]-->
|
||||
<!-- endbuild -->
|
||||
|
||||
<!-- build:js(.) scripts/vendor.js -->
|
||||
|
|
@ -139,17 +141,17 @@ limitations under the License.
|
|||
<!-- endbower -->
|
||||
<!-- endbuild -->
|
||||
<!-- build:js({.tmp,app}) scripts/scripts.js -->
|
||||
<script src="scripts/app.js"></script>
|
||||
<script src="scripts/controllers/main.js"></script>
|
||||
<script src="scripts/controllers/notebook.js"></script>
|
||||
<script src="scripts/controllers/interpreter.js"></script>
|
||||
<script src="scripts/directives/ngenter.js"></script>
|
||||
<script src="scripts/directives/dropdowninput.js"></script>
|
||||
<script src="scripts/directives/resizable.js"></script>
|
||||
<script src="scripts/controllers/paragraph.js"></script>
|
||||
<script src="scripts/controllers/nav.js"></script>
|
||||
<script src="scripts/directives/ngdelete.js"></script>
|
||||
<script src="scripts/directives/popover-html-unsafe.js"></script>
|
||||
<script src="app/app.js"></script>
|
||||
<script src="app/home/home.controller.js"></script>
|
||||
<script src="app/notebook/notebook.controller.js"></script>
|
||||
<script src="app/interpreter/interpreter.controller.js"></script>
|
||||
<script src="app/notebook/paragraph/paragraph.controller.js"></script>
|
||||
<script src="components/navbar/navbar.controller.js"></script>
|
||||
<script src="components/directives/ngdelete.js"></script>
|
||||
<script src="components/directives/popover-html-unsafe.js"></script>
|
||||
<script src="components/scripts/directives/ngenter.js"></script>
|
||||
<script src="components/scripts/directives/dropdowninput.js"></script>
|
||||
<script src="components/scripts/directives/resizable.js"></script>
|
||||
<!-- endbuild -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,494 +0,0 @@
|
|||
/* global confirm:false, alert:false */
|
||||
/* jshint loopfunc: true */
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name zeppelinWebApp.controller:NotebookCtrl
|
||||
* @description
|
||||
* # NotebookCtrl
|
||||
* Controller of notes, manage the note (update)
|
||||
*
|
||||
*/
|
||||
angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $route, $routeParams, $location, $rootScope, $http) {
|
||||
$scope.note = null;
|
||||
$scope.showEditor = false;
|
||||
$scope.editorToggled = false;
|
||||
$scope.tableToggled = false;
|
||||
$scope.viewOnly = false;
|
||||
$scope.looknfeelOption = [ 'default', 'simple', 'report'];
|
||||
$scope.cronOption = [
|
||||
{name: 'None', value : undefined},
|
||||
{name: '1m', value: '0 0/1 * * * ?'},
|
||||
{name: '5m', value: '0 0/5 * * * ?'},
|
||||
{name: '1h', value: '0 0 0/1 * * ?'},
|
||||
{name: '3h', value: '0 0 0/3 * * ?'},
|
||||
{name: '6h', value: '0 0 0/6 * * ?'},
|
||||
{name: '12h', value: '0 0 0/12 * * ?'},
|
||||
{name: '1d', value: '0 0 0 * * ?'}
|
||||
];
|
||||
|
||||
$scope.interpreterSettings = [];
|
||||
$scope.interpreterBindings = [];
|
||||
|
||||
var angularObjectRegistry = {};
|
||||
|
||||
$scope.getCronOptionNameFromValue = function(value) {
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
for (var o in $scope.cronOption) {
|
||||
if ($scope.cronOption[o].value===value) {
|
||||
return $scope.cronOption[o].name;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
/** Init the new controller */
|
||||
var initNotebook = function() {
|
||||
$rootScope.$emit('sendNewEvent', {op: 'GET_NOTE', data: {id: $routeParams.noteId}});
|
||||
};
|
||||
|
||||
initNotebook();
|
||||
|
||||
/** Remove the note and go back tot he main page */
|
||||
/** TODO(anthony): In the nearly future, go back to the main page and telle to the dude that the note have been remove */
|
||||
$scope.removeNote = function(noteId) {
|
||||
var result = confirm('Do you want to delete this notebook?');
|
||||
if (result) {
|
||||
$rootScope.$emit('sendNewEvent', {op: 'DEL_NOTE', data: {id: noteId}});
|
||||
$location.path('/#');
|
||||
}
|
||||
};
|
||||
|
||||
$scope.runNote = function() {
|
||||
var result = confirm('Run all paragraphs?');
|
||||
if (result) {
|
||||
$scope.$broadcast('runParagraph');
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleAllEditor = function() {
|
||||
if ($scope.editorToggled) {
|
||||
$scope.$broadcast('closeEditor');
|
||||
} else {
|
||||
$scope.$broadcast('openEditor');
|
||||
}
|
||||
$scope.editorToggled = !$scope.editorToggled;
|
||||
};
|
||||
|
||||
$scope.showAllEditor = function() {
|
||||
$scope.$broadcast('openEditor');
|
||||
};
|
||||
|
||||
$scope.hideAllEditor = function() {
|
||||
$scope.$broadcast('closeEditor');
|
||||
};
|
||||
|
||||
$scope.toggleAllTable = function() {
|
||||
if ($scope.tableToggled) {
|
||||
$scope.$broadcast('closeTable');
|
||||
} else {
|
||||
$scope.$broadcast('openTable');
|
||||
}
|
||||
$scope.tableToggled = !$scope.tableToggled;
|
||||
};
|
||||
|
||||
$scope.showAllTable = function() {
|
||||
$scope.$broadcast('openTable');
|
||||
};
|
||||
|
||||
$scope.hideAllTable = function() {
|
||||
$scope.$broadcast('closeTable');
|
||||
};
|
||||
|
||||
$scope.isNoteRunning = function() {
|
||||
var running = false;
|
||||
if(!$scope.note){ return false; }
|
||||
for (var i=0; i<$scope.note.paragraphs.length; i++) {
|
||||
if ( $scope.note.paragraphs[i].status === 'PENDING' || $scope.note.paragraphs[i].status === 'RUNNING') {
|
||||
running = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return running;
|
||||
};
|
||||
|
||||
$scope.setLookAndFeel = function(looknfeel) {
|
||||
$scope.note.config.looknfeel = looknfeel;
|
||||
$scope.setConfig();
|
||||
};
|
||||
|
||||
/** Set cron expression for this note **/
|
||||
$scope.setCronScheduler = function(cronExpr) {
|
||||
$scope.note.config.cron = cronExpr;
|
||||
$scope.setConfig();
|
||||
};
|
||||
|
||||
/** Update note config **/
|
||||
$scope.setConfig = function(config) {
|
||||
if(config) {
|
||||
$scope.note.config = config;
|
||||
}
|
||||
$rootScope.$emit('sendNewEvent', {op: 'NOTE_UPDATE', data: {id: $scope.note.id, name: $scope.note.name, config : $scope.note.config}});
|
||||
};
|
||||
|
||||
/** Update the note name */
|
||||
$scope.sendNewName = function() {
|
||||
$scope.showEditor = false;
|
||||
if ($scope.note.name) {
|
||||
$rootScope.$emit('sendNewEvent', {op: 'NOTE_UPDATE', data: {id: $scope.note.id, name: $scope.note.name, config : $scope.note.config}});
|
||||
}
|
||||
};
|
||||
|
||||
/** update the current note */
|
||||
$scope.$on('setNoteContent', function(event, note) {
|
||||
$scope.paragraphUrl = $routeParams.paragraphId;
|
||||
$scope.asIframe = $routeParams.asIframe;
|
||||
if ($scope.paragraphUrl) {
|
||||
note = cleanParagraphExcept($scope.paragraphUrl, note);
|
||||
$rootScope.$emit('setIframe', $scope.asIframe);
|
||||
}
|
||||
|
||||
if ($scope.note === null) {
|
||||
$scope.note = note;
|
||||
} else {
|
||||
updateNote(note);
|
||||
}
|
||||
initializeLookAndFeel();
|
||||
//open interpreter binding setting when there're none selected
|
||||
getInterpreterBindings(getInterpreterBindingsCallBack);
|
||||
});
|
||||
|
||||
|
||||
var initializeLookAndFeel = function() {
|
||||
if (!$scope.note.config.looknfeel) {
|
||||
$scope.note.config.looknfeel = 'default';
|
||||
} else {
|
||||
$scope.viewOnly = $scope.note.config.looknfeel === 'report' ? true : false;
|
||||
}
|
||||
$rootScope.$emit('setLookAndFeel', $scope.note.config.looknfeel);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var cleanParagraphExcept = function(paragraphId, note) {
|
||||
var noteCopy = {};
|
||||
noteCopy.id = note.id;
|
||||
noteCopy.name = note.name;
|
||||
noteCopy.config = note.config;
|
||||
noteCopy.info = note.info;
|
||||
noteCopy.paragraphs = [];
|
||||
for (var i=0; i<note.paragraphs.length; i++) {
|
||||
if (note.paragraphs[i].id === paragraphId) {
|
||||
noteCopy.paragraphs[0] = note.paragraphs[i];
|
||||
if (!noteCopy.paragraphs[0].config) {
|
||||
noteCopy.paragraphs[0].config = {};
|
||||
}
|
||||
noteCopy.paragraphs[0].config.editorHide = true;
|
||||
noteCopy.paragraphs[0].config.tableHide = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return noteCopy;
|
||||
};
|
||||
|
||||
$scope.$on('moveParagraphUp', function(event, paragraphId) {
|
||||
var newIndex = -1;
|
||||
for (var i=0; i<$scope.note.paragraphs.length; i++) {
|
||||
if ($scope.note.paragraphs[i].id === paragraphId) {
|
||||
newIndex = i-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newIndex<0 || newIndex>=$scope.note.paragraphs.length) {
|
||||
return;
|
||||
}
|
||||
$rootScope.$emit('sendNewEvent', { op: 'MOVE_PARAGRAPH', data : {id: paragraphId, index: newIndex}});
|
||||
});
|
||||
|
||||
// create new paragraph on current position
|
||||
$scope.$on('insertParagraph', function(event, paragraphId) {
|
||||
var newIndex = -1;
|
||||
for (var i=0; i<$scope.note.paragraphs.length; i++) {
|
||||
if ($scope.note.paragraphs[i].id === paragraphId) {
|
||||
newIndex = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newIndex === $scope.note.paragraphs.length) {
|
||||
alert('Cannot insert after the last paragraph.');
|
||||
return;
|
||||
}
|
||||
if (newIndex < 0 || newIndex > $scope.note.paragraphs.length) {
|
||||
return;
|
||||
}
|
||||
$rootScope.$emit('sendNewEvent', { op: 'INSERT_PARAGRAPH', data : {index: newIndex}});
|
||||
});
|
||||
|
||||
$scope.$on('moveParagraphDown', function(event, paragraphId) {
|
||||
var newIndex = -1;
|
||||
for (var i=0; i<$scope.note.paragraphs.length; i++) {
|
||||
if ($scope.note.paragraphs[i].id === paragraphId) {
|
||||
newIndex = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newIndex<0 || newIndex>=$scope.note.paragraphs.length) {
|
||||
return;
|
||||
}
|
||||
$rootScope.$emit('sendNewEvent', { op: 'MOVE_PARAGRAPH', data : {id: paragraphId, index: newIndex}});
|
||||
});
|
||||
|
||||
$scope.$on('moveFocusToPreviousParagraph', function(event, currentParagraphId){
|
||||
var focus = false;
|
||||
for (var i=$scope.note.paragraphs.length-1; i>=0; i--) {
|
||||
if (focus === false ) {
|
||||
if ($scope.note.paragraphs[i].id === currentParagraphId) {
|
||||
focus = true;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
var p = $scope.note.paragraphs[i];
|
||||
if (!p.config.hide && !p.config.editorHide && !p.config.tableHide) {
|
||||
$scope.$broadcast('focusParagraph', $scope.note.paragraphs[i].id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on('moveFocusToNextParagraph', function(event, currentParagraphId){
|
||||
var focus = false;
|
||||
for (var i=0; i<$scope.note.paragraphs.length; i++) {
|
||||
if (focus === false ) {
|
||||
if ($scope.note.paragraphs[i].id === currentParagraphId) {
|
||||
focus = true;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
var p = $scope.note.paragraphs[i];
|
||||
if (!p.config.hide && !p.config.editorHide && !p.config.tableHide) {
|
||||
$scope.$broadcast('focusParagraph', $scope.note.paragraphs[i].id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var updateNote = function(note) {
|
||||
/** update Note name */
|
||||
if (note.name !== $scope.note.name) {
|
||||
console.log('change note name: %o to %o', $scope.note.name, note.name);
|
||||
$scope.note.name = note.name;
|
||||
}
|
||||
|
||||
$scope.note.config = note.config;
|
||||
$scope.note.info = note.info;
|
||||
|
||||
var newParagraphIds = note.paragraphs.map(function(x) {return x.id;});
|
||||
var oldParagraphIds = $scope.note.paragraphs.map(function(x) {return x.id;});
|
||||
|
||||
var numNewParagraphs = newParagraphIds.length;
|
||||
var numOldParagraphs = oldParagraphIds.length;
|
||||
|
||||
/** add a new paragraph */
|
||||
if (numNewParagraphs > numOldParagraphs) {
|
||||
for (var index in newParagraphIds) {
|
||||
if (oldParagraphIds[index] !== newParagraphIds[index]) {
|
||||
$scope.note.paragraphs.splice(index, 0, note.paragraphs[index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** update or move paragraph */
|
||||
if (numNewParagraphs === numOldParagraphs) {
|
||||
for (var idx in newParagraphIds) {
|
||||
var newEntry = note.paragraphs[idx];
|
||||
if (oldParagraphIds[idx] === newParagraphIds[idx]) {
|
||||
$scope.$broadcast('updateParagraph', {paragraph: newEntry});
|
||||
} else {
|
||||
// move paragraph
|
||||
var oldIdx = oldParagraphIds.indexOf(newParagraphIds[idx]);
|
||||
$scope.note.paragraphs.splice(oldIdx, 1);
|
||||
$scope.note.paragraphs.splice(idx, 0, newEntry);
|
||||
// rebuild id list since paragraph has moved.
|
||||
oldParagraphIds = $scope.note.paragraphs.map(function(x) {return x.id;});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** remove paragraph */
|
||||
if (numNewParagraphs < numOldParagraphs) {
|
||||
for (var oldidx in oldParagraphIds) {
|
||||
if(oldParagraphIds[oldidx] !== newParagraphIds[oldidx]) {
|
||||
$scope.note.paragraphs.splice(oldidx, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var getInterpreterBindings = function(callback) {
|
||||
$http.get(getRestApiBase()+ '/notebook/interpreter/bind/' +$scope.note.id).
|
||||
success(function(data, status, headers, config) {
|
||||
$scope.interpreterBindings = data.body;
|
||||
$scope.interpreterBindingsOrig = jQuery.extend(true, [], $scope.interpreterBindings); // to check dirty
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
|
||||
var getInterpreterBindingsCallBack = function() {
|
||||
var selected = false;
|
||||
for (var i in $scope.interpreterBindings) {
|
||||
var setting = $scope.interpreterBindings[i];
|
||||
if (setting.selected) {
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!selected) {
|
||||
// make default selection
|
||||
var selectedIntp = {};
|
||||
for (var i in $scope.interpreterBindings) {
|
||||
var setting = $scope.interpreterBindings[i];
|
||||
if (!selectedIntp[setting.group]) {
|
||||
setting.selected = true;
|
||||
selectedIntp[setting.group] = true;
|
||||
}
|
||||
}
|
||||
$scope.showSetting = true;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.interpreterSelectionListeners = {
|
||||
accept : function(sourceItemHandleScope, destSortableScope) {return true;},
|
||||
itemMoved: function (event) {},
|
||||
orderChanged: function(event) {}
|
||||
};
|
||||
|
||||
$scope.openSetting = function() {
|
||||
$scope.showSetting = true;
|
||||
getInterpreterBindings();
|
||||
};
|
||||
|
||||
$scope.closeSetting = function() {
|
||||
if (isSettingDirty()) {
|
||||
var result = confirm('Changes will be discarded');
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$scope.showSetting = false;
|
||||
};
|
||||
|
||||
$scope.saveSetting = function() {
|
||||
var selectedSettingIds = [];
|
||||
for (var no in $scope.interpreterBindings) {
|
||||
var setting = $scope.interpreterBindings[no];
|
||||
if (setting.selected) {
|
||||
selectedSettingIds.push(setting.id);
|
||||
}
|
||||
}
|
||||
|
||||
$http.put(getRestApiBase() + '/notebook/interpreter/bind/' + $scope.note.id,
|
||||
selectedSettingIds).
|
||||
success(function(data, status, headers, config) {
|
||||
console.log('Interpreter binding %o saved', selectedSettingIds);
|
||||
$scope.showSetting = false;
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.toggleSetting = function() {
|
||||
if ($scope.showSetting) {
|
||||
$scope.closeSetting();
|
||||
} else {
|
||||
$scope.openSetting();
|
||||
}
|
||||
};
|
||||
|
||||
var isSettingDirty = function() {
|
||||
if (angular.equals($scope.interpreterBindings, $scope.interpreterBindingsOrig)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.$on('angularObjectUpdate', function(event, data) {
|
||||
if (data.noteId === $scope.note.id) {
|
||||
var scope = $rootScope.compiledScope;
|
||||
var varName = data.angularObject.name;
|
||||
|
||||
if (angular.equals(data.angularObject.object, scope[varName])) {
|
||||
// return when update has no change
|
||||
return;
|
||||
}
|
||||
|
||||
if (!angularObjectRegistry[varName]) {
|
||||
angularObjectRegistry[varName] = {
|
||||
interpreterGroupId : data.interpreterGroupId,
|
||||
}
|
||||
}
|
||||
|
||||
angularObjectRegistry[varName].skipEmit = true;
|
||||
|
||||
if (!angularObjectRegistry[varName].clearWatcher) {
|
||||
angularObjectRegistry[varName].clearWatcher = scope.$watch(varName, function(newValue, oldValue) {
|
||||
if (angularObjectRegistry[varName].skipEmit) {
|
||||
angularObjectRegistry[varName].skipEmit = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$rootScope.$emit('sendNewEvent', {
|
||||
op: 'ANGULAR_OBJECT_UPDATED',
|
||||
data: {
|
||||
noteId: $routeParams.noteId,
|
||||
name:varName,
|
||||
value:newValue,
|
||||
interpreterGroupId:angularObjectRegistry[varName].interpreterGroupId
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
scope[varName] = data.angularObject.object;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var isFunction = function(functionToCheck) {
|
||||
var getType = {};
|
||||
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -1,508 +0,0 @@
|
|||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
.paragraph-col {
|
||||
margin: 0 0 0 0px;
|
||||
padding: 0 0 0 0px;
|
||||
}
|
||||
|
||||
.paragraph {
|
||||
padding: 2px 8px 4px 8px;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.paragraph .tableDisplay .hljs {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.paragraph .ace_print-margin {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.paragraphAsIframe{
|
||||
padding: 0px 0px 0px 0px;
|
||||
margin-top: -79px;
|
||||
margin-left: -10px;
|
||||
margin-right: -10px;
|
||||
}
|
||||
|
||||
.paragraphAsIframe .control {
|
||||
background-color: rgba(255,255,255,0.9);
|
||||
border-top: 1px solid #EFEFEF;
|
||||
display: none;
|
||||
float: right;
|
||||
color: #999;
|
||||
margin-top: -9px;
|
||||
margin-right:0px;
|
||||
position:absolute;
|
||||
clear:both;
|
||||
right:25px;
|
||||
/*z-index:10;*/
|
||||
}
|
||||
|
||||
.paragraphAsIframe table {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.paragraphAsIframe .editor {
|
||||
width: 100%;
|
||||
border-left: 4px solid #EEEEEE;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.paragraphAsIframe .text {
|
||||
white-space: pre;
|
||||
display: block;
|
||||
unicode-bidi: embed;
|
||||
display: block !important;
|
||||
margin: 0 0 10px!important;
|
||||
font-size: 12px!important;
|
||||
line-height: 1.42857143!important;
|
||||
word-break: break-all!important;
|
||||
word-wrap: break-word!important;
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||
}
|
||||
|
||||
.ace_marker-layer .ace_selection {
|
||||
z-index: 0 !important;
|
||||
}
|
||||
|
||||
.ace_marker-layer .ace_selected-word {
|
||||
z-index: 0 !important;
|
||||
}
|
||||
|
||||
.labelBtn {
|
||||
padding: .2em .6em .3em;
|
||||
font-size: 75%;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
border-radius: .25em;
|
||||
}
|
||||
|
||||
.note-jump {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.noteBtnfa {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.control span {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.control {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.paragraph-space {
|
||||
margin-bottom: 5px;
|
||||
padding: 10px !important;
|
||||
}
|
||||
|
||||
.paragraph .control {
|
||||
background-color: rgba(255,255,255,0.85);
|
||||
/*display: none;*/
|
||||
float: right;
|
||||
color: #999;
|
||||
margin-top: 1px;
|
||||
margin-right: 5px;
|
||||
position:absolute;
|
||||
clear:both;
|
||||
right:15px;
|
||||
top: 16px;
|
||||
text-align:right;
|
||||
font-size:12px;
|
||||
}
|
||||
|
||||
.paragraph .control li{
|
||||
font-size:12px;
|
||||
margin-bottom:4px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.paragraph table {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.paragraph .title {
|
||||
margin: 3px 0px 0px 0px;
|
||||
height: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.paragraph .title div {
|
||||
width: 80%;
|
||||
font-weight: bold;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 17px !important;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.paragraph .title input {
|
||||
width: 80%;
|
||||
line-height: 1.42857143;
|
||||
color: #555;
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
|
||||
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
text-transform: capitalize;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 14px!important;
|
||||
}
|
||||
|
||||
.paragraph .editor {
|
||||
width: 100%;
|
||||
border-left: 4px solid #DDDDDD;
|
||||
background: rgba(255, 255, 255, 0.0);
|
||||
margin: 7px 0 2px 0px;
|
||||
}
|
||||
|
||||
.paragraph .text {
|
||||
white-space: pre;
|
||||
display: block;
|
||||
unicode-bidi: embed;
|
||||
display: block !important;
|
||||
margin: 0 0 0px !important;
|
||||
line-height: 1.42857143 !important;
|
||||
word-break: break-all !important;
|
||||
word-wrap: break-word !important;
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||
font-size: 12px !important;
|
||||
margin-bottom: 5px !important;
|
||||
}
|
||||
|
||||
.paragraph p {
|
||||
margin : 0 0 0 0px;
|
||||
}
|
||||
|
||||
.paragraph div svg {
|
||||
width : 100%;
|
||||
}
|
||||
|
||||
.ace-tm {
|
||||
background-color: #FFFFFF;
|
||||
color: black;
|
||||
}
|
||||
.ace_editor {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||
font-size: 12px;
|
||||
line-height: normal;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.ace_hidden-cursors {opacity:0}
|
||||
|
||||
/** Remove z-index to ace */
|
||||
.ace_text-input, .ace_gutter, .ace_layer,
|
||||
.emacs-mode, .ace_text-layer, .ace_cursor-layer,
|
||||
.ace_cursor, .ace_scrollbar {
|
||||
z-index:auto !important;
|
||||
}
|
||||
|
||||
/** Force opacity:0 to textarea in writing texts **/
|
||||
.ace_text-input.ace_composition {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
#main .emacs-mode .ace_cursor {
|
||||
background-color:#C0C0C0!important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.paragraph .status {
|
||||
font-size: 10px;
|
||||
color: #AAAAAA;
|
||||
text-align: right;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.paragraph .runControl {
|
||||
font-size: 1px;
|
||||
color: #AAAAAA;
|
||||
height:4px;
|
||||
margin: 1px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.paragraph .runControl .progress {
|
||||
position: relative;
|
||||
width:100%;
|
||||
height:4px;
|
||||
z-index:100;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.paragraph .runControl .progress .progress-bar {
|
||||
z-index:100;
|
||||
}
|
||||
|
||||
.paragraph .executionTime {
|
||||
color: #999;
|
||||
font-size: 10px;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
|
||||
.disable {
|
||||
opacity:0.4!important;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.noteAction {
|
||||
margin-left: -10px;
|
||||
margin-right: -10px;
|
||||
margin-top: -10px;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
.noteAction li{
|
||||
font-size:12px;
|
||||
margin-bottom:4px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.new_h3 {
|
||||
margin-top: 1px;
|
||||
padding-top: 7px;
|
||||
}
|
||||
|
||||
.form-control2 {
|
||||
width: 100%;
|
||||
margin-left: 15px;
|
||||
font-size: 29px;
|
||||
line-height: 1.42857143;
|
||||
color: #555;
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
|
||||
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
}
|
||||
|
||||
.form-control-static2 {
|
||||
padding-top: 7px;
|
||||
font-size: 29px;
|
||||
margin-left: 15px;
|
||||
padding-bottom: 7px;
|
||||
margin-bottom: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* panel default */
|
||||
.panel-default {
|
||||
/* border: none; */
|
||||
border-color: #DDDDDD;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.panel-group .panel-default {
|
||||
/*border: solid #e5e5e5;
|
||||
border-width: 1px 1px 2px;*/
|
||||
}
|
||||
|
||||
.panel-default > .panel-heading {
|
||||
color: #34495e;
|
||||
background-color: #ffffff;
|
||||
border-color: #e5e5e5;
|
||||
}
|
||||
|
||||
.panel-default > .panel-heading + .panel-collapse .panel-body {
|
||||
border-top-color: #e5e5e5;
|
||||
}
|
||||
|
||||
.panel-default > .panel-heading > .dropdown .caret {
|
||||
border-color: #ecf0f1 transparent;
|
||||
}
|
||||
|
||||
.panel-default > .panel-footer + .panel-collapse .panel-body {
|
||||
border-bottom-color: #e5e5e5;
|
||||
}
|
||||
|
||||
.panel-body-heading {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding-left: 10px;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.paragraph-margin {
|
||||
margin-right: 2px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.tableDisplay img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.tableDisplay .btn-group span {
|
||||
margin: 10px 0px 0px 10px;
|
||||
font-size:12px;
|
||||
}
|
||||
.tableDisplay .btn-group span a {
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.tableDisplay .option {
|
||||
padding: 5px 5px 5px 5px;
|
||||
font-size:12px;
|
||||
height:auto;
|
||||
overflow : auto;
|
||||
/*min-height: 200px;*/
|
||||
border-top: 1px solid #ecf0f1;
|
||||
|
||||
}
|
||||
|
||||
.tableDisplay .option .columns {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tableDisplay .option .columns ul {
|
||||
|
||||
background-color: white;
|
||||
/*min-width: 100px;*/
|
||||
width:auto;
|
||||
padding: 3px 3px 3px 3px;
|
||||
height : 150px;
|
||||
border: 1px solid #CCC;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
|
||||
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
|
||||
}
|
||||
|
||||
.tableDisplay .option .columns ul li {
|
||||
margin: 3px 3px 3px 3px;
|
||||
}
|
||||
|
||||
.tableDisplay .option .columns ul li span {
|
||||
cursor: pointer;
|
||||
margin-left: 3px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.tableDisplay .option .columns ul li div ul { /* aggregation menu */
|
||||
width:auto;
|
||||
height:auto;
|
||||
}
|
||||
|
||||
.tableDisplay .option .columns ul li div ul li a {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tableDisplay .option .columns a:focus,
|
||||
.tableDisplay .option .columns a:hover {
|
||||
text-decoration: none;
|
||||
outline: 0;
|
||||
outline-offset: 0px;
|
||||
}
|
||||
|
||||
.graphContainer {
|
||||
position:relative;
|
||||
margin-bottom: 5px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.noOverflow {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.graphContainer .table {
|
||||
overflow: hidden;
|
||||
margin-bottom: 5px !important;
|
||||
}
|
||||
|
||||
.allFields {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.noDot {
|
||||
list-style-type: none;
|
||||
padding-left:5px;
|
||||
}
|
||||
|
||||
.liVertical {
|
||||
display:block;
|
||||
float:left;
|
||||
padding: 5px;
|
||||
}
|
||||
.row {
|
||||
margin-right: 0px !important
|
||||
}
|
||||
|
||||
.lightBold {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.resizable-helper {
|
||||
border: 3px solid #DDDDDD;
|
||||
}
|
||||
|
||||
/* note setting panel */
|
||||
.setting {
|
||||
background-color: white;
|
||||
padding: 10px 15px 15px 15px;
|
||||
margin-left: -10px;
|
||||
margin-right: -10px;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
|
||||
border-bottom: 1px solid #E5E5E5;
|
||||
}
|
||||
|
||||
.setting .interpreterSettings {
|
||||
list-style-type: none;
|
||||
background-color: #EFEFEF;
|
||||
padding: 10px 10px 10px 10px;
|
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.15);
|
||||
border: 1px solid #E5E5E5;
|
||||
}
|
||||
|
||||
.setting .interpreterSettings div div {
|
||||
margin: 2px 0px 2px 0px;
|
||||
}
|
||||
|
||||
.setting .interpreterSettings div div {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.setting .modal-header {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.setting .modal-body {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.setting .modal-footer {
|
||||
border: 0px;
|
||||
}
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
<!--
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!-- Here the controller <NotebookCtrl> is not needed because explicitly set in the app.js (route) -->
|
||||
<div>
|
||||
<div class="noteAction" ng-show="note.id && !paragraphUrl">
|
||||
<h3 class="new_h3">
|
||||
<input type="text" class="form-control2" placeholder="{{note.name || 'Note ' + note.id}}" style="width:200px;"
|
||||
ng-show="showEditor" ng-model="note.name" ng-enter="sendNewName()" ng-delete="showEditor = false" autofocus/>
|
||||
<p class="form-control-static2" ng-click="showEditor = true" ng-show="!showEditor">{{note.name || 'Note ' + note.id}}</p>
|
||||
<span class="labelBtn btn-group">
|
||||
<button type="button"
|
||||
class="btn btn-default btn-xs"
|
||||
ng-click="runNote()"
|
||||
ng-if="!isNoteRunning()"
|
||||
tooltip-placement="top" tooltip="Run all the note">
|
||||
<i class="icon-control-play"></i>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
class="btn btn-default btn-xs"
|
||||
ng-click="toggleAllEditor()"
|
||||
ng-hide="viewOnly"
|
||||
tooltip-placement="top" tooltip="Show/hide the code">
|
||||
<i ng-class="editorToggled ? 'fa icon-size-actual' : 'fa icon-size-fullscreen'"></i></button>
|
||||
|
||||
<button type="button"
|
||||
class="btn btn-default btn-xs"
|
||||
ng-click="toggleAllTable()"
|
||||
ng-hide="viewOnly"
|
||||
tooltip-placement="top" tooltip="Show/hide the output">
|
||||
<i ng-class="tableToggled ? 'fa icon-notebook' : 'fa icon-book-open'"></i></button>
|
||||
|
||||
<button type="button"
|
||||
class="btn btn-default btn-xs"
|
||||
ng-click="removeNote(note.id)"
|
||||
ng-hide="viewOnly"
|
||||
tooltip-placement="top" tooltip="Remove the notebook">
|
||||
<i class="icon-trash"></i></button>
|
||||
</span>
|
||||
|
||||
<span ng-hide="viewOnly">
|
||||
<div class="labelBtn btn-group">
|
||||
<div class="btn btn-default btn-xs dropdown-toggle"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
ng-class="{ 'btn-info' : note.config.cron, 'btn-danger' : note.info.cron, 'btn-default' : !note.config.cron}">
|
||||
<span class="fa fa-clock-o"></span> {{getCronOptionNameFromValue(note.config.cron)}}
|
||||
</div>
|
||||
<ul class="dropdown-menu" role="menu" style="width:300px">
|
||||
<li>
|
||||
<div style="padding:10px 20px 0 20px;font-weight:normal;word-wrap:break-word">
|
||||
Run note with cron scheduler.
|
||||
Either choose from<br/>preset or write your own <a href="http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger" target=_blank>cron expression</a>.
|
||||
<br/><br/>
|
||||
<span>- Preset</span>
|
||||
<a ng-repeat="cr in cronOption"
|
||||
type="button"
|
||||
ng-click="setCronScheduler(cr.value)"
|
||||
style="cursor:pointer"
|
||||
dropdown-input>{{cr.name}}</a>
|
||||
<br/><br/>
|
||||
<span>- Cron expression</span>
|
||||
<input type="text"
|
||||
ng-model="note.config.cron"
|
||||
ng-change="setCronScheduler(note.config.cron)"
|
||||
dropdown-input>
|
||||
</input>
|
||||
<p ng-show="note.info.cron"
|
||||
style="color:red">
|
||||
{{note.info.cron}}
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<div class="pull-right"
|
||||
style="margin-top:15px; margin-right:15px; font-size:15px;">
|
||||
<span style="position:relative; top:3px; margin-right:4px; cursor:pointer"
|
||||
data-toggle="modal"
|
||||
data-target="#shortcutModal"
|
||||
tooltip-placement="top" tooltip="List of shortcut">
|
||||
<i class="icon-question"></i>
|
||||
</span>
|
||||
<span style="position:relative; top:2px; margin-right:4px; cursor:pointer;"
|
||||
ng-click="toggleSetting()"
|
||||
tooltip-placement="top" tooltip="Interpreter binding">
|
||||
<i class="fa fa-cog"
|
||||
ng-style="{color: showSetting ? '#3071A9' : 'black' }"></i>
|
||||
</span>
|
||||
|
||||
<span class="btn-group">
|
||||
<button type="button"
|
||||
class="btn btn-default btn-xs dropdown-toggle"
|
||||
data-toggle="dropdown">
|
||||
{{note.config.looknfeel}} <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu pull-right" role="menu">
|
||||
<li ng-repeat="looknfeel in looknfeelOption">
|
||||
<a style="cursor:pointer"
|
||||
ng-click="setLookAndFeel(looknfeel)">{{looknfeel}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<!-- settings -->
|
||||
<div ng-show="showSetting"
|
||||
class="setting">
|
||||
<div>
|
||||
<h4>Settings</h4>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
<h5>Interpreter binding</h5>
|
||||
<p>
|
||||
Bind interpreter for this note.
|
||||
Click to Bind/Unbind interpreter.
|
||||
Drag and drop to reorder interpreters. <br />
|
||||
The first interpreter on the list becomes default. To create/remove interpreters, go to <a href="/#/interpreter">Interpreter</a> menu.
|
||||
</p>
|
||||
|
||||
<div class="interpreterSettings"
|
||||
as-sortable="interpreterSelectionListeners" data-ng-model="interpreterBindings">
|
||||
<div data-ng-repeat="item in interpreterBindings" as-sortable-item>
|
||||
<div as-sortable-item-handle
|
||||
ng-click="item.selected = !item.selected"
|
||||
class="btn"
|
||||
ng-class="{'btn-info': item.selected, 'btn-default': !item.selected}"><font style="font-size:16px">{{item.name}}</font> <small><span ng-repeat="intp in item.interpreters"><span ng-show="!$first">, </span>%{{intp.name}}</span></small></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<button class="btn btn-primary" ng-click="saveSetting()">Save</button>
|
||||
<button class="btn btn-default" ng-click="closeSetting()">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="note-jump"></div>
|
||||
|
||||
<!-- Include the paragraphs according to the note -->
|
||||
<div id="{{currentParagraph.id}}_paragraphColumn_main"
|
||||
ng-repeat="currentParagraph in note.paragraphs"
|
||||
ng-controller="ParagraphCtrl"
|
||||
ng-Init="init(currentParagraph)"
|
||||
ng-class="columnWidthClass(currentParagraph.config.colWidth)"
|
||||
class="paragraph-col">
|
||||
<div id="{{currentParagraph.id}}_paragraphColumn"
|
||||
ng-include src="'views/paragraph.html'"
|
||||
ng-class="{'paragraph-space box paragraph-margin': !asIframe, 'focused': paragraphFocused}"
|
||||
ng-hide="currentParagraph.config.tableHide && viewOnly">
|
||||
</div>
|
||||
</div>
|
||||
<div style="clear:both;height:10px"></div>
|
||||
</div>
|
||||
|
|
@ -1,449 +0,0 @@
|
|||
<!--
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<div id="{{paragraph.id}}_container"
|
||||
ng-class="{'paragraph outlineOnFocus': !asIframe, 'paragraphAsIframe': asIframe}">
|
||||
|
||||
<div ng-show="paragraph.config.title"
|
||||
id="{{paragraph.id}}_title"
|
||||
class="title">
|
||||
<input type="text"
|
||||
placeholder="Edit title"
|
||||
ng-model="paragraph.title"
|
||||
ng-show="showTitleEditor"
|
||||
ng-delete="showTitleEditor = false"
|
||||
ng-enter="setTitle(); showTitleEditor = false"/>
|
||||
<div ng-click="showTitleEditor = !asIframe && !viewOnly"
|
||||
ng-show="!showTitleEditor"
|
||||
ng-bind-html="paragraph.title || 'Untitled'">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div ng-show="!paragraph.config.editorHide">
|
||||
<div id="{{paragraph.id}}_editor"
|
||||
style="opacity: 1;"
|
||||
class="editor"
|
||||
ui-ace="{
|
||||
onLoad : aceLoaded,
|
||||
onChange: aceChanged,
|
||||
require : ['ace/ext/language_tools']
|
||||
}"
|
||||
ng-model="paragraph.text"
|
||||
ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="{{paragraph.id}}_runControl" class="runControl">
|
||||
<div ng-if="(getProgress()<=0 || getProgress()>=100) && (paragraph.status=='RUNNING' )">
|
||||
<div id="{{paragraph.id}}_progress"
|
||||
class="progress">
|
||||
<div class="progress-bar progress-bar-striped active" role="progressbar" style="width:100%;"></div>
|
||||
<span class="sr-only"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="getProgress()>0 && getProgress()<100 && paragraph.status=='RUNNING'">
|
||||
<div id="{{paragraph.id}}_progress"
|
||||
class="progress">
|
||||
<div class="progress-bar" role="progressbar" style="width:{{getProgress()}}%;"></div>
|
||||
<span class="sr-only">{{getProgress()}}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id="{{paragraph.id}}_form" role="form"
|
||||
ng-show="!paragraph.config.tableHide && !asIframe"
|
||||
class="form-horizontal">
|
||||
<div class="form-group"
|
||||
ng-repeat="formulaire in paragraph.settings.forms"
|
||||
ng-Init="loadForm(formulaire, paragraph.settings.params)">
|
||||
<label class="col-sm-1 control-label input-sm" ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }">{{formulaire.name}}</label>
|
||||
<div class="col-sm-3">
|
||||
<input class="form-control input-sm"
|
||||
ng-if="!paragraph.settings.forms[formulaire.name].options"
|
||||
ng-enter="runParagraph(getEditorValue())"
|
||||
ng-model="paragraph.settings.params[formulaire.name]"
|
||||
ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
|
||||
name="{{formulaire.name}}">
|
||||
</input>
|
||||
|
||||
<select class="form-control input-sm"
|
||||
ng-if="paragraph.settings.forms[formulaire.name].options"
|
||||
ng-change="runParagraph(getEditorValue())"
|
||||
ng-model="paragraph.settings.params[formulaire.name]"
|
||||
ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
|
||||
name="{{formulaire.name}}"
|
||||
ng-options="option.value as (option.displayName||option.value) for option in paragraph.settings.forms[formulaire.name].options"
|
||||
>
|
||||
<!--
|
||||
<option
|
||||
ng-repeat="option in paragraph.settings.forms[formulaire.name].options"
|
||||
value="{{option.value}}"
|
||||
>{{option.displayName || option.value}}
|
||||
</option>
|
||||
-->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Rendering -->
|
||||
<div class='tableDisplay' ng-show="!paragraph.config.tableHide">
|
||||
<div id="{{paragraph.id}}_switch"
|
||||
ng-if="paragraph.result.type == 'TABLE' && !asIframe && !viewOnly"
|
||||
class="btn-group"
|
||||
style='margin-bottom: 10px;'>
|
||||
<button type="button" class="btn btn-default btn-sm"
|
||||
ng-class="{'active': isGraphMode('table')}"
|
||||
ng-click="setGraphMode('table', true)" ><i class="fa fa-table"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-sm"
|
||||
ng-class="{'active': isGraphMode('multiBarChart')}"
|
||||
ng-click="setGraphMode('multiBarChart', true)"><i class="fa fa-bar-chart"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-sm"
|
||||
ng-class="{'active': isGraphMode('pieChart')}"
|
||||
ng-click="setGraphMode('pieChart', true)"><i class="fa fa-pie-chart"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-sm"
|
||||
ng-class="{'active': isGraphMode('stackedAreaChart')}"
|
||||
ng-click="setGraphMode('stackedAreaChart', true)"><i class="fa fa-area-chart"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-sm"
|
||||
ng-class="{'active': isGraphMode('lineChart')}"
|
||||
ng-click="setGraphMode('lineChart', true)"><i class="fa fa-line-chart"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-sm"
|
||||
ng-class="{'active': isGraphMode('scatterChart')}"
|
||||
ng-click="setGraphMode('scatterChart', true)"><i class="cf cf-scatter-chart"></i>
|
||||
</button>
|
||||
</div>
|
||||
<span ng-if="getResultType()=='TABLE' && getGraphMode()!='table' && !asIframe && !viewOnly"
|
||||
style="margin-left:10px; cursor:pointer; display: inline-block; vertical-align:top; position: relative; line-height:30px;">
|
||||
<a class="btnText" ng-if="paragraph.config.graph.optionOpen"
|
||||
ng-click="toggleGraphOption()">
|
||||
settings <span class="fa fa-caret-up"></span>
|
||||
</a>
|
||||
<a class="btnText" ng-if="!paragraph.config.graph.optionOpen"
|
||||
ng-click="toggleGraphOption()" >
|
||||
settings <span class="fa fa-caret-down"></span>
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<div class="option lightBold" style="overflow: visible;"
|
||||
ng-if="getResultType()=='TABLE' && getGraphMode()!='table'
|
||||
&& paragraph.config.graph.optionOpen && !asIframe && !viewOnly">
|
||||
All fields:
|
||||
<div class="allFields row">
|
||||
<ul class="noDot">
|
||||
<li class="liVertical" ng-repeat="col in paragraph.result.columnNames">
|
||||
<div class="btn btn-default btn-xs"
|
||||
data-drag="true"
|
||||
data-jqyoui-options="{revert: 'invalid', helper: 'clone'}"
|
||||
ng-model="paragraph.result.columnNames"
|
||||
jqyoui-draggable="{index: {{$index}}, placeholder: 'keep'}">
|
||||
{{col.name | limitTo: 30}}{{col.name.length > 30 ? '...' : ''}}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="row" ng-if="getGraphMode()!='scatterChart'">
|
||||
<div class="col-md-4">
|
||||
<span class="columns lightBold">
|
||||
Keys
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.keys"
|
||||
jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled">
|
||||
<li ng-repeat="item in paragraph.config.graph.keys">
|
||||
<button class="btn btn-primary btn-xs">
|
||||
{{item.name}} <span class="fa fa-close" ng-click="removeGraphOptionKeys($index)"></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<span class="columns lightBold">
|
||||
Groups
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.groups"
|
||||
jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled">
|
||||
<li ng-repeat="item in paragraph.config.graph.groups">
|
||||
<button class="btn btn-success btn-xs">
|
||||
{{item.name}} <span class="fa fa-close" ng-click="removeGraphOptionGroups($index)"></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<span class="columns lightBold">
|
||||
Values
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.values"
|
||||
jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled">
|
||||
<li ng-repeat="item in paragraph.config.graph.values">
|
||||
<div class="btn-group">
|
||||
<div class="btn btn-info btn-xs dropdown-toggle"
|
||||
type="button"
|
||||
data-toggle="dropdown">
|
||||
{{item.name | limitTo: 30}}{{item.name.length > 30 ? '...' : ''}}
|
||||
<font style="color:#EEEEEE;"><span class="lightBold" style="text-transform: uppercase;">{{item.aggr}}</span></font>
|
||||
<span class="fa fa-close" ng-click="removeGraphOptionValues($index)"></span>
|
||||
</div>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li ng-click="setGraphOptionValueAggr($index, 'sum')"><a>sum</a></li>
|
||||
<li ng-click="setGraphOptionValueAggr($index, 'count')"><a>count</a></li>
|
||||
<li ng-click="setGraphOptionValueAggr($index, 'avg')"><a>avg</a></li>
|
||||
<li ng-click="setGraphOptionValueAggr($index, 'min')"><a>min</a></li>
|
||||
<li ng-click="setGraphOptionValueAggr($index, 'max')"><a>max</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" ng-if="getGraphMode()=='scatterChart'">
|
||||
<div class="col-md-3">
|
||||
<span class="columns lightBold">
|
||||
xAxis
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.scatter.xAxis"
|
||||
jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled"
|
||||
style="height:36px">
|
||||
<li ng-if="paragraph.config.graph.scatter.xAxis">
|
||||
<button class="btn btn-primary btn-xs">
|
||||
{{paragraph.config.graph.scatter.xAxis.name}} <span class="fa fa-close" ng-click="removeScatterOptionXaxis($index)"></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<span class="columns lightBold">
|
||||
yAxis
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.scatter.yAxis"
|
||||
jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled"
|
||||
style="height:36px">
|
||||
<li ng-if="paragraph.config.graph.scatter.yAxis">
|
||||
<button class="btn btn-success btn-xs">
|
||||
{{paragraph.config.graph.scatter.yAxis.name}} <span class="fa fa-close" ng-click="removeScatterOptionYaxis($index)"></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<span class="columns lightBold">
|
||||
group
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.scatter.group"
|
||||
jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled"
|
||||
style="height:36px">
|
||||
<li ng-if="paragraph.config.graph.scatter.group">
|
||||
<button class="btn btn-info btn-xs">
|
||||
{{paragraph.config.graph.scatter.group.name}} <span class="fa fa-close" ng-click="removeScatterOptionGroup($index)"></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<span class="columns lightBold">
|
||||
size
|
||||
<a tabindex="0" class="fa fa-info-circle" role="button" popover-placement="top"
|
||||
popover-trigger="focus"
|
||||
popover-html-unsafe="<li>Size option is valid only when you drop numeric field here.</li>
|
||||
<li>When data in each axis are discrete, 'number of values in corresponding coordinate' will be used as size.</li>
|
||||
<li>Zeppelin consider values as discrete when the values contain string value 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>"></a>
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.scatter.size"
|
||||
jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled"
|
||||
style="height:36px">
|
||||
<li ng-if="paragraph.config.graph.scatter.size">
|
||||
<button class="btn btn-xs" style="color:white" ng-class="{'btn-warning': isValidSizeOption(paragraph.config.graph.scatter, paragraph.result.rows)}">
|
||||
{{paragraph.config.graph.scatter.size.name}} <span class="fa fa-close" ng-click="removeScatterOptionSize($index)"></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="p{{paragraph.id}}_graph"
|
||||
class="graphContainer"
|
||||
ng-class="{'noOverflow': getGraphMode()=='table'}"
|
||||
ng-if="getResultType()=='TABLE'"
|
||||
allowresize="{{!asIframe && !viewOnly}}"
|
||||
resizable on-resize="setGraphHeight();">
|
||||
|
||||
<div ng-if="getGraphMode()=='table'"
|
||||
id="p{{paragraph.id}}_table"
|
||||
class="table">
|
||||
</div>
|
||||
|
||||
<div ng-if="getGraphMode()=='multiBarChart'"
|
||||
id="p{{paragraph.id}}_multiBarChart">
|
||||
<svg></svg>
|
||||
</div>
|
||||
|
||||
<div ng-if="getGraphMode()=='pieChart'"
|
||||
id="p{{paragraph.id}}_pieChart">
|
||||
<svg></svg>
|
||||
</div>
|
||||
|
||||
<div ng-if="getGraphMode()=='stackedAreaChart'"
|
||||
id="p{{paragraph.id}}_stackedAreaChart">
|
||||
<svg></svg>
|
||||
</div>
|
||||
|
||||
<div ng-if="getGraphMode()=='lineChart'"
|
||||
id="p{{paragraph.id}}_lineChart">
|
||||
<svg></svg>
|
||||
</div>
|
||||
|
||||
<div ng-if="getGraphMode()=='scatterChart'"
|
||||
id="p{{paragraph.id}}_scatterChart">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="{{paragraph.id}}_comment"
|
||||
class="text"
|
||||
ng-if="getResultType()=='TABLE' && paragraph.result.comment"
|
||||
ng-Init="loadResultType(paragraph.result)"
|
||||
ng-bind-html="paragraph.result.comment">
|
||||
</div>
|
||||
|
||||
<div id="{{paragraph.id}}_text"
|
||||
class="text"
|
||||
ng-if="paragraph.result.type == 'TEXT'"
|
||||
ng-Init="loadResultType(paragraph.result)"
|
||||
ng-bind="paragraph.result.msg">
|
||||
</div>
|
||||
|
||||
<div id="p{{paragraph.id}}_html"
|
||||
ng-if="paragraph.result.type == 'HTML'"
|
||||
ng-Init="loadResultType(paragraph.result)">
|
||||
</div>
|
||||
|
||||
<div id="p{{paragraph.id}}_angular"
|
||||
ng-if="paragraph.result.type == 'ANGULAR'"
|
||||
ng-Init="loadResultType(paragraph.result)">
|
||||
</div>
|
||||
|
||||
<img id="{{paragraph.id}}_img"
|
||||
ng-if="paragraph.result.type == 'IMG'"
|
||||
ng-Init="loadResultType(paragraph.result)"
|
||||
ng-src="{{getBase64ImageSrc(paragraph.result.msg)}}">
|
||||
</img>
|
||||
|
||||
<div id="{{paragraph.id}}_error"
|
||||
class="error"
|
||||
ng-if="paragraph.status == 'ERROR'"
|
||||
ng-bind="paragraph.errorMessage">
|
||||
</div>
|
||||
|
||||
<div id="{{paragraph.id}}_executionTime" class="executionTime" ng-bind-html="getExecutionTime()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="{{paragraph.id}}_control" class="control" ng-show="!asIframe">
|
||||
|
||||
<span>
|
||||
{{paragraph.status}}
|
||||
</span>
|
||||
|
||||
<span ng-if="paragraph.status=='RUNNING'">
|
||||
{{getProgress()}}%
|
||||
</span>
|
||||
|
||||
<!-- Run / Cancel button -->
|
||||
<span class="icon-control-play" style="cursor:pointer;color:#3071A9" tooltip-placement="top" tooltip="Run this paragraph"
|
||||
ng-click="runParagraph(getEditorValue())"
|
||||
ng-show="paragraph.status!='RUNNING' && paragraph.status!='PENDING'"></span>
|
||||
<span class="icon-control-pause" style="cursor:pointer;color:#CD5C5C" tooltip-placement="top" tooltip="Cancel"
|
||||
ng-click="cancelParagraph()"
|
||||
ng-show="paragraph.status=='RUNNING' || paragraph.status=='PENDING'"></span>
|
||||
|
||||
<span class="{{paragraph.config.editorHide ? 'icon-size-fullscreen' : 'icon-size-actual'}}" style="cursor:pointer;" tooltip-placement="top" tooltip="{{(paragraph.config.editorHide ? 'Show' : 'Hide') + ' editor'}}"
|
||||
ng-click="toggleEditor()"></span>
|
||||
<span class="{{paragraph.config.tableHide ? 'icon-notebook' : 'icon-book-open'}}" style="cursor:pointer;" tooltip-placement="top" tooltip="{{(paragraph.config.tableHide ? 'Show' : 'Hide') + ' output'}}"
|
||||
ng-click="toggleOutput()"></span>
|
||||
|
||||
<span class="dropdown navbar-right">
|
||||
<span class="icon-settings" style="cursor:pointer"
|
||||
data-toggle="dropdown"
|
||||
type="button">
|
||||
</span>
|
||||
<ul class="dropdown-menu" role="menu" style="width:200px;">
|
||||
<li>
|
||||
<a class="fa fa-arrows-h dropdown"> Width
|
||||
<form style="display:inline; margin-left:5px;">
|
||||
<select ng-model="paragraph.config.colWidth"
|
||||
class="selectpicker"
|
||||
ng-change="changeColWidth()"
|
||||
ng-options="col for col in colWidthOption"></select>
|
||||
</form>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="icon-arrow-up" style="cursor:pointer"
|
||||
ng-click="moveUp()"> Move Up</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="icon-arrow-down" style="cursor:pointer"
|
||||
ng-click="moveDown()"> Move Down</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="icon-plus" style="cursor:pointer"
|
||||
ng-click="insertNew()"> Insert New</a>
|
||||
</li>
|
||||
<li>
|
||||
<!-- paragraph handler -->
|
||||
<a class="fa fa-font" style="cursor:pointer"
|
||||
ng-click="hideTitle()"
|
||||
ng-show="paragraph.config.title"> Hide title</a>
|
||||
<a class="fa fa-font" style="cursor:pointer"
|
||||
ng-click="showTitle()"
|
||||
ng-show="!paragraph.config.title"> Show title</a>
|
||||
</li>
|
||||
|
||||
<li><a class="icon-share-alt" style="cursor:pointer"
|
||||
ng-click="goToSingleParagraph()"> Link this paragraph</a>
|
||||
</li>
|
||||
<li>
|
||||
<!-- remove paragraph -->
|
||||
<a class="fa fa-times" style="cursor:pointer"
|
||||
ng-click="removeParagraph()"> Remove</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
{
|
||||
"name": "zeppelin-web",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {},
|
||||
"dependencies": {
|
||||
"grunt-angular-templates": "^0.5.7",
|
||||
"grunt-dom-munger": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bower": "",
|
||||
"grunt": "^0.4.1",
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
<exclude>**/.settings/*</exclude>
|
||||
<exclude>**/.classpath</exclude>
|
||||
<exclude>**/.project</exclude>
|
||||
<exclude>**/target/**</exclude>
|
||||
<exclude>**/target/**</exclude>
|
||||
<exclude>node/**</exclude>
|
||||
<exclude>node_modules/**</exclude>
|
||||
<exclude>bower_components/**</exclude>
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
<goal>npm</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
|
||||
|
||||
<execution>
|
||||
<id>bower install</id>
|
||||
<goals>
|
||||
|
|
|
|||