blacklight 9.0.0.beta1 → 9.0.0.beta3
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 +81 -3
- data/.rubocop_todo.yml +43 -67
- data/.solr_wrapper.yml +2 -0
- data/VERSION +1 -1
- data/app/assets/builds/blacklight.css +17 -18
- data/app/assets/javascripts/blacklight/blacklight.esm.js +43 -73
- data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +43 -73
- data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
- data/app/assets/stylesheets/blacklight/_blacklight_base.scss +0 -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/constraint_layout_component.html.erb +1 -6
- data/app/components/blacklight/constraint_layout_component.rb +9 -0
- 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.html.erb +2 -2
- 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.html.erb +3 -3
- data/app/components/blacklight/document_component.rb +5 -5
- data/app/components/blacklight/document_title_component.rb +6 -10
- data/app/components/blacklight/facet_field_checkboxes_component.rb +4 -18
- data/app/components/blacklight/facet_field_component.rb +4 -15
- data/app/components/blacklight/facet_field_filter_component.rb +4 -19
- data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +4 -23
- data/app/components/blacklight/facet_field_list_component.rb +4 -30
- data/app/components/blacklight/facet_field_no_layout_component.rb +4 -8
- data/app/components/blacklight/facet_field_pagination_component.html.erb +2 -2
- data/app/components/blacklight/facet_item_component.rb +4 -72
- 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 +39 -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 +40 -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/icons/remove_component.rb +2 -2
- data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +2 -2
- data/app/components/blacklight/response/facet_group_component.html.erb +3 -3
- data/app/components/blacklight/response/facet_group_component.rb +9 -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/system/flash_message_component.html.erb +1 -1
- data/app/components/blacklight/system/flash_message_component.rb +0 -9
- data/app/components/blacklight/system/modal_component.html.erb +1 -2
- 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 +16 -27
- 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/catalog_helper_behavior.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/bookmark_toggle.js +7 -2
- data/app/javascript/blacklight-frontend/checkbox_submit.js +8 -1
- 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 +2 -6
- 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 +8 -4
- 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 +14 -13
- data/config/locales/blacklight.ca.yml +1 -0
- data/config/locales/blacklight.de.yml +13 -12
- data/config/locales/blacklight.en.yml +1 -0
- data/config/locales/blacklight.es.yml +13 -12
- data/config/locales/blacklight.fr.yml +14 -13
- data/config/locales/blacklight.hu.yml +15 -14
- data/config/locales/blacklight.it.yml +15 -14
- data/config/locales/blacklight.nl.yml +13 -12
- data/config/locales/blacklight.pt-BR.yml +15 -14
- data/config/locales/blacklight.sq.yml +14 -13
- data/config/locales/blacklight.zh.yml +11 -10
- 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 +9 -4
- 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 +12 -10
- 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 +6 -4
- 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 +5 -3
- 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/features/modal_spec.rb +1 -1
- 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 +52 -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/presenters/blacklight/json_presenter_spec.rb +17 -0
- 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 +57 -29
- data/.github/workflows/ruby.yml +0 -98
- data/app/assets/stylesheets/blacklight/_icons.scss +0 -4
- 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,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight
|
4
|
+
module Facets
|
5
|
+
class ItemComponent < Blacklight::Component
|
6
|
+
attr_reader :label, :href, :hits
|
7
|
+
|
8
|
+
with_collection_parameter :facet_item
|
9
|
+
|
10
|
+
def initialize(facet_item:, wrapping_element: 'li', suppress_link: false)
|
11
|
+
@facet_item = facet_item
|
12
|
+
@label = facet_item.label
|
13
|
+
@hits = facet_item.hits
|
14
|
+
@href = facet_item.href
|
15
|
+
@selected = facet_item.selected?
|
16
|
+
@wrapping_element = wrapping_element
|
17
|
+
@suppress_link = suppress_link
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
# if the downstream app has overridden the helper methods we'd usually call,
|
22
|
+
# use the helpers to preserve compatibility
|
23
|
+
content = if @selected
|
24
|
+
render_selected_facet_value
|
25
|
+
else
|
26
|
+
render_facet_value
|
27
|
+
end
|
28
|
+
|
29
|
+
return '' if content.blank?
|
30
|
+
return content unless @wrapping_element
|
31
|
+
|
32
|
+
content_tag @wrapping_element, content
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Standard display of a facet value in a list. Used in both _facets sidebar
|
37
|
+
# partial and catalog/facet expanded list. Will output facet value name as
|
38
|
+
# a link to add that to your restrictions, with count in parens.
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
# @private
|
42
|
+
def render_facet_value
|
43
|
+
tag.span(class: "facet-label") do
|
44
|
+
link_to_unless(@suppress_link, label, href, class: "facet-select", rel: "nofollow")
|
45
|
+
end + render_facet_count
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Standard display of a SELECTED facet value (e.g. without a link and with a remove button)
|
50
|
+
# @see #render_facet_value
|
51
|
+
#
|
52
|
+
# @private
|
53
|
+
def render_selected_facet_value
|
54
|
+
concat render(Blacklight::Facets::SelectedValueComponent.new(label: label, href: href))
|
55
|
+
concat render_facet_count(classes: ["selected"])
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Renders a count value for facet limits. Can be over-ridden locally
|
60
|
+
# to change style. And can be called by plugins to get consistent display.
|
61
|
+
#
|
62
|
+
# @param [Hash] options
|
63
|
+
# @option options [Array<String>] an array of classes to add to count span.
|
64
|
+
# @return [String]
|
65
|
+
# @private
|
66
|
+
def render_facet_count(options = {})
|
67
|
+
classes = (options[:classes] || []) << "facet-count"
|
68
|
+
|
69
|
+
render Blacklight::Facets::CountComponent.new(hits: hits, classes: classes)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= render(layout.new(facet_field: @facet_field)) do |component| %>
|
2
|
+
<% component.with_label do %>
|
3
|
+
<%= @facet_field.label %>
|
4
|
+
<% end %>
|
5
|
+
<% component.with_body do %>
|
6
|
+
<%= render(Blacklight::Facets::InclusiveConstraintComponent.new(facet_field: @facet_field)) %>
|
7
|
+
<ul class="facet-values list-unstyled">
|
8
|
+
<%= render facet_items %>
|
9
|
+
</ul>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight
|
4
|
+
module Facets
|
5
|
+
class ListComponent < Blacklight::Component
|
6
|
+
def initialize(facet_field:, layout: nil)
|
7
|
+
@facet_field = facet_field
|
8
|
+
@layout = layout == false ? Blacklight::Facets::NoLayoutComponent : Blacklight::Facets::FieldComponent
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_accessor :layout
|
12
|
+
|
13
|
+
def facet_items(wrapping_element: :li, **item_args)
|
14
|
+
facet_item_component_class.with_collection(facet_item_presenters, wrapping_element: wrapping_element, **item_args)
|
15
|
+
end
|
16
|
+
|
17
|
+
def facet_item_presenters
|
18
|
+
@facet_field.paginator.items.map do |item|
|
19
|
+
facet_item_presenter(item)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def render?
|
24
|
+
@facet_field.paginator&.items&.any?
|
25
|
+
end
|
26
|
+
|
27
|
+
def facet_item_presenter(facet_item)
|
28
|
+
facet_config.item_presenter.new(facet_item, facet_config, helpers, @facet_field.key)
|
29
|
+
end
|
30
|
+
|
31
|
+
def facet_item_component_class
|
32
|
+
facet_config.item_component
|
33
|
+
end
|
34
|
+
|
35
|
+
def facet_config
|
36
|
+
@facet_field.facet_field
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight
|
4
|
+
module Facets
|
5
|
+
# Standard display of a selected facet value (e.g. without a link and with a remove button)
|
6
|
+
class SelectedValueComponent < Blacklight::Component
|
7
|
+
def initialize(label:, href:)
|
8
|
+
@label = label
|
9
|
+
@href = href
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :label, :href
|
14
|
+
|
15
|
+
def call
|
16
|
+
tag.span(class: "facet-label") do
|
17
|
+
tag.span(label, class: "selected") + remove_link
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def remove_link
|
22
|
+
link_to(href, class: "remove ps-2", rel: "nofollow") do
|
23
|
+
render(Blacklight::Icons::RemoveComponent.new(aria_hidden: true)) +
|
24
|
+
tag.span(t(:'blacklight.search.facets.selected.remove'), class: 'visually-hidden')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<label for="facet_suggest_<%= key %>">
|
2
|
+
<%= I18n.t('blacklight.search.facets.suggest.label', field_label: label) %>
|
3
|
+
</label>
|
4
|
+
<%= text_field_tag "facet_suggest_#{key}",
|
5
|
+
nil,
|
6
|
+
class: "facet-suggest form-control mb-3",
|
7
|
+
data: {
|
8
|
+
facet_field: key,
|
9
|
+
facet_search_context: helpers.search_facet_path(id: key)
|
10
|
+
},
|
11
|
+
placeholder: I18n.t('blacklight.search.form.search.placeholder')
|
12
|
+
%>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight
|
4
|
+
module Facets
|
5
|
+
class SuggestComponent < Blacklight::Component
|
6
|
+
def initialize(presenter:)
|
7
|
+
@presenter = presenter
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
attr_accessor :presenter
|
13
|
+
|
14
|
+
delegate :suggest, :key, :label, to: :presenter
|
15
|
+
|
16
|
+
def render?
|
17
|
+
# Draw if suggest is true or not present
|
18
|
+
suggest != false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -7,8 +7,8 @@ module Blacklight
|
|
7
7
|
# Blacklight::Icons::RemoveComponent.svg = '<svg>your SVG here</svg>'
|
8
8
|
class RemoveComponent < Blacklight::Icons::IconComponent
|
9
9
|
self.svg = <<~SVG
|
10
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x
|
11
|
-
<path d="
|
10
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x-lg" viewBox="0 0 16 16">
|
11
|
+
<path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"/>
|
12
12
|
</svg>
|
13
13
|
SVG
|
14
14
|
end
|
@@ -4,8 +4,8 @@ module Blacklight
|
|
4
4
|
class MetadataFieldPlainTextLayoutComponent < Blacklight::MetadataFieldLayoutComponent
|
5
5
|
with_collection_parameter :field
|
6
6
|
|
7
|
-
def initialize(field:, **
|
8
|
-
super(field: field,
|
7
|
+
def initialize(field:, **)
|
8
|
+
super(field: field, **, value_tag: nil)
|
9
9
|
end
|
10
10
|
|
11
11
|
# rubocop:disable Rails/OutputSafety
|
@@ -1,12 +1,12 @@
|
|
1
1
|
<% # main container for facets/limits menu -%>
|
2
|
-
<%= content_tag :div, id: @id, class:
|
2
|
+
<%= content_tag :div, id: @id, class: container_classes do %>
|
3
3
|
<div class="facets-header">
|
4
|
-
<%= content_tag :h2, @title, class:
|
4
|
+
<%= content_tag :h2, @title, class: header_classes if @title %>
|
5
5
|
|
6
6
|
<%= collapse_toggle_button(@panel_id) %>
|
7
7
|
</div>
|
8
8
|
|
9
|
-
<div id="<%= @panel_id %>" class="
|
9
|
+
<div id="<%= @panel_id %>" class="<%= body_classes %>">
|
10
10
|
<%= body %>
|
11
11
|
</div>
|
12
12
|
<% end %>
|
@@ -8,13 +8,20 @@ module Blacklight
|
|
8
8
|
|
9
9
|
# @param [String] id a unique identifier for the group
|
10
10
|
# @param [String] title the title of the facet group section
|
11
|
-
def initialize(id:, title: nil
|
11
|
+
def initialize(id:, title: nil, body_classes: 'facets-collapse d-lg-block collapse accordion',
|
12
|
+
header_classes: 'facets-heading h4',
|
13
|
+
container_classes: 'facets sidenav facets-toggleable-md')
|
12
14
|
@groupname = id
|
13
15
|
@id = id ? "facets-#{id}" : 'facets'
|
14
16
|
@title = title || I18n.t("blacklight.search.#{@id}.title")
|
15
17
|
@panel_id = id ? "facet-panel-#{id}-collapse" : 'facet-panel-collapse'
|
18
|
+
@body_classes = body_classes
|
19
|
+
@header_classes = header_classes
|
20
|
+
@container_classes = container_classes
|
16
21
|
end
|
17
22
|
|
23
|
+
attr_accessor :body_classes, :header_classes, :container_classes
|
24
|
+
|
18
25
|
def collapse_toggle_button(panel_id)
|
19
26
|
render button_component.new(panel_id: panel_id)
|
20
27
|
end
|
@@ -24,6 +31,7 @@ module Blacklight
|
|
24
31
|
end
|
25
32
|
|
26
33
|
def render?
|
34
|
+
# debugger
|
27
35
|
body.present?
|
28
36
|
end
|
29
37
|
end
|
@@ -6,7 +6,7 @@ module Blacklight
|
|
6
6
|
renders_one :button, DropdownButtonComponent
|
7
7
|
|
8
8
|
renders_many :options, (lambda do |text:, url:, selected: false|
|
9
|
-
link_to(text, url, class: "dropdown-item #{'active' if selected}",
|
9
|
+
link_to(text, url, class: "dropdown-item #{'active' if selected}", aria: { current: ('page' if selected) })
|
10
10
|
end)
|
11
11
|
|
12
12
|
# rubocop:disable Metrics/ParameterLists
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="alert alert-dismissible <%= @classes %>">
|
2
2
|
<%= message %>
|
3
|
-
<%= tag.button
|
3
|
+
<%= tag.button '', type: "button", class: "btn-close",
|
4
4
|
data: { dismiss: "alert", bs_dismiss: "alert" },
|
5
5
|
aria: { label: "Close" } %>
|
6
6
|
</div>
|
@@ -16,15 +16,6 @@ module Blacklight
|
|
16
16
|
with_message { @message } if @message
|
17
17
|
end
|
18
18
|
|
19
|
-
# Bootstrap 4 requires the span, but Bootstrap 5 should not have it.
|
20
|
-
# See https://getbootstrap.com/docs/4.6/components/alerts/#dismissing
|
21
|
-
# https://getbootstrap.com/docs/5.1/components/alerts/#dismissing
|
22
|
-
def button_contents
|
23
|
-
return if helpers.controller.blacklight_config.bootstrap_version == 5
|
24
|
-
|
25
|
-
tag.span '×'.html_safe, aria: { hidden: true }
|
26
|
-
end
|
27
|
-
|
28
19
|
def alert_class(type)
|
29
20
|
case type.to_s
|
30
21
|
when 'success' then "alert-success"
|
@@ -6,8 +6,7 @@
|
|
6
6
|
<h1 class="modal-title"><%= title %></h1>
|
7
7
|
<% end) %>
|
8
8
|
|
9
|
-
<button type="button" class="blacklight-modal-close btn-close
|
10
|
-
<span aria-hidden="true" class="visually-hidden">×</span>
|
9
|
+
<button type="button" class="blacklight-modal-close btn-close" data-bl-dismiss="modal" aria-label="<%= t('blacklight.modal.close') %>">
|
11
10
|
</button>
|
12
11
|
</div>
|
13
12
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<nav class="navbar navbar-expand-md
|
1
|
+
<nav class="navbar navbar-expand-md bg-dark topbar" aria-label="<%= aria_label %>">
|
2
2
|
<div class="<%= container_classes %>">
|
3
3
|
<%= logo_link %>
|
4
4
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-bs-toggle="collapse" data-target="#user-util-collapse" data-bs-target="#user-util-collapse" aria-controls="user-util-collapse" aria-expanded="false" aria-label="Toggle navigation">
|
@@ -36,8 +36,8 @@ module Blacklight::Bookmarks
|
|
36
36
|
|
37
37
|
# Blacklight uses #search_action_url to figure out the right URL for
|
38
38
|
# the global search box
|
39
|
-
def search_action_url
|
40
|
-
search_catalog_url(*
|
39
|
+
def search_action_url(*)
|
40
|
+
search_catalog_url(*)
|
41
41
|
end
|
42
42
|
|
43
43
|
# @return [Hash] a hash of context information to pass through to the search service
|
@@ -110,7 +110,7 @@ module Blacklight::Bookmarks
|
|
110
110
|
|
111
111
|
success = @bookmarks.all? do |bookmark|
|
112
112
|
bookmark = current_or_guest_user.bookmarks.find_by(bookmark)
|
113
|
-
bookmark
|
113
|
+
bookmark&.delete && bookmark.destroyed?
|
114
114
|
end
|
115
115
|
|
116
116
|
if success
|
@@ -9,13 +9,13 @@ module Blacklight::Catalog
|
|
9
9
|
include Blacklight::Configurable
|
10
10
|
include Blacklight::SearchContext
|
11
11
|
include Blacklight::Searchable
|
12
|
+
include Blacklight::Facetable
|
12
13
|
|
13
14
|
# The following code is executed when someone includes blacklight::catalog in their
|
14
15
|
# own controller.
|
15
16
|
included do
|
16
17
|
if respond_to? :helper_method
|
17
18
|
helper_method :sms_mappings, :has_search_parameters?
|
18
|
-
helper_method :search_facet_path
|
19
19
|
end
|
20
20
|
|
21
21
|
record_search_parameters
|
@@ -80,17 +80,19 @@ module Blacklight::Catalog
|
|
80
80
|
|
81
81
|
# displays values and pagination links for a single facet field
|
82
82
|
def facet
|
83
|
+
# @facet is a Blacklight::Configuration::FacetField
|
83
84
|
@facet = blacklight_config.facet_fields[params[:id]]
|
84
85
|
raise ActionController::RoutingError, 'Not Found' unless @facet
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
search_service.facet_suggest_response(@facet.key, params[:query_fragment])
|
87
|
+
@response = if params[:query_fragment].present?
|
88
|
+
facet_search_service.facet_suggest_response(@facet.key, params[:query_fragment])
|
89
89
|
else
|
90
|
-
|
90
|
+
facet_search_service.facet_field_response(@facet.key)
|
91
91
|
end
|
92
|
+
|
92
93
|
@display_facet = @response.aggregations[@facet.field]
|
93
94
|
|
95
|
+
# @presenter is a Blacklight::FacetFieldPresenter
|
94
96
|
@presenter = @facet.presenter.new(@facet, @display_facet, view_context)
|
95
97
|
@pagination = @presenter.paginator
|
96
98
|
respond_to do |format|
|
@@ -139,15 +141,6 @@ module Blacklight::Catalog
|
|
139
141
|
params[:search_field].present? || search_state.has_constraints?
|
140
142
|
end
|
141
143
|
|
142
|
-
def search_facet_path(options = {})
|
143
|
-
opts = search_state
|
144
|
-
.to_h
|
145
|
-
.merge(action: "facet", only_path: true)
|
146
|
-
.merge(options)
|
147
|
-
.except(:page)
|
148
|
-
url_for opts
|
149
|
-
end
|
150
|
-
|
151
144
|
private
|
152
145
|
|
153
146
|
#
|
@@ -236,25 +229,17 @@ module Blacklight::Catalog
|
|
236
229
|
# Email Action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
|
237
230
|
def email_action documents
|
238
231
|
mail = RecordMailer.email_record(documents, { to: params[:to], message: params[:message], config: blacklight_config }, url_options)
|
239
|
-
|
240
|
-
mail.deliver_now
|
241
|
-
else
|
242
|
-
mail.deliver
|
243
|
-
end
|
232
|
+
mail.deliver_now
|
244
233
|
end
|
245
234
|
|
246
235
|
# SMS action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
|
247
236
|
def sms_action documents
|
248
237
|
to = "#{params[:to].gsub(/[^\d]/, '')}@#{params[:carrier]}"
|
249
238
|
mail = RecordMailer.sms_record(documents, { to: to, config: blacklight_config }, url_options)
|
250
|
-
|
251
|
-
mail.deliver_now
|
252
|
-
else
|
253
|
-
mail.deliver
|
254
|
-
end
|
239
|
+
mail.deliver_now
|
255
240
|
end
|
256
241
|
|
257
|
-
def
|
242
|
+
def sms_params_valid?
|
258
243
|
if params[:to].blank?
|
259
244
|
flash[:error] = I18n.t('blacklight.sms.errors.to.blank')
|
260
245
|
elsif params[:carrier].blank?
|
@@ -267,12 +252,14 @@ module Blacklight::Catalog
|
|
267
252
|
|
268
253
|
flash[:error].blank?
|
269
254
|
end
|
255
|
+
alias validate_sms_params sms_params_valid?
|
256
|
+
Blacklight.deprecation.deprecate_methods(Blacklight::Catalog, validate_sms_params: 'use Catalog#sms_params_valid? instead')
|
270
257
|
|
271
258
|
def sms_mappings
|
272
259
|
Blacklight::Engine.config.blacklight.sms_mappings
|
273
260
|
end
|
274
261
|
|
275
|
-
def
|
262
|
+
def email_params_valid?
|
276
263
|
if params[:to].blank?
|
277
264
|
flash[:error] = I18n.t('blacklight.email.errors.to.blank')
|
278
265
|
elsif !params[:to].match(Blacklight::Engine.config.blacklight.email_regexp)
|
@@ -281,6 +268,8 @@ module Blacklight::Catalog
|
|
281
268
|
|
282
269
|
flash[:error].blank?
|
283
270
|
end
|
271
|
+
alias validate_email_params email_params_valid?
|
272
|
+
Blacklight.deprecation.deprecate_methods(Blacklight::Catalog, validate_email_params: 'use Catalog#email_params_valid? instead')
|
284
273
|
|
285
274
|
def start_new_search_session?
|
286
275
|
action_name == "index"
|
@@ -293,7 +282,7 @@ module Blacklight::Catalog
|
|
293
282
|
def blacklight_advanced_search_form_search_service
|
294
283
|
form_search_state = search_state_class.new(blacklight_advanced_search_form_params, blacklight_config, self)
|
295
284
|
|
296
|
-
search_service_class.new(config: blacklight_config, search_state: form_search_state,
|
285
|
+
search_service_class.new(config: blacklight_config, search_state: form_search_state, **search_service_context)
|
297
286
|
end
|
298
287
|
|
299
288
|
def blacklight_advanced_search_form_params
|
@@ -130,7 +130,7 @@ module Blacklight::Controller
|
|
130
130
|
# send the user home if the access was previously denied by the same
|
131
131
|
# request to avoid sending the user back to the login page
|
132
132
|
# (e.g. protected page -> logout -> returned to protected page -> home)
|
133
|
-
redirect_to(root_url) && flash.discard && return if request.referer
|
133
|
+
redirect_to(root_url) && flash.discard && return if request.referer&.ends_with?(request.fullpath)
|
134
134
|
|
135
135
|
redirect_to(root_url) && return unless has_user_authentication_provider?
|
136
136
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The Facetable module can be included onto classes that need to initialize a FacetSearchService.
|
4
|
+
# There are two dependencies you must provide on the including class. Typically these
|
5
|
+
# would be provided by Blacklight::Controller
|
6
|
+
# 1. search_state
|
7
|
+
# 2. blacklight_config
|
8
|
+
#
|
9
|
+
# Additionally, the including class may override the facet_search_service_context method to provide
|
10
|
+
# further context to the SearchService. For example you could override this to provide the
|
11
|
+
# currently signed in user.
|
12
|
+
module Blacklight::Facetable
|
13
|
+
extend ActiveSupport::Concern
|
14
|
+
|
15
|
+
included do
|
16
|
+
# Which class to use for the search service. You can subclass SearchService if you
|
17
|
+
# want to override any of the methods (e.g. SearchService#fetch)
|
18
|
+
class_attribute :facet_search_service_class
|
19
|
+
self.facet_search_service_class = Blacklight::FacetSearchService
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Blacklight::FacetSearchService]
|
23
|
+
def facet_search_service
|
24
|
+
facet_search_service_class.new(config: blacklight_config, search_state: search_state, user_params: search_state.to_h, **facet_search_service_context)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Override this method on the class that includes Blacklight::Facetable to provide more context to the search service if necessary.
|
28
|
+
# For example, if your search builder needs to be aware of the current user, override this method to return a hash including the current user.
|
29
|
+
# Then the search builder could use some property about the current user to construct a constraint on the search.
|
30
|
+
# @return [Hash] a hash of context information to pass through to the search service
|
31
|
+
def facet_search_service_context
|
32
|
+
search_service_context
|
33
|
+
end
|
34
|
+
end
|
@@ -40,7 +40,7 @@ module Blacklight::SearchContext
|
|
40
40
|
@page_link_data[:prev] = page_links_document_path(documents.first, index)
|
41
41
|
@page_link_data[:next] = page_links_document_path(documents.last, index + 2)
|
42
42
|
end
|
43
|
-
if response&.total
|
43
|
+
if response&.total&.positive?
|
44
44
|
@page_link_data[:counterRaw] = counter_param
|
45
45
|
@page_link_data[:counterDelimited] = helpers.number_with_delimiter(counter_param.to_i)
|
46
46
|
@page_link_data[:totalRaw] = response.total
|
@@ -21,7 +21,7 @@ module Blacklight::Searchable
|
|
21
21
|
|
22
22
|
# @return [Blacklight::SearchService]
|
23
23
|
def search_service
|
24
|
-
search_service_class.new(config: blacklight_config, search_state: search_state,
|
24
|
+
search_service_class.new(config: blacklight_config, search_state: search_state, **search_service_context)
|
25
25
|
end
|
26
26
|
|
27
27
|
# Override this method on the class that includes Blacklight::Searchable to provide more context to the search service if necessary.
|
@@ -169,7 +169,7 @@ module Blacklight::CatalogHelperBehavior
|
|
169
169
|
constraints += search_state.filters.collect { |filter| render_search_to_page_title_filter(filter.key, filter.values) }
|
170
170
|
end
|
171
171
|
|
172
|
-
constraints.join('
|
172
|
+
constraints.join(t('blacklight.search.page_title.joiner'))
|
173
173
|
end
|
174
174
|
|
175
175
|
##
|
@@ -96,7 +96,7 @@ module Blacklight::ConfigurationHelperBehavior
|
|
96
96
|
#
|
97
97
|
# @param [Blacklight::Solr::Configuration::Field] field_config
|
98
98
|
# @return [Boolean]
|
99
|
-
def should_render_field?(field_config, *
|
100
|
-
blacklight_configuration_context.evaluate_if_unless_configuration
|
99
|
+
def should_render_field?(field_config, *)
|
100
|
+
blacklight_configuration_context.evaluate_if_unless_configuration(field_config, *)
|
101
101
|
end
|
102
102
|
end
|
@@ -38,10 +38,12 @@ module Blacklight::DocumentHelperBehavior
|
|
38
38
|
|
39
39
|
##
|
40
40
|
# Check if the document is in the user's bookmarks
|
41
|
+
# Note: we do string comparison of the classes, because hot reloading in the development environment may cause each to have
|
42
|
+
# separate versions of the class loaded (see document.class.object_id and Bookmark#document_type.object_id)
|
41
43
|
# @param [Blacklight::Document] document
|
42
44
|
# @return [Boolean]
|
43
45
|
def bookmarked? document
|
44
|
-
current_bookmarks.any? { |x| x.document_id == document.id && x.document_type == document.class }
|
46
|
+
current_bookmarks.any? { |x| x.document_id == document.id && x.document_type.to_s == document.class.to_s }
|
45
47
|
end
|
46
48
|
|
47
49
|
##
|
@@ -7,6 +7,15 @@ module Blacklight::FacetsHelperBehavior
|
|
7
7
|
facet_config.presenter.new(facet_config, display_facet, self)
|
8
8
|
end
|
9
9
|
|
10
|
+
def search_facet_path(options = {})
|
11
|
+
opts = search_state
|
12
|
+
.to_h
|
13
|
+
.merge(action: "facet", only_path: true)
|
14
|
+
.merge(options)
|
15
|
+
.except(:page)
|
16
|
+
url_for opts
|
17
|
+
end
|
18
|
+
|
10
19
|
private
|
11
20
|
|
12
21
|
def facet_value_for_facet_item item
|
@@ -7,7 +7,7 @@ module Blacklight::IconHelperBehavior
|
|
7
7
|
# Returns the raw SVG (String) for a Blacklight Icon
|
8
8
|
# @param [String, Symbol] icon_name
|
9
9
|
# @return [String]
|
10
|
-
def blacklight_icon(icon_name, **
|
11
|
-
render "Blacklight::Icons::#{icon_name.to_s.camelize}Component".constantize.new(**
|
10
|
+
def blacklight_icon(icon_name, **)
|
11
|
+
render "Blacklight::Icons::#{icon_name.to_s.camelize}Component".constantize.new(**)
|
12
12
|
end
|
13
13
|
end
|
@@ -1,12 +1,17 @@
|
|
1
1
|
import CheckboxSubmit from 'blacklight-frontend/checkbox_submit'
|
2
2
|
|
3
3
|
const BookmarkToggle = (e) => {
|
4
|
-
|
5
|
-
|
4
|
+
const elementType = e.target.getAttribute('data-checkboxsubmit-target');
|
5
|
+
if (elementType == 'checkbox' || elementType == 'label') {
|
6
|
+
const form = e.target.closest('form');
|
6
7
|
if (form) new CheckboxSubmit(form).clicked(e);
|
8
|
+
if (e.code == 'Space') e.preventDefault();
|
7
9
|
}
|
8
10
|
};
|
9
11
|
|
10
12
|
document.addEventListener('click', BookmarkToggle);
|
13
|
+
document.addEventListener('keydown', function (e) {
|
14
|
+
if (e.key === 'Enter' || e.code == 'Space') { BookmarkToggle(e); } }
|
15
|
+
);
|
11
16
|
|
12
17
|
export default BookmarkToggle
|