blacklight 7.5.0 → 7.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.docker/app/Dockerfile +26 -0
  3. data/.docker/app/entrypoint.sh +6 -0
  4. data/.env +5 -0
  5. data/.gitignore +0 -1
  6. data/.rubocop_todo.yml +26 -37
  7. data/.travis.yml +16 -24
  8. data/Gemfile +4 -1
  9. data/README.md +4 -0
  10. data/VERSION +1 -1
  11. data/app/assets/stylesheets/blacklight/_pagination.scss +4 -0
  12. data/app/components/blacklight/constraint_layout_component.html.erb +23 -0
  13. data/app/components/blacklight/constraint_layout_component.rb +16 -0
  14. data/app/components/blacklight/facet_field_component.html.erb +25 -0
  15. data/app/components/blacklight/facet_field_component.rb +11 -0
  16. data/app/components/blacklight/facet_field_list_component.html.erb +18 -0
  17. data/app/components/blacklight/facet_field_list_component.rb +22 -0
  18. data/app/components/blacklight/facet_field_no_layout_component.rb +13 -0
  19. data/app/components/blacklight/facet_item_component.rb +120 -0
  20. data/app/controllers/concerns/blacklight/catalog.rb +4 -1
  21. data/app/helpers/blacklight/blacklight_helper_behavior.rb +4 -2
  22. data/app/helpers/blacklight/catalog_helper_behavior.rb +2 -4
  23. data/app/helpers/blacklight/configuration_helper_behavior.rb +3 -2
  24. data/app/helpers/blacklight/facets_helper_behavior.rb +84 -48
  25. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +64 -33
  26. data/app/javascript/blacklight/modal.js +1 -1
  27. data/app/models/blacklight/icon.rb +11 -5
  28. data/app/models/concerns/blacklight/document/extensions.rb +3 -0
  29. data/app/models/concerns/blacklight/document/semantic_fields.rb +0 -4
  30. data/app/presenters/blacklight/document_presenter.rb +27 -36
  31. data/app/presenters/blacklight/facet_field_presenter.rb +57 -0
  32. data/app/presenters/blacklight/facet_item_presenter.rb +81 -0
  33. data/app/presenters/blacklight/field_presenter.rb +31 -6
  34. data/app/presenters/blacklight/index_presenter.rb +2 -2
  35. data/app/presenters/blacklight/show_presenter.rb +3 -3
  36. data/app/views/catalog/_citation.html.erb +1 -1
  37. data/app/views/catalog/_constraints.html.erb +2 -2
  38. data/app/views/catalog/_constraints_element.html.erb +5 -24
  39. data/app/views/catalog/_email_form.html.erb +1 -1
  40. data/app/views/catalog/_facet_layout.html.erb +8 -17
  41. data/app/views/catalog/_facet_limit.html.erb +3 -12
  42. data/app/views/catalog/_facet_pagination.html.erb +2 -2
  43. data/app/views/catalog/_facet_pivot.html.erb +4 -4
  44. data/app/views/catalog/_field.json.jbuilder +2 -2
  45. data/app/views/catalog/_index.html.erb +3 -3
  46. data/app/views/catalog/_previous_next_doc.html.erb +5 -5
  47. data/app/views/catalog/_search_form.html.erb +1 -1
  48. data/app/views/catalog/_show.html.erb +3 -3
  49. data/app/views/catalog/_sms_form.html.erb +1 -1
  50. data/app/views/catalog/_sort_and_per_page.html.erb +1 -1
  51. data/app/views/catalog/_start_over.html.erb +1 -0
  52. data/app/views/catalog/_thumbnail.html.erb +1 -1
  53. data/app/views/catalog/index.json.jbuilder +2 -1
  54. data/app/views/catalog/show.html.erb +1 -1
  55. data/app/views/catalog/show.json.jbuilder +2 -1
  56. data/app/views/layouts/blacklight/base.html.erb +2 -2
  57. data/blacklight.gemspec +1 -0
  58. data/config/locales/blacklight.ar.yml +30 -24
  59. data/config/locales/blacklight.de.yml +2 -0
  60. data/config/locales/blacklight.en.yml +2 -0
  61. data/config/locales/blacklight.es.yml +2 -0
  62. data/config/locales/blacklight.fr.yml +2 -0
  63. data/config/locales/blacklight.hu.yml +2 -0
  64. data/config/locales/blacklight.it.yml +2 -0
  65. data/config/locales/blacklight.nl.yml +2 -0
  66. data/config/locales/blacklight.pt-BR.yml +2 -0
  67. data/config/locales/blacklight.sq.yml +2 -0
  68. data/config/locales/blacklight.zh.yml +2 -0
  69. data/docker-compose.yml +35 -0
  70. data/lib/blacklight/configuration/field.rb +5 -4
  71. data/lib/blacklight/engine.rb +2 -6
  72. data/lib/blacklight/nested_open_struct_with_hash_access.rb +1 -1
  73. data/lib/blacklight/search_state.rb +52 -0
  74. data/lib/blacklight/solr/response/facets.rb +2 -0
  75. data/lib/generators/blacklight/assets_generator.rb +10 -0
  76. data/package.json +1 -1
  77. data/spec/{views/catalog/_constraints_element.html.erb_spec.rb → components/blacklight/constraint_layout_component_spec.rb} +22 -12
  78. data/spec/components/blacklight/facet_field_list_component_spec.rb +108 -0
  79. data/spec/components/blacklight/facet_item_component_spec.rb +50 -0
  80. data/spec/controllers/catalog_controller_spec.rb +13 -1
  81. data/spec/features/facets_spec.rb +1 -1
  82. data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +3 -0
  83. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +24 -12
  84. data/spec/helpers/blacklight/render_constraints_helper_behavior_spec.rb +4 -23
  85. data/spec/helpers/blacklight_helper_spec.rb +17 -0
  86. data/spec/helpers/catalog_helper_spec.rb +0 -7
  87. data/spec/lib/blacklight/search_state_spec.rb +50 -0
  88. data/spec/models/blacklight/icon_spec.rb +15 -6
  89. data/spec/models/blacklight/solr/response/facets_spec.rb +30 -1
  90. data/spec/presenters/blacklight/document_presenter_spec.rb +22 -62
  91. data/spec/presenters/blacklight/facet_field_presenter_spec.rb +109 -0
  92. data/spec/presenters/blacklight/facet_item_presenter_spec.rb +92 -0
  93. data/spec/presenters/blacklight/field_presenter_spec.rb +268 -0
  94. data/spec/presenters/blacklight/index_presenter_spec.rb +0 -142
  95. data/spec/presenters/blacklight/show_presenter_spec.rb +0 -177
  96. data/spec/spec_helper.rb +2 -0
  97. data/spec/support/presenter_test_helpers.rb +11 -0
  98. data/spec/views/catalog/_facet_group.html.erb_spec.rb +1 -0
  99. data/spec/views/catalog/_previous_next_doc.html.erb_spec.rb +18 -0
  100. data/tasks/blacklight.rake +30 -23
  101. metadata +48 -7
  102. data/Vagrantfile +0 -79
  103. data/provision.sh +0 -30
@@ -6,14 +6,19 @@
6
6
  # Includes methods for rendering contraints graphically on the
7
7
  # search results page (render_constraints(_*))
8
8
  module Blacklight::RenderConstraintsHelperBehavior
9
+ extend Deprecation
10
+ self.deprecation_horizon = 'blacklight 8.0'
11
+
9
12
  ##
10
13
  # Check if the query has any constraints defined (a query, facet, etc)
11
14
  #
12
15
  # @param [Hash] localized_params query parameters
13
16
  # @return [Boolean]
14
- def query_has_constraints?(localized_params = params)
15
- !(localized_params[:q].blank? && localized_params[:f].blank?)
17
+ def query_has_constraints?(params_or_search_state = search_state)
18
+ search_state = convert_to_search_state(params_or_search_state)
19
+ search_state.has_constraints?
16
20
  end
21
+ deprecation_deprecate :query_has_constraints?
17
22
 
18
23
  ##
19
24
  # Render the actual constraints, not including header or footer
@@ -21,8 +26,16 @@ module Blacklight::RenderConstraintsHelperBehavior
21
26
  #
22
27
  # @param [Hash] localized_params query parameters
23
28
  # @return [String]
24
- def render_constraints(localized_params = params)
25
- render_constraints_query(localized_params) + render_constraints_filters(localized_params)
29
+ def render_constraints(localized_params = params, local_search_state = search_state)
30
+ params_or_search_state = if localized_params != params
31
+ localized_params
32
+ else
33
+ local_search_state
34
+ end
35
+
36
+ Deprecation.silence(Blacklight::RenderConstraintsHelperBehavior) do
37
+ render_constraints_query(params_or_search_state) + render_constraints_filters(params_or_search_state)
38
+ end
26
39
  end
27
40
 
28
41
  ##
@@ -30,15 +43,20 @@ module Blacklight::RenderConstraintsHelperBehavior
30
43
  #
31
44
  # @param [ActionController::Parameters] localized_params query parameters
32
45
  # @return [String]
33
- def render_constraints_query(localized_params = params)
46
+ def render_constraints_query(params_or_search_state = search_state)
47
+ search_state = convert_to_search_state(params_or_search_state)
48
+
34
49
  # So simple don't need a view template, we can just do it here.
35
- return "".html_safe if localized_params[:q].blank?
50
+ return "".html_safe if search_state.query_param.blank?
36
51
 
37
- render_constraint_element(constraint_query_label(localized_params),
38
- localized_params[:q],
39
- classes: ["query"],
40
- remove: remove_constraint_url(localized_params))
52
+ Deprecation.silence(Blacklight::RenderConstraintsHelperBehavior) do
53
+ render_constraint_element(constraint_query_label(search_state),
54
+ search_state.query_param,
55
+ classes: ["query"],
56
+ remove: remove_constraint_url(search_state))
57
+ end
41
58
  end
59
+ deprecation_deprecate :render_constraints_query
42
60
 
43
61
  ##
44
62
  # Provide a url for removing a particular constraint. This can be overriden
@@ -47,52 +65,53 @@ module Blacklight::RenderConstraintsHelperBehavior
47
65
  #
48
66
  # @param [ActionController::Parameters] localized_params query parameters
49
67
  # @return [String]
50
- def remove_constraint_url(localized_params)
51
- scope = localized_params.delete(:route_set) || self
52
-
53
- unless localized_params.is_a? ActionController::Parameters
54
- localized_params = ActionController::Parameters.new(localized_params)
55
- end
68
+ def remove_constraint_url(params_or_search_state = search_state)
69
+ search_state = convert_to_search_state(params_or_search_state)
56
70
 
57
- options = localized_params.merge(q: nil, action: 'index')
58
- options.permit!
59
- scope.url_for(options)
71
+ search_action_path(search_state.remove_query_params)
60
72
  end
73
+ deprecation_deprecate :remove_constraint_url
61
74
 
62
75
  ##
63
76
  # Render the facet constraints
64
77
  # @param [Hash] localized_params query parameters
65
78
  # @return [String]
66
- def render_constraints_filters(localized_params = params)
67
- return "".html_safe unless localized_params[:f]
79
+ def render_constraints_filters(params_or_search_state = search_state)
80
+ search_state = convert_to_search_state(params_or_search_state)
68
81
 
69
- path = controller.search_state_class.new(localized_params, blacklight_config, controller)
70
- content = []
71
- localized_params[:f].each_pair do |facet, values|
72
- content << render_filter_element(facet, values, path)
73
- end
82
+ return "".html_safe if search_state.filter_params.blank?
74
83
 
75
- safe_join(content.flatten, "\n")
84
+ Deprecation.silence(Blacklight::RenderConstraintsHelperBehavior) do
85
+ safe_join(search_state.filter_params.each_pair.map do |facet, values|
86
+ render_filter_element(facet, values, search_state)
87
+ end, "\n")
88
+ end
76
89
  end
90
+ deprecation_deprecate :render_constraints_filters
77
91
 
78
92
  ##
79
93
  # Render a single facet's constraint
80
94
  # @param [String] facet field
81
95
  # @param [Array<String>] values selected facet values
82
- # @param [Blacklight::SearchState] path query parameters
96
+ # @param [Blacklight::SearchState] path query parameters (unused)
83
97
  # @return [String]
84
- def render_filter_element(facet, values, path)
98
+ def render_filter_element(facet, values, search_state)
85
99
  facet_config = facet_configuration_for_field(facet)
86
100
 
87
101
  safe_join(Array(values).map do |val|
88
102
  next if val.blank? # skip empty string
89
103
 
90
- render_constraint_element(facet_field_label(facet_config.key),
91
- facet_display_value(facet, val),
92
- remove: search_action_path(path.remove_facet_params(facet, val)),
93
- classes: ["filter", "filter-" + facet.parameterize])
104
+ presenter = facet_item_presenter(facet_config, val, facet)
105
+
106
+ Deprecation.silence(Blacklight::RenderConstraintsHelperBehavior) do
107
+ render_constraint_element(facet_field_label(facet_config.key),
108
+ presenter.label,
109
+ remove: presenter.remove_href(search_state),
110
+ classes: ["filter", "filter-" + facet.parameterize])
111
+ end
94
112
  end, "\n")
95
113
  end
114
+ deprecation_deprecate :render_filter_element
96
115
 
97
116
  # Render a label/value constraint on the screen. Can be called
98
117
  # by plugins and such to get application-defined rendering.
@@ -111,4 +130,16 @@ module Blacklight::RenderConstraintsHelperBehavior
111
130
  def render_constraint_element(label, value, options = {})
112
131
  render(partial: "catalog/constraints_element", locals: { label: label, value: value, options: options })
113
132
  end
133
+ deprecation_deprecate :render_constraint_element
134
+
135
+ private
136
+
137
+ def convert_to_search_state(params_or_search_state)
138
+ if params_or_search_state.is_a? Blacklight::SearchState
139
+ params_or_search_state
140
+ else
141
+ # deprecated
142
+ controller.search_state_class.new(params_or_search_state, blacklight_config, controller)
143
+ end
144
+ end
114
145
  end
@@ -44,7 +44,7 @@
44
44
 
45
45
  <div class="modal-body">
46
46
  <p>Some message</p>
47
- <%= link_to "This result will still be within modal", some_link, data: { blacklight: "preserve" } %>
47
+ <%= link_to "This result will still be within modal", some_link, data: { blacklight_modal: "preserve" } %>
48
48
  </div>
49
49
 
50
50
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Blacklight
4
4
  class Icon
5
- attr_reader :icon_name, :aria_hidden, :label, :role
5
+ attr_reader :icon_name, :aria_hidden, :label, :role, :additional_options
6
6
  ##
7
7
  # @param [String, Symbol] icon_name
8
8
  # @param [Hash] options
@@ -10,12 +10,14 @@ module Blacklight
10
10
  # @param [Boolean] aria_hidden include aria_hidden attribute
11
11
  # @param [Boolean] label include <title> and aria-label as part of svg
12
12
  # @param [String] role role attribute to be included in svg
13
- def initialize(icon_name, classes: '', aria_hidden: false, label: true, role: 'image')
13
+ # @param [Hash] additional_options the way forward instead of named arguments
14
+ def initialize(icon_name, classes: '', aria_hidden: false, label: true, role: 'img', additional_options: {})
14
15
  @icon_name = icon_name
15
16
  @classes = classes
16
17
  @aria_hidden = aria_hidden
17
18
  @label = label
18
19
  @role = role
20
+ @additional_options = additional_options
19
21
  end
20
22
 
21
23
  ##
@@ -24,17 +26,17 @@ module Blacklight
24
26
  def svg
25
27
  svg = ng_xml.at_xpath('svg')
26
28
  svg['role'] = role
27
- svg['aria-labelled-by'] = unique_id if label
29
+ svg['aria-labelledby'] = unique_id if label
28
30
  svg.add_child("<title id='#{unique_id}'>#{icon_label}</title>") if label
29
31
  ng_xml.to_xml
30
32
  end
31
33
 
32
34
  def icon_label
33
- I18n.translate("blacklight.icon.#{icon_name}", default: "#{icon_name} icon")
35
+ I18n.translate("blacklight.icon.#{icon_name_context}", default: "#{icon_name} icon")
34
36
  end
35
37
 
36
38
  def unique_id
37
- @unique_id ||= "bl-icon-#{icon_name}-#{SecureRandom.hex(8)}"
39
+ @unique_id ||= "bl-icon-#{icon_name_context}-#{SecureRandom.hex(8)}"
38
40
  end
39
41
 
40
42
  ##
@@ -66,6 +68,10 @@ module Blacklight
66
68
 
67
69
  private
68
70
 
71
+ def icon_name_context
72
+ [icon_name, additional_options[:label_context]].compact.join('_')
73
+ end
74
+
69
75
  def file
70
76
  # Rails.application.assets is `nil` in production mode (where compile assets is enabled).
71
77
  # This workaround is based off of this comment: https://github.com/fphilipe/premailer-rails/issues/145#issuecomment-225992564
@@ -32,6 +32,9 @@ module Blacklight::Document::Extensions
32
32
  module ClassMethods
33
33
  attr_writer :registered_extensions
34
34
 
35
+ # Returns array of hashes of registered extensions. Each hash
36
+ # has a :module_obj key and a :condition_proc key. Usually this
37
+ # method is only used internally in #apply_extensions, but if you
35
38
  # want to zero out all previously registered extensions you can call:
36
39
  # SolrDocument.registered_extensions = nil
37
40
  def registered_extensions
@@ -4,10 +4,6 @@ module Blacklight::Document
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  module ClassMethods
7
- # Returns array of hashes of registered extensions. Each hash
8
- # has a :module_obj key and a :condition_proc key. Usually this
9
- # method is only used internally in #apply_extensions, but if you
10
-
11
7
  # Class-level method for accessing/setting semantic mappings
12
8
  # for solr stored fields. Can be set by local app, key is
13
9
  # a symbol for a semantic, value is a solr _stored_ field.
@@ -19,10 +19,14 @@ module Blacklight
19
19
 
20
20
  # @return [Hash<String,Configuration::Field>] all the fields for this index view that should be rendered
21
21
  def fields_to_render
22
- fields.select do |_name, field_config|
23
- # rubocop:disable Style/PreferredHashMethods
24
- render_field?(field_config) && has_value?(field_config)
25
- # rubocop:enable Style/PreferredHashMethods
22
+ return to_enum(:fields_to_render) unless block_given?
23
+
24
+ fields.each do |name, field_config|
25
+ field_presenter = field_presenter(field_config)
26
+
27
+ next unless field_presenter.render_field? && field_presenter.any?
28
+
29
+ yield name, field_config, field_presenter
26
30
  end
27
31
  end
28
32
 
@@ -32,11 +36,11 @@ module Blacklight
32
36
  #
33
37
  # @return [String]
34
38
  def heading
35
- return field_values(view_config.title_field) if view_config.title_field.is_a? Blacklight::Configuration::Field
39
+ return field_value(view_config.title_field) if view_config.title_field.is_a? Blacklight::Configuration::Field
36
40
 
37
41
  fields = Array.wrap(view_config.title_field) + [configuration.document_model.unique_key]
38
- f = fields.lazy.map { |field| field_config(field) }.detect { |field_config| retrieve_values(field_config).any? }
39
- field_values(f, except_operations: [Rendering::HelperMethod])
42
+ f = fields.lazy.map { |field| field_config(field) }.detect { |field_config| field_presenter(field_config).any? }
43
+ field_value(f, except_operations: [Rendering::HelperMethod])
40
44
  end
41
45
 
42
46
  def display_type(base_name = nil, default: nil)
@@ -44,7 +48,7 @@ module Blacklight
44
48
  fields += Array.wrap(view_config[:"#{base_name}_display_type_field"]) if base_name && view_config.key?(:"#{base_name}_display_type_field")
45
49
  fields += Array.wrap(view_config.display_type_field)
46
50
 
47
- display_type = fields.lazy.map { |field| retrieve_values(field_config(field)) }.detect(&:any?)
51
+ display_type = fields.lazy.map { |field| field_presenter(field_config(field)) }.detect(&:any?)&.values
48
52
  display_type ||= Array(default) if default
49
53
 
50
54
  display_type || []
@@ -55,11 +59,11 @@ module Blacklight
55
59
  #
56
60
  # Allow an extention point where information in the document
57
61
  # may drive the value of the field
58
- # @param [Configuration::Field] field
62
+ # @param [Configuration::Field] field_config
59
63
  # @param [Hash] options
60
64
  # @option options [String] :value
61
- def field_value field, options = {}
62
- field_values(field, options)
65
+ def field_value field_config, options = {}
66
+ field_presenter(field_config, options).render
63
67
  end
64
68
 
65
69
  def thumbnail
@@ -68,41 +72,28 @@ module Blacklight
68
72
 
69
73
  private
70
74
 
71
- ##
72
- # Check to see if the given field should be rendered in this context
73
- # @param [Blacklight::Configuration::Field] field_config
74
- # @return [Boolean]
75
75
  def render_field?(field_config)
76
- view_context.should_render_field?(field_config, document)
76
+ field_presenter(field_config).render_field?
77
77
  end
78
+ deprecation_deprecate render_field?: 'Use FieldPresenter#render_field?'
78
79
 
79
- ##
80
- # Check if a document has (or, might have, in the case of accessor methods) a value for
81
- # the given solr field
82
- # @param [Blacklight::Configuration::Field] field_config
83
- # @return [Boolean]
84
80
  def has_value?(field_config)
85
- retrieve_values(field_config).present?
81
+ field_presenter(field_config).any?
86
82
  end
83
+ deprecation_deprecate has_value?: 'Use FieldPresenter#any?'
87
84
 
88
- ##
89
- # Get the value for a document's field, and prepare to render it.
90
- # - highlight_field
91
- # - accessor
92
- # - solr field
93
- #
94
- # Rendering:
95
- # - helper_method
96
- # - link_to_facet
97
- # @param [Blacklight::Configuration::Field] field_config solr field configuration
98
- # @param [Hash] options additional options to pass to the rendering helpers
99
85
  def field_values(field_config, options = {})
100
- options[:values] ||= retrieve_values(field_config) unless options.key? :value
101
- FieldPresenter.new(view_context, document, field_config, options).render
86
+ field_value(field_config, options)
102
87
  end
88
+ deprecation_deprecate field_values: 'Use #field_value'
103
89
 
104
90
  def retrieve_values(field_config)
105
- FieldRetriever.new(document, field_config).fetch
91
+ field_presenter(field_config).values
92
+ end
93
+ deprecation_deprecate retrieve_values: 'Use FieldPresenter#values'
94
+
95
+ def field_presenter(field_config, options = {})
96
+ FieldPresenter.new(view_context, document, field_config, options)
106
97
  end
107
98
  end
108
99
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class FacetFieldPresenter
5
+ attr_reader :facet_field, :display_facet, :view_context, :search_state
6
+
7
+ delegate :key, to: :facet_field
8
+ delegate :field_name, to: :display_facet
9
+
10
+ def initialize(facet_field, display_facet, view_context, search_state = view_context.search_state)
11
+ @facet_field = facet_field
12
+ @display_facet = display_facet
13
+ @view_context = view_context
14
+ @search_state = search_state
15
+ end
16
+
17
+ def collapsed?
18
+ Deprecation.silence(Blacklight::FacetsHelperBehavior) do
19
+ view_context.should_collapse_facet?(facet_field)
20
+ end
21
+ end
22
+
23
+ def active?
24
+ Deprecation.silence(Blacklight::FacetsHelperBehavior) do
25
+ view_context.facet_field_in_params?(key)
26
+ end
27
+ end
28
+
29
+ def in_modal?
30
+ search_state.params[:action] == "facet"
31
+ end
32
+
33
+ def modal_path
34
+ return unless paginator
35
+
36
+ view_context.search_facet_path(id: key) unless paginator&.last_page?
37
+ end
38
+
39
+ def label
40
+ view_context.facet_field_label(key)
41
+ end
42
+
43
+ # @private
44
+ # @deprecated
45
+ def html_id
46
+ Deprecation.silence(Blacklight::FacetsHelperBehavior) do
47
+ view_context.facet_field_id(facet_field)
48
+ end
49
+ end
50
+
51
+ def paginator
52
+ return unless display_facet
53
+
54
+ @paginator ||= view_context.facet_paginator(facet_field, display_facet)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class FacetItemPresenter
5
+ attr_reader :facet_item, :facet_config, :view_context, :search_state, :facet_field
6
+
7
+ delegate :hits, to: :facet_item
8
+
9
+ def initialize(facet_item, facet_config, view_context, facet_field, search_state = view_context.search_state)
10
+ @facet_item = facet_item
11
+ @facet_config = facet_config
12
+ @view_context = view_context
13
+ @facet_field = facet_field
14
+ @search_state = search_state
15
+ end
16
+
17
+ ##
18
+ # Check if the query parameters have the given facet field with the
19
+ # given value.
20
+ def selected?
21
+ search_state.has_facet? facet_config, value: facet_value
22
+ end
23
+
24
+ ##
25
+ # Get the displayable version of a facet's value
26
+ #
27
+ # @return [String]
28
+ def label
29
+ return @view_context.facet_display_value(@facet_field, @facet_item) unless @view_context.method(:facet_display_value).owner == Blacklight::FacetsHelperBehavior
30
+
31
+ value = if facet_item.respond_to? :label
32
+ facet_item.label
33
+ else
34
+ facet_value
35
+ end
36
+
37
+ if facet_config.helper_method
38
+ view_context.public_send(facet_config.helper_method, value)
39
+ elsif facet_config.query && facet_config.query[value]
40
+ facet_config.query[value][:label]
41
+ elsif facet_config.date
42
+ localization_options = facet_config.date == true ? {} : facet_config.date
43
+ I18n.l(Time.zone.parse(value), localization_options)
44
+ else
45
+ value
46
+ end
47
+ end
48
+
49
+ def href(path_options = {})
50
+ if selected?
51
+ remove_href
52
+ else
53
+ add_href(path_options)
54
+ end
55
+ end
56
+
57
+ # @private
58
+ def remove_href(path = search_state)
59
+ view_context.search_action_path(path.remove_facet_params(facet_config.key, facet_item))
60
+ end
61
+
62
+ # @private
63
+ def add_href(path_options = {})
64
+ if facet_config.url_method
65
+ view_context.public_send(facet_config.url_method, facet_config.key, facet_item)
66
+ else
67
+ view_context.search_action_path(search_state.add_facet_params_and_redirect(facet_config.key, facet_item).merge(path_options))
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def facet_value
74
+ if facet_item.respond_to? :value
75
+ facet_item.value
76
+ else
77
+ facet_item
78
+ end
79
+ end
80
+ end
81
+ end