X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/b32fabbac03030dba208d68750e06801fb2dfcec..467722fb20db289fa1eb0833e2d87ee56ed91ba7:/apps/workbench/app/assets/javascripts/models/loader.js diff --git a/apps/workbench/app/assets/javascripts/models/loader.js b/apps/workbench/app/assets/javascripts/models/loader.js index c1205bc555..0b29de68de 100644 --- a/apps/workbench/app/assets/javascripts/models/loader.js +++ b/apps/workbench/app/assets/javascripts/models/loader.js @@ -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++