2884: Can now choose a specific folder to browse in the file selector modal.
authorPeter Amstutz <peter.amstutz@curoverse.com>
Tue, 17 Jun 2014 21:04:42 +0000 (17:04 -0400)
committerPeter Amstutz <peter.amstutz@curoverse.com>
Tue, 17 Jun 2014 21:04:42 +0000 (17:04 -0400)
18 files changed:
apps/workbench/app/assets/javascripts/application.js
apps/workbench/app/assets/javascripts/collections.js
apps/workbench/app/assets/javascripts/infinite_scroll.js
apps/workbench/app/assets/stylesheets/application.css.scss
apps/workbench/app/assets/stylesheets/select_modal.css.scss
apps/workbench/app/controllers/application_controller.rb
apps/workbench/app/controllers/collections_controller.rb
apps/workbench/app/models/arvados_base.rb
apps/workbench/app/views/application/_choose.html.erb
apps/workbench/app/views/application/_choose.js.erb
apps/workbench/app/views/application/_content.html.erb
apps/workbench/app/views/application/_projects_tree_menu.html.erb [new file with mode: 0644]
apps/workbench/app/views/collections/_choose_rows.html.erb
apps/workbench/app/views/collections/index.js.erb
apps/workbench/app/views/layouts/application.html.erb
apps/workbench/app/views/pipeline_instances/show.js.erb
apps/workbench/app/views/users/home.js.erb
services/api/app/controllers/arvados/v1/groups_controller.rb

index e35e93c5d33af1f78a0d4ef6298d827b11095ffc..1a8b9900a21fb50417dde6498d868682cc52b7e0 100644 (file)
@@ -58,6 +58,14 @@ jQuery(function($){
                 $('.loading').fadeOut('fast', 0);
             }
         }).
+        on('ajaxSend', function(e, xhr) {
+            // map jquery event to rails event
+            $(document).trigger('ajax:send');
+        }).
+        on('ajaxComplete', function(e, xhr) {
+            // map jquery event to rails event
+            $(document).trigger('ajax:complete');
+        }).
         on('click', '.removable-tag a', function(e) {
             var tag_span = $(this).parents('[data-tag-link-uuid]').eq(0)
             tag_span.fadeTo('fast', 0.2);
index e95783512721b87b2aea0e47ec80e919646608b8..865f121e56b20e4bdb1e59a388a6316430740e81 100644 (file)
@@ -20,7 +20,6 @@ jQuery(function($){
                }).
             done(function(data, status, jqxhr) {
                 var context = this;
-                $(document).trigger('ajax:complete');
                 // Remove "danger" status in case a previous action failed
                 $('.btn-danger', context.toggle_group).
                     addClass('btn-info').
@@ -32,7 +31,6 @@ jQuery(function($){
             fail(function(jqxhr, status, error) {
                 var context = this;
                 var saved_state;
-                $(document).trigger('ajax:complete');
                 // Add a visual indication that something failed
                 $(context.button).
                     addClass('btn-danger').
@@ -53,6 +51,5 @@ jQuery(function($){
                     window.alert("Request failed.");
                 }
             });
-        $(document).trigger('ajax:send');
     });
 });
index 64a90e2255d117ba7416e5d362269e53aba5ee70..498f10a1167a7c59ea19559927dc8d750db5093e 100644 (file)
@@ -34,7 +34,6 @@ function maybe_load_more_content() {
             done(function(data, status, jqxhr) {
                 $(this.container).append(data.content);
                 $(this.container).attr('data-infinite-content-href', data.next_page_href);
-                $(document).trigger('ajax:complete');
             });
     }
 }
index 4fea7aebc09261df394dc754437157c9abe24e08..a50a34e54e631d1caa2035c028992a8502bbc730 100644 (file)
@@ -115,6 +115,15 @@ nav.navbar-fixed-top {
 .navbar.breadcrumbs .nav > li.nav-separator > i {
     color: #bbb;
 }
+.navbar.breadcrumbs .navbar-form {
+  margin-top: 0px;
+  margin-bottom: 0px;
+}
+.navbar.breadcrumbs .navbar-text {
+  margin-top: 0px;
+  margin-bottom: 0px;
+}
+
 nav.navbar-fixed-top .navbar-nav.navbar-right > li.open > a,
 nav.navbar-fixed-top .navbar-nav.navbar-right > li.open > a:focus,
 nav.navbar-fixed-top .navbar-nav.navbar-right > li.open > a:hover {
index 5aab6698259afb271c0f1feac0782b58df3382ef..09017697b646298a2a71d34b5c16c60db662a5bb 100644 (file)
@@ -5,6 +5,7 @@
 }
 .selectable.active, .selectable:hover {
     background: #d9edf7;
+    cursor: pointer;
 }
 .selectable.active,
 .selectable.active *,
index ebd8661f55800674b1bfb653b84e39f342bf16e3..02b9501e9388f6f8ff1ea5e97e28c5d438504dbc 100644 (file)
@@ -12,7 +12,7 @@ class ApplicationController < ActionController::Base
   around_filter :thread_with_optional_api_token
   before_filter :check_user_agreements, except: ERROR_ACTIONS
   before_filter :check_user_notifications, except: ERROR_ACTIONS
-  before_filter :find_object_by_uuid, except: [:index] + ERROR_ACTIONS
+  before_filter :find_object_by_uuid, except: [:index, :choose] + ERROR_ACTIONS
   theme :select_theme
 
   begin
index 3017be95ea7d3a3f0713bd581962bb1511f1f857..593b3f83c1f18f3378e4aaa5ea994c964f679ba7 100644 (file)
@@ -44,13 +44,23 @@ class CollectionsController < ApplicationController
 
   def choose
     params[:limit] ||= 20
-    @objects = Link.
-      filter([['link_class','=','name'],
-              ['head_uuid','is_a','arvados#collection']])
+
+    filter = [['link_class','=','name'],
+              ['head_uuid','is_a','arvados#collection']]
+
+    if params[:project_uuid] and !params[:project_uuid].empty?
+      filter << ['tail_uuid', '=', params[:project_uuid]]
+    end
+
+    @objects = Link.filter(filter)
+
     find_objects_for_index
     @next_page_href = (next_page_offset and
                        url_for(offset: next_page_offset, partial: true))
     @name_links = @objects
+
+    puts "and the result is (1) ", @name_links.results
+
     @objects = Collection.
       filter([['uuid','in',@name_links.collect(&:head_uuid)]])
     super
index aca87868c3ab7f1f3523fc66d6569f031c8e99f2..3b5ac86f91c0c0f0134045a8e75a19bbc76c536d 100644 (file)
@@ -295,6 +295,10 @@ class ArvadosBase < ActiveRecord::Base
     self.class.to_s.underscore.humanize
   end
 
+  def self.class_for_display
+    self.to_s.underscore.humanize
+  end
+
   def self.creatable?
     current_user
   end
index 5c2aa96a83dd4f442248b38eb6266ecfb667cefa..fdd3d3c44478cf2ae8b654f558655b7626cc1670 100644 (file)
@@ -3,31 +3,50 @@
     <div class="modal-content">
       <div class="modal-header">
         <button type="button" class="close" onClick="reset_form()" data-dismiss="modal" aria-hidden="true">&times;</button>
-        <h4 class="modal-title"><%= params[:title] || "Choose #{@objects.first.class_for_display}" %></h4>
+        <h4 class="modal-title"><%= params[:title] || "Choose #{@objects.first.andand.class_for_display}" %></h4>
       </div>
       <div class="modal-body">
-        <div>
-          <div class="row">
-            <div class="col-sm-6">
-            </div>
-            <div class="col-sm-6">
-              <input type="text" class="form-control filterable-control" placeholder="Search" data-filterable-target=".modal.arv-choose .selectable-container"/>
-            </div>
+        <nav class="navbar navbar-default breadcrumbs" role="navigation">
+          <ul class="nav navbar-nav navbar-left">
+            <li class="dropdown">
+            <%= render partial: "projects_tree_menu", locals: {
+                  :project_link_to => Proc.new do |pnode, &block|
+                    link_to "#", {"class" => "chooser-show-project", "data-project-uuid" => pnode[:object].uuid }, &block
+                   end,
+                  :top_button => Proc.new do %>
+                    <% link_to "#", {"class" => "chooser-show-project btn btn-xs btn-default pull-right" } do %>
+                      All <%= controller.model_class.class_for_display.pluralize.downcase %>
+                    <% end %>
+                  <% end %>
+             <% } %>
+            </li>
+            <li class="nav-separator">
+              <i class="fa fa-lg fa-angle-double-right"></i>
+            </li>
+            <li><p class="navbar-text" id="chooser-breadcrumb">All <%= controller.model_class.class_for_display.pluralize.downcase %></span></li>
+          </ul>
+          <div class="navbar-form navbar-right">
+            <input type="text" class="form-control filterable-control" placeholder="Search" data-filterable-target=".modal.arv-choose .selectable-container"/>
           </div>
-        </div>
+        </nav>
 
         <div class="row" style="height: 20em">
-          <div class="col-sm-6 container-fluid arv-filterable-list selectable-container" style="height: 100%; overflow-y: scroll" data-infinite-scroller="#choose-scroll" id="choose-scroll" data-infinite-content-href="<%= @next_page_href %>">
-          <%= render partial: 'choose_rows', locals: {multiple: multiple} %>
+          <div class="col-sm-6 container-fluid arv-filterable-list selectable-container"
+               style="height: 100%; overflow-y: scroll"
+               data-infinite-scroller="#choose-scroll"
+               id="choose-scroll"
+               data-infinite-content-href="<%= @next_page_href %>">
+            <%= render partial: 'choose_rows', locals: {multiple: multiple} %>
           </div>
           <div class="col-sm-6 modal-dialog-preview-pane" style="height: 100%; overflow-y: scroll">
           </div>
-      </div>
+        </div>
 
-      <div class="modal-footer">
-        <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Cancel</button>
-        <button class="btn btn-primary" aria-hidden="true" data-enable-if-selection disabled><%= raw(params[:action_name]) || 'Select' %></button>
-        <div class="modal-error hide" style="text-align: left; margin-top: 1em;">
+        <div class="modal-footer">
+          <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Cancel</button>
+          <button class="btn btn-primary" aria-hidden="true" data-enable-if-selection disabled><%= raw(params[:action_name]) || 'Select' %></button>
+          <div class="modal-error hide" style="text-align: left; margin-top: 1em;">
+          </div>
         </div>
       </div>
     </div>
index 3bb369451add5674495a5747540aa72ef7f53f12..14de170ff315b5970b1c2388c4b240aab177033d 100644 (file)
@@ -5,4 +5,24 @@ $('body > .modal-container .modal .modal-footer .btn-primary').
     attr('data-action-href', '<%= j params[:action_href] %>').
     attr('data-method', '<%= j params[:action_method] %>').
     data('action-data', <%= raw params[:action_data] %>);
-$(document).trigger('ajax:complete');
+$(".chooser-show-project").on("click", function() {
+  $("#choose-scroll").html("<%=j image_tag 'ajax-loader.gif' %>");
+  var t = $(this);
+  var d = {
+      partial: true,
+      multiple: <%= multiple %>
+    };
+  if (t.attr("data-project-uuid") != null) {
+    d.project_uuid = t.attr("data-project-uuid");
+  }
+  $.ajax('<%=j url_for %>', {
+    dataType: "json",
+    type: "GET",
+    data: d
+  }).done(function(data, status, jqxhr) {
+    console.log(data);
+    $("#chooser-breadcrumb").text(t.text());
+    $("#choose-scroll").html(data.content);
+    $("#choose-scroll").prop("data-infinite-content-href", "next_page_href");
+  });
+});
index 418923c85abf033f9b988245f0efa573df5ed4bd..02f2e6f88fa729b6e89066201f9a2f9eff9f02ab 100644 (file)
   function ajaxRefreshTabPane(pane) {
     if (!tab_pane_valid_state[pane]) {
       tab_pane_valid_state[pane] = true;
-      $(document).trigger('ajax:send');
       $.ajax('<%=j url_for() %>?<%= raw(controller.request.query_string) %>&tab_pane='+pane, {dataType: 'html', type: 'GET'}).
         done(function(data, status, jqxhr) {
           $('#' + pane + ' > div > div').html(data);
-          $(document).trigger('ajax:complete');
           ajaxRefreshTabPane(pane);
         });
     }
diff --git a/apps/workbench/app/views/application/_projects_tree_menu.html.erb b/apps/workbench/app/views/application/_projects_tree_menu.html.erb
new file mode 100644 (file)
index 0000000..390ef77
--- /dev/null
@@ -0,0 +1,31 @@
+            <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="projects-menu">
+              <i class="fa fa-lg fa-fw fa-home"></i>
+              Projects
+              <span class="caret"></span>
+            </a>
+            <ul class="dropdown-menu" role="menu">
+              <li role="presentation" class="dropdown-header">
+                <%= top_button.call %>
+                My projects
+              </li>
+              <% my_project_tree.each do |pnode| %>
+                <% next if pnode[:object].class != Group %>
+                <li style="padding-left: <%= pnode[:depth]-1 %>em">
+                  <%= project_link_to.call pnode do %>
+                    <%= pnode[:object].name %>
+                  <% end %>
+                </li>
+              <% end %>
+              <li class="divider">
+              <li role="presentation" class="dropdown-header">
+                Projects shared with me
+              </li>
+              <% shared_project_tree.each do |pnode| %>
+                <% next if pnode[:object].class != Group %>
+                <li style="padding-left: <%= pnode[:depth]-1 %>em">
+                  <%= project_link_to.call pnode do %>
+                    <i class="fa fa-fw fa-share-alt" style="color:#aaa"></i> <%= pnode[:object].name %>
+                  <% end %>
+                </li>
+              <% end %>
+            </ul>
index d87f56f9cd4136c40009c71e67113271b6fde2b5..170ce77b7a355f63e6841bbb73d21975f8aaedd5 100644 (file)
@@ -1,5 +1,8 @@
+<% puts "and the result is (2) ", @name_links.results, "objects is #{@objects}" %>
 <% @name_links.each do |name_link| %>
+  <% puts "looking up #{name_link.head_uuid}" %>
   <% if (object = get_object(name_link.head_uuid)) %>
+    <% puts "got #{object}" %>
     <div class="row filterable selectable <%= 'multiple' if multiple %>" data-object-uuid="<%= name_link.uuid %>"
          data-preview-href="<%= url_for object %>?tab_pane=chooser_preview"
          style="margin-left: 1em; border-bottom-style: solid; border-bottom-width: 1px; border-bottom-color: #DDDDDD">
index 46f7d176b8b44ab7f2587ab45f1409d0ea7b73ef..44839f42b21486a4db58c04c0da8d3399733b40f 100644 (file)
@@ -2,4 +2,3 @@ if(history.replaceState)
     history.replaceState(null, null, "<%= escape_javascript(@request_url) %>");
 $('table#collections-index tbody').html("<%= escape_javascript(render partial: 'index_tbody') %>");
 $('table#collections-index tbody').fadeTo(200, 1.0);
-$(document).trigger('ajax:complete');
index 778268ea5b0ad424a161768b51a9befce5ef556e..23e071525f254db74e4af36479aa9478ee40b5b3 100644 (file)
       <nav class="navbar navbar-default breadcrumbs" role="navigation">
         <ul class="nav navbar-nav navbar-left">
           <li class="dropdown">
-            <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="projects-menu">
-              <i class="fa fa-lg fa-fw fa-home"></i>
-              Projects
-              <span class="caret"></span>
-            </a>
-            <ul class="dropdown-menu" role="menu">
-              <li role="presentation" class="dropdown-header">
-                <%= link_to projects_path('project[owner_uuid]' => current_project_uuid), method: 'post', class: 'btn btn-xs btn-default pull-right' do %>
-                  <i class="fa fa-plus"></i> New project
-                <% end %>
-                My projects
-              </li>
-              <% my_project_tree.each do |pnode| %>
-                <% next if pnode[:object].class != Group %>
-                <li style="padding-left: <%= pnode[:depth]-1 %>em">
-                  <%= link_to(pnode[:object].name, project_path(pnode[:object].uuid), data: {object_uuid: pnode[:object].uuid, name: 'name'}) %>
-                </li>
-              <% end %>
-              <li class="divider">
-              <li role="presentation" class="dropdown-header">
-                Projects shared with me
-              </li>
-              <% shared_project_tree.each do |pnode| %>
-                <% next if pnode[:object].class != Group %>
-                <li style="padding-left: <%= pnode[:depth]-1 %>em">
-                  <%= link_to project_path(pnode[:object].uuid), data: {object_uuid: pnode[:object].uuid, name: 'name'} do %>
-                    <i class="fa fa-fw fa-share-alt" style="color:#aaa"></i> <%= pnode[:object].name %>
+            <%= render partial: "projects_tree_menu", locals: {
+                  :project_link_to => Proc.new do |pnode, &block|
+                    link_to(project_path(pnode[:object].uuid), data: {object_uuid: pnode[:object].uuid, name: 'name'}, &block)
+                  end,
+                  :top_button => Proc.new do %>
+                    <% link_to projects_path('project[owner_uuid]' => current_project_uuid), method: 'post', class: 'btn btn-xs btn-default pull-right' do %>
+                      <i class="fa fa-plus"></i> New project
+                    <% end %>
                   <% end %>
-                </li>
-              <% end %>
-            </ul>
+            <% } %>
           </li>
           <% project_breadcrumbs.each do |p| %>
             <li class="nav-separator">
index bdb703ed17800be4ebe94688d79286bcbb083d63..8ab1e8f68fdb5fa87150ded440436c947fd1f41e 100644 (file)
@@ -13,4 +13,3 @@ if ($('div#page-wrapper').html() != new_content) {
         $('.nav-tabs li a[href="' + href + '"]').tab('show');
     });
 }
-$(document).trigger('ajax:complete');
index b67a933b784ac435c79b6086b7bfd08ec6a84f55..d845186cf856c36e4c89e2e86b05f65c33ae2a69 100644 (file)
@@ -1,4 +1,3 @@
 var new_content = "<%= escape_javascript(render partial: 'tables') %>";
 if ($('div#home-tables').html() != new_content)
    $('div#home-tables').html(new_content);
-$(document).trigger('ajax:complete');
index da82e81ef81374e39994b08a27518e3f60de84e6..d7b330df9a70d5a7f5e1eee926e13500ed8a5d96 100644 (file)
@@ -24,6 +24,9 @@ class Arvados::V1::GroupsController < ApplicationController
      Job, PipelineInstance, PipelineTemplate,
      Collection,
      Human, Specimen, Trait].each do |klass|
+      if params[:object_kind] and klass.kind != params[:object_kind]
+        continue
+      end
       @objects = klass.readable_by(*@read_users)
       cond_sql = "#{klass.table_name}.owner_uuid = ?"
       cond_params = [@object.uuid]