diff --git a/app/controllers/collections_controller.rb b/app/controllers/collections_controller.rb
index 0877f89f6cf..62a2eab26f4 100644
--- a/app/controllers/collections_controller.rb
+++ b/app/controllers/collections_controller.rb
@@ -43,8 +43,9 @@ def index
flash_search_warnings(@collections)
@page_subtitle = t(".subcollections_page_title", collection_title: @collection.title)
elsif params[:user_id]
+ @sort_and_filter = true
@user = User.find_by!(login: params[:user_id])
- @search = CollectionSearchForm.new({ maintainer_id: @user.id, sort_column: "title.keyword" }.merge(page: params[:page]))
+ @search = CollectionSearchForm.new(collection_filter_params.merge({ maintainer_id: @user.id, default_sort_column: "title.keyword" }.merge(page: params[:page])))
@collections = @search.search_results.scope(:for_search)
flash_search_warnings(@collections)
@page_subtitle = ts("%{username} - Collections", username: @user.login)
@@ -194,7 +195,7 @@ def destroy
private
def collection_filter_params
- params.permit(:commit, collection_search: [
+ params.permit(:commit, :user_id, collection_search: [
:title, :challenge_type, :moderated, :multifandom, :closed, :tag,
:sort_column, :sort_direction
])[:collection_search] || {}
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 34d7ec9f3c2..9282b7dd811 100755
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -19,10 +19,11 @@ def link_to_function(name, *args, &block)
def classes_for_main
class_names = controller.controller_name + '-' + controller.action_name
- show_sidebar = (!@hide_dashboard && (@user || @admin_posts || @collection || show_wrangling_dashboard))
- class_names += " dashboard" if show_sidebar
-
- class_names += " filtered" if page_has_filters?
+ # Rails/HelperInstanceVariable is disabled for the two following lines given this warning is raised for reusing helpers. This function is only used once in application.html.erb
+ # Whether or not the sidebar should be shown
+ class_names += " dashboard" if !@hide_dashboard && (@user || @admin_posts || @collection || show_wrangling_dashboard) # rubocop:disable Rails/HelperInstanceVariable
+ # Whether or not the page will have filters
+ class_names += " filtered" if @facets.present? || (controller.controller_name == "collections" && @sort_and_filter) || (controller.action_name == "unassigned" && controller.controller_name == "fandoms") # rubocop:disable Rails/HelperInstanceVariable
case controller.controller_name
when "abuse_reports", "feedbacks", "known_issues"
@@ -57,10 +58,6 @@ def classes_for_main
class_names
end
- def page_has_filters?
- @facets.present? || (controller.action_name == 'index' && controller.controller_name == 'collections') || (controller.action_name == 'unassigned' && controller.controller_name == 'fandoms')
- end
-
# This is used to make the current page we're on (determined by the path or by the specified condition) a span with class "current" and it allows us to add a title attribute to the link or the span
def span_if_current(link_to_default_text, path, condition=nil, title_attribute_default_text=nil)
is_current = condition.nil? ? current_page?(path) : condition
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index dcb9be97318..a98848c890c 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -1,7 +1,6 @@
module SearchHelper
-
# modified from mislav-will_paginate-2.3.2/lib/will_paginate/view_helpers.rb
- def search_header(collection, search, item_name, parent=nil)
+ def search_header(collection, search, item_name, parent = nil)
header = []
if !collection.respond_to?(:total_pages)
header << ts("Recent #{item_name.pluralize}")
@@ -53,6 +52,16 @@ def works_original_path
)
end
+ def collections_original_path
+ url_for(
+ controller: :collections,
+ action: :index,
+ only_path: true,
+ **params.slice(:title, :challenge_type, :moderated, :multifandom, :closed, :tag,
+ :sort_column, :sort_direction).permit!
+ )
+ end
+
def bookmarks_original_path
url_for(
controller: :bookmarks,
diff --git a/app/models/search/collection_search_form.rb b/app/models/search/collection_search_form.rb
index 13976949d9e..097a621d63c 100644
--- a/app/models/search/collection_search_form.rb
+++ b/app/models/search/collection_search_form.rb
@@ -71,7 +71,7 @@ def sort_options
end
def default_sort_column
- "created_at"
+ options[:default_sort_column] ||= "created_at"
end
def default_sort_direction
diff --git a/app/views/collections/_filters.html.erb b/app/views/collections/_filters.html.erb
index 03e2b280107..b6994f397e8 100644
--- a/app/views/collections/_filters.html.erb
+++ b/app/views/collections/_filters.html.erb
@@ -1,4 +1,10 @@
-<%= form_for @search, as: :collection_search, url: collections_path, html: { method: :get, class: "narrow-hidden filters", id: "collection-filters" } do |f| %>
+<%= form_for @search, as: :collection_search,
+ url: (@user ? user_collections_path(@user) : collections_path),
+ html: {
+ method: :get,
+ class: "narrow-hidden filters",
+ id: "collection-filters"
+ } do |f| %>
<%= t(".landmark") %>
<%= field_set_tag t(".legend") do %>
@@ -133,7 +139,7 @@
- <%= submit_tag t(".submit.button") %>
<% end %>
<% # On narrow screens, link jumps to top of index when JavaScript is disabled and closes filters when JavaScript is enabled %>
diff --git a/app/views/collections/index.html.erb b/app/views/collections/index.html.erb
index f3329008b9a..bdd96e0f245 100755
--- a/app/views/collections/index.html.erb
+++ b/app/views/collections/index.html.erb
@@ -13,37 +13,37 @@
<% if @collections.empty? %>
- <%= ts("Sorry, there were no collections found.") %>
+ <%= t(".page_heading.no_results") %>
<% else %>
- <%= search_header @collections, @query, ts("Collection") %>
+ <%= search_header @collections, @query, t(".page_heading.search_header") %>
<% end %>
-<%= ts("Navigation") %>
-
- <% # Collections and Open Challenges links unless a logged in user viewing own collections page %>
+<%= t(".navigation.landmark_heading") %>
+
+ <%# Collections and Open Challenges links unless a logged in user viewing own collections page %>
<% unless logged_in? && @user && @user == current_user %>
- - <%= span_if_current ts("Collections"), collections_path %>
- - <%= link_to ts("Open Challenges"), list_challenges_collections_path %>
+ - <%= span_if_current t(".navigation.actions.collections"), collections_path %>
+ - <%= link_to t(".navigation.actions.open_challenges"), list_challenges_collections_path %>
<% end %>
<% if logged_in? %>
- <% # Logged in user on own collections index gets links for user Collections and Manage Collection Items %>
+ <%# Logged in user on own collections index gets links for user Collections and Manage Collection Items %>
<% if @user && @user == current_user %>
- - <%= span_if_current ts("Collections"), user_collections_path(@user) %>
- - <%= link_to ts("Manage Collection Items"), user_collection_items_path(@user) %>
+ - <%= span_if_current t(".navigation.actions.collections"), user_collections_path(@user) %>
+ - <%= link_to t(".navigation.actions.manage_items"), user_collection_items_path(@user) %>
<% end %>
- <% # Logged in collection maintainer on own collection gets link for New Subcollection and all other logged in users get New Collection link %>
+ <%# Logged in collection maintainer on own collection gets link for New Subcollection and all other logged in users get New Collection link %>
<% if @collection && !@collection.parent && @collection.user_is_maintainer?(current_user) %>
- - <%= link_to ts("New Subcollection"), new_collection_collection_path(@collection) %>
+ - <%= link_to t(".navigation.actions.new_subcollection"), new_collection_collection_path(@collection) %>
<% else %>
- - <%= link_to ts("New Collection"), new_collection_path %>
+ - <%= link_to t(".navigation.actions.new_collection"), new_collection_path %>
<% end %>
<% end %>
<% if @sort_and_filter %>
- <% # Filters button for narrow screens jumps to filters when JavaScript is disabled and opens filters when JavaScript is enabled %>
- - <%= ts("Filters") %>
+ <%# Filters button for narrow screens jumps to filters when JavaScript is disabled and opens filters when JavaScript is enabled %>
+ - <%= t(".navigation.actions.filters") %>
<% end %>
@@ -52,7 +52,7 @@
<%= will_paginate @collections %>
- <%= ts("List of Collections") %>
+ <%= t(".main_content.landmark_heading") %>
<% @collections.each do |collection| %>
<%= render :partial => "collection_blurb", :locals => {:collection => collection} %>
diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml
index 630a3291f93..36035f93a5a 100644
--- a/config/locales/views/en.yml
+++ b/config/locales/views/en.yml
@@ -821,10 +821,23 @@ en:
footnote: Use this if your collection is not fandom-specific.
label: Multifandom
index:
+ main_content:
+ landmark_heading: List of Collections
+ navigation:
+ actions:
+ collections: Collections
+ filters: Filters
+ manage_items: Manage Collection Items
+ new_collection: New Collection
+ new_subcollection: New Subcollection
+ open_challenges: Open Challenges
+ landmark_heading: Navigation
page_heading:
challenges_subcollections_in: Challenges/Subcollections in %{collection}
collections_in_the: Collections in the %{archive}
collections_including: Collections including %{work}
+ no_results: Sorry, there were no collections found.
+ search_header: Collection
users_collections: "%{user}'s Collections"
sidebar:
bookmarks: Bookmarked Items (%{count})
diff --git a/features/collections/collection_browse.feature b/features/collections/collection_browse.feature
index b89a84eafbf..11bf998ca0a 100644
--- a/features/collections/collection_browse.feature
+++ b/features/collections/collection_browse.feature
@@ -287,6 +287,79 @@ Feature: Collection
And the 2nd collection result should contain "Privates"
And the 2nd collection result should contain "Bookmarked Items: 1"
+Scenario: Sort collections by Works and Bookmarks from user's collection
+
+ Given I have a collection "Privates"
+ And I have a collection "Publics"
+ And a set of collections for searching
+ When I go to the collections page
+ Then I should not see "2 Collections"
+ When I am logged in as the owner of "Privates"
+ And I post the work "Private 1" in the collection "Privates"
+ And I lock the work "Private 1"
+ And I post the work "Private 2" in the collection "Privates"
+ And I lock the work "Private 2"
+ And I bookmark the work "Private 1" to the collection "Publics"
+ And I bookmark the work "Private 2" to the collection "Publics"
+ And I post the work "Public 1" in the collection "Publics"
+ And I bookmark the work "Public 1" to the collection "Privates"
+ And all indexing jobs have been run
+ And I change my username to "Owner"
+ And I go to Owner's collections page
+ And I select "Works" from "Sort by"
+ And I select "Descending" from "Sort direction"
+ And I press "Sort and Filter"
+ Then the 1st collection result should contain "Privates"
+ And the 1st collection result should contain "Works: 2"
+ And the 2nd collection result should contain "Publics"
+ And the 2nd collection result should contain "Works: 1"
+ And I should see "2 Collections"
+ When I log out
+ Then the 1st collection result should contain "Publics"
+ And the 1st collection result should contain "Works: 1"
+ And the 2nd collection result should contain "Privates"
+ And the 2st collection result should contain "Works: 0"
+ And I should see "2 Collections"
+ When I am logged in as a super admin
+ And I go to Owner's collections page
+ And I select "Works" from "Sort by"
+ And I select "Descending" from "Sort direction"
+ And I press "Sort and Filter"
+ Then the 1st collection result should contain "Privates"
+ And the 1st collection result should contain "Works: 2"
+ And the 2nd collection result should contain "Publics"
+ And the 2nd collection result should contain "Works: 1"
+ And I should see "2 Collections"
+ When I go to Owner's collections page
+ And I select "Bookmarked Items" from "Sort by"
+ And I select "Descending" from "Sort direction"
+ And I press "Sort and Filter"
+ Then the 1st collection result should contain "Publics"
+ And the 1st collection result should contain "Bookmarked Items: 2"
+ And the 2nd collection result should contain "Privates"
+ And the 2nd collection result should contain "Bookmarked Items: 1"
+ And I should see "2 Collections"
+ When I log out
+ And I go to Owner's collections page
+ And I select "Bookmarked Items" from "Sort by"
+ And I select "Descending" from "Sort direction"
+ And I press "Sort and Filter"
+ Then the 1nd collection result should contain "Privates"
+ And the 1st collection result should contain "Bookmarked Items: 1"
+ And the 2nd collection result should contain "Publics"
+ And the 2nd collection result should not contain "Bookmarked Items"
+ And I should see "2 Collections"
+ When I am logged in as a super admin
+ And I go to Owner's collections page
+ And I select "Bookmarked Items" from "collection_search_sort_column"
+ And I select "Descending" from "collection_search_sort_direction"
+ And I press "Sort and Filter"
+ Then the 1st collection result should contain "Publics"
+ And the 1st collection result should contain "Bookmarked Items: 2"
+ And the 2nd collection result should contain "Privates"
+ And the 2nd collection result should contain "Bookmarked Items: 1"
+ And I should see "2 Collections"
+
Scenario: Look at a collection, see the rules and intro and FAQ
Given a set of collections for searching
diff --git a/features/search/filters.feature b/features/search/filters.feature
index 7613934f3af..3cde4db4047 100644
--- a/features/search/filters.feature
+++ b/features/search/filters.feature
@@ -1,8 +1,8 @@
@users
Feature: Filters
- In order to ensure filtering works on works and bookmarks
+ In order to ensure filtering works on works, bookmarks and collections
As a humble user
- I want to filter on a user's works and bookmarks
+ I want to filter on a user's works, bookmarks and collections
Background:
Given a canonical fandom "The Hobbit"
@@ -363,3 +363,21 @@ Feature: Filters
When I fill in "work_search_query" with "bad~query!!!"
And I press "Sort and Filter"
Then I should see "Your search failed because of a syntax error"
+
+ @collections
+ Scenario: Filtering on a user collection page should only return collections by that user.
+ Given a collection "Duplicate Name" with name "collection1" owned by "meatloaf"
+ And a collection "Duplicate Name" with name "collection2" owned by "recengine"
+ And a collection "The Hobbits" with name "collectionhobbit" owned by "recengine"
+ And a collection "Not Mine!" with name "yours" owned by "iminvisible"
+ And all indexing jobs have been run
+ When I go to recengine's collections page
+ And I fill in "Filter by title" with "Duplicate Name"
+ And I press "Sort and Filter"
+ Then I should see "1 Collection"
+ When I follow "Clear Filters"
+ Then I should see "2 Collections"
+ When I fill in "Filter by title" with "Not Mine!"
+ And I press "Sort and Filter"
+ Then I should not see "iminvisible"
+ And I should see "Sorry, there were no collections found."
diff --git a/features/step_definitions/collection_steps.rb b/features/step_definitions/collection_steps.rb
index a5700434ec9..b0ab7e70003 100644
--- a/features/step_definitions/collection_steps.rb
+++ b/features/step_definitions/collection_steps.rb
@@ -82,6 +82,11 @@
collection.collection_preference.update_attribute(:closed, true) if closed.present?
end
+Given "a collection {string} with name {string} owned by {string}" do |title, name, owner|
+ user = ensure_user(owner)
+ FactoryBot.create(:collection, title: title, name: (name.presence || title.gsub(/[^\w]/, "_")), owner: user.default_pseud)
+end
+
Given /^I open the collection with the title "([^\"]*)"$/ do |title|
step %{I am logged in as "moderator"}
visit collection_path(Collection.find_by(title: title))
@@ -107,7 +112,7 @@
visit collection_path(Collection.find_by(title: title))
click_link("Membership")
step %{I fill in "participants_to_invite" with "#{name}"}
- step %{I press "Submit"}
+ step %{I press "Submit"}
step %{I select "Moderator" from "#{name}_role"}
# TODO: fix the form, it is malformed right now
@@ -178,21 +183,19 @@
When /^I set up (?:a|the) collection "([^"]*)"(?: with name "([^"]*)")?$/ do |title, name|
visit new_collection_path
- fill_in("collection_name", with: (name.blank? ? title.gsub(/[^\w]/, '_') : name))
+ fill_in("collection_name", with: (name.presence || title.gsub(/[^\w]/, "_")))
fill_in("collection_title", with: title)
end
When /^I create (?:a|the) collection "([^"]*)"(?: with name "([^"]*)")?$/ do |title, name|
- name = title.gsub(/[^\w]/, '_') if name.blank?
+ name = title.gsub(/[^\w]/, "_") if name.blank?
step %{I set up the collection "#{title}" with name "#{name}"}
step %{I submit}
end
When /^I add (?:a|the) subcollection "([^"]*)"(?: with name "([^"]*)")? to (?:a|the) parent collection named "([^"]*)"$/ do |title, name, parent_name|
- if Collection.find_by_name(parent_name).nil?
- step %{I create the collection "#{parent_name}" with name "#{parent_name}"}
- end
- name = title.gsub(/[^\w]/, '_') if name.blank?
+ step %{I create the collection "#{parent_name}" with name "#{parent_name}"} if Collection.find_by_name(parent_name).nil?
+ name = title.gsub(/[^\w]/, "_") if name.blank?
step %{I set up the collection "#{title}" with name "#{name}"}
fill_in("collection_parent_name", with: parent_name)
step %{I submit}
diff --git a/features/support/paths.rb b/features/support/paths.rb
index 7f8845055e5..603dbb7b792 100644
--- a/features/support/paths.rb
+++ b/features/support/paths.rb
@@ -169,6 +169,8 @@ def path_to(page_name)
edit_skin_path(Skin.find_by(title: $1), wizard: true)
when /^the new collection page/
new_collection_path
+ when /^(.*?)(?:'s)? collections page$/i
+ user_collections_path(user_id: Regexp.last_match(1))
when /^"(.*)" collection's page$/i # e.g. when I go to "Collection name" collection's page
step %{all indexing jobs have been run} # reindex to show recent works/bookmarks
collection_path(Collection.find_by(title: $1))
diff --git a/public/stylesheets/site/2.0/17-zone-home.css b/public/stylesheets/site/2.0/17-zone-home.css
index 413f74c74fc..504e23c93c5 100644
--- a/public/stylesheets/site/2.0/17-zone-home.css
+++ b/public/stylesheets/site/2.0/17-zone-home.css
@@ -65,10 +65,6 @@ user home, collections and challenges home, tag home, admin comms home
/* (no filters) */
-.dashboard.collections-index .index {
- width: 100%;
-}
-
.dashboard.works-index h4.landmark, .dashboard.works-index ol.pagination {
float: right;
width: 100%;
diff --git a/public/stylesheets/site/2.0/18-zone-searchbrowse.css b/public/stylesheets/site/2.0/18-zone-searchbrowse.css
index b1dbe7a639d..d5e511158e3 100644
--- a/public/stylesheets/site/2.0/18-zone-searchbrowse.css
+++ b/public/stylesheets/site/2.0/18-zone-searchbrowse.css
@@ -68,6 +68,7 @@ li.search fieldset {
form.filters {
width: 23%;
float: right;
+ clear: right;
}
.filters h4 {