Repository: zeppelin
Updated Branches:
  refs/heads/master a47ff95ed -> dcf2c7a2c


[ZEPPELIN-2060] Make dynamic select form turn on or off using checkbox

### What is this PR for?
I added "Auto Run" checkbox for select dynamic form to make user turn on / off 
automatic running after the form value changed.

### What type of PR is it?
Improvement

### Todos
* [x] - update docs after getting feedback

### 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

### Screenshots (if appropriate)
 - "Auto Run" checkbox button will be shown only in select dynamic form's 
dropdown menu
![record1](https://cloud.githubusercontent.com/assets/10060731/23608140/4d3ee016-02ab-11e7-8678-ed21f30a3e0e.gif)

 - _**turn on**_ "Auto Run"-> auto run right after the value changed / _**turn 
off**_ -> need to press `Enter`
![record2](https://cloud.githubusercontent.com/assets/10060731/23608142/4e950ed6-02ab-11e7-9035-fd6c3c40f501.gif)

### Questions:
* Does the licenses files need update? no
* Is there breaking changes for older versions? no
* Does this needs documentation? yes, maybe [this 
part](https://github.com/apache/zeppelin/blob/master/docs/manual/dynamicform.md#select-form)

Author: AhyoungRyu <fbdkdu...@hanmail.net>

Closes #2100 from AhyoungRyu/feature/turnOnOrOffAutoRun and squashes the 
following commits:

4043579 [AhyoungRyu] Add 'setting: {forms: {}}' info to paragraphMock
47dcb5f [AhyoungRyu] Persist 'runOnSelectionChange' under note.json's config 
field
4904f38 [AhyoungRyu] Update dynamicForm docs
66c6c21 [AhyoungRyu] Add test case for behaviour of 'Run on selection change'
8a0ca30 [AhyoungRyu] Change label to 'Run on selection change'
5075711 [AhyoungRyu] Add a space next to checkbox
f2e3259 [AhyoungRyu] 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/dcf2c7a2
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/dcf2c7a2
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/dcf2c7a2

Branch: refs/heads/master
Commit: dcf2c7a2c86eef9411ccdf5d50b9851b89dd98b0
Parents: a47ff95
Author: AhyoungRyu <fbdkdu...@hanmail.net>
Authored: Thu Mar 16 18:12:26 2017 +0900
Committer: ahyoungryu <ahyoung...@apache.org>
Committed: Fri Mar 17 10:00:55 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       |  36 +++++++++++--------
 .../notebook/paragraph/paragraph.controller.js  |  18 +++++++++-
 .../paragraph/paragraph.controller.test.js      |   5 ++-
 7 files changed, 93 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/dcf2c7a2/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/dcf2c7a2/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/dcf2c7a2/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 458b8d4..0507767 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/dcf2c7a2/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 5f9c462..1411725 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
@@ -89,6 +89,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">
@@ -100,15 +113,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/dcf2c7a2/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 65d13b7..7305440 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="runParagraphFromButton(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="runParagraphFromButton(getEditorValue())"
+             ng-change="runParagraphFromButton(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="runParagraphFromButton(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/dcf2c7a2/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 ab47d56..0f752fe 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
@@ -26,6 +26,7 @@ function ParagraphCtrl($scope, $rootScope, $route, $window, 
$routeParams, $locat
   'ngInject';
 
   var ANGULAR_FUNCTION_OBJECT_NAME_PREFIX = '_Z_ANGULAR_FUNC_';
+  $rootScope.keys = Object.keys;
   $scope.parentNote = null;
   $scope.paragraph = {};
   $scope.paragraph.results = {};
@@ -121,14 +122,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 = {};
     }
@@ -377,6 +388,11 @@ function ParagraphCtrl($scope, $rootScope, $route, 
$window, $routeParams, $locat
     $scope.runParagraph(paragraphText, false, false)
   };
 
+  $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/dcf2c7a2/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 1aa4a4a..f8a1f63 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: {

Reply via email to