blacklight 9.0.0.beta1 → 9.0.0.beta2
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.
- checksums.yaml +4 -4
- data/.github/matrix.json +47 -0
- data/.github/workflows/build.yml +16 -0
- data/.github/workflows/lint.yml +25 -0
- data/.github/workflows/main.yml +22 -0
- data/.github/workflows/release_7_x_scheduled.yml +39 -0
- data/.github/workflows/release_8_x_scheduled.yml +39 -0
- data/.github/workflows/test.yml +53 -0
- data/.rubocop.yml +70 -2
- data/.rubocop_todo.yml +43 -67
- data/.solr_wrapper.yml +2 -0
- data/VERSION +1 -1
- data/app/assets/builds/blacklight.css +19 -15
- data/app/assets/javascripts/blacklight/blacklight.esm.js +31 -69
- data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +31 -69
- data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
- data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +4 -0
- data/app/assets/stylesheets/blacklight/_facets.scss +2 -2
- data/app/assets/stylesheets/blacklight/_header.scss +4 -0
- data/app/assets/stylesheets/blacklight/_modal.scss +9 -8
- data/app/assets/stylesheets/blacklight/_pagination.scss +1 -3
- data/app/assets/stylesheets/blacklight/_search_history.scss +0 -4
- data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +3 -0
- data/app/components/blacklight/advanced_search_form_component.rb +2 -2
- data/app/components/blacklight/constraints_component.rb +2 -2
- data/app/components/blacklight/document/action_component.rb +1 -3
- data/app/components/blacklight/document/bookmark_component.rb +2 -2
- data/app/components/blacklight/document/more_like_this_component.rb +2 -2
- data/app/components/blacklight/document/page_header_component.rb +2 -2
- data/app/components/blacklight/document/thumbnail_component.html.erb +3 -7
- data/app/components/blacklight/document/thumbnail_component.rb +7 -6
- data/app/components/blacklight/document_component.rb +3 -3
- data/app/components/blacklight/document_title_component.rb +3 -10
- data/app/components/blacklight/facet_field_checkboxes_component.rb +2 -20
- data/app/components/blacklight/facet_field_component.rb +2 -17
- data/app/components/blacklight/facet_field_filter_component.rb +2 -21
- data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +4 -25
- data/app/components/blacklight/facet_field_list_component.rb +2 -32
- data/app/components/blacklight/facet_field_no_layout_component.rb +2 -10
- data/app/components/blacklight/facet_field_pagination_component.html.erb +2 -2
- data/app/components/blacklight/facet_item_component.rb +2 -74
- data/app/components/blacklight/facet_item_pivot_component.rb +1 -1
- data/app/components/blacklight/facets/checkboxes_component.rb +26 -0
- data/app/components/blacklight/facets/count_component.rb +23 -0
- data/app/components/blacklight/{facet_field_component.html.erb → facets/field_component.html.erb} +1 -1
- data/app/components/blacklight/facets/field_component.rb +23 -0
- data/app/components/blacklight/facets/filters_component.html.erb +4 -0
- data/app/components/blacklight/facets/filters_component.rb +27 -0
- data/app/components/blacklight/{facet_field_inclusive_constraint_component.html.erb → facets/inclusive_constraint_component.html.erb} +1 -1
- data/app/components/blacklight/facets/inclusive_constraint_component.rb +31 -0
- data/app/components/blacklight/{facet_field_filter_component.html.erb → facets/index_navigation_component.html.erb} +1 -1
- data/app/components/blacklight/facets/index_navigation_component.rb +32 -0
- data/app/components/blacklight/facets/item_component.rb +73 -0
- data/app/components/blacklight/facets/list_component.html.erb +11 -0
- data/app/components/blacklight/facets/list_component.rb +38 -0
- data/app/components/blacklight/facets/no_layout_component.rb +16 -0
- data/app/components/blacklight/facets/selected_value_component.rb +29 -0
- data/app/components/blacklight/facets/suggest_component.html.erb +12 -0
- data/app/components/blacklight/facets/suggest_component.rb +22 -0
- data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +2 -2
- data/app/components/blacklight/response/facet_group_component.html.erb +1 -1
- data/app/components/blacklight/response/facet_group_component.rb +5 -1
- data/app/components/blacklight/system/dropdown_component.html.erb +1 -1
- data/app/components/blacklight/system/dropdown_component.rb +1 -1
- data/app/components/blacklight/top_navbar_component.html.erb +1 -1
- data/app/controllers/concerns/blacklight/bookmarks.rb +3 -3
- data/app/controllers/concerns/blacklight/catalog.rb +10 -25
- data/app/controllers/concerns/blacklight/controller.rb +1 -1
- data/app/controllers/concerns/blacklight/facetable.rb +34 -0
- data/app/controllers/concerns/blacklight/search_context.rb +1 -1
- data/app/controllers/concerns/blacklight/searchable.rb +1 -1
- data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -2
- data/app/helpers/blacklight/document_helper_behavior.rb +3 -1
- data/app/helpers/blacklight/facets_helper_behavior.rb +9 -0
- data/app/helpers/blacklight/icon_helper_behavior.rb +2 -2
- data/app/javascript/blacklight-frontend/checkbox_submit.js +3 -0
- data/app/javascript/blacklight-frontend/debounce.js +1 -1
- data/app/javascript/blacklight-frontend/facet_suggest.js +23 -3
- data/app/javascript/blacklight-frontend/index.js +0 -2
- data/app/javascript/blacklight-frontend/modal.js +1 -4
- data/app/javascript/blacklight-frontend/search_context.js +3 -2
- data/app/models/facet_search_builder.rb +5 -0
- data/app/presenters/blacklight/facet_field_presenter.rb +1 -1
- data/app/presenters/blacklight/json_presenter.rb +1 -3
- data/app/presenters/blacklight/rendering/helper_method.rb +4 -4
- data/app/presenters/blacklight/rendering/join.rb +2 -2
- data/app/services/blacklight/facet_search_service.rb +44 -0
- data/app/services/blacklight/field_retriever.rb +1 -1
- data/app/services/blacklight/search_service.rb +6 -6
- data/app/values/blacklight/types.rb +2 -2
- data/app/views/catalog/_facet_pivot.html.erb +1 -1
- data/app/views/catalog/_home_text.html.erb +2 -2
- data/app/views/catalog/_sort_and_per_page.html.erb +1 -1
- data/app/views/catalog/facet.html.erb +8 -10
- data/config/locales/blacklight.ar.yml +2 -2
- data/config/locales/blacklight.es.yml +2 -2
- data/config/locales/blacklight.fr.yml +2 -2
- data/config/locales/blacklight.hu.yml +2 -2
- data/config/locales/blacklight.it.yml +2 -2
- data/config/locales/blacklight.nl.yml +1 -1
- data/config/locales/blacklight.pt-BR.yml +2 -2
- data/config/locales/blacklight.sq.yml +2 -2
- data/config/locales/blacklight.zh.yml +2 -2
- data/lib/blacklight/abstract_repository.rb +2 -2
- data/lib/blacklight/abstract_search_builder.rb +154 -0
- data/lib/blacklight/configuration/context.rb +3 -3
- data/lib/blacklight/configuration/facet_field.rb +6 -6
- data/lib/blacklight/configuration/field.rb +4 -4
- data/lib/blacklight/configuration/fields.rb +0 -1
- data/lib/blacklight/configuration/search_field.rb +1 -1
- data/lib/blacklight/configuration/view_config.rb +2 -2
- data/lib/blacklight/configuration.rb +6 -7
- data/lib/blacklight/facet_search_builder.rb +18 -0
- data/lib/blacklight/nested_open_struct_with_hash_access.rb +1 -1
- data/lib/blacklight/open_struct_with_hash_access.rb +2 -2
- data/lib/blacklight/search_builder.rb +1 -159
- data/lib/blacklight/search_state/filter_field.rb +4 -4
- data/lib/blacklight/search_state/pivot_filter_field.rb +4 -4
- data/lib/blacklight/solr/abstract_filter_query_builder.rb +77 -0
- data/lib/blacklight/solr/default_filter_query_builder.rb +20 -0
- data/lib/blacklight/solr/facet_search_builder_behavior.rb +62 -0
- data/lib/blacklight/solr/repository.rb +8 -9
- data/lib/blacklight/solr/response/facets.rb +2 -2
- data/lib/blacklight/solr/response/params.rb +0 -4
- data/lib/blacklight/solr/response.rb +5 -1
- data/lib/blacklight/solr/search_builder_behavior.rb +17 -132
- data/lib/blacklight.rb +1 -1
- data/lib/generators/blacklight/assets/importmap_generator.rb +3 -5
- data/lib/generators/blacklight/assets_generator.rb +1 -1
- data/lib/generators/blacklight/search_builder_generator.rb +1 -1
- data/lib/generators/blacklight/templates/.solr_wrapper.yml +2 -0
- data/lib/generators/blacklight/templates/catalog_controller.rb +3 -1
- data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +0 -4
- data/package.json +3 -3
- data/spec/components/blacklight/advanced_search_form_component_spec.rb +18 -22
- data/spec/components/blacklight/constraint_layout_component_spec.rb +8 -8
- data/spec/components/blacklight/constraints_component_spec.rb +11 -11
- data/spec/components/blacklight/document/action_component_spec.rb +23 -15
- data/spec/components/blacklight/document/group_component_spec.rb +10 -15
- data/spec/components/blacklight/document/page_header_component_spec.rb +35 -28
- data/spec/components/blacklight/document/sidebar_component_spec.rb +5 -11
- data/spec/components/blacklight/document_component_spec.rb +98 -65
- data/spec/components/blacklight/facet_component_spec.rb +12 -8
- data/spec/components/blacklight/facet_item_pivot_component_spec.rb +12 -12
- data/spec/components/blacklight/{facet_field_checkboxes_component_spec.rb → facets/checkboxes_component_spec.rb} +13 -13
- data/spec/components/blacklight/facets/filters_component_spec.rb +36 -0
- data/spec/components/blacklight/facets/index_navigation_component_spec.rb +40 -0
- data/spec/components/blacklight/{facet_item_component_spec.rb → facets/item_component_spec.rb} +10 -10
- data/spec/components/blacklight/{facet_field_list_component_spec.rb → facets/list_component_spec.rb} +23 -23
- data/spec/components/blacklight/facets/suggest_component_spec.rb +68 -0
- data/spec/components/blacklight/header_component_spec.rb +2 -4
- data/spec/components/blacklight/hidden_search_state_component_spec.rb +7 -7
- data/spec/components/blacklight/metadata_field_component_spec.rb +17 -15
- data/spec/components/blacklight/response/facet_group_component_spec.rb +37 -0
- data/spec/components/blacklight/response/pagination_component_spec.rb +1 -1
- data/spec/components/blacklight/response/spellcheck_component_spec.rb +1 -1
- data/spec/components/blacklight/search_bar_component_spec.rb +4 -4
- data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +2 -2
- data/spec/components/blacklight/search_context/server_item_pagination_component_spec.rb +3 -5
- data/spec/components/blacklight/skip_link_component_spec.rb +8 -11
- data/spec/components/blacklight/start_over_button_component_spec.rb +4 -4
- data/spec/components/blacklight/system/dropdown_component_spec.rb +26 -0
- data/spec/components/blacklight/system/flash_message_component_spec.rb +7 -11
- data/spec/controllers/catalog_controller_spec.rb +12 -20
- data/spec/features/facets_spec.rb +70 -7
- data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +10 -0
- data/spec/lib/blacklight/configuration/facet_field_spec.rb +2 -2
- data/spec/lib/blacklight/parameters_spec.rb +12 -1
- data/spec/lib/blacklight/search_state/filter_field_spec.rb +18 -0
- data/spec/models/blacklight/configuration_spec.rb +32 -28
- data/spec/models/blacklight/facet_search_builder_spec.rb +19 -0
- data/spec/models/blacklight/search_builder_spec.rb +1 -11
- data/spec/models/blacklight/solr/default_filter_query_builder_spec.rb +72 -0
- data/spec/models/blacklight/solr/document_spec.rb +0 -4
- data/spec/models/blacklight/solr/facet_search_builder_behavior_spec.rb +929 -0
- data/spec/models/blacklight/solr/repository_spec.rb +31 -29
- data/spec/models/blacklight/solr/response/facets_spec.rb +86 -40
- data/spec/models/blacklight/solr/response/group_response_spec.rb +8 -5
- data/spec/models/blacklight/solr/response/group_spec.rb +9 -5
- data/spec/models/blacklight/solr/response_spec.rb +96 -64
- data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +2 -227
- data/spec/models/solr_document_spec.rb +5 -1
- data/spec/services/blacklight/search_service_spec.rb +6 -27
- data/spec/spec_helper.rb +0 -1
- data/spec/support/view_component_test_helpers.rb +0 -18
- data/spec/views/catalog/facet.html.erb_spec.rb +10 -3
- data/spec/views/catalog/index.atom.builder_spec.rb +6 -3
- data/spec/views/catalog/index.html.erb_spec.rb +3 -1
- metadata +58 -29
- data/.github/workflows/ruby.yml +0 -98
- data/app/components/blacklight/facet_field_list_component.html.erb +0 -19
- data/app/components/blacklight/search/facet_suggest_input.html.erb +0 -9
- data/app/components/blacklight/search/facet_suggest_input.rb +0 -16
- data/app/javascript/blacklight-frontend/modalForm.js +0 -60
- data/app/views/catalog/_facet_index_navigation.html.erb +0 -1
- data/app/views/catalog/_facet_layout.html.erb +0 -8
- data/app/views/catalog/_facet_pagination.html.erb +0 -1
- data/spec/components/blacklight/document_metadata_component_spec.rb +0 -0
- data/spec/components/blacklight/search/facet_suggest_input_spec.rb +0 -33
- data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +0 -43
- data/spec/views/catalog/_facet_layout.html.erb_spec.rb +0 -41
- /data/app/components/blacklight/{facet_field_checkboxes_component.html.erb → facets/checkboxes_component.html.erb} +0 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight::Solr
|
4
|
+
class AbstractFilterQueryBuilder
|
5
|
+
def initialize(blacklight_config:)
|
6
|
+
@blacklight_config = blacklight_config
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :blacklight_config
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def facet_inclusive_value_to_fq_string(facet_field, values)
|
14
|
+
return if values.blank?
|
15
|
+
|
16
|
+
return facet_value_to_fq_string(facet_field, values.first) if values.length == 1
|
17
|
+
|
18
|
+
facet_config = blacklight_config.facet_fields[facet_field]
|
19
|
+
|
20
|
+
local_params = []
|
21
|
+
local_params << "tag=#{facet_config.tag}" if facet_config&.tag
|
22
|
+
|
23
|
+
solr_filters = values.each_with_object({}).with_index do |(v, h), index|
|
24
|
+
h["f_inclusive.#{facet_field}.#{index}"] = facet_value_to_fq_string(facet_field, v, use_local_params: false)
|
25
|
+
end
|
26
|
+
|
27
|
+
filter_query = solr_filters.keys.map do |k|
|
28
|
+
"{!query v=$#{k}}"
|
29
|
+
end.join(' OR ')
|
30
|
+
|
31
|
+
["{!lucene#{" #{local_params.join(' ')}" unless local_params.empty?}}#{filter_query}", solr_filters]
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Convert a facet/value pair into a solr fq parameter
|
36
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
37
|
+
def facet_value_to_fq_string(facet_field, value, use_local_params: true)
|
38
|
+
facet_config = blacklight_config.facet_fields[facet_field]
|
39
|
+
|
40
|
+
solr_field = facet_config.field if facet_config && !facet_config.query
|
41
|
+
solr_field ||= facet_field
|
42
|
+
|
43
|
+
local_params = []
|
44
|
+
local_params << "tag=#{facet_config.tag}" if use_local_params && facet_config&.tag
|
45
|
+
|
46
|
+
if facet_config&.query
|
47
|
+
if facet_config.query[value]
|
48
|
+
facet_config.query[value][:fq]
|
49
|
+
else
|
50
|
+
# exclude all documents if the custom facet key specified was not found
|
51
|
+
'-*:*'
|
52
|
+
end
|
53
|
+
elsif value.is_a?(Range)
|
54
|
+
prefix = "{!#{local_params.join(' ')}}" unless local_params.empty?
|
55
|
+
start = value.begin || '*'
|
56
|
+
finish = value.end || '*'
|
57
|
+
"#{prefix}#{solr_field}:[#{start} TO #{finish}]"
|
58
|
+
elsif value == Blacklight::SearchState::FilterField::MISSING
|
59
|
+
"-#{solr_field}:[* TO *]"
|
60
|
+
else
|
61
|
+
"{!term f=#{solr_field}#{" #{local_params.join(' ')}" unless local_params.empty?}}#{convert_to_term_value(value)}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
65
|
+
|
66
|
+
def convert_to_term_value(value)
|
67
|
+
case value
|
68
|
+
when DateTime, Time
|
69
|
+
value.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
70
|
+
when Date
|
71
|
+
value.to_time(:local).strftime("%Y-%m-%dT%H:%M:%SZ")
|
72
|
+
else
|
73
|
+
value.to_s
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight::Solr
|
4
|
+
class DefaultFilterQueryBuilder < AbstractFilterQueryBuilder
|
5
|
+
def call(filter, _solr_parameters)
|
6
|
+
filter_queries = []
|
7
|
+
all_subqueries = {}
|
8
|
+
filter.values.compact_blank.each do |value|
|
9
|
+
filter_query, subqueries = if value.is_a?(Array)
|
10
|
+
facet_inclusive_value_to_fq_string(filter.key, value.compact_blank)
|
11
|
+
else
|
12
|
+
facet_value_to_fq_string(filter.config.key, value)
|
13
|
+
end
|
14
|
+
filter_queries << filter_query
|
15
|
+
all_subqueries.merge!(subqueries) if subqueries
|
16
|
+
end
|
17
|
+
[filter_queries, all_subqueries]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight::Solr
|
4
|
+
module FacetSearchBuilderBehavior
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
include Blacklight::Solr::SearchBuilderBehavior
|
9
|
+
self.default_processor_chain = [:default_solr_parameters,
|
10
|
+
:add_search_field_default_parameters,
|
11
|
+
:add_query_to_solr,
|
12
|
+
:add_facet_fq_to_solr,
|
13
|
+
:add_facetting_to_solr,
|
14
|
+
:add_solr_fields_to_query,
|
15
|
+
:add_additional_filters,
|
16
|
+
:add_facet_paging_to_solr,
|
17
|
+
:add_facet_suggestion_parameters]
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_facet_paging_to_solr(solr_params)
|
21
|
+
return if facet.blank?
|
22
|
+
|
23
|
+
facet_config = blacklight_config.facet_fields[facet]
|
24
|
+
|
25
|
+
solr_params[:rows] = 0
|
26
|
+
|
27
|
+
limit = if solr_params["facet.limit"]
|
28
|
+
solr_params["facet.limit"].to_i
|
29
|
+
else
|
30
|
+
facet_config.fetch(:more_limit, blacklight_config.default_more_limit)
|
31
|
+
end
|
32
|
+
|
33
|
+
page = search_state.facet_page
|
34
|
+
sort = search_state.facet_sort
|
35
|
+
prefix = search_state.facet_prefix
|
36
|
+
offset = (page - 1) * limit
|
37
|
+
|
38
|
+
if facet_config.json
|
39
|
+
add_solr_facet_json_params(solr_parameters, facet, facet_config, limit: limit + 1, offset: offset, sort: sort, prefix: prefix)
|
40
|
+
return
|
41
|
+
end
|
42
|
+
|
43
|
+
# Now override with our specific things for fetching facet values
|
44
|
+
facet_ex = facet_config.respond_to?(:ex) ? facet_config.ex : nil
|
45
|
+
solr_params[:'facet.field'] = with_ex_local_param(facet_ex, facet_config.field)
|
46
|
+
|
47
|
+
# Need to set as f.facet_field.facet.* to make sure we
|
48
|
+
# override any field-specific default in the solr request handler.
|
49
|
+
solr_params[:"f.#{facet_config.field}.facet.limit"] = limit + 1
|
50
|
+
solr_params[:"f.#{facet_config.field}.facet.offset"] = offset
|
51
|
+
solr_params[:"f.#{facet_config.field}.facet.sort"] = sort if sort
|
52
|
+
solr_params[:"f.#{facet_config.field}.facet.prefix"] = prefix if prefix
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_facet_suggestion_parameters(solr_params)
|
56
|
+
return if facet.blank? || facet_suggestion_query.blank?
|
57
|
+
|
58
|
+
solr_params[:'facet.contains'] = facet_suggestion_query[0..50]
|
59
|
+
solr_params[:'facet.contains.ignoreCase'] = true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -8,7 +8,6 @@ module Blacklight::Solr
|
|
8
8
|
# @param [Hash] params additional solr query parameters
|
9
9
|
def find id, params = {}
|
10
10
|
doc_params = params.reverse_merge(blacklight_config.default_document_solr_params)
|
11
|
-
.reverse_merge(qt: blacklight_config.document_solr_request_handler)
|
12
11
|
.merge(blacklight_config.document_unique_id_param => id)
|
13
12
|
|
14
13
|
solr_response = send_and_receive blacklight_config.document_solr_path || blacklight_config.solr_path, doc_params
|
@@ -27,7 +26,11 @@ module Blacklight::Solr
|
|
27
26
|
# Execute a search query against solr
|
28
27
|
# @param [Hash] params solr query parameters
|
29
28
|
# @param [String] path solr request handler path
|
30
|
-
def search pos_params =
|
29
|
+
def search pos_params = nil, path: nil, params: nil, **kwargs
|
30
|
+
if pos_params
|
31
|
+
Blacklight.deprecation.warn("Passing positional arguments to search() is deprecated. Use the params kwarg instead.")
|
32
|
+
end
|
33
|
+
|
31
34
|
request_params = (params || pos_params).reverse_merge(kwargs).reverse_merge({ qt: blacklight_config.qt })
|
32
35
|
|
33
36
|
send_and_receive(path || default_search_path(request_params), request_params)
|
@@ -56,15 +59,11 @@ module Blacklight::Solr
|
|
56
59
|
end
|
57
60
|
|
58
61
|
##
|
59
|
-
# Execute a solr query
|
62
|
+
# Execute a solr query at the given path with the parameters
|
60
63
|
# TODO: Make this private after we have a way to abstract admin/luke and ping
|
61
64
|
# @see [RSolr::Client#send_and_receive]
|
62
|
-
# @
|
63
|
-
#
|
64
|
-
# @param [String] solr path (defaults to blacklight_config.solr_path)
|
65
|
-
# @param [Hash] parameters for RSolr::Client#send_and_receive
|
66
|
-
# @overload find(params)
|
67
|
-
# @param [Hash] parameters for RSolr::Client#send_and_receive
|
65
|
+
# @param [String] path solr path (defaults to blacklight_config.solr_path)
|
66
|
+
# @param [Hash, Blacklight::SearchBuilder] solr_params parameters for RSolr::Client#send_and_receive
|
68
67
|
# @return [Blacklight::Solr::Response] the solr response object
|
69
68
|
def send_and_receive(path, solr_params = {})
|
70
69
|
benchmark("Solr fetch", level: :debug) do
|
@@ -229,7 +229,7 @@ module Blacklight::Solr::Response::Facets
|
|
229
229
|
|
230
230
|
blacklight_config.facet_fields.select { |_k, v| v.query }.each_with_object({}) do |(field_name, facet_field), hash|
|
231
231
|
salient_facet_queries = facet_field.query.map { |_k, x| x[:fq] }
|
232
|
-
items = facet_queries.
|
232
|
+
items = facet_queries.slice(*salient_facet_queries).reject { |_value, hits| hits.zero? }.map do |value, hits|
|
233
233
|
salient_fields = facet_field.query.select { |_key, val| val[:fq] == value }
|
234
234
|
key = ((salient_fields.keys if salient_fields.respond_to? :keys) || salient_fields.first).first
|
235
235
|
Blacklight::Solr::Response::Facets::FacetItem.new(value: key, hits: hits, label: facet_field.query[key][:label])
|
@@ -250,7 +250,7 @@ module Blacklight::Solr::Response::Facets
|
|
250
250
|
|
251
251
|
salient_facet_queries = facet_field.query.map { |_k, x| x[:fq] }
|
252
252
|
|
253
|
-
relevant_facet_data = self['facets'].
|
253
|
+
relevant_facet_data = self['facets'].slice(*salient_facet_queries).reject { |_key, data| data['count'].zero? }
|
254
254
|
|
255
255
|
relevant_facet_data.map do |key, data|
|
256
256
|
salient_fields = facet_field.query.select { |_key, val| val[:fq] == key }
|
@@ -52,10 +52,6 @@ module Blacklight::Solr::Response::Params
|
|
52
52
|
|
53
53
|
private
|
54
54
|
|
55
|
-
def search_builder
|
56
|
-
request_params if request_params.is_a?(Blacklight::SearchBuilder)
|
57
|
-
end
|
58
|
-
|
59
55
|
# Extract JSON Request API parameters from the response header or the request itself
|
60
56
|
def json_params
|
61
57
|
encoded_json_params = header&.dig('params', 'json')
|
@@ -8,12 +8,16 @@ class Blacklight::Solr::Response < ActiveSupport::HashWithIndifferentAccess
|
|
8
8
|
include MoreLikeThis
|
9
9
|
include Params
|
10
10
|
|
11
|
-
attr_reader :request_params
|
11
|
+
attr_reader :request_params, :search_builder
|
12
12
|
attr_accessor :blacklight_config, :options
|
13
13
|
|
14
14
|
delegate :document_factory, to: :blacklight_config
|
15
15
|
|
16
|
+
# @param [Hash] data
|
17
|
+
# @param [Hash, Blacklight::SearchBuilder] request_params a SearchBuilder or a Hash of parameters
|
16
18
|
def initialize(data, request_params, options = {})
|
19
|
+
@search_builder = request_params if request_params.is_a?(Blacklight::SearchBuilder)
|
20
|
+
|
17
21
|
super(force_to_utf8(ActiveSupport::HashWithIndifferentAccess.new(data)))
|
18
22
|
@request_params = ActiveSupport::HashWithIndifferentAccess.new(request_params)
|
19
23
|
self.blacklight_config = options[:blacklight_config]
|
@@ -10,7 +10,6 @@ module Blacklight::Solr
|
|
10
10
|
:add_query_to_solr, :add_facet_fq_to_solr,
|
11
11
|
:add_facetting_to_solr, :add_solr_fields_to_query, :add_paging_to_solr,
|
12
12
|
:add_sorting_to_solr, :add_group_config_to_solr,
|
13
|
-
:add_facet_paging_to_solr, :add_facet_suggestion_parameters,
|
14
13
|
:add_adv_search_clauses,
|
15
14
|
:add_additional_filters
|
16
15
|
]
|
@@ -128,25 +127,19 @@ module Blacklight::Solr
|
|
128
127
|
end
|
129
128
|
|
130
129
|
search_state.filters.each do |filter|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
solr_parameters.append_filter_query(fq)
|
136
|
-
end
|
137
|
-
solr_parameters.merge!(subqueries) if subqueries
|
130
|
+
filter_query_builder_class_or_proc = filter.config.filter_query_builder || DefaultFilterQueryBuilder
|
131
|
+
if filter_query_builder_class_or_proc.is_a?(Class)
|
132
|
+
filter_query_builder = filter_query_builder_class_or_proc.new(blacklight_config: blacklight_config)
|
133
|
+
filter_query, subqueries = filter_query_builder.call(filter, solr_parameters)
|
138
134
|
else
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
solr_parameters.append_filter_query filter_query
|
147
|
-
solr_parameters.merge!(subqueries) if subqueries
|
148
|
-
end
|
135
|
+
# TODO: Maybe deprecate proc?
|
136
|
+
filter_query, subqueries = filter_query_builder_class_or_proc.call(self, filter, solr_parameters)
|
137
|
+
end
|
138
|
+
|
139
|
+
Array(filter_query).each do |fq|
|
140
|
+
solr_parameters.append_filter_query(fq)
|
149
141
|
end
|
142
|
+
solr_parameters.merge!(subqueries) if subqueries
|
150
143
|
end
|
151
144
|
end
|
152
145
|
|
@@ -190,10 +183,8 @@ module Blacklight::Solr
|
|
190
183
|
solr_parameters[:"f.#{facet.field}.facet.sort"] = facet.sort
|
191
184
|
end
|
192
185
|
|
193
|
-
|
194
|
-
facet.
|
195
|
-
solr_parameters[:"f.#{facet.field}.#{k}"] = v
|
196
|
-
end
|
186
|
+
facet.solr_params&.each do |k, v|
|
187
|
+
solr_parameters[:"f.#{facet.field}.#{k}"] = v
|
197
188
|
end
|
198
189
|
|
199
190
|
limit = facet_limit_with_pagination(field_name)
|
@@ -203,9 +194,9 @@ module Blacklight::Solr
|
|
203
194
|
|
204
195
|
def add_solr_fields_to_query solr_parameters
|
205
196
|
blacklight_config.show_fields.select(&method(:should_add_field_to_request?)).each_value do |field|
|
206
|
-
field.solr_params
|
197
|
+
field.solr_params&.each do |k, v|
|
207
198
|
solr_parameters[:"f.#{field.field}.#{k}"] = v
|
208
|
-
end
|
199
|
+
end
|
209
200
|
end
|
210
201
|
|
211
202
|
blacklight_config.index_fields.select(&method(:should_add_field_to_request?)).each_value do |field|
|
@@ -214,9 +205,9 @@ module Blacklight::Solr
|
|
214
205
|
solr_parameters.append_highlight_field field.field
|
215
206
|
end
|
216
207
|
|
217
|
-
field.solr_params
|
208
|
+
field.solr_params&.each do |k, v|
|
218
209
|
solr_parameters[:"f.#{field.field}.#{k}"] = v
|
219
|
-
end
|
210
|
+
end
|
220
211
|
end
|
221
212
|
end
|
222
213
|
|
@@ -242,48 +233,6 @@ module Blacklight::Solr
|
|
242
233
|
solr_parameters[:group] = false if search_state.filter(grouped_key_for_results).any?
|
243
234
|
end
|
244
235
|
|
245
|
-
def add_facet_paging_to_solr(solr_params)
|
246
|
-
return if facet.blank?
|
247
|
-
|
248
|
-
facet_config = blacklight_config.facet_fields[facet]
|
249
|
-
|
250
|
-
solr_params[:rows] = 0
|
251
|
-
|
252
|
-
limit = if solr_params["facet.limit"]
|
253
|
-
solr_params["facet.limit"].to_i
|
254
|
-
else
|
255
|
-
facet_config.fetch(:more_limit, blacklight_config.default_more_limit)
|
256
|
-
end
|
257
|
-
|
258
|
-
page = search_state.facet_page
|
259
|
-
sort = search_state.facet_sort
|
260
|
-
prefix = search_state.facet_prefix
|
261
|
-
offset = (page - 1) * limit
|
262
|
-
|
263
|
-
if facet_config.json
|
264
|
-
add_solr_facet_json_params(solr_parameters, facet, facet_config, limit: limit + 1, offset: offset, sort: sort, prefix: prefix)
|
265
|
-
return
|
266
|
-
end
|
267
|
-
|
268
|
-
# Now override with our specific things for fetching facet values
|
269
|
-
facet_ex = facet_config.respond_to?(:ex) ? facet_config.ex : nil
|
270
|
-
solr_params[:'facet.field'] = with_ex_local_param(facet_ex, facet_config.field)
|
271
|
-
|
272
|
-
# Need to set as f.facet_field.facet.* to make sure we
|
273
|
-
# override any field-specific default in the solr request handler.
|
274
|
-
solr_params[:"f.#{facet_config.field}.facet.limit"] = limit + 1
|
275
|
-
solr_params[:"f.#{facet_config.field}.facet.offset"] = offset
|
276
|
-
solr_params[:"f.#{facet_config.field}.facet.sort"] = sort if sort
|
277
|
-
solr_params[:"f.#{facet_config.field}.facet.prefix"] = prefix if prefix
|
278
|
-
end
|
279
|
-
|
280
|
-
def add_facet_suggestion_parameters(solr_params)
|
281
|
-
return if facet.blank? || facet_suggestion_query.blank?
|
282
|
-
|
283
|
-
solr_params[:'facet.contains'] = facet_suggestion_query[0..50]
|
284
|
-
solr_params[:'facet.contains.ignoreCase'] = true
|
285
|
-
end
|
286
|
-
|
287
236
|
def with_ex_local_param(ex, value)
|
288
237
|
if ex
|
289
238
|
"{!ex=#{ex}}#{value}"
|
@@ -340,70 +289,6 @@ module Blacklight::Solr
|
|
340
289
|
|
341
290
|
private
|
342
291
|
|
343
|
-
##
|
344
|
-
# Convert a facet/value pair into a solr fq parameter
|
345
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
346
|
-
def facet_value_to_fq_string(facet_field, value, use_local_params: true)
|
347
|
-
facet_config = blacklight_config.facet_fields[facet_field]
|
348
|
-
|
349
|
-
solr_field = facet_config.field if facet_config && !facet_config.query
|
350
|
-
solr_field ||= facet_field
|
351
|
-
|
352
|
-
local_params = []
|
353
|
-
local_params << "tag=#{facet_config.tag}" if use_local_params && facet_config && facet_config.tag
|
354
|
-
|
355
|
-
if facet_config && facet_config.query
|
356
|
-
if facet_config.query[value]
|
357
|
-
facet_config.query[value][:fq]
|
358
|
-
else
|
359
|
-
# exclude all documents if the custom facet key specified was not found
|
360
|
-
'-*:*'
|
361
|
-
end
|
362
|
-
elsif value.is_a?(Range)
|
363
|
-
prefix = "{!#{local_params.join(' ')}}" unless local_params.empty?
|
364
|
-
start = value.begin || '*'
|
365
|
-
finish = value.end || '*'
|
366
|
-
"#{prefix}#{solr_field}:[#{start} TO #{finish}]"
|
367
|
-
elsif value == Blacklight::SearchState::FilterField::MISSING
|
368
|
-
"-#{solr_field}:[* TO *]"
|
369
|
-
else
|
370
|
-
"{!term f=#{solr_field}#{" #{local_params.join(' ')}" unless local_params.empty?}}#{convert_to_term_value(value)}"
|
371
|
-
end
|
372
|
-
end
|
373
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
374
|
-
|
375
|
-
def facet_inclusive_value_to_fq_string(facet_field, values)
|
376
|
-
return if values.blank?
|
377
|
-
|
378
|
-
return facet_value_to_fq_string(facet_field, values.first) if values.length == 1
|
379
|
-
|
380
|
-
facet_config = blacklight_config.facet_fields[facet_field]
|
381
|
-
|
382
|
-
local_params = []
|
383
|
-
local_params << "tag=#{facet_config.tag}" if facet_config && facet_config.tag
|
384
|
-
|
385
|
-
solr_filters = values.each_with_object({}).with_index do |(v, h), index|
|
386
|
-
h["f_inclusive.#{facet_field}.#{index}"] = facet_value_to_fq_string(facet_field, v, use_local_params: false)
|
387
|
-
end
|
388
|
-
|
389
|
-
filter_query = solr_filters.keys.map do |k|
|
390
|
-
"{!query v=$#{k}}"
|
391
|
-
end.join(' OR ')
|
392
|
-
|
393
|
-
["{!lucene#{" #{local_params.join(' ')}" unless local_params.empty?}}#{filter_query}", solr_filters]
|
394
|
-
end
|
395
|
-
|
396
|
-
def convert_to_term_value(value)
|
397
|
-
case value
|
398
|
-
when DateTime, Time
|
399
|
-
value.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
400
|
-
when Date
|
401
|
-
value.to_time(:local).strftime("%Y-%m-%dT%H:%M:%SZ")
|
402
|
-
else
|
403
|
-
value.to_s
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
292
|
##
|
408
293
|
# The key to use to retrieve the grouped field to display
|
409
294
|
def grouped_key_for_results
|
data/lib/blacklight.rb
CHANGED
@@ -10,7 +10,7 @@ module Blacklight
|
|
10
10
|
<<~CONTENT
|
11
11
|
pin "@github/auto-complete-element", to: "https://cdn.skypack.dev/@github/auto-complete-element"
|
12
12
|
pin "@popperjs/core", to: "https://ga.jspm.io/npm:@popperjs/core@2.11.6/dist/umd/popper.min.js"
|
13
|
-
pin "bootstrap", to: "https://ga.jspm.io/npm:bootstrap@#{(defined?(Bootstrap) && Bootstrap::VERSION) || '5.3.
|
13
|
+
pin "bootstrap", to: "https://ga.jspm.io/npm:bootstrap@#{(defined?(Bootstrap) && Bootstrap::VERSION) || '5.3.5'}/dist/js/bootstrap.js"
|
14
14
|
CONTENT
|
15
15
|
end
|
16
16
|
|
@@ -49,10 +49,8 @@ module Blacklight
|
|
49
49
|
else
|
50
50
|
append_to_file 'app/assets/stylesheets/application.css' do
|
51
51
|
<<~CONTENT
|
52
|
-
|
53
|
-
|
54
|
-
*/
|
55
|
-
@import url(https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css);
|
52
|
+
@import url(https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/css/bootstrap.min.css);
|
53
|
+
@import url("blacklight.css");
|
56
54
|
CONTENT
|
57
55
|
end
|
58
56
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Blacklight
|
4
4
|
class AssetsGenerator < Rails::Generators::Base
|
5
|
-
class_option :'bootstrap-version', type: :string, default: ENV.fetch('BOOTSTRAP_VERSION', '5.3.
|
5
|
+
class_option :'bootstrap-version', type: :string, default: ENV.fetch('BOOTSTRAP_VERSION', '5.3.5'), desc: "Set the generated app's bootstrap version"
|
6
6
|
|
7
7
|
def run_asset_pipeline_specific_generator
|
8
8
|
generated_options = "--bootstrap-version='#{options[:'bootstrap-version']}'" if options[:'bootstrap-version']
|
@@ -105,9 +105,11 @@ class <%= controller_name.classify %>Controller < ApplicationController
|
|
105
105
|
# :show may be set to false if you don't want the facet to be drawn in the
|
106
106
|
# facet bar
|
107
107
|
#
|
108
|
-
#
|
108
|
+
# Set :index_range to true if you want the facet pagination view to have facet prefix-based navigation.
|
109
109
|
# (useful when user clicks "more" on a large facet and wants to navigate alphabetically across a large set of results)
|
110
110
|
# :index_range can be an array or range of prefixes that will be used to create the navigation (note: It is case sensitive when searching values)
|
111
|
+
# This control only displays when the user has selected "A-Z Sort" (You make make this the default by setting "sort: 'index'"
|
112
|
+
# in the facet config)
|
111
113
|
|
112
114
|
config.add_facet_field 'format', label: 'Format'
|
113
115
|
config.add_facet_field 'pub_date_ssim', label: 'Publication Year', single: true
|
@@ -47,7 +47,6 @@
|
|
47
47
|
full_title_tsim
|
48
48
|
short_title_tsim
|
49
49
|
alternative_title_tsim
|
50
|
-
active_fedora_model_ssi
|
51
50
|
title_tsim
|
52
51
|
author_tsim
|
53
52
|
subject_tsim
|
@@ -84,7 +83,6 @@
|
|
84
83
|
<str name="facet">true</str>
|
85
84
|
<str name="facet.mincount">1</str>
|
86
85
|
<str name="facet.limit">10</str>
|
87
|
-
<str name="facet.field">active_fedora_model_ssi</str>
|
88
86
|
<str name="facet.field">subject_ssim</str>
|
89
87
|
|
90
88
|
<str name="spellcheck">true</str>
|
@@ -116,7 +114,6 @@
|
|
116
114
|
full_title_tsim
|
117
115
|
short_title_tsim
|
118
116
|
alternative_title_tsim
|
119
|
-
active_fedora_model_ssi
|
120
117
|
title_tsim
|
121
118
|
author_tsim
|
122
119
|
subject_tsim
|
@@ -153,7 +150,6 @@
|
|
153
150
|
<str name="facet">true</str>
|
154
151
|
<str name="facet.mincount">1</str>
|
155
152
|
<str name="facet.limit">10</str>
|
156
|
-
<str name="facet.field">active_fedora_model_ssi</str>
|
157
153
|
<str name="facet.field">subject_ssim</str>
|
158
154
|
|
159
155
|
<str name="spellcheck">true</str>
|
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "blacklight-frontend",
|
3
|
-
"version": "9.0.0-
|
3
|
+
"version": "9.0.0-beta2",
|
4
4
|
"description": "The frontend code and styles for Blacklight",
|
5
5
|
"exports": {
|
6
6
|
"./blacklight.esm.js": "./app/assets/javascripts/blacklight/blacklight.esm.js",
|
@@ -34,13 +34,13 @@
|
|
34
34
|
"rollup": "^4.24.0",
|
35
35
|
"rollup-plugin-includepaths": "^0.2.4",
|
36
36
|
"sass": "^1.80.3",
|
37
|
-
"bootstrap": "^5.3.
|
37
|
+
"bootstrap": "^5.3.5"
|
38
38
|
},
|
39
39
|
"browserslist": [
|
40
40
|
"defaults",
|
41
41
|
"not IE 11"
|
42
42
|
],
|
43
43
|
"dependencies": {
|
44
|
-
"bootstrap": ">=
|
44
|
+
"bootstrap": ">=5.3.5 <6.0.0"
|
45
45
|
}
|
46
46
|
}
|
@@ -3,49 +3,45 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Blacklight::AdvancedSearchFormComponent, type: :component do
|
6
|
-
subject(:render) do
|
7
|
-
component.render_in(view_context)
|
8
|
-
end
|
9
|
-
|
10
6
|
let(:component) { described_class.new(url: '/whatever', response: response, params: params) }
|
11
|
-
let(:response) { Blacklight::Solr::Response.new({ facet_counts: { facet_fields: { format: { 'Book' => 10, 'CD' => 5 } } } }.with_indifferent_access,
|
12
|
-
let(:
|
13
|
-
|
14
|
-
let(:rendered) do
|
15
|
-
Capybara::Node::Simple.new(render)
|
7
|
+
let(:response) { Blacklight::Solr::Response.new({ facet_counts: { facet_fields: { format: { 'Book' => 10, 'CD' => 5 } } } }.with_indifferent_access, search_builder) }
|
8
|
+
let(:search_builder) do
|
9
|
+
Blacklight::SearchBuilder.new(view_context)
|
16
10
|
end
|
11
|
+
let(:params) { {} }
|
17
12
|
|
18
|
-
let(:view_context) {
|
13
|
+
let(:view_context) { vc_test_controller.view_context }
|
19
14
|
|
20
15
|
before do
|
21
16
|
allow(view_context).to receive(:facet_limit_for).and_return(nil)
|
17
|
+
render_inline component
|
22
18
|
end
|
23
19
|
|
24
20
|
context 'with additional parameters' do
|
25
21
|
let(:params) { { some: :parameter, an_array: [1, 2] } }
|
26
22
|
|
27
23
|
it 'adds additional parameters as hidden fields' do
|
28
|
-
expect(
|
29
|
-
expect(
|
30
|
-
expect(
|
24
|
+
expect(page).to have_field 'some', with: 'parameter', type: :hidden
|
25
|
+
expect(page).to have_field 'an_array[]', with: '1', type: :hidden
|
26
|
+
expect(page).to have_field 'an_array[]', with: '2', type: :hidden
|
31
27
|
end
|
32
28
|
end
|
33
29
|
|
34
30
|
it 'has text fields for each search field' do
|
35
|
-
expect(
|
36
|
-
expect(
|
37
|
-
expect(
|
38
|
-
expect(
|
39
|
-
expect(
|
31
|
+
expect(page).to have_css '.advanced-search-field', count: 4
|
32
|
+
expect(page).to have_field 'clause_0_field', with: 'all_fields', type: :hidden
|
33
|
+
expect(page).to have_field 'clause_1_field', with: 'title', type: :hidden
|
34
|
+
expect(page).to have_field 'clause_2_field', with: 'author', type: :hidden
|
35
|
+
expect(page).to have_field 'clause_3_field', with: 'subject', type: :hidden
|
40
36
|
end
|
41
37
|
|
42
38
|
it 'has filters' do
|
43
|
-
expect(
|
44
|
-
expect(
|
45
|
-
expect(
|
39
|
+
expect(page).to have_css '.blacklight-format'
|
40
|
+
expect(page).to have_field 'f_inclusive[format][]', with: 'Book'
|
41
|
+
expect(page).to have_field 'f_inclusive[format][]', with: 'CD'
|
46
42
|
end
|
47
43
|
|
48
44
|
it 'has a sort field' do
|
49
|
-
expect(
|
45
|
+
expect(page).to have_select 'sort', options: %w[relevance year author title]
|
50
46
|
end
|
51
47
|
end
|