Skip to content

Extract facet presenters and components #2268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2020-02-03 11:07:48 -0800 using RuboCop version 0.63.1.
# on 2020-03-30 10:03:33 -0700 using RuboCop version 0.63.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
Expand Down Expand Up @@ -177,7 +177,7 @@ Lint/UselessComparison:
Exclude:
- 'spec/models/blacklight/document/active_model_shim_spec.rb'

# Offense count: 59
# Offense count: 60
Metrics/AbcSize:
Max: 49

Expand All @@ -201,20 +201,20 @@ Metrics/ClassLength:
Metrics/CyclomaticComplexity:
Max: 11

# Offense count: 54
# Offense count: 56
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/MethodLength:
Max: 31
Max: 30

# Offense count: 8
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 212

# Offense count: 2
# Offense count: 5
# Configuration parameters: CountKeywordArgs.
Metrics/ParameterLists:
Max: 6
Max: 7

# Offense count: 16
Metrics/PerceivedComplexity:
Expand Down Expand Up @@ -287,7 +287,7 @@ RSpec/BeforeAfterAll:
RSpec/ContextWording:
Enabled: false

# Offense count: 55
# Offense count: 56
RSpec/DescribeClass:
Enabled: false

Expand All @@ -297,7 +297,7 @@ RSpec/EmptyExampleGroup:
Exclude:
- 'spec/models/blacklight/solr/search_builder_spec.rb'

# Offense count: 129
# Offense count: 130
# Configuration parameters: Max.
RSpec/ExampleLength:
Enabled: false
Expand All @@ -321,7 +321,7 @@ RSpec/FilePath:
- 'spec/presenters/pipeline_spec.rb'
- 'spec/presenters/thumbnail_presenter_spec.rb'

# Offense count: 192
# Offense count: 191
# Configuration parameters: AssignmentOnly.
RSpec/InstanceVariable:
Enabled: false
Expand Down Expand Up @@ -371,12 +371,12 @@ RSpec/MessageSpies:
- 'spec/presenters/blacklight/field_presenter_spec.rb'
- 'spec/presenters/thumbnail_presenter_spec.rb'

# Offense count: 340
# Offense count: 343
# Configuration parameters: AggregateFailuresByDefault.
RSpec/MultipleExpectations:
Max: 16

# Offense count: 337
# Offense count: 341
# Configuration parameters: IgnoreSharedExamples.
RSpec/NamedSubject:
Enabled: false
Expand Down Expand Up @@ -412,7 +412,7 @@ RSpec/SubjectStub:
- 'spec/models/blacklight/search_builder_spec.rb'
- 'spec/services/blacklight/search_service_spec.rb'

# Offense count: 120
# Offense count: 118
# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
RSpec/VerifiedDoubles:
Enabled: false
Expand Down Expand Up @@ -497,7 +497,7 @@ Style/ConditionalAssignment:
Exclude:
- 'lib/blacklight/solr/response/spelling.rb'

# Offense count: 94
# Offense count: 99
Style/Documentation:
Enabled: false

Expand Down
25 changes: 25 additions & 0 deletions app/components/blacklight/facet_field_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<div class="card facet-limit blacklight-<%= @facet_field.key %> <%= 'facet-limit-active' if @facet_field.active? %>">
<h3 class="card-header p-0 facet-field-heading" id="<%= @facet_field.html_id %>-header">
<button
class="btn btn-block p-2 text-left collapse-toggle <%= "collapsed" if @facet_field.collapsed? %>"
data-toggle="collapse"
data-target="#<%= @facet_field.html_id %>"
aria-expanded="<%= @facet_field.collapsed? ? 'false' : 'true' %>"
>
<%= label %>
</button>
</h3>
<div id="<%= @facet_field.html_id %>" aria-labelledby="<%= @facet_field.html_id %>-header" class="panel-collapse facet-content collapse <%= "show" unless @facet_field.collapsed? %>">
<div class="card-body">
<%= body %>

<% if @facet_field.modal_path %>
<div class="more_facets">
<%= link_to t("more_#{@facet_field.key}_html", scope: 'blacklight.search.facets', default: :more_html, field_name: @facet_field.label),
@facet_field.modal_path,
data: { blacklight_modal: 'trigger' } %>
</div>
<% end %>
</div>
</div>
</div>
11 changes: 11 additions & 0 deletions app/components/blacklight/facet_field_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

module Blacklight
class FacetFieldComponent < ::ViewComponent::Base
with_content_areas :label, :body

def initialize(facet_field:)
@facet_field = facet_field
end
end
end
18 changes: 18 additions & 0 deletions app/components/blacklight/facet_field_list_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<%= render(@layout.new(facet_field: @facet_field)) do |component| %>
<% component.with(:label) do %>
<%= @facet_field.label %>
<% end %>
<% component.with(:body) do %>
<ul class="facet-values list-unstyled">
<%= render_facet_limit_list @facet_field.paginator, @facet_field.key %>
</ul>
<%# backwards compatibility, ugh %>
<% if @layout == Blacklight::FacetFieldNoLayoutComponent && !@facet_field.in_modal? && @facet_field.modal_path %>
<div class="more_facets">
<%= link_to t("more_#{@facet_field.key}_html", scope: 'blacklight.search.facets', default: :more_html, field_name: @facet_field.label),
@facet_field.modal_path,
data: { blacklight_modal: 'trigger' } %>
</div>
<% end %>
<% end %>
<% end %>
22 changes: 22 additions & 0 deletions app/components/blacklight/facet_field_list_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module Blacklight
class FacetFieldListComponent < ::ViewComponent::Base
def initialize(facet_field:, layout: nil)
@facet_field = facet_field
@layout = layout == false ? FacetFieldNoLayoutComponent : Blacklight::FacetFieldComponent
end

# Here for backwards compatibility only.
# @private
def render_facet_limit_list(*args)
Deprecation.silence(Blacklight::FacetsHelperBehavior) do
@view_context.render_facet_limit_list(*args)
end
end

def render?
@facet_field.paginator.items.any?
end
end
end
13 changes: 13 additions & 0 deletions app/components/blacklight/facet_field_no_layout_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Blacklight
class FacetFieldNoLayoutComponent < ::ViewComponent::Base
with_content_areas :label, :body

def initialize(**); end

def call
body
end
end
end
120 changes: 120 additions & 0 deletions app/components/blacklight/facet_item_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# frozen_string_literal: true

module Blacklight
class FacetItemComponent < ::ViewComponent::Base
with_collection_parameter :facet_item

def initialize(facet_item:, wrapping_element: 'li', suppress_link: false)
@facet_item = facet_item
@label = facet_item.label
@hits = facet_item.hits
@href = facet_item.href
@selected = facet_item.selected?
@wrapping_element = wrapping_element
@suppress_link = suppress_link
end

def call
# if the downstream app has overridden the helper methods we'd usually call,
# use the helpers to preserve compatibility
content = if overridden_helper_methods?
content_from_legacy_view_helper
elsif @selected
render_selected_facet_value
else
render_facet_value
end

return if content.blank?
return content unless @wrapping_element

content_tag @wrapping_element, content
end

# This is a little shim to let us call the render methods below outside the
# usual component rendering cycle (for backward compatibility)
# @private
# @deprecated
def with_view_context(view_context)
@view_context = view_context
self
end

# Check if the downstream application has overridden these methods
# @deprecated
# @private
def overridden_helper_methods?
return false if explicit_component_configuration?

@view_context.method(:render_facet_item).owner != Blacklight::FacetsHelperBehavior ||
@view_context.method(:render_facet_value).owner != Blacklight::FacetsHelperBehavior ||
@view_context.method(:render_selected_facet_value).owner != Blacklight::FacetsHelperBehavior
end

# Call out to the helper method equivalent of this component
# @deprecated
# @private
def content_from_legacy_view_helper
Deprecation.warn('Calling out to the #render_facet_item helper for backwards compatibility.')
Deprecation.silence(Blacklight::FacetsHelperBehavior) do
@view_context.render_facet_item(@facet_item.facet_field, @facet_item.facet_item)
end
end

##
# Standard display of a facet value in a list. Used in both _facets sidebar
# partial and catalog/facet expanded list. Will output facet value name as
# a link to add that to your restrictions, with count in parens.
#
# @param [Blacklight::Solr::Response::Facets::FacetField] facet_field
# @param [Blacklight::Solr::Response::Facets::FacetItem] item
# @param [Hash] options
# @option options [Boolean] :suppress_link display the facet, but don't link to it
# @return [String]
# @private
def render_facet_value
content_tag(:span, class: "facet-label") do
link_to_unless(@suppress_link, @label, @href, class: "facet-select")
end + render_facet_count
end

##
# Standard display of a SELECTED facet value (e.g. without a link and with a remove button)
# @see #render_facet_value
# @param [Blacklight::Solr::Response::Facets::FacetField] facet_field
# @param [String] item
# @private
def render_selected_facet_value
content_tag(:span, class: "facet-label") do
content_tag(:span, @label, class: "selected") +
# remove link
link_to(@href, class: "remove") do
content_tag(:span, '✖', class: "remove-icon") +
content_tag(:span, '[remove]', class: 'sr-only')
end
end + render_facet_count(classes: ["selected"])
end

##
# Renders a count value for facet limits. Can be over-ridden locally
# to change style. And can be called by plugins to get consistent display.
#
# @param [Integer] num number of facet results
# @param [Hash] options
# @option options [Array<String>] an array of classes to add to count span.
# @return [String]
# @private
def render_facet_count(options = {})
return @view_context.render_facet_count(@hits, options) unless @view_context.method(:render_facet_count).owner == Blacklight::FacetsHelperBehavior || explicit_component_configuration?

classes = (options[:classes] || []) << "facet-count"
content_tag("span", t('blacklight.search.facets.count', number: number_with_delimiter(@hits)), class: classes)
end

private

def explicit_component_configuration?
@facet_item.facet_config.item_component.present?
end
end
end
2 changes: 1 addition & 1 deletion app/helpers/blacklight/catalog_helper_behavior.rb
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def render_search_to_page_title_filter(facet, values)
facet_config = facet_configuration_for_field(facet)
filter_label = facet_field_label(facet_config.key)
filter_value = if values.size < 3
values.map { |value| facet_display_value(facet, value) }.to_sentence
values.map { |value| facet_item_presenter(facet_config, value, facet).label }.to_sentence
else
t('blacklight.search.page_title.many_constraint_values', values: values.size)
end
Expand Down
Loading