blacklight_range_limit 8.1.0 → 8.2.0

Sign up to get free protection for your applications and to get access to all the features.
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 +70 -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 = number_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(&:to_i)
59
+ ends = Array(params.dig(param_key, config.key, :end)).map(&:to_i)
60
+ begins.zip(ends).map { |b_bound, e_bound| Range.new(b_bound, e_bound) }
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