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.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. data/.github/matrix.json +47 -0
  3. data/.github/workflows/build.yml +16 -0
  4. data/.github/workflows/lint.yml +25 -0
  5. data/.github/workflows/main.yml +22 -0
  6. data/.github/workflows/release_7_x_scheduled.yml +39 -0
  7. data/.github/workflows/release_8_x_scheduled.yml +39 -0
  8. data/.github/workflows/test.yml +53 -0
  9. data/.rubocop.yml +70 -2
  10. data/.rubocop_todo.yml +43 -67
  11. data/.solr_wrapper.yml +2 -0
  12. data/VERSION +1 -1
  13. data/app/assets/builds/blacklight.css +19 -15
  14. data/app/assets/javascripts/blacklight/blacklight.esm.js +31 -69
  15. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  16. data/app/assets/javascripts/blacklight/blacklight.js +31 -69
  17. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  18. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +4 -0
  19. data/app/assets/stylesheets/blacklight/_facets.scss +2 -2
  20. data/app/assets/stylesheets/blacklight/_header.scss +4 -0
  21. data/app/assets/stylesheets/blacklight/_modal.scss +9 -8
  22. data/app/assets/stylesheets/blacklight/_pagination.scss +1 -3
  23. data/app/assets/stylesheets/blacklight/_search_history.scss +0 -4
  24. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +3 -0
  25. data/app/components/blacklight/advanced_search_form_component.rb +2 -2
  26. data/app/components/blacklight/constraints_component.rb +2 -2
  27. data/app/components/blacklight/document/action_component.rb +1 -3
  28. data/app/components/blacklight/document/bookmark_component.rb +2 -2
  29. data/app/components/blacklight/document/more_like_this_component.rb +2 -2
  30. data/app/components/blacklight/document/page_header_component.rb +2 -2
  31. data/app/components/blacklight/document/thumbnail_component.html.erb +3 -7
  32. data/app/components/blacklight/document/thumbnail_component.rb +7 -6
  33. data/app/components/blacklight/document_component.rb +3 -3
  34. data/app/components/blacklight/document_title_component.rb +3 -10
  35. data/app/components/blacklight/facet_field_checkboxes_component.rb +2 -20
  36. data/app/components/blacklight/facet_field_component.rb +2 -17
  37. data/app/components/blacklight/facet_field_filter_component.rb +2 -21
  38. data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +4 -25
  39. data/app/components/blacklight/facet_field_list_component.rb +2 -32
  40. data/app/components/blacklight/facet_field_no_layout_component.rb +2 -10
  41. data/app/components/blacklight/facet_field_pagination_component.html.erb +2 -2
  42. data/app/components/blacklight/facet_item_component.rb +2 -74
  43. data/app/components/blacklight/facet_item_pivot_component.rb +1 -1
  44. data/app/components/blacklight/facets/checkboxes_component.rb +26 -0
  45. data/app/components/blacklight/facets/count_component.rb +23 -0
  46. data/app/components/blacklight/{facet_field_component.html.erb → facets/field_component.html.erb} +1 -1
  47. data/app/components/blacklight/facets/field_component.rb +23 -0
  48. data/app/components/blacklight/facets/filters_component.html.erb +4 -0
  49. data/app/components/blacklight/facets/filters_component.rb +27 -0
  50. data/app/components/blacklight/{facet_field_inclusive_constraint_component.html.erb → facets/inclusive_constraint_component.html.erb} +1 -1
  51. data/app/components/blacklight/facets/inclusive_constraint_component.rb +31 -0
  52. data/app/components/blacklight/{facet_field_filter_component.html.erb → facets/index_navigation_component.html.erb} +1 -1
  53. data/app/components/blacklight/facets/index_navigation_component.rb +32 -0
  54. data/app/components/blacklight/facets/item_component.rb +73 -0
  55. data/app/components/blacklight/facets/list_component.html.erb +11 -0
  56. data/app/components/blacklight/facets/list_component.rb +38 -0
  57. data/app/components/blacklight/facets/no_layout_component.rb +16 -0
  58. data/app/components/blacklight/facets/selected_value_component.rb +29 -0
  59. data/app/components/blacklight/facets/suggest_component.html.erb +12 -0
  60. data/app/components/blacklight/facets/suggest_component.rb +22 -0
  61. data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +2 -2
  62. data/app/components/blacklight/response/facet_group_component.html.erb +1 -1
  63. data/app/components/blacklight/response/facet_group_component.rb +5 -1
  64. data/app/components/blacklight/system/dropdown_component.html.erb +1 -1
  65. data/app/components/blacklight/system/dropdown_component.rb +1 -1
  66. data/app/components/blacklight/top_navbar_component.html.erb +1 -1
  67. data/app/controllers/concerns/blacklight/bookmarks.rb +3 -3
  68. data/app/controllers/concerns/blacklight/catalog.rb +10 -25
  69. data/app/controllers/concerns/blacklight/controller.rb +1 -1
  70. data/app/controllers/concerns/blacklight/facetable.rb +34 -0
  71. data/app/controllers/concerns/blacklight/search_context.rb +1 -1
  72. data/app/controllers/concerns/blacklight/searchable.rb +1 -1
  73. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -2
  74. data/app/helpers/blacklight/document_helper_behavior.rb +3 -1
  75. data/app/helpers/blacklight/facets_helper_behavior.rb +9 -0
  76. data/app/helpers/blacklight/icon_helper_behavior.rb +2 -2
  77. data/app/javascript/blacklight-frontend/checkbox_submit.js +3 -0
  78. data/app/javascript/blacklight-frontend/debounce.js +1 -1
  79. data/app/javascript/blacklight-frontend/facet_suggest.js +23 -3
  80. data/app/javascript/blacklight-frontend/index.js +0 -2
  81. data/app/javascript/blacklight-frontend/modal.js +1 -4
  82. data/app/javascript/blacklight-frontend/search_context.js +3 -2
  83. data/app/models/facet_search_builder.rb +5 -0
  84. data/app/presenters/blacklight/facet_field_presenter.rb +1 -1
  85. data/app/presenters/blacklight/json_presenter.rb +1 -3
  86. data/app/presenters/blacklight/rendering/helper_method.rb +4 -4
  87. data/app/presenters/blacklight/rendering/join.rb +2 -2
  88. data/app/services/blacklight/facet_search_service.rb +44 -0
  89. data/app/services/blacklight/field_retriever.rb +1 -1
  90. data/app/services/blacklight/search_service.rb +6 -6
  91. data/app/values/blacklight/types.rb +2 -2
  92. data/app/views/catalog/_facet_pivot.html.erb +1 -1
  93. data/app/views/catalog/_home_text.html.erb +2 -2
  94. data/app/views/catalog/_sort_and_per_page.html.erb +1 -1
  95. data/app/views/catalog/facet.html.erb +8 -10
  96. data/config/locales/blacklight.ar.yml +2 -2
  97. data/config/locales/blacklight.es.yml +2 -2
  98. data/config/locales/blacklight.fr.yml +2 -2
  99. data/config/locales/blacklight.hu.yml +2 -2
  100. data/config/locales/blacklight.it.yml +2 -2
  101. data/config/locales/blacklight.nl.yml +1 -1
  102. data/config/locales/blacklight.pt-BR.yml +2 -2
  103. data/config/locales/blacklight.sq.yml +2 -2
  104. data/config/locales/blacklight.zh.yml +2 -2
  105. data/lib/blacklight/abstract_repository.rb +2 -2
  106. data/lib/blacklight/abstract_search_builder.rb +154 -0
  107. data/lib/blacklight/configuration/context.rb +3 -3
  108. data/lib/blacklight/configuration/facet_field.rb +6 -6
  109. data/lib/blacklight/configuration/field.rb +4 -4
  110. data/lib/blacklight/configuration/fields.rb +0 -1
  111. data/lib/blacklight/configuration/search_field.rb +1 -1
  112. data/lib/blacklight/configuration/view_config.rb +2 -2
  113. data/lib/blacklight/configuration.rb +6 -7
  114. data/lib/blacklight/facet_search_builder.rb +18 -0
  115. data/lib/blacklight/nested_open_struct_with_hash_access.rb +1 -1
  116. data/lib/blacklight/open_struct_with_hash_access.rb +2 -2
  117. data/lib/blacklight/search_builder.rb +1 -159
  118. data/lib/blacklight/search_state/filter_field.rb +4 -4
  119. data/lib/blacklight/search_state/pivot_filter_field.rb +4 -4
  120. data/lib/blacklight/solr/abstract_filter_query_builder.rb +77 -0
  121. data/lib/blacklight/solr/default_filter_query_builder.rb +20 -0
  122. data/lib/blacklight/solr/facet_search_builder_behavior.rb +62 -0
  123. data/lib/blacklight/solr/repository.rb +8 -9
  124. data/lib/blacklight/solr/response/facets.rb +2 -2
  125. data/lib/blacklight/solr/response/params.rb +0 -4
  126. data/lib/blacklight/solr/response.rb +5 -1
  127. data/lib/blacklight/solr/search_builder_behavior.rb +17 -132
  128. data/lib/blacklight.rb +1 -1
  129. data/lib/generators/blacklight/assets/importmap_generator.rb +3 -5
  130. data/lib/generators/blacklight/assets_generator.rb +1 -1
  131. data/lib/generators/blacklight/search_builder_generator.rb +1 -1
  132. data/lib/generators/blacklight/templates/.solr_wrapper.yml +2 -0
  133. data/lib/generators/blacklight/templates/catalog_controller.rb +3 -1
  134. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +0 -4
  135. data/package.json +3 -3
  136. data/spec/components/blacklight/advanced_search_form_component_spec.rb +18 -22
  137. data/spec/components/blacklight/constraint_layout_component_spec.rb +8 -8
  138. data/spec/components/blacklight/constraints_component_spec.rb +11 -11
  139. data/spec/components/blacklight/document/action_component_spec.rb +23 -15
  140. data/spec/components/blacklight/document/group_component_spec.rb +10 -15
  141. data/spec/components/blacklight/document/page_header_component_spec.rb +35 -28
  142. data/spec/components/blacklight/document/sidebar_component_spec.rb +5 -11
  143. data/spec/components/blacklight/document_component_spec.rb +98 -65
  144. data/spec/components/blacklight/facet_component_spec.rb +12 -8
  145. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +12 -12
  146. data/spec/components/blacklight/{facet_field_checkboxes_component_spec.rb → facets/checkboxes_component_spec.rb} +13 -13
  147. data/spec/components/blacklight/facets/filters_component_spec.rb +36 -0
  148. data/spec/components/blacklight/facets/index_navigation_component_spec.rb +40 -0
  149. data/spec/components/blacklight/{facet_item_component_spec.rb → facets/item_component_spec.rb} +10 -10
  150. data/spec/components/blacklight/{facet_field_list_component_spec.rb → facets/list_component_spec.rb} +23 -23
  151. data/spec/components/blacklight/facets/suggest_component_spec.rb +68 -0
  152. data/spec/components/blacklight/header_component_spec.rb +2 -4
  153. data/spec/components/blacklight/hidden_search_state_component_spec.rb +7 -7
  154. data/spec/components/blacklight/metadata_field_component_spec.rb +17 -15
  155. data/spec/components/blacklight/response/facet_group_component_spec.rb +37 -0
  156. data/spec/components/blacklight/response/pagination_component_spec.rb +1 -1
  157. data/spec/components/blacklight/response/spellcheck_component_spec.rb +1 -1
  158. data/spec/components/blacklight/search_bar_component_spec.rb +4 -4
  159. data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +2 -2
  160. data/spec/components/blacklight/search_context/server_item_pagination_component_spec.rb +3 -5
  161. data/spec/components/blacklight/skip_link_component_spec.rb +8 -11
  162. data/spec/components/blacklight/start_over_button_component_spec.rb +4 -4
  163. data/spec/components/blacklight/system/dropdown_component_spec.rb +26 -0
  164. data/spec/components/blacklight/system/flash_message_component_spec.rb +7 -11
  165. data/spec/controllers/catalog_controller_spec.rb +12 -20
  166. data/spec/features/facets_spec.rb +70 -7
  167. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +10 -0
  168. data/spec/lib/blacklight/configuration/facet_field_spec.rb +2 -2
  169. data/spec/lib/blacklight/parameters_spec.rb +12 -1
  170. data/spec/lib/blacklight/search_state/filter_field_spec.rb +18 -0
  171. data/spec/models/blacklight/configuration_spec.rb +32 -28
  172. data/spec/models/blacklight/facet_search_builder_spec.rb +19 -0
  173. data/spec/models/blacklight/search_builder_spec.rb +1 -11
  174. data/spec/models/blacklight/solr/default_filter_query_builder_spec.rb +72 -0
  175. data/spec/models/blacklight/solr/document_spec.rb +0 -4
  176. data/spec/models/blacklight/solr/facet_search_builder_behavior_spec.rb +929 -0
  177. data/spec/models/blacklight/solr/repository_spec.rb +31 -29
  178. data/spec/models/blacklight/solr/response/facets_spec.rb +86 -40
  179. data/spec/models/blacklight/solr/response/group_response_spec.rb +8 -5
  180. data/spec/models/blacklight/solr/response/group_spec.rb +9 -5
  181. data/spec/models/blacklight/solr/response_spec.rb +96 -64
  182. data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +2 -227
  183. data/spec/models/solr_document_spec.rb +5 -1
  184. data/spec/services/blacklight/search_service_spec.rb +6 -27
  185. data/spec/spec_helper.rb +0 -1
  186. data/spec/support/view_component_test_helpers.rb +0 -18
  187. data/spec/views/catalog/facet.html.erb_spec.rb +10 -3
  188. data/spec/views/catalog/index.atom.builder_spec.rb +6 -3
  189. data/spec/views/catalog/index.html.erb_spec.rb +3 -1
  190. metadata +58 -29
  191. data/.github/workflows/ruby.yml +0 -98
  192. data/app/components/blacklight/facet_field_list_component.html.erb +0 -19
  193. data/app/components/blacklight/search/facet_suggest_input.html.erb +0 -9
  194. data/app/components/blacklight/search/facet_suggest_input.rb +0 -16
  195. data/app/javascript/blacklight-frontend/modalForm.js +0 -60
  196. data/app/views/catalog/_facet_index_navigation.html.erb +0 -1
  197. data/app/views/catalog/_facet_layout.html.erb +0 -8
  198. data/app/views/catalog/_facet_pagination.html.erb +0 -1
  199. data/spec/components/blacklight/document_metadata_component_spec.rb +0 -0
  200. data/spec/components/blacklight/search/facet_suggest_input_spec.rb +0 -33
  201. data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +0 -43
  202. data/spec/views/catalog/_facet_layout.html.erb_spec.rb +0 -41
  203. /data/app/components/blacklight/{facet_field_checkboxes_component.html.erb → facets/checkboxes_component.html.erb} +0 -0
@@ -1,14 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Blacklight
4
- class FacetFieldNoLayoutComponent < Blacklight::Component
5
- renders_one :label
6
- renders_one :body
7
-
8
- def initialize(**); end
9
-
10
- def call
11
- body.to_s
12
- end
13
- end
4
+ class FacetFieldNoLayoutComponent < Facets::NoLayoutComponent; end
5
+ FacetFieldNoLayoutComponent = ActiveSupport::Deprecation::DeprecatedConstantProxy.new("FacetFieldNoLayoutComponent", "Blacklight::Facets::NoLayoutComponent", ActiveSupport::Deprecation.new)
14
6
  end
@@ -1,10 +1,10 @@
1
1
  <div class="prev_next_links btn-group">
2
2
  <%= helpers.link_to_previous_page @facet_field.paginator, raw(t('views.pagination.previous')), params: @facet_field.search_state.to_h, param_name: param_name, class: 'btn btn-link', data: { blacklight_modal: "preserve" } do %>
3
- <%= content_tag :span, raw(t('views.pagination.previous')), class: 'disabled btn' %>
3
+ <%= content_tag :a, raw(t('views.pagination.previous')), class: 'disabled btn btn-link text-decoration-none', aria: { disabled: true } %>
4
4
  <% end %>
5
5
 
6
6
  <%= helpers.link_to_next_page @facet_field.paginator, raw(t('views.pagination.next')), params: @facet_field.search_state.to_h, param_name: param_name, class: 'btn btn-link', data: { blacklight_modal: "preserve" } do %>
7
- <%= content_tag :span, raw(t('views.pagination.next')), class: 'disabled btn' %>
7
+ <%= content_tag :a, raw(t('views.pagination.next')), class: 'disabled btn btn-link text-decoration-none', aria: { disabled: true } %>
8
8
  <% end %>
9
9
  </div>
10
10
 
@@ -1,78 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Blacklight
4
- class FacetItemComponent < Blacklight::Component
5
- attr_reader :label, :href, :hits
6
-
7
- with_collection_parameter :facet_item
8
-
9
- def initialize(facet_item:, wrapping_element: 'li', suppress_link: false)
10
- @facet_item = facet_item
11
- @label = facet_item.label
12
- @hits = facet_item.hits
13
- @href = facet_item.href
14
- @selected = facet_item.selected?
15
- @wrapping_element = wrapping_element
16
- @suppress_link = suppress_link
17
- end
18
-
19
- def call
20
- # if the downstream app has overridden the helper methods we'd usually call,
21
- # use the helpers to preserve compatibility
22
- content = if @selected
23
- render_selected_facet_value
24
- else
25
- render_facet_value
26
- end
27
-
28
- return '' if content.blank?
29
- return content unless @wrapping_element
30
-
31
- content_tag @wrapping_element, content
32
- end
33
-
34
- ##
35
- # Standard display of a facet value in a list. Used in both _facets sidebar
36
- # partial and catalog/facet expanded list. Will output facet value name as
37
- # a link to add that to your restrictions, with count in parens.
38
- #
39
- # @return [String]
40
- # @private
41
- def render_facet_value
42
- tag.span(class: "facet-label") do
43
- link_to_unless(@suppress_link, label, href, class: "facet-select", rel: "nofollow")
44
- end + render_facet_count
45
- end
46
-
47
- ##
48
- # Standard display of a SELECTED facet value (e.g. without a link and with a remove button)
49
- # @see #render_facet_value
50
- #
51
- # @private
52
- def render_selected_facet_value
53
- tag.span(class: "facet-label") do
54
- tag.span(label, class: "selected") +
55
- # remove link
56
- link_to(href, class: "remove", rel: "nofollow") do
57
- render(Blacklight::Icons::RemoveComponent.new(aria_hidden: true)) +
58
- tag.span(helpers.t(:'blacklight.search.facets.selected.remove'), class: 'visually-hidden')
59
- end
60
- end + render_facet_count(classes: ["selected"])
61
- end
62
-
63
- ##
64
- # Renders a count value for facet limits. Can be over-ridden locally
65
- # to change style. And can be called by plugins to get consistent display.
66
- #
67
- # @param [Hash] options
68
- # @option options [Array<String>] an array of classes to add to count span.
69
- # @return [String]
70
- # @private
71
- def render_facet_count(options = {})
72
- return '' if hits.blank?
73
-
74
- classes = (options[:classes] || []) << "facet-count"
75
- tag.span(t('blacklight.search.facets.count', number: number_with_delimiter(hits)), class: classes)
76
- end
77
- end
4
+ class FacetItemComponent < Facets::ItemComponent; end
5
+ FacetItemComponent = ActiveSupport::Deprecation::DeprecatedConstantProxy.new("FacetItemComponent", "Blacklight::Facets::ItemComponent", ActiveSupport::Deprecation.new)
78
6
  end
@@ -28,7 +28,7 @@ module Blacklight
28
28
  end
29
29
 
30
30
  def call
31
- facet = Blacklight::FacetItemComponent.new(facet_item: @facet_item, wrapping_element: nil, suppress_link: @suppress_link)
31
+ facet = Blacklight::Facets::ItemComponent.new(facet_item: @facet_item, wrapping_element: nil, suppress_link: @suppress_link)
32
32
 
33
33
  id = "h-#{self.class.mint_id}" if @collapsing && has_items?
34
34
 
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Facets
5
+ class CheckboxesComponent < 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
+ def render?
12
+ presenters.any?
13
+ end
14
+
15
+ def presenters
16
+ return [] unless @facet_field.paginator
17
+
18
+ return to_enum(:presenters) unless block_given?
19
+
20
+ @facet_field.paginator.items.each do |item|
21
+ yield Blacklight::FacetCheckboxItemPresenter.new(item, @facet_field.facet_field, helpers, @facet_field.key, @facet_field.search_state)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Facets
5
+ # Display count of a facet value
6
+ class CountComponent < Blacklight::Component
7
+ def initialize(hits:, classes:)
8
+ @hits = hits
9
+ @classes = classes
10
+ end
11
+
12
+ attr_reader :hits, :classes
13
+
14
+ def render?
15
+ hits.present?
16
+ end
17
+
18
+ def call
19
+ tag.span(t('blacklight.search.facets.count', number: number_with_delimiter(hits)), class: classes)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -8,7 +8,7 @@
8
8
  data-target="#<%= html_id %>"
9
9
  data-bs-target="#<%= html_id %>"
10
10
  aria-expanded="<%= @facet_field.collapsed? ? 'false' : 'true' %>"
11
- arial-controls="<%= html_id %>"
11
+ aria-controls="<%= html_id %>"
12
12
  >
13
13
  <%= label %>
14
14
  </button>
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Facets
5
+ class FieldComponent < Blacklight::Component
6
+ renders_one :label
7
+ renders_one :body
8
+
9
+ # @param [Blacklight::FacetFieldPresenter] facet_field
10
+ def initialize(facet_field:)
11
+ @facet_field = facet_field
12
+ end
13
+
14
+ def html_id
15
+ "facet-#{@facet_field.key.parameterize}"
16
+ end
17
+
18
+ def header_html_id
19
+ "#{html_id}-header"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ <div class="<%= classes %>">
2
+ <%= render Blacklight::Facets::SuggestComponent.new(presenter: presenter) %>
3
+ <%= render Blacklight::Facets::IndexNavigationComponent.new(presenter: presenter) %>
4
+ </div>
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight::Facets
4
+ class FiltersComponent < Blacklight::Component
5
+ # @param [Blacklight::FacetFieldPresenter] presenter
6
+ def initialize(presenter:, classes: 'facet-filters card card-body bg-light p-3 mb-3 border-0')
7
+ @presenter = presenter
8
+ @classes = classes
9
+ end
10
+
11
+ def facet
12
+ @presenter.facet_field
13
+ end
14
+
15
+ attr_reader :classes, :presenter
16
+
17
+ delegate :display_facet, to: :presenter
18
+
19
+ def render?
20
+ facet.suggest != false || render_index_navigation?
21
+ end
22
+
23
+ def render_index_navigation?
24
+ facet.index_range && display_facet.index?
25
+ end
26
+ end
27
+ end
@@ -1,6 +1,6 @@
1
1
  <div class="inclusive_or card card-body bg-light mb-3">
2
2
  <h5><%= t('blacklight.advanced_search.any_of') %></h5>
3
3
  <ul class="list-unstyled facet-values">
4
- <%= render(Blacklight::FacetItemComponent.with_collection(presenters.to_a)) %>
4
+ <%= render Blacklight::Facets::ItemComponent.with_collection(presenters.to_a) %>
5
5
  </ul>
6
6
  </div>
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Facets
5
+ class InclusiveConstraintComponent < Blacklight::Component
6
+ with_collection_parameter :facet_field
7
+
8
+ def initialize(facet_field:, values: nil)
9
+ @facet_field = facet_field
10
+ @values = values
11
+ end
12
+
13
+ def values
14
+ @values ||= @facet_field.values.find { |v| v.is_a? Array }
15
+ @values || []
16
+ end
17
+
18
+ def render?
19
+ values.present?
20
+ end
21
+
22
+ def presenters
23
+ return to_enum(:presenters) unless block_given?
24
+
25
+ values.each do |item|
26
+ yield Blacklight::FacetGroupedItemPresenter.new(values, item, @facet_field.facet_field, helpers, @facet_field.key, @facet_field.search_state)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -3,7 +3,7 @@
3
3
  <li class="page-item <%= 'active' if prefix.blank? %>">
4
4
  <%= link_to t('blacklight.search.facets.all'), clear_facet_prefix_url, data: { blacklight_modal: "preserve" }, class: 'page-link' %>
5
5
  </li>
6
- <% @facet_field.facet_field.index_range.each do |letter| %>
6
+ <% index_range.each do |letter| %>
7
7
  <li class="page-item <%= 'active' if prefix == letter %>">
8
8
  <%= link_to(letter, facet_prefix_url(letter), class: 'page-link', data: { blacklight_modal: "preserve" }) %>
9
9
  </li>
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Facets
5
+ class IndexNavigationComponent < Blacklight::Component
6
+ # @params [Blacklight::FacetFieldPresenter] presenter
7
+ def initialize(presenter:)
8
+ @presenter = presenter
9
+ end
10
+
11
+ def render?
12
+ index_range && @presenter.display_facet.index?
13
+ end
14
+
15
+ def index_range
16
+ @presenter.facet_field.index_range
17
+ end
18
+
19
+ def prefix
20
+ @presenter.paginator.prefix
21
+ end
22
+
23
+ def clear_facet_prefix_url
24
+ @presenter.paginator.params_for_resort_url('index', @presenter.search_state.to_h.except(@presenter.paginator.request_keys[:prefix]))
25
+ end
26
+
27
+ def facet_prefix_url(letter)
28
+ @presenter.paginator.params_for_resort_url('index', @presenter.search_state.to_h.merge(@presenter.paginator.request_keys[:prefix] => letter))
29
+ end
30
+ end
31
+ end
32
+ end
@@ -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,38 @@
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
+ def facet_items(wrapping_element: :li, **item_args)
12
+ facet_item_component_class.with_collection(facet_item_presenters, wrapping_element: wrapping_element, **item_args)
13
+ end
14
+
15
+ def facet_item_presenters
16
+ @facet_field.paginator.items.map do |item|
17
+ facet_item_presenter(item)
18
+ end
19
+ end
20
+
21
+ def render?
22
+ @facet_field.paginator&.items&.any?
23
+ end
24
+
25
+ def facet_item_presenter(facet_item)
26
+ facet_config.item_presenter.new(facet_item, facet_config, helpers, @facet_field.key)
27
+ end
28
+
29
+ def facet_item_component_class
30
+ facet_config.item_component
31
+ end
32
+
33
+ def facet_config
34
+ @facet_field.facet_field
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Facets
5
+ class NoLayoutComponent < Blacklight::Component
6
+ renders_one :label
7
+ renders_one :body
8
+
9
+ def initialize(**); end
10
+
11
+ def call
12
+ body.to_s
13
+ end
14
+ end
15
+ end
16
+ 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
@@ -4,8 +4,8 @@ module Blacklight
4
4
  class MetadataFieldPlainTextLayoutComponent < Blacklight::MetadataFieldLayoutComponent
5
5
  with_collection_parameter :field
6
6
 
7
- def initialize(field:, **kwargs)
8
- super(field: field, **kwargs, value_tag: nil)
7
+ def initialize(field:, **)
8
+ super(field: field, **, value_tag: nil)
9
9
  end
10
10
 
11
11
  # rubocop:disable Rails/OutputSafety
@@ -6,7 +6,7 @@
6
6
  <%= collapse_toggle_button(@panel_id) %>
7
7
  </div>
8
8
 
9
- <div id="<%= @panel_id %>" class="facets-collapse d-lg-block collapse accordion">
9
+ <div id="<%= @panel_id %>" class="<%= body_classes %>">
10
10
  <%= body %>
11
11
  </div>
12
12
  <% end %>
@@ -8,13 +8,16 @@ 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
12
  @groupname = id
13
13
  @id = id ? "facets-#{id}" : 'facets'
14
14
  @title = title || I18n.t("blacklight.search.#{@id}.title")
15
15
  @panel_id = id ? "facet-panel-#{id}-collapse" : 'facet-panel-collapse'
16
+ @body_classes = body_classes
16
17
  end
17
18
 
19
+ attr_accessor :body_classes
20
+
18
21
  def collapse_toggle_button(panel_id)
19
22
  render button_component.new(panel_id: panel_id)
20
23
  end
@@ -24,6 +27,7 @@ module Blacklight
24
27
  end
25
28
 
26
29
  def render?
30
+ # debugger
27
31
  body.present?
28
32
  end
29
33
  end
@@ -1,7 +1,7 @@
1
1
  <%= content_tag :div, id: @id, class: @classes.join(' ') do %>
2
2
  <%= button %>
3
3
 
4
- <div class="dropdown-menu" role="menu">
4
+ <div class="dropdown-menu">
5
5
  <% options.each do |option| %>
6
6
  <%= option %>
7
7
  <% 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}", role: 'menuitem', aria: { current: ('page' 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,4 +1,4 @@
1
- <nav class="navbar navbar-expand-md navbar-dark bg-dark topbar" aria-label="<%= aria_label %>">
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 *args
40
- search_catalog_url(*args)
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 && bookmark.delete && bookmark.destroyed?
113
+ bookmark&.delete && bookmark.destroyed?
114
114
  end
115
115
 
116
116
  if success