[ARVADOS] updated: c19ef999c3b938e6d3cdc3746fab5bad8aba3403

git at public.curoverse.com git at public.curoverse.com
Thu May 1 22:58:29 EDT 2014


Summary of changes:
 .../app/assets/javascripts/application.js          |    7 +
 .../app/assets/javascripts/collections.js          |   59 ++
 apps/workbench/app/assets/javascripts/folders.js   |    7 +
 .../{collections.js.coffee => folders.js.coffee}   |    0
 apps/workbench/app/assets/javascripts/selection.js |   18 +-
 .../app/assets/stylesheets/application.css.scss    |   23 +
 .../app/assets/stylesheets/collections.css.scss    |   21 +-
 .../{links.css.scss => folders.css.scss}           |    2 +-
 .../app/assets/stylesheets/sb-admin.css.scss       |    5 +-
 .../workbench/app/assets/stylesheets/selection.css |   22 +-
 .../app/controllers/actions_controller.rb          |   42 ++-
 .../app/controllers/application_controller.rb      |   49 ++-
 .../app/controllers/collections_controller.rb      |   34 ++-
 .../app/controllers/folders_controller.rb          |   69 +++
 .../workbench/app/controllers/groups_controller.rb |   12 +-
 apps/workbench/app/controllers/users_controller.rb |   36 +-
 .../app/controllers/websocket_controller.rb        |   10 +
 apps/workbench/app/helpers/application_helper.rb   |    2 +-
 apps/workbench/app/helpers/folders_helper.rb       |    2 +
 apps/workbench/app/models/arvados_base.rb          |   30 +-
 apps/workbench/app/models/arvados_resource_list.rb |    3 +-
 apps/workbench/app/models/group.rb                 |    8 +-
 apps/workbench/app/models/log.rb                   |    5 +
 apps/workbench/app/models/user.rb                  |    9 -
 .../app/views/application/_content.html.erb        |    2 +-
 .../views/application/_show_object_button.html.erb |    3 +
 .../app/views/application/_show_recent.html.erb    |   21 +-
 .../workbench/app/views/application/index.html.erb |    6 +-
 .../app/views/collections/_index_tbody.html.erb    |   10 +-
 .../app/views/collections/_show_files.html.erb     |   12 +
 .../app/views/collections/_show_recent.html.erb    |    8 +-
 .../app/views/collections/_toggle_persist.html.erb |    3 +
 .../app/views/folders/_show_my_folders.html.erb    |    2 +
 .../views/folders/_show_shared_with_me.html.erb    |    2 +
 apps/workbench/app/views/folders/show.html.erb     |  183 +++++++
 .../app/views/groups/_show_recent.html.erb         |    2 +-
 apps/workbench/app/views/groups/show.html.erb      |  212 --------
 .../app/views/layouts/application.html.erb         |   96 ++--
 apps/workbench/app/views/logs/show.html.erb        |    1 -
 apps/workbench/app/views/users/_tables.html.erb    |  120 +++--
 apps/workbench/app/views/websocket/index.html.erb  |   34 ++
 apps/workbench/config/routes.rb                    |    7 +-
 .../folders_controller_test.rb}                    |    2 +-
 .../workbench/test/integration/collections_test.rb |   42 ++
 apps/workbench/test/integration/folders_test.rb    |   24 +
 apps/workbench/test/integration/smoke_test.rb      |    2 +-
 apps/workbench/test/integration/users_test.rb      |   49 +-
 .../test/integration/virtual_machines_test.rb      |    4 +-
 apps/workbench/test/unit/group_test.rb             |   12 +-
 .../test/unit/helpers/folders_helper_test.rb       |    4 +
 apps/workbench/test/unit/user_test.rb              |   12 -
 doc/api/methods/groups.html.textile.liquid         |   26 +-
 doc/api/methods/users.html.textile.liquid          |   12 -
 sdk/cli/bin/arv-run-pipeline-instance              |    4 +-
 sdk/ruby/lib/arvados.rb                            |   36 +-
 services/api/Gemfile                               |    5 +
 services/api/Gemfile.lock                          |   12 +
 .../api/app/controllers/application_controller.rb  |  304 +++--------
 .../app/controllers/arvados/v1/nodes_controller.rb |    2 +-
 .../controllers/arvados/v1/schema_controller.rb    |    6 +
 services/api/app/middlewares/arvados_api_token.rb  |   61 +++
 services/api/app/middlewares/rack_socket.rb        |   86 +++
 .../api/app/models/api_client_authorization.rb     |   12 +
 services/api/app/models/arvados_model.rb           |   93 +++-
 services/api/app/models/blob.rb                    |   19 +-
 services/api/app/models/link.rb                    |   11 +
 services/api/app/models/log.rb                     |    8 +-
 services/api/app/models/node.rb                    |    2 +-
 services/api/config/application.yml.example        |    7 +
 services/api/config/initializers/authorization.rb  |    5 +
 services/api/config/initializers/eventbus.rb       |   18 +
 services/api/config/routes.rb                      |    3 +-
 .../20140423132913_add_object_owner_to_logs.rb     |   27 +
 ...0140501165548_add_unique_name_index_to_links.rb |   13 +
 services/api/db/schema.rb                          |    7 +-
 services/api/lib/current_api_client.rb             |   13 -
 services/api/lib/eventbus.rb                       |  226 ++++++++
 services/api/lib/load_param.rb                     |   88 +++
 services/api/lib/record_filters.rb                 |   75 +++
 .../test/fixtures/api_client_authorizations.yml    |   15 +
 services/api/test/fixtures/links.yml               |   32 +-
 services/api/test/fixtures/logs.yml                |   31 +-
 services/api/test/fixtures/repositories.yml        |    9 +-
 services/api/test/fixtures/specimens.yml           |   24 +-
 .../arvados/v1/groups_controller_test.rb           |   78 +++-
 .../functional/arvados/v1/links_controller_test.rb |   13 +
 .../functional/arvados/v1/nodes_controller_test.rb |    9 +
 .../functional/arvados/v1/users_controller_test.rb |   76 ---
 .../api_client_authorizations_scopes_test.rb       |   68 +--
 .../api/test/integration/login_workflow_test.rb    |   25 +
 .../api/test/integration/reader_tokens_test.rb     |   85 +++
 services/api/test/integration/websocket_test.rb    |  570 ++++++++++++++++++++
 services/api/test/test_helper.rb                   |   29 +-
 services/api/test/unit/blob_test.rb                |   27 +
 services/api/test/unit/link_test.rb                |   47 ++-
 services/api/test/unit/log_test.rb                 |   21 +
 services/api/test/websocket_runner.rb              |   42 ++
 services/keep/src/keep/keep.go                     |  271 +++-------
 services/keep/src/keep/keep_test.go                |  162 +++---
 services/keep/src/keep/volume.go                   |  129 +++++
 services/keep/src/keep/volume_unix.go              |  295 ++++++++++
 services/keep/src/keep/volume_unix_test.go         |  245 +++++++++
 102 files changed, 3608 insertions(+), 1226 deletions(-)
 create mode 100644 apps/workbench/app/assets/javascripts/collections.js
 create mode 100644 apps/workbench/app/assets/javascripts/folders.js
 rename apps/workbench/app/assets/javascripts/{collections.js.coffee => folders.js.coffee} (100%)
 copy apps/workbench/app/assets/stylesheets/{links.css.scss => folders.css.scss} (64%)
 create mode 100644 apps/workbench/app/controllers/folders_controller.rb
 create mode 100644 apps/workbench/app/controllers/websocket_controller.rb
 create mode 100644 apps/workbench/app/helpers/folders_helper.rb
 create mode 100644 apps/workbench/app/views/application/_show_object_button.html.erb
 create mode 100644 apps/workbench/app/views/collections/_toggle_persist.html.erb
 create mode 100644 apps/workbench/app/views/folders/_show_my_folders.html.erb
 create mode 100644 apps/workbench/app/views/folders/_show_shared_with_me.html.erb
 create mode 100644 apps/workbench/app/views/folders/show.html.erb
 delete mode 100644 apps/workbench/app/views/groups/show.html.erb
 delete mode 100644 apps/workbench/app/views/logs/show.html.erb
 create mode 100644 apps/workbench/app/views/websocket/index.html.erb
 copy apps/workbench/test/{unit/job_test.rb => functional/folders_controller_test.rb} (57%)
 create mode 100644 apps/workbench/test/integration/collections_test.rb
 create mode 100644 apps/workbench/test/integration/folders_test.rb
 create mode 100644 apps/workbench/test/unit/helpers/folders_helper_test.rb
 create mode 100644 services/api/app/middlewares/arvados_api_token.rb
 create mode 100644 services/api/app/middlewares/rack_socket.rb
 create mode 100644 services/api/config/initializers/authorization.rb
 create mode 100644 services/api/config/initializers/eventbus.rb
 create mode 100644 services/api/db/migrate/20140423132913_add_object_owner_to_logs.rb
 create mode 100644 services/api/db/migrate/20140501165548_add_unique_name_index_to_links.rb
 create mode 100644 services/api/lib/eventbus.rb
 create mode 100644 services/api/lib/load_param.rb
 create mode 100644 services/api/lib/record_filters.rb
 create mode 100644 services/api/test/integration/login_workflow_test.rb
 create mode 100644 services/api/test/integration/reader_tokens_test.rb
 create mode 100644 services/api/test/integration/websocket_test.rb
 create mode 100644 services/api/test/websocket_runner.rb
 create mode 100644 services/keep/src/keep/volume.go
 create mode 100644 services/keep/src/keep/volume_unix.go
 create mode 100644 services/keep/src/keep/volume_unix_test.go

       via  c19ef999c3b938e6d3cdc3746fab5bad8aba3403 (commit)
       via  c8444a1f49cb77bc32f62135247f12301f4927d7 (commit)
       via  70fa68ef9087dd85d6e18fba2ef11f94ddeb95a4 (commit)
       via  4aee1d7246e344099fe7e10264d009e49aeafee0 (commit)
       via  2bb2789ff129b4112d81ba343fadfb7ad362ecd1 (commit)
       via  d02c4efcfdbe8f21fba895749988b14b7db41310 (commit)
       via  1c9ae7e8c8d7920602250958333751b769fb3a72 (commit)
       via  b93c1cd880d8367d11bd3fd7574e55f4545a34c5 (commit)
       via  ccce5e8ad71ed2e50ecd57c0f73f1aaafc468539 (commit)
       via  70fddd1f7cacaa0db92b3b76a0baeeddf6f0d9b6 (commit)
       via  83dcc2c95eeb38c6b0f6f7509338aa729f14d762 (commit)
       via  3bd5f6c3f353059c15eeea51b16b2fdee694d504 (commit)
       via  7ce745d5645dc49c2833c1c617fd488bf3a62307 (commit)
       via  fb72864bb6f2ee3ca702b914c97d06a76e01ab0d (commit)
       via  cd08497d1c914cd75fd8be08f9f3ef3bc75485f2 (commit)
       via  6a53a3c5d97d33586567f8df082a725f7d229327 (commit)
       via  681496f40864418fc1ee46277941a40d3445107c (commit)
       via  c6068bbeea3ea9bfee45204c2990caef0d4ec1ae (commit)
       via  ec824d69dee0696b1ca4748fbe5b912634940d53 (commit)
       via  76b9eebf07b424ec2a8fde9b7760b8ce499063bc (commit)
       via  33b49fa0be7d8e0774c80ec315985dcdf8535962 (commit)
       via  83781a4f423a3671a5ec6d4b1cd6a0bbeacef3a6 (commit)
       via  ac317fea1f11179b33eae7e06a60ba60df218f1c (commit)
       via  568ea04cdde8988a675754372f618d937d3757e0 (commit)
       via  fca1b2bd47910761f0c2603e72681670443e4be8 (commit)
       via  4c19fb79d7b96bc18a1843182d3675c7a4de683d (commit)
       via  f23a72b89383c797663b5ec77d342bab20f239f4 (commit)
       via  6177a6474c312d5d5b9c1f0eaa3ebd089a64b5f1 (commit)
       via  9820178bf518d9ddace8c27ea383e5c37d86c8fe (commit)
       via  b7161fff2cb2fdd2bc0975c75f1fbc32f625343b (commit)
       via  5d5c69bb5a60127aa509fac4bdfb8ea915eacadc (commit)
       via  73d73c7b799ddb60363ddf409d8d301b27c82c00 (commit)
       via  02377152d7e368b6b73b2a94ceb68c99f9d55959 (commit)
       via  a6439c7ddc3407193889386051f06df2a1e74ea9 (commit)
       via  0e69f5346c474da7b2244546db4476f8ca21946f (commit)
       via  3063c6106a83102214deb9d86ec621c0bb85d4b7 (commit)
       via  c623120453858c2ce47ab135f250c33a627a344d (commit)
       via  20347d900fb2d75a3f3eef91d4da17a559b0ecd6 (commit)
       via  da67c81ff6cc5fd540c0725de1c8208c2d8933be (commit)
       via  f107a5232d5e8788ae19daf1c5f6639f0c3cdb68 (commit)
       via  7df1885cee1d6eb0f65a010f13ca7e9ff59c80d9 (commit)
       via  c66afecd36cf7d91223b5db79f3e120954f8217d (commit)
       via  57b46f9b292e561739fde3ea098c366db8f4bc23 (commit)
       via  e8f81804c24307b6702b1897c80b4be832254454 (commit)
       via  1812950e91daaf7a1b02e3777c4e1d483b42d018 (commit)
       via  e87cfcde836ef572a722d645655c7a05fb3f473d (commit)
       via  4fb767326911e01898e5ae28a55a1491b9535b36 (commit)
       via  943feeec776bb75c685cbdee9466f8db3cdf5da7 (commit)
       via  1433693e08e2d4052cc94f6a5902523b08bbc1ac (commit)
       via  e20c9587ad703ae8e1f81251a6e209834a52d448 (commit)
       via  a4724fe92e651abb06acf8c5e75184561a55c854 (commit)
       via  208e172287aba3be7cb988a2c416e4281a2e5f60 (commit)
       via  b0c30631bceb2d1837b52d1d3475e52aee4c9c43 (commit)
       via  840e7d7f96f763ae139545dca5d6dfa5a54f6cc6 (commit)
       via  cc22cd28f536fa6fd95732372177d36a94a4c08d (commit)
       via  b421d5c4754315cdd8b70b6bbea5b5f23fb425de (commit)
       via  d39470cbc160b9d51033a564e0b8867388a5a1d3 (commit)
       via  1c45ed6a43b01a4f216cf8877b35d9ad18e1c5b5 (commit)
       via  9cfbcdf804974812b1a4ec514f5dc7902fce6137 (commit)
       via  8adde5132926e8f9cc1b01d79f9307614cc6021e (commit)
       via  8eaad00b025167a7505ba11ad6a05b52a43c2399 (commit)
       via  30f834eef8916c0d613c098a4897ac932a2e0b37 (commit)
       via  c18bde8300e115b215e58d6930d0495b2c33b49f (commit)
       via  4e3ac7f8bafde72ae397f79bfc36409e682b13e5 (commit)
       via  7b9cff04eb463c666b8126ebc6c4dfcc00a536c0 (commit)
       via  f845c0645d9136a1e4ad993ecf34a156367e73b7 (commit)
       via  03e570095885982d23e234bce8e1c068314b63af (commit)
       via  5c2758ca38d01a905253f86e63be3a5fe03a3871 (commit)
       via  52c4f2b7fe631f3d7ad16105cb2f86cf6c004fc8 (commit)
       via  e54bdba73b65e31b03fd1d43bfe69d0f43bbd8d8 (commit)
       via  0eb59e3acf9f13e89bd010f7f65a4d31554183fc (commit)
       via  915de6c854cd559ebd029b24939149e37b18c8cf (commit)
       via  71b1b7b045419817d1c9dc62a3a296b746d9117c (commit)
       via  4ab25f3b39de88d6d2382bb91af9d67bd6de3bd3 (commit)
       via  2ea7a68942928d1d37166726be5114cb7fbdb75b (commit)
       via  f74cbd153b5cbe4e3678c9b86178019f593b553d (commit)
       via  f37f7c068b8d59934c7b0632d531c08470323123 (commit)
       via  e05f165ac12cb54faad707548b8b8f2005f2eef6 (commit)
       via  b860994fa83b9f11b7243220efb8f2fe9b2e2917 (commit)
       via  4fa5a3d3958eae7ecce681e0ea7a4ac8cc43e48d (commit)
       via  a28be6d77750a6cbded994612d95ee973cb4c01e (commit)
       via  58dd340f19c3e0225ad189e60a58872d3aa3f7c2 (commit)
       via  e537bd8dd1ac786164f192374e0d076bdc0327f3 (commit)
       via  995dd33ec5bc9ebb7cc4ff075a1f5e1a4e7db20c (commit)
       via  1c5176d87df0dbd25db6ff1fb2ab82ae17472145 (commit)
       via  5d356c84dcf8f3a2129cce0f4fbfc50f16a8a339 (commit)
       via  4eb42fd91dc5e50840e0d3db5d5201561602a508 (commit)
       via  7c12fc4d989dd2b4c47a174280a4f9526ecb0798 (commit)
       via  f6f07b1856fc0aa32cdf1f96d5bdeb12e9e314ef (commit)
       via  919cf4c2c9f803f0cdb80619bcbf5d23b7c02d25 (commit)
       via  6c0b68255c0c66d90c0473561461d9215860f018 (commit)
       via  9e97504e5f65c8a3a6f1f34da678ac7e1828e8e1 (commit)
       via  62db3393df8d6bc7c48a3c5101468361cb2f3cf3 (commit)
       via  e062efe37ddf066af1c5c762b126bb72766fee25 (commit)
       via  dbce533271fca5a106ab8a00ad2621177445131f (commit)
       via  20334fa95bb7d554c09225c02fae3d4e83c6c6c5 (commit)
       via  0a72fd5c9f764eba4fc295d8beb24ac3d01885c5 (commit)
       via  87f17f28080eef37ad940a039fd1623e72e3058e (commit)
       via  c72f1de32f688690d1161a1852e471e88919e057 (commit)
       via  f0ca76acaa3a4e3713f7aef6a6bb778e6e71e562 (commit)
       via  1f9df3c7140d4eacf58d4e19a7ddc81260296229 (commit)
       via  78b5bfcb1fa832e4460cfaa41f7815ce1d07a9a4 (commit)
       via  93db9aecb724964a37474104243a6d619b56769f (commit)
       via  da3e84a0984d60a2f4bec00672eb766e2e978859 (commit)
       via  aaa65e9d351284278ccb6d3e803fd3dd4f748c31 (commit)
       via  73cf2bb90245787fbbd7c18da51329524c40f6af (commit)
       via  da1614ac6d9b1b2aeba6267b304ce70c1726b608 (commit)
       via  7130989e6493555eba3491cfc9c8dddd1e1a545a (commit)
       via  923e2bd7d962f1a0feefc73ae4f4531c8235a591 (commit)
       via  eca0d3d0a6938e08dde6067c4565754c45f5ebb7 (commit)
       via  04cc77648cc62c73433801475c27ede4ceb76c8b (commit)
       via  fa257c28461627fe6700dd8fd2152e380f8725d4 (commit)
       via  cb52a672642bdec7c6a97868a68bbb9b8daa0efb (commit)
       via  d07a96a0f0c11b98ecc927f0b3e0b052f8ef99f7 (commit)
       via  b66ad0b212a80c117b5b344a715331962d0bfe2d (commit)
       via  e484a466d78c87114779b596d6ecd79f22088ee2 (commit)
       via  aa920f1659aa830861c196617fe664f35b5c12ef (commit)
       via  c283713dc8762c396407f68129fb276dc4a746fc (commit)
       via  4e047434f0c6958db039cf9ab55e3f7f44da44c9 (commit)
       via  7bc20af4935fee1caa566e86a074022f0b60d166 (commit)
       via  8202cb5f1682588e35dcf90519f53d74c06d4aa6 (commit)
      from  420949e37a2903ab87f64f57278dfdc6a261a7f3 (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 c19ef999c3b938e6d3cdc3746fab5bad8aba3403
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 22:58:20 2014 -0400

    Use class_for_display more.

diff --git a/apps/workbench/app/models/arvados_base.rb b/apps/workbench/app/models/arvados_base.rb
index 9229cfc..a4ec7ab 100644
--- a/apps/workbench/app/models/arvados_base.rb
+++ b/apps/workbench/app/models/arvados_base.rb
@@ -310,7 +310,7 @@ class ArvadosBase < ActiveRecord::Base
   end
 
   def content_summary
-    self.class.to_s
+    self.class_for_display
   end
 
   def selection_label
diff --git a/apps/workbench/app/views/folders/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
index 200b0f3..e02e9db 100644
--- a/apps/workbench/app/views/folders/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -139,7 +139,7 @@
                 <%= render :partial => "show_object_button", :locals => {object: object, size: 'xs'} %>
               </td>
               <td>
-                <%= render_editable_attribute name_link, 'name', nil, { 'data-emptytext' => "Unnamed #{object.class}" } %>
+                <%= render_editable_attribute name_link, 'name', nil, { 'data-emptytext' => "Unnamed #{object.class_for_display}" } %>
               </td>
               <td>
                 <%= object.content_summary %>

commit c8444a1f49cb77bc32f62135247f12301f4927d7
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 22:54:40 2014 -0400

    Add folder list to left nav.

diff --git a/apps/workbench/app/assets/stylesheets/application.css.scss b/apps/workbench/app/assets/stylesheets/application.css.scss
index 9259c9e..37e8e72 100644
--- a/apps/workbench/app/assets/stylesheets/application.css.scss
+++ b/apps/workbench/app/assets/stylesheets/application.css.scss
@@ -178,3 +178,7 @@ table.table-fixed-header-row tbody {
     padding-top: 10px;
     padding-bottom: 10px;
 }
+.navbar-nav.side-nav > li.dropdown > ul.dropdown-menu > li > a {
+    padding-top: 5px;
+    padding-bottom: 5px;
+}
diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb
index c7c3520..46b2085 100644
--- a/apps/workbench/app/controllers/application_controller.rb
+++ b/apps/workbench/app/controllers/application_controller.rb
@@ -1,12 +1,14 @@
 class ApplicationController < ActionController::Base
+  ERROR_ACTIONS = [:render_exception, :render_not_found]
   respond_to :html, :json, :js
   protect_from_forgery
   around_filter :thread_clear
   around_filter :thread_with_mandatory_api_token, :except => [:render_exception, :render_not_found]
   around_filter :thread_with_optional_api_token
-  before_filter :find_object_by_uuid, :except => [:index, :render_exception, :render_not_found]
-  before_filter :check_user_agreements, :except => [:render_exception, :render_not_found]
-  before_filter :check_user_notifications, :except => [:render_exception, :render_not_found]
+  before_filter :find_object_by_uuid, :except => [:index] + ERROR_ACTIONS
+  before_filter :check_user_agreements, :except => ERROR_ACTIONS
+  before_filter :check_user_notifications, :except => ERROR_ACTIONS
+  before_filter :check_my_folders, :except => ERROR_ACTIONS
   theme :select_theme
 
   begin
@@ -387,6 +389,15 @@ class ApplicationController < ActionController::Base
     }
   }
 
+  def check_my_folders
+    @my_top_level_folders = lambda do
+      @top_level_folders ||= Group.
+        filter([['group_class','=','folder'],
+                ['owner_uuid','=',current_user.uuid]]).
+        sort_by(&:name)
+    end
+  end
+
   def check_user_notifications
     @notification_count = 0
     @notifications = []
diff --git a/apps/workbench/app/views/layouts/application.html.erb b/apps/workbench/app/views/layouts/application.html.erb
index a7a9750..0923f8f 100644
--- a/apps/workbench/app/views/layouts/application.html.erb
+++ b/apps/workbench/app/views/layouts/application.html.erb
@@ -70,12 +70,24 @@
             <li class="dropdown">
               <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-lg fa-hand-o-up fa-fw"></i> Help <b class="caret"></b></a>
               <ul class="dropdown-menu">
-                <li><%= link_to raw('<i class="fa fa-lg fa-book fa-fw"></i> Tutorials and User guide'), "#{Rails.configuration.arvados_docsite}/user", target: "_blank" %></li>
-                <li><%= link_to raw('<i class="fa fa-lg fa-book fa-fw"></i> API Reference'), "#{Rails.configuration.arvados_docsite}/api", target: "_blank" %></li>
-                <li><%= link_to raw('<i class="fa fa-lg fa-book fa-fw"></i> SDK Reference'), "#{Rails.configuration.arvados_docsite}/sdk", target: "_blank" %></li>
+                <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> Tutorials and User guide'), "#{Rails.configuration.arvados_docsite}/user", target: "_blank" %></li>
+                <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> API Reference'), "#{Rails.configuration.arvados_docsite}/api", target: "_blank" %></li>
+                <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> SDK Reference'), "#{Rails.configuration.arvados_docsite}/sdk", target: "_blank" %></li>
               </ul>
             </li>
 
+            <li class="dropdown">
+              <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-lg fa-folder-o fa-fw"></i> Folders <b class="caret"></b></a>
+              <ul class="dropdown-menu">
+                <li><%= link_to raw('<i class="fa fa-plus fa-fw"></i> Create new folder'), folders_path, method: :post %></li>
+                <% @my_top_level_folders.call.each do |folder| %>
+                <li><%= link_to raw('<i class="fa fa-folder-open fa-fw"></i> ') + folder.name, folder_path(folder) %></li>
+                <% end %>
+                <li><a href="/folders">
+                    <i class="fa fa-ellipsis-h fa-fw"></i> Show all folders
+                </a></li>
+              </ul>
+            </li>
             <li><a href="/collections">
                 <i class="fa fa-lg fa-briefcase fa-fw"></i> Collections (data files)
             </a></li>
@@ -85,9 +97,6 @@
             <li><a href="/pipeline_templates">
                 <i class="fa fa-lg fa-gears fa-fw"></i> Pipeline templates
             </a></li>
-            <li><a href="/folders">
-                <i class="fa fa-lg fa-folder-o fa-fw"></i> Folders
-            </a></li>
             <li> </li>
             <li><a href="/repositories">
                 <i class="fa fa-lg fa-code-fork fa-fw"></i> Repositories

commit 70fa68ef9087dd85d6e18fba2ef11f94ddeb95a4
Merge: 4aee1d7 2bb2789
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 22:24:06 2014 -0400

    Merge branch '2640-folder-api' into 1970-folder-view


commit 4aee1d7246e344099fe7e10264d009e49aeafee0
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 22:23:57 2014 -0400

    Add "Copy selections to current folder" button to selection drop-down.

diff --git a/apps/workbench/app/assets/javascripts/selection.js b/apps/workbench/app/assets/javascripts/selection.js
index d70794d..f8dbed5 100644
--- a/apps/workbench/app/assets/javascripts/selection.js
+++ b/apps/workbench/app/assets/javascripts/selection.js
@@ -49,15 +49,21 @@ jQuery(function($){
     }
 
     var update_count = function(e) {
+        var html;
+        var this_object_uuid = $('#selection-form-content').
+            closest('form').
+            find('input[name=uuid]').val();
         var lst = get_selection_list();
         $("#persistent-selection-count").text(lst.length);
         if (lst.length > 0) {
-            $('#selection-form-content').html(
-                '<li><a href="#" id="clear_selections_button">Clear selections</a></li>'
-                    + '<li><input type="submit" name="combine_selected_files_into_collection" '
-                    + ' id="combine_selected_files_into_collection" '
-                    + ' value="Combine selected collections and files into a new collection" /></li>'
-                    + '<li class="notification"><table style="width: 100%"></table></li>');
+            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_folder" id="copy_selections_into_folder"><i class="fa fa-fw fa-folder-open"></i> Copy selections into this folder</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>'
+                + '<li class="notification"><table style="width: 100%"></table></li>';
+            $('#selection-form-content').html(html);
 
             for (var i = 0; i < lst.length; i++) {
                 $('#selection-form-content > li > table').append("<tr>"
diff --git a/apps/workbench/app/assets/stylesheets/selection.css b/apps/workbench/app/assets/stylesheets/selection.css
index 147d6fe..5e0da41 100644
--- a/apps/workbench/app/assets/stylesheets/selection.css
+++ b/apps/workbench/app/assets/stylesheets/selection.css
@@ -2,18 +2,8 @@
     width: 500px;
 }
 
-#selection-form-content > li > a, #selection-form-content > li > input {
-    display: block;
-    padding: 3px 20px;
-    clear: both;
-    font-weight: normal;
-    line-height: 1.42857;
-    color: rgb(51, 51, 51);
-    white-space: nowrap;    
-    border: none;
-    background: transparent;
-    width: 100%;
-    text-align: left;
+#selection-form-content > li > a, #selection-form-content > li > button {
+    margin: 3px 20px;
 }
 
 #selection-form-content li table tr {
@@ -22,8 +12,6 @@
     border-top: 1px solid rgb(221, 221, 221);
 }
 
-#selection-form-content a:hover, #selection-form-content a:focus, #selection-form-content input:hover, #selection-form-content input:focus, #selection-form-content tr:hover {
-    text-decoration: none;
-    color: rgb(38, 38, 38);
-    background-color: whitesmoke;
-}
\ No newline at end of file
+#selection-form-content li table tr:last-child {
+    border-bottom: 1px solid rgb(221, 221, 221);
+}
diff --git a/apps/workbench/app/controllers/actions_controller.rb b/apps/workbench/app/controllers/actions_controller.rb
index 8a817f0..87b1448 100644
--- a/apps/workbench/app/controllers/actions_controller.rb
+++ b/apps/workbench/app/controllers/actions_controller.rb
@@ -1,8 +1,39 @@
 class ActionsController < ApplicationController
 
-  skip_before_filter :find_object_by_uuid, only: :post
+  @@exposed_actions = {}
+  def self.expose_action method, &block
+    @@exposed_actions[method] = true
+    define_method method, block
+  end
+
+  def model_class
+    ArvadosBase::resource_class_for_uuid(params[:uuid])
+  end
+
+  def post
+    params.keys.collect(&:to_sym).each do |param|
+      if @@exposed_actions[param]
+        return self.send(param.to_s)
+      end
+    end
+    redirect_to :back
+  end
+
+  expose_action :copy_selections_into_folder do
+    already_named = Link.
+      filter([['tail_uuid','=', at object.uuid],
+              ['head_uuid','in',params["selection"]]]).
+      collect(&:head_uuid)
+    (params["selection"] - already_named).each do |s|
+      Link.create(tail_uuid: @object.uuid,
+                  head_uuid: s,
+                  link_class: 'name',
+                  name: "#{s} added #{Time.now}")
+    end
+    redirect_to @object
+  end
 
-  def combine_selected_files_into_collection
+  expose_action :combine_selected_files_into_collection do
     lst = []
     files = []
     params["selection"].each do |s|
@@ -87,11 +118,4 @@ class ActionsController < ApplicationController
     redirect_to controller: 'collections', action: :show, id: newc.uuid
   end
 
-  def post
-    if params["combine_selected_files_into_collection"]
-      combine_selected_files_into_collection
-    else
-      redirect_to :back
-    end
-  end
 end
diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb
index e9d4dd5..c7c3520 100644
--- a/apps/workbench/app/controllers/application_controller.rb
+++ b/apps/workbench/app/controllers/application_controller.rb
@@ -200,8 +200,14 @@ class ApplicationController < ActionController::Base
     if params[:id] and params[:id].match /\D/
       params[:uuid] = params.delete :id
     end
-    if params[:uuid].is_a? String
-      @object = model_class.find(params[:uuid])
+    if not model_class
+      @object = nil
+    elsif params[:uuid].is_a? String
+      if params[:uuid].empty?
+        @object = nil
+      else
+        @object = model_class.find(params[:uuid])
+      end
     else
       @object = model_class.where(uuid: params[:uuid]).first
     end
diff --git a/apps/workbench/app/controllers/folders_controller.rb b/apps/workbench/app/controllers/folders_controller.rb
index 43b6f40..0c9b963 100644
--- a/apps/workbench/app/controllers/folders_controller.rb
+++ b/apps/workbench/app/controllers/folders_controller.rb
@@ -35,6 +35,7 @@ class FoldersController < ApplicationController
         @shared_with_me << folder
       end
     end
+    @object
   end
 
   def show
@@ -42,6 +43,22 @@ class FoldersController < ApplicationController
     @share_links = Link.filter([['head_uuid', '=', @object.uuid],
                                 ['link_class', '=', 'permission']])
     @logs = Log.limit(10).filter([['object_uuid', '=', @object.uuid]])
+
+    @objects_and_names = []
+    @objects.each do |object|
+      if !(name_links = @objects.links_for(object, 'name')).empty?
+        name_links.each do |name_link|
+          @objects_and_names << [object, name_link]
+        end
+      else
+        @objects_and_names << [object,
+                               Link.new(tail_uuid: @object.uuid,
+                                        head_uuid: object.uuid,
+                                        link_class: "name",
+                                        name: "")]
+      end
+    end
+
     super
   end
 
diff --git a/apps/workbench/app/models/arvados_resource_list.rb b/apps/workbench/app/models/arvados_resource_list.rb
index f6bcaae..d585b3c 100644
--- a/apps/workbench/app/models/arvados_resource_list.rb
+++ b/apps/workbench/app/models/arvados_resource_list.rb
@@ -164,7 +164,8 @@ class ArvadosResourceList
     end
   end
 
-  def name_for item_or_uuid
+  # Note: this arbitrarily chooses one of (possibly) multiple names.
+  def names_for item_or_uuid
     links_for(item_or_uuid, 'name').first.andand.name
   end
 
diff --git a/apps/workbench/app/views/folders/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
index 505a8c2..200b0f3 100644
--- a/apps/workbench/app/views/folders/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -130,7 +130,7 @@
               <col width="15%" />
               <col width="29%" />
             </colgroup>
-            <% @objects.each do |object| %>
+            <% @objects_and_names.each do |object, name_link| %>
             <tr>
               <td>
                 <%= render :partial => "selection_checkbox", :locals => {object: object} %>
@@ -139,7 +139,6 @@
                 <%= render :partial => "show_object_button", :locals => {object: object, size: 'xs'} %>
               </td>
               <td>
-                <% name_link = @objects.links_for(object, 'name').first || Link.new(link_class: "name", owner_uuid: @object.uuid, tail_uuid: @object.uuid, head_uuid: object.uuid, name: "") %>
                 <%= render_editable_attribute name_link, 'name', nil, { 'data-emptytext' => "Unnamed #{object.class}" } %>
               </td>
               <td>
diff --git a/apps/workbench/app/views/layouts/application.html.erb b/apps/workbench/app/views/layouts/application.html.erb
index d873991..a7a9750 100644
--- a/apps/workbench/app/views/layouts/application.html.erb
+++ b/apps/workbench/app/views/layouts/application.html.erb
@@ -178,6 +178,7 @@
             </a>
               <ul class="dropdown-menu" role="menu" id="persistent-selection-list">
                 <%= form_tag '/actions' do %>
+                <%= hidden_field_tag 'uuid', @object.andand.uuid %>
                 <div id="selection-form-content"></div>
                 <% end %>
             </ul>

commit d02c4efcfdbe8f21fba895749988b14b7db41310
Merge: ec824d6 1c9ae7e
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 19:57:07 2014 -0400

    Merge branch '2640-folder-api' into 1970-folder-view

diff --cc apps/workbench/config/routes.rb
index c64c31e,cac3431..473ebe3
--- a/apps/workbench/config/routes.rb
+++ b/apps/workbench/config/routes.rb
@@@ -44,9 -44,9 +44,10 @@@ ArvadosWorkbench::Application.routes.dr
      post 'set_persistent', on: :member
    end
    get '/collections/:uuid/*file' => 'collections#show_file', :format => false
 +  resources :folders
  
    post 'actions' => 'actions#post'
+   get 'websockets' => 'websocket#index'
  
    root :to => 'users#welcome'
  
diff --cc services/api/app/controllers/application_controller.rb
index fbfe959,e93c2ab..47f9d44
--- a/services/api/app/controllers/application_controller.rb
+++ b/services/api/app/controllers/application_controller.rb
@@@ -89,10 -92,10 +92,10 @@@ class ApplicationController < ActionCon
          # disappointed: when Rails reloads model classes, we get two
          # distinct classes called Link which do not equal each
          # other. But we can still rely on klass.to_s to be "Link".
 -      when 'ApiClientAuthorization', 'UserAgreement'
 +      when 'ApiClientAuthorization', 'UserAgreement', 'Link'
          # Do not want.
        else
-         @objects = klass.readable_by(current_user)
+         @objects = klass.readable_by(*@read_users)
          cond_sql = "#{klass.table_name}.owner_uuid = ?"
          cond_params = [@object.uuid]
          if params[:include_linked]
diff --cc services/api/test/fixtures/specimens.yml
index a1fbc3b,40f78c1..3465167
--- a/services/api/test/fixtures/specimens.yml
+++ b/services/api/test/fixtures/specimens.yml
@@@ -1,35 -1,23 +1,35 @@@
  owned_by_active_user:
-   uuid: zzzzz-2x53u-3zx463qyo0k4xrn
+   uuid: zzzzz-j58dm-3zx463qyo0k4xrn
    owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
 +  created_at: 2014-04-21 15:37:48 -0400
 +  modified_at: 2014-04-21 15:37:48 -0400
  
  owned_by_private_group:
-   uuid: zzzzz-2x53u-5m3qwg45g3nlpu6
+   uuid: zzzzz-j58dm-5m3qwg45g3nlpu6
    owner_uuid: zzzzz-j7d0g-rew6elm53kancon
 +  created_at: 2014-04-21 15:37:48 -0400
 +  modified_at: 2014-04-21 15:37:48 -0400
  
  owned_by_spectator:
-   uuid: zzzzz-2x53u-3b0xxwzlbzxq5yr
+   uuid: zzzzz-j58dm-3b0xxwzlbzxq5yr
    owner_uuid: zzzzz-tpzed-l1s2piq4t4mps8r
 +  created_at: 2014-04-21 15:37:48 -0400
 +  modified_at: 2014-04-21 15:37:48 -0400
  
  in_afolder:
-   uuid: zzzzz-2x53u-7r18rnd5nzhg5yk
+   uuid: zzzzz-j58dm-7r18rnd5nzhg5yk
    owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
 +  created_at: 2014-04-21 15:37:48 -0400
 +  modified_at: 2014-04-21 15:37:48 -0400
  
  in_asubfolder:
-   uuid: zzzzz-2x53u-c40lddwcqqr1ffs
+   uuid: zzzzz-j58dm-c40lddwcqqr1ffs
    owner_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x
 +  created_at: 2014-04-21 15:37:48 -0400
 +  modified_at: 2014-04-21 15:37:48 -0400
  
  in_afolder_linked_from_asubfolder:
-   uuid: zzzzz-2x53u-5gid26432uujf79
+   uuid: zzzzz-j58dm-5gid26432uujf79
    owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
 +  created_at: 2014-04-21 15:37:48 -0400
 +  modified_at: 2014-04-21 15:37:48 -0400

commit ec824d69dee0696b1ca4748fbe5b912634940d53
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 11:51:57 2014 -0400

    Add "show object" button partials.

diff --git a/apps/workbench/app/views/application/_show_object_button.html.erb b/apps/workbench/app/views/application/_show_object_button.html.erb
new file mode 100644
index 0000000..81ca745
--- /dev/null
+++ b/apps/workbench/app/views/application/_show_object_button.html.erb
@@ -0,0 +1,3 @@
+<% htmloptions = {class: ''}.merge(htmloptions || {})
+   htmloptions[:class] += " btn-#{size}" rescue nil %>
+<%= link_to_if_arvados_object object, { link_text: raw('Show <i class="fa fa-fw fa-arrow-circle-right"></i>') }, { class: 'btn btn-default ' + htmloptions[:class] } %>
diff --git a/apps/workbench/app/views/folders/_show_my_folders.html.erb b/apps/workbench/app/views/folders/_show_my_folders.html.erb
new file mode 100644
index 0000000..b009acf
--- /dev/null
+++ b/apps/workbench/app/views/folders/_show_my_folders.html.erb
@@ -0,0 +1,2 @@
+<%= render(partial: 'show_recent',
+    locals: { comparable: comparable, objects: @my_folders }) %>
diff --git a/apps/workbench/app/views/folders/_show_shared_with_me.html.erb b/apps/workbench/app/views/folders/_show_shared_with_me.html.erb
new file mode 100644
index 0000000..6ccf983
--- /dev/null
+++ b/apps/workbench/app/views/folders/_show_shared_with_me.html.erb
@@ -0,0 +1,2 @@
+<%= render(partial: 'show_recent',
+    locals: { comparable: comparable, objects: @shared_with_me }) %>

commit 76b9eebf07b424ec2a8fde9b7760b8ce499063bc
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 11:50:51 2014 -0400

    Add "Shared with" section to Sharing/Permissions panel.

diff --git a/apps/workbench/app/controllers/folders_controller.rb b/apps/workbench/app/controllers/folders_controller.rb
index 566b1a9..43b6f40 100644
--- a/apps/workbench/app/controllers/folders_controller.rb
+++ b/apps/workbench/app/controllers/folders_controller.rb
@@ -39,6 +39,8 @@ class FoldersController < ApplicationController
 
   def show
     @objects = @object.contents include_linked: true
+    @share_links = Link.filter([['head_uuid', '=', @object.uuid],
+                                ['link_class', '=', 'permission']])
     @logs = Log.limit(10).filter([['object_uuid', '=', @object.uuid]])
     super
   end
diff --git a/apps/workbench/app/views/folders/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
index bacf669..505a8c2 100644
--- a/apps/workbench/app/views/folders/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -65,6 +65,13 @@
         -->
 	<div style="height:0.5em;"></div>
         <p>Owner: <%= link_to_if_arvados_object @object.owner_uuid, friendly_name: true %></p>
+        <% if @share_links.any? %>
+        <p>Shared with:
+          <% @share_links.andand.each do |link| %>
+          <br /><%= link_to_if_arvados_object link.tail_uuid, friendly_name: true %>
+          <% end %>
+        </p>
+        <% end %>
       </div>
     </div>
   </div>

commit ac317fea1f11179b33eae7e06a60ba60df218f1c
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 23:25:32 2014 -0400

    Update tests for new layout.

diff --git a/apps/workbench/test/integration/folders_test.rb b/apps/workbench/test/integration/folders_test.rb
index 4d569e4..d9322e6 100644
--- a/apps/workbench/test/integration/folders_test.rb
+++ b/apps/workbench/test/integration/folders_test.rb
@@ -9,16 +9,16 @@ class FoldersTest < ActionDispatch::IntegrationTest
     visit page_with_token 'active', '/'
     find('nav a', text: 'Folders').click
     find('tr', text: 'A Folder').
-      find('a', text: 'zzzzz-').
+      find('a,button', text: 'Show').
       click
     within('.panel', text: api_fixture('groups')['afolder']['name']) do
       find('span', text: api_fixture('groups')['afolder']['name']).click
       find('.glyphicon-ok').click
       find('.btn', text: 'Edit description').click
-      find('textarea').set('I just edited this.')
-      find('.glyphicon-ok').click
+      find('.editable-input textarea').set('I just edited this.')
+      find('.editable-submit').click
     end
-    find('.panel', text: 'I just edited this.')
+    #find('.panel', text: 'I just edited this.')
   end
 
 end
diff --git a/apps/workbench/test/integration/users_test.rb b/apps/workbench/test/integration/users_test.rb
index 06d420c..bd69f99 100644
--- a/apps/workbench/test/integration/users_test.rb
+++ b/apps/workbench/test/integration/users_test.rb
@@ -23,7 +23,9 @@ class UsersTest < ActionDispatch::IntegrationTest
       assert (text.include? 'true false'), 'Expected is_active'
     end
 
-    click_link 'zzzzz-tpzed-xurymjxw79nv3jz'
+    find('tr', text: 'zzzzz-tpzed-xurymjxw79nv3jz').
+      find('a,button', text: 'Show').
+      click
     assert page.has_text? 'Attributes'
     assert page.has_text? 'Metadata'
     assert page.has_text? 'Admin'
@@ -63,23 +65,20 @@ class UsersTest < ActionDispatch::IntegrationTest
       click_button "Submit"
     end
 
-    sleep(0.1)
-
-    # verify that the new user showed up in the users page
-    assert page.has_text? 'foo at example.com'
-
-    new_user_uuid = nil
-    all("tr").each do |elem|
-      if elem.text.include? 'foo at example.com'
-        new_user_uuid = elem.text.split[0]
-        break
-      end
-    end
+    sleep 0.1
 
+    # verify that the new user showed up in the users page and find
+    # the new user's UUID
+    new_user_uuid =
+      find('tr[data-object-uuid]', text: 'foo at example.com').
+      find('td', text: '-tpzed-').
+      text
     assert new_user_uuid, "Expected new user uuid not found"
 
     # go to the new user's page
-    click_link new_user_uuid
+    find('tr', text: new_user_uuid).
+      find('a,button', text: 'Show').
+      click
 
     assert page.has_text? 'modified_by_user_uuid'
     page.within(:xpath, '//span[@data-name="is_active"]') do
@@ -102,10 +101,10 @@ class UsersTest < ActionDispatch::IntegrationTest
 
     click_link 'Users'
 
-    assert page.has_link? 'zzzzz-tpzed-xurymjxw79nv3jz'
-
     # click on active user
-    click_link 'zzzzz-tpzed-xurymjxw79nv3jz'
+    find('tr', text: 'zzzzz-tpzed-xurymjxw79nv3jz').
+      find('a,button', text: 'Show').
+      click
 
     # Setup user
     click_link 'Admin'
@@ -161,10 +160,10 @@ class UsersTest < ActionDispatch::IntegrationTest
 
     click_link 'Users'
 
-    assert page.has_link? 'zzzzz-tpzed-xurymjxw79nv3jz'
-
     # click on active user
-    click_link 'zzzzz-tpzed-xurymjxw79nv3jz'
+    find('tr', text: 'zzzzz-tpzed-xurymjxw79nv3jz').
+      find('a,button', text: 'Show').
+      click
 
     # Verify that is_active is set
     click_link 'Attributes'

commit 568ea04cdde8988a675754372f618d937d3757e0
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 23:24:49 2014 -0400

    Do not return Links with group contents

diff --git a/services/api/app/controllers/application_controller.rb b/services/api/app/controllers/application_controller.rb
index 140ee4e..fbfe959 100644
--- a/services/api/app/controllers/application_controller.rb
+++ b/services/api/app/controllers/application_controller.rb
@@ -89,7 +89,7 @@ class ApplicationController < ActionController::Base
         # disappointed: when Rails reloads model classes, we get two
         # distinct classes called Link which do not equal each
         # other. But we can still rely on klass.to_s to be "Link".
-      when 'ApiClientAuthorization', 'UserAgreement'
+      when 'ApiClientAuthorization', 'UserAgreement', 'Link'
         # Do not want.
       else
         @objects = klass.readable_by(current_user)

commit fca1b2bd47910761f0c2603e72681670443e4be8
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 18:45:41 2014 -0400

    Synchronize "show more" button style, turn off cards for now

diff --git a/apps/workbench/app/views/application/_show_recent.html.erb b/apps/workbench/app/views/application/_show_recent.html.erb
index ab1cd7f..c36f27c 100644
--- a/apps/workbench/app/views/application/_show_recent.html.erb
+++ b/apps/workbench/app/views/application/_show_recent.html.erb
@@ -36,7 +36,7 @@
         <%= render :partial => "selection_checkbox", :locals => {:object => object} %>
       </td>
       <td>
-        <%= render :partial => "show_object_button", :locals => {object: object} %>
+        <%= render :partial => "show_object_button", :locals => {object: object, size: 'xs'} %>
       </td>
 
       <% object.attributes_for_display.each do |attr, attrvalue| %>
diff --git a/apps/workbench/app/views/folders/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
index bdf9b13..bacf669 100644
--- a/apps/workbench/app/views/folders/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -38,9 +38,9 @@
 	</p>
         <% end %>
         <% if @logs.any? %>
-	<%= link_to raw('Show all activity   <i class="fa fa-hand-o-right"></i>'),
+	<%= link_to raw('Show all activity   <i class="fa fa-fw fa-arrow-circle-right"></i>'),
             logs_path(filters: [['object_uuid','=', at object.uuid]].to_json),
-            class: 'btn btn-sm btn-info' %>
+            class: 'btn btn-sm btn-default' %>
         <% else %>
         <p>
           Created: <%= @object.created_at.to_s(:long) %>
@@ -70,6 +70,8 @@
   </div>
 </div>
 
+<% if @show_cards %>
+<!-- disable cards section until we have bookmarks -->
 <div class="row">
   <% @objects[0..3].each do |object| %>
   <div class="card arvados-object">
@@ -83,11 +85,13 @@
       <div class="desc"><%= object.respond_to?(:description) ? object.description : object.uuid %></div>
     </div>
     <div class="card-bottom">
-      <%= link_to_if_arvados_object object, {link_text: 'Open'}, {class: 'btn btn-default btn-block'} %>
+      <%= render :partial => "show_object_button", :locals => {object: object, htmloptions: {class: 'btn-default btn-block'}} %>
     </div>
   </div>
   <% end %>
 </div>
+<!-- end disabled cards section -->
+<% end %>
 
 <div class="row">
   <div class="col-md-12">
@@ -125,7 +129,7 @@
                 <%= render :partial => "selection_checkbox", :locals => {object: object} %>
               </td>
               <td>
-                <%= render :partial => "show_object_button", :locals => {object: object} %>
+                <%= render :partial => "show_object_button", :locals => {object: object, size: 'xs'} %>
               </td>
               <td>
                 <% name_link = @objects.links_for(object, 'name').first || Link.new(link_class: "name", owner_uuid: @object.uuid, tail_uuid: @object.uuid, head_uuid: object.uuid, name: "") %>

commit 4c19fb79d7b96bc18a1843182d3675c7a4de683d
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 18:33:12 2014 -0400

    Focus/hover side navs with white instead of arbitrary color.

diff --git a/apps/workbench/app/assets/stylesheets/sb-admin.css.scss b/apps/workbench/app/assets/stylesheets/sb-admin.css.scss
index 61a7533..9bae214 100644
--- a/apps/workbench/app/assets/stylesheets/sb-admin.css.scss
+++ b/apps/workbench/app/assets/stylesheets/sb-admin.css.scss
@@ -134,7 +134,7 @@ table.tablesorter thead tr th:hover {
   .side-nav>li.dropdown>ul.dropdown-menu>li>a:hover,
   .side-nav>li.dropdown>ul.dropdown-menu>li>a.active,
   .side-nav>li.dropdown>ul.dropdown-menu>li>a:focus {
-        background-color: #f8ffff;
+        background-color: #ffffff;
   }
 
   .side-nav>li>a {
@@ -143,7 +143,7 @@ table.tablesorter thead tr th:hover {
 
   .navbar-default .navbar-nav.side-nav>li>a:hover,
   .navbar-default .navbar-nav.side-nav>li>a:focus {
-        background-color: #f8ffff;
+        background-color: #ffffff;
   }
 
   /* Nav Messages */

commit f23a72b89383c797663b5ec77d342bab20f239f4
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 18:32:18 2014 -0400

    Render cards with real content from first few items.

diff --git a/apps/workbench/app/views/folders/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
index ec79e7b..bdf9b13 100644
--- a/apps/workbench/app/views/folders/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -71,51 +71,7 @@
 </div>
 
 <div class="row">
-  <div class="card arvados-object">
-    <div class="card-top green">
-      <a href="#">
-        <img src="/favicon.ico" alt=""/>
-      </a>
-    </div>
-    <div class="card-info">
-      <a class="title" href="#">Test dataset</a>
-      <div class="desc">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
-    </div>
-    <div class="card-bottom">
-      <button class="btn btn-default btn-block">Show details</button>
-    </div>
-  </div>
-
-  <div class="card arvados-object">
-    <div class="card-top green">
-      <a href="#">
-        <img src="/favicon.ico" alt=""/>
-      </a>
-    </div>
-    <div class="card-info">
-      <a class="title" href="#">GATK Exome Pipeline</a>
-      <div class="desc">exome p.e. fastq -> vcf</div>
-    </div>
-    <div class="card-bottom">
-      <button class="btn btn-default btn-block">Show details</button>
-    </div>
-  </div>
-
-  <div class="card arvados-object">
-    <div class="card-top blue">
-      <a href="#">
-        <img src="/favicon.ico" alt=""/>
-      </a>
-    </div>
-    <div class="card-info">
-      <a class="title" href="#">Reference result</a>
-      <div class="desc">Known good -- checked concordance against other datasets</div>
-    </div>
-    <div class="card-bottom">
-      <button class="btn btn-default btn-block">Show details</button>
-    </div>
-  </div>
-
+  <% @objects[0..3].each do |object| %>
   <div class="card arvados-object">
     <div class="card-top blue">
       <a href="#">
@@ -123,13 +79,14 @@
       </a>
     </div>
     <div class="card-info">
-      <a class="title" href="#">Some other thing</a>
-      <div class="desc">(Objects that are "starred" appear in this area)</div>
+      <span class="title"><%= @objects.name_for(object) || object.class_for_display %></span>
+      <div class="desc"><%= object.respond_to?(:description) ? object.description : object.uuid %></div>
     </div>
     <div class="card-bottom">
-      <button class="btn btn-default btn-block">Show details</button>
+      <%= link_to_if_arvados_object object, {link_text: 'Open'}, {class: 'btn btn-default btn-block'} %>
     </div>
   </div>
+  <% end %>
 </div>
 
 <div class="row">

commit 6177a6474c312d5d5b9c1f0eaa3ebd089a64b5f1
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 18:22:28 2014 -0400

    Fix up table columns, use explicit Open button instead of linking uuid

diff --git a/apps/workbench/app/controllers/folders_controller.rb b/apps/workbench/app/controllers/folders_controller.rb
index 3f536fb..566b1a9 100644
--- a/apps/workbench/app/controllers/folders_controller.rb
+++ b/apps/workbench/app/controllers/folders_controller.rb
@@ -3,8 +3,38 @@ class FoldersController < ApplicationController
     Group
   end
 
+  def index_pane_list
+    %w(My_folders Shared_with_me)
+  end
+
   def index
-    @objects = Group.where group_class: 'folder'
+    @my_folders = []
+    @shared_with_me = []
+    @objects = Group.where(group_class: 'folder').order('name')
+    owner_of = {}
+    moretodo = true
+    while moretodo
+      moretodo = false
+      @objects.each do |folder|
+        if !owner_of[folder.uuid]
+          moretodo = true
+          owner_of[folder.uuid] = folder.owner_uuid
+        end
+        if owner_of[folder.owner_uuid]
+          if owner_of[folder.uuid] != owner_of[folder.owner_uuid]
+            owner_of[folder.uuid] = owner_of[folder.owner_uuid]
+            moretodo = true
+          end
+        end
+      end
+    end
+    @objects.each do |folder|
+      if owner_of[folder.uuid] == current_user.uuid
+        @my_folders << folder
+      else
+        @shared_with_me << folder
+      end
+    end
   end
 
   def show
diff --git a/apps/workbench/app/models/arvados_base.rb b/apps/workbench/app/models/arvados_base.rb
index 45a4d8b..9229cfc 100644
--- a/apps/workbench/app/models/arvados_base.rb
+++ b/apps/workbench/app/models/arvados_base.rb
@@ -25,17 +25,23 @@ class ArvadosBase < ActiveRecord::Base
     super(*args)
     @attribute_sortkey ||= {
       'id' => nil,
-      'uuid' => '000',
-      'owner_uuid' => '001',
-      'created_at' => '002',
-      'modified_at' => '003',
-      'modified_by_user_uuid' => '004',
-      'modified_by_client_uuid' => '005',
-      'name' => '050',
-      'tail_uuid' => '100',
-      'head_uuid' => '101',
-      'info' => 'zzz-000',
-      'updated_at' => 'zzz-999'
+      'name' => '000',
+      'owner_uuid' => '002',
+      'event_type' => '100',
+      'link_class' => '100',
+      'group_class' => '100',
+      'tail_uuid' => '101',
+      'head_uuid' => '102',
+      'object_uuid' => '102',
+      'summary' => '104',
+      'description' => '104',
+      'properties' => '150',
+      'info' => '150',
+      'created_at' => '200',
+      'modified_at' => '201',
+      'modified_by_user_uuid' => '202',
+      'modified_by_client_uuid' => '203',
+      'uuid' => '999',
     }
   end
 
diff --git a/apps/workbench/app/views/application/_content.html.erb b/apps/workbench/app/views/application/_content.html.erb
index 53444a5..8a0624b 100644
--- a/apps/workbench/app/views/application/_content.html.erb
+++ b/apps/workbench/app/views/application/_content.html.erb
@@ -4,7 +4,7 @@
 <% pane_list ||= %w(recent) %>
 <% panes = Hash[pane_list.map { |pane|
      [pane, render(partial: 'show_' + pane.downcase,
-                   locals: { comparable: comparable })]
+                   locals: { comparable: comparable, objects: @objects })]
    }.compact] %>
 
 <ul class="nav nav-tabs">
diff --git a/apps/workbench/app/views/application/_show_recent.html.erb b/apps/workbench/app/views/application/_show_recent.html.erb
index aabd021..ab1cd7f 100644
--- a/apps/workbench/app/views/application/_show_recent.html.erb
+++ b/apps/workbench/app/views/application/_show_recent.html.erb
@@ -1,4 +1,4 @@
-<% if @objects.empty? %>
+<% if objects.empty? %>
 <br/>
 <p style="text-align: center">
   No <%= controller.controller_name.humanize.downcase %> to display.
@@ -6,9 +6,9 @@
 
 <% else %>
 
-<% attr_blacklist = ' created_at modified_at modified_by_user_uuid modified_by_client_uuid updated_at' %>
+<% attr_blacklist = ' created_at modified_at modified_by_user_uuid modified_by_client_uuid updated_at owner_uuid group_class' %>
 
-<%= render partial: "paging", locals: {results: @objects, object: @object} %>
+<%= render partial: "paging", locals: {results: objects, object: @object} %>
 
 <%= form_tag do |f| %>
 
@@ -16,7 +16,8 @@
   <thead>
     <tr>
       <th></th>
-      <% @objects.first.attributes_for_display.each do |attr, attrvalue| %>
+      <th></th>
+      <% objects.first.attributes_for_display.each do |attr, attrvalue| %>
       <% next if attr_blacklist.index(" "+attr) %>
       <th class="arv-attr-<%= attr %>">
         <%= controller.model_class.attribute_info[attr.to_sym].andand[:column_heading] or attr.sub /_uuid/, '' %>
@@ -29,18 +30,20 @@
   </thead>
       
   <tbody>
-    <% @objects.each do |object| %>
+    <% objects.each do |object| %>
     <tr data-object-uuid="<%= object.uuid %>">
       <td>
         <%= render :partial => "selection_checkbox", :locals => {:object => object} %>
       </td>
+      <td>
+        <%= render :partial => "show_object_button", :locals => {object: object} %>
+      </td>
 
       <% object.attributes_for_display.each do |attr, attrvalue| %>
       <% next if attr_blacklist.index(" "+attr) %>
       <td class="arv-object-<%= object.class.to_s %> arv-attr-<%= attr %>">
         <% if attr == 'uuid' %>
-        <%= link_to_if_arvados_object object %>
-        <%= link_to_if_arvados_object(object, { link_text: raw('<i class="icon-hand-right"></i>') }) %>
+        <span class="arvados-uuid"><%= attrvalue %></span>
         <% else %>
         <% if object.attribute_editable? attr %>
         <%= render_editable_attribute object, attr %>
@@ -65,6 +68,6 @@
 
 <% end %>
 
-<%= render partial: "paging", locals: {results: @objects, object: @object} %>
+<%= render partial: "paging", locals: {results: objects, object: @object} %>
 
 <% end %>
diff --git a/apps/workbench/app/views/application/index.html.erb b/apps/workbench/app/views/application/index.html.erb
index a32e7bf..20af648 100644
--- a/apps/workbench/app/views/application/index.html.erb
+++ b/apps/workbench/app/views/application/index.html.erb
@@ -1,5 +1,5 @@
 <% content_for :page_title do %>
-<%= controller.model_class.to_s.pluralize.underscore.capitalize.gsub('_', ' ') %>
+<%= controller.controller_name.humanize.capitalize %>
 <% end %>
 
 <% content_for :tab_line_buttons do %>
diff --git a/apps/workbench/app/views/folders/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
index c7db562..ec79e7b 100644
--- a/apps/workbench/app/views/folders/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -152,17 +152,25 @@
       <div class="panel-body">
         <p>
         </p>
-        <table class="table">
+        <table class="table table-condensed arv-index">
           <tbody>
             <colgroup>
+              <col width="3%" />
+              <col width="8%" />
               <col width="30%" />
-              <col width="20%" />
-              <col width="20%" />
-              <col width="30%" />
+              <col width="15%" />
+              <col width="15%" />
+              <col width="29%" />
             </colgroup>
             <% @objects.each do |object| %>
             <tr>
               <td>
+                <%= render :partial => "selection_checkbox", :locals => {object: object} %>
+              </td>
+              <td>
+                <%= render :partial => "show_object_button", :locals => {object: object} %>
+              </td>
+              <td>
                 <% name_link = @objects.links_for(object, 'name').first || Link.new(link_class: "name", owner_uuid: @object.uuid, tail_uuid: @object.uuid, head_uuid: object.uuid, name: "") %>
                 <%= render_editable_attribute name_link, 'name', nil, { 'data-emptytext' => "Unnamed #{object.class}" } %>
               </td>
@@ -175,7 +183,7 @@
                 </span>
               </td>
               <td class="arvados-uuid">
-                <%= link_to_if_arvados_object(object, {no_tags: true}) %>
+                <%= object.uuid %>
               </td>
             </tr>
             <% end %>
@@ -183,15 +191,20 @@
           <thead>
             <tr>
               <th>
-                Name
               </th>
               <th>
               </th>
               <th>
-                Modified
+                name
+              </th>
+              <th>
+                type
+              </th>
+              <th>
+                modified
               </th>
               <th>
-                UUID
+                uuid
               </th>
             </tr>
           </thead>

commit 9820178bf518d9ddace8c27ea383e5c37d86c8fe
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 16:57:16 2014 -0400

    Add integration test for folders.

diff --git a/apps/workbench/test/integration/folders_test.rb b/apps/workbench/test/integration/folders_test.rb
new file mode 100644
index 0000000..4d569e4
--- /dev/null
+++ b/apps/workbench/test/integration/folders_test.rb
@@ -0,0 +1,24 @@
+require 'integration_helper'
+require 'selenium-webdriver'
+require 'headless'
+
+class FoldersTest < ActionDispatch::IntegrationTest
+
+  test 'Find a folder and edit its description' do
+    Capybara.current_driver = Capybara.javascript_driver
+    visit page_with_token 'active', '/'
+    find('nav a', text: 'Folders').click
+    find('tr', text: 'A Folder').
+      find('a', text: 'zzzzz-').
+      click
+    within('.panel', text: api_fixture('groups')['afolder']['name']) do
+      find('span', text: api_fixture('groups')['afolder']['name']).click
+      find('.glyphicon-ok').click
+      find('.btn', text: 'Edit description').click
+      find('textarea').set('I just edited this.')
+      find('.glyphicon-ok').click
+    end
+    find('.panel', text: 'I just edited this.')
+  end
+
+end

commit b7161fff2cb2fdd2bc0975c75f1fbc32f625343b
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 16:56:18 2014 -0400

    Fix "show all activity".

diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb
index 31f3464..e9d4dd5 100644
--- a/apps/workbench/app/controllers/application_controller.rb
+++ b/apps/workbench/app/controllers/application_controller.rb
@@ -71,7 +71,16 @@ class ApplicationController < ActionController::Base
       offset = 0
     end
 
-    @objects ||= model_class.limit(limit).offset(offset).all
+    if params[:filters]
+      filters = params[:filters]
+      if filters.is_a? String
+        filters = Oj.load filters
+      end
+    else
+      filters = []
+    end
+
+    @objects ||= model_class.filter(filters).limit(limit).offset(offset).all
     respond_to do |f|
       f.json { render json: @objects }
       f.html { render }
diff --git a/apps/workbench/app/models/log.rb b/apps/workbench/app/models/log.rb
index c804bf7..39d585b 100644
--- a/apps/workbench/app/models/log.rb
+++ b/apps/workbench/app/models/log.rb
@@ -1,3 +1,8 @@
 class Log < ArvadosBase
   attr_accessor :object
+  def self.creatable?
+    # Technically yes, but not worth offering: it will be empty, and
+    # you won't be able to edit it.
+    false
+  end
 end
diff --git a/apps/workbench/app/views/folders/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
index cc7a347..c7db562 100644
--- a/apps/workbench/app/views/folders/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -39,7 +39,7 @@
         <% end %>
         <% if @logs.any? %>
 	<%= link_to raw('Show all activity   <i class="fa fa-hand-o-right"></i>'),
-            logs_path(filters: [['object_uuid','=', at object.uuid]]),
+            logs_path(filters: [['object_uuid','=', at object.uuid]].to_json),
             class: 'btn btn-sm btn-info' %>
         <% else %>
         <p>
diff --git a/apps/workbench/app/views/logs/show.html.erb b/apps/workbench/app/views/logs/show.html.erb
deleted file mode 100644
index 9079085..0000000
--- a/apps/workbench/app/views/logs/show.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render :partial => 'application/arvados_object' %>

commit 5d5c69bb5a60127aa509fac4bdfb8ea915eacadc
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 16:56:05 2014 -0400

    Less side-nav padding.

diff --git a/apps/workbench/app/assets/stylesheets/application.css.scss b/apps/workbench/app/assets/stylesheets/application.css.scss
index 197ddbd..9259c9e 100644
--- a/apps/workbench/app/assets/stylesheets/application.css.scss
+++ b/apps/workbench/app/assets/stylesheets/application.css.scss
@@ -174,3 +174,7 @@ table.table-fixed-header-row tbody {
 .side-nav {
     border-right: 1px solid #e7e7e7;
 }
+.navbar-nav.side-nav > li > a {
+    padding-top: 10px;
+    padding-bottom: 10px;
+}

commit 0e69f5346c474da7b2244546db4476f8ca21946f
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 16:13:13 2014 -0400

    Move up more useful navs, make activity text smaller.

diff --git a/apps/workbench/app/assets/stylesheets/application.css.scss b/apps/workbench/app/assets/stylesheets/application.css.scss
index c03548c..197ddbd 100644
--- a/apps/workbench/app/assets/stylesheets/application.css.scss
+++ b/apps/workbench/app/assets/stylesheets/application.css.scss
@@ -40,6 +40,9 @@ table.table-justforlayout>tbody>tr>th{
 table.table-justforlayout {
     margin-bottom: 0;
 }
+.smaller-text {
+    font-size: .8em;
+}
 .deemphasize {
     font-size: .8em;
     color: #888;
diff --git a/apps/workbench/app/views/folders/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
index da848b2..cc7a347 100644
--- a/apps/workbench/app/views/folders/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -24,7 +24,7 @@
 	  Activity
 	</h3>
       </div>
-      <div class="panel-body">
+      <div class="panel-body smaller-text">
         <!--
 	<input type="text" class="form-control" placeholder="Search"/>
         -->
diff --git a/apps/workbench/app/views/layouts/application.html.erb b/apps/workbench/app/views/layouts/application.html.erb
index 84579d9..d873991 100644
--- a/apps/workbench/app/views/layouts/application.html.erb
+++ b/apps/workbench/app/views/layouts/application.html.erb
@@ -89,6 +89,12 @@
                 <i class="fa fa-lg fa-folder-o fa-fw"></i> Folders
             </a></li>
             <li> </li>
+            <li><a href="/repositories">
+                <i class="fa fa-lg fa-code-fork fa-fw"></i> Repositories
+            </a></li>
+            <li><a href="/virtual_machines">
+                <i class="fa fa-lg fa-cloud fa-fw"></i> Virtual machines
+            </a></li>
             <li><a href="/humans">
                 <i class="fa fa-lg fa-male fa-fw"></i> Humans
             </a></li>
@@ -101,12 +107,6 @@
             <li><a href="/links">
                 <i class="fa fa-lg fa-arrows-h fa-fw"></i> Links
             </a></li>
-            <li><a href="/repositories">
-                <i class="fa fa-lg fa-code-fork fa-fw"></i> Repositories
-            </a></li>
-            <li><a href="/virtual_machines">
-                <i class="fa fa-lg fa-cloud fa-fw"></i> Virtual machines
-            </a></li>
             <% if current_user.andand.is_admin %>
               <li><a href="/users">
                   <i class="fa fa-lg fa-user fa-fw"></i> Users

commit 3063c6106a83102214deb9d86ec621c0bb85d4b7
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 16:09:32 2014 -0400

    Fix tests to work with new css/layout.

diff --git a/apps/workbench/app/views/folders/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
index c02c48b..da848b2 100644
--- a/apps/workbench/app/views/folders/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -171,7 +171,7 @@
               </td>
               <td title="<%= object.modified_at %>">
                 <span>
-                  <%= raw distance_of_time_in_words(object.modified_at, Time.now).sub('about ','~').sub(' ',' ') + ' ago' %>
+                  <%= raw distance_of_time_in_words(object.modified_at, Time.now).sub('about ','~').sub(' ',' ') + ' ago' rescue object.modified_at %>
                 </span>
               </td>
               <td class="arvados-uuid">
diff --git a/apps/workbench/app/views/layouts/application.html.erb b/apps/workbench/app/views/layouts/application.html.erb
index a1738b4..84579d9 100644
--- a/apps/workbench/app/views/layouts/application.html.erb
+++ b/apps/workbench/app/views/layouts/application.html.erb
@@ -105,7 +105,7 @@
                 <i class="fa fa-lg fa-code-fork fa-fw"></i> Repositories
             </a></li>
             <li><a href="/virtual_machines">
-                <i class="fa fa-lg fa-ellipsis-h fa-fw"></i> Virtual machines
+                <i class="fa fa-lg fa-cloud fa-fw"></i> Virtual machines
             </a></li>
             <% if current_user.andand.is_admin %>
               <li><a href="/users">
@@ -124,8 +124,6 @@
           </ul>
         <% end %>
 
-
-
         <ul class="nav navbar-nav navbar-left breadcrumbs">
           <% if current_user %>
             <% if content_for?(:breadcrumbs) %>
diff --git a/apps/workbench/test/integration/smoke_test.rb b/apps/workbench/test/integration/smoke_test.rb
index 700c8e6..864224b 100644
--- a/apps/workbench/test/integration/smoke_test.rb
+++ b/apps/workbench/test/integration/smoke_test.rb
@@ -23,7 +23,7 @@ class SmokeTest < ActionDispatch::IntegrationTest
     visit page_with_token('active_trustedclient', '/')
     assert_visit_success
     click_link 'user-menu'
-    urls = [all_links_in('.arvados-nav'),
+    urls = [all_links_in('nav'),
             all_links_in('.navbar', /^Manage /)].flatten
     seen_urls = ['/']
     while not (url = urls.shift).nil?
diff --git a/apps/workbench/test/integration/users_test.rb b/apps/workbench/test/integration/users_test.rb
index df7d245..06d420c 100644
--- a/apps/workbench/test/integration/users_test.rb
+++ b/apps/workbench/test/integration/users_test.rb
@@ -31,10 +31,10 @@ class UsersTest < ActionDispatch::IntegrationTest
     # go to the Attributes tab
     click_link 'Attributes'
     assert page.has_text? 'modified_by_user_uuid'
-    page.within(:xpath, '//a[@data-name="is_active"]') do
+    page.within(:xpath, '//span[@data-name="is_active"]') do
       assert_equal "true", text, "Expected user's is_active to be true"
     end
-    page.within(:xpath, '//a[@data-name="is_admin"]') do
+    page.within(:xpath, '//span[@data-name="is_admin"]') do
       assert_equal "false", text, "Expected user's is_admin to be false"
     end
 
@@ -82,7 +82,7 @@ class UsersTest < ActionDispatch::IntegrationTest
     click_link new_user_uuid
 
     assert page.has_text? 'modified_by_user_uuid'
-    page.within(:xpath, '//a[@data-name="is_active"]') do
+    page.within(:xpath, '//span[@data-name="is_active"]') do
       assert_equal "false", text, "Expected new user's is_active to be false"
     end
 
@@ -169,7 +169,7 @@ class UsersTest < ActionDispatch::IntegrationTest
     # Verify that is_active is set
     click_link 'Attributes'
     assert page.has_text? 'modified_by_user_uuid'
-    page.within(:xpath, '//a[@data-name="is_active"]') do
+    page.within(:xpath, '//span[@data-name="is_active"]') do
       assert_equal "true", text, "Expected user's is_active to be true"
     end
 
@@ -185,7 +185,7 @@ class UsersTest < ActionDispatch::IntegrationTest
     # Should now be back in the Attributes tab for the user
     page.driver.browser.switch_to.alert.accept
     assert page.has_text? 'modified_by_user_uuid'
-    page.within(:xpath, '//a[@data-name="is_active"]') do
+    page.within(:xpath, '//span[@data-name="is_active"]') do
       assert_equal "false", text, "Expected user's is_active to be false after unsetup"
     end
 
diff --git a/apps/workbench/test/integration/virtual_machines_test.rb b/apps/workbench/test/integration/virtual_machines_test.rb
index 541a7aa..26da0d0 100644
--- a/apps/workbench/test/integration/virtual_machines_test.rb
+++ b/apps/workbench/test/integration/virtual_machines_test.rb
@@ -7,8 +7,8 @@ class VirtualMachinesTest < ActionDispatch::IntegrationTest
     click_link 'Virtual machines'
     assert page.has_text? 'testvm.shell'
     click_on 'Add a new virtual machine'
-    assert page.has_text? 'none'
-    click_link 'none'
+    find('tr', text: 'hostname').
+      find('span', text: 'none').click
     assert page.has_text? 'Update hostname'
     fill_in 'editable-text', with: 'testname'
     click_button 'editable-submit'
diff --git a/services/api/test/fixtures/specimens.yml b/services/api/test/fixtures/specimens.yml
index 6ad7cfe..a1fbc3b 100644
--- a/services/api/test/fixtures/specimens.yml
+++ b/services/api/test/fixtures/specimens.yml
@@ -1,23 +1,35 @@
 owned_by_active_user:
   uuid: zzzzz-2x53u-3zx463qyo0k4xrn
   owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  created_at: 2014-04-21 15:37:48 -0400
+  modified_at: 2014-04-21 15:37:48 -0400
 
 owned_by_private_group:
   uuid: zzzzz-2x53u-5m3qwg45g3nlpu6
   owner_uuid: zzzzz-j7d0g-rew6elm53kancon
+  created_at: 2014-04-21 15:37:48 -0400
+  modified_at: 2014-04-21 15:37:48 -0400
 
 owned_by_spectator:
   uuid: zzzzz-2x53u-3b0xxwzlbzxq5yr
   owner_uuid: zzzzz-tpzed-l1s2piq4t4mps8r
+  created_at: 2014-04-21 15:37:48 -0400
+  modified_at: 2014-04-21 15:37:48 -0400
 
 in_afolder:
   uuid: zzzzz-2x53u-7r18rnd5nzhg5yk
   owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
+  created_at: 2014-04-21 15:37:48 -0400
+  modified_at: 2014-04-21 15:37:48 -0400
 
 in_asubfolder:
   uuid: zzzzz-2x53u-c40lddwcqqr1ffs
   owner_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x
+  created_at: 2014-04-21 15:37:48 -0400
+  modified_at: 2014-04-21 15:37:48 -0400
 
 in_afolder_linked_from_asubfolder:
   uuid: zzzzz-2x53u-5gid26432uujf79
   owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
+  created_at: 2014-04-21 15:37:48 -0400
+  modified_at: 2014-04-21 15:37:48 -0400

commit c623120453858c2ce47ab135f250c33a627a344d
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 14:32:45 2014 -0400

    Use separator instead of drop-down for less-used nav links.

diff --git a/apps/workbench/app/views/layouts/application.html.erb b/apps/workbench/app/views/layouts/application.html.erb
index 2e17f54..a1738b4 100644
--- a/apps/workbench/app/views/layouts/application.html.erb
+++ b/apps/workbench/app/views/layouts/application.html.erb
@@ -88,43 +88,39 @@
             <li><a href="/folders">
                 <i class="fa fa-lg fa-folder-o fa-fw"></i> Folders
             </a></li>
-            <li class="dropdown">
-              <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-lg fa-ellipsis-h fa-fw"></i> More <b class="caret"></b></a>
-              <ul class="dropdown-menu">
-                <li><a href="/humans">
-                    <i class="fa fa-lg fa-male fa-fw"></i> Humans
-                </a></li>
-                <li><a href="/specimens">
-                    <i class="fa fa-lg fa-flask fa-fw"></i> Specimens
-                </a></li>
-                <li><a href="/traits">
-                    <i class="fa fa-lg fa-clipboard fa-fw"></i> Traits
-                </a></li>
-                <li><a href="/links">
-                    <i class="fa fa-lg fa-arrows-h fa-fw"></i> Links
-                </a></li>
-                <li><a href="/repositories">
-                    <i class="fa fa-lg fa-code-fork fa-fw"></i> Repositories
-                </a></li>
-                <li><a href="/virtual_machines">
-                    <i class="fa fa-lg fa-ellipsis-h fa-fw"></i> Virtual machines
-                </a></li>
-                <% if current_user.andand.is_admin %>
-                  <li><a href="/users">
-                      <i class="fa fa-lg fa-user fa-fw"></i> Users
-                  </a></li>
-                <% end %>
-                <li><a href="/groups">
-                    <i class="fa fa-lg fa-users fa-fw"></i> Groups
-                </a></li>
-                <li><a href="/nodes">
-                    <i class="fa fa-lg fa-cogs fa-fw"></i> Compute nodes
-                </a></li>
-                <li><a href="/keep_disks">
-                    <i class="fa fa-lg fa-hdd-o fa-fw"></i> Keep disks
-                </a></li>
-              </ul>
-            </li>
+            <li> </li>
+            <li><a href="/humans">
+                <i class="fa fa-lg fa-male fa-fw"></i> Humans
+            </a></li>
+            <li><a href="/specimens">
+                <i class="fa fa-lg fa-flask fa-fw"></i> Specimens
+            </a></li>
+            <li><a href="/traits">
+                <i class="fa fa-lg fa-clipboard fa-fw"></i> Traits
+            </a></li>
+            <li><a href="/links">
+                <i class="fa fa-lg fa-arrows-h fa-fw"></i> Links
+            </a></li>
+            <li><a href="/repositories">
+                <i class="fa fa-lg fa-code-fork fa-fw"></i> Repositories
+            </a></li>
+            <li><a href="/virtual_machines">
+                <i class="fa fa-lg fa-ellipsis-h fa-fw"></i> Virtual machines
+            </a></li>
+            <% if current_user.andand.is_admin %>
+              <li><a href="/users">
+                  <i class="fa fa-lg fa-user fa-fw"></i> Users
+              </a></li>
+            <% end %>
+            <li><a href="/groups">
+                <i class="fa fa-lg fa-users fa-fw"></i> Groups
+            </a></li>
+            <li><a href="/nodes">
+                <i class="fa fa-lg fa-cogs fa-fw"></i> Compute nodes
+            </a></li>
+            <li><a href="/keep_disks">
+                <i class="fa fa-lg fa-hdd-o fa-fw"></i> Keep disks
+            </a></li>
           </ul>
         <% end %>
 

commit 20347d900fb2d75a3f3eef91d4da17a559b0ecd6
Merge: f107a52 da67c81
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 14:14:42 2014 -0400

    Merge branch '2640-folder-api' into 1970-folder-view

diff --cc apps/workbench/config/routes.rb
index 2d02566,f915671..c64c31e
--- a/apps/workbench/config/routes.rb
+++ b/apps/workbench/config/routes.rb
@@@ -40,9 -40,10 +40,11 @@@ ArvadosWorkbench::Application.routes.dr
    end
    resources :links
    match '/collections/graph' => 'collections#graph'
-   resources :collections
+   resources :collections do
+     post 'set_persistent', on: :member
+   end
    get '/collections/:uuid/*file' => 'collections#show_file', :format => false
 +  resources :folders
  
    post 'actions' => 'actions#post'
  

commit f107a5232d5e8788ae19daf1c5f6639f0c3cdb68
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 13:50:59 2014 -0400

    Fix "create folder"

diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb
index 6a761f6..31f3464 100644
--- a/apps/workbench/app/controllers/application_controller.rb
+++ b/apps/workbench/app/controllers/application_controller.rb
@@ -129,10 +129,10 @@ class ApplicationController < ActionController::Base
   end
 
   def create
-    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
+    @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!
 
     respond_to do |f|
diff --git a/apps/workbench/app/controllers/folders_controller.rb b/apps/workbench/app/controllers/folders_controller.rb
index 12ffc20..3f536fb 100644
--- a/apps/workbench/app/controllers/folders_controller.rb
+++ b/apps/workbench/app/controllers/folders_controller.rb
@@ -14,8 +14,7 @@ class FoldersController < ApplicationController
   end
 
   def create
-    params['folder'] ||= {}.with_indifferent_access
-    params['folder']['group_class'] = 'folder'
+    @new_resource_attrs = (params['folder'] || {}).merge(group_class: 'folder')
     super
   end
 end
diff --git a/apps/workbench/app/models/group.rb b/apps/workbench/app/models/group.rb
index c628b56..53a9496 100644
--- a/apps/workbench/app/models/group.rb
+++ b/apps/workbench/app/models/group.rb
@@ -7,4 +7,8 @@ class Group < ArvadosBase
     ret.results = $arvados_api_client.unpack_api_response(res)
     ret
   end
+
+  def class_for_display
+    group_class == 'folder' ? 'Folder' : super
+  end
 end
diff --git a/apps/workbench/app/views/application/index.html.erb b/apps/workbench/app/views/application/index.html.erb
index 06735c1..a32e7bf 100644
--- a/apps/workbench/app/views/application/index.html.erb
+++ b/apps/workbench/app/views/application/index.html.erb
@@ -12,7 +12,7 @@
           'data-target' => '#user-setup-modal-window', return_to: request.url}  %>
       <div id="user-setup-modal-window" class="modal fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"></div>
     <% else %>
-      <%= button_to "Add a new #{controller.controller_name.humanize.downcase}",
+      <%= button_to "Add a new #{controller.controller_name.singularize.humanize.downcase}",
         { action: 'create' },
         { class: 'btn btn-primary pull-right' } %>
     <% end %>
diff --git a/apps/workbench/app/views/folders/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
index a89afbc..c02c48b 100644
--- a/apps/workbench/app/views/folders/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -46,7 +46,7 @@
           Created: <%= @object.created_at.to_s(:long) %>
         </p>
         <p>
-          Last modified: <%= @object.modified_at.to_s(:long) %> by <%= link_to_if_arvados_object @object.modified_by_user_uuid %>
+          Last modified: <%= @object.modified_at.to_s(:long) %> by <%= link_to_if_arvados_object @object.modified_by_user_uuid, friendly_name: true %>
         </p>
         <% end %>
       </div>

commit 7df1885cee1d6eb0f65a010f13ca7e9ff59c80d9
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 13:37:34 2014 -0400

    Fix no-side-nav mode.

diff --git a/apps/workbench/app/assets/stylesheets/application.css.scss b/apps/workbench/app/assets/stylesheets/application.css.scss
index 92a5670..c03548c 100644
--- a/apps/workbench/app/assets/stylesheets/application.css.scss
+++ b/apps/workbench/app/assets/stylesheets/application.css.scss
@@ -167,3 +167,7 @@ table.table-fixed-header-row tbody {
 .editable-popup.popover {
     z-index:1055;
 }
+
+.side-nav {
+    border-right: 1px solid #e7e7e7;
+}
diff --git a/apps/workbench/app/assets/stylesheets/sb-admin.css.scss b/apps/workbench/app/assets/stylesheets/sb-admin.css.scss
index e9b99d6..61a7533 100644
--- a/apps/workbench/app/assets/stylesheets/sb-admin.css.scss
+++ b/apps/workbench/app/assets/stylesheets/sb-admin.css.scss
@@ -94,7 +94,6 @@ table.tablesorter thead tr th:hover {
 
   #page-wrapper {
         padding: 15px 25px;
-        border-left: 1px solid #e7e7e7;
   }
 
   /* Side Nav */
diff --git a/apps/workbench/app/views/layouts/application.html.erb b/apps/workbench/app/views/layouts/application.html.erb
index 42363a0..2e17f54 100644
--- a/apps/workbench/app/views/layouts/application.html.erb
+++ b/apps/workbench/app/views/layouts/application.html.erb
@@ -60,8 +60,8 @@
       </div>
 
       <div class="collapse navbar-collapse">
+        <% if current_user.andand.is_active %>
           <ul class="nav navbar-nav side-nav">
-            <% if current_user.andand.is_active %>
 
             <li class="<%= 'arvados-nav-active' if params[:action] == 'home' %>">
               <a href="/"><i class="fa fa-lg fa-dashboard fa-fw"></i> Dashboard</a>
@@ -125,8 +125,8 @@
                 </a></li>
               </ul>
             </li>
-            <% end %>
           </ul>
+        <% end %>
 
 
 

commit c66afecd36cf7d91223b5db79f3e120954f8217d
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 11:43:26 2014 -0400

    Move folders into a separate controller. Add description-editing.

diff --git a/apps/workbench/app/assets/javascripts/folders.js b/apps/workbench/app/assets/javascripts/folders.js
new file mode 100644
index 0000000..2e413b4
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/folders.js
@@ -0,0 +1,7 @@
+$(document).
+    on('ready ajax:complete', function() {
+        $("[data-toggle='x-editable']").click(function(e) {
+            e.stopPropagation();
+            $($(this).attr('data-toggle-selector')).editable('toggle');
+        });
+    });
diff --git a/apps/workbench/app/assets/javascripts/folders.js.coffee b/apps/workbench/app/assets/javascripts/folders.js.coffee
new file mode 100644
index 0000000..7615679
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/folders.js.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/apps/workbench/app/assets/stylesheets/application.css.scss b/apps/workbench/app/assets/stylesheets/application.css.scss
index c918125..92a5670 100644
--- a/apps/workbench/app/assets/stylesheets/application.css.scss
+++ b/apps/workbench/app/assets/stylesheets/application.css.scss
@@ -159,3 +159,11 @@ table.table-fixed-header-row tbody {
 .row-fill-height, .row-fill-height>div[class*='col-'] {
     display: flex;
 }
+.row-fill-height>div[class*='col-']>div {
+    width: 100%;
+}
+
+/* Show editable popover above side-nav */
+.editable-popup.popover {
+    z-index:1055;
+}
diff --git a/apps/workbench/app/assets/stylesheets/folders.css.scss b/apps/workbench/app/assets/stylesheets/folders.css.scss
new file mode 100644
index 0000000..1dea791
--- /dev/null
+++ b/apps/workbench/app/assets/stylesheets/folders.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the folders controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb
index 169f304..6a761f6 100644
--- a/apps/workbench/app/controllers/application_controller.rb
+++ b/apps/workbench/app/controllers/application_controller.rb
@@ -129,8 +129,9 @@ class ApplicationController < ActionController::Base
   end
 
   def create
-    new_resource_attrs = params[model_class.to_s.underscore.singularize].
-      reject { |k,v| k.to_s == 'uuid' }
+    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!
 
@@ -170,10 +171,6 @@ class ApplicationController < ActionController::Base
     controller_name.classify.constantize
   end
 
-  def model_class_for_display
-    model_class.to_s
-  end
-
   def breadcrumb_page_name
     (@breadcrumb_page_name ||
      (@object.friendly_link_name if @object.respond_to? :friendly_link_name) ||
diff --git a/apps/workbench/app/controllers/folders_controller.rb b/apps/workbench/app/controllers/folders_controller.rb
new file mode 100644
index 0000000..12ffc20
--- /dev/null
+++ b/apps/workbench/app/controllers/folders_controller.rb
@@ -0,0 +1,21 @@
+class FoldersController < ApplicationController
+  def model_class
+    Group
+  end
+
+  def index
+    @objects = Group.where group_class: 'folder'
+  end
+
+  def show
+    @objects = @object.contents include_linked: true
+    @logs = Log.limit(10).filter([['object_uuid', '=', @object.uuid]])
+    super
+  end
+
+  def create
+    params['folder'] ||= {}.with_indifferent_access
+    params['folder']['group_class'] = 'folder'
+    super
+  end
+end
diff --git a/apps/workbench/app/controllers/groups_controller.rb b/apps/workbench/app/controllers/groups_controller.rb
index 6c0264e..854496a 100644
--- a/apps/workbench/app/controllers/groups_controller.rb
+++ b/apps/workbench/app/controllers/groups_controller.rb
@@ -1,30 +1,13 @@
 class GroupsController < ApplicationController
-  def model_class_for_display
-    params[:group_class] || super
-  end
-
   def index
-    if params[:group_class]
-      @groups = Group.where(group_class: params[:group_class])
-    else
-      @groups = Group.all
-    end
+    @groups = Group.filter [['group_class', 'not in', ['folder']]]
     @group_uuids = @groups.collect &:uuid
     @links_from = Link.where link_class: 'permission', tail_uuid: @group_uuids
     @links_to = Link.where link_class: 'permission', head_uuid: @group_uuids
   end
 
   def show
-    @objects = @object.contents include_linked: true
-    super
-  end
-
-  def create
-    # params[:group_class]=='folder' if we were routed through /folders
-    logger.error params.inspect
-    if (rsc = params[:group_class])
-      params['group'] = (params[rsc] || {}).merge(group_class: rsc)
-    end
+    return redirect_to(folder_path(@object)) if @object.group_class == 'folder'
     super
   end
 end
diff --git a/apps/workbench/app/helpers/application_helper.rb b/apps/workbench/app/helpers/application_helper.rb
index d6b258b..4e883f5 100644
--- a/apps/workbench/app/helpers/application_helper.rb
+++ b/apps/workbench/app/helpers/application_helper.rb
@@ -156,7 +156,7 @@ module ApplicationHelper
     end
     ajax_options['data-pk'] = ajax_options['data-pk'].to_json
 
-    link_to attrvalue.to_s, '#', {
+    content_tag 'span', attrvalue.to_s, {
       "data-emptytext" => "none",
       "data-placement" => "bottom",
       "data-type" => input_type,
diff --git a/apps/workbench/app/helpers/folders_helper.rb b/apps/workbench/app/helpers/folders_helper.rb
new file mode 100644
index 0000000..d27e7b4
--- /dev/null
+++ b/apps/workbench/app/helpers/folders_helper.rb
@@ -0,0 +1,2 @@
+module FoldersHelper
+end
diff --git a/apps/workbench/app/views/application/_show_recent.html.erb b/apps/workbench/app/views/application/_show_recent.html.erb
index b02ce19..aabd021 100644
--- a/apps/workbench/app/views/application/_show_recent.html.erb
+++ b/apps/workbench/app/views/application/_show_recent.html.erb
@@ -1,7 +1,7 @@
 <% if @objects.empty? %>
 <br/>
 <p style="text-align: center">
-  No <%= controller.model_class_for_display.pluralize.underscore.gsub '_', ' ' %> to display.
+  No <%= controller.controller_name.humanize.downcase %> to display.
 </p>
 
 <% else %>
diff --git a/apps/workbench/app/views/application/index.html.erb b/apps/workbench/app/views/application/index.html.erb
index f6bd49c..06735c1 100644
--- a/apps/workbench/app/views/application/index.html.erb
+++ b/apps/workbench/app/views/application/index.html.erb
@@ -12,8 +12,8 @@
           'data-target' => '#user-setup-modal-window', return_to: request.url}  %>
       <div id="user-setup-modal-window" class="modal fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"></div>
     <% else %>
-      <%= button_to "Add a new #{controller.model_class_for_display.underscore.gsub '_', ' '}",
-        { action: 'create', return_to: request.url },
+      <%= button_to "Add a new #{controller.controller_name.humanize.downcase}",
+        { action: 'create' },
         { class: 'btn btn-primary pull-right' } %>
     <% end %>
 
diff --git a/apps/workbench/app/views/groups/show.html.erb b/apps/workbench/app/views/folders/show.html.erb
similarity index 76%
rename from apps/workbench/app/views/groups/show.html.erb
rename to apps/workbench/app/views/folders/show.html.erb
index b6f970f..a89afbc 100644
--- a/apps/workbench/app/views/groups/show.html.erb
+++ b/apps/workbench/app/views/folders/show.html.erb
@@ -1,27 +1,19 @@
-<% content_for :css do %>
-.arvados-nav-container {
-    display:none;
-}
-<% end %>
-
 <div class="row row-fill-height">
   <div class="col-md-6">
     <div class="panel panel-info">
       <div class="panel-heading">
-	<a class="btn btn-xs btn-info pull-right">
-	  Rename
-	</a>
 	<h3 class="panel-title">
-	  <%= @object.name %>
+	  <%= render_editable_attribute @object, 'name', nil, { 'data-emptytext' => "New folder" } %>
 	</h3>
       </div>
       <div class="panel-body">
-	<img src="/favicon.ico" class="pull-right" alt=""/>
+        <img src="/favicon.ico" class="pull-right" alt="" style="opacity: 0.3"/>
 	<p>
-	  This folder was created <%= @object.created_at %>. (This
-	  description defaults to something generic.)
+	  <%= render_editable_attribute @object, 'description', nil, { 'data-emptytext' => "Created: #{@object.created_at.to_s(:long)}", 'data-toggle' => 'manual', 'id' => "#{@object.uuid}-description" } %>
 	</p>
-	<a href="#" class="btn btn-xs btn-info">Edit description</a>
+        <% if @object.attribute_editable? 'description' %>
+	<a href="#" class="btn btn-xs btn-info" data-toggle="x-editable" data-toggle-selector="#<%= @object.uuid %>-description">Edit description</a>
+        <% end %>
       </div>
     </div>
   </div>
@@ -33,17 +25,30 @@
 	</h3>
       </div>
       <div class="panel-body">
+        <!--
 	<input type="text" class="form-control" placeholder="Search"/>
+        -->
 	<div style="height:0.5em;"></div>
+        <% @logs[0..2].each do |log| %>
 	<p>
-	  11:12 - Some Subfolder added
-	</p>
-	<p>
-	  10:06 - <%= @object.name %> - renamed from OldFolderName to <%= @object.name %>
-	</p>
-	<p>
-	  10:01 - Test Dataset (4 GiB collection) added to <%= @object.name %> by <%= link_to_if_arvados_object @object.owner_uuid, friendly_name: true %>
+	  <%= time_ago_in_words(log.event_at) %> ago: <%= log.summary %>
+          <% if log.object_uuid %>
+          <%= link_to_if_arvados_object log.object_uuid, link_text: raw('<i class="fa fa-hand-o-right"></i>') %>
+          <% end %>
 	</p>
+        <% end %>
+        <% if @logs.any? %>
+	<%= link_to raw('Show all activity   <i class="fa fa-hand-o-right"></i>'),
+            logs_path(filters: [['object_uuid','=', at object.uuid]]),
+            class: 'btn btn-sm btn-info' %>
+        <% else %>
+        <p>
+          Created: <%= @object.created_at.to_s(:long) %>
+        </p>
+        <p>
+          Last modified: <%= @object.modified_at.to_s(:long) %> by <%= link_to_if_arvados_object @object.modified_by_user_uuid %>
+        </p>
+        <% end %>
       </div>
     </div>
   </div>
@@ -55,25 +60,11 @@
 	</h3>
       </div>
       <div class="panel-body">
+        <!--
 	<input type="text" class="form-control" placeholder="Search"/>
+        -->
 	<div style="height:0.5em;"></div>
-	<table class="table table-condensed">
-	  <tbody>
-	    <tr>
-	      <td><%= link_to_if_arvados_object @object.owner_uuid, friendly_name: true %></td>
-	      <td>Owner</td>
-	    </tr>
-	    <tr>
-	      <td>Someone Else</td>
-	      <td>read only</td>
-	    </tr>
-	    <tr>
-	      <td>Someone Else</td>
-	      <td>read+write</td>
-	    </tr>
-	  </tbody>
-	  <thead><tr><th>User</th><th>Role</th></tr></thead>
-	</table>
+        <p>Owner: <%= link_to_if_arvados_object @object.owner_uuid, friendly_name: true %></p>
       </div>
     </div>
   </div>
diff --git a/apps/workbench/app/views/groups/_show_recent.html.erb b/apps/workbench/app/views/groups/_show_recent.html.erb
index 83b31cc..c709e89 100644
--- a/apps/workbench/app/views/groups/_show_recent.html.erb
+++ b/apps/workbench/app/views/groups/_show_recent.html.erb
@@ -4,7 +4,7 @@
   <thead>
     <tr class="contain-align-left">
       <th>
-	<%= controller.model_class_for_display.capitalize %>
+	Group
       </th><th>
 	Owner
       </th><th>
diff --git a/apps/workbench/app/views/layouts/application.html.erb b/apps/workbench/app/views/layouts/application.html.erb
index 094cbc9..42363a0 100644
--- a/apps/workbench/app/views/layouts/application.html.erb
+++ b/apps/workbench/app/views/layouts/application.html.erb
@@ -138,7 +138,7 @@
               <li class="nav-separator"><span class="glyphicon glyphicon-arrow-right"></span></li>
               <li>
                 <%= link_to(
-                            controller.model_class_for_display.pluralize.underscore.gsub('_', ' '),
+                            controller.controller_name.humanize.downcase,
                             url_for({controller: params[:controller]})) %>
               </li>
               <% if params[:action] != 'index' %>
diff --git a/apps/workbench/config/routes.rb b/apps/workbench/config/routes.rb
index 4fb6578..2d02566 100644
--- a/apps/workbench/config/routes.rb
+++ b/apps/workbench/config/routes.rb
@@ -42,7 +42,7 @@ ArvadosWorkbench::Application.routes.draw do
   match '/collections/graph' => 'collections#graph'
   resources :collections
   get '/collections/:uuid/*file' => 'collections#show_file', :format => false
-  resources :folders, controller: :groups, group_class: 'folder'
+  resources :folders
 
   post 'actions' => 'actions#post'
 
diff --git a/apps/workbench/test/functional/folders_controller_test.rb b/apps/workbench/test/functional/folders_controller_test.rb
new file mode 100644
index 0000000..2e06cca
--- /dev/null
+++ b/apps/workbench/test/functional/folders_controller_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class FoldersControllerTest < ActionController::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end
diff --git a/apps/workbench/test/unit/helpers/folders_helper_test.rb b/apps/workbench/test/unit/helpers/folders_helper_test.rb
new file mode 100644
index 0000000..5b4c557
--- /dev/null
+++ b/apps/workbench/test/unit/helpers/folders_helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class FoldersHelperTest < ActionView::TestCase
+end

commit cc22cd28f536fa6fd95732372177d36a94a4c08d
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 02:43:47 2014 -0400

    Make "create folder" button work

diff --git a/apps/workbench/app/controllers/groups_controller.rb b/apps/workbench/app/controllers/groups_controller.rb
index 416969f..6c0264e 100644
--- a/apps/workbench/app/controllers/groups_controller.rb
+++ b/apps/workbench/app/controllers/groups_controller.rb
@@ -18,4 +18,13 @@ class GroupsController < ApplicationController
     @objects = @object.contents include_linked: true
     super
   end
+
+  def create
+    # params[:group_class]=='folder' if we were routed through /folders
+    logger.error params.inspect
+    if (rsc = params[:group_class])
+      params['group'] = (params[rsc] || {}).merge(group_class: rsc)
+    end
+    super
+  end
 end

commit d39470cbc160b9d51033a564e0b8867388a5a1d3
Author: Tom Clegg <tom at curoverse.com>
Date:   Tue Apr 29 17:06:58 2014 -0400

    Rename owned_items to contents.

diff --git a/apps/workbench/app/controllers/groups_controller.rb b/apps/workbench/app/controllers/groups_controller.rb
index 358cb2c..416969f 100644
--- a/apps/workbench/app/controllers/groups_controller.rb
+++ b/apps/workbench/app/controllers/groups_controller.rb
@@ -15,7 +15,7 @@ class GroupsController < ApplicationController
   end
 
   def show
-    @objects = @object.owned_items include_linked: true
+    @objects = @object.contents include_linked: true
     super
   end
 end

commit 1c45ed6a43b01a4f216cf8877b35d9ad18e1c5b5
Merge: 420949e 9cfbcdf
Author: Tom Clegg <tom at curoverse.com>
Date:   Tue Apr 29 17:05:24 2014 -0400

    Merge branch '2640-folder-api' into 1970-folder-view


-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list