blacklight 7.16.0 → 7.17.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/.rubocop.yml +4 -0
- data/VERSION +1 -1
- data/app/components/blacklight/advanced_search_form_component.html.erb +9 -3
- data/app/components/blacklight/advanced_search_form_component.rb +48 -35
- data/app/components/blacklight/constraints_component.html.erb +19 -3
- data/app/components/blacklight/constraints_component.rb +5 -1
- data/app/components/blacklight/content_areas_shim.rb +12 -0
- data/app/components/blacklight/document/action_component.rb +4 -0
- data/app/components/blacklight/document/actions_component.html.erb +3 -5
- data/app/components/blacklight/document/actions_component.rb +14 -1
- data/app/components/blacklight/document_component.html.erb +4 -7
- data/app/components/blacklight/document_component.rb +73 -73
- data/app/components/blacklight/document_metadata_component.html.erb +2 -2
- data/app/components/blacklight/document_metadata_component.rb +13 -2
- data/app/components/blacklight/document_title_component.html.erb +17 -0
- data/app/components/blacklight/document_title_component.rb +59 -0
- data/app/components/blacklight/facet_field_checkboxes_component.html.erb +2 -2
- data/app/components/blacklight/facet_field_component.rb +4 -1
- data/app/components/blacklight/facet_field_list_component.html.erb +2 -2
- data/app/components/blacklight/facet_field_no_layout_component.rb +4 -1
- data/app/components/blacklight/metadata_field_component.html.erb +2 -2
- data/app/components/blacklight/metadata_field_layout_component.html.erb +3 -1
- data/app/components/blacklight/metadata_field_layout_component.rb +26 -1
- data/app/components/blacklight/response/view_type_button_component.html.erb +4 -0
- data/app/components/blacklight/response/view_type_button_component.rb +36 -0
- data/app/components/blacklight/response/view_type_component.html.erb +2 -5
- data/app/components/blacklight/response/view_type_component.rb +9 -13
- data/app/components/blacklight/search_bar_component.rb +4 -1
- data/app/components/blacklight/system/dropdown_component.html.erb +4 -7
- data/app/components/blacklight/system/dropdown_component.rb +24 -0
- data/app/components/blacklight/system/flash_message_component.html.erb +1 -1
- data/app/components/blacklight/system/flash_message_component.rb +7 -1
- data/app/components/blacklight/system/modal_component.rb +7 -1
- data/app/views/catalog/_citation.html.erb +1 -1
- data/app/views/catalog/_document.html.erb +2 -2
- data/app/views/catalog/_facet_layout.html.erb +2 -2
- data/app/views/catalog/_show_main_content.html.erb +3 -3
- data/app/views/catalog/email.html.erb +2 -2
- data/app/views/catalog/email_success.html.erb +1 -1
- data/app/views/catalog/facet.html.erb +3 -3
- data/app/views/catalog/sms.html.erb +2 -2
- data/app/views/catalog/sms_success.html.erb +1 -1
- data/blacklight.gemspec +1 -1
- data/config/locales/blacklight.de.yml +2 -2
- data/lib/blacklight/engine.rb +3 -1
- data/lib/blacklight/solr/facet_paginator.rb +2 -0
- data/lib/blacklight/solr/request.rb +31 -0
- data/lib/blacklight/solr/response.rb +2 -16
- data/lib/blacklight/solr/response/facets.rb +76 -22
- data/lib/blacklight/solr/response/params.rb +104 -0
- data/lib/blacklight/solr/search_builder_behavior.rb +49 -29
- data/lib/generators/blacklight/assets_generator.rb +6 -2
- data/lib/generators/blacklight/user_generator.rb +1 -1
- data/spec/components/blacklight/document_component_spec.rb +3 -3
- data/spec/models/blacklight/solr/facet_paginator_spec.rb +4 -0
- data/spec/models/blacklight/solr/request_spec.rb +62 -29
- data/spec/models/blacklight/solr/response/facets_spec.rb +109 -0
- data/spec/models/blacklight/solr/response_spec.rb +10 -0
- data/spec/models/blacklight/solr/search_builder_spec.rb +17 -0
- metadata +14 -8
@@ -2,16 +2,27 @@
|
|
2
2
|
|
3
3
|
module Blacklight
|
4
4
|
class DocumentMetadataComponent < ::ViewComponent::Base
|
5
|
+
renders_many :fields, (lambda do |component: nil, **kwargs|
|
6
|
+
(component || Blacklight::MetadataFieldComponent).new(**kwargs)
|
7
|
+
end)
|
5
8
|
with_collection_parameter :fields
|
6
9
|
|
7
10
|
# @param fields [Enumerable<Blacklight::FieldPresenter>] Document field presenters
|
8
|
-
def initialize(fields
|
11
|
+
def initialize(fields: [], show: false)
|
9
12
|
@fields = fields
|
10
13
|
@show = show
|
11
14
|
end
|
12
15
|
|
16
|
+
def before_render
|
17
|
+
return unless fields
|
18
|
+
|
19
|
+
@fields.each do |field|
|
20
|
+
field(component: field_component(field), field: field, show: @show)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
13
24
|
def render?
|
14
|
-
|
25
|
+
fields.present?
|
15
26
|
end
|
16
27
|
|
17
28
|
def field_component(field)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<header class="documentHeader row">
|
2
|
+
<%= content_tag @as, class: @classes do %>
|
3
|
+
<% before_title.each do |t| %>
|
4
|
+
<%= t %>
|
5
|
+
<% end %>
|
6
|
+
|
7
|
+
<%= counter -%><%= title -%>
|
8
|
+
|
9
|
+
<% after_title.each do |t| %>
|
10
|
+
<%= t %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<% actions.each do |action| %>
|
15
|
+
<%= action %>
|
16
|
+
<% end %>
|
17
|
+
</header>
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight
|
4
|
+
class DocumentTitleComponent < ::ViewComponent::Base
|
5
|
+
renders_many :before_title
|
6
|
+
renders_many :after_title
|
7
|
+
renders_many :actions
|
8
|
+
|
9
|
+
# rubocop:disable Metrics/ParameterLists
|
10
|
+
def initialize(title = nil, document: nil, presenter: nil, as: :h3, counter: nil, classes: 'index_title document-title-heading col', link_to_document: true, document_component: nil)
|
11
|
+
raise ArgumentError, 'missing keyword: :document or :presenter' if presenter.nil? && document.nil?
|
12
|
+
|
13
|
+
@title = title
|
14
|
+
@document = document
|
15
|
+
@presenter = presenter
|
16
|
+
@as = as || :h3
|
17
|
+
@counter = counter
|
18
|
+
@classes = classes
|
19
|
+
@link_to_document = link_to_document
|
20
|
+
@document_component = document_component
|
21
|
+
end
|
22
|
+
# rubocop:enable Metrics/ParameterLists
|
23
|
+
|
24
|
+
# Content for the document title area; should be an inline element
|
25
|
+
def title
|
26
|
+
if @link_to_document
|
27
|
+
@view_context.link_to_document presenter.document, @title.presence || content.presence, counter: @counter, itemprop: 'name'
|
28
|
+
else
|
29
|
+
content_tag('span', @title.presence || content.presence || presenter.heading, itemprop: 'name')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Content for the document actions area
|
34
|
+
def actions
|
35
|
+
if block_given?
|
36
|
+
@has_actions_slot = true
|
37
|
+
return super
|
38
|
+
end
|
39
|
+
|
40
|
+
(@has_actions_slot && get_slot(:actions)) ||
|
41
|
+
([@document_component&.actions] if @document_component&.actions.present?) ||
|
42
|
+
[@view_context.render_index_doc_actions(presenter.document, wrapping_class: 'index-document-functions col-sm-3 col-lg-2')]
|
43
|
+
end
|
44
|
+
|
45
|
+
def counter
|
46
|
+
return unless @counter
|
47
|
+
|
48
|
+
content_tag :span, class: 'document-counter' do
|
49
|
+
t('blacklight.search.documents.counter', counter: @counter)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def presenter
|
56
|
+
@presenter ||= @view_context.document_presenter(@document)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<%= render(@layout.new(facet_field: @facet_field)) do |component| %>
|
2
|
-
<% component.
|
2
|
+
<% component.label do %>
|
3
3
|
<%= @facet_field.label %>
|
4
4
|
<% end %>
|
5
5
|
|
6
|
-
<% component.
|
6
|
+
<% component.body do %>
|
7
7
|
<ul class="facet-values list-unstyled blacklight-facet-checkboxes">
|
8
8
|
<% presenters.each_with_index do |presenter, idx| -%>
|
9
9
|
<li>
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<%= render(@layout.new(facet_field: @facet_field)) do |component| %>
|
2
|
-
<% component.
|
2
|
+
<% component.label do %>
|
3
3
|
<%= @facet_field.label %>
|
4
4
|
<% end %>
|
5
|
-
<% component.
|
5
|
+
<% component.body do %>
|
6
6
|
<%= @view_context.render(Blacklight::FacetFieldInclusiveConstraintComponent.new(facet_field: @facet_field)) %>
|
7
7
|
<ul class="facet-values list-unstyled">
|
8
8
|
<%= render_facet_limit_list @facet_field.paginator, @facet_field.key %>
|
@@ -2,8 +2,17 @@
|
|
2
2
|
|
3
3
|
module Blacklight
|
4
4
|
class MetadataFieldLayoutComponent < ::ViewComponent::Base
|
5
|
+
include Blacklight::ContentAreasShim
|
6
|
+
|
5
7
|
with_collection_parameter :field
|
6
|
-
|
8
|
+
renders_one :label
|
9
|
+
renders_many :values, (lambda do |value: nil, &block|
|
10
|
+
if block
|
11
|
+
content_tag :dd, class: "#{@value_class} blacklight-#{@key}", &block
|
12
|
+
else
|
13
|
+
content_tag :dd, value, class: "#{@value_class} blacklight-#{@key}"
|
14
|
+
end
|
15
|
+
end)
|
7
16
|
|
8
17
|
# @param field [Blacklight::FieldPresenter]
|
9
18
|
def initialize(field:, label_class: 'col-md-3', value_class: 'col-md-9')
|
@@ -12,5 +21,21 @@ module Blacklight
|
|
12
21
|
@label_class = label_class
|
13
22
|
@value_class = value_class
|
14
23
|
end
|
24
|
+
|
25
|
+
def value(*args, **kwargs, &block)
|
26
|
+
return set_slot(:values, *args, **kwargs, &block) if block_given?
|
27
|
+
|
28
|
+
Deprecation.warn('The `value` content area is deprecated; render from the values slot instead')
|
29
|
+
|
30
|
+
values.first
|
31
|
+
end
|
32
|
+
|
33
|
+
def with(slot_name, *args, **kwargs, &block)
|
34
|
+
if slot_name == :value
|
35
|
+
super(:values, *args, **kwargs, &block)
|
36
|
+
else
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
15
40
|
end
|
16
41
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight
|
4
|
+
module Response
|
5
|
+
# Render spellcheck results for a search query
|
6
|
+
class ViewTypeButtonComponent < ViewComponent::Base
|
7
|
+
with_collection_parameter :view
|
8
|
+
# @param [Blacklight::Configuration::View] view
|
9
|
+
def initialize(view:, key: nil, selected: false, search_state: nil, classes: 'btn btn-outline-secondary btn-icon')
|
10
|
+
@view = view
|
11
|
+
@key = key || view.key
|
12
|
+
@selected = selected
|
13
|
+
@classes = classes
|
14
|
+
@search_state = search_state
|
15
|
+
end
|
16
|
+
|
17
|
+
def icon
|
18
|
+
@view_context.render_view_type_group_icon(@view)
|
19
|
+
end
|
20
|
+
|
21
|
+
def label
|
22
|
+
Deprecation.silence(Blacklight::ConfigurationHelperBehavior) do
|
23
|
+
@view_context.view_label(@view)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def url
|
28
|
+
@view_context.url_for(@search_state.to_h.merge(view: @key))
|
29
|
+
end
|
30
|
+
|
31
|
+
def selected?
|
32
|
+
@selected
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,11 +1,8 @@
|
|
1
1
|
<div class="view-type">
|
2
2
|
<span class="sr-only"><%= t('blacklight.search.view_title') %></span>
|
3
3
|
<div class="view-type-group btn-group">
|
4
|
-
<%
|
5
|
-
<%=
|
6
|
-
<%= icon(view) %>
|
7
|
-
<span class="caption"><%= label(view) %></span>
|
8
|
-
<% end %>
|
4
|
+
<% views.each do |view| %>
|
5
|
+
<%= view %>
|
9
6
|
<% end %>
|
10
7
|
</div>
|
11
8
|
</div>
|
@@ -4,6 +4,8 @@ module Blacklight
|
|
4
4
|
module Response
|
5
5
|
# Render spellcheck results for a search query
|
6
6
|
class ViewTypeComponent < ViewComponent::Base
|
7
|
+
renders_many :views, 'Blacklight::Response::ViewTypeButtonComponent'
|
8
|
+
|
7
9
|
# @param [Blacklight::Response] response
|
8
10
|
def initialize(response:, views: {}, search_state:, selected: nil)
|
9
11
|
@response = response
|
@@ -12,25 +14,19 @@ module Blacklight
|
|
12
14
|
@selected = selected
|
13
15
|
end
|
14
16
|
|
15
|
-
def
|
16
|
-
|
17
|
-
@view_context.has_alternative_views?
|
18
|
-
end
|
19
|
-
end
|
17
|
+
def before_render
|
18
|
+
return if views.any?
|
20
19
|
|
21
|
-
|
22
|
-
|
20
|
+
@views.each do |key, config|
|
21
|
+
view(key: key, view: config, selected: @selected == key, search_state: @search_state)
|
22
|
+
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def render?
|
26
26
|
Deprecation.silence(Blacklight::ConfigurationHelperBehavior) do
|
27
|
-
@view_context.
|
27
|
+
@view_context.has_alternative_views?
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
31
|
-
def url(view)
|
32
|
-
@view_context.url_for(@search_state.to_h.merge(view: view))
|
33
|
-
end
|
34
30
|
end
|
35
31
|
end
|
36
32
|
end
|
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
module Blacklight
|
4
4
|
class SearchBarComponent < ::ViewComponent::Base
|
5
|
-
|
5
|
+
include Blacklight::ContentAreasShim
|
6
|
+
|
7
|
+
renders_one :append
|
8
|
+
renders_one :prepend
|
6
9
|
|
7
10
|
# rubocop:disable Metrics/ParameterLists
|
8
11
|
def initialize(
|
@@ -1,12 +1,9 @@
|
|
1
1
|
<%= content_tag :div, id: @id, class: @classes.join(' ') do %>
|
2
|
-
|
3
|
-
<%= t(:button_label_html, default: :label_html, scope: "blacklight.search.#{@param}", @interpolation => label_for_value(@selected)) %> <span class="caret"></span>
|
4
|
-
</button>
|
2
|
+
<%= button %>
|
5
3
|
|
6
4
|
<div class="dropdown-menu" role="menu">
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
<%- end -%>
|
5
|
+
<% options.each do |option| %>
|
6
|
+
<%= option %>
|
7
|
+
<% end %>
|
11
8
|
</div>
|
12
9
|
<% end %>
|
@@ -3,6 +3,15 @@
|
|
3
3
|
module Blacklight
|
4
4
|
module System
|
5
5
|
class DropdownComponent < ViewComponent::Base
|
6
|
+
renders_one :button, (lambda do |classes:, label:|
|
7
|
+
button_tag class: classes, aria: { expanded: false }, data: { toggle: 'dropdown' } do
|
8
|
+
safe_join([label, content_tag(:span, '', class: 'caret')])
|
9
|
+
end
|
10
|
+
end)
|
11
|
+
renders_many :options, (lambda do |text:, url:, selected: false|
|
12
|
+
link_to(text, url, class: "dropdown-item #{'active' if selected}", role: 'menuitem', aria: { current: ('page' if selected) })
|
13
|
+
end)
|
14
|
+
|
6
15
|
# rubocop:disable Metrics/ParameterLists
|
7
16
|
def initialize(param:, choices:, search_state:, id: nil, classes: [], default: nil, selected: nil, interpolation: :field)
|
8
17
|
@param = param
|
@@ -15,6 +24,21 @@ module Blacklight
|
|
15
24
|
end
|
16
25
|
# rubocop:enable Metrics/ParameterLists
|
17
26
|
|
27
|
+
def button_label
|
28
|
+
t(:button_label_html, default: :label_html, scope: "blacklight.search.#{@param}", @interpolation => label_for_value(@selected))
|
29
|
+
end
|
30
|
+
|
31
|
+
def before_render
|
32
|
+
button(classes: 'btn btn-outline-secondary dropdown-toggle', label: button_label) unless button
|
33
|
+
|
34
|
+
return if options.any?
|
35
|
+
|
36
|
+
options(@choices.map do |option|
|
37
|
+
text, value = option_text_and_value(option)
|
38
|
+
{ text: text, url: @view_context.url_for(@search_state.params_for_search(@param => value)), selected: @selected == value }
|
39
|
+
end)
|
40
|
+
end
|
41
|
+
|
18
42
|
def render?
|
19
43
|
@choices.many?
|
20
44
|
end
|
@@ -3,13 +3,19 @@
|
|
3
3
|
module Blacklight
|
4
4
|
module System
|
5
5
|
class FlashMessageComponent < ViewComponent::Base
|
6
|
+
renders_one :message
|
7
|
+
|
6
8
|
with_collection_parameter :message
|
7
9
|
|
8
|
-
def initialize(message
|
10
|
+
def initialize(message: nil, type:)
|
9
11
|
@message = message
|
10
12
|
@classes = alert_class(type)
|
11
13
|
end
|
12
14
|
|
15
|
+
def before_render
|
16
|
+
message { @message } if @message
|
17
|
+
end
|
18
|
+
|
13
19
|
def alert_class(type)
|
14
20
|
case type.to_s
|
15
21
|
when 'success' then "alert-success"
|
@@ -3,7 +3,13 @@
|
|
3
3
|
module Blacklight
|
4
4
|
module System
|
5
5
|
class ModalComponent < ViewComponent::Base
|
6
|
-
|
6
|
+
include Blacklight::ContentAreasShim
|
7
|
+
|
8
|
+
renders_one :prefix
|
9
|
+
renders_one :header
|
10
|
+
renders_one :title
|
11
|
+
renders_one :body
|
12
|
+
renders_one :footer
|
7
13
|
end
|
8
14
|
end
|
9
15
|
end
|