X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/6862544ea5ff9272c537672a7a9cc6c98d0192fe..f1aec3387f765a3f8a2f3f2c22d3a53fb4f9f1f3:/apps/workbench/app/assets/javascripts/tab_panes.js diff --git a/apps/workbench/app/assets/javascripts/tab_panes.js b/apps/workbench/app/assets/javascripts/tab_panes.js index fc05fde15a..b19a277ef7 100644 --- a/apps/workbench/app/assets/javascripts/tab_panes.js +++ b/apps/workbench/app/assets/javascripts/tab_panes.js @@ -1,3 +1,7 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + // Load tab panes on demand. See app/views/application/_content.html.erb // Fire when a tab is selected/clicked. @@ -10,30 +14,33 @@ $(document).on('shown.bs.tab', '[data-toggle="tab"]', function(event) { // Ask a refreshable pane to reload via ajax. // -// Target of this event is the anchor element that manages the pane. A reload -// consists of an AJAX call to load the "data-pane-content-url" and replace the -// contents of the DOM node pointed to by "href". +// Target of this event is the DOM element to be updated. A reload +// consists of an AJAX call to load the "data-pane-content-url" and +// replace the content of the target element with the retrieved HTML. // -// There are four CSS classes set on the object to indicate its state: +// There are four CSS classes set on the element to indicate its state: // pane-loading, pane-stale, pane-loaded, pane-reload-pending // // There are five states based on the presence or absence of css classes: // -// 1. no pane-* states means the pane must be loaded when the pane becomes active +// 1. Absence of any pane-* states means the pane is empty, and should +// be loaded as soon as it becomes visible. // -// 2. "pane-loading" means an AJAX call has been made to reload the pane and we are -// waiting on a result +// 2. "pane-loading" means an AJAX call has been made to reload the +// pane and we are waiting on a result. // -// 3. "pane-loading pane-stale" indicates a pane that is already loading has -// been invalidated and should schedule a reload immediately when the current -// load completes. (This happens when there is a cluster of events, where the -// reload is triggered by the first event, but we want ensure that we -// eventually load the final quiescent state). +// 3. "pane-loading pane-stale" means the pane is loading, but has +// already been invalidated and should schedule a reload as soon as +// possible after the current load completes. (This happens when there +// is a cluster of events, where the reload is triggered by the first +// event, but we want ensure that we eventually load the final +// quiescent state). // -// 4. "pane-loaded" means the pane is up to date +// 4. "pane-loaded" means the pane is up to date. // -// 5. "pane-loaded pane-reload-pending" indicates a reload is scheduled (but has -// not started yet), suppressing scheduling of any further reloads. +// 5. "pane-loaded pane-reload-pending" means a reload is needed, and +// has been scheduled, but has not started because the pane's +// minimum-time-between-reloads throttle has not yet been reached. // $(document).on('arv:pane:reload', '[data-pane-content-url]', function(e) { if (this != e.target) { @@ -103,8 +110,8 @@ $(document).on('arv:pane:reload', '[data-pane-content-url]', function(e) { var content_url = $pane.attr('data-pane-content-url'); $.ajax(content_url, {dataType: 'html', type: 'GET', context: $pane}). done(function(data, status, jqxhr) { - // Preserve collapsed state var $pane = this; + // Preserve collapsed state var collapsable = {}; $(".collapse", this).each(function(i, c) { collapsable[c.id] = $(c).hasClass('in'); @@ -121,7 +128,7 @@ $(document).on('arv:pane:reload', '[data-pane-content-url]', function(e) { $pane.removeClass('pane-loading'); $pane.addClass('pane-loaded'); $pane.attr('data-loaded-at', (new Date()).getTime()); - $pane.trigger('arv:pane:loaded'); + $pane.trigger('arv:pane:loaded', [$pane]); if ($pane.hasClass('pane-stale')) { $pane.trigger('arv:pane:reload'); @@ -130,7 +137,23 @@ $(document).on('arv:pane:reload', '[data-pane-content-url]', function(e) { var $pane = this; var errhtml; var contentType = jqxhr.getResponseHeader('Content-Type'); - if (contentType && contentType.match(/\btext\/html\b/)) { + if (jqxhr.readyState == 0 || jqxhr.status == 0) { + if ($pane.attr('data-loaded-at') > 0) { + // Stale content is already present. Leave it + // there while loading the next page. + $pane.removeClass('pane-loading'); + $pane.addClass('pane-loaded'); + // ...but schedule another refresh (after a + // throttle delay) in case the act of navigating + // away gets cancelled itself, leaving this page + // with content that we know is stale. + $pane.addClass('pane-stale'); + $pane.attr('data-loaded-at', (new Date()).getTime()); + $pane.trigger('arv:pane:reload'); + return; + } + errhtml = "Cancelled."; + } else if (contentType && contentType.match(/\btext\/html\b/)) { var $response = $(jqxhr.responseText); var $wrapper = $('div#page-wrapper', $response); if ($wrapper.length) { @@ -145,7 +168,7 @@ $(document).on('arv:pane:reload', '[data-pane-content-url]', function(e) { replace(//g, '>'); } - $pane.html('

' + + $pane.html('

' + '' + ' ' + 'Reload tab

');