Merge branch 'master' into 3654-combine-selections
[arvados.git] / apps / workbench / app / assets / javascripts / tab_panes.js
1 // Load tab panes on demand. See app/views/application/_content.html.erb
2
3 // Fire when a tab is selected/clicked. Check whether the content in
4 // the corresponding pane is loaded (or is being loaded). If not,
5 // start an AJAX request to load the content.
6 $(document).on('shown.bs.tab', '[data-toggle="tab"]', function(e) {
7     var content_url = $(e.target).attr('data-pane-content-url');
8     var $pane = $($(e.target).attr('href'));
9     if ($pane.hasClass('loaded'))
10         return;
11     $.ajax(content_url, {dataType: 'html', type: 'GET', context: $pane}).
12         done(function(data, status, jqxhr) {
13             $('> div > div', this).html(data);
14             $(this).addClass('loaded');
15             $(this).trigger('arv:pane:loaded');
16         }).fail(function(jqxhr, status, error) {
17             var errhtml;
18             if (jqxhr.getResponseHeader('Content-Type').match(/\btext\/html\b/)) {
19                 var $response = $(jqxhr.responseText);
20                 var $wrapper = $('div#page-wrapper', $response);
21                 if ($wrapper.length) {
22                     errhtml = $wrapper.html();
23                 } else {
24                     errhtml = jqxhr.responseText;
25                 }
26             } else {
27                 errhtml = ("An error occurred: " +
28                            (jqxhr.responseText || status)).
29                     replace(/&/g, '&').
30                     replace(/</g, '&lt;').
31                     replace(/>/g, '&gt;');
32             }
33             $('> div > div', this).html(
34                 '<div><p>' +
35                     '<a href="#" class="btn btn-primary tab_reload">' +
36                     '<i class="fa fa-fw fa-refresh"></i> ' +
37                     'Reload tab</a></p><iframe></iframe></div>');
38             $('.tab_reload', this).click(function() {
39                 $('> div > div', $pane).html(
40                     '<div class="spinner spinner-32px spinner-h-center"></div>');
41                 $pane.trigger('arv:pane:reload');
42             });
43             // We want to render the error in an iframe, in order to
44             // avoid conflicts with the main page's element ids, etc.
45             // In order to do that dynamically, we have to set a
46             // timeout on the iframe window to load our HTML *after*
47             // the default source (e.g., about:blank) has loaded.
48             var iframe = $('iframe', this)[0];
49             iframe.contentWindow.setTimeout(function() {
50                 $('body', iframe.contentDocument).html(errhtml);
51                 iframe.height = iframe.contentDocument.body.scrollHeight + "px";
52             }, 1);
53             $(this).addClass('loaded');
54         });
55 });
56
57 // Fire when the content in a tab pane becomes stale/dirty. If the
58 // pane is visible now, reload it right away. Otherwise, just replace
59 // the current content with a spinner for now: there's no need to load
60 // the new content unless/until the user clicks the corresponding tab.
61 $(document).on('arv:pane:reload', '.tab-pane', function() {
62     // Unload a single pane. Reload it if it's active.
63     $(this).removeClass('loaded');
64     if ($(this).hasClass('active')) {
65         $('[href=#' + $(this).attr('id') + ']').trigger('shown.bs.tab');
66     } else {
67         // When the user selects this tab, show a spinner instead of
68         // old content while loading.
69         $('> div > div', this).
70             html('<div class="spinner spinner-32px spinner-h-center"></div>');
71     }
72 });
73
74 // Mark all panes as stale/dirty. Refresh the active pane.
75 $(document).on('arv-log-event arv:pane:reload:all', function() {
76     $('.tab-pane.loaded').trigger('arv:pane:reload');
77 });