18947: Remove errant uses of runsu.sh.
[arvados.git] / apps / workbench / app / assets / javascripts / models / loader.js
index c1205bc555d795b249c39c8175dd6497f8a25b15..0b29de68dea7c6f8205365cb377e547e37eb3d24 100644 (file)
@@ -26,7 +26,7 @@ window.MultipageLoader = function(config) {
         LOADING: 'loading',
         READY: 'ready',
 
-        items: m.stream(),
+        items: m.stream([]),
         thresholdItem: null,
         loadMore: function() {
             if (loader.state == loader.DONE || loader.state == loader.LOADING)
@@ -37,7 +37,7 @@ window.MultipageLoader = function(config) {
             ] : []
             loader.state = loader.LOADING
             loader.loadFunc(filters).then(function(resp) {
-                var items = loader.items() || []
+                var items = loader.items()
                 Array.prototype.push.apply(items, resp.items)
                 if (resp.items.length == 0) {
                     loader.state = loader.DONE
@@ -65,7 +65,7 @@ window.MergingLoader = function(config) {
     var loader = this
     Object.assign(loader, config, {
         // Sorted items ready to display, merged from all children.
-        items: m.stream(),
+        items: m.stream([]),
         state: 'ready',
         DONE: 'done',
         LOADING: 'loading',
@@ -97,25 +97,42 @@ window.MergingLoader = function(config) {
             })
         },
         mergeItems: function() {
-            // cutoff is the topmost (recent) of {bottom (oldest) entry of
-            // any child that still has more pages left to fetch}
+            // We want to avoid moving items around on the screen once
+            // they're displayed.
+            //
+            // To this end, here we find the last safely displayable
+            // item ("cutoff") by getting the last item from each
+            // unfinished child, and taking the topmost (most recent)
+            // one of those.
+            //
+            // (If we were to display an item below that cutoff, the
+            // next page of results from an unfinished child could
+            // include items that get inserted above the cutoff,
+            // causing the cutoff item to move down.)
             var cutoff
+            var cutoffUnknown = false
             loader.children.forEach(function(child) {
+                if (child.state == child.DONE)
+                    return
                 var items = child.items()
-                if (items.length == 0 || child.state == child.DONE)
+                if (items.length == 0) {
+                    // No idea what's coming in the next page.
+                    cutoffUnknown = true
                     return
+                }
                 var last = items[items.length-1].modified_at
                 if (!cutoff || cutoff < last)
                     cutoff = last
             })
+            if (cutoffUnknown)
+                return
             var combined = []
             loader.children.forEach(function(child) {
                 child.itemsDisplayed = 0
                 child.items().every(function(item) {
                     if (cutoff && item.modified_at < cutoff)
-                        // Some other children haven't caught up to this
-                        // point, so don't display this item or anything
-                        // after it.
+                        // Don't display this item or anything after
+                        // it (see "cutoff" comment above).
                         return false
                     combined.push(item)
                     child.itemsDisplayed++