Skip to content

Commit

Permalink
Migrate constraints to viewcomponents (#3361)
Browse files Browse the repository at this point in the history
Resolves DEPRECATION WARNING: constraint_query_label is deprecated
  • Loading branch information
sandbergja committed Jan 18, 2023
1 parent c3f288a commit a1adaa6
Show file tree
Hide file tree
Showing 15 changed files with 183 additions and 129 deletions.
3 changes: 2 additions & 1 deletion app/assets/stylesheets/components/overrides.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ main {
-webkit-box-shadow: none;
margin-bottom: 0.35em;
padding: 2px 15px;
display: block;
}

.orange {
Expand Down Expand Up @@ -167,4 +168,4 @@ address {
.dl-horizontal.dl-invert .col-md-3,
.dl-horizontal.dl-invert .col-md-9 {
padding-left: 0;
}
}
5 changes: 5 additions & 0 deletions app/components/orangelight/constraint_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= render(@layout.new(
classes: (Array(@classes) + ["filter-#{@facet_item_presenter.key.parameterize}"]).join(' '),
label: @facet_item_presenter.field_label,
value: constraint_value,
remove_path: @facet_item_presenter.remove_href)) %>
18 changes: 18 additions & 0 deletions app/components/orangelight/constraint_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

class Orangelight::ConstraintComponent < Blacklight::ConstraintComponent
def constraint_value
if old_style_params?
@facet_item_presenter.constraint_label['0']
elsif @facet_item_presenter.constraint_label.respond_to? :to_s
@facet_item_presenter.constraint_label
end
end

private

def old_style_params?
@facet_item_presenter.constraint_label.is_a?(ActiveSupport::HashWithIndifferentAccess) &&
@facet_item_presenter.constraint_label.key?('0')
end
end
38 changes: 38 additions & 0 deletions app/components/orangelight/constraints_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<%= content_tag @tag || :div, id: @id, class: @classes do %>
<% if @render_headers %>
<h2 class="sr-only visually-hidden"><%= t('blacklight.search.search_constraints_header') %></h2>
<% end %>

<div class="button--start-over">
<%= render_start_over_link(start_over_path) %>
</div>
<div class="button--edit-search">
<%=link_to t('blacklight.search.edit_search'),
edit_search_link,
class: "catalog_editSearchLink btn btn-outline-secondary",
id: "editSearchLink" %>
</div>

<% if @render_headers %>
<span class="constraints-label sr-only visually-hidden"><%= t('blacklight.search.filters.title') %></span>
<% end %>
<% if query_constraints_area.present? %>
<% query_constraints_area.each do |constraint| %>
<%= constraint %>
<% end %>
<% else %>
<%= query_constraints %>
<% end %>
<% if facet_constraints_area.present? %>
<% facet_constraints_area.each do |constraint| %>
<%= constraint %>
<% end %>
<% else %>
<%= facet_constraints %>
<% end %>
<% additional_constraints.each do |constraints| %>
<%= constraints %>
<% end %>
<% end %>
62 changes: 62 additions & 0 deletions app/components/orangelight/constraints_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# frozen_string_literal: true

class Orangelight::ConstraintsComponent < Blacklight::ConstraintsComponent
# rubocop:disable Metrics/ParameterLists
def initialize(search_state:,
tag: :div,
render_headers: true,
id: 'appliedParams', classes: 'clearfix constraints-container',
query_constraint_component: Blacklight::ConstraintLayoutComponent,
query_constraint_component_options: {},
facet_constraint_component: Orangelight::ConstraintComponent,
facet_constraint_component_options: {},
start_over_component: Blacklight::StartOverButtonComponent)
super
end
# rubocop:enable Metrics/ParameterLists

def query_constraints
super + guided_search_constraints
end

def remove_guided_query_path(index)
url_for @search_state.to_h.reject { |k, _v| k.match?(/[f|q|op]#{index}/) }
end

def render?
super || @search_state.to_h.keys.any? { |param| param.match?(/[f|q|op][1-3]/) }
end

private

def guided_search_constraints
constraints_string = ''.html_safe
(1..3).each do |index|
constraints_string += helpers.render(
@query_constraint_component.new(
search_state: @search_state,
value: guided_search_value(index),
label: guided_search_label(index),
remove_path: remove_guided_query_path(index),
classes: 'query',
**@query_constraint_component_options
)
)
end
constraints_string
end

def guided_search_value(index)
params = @search_state.to_h
return if params[:"q#{index}"].blank?

has_operator = params[:"op#{index}"].present?
prefix = has_operator ? params[:"op#{index}"].upcase + ' ' : ''
prefix + params[:"q#{index}"]
end

def guided_search_label(index)
search_field = @search_state.params[:"f#{index}"]
helpers.label_for_search_field(search_field) unless helpers.default_search_field?(search_field)
end
end
2 changes: 2 additions & 0 deletions app/controllers/catalog_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,8 @@ class CatalogController < ApplicationController
:op1, :op2, :op3,
:q1, :q2, :q3
]

config.index.constraints_component = Orangelight::ConstraintsComponent
end

def render_search_results_as_json
Expand Down
1 change: 0 additions & 1 deletion app/controllers/search_history_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
class SearchHistoryController < ApplicationController
include Blacklight::SearchHistory

helper BlacklightAdvancedSearch::RenderConstraintsOverride
helper RangeLimitHelper
end
64 changes: 0 additions & 64 deletions app/helpers/advanced_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -212,67 +212,3 @@ def process_query(_params, config)
end
end
end

module BlacklightAdvancedSearch
module CatalogHelperOverride
def remove_guided_keyword_query(fields, my_params = params)
my_params = Blacklight::SearchState.new(my_params, blacklight_config).to_h
fields.each do |guided_field|
my_params.delete(guided_field)
end
my_params
end
end
end

module BlacklightAdvancedSearch
module RenderConstraintsOverride
def guided_search(my_params = params)
constraints = []
if my_params[:q1].present? && my_params[:f1].present?
label = blacklight_config.search_fields[my_params[:f1]].try(:label)
if label
query = my_params[:q1]
constraints << render_constraint_element(
label, query,
remove: search_catalog_path(remove_guided_keyword_query(%i[f1 q1], my_params))
)
end
end
if my_params[:q2].present? && my_params[:f2].present?
label = blacklight_config.search_fields[my_params[:f2]].try(:label)
if label
query = my_params[:q2]
query = 'NOT ' + my_params[:q2] if my_params[:op2] == 'NOT'
constraints << render_constraint_element(
label, query,
remove: search_catalog_path(remove_guided_keyword_query(%i[f2 q2 op2], my_params))
)
end
end
if my_params[:q3].present? && my_params[:f3].present?
label = blacklight_config.search_fields[my_params[:f3]].try(:label)
if label
query = my_params[:q3]
query = 'NOT ' + my_params[:q3] if my_params[:op3] == 'NOT'
constraints << render_constraint_element(
label, query,
remove: search_catalog_path(remove_guided_keyword_query(%i[f3 q3 op3], my_params))
)
end
end
constraints
end

# Over-ride of Blacklight method, provide advanced constraints if needed,
# otherwise call super.
def render_constraints_query(my_params = params)
if advanced_query.nil? || advanced_query.keyword_queries.empty?
super(my_params)
else
content = guided_search
safe_join(content.flatten, "\n")
end
end
end
end
2 changes: 1 addition & 1 deletion app/helpers/blacklight_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def truncated_link(doc, field_or_string, opts = { counter: nil }, length = 200)

# Links to correct advanced search page based on advanced_type parameter value
def edit_search_link
url = blacklight_advanced_search_engine.advanced_search_path(params.permit!.except(:controller, :action).to_h)
url = BlacklightAdvancedSearch::Engine.routes.url_helpers.advanced_search_path(params.permit!.except(:controller, :action).to_h)
if params[:advanced_type] == 'numismatics'
url.gsub('/advanced', '/numismatics')
else
Expand Down
14 changes: 0 additions & 14 deletions app/views/catalog/_constraints.html.erb

This file was deleted.

33 changes: 0 additions & 33 deletions app/views/catalog/_constraints_element.html.erb

This file was deleted.

4 changes: 3 additions & 1 deletion app/views/catalog/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<%= render 'constraints' %>
<div class="col-12">
<%= render 'constraints' %>
</div>
<div id="sidebar" class="col-12 col-md-4">
<%= render 'search_sidebar' %>
</div>
Expand Down
17 changes: 17 additions & 0 deletions spec/components/orangelight/constraint_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe Orangelight::ConstraintComponent, type: :component do
let(:facet_item_presenter) { instance_double(Blacklight::FacetItemPresenter) }

it "can handle the odd format[0]-style params" do
allow(facet_item_presenter).to receive(:key).and_return('key')
allow(facet_item_presenter).to receive(:field_label).and_return('Format')
allow(facet_item_presenter).to receive(:constraint_label).and_return({ "0" => "Audio" }.with_indifferent_access)
allow(facet_item_presenter).to receive(:remove_href).and_return('/bye')

component = described_class.new(facet_item_presenter:)
expect(render_inline(component).to_s).to include('Format: Audio')
end
end
33 changes: 33 additions & 0 deletions spec/components/orangelight/constraints_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe Orangelight::ConstraintsComponent, type: :component do
let(:params) do
{
action: 'index', controller: 'catalog',
q1: 'dogs', f1: 'title',
op2: 'not', q2: 'cats', f2: 'title',
op3: '', q3: '', f3: ''
}
end
let(:search_state) { Blacklight::SearchState.new(params, Blacklight::Configuration.new) }
let(:component) { described_class.new(search_state:) }

describe '#remove_guided_query_path' do
it 'generates a valid path for removing guided search queries' do
render_inline(component)
expect(component.remove_guided_query_path(1)).to eq(
'/?f2=title&f3=&op2=not&op3=&q2=cats&q3='
)
end
end
describe 'advanced search query constraints' do
let(:rendered) { Capybara::Node::Simple.new(render_inline(component).to_s) }
it 'includes constraints for non-empty search params' do
expect(rendered).to have_selector('.applied-filter.constraint', text: 'Title: dogs')
expect(rendered).to have_selector('.applied-filter.constraint', text: 'Title: NOT cats')
expect(rendered).to have_selector('.applied-filter.constraint', count: 2)
end
end
end
16 changes: 2 additions & 14 deletions spec/requests/request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,25 +252,13 @@
stub_holding_locations
get '/catalog?&search_field=advanced&f1=left_anchor&q1=searching+for1&op2=AND&f2='\
'left_anchor&q2=searching+for&op3=AND&f3=left_anchor&q3=searching+for'
expect(response.body.include?('<a class="btn btn-outline-secondary remove" '\
'href="/catalog?action=index&amp;controller=catalog&amp;'\
'f2=left_anchor&amp;f3=left_anchor&amp;op2=AND&amp;op3='\
'AND&amp;q2=searching+for&amp;q3=searching+for&amp;'\
'search_field=advanced"><i class="fa '\
'fa-times" aria-hidden="true"></i><span class="sr-only">Remove '\
'constraint Title starts with: searching for1</span></a>')).to eq true
expect(response.body).to include 'Remove constraint Title starts with: searching for1'
get '/catalog.json?&search_field=advanced&f1=left_anchor&q1=searching+for1&op2=AND&f2='\
'left_anchor&q2=searching+for&op3=AND&f3=left_anchor&q3=searching+for'
r = JSON.parse(response.body)
expect(r['data'].any? { |d| d['id'] == '9965749873506421' }).to eq false
get '/catalog?f2=left_anchor&amp;f3=left_anchor&amp;op2=AND&amp;op3=AND&amp;q2=searching+for&amp;q3=searching+for&amp;search_field=advanced'
expect(response.body.include?('<a class="btn btn-outline-secondary remove" '\
'href="/catalog?action=index&amp;controller=catalog&amp;'\
'f2=left_anchor&amp;f3=left_anchor&amp;op2=AND&amp;op3='\
'AND&amp;q2=searching+for&amp;q3=searching+for&amp;'\
'search_field=advanced"><i class="fa '\
'fa-times" aria-hidden="true"></i><span class="sr-only">'\
'Remove constraint Starts with: searching for1</span></a>')).to eq false
expect(response.body).not_to include 'Remove constraint Title starts with: searching for1'
get '/catalog.json?f2=left_anchor&amp;f3=left_anchor&amp;op2=AND&amp;op3=AND&amp;q2=searching+for&amp;q3=searching+for&amp;search_field=advanced'
r = JSON.parse(response.body)
expect(r['data'].any? { |d| d['id'] == '9965749873506421' }).to eq true
Expand Down

0 comments on commit a1adaa6

Please sign in to comment.