blacklight_range_limit 8.0.1 → 8.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +14 -46
  3. data/README.md +4 -4
  4. data/VERSION +1 -1
  5. data/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js +1 -1
  6. data/app/assets/javascripts/blacklight_range_limit/range_limit_plotting.js +27 -15
  7. data/app/assets/javascripts/blacklight_range_limit/range_limit_slider.js +29 -9
  8. data/app/components/blacklight_range_limit/range_facet_component.html.erb +48 -0
  9. data/app/components/blacklight_range_limit/range_facet_component.rb +29 -0
  10. data/app/components/blacklight_range_limit/range_form_component.html.erb +12 -0
  11. data/app/components/blacklight_range_limit/range_form_component.rb +46 -0
  12. data/app/components/blacklight_range_limit/range_segments_component.html.erb +3 -0
  13. data/app/components/blacklight_range_limit/range_segments_component.rb +26 -0
  14. data/app/helpers/range_limit_helper.rb +70 -79
  15. data/app/presenters/blacklight_range_limit/facet_field_presenter.rb +85 -0
  16. data/app/presenters/blacklight_range_limit/facet_item_presenter.rb +45 -0
  17. data/app/presenters/blacklight_range_limit/filter_field.rb +85 -0
  18. data/app/views/blacklight_range_limit/_range_segments.html.erb +7 -21
  19. data/app/views/blacklight_range_limit/range_segments.html.erb +1 -1
  20. data/app/views/catalog/range_limit_panel.html.erb +1 -0
  21. data/blacklight_range_limit.gemspec +1 -1
  22. data/config/locales/blacklight_range_limit.de.yml +13 -0
  23. data/config/locales/blacklight_range_limit.it.yml +13 -0
  24. data/lib/blacklight_range_limit/controller_override.rb +41 -24
  25. data/lib/blacklight_range_limit/engine.rb +4 -0
  26. data/lib/blacklight_range_limit/facet_field_config_override.rb +25 -0
  27. data/lib/blacklight_range_limit/range_limit_builder.rb +15 -39
  28. data/lib/blacklight_range_limit/segment_calculation.rb +2 -2
  29. data/lib/blacklight_range_limit.rb +31 -12
  30. data/lib/generators/blacklight_range_limit/install_generator.rb +3 -17
  31. data/solr/conf/schema.xml +0 -13
  32. data/solr/conf/solrconfig.xml +1 -0
  33. data/spec/components/range_facet_component_spec.rb +111 -0
  34. data/spec/features/a_javascript_spec.rb +4 -4
  35. data/spec/features/blacklight_range_limit_spec.rb +7 -6
  36. data/spec/helpers/blacklight_range_limit_helper_spec.rb +7 -7
  37. data/spec/presenters/facet_field_presenter_spec.rb +144 -0
  38. data/spec/presenters/facet_item_presenter_spec.rb +47 -0
  39. data/spec/presenters/filter_field_spec.rb +79 -0
  40. data/spec/spec_helper.rb +7 -0
  41. data/spec/support/presenter_test_helpers.rb +11 -0
  42. data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
  43. metadata +40 -17
  44. data/app/views/blacklight_range_limit/_range_limit_panel.html.erb +0 -90
  45. data/app/views/blacklight_range_limit/range_limit_panel.html.erb +0 -10
  46. data/lib/blacklight_range_limit/view_helper_override.rb +0 -100
  47. data/lib/generators/blacklight_range_limit/templates/search_history_controller.rb +0 -7
  48. data/spec/lib/blacklight_range_limit/view_helper_override_helper_spec.rb +0 -137
@@ -1,76 +1,55 @@
1
- # Additional helper methods used by view templates inside this plugin.
2
1
  module RangeLimitHelper
2
+ extend Deprecation
3
+
3
4
  def range_limit_url(options = {})
4
5
  main_app.url_for(search_state.to_h.merge(action: 'range_limit').merge(options))
5
6
  end
7
+ deprecation_deprecate :range_limit_url
6
8
 
7
9
  def range_limit_panel_url(options = {})
8
- main_app.url_for(search_state.to_h.merge(action: 'range_limit_panel').merge(options))
10
+ search_facet_path(id: options[:id])
9
11
  end
12
+ deprecation_deprecate :range_limit_panel_url
10
13
 
11
14
  # type is 'begin' or 'end'
12
15
  def render_range_input(solr_field, type, input_label = nil, maxlength=4)
13
- type = type.to_s
14
-
15
- default = params["range"][solr_field][type] if params["range"] && params["range"][solr_field] && params["range"][solr_field][type]
16
-
17
- html = text_field_tag("range[#{solr_field}][#{type}]", default, :maxlength=>maxlength, :class => "form-control text-center range_#{type}")
18
- html += label_tag("range[#{solr_field}][#{type}]", input_label, class: 'sr-only') if input_label.present?
19
- html
16
+ range_form_component(solr_field).render_range_input(type, input_label, maxlength)
20
17
  end
18
+ deprecation_deprecate :render_range_input
21
19
 
22
20
  # type is 'min' or 'max'
23
21
  # Returns smallest and largest value in current result set, if available
24
22
  # from stats component response.
25
23
  def range_results_endpoint(solr_field, type)
26
- stats = stats_for_field(solr_field)
24
+ presenter = range_facet_field_presenter(solr_field)
27
25
 
28
- return nil unless stats
29
- # StatsComponent returns weird min/max when there are in
30
- # fact no values
31
- return nil if @response.total == stats["missing"]
32
-
33
- return stats[type].to_s.gsub(/\.0+/, '')
26
+ case type.to_s
27
+ when 'min'
28
+ presenter.min
29
+ when 'max'
30
+ presenter.max
31
+ end
34
32
  end
33
+ deprecation_deprecate :range_results_endpoint
35
34
 
36
35
  def range_display(solr_field, my_params = params)
37
- return "" unless my_params[:range] && my_params[:range][solr_field]
38
-
39
- hash = my_params[:range][solr_field]
40
-
41
- if hash["missing"]
42
- return t('blacklight.range_limit.missing')
43
- elsif hash["begin"] || hash["end"]
44
- if hash["begin"] == hash["end"]
45
- return t(
46
- 'blacklight.range_limit.single_html',
47
- begin: format_range_display_value(hash['begin'], solr_field),
48
- begin_value: hash['begin']
49
- )
50
- else
51
- return t(
52
- 'blacklight.range_limit.range_html',
53
- begin: format_range_display_value(hash['begin'], solr_field),
54
- begin_value: hash['begin'],
55
- end: format_range_display_value(hash['end'], solr_field),
56
- end_value: hash['end']
57
- )
58
- end
59
- end
36
+ facet_config = blacklight_config.facet_fields[solr_field]
37
+ presenter = range_facet_field_presenter(solr_field)
38
+ return unless presenter.selected_range
60
39
 
61
- ''
40
+ facet_item = Blacklight::Solr::Response::Facets::FacetItem.new(value: presenter.selected_range, hits: presenter.response.total)
41
+
42
+ facet_config.item_presenter.new(facet_item, facet_config, self, solr_field).label
62
43
  end
44
+ deprecation_deprecate :range_display
63
45
 
64
46
  ##
65
47
  # A method that is meant to be overridden downstream to format how a range
66
48
  # label might be displayed to a user. By default it just returns the value
67
49
  # as rendered by the presenter
68
50
  def format_range_display_value(value, solr_field)
69
- if respond_to?(:facet_item_presenter)
70
- facet_item_presenter(facet_configuration_for_field(solr_field), value, solr_field).label
71
- else
72
- facet_display_value(solr_field, value)
73
- end
51
+ Deprecation.warn(RangeLimitHelper, 'Helper #format_range_display_value is deprecated without replacement')
52
+ facet_item_presenter(facet_configuration_for_field(solr_field), value, solr_field).label
74
53
  end
75
54
 
76
55
  # Show the limit area if:
@@ -79,61 +58,73 @@ module RangeLimitHelper
79
58
  # 2) stats show max > min, OR
80
59
  # 3) count > 0 if no stats available.
81
60
  def should_show_limit(solr_field)
82
- stats = stats_for_field(solr_field)
61
+ presenter = range_facet_field_presenter(solr_field)
83
62
 
84
- (params["range"] && params["range"][solr_field]) ||
85
- ( stats &&
86
- stats["max"] > stats["min"]) ||
87
- ( !stats && @response.total > 0 )
63
+ presenter.selected_range ||
64
+ (presenter.max && presenter.min && presenter.max > presenter.min) ||
65
+ @response.total.positive?
88
66
  end
89
67
 
90
68
  def stats_for_field(solr_field)
91
- @response["stats"]["stats_fields"][solr_field] if @response["stats"] && @response["stats"]["stats_fields"]
69
+ range_facet_field_presenter(solr_field).send(:stats_for_field)
92
70
  end
71
+ deprecation_deprecate :stats_for_field
93
72
 
94
73
  def stats_for_field?(solr_field)
95
74
  stats_for_field(solr_field).present?
96
75
  end
76
+ deprecation_deprecate :stats_for_field?
97
77
 
98
78
  def add_range_missing(solr_field, my_params = params)
99
- my_params = Blacklight::SearchState.new(my_params.except(:page), blacklight_config).to_h
100
- my_params["range"] ||= {}
101
- my_params["range"][solr_field] ||= {}
102
- my_params["range"][solr_field]["missing"] = "true"
103
-
104
- my_params
79
+ Blacklight::SearchState.new(my_params.except(:page), blacklight_config).filter(solr_field).add(Blacklight::SearchState::FilterField::MISSING)
105
80
  end
81
+ deprecation_deprecate :add_range_missing
106
82
 
107
83
  def add_range(solr_field, from, to, my_params = params)
108
- my_params = Blacklight::SearchState.new(my_params.except(:page), blacklight_config).to_h
109
- my_params["range"] ||= {}
110
- my_params["range"][solr_field] ||= {}
84
+ Blacklight::SearchState.new(my_params.except(:page), blacklight_config).filter(solr_field).add(from..to)
85
+ end
86
+ deprecation_deprecate :add_range
87
+
88
+ def has_selected_range_limit?(solr_field)
89
+ range_facet_field_presenter(solr_field).selected_range.present?
90
+ end
91
+ deprecation_deprecate :has_selected_range_limit?
111
92
 
112
- my_params["range"][solr_field]["begin"] = from
113
- my_params["range"][solr_field]["end"] = to
114
- my_params["range"][solr_field].delete("missing")
93
+ def selected_missing_for_range_limit?(solr_field)
94
+ search_state.filter(solr_field).values.first == Blacklight::SearchState::FilterField::MISSING
95
+ end
96
+ deprecation_deprecate :selected_missing_for_range_limit?
115
97
 
116
- # eliminate temporary range status params that were just
117
- # for looking things up
118
- my_params.delete("range_field")
119
- my_params.delete("range_start")
120
- my_params.delete("range_end")
98
+ def remove_range_param(solr_field, my_params = params)
99
+ Blacklight::SearchState.new(my_params.except(:page), blacklight_config).filter(solr_field).remove(0..0)
100
+ end
121
101
 
122
- return my_params
102
+ # Looks in the solr @response for ["facet_counts"]["facet_queries"][solr_field], for elements
103
+ # expressed as "solr_field:[X to Y]", turns them into
104
+ # a list of hashes with [:from, :to, :count], sorted by
105
+ # :from. Assumes integers for sorting purposes.
106
+ def solr_range_queries_to_a(solr_field)
107
+ range_facet_field_presenter(solr_field).range_queries.map do |item|
108
+ { from: item.value.first, to: item.value.last, count: item.hits }
109
+ end
123
110
  end
111
+ deprecation_deprecate :solr_range_queries_to_a
124
112
 
125
- def has_selected_range_limit?(solr_field)
126
- params["range"] &&
127
- params["range"][solr_field] &&
128
- (
129
- params["range"][solr_field]["begin"].present? ||
130
- params["range"][solr_field]["end"].present? ||
131
- params["range"][solr_field]["missing"]
132
- )
113
+ def range_config(solr_field)
114
+ BlacklightRangeLimit.range_config(blacklight_config, solr_field)
133
115
  end
116
+ deprecation_deprecate :range_config
134
117
 
135
- def selected_missing_for_range_limit?(solr_field)
136
- params["range"] && params["range"][solr_field] && params["range"][solr_field]["missing"]
118
+ private
119
+
120
+ def range_facet_field_presenter(key)
121
+ facet_config = blacklight_config.facet_fields[key] || Blacklight::Configuration::FacetField.new(key: key, **BlacklightRangeLimit.default_range_config)
122
+ facet_field_presenter(facet_config, Blacklight::Solr::Response::Facets::FacetField.new(key, [], response: @response))
137
123
  end
138
124
 
125
+ def range_form_component(key)
126
+ presenter = range_facet_field_presenter(key)
127
+
128
+ BlacklightRangeLimit::RangeFormComponent.new(facet_field: presenter)
129
+ end
139
130
  end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlacklightRangeLimit
4
+ class FacetFieldPresenter < Blacklight::FacetFieldPresenter
5
+ delegate :response, to: :display_facet
6
+ delegate :blacklight_config, to: :search_state
7
+
8
+ def range_queries
9
+ return [] unless response.dig('facet_counts', 'facet_queries')
10
+
11
+ range_regex = /#{facet_field.field}: *\[ *(-?\d+) *TO *(-?\d+) *\]/
12
+
13
+ array = response.dig('facet_counts', 'facet_queries').map do |query, count|
14
+ if (match = range_regex.match(query))
15
+ Blacklight::Solr::Response::Facets::FacetItem.new(value: match[1].to_i..match[2].to_i, hits: count)
16
+ end
17
+ end
18
+
19
+ array.compact.sort_by { |item| item.value.first }
20
+ end
21
+
22
+ def paginator
23
+ nil
24
+ end
25
+
26
+ def min
27
+ range_results_endpoint(:min)
28
+ end
29
+
30
+ def max
31
+ range_results_endpoint(:max)
32
+ end
33
+
34
+ def selected_range
35
+ search_state.filter(key).values.first
36
+ end
37
+
38
+ def selected_range_facet_item
39
+ return unless selected_range
40
+
41
+ Blacklight::Solr::Response::Facets::FacetItem.new(value: selected_range, hits: response.total)
42
+ end
43
+
44
+ def missing_facet_item
45
+ return unless missing.positive?
46
+
47
+ Blacklight::Solr::Response::Facets::FacetItem.new(
48
+ value: Blacklight::SearchState::FilterField::MISSING,
49
+ hits: missing
50
+ )
51
+ end
52
+
53
+ def missing_selected?
54
+ selected_range == Blacklight::SearchState::FilterField::MISSING
55
+ end
56
+
57
+ def range_config
58
+ @facet_field.range_config
59
+ end
60
+
61
+ private
62
+
63
+ def missing
64
+ stats_for_field.fetch('missing', 0)
65
+ end
66
+
67
+ def stats_for_field
68
+ response.dig('stats', 'stats_fields', facet_field.field) || {}
69
+ end
70
+
71
+ # type is 'min' or 'max'
72
+ # Returns smallest and largest value in current result set, if available
73
+ # from stats component response.
74
+ def range_results_endpoint(type)
75
+ stats = stats_for_field
76
+
77
+ return nil unless stats.key? type
78
+ # StatsComponent returns weird min/max when there are in
79
+ # fact no values
80
+ return nil if response.total == stats['missing']
81
+
82
+ stats[type].to_s.gsub(/\.0+/, '')
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlacklightRangeLimit
4
+ # Override the default item presenter to provide custom labels for
5
+ # range data.
6
+ class FacetItemPresenter < Blacklight::FacetItemPresenter
7
+ def label
8
+ label_for_range || super
9
+ end
10
+
11
+ private
12
+
13
+ def label_for_range
14
+ return unless value.is_a? Range
15
+
16
+ view_context.t(
17
+ range_limit_label_key,
18
+ begin: format_range_display_value(value.first),
19
+ begin_value: value.first,
20
+ end: format_range_display_value(value.last),
21
+ end_value: value.last
22
+ )
23
+ end
24
+
25
+ def range_limit_label_key
26
+ if value.first == value.last
27
+ 'blacklight.range_limit.single_html'
28
+ else
29
+ 'blacklight.range_limit.range_html'
30
+ end
31
+ end
32
+
33
+ ##
34
+ # A method that is meant to be overridden downstream to format how a range
35
+ # label might be displayed to a user. By default it just returns the value.
36
+ def format_range_display_value(value)
37
+ if view_context.method(:format_range_display_value).owner == RangeLimitHelper
38
+ value
39
+ else
40
+ Deprecation.warn(BlacklightRangeLimit, 'Helper method #format_range_display_value has been overridden; implement a custom FacetItemPresenter instead')
41
+ view_context.format_range_display_value(value, key)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlacklightRangeLimit
4
+ # Modeling access to filter query parameters
5
+ class FilterField < Blacklight::SearchState::FilterField
6
+ # this accessor is unnecessary after Blacklight 7.25.0
7
+ attr_accessor :filters_key
8
+
9
+ def initialize(config, search_state)
10
+ super
11
+ @filters_key = :range
12
+ end
13
+
14
+ # @param [String,#value] a filter item to add to the url
15
+ # @return [Blacklight::SearchState] new state
16
+ def add(item)
17
+ new_state = search_state.reset_search
18
+ params = new_state.params
19
+
20
+ value = as_url_parameter(item)
21
+
22
+ if value.is_a? Range
23
+ param_key = filters_key
24
+ params[param_key] = (params[param_key] || {}).dup
25
+ params[param_key][config.key] = { begin: value.first, end: value.last }
26
+ new_state.reset(params)
27
+ else
28
+ super
29
+ end
30
+ end
31
+
32
+ # @param [String,#value] a filter to remove from the url
33
+ # @return [Blacklight::SearchState] new state
34
+ def remove(item)
35
+ new_state = search_state.reset_search
36
+ params = new_state.params
37
+ value = as_url_parameter(item)
38
+
39
+ if value.is_a? Range
40
+ param_key = filters_key
41
+ params[param_key] = (params[param_key] || {}).dup
42
+ params[param_key]&.delete(config.key)
43
+ new_state.reset(params)
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ # @return [Array] an array of applied filters
50
+ def values(except: [])
51
+ params = search_state.params
52
+ param_key = filters_key
53
+ return [] unless params.dig(param_key, config.key)
54
+
55
+ range = if params.dig(param_key, config.key).is_a? Range
56
+ params.dig(param_key, config.key)
57
+ else
58
+ begins = Array(params.dig(param_key, config.key, :begin)).map(&:presence)
59
+ ends = Array(params.dig(param_key, config.key, :end)).map(&:presence)
60
+ begins.zip(ends).map { |b_bound, e_bound| Range.new(b_bound&.to_i, e_bound&.to_i) if b_bound && e_bound }.compact
61
+ end
62
+
63
+ f = except.include?(:filters) ? [] : Array(range)
64
+ f_missing = [] if except.include?(:missing)
65
+ f_missing ||= [Blacklight::SearchState::FilterField::MISSING] if params.dig(filters_key, "-#{key}")&.any? { |v| v == Blacklight::Engine.config.blacklight.facet_missing_param }
66
+
67
+ f + (f_missing || [])
68
+ end
69
+
70
+ # @param [String,#value] a filter to remove from the url
71
+ # @return [Boolean] whether the provided filter is currently applied/selected
72
+ delegate :include?, to: :values
73
+
74
+ # @since Blacklight v7.25.2
75
+ # normal filter fields demangle when they encounter a hash, which they assume to be a number-indexed map
76
+ # this filter should allow (expect) hashes if the keys include 'begin' or 'end'
77
+ def permitted_params
78
+ {
79
+ # { begin: [], end: [] } or [:begin, :end]
80
+ filters_key => { config.key => { begin: [], end: [] }, "-#{config.key}" => [] },
81
+ inclusive_filters_key => { config.key => { begin: [], end: [] } }
82
+ }
83
+ end
84
+ end
85
+ end
@@ -1,22 +1,8 @@
1
- <% # must pass in local variable :solr_field
2
- %>
1
+ <% Deprecation.warn(BlacklightRangeLimit, 'The blacklight_range_limit/range_segments partial is deprecated. Render the RangeSegmentsComponent directly.') %>
3
2
 
4
- <ul class="facet-values list-unstyled">
5
- <% solr_range_queries_to_a(solr_field).each do |hash| %>
6
- <li>
7
- <span class="facet-label">
8
- <%= link_to(
9
- t('blacklight.range_limit.range_html',
10
- begin: format_range_display_value(hash[:from], solr_field),
11
- begin_value: hash[:from],
12
- end: format_range_display_value(hash[:to], solr_field),
13
- end_value: hash[:to]
14
- ),
15
- search_action_url(add_range(solr_field, hash[:from], hash[:to]).except(:controller, :action)),
16
- class: 'facet_select'
17
- ) %>
18
- </span>
19
- <%= render_facet_count hash[:count], classes: ['count'] %>
20
- </li>
21
- <% end %>
22
- </ul>
3
+ <%
4
+ facet = blacklight_config.facet_fields[solr_field]
5
+ display_facet = @response.aggregations[facet.field] || Blacklight::Solr::Response::Facets::FacetField.new(facet.key, [], response: @response)
6
+ presenter = (facet.presenter || BlacklightRangeLimit::FacetFieldPresenter).new(facet, display_facet, self)
7
+ %>
8
+ <%= render BlacklightRangeLimit::RangeSegmentsComponent.new(facet_field: presenter) %>
@@ -1 +1 @@
1
- <%= render :partial => "blacklight_range_limit/range_segments", :locals => {:solr_field => solr_field} %>
1
+ <%= render BlacklightRangeLimit::RangeSegmentsComponent.new(facet_field: facet_field) %>
@@ -0,0 +1 @@
1
+ <%= render template: 'catalog/facet' %>
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
 
18
18
  s.license = 'Apache 2.0'
19
19
 
20
- s.add_dependency 'blacklight', '~> 7.0'
20
+ s.add_dependency 'blacklight', '>= 7.22.2', '< 9'
21
21
 
22
22
  s.add_development_dependency 'rspec', '~> 3.0'
23
23
  s.add_development_dependency 'rspec-rails'
@@ -0,0 +1,13 @@
1
+ de:
2
+ blacklight:
3
+ range_limit:
4
+ range_begin: "%{field_label} Bereichsanfang"
5
+ range_end: "%{field_label} Bereichsende"
6
+ submit_limit: 'Anwenden'
7
+ remove_limit: 'Entfernen'
8
+ missing: 'Unbekannt'
9
+ view_distribution: 'Verteilung Anzeigen'
10
+ view_larger: 'Größer anzeigen »'
11
+ results_range_html: 'Aktuelle Ergebnisse reichen von <span class="min">%{min}</span> bis <span class="max">%{max}</span>'
12
+ single_html: '<span class="single" data-blrl-single="%{begin_value}">%{begin}</span>'
13
+ range_html: '<span class="from" data-blrl-begin="%{begin_value}">%{begin}</span> bis <span class="to" data-blrl-end="%{end_value}">%{end}</span>'
@@ -0,0 +1,13 @@
1
+ it:
2
+ blacklight:
3
+ range_limit:
4
+ range_begin: "%{field_label} da"
5
+ range_end: "%{field_label} a"
6
+ submit_limit: 'Invia'
7
+ remove_limit: 'cancella'
8
+ missing: 'Data sconosciuta'
9
+ view_distribution: 'Visualizzazione della distribuzione'
10
+ view_larger: 'Visualizza più grande »'
11
+ results_range_html: 'Risultati attuali vanno da <span class="min">%{min}</span> a <span class="max">%{max}</span>'
12
+ single_html: '<span class="single" data-blrl-single="%{begin_value}">%{begin}</span>'
13
+ range_html: '<span class="from" data-blrl-begin="%{begin_value}">%{begin}</span> a <span class="to" data-blrl-end="%{end_value}">%{end}</span>'
@@ -4,12 +4,37 @@
4
4
  require 'blacklight_range_limit/segment_calculation'
5
5
  module BlacklightRangeLimit
6
6
  module ControllerOverride
7
+ extend Deprecation
7
8
  extend ActiveSupport::Concern
8
9
 
10
+ RANGE_LIMIT_FIELDS = [:range_end, :range_field, :range_start].freeze
11
+
9
12
  included do
10
- helper BlacklightRangeLimit::ViewHelperOverride
11
- helper RangeLimitHelper
12
- helper_method :has_range_limit_parameters?
13
+ before_action do
14
+ template = lookup_context.find_all('blacklight_range_limit/range_limit_panel', lookup_context.prefixes + [""], true, [:field_name], {}).first
15
+
16
+ if template
17
+ fields = blacklight_config.facet_fields.select { |_k, v| v.range && !v.had_existing_component_configuration }
18
+
19
+ fields.each_value do |facet_config|
20
+ Deprecation.warn(BlacklightRangeLimit, 'Found partial blacklight_range_limit/range_limit_panel, so falling back to legacy behavior.') unless facet_config.partial
21
+ facet_config.partial ||= 'blacklight_range_limit/range_limit_panel'
22
+ facet_config.component = nil
23
+ end
24
+ else
25
+ fields = blacklight_config.facet_fields.select { |_k, v| v.partial == 'blacklight_range_limit/range_limit_panel' }
26
+ fields.each_value do |facet_config|
27
+ Deprecation.warn(BlacklightRangeLimit, 'Ignoring partial configuration for missing blacklight_range_limit/range_limit_panel partial')
28
+ facet_config.partial = nil
29
+ end
30
+ end
31
+
32
+ # Blacklight 7.25+: Allow range limit params if necessary
33
+ if blacklight_config.search_state_fields
34
+ missing_keys = RANGE_LIMIT_FIELDS - blacklight_config.search_state_fields
35
+ blacklight_config.search_state_fields.concat(missing_keys)
36
+ end
37
+ end
13
38
  end
14
39
 
15
40
  # Action method of our own!
@@ -17,6 +42,9 @@ module BlacklightRangeLimit
17
42
  # Used when we need a second Solr query to get range facets, after the
18
43
  # first found min/max from result set.
19
44
  def range_limit
45
+ @facet = blacklight_config.facet_fields[params[:range_field]]
46
+ raise ActionController::RoutingError, 'Not Found' unless @facet&.range
47
+
20
48
  # We need to swap out the add_range_limit_params search param filter,
21
49
  # and instead add in our fetch_specific_range_limit filter,
22
50
  # to fetch only the range limit segments for only specific
@@ -26,33 +54,22 @@ module BlacklightRangeLimit
26
54
  @response, _ = search_service.search_results do |search_builder|
27
55
  search_builder.except(:add_range_limit_params).append(:fetch_specific_range_limit)
28
56
  end
29
- render('blacklight_range_limit/range_segments', :locals => {:solr_field => params[:range_field]}, :layout => !request.xhr?)
30
- end
31
57
 
32
- # over-ride, call super, but make sure our range limits count too
33
- def has_search_parameters?
34
- super || has_range_limit_parameters?
35
- end
58
+ display_facet = @response.aggregations[@facet.field] || Blacklight::Solr::Response::Facets::FacetField.new(@facet.key, [], response: @response)
36
59
 
37
- def has_range_limit_parameters?(my_params = params)
38
- my_params[:range] &&
39
- my_params[:range].to_unsafe_h.any? do |key, v|
40
- v.present? && v.respond_to?(:'[]') &&
41
- (v["begin"].present? || v["end"].present? || v["missing"].present?)
42
- end
60
+ @presenter = (@facet.presenter || BlacklightRangeLimit::FacetFieldPresenter).new(@facet, display_facet, view_context)
61
+
62
+ render 'blacklight_range_limit/range_segments', locals: { facet_field: @presenter }, layout: !request.xhr?
43
63
  end
44
64
 
45
65
  def range_limit_panel
46
- @facet = blacklight_config.facet_fields[params[:id]]
47
- raise ActionController::RoutingError, 'Not Found' unless @facet
48
-
49
- @response = search_service.search_results.first
66
+ Deprecation.warn(BlacklightRangeLimit::ControllerOverride, 'range_limit_panel is deprecated; use the normal facet modal route instead')
67
+ facet
68
+ end
50
69
 
51
- respond_to do |format|
52
- format.html do
53
- # Draw the partial for the "more" facet modal window:
54
- return render 'blacklight_range_limit/range_limit_panel', layout: !request.xhr?
55
- end
70
+ class_methods do
71
+ def default_range_config
72
+ BlacklightRangeLimit.default_range_config
56
73
  end
57
74
  end
58
75
  end
@@ -15,5 +15,9 @@ module BlacklightRangeLimit
15
15
  config.action_dispatch.rescue_responses.merge!(
16
16
  "BlacklightRangeLimit::InvalidRange" => :not_acceptable
17
17
  )
18
+
19
+ config.before_configuration do
20
+ Blacklight::Configuration::FacetField.prepend BlacklightRangeLimit::FacetFieldConfigOverride
21
+ end
18
22
  end
19
23
  end
@@ -0,0 +1,25 @@
1
+ module BlacklightRangeLimit
2
+ # Override the upstream normalize method to inject range limit defaults
3
+ module FacetFieldConfigOverride
4
+ def normalize!(*args)
5
+ normalize_range! if range
6
+
7
+ super
8
+ end
9
+
10
+ def normalize_range!
11
+ self.had_existing_component_configuration = component.present?
12
+
13
+ if range.is_a? Hash
14
+ self.range_config = range
15
+ self.range = true
16
+ end
17
+
18
+ if range_config
19
+ self.range_config = range_config.reverse_merge(BlacklightRangeLimit.default_range_config[:range_config])
20
+ end
21
+
22
+ @table.reverse_merge!(BlacklightRangeLimit.default_range_config)
23
+ end
24
+ end
25
+ end