Skip to content
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

Support open-ended ranges #278

Merged
merged 4 commits into from
Nov 14, 2024
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
4 changes: 2 additions & 2 deletions app/components/blacklight_range_limit/range_form_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ def initialize(facet_field:, classes: BlacklightRangeLimit.classes)
end

def begin_value_default
@facet_field.selected_range.is_a?(Range) ? @facet_field.selected_range.first : @facet_field.min
@facet_field.selected_range.is_a?(Range) ? @facet_field.selected_range.begin : @facet_field.min
end

def end_value_default
@facet_field.selected_range.is_a?(Range) ? @facet_field.selected_range.last : @facet_field.max
@facet_field.selected_range.is_a?(Range) ? @facet_field.selected_range.end : @facet_field.max
end

def begin_input_name
Expand Down
10 changes: 5 additions & 5 deletions app/presenters/blacklight_range_limit/facet_item_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ def label_for_range

view_context.t(
range_limit_label_key,
begin: format_range_display_value(value.first),
begin_value: value.first,
end: format_range_display_value(value.last),
end_value: value.last
begin: format_range_display_value(value.begin),
begin_value: value.begin,
end: format_range_display_value(value.end),
end_value: value.end
)
end

def range_limit_label_key
if value.first == value.last
if value.begin == value.end
'blacklight.range_limit.single_html'
else
'blacklight.range_limit.range_html'
Expand Down
4 changes: 2 additions & 2 deletions app/presenters/blacklight_range_limit/filter_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def add(item)
if value.is_a? Range
param_key = filters_key
params[param_key] = (params[param_key] || {}).dup
params[param_key][config.key] = { begin: value.first, end: value.last }
params[param_key][config.key] = { begin: value.begin, end: value.end }
new_state.reset(params)
else
super
Expand Down Expand Up @@ -55,7 +55,7 @@ def values(except: [])
elsif params.dig(param_key, config.key).is_a? Hash
b_bound = params.dig(param_key, config.key, :begin).presence
e_bound = params.dig(param_key, config.key, :end).presence
Range.new(b_bound&.to_i, e_bound&.to_i) if b_bound && e_bound
Range.new(b_bound&.to_i, e_bound&.to_i) if b_bound || e_bound
end

f = except.include?(:filters) ? [] : [range].compact
Expand Down
41 changes: 39 additions & 2 deletions lib/blacklight_range_limit/range_limit_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,17 @@ def add_range_limit_params(solr_params)
next unless range_config[:chart_js] || range_config[:textual_facets]

selected_value = search_state.filter(config.key).values.first
range = (selected_value if selected_value.is_a? Range) || range_config[:assumed_boundaries]

add_range_segments_to_solr!(solr_params, field_key, range.first, range.last) if range.present?
range = if selected_value.is_a? Range
selected_value
elsif range_config[:assumed_boundaries]
Range.new(*range_config[:assumed_boundaries])
else
nil
end

# If we have both ends of a range
add_range_segments_to_solr!(solr_params, field_key, range.begin, range.end) if range && range.count != Float::INFINITY
end

solr_params
Expand Down Expand Up @@ -61,5 +69,34 @@ def fetch_specific_range_limit(solr_params)
return solr_params
end

# hacky polyfill for new Blacklight behavior we need, if we don't have it yet
#
# https://github.com/projectblacklight/blacklight/pull/3213
# https://github.com/projectblacklight/blacklight/pull/3443
bl_version = Gem.loaded_specs["blacklight"]&.version
if bl_version && (bl_version <= Gem::Version.new("8.6.1"))
def facet_value_to_fq_string(facet_field, value, use_local_params: true)
facet_config = blacklight_config.facet_fields[facet_field]

# if it's an one-end range, and condition from original that would use query instead isn't met
if value.is_a?(Range) && (value.count == Float::INFINITY) && !facet_config&.query
# Adapted from
# https://github.com/projectblacklight/blacklight/blob/1494bd0884efe7a48623e9b37abe558fa6348e2a/lib/blacklight/solr/search_builder_behavior.rb#L362-L366

solr_field = facet_config.field if facet_config && !facet_config.query
solr_field ||= facet_field

local_params = []
local_params << "tag=#{facet_config.tag}" if use_local_params && facet_config && facet_config.tag

prefix = "{!#{local_params.join(' ')}}" unless local_params.empty?

"#{prefix}#{solr_field}:[#{value.begin || "*"} TO #{value.end || "*"}]"
else
super
end
end
end

end
end
44 changes: 44 additions & 0 deletions spec/features/run_through_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,50 @@
end
end

context "open-ended range" do
it "can search" do
visit search_catalog_path

click_button 'Publication Date Sort'

within ".facet-limit.blacklight-pub_date_si" do
find("input#range_pub_date_si_begin").set("")
find("input#range_pub_date_si_end").set(end_range)
click_button "Apply limit"
end

expect(page).to have_css(".applied-filter", text: /Publication Date Sort +to #{end_range}/)
expect(page).not_to have_text("No entries found")
expect(page).to have_css(".document")

within ".facet-limit.blacklight-pub_date_si" do
# expect expandable limits
find("summary", text: "Range List").click
expect(page).to have_css("details ul.facet-values li")
end
end
end

context "submitted with empty boundaries" do
jrochkind marked this conversation as resolved.
Show resolved Hide resolved
it "does not apply filter" do
visit search_catalog_path

click_button 'Publication Date Sort'

within ".facet-limit.blacklight-pub_date_si" do
find("input#range_pub_date_si_begin").set("")
find("input#range_pub_date_si_end").set("")
click_button "Apply limit"
end
expect(page).not_to have_css(".applied-filter")

click_button 'Publication Date Sort'
within ".facet-limit.blacklight-pub_date_si" do
expect(page).not_to have_css(".selected")
end
end
end

context 'when assumed boundaries configured' do
before do
CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config = {
Expand Down
37 changes: 36 additions & 1 deletion spec/presenters/filter_field_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,18 @@
describe '#add' do
it 'adds a new range parameter' do
new_state = filter.add(1999..2099)

expect(new_state.params.dig(:range, 'some_field')).to include begin: 1999, end: 2099
end

it "adds end-less range" do
new_state = filter.add(1999..nil)
expect(new_state.params.dig(:range, 'some_field')).to include begin: 1999, end: nil
end

it "adds begin-less range" do
new_state = filter.add(nil..2099)
expect(new_state.params.dig(:range, 'some_field')).to include begin: nil, end: 2099
end
end

context 'with some existing data' do
Expand All @@ -32,6 +41,12 @@
new_state = filter.add(1999..2099)

expect(new_state.params.dig(:range, 'some_field')).to include begin: 1999, end: 2099

new_state = filter.add(1999..nil)
expect(new_state.params.dig(:range, 'some_field')).to include begin: 1999, end: nil

new_state = filter.add(nil..2099)
expect(new_state.params.dig(:range, 'some_field')).to include begin: nil, end: 2099
end
end

Expand Down Expand Up @@ -66,6 +81,26 @@
end
end

context 'with an end-less range' do
let(:param_values) { { range: { some_field: { begin: '2013', end: '' } } } }

describe '#values' do
it 'converts the parameters to a Range' do
expect(filter.values).to eq [2013..nil]
end
end
end

context 'with an begin-less range' do
let(:param_values) { { range: { some_field: { begin: '', end: '2022' } } } }

describe '#values' do
it 'converts the parameters to a Range' do
expect(filter.values).to eq [nil..2022]
end
end
end

context 'with empty data' do
let(:param_values) { { range: { some_field: { begin: '', end: '' } } } }

Expand Down
Loading