[ARVADOS] updated: 9be9761666fd091496bee885b37598db9a6ab38a
git at public.curoverse.com
git at public.curoverse.com
Thu Sep 11 15:52:18 EDT 2014
Summary of changes:
.../app/assets/javascripts/pipeline_instances.js | 2 +-
apps/workbench/app/assets/javascripts/tab_panes.js | 130 +++++++++++----------
.../assets/stylesheets/pipeline_instances.css.scss | 10 ++
.../controllers/pipeline_instances_controller.rb | 4 +-
.../app/helpers/pipeline_instances_helper.rb | 2 +-
.../app/views/application/_content.html.erb | 9 +-
.../_show_components_running.html.erb | 37 +++---
.../app/views/pipeline_instances/show.html.erb | 49 ++------
8 files changed, 115 insertions(+), 128 deletions(-)
via 9be9761666fd091496bee885b37598db9a6ab38a (commit)
from a0fc519db4f3664366c356d21a8478495f2ae78b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 9be9761666fd091496bee885b37598db9a6ab38a
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date: Thu Sep 11 15:52:14 2014 -0400
3187: Generalized reloading to reload other parts of the page in addition to
just tabs. Panel reloading no longer messes up collapsable panel state.
diff --git a/apps/workbench/app/assets/javascripts/pipeline_instances.js b/apps/workbench/app/assets/javascripts/pipeline_instances.js
index d485bc5..3c949f4 100644
--- a/apps/workbench/app/assets/javascripts/pipeline_instances.js
+++ b/apps/workbench/app/assets/javascripts/pipeline_instances.js
@@ -114,6 +114,6 @@ showhide_compare();
setInterval(function(){
if ($('[data-pipeline-state=RunningOnServer],[data-pipeline-state=RunningOnClient]').length > 0) {
- $('#Components.tab-pane,#Graph.tab-pane').trigger('arv:pane:reload');
+ $('#Components-tab,#Graph-tab,#pipeline-instance-tab-buttons').trigger('arv:pane:reload');
}
}, 15000);
diff --git a/apps/workbench/app/assets/javascripts/tab_panes.js b/apps/workbench/app/assets/javascripts/tab_panes.js
index 411a009..846d680 100644
--- a/apps/workbench/app/assets/javascripts/tab_panes.js
+++ b/apps/workbench/app/assets/javascripts/tab_panes.js
@@ -1,77 +1,83 @@
// 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.
+// Fire when a tab is selected/clicked.
$(document).on('shown.bs.tab', '[data-toggle="tab"]', function(e) {
- var content_url = $(e.target).attr('data-pane-content-url');
+ $(this).trigger('arv:pane:reload');
+});
+
+// Fire when the content in a pane becomes stale/dirty. If the pane is
+// 'active', reload it right away. Otherwise, just replace the current content
+// with a spinner for now, don't load the new content unless/until the pane
+// becomes active.
+$(document).on('arv:pane:reload', function(e) {
+ // Unload a single pane. Reload it if it's active.
+ $(e.target).removeClass('loaded');
var $pane = $($(e.target).attr('href'));
- if ($pane.hasClass('loaded'))
- return;
- $.ajax(content_url, {dataType: 'html', type: 'GET', context: $pane}).
- 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();
+ if ($pane.hasClass('active')) {
+ var content_url = $(e.target).attr('data-pane-content-url');
+ $.ajax(content_url, {dataType: 'html', type: 'GET', context: $pane}).
+ done(function(data, status, jqxhr) {
+ // Preserve collapsed state
+ var collapsable = {};
+ $(".collapse", $pane).each(function(i, c) {
+ collapsable[c.id] = $(c).hasClass('in');
+ });
+ var tmp = $(data);
+ $(".collapse", tmp).each(function(i, c) {
+ if (collapsable[c.id]) {
+ $(c).addClass('in');
+ } else {
+ $(c).removeClass('in');
+ }
+ });
+ $pane.html(tmp);
+ e.target.addClass('loaded');
+ $pane.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 = jqxhr.responseText;
+ errhtml = ("An error occurred: " +
+ (jqxhr.responseText || status)).
+ replace(/&/g, '&').
+ replace(/</g, '<').
+ replace(/>/g, '>');
}
- } else {
- errhtml = ("An error occurred: " +
- (jqxhr.responseText || status)).
- replace(/&/g, '&').
- replace(/</g, '<').
- replace(/>/g, '>');
- }
- $('> div > div', this).html(
- '<div><p>' +
- '<a href="#" class="btn btn-primary tab_reload">' +
- '<i class="fa fa-fw fa-refresh"></i> ' +
- 'Reload tab</a></p><iframe></iframe></div>');
- $('.tab_reload', this).click(function() {
- $('> div > div', $pane).html(
- '<div class="spinner spinner-32px spinner-h-center"></div>');
- $pane.trigger('arv:pane:reload');
+ $pane.html('<div><p>' +
+ '<a href="#" class="btn btn-primary tab_reload">' +
+ '<i class="fa fa-fw fa-refresh"></i> ' +
+ 'Reload tab</a></p><iframe></iframe></div>');
+ $('.tab_reload', $pane).click(function() {
+ $pane.html('<div class="spinner spinner-32px spinner-h-center"></div>');
+ $(e.target).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', e.target)[0];
+ iframe.contentWindow.setTimeout(function() {
+ $('body', iframe.contentDocument).html(errhtml);
+ iframe.height = iframe.contentDocument.body.scrollHeight + "px";
+ }, 1);
+ $(e.target).addClass('loaded');
});
- // 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');
- });
-});
-
-// 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
+ // When the user selects e.target tab, show a spinner instead of
// old content while loading.
- $('> div > div', this).
- html('<div class="spinner spinner-32px spinner-h-center"></div>');
+ $pane.html('<div class="spinner spinner-32px spinner-h-center"></div>');
}
});
// 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');
+ $('.pane-anchor.loaded').trigger('arv:pane:reload');
});
diff --git a/apps/workbench/app/assets/stylesheets/pipeline_instances.css.scss b/apps/workbench/app/assets/stylesheets/pipeline_instances.css.scss
index 16d1879..c89e93d 100644
--- a/apps/workbench/app/assets/stylesheets/pipeline_instances.css.scss
+++ b/apps/workbench/app/assets/stylesheets/pipeline_instances.css.scss
@@ -21,3 +21,13 @@
.pipeline_color_legend a {
color: #000;
}
+
+.col-md-1.pipeline-instance-spacing {
+ padding: 0px;
+ margin: 0px;
+}
+
+.col-md-3.pipeline-instance-spacing > .progress {
+ padding: 0px;
+ margin: 0px;
+}
\ No newline at end of file
diff --git a/apps/workbench/app/controllers/pipeline_instances_controller.rb b/apps/workbench/app/controllers/pipeline_instances_controller.rb
index 72af56a..8ee06c3 100644
--- a/apps/workbench/app/controllers/pipeline_instances_controller.rb
+++ b/apps/workbench/app/controllers/pipeline_instances_controller.rb
@@ -33,8 +33,8 @@ class PipelineInstancesController < ApplicationController
if params['script'] == 'use_same'
# Go through each component and copy the script_version from each job.
@object.components.each do |cname, component|
- if source.components['cname'][:job]
- component.script_version = source.components[cname][:job].script_version
+ if source.components[cname][:job]
+ component[:script_version] = source.components[cname][:job][:script_version]
end
end
end
diff --git a/apps/workbench/app/helpers/pipeline_instances_helper.rb b/apps/workbench/app/helpers/pipeline_instances_helper.rb
index a17f125..995b1c3 100644
--- a/apps/workbench/app/helpers/pipeline_instances_helper.rb
+++ b/apps/workbench/app/helpers/pipeline_instances_helper.rb
@@ -69,7 +69,7 @@ module PipelineInstancesHelper
timestamps = merge_range timestamps, started_at, finished_at
end
end
- timestamps.map { |t| t[1] - t[0] }.reduce(:+)
+ timestamps.map { |t| t[1] - t[0] }.reduce(:+) || 0
end
protected
diff --git a/apps/workbench/app/views/application/_content.html.erb b/apps/workbench/app/views/application/_content.html.erb
index 4379758..7249e32 100644
--- a/apps/workbench/app/views/application/_content.html.erb
+++ b/apps/workbench/app/views/application/_content.html.erb
@@ -4,7 +4,14 @@
<ul class="nav nav-tabs">
<% pane_list.each_with_index do |pane, i| %>
- <li class="<%= 'active' if i==0 %>"><a href="#<%= pane %>" data-toggle="tab" id="<%= pane %>-tab" data-pane-content-url="<%= url_for(params.merge(tab_pane: pane)) %>"> <%= pane.gsub('_', ' ') %></a></li>
+ <li class="<%= 'active' if i==0 %>">
+ <a href="#<%= pane %>" data-toggle="tab"
+ class="pane-anchor"
+ id="<%= pane %>-tab"
+ data-pane-content-url="<%= url_for(params.merge(tab_pane: pane)) %>">
+ <%= pane.gsub('_', ' ') %>
+ </a>
+ </li>
<% end %>
</ul>
<div class="tab-content">
diff --git a/apps/workbench/app/views/pipeline_instances/_show_components_running.html.erb b/apps/workbench/app/views/pipeline_instances/_show_components_running.html.erb
index 8fb263c..b9500f6 100644
--- a/apps/workbench/app/views/pipeline_instances/_show_components_running.html.erb
+++ b/apps/workbench/app/views/pipeline_instances/_show_components_running.html.erb
@@ -32,17 +32,12 @@
<%# want to buy: algorithm that calculates wall clock runtime that takes into account
concurrent jobs. %>
- <% runningtime = render_pipeline_jobs.map { |j|
- if j[:job] and j[:job].started_at
- (if j[:job].finished_at then j[:job].finished_at else Time.now() end) - j[:job].started_at
- else
- 0
- end
- }.reduce(:+) %>
+ <% runningtime = determine_wallclock_runtime(render_pipeline_jobs.map {|j| j[:job]}) %>
<%= runtime(runningtime, true) %><% if tasks.size == 0 %>.<% else %>,
using
<% cputime = tasks.map { |task|
+ puts "started at #{task.started_at}"
if task.started_at
(if task.finished_at then task.finished_at else Time.now() end) - task.started_at
else
@@ -74,8 +69,12 @@
<% puts current_job.inspect %>
<% if current_job %>
+ <div class="col-md-1">
+ <%= render(partial: 'job_status_label', locals: { j: current_job }) %>
+ </div>
+
<div class="col-md-3">
- <% if current_job.started_at %>
+ <% if current_job[:started_at] %>
<% walltime = ((if current_job.finished_at then current_job.finished_at else Time.now() end) - current_job.started_at) %>
<% cputime = tasks.map { |task|
if task.started_at and task.job_uuid == current_job.uuid
@@ -88,33 +87,29 @@
<% end %>
</div>
- <% if current_job.state.in? ["Completed", "Failed", "Canceled"] %>
- <div class="col-md-3">
- <%= render(partial: 'job_status_label', locals: { j: current_job }) %>
- </div>
+ <% if Job::state(current_job).in? ["Completed", "Failed", "Canceled"] %>
<div class="col-md-3">
<% if pj[:output_uuid] %>
<%= link_to_if_arvados_object pj[:output_uuid] %>
<% elsif current_job.andand[:output] %>
<%= link_to_if_arvados_object current_job[:output], link_text: "Output of #{pj[:name]}" %>
+ <% else %>
+ No output.
<% end %>
</div>
- <% elsif current_job.state == "Running" %>
- <div class="col-md-3">
+ <% elsif Job::state(current_job) == "Running" %>
+ <div class="col-md-3 pipeline-instance-spacing">
<%= pj[:progress_bar] %>
</div>
- <div class="col-md-3">
+ <div class="col-md-1 pipeline-instance-spacing">
<%= form_tag "/jobs/#{current_job.uuid}/cancel", style: "display:inline; padding-left: 1em" do |f| %>
<%= hidden_field_tag :return_to, url_for(@object) %>
- <%= button_tag "Cancel", {class: 'btn btn-danger', id: "cancel-job-button"} %>
+ <%= button_tag "Cancel", {class: 'btn btn-xs btn-danger', id: "cancel-job-button"} %>
</div>
<% end %>
- <% elsif current_job.state == "Queued" %>
- <div class="col-md-1">
- <span class="label label-default">Queued</span>
- </div>
+ <% elsif Job::state(current_job) == "Queued" %>
<div class="col-md-5">
- <% queuetime = Time.now - current_job.created_at %>
+ <% queuetime = Time.now - current_job[:created_at] %>
Queued for <%= runtime(queuetime, true) %>.
There
<% if current_job.queue_position == 0 %>
diff --git a/apps/workbench/app/views/pipeline_instances/show.html.erb b/apps/workbench/app/views/pipeline_instances/show.html.erb
index f43369f..7d9d30f 100644
--- a/apps/workbench/app/views/pipeline_instances/show.html.erb
+++ b/apps/workbench/app/views/pipeline_instances/show.html.erb
@@ -13,46 +13,15 @@
<% content_for :tab_line_buttons do %>
- <% if @object.state.in? ['Complete', 'Failed', 'Cancelled'] %>
-
- <%= link_to(copy_pipeline_instance_path('id' => @object.uuid, 'script' => "use_latest", "components" => "use_latest", "pipeline_instance[state]" => "RunningOnServer"),
- class: 'btn btn-primary',
- #data: {toggle: :tooltip, placement: :top}, title: 'Re-run',
- method: :post,
- ) do %>
- <i class="fa fa-fw fa-play"></i> Re-run with latest
- <% end %>
-
- <%= link_to raw('<i class="fa fa-fw fa-cogs"></i> Re-run options'),
- "#",
- {class: 'btn btn-primary', 'data-toggle' => "modal",
- 'data-target' => '#clone-and-edit-modal-window'} %>
- <% end %>
-
- <% if @object.state.in? ['New', 'Ready'] %>
- <%= link_to(url_for('pipeline_instance[state]' => 'RunningOnServer'),
- class: 'btn btn-primary run-pipeline-button',
- method: :patch
- ) do %>
- <i class="fa fa-fw fa-play"></i> Run
- <% end %>
- <% else %>
- <% if @object.state.in? ['RunningOnClient', 'RunningOnServer'] %>
- <%= link_to(url_for('pipeline_instance[state]' => 'Paused'),
- class: 'btn btn-primary run-pipeline-button',
- method: :patch
- ) do %>
- <i class="fa fa-fw fa-pause"></i> Pause
- <% end %>
- <% elsif @object.state == 'Paused' %>
- <%= link_to(url_for('pipeline_instance[state]' => 'RunningOnServer'),
- class: 'btn btn-primary run-pipeline-button',
- method: :patch
- ) do %>
- <i class="fa fa-fw fa-play"></i> Resume
- <% end %>
- <% end %>
- <% end %>
+ <div id="pipeline-instance-tab-buttons"
+ class="pane-anchor loaded"
+ href="#pipeline-instance-tab-buttons-pane"
+ data-pane-content-url="<%= url_for(params.merge(tab_pane: "tab_buttons")) %>"
+ >
+ <div id="pipeline-instance-tab-buttons-pane" class="active">
+ <%= render partial: 'show_tab_buttons', locals: {object: @object}%>
+ </div>
+ </div>
<% end %>
<%= render partial: 'content', layout: 'content_layout', locals: {pane_list: controller.show_pane_list }%>
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list