Skip to content

Commit

Permalink
Add item type facet
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Dolski committed Mar 13, 2024
1 parent 8c19033 commit 145237d
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 18 deletions.
4 changes: 4 additions & 0 deletions app/assets/javascripts/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ const SearchView = {
$(this).find("select:nth(1)"));
});

$("[name=item_type]").on("change", function() {
$(this).parents("form:first").submit();
});

// When the Simple Search or Advanced Search submit button is clicked,
// clear all form fields in the other tab pane, so they don't get sent
// along as well.
Expand Down
27 changes: 23 additions & 4 deletions app/controllers/search_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class SearchController < ApplicationController
def index
@permitted_params = params.permit(Search::SIMPLE_SEARCH_PARAMS +
Search::advanced_search_params +
Search::RESULTS_PARAMS)
Search::RESULTS_PARAMS +
[:item_type])
@start = [@permitted_params[:start].to_i.abs, max_start].min
@window = window_size
@items = EntityRelation.new.
Expand All @@ -24,17 +25,35 @@ def index
start(@start).
limit(@window)
if institution_host?
@items = @items.institution(current_institution)
@items.institution(current_institution)
if policy(Item).show_private?
case params[:item_type]
when "private"
@items.
filter_range("#{Item::IndexFields::EMBARGOES}.#{Embargo::IndexFields::ALL_ACCESS_EXPIRES_AT}",
:gt,
Time.now.strftime("%Y-%m-%d")).
must_not(Item::IndexFields::STAGE, Item::Stages::WITHDRAWN)
when "rejected"
@items.filter(Item::IndexFields::STAGE, Item::Stages::REJECTED)
when "withdrawn"
@items.filter(Item::IndexFields::STAGE, Item::Stages::WITHDRAWN)
when "deleted"
@items.include_buried.
filter(Item::IndexFields::STAGE, Item::Stages::BURIED)
end
else
@items = policy_scope(@items, policy_scope_class: ItemPolicy::Scope)
end
else
@items = @items.metadata_profile(MetadataProfile.global)
@items.metadata_profile(MetadataProfile.global)
end
if @permitted_params[:sort].present?
@items.order(@permitted_params[:sort] =>
(@permitted_params[:direction] == "desc") ? :desc : :asc)
end
process_search_query(@items)

@items = policy_scope(@items, policy_scope_class: ItemPolicy::Scope)
@count = @items.count
@facets = @items.facets
@current_page = @items.page
Expand Down
80 changes: 66 additions & 14 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,30 @@ def date_range_picker
def facets_as_cards(facets, permitted_params)
return nil unless facets
html = StringIO.new
if institution_host? && policy(Item).show_private?
# This is a "fake" facet that is presented like the other facets in the
# UI, but doesn't work the same way.
facet = Facet.new
facet.name = "Item Type"
facet.field = ""
facet.terms << FacetTerm.new(name: "public",
label: "Public",
facet: facet)
facet.terms << FacetTerm.new(name: "private",
label: "Private",
facet: facet)
facet.terms << FacetTerm.new(name: "rejected",
label: "Rejected",
facet: facet)
facet.terms << FacetTerm.new(name: "withdrawn",
label: "Withdrawn",
facet: facet)
facet.terms << FacetTerm.new(name: "deleted",
label: "Deleted",
facet: facet)
html << facet_card(facet, permitted_params, name: "item_type",
control: "radio", checked_value: "public")
end
facets.select{ |f| f.terms.any? }.each do |facet|
html << facet_card(facet, permitted_params)
end
Expand Down Expand Up @@ -747,11 +771,15 @@ def resource_list_row(resource,
use_resource_host: true,
show_institution: false,
show_private_normally: false)
embargoed_item = !show_private_normally &&
resource.kind_of?(Item) &&
resource.embargoed_for?(user: current_user,
client_hostname: request_context.client_hostname,
client_ip: request_context.client_ip)
embargoed_item = withdrawn_item = rejected_item = buried_item = false
if !show_private_normally && resource.kind_of?(Item)
embargoed_item = resource.embargoed_for?(user: current_user,
client_hostname: request_context.client_hostname,
client_ip: request_context.client_ip)
withdrawn_item = resource.withdrawn?
buried_item = resource.buried?
rejected_item = resource.rejected?
end
thumb = thumbnail_for(resource)
if use_resource_host
resource_url = polymorphic_url(resource, host: resource.institution.fqdn)
Expand All @@ -777,7 +805,7 @@ def resource_list_row(resource,
html << "</div>"
html << "<div class=\"flex-grow-1 ms-3\">"
html << "<h5 class=\"mt-0 mb-0\">"
if embargoed_item
if embargoed_item && !policy(resource).show?
html << resource.title
else
html << link_to(resource.title, resource_url)
Expand All @@ -789,6 +817,15 @@ def resource_list_row(resource,
if embargoed_item
html << " <span class=\"badge text-bg-danger\">EMBARGOED</span>"
end
if withdrawn_item
html << " <span class=\"badge text-bg-danger\">WITHDRAWN</span>"
end
if rejected_item
html << " <span class=\"badge text-bg-danger\">REJECTED</span>"
end
if buried_item
html << " <span class=\"badge text-bg-danger\">DELETED</span>"
end
html << "</h5>"

if resource.kind_of?(Item)
Expand Down Expand Up @@ -954,28 +991,43 @@ def toast!(title:, message:, icon: nil)
##
# @param facet [Facet]
# @param permitted_params [ActionController::Parameters]
# @param name [String]
# @param control [String] Input type (`checkbox` or `radio`).
# @param checked_value [String] Value to pre-check.
#
def facet_card(facet, permitted_params)
def facet_card(facet,
permitted_params,
name: "fq[]",
control: "checkbox",
checked_value: nil)
panel = StringIO.new
panel << "<div class=\"card facet\" id=\"#{facet.field}\">"
panel << "<h5 class=\"card-header\">#{facet.name}</h5>"
panel << '<div class="card-body">'
panel << '<ul>'
facet.terms.each do |term|
checked = (permitted_params[:fq]&.include?(term.query)) ? "checked" : nil
checked_params = term.removed_from_params(permitted_params.deep_dup).except(:start)
unchecked_params = term.added_to_params(permitted_params.deep_dup).except(:start)
term_label = truncate(sanitize(term.label, tags: []), length: 80)
term_label = truncate(sanitize(term.label, tags: []), length: 80)
query = term.query.gsub('"', '&quot;')
if name == "fq[]"
checked = (permitted_params[:fq]&.include?(term.query)) ? "checked" : nil
checked_params = term.removed_from_params(permitted_params.deep_dup).except(:start)
unchecked_params = term.added_to_params(permitted_params.deep_dup).except(:start)
elsif query == checked_value
checked = "checked"
else
checked = (params[name.to_sym] == query) ? "checked" : ""
end
panel << '<li class="term">'
panel << '<label>'
query = term.query.gsub('"', '&quot;')
panel << "<input type=\"checkbox\" name=\"fq[]\" #{checked} "\
panel << "<input type=\"#{control}\" name=\"#{name}\" #{checked} "\
"data-query=\"#{query}\" "\
"data-checked-href=\"#{url_for(unchecked_params)}\" "\
"data-unchecked-href=\"#{url_for(checked_params)}\" "\
"value=\"#{query}\"> "
panel << "<span class=\"term-name\">#{term_label}</span> "
panel << "<span class=\"count\">#{term.count}</span>"
if term.count > 0
panel << "<span class=\"count\">#{term.count}</span>"
end
panel << '</label>'
panel << '</li>'
end
Expand Down
4 changes: 4 additions & 0 deletions app/policies/item_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,10 @@ def show_metadata
end
end

def show_private
review
end

def show_properties
show_access
end
Expand Down
13 changes: 13 additions & 0 deletions app/search/entity_relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ def initialize
@must_nots << [Item::IndexFields::STAGE, Item::Stages::BURIED]
end

##
# Buried items are excluded from results by default--this method removes that
# exclusion.
#
# @return [self]
#
def include_buried
@must_nots.delete([Unit::IndexFields::BURIED, true])
@must_nots.delete([Collection::IndexFields::BURIED, true])
@must_nots.delete([Item::IndexFields::STAGE, Item::Stages::BURIED])
self
end

##
# Filters out items with current all-access embargoes.
#
Expand Down
59 changes: 59 additions & 0 deletions test/policies/item_policy_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1728,6 +1728,65 @@ class ScopeTest < ActiveSupport::TestCase
assert !policy.show_metadata?
end

# show_private?()

test "show_private?() does not authorize a nil user" do
context = RequestContext.new(user: nil,
institution: @item.institution)
policy = ItemPolicy.new(context, @item)
assert !policy.show_private?
end

test "show_private?() does not authorize an incorrect scope" do
context = RequestContext.new(user: users(:southwest_admin),
institution: institutions(:northeast))
policy = ItemPolicy.new(context, @item)
assert !policy.show_private?
end

test "show_private?() does not authorize non-sysadmins" do
user = users(:southwest)
context = RequestContext.new(user: user,
institution: @item.institution)
policy = ItemPolicy.new(context, @item)
assert !policy.show_private?
end

test "show_private?() authorizes sysadmins" do
user = users(:southwest_sysadmin)
context = RequestContext.new(user: user,
institution: @item.institution)
policy = ItemPolicy.new(context, @item)
assert policy.show_private?
end

test "show_private?() authorizes administrators of the same institution" do
user = users(:southwest_admin)
context = RequestContext.new(user: user,
institution: @item.institution)
policy = ItemPolicy.new(context, @item)
assert policy.show_private?
end

test "show_private?() does not authorize administrators of a different
institution" do
user = users(:southwest_admin)
context = RequestContext.new(user: user,
institution: institutions(:northeast))
policy = ItemPolicy.new(context, @item)
assert !policy.show_private?
end

test "show_private?() respects role limits" do
# sysadmin user limited to an insufficient role
user = users(:southwest_sysadmin)
context = RequestContext.new(user: user,
institution: @item.institution,
role_limit: Role::COLLECTION_SUBMITTER)
policy = ItemPolicy.new(context, @item)
assert !policy.show_private?
end

# show_properties?()

test "show_properties?() does not authorize a nil user" do
Expand Down

0 comments on commit 145237d

Please sign in to comment.