blacklight 7.27.0 → 7.29.0
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/workflows/ruby.yml +6 -6
- data/VERSION +1 -1
- data/app/assets/stylesheets/blacklight/_group.scss +2 -2
- data/app/components/blacklight/advanced_search_form_component.rb +1 -1
- data/app/components/blacklight/facet_component.rb +5 -6
- data/app/components/blacklight/search_context_component.html.erb +2 -2
- data/app/components/blacklight/search_context_component.rb +4 -4
- data/app/controllers/concerns/blacklight/catalog.rb +1 -0
- data/app/helpers/blacklight/url_helper_behavior.rb +4 -4
- data/app/models/search.rb +2 -1
- data/app/services/blacklight/search_params_yaml_coder.rb +48 -0
- data/app/views/catalog/_advanced_search_help.html.erb +1 -1
- data/app/views/catalog/index.json.jbuilder +10 -8
- data/lib/blacklight/engine.rb +2 -0
- data/lib/blacklight/search_builder.rb +1 -1
- data/spec/components/blacklight/facet_component_spec.rb +19 -0
- data/spec/models/search_spec.rb +33 -14
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 752a397403b186b177e51a6f260f7f385d9e1db6c26abdb9b37c9c25ecf2ad04
|
4
|
+
data.tar.gz: f81dc90a28f7c9d9cecc35f60e119bd09ec96bd12584b8f1ffb39e51845a0588
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54c453918cd5521dd2ee24df0d7d874c48705d14422f8746a10bd262681e411ed54efef1202f9785beec20169ca5ca9acd4d648e730df8a930d2aa659190d905
|
7
|
+
data.tar.gz: 8014988552c75ebb9bbbd82dcad688dfcd3ea2b6126b63c4c178ab32fe034787bdd61b75a826ecdb1c9022e148a7f9911eb99e7c35090de9361d434756fb85a1
|
data/.github/workflows/ruby.yml
CHANGED
@@ -76,11 +76,11 @@ jobs:
|
|
76
76
|
- name: Install dependencies
|
77
77
|
run: bundle install
|
78
78
|
env:
|
79
|
-
RAILS_VERSION: 6.0.
|
79
|
+
RAILS_VERSION: 6.0.5.1
|
80
80
|
- name: Run tests
|
81
81
|
run: bundle exec rake ci
|
82
82
|
env:
|
83
|
-
RAILS_VERSION: 6.0.
|
83
|
+
RAILS_VERSION: 6.0.5.1
|
84
84
|
ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
|
85
85
|
test_rails5_2:
|
86
86
|
runs-on: ubuntu-latest
|
@@ -96,11 +96,11 @@ jobs:
|
|
96
96
|
- name: Install dependencies
|
97
97
|
run: bundle install
|
98
98
|
env:
|
99
|
-
RAILS_VERSION: 5.2.
|
99
|
+
RAILS_VERSION: 5.2.8.1
|
100
100
|
- name: Run tests
|
101
101
|
run: bundle exec rake ci
|
102
102
|
env:
|
103
|
-
RAILS_VERSION: 5.2.
|
103
|
+
RAILS_VERSION: 5.2.8.1
|
104
104
|
ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
|
105
105
|
|
106
106
|
test_rails6_1:
|
@@ -117,11 +117,11 @@ jobs:
|
|
117
117
|
- name: Install dependencies
|
118
118
|
run: bundle install
|
119
119
|
env:
|
120
|
-
RAILS_VERSION: 6.1.
|
120
|
+
RAILS_VERSION: 6.1.6.1
|
121
121
|
- name: Run tests
|
122
122
|
run: bundle exec rake ci
|
123
123
|
env:
|
124
|
-
RAILS_VERSION: 6.1.
|
124
|
+
RAILS_VERSION: 6.1.6.1
|
125
125
|
ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-keeps --skip-action-cable --skip-test'
|
126
126
|
api_test:
|
127
127
|
runs-on: ubuntu-latest
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
7.
|
1
|
+
7.29.0
|
@@ -43,7 +43,7 @@ module Blacklight
|
|
43
43
|
search_field_control do
|
44
44
|
fields_for('clause[]', i, include_id: false) do |f|
|
45
45
|
content_tag(:div, class: 'form-group advanced-search-field row') do
|
46
|
-
f.label(:query, field.display_label('search'), class: "col-
|
46
|
+
f.label(:query, field.display_label('search'), class: "col-sm-3 col-form-label text-md-right") +
|
47
47
|
content_tag(:div, class: 'col-sm-9') do
|
48
48
|
f.hidden_field(:field, value: field.key) +
|
49
49
|
f.text_field(:query, value: query_for_search_clause(field.key), class: 'form-control')
|
@@ -11,8 +11,8 @@ module Blacklight
|
|
11
11
|
# @param [Blacklight::Solr::Response::Facets::FacetField] display_facet
|
12
12
|
# @param [Blacklight::Configuration] blacklight_config
|
13
13
|
# @param [Boolean] layout
|
14
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
15
|
-
def initialize(display_facet_or_field_config: nil, display_facet: nil, field_config: nil, response: nil, blacklight_config: nil, **component_args)
|
14
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/ParameterLists
|
15
|
+
def initialize(display_facet_or_field_config: nil, display_facet: nil, field_config: nil, response: nil, blacklight_config: nil, component: nil, **component_args)
|
16
16
|
if display_facet_or_field_config.is_a? Blacklight::FacetFieldPresenter
|
17
17
|
@facet_field_presenter = display_facet_or_field_config
|
18
18
|
@field_config = @facet_field_presenter.facet_field
|
@@ -30,9 +30,10 @@ module Blacklight
|
|
30
30
|
raise ArgumentError, 'You must provide one of display_facet or field_config' unless @field_config
|
31
31
|
end
|
32
32
|
|
33
|
+
@component = component || (@field_config.component == true ? Blacklight::FacetFieldListComponent : @field_config.component)
|
33
34
|
@component_args = component_args
|
34
35
|
end
|
35
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
36
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/ParameterLists
|
36
37
|
|
37
38
|
def render?
|
38
39
|
helpers.should_render_field?(@field_config, @display_facet)
|
@@ -41,10 +42,8 @@ module Blacklight
|
|
41
42
|
def call
|
42
43
|
return render_partial if @field_config.partial
|
43
44
|
|
44
|
-
component = @field_config.component == true ? Blacklight::FacetFieldListComponent : @field_config.component
|
45
|
-
|
46
45
|
render(
|
47
|
-
component.new(
|
46
|
+
@component.new(
|
48
47
|
facet_field: @facet_field_presenter || helpers.facet_field_presenter(@field_config, @display_facet),
|
49
48
|
**@component_args
|
50
49
|
)
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<div class='pagination-search-widgets'>
|
2
2
|
|
3
3
|
<div class="page-links">
|
4
|
-
<%= link_to_previous_document
|
4
|
+
<%= link_to_previous_document %> |
|
5
5
|
|
6
6
|
<%= item_page_entry_info %> |
|
7
7
|
|
8
|
-
<%= link_to_next_document
|
8
|
+
<%= link_to_next_document %>
|
9
9
|
</div>
|
10
10
|
</div>
|
@@ -19,15 +19,15 @@ module Blacklight
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def link_to_previous_document(*args)
|
22
|
+
def link_to_previous_document(document = nil, *args, **kwargs)
|
23
23
|
Deprecation.silence(Blacklight::UrlHelperBehavior) do
|
24
|
-
helpers.link_to_previous_document(*args)
|
24
|
+
helpers.link_to_previous_document(document || @search_context[:prev], *args, **kwargs)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def link_to_next_document(*args)
|
28
|
+
def link_to_next_document(document = nil, *args, **kwargs)
|
29
29
|
Deprecation.silence(Blacklight::UrlHelperBehavior) do
|
30
|
-
helpers.link_to_next_document(*args)
|
30
|
+
helpers.link_to_next_document(document || @search_context[:next], *args, **kwargs)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -253,6 +253,7 @@ module Blacklight::Catalog
|
|
253
253
|
# By default, any search action from a Blacklight::Catalog controller
|
254
254
|
# should use the current controller when constructing the route.
|
255
255
|
def search_action_url options = {}
|
256
|
+
options = options.to_h if options.is_a? Blacklight::SearchState
|
256
257
|
url_for(options.reverse_merge(action: 'index'))
|
257
258
|
end
|
258
259
|
|
@@ -52,8 +52,8 @@ module Blacklight::UrlHelperBehavior
|
|
52
52
|
##
|
53
53
|
# Link to the previous document in the current search context
|
54
54
|
# @deprecated
|
55
|
-
def link_to_previous_document(previous_document)
|
56
|
-
link_opts = session_tracking_params(previous_document, search_session['counter'].to_i - 1).merge(class:
|
55
|
+
def link_to_previous_document(previous_document, classes: 'previous', **addl_link_opts)
|
56
|
+
link_opts = session_tracking_params(previous_document, search_session['counter'].to_i - 1).merge(class: classes, rel: 'prev').merge(addl_link_opts)
|
57
57
|
link_to_unless previous_document.nil?, raw(t('views.pagination.previous')), url_for_document(previous_document), link_opts do
|
58
58
|
tag.span raw(t('views.pagination.previous')), class: 'previous'
|
59
59
|
end
|
@@ -63,8 +63,8 @@ module Blacklight::UrlHelperBehavior
|
|
63
63
|
##
|
64
64
|
# Link to the next document in the current search context
|
65
65
|
# @deprecated
|
66
|
-
def link_to_next_document(next_document)
|
67
|
-
link_opts = session_tracking_params(next_document, search_session['counter'].to_i + 1).merge(class:
|
66
|
+
def link_to_next_document(next_document, classes: 'next', **addl_link_opts)
|
67
|
+
link_opts = session_tracking_params(next_document, search_session['counter'].to_i + 1).merge(class: classes, rel: 'next').merge(addl_link_opts)
|
68
68
|
link_to_unless next_document.nil?, raw(t('views.pagination.next')), url_for_document(next_document), link_opts do
|
69
69
|
tag.span raw(t('views.pagination.next')), class: 'next'
|
70
70
|
end
|
data/app/models/search.rb
CHANGED
@@ -3,7 +3,8 @@
|
|
3
3
|
class Search < ApplicationRecord
|
4
4
|
belongs_to :user, optional: true
|
5
5
|
|
6
|
-
|
6
|
+
# use a backwards-compatible serializer until the Rails API stabilizes and we can evaluate for major-revision compatibility
|
7
|
+
serialize :query_params, Blacklight::SearchParamsYamlCoder
|
7
8
|
|
8
9
|
# A Search instance is considered a saved search if it has a user_id.
|
9
10
|
def saved?
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight
|
4
|
+
# This is a custom YAML coder for (de)serializing blacklight search parameters that
|
5
|
+
# supports deserializing HashWithIndifferentAccess parameters (as was historically done by Blacklight).
|
6
|
+
class SearchParamsYamlCoder
|
7
|
+
# Serializes an attribute value to a string that will be stored in the database.
|
8
|
+
def self.dump(obj)
|
9
|
+
# Convert HWIA to an ordinary hash so we have some hope of using the regular YAML encoder in the future
|
10
|
+
obj = obj.to_hash if obj.is_a?(ActiveSupport::HashWithIndifferentAccess)
|
11
|
+
|
12
|
+
YAML.dump(obj)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Deserializes a string from the database to an attribute value.
|
16
|
+
def self.load(yaml)
|
17
|
+
return yaml unless yaml.is_a?(String) && yaml.start_with?("---")
|
18
|
+
|
19
|
+
params = yaml_load(yaml)
|
20
|
+
|
21
|
+
params.with_indifferent_access
|
22
|
+
end
|
23
|
+
|
24
|
+
# rubocop:disable Security/YAMLLoad
|
25
|
+
if YAML.respond_to?(:unsafe_load)
|
26
|
+
def self.yaml_load(payload)
|
27
|
+
if ActiveRecord.try(:use_yaml_unsafe_load) || ActiveRecord::Base.try(:use_yaml_unsafe_load)
|
28
|
+
YAML.unsafe_load(payload)
|
29
|
+
else
|
30
|
+
permitted_classes = (ActiveRecord.try(:yaml_column_permitted_classes) || ActiveRecord::Base.try(:yaml_column_permitted_classes) || []) +
|
31
|
+
Blacklight::Engine.config.blacklight.search_params_permitted_classes
|
32
|
+
YAML.safe_load(payload, permitted_classes: permitted_classes, aliases: true)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
else
|
36
|
+
def self.yaml_load(payload)
|
37
|
+
if ActiveRecord.try(:use_yaml_unsafe_load) || ActiveRecord::Base.try(:use_yaml_unsafe_load)
|
38
|
+
YAML.load(payload)
|
39
|
+
else
|
40
|
+
permitted_classes = (ActiveRecord.try(:yaml_column_permitted_classes) || ActiveRecord::Base.try(:yaml_column_permitted_classes) || []) +
|
41
|
+
Blacklight::Engine.config.blacklight.search_params_permitted_classes
|
42
|
+
YAML.safe_load(payload, permitted_classes: permitted_classes, aliases: true)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
# rubocop:enable Security/YAMLLoad
|
47
|
+
end
|
48
|
+
end
|
@@ -67,14 +67,16 @@ json.included do
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
|
71
|
-
json.
|
72
|
-
|
73
|
-
|
74
|
-
json.
|
75
|
-
|
76
|
-
|
77
|
-
json.
|
70
|
+
Deprecation.silence(Blacklight::ConfigurationHelperBehavior) do
|
71
|
+
json.array! search_fields do |(label, key)|
|
72
|
+
json.type 'search_field'
|
73
|
+
json.id key
|
74
|
+
json.attributes do
|
75
|
+
json.label label
|
76
|
+
end
|
77
|
+
json.links do
|
78
|
+
json.self url_for(search_state.to_h.merge(search_field: key, only_path: false))
|
79
|
+
end
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
data/lib/blacklight/engine.rb
CHANGED
@@ -59,6 +59,8 @@ module Blacklight
|
|
59
59
|
outer_window: 2
|
60
60
|
}
|
61
61
|
|
62
|
+
bl_global_config.search_params_permitted_classes = [ActiveSupport::HashWithIndifferentAccess, Symbol]
|
63
|
+
|
62
64
|
# Anything that goes into Blacklight::Engine.config is stored as a class
|
63
65
|
# variable on Railtie::Configuration. we're going to encapsulate all the
|
64
66
|
# Blacklight specific stuff in this single struct:
|
@@ -27,7 +27,7 @@ module Blacklight
|
|
27
27
|
end
|
28
28
|
|
29
29
|
@blacklight_params = {}
|
30
|
-
search_state_class = @scope
|
30
|
+
search_state_class = @scope.try(:search_state_class) || Blacklight::SearchState
|
31
31
|
@search_state = search_state_class.new(@blacklight_params, @scope&.blacklight_config, @scope)
|
32
32
|
@additional_filters = {}
|
33
33
|
@merged_params = {}
|
@@ -26,6 +26,25 @@ RSpec.describe Blacklight::FacetComponent, type: :component do
|
|
26
26
|
expect(rendered).to have_selector 'ul.facet-values'
|
27
27
|
end
|
28
28
|
|
29
|
+
context 'with a provided component' do
|
30
|
+
let(:component_kwargs) { { field_config: facet_config, display_facet: display_facet, component: component_class } }
|
31
|
+
let(:component_class) do
|
32
|
+
Class.new(Blacklight::FacetFieldListComponent) do
|
33
|
+
def self.name
|
34
|
+
'CustomFacetComponent'
|
35
|
+
end
|
36
|
+
|
37
|
+
def call
|
38
|
+
'Custom facet rendering'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'renders the provided component' do
|
44
|
+
expect(rendered).to have_content 'Custom facet rendering'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
29
48
|
context 'with a facet configured to use a partial' do
|
30
49
|
let(:facet_config) do
|
31
50
|
Blacklight::Configuration::FacetField.new(key: 'field', partial: 'catalog/facet_partial').normalize!
|
data/spec/models/search_spec.rb
CHANGED
@@ -1,32 +1,51 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe Search do
|
4
|
+
let(:search) { described_class.new(user: user) }
|
4
5
|
let(:user) { User.create! email: 'xyz@example.com', password: 'xyz12345' }
|
6
|
+
let(:hash_params) { { q: "query", f: { facet: "filter" } } }
|
7
|
+
let(:query_params) { hash_params }
|
5
8
|
|
6
9
|
describe "query_params" do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
shared_examples "persisting query_params" do
|
11
|
+
it "can save and retrieve the hash" do
|
12
|
+
search.query_params = query_params
|
13
|
+
search.save!
|
14
|
+
expect(described_class.find(search.id).query_params).to eq query_params.with_indifferent_access
|
15
|
+
end
|
10
16
|
end
|
11
17
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
18
|
+
context "are an indifferent hash" do
|
19
|
+
include_context "persisting query_params" do
|
20
|
+
let(:query_params) { hash_params.with_indifferent_access }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "are a string-keyed hash" do
|
25
|
+
include_context "persisting query_params" do
|
26
|
+
let(:query_params) { hash_params.with_indifferent_access.to_hash }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "include symbol keys" do
|
31
|
+
include_context "persisting query_params" do
|
32
|
+
let(:query_params) { hash_params }
|
33
|
+
end
|
16
34
|
end
|
17
35
|
end
|
18
36
|
|
19
37
|
describe "saved?" do
|
20
38
|
it "is true when user_id is not NULL and greater than 0" do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
expect(@search).to be_saved
|
39
|
+
search.save!
|
40
|
+
expect(search).to be_saved
|
25
41
|
end
|
26
42
|
|
27
|
-
|
28
|
-
|
29
|
-
|
43
|
+
context "when user_id is NULL or less than 1" do
|
44
|
+
let(:search) { described_class.create }
|
45
|
+
|
46
|
+
it "is false" do
|
47
|
+
expect(search).not_to be_saved
|
48
|
+
end
|
30
49
|
end
|
31
50
|
end
|
32
51
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blacklight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.29.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Rochkind
|
@@ -14,10 +14,10 @@ authors:
|
|
14
14
|
- Dan Funk
|
15
15
|
- Naomi Dushay
|
16
16
|
- Justin Coyne
|
17
|
-
autorequire:
|
17
|
+
autorequire:
|
18
18
|
bindir: exe
|
19
19
|
cert_chain: []
|
20
|
-
date: 2022-07-
|
20
|
+
date: 2022-07-26 00:00:00.000000000 Z
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
23
|
name: rails
|
@@ -577,6 +577,7 @@ files:
|
|
577
577
|
- app/presenters/blacklight/thumbnail_presenter.rb
|
578
578
|
- app/services/blacklight/document_factory.rb
|
579
579
|
- app/services/blacklight/field_retriever.rb
|
580
|
+
- app/services/blacklight/search_params_yaml_coder.rb
|
580
581
|
- app/services/blacklight/search_service.rb
|
581
582
|
- app/values/blacklight/types.rb
|
582
583
|
- app/views/blacklight/nav/_bookmark.html.erb
|
@@ -933,7 +934,7 @@ homepage: http://projectblacklight.org/
|
|
933
934
|
licenses:
|
934
935
|
- Apache 2.0
|
935
936
|
metadata: {}
|
936
|
-
post_install_message:
|
937
|
+
post_install_message:
|
937
938
|
rdoc_options: []
|
938
939
|
require_paths:
|
939
940
|
- lib
|
@@ -948,8 +949,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
948
949
|
- !ruby/object:Gem::Version
|
949
950
|
version: '0'
|
950
951
|
requirements: []
|
951
|
-
rubygems_version: 3.
|
952
|
-
signing_key:
|
952
|
+
rubygems_version: 3.2.32
|
953
|
+
signing_key:
|
953
954
|
specification_version: 4
|
954
955
|
summary: Blacklight provides a discovery interface for any Solr (http://lucene.apache.org/solr)
|
955
956
|
index.
|