X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/d188143b2acd99dc594231360eeaf3e178794ff8..59e8a18aef4164875cf43a0382db6a70671bf87f:/apps/workbench/app/assets/javascripts/tab_panes.js?ds=sidebyside diff --git a/apps/workbench/app/assets/javascripts/tab_panes.js b/apps/workbench/app/assets/javascripts/tab_panes.js index 55cf7d808d..411a009f5c 100644 --- a/apps/workbench/app/assets/javascripts/tab_panes.js +++ b/apps/workbench/app/assets/javascripts/tab_panes.js @@ -1,3 +1,8 @@ +// Load tab panes on demand. See app/views/application/_content.html.erb + +// Fire when a tab is selected/clicked. Check whether the content in +// the corresponding pane is loaded (or is being loaded). If not, +// start an AJAX request to load the content. $(document).on('shown.bs.tab', '[data-toggle="tab"]', function(e) { var content_url = $(e.target).attr('data-pane-content-url'); var $pane = $($(e.target).attr('href')); @@ -7,10 +12,66 @@ $(document).on('shown.bs.tab', '[data-toggle="tab"]', function(e) { done(function(data, status, jqxhr) { $('> div > div', this).html(data); $(this).addClass('loaded'); + $(this).trigger('arv:pane:loaded'); + }).fail(function(jqxhr, status, error) { + var errhtml; + if (jqxhr.getResponseHeader('Content-Type').match(/\btext\/html\b/)) { + var $response = $(jqxhr.responseText); + var $wrapper = $('div#page-wrapper', $response); + if ($wrapper.length) { + errhtml = $wrapper.html(); + } else { + errhtml = jqxhr.responseText; + } + } else { + errhtml = ("An error occurred: " + + (jqxhr.responseText || status)). + replace(/&/g, '&'). + replace(//g, '>'); + } + $('> div > div', this).html( + '

' + + '' + + ' ' + + 'Reload tab

'); + $('.tab_reload', this).click(function() { + $('> div > div', $pane).html( + '
'); + $pane.trigger('arv:pane:reload'); + }); + // We want to render the error in an iframe, in order to + // avoid conflicts with the main page's element ids, etc. + // In order to do that dynamically, we have to set a + // timeout on the iframe window to load our HTML *after* + // the default source (e.g., about:blank) has loaded. + var iframe = $('iframe', this)[0]; + iframe.contentWindow.setTimeout(function() { + $('body', iframe.contentDocument).html(errhtml); + iframe.height = iframe.contentDocument.body.scrollHeight + "px"; + }, 1); + $(this).addClass('loaded'); }); }); -$(document).on('arv-log-event', function() { - $('[data-pane-content-url]').removeClass('loaded'); - $('.tab-pane.active').trigger('shown.bs.tab'); +// Fire when the content in a tab pane becomes stale/dirty. If the +// pane is visible now, reload it right away. Otherwise, just replace +// the current content with a spinner for now: there's no need to load +// the new content unless/until the user clicks the corresponding tab. +$(document).on('arv:pane:reload', '.tab-pane', function() { + // Unload a single pane. Reload it if it's active. + $(this).removeClass('loaded'); + if ($(this).hasClass('active')) { + $('[href=#' + $(this).attr('id') + ']').trigger('shown.bs.tab'); + } else { + // When the user selects this tab, show a spinner instead of + // old content while loading. + $('> div > div', this). + html('
'); + } +}); + +// Mark all panes as stale/dirty. Refresh the active pane. +$(document).on('arv-log-event arv:pane:reload:all', function() { + $('.tab-pane.loaded').trigger('arv:pane:reload'); });