[ARVADOS] updated: 1b97a93f4a0e51836331c298c3946e02b6fe82ae
git at public.curoverse.com
git at public.curoverse.com
Thu Jun 12 12:50:13 EDT 2014
Summary of changes:
apps/workbench/app/assets/images/ajax-loader.gif | Bin 0 -> 3208 bytes
.../app/assets/javascripts/application.js | 12 +-
apps/workbench/app/assets/javascripts/editable.js | 3 +
apps/workbench/app/assets/javascripts/event_log.js | 25 +-
.../app/assets/javascripts/pipeline_instances.js | 9 -
apps/workbench/app/assets/javascripts/selection.js | 10 +-
.../app/assets/stylesheets/application.css.scss | 3 +-
.../app/controllers/actions_controller.rb | 80 +++---
.../app/controllers/application_controller.rb | 248 ++++++++++++++--
.../app/controllers/collections_controller.rb | 10 +-
.../workbench/app/controllers/groups_controller.rb | 1 +
apps/workbench/app/controllers/jobs_controller.rb | 13 +-
.../controllers/pipeline_instances_controller.rb | 26 +-
.../app/controllers/projects_controller.rb | 3 +
.../app/controllers/sessions_controller.rb | 3 +
apps/workbench/app/helpers/application_helper.rb | 52 +++-
apps/workbench/app/models/arvados_api_client.rb | 4 +
apps/workbench/app/models/arvados_base.rb | 11 +-
apps/workbench/app/models/job.rb | 4 +
.../app/views/application/_content.html.erb | 75 ++++-
.../application/_show_advanced_metadata.html.erb | 12 +
apps/workbench/app/views/collections/show.html.erb | 7 +-
.../workbench/app/views/jobs/_show_status.html.erb | 93 ++++++
.../app/views/layouts/application.html.erb | 8 +-
.../app/views/projects/_show_contents.html.erb | 67 +++--
.../views/projects/_show_contents_rows.html.erb | 4 +-
.../app/views/projects/_show_permissions.html.erb | 13 +-
.../workbench/app/views/users/_show_admin.html.erb | 2 -
apps/workbench/app/views/users/_tables.html.erb | 51 +++-
apps/workbench/config/routes.rb | 4 +-
.../test/functional/application_controller_test.rb | 299 ++++++++++++++++++++
.../test/integration/pipeline_instances_test.rb | 2 +-
apps/workbench/test/integration/projects_test.rb | 5 +-
apps/workbench/test/integration/users_test.rb | 3 -
sdk/cli/bin/arv-run-pipeline-instance | 20 +-
sdk/cli/bin/crunch-job | 9 +-
sdk/go/src/arvados.org/keepclient/keepclient.go | 42 +--
.../src/arvados.org/keepclient/keepclient_test.go | 76 ++---
sdk/go/src/arvados.org/keepclient/support.go | 51 +---
sdk/go/src/arvados.org/sdk/sdk.go | 232 +++++++++++++++
sdk/go/src/arvados.org/sdk/sdk_test.go | 92 ++++++
services/api/Gemfile | 2 +
services/api/Gemfile.lock | 3 +
.../app/controllers/arvados/v1/jobs_controller.rb | 2 +-
.../app/controllers/arvados/v1/nodes_controller.rb | 12 +-
.../controllers/arvados/v1/schema_controller.rb | 3 +-
services/api/app/middlewares/rack_socket.rb | 2 +-
services/api/app/models/job.rb | 2 +
services/api/app/models/node.rb | 9 +
.../20140530200539_add_supplied_script_version.rb | 9 +
services/api/db/schema.rb | 4 +-
services/api/script/cancel_stale_jobs.rb | 37 +++
services/api/script/crunch-dispatch.rb | 103 +++++--
services/api/test/fixtures/links.yml | 2 +-
services/api/test/fixtures/nodes.yml | 1 +
.../arvados/v1/collections_controller_test.rb | 29 +-
.../functional/arvados/v1/nodes_controller_test.rb | 16 ++
services/api/test/unit/node_test.rb | 22 +-
services/{keep => crunch/crunchstat}/go.sh | 2 -
.../src/arvados.org/crunchstat/crunchstat.go | 311 +++++++++++++++++++++
services/fuse/bin/arv-mount | 16 +-
.../keep/src/arvados.org/keepproxy/keepproxy.go | 32 +--
.../src/arvados.org/keepproxy/keepproxy_test.go | 9 +-
63 files changed, 1939 insertions(+), 373 deletions(-)
create mode 100644 apps/workbench/app/assets/images/ajax-loader.gif
create mode 100644 apps/workbench/app/views/jobs/_show_status.html.erb
create mode 100644 apps/workbench/test/functional/application_controller_test.rb
create mode 100644 sdk/go/src/arvados.org/sdk/sdk.go
create mode 100644 sdk/go/src/arvados.org/sdk/sdk_test.go
create mode 100644 services/api/db/migrate/20140530200539_add_supplied_script_version.rb
create mode 100755 services/api/script/cancel_stale_jobs.rb
copy services/{keep => crunch/crunchstat}/go.sh (92%)
create mode 100644 services/crunch/crunchstat/src/arvados.org/crunchstat/crunchstat.go
via 1b97a93f4a0e51836331c298c3946e02b6fe82ae (commit)
via 6a4c33f0b3689f97d18b2d75f54787245c1ebeb9 (commit)
via 719ba7f6247cf1697d81193b46bd768202ebb064 (commit)
via 965700e2e2e981e1ba56c2101d3df2fd759ddb81 (commit)
via b64228f1f547c720b79a242d6d8d368a64923885 (commit)
via 70542a2d6d6a2792f1dc68b1531e783e7611b474 (commit)
via a959f21c8147f26362df392bc3fd3290db69de85 (commit)
via 70f1004b17fac3c772c8f938b5a72ff3a3ebc67a (commit)
via a9beb0e51fdd2782c4aeaa1f5c2d20d6ad7dd435 (commit)
via 9bda231180fc58e67b0c322c16be223154965b66 (commit)
via 85ce092000d72c5dda03bd4763c9613bb9a46437 (commit)
via 5da7bddd63790e524e4b22a6944a92065409241d (commit)
via 0548dd424d6f21f3eb97f3e98d37a604b44b025a (commit)
via 7ccba0ea6cb9916a1bad55f13cc45029f0bc37bd (commit)
via eaa312ea7c35e35c64dbef9624be1d9c7df034ef (commit)
via 70148c4918a95ee9a49a18bf5789801d02e8ef5e (commit)
via f0a048b4b9792550f59ee23b13c09cca21681eb4 (commit)
via d161e2280a03b4a1c9675f5ed1946310a9942acd (commit)
via 23fd8b137488baeb3138e2127294e8e14917d3ed (commit)
via 82c4697bf24b10f3fb66d303ae73499095b5742a (commit)
via 505f5c37bb9fe1fe93f8bdbd2d2072e783832f20 (commit)
via 541ce54ba2c7c8f9783da04f947ccf055b72ae2c (commit)
via 35db7f5c7f1d62f996550f51fc4f0dd4f77627fb (commit)
via 799e968ef79906bcd8b491f1ad99572b1cc21ccc (commit)
via a314e176f65f97059b43f50a84814f4fe5e5d73d (commit)
via f883adf66c3da731904d5c25c779a13416ce9193 (commit)
via 2bd11a587ca12d8921042d86df4d095c79243dbc (commit)
via d687fed365e545dea1c9283e917e05bb2a4ed07c (commit)
via 92594178fbe4155f3122a1b0a52b5b3da995aabb (commit)
via 4d73cd3503ca20ec4d1f8198617fea3bf481a48e (commit)
via 40e48b2aac96a71c8ae3c2265f43b882f415e63d (commit)
via 90f3d66faa1a87b0b230a8a9a7a9879e66f29cd0 (commit)
via 497ea8e6fd12ce91cad108af78df5e3802a79d69 (commit)
via 7e865395a4ccf9f17b904c3700064328d52db121 (commit)
via 9a48ecf1c92b9b8f513a5e621a0e263ccde076e4 (commit)
via 468a80200c8ef3e4a56700714e9af537d87a20bc (commit)
via 3692a4ac4d8f76d2e704af5e504652650b4a00cc (commit)
via 73c0b152d18774266e72916d6f8cedb3199b535c (commit)
via 0ef7495b59056c8f115a42bd843ce432c9282e8c (commit)
via 67578498c5de67fe2e821a3d91c1d2b7294df579 (commit)
via 2cdc648b5367efd4c8e7b2ede93a2b3ba0871c17 (commit)
via 97a1da1dfde9ef3ef195f7513309da8c6bb17978 (commit)
via 73688a1ef6387fe8a8b1b2f09a8936198f79d66e (commit)
via a2bcc06c1bda757ed8c869d7f9ad235f56abdcf4 (commit)
via dd6e25d53f9cf02f91b419584ff4c331e0618a24 (commit)
via 400829b3835f0a129116a2eed926d12a0636aeab (commit)
via f6e5ba4510e2072415a8d6b5369b11b8003ddafa (commit)
via 55b94087ff4590c54cf1f43d941c6cb24153dded (commit)
via ef3e10bdf2324f3c9e6427b3fd085e6b05e3877c (commit)
via 408649cc0e9ad3d30296b0750680fb62fefe6d82 (commit)
via 1bd85c64fbf485acceac4711ff06e6b2f548d40a (commit)
via 879e1f31b0165c6abaa35a023ff66400757bb44b (commit)
via 987b88a5441387ff91877464def7933064815b59 (commit)
via f3da69fb1b882c7fe8feb765ad0558f13706931a (commit)
via f0d8ab52b77f74e9294fe634207ce6e1ff9748a1 (commit)
via 620a10bed55b85294baad9dba965ea8dad59e884 (commit)
via 488a811374ff4bdeed9f2f2f57d9ef31d9369b5b (commit)
via 626db8559ebaa13df19dafe9bb03b1bd484b762c (commit)
via 2f3d49bde80526060d3337f13dfa91cd581ac222 (commit)
via 6a8463eea9e32cb5cffcaf2f04667520794404ec (commit)
via fa87d357fdefd594b378cda9b4d73487df60d262 (commit)
via 1f760632ae0fbb9f11af5cfb831b7c3ed49a7009 (commit)
via 428973c03d4b4cd96adc80a514beffbb739d987a (commit)
via 35c20b4ad8220131f7f6bad6b3806a7d28df3ef3 (commit)
via f48482bd37d3ae5a5f1aa488fa330f77c5fd640d (commit)
via 0e7e57bbd8030c8144a18e43e68945ab11ad094c (commit)
via 32f6ee6884704bde04878f5cbc176a7a819a50e8 (commit)
via 38a55a1518838ea68cba69b4e8d1c27d2128328d (commit)
via 0b4f867ef14af38c07b910643fbe8cc6a93e6bb6 (commit)
via cea92754dfacf2b409d1f5b45dd0775fc44c842d (commit)
via f0bf04abdbb7e4b47be85585fba5789d695bb31e (commit)
via a163b0c7b5afa782281f67f0fa0ca0e4b41c518f (commit)
via c4cfb4caca122ba09ab9153453650c308457e675 (commit)
via a46f0152c44fe20eba4db38858eaa2f99bae83f2 (commit)
via f3b4b263d8c656e15993ea71146747e8cf102bf9 (commit)
via 16cc50a4161448f9987635e06fe3d772ee0321ab (commit)
via 25f3a23bc8794b77a1b5fa1e5e7f9c38a152dd8f (commit)
via 33fed6bb30180c9dedb046d6266acbbc48dcfcd4 (commit)
via 87dc5129e903cb7452e06c936d8e5e581c4d2481 (commit)
via bc784d9eeadfc04aedea9772bb8913f5e8b86cd1 (commit)
via 10486fd2453c92a62c0a97491259d1391e5cb872 (commit)
via cdc46777d33cc341969ba791175a8ca0925e77dc (commit)
via 570201300b90a676b4bc49ea02627d1057386615 (commit)
via 3674d731b92e091811872eef0b909171d3574614 (commit)
via 3273eb53cd985cf13e1e0785ba853af2d0a8c2c6 (commit)
via 03812184bfa1ab7f17960ef48ff30798333bdd54 (commit)
via 1ec252c8087c1f167d969e26c584ff346f4ac457 (commit)
via 6b13646940de2e5a62e600f2d7d82c72e3a4ae59 (commit)
via dfe74093596d3d7378e6f0d3e5f843f44d987074 (commit)
via bf7687829f5222375441cf75c7d82d82a4f508c4 (commit)
via 137cd3ce818d4789355ea8d92cd2e2ea73318c4f (commit)
via f6f4efcf298d5c37b5eb8a88eb164cf8b77ae928 (commit)
via c7a21e6294f1eb905ace3d717f9dcfb4d4c39f0b (commit)
via 9fd2051619bf6246708489e39515fb94b43a3199 (commit)
via ca77755f57b0478e3f4fbe3e6a6d7ade95012808 (commit)
via 66da5859254325690a78512d03b6b02e3f69a237 (commit)
via 349ab8f9e11d462c878cd6be6d24bf5790af3d50 (commit)
via 8c9fa09deea0cb68b68f110fdbb1b1daa50a618c (commit)
via 161478d5be79e83f3e200b46f0d8d003caa2ffe0 (commit)
via ae09643622ecea00bab110f20029f01c83e1cf30 (commit)
via 2a64eae3cf8363c596feda5337ea20ce356ca11f (commit)
via 114df81b90be76e6921b9f20c9ddb272567c82e1 (commit)
via a276e40691a8f96b321879de2279159ef08b804f (commit)
via cb77d123755112d17f2e7bb2bd869d957d8a00f3 (commit)
via 618a868118721baa683d151949759e1e9e516b4a (commit)
via cda441b1b6e50811c7dbd8d5c61ead1b39c91857 (commit)
via 2c6c1cb11153849e87496bb8d1f5ff24f439a6a4 (commit)
via ec08a1b9aefcd801d1f0c0b282b268cbee6939bc (commit)
via 2f1baf225599d7ae5dec4611696774e6a7100d58 (commit)
via f10a7f68c6ef25cf4ba87045201b17093a11249e (commit)
via a0aba6d6dec99a25cc2622b49fb7d29634a3e8c3 (commit)
via 4bf9e0c663789cbb748e628e8e86a8ea9ab047c5 (commit)
via 2c77b59f16d698fa5368c2aa28f5c304c3f7e53b (commit)
via 270a94c35d496daeabc39300611f727ce307f353 (commit)
via a285726d2297f71254529ab7d5b02f9246a0c413 (commit)
via e881778afbede03d32b842334113cba198052cfb (commit)
via 18e7ea91bc5e9cd7cd1f25bd009a67e6fd2cc06b (commit)
via 5779020e2f38bbc88dc436b33dcaf7dbd8292752 (commit)
via a975c45ec9908660db54b1f22399fc2c43488af5 (commit)
via 09d3d4d177810ee9aea235eddbda9306f1aa5b7b (commit)
via f8d2097375c2d105b53de18a5ec7afdb7eb36b78 (commit)
via c67402c3d993007f7d925d605eb486d21df4e278 (commit)
via 8ca3553c699e5fb2e026aa1ab0c0f20b6c43881f (commit)
from 2cf679eb06b02a98f0597b709eaea581bbe82273 (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 1b97a93f4a0e51836331c298c3946e02b6fe82ae
Author: Tom Clegg <tom at curoverse.com>
Date: Thu Jun 12 12:49:43 2014 -0400
2872: Fix selector in test case.
diff --git a/apps/workbench/test/integration/projects_test.rb b/apps/workbench/test/integration/projects_test.rb
index 73733d2..76a61b4 100644
--- a/apps/workbench/test/integration/projects_test.rb
+++ b/apps/workbench/test/integration/projects_test.rb
@@ -70,10 +70,9 @@ class ProjectsTest < ActionDispatch::IntegrationTest
end
wait_for_ajax
- click_link 'Permissions'
- find('input[value="Move to..."]').click
+ click_link 'Move to...'
find('.selectable', text: 'Project 1234').click
- find('a,button', text: 'Move').click
+ find('.modal-footer a,button', text: 'Move').click
wait_for_ajax
# Wait for the page to refresh and show the new parent in Permissions panel
commit 6a4c33f0b3689f97d18b2d75f54787245c1ebeb9
Author: Tom Clegg <tom at curoverse.com>
Date: Thu Jun 12 11:36:21 2014 -0400
2872: Add "move to project" button, fix "copy to project" behavior
(really copy, instead of adding a link).
diff --git a/apps/workbench/app/assets/javascripts/selection.js b/apps/workbench/app/assets/javascripts/selection.js
index 84d65cd..0fa2e9a 100644
--- a/apps/workbench/app/assets/javascripts/selection.js
+++ b/apps/workbench/app/assets/javascripts/selection.js
@@ -57,8 +57,10 @@ jQuery(function($){
$("#persistent-selection-count").text(lst.length);
if (lst.length > 0) {
html = '<li><a href="#" class="btn btn-xs btn-info" id="clear_selections_button"><i class="fa fa-fw fa-ban"></i> Clear selections</a></li>';
- if (this_object_uuid.match('-j7d0g-'))
- html += '<li><button class="btn btn-xs btn-info" type="submit" name="copy_selections_into_project" id="copy_selections_into_project"><i class="fa fa-fw fa-folder-open"></i> Copy selections into this project</button></li>';
+ if (this_object_uuid.match('-j7d0g-')) {
+ html += '<li><button class="btn btn-xs btn-info" type="submit" name="copy_selections_into_project" id="copy_selections_into_project"><i class="fa fa-fw fa-copy"></i> Copy selections into this project</button></li>';
+ html += '<li><button class="btn btn-xs btn-info" type="submit" name="move_selections_into_project" id="move_selections_into_project"><i class="fa fa-fw fa-truck"></i> Move selections into this project</button></li>';
+ }
html += '<li><button class="btn btn-xs btn-info" type="submit" name="combine_selected_files_into_collection" '
+ ' id="combine_selected_files_into_collection">'
+ '<i class="fa fa-fw fa-archive"></i> Combine selected collections and files into a new collection</button></li>'
@@ -200,8 +202,8 @@ function enable_disable_selection_actions() {
var $checked = $('.persistent-selection:checkbox:checked');
$('[data-selection-action]').
closest('div.btn-group-sm').
- find('*').
- prop('disabled', ($checked.length == 0));
+ find('ul li').
+ toggleClass('disabled', ($checked.length == 0));
$('[data-selection-action=compare]').
closest('li').
toggleClass('disabled',
diff --git a/apps/workbench/app/controllers/actions_controller.rb b/apps/workbench/app/controllers/actions_controller.rb
index 06775fc..6fbdf29 100644
--- a/apps/workbench/app/controllers/actions_controller.rb
+++ b/apps/workbench/app/controllers/actions_controller.rb
@@ -20,43 +20,51 @@ class ActionsController < ApplicationController
end
expose_action :copy_selections_into_project do
- link_selections = Link.filter([['uuid','in',params["selection"]]])
- link_uuids = link_selections.collect(&:uuid)
-
- # Given a link uuid, we'll add the link's head_uuid. Given another
- # type, we'll add the object itself.
- uuids_to_add = params["selection"] - link_uuids
- uuids_to_add += link_selections.collect(&:head_uuid)
-
- # Skip anything that's already here.
- already_named = Link.
- filter([['tail_uuid','=', at object.uuid],
- ['head_uuid','in',uuids_to_add],
- ['link_class','=','name']]).
- collect(&:head_uuid)
- uuids_to_add -= already_named
-
- # Given a name link, we'll try to add the linked object using the
- # same name.
- name_for = {}
- link_selections.
- select { |x| x.link_class == 'name' }.
- each do |link|
- name_for[link.head_uuid] = link.name
- end
+ move_or_copy :copy
+ end
+
+ expose_action :move_selections_into_project do
+ move_or_copy :move
+ end
- uuids_to_add.each do |s|
- name = name_for[s] || s
- begin
- Link.create(tail_uuid: @object.uuid,
- head_uuid: s,
- link_class: 'name',
- name: name)
- rescue
- Link.create(tail_uuid: @object.uuid,
- head_uuid: s,
- link_class: 'name',
- name: name + " (#{Time.now.localtime})")
+ def move_or_copy action
+ uuids_to_add = params["selection"]
+ uuids_to_add.
+ collect { |x| ArvadosBase::resource_class_for_uuid(x) }.
+ uniq.
+ each do |resource_class|
+ resource_class.filter([['uuid','in',uuids_to_add]]).each do |src|
+ if resource_class == Collection
+ dst = Link.new(owner_uuid: @object.uuid,
+ tail_uuid: @object.uuid,
+ head_uuid: src.uuid,
+ link_class: 'name',
+ name: @object.uuid)
+ else
+ case action
+ when :copy
+ dst = src.dup
+ if dst.respond_to? :'name='
+ if dst.name
+ dst.name = "Copy of #{dst.name}"
+ else
+ dst.name = "Copy of unnamed #{dst.class_for_display.downcase}"
+ end
+ end
+ when :move
+ dst = src
+ else
+ raise ArgumentError.new "Unsupported action #{action}"
+ end
+ dst.owner_uuid = @object.uuid
+ dst.tail_uuid = @object.uuid if dst.class == Link
+ end
+ begin
+ dst.save!
+ rescue
+ dst.name += " (#{Time.now.localtime})" if dst.respond_to? :name=
+ dst.save!
+ end
end
end
redirect_to @object
commit 719ba7f6247cf1697d81193b46bd768202ebb064
Author: Tom Clegg <tom at curoverse.com>
Date: Thu Jun 12 11:35:28 2014 -0400
2872: Fix "remove" icon and pencil icon placement.
diff --git a/apps/workbench/app/views/projects/_show_contents_rows.html.erb b/apps/workbench/app/views/projects/_show_contents_rows.html.erb
index 8b19c00..68561f8 100644
--- a/apps/workbench/app/views/projects/_show_contents_rows.html.erb
+++ b/apps/workbench/app/views/projects/_show_contents_rows.html.erb
@@ -9,7 +9,7 @@
<% if project.editable? %>
<%= link_to({action: 'remove_item', id: project.uuid, item_uuid: ((name_link && name_link.uuid) || object.uuid)}, method: :delete, remote: true, data: {confirm: "Remove #{object.class_for_display.downcase} #{name_object.name rescue object.uuid} from this project?", toggle: 'tooltip', placement: 'top'}, class: 'btn btn-sm btn-default btn-nodecorate', title: 'remove') do %>
- <i class="fa fa-fw fa-ban"></i>
+ <i class="fa fa-fw fa-trash-o"></i>
<% end %>
<% else %>
<i class="fa fa-fw"></i><%# placeholder %>
@@ -17,7 +17,7 @@
<%= render :partial => "show_object_button", :locals => {object: object, size: 'sm', name_link: name_link} %>
- <%= render_editable_attribute (name_link || object), 'name', nil, {btnplacement: :left, tiptitle: 'rename'} %>
+ <%= render_editable_attribute (name_link || object), 'name', nil, {tiptitle: 'rename'} %>
</td>
<td class="arv-description-in-table">
<%= render_controller_partial(
commit 965700e2e2e981e1ba56c2101d3df2fd759ddb81
Author: Tom Clegg <tom at curoverse.com>
Date: Thu Jun 12 11:30:25 2014 -0400
2872: Muster all the "move" and "add" buttons up to the right side of the tabs.
diff --git a/apps/workbench/app/views/projects/_show_contents.html.erb b/apps/workbench/app/views/projects/_show_contents.html.erb
index 5132796..3b21b40 100644
--- a/apps/workbench/app/views/projects/_show_contents.html.erb
+++ b/apps/workbench/app/views/projects/_show_contents.html.erb
@@ -11,9 +11,47 @@
<% end %>
<% content_for :tab_line_buttons do %>
- <% if @objects_and_names.empty? %>
- <%= button_to(project_path(id: @object.uuid, return_to: projects_path), method: 'delete', class: 'btn btn-sm btn-primary', data: {confirm: "Really delete project '#{@object.name}'?"}) do %>
- <i class="fa fa-fw fa-trash-o"></i> Delete project
+ <% if @object.editable? %>
+ <%= link_to(
+ choose_collections_path(
+ title: 'Add data to project:',
+ multiple: true,
+ action_name: 'Add',
+ action_href: actions_path(id: @object.uuid),
+ action_method: 'post',
+ action_data: {selection_param: 'selection[]', copy_selections_into_project: @object.uuid, success: 'page-refresh'}.to_json),
+ { class: "btn btn-primary btn-sm", remote: true, method: 'get', data: {'event-after-select' => 'page-refresh'} }) do %>
+ <i class="fa fa-fw fa-plus"></i> Add data
+ <% end %>
+ <%= link_to(
+ choose_pipeline_templates_path(
+ title: 'Choose a pipeline to run:',
+ action_name: 'Next: choose inputs <i class="fa fa-fw fa-arrow-circle-right"></i>',
+ action_href: pipeline_instances_path,
+ action_method: 'post',
+ action_data: {'selection_param' => 'pipeline_instance[pipeline_template_uuid]', 'pipeline_instance[owner_uuid]' => @object.uuid, 'success' => 'redirect-to-created-object'}.to_json),
+ { class: "btn btn-primary btn-sm", remote: true, method: 'get' }) do %>
+ <i class="fa fa-fw fa-gear"></i> Run a pipeline
+ <% end %>
+ <%= link_to projects_path(method: 'post', owner_uuid: @object.uuid), class: 'btn btn-sm btn-primary' do %>
+ <i class="fa fa-fw fa-plus"></i>
+ Add a subproject
+ <% end %>
+ <%= link_to(
+ choose_projects_path(
+ title: 'Move this project to...',
+ editable: true,
+ action_name: 'Move',
+ action_href: project_path(@object.uuid),
+ action_method: 'put',
+ action_data: {selection_param: 'project[owner_uuid]', success: 'page-refresh'}.to_json),
+ { class: "btn btn-sm btn-primary arv-move-to-project", remote: true, method: 'get' }) do %>
+ <i class="fa fa-fw fa-truck"></i> Move to...
+ <% end %>
+ <% if @objects_and_names.empty? %>
+ <%= button_to(project_path(id: @object.uuid, return_to: projects_path), method: 'delete', class: 'btn btn-sm btn-primary', data: {confirm: "Really delete project '#{@object.name}'?"}) do %>
+ <i class="fa fa-fw fa-trash-o"></i> Delete project
+ <% end %>
<% end %>
<% end %>
<% end %>
@@ -42,29 +80,6 @@
%></li>
</ul>
</div>
- <% if @object.editable? %>
- <%= link_to(
- choose_collections_path(
- title: 'Add data to project:',
- multiple: true,
- action_name: 'Add',
- action_href: actions_path(id: @object.uuid),
- action_method: 'post',
- action_data: {selection_param: 'selection[]', copy_selections_into_project: @object.uuid, success: 'page-refresh'}.to_json),
- { class: "btn btn-primary btn-sm", remote: true, method: 'get', data: {'event-after-select' => 'page-refresh'} }) do %>
- <i class="fa fa-fw fa-plus"></i> Add data
- <% end %>
- <%= link_to(
- choose_pipeline_templates_path(
- title: 'Choose a pipeline to run:',
- action_name: 'Next: choose inputs <i class="fa fa-fw fa-arrow-circle-right"></i>',
- action_href: pipeline_instances_path,
- action_method: 'post',
- action_data: {'selection_param' => 'pipeline_instance[pipeline_template_uuid]', 'pipeline_instance[owner_uuid]' => @object.uuid, 'success' => 'redirect-to-created-object'}.to_json),
- { class: "btn btn-primary btn-sm", remote: true, method: 'get' }) do %>
- <i class="fa fa-fw fa-gear"></i> Run a pipeline
- <% end %>
- <% end %>
</div>
<div class="col-sm-3">
<form class="form-inline" role="form">
diff --git a/apps/workbench/app/views/projects/_show_permissions.html.erb b/apps/workbench/app/views/projects/_show_permissions.html.erb
index 9d93ce0..0817062 100644
--- a/apps/workbench/app/views/projects/_show_permissions.html.erb
+++ b/apps/workbench/app/views/projects/_show_permissions.html.erb
@@ -1,6 +1,6 @@
<div>
<div class="row">
- <div class="col-md-6">
+ <div class="col-md-6 col-md-push-6">
<div class="panel panel-default">
<div class="panel-heading">
Additional permissions
@@ -19,7 +19,7 @@
</div>
</div>
</div>
- <div class="col-md-6">
+ <div class="col-md-6 col-md-pull-6">
<% if @object.owner %>
<div class="panel panel-default">
<div class="panel-heading">
@@ -35,15 +35,6 @@
<i class="fa fa-fw fa-folder"></i>
<% end %>
<%= link_to_if_arvados_object @object.owner_uuid, friendly_name: true %>
- <%= button_to('Move to...',
- choose_projects_path(
- title: 'Move to...',
- editable: true,
- action_name: 'Move',
- action_href: project_path(@object.uuid),
- action_method: 'put',
- action_data: {selection_param: 'project[owner_uuid]', success: 'page-refresh'}.to_json),
- { class: "btn btn-default btn-xs arv-move-to-project", remote: true, method: 'get' }) %>
</p>
</div>
</div>
commit b64228f1f547c720b79a242d6d8d368a64923885
Author: Tom Clegg <tom at curoverse.com>
Date: Thu Jun 12 11:29:01 2014 -0400
2872: Show projectless jobs/pipelines in "recent" list too.
diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb
index 6457cd0..3a9ccf2 100644
--- a/apps/workbench/app/controllers/application_controller.rb
+++ b/apps/workbench/app/controllers/application_controller.rb
@@ -587,9 +587,8 @@ class ApplicationController < ActionController::Base
helper_method :recent_jobs_and_pipelines
def recent_jobs_and_pipelines
- in_my_projects = ['owner_uuid','in',my_projects.collect(&:uuid)]
- (Job.limit(10).filter([in_my_projects]) |
- PipelineInstance.limit(10).filter([in_my_projects])).
+ (Job.limit(10) |
+ PipelineInstance.limit(10)).
sort_by do |x|
x.finished_at || x.started_at || x.created_at rescue x.created_at
end
commit 70542a2d6d6a2792f1dc68b1531e783e7611b474
Author: Tom Clegg <tom at curoverse.com>
Date: Thu Jun 12 10:40:00 2014 -0400
2872: Fix tests broken in merge.
diff --git a/apps/workbench/app/controllers/projects_controller.rb b/apps/workbench/app/controllers/projects_controller.rb
index f73b6c0..89a50b2 100644
--- a/apps/workbench/app/controllers/projects_controller.rb
+++ b/apps/workbench/app/controllers/projects_controller.rb
@@ -91,6 +91,9 @@ class ProjectsController < ApplicationController
end
def show
+ if !@object
+ return render_not_found("object not found")
+ end
@objects = @object.contents(limit: 50,
include_linked: true,
offset: params[:offset] || 0)
diff --git a/apps/workbench/app/views/application/_content.html.erb b/apps/workbench/app/views/application/_content.html.erb
index b7f27df..0cd3a2c 100644
--- a/apps/workbench/app/views/application/_content.html.erb
+++ b/apps/workbench/app/views/application/_content.html.erb
@@ -26,7 +26,7 @@
if (!tab_pane_valid_state[pane]) {
tab_pane_valid_state[pane] = true;
$(document).trigger('ajax:send');
- $.ajax('<%=j url_for @object %>?tab_pane='+pane, {dataType: 'html', type: 'GET'}).
+ $.ajax('<%=j url_for() %>?tab_pane='+pane, {dataType: 'html', type: 'GET'}).
done(function(data, status, jqxhr) {
$('#' + pane + ' > div > div').html(data);
$(document).trigger('ajax:complete');
diff --git a/apps/workbench/app/views/collections/show.html.erb b/apps/workbench/app/views/collections/show.html.erb
index f91357b..bf2e7aa 100644
--- a/apps/workbench/app/views/collections/show.html.erb
+++ b/apps/workbench/app/views/collections/show.html.erb
@@ -4,7 +4,7 @@
<div class="panel-heading">
<h3 class="panel-title">
<% i = 0 %>
- <% @folder_links.each do |l| %>
+ <% @project_links.each do |l| %>
<%= if i > 0 then ', ' end %>
<% i += 1 %>
<%= l.name %>
diff --git a/apps/workbench/app/views/layouts/application.html.erb b/apps/workbench/app/views/layouts/application.html.erb
index ec26409..c42abfe 100644
--- a/apps/workbench/app/views/layouts/application.html.erb
+++ b/apps/workbench/app/views/layouts/application.html.erb
@@ -99,8 +99,8 @@
</li>
<% end %>
- <li class="dropdown notification-menu">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="collections-menu">
+ <li class="dropdown selection-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
<span class="fa fa-lg fa-paperclip"></span>
<span class="badge" id="persistent-selection-count"></span>
</a>
diff --git a/apps/workbench/test/integration/pipeline_instances_test.rb b/apps/workbench/test/integration/pipeline_instances_test.rb
index f0620cb..a85fd99 100644
--- a/apps/workbench/test/integration/pipeline_instances_test.rb
+++ b/apps/workbench/test/integration/pipeline_instances_test.rb
@@ -96,7 +96,7 @@ class PipelineInstancesTest < ActionDispatch::IntegrationTest
visit '/projects'
find('.arv-project-list a,button', text: 'A Project').click
- find('#collections-menu').click
+ find('li.selection-menu > a').click
click_button 'Copy selections into this project'
# create a pipeline instance
diff --git a/services/api/test/fixtures/links.yml b/services/api/test/fixtures/links.yml
index 397659e..1729bd2 100644
--- a/services/api/test/fixtures/links.yml
+++ b/services/api/test/fixtures/links.yml
@@ -247,7 +247,7 @@ foo_repository_writable_by_active:
tail_uuid: zzzzz-tpzed-xurymjxw79nv3jz
link_class: permission
name: can_write
- head_uuid: zzzzz-2x53u-382brsig8rp3666
+ head_uuid: zzzzz-s0uqq-382brsig8rp3666
properties: {}
miniadmin_user_is_a_testusergroup_admin:
commit a959f21c8147f26362df392bc3fd3290db69de85
Merge: 70f1004 a9beb0e
Author: Tom Clegg <tom at curoverse.com>
Date: Wed Jun 11 23:57:37 2014 -0400
2872: Merge branch 'master' into 2872-folder-nav
Conflicts:
apps/workbench/app/assets/javascripts/pipeline_instances.js
apps/workbench/app/controllers/application_controller.rb
apps/workbench/app/controllers/collections_controller.rb
apps/workbench/app/controllers/jobs_controller.rb
apps/workbench/app/helpers/application_helper.rb
apps/workbench/app/models/job.rb
apps/workbench/app/views/application/_content.html.erb
apps/workbench/app/views/application/_show_metadata.html.erb
apps/workbench/app/views/pipeline_instances/_show_components.html.erb
diff --cc apps/workbench/app/assets/javascripts/pipeline_instances.js
index 54595ab,c61e336..f206213
--- a/apps/workbench/app/assets/javascripts/pipeline_instances.js
+++ b/apps/workbench/app/assets/javascripts/pipeline_instances.js
@@@ -47,51 -47,19 +47,42 @@@ $(document).on('ready ajax:complete', f
run_pipeline_button_state();
});
- $(document).on('ajax:complete ready', function() {
- var a = $('.arv-log-event-listener');
- if (a.length > 0) {
- $('.arv-log-event-listener').each(function() {
- subscribeToEventLog(this.id);
- });
- }
- });
-
$(document).on('arv-log-event', '.arv-log-event-handler-append-logs', function(event, eventData){
- var parsedData = JSON.parse(eventData);
+ var wasatbottom = ($(this).scrollTop() + $(this).height() >=
+ this.scrollHeight);
+ var parsedData = JSON.parse(eventData);
+ var propertyText = undefined;
+ var properties = parsedData.properties;
- var propertyText = undefined
-
- var properties = parsedData.properties;
if (properties !== null) {
- propertyText = properties.text;
+ propertyText = properties.text;
}
-
if (propertyText !== undefined) {
- $(this).append(propertyText + "<br/>");
+ $(this).append(propertyText + "<br/>");
} else {
- $(this).append(parsedData.summary + "<br/>");
+ $(this).append(parsedData.summary + "<br/>");
}
+ if (wasatbottom)
+ this.scrollTop = this.scrollHeight;
+}).on('ready ajax:complete', function(){
+ $('.arv-log-event-handler-append-logs').each(function() {
+ this.scrollTop = this.scrollHeight;
+ });
});
+
+var showhide_compare = function() {
+ var form = $('form#compare')[0];
+ $('input[type=hidden][name="uuids[]"]', form).remove();
+ $('input[type=submit]', form).prop('disabled',true).show();
+ var checked_inputs = $('[data-object-uuid*=-d1hrv-] input[name="uuids[]"]:checked');
+ if (checked_inputs.length >= 2 && checked_inputs.length <= 3) {
+ checked_inputs.each(function(){
+ if(this.checked) {
+ $('input[type=submit]', form).prop('disabled',false).show();
+ $(form).append($('<input type="hidden" name="uuids[]"/>').val(this.value));
+ }
+ });
+ }
+};
+$('[data-object-uuid*=-d1hrv-] input[name="uuids[]"]').on('click', showhide_compare);
+showhide_compare();
diff --cc apps/workbench/app/controllers/application_controller.rb
index 48b508a,a0cadb2..6457cd0
--- a/apps/workbench/app/controllers/application_controller.rb
+++ b/apps/workbench/app/controllers/application_controller.rb
@@@ -85,32 -100,10 +85,44 @@@ class ApplicationController < ActionCon
end
@objects ||= model_class
- @objects = @objects.filter(@filters).limit(@limit).offset(@offset).all
+ @objects = @objects.filter(@filters).limit(@limit).offset(@offset)
+ end
+
++ def render_index
++ respond_to do |f|
++ f.json { render json: @objects }
++ f.html {
++ if params['tab_pane']
++ comparable = self.respond_to? :compare
++ render(partial: 'show_' + params['tab_pane'].downcase,
++ locals: { comparable: comparable, objects: @objects })
++ else
++ render
++ end
++ }
++ f.js { render }
++ end
++ end
++
++ def index
++ find_objects_for_index if !@objects
+ render_index
+ end
+
+ helper_method :next_page_offset
+ def next_page_offset
+ if @objects.respond_to?(:result_offset) and
+ @objects.respond_to?(:result_limit) and
+ @objects.respond_to?(:items_available)
+ next_offset = @objects.result_offset + @objects.result_limit
+ if next_offset < @objects.items_available
+ next_offset
+ else
+ nil
+ end
+ end
+ end
+
- def index
- find_objects_for_index if !@objects
- respond_to do |f|
- f.json { render json: @objects }
- f.html { render }
- f.js { render }
- end
- end
-
def show
if !@object
return render_not_found("object not found")
@@@ -118,10 -111,16 +130,14 @@@
respond_to do |f|
f.json { render json: @object.attributes.merge(href: url_for(@object)) }
f.html {
- if request.method.in? ['GET', 'HEAD']
+ if params['tab_pane']
+ comparable = self.respond_to? :compare
+ render(partial: 'show_' + params['tab_pane'].downcase,
+ locals: { comparable: comparable, objects: @objects })
++ elsif request.method.in? ['GET', 'HEAD']
+ render
else
- if request.method == 'GET'
- render
- else
- redirect_to params[:return_to] || @object
- end
+ redirect_to params[:return_to] || @object
end
}
f.js { render }
@@@ -186,29 -163,20 +202,38 @@@
@new_resource_attrs ||= params[model_class.to_s.underscore.singularize]
@new_resource_attrs ||= {}
@new_resource_attrs.reject! { |k,v| k.to_s == 'uuid' }
- @object ||= model_class.new @new_resource_attrs
- @object.save!
- show
+ @object ||= model_class.new @new_resource_attrs, params["options"]
+ if @object.save
+ respond_to do |f|
+ f.json { render json: @object.attributes.merge(href: url_for(@object)) }
+ f.html {
+ redirect_to @object
+ }
+ f.js { render }
+ end
+ else
+ self.render_error status: 422
+ end
end
+ # Clone the given object, merging any attribute values supplied as
+ # with a create action.
+ def copy
+ @new_resource_attrs ||= params[model_class.to_s.underscore.singularize]
+ @new_resource_attrs ||= {}
+ @object = @object.dup
+ @object.update_attributes @new_resource_attrs
+ if not @new_resource_attrs[:name] and @object.respond_to? :name
+ if @object.name and @object.name != ''
+ @object.name = "Copy of #{@object.name}"
+ else
+ @object.name = "Copy of unnamed #{@object.class_for_display.downcase}"
+ end
+ end
+ @object.save!
+ show
+ end
+
def destroy
if @object.destroy
respond_to do |f|
@@@ -325,7 -297,17 +360,17 @@@
# call to verify its authenticity.
if verify_api_token
session[:arvados_api_token] = params[:api_token]
+ u = User.current
+ session[:user] = {
+ uuid: u.uuid,
+ email: u.email,
+ first_name: u.first_name,
+ last_name: u.last_name,
+ is_active: u.is_active,
+ is_admin: u.is_admin,
+ prefs: u.prefs
+ }
- if !request.format.json? and request.method == 'GET'
+ if !request.format.json? and request.method.in? ['GET', 'HEAD']
# Repeat this request with api_token in the (new) session
# cookie instead of the query string. This prevents API
# tokens from appearing in (and being inadvisedly copied
@@@ -532,60 -498,171 +579,228 @@@
end
end
+ helper_method :projects_shared_with_me
+ def projects_shared_with_me
+ my_project_uuids = my_projects.collect &:uuid
+ all_projects.reject { |x| x.uuid.in? my_project_uuids }
+ end
+
+ helper_method :recent_jobs_and_pipelines
+ def recent_jobs_and_pipelines
+ in_my_projects = ['owner_uuid','in',my_projects.collect(&:uuid)]
+ (Job.limit(10).filter([in_my_projects]) |
+ PipelineInstance.limit(10).filter([in_my_projects])).
+ sort_by do |x|
+ x.finished_at || x.started_at || x.created_at rescue x.created_at
+ end
+ end
+
+ helper_method :get_object
+ def get_object uuid
+ if @get_object.nil? and @objects
+ @get_object = @objects.each_with_object({}) do |object, h|
+ h[object.uuid] = object
+ end
+ end
+ @get_object ||= {}
+ @get_object[uuid]
+ end
+
+ helper_method :project_breadcrumbs
+ def project_breadcrumbs
+ crumbs = []
+ current = @name_link || @object
+ while current
+ if current.is_a?(Group) and current.group_class.in?(['project','folder'])
+ crumbs.prepend current
+ end
+ if current.is_a? Link
+ current = Group.find?(current.tail_uuid)
+ else
+ current = Group.find?(current.owner_uuid)
+ end
+ end
+ crumbs
+ end
+
+ helper_method :current_project_uuid
+ def current_project_uuid
+ if @object.is_a? Group and @object.group_class.in?(['project','folder'])
+ @object.uuid
+ elsif @name_link.andand.tail_uuid
+ @name_link.tail_uuid
+ elsif @object and resource_class_for_uuid(@object.owner_uuid) == Group
+ @object.owner_uuid
+ else
+ nil
+ end
+ end
++
+ # helper method to get links for given object or uuid
+ helper_method :links_for_object
+ def links_for_object object_or_uuid
+ raise ArgumentError, 'No input argument' unless object_or_uuid
+ preload_links_for_objects([object_or_uuid])
+ uuid = object_or_uuid.is_a?(String) ? object_or_uuid : object_or_uuid.uuid
+ @all_links_for[uuid] ||= []
+ end
+
+ # helper method to preload links for given objects and uuids
+ helper_method :preload_links_for_objects
+ def preload_links_for_objects objects_and_uuids
+ @all_links_for ||= {}
+
+ raise ArgumentError, 'Argument is not an array' unless objects_and_uuids.is_a? Array
+ return @all_links_for if objects_and_uuids.empty?
+
+ uuids = objects_and_uuids.collect { |x| x.is_a?(String) ? x : x.uuid }
+
+ # if already preloaded for all of these uuids, return
+ if not uuids.select { |x| @all_links_for[x].nil? }.any?
+ return @all_links_for
+ end
+
+ uuids.each do |x|
+ @all_links_for[x] = []
+ end
+
+ # TODO: make sure we get every page of results from API server
+ Link.filter([['head_uuid', 'in', uuids]]).each do |link|
+ @all_links_for[link.head_uuid] << link
+ end
+ @all_links_for
+ end
+
+ # helper method to get a certain number of objects of a specific type
+ # this can be used to replace any uses of: "dataclass.limit(n)"
+ helper_method :get_n_objects_of_class
+ def get_n_objects_of_class dataclass, size
+ @objects_map_for ||= {}
+
+ raise ArgumentError, 'Argument is not a data class' unless dataclass.is_a? Class
+ raise ArgumentError, 'Argument is not a valid limit size' unless (size && size>0)
+
+ # if the objects_map_for has a value for this dataclass, and the
+ # size used to retrieve those objects is equal, return it
+ size_key = "#{dataclass.name}_size"
+ if @objects_map_for[dataclass.name] && @objects_map_for[size_key] &&
+ (@objects_map_for[size_key] == size)
+ return @objects_map_for[dataclass.name]
+ end
+
+ @objects_map_for[size_key] = size
+ @objects_map_for[dataclass.name] = dataclass.limit(size)
+ end
+
+ # helper method to get collections for the given uuid
+ helper_method :collections_for_object
+ def collections_for_object uuid
+ raise ArgumentError, 'No input argument' unless uuid
+ preload_collections_for_objects([uuid])
+ @all_collections_for[uuid] ||= []
+ end
+
+ # helper method to preload collections for the given uuids
+ helper_method :preload_collections_for_objects
+ def preload_collections_for_objects uuids
+ @all_collections_for ||= {}
+
+ raise ArgumentError, 'Argument is not an array' unless uuids.is_a? Array
+ return @all_collections_for if uuids.empty?
+
+ # if already preloaded for all of these uuids, return
+ if not uuids.select { |x| @all_collections_for[x].nil? }.any?
+ return @all_collections_for
+ end
+
+ uuids.each do |x|
+ @all_collections_for[x] = []
+ end
+
+ # TODO: make sure we get every page of results from API server
+ Collection.where(uuid: uuids).each do |collection|
+ @all_collections_for[collection.uuid] << collection
+ end
+ @all_collections_for
+ end
+
+ # helper method to get log collections for the given log
+ helper_method :log_collections_for_object
+ def log_collections_for_object log
+ raise ArgumentError, 'No input argument' unless log
+
+ preload_log_collections_for_objects([log])
+
+ uuid = log
+ fixup = /([a-f0-9]{32}\+\d+)(\+?.*)/.match(log)
+ if fixup && fixup.size>1
+ uuid = fixup[1]
+ end
+
+ @all_log_collections_for[uuid] ||= []
+ end
+
+ # helper method to preload collections for the given uuids
+ helper_method :preload_log_collections_for_objects
+ def preload_log_collections_for_objects logs
+ @all_log_collections_for ||= {}
+
+ raise ArgumentError, 'Argument is not an array' unless logs.is_a? Array
+ return @all_log_collections_for if logs.empty?
+
+ uuids = []
+ logs.each do |log|
+ fixup = /([a-f0-9]{32}\+\d+)(\+?.*)/.match(log)
+ if fixup && fixup.size>1
+ uuids << fixup[1]
+ else
+ uuids << log
+ end
+ end
+
+ # if already preloaded for all of these uuids, return
+ if not uuids.select { |x| @all_log_collections_for[x].nil? }.any?
+ return @all_log_collections_for
+ end
+
+ uuids.each do |x|
+ @all_log_collections_for[x] = []
+ end
+
+ # TODO: make sure we get every page of results from API server
+ Collection.where(uuid: uuids).each do |collection|
+ @all_log_collections_for[collection.uuid] << collection
+ end
+ @all_log_collections_for
+ end
+
+ # helper method to get object of a given dataclass and uuid
+ helper_method :object_for_dataclass
+ def object_for_dataclass dataclass, uuid
+ raise ArgumentError, 'No input argument dataclass' unless (dataclass && uuid)
+ preload_objects_for_dataclass(dataclass, [uuid])
+ @objects_for[uuid]
+ end
+
+ # helper method to preload objects for given dataclass and uuids
+ helper_method :preload_objects_for_dataclass
+ def preload_objects_for_dataclass dataclass, uuids
+ @objects_for ||= {}
+
+ raise ArgumentError, 'Argument is not a data class' unless dataclass.is_a? Class
+ raise ArgumentError, 'Argument is not an array' unless uuids.is_a? Array
+
+ return @objects_for if uuids.empty?
+
+ # if already preloaded for all of these uuids, return
+ if not uuids.select { |x| @objects_for[x].nil? }.any?
+ return @objects_for
+ end
+
+ dataclass.where(uuid: uuids).each do |obj|
+ @objects_for[obj.uuid] = obj
+ end
+ @objects_for
+ end
+
end
diff --cc apps/workbench/app/controllers/collections_controller.rb
index 0148b72,6a5df87..88dadbb
--- a/apps/workbench/app/controllers/collections_controller.rb
+++ b/apps/workbench/app/controllers/collections_controller.rb
@@@ -157,10 -143,10 +159,10 @@@ class CollectionsController < Applicati
end
@output_of = jobs_with.call(output: @object.uuid)
@log_of = jobs_with.call(log: @object.uuid)
- project_links = Link.limit(RELATION_LIMIT).order("modified_at DESC")
- @folder_links = Link.limit(RELATION_LIMIT).order("modified_at DESC")
++ @project_links = Link.limit(RELATION_LIMIT).order("modified_at DESC")
.where(head_uuid: @object.uuid, link_class: 'name').results
- project_hash = Group.where(uuid: project_links.map(&:tail_uuid)).to_hash
- @projects = project_links.map { |link| project_hash[link.tail_uuid] }
- folder_hash = Group.where(uuid: @folder_links.map(&:tail_uuid)).to_hash
- @folders = @folder_links.map { |link| folder_hash[link.tail_uuid] }
++ project_hash = Group.where(uuid: @project_links.map(&:tail_uuid)).to_hash
++ @projects = @project_links.map { |link| project_hash[link.tail_uuid] }
@permissions = Link.limit(RELATION_LIMIT).order("modified_at DESC")
.where(head_uuid: @object.uuid, link_class: 'permission',
name: 'can_read').results
diff --cc apps/workbench/app/controllers/jobs_controller.rb
index 8743a6f,b7526c9..ff3ac6b
--- a/apps/workbench/app/controllers/jobs_controller.rb
+++ b/apps/workbench/app/controllers/jobs_controller.rb
@@@ -44,6 -53,6 +53,6 @@@ class JobsController < ApplicationContr
end
def show_pane_list
- %w(Details Provenance Advanced)
- %w(Status Attributes Provenance Metadata JSON API)
++ %w(Status Details Provenance Advanced)
end
end
diff --cc apps/workbench/app/controllers/pipeline_instances_controller.rb
index ccbd06f,500927b..a4a9d69
--- a/apps/workbench/app/controllers/pipeline_instances_controller.rb
+++ b/apps/workbench/app/controllers/pipeline_instances_controller.rb
@@@ -3,44 -3,10 +3,46 @@@ class PipelineInstancesController < App
before_filter :find_objects_by_uuid, only: :compare
include PipelineInstancesHelper
+ def copy
+ @object = @object.dup
+ @object.components.each do |cname, component|
+ component.delete :job
+ end
+ @object.state = 'New'
+ super
+ end
+
+ def update
+ @updates ||= params[@object.class.to_s.underscore.singularize.to_sym]
+ if (components = @updates[:components])
+ components.each do |cname, component|
+ if component[:script_parameters]
+ component[:script_parameters].each do |param, value_info|
+ if value_info.is_a? Hash
+ if resource_class_for_uuid(value_info[:value]) == Link
+ # Use the link target, not the link itself, as script
+ # parameter; but keep the link info around as well.
+ link = Link.find value_info[:value]
+ value_info[:value] = link.head_uuid
+ value_info[:link_uuid] = link.uuid
+ value_info[:link_name] = link.name
+ else
+ # Delete stale link_uuid and link_name data.
+ value_info[:link_uuid] = nil
+ value_info[:link_name] = nil
+ end
+ end
+ end
+ end
+ end
+ end
+ super
+ end
+
def graph(pipelines)
- count = {}
+ return nil, nil if params['tab_pane'] != "Graph"
+
+ count = {}
provenance = {}
pips = {}
n = 1
diff --cc apps/workbench/app/helpers/application_helper.rb
index 784958b,2b7ec14..66267e0
--- a/apps/workbench/app/helpers/application_helper.rb
+++ b/apps/workbench/app/helpers/application_helper.rb
@@@ -294,12 -236,37 +300,28 @@@ module ApplicationHelpe
datatype = 'text'
end
- id = "#{object.uuid}-#{subattr.join('-')}"
- dn = "[#{attr}]"
- subattr.each do |a|
- dn += "[#{a}]"
- end
- if value_info.is_a? Hash
- dn += '[value]'
- end
-
+ # preload data
+ preload_uuids = []
+ items = []
selectables = []
+
attrtext = attrvalue
if dataclass and dataclass.is_a? Class
+ objects = get_n_objects_of_class dataclass, 10
+ objects.each do |item|
+ items << item
+ preload_uuids << item.uuid
+ end
if attrvalue and !attrvalue.empty?
- Link.where(head_uuid: attrvalue, link_class: ["tag", "identifier"]).each do |tag|
- attrtext += " [#{tag.name}]"
+ preload_uuids << attrvalue
+ end
+ preload_links_for_objects preload_uuids
+
+ if attrvalue and !attrvalue.empty?
+ links_for_object(attrvalue).each do |link|
+ if link.link_class.in? ["tag", "identifier"]
+ attrtext += " [#{link.name}]"
+ end
end
selectables.append({name: attrtext, uuid: attrvalue, type: dataclass.to_s})
end
diff --cc apps/workbench/app/models/job.rb
index 2a69c28,173d3a0..aac6168
--- a/apps/workbench/app/models/job.rb
+++ b/apps/workbench/app/models/job.rb
@@@ -15,18 -11,7 +15,22 @@@ class Job < ArvadosBas
false
end
+ def default_name
+ if script
+ x = "\"#{script}\" job"
+ else
+ x = super
+ end
+ if finished_at
+ x += " finished #{finished_at.strftime('%b %-d')}"
+ elsif started_at
+ x += " started #{started_at.strftime('%b %-d')}"
+ elsif created_at
+ x += " submitted #{created_at.strftime('%b %-d')}"
+ end
+ end
++
+ def cancel
+ arvados_api_client.api "jobs/#{self.uuid}/", "cancel", {}
+ end
end
diff --cc apps/workbench/app/views/application/_content.html.erb
index e634362,353bd74..b7f27df
--- a/apps/workbench/app/views/application/_content.html.erb
+++ b/apps/workbench/app/views/application/_content.html.erb
@@@ -1,24 -1,34 +1,55 @@@
+<% content_for :content_top do %>
+ <% if @object and not @object.is_a?(Group) and @object.class.goes_in_projects? and @object.owner_uuid == current_user.uuid %>
+ <div class="pull-right" style="width: 40%">
+ <div class="alert alert-warning alert-dismissable">
+ <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
+ <strong>Hey.</strong> This <%= @object.class_for_display.downcase %> belongs to your account, but it's not in any of your projects. If you want it to be easy to find in the future, you should move it to a project.<br />
+ <%= button_to(choose_projects_path(
+ title: 'Move to...',
+ editable: true,
+ action_name: 'Move',
+ action_href: url_for(action: :update),
+ action_method: 'patch',
+ action_data: {selection_param: @object.resource_param_name+'[owner_uuid]', success: 'page-refresh'}.to_json),
+ { class: "btn btn-primary btn-sm", remote: true, method: 'get' }) do %>
+ <i class="fa fa-fw fa-folder"></i> Choose a project...
+ <% end %>
+ </div>
+ </div>
+ <% end %>
+<% end %>
+
+ <% content_for :js do %>
+ tab_pane_valid_state = {};
+
+ function ajaxRefreshTabPane(pane) {
+ if (!tab_pane_valid_state[pane]) {
+ tab_pane_valid_state[pane] = true;
+ $(document).trigger('ajax:send');
+ $.ajax('<%=j url_for @object %>?tab_pane='+pane, {dataType: 'html', type: 'GET'}).
+ done(function(data, status, jqxhr) {
+ $('#' + pane + ' > div > div').html(data);
+ $(document).trigger('ajax:complete');
+ ajaxRefreshTabPane(pane);
+ });
+ }
+ }
+
+ $(window).on('load', smart_scroll_fixup);
+ $(document).on('shown.bs.tab', 'ul.nav-tabs > li > a', smart_scroll_fixup);
+
+ $(document).on('shown.bs.tab', function(e) {
+ ajaxRefreshTabPane(e.target.id.slice(0, -4));
+ });
+
+ $(document).on('arv-log-event', function() {
+ <% pane_list.each do |pane| %>
+ tab_pane_valid_state['<%=j pane %>'] = false;
+ <% end %>
+ ajaxRefreshTabPane($('.tab-pane.active')[0].id);
+ });
+ <% end %>
+
<% content_for :tab_panes do %>
<% comparable = controller.respond_to? :compare %>
@@@ -34,10 -39,36 +60,36 @@@
<% end %>
</ul>
<div class="tab-content">
- <% panes.each_with_index do |(pane, content), i| %>
- <div id="<%= pane %>" class="tab-pane fade <%= 'in active' if i==0 %>">
+ <% pane_list.each_with_index do |pane, i| %>
+ <div id="<%= pane %>"
+ class="tab-pane fade <%= 'in active' if i==0 %> arv-log-event-listener"
+ <% if controller.action_name == "index" %>
+ data-object-kind="arvados#<%= ArvadosApiClient.class_kind controller.model_class %>"
+ <% else %>
+ data-object-uuid="<%= @object.uuid %>"
+ <% end %>
+ >
+
+ <% content_for :js do %>
+ <% if i == 0 %>
+ tab_pane_valid_state['<%=j pane %>'] = true;
+ <% else %>
+ tab_pane_valid_state['<%=j pane %>'] = false;
+ $(document).on('ready', function() {
+ ajaxRefreshTabPane('<%=j pane %>');
+ });
+ <% end %>
+ <% end %>
+
- <div class="smart-scroll" style="margin-top:0.5em;">
+ <div id="<%= pane %>-scroll" class="<%= 'smart-scroll' if pane.match(/graph/) %>" style="margin-top:0.5em;">
- <%= content %>
+ <div class="pane-content">
+ <% if i == 0 %>
+ <%= render(partial: 'show_' + pane.downcase,
+ locals: { comparable: comparable, objects: @objects }) %>
+ <% else %>
+ <%= image_tag 'ajax-loader.gif' %>
+ <% end %>
+ </div>
</div>
</div>
<% end %>
diff --cc apps/workbench/app/views/application/_show_advanced_metadata.html.erb
index 68e4298,0000000..c036b36
mode 100644,000000..100644
--- a/apps/workbench/app/views/application/_show_advanced_metadata.html.erb
+++ b/apps/workbench/app/views/application/_show_advanced_metadata.html.erb
@@@ -1,44 -1,0 +1,56 @@@
+<% outgoing = Link.where(tail_uuid: @object.uuid) %>
+<% incoming = Link.where(head_uuid: @object.uuid) %>
+
++<%
++ preload_uuids = []
++ preload_head_uuids = []
++ outgoing.results.each do |link|
++ preload_uuids << link.uuid
++ preload_uuids << link.head_uuid
++ preload_head_uuids << link.head_uuid
++ end
++ preload_collections_for_objects preload_uuids
++ preload_links_for_objects preload_head_uuids
++%>
++
+<% if (outgoing | incoming).any? %>
+<table class="table topalign">
+ <colgroup>
+ <col width="20%" />
+ <col width="10%" />
+ <col width="10%" />
+ <col width="20%" />
+ <col width="20%" />
+ <col width="20%" />
+ </colgroup>
+ <thead>
+ <tr>
+ <th></th>
+ <th>link_class</th>
+ <th>name</th>
+ <th>tail</th>
+ <th>head</th>
+ <th>properties</th>
+ </tr>
+ </thead>
+ <tbody>
+ <% (outgoing | incoming).each do |link| %>
+ <tr>
+ <td>
+ <%= render partial: 'show_object_button', locals: { object: link, size: 'xs' } %>
+ <span class="arvados-uuid"><%= link.uuid %></span>
+ </td>
+ <td><%= link.link_class %></td>
+ <td><%= link.name %></td>
+ <td><%= link.tail_uuid == object.uuid ? 'this' : (render partial: 'application/arvados_attr_value', locals: { obj: link, attr: "tail_uuid", attrvalue: link.tail_uuid, editable: false }) %></td>
+ <td><%= link.head_uuid == object.uuid ? 'this' : (render partial: 'application/arvados_attr_value', locals: { obj: link, attr: "head_uuid", attrvalue: link.head_uuid, editable: false }) %></td>
+ <td><%= render partial: 'application/arvados_attr_value', locals: { obj: link, attr: "properties", attrvalue: link.properties, editable: false } %></td>
+ </tr>
+ <% end %>
+ </tbody>
+</table>
+<% else %>
+<span class="deemphasize">
+ (No metadata links found)
+</span>
+<% end %>
commit 70f1004b17fac3c772c8f938b5a72ff3a3ebc67a
Author: Tom Clegg <tom at curoverse.com>
Date: Wed Jun 11 23:31:41 2014 -0400
2872: Fix bookmark bar causing spurious window width.
diff --git a/apps/workbench/app/assets/stylesheets/application.css.scss b/apps/workbench/app/assets/stylesheets/application.css.scss
index f507ccd..c01195c 100644
--- a/apps/workbench/app/assets/stylesheets/application.css.scss
+++ b/apps/workbench/app/assets/stylesheets/application.css.scss
@@ -104,8 +104,9 @@ nav.navbar-fixed-top {
.navbar.breadcrumbs {
line-height: 50px;
border-radius: 0;
- width: 10000px;
margin-bottom: 0;
+ border-right: 0;
+ border-left: 0;
}
.navbar.breadcrumbs .nav > li > a,
.navbar.breadcrumbs .nav > li {
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list