Repository: zeppelin
Updated Branches:
  refs/heads/master 6f8b29f5f -> 4f95555ed


ZEPPELIN-3072: Zeppelin UI becomes slow/unresponsive if there are too many 
notebooks

Zeppelin UI becomes slow/unresponsive if there are too many notebooks

Have attached a notebook directory in 
[JIRA](https://issues.apache.org/jira/secure/attachment/12898650/notebook.zip) 
with 500+ notebooks, now with these notebooks, every time user goes to homepage 
Zeppelin UI becomes unresponsive for few seconds.

[Bug Fix | Improvement]

* [x] - Fix search box
* [x] - Order of notebook

* [ZEPPELIN-3072](https://issues.apache.org/jira/browse/ZEPPELIN-3072)

 Create 500+ notebook, or import it from 
[JIRA](https://issues.apache.org/jira/secure/attachment/12898650/notebook.zip), 
now observe UI it becomes slow/laggy while homepage is rendering.

Before:
![before](https://user-images.githubusercontent.com/674497/33070354-c36acdfa-cedd-11e7-81f9-ff0b526622f3.gif)

After:
![after](https://user-images.githubusercontent.com/674497/33070353-c3317988-cedd-11e7-9431-fcf596928c3b.gif)

* Does the licenses files need update? N/A
* Is there breaking changes for older versions? N/A
* Does this needs documentation? N/A

Author: prabhjyotsingh <[email protected]>

Closes #2683 from prabhjyotsingh/ZEPPELIN-3072 and squashes the following 
commits:

06b8ef801 [prabhjyotsingh] add license file
483a3ff77 [prabhjyotsingh] navbar dropdown bug
eb506ba9e [prabhjyotsingh] fix test
00ec295dc [prabhjyotsingh] fix sort and serch
b4cbba891 [prabhjyotsingh] ZEPPELIN-3072: Zeppelin UI becomes slow/unresponsive 
if there are too many notebooks

Change-Id: Ibc157312b726b9704cab088192a39e942d8da43d


Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/4f95555e
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/4f95555e
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/4f95555e

Branch: refs/heads/master
Commit: 4f95555edca35f2576cdfe32c7467c5aad6583f8
Parents: 6f8b29f
Author: prabhjyotsingh <[email protected]>
Authored: Thu Nov 23 14:35:48 2017 +0530
Committer: prabhjyotsingh <[email protected]>
Committed: Fri Nov 24 17:54:09 2017 +0530

----------------------------------------------------------------------
 LICENSE                                         |  1 +
 licenses/LICENSE-ngInfiniteScroll-1.3.4         | 22 +++++++
 zeppelin-web/bower.json                         |  3 +-
 zeppelin-web/karma.conf.js                      |  1 +
 zeppelin-web/src/app/app.js                     |  1 +
 zeppelin-web/src/app/home/home.controller.js    |  5 ++
 zeppelin-web/src/app/home/home.html             | 10 +--
 zeppelin-web/src/app/home/notebook.html         |  8 +--
 .../array-ordering/array-ordering.service.js    |  4 +-
 .../expand-collapse.directive.js                |  6 +-
 .../navbar/navbar-note-list-elem.html           | 16 ++---
 .../src/components/navbar/navbar.controller.js  |  5 ++
 zeppelin-web/src/components/navbar/navbar.html  |  8 +--
 .../components/note-list/note-list.factory.js   |  3 +-
 .../note-list/note-list.factory.test.js         | 64 ++++++++++----------
 zeppelin-web/src/index.html                     |  1 +
 16 files changed, 98 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index 142bd49..c1f6f7e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -235,6 +235,7 @@ The text of each license is also included at 
licenses/LICENSE-[project]-[version
     (The MIT License) Simple line icons v1.0.0 
(http://thesabbir.github.io/simple-line-icons/) - 
https://github.com/thesabbir/simple-line-icons/tree/1.0.0
     (The MIT License) jekyll-bootstrap 0.3.0 
(https://github.com/plusjade/jekyll-bootstrap) - 
https://github.com/plusjade/jekyll-bootstrap
     (The MIT License) jekyll 1.3.0 (http://jekyllrb.com/) - 
https://github.com/jekyll/jekyll/blob/v1.3.0/LICENSE
+    (The MIT License) ngInfiniteScroll 1.3.4 
(https://github.com/sroze/ngInfiniteScroll) - 
https://github.com/sroze/ngInfiniteScroll/blob/master/LICENSE
 
 ========================================================================
 MIT-style licenses

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/licenses/LICENSE-ngInfiniteScroll-1.3.4
----------------------------------------------------------------------
diff --git a/licenses/LICENSE-ngInfiniteScroll-1.3.4 
b/licenses/LICENSE-ngInfiniteScroll-1.3.4
new file mode 100644
index 0000000..44ae2bf
--- /dev/null
+++ b/licenses/LICENSE-ngInfiniteScroll-1.3.4
@@ -0,0 +1,22 @@
+Copyright (c) 2012 Michelle Tilley
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/bower.json
----------------------------------------------------------------------
diff --git a/zeppelin-web/bower.json b/zeppelin-web/bower.json
index 2b5135f..3de9f56 100644
--- a/zeppelin-web/bower.json
+++ b/zeppelin-web/bower.json
@@ -33,7 +33,8 @@
     "select2": "^4.0.3",
     "MathJax": "2.7.0",
     "ngclipboard": "^1.1.1",
-    "jsdiff": "3.3.0"
+    "jsdiff": "3.3.0",
+    "ngInfiniteScroll": "^1.3.4"
   },
   "devDependencies": {
     "angular-mocks": "1.5.7"

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/karma.conf.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/karma.conf.js b/zeppelin-web/karma.conf.js
index 8a03bec..3e573a9 100644
--- a/zeppelin-web/karma.conf.js
+++ b/zeppelin-web/karma.conf.js
@@ -87,6 +87,7 @@ module.exports = function(config) {
       'bower_components/clipboard/dist/clipboard.js',
       'bower_components/ngclipboard/dist/ngclipboard.js',
       'bower_components/jsdiff/diff.js',
+      'bower_components/ngInfiniteScroll/build/ng-infinite-scroll.js',
       'bower_components/angular-mocks/angular-mocks.js',
       // endbower
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/app/app.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/app.js b/zeppelin-web/src/app/app.js
index d46d026..5a4c016 100644
--- a/zeppelin-web/src/app/app.js
+++ b/zeppelin-web/src/app/app.js
@@ -44,6 +44,7 @@ const requiredModules = [
   'ngResource',
   'ngclipboard',
   'angularViewportWatch',
+  'infinite-scroll',
   'ui.grid',
   'ui.grid.exporter',
   'ui.grid.edit', 'ui.grid.rowEdit',

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/app/home/home.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/home/home.controller.js 
b/zeppelin-web/src/app/home/home.controller.js
index 2cf8439..d2823dd 100644
--- a/zeppelin-web/src/app/home/home.controller.js
+++ b/zeppelin-web/src/app/home/home.controller.js
@@ -24,6 +24,7 @@ function HomeCtrl ($scope, noteListFactory, websocketMsgSrv, 
$rootScope, arrayOr
   vm.websocketMsgSrv = websocketMsgSrv
   vm.arrayOrderingSrv = arrayOrderingSrv
   vm.noteActionService = noteActionService
+  vm.numberOfNotesDisplayed = window.innerHeight / 20
 
   vm.notebookHome = false
   vm.noteCustomHome = true
@@ -85,6 +86,10 @@ function HomeCtrl ($scope, noteListFactory, websocketMsgSrv, 
$rootScope, arrayOr
     }
   })
 
+  $scope.loadMoreNotes = function () {
+    vm.numberOfNotesDisplayed += 10
+  }
+
   $scope.renameNote = function (nodeId, nodePath) {
     vm.noteActionService.renameNote(nodeId, nodePath)
   }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/app/home/home.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/home/home.html 
b/zeppelin-web/src/app/home/home.html
index 1ab9718..0285754 100644
--- a/zeppelin-web/src/app/home/home.html
+++ b/zeppelin-web/src/app/home/home.html
@@ -40,16 +40,16 @@ limitations under the License.
               <i style="font-size: 15px;" class="icon-notebook"></i> Create 
new note</a></h5>
             <ul id="notebook-names">
               <li class="filter-names" 
ng-include="'components/note-name-filter/note-name-filter.html'"></li>
-              <li ng-repeat="note in home.notes.list | filter:query.q | 
orderBy:node:false:home.arrayOrderingSrv.noteComparator track by $index">
+              <li ng-repeat="note in home.notes.list | filter:query.q track by 
$index">
                 <i style="font-size: 10px;" class="icon-doc"></i>
                 <a style="text-decoration: none;" 
href="#/notebook/{{note.id}}">{{noteName(note)}}</a>
               </li>
-              <div ng-if="!query.q || query.q === ''">
-                <li ng-repeat="node in home.notes.root.children | 
orderBy:node:false:home.arrayOrderingSrv.noteComparator track by $index"
+              <div ng-if="!query.q || query.q === ''" 
infinite-scroll="loadMoreNotes()">
+                <li ng-repeat="node in home.notes.root.children | 
limitTo:home.numberOfNotesDisplayed track by $index"
                     ng-include src="'app/home/notebook-template.html'" 
ng-class="note_folder_renderer"></li>
               </div>
-              <div ng-if="query.q">
-                <li ng-repeat="node in home.notes.flatList| filter:query.q | 
orderBy:home.arrayOrderingSrv.noteFlatListOrdering track by $index"
+              <div ng-if="query.q" infinite-scroll="loadMoreNotes()">
+                <li ng-repeat="node in home.notes.flatList | filter:query.q | 
orderBy:home.arrayOrderingSrv.noteFlatListOrdering | 
limitTo:home.numberOfNotesDisplayed track by $index"
                     ng-include src="'app/home/notebook-template.html'" 
ng-class="note_folder_renderer"></li>
              </div>
             </ul>

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/app/home/notebook.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/home/notebook.html 
b/zeppelin-web/src/app/home/notebook.html
index a6f2416..ff1eb75 100644
--- a/zeppelin-web/src/app/home/notebook.html
+++ b/zeppelin-web/src/app/home/notebook.html
@@ -27,12 +27,12 @@ limitations under the License.
            <i style="font-size: 15px;" class="icon-notebook"></i> Create new 
note</a></h5>
        <ul id="notebook-names">
          <li class="filter-names" 
ng-include="'components/note-name-filter/note-name-filter.html'"></li>
-         <div ng-if="!query.q || query.q === ''">
-           <li ng-repeat="node in home.notes.root.children | 
orderBy:node:false:home.arrayOrderingSrv.noteComparator track by $index"
+         <div ng-if="!query.q || query.q === ''" 
infinite-scroll="loadMoreNotes()">
+           <li ng-repeat="node in home.notes.root.children | 
limitTo:home.numberOfNotesDisplayed track by $index"
                ng-include src="'app/home/notebook-template.html'" 
ng-class="note_folder_renderer"></li>
          </div>
-         <div ng-if="query.q">
-           <li ng-repeat="node in home.notes.flatList | filter:query.q | 
orderBy:home.arrayOrderingSrv.noteFlatListOrdering track by $index"
+         <div ng-if="query.q" infinite-scroll="loadMoreNotes()">
+           <li ng-repeat="node in home.notes.flatList | filter:query.q | 
orderBy:home.arrayOrderingSrv.noteFlatListOrdering | 
limitTo:home.numberOfNotesDisplayed track by $index"
                ng-include src="'app/home/notebook-template.html'" 
ng-class="note_folder_renderer"></li>
          </div>
        </ul>

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/components/array-ordering/array-ordering.service.js
----------------------------------------------------------------------
diff --git 
a/zeppelin-web/src/components/array-ordering/array-ordering.service.js 
b/zeppelin-web/src/components/array-ordering/array-ordering.service.js
index 850a5da..6fa1ad9 100644
--- a/zeppelin-web/src/components/array-ordering/array-ordering.service.js
+++ b/zeppelin-web/src/components/array-ordering/array-ordering.service.js
@@ -35,8 +35,8 @@ function ArrayOrderingService(TRASH_FOLDER_ID) {
   }
 
   this.noteComparator = function (v1, v2) {
-    let note1 = v1.value
-    let note2 = v2.value
+    let note1 = v1.value || v1
+    let note2 = v2.value || v2
 
     if (note1.id === TRASH_FOLDER_ID) {
       return 1

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js
----------------------------------------------------------------------
diff --git 
a/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js
 
b/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js
index 95e0681..e4280e8 100644
--- 
a/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js
+++ 
b/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js
@@ -21,11 +21,11 @@ function expandCollapseDirective() {
     restrict: 'EA',
     link: function (scope, element, attrs) {
       angular.element(element).click(function (event) {
-        if (angular.element(element).find('.expandable:visible').length > 1) {
-          angular.element(element).find('.expandable:visible').slideUp('slow')
+        if (angular.element(element).next('.expandable:visible').length > 1) {
+          angular.element(element).next('.expandable:visible').slideUp('slow')
           
angular.element(element).find('i.fa-folder-open').toggleClass('fa-folder 
fa-folder-open')
         } else {
-          
angular.element(element).find('.expandable').first().slideToggle('200', 
function () {
+          
angular.element(element).next('.expandable').first().slideToggle('200', 
function () {
             // do not toggle trash folder
             if (angular.element(element).find('.fa-trash-o').length === 0) {
               
angular.element(element).find('i').first().toggleClass('fa-folder 
fa-folder-open')

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/components/navbar/navbar-note-list-elem.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/navbar/navbar-note-list-elem.html 
b/zeppelin-web/src/components/navbar/navbar-note-list-elem.html
index ad1f771..911f1f1 100644
--- a/zeppelin-web/src/components/navbar/navbar-note-list-elem.html
+++ b/zeppelin-web/src/components/navbar/navbar-note-list-elem.html
@@ -38,13 +38,13 @@ limitations under the License.
           </div>
         </a>
       </div>
-      <div class="expandable" style="color: black;">
-        <ul>
-          <li ng-repeat="node in node.children | 
orderBy:node:false:navbar.arrayOrderingSrv.noteComparator track by $index"
-              ng-class="{'active' : navbar.isActive(node.id)}"
-              ng-include="'components/navbar/navbar-note-list-elem.html'">
-          </li>
-        </ul>
-      </div>
   </expand-collapse>
+  <div class="expandable" style="color: black;">
+    <ul>
+      <li ng-repeat="node in node.children | 
orderBy:node:false:navbar.arrayOrderingSrv.noteComparator track by $index"
+          ng-class="{'active' : navbar.isActive(node.id)}"
+          ng-include="'components/navbar/navbar-note-list-elem.html'">
+      </li>
+    </ul>
+  </div>
 </li>

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/components/navbar/navbar.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/navbar/navbar.controller.js 
b/zeppelin-web/src/components/navbar/navbar.controller.js
index 0ac2f18..e92813b 100644
--- a/zeppelin-web/src/components/navbar/navbar.controller.js
+++ b/zeppelin-web/src/components/navbar/navbar.controller.js
@@ -30,6 +30,7 @@ function NavCtrl ($scope, $rootScope, $http, $routeParams, 
$location,
   vm.showLoginWindow = showLoginWindow
   vm.TRASH_FOLDER_ID = TRASH_FOLDER_ID
   vm.isFilterNote = isFilterNote
+  vm.numberOfNotesDisplayed = 10
 
   $scope.query = {q: ''}
 
@@ -153,6 +154,10 @@ function NavCtrl ($scope, $rootScope, $http, $routeParams, 
$location,
     })
   }
 
+  $scope.loadMoreNotes = function () {
+    vm.numberOfNotesDisplayed += 10
+  }
+
   $scope.calculateTooltipPlacement = function (note) {
     if (note !== undefined && note.name !== undefined) {
       let length = note.name.length

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/components/navbar/navbar.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/navbar/navbar.html 
b/zeppelin-web/src/components/navbar/navbar.html
index 597ed51..59d65c9 100644
--- a/zeppelin-web/src/components/navbar/navbar.html
+++ b/zeppelin-web/src/components/navbar/navbar.html
@@ -46,13 +46,13 @@ limitations under the License.
             <li class="divider hidden-xs"></li>
             <div id="notebook-list" class="scrollbar-container" 
ng-if="isDrawNavbarNoteList">
               <li class="filter-names" 
ng-include="'components/note-name-filter/note-name-filter.html'"></li>
-              <div ng-if="!query.q || query.q === ''">
-              <li ng-repeat="node in navbar.notes.root.children | 
orderBy:node:false:navbar.arrayOrderingSrv.noteComparator track by node.id"
+              <div ng-if="!query.q || query.q === ''" 
infinite-scroll="loadMoreNotes()">
+              <li ng-repeat="node in navbar.notes.root.children | 
limitTo:navbar.numberOfNotesDisplayed track by node.id"
                   ng-class="{'active' : navbar.isActive(node.id)}" 
ng-include="'components/navbar/navbar-note-list-elem.html'">
               </li>
             </div>
-            <div ng-if="query.q">
-              <li ng-repeat="node in navbar.notes.flatList | filter : query.q 
| orderBy:navbar.arrayOrderingSrv.noteFlatListOrdering track by node.id"
+            <div ng-if="query.q" infinite-scroll="myPagingFunction()">
+              <li ng-repeat="node in navbar.notes.flatList | filter : query.q 
| orderBy:navbar.arrayOrderingSrv.noteFlatListOrdering | 
limitTo:navbar.numberOfNotesDisplayed track by node.id"
                   ng-class="{'active' : navbar.isActive(node.id)}" 
ng-include="'components/navbar/navbar-note-list-elem.html'">
               </li>
             </div>

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/components/note-list/note-list.factory.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-list/note-list.factory.js 
b/zeppelin-web/src/components/note-list/note-list.factory.js
index 21abbc0..5e2c513 100644
--- a/zeppelin-web/src/components/note-list/note-list.factory.js
+++ b/zeppelin-web/src/components/note-list/note-list.factory.js
@@ -14,7 +14,7 @@
 
 angular.module('zeppelinWebApp').factory('noteListFactory', NoteListFactory)
 
-function NoteListFactory(TRASH_FOLDER_ID) {
+function NoteListFactory(arrayOrderingSrv, TRASH_FOLDER_ID) {
   'ngInject'
 
   const notes = {
@@ -42,6 +42,7 @@ function NoteListFactory(TRASH_FOLDER_ID) {
 
         return root
       }, notes.root)
+      notes.root.children.sort(arrayOrderingSrv.noteComparator)
     }
   }
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/components/note-list/note-list.factory.test.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-list/note-list.factory.test.js 
b/zeppelin-web/src/components/note-list/note-list.factory.test.js
index 58d5d42..c16504c 100644
--- a/zeppelin-web/src/components/note-list/note-list.factory.test.js
+++ b/zeppelin-web/src/components/note-list/note-list.factory.test.js
@@ -38,38 +38,38 @@ describe('Factory: NoteList', function () {
 
     let folderList = noteList.root.children
     expect(folderList.length).toBe(5)
-    expect(folderList[0].name).toBe('A')
-    expect(folderList[0].id).toBe('000001')
-    expect(folderList[1].name).toBe('B')
+    expect(folderList[3].name).toBe('A')
+    expect(folderList[3].id).toBe('000001')
+    expect(folderList[4].name).toBe('B')
     expect(folderList[2].name).toBe('000003')
-    expect(folderList[3].name).toBe('C')
-    expect(folderList[3].id).toBe('C')
-    expect(folderList[3].children.length).toBe(3)
-    expect(folderList[3].children[0].name).toBe('CA')
-    expect(folderList[3].children[0].id).toBe('000004')
-    expect(folderList[3].children[0].children).toBeUndefined()
-    expect(folderList[3].children[1].name).toBe('CB')
-    expect(folderList[3].children[1].id).toBe('000005')
-    expect(folderList[3].children[1].children).toBeUndefined()
-    expect(folderList[3].children[2].name).toBe('CB')
-    expect(folderList[3].children[2].id).toBe('C/CB')
-    expect(folderList[3].children[2].children.length).toBe(3)
-    expect(folderList[3].children[2].children[0].name).toBe('CBA')
-    expect(folderList[3].children[2].children[0].id).toBe('000006')
-    expect(folderList[3].children[2].children[0].children).toBeUndefined()
-    expect(folderList[3].children[2].children[1].name).toBe('CBA')
-    expect(folderList[3].children[2].children[1].id).toBe('000007')
-    expect(folderList[3].children[2].children[1].children).toBeUndefined()
-    expect(folderList[3].children[2].children[2].name).toBe('CBB')
-    expect(folderList[3].children[2].children[2].id).toBe('000008')
-    expect(folderList[3].children[2].children[2].children).toBeUndefined()
-    expect(folderList[4].name).toBe('D')
-    expect(folderList[4].id).toBe('D')
-    expect(folderList[4].children.length).toBe(1)
-    expect(folderList[4].children[0].name).toBe('D[A')
-    expect(folderList[4].children[0].id).toBe('D/D[A')
-    expect(folderList[4].children[0].children[0].name).toBe('DA]B')
-    expect(folderList[4].children[0].children[0].id).toBe('000009')
-    expect(folderList[4].children[0].children[0].children).toBeUndefined()
+    expect(folderList[0].name).toBe('C')
+    expect(folderList[0].id).toBe('C')
+    expect(folderList[0].children.length).toBe(3)
+    expect(folderList[0].children[0].name).toBe('CA')
+    expect(folderList[0].children[0].id).toBe('000004')
+    expect(folderList[0].children[0].children).toBeUndefined()
+    expect(folderList[0].children[1].name).toBe('CB')
+    expect(folderList[0].children[1].id).toBe('000005')
+    expect(folderList[0].children[1].children).toBeUndefined()
+    expect(folderList[0].children[2].name).toBe('CB')
+    expect(folderList[0].children[2].id).toBe('C/CB')
+    expect(folderList[0].children[2].children.length).toBe(3)
+    expect(folderList[0].children[2].children[0].name).toBe('CBA')
+    expect(folderList[0].children[2].children[0].id).toBe('000006')
+    expect(folderList[0].children[2].children[0].children).toBeUndefined()
+    expect(folderList[0].children[2].children[1].name).toBe('CBA')
+    expect(folderList[0].children[2].children[1].id).toBe('000007')
+    expect(folderList[0].children[2].children[1].children).toBeUndefined()
+    expect(folderList[0].children[2].children[2].name).toBe('CBB')
+    expect(folderList[0].children[2].children[2].id).toBe('000008')
+    expect(folderList[0].children[2].children[2].children).toBeUndefined()
+    expect(folderList[1].name).toBe('D')
+    expect(folderList[1].id).toBe('D')
+    expect(folderList[1].children.length).toBe(1)
+    expect(folderList[1].children[0].name).toBe('D[A')
+    expect(folderList[1].children[0].id).toBe('D/D[A')
+    expect(folderList[1].children[0].children[0].name).toBe('DA]B')
+    expect(folderList[1].children[0].children[0].id).toBe('000009')
+    expect(folderList[1].children[0].children[0].children).toBeUndefined()
   })
 })

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4f95555e/zeppelin-web/src/index.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/index.html b/zeppelin-web/src/index.html
index 9a126f1..15a5085 100644
--- a/zeppelin-web/src/index.html
+++ b/zeppelin-web/src/index.html
@@ -166,6 +166,7 @@ limitations under the License.
     <script src="bower_components/clipboard/dist/clipboard.js"></script>
     <script src="bower_components/ngclipboard/dist/ngclipboard.js"></script>
     <script src="bower_components/jsdiff/diff.js"></script>
+    <script 
src="bower_components/ngInfiniteScroll/build/ng-infinite-scroll.js"></script>
     <!-- endbower -->
     <!-- endbuild -->
   </body>

Reply via email to