Merge remote-tracking branch 'origin/master' into livyInterperter

This commit is contained in:
Prabhjyot Singh 2016-05-17 13:19:23 +05:30
commit 6f1503f4b4
11 changed files with 100 additions and 154 deletions

View file

@ -47,7 +47,7 @@ Bind a value to an angular object and a **mandatory** target paragraph:
```
<img src="/assets/themes/zeppelin/img/screenshots/z_angularBind.gif" />
<img src="../assets/themes/zeppelin/img/screenshots/z_angularBind.gif" />
<hr/>
@ -63,7 +63,7 @@ Unbind/remove a value from angular object and a **mandatory** target paragraph:
```
<img src="/assets/themes/zeppelin/img/screenshots/z_angularUnbind.gif" />
<img src="../assets/themes/zeppelin/img/screenshots/z_angularUnbind.gif" />
The signature for the **`z.angularBind() / z.angularUnbind()`** functions are:
@ -97,7 +97,7 @@ You can also trigger paragraph execution by calling **`z.runParagraph()`** funct
```
<img src="/assets/themes/zeppelin/img/screenshots/z_runParagraph.gif" />
<img src="../assets/themes/zeppelin/img/screenshots/z_runParagraph.gif" />
<br />
### Overriding dynamic form with Angular Object
@ -109,7 +109,7 @@ The idea is to create a custom form using plain HTML/AngularJS code and bind act
Consequently if you use the **Dynamic Form** syntax in a paragraph and there is a bound Angular object having the same name as the _${formName}_, the Angular object will have higher priority and the **Dynamic Form** will not be displayed. Example:
<img src="/assets/themes/zeppelin/img/screenshots/z_angularJs_overriding_dynamic_form.gif" />
<img src="../assets/themes/zeppelin/img/screenshots/z_angularJs_overriding_dynamic_form.gif" />
<br />

View file

@ -34,12 +34,12 @@ To create text input form, use _${formName}_ templates.
for example
<img src="/assets/themes/zeppelin/img/screenshots/form_input.png" />
<img src="../assets/themes/zeppelin/img/screenshots/form_input.png" />
Also you can provide default value, using _${formName=defaultValue}_.
<img src="/assets/themes/zeppelin/img/screenshots/form_input_default.png" />
<img src="../assets/themes/zeppelin/img/screenshots/form_input_default.png" />
#### Select form
@ -48,21 +48,21 @@ To create select form, use _${formName=defaultValue,option1|option2...}_
for example
<img src="/assets/themes/zeppelin/img/screenshots/form_select.png" />
<img src="../assets/themes/zeppelin/img/screenshots/form_select.png" />
Also you can separate option's display name and value, using _${formName=defaultValue,option1(DisplayName)|option2(DisplayName)...}_
<img src="/assets/themes/zeppelin/img/screenshots/form_select_displayname.png" />
<img src="../assets/themes/zeppelin/img/screenshots/form_select_displayname.png" />
#### Checkbox form
For multi-selection, you can create a checkbox form using _${checkbox:formName=defaultValue1|defaultValue2...,option1|option2...}_. The variable will be substituted by a comma-separated string based on the selected items. For example:
<img src="/assets/themes/zeppelin/img/screenshots/form_checkbox.png">
<img src="../assets/themes/zeppelin/img/screenshots/form_checkbox.png">
Besides, you can specify the delimiter using _${checkbox(delimiter):formName=...}_:
<img src="/assets/themes/zeppelin/img/screenshots/form_checkbox_delimiter.png">
<img src="../assets/themes/zeppelin/img/screenshots/form_checkbox_delimiter.png">
### Creates Programmatically
@ -89,7 +89,7 @@ print("Hello "+z.input("name"))
</div>
</div>
<img src="/assets/themes/zeppelin/img/screenshots/form_input_prog.png" />
<img src="../assets/themes/zeppelin/img/screenshots/form_input_prog.png" />
####Text input form with default value
<div class="codetabs">
@ -110,7 +110,7 @@ print("Hello "+z.input("name", "sun"))
</div>
</div>
<img src="/assets/themes/zeppelin/img/screenshots/form_input_default_prog.png" />
<img src="../assets/themes/zeppelin/img/screenshots/form_input_default_prog.png" />
####Select form
<div class="codetabs">
@ -143,7 +143,7 @@ print("Hello "+z.select("day", [("1","mon"),
</div>
</div>
<img src="/assets/themes/zeppelin/img/screenshots/form_select_prog.png" />
<img src="../assets/themes/zeppelin/img/screenshots/form_select_prog.png" />
#### Checkbox form
<div class="codetabs">
@ -166,4 +166,4 @@ print("Hello "+ " and ".join(z.checkbox("fruit", options, ["apple"])))
</div>
</div>
<img src="/assets/themes/zeppelin/img/screenshots/form_checkbox_prog.png" />
<img src="../assets/themes/zeppelin/img/screenshots/form_checkbox_prog.png" />

View file

@ -48,7 +48,7 @@ The `Notebook` menu proposes almost the same features as the note management sec
2. Filter node by name
3. Create a new note
<img src="/assets/themes/zeppelin/img/ui-img/notebook_menu.png" />
<img src="../assets/themes/zeppelin/img/ui-img/notebook_menu.png" />
### 2. Interpreter
@ -57,13 +57,13 @@ In this menu you can:
1. Configure existing **interpreter instance**
2. Add/remove **interpreter instances**
<img src="/assets/themes/zeppelin/img/ui-img/interpreter_menu.png" />
<img src="../assets/themes/zeppelin/img/ui-img/interpreter_menu.png" />
### 3. Configuration
This menu displays all the Zeppelin configuration that are set in the config file `$ZEPPELIN_HOME/conf/zeppelin-site.xml`
<img src="/assets/themes/zeppelin/img/ui-img/configuration_menu.png" />
<img src="../assets/themes/zeppelin/img/ui-img/configuration_menu.png" />
<br />
@ -71,13 +71,13 @@ This menu displays all the Zeppelin configuration that are set in the config fil
Each Zeppelin note is composed of 1 .. N paragraphs. The note can be viewed as a paragraph container.
<img src="/assets/themes/zeppelin/img/ui-img/note_paragraph_layout.png" />
<img src="../assets/themes/zeppelin/img/ui-img/note_paragraph_layout.png" />
### Paragraph
Each paragraph consists of 2 sections: `code section` where you put your source code and `result section` where you can see the result of the code execution.
<img src="/assets/themes/zeppelin/img/ui-img/paragraph_layout.png" />
<img src="../assets/themes/zeppelin/img/ui-img/paragraph_layout.png" />
On the top-right corner of each paragraph there are some commands to:
@ -88,7 +88,7 @@ On the top-right corner of each paragraph there are some commands to:
To configure the paragraph, just click on the gear icon:
<img src="/assets/themes/zeppelin/img/ui-img/paragraph_configuration_dialog.png" />
<img src="../assets/themes/zeppelin/img/ui-img/paragraph_configuration_dialog.png" />
From this dialog, you can (in descending order):
@ -108,7 +108,7 @@ From this dialog, you can (in descending order):
At the top of the note, you can find a toolbar which exposes command buttons as well as configuration, security and display options
<img src="/assets/themes/zeppelin/img/ui-img/note_toolbar.png" />
<img src="../assets/themes/zeppelin/img/ui-img/note_toolbar.png" />
On the far right is displayed the note name, just click on it to reveal the input form and update it
@ -124,7 +124,7 @@ In the middle of the toolbar you can find the command buttons:
* delete the note
* schedule the execution of **all paragraph** using a CRON syntax
<img src="/assets/themes/zeppelin/img/ui-img/note_commands.png" />
<img src="../assets/themes/zeppelin/img/ui-img/note_commands.png" />
On the right of the note tool bar you can find configuration icons:
@ -133,7 +133,7 @@ On the right of the note tool bar you can find configuration icons:
* configure the note permissions
* switch the node display mode between `default`, `simple` and `report`
<img src="/assets/themes/zeppelin/img/ui-img/note_configuration.png" />
<img src="../assets/themes/zeppelin/img/ui-img/note_configuration.png" />

View file

@ -132,6 +132,10 @@ The text of each license is also included at licenses/LICENSE-[project]-[version
(The MIT License) lodash v3.9.3 (https://lodash.com/) - https://github.com/lodash/lodash/blob/3.9.3/LICENSE.txt
(The MIT License) angular-filter v0.5.4 (https://github.com/a8m/angular-filter) - https://github.com/a8m/angular-filter/blob/v0.5.4/license.md
(The MIT License) ngToast v1.5.5 (http://tamerayd.in/ngToast/) - http://tameraydin.mit-license.org/
(The MIT License) Handsontable v0.24.2 (https://github.com/handsontable/handsontable) - https://github.com/handsontable/handsontable/blob/master/LICENSE
(The MIT License) Zeroclipboard v2.2.0 (https://github.com/zeroclipboard/zeroclipboard) - https://github.com/zeroclipboard/zeroclipboard/blob/v2.2.0/LICENSE
(The MIT License) Moment v2.9.0 (https://github.com/moment/moment) - https://github.com/moment/moment/blob/2.9.0/LICENSE
(The MIT License) Pikaday v1.3.2 (https://github.com/dbushell/Pikaday) - https://github.com/dbushell/Pikaday/blob/1.3.2/LICENSE
(The MIT License) slf4j v1.7.10 (org.slf4j:slf4j-api:jar:1.7.10 - http://www.slf4j.org) - http://www.slf4j.org/license.html
(The MIT License) slf4j-log4j12 v1.7.10 (org.slf4j:slf4j-log4j12:jar:1.7.10 - http://www.slf4j.org) - http://www.slf4j.org/license.html
(The MIT License) bcprov-jdk15on v1.51 (org.bouncycastle:bcprov-jdk15on:jar:1.51 - http://www.bouncycastle.org/java.html) - http://www.bouncycastle.org/licence.html

View file

@ -167,9 +167,8 @@ public class SparkParagraphIT extends AbstractZeppelinIT {
WebElement paragraph1Result = driver.findElement(By.xpath(
getParagraphXPath(1) + "//div[@class=\"tableDisplay\"]"));
collector.checkThat("Paragraph from SparkParagraphIT of testSqlSpark result: ",
paragraph1Result.getText().toString(), CoreMatchers.equalTo("age job marital education balance\n" +
"30 unemployed married primary 1,787")
);
paragraph1Result.getText().toString(), CoreMatchers.equalTo("age\njob\nmarital\neducation\nbalance\n30" +
" unemployed married primary 1,787\nage\njob\nmarital\neducation\nbalance"));
} catch (Exception e) {
handleException("Exception in SparkParagraphIT while testSqlSpark", e);
}

View file

@ -31,6 +31,7 @@
"nv": false,
"ace": false,
"d3": false,
"BootstrapDialog": false
"BootstrapDialog": false,
"Handsontable": false
}
}

View file

@ -30,9 +30,7 @@
"ngtoast": "~2.0.0",
"ng-focus-if": "~1.0.2",
"bootstrap3-dialog": "bootstrap-dialog#~1.34.7",
"floatThead": "~1.3.2",
"datatables.net-bs": "~1.10.11",
"datatables.net-buttons-bs": "~1.1.2"
"handsontable": "~0.24.2"
},
"devDependencies": {
"angular-mocks": "1.5.0"

View file

@ -969,7 +969,8 @@ angular.module('zeppelinWebApp')
return '';
}
var user = 'anonymous';
if (pdata.authenticationInfo !== null && pdata.authenticationInfo.user !== null) {
var authInfo = pdata.authenticationInfo;
if (authInfo && authInfo.user) {
user = pdata.authenticationInfo.user;
}
var dateUpdated = (pdata.dateUpdated === null) ? 'unknown' : pdata.dateUpdated;
@ -1218,110 +1219,42 @@ angular.module('zeppelinWebApp')
};
var setTable = function(type, data, refresh) {
var getTableContentFormat = function(d) {
if (isNaN(d)) {
if (d.length>'%html'.length && '%html ' === d.substring(0, '%html '.length)) {
return 'html';
} else {
return '';
}
} else {
return '';
}
};
var formatTableContent = function(d) {
if (isNaN(d)) {
var f = getTableContentFormat(d);
if (f !== '') {
return d.substring(f.length+2);
} else {
return d;
}
} else {
var dStr = d.toString();
var splitted = dStr.split('.');
var formatted = splitted[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
if (splitted.length>1) {
formatted+= '.'+splitted[1];
}
return formatted;
}
};
var renderTable = function() {
var html = '';
html += '<table class="table table-hover table-condensed">';
html += ' <thead>';
html += ' <tr style="background-color: #F6F6F6; font-weight: bold;">';
for (var titleIndex in $scope.paragraph.result.columnNames) {
html += '<th>'+$scope.paragraph.result.columnNames[titleIndex].name+'</th>';
}
html += ' </tr>';
html += ' </thead>';
html += ' <tbody>';
for (var r in $scope.paragraph.result.msgTable) {
var row = $scope.paragraph.result.msgTable[r];
html += ' <tr>';
for (var index in row) {
var v = row[index].value;
if (getTableContentFormat(v) !== 'html') {
v = v.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
return '&#'+i.charCodeAt(0)+';';
});
}
html += ' <td>'+formatTableContent(v)+'</td>';
var height = $scope.paragraph.config.graph.height;
angular.element('#p' + $scope.paragraph.id + '_table').css('height', height);
var resultRows = $scope.paragraph.result.rows;
var columnNames = _.pluck($scope.paragraph.result.columnNames, 'name');
var container = document.getElementById('p' + $scope.paragraph.id + '_table');
var handsontable = new Handsontable(container, {
data: resultRows,
colHeaders: columnNames,
rowHeaders: false,
stretchH: 'all',
sortIndicator: true,
columnSorting: true,
contextMenu: false,
manualColumnResize: true,
manualRowResize: true,
editor: false,
fillHandle: false,
disableVisualSelection: true,
cells: function (row, col, prop) {
var cellProperties = {};
cellProperties.renderer = function(instance, td, row, col, prop, value, cellProperties) {
Handsontable.NumericCell.renderer.apply(this, arguments);
if (!isNaN(value)) {
cellProperties.type = 'numeric';
cellProperties.format = '0,0';
cellProperties.editor = false;
td.style.textAlign = 'left';
} else if (value.length > '%html'.length && '%html ' === value.substring(0, '%html '.length)) {
td.innerHTML = value.substring('%html'.length);
}
};
return cellProperties;
}
html += ' </tr>';
}
html += ' </tbody>';
html += '</table>';
var tableDomEl = angular.element('#p' + $scope.paragraph.id + '_table');
tableDomEl.html(html);
var oTable = tableDomEl.children(1).DataTable({
paging: false,
info: false,
autoWidth: false,
lengthChange: false,
searching: false,
dom: '<>'
});
if ($scope.paragraph.result.msgTable.length > 10000) {
tableDomEl.css({
'overflow': 'scroll',
'height': $scope.paragraph.config.graph.height
});
} else {
var dataTable = angular.element('#p' + $scope.paragraph.id + '_table .table');
dataTable.floatThead({
scrollContainer: function(dataTable) {
return tableDomEl;
}
});
dataTable.on('remove', function () {
dataTable.floatThead('destroy');
});
tableDomEl.css({
'position': 'relative',
'height': '100%'
});
tableDomEl.perfectScrollbar('destroy')
.perfectScrollbar({minScrollbarLength: 20});
angular.element('.ps-scrollbar-y-rail').css('z-index', '1002');
// set table height
var psHeight = $scope.paragraph.config.graph.height;
tableDomEl.css('height', psHeight);
tableDomEl.perfectScrollbar('update');
}
};
var retryRenderer = function() {

View file

@ -396,6 +396,29 @@ table.dataTable.table-condensed .sorting_desc:after {
background: none;
}
/*
Handsontable
*/
.handsontable th {
font-weight: bold;
}
.handsontable th, .handsontable td {
border-right: 0px;
border-left: 0px !important;
padding: 4px;
}
.handsontable tr:first-child th {
text-align: left;
border-top: 0px;
padding: 4px 0px 0px 0px;
border-left: 0px;
border-right: 0px;
border-bottom: 2px solid #CCC;
}
/*
Pivot CSS
*/

View file

@ -44,8 +44,8 @@ limitations under the License.
<link rel="stylesheet" href="bower_components/highlightjs/styles/github.css" />
<link rel="stylesheet" href="bower_components/ngtoast/dist/ngToast.css" />
<link rel="stylesheet" href="bower_components/bootstrap3-dialog/dist/css/bootstrap-dialog.min.css" />
<link rel="stylesheet" href="bower_components/datatables.net-bs/css/dataTables.bootstrap.css" />
<link rel="stylesheet" href="bower_components/datatables.net-buttons-bs/css/buttons.bootstrap.css" />
<link rel="stylesheet" href="bower_components/pikaday/css/pikaday.css" />
<link rel="stylesheet" href="bower_components/handsontable/dist/handsontable.css" />
<!-- endbower -->
<link rel="stylesheet" href="bower_components/jquery-ui/themes/base/all.css" />
<!-- endbuild -->
@ -132,16 +132,10 @@ limitations under the License.
<script src="bower_components/ngtoast/dist/ngToast.js"></script>
<script src="bower_components/ng-focus-if/focusIf.js"></script>
<script src="bower_components/bootstrap3-dialog/dist/js/bootstrap-dialog.min.js"></script>
<script src="bower_components/floatThead/dist/jquery.floatThead.js"></script>
<script src="bower_components/floatThead/dist/jquery.floatThead.min.js"></script>
<script src="bower_components/datatables.net/js/jquery.dataTables.js"></script>
<script src="bower_components/datatables.net-bs/js/dataTables.bootstrap.js"></script>
<script src="bower_components/datatables.net-buttons/js/dataTables.buttons.js"></script>
<script src="bower_components/datatables.net-buttons/js/buttons.colVis.js"></script>
<script src="bower_components/datatables.net-buttons/js/buttons.flash.js"></script>
<script src="bower_components/datatables.net-buttons/js/buttons.html5.js"></script>
<script src="bower_components/datatables.net-buttons/js/buttons.print.js"></script>
<script src="bower_components/datatables.net-buttons-bs/js/buttons.bootstrap.js"></script>
<script src="bower_components/zeroclipboard/dist/ZeroClipboard.js"></script>
<script src="bower_components/moment/moment.js"></script>
<script src="bower_components/pikaday/pikaday.js"></script>
<script src="bower_components/handsontable/dist/handsontable.js"></script>
<!-- endbower -->
<!-- endbuild -->
<!-- build:js({.tmp,src}) scripts/scripts.js -->

View file

@ -59,16 +59,10 @@ module.exports = function(config) {
'bower_components/ngtoast/dist/ngToast.js',
'bower_components/ng-focus-if/focusIf.js',
'bower_components/bootstrap3-dialog/dist/js/bootstrap-dialog.min.js',
'bower_components/floatThead/dist/jquery.floatThead.js',
'bower_components/floatThead/dist/jquery.floatThead.min.js',
'bower_components/datatables.net/js/jquery.dataTables.js',
'bower_components/datatables.net-bs/js/dataTables.bootstrap.js',
'bower_components/datatables.net-buttons/js/dataTables.buttons.js',
'bower_components/datatables.net-buttons/js/buttons.colVis.js',
'bower_components/datatables.net-buttons/js/buttons.flash.js',
'bower_components/datatables.net-buttons/js/buttons.html5.js',
'bower_components/datatables.net-buttons/js/buttons.print.js',
'bower_components/datatables.net-buttons-bs/js/buttons.bootstrap.js',
'bower_components/zeroclipboard/dist/ZeroClipboard.js',
'bower_components/moment/moment.js',
'bower_components/pikaday/pikaday.js',
'bower_components/handsontable/dist/handsontable.js',
'bower_components/angular-mocks/angular-mocks.js',
// endbower
'src/app/app.js',