blacklight 8.2.2 → 8.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (225) hide show
  1. checksums.yaml +4 -4
  2. data/.env +1 -1
  3. data/.github/workflows/ruby.yml +60 -62
  4. data/.rubocop.yml +229 -21
  5. data/.rubocop_todo.yml +22 -55
  6. data/Gemfile +2 -10
  7. data/README.md +2 -2
  8. data/VERSION +1 -1
  9. data/app/assets/javascripts/blacklight/blacklight.esm.js +5 -1
  10. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  11. data/app/assets/javascripts/blacklight/blacklight.js +5 -1
  12. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  13. data/app/assets/stylesheets/blacklight/_balanced_list.scss +1 -1
  14. data/app/assets/stylesheets/blacklight/_bookmark.scss +30 -0
  15. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +0 -4
  16. data/app/assets/stylesheets/blacklight/_constraints.scss +15 -9
  17. data/app/assets/stylesheets/blacklight/_controls.scss +0 -1
  18. data/app/assets/stylesheets/blacklight/_facets.scss +33 -37
  19. data/app/assets/stylesheets/blacklight/_header.scss +2 -35
  20. data/app/assets/stylesheets/blacklight/_icons.scss +3 -2
  21. data/app/assets/stylesheets/blacklight/_layout.scss +3 -0
  22. data/app/assets/stylesheets/blacklight/_mixins.scss +6 -21
  23. data/app/assets/stylesheets/blacklight/_search_form.scss +3 -8
  24. data/app/assets/stylesheets/blacklight/_search_history.scss +5 -5
  25. data/app/assets/stylesheets/blacklight/_search_results.scss +5 -2
  26. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +16 -10
  27. data/app/components/blacklight/advanced_search_form_component.html.erb +1 -1
  28. data/app/components/blacklight/advanced_search_form_component.rb +6 -0
  29. data/app/components/blacklight/constraint_layout_component.html.erb +2 -9
  30. data/app/components/blacklight/constraint_layout_component.rb +8 -0
  31. data/app/components/blacklight/constraints_component.rb +3 -3
  32. data/app/components/blacklight/document/action_component.rb +2 -1
  33. data/app/components/blacklight/document/bookmark_component.html.erb +2 -1
  34. data/app/components/blacklight/document/bookmark_component.rb +6 -0
  35. data/app/components/blacklight/document/page_header_component.html.erb +7 -0
  36. data/app/components/blacklight/document/page_header_component.rb +85 -0
  37. data/app/components/blacklight/document_component.rb +1 -1
  38. data/app/components/blacklight/facet_component.rb +1 -1
  39. data/app/components/blacklight/facet_field_checkboxes_component.html.erb +1 -1
  40. data/app/components/blacklight/facet_field_checkboxes_component.rb +1 -1
  41. data/app/components/blacklight/facet_field_inclusive_constraint_component.html.erb +1 -1
  42. data/app/components/blacklight/facet_field_list_component.html.erb +1 -1
  43. data/app/components/blacklight/facet_item_component.rb +1 -1
  44. data/app/components/blacklight/facet_item_pivot_component.rb +2 -2
  45. data/app/components/blacklight/icons/bookmark_icon_component.rb +17 -0
  46. data/app/components/blacklight/icons/icon_component.rb +9 -4
  47. data/app/components/blacklight/icons/remove_component.rb +16 -0
  48. data/app/components/blacklight/metadata_field_component.html.erb +1 -1
  49. data/app/components/blacklight/metadata_field_component.rb +5 -0
  50. data/app/components/blacklight/response/facet_group_component.rb +1 -1
  51. data/app/components/blacklight/response/pagination_component.html.erb +1 -1
  52. data/app/components/blacklight/response/sort_component.html.erb +1 -6
  53. data/app/components/blacklight/response/sort_component.rb +15 -0
  54. data/app/components/blacklight/search/per_page_component.html.erb +2 -0
  55. data/app/components/blacklight/search/per_page_component.rb +50 -0
  56. data/app/components/blacklight/search_bar_component.html.erb +1 -1
  57. data/app/components/blacklight/search_context/server_item_pagination_component.html.erb +4 -7
  58. data/app/components/blacklight/skip_link_component.html.erb +7 -0
  59. data/app/components/blacklight/skip_link_component.rb +17 -0
  60. data/app/components/blacklight/system/dropdown_button_component.rb +18 -0
  61. data/app/components/blacklight/system/dropdown_component.rb +4 -7
  62. data/app/components/blacklight/system/flash_message_component.html.erb +1 -1
  63. data/app/components/blacklight/top_navbar_component.html.erb +2 -2
  64. data/app/components/blacklight/top_navbar_component.rb +4 -0
  65. data/app/helpers/blacklight/catalog_helper_behavior.rb +3 -5
  66. data/app/helpers/blacklight/component_helper_behavior.rb +4 -4
  67. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -0
  68. data/app/helpers/blacklight/layout_helper_behavior.rb +3 -3
  69. data/app/javascript/blacklight/checkbox_submit.js +5 -1
  70. data/app/models/concerns/blacklight/document/semantic_fields.rb +1 -1
  71. data/app/presenters/blacklight/facet_checkbox_item_presenter.rb +11 -0
  72. data/app/presenters/blacklight/facet_field_presenter.rb +9 -1
  73. data/app/services/blacklight/search_service.rb +9 -1
  74. data/app/views/catalog/_per_page_widget.html.erb +1 -10
  75. data/app/views/catalog/_search_results.html.erb +1 -1
  76. data/app/views/catalog/_show_main_content.html.erb +1 -1
  77. data/app/views/catalog/show.html.erb +0 -2
  78. data/app/views/catalog/suggest.html.erb +1 -1
  79. data/app/views/kaminari/blacklight/_page.html.erb +14 -8
  80. data/app/views/layouts/blacklight/base.html.erb +3 -4
  81. data/app/views/shared/_flash_messages.html.erb +1 -1
  82. data/blacklight.gemspec +4 -0
  83. data/{docker-compose.yml → compose.yaml} +1 -1
  84. data/config/locales/blacklight.ar.yml +3 -0
  85. data/config/locales/blacklight.de.yml +3 -0
  86. data/config/locales/blacklight.en.yml +216 -229
  87. data/config/locales/blacklight.es.yml +3 -0
  88. data/config/locales/blacklight.fr.yml +3 -0
  89. data/config/locales/blacklight.hu.yml +3 -0
  90. data/config/locales/blacklight.it.yml +3 -0
  91. data/config/locales/blacklight.nl.yml +3 -0
  92. data/config/locales/blacklight.pt-BR.yml +3 -0
  93. data/config/locales/blacklight.sq.yml +3 -0
  94. data/config/locales/blacklight.zh.yml +3 -0
  95. data/lib/blacklight/abstract_repository.rb +6 -0
  96. data/lib/blacklight/configuration.rb +33 -19
  97. data/lib/blacklight/nested_open_struct_with_hash_access.rb +2 -2
  98. data/lib/blacklight/parameters.rb +1 -1
  99. data/lib/blacklight/solr/repository.rb +11 -4
  100. data/lib/blacklight/solr/request.rb +1 -1
  101. data/lib/blacklight/solr/response/facets.rb +1 -1
  102. data/lib/blacklight/solr/response/params.rb +1 -1
  103. data/lib/blacklight/solr/response.rb +0 -12
  104. data/lib/blacklight/solr/search_builder_behavior.rb +2 -2
  105. data/lib/blacklight/solr.rb +0 -6
  106. data/lib/blacklight.rb +4 -14
  107. data/lib/generators/blacklight/assets/propshaft_generator.rb +2 -2
  108. data/lib/generators/blacklight/models_generator.rb +1 -1
  109. data/package.json +1 -1
  110. data/spec/components/blacklight/advanced_search_form_component_spec.rb +2 -2
  111. data/spec/components/blacklight/constraint_layout_component_spec.rb +11 -11
  112. data/spec/components/blacklight/constraints_component_spec.rb +9 -9
  113. data/spec/components/blacklight/document/action_component_spec.rb +1 -1
  114. data/spec/components/blacklight/document/group_component_spec.rb +3 -3
  115. data/spec/components/blacklight/document/page_header_component_spec.rb +92 -0
  116. data/spec/components/blacklight/document/sidebar_component_spec.rb +3 -4
  117. data/spec/components/blacklight/document_component_spec.rb +41 -25
  118. data/spec/components/blacklight/facet_component_spec.rb +2 -2
  119. data/spec/components/blacklight/facet_field_checkboxes_component_spec.rb +5 -5
  120. data/spec/components/blacklight/facet_field_list_component_spec.rb +13 -13
  121. data/spec/components/blacklight/facet_item_component_spec.rb +5 -5
  122. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +6 -6
  123. data/spec/components/blacklight/header_component_spec.rb +1 -2
  124. data/spec/components/blacklight/hidden_search_state_component_spec.rb +6 -6
  125. data/spec/components/blacklight/icons/icon_component_spec.rb +42 -0
  126. data/spec/components/blacklight/metadata_field_component_spec.rb +3 -3
  127. data/spec/components/blacklight/response/pagination_component_spec.rb +4 -4
  128. data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +1 -1
  129. data/spec/components/blacklight/search_context/server_item_pagination_component_spec.rb +2 -4
  130. data/spec/components/blacklight/system/flash_message_component_spec.rb +5 -5
  131. data/spec/controllers/blacklight/catalog_spec.rb +2 -2
  132. data/spec/controllers/blacklight/{catalog/component_configuration_spec.rb → configurable_spec.rb} +1 -1
  133. data/spec/controllers/bookmarks_controller_spec.rb +10 -10
  134. data/spec/controllers/catalog_controller_spec.rb +29 -31
  135. data/spec/features/advanced_search_spec.rb +30 -16
  136. data/spec/features/alternate_controller_spec.rb +9 -9
  137. data/spec/features/axe_spec.rb +4 -4
  138. data/spec/features/bookmarks_spec.rb +34 -19
  139. data/spec/features/citation_spec.rb +1 -1
  140. data/spec/features/did_you_mean_spec.rb +23 -23
  141. data/spec/features/facet_missing_spec.rb +9 -9
  142. data/spec/features/facets_spec.rb +21 -20
  143. data/spec/features/modal_spec.rb +4 -4
  144. data/spec/features/record_view_spec.rb +2 -2
  145. data/spec/features/search_context_spec.rb +6 -6
  146. data/spec/features/search_crawler_spec.rb +5 -5
  147. data/spec/features/search_filters_spec.rb +65 -65
  148. data/spec/features/search_history_spec.rb +12 -12
  149. data/spec/features/search_pagination_spec.rb +10 -10
  150. data/spec/features/search_results_spec.rb +1 -1
  151. data/spec/features/search_sort_spec.rb +4 -4
  152. data/spec/features/search_spec.rb +25 -25
  153. data/spec/features/sitelinks_search_box_spec.rb +2 -2
  154. data/spec/features/sms_spec.rb +1 -1
  155. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +2 -2
  156. data/spec/helpers/blacklight/layout_helper_behavior_spec.rb +20 -3
  157. data/spec/helpers/blacklight/render_partials_helper_behavior_spec.rb +2 -1
  158. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +7 -8
  159. data/spec/helpers/blacklight_helper_spec.rb +13 -15
  160. data/spec/helpers/catalog_helper_spec.rb +3 -6
  161. data/spec/i18n_spec.rb +2 -1
  162. data/spec/lib/blacklight/nested_open_struct_with_hash_access_spec.rb +1 -1
  163. data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +1 -1
  164. data/spec/lib/blacklight/search_state_spec.rb +4 -4
  165. data/spec/lib/tasks/blacklight_task_spec.rb +2 -1
  166. data/spec/models/blacklight/configurable_spec.rb +1 -1
  167. data/spec/models/blacklight/configuration/context_spec.rb +1 -1
  168. data/spec/models/blacklight/configuration_spec.rb +14 -14
  169. data/spec/models/blacklight/document/active_model_shim_spec.rb +1 -1
  170. data/spec/models/blacklight/document/cache_key_spec.rb +1 -1
  171. data/spec/models/blacklight/document_spec.rb +1 -1
  172. data/spec/models/blacklight/facet_paginator_spec.rb +14 -14
  173. data/spec/models/blacklight/icon_spec.rb +1 -1
  174. data/spec/models/blacklight/search_builder_spec.rb +1 -1
  175. data/spec/models/blacklight/solr/document_spec.rb +3 -3
  176. data/spec/models/blacklight/solr/facet_paginator_spec.rb +1 -1
  177. data/spec/models/blacklight/solr/repository_spec.rb +33 -15
  178. data/spec/models/blacklight/solr/request_spec.rb +1 -1
  179. data/spec/models/blacklight/solr/response/facets_spec.rb +3 -3
  180. data/spec/models/blacklight/solr/response/group_response_spec.rb +1 -1
  181. data/spec/models/blacklight/solr/response/group_spec.rb +2 -2
  182. data/spec/models/blacklight/solr/response_spec.rb +3 -3
  183. data/spec/models/blacklight/solr/{search_builder_spec.rb → search_builder_behavior_spec.rb} +10 -20
  184. data/spec/models/blacklight/suggest/response_spec.rb +1 -1
  185. data/spec/models/blacklight/suggest_search_spec.rb +1 -1
  186. data/spec/models/blacklight/user_spec.rb +1 -1
  187. data/spec/models/bookmark_spec.rb +1 -1
  188. data/spec/models/solr_document_spec.rb +1 -1
  189. data/spec/presenters/blacklight/document_presenter_spec.rb +3 -4
  190. data/spec/presenters/blacklight/facet_checkbox_item_presenter_spec.rb +42 -0
  191. data/spec/presenters/blacklight/facet_field_presenter_spec.rb +14 -0
  192. data/spec/presenters/blacklight/field_presenter_spec.rb +1 -1
  193. data/spec/presenters/blacklight/index_presenter_spec.rb +2 -3
  194. data/spec/presenters/blacklight/json_presenter_spec.rb +1 -1
  195. data/spec/presenters/{pipeline_spec.rb → blacklight/rendering/pipeline_spec.rb} +1 -1
  196. data/spec/presenters/blacklight/show_presenter_spec.rb +5 -6
  197. data/spec/presenters/{thumbnail_presenter_spec.rb → blacklight/thumbnail_presenter_spec.rb} +5 -3
  198. data/spec/requests/load_suggestions_spec.rb +5 -5
  199. data/spec/routing/catalog_routing_spec.rb +1 -1
  200. data/spec/services/blacklight/field_retriever_spec.rb +1 -1
  201. data/spec/services/blacklight/search_service_spec.rb +11 -11
  202. data/spec/spec_helper.rb +2 -2
  203. data/spec/support/features/search_helpers.rb +2 -2
  204. data/spec/support/features/session_helpers.rb +3 -3
  205. data/spec/test_app_templates/lib/generators/test_app_generator.rb +3 -3
  206. data/spec/views/catalog/_document.html.erb_spec.rb +1 -4
  207. data/spec/views/catalog/_document_list.html.erb_spec.rb +2 -2
  208. data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +5 -6
  209. data/spec/views/catalog/_facet_layout.html.erb_spec.rb +7 -7
  210. data/spec/views/catalog/_paginate_compact.html.erb_spec.rb +4 -4
  211. data/spec/views/catalog/_show_sidebar.erb_spec.rb +1 -4
  212. data/spec/views/catalog/_show_tools.html.erb_spec.rb +1 -2
  213. data/spec/views/catalog/_view_type_group.html.erb_spec.rb +7 -7
  214. data/spec/views/catalog/email_success.html.erb_spec.rb +1 -1
  215. data/spec/views/catalog/facet.html.erb_spec.rb +1 -1
  216. data/spec/views/catalog/facet.json.jbuilder_spec.rb +1 -1
  217. data/spec/views/catalog/index.atom.builder_spec.rb +18 -19
  218. data/spec/views/catalog/index.html.erb_spec.rb +2 -4
  219. data/spec/views/catalog/index.json.jbuilder_spec.rb +5 -8
  220. data/spec/views/catalog/show.html.erb_spec.rb +3 -5
  221. data/spec/views/catalog/show.json.jbuilder_spec.rb +1 -2
  222. data/spec/views/catalog/sms_success.html.erb_spec.rb +1 -1
  223. data/spec/views/shared/_user_util_links.html.erb_spec.rb +2 -3
  224. data/tasks/blacklight.rake +5 -5
  225. metadata +84 -12
@@ -5,24 +5,6 @@ module Blacklight
5
5
  # Blacklight::Configuration holds the configuration for a Blacklight::Controller, including
6
6
  # fields to display, facets to show, sort options, and search fields.
7
7
  class Configuration < OpenStructWithHashAccess
8
- extend ActiveSupport::Autoload
9
- eager_autoload do
10
- autoload :Context
11
- autoload :ViewConfig
12
- autoload :ToolConfig
13
- autoload :Fields
14
- autoload :Field
15
- autoload :NullField
16
- autoload :NullDisplayField
17
- autoload :SearchField
18
- autoload :FacetField
19
- autoload :SortField
20
- autoload :DisplayField
21
- autoload :IndexField
22
- autoload :ShowField
23
- autoload :SessionTrackingConfig
24
- end
25
-
26
8
  class_attribute :default_values, default: {}
27
9
 
28
10
  # Set up Blacklight::Configuration.default_values to contain the basic, required Blacklight fields
@@ -59,7 +41,9 @@ module Blacklight
59
41
  # rubocop:disable Metrics/BlockLength
60
42
  default_configuration do
61
43
  property :logo_link, default: nil
44
+ property :skip_link_component, default: Blacklight::SkipLinkComponent
62
45
  property :header_component, default: Blacklight::HeaderComponent
46
+ property :full_width_layout, default: false
63
47
 
64
48
  # bootstrap_version may be set to 4 or 5
65
49
  bootstrap_version = ENV['BOOTSTRAP_VERSION'].presence || "5"
@@ -98,6 +82,10 @@ module Blacklight
98
82
  # @!attribute default_document_solr_params
99
83
  # @return [Hash] Default values of parameters to send with every single-document request
100
84
  property :default_document_solr_params, default: {}
85
+ # @!attribute fetch_many_documents_path
86
+ # @since v8.4.0
87
+ # @return [String] The url path (relative to the solr base url) to use when requesting multiple documents by id
88
+ property :fetch_many_documents_path, default: nil
101
89
  # @!attribute fetch_many_document_params
102
90
  # @since v7.0.0
103
91
  # @return [Hash] Default values of parameters to send with every multi-document request
@@ -145,6 +133,12 @@ module Blacklight
145
133
  # @return [#partials]
146
134
  property :navbar, default: OpenStructWithHashAccess.new(partials: {})
147
135
 
136
+ # @!attribute bookmark_icon_component
137
+ # @since v8.3.1
138
+ # component class used to render a document
139
+ # set to Blacklight::Icons::BookmarkIconComponent to replace checkbox with icon
140
+ property :bookmark_icon_component, default: nil
141
+
148
142
  # @!attribute index
149
143
  # General configuration for all views
150
144
  # @return [Blacklight::Configuration::ViewConfig::Index]
@@ -154,6 +148,7 @@ module Blacklight
154
148
  # component class used to render a document
155
149
  document_component: Blacklight::DocumentComponent,
156
150
  sidebar_component: Blacklight::Search::SidebarComponent,
151
+ dropdown_component: Blacklight::System::DropdownComponent,
157
152
  # solr field to use to render a document title
158
153
  title_field: nil,
159
154
  # solr field to use to render format-specific partials
@@ -190,6 +185,8 @@ module Blacklight
190
185
  # in Blacklight 9, the default show_tools_component configuration will
191
186
  # be Blacklight::Document::ShowToolsComponent
192
187
  show_tools_component: nil,
188
+ show_header_tools_component: nil,
189
+ document_header_component: Blacklight::Document::PageHeaderComponent,
193
190
  sidebar_component: Blacklight::Document::SidebarComponent,
194
191
  display_type_field: nil,
195
192
  # the "field access" key to use to look up the document display fields
@@ -200,7 +197,8 @@ module Blacklight
200
197
  route: nil,
201
198
  # partials to render for each document(see #render_document_partials)
202
199
  partials: [],
203
- document_actions: NestedOpenStructWithHashAccess.new(ToolConfig)
200
+ document_actions: NestedOpenStructWithHashAccess.new(ToolConfig),
201
+ header_actions: NestedOpenStructWithHashAccess.new(ToolConfig)
204
202
  )
205
203
 
206
204
  # @!attribute action_mapping
@@ -547,6 +545,22 @@ module Blacklight
547
545
  add_action(show.document_actions, name, opts)
548
546
  klass && ActionBuilder.new(klass, name, opts).build
549
547
  end
548
+
549
+ # Add a partial to the show page header when rendering a document.
550
+ # @!macro partial_if_unless
551
+ # @param name [String] the name of the document partial
552
+ # @param opts [Hash]
553
+ # @option opts [Class] :component draw a component
554
+ # @option opts [String] :partial partial to draw if component is false
555
+ # @option opts [Symbol,Proc] :if render this action if the method identified by the symbol or the proc evaluates to true. The proc will receive the action configuration and the document or documents for the action.
556
+ # @option opts [Symbol,Proc] :unless render this action unless the method identified by the symbol or the proc evaluates to true. The proc will receive the action configuration and the document or documents for the action.
557
+ def add_show_header_tools_partial(name, opts = {})
558
+ opts[:partial] ||= 'document_action'
559
+
560
+ add_action(show.header_actions, name, opts)
561
+ klass && ActionBuilder.new(klass, name, opts).build
562
+ end
563
+
550
564
  # rubocop:enable Layout/LineLength
551
565
 
552
566
  # Add a tool for the search result list itself
@@ -20,7 +20,7 @@ module Blacklight
20
20
  end
21
21
  end
22
22
 
23
- super value
23
+ super(value)
24
24
  set_default_proc!
25
25
  end
26
26
 
@@ -56,7 +56,7 @@ module Blacklight
56
56
  # to the internal hash
57
57
  def marshal_load x
58
58
  @nested_class = x.first
59
- super x.last
59
+ super(x.last)
60
60
  set_default_proc!
61
61
  end
62
62
 
@@ -7,7 +7,7 @@ module Blacklight
7
7
  # from the provided parameters.
8
8
  # @param [Hash] params parameters
9
9
  def self.sanitize params
10
- params.reject { |_k, v| v.nil? } # rubocop:disable Style/CollectionCompact not available in Rails 6.0
10
+ params.reject { |_k, v| v.nil? } # not available in Rails 6.0
11
11
  .except(:action, :controller, :id, :commit, :utf8)
12
12
  end
13
13
 
@@ -17,13 +17,20 @@ module Blacklight::Solr
17
17
  solr_response
18
18
  end
19
19
 
20
+ # Find multiple documents by their ids
21
+ # @param [Hash] _params query parameters
22
+ def find_many(params)
23
+ search(params: params, path: blacklight_config.fetch_many_documents_path)
24
+ end
25
+
20
26
  ##
21
27
  # Execute a search query against solr
22
28
  # @param [Hash] params solr query parameters
23
- def search params = {}
24
- request_params = params.reverse_merge({ qt: blacklight_config.qt })
29
+ # @param [String] path solr request handler path
30
+ def search pos_params = {}, path: nil, params: nil, **kwargs
31
+ request_params = (params || pos_params).reverse_merge(kwargs).reverse_merge({ qt: blacklight_config.qt })
25
32
 
26
- send_and_receive search_path(request_params), request_params
33
+ send_and_receive(path || default_search_path(request_params), request_params)
27
34
  end
28
35
 
29
36
  # @param [Hash] request_params
@@ -126,7 +133,7 @@ module Blacklight::Solr
126
133
  end
127
134
 
128
135
  # @return [String]
129
- def search_path(solr_params)
136
+ def default_search_path(solr_params)
130
137
  return blacklight_config.json_solr_path if blacklight_config.json_solr_path && uses_json_query_dsl?(solr_params)
131
138
 
132
139
  blacklight_config.solr_path
@@ -14,7 +14,7 @@ class Blacklight::Solr::Request < ActiveSupport::HashWithIndifferentAccess
14
14
  super()
15
15
  update(constructor)
16
16
  else
17
- super(constructor)
17
+ super
18
18
  end
19
19
  end
20
20
 
@@ -102,7 +102,7 @@ module Blacklight::Solr::Response::Facets
102
102
 
103
103
  class NullFacetField < FacetField
104
104
  def initialize name, items = [], response: nil, **kwargs
105
- super(name, items, response: response, **kwargs)
105
+ super
106
106
  end
107
107
  end
108
108
 
@@ -98,7 +98,7 @@ module Blacklight::Solr::Response::Params
98
98
  json_params[json_key || key],
99
99
  json_params.dig(:params, key),
100
100
  json_params.dig(:params, "json.#{key}")
101
- ].select(&:present?).inject([]) do |memo, arr|
101
+ ].compact_blank.inject([]) do |memo, arr|
102
102
  memo.concat(Array.wrap(arr))
103
103
  end
104
104
  end
@@ -1,18 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Blacklight::Solr::Response < ActiveSupport::HashWithIndifferentAccess
4
- extend ActiveSupport::Autoload
5
- eager_autoload do
6
- autoload :PaginationMethods
7
- autoload :Response
8
- autoload :Spelling
9
- autoload :Facets
10
- autoload :MoreLikeThis
11
- autoload :GroupResponse
12
- autoload :Group
13
- autoload :Params
14
- end
15
-
16
4
  include PaginationMethods
17
5
  include Spelling
18
6
  include Facets
@@ -161,7 +161,7 @@ module Blacklight::Solr
161
161
  limit: facet_limit_with_pagination(field_name)
162
162
  ).merge(additional_parameters)
163
163
 
164
- solr_parameters[:json][:facet][field_name] = field_config.select { |_k, v| v.present? }
164
+ solr_parameters[:json][:facet][field_name] = field_config.compact_blank
165
165
  end
166
166
 
167
167
  ##
@@ -324,7 +324,7 @@ module Blacklight::Solr
324
324
  unless val =~ /^[a-zA-Z0-9$_\-\^]+$/
325
325
  val = options[:quote] +
326
326
  # Yes, we need crazy escaping here, to deal with regexp esc too!
327
- val.gsub("'", "\\\\\'").gsub('"', "\\\\\"") +
327
+ val.gsub("'", "\\\\'").gsub('"', "\\\\\"") +
328
328
  options[:quote]
329
329
  end
330
330
  val
@@ -2,11 +2,5 @@
2
2
 
3
3
  module Blacklight
4
4
  module Solr
5
- autoload :Document, 'blacklight/solr/document'
6
- autoload :FacetPaginator, 'blacklight/solr/facet_paginator'
7
- autoload :Repository, 'blacklight/solr/repository'
8
- autoload :Request, 'blacklight/solr/request'
9
- autoload :Response, 'blacklight/solr/response'
10
- autoload :SearchBuilderBehavior, 'blacklight/solr/search_builder_behavior'
11
5
  end
12
6
  end
data/lib/blacklight.rb CHANGED
@@ -1,23 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'kaminari'
4
- require 'blacklight/open_struct_with_hash_access'
5
- require 'blacklight/nested_open_struct_with_hash_access'
6
4
  require 'jbuilder'
5
+ require "zeitwerk"
6
+ loader = Zeitwerk::Loader.for_gem
7
+ loader.ignore("#{__dir__}/generators")
8
+ loader.setup
7
9
 
8
10
  module Blacklight
9
- autoload :AbstractRepository, 'blacklight/abstract_repository'
10
- autoload :Component, 'blacklight/component'
11
- autoload :Configuration, 'blacklight/configuration'
12
- autoload :Exceptions, 'blacklight/exceptions'
13
- autoload :Parameters, 'blacklight/parameters'
14
- autoload :Routes, 'blacklight/routes'
15
- autoload :RuntimeRegistry, 'blacklight/runtime_registry'
16
- autoload :SearchBuilder, 'blacklight/search_builder'
17
- autoload :SearchState, 'blacklight/search_state'
18
- autoload :Solr, 'blacklight/solr'
19
-
20
- require 'blacklight/version'
21
11
  require 'blacklight/engine' if defined?(Rails)
22
12
 
23
13
  def self.blacklight_config_file
@@ -5,9 +5,9 @@ module Blacklight
5
5
  class PropshaftGenerator < Rails::Generators::Base
6
6
  def add_package
7
7
  if ENV['CI']
8
- run "yarn add blacklight-frontend:#{Blacklight::Engine.root}"
8
+ run "yarn add file:#{Blacklight::Engine.root}"
9
9
  else
10
- run 'yarn add blacklight-frontend'
10
+ run "yarn add blacklight-frontend@#{Blacklight::VERSION}"
11
11
  end
12
12
  end
13
13
 
@@ -36,7 +36,7 @@ module Blacklight
36
36
  concerns :exportable
37
37
  end
38
38
 
39
- resources :bookmarks do
39
+ resources :bookmarks, only: [:index, :update, :create, :destroy] do
40
40
  concerns :exportable
41
41
 
42
42
  collection do
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blacklight-frontend",
3
- "version": "8.2.2",
3
+ "version": "8.4.0",
4
4
  "description": "The frontend code and styles for Blacklight",
5
5
  "main": "app/assets/javascripts/blacklight",
6
6
  "module": "app/assets/javascripts/blacklight/blacklight.esm.js",
@@ -32,7 +32,7 @@ RSpec.describe Blacklight::AdvancedSearchFormComponent, type: :component do
32
32
  end
33
33
 
34
34
  it 'has text fields for each search field' do
35
- expect(rendered).to have_selector '.advanced-search-field', count: 4
35
+ expect(rendered).to have_css '.advanced-search-field', count: 4
36
36
  expect(rendered).to have_field 'clause_0_field', with: 'all_fields', type: :hidden
37
37
  expect(rendered).to have_field 'clause_1_field', with: 'title', type: :hidden
38
38
  expect(rendered).to have_field 'clause_2_field', with: 'author', type: :hidden
@@ -40,7 +40,7 @@ RSpec.describe Blacklight::AdvancedSearchFormComponent, type: :component do
40
40
  end
41
41
 
42
42
  it 'has filters' do
43
- expect(rendered).to have_selector '.blacklight-format'
43
+ expect(rendered).to have_css '.blacklight-format'
44
44
  expect(rendered).to have_field 'f_inclusive[format][]', with: 'Book'
45
45
  expect(rendered).to have_field 'f_inclusive[format][]', with: 'CD'
46
46
  end
@@ -13,11 +13,11 @@ RSpec.describe Blacklight::ConstraintLayoutComponent, type: :component do
13
13
  end
14
14
 
15
15
  it "renders label and value" do
16
- expect(rendered).to have_selector("span.applied-filter.constraint") do |s|
16
+ expect(rendered).to have_css("span.applied-filter.constraint") do |s|
17
17
  expect(s).to have_css("span.constraint-value")
18
- expect(s).not_to have_css("a.constraint-value")
19
- expect(s).to have_selector "span.filter-name", text: "my label"
20
- expect(s).to have_selector "span.filter-value", text: "my value"
18
+ expect(s).to have_no_css("a.constraint-value")
19
+ expect(s).to have_css "span.filter-name", text: "my label"
20
+ expect(s).to have_css "span.filter-value", text: "my value"
21
21
  end
22
22
  end
23
23
  end
@@ -28,14 +28,14 @@ RSpec.describe Blacklight::ConstraintLayoutComponent, type: :component do
28
28
  end
29
29
 
30
30
  it "includes remove link" do
31
- expect(rendered).to have_selector("span.applied-filter") do |s|
32
- expect(s).to have_selector(".remove[href='http://remove']")
31
+ expect(rendered).to have_css("span.applied-filter") do |s|
32
+ expect(s).to have_css(".remove[href='http://remove']")
33
33
  end
34
34
  end
35
35
 
36
36
  it "has an accessible remove label" do
37
- expect(rendered).to have_selector(".remove") do |s|
38
- expect(s).to have_selector('.visually-hidden', text: 'Remove constraint my label: my value')
37
+ expect(rendered).to have_css(".remove") do |s|
38
+ expect(s).to have_css('.visually-hidden', text: 'Remove constraint my label: my value')
39
39
  end
40
40
  end
41
41
  end
@@ -46,7 +46,7 @@ RSpec.describe Blacklight::ConstraintLayoutComponent, type: :component do
46
46
  end
47
47
 
48
48
  it "includes them" do
49
- expect(rendered).to have_selector("span.applied-filter.constraint.class1.class2")
49
+ expect(rendered).to have_css("span.applied-filter.constraint.class1.class2")
50
50
  end
51
51
  end
52
52
 
@@ -56,8 +56,8 @@ RSpec.describe Blacklight::ConstraintLayoutComponent, type: :component do
56
56
  end
57
57
 
58
58
  it "does not escape key and value" do
59
- expect(rendered).to have_selector("span.applied-filter.constraint span.filter-name span.custom_label")
60
- expect(rendered).to have_selector("span.applied-filter.constraint span.filter-value span.custom_value")
59
+ expect(rendered).to have_css("span.applied-filter.constraint span.filter-name span.custom_label")
60
+ expect(rendered).to have_css("span.applied-filter.constraint span.filter-value span.custom_value")
61
61
  end
62
62
  end
63
63
  end
@@ -36,15 +36,15 @@ RSpec.describe Blacklight::ConstraintsComponent, type: :component do
36
36
  end
37
37
 
38
38
  it 'has a header' do
39
- expect(rendered).to have_selector('h2', text: 'Search Constraints')
39
+ expect(rendered).to have_css('h2', text: 'Search Constraints')
40
40
  end
41
41
 
42
42
  it 'wraps the output in a div' do
43
- expect(rendered).to have_selector('div#appliedParams')
43
+ expect(rendered).to have_css('div#appliedParams')
44
44
  end
45
45
 
46
46
  it 'renders the query' do
47
- expect(rendered).to have_selector('.applied-filter.constraint', text: 'some query')
47
+ expect(rendered).to have_css('.applied-filter.constraint', text: 'some query')
48
48
  end
49
49
  end
50
50
 
@@ -52,15 +52,15 @@ RSpec.describe Blacklight::ConstraintsComponent, type: :component do
52
52
  let(:query_params) { { f: { some_facet: ['some value'] } } }
53
53
 
54
54
  it 'renders the query' do
55
- expect(rendered).to have_selector('.constraint-value > .filter-name', text: 'Some Facet').and(have_selector('.constraint-value > .filter-value', text: 'some value'))
55
+ expect(rendered).to have_css('.constraint-value > .filter-name', text: 'Some Facet').and(have_css('.constraint-value > .filter-value', text: 'some value'))
56
56
  end
57
57
 
58
58
  context 'that is not configured' do
59
59
  let(:query_params) { { f: { some_facet: ['some value'], missing: ['another value'] } } }
60
60
 
61
61
  it 'renders only the configured constraints' do
62
- expect(rendered).to have_selector('.constraint-value > .filter-name', text: 'Some Facet').and(have_selector('.constraint-value > .filter-value', text: 'some value'))
63
- expect(rendered).not_to have_selector('.constraint-value > .filter-name', text: 'Missing')
62
+ expect(rendered).to have_css('.constraint-value > .filter-name', text: 'Some Facet').and(have_css('.constraint-value > .filter-value', text: 'some value'))
63
+ expect(rendered).to have_no_css('.constraint-value > .filter-name', text: 'Missing')
64
64
  end
65
65
  end
66
66
  end
@@ -71,15 +71,15 @@ RSpec.describe Blacklight::ConstraintsComponent, type: :component do
71
71
  let(:query_params) { { q: 'some query', f: { some_facet: ['some value'] } } }
72
72
 
73
73
  it 'wraps the output in a span' do
74
- expect(rendered).to have_selector('span .constraint')
74
+ expect(rendered).to have_css('span .constraint')
75
75
  end
76
76
 
77
77
  it 'renders the search state as lightly-decorated text' do
78
- expect(rendered).to have_selector('.constraint > .filter-values', text: 'some query').and(have_selector('.constraint', text: 'Some Facet:some value'))
78
+ expect(rendered).to have_css('.constraint > .filter-values', text: 'some query').and(have_css('.constraint', text: 'Some Facet:some value'))
79
79
  end
80
80
 
81
81
  it 'omits the headers' do
82
- expect(rendered).not_to have_selector('h2', text: 'Search Constraints')
82
+ expect(rendered).to have_no_css('h2', text: 'Search Constraints')
83
83
  end
84
84
  end
85
85
  end
@@ -36,7 +36,7 @@ RSpec.describe Blacklight::Document::ActionComponent, type: :component do
36
36
  let(:action) { Blacklight::Configuration::ToolConfig.new(name: '', partial: '/some/tool') }
37
37
 
38
38
  it 'render the partial' do
39
- allow(view_context).to receive(:render).with(hash_including(partial: '/some/tool')).and_return('tool')
39
+ allow(view_context).to receive(:render).with(hash_including(partial: '/some/tool'), {}).and_return('tool')
40
40
 
41
41
  expect(rendered).to have_content 'tool'
42
42
  end
@@ -26,9 +26,9 @@ RSpec.describe Blacklight::Document::GroupComponent, type: :component do
26
26
  end
27
27
 
28
28
  it 'renders the group with a header' do
29
- expect(rendered).to have_selector 'div.group'
30
- expect(rendered).to have_selector 'h2', text: 'group1'
31
- expect(rendered).not_to have_link 'more'
29
+ expect(rendered).to have_css 'div.group'
30
+ expect(rendered).to have_css 'h2', text: 'group1'
31
+ expect(rendered).to have_no_link 'more'
32
32
  end
33
33
 
34
34
  it 'renders the group documents' do
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::Document::PageHeaderComponent, type: :component do
6
+ subject(:component) { described_class.new(document: document, search_context: search_context, search_session: current_search_session) }
7
+
8
+ let(:show_header_tools_component) { Class.new(Blacklight::Document::ShowToolsComponent) }
9
+
10
+ let(:view_context) { controller.view_context }
11
+ let(:render) do
12
+ component.render_in(view_context)
13
+ end
14
+
15
+ let(:rendered) do
16
+ Capybara::Node::Simple.new(render)
17
+ end
18
+
19
+ let(:document) { SolrDocument.new(id: 'x', title_tsim: 'Title') }
20
+
21
+ let(:blacklight_config) do
22
+ CatalogController.blacklight_config.deep_copy
23
+ end
24
+
25
+ # rubocop:disable RSpec/SubjectStub
26
+ before do
27
+ # Every call to view_context returns a different object. This ensures it stays stable.
28
+ allow(controller).to receive_messages(blacklight_config: blacklight_config)
29
+ allow(controller).to receive(:current_search_session).and_return(double(id: document.id))
30
+ controller.class.helper_method :current_search_session
31
+ allow(controller).to receive_messages(controller_name: 'catalog', link_to_previous_document: '', link_to_next_document: '')
32
+ allow(view_context).to receive_messages(search_context: search_context, search_session: current_search_session, current_search_session: current_search_session)
33
+ allow(component).to receive(:render).and_call_original
34
+ allow(component).to receive(:render).with(an_instance_of(show_header_tools_component)).and_return('tool component content')
35
+ replace_hash = { 'application/_start_over.html.erb' => 'Start Over' }
36
+ if Rails.version.to_f >= 7.1
37
+ controller.prepend_view_path(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
38
+ else
39
+ view_context.view_paths.unshift(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
40
+ end
41
+ end
42
+ # rubocop:enable RSpec/SubjectStub
43
+
44
+ context "all variables are empty" do
45
+ let(:search_context) { nil }
46
+ let(:current_search_session) { {} }
47
+
48
+ it 'does not render' do
49
+ expect(rendered.native.inner_html).to be_blank
50
+ end
51
+
52
+ context 'has header tools' do
53
+ before do
54
+ blacklight_config.show.show_header_tools_component = show_header_tools_component
55
+ end
56
+
57
+ it 'renders the tools' do
58
+ expect(rendered).to have_text 'tool component content'
59
+ expect(rendered).to have_css '.row'
60
+ end
61
+ end
62
+ end
63
+
64
+ context "has pagination" do
65
+ let(:search_context) { { next: next_doc, prev: prev_doc } }
66
+ let(:prev_doc) { SolrDocument.new(id: '777') }
67
+ let(:next_doc) { SolrDocument.new(id: '888') }
68
+ let(:current_search_session) { { query_params: { q: 'abc' }, 'id' => '123', 'document_id' => document.id } }
69
+
70
+ it 'renders pagination' do
71
+ expect(rendered).to have_text 'Previous'
72
+ expect(rendered).to have_text 'Next'
73
+ expect(rendered).to have_text 'Start Over'
74
+ expect(rendered).to have_text 'Back to Search'
75
+ end
76
+
77
+ context 'has header tools' do
78
+ before do
79
+ blacklight_config.show.show_header_tools_component = show_header_tools_component
80
+ end
81
+
82
+ it 'renders the tools and pagination' do
83
+ expect(rendered).to have_text 'Previous'
84
+ expect(rendered).to have_text 'Next'
85
+ expect(rendered).to have_text 'Start Over'
86
+ expect(rendered).to have_text 'Back to Search'
87
+ expect(rendered).to have_text 'tool component content'
88
+ expect(rendered).to have_css '.row'
89
+ end
90
+ end
91
+ end
92
+ end
@@ -26,8 +26,7 @@ RSpec.describe Blacklight::Document::SidebarComponent, type: :component do
26
26
 
27
27
  before do
28
28
  # Every call to view_context returns a different object. This ensures it stays stable.
29
- allow(controller).to receive(:view_context).and_return(view_context)
30
- allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
29
+ allow(controller).to receive_messages(view_context: view_context, blacklight_config: blacklight_config)
31
30
  end
32
31
 
33
32
  describe '#render_show_tools' do
@@ -42,7 +41,7 @@ RSpec.describe Blacklight::Document::SidebarComponent, type: :component do
42
41
  end
43
42
 
44
43
  it 'renders show_tools partial' do
45
- expect(rendered).to have_selector 'div[@class="expected-show_tools"]'
44
+ expect(rendered).to have_css 'div[@class="expected-show_tools"]'
46
45
  end
47
46
  end
48
47
 
@@ -55,7 +54,7 @@ RSpec.describe Blacklight::Document::SidebarComponent, type: :component do
55
54
  end
56
55
 
57
56
  it 'renders configured show_tools component' do
58
- expect(rendered).to have_selector 'div[@class="expected-show_tools"]'
57
+ expect(rendered).to have_css 'div[@class="expected-show_tools"]'
59
58
  end
60
59
  end
61
60
  # rubocop:enable RSpec/SubjectStub