var src; // url for retrieving content
var scrollHeight;
var spinner, colspan;
+ var serial = Date.now();
scrollHeight = scroller.scrollHeight || $('body')[0].scrollHeight;
if ($(scroller).scrollTop() + $(scroller).height()
>
scrollHeight - 50) {
container = $(this).data('infinite-container');
+ if (!$(container).attr('data-infinite-content-href0')) {
+ // Remember the first page source url, so we can refresh
+ // from page 1 later.
+ $(container).attr('data-infinite-content-href0',
+ $(container).attr('data-infinite-content-href'));
+ }
src = $(container).attr('data-infinite-content-href');
if (!src)
// Finished
}
$(container).find(".spinner").detach();
$(container).append(spinner);
+ $(container).attr('data-infinite-serial', serial);
$.ajax(src,
{dataType: 'json',
type: 'GET',
- data: {},
- context: {container: container, src: src}}).
- always(function() {
- }).
+ data: ($(container).data('infinite-content-params') || {}),
+ context: {container: container, src: src, serial: serial}}).
fail(function(jqxhr, status, error) {
var $faildiv;
+ if ($(this.container).attr('data-infinite-serial') != this.serial) {
+ // A newer request is already in progress.
+ return;
+ }
if (jqxhr.readyState == 0 || jqxhr.status == 0) {
message = "Cancelled."
} else if (jqxhr.responseJSON && jqxhr.responseJSON.errors) {
$(this.container).find('div.spinner').replaceWith($faildiv);
}).
done(function(data, status, jqxhr) {
+ if ($(this.container).attr('data-infinite-serial') != this.serial) {
+ // A newer request is already in progress.
+ return;
+ }
$(this.container).find(".spinner").detach();
$(this.container).append(data.content);
$(this.container).attr('data-infinite-content-href', data.next_page_href);
$retry_div.replaceWith('<div class="spinner spinner-32px spinner-h-center" />');
$scroller.trigger('scroll');
}).
+ on('refresh-content', '[data-infinite-scroller]', function() {
+ // Clear all rows, reset source href to initial state, and
+ // (if the container is visible) start loading content.
+ var first_page_href = $(this).attr('data-infinite-content-href0');
+ if (!first_page_href)
+ first_page_href = $(this).attr('data-infinite-content-href');
+ $(this).
+ html('').
+ attr('data-infinite-content-href', first_page_href);
+ $('.infinite-scroller').
+ trigger('scroll');
+ }).
on('ready ajax:complete', function() {
$('[data-infinite-scroller]').each(function() {
var $scroller = $($(this).attr('data-infinite-scroller'));
$(document).trigger(event_name!=null ? event_name : 'page-refresh',
[data, status, jqxhr, this.action_data]);
});
+}).on('click', '.chooser-show-project', function() {
+ $(this).attr('href', '#');
+ $($(this).closest('[data-filterable-target]').attr('data-filterable-target')).
+ data('infinite-content-params',
+ {'filters[]': JSON.stringify(['owner_uuid', '=', $(this).attr('data-project-uuid')])}).
+ trigger('refresh-content');
});
$(document).on('page-refresh', function(event, data, status, jqxhr, action_data) {
window.location.reload();
filters = params[:filters]
if filters.is_a? String
filters = Oj.load filters
+ elsif filters.is_a? Array
+ filters = filters.collect do |filter|
+ if filter.is_a? String
+ # Accept filters[]=["foo","=","bar"]
+ Oj.load filter
+ else
+ # Accept filters=[["foo","=","bar"]]
+ filter
+ end
+ end
end
@filters += filters
end
def choose
params[:limit] ||= 40
- if !@objects
- if params[:project_uuid] and !params[:project_uuid].empty?
- # We want the chooser to show objects of the controllers's model_class
- # type within a specific project specified by project_uuid, so fetch the
- # project and request the contents of the project filtered on the
- # controllers's model_class kind.
- @objects = Group.find(params[:project_uuid]).contents({:filters => [['uuid', 'is_a', "arvados\##{ArvadosApiClient.class_kind(model_class)}"]]})
- end
- find_objects_for_index if !@objects
- end
+ find_objects_for_index if !@objects
respond_to do |f|
if params[:partial]
f.json {
params[:limit] ||= 40
- 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)
+ @filters += [['link_class','=','name'],
+ ['head_uuid','is_a','arvados#collection']]
+ @objects = Link
find_objects_for_index
+
@name_links = @objects
@objects = Collection.
<div class="modal-body">
<div class="input-group">
+ <input type="text" class="form-control filterable-control" placeholder="Search" data-filterable-target=".modal.arv-choose .selectable-container"/>
<% if params[:by_project] %>
- <div class="input-group-btn">
+ <div class="input-group-btn" data-filterable-target=".modal.arv-choose .selectable-container">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
- Projects <span class="caret"></span>
+ Filter by project <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
+ <li>
+ <%= link_to '#', class: 'chooser-show-project' do %>
+ Remove filter (search all projects)
+ <% end %>
+ </li>
+ <li class="divider" />
<%= 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 class="divider" />
- <li><span class="navbar-text" id="chooser-breadcrumb">All <%= controller.model_class.class_for_display.pluralize.downcase %></span></li>
+ :top_button => nil
+ } %>
</ul>
</div>
<% end %>
- <input type="text" class="form-control filterable-control" placeholder="Search" data-filterable-target=".modal.arv-choose .selectable-container"/>
</div>
+ <div style="height: 1em" />
<div class="row" style="height: 20em">
<div class="col-sm-6 container 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 partial: true %>">
+ data-infinite-content-href="<%= next_page_href partial: true %>"
+ data-infinite-content-href0="<%= url_for partial: true %>">
<%= render partial: 'choose_rows', locals: {multiple: multiple} %>
</div>
<div class="col-sm-6 modal-dialog-preview-pane" style="height: 100%; overflow-y: scroll">
attr('data-action-href', '<%= j params[:action_href] %>').
attr('data-method', '<%= j params[:action_method] %>').
data('action-data', <%= raw params[:action_data] %>);
-$(".chooser-show-project").on("click", function() {
- $("#choose-scroll").html("<div class=\"spinner spinner-32px spinner-h-center\"></div>");
- $(".modal-dialog-preview-pane").html('');
- var t = $(this);
- var d = {
- partial: true,
- multiple: <%= multiple || "false" %>
- };
- 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) {
- $("#chooser-breadcrumb").text(t.text());
- $("#choose-scroll").html(data.content);
- $("#choose-scroll").prop("data-infinite-content-href", "next_page_href");
- });
-});
<li role="presentation" class="dropdown-header">
- <%= top_button.call %>
+ <%= top_button.andand.call %>
My projects
</li>
<% my_project_tree.each do |pnode| %>
action: 'choose',
controller: 'search',
title: 'Search',
+ by_project: true,
action_name: 'Show',
action_href: url_for(controller: :actions, action: :show),
action_method: 'get',
except: [:index, :create] + ERROR_ACTIONS)
before_filter :load_limit_offset_order_params, only: [:index, :contents]
before_filter :load_where_param, only: [:index, :contents]
- before_filter :load_filters_param, only: [:index, :contents]
+ before_filter :load_filters_param, only: [:index, :contents, :choose]
before_filter :find_objects_for_index, :only => :index
before_filter :reload_object_before_update, :only => :update
before_filter(:render_404_if_no_object,