Repository: zeppelin Updated Branches: refs/heads/branch-0.7 39ce7a2b5 -> e5b19de65
[branch-0.7][ZEPPELIN-2060] Make dynamic select form turn on or off using checkbox ### What is this PR for? This PR is same with #2100 with base branch `branch-0.7`. ### What type of PR is it? Improvement ### What is the Jira issue? [ZEPPELIN-2060](https://issues.apache.org/jira/browse/ZEPPELIN-2060) ### How should this be tested? 1. Apply this patch and run Zeppelin web as dev mode ```bash # under zeppelin-web $ yarn run dev ``` 2. Go to Spark tutorial note and try to change value in select form as below screenshot imgs <img width="349" alt="screen shot 2017-03-14 at 10 52 22 pm" src="https://cloud.githubusercontent.com/assets/10060731/23903934/9382ac6a-0909-11e7-86b6-6a0b904c8202.png"> ### Screenshots (if appropriate) ### Questions: * Does the licenses files need update? no * Is there breaking changes for older versions? no * Does this needs documentation? yes. updated [dynamicform.md](https://github.com/apache/zeppelin/compare/branch-0.7...AhyoungRyu:branch-0.7/turnOnOrOffAutoRun?expand=1#diff-aba7dc68954cf4c48b87deccf1914bfb) Author: AhyoungRyu <[email protected]> Closes #2148 from AhyoungRyu/branch-0.7/turnOnOrOffAutoRun and squashes the following commits: 40a1478 [AhyoungRyu] [ZEPPELIN-2060] Make dynamic select form turn on or off using checkbox Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/e5b19de6 Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/e5b19de6 Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/e5b19de6 Branch: refs/heads/branch-0.7 Commit: e5b19de658ef0efe7506eb358af86058b86b5ea8 Parents: 39ce7a2 Author: AhyoungRyu <[email protected]> Authored: Thu Mar 16 18:12:26 2017 +0900 Committer: Jongyoul Lee <[email protected]> Committed: Sat Mar 18 19:47:31 2017 +0900 ---------------------------------------------------------------------- .../img/screenshots/selectForm-checkbox.png | Bin 0 -> 9377 bytes docs/manual/dynamicform.md | 6 ++- .../integration/ParagraphActionsIT.java | 29 ++++++++++++ .../notebook/paragraph/paragraph-control.html | 19 ++++++-- .../paragraph-parameterizedQueryForm.html | 46 +++++++++++-------- .../notebook/paragraph/paragraph.controller.js | 18 +++++++- .../paragraph/paragraph.controller.test.js | 5 +- 7 files changed, 98 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zeppelin/blob/e5b19de6/docs/assets/themes/zeppelin/img/screenshots/selectForm-checkbox.png ---------------------------------------------------------------------- diff --git a/docs/assets/themes/zeppelin/img/screenshots/selectForm-checkbox.png b/docs/assets/themes/zeppelin/img/screenshots/selectForm-checkbox.png new file mode 100644 index 0000000..47f9fa9 Binary files /dev/null and b/docs/assets/themes/zeppelin/img/screenshots/selectForm-checkbox.png differ http://git-wip-us.apache.org/repos/asf/zeppelin/blob/e5b19de6/docs/manual/dynamicform.md ---------------------------------------------------------------------- diff --git a/docs/manual/dynamicform.md b/docs/manual/dynamicform.md index 12f51a9..b3ef4ed 100644 --- a/docs/manual/dynamicform.md +++ b/docs/manual/dynamicform.md @@ -56,7 +56,11 @@ Also you can separate option's display name and value, using `${formName=default <img src="../assets/themes/zeppelin/img/screenshots/form_select_displayname.png" /> -Hit enter after selecting option to run the paragraph with new value. +The paragraph will be automatically run after you change your selection by default. +But in case you have multiple select forms in one paragraph, you might want to run the paragraph after changing all the selections. +You can control this by unchecking the below **Run on selection change** option in the setting menu. Even if you uncheck this option, still you can run it by pressing `Enter`. + +<img src="../assets/themes/zeppelin/img/screenshots/selectForm-checkbox.png" /> ### Checkbox form http://git-wip-us.apache.org/repos/asf/zeppelin/blob/e5b19de6/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java index feade7f..d5b4609 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java @@ -257,6 +257,35 @@ public class ParagraphActionsIT extends AbstractZeppelinIT { } @Test + public void testRunOnSelectionCheckbox() throws Exception { + if (!endToEndTestEnabled()) { + return; + } + try { + String xpathToCheckbox = getParagraphXPath(1) + "//ul/li/form/input[contains(@ng-checked, 'true')]"; + + createNewNote(); + + waitForParagraph(1, "READY"); + setTextOfParagraph(1, "%md My selection is ${my selection=1,1|2|3}"); + runParagraph(1); + + driver.findElement(By.xpath(getParagraphXPath(1) + "//span[@class='icon-settings']")).click(); + collector.checkThat("'Run on selection change' checkbox will be shown under dropdown menu ", + driver.findElement(By.xpath(getParagraphXPath(1) + "//ul/li/form/input[contains(@ng-click, 'turnOnAutoRun(paragraph)')]")).isDisplayed(), + CoreMatchers.equalTo(true)); + + driver.findElement(By.xpath(xpathToCheckbox)).click(); + collector.checkThat("If 'Run on selection change' checkbox is unchecked, 'paragraph.config.runOnSelectionChange' will be false ", + driver.findElement(By.xpath(getParagraphXPath(1) + "//ul/li/span[contains(@ng-if, 'paragraph.config.runOnSelectionChange == false')]")).isDisplayed(), + CoreMatchers.equalTo(true)); + + } catch (Exception e) { + handleException("Exception in ParagraphActionsIT while testRunOnSelectionButton ", e); + } + } + + @Test public void testClearOutputButton() throws Exception { if (!endToEndTestEnabled()) { return; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/e5b19de6/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html index 644761e..9833f48 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html @@ -55,6 +55,19 @@ limitations under the License. </a> </li> <li role="separator" class="divider"></li> + <li style="padding-top:8px" + ng-if="paragraph.settings.forms[$root.keys(paragraph.settings.forms)].options && + paragraph.settings.forms[$root.keys(paragraph.settings.forms)].type != 'checkbox'"> + <span ng-if="paragraph.config.runOnSelectionChange == true" class="fa fa-toggle-on shortcut-icon" style="padding:3px 8px 8px 20px"></span> + <span ng-if="paragraph.config.runOnSelectionChange == false" class="fa fa-toggle-off shortcut-icon" style="padding:3px 8px 8px 20px"></span>Run on selection change + <form style="display:inline; float:right"> + <input type="checkbox" + style="width:16px; margin-right:20px" + tooltip-placement="top" tooltip="Even if you uncheck this, still can run the paragraph by pressing Enter" + ng-checked="{{paragraph.config.runOnSelectionChange}}" + ng-click="turnOnAutoRun(paragraph)"/> + </form> + </li> <li> <a ng-click="$event.stopPropagation()" class="dropdown"><span class="fa fa-arrows-h shortcut-icon"></span>Width <form style="display:inline; margin-left:5px; float:right"> @@ -66,15 +79,15 @@ limitations under the License. </a> </li> <li> - <a ng-click="moveUp(paragraph)" ng-hide="$first"><span class="icon-arrow-up shortcut-icon"></span>Move Up + <a ng-click="moveUp(paragraph)" ng-hide="$first"><span class="icon-arrow-up shortcut-icon"></span>Move up <span class="shortcut-keys">Ctrl+{{ isMac ? 'Option' : 'Alt'}}+k</span></a> </li> <li> - <a ng-click="moveDown(paragraph)" ng-hide="$last"><span class="icon-arrow-down shortcut-icon"></span>Move Down + <a ng-click="moveDown(paragraph)" ng-hide="$last"><span class="icon-arrow-down shortcut-icon"></span>Move down <span class="shortcut-keys">Ctrl+{{ isMac ? 'Option' : 'Alt'}}+j</span></a> </li> <li> - <a ng-click="insertNew('below')"><span class="icon-plus shortcut-icon"></span>Insert New + <a ng-click="insertNew('below')"><span class="icon-plus shortcut-icon"></span>Insert new <span class="shortcut-keys">Ctrl+{{ isMac ? 'Option' : 'Alt'}}+b</span></a> </li> <li> http://git-wip-us.apache.org/repos/asf/zeppelin/blob/e5b19de6/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html index 117e11c..7ead979 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html @@ -19,33 +19,41 @@ limitations under the License. ng-init="loadForm(formulaire, paragraph.settings.params)"> <label class="control-label input-sm" ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }">{{formulaire.name}}</label> <div> - <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}}" /> - + </div> + <div ng-if="paragraph.config.runOnSelectionChange == true"> <select class="form-control input-sm" - ng-if="paragraph.settings.forms[formulaire.name].options && paragraph.settings.forms[formulaire.name].type != 'checkbox'" - ng-enter="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"> + ng-if="paragraph.settings.forms[formulaire.name].options && paragraph.settings.forms[formulaire.name].type != 'checkbox'" + 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"> </select> - - <div ng-if="paragraph.settings.forms[formulaire.name].type == 'checkbox'"> - <label ng-repeat="option in paragraph.settings.forms[formulaire.name].options" - class="checkbox-item input-sm"> - <input type="checkbox" - ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }" - ng-checked="paragraph.settings.params[formulaire.name].indexOf(option.value) > -1" - ng-click="toggleCheckbox(formulaire, option, false)"/>{{option.displayName||option.value}} - </label> - </div> - + </div> + <div ng-if="paragraph.config.runOnSelectionChange == false"> + <select class="form-control input-sm" + ng-if="paragraph.settings.forms[formulaire.name].options && paragraph.settings.forms[formulaire.name].type != 'checkbox'" + ng-enter="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"> + </select> + </div> + <div ng-if="paragraph.settings.forms[formulaire.name].type == 'checkbox'"> + <label ng-repeat="option in paragraph.settings.forms[formulaire.name].options" + class="checkbox-item input-sm"> + <input type="checkbox" + ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }" + ng-checked="paragraph.settings.params[formulaire.name].indexOf(option.value) > -1" + ng-click="toggleCheckbox(formulaire, option, false)"/> {{option.displayName||option.value}} + </label> </div> </div> </form> http://git-wip-us.apache.org/repos/asf/zeppelin/blob/e5b19de6/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js index 222ab12..b039a47 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js @@ -36,6 +36,7 @@ function ParagraphCtrl($scope, $rootScope, $route, $window, $routeParams, $locat $timeout, $compile, $http, $q, websocketMsgSrv, baseUrlSrv, ngToast, saveAsService, noteVarShareService) { var ANGULAR_FUNCTION_OBJECT_NAME_PREFIX = '_Z_ANGULAR_FUNC_'; + $rootScope.keys = Object.keys; $scope.parentNote = null; $scope.paragraph = null; $scope.originalText = ''; @@ -123,14 +124,24 @@ function ParagraphCtrl($scope, $rootScope, $route, $window, $routeParams, $locat }; var initializeDefault = function(config) { + var forms = $scope.paragraph.settings.forms; + if (!config.colWidth) { config.colWidth = 12; } - + if (config.enabled === undefined) { config.enabled = true; } + if (forms[Object.keys(forms)]) { + if (forms[Object.keys(forms)].options && forms[Object.keys(forms)].type !== 'checkbox') { + if (config.runOnSelectionChange === undefined) { + config.runOnSelectionChange = true; + } + } + } + if (!config.results) { config.results = {}; } @@ -257,6 +268,11 @@ function ParagraphCtrl($scope, $rootScope, $route, $window, $routeParams, $locat } }; + $scope.turnOnAutoRun = function (paragraph) { + paragraph.config.runOnSelectionChange = !paragraph.config.runOnSelectionChange; + commitParagraph(paragraph); + }; + $scope.moveUp = function(paragraph) { $scope.$emit('moveParagraphUp', paragraph); }; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/e5b19de6/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.test.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.test.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.test.js index 4089d2d..20c1f7b 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.test.js +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.test.js @@ -5,7 +5,10 @@ describe('Controller: ParagraphCtrl', function() { var scope; var websocketMsgSrvMock = {}; var paragraphMock = { - config: {} + config: {}, + settings: { + forms: {} + } }; var route = { current: {
