blacklight 9.0.0.beta8 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/.env +3 -3
  3. data/.github/matrix.json +18 -34
  4. data/.github/workflows/lint.yml +1 -1
  5. data/.github/workflows/test.yml +4 -3
  6. data/.rubocop.yml +72 -7
  7. data/.rubocop_todo.yml +142 -268
  8. data/Gemfile +1 -1
  9. data/README.md +4 -11
  10. data/VERSION +1 -1
  11. data/app/assets/builds/blacklight.css +37 -23
  12. data/app/assets/images/blacklight/logo-dark.svg +184 -0
  13. data/app/assets/images/blacklight/logo.svg +184 -0
  14. data/app/assets/javascripts/blacklight/blacklight.esm.js +134 -48
  15. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  16. data/app/assets/javascripts/blacklight/blacklight.js +134 -48
  17. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  18. data/app/assets/stylesheets/blacklight/_balanced_list.scss +1 -1
  19. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +17 -0
  20. data/app/assets/stylesheets/blacklight/_constraints.scss +2 -2
  21. data/app/assets/stylesheets/blacklight/_facets.scss +14 -10
  22. data/app/assets/stylesheets/blacklight/_header.scss +0 -4
  23. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +5 -9
  24. data/app/components/blacklight/facets/filters_component.rb +1 -1
  25. data/app/components/blacklight/facets/inclusive_constraint_component.html.erb +1 -1
  26. data/app/components/blacklight/facets/suggest_component.html.erb +17 -12
  27. data/app/components/blacklight/icons/checkmark_component.rb +16 -0
  28. data/app/components/blacklight/icons/circle_half_component.rb +16 -0
  29. data/app/components/blacklight/icons/moon_stars_component.rb +17 -0
  30. data/app/components/blacklight/icons/sun_component.rb +16 -0
  31. data/app/components/blacklight/metadata_field_component.rb +1 -1
  32. data/app/components/blacklight/search_navbar_component.html.erb +1 -1
  33. data/app/components/blacklight/theme_switcher_component.html.erb +31 -0
  34. data/app/components/blacklight/theme_switcher_component.rb +6 -0
  35. data/app/components/blacklight/top_navbar_component.html.erb +1 -1
  36. data/app/controllers/concerns/blacklight/bookmarks.rb +8 -14
  37. data/app/controllers/concerns/blacklight/catalog.rb +12 -14
  38. data/app/controllers/concerns/blacklight/controller.rb +54 -11
  39. data/app/controllers/concerns/blacklight/guest_user.rb +51 -0
  40. data/app/controllers/concerns/blacklight/search_context.rb +1 -1
  41. data/app/controllers/concerns/blacklight/search_history.rb +3 -1
  42. data/app/controllers/concerns/blacklight/searchable.rb +18 -0
  43. data/app/helpers/blacklight/layout_helper_behavior.rb +7 -0
  44. data/app/javascript/blacklight-frontend/checkbox_submit.js +2 -2
  45. data/app/javascript/blacklight-frontend/color_theme_switcher.js +85 -0
  46. data/app/javascript/blacklight-frontend/facet_suggest.js +4 -1
  47. data/app/javascript/blacklight-frontend/index.js +2 -0
  48. data/app/models/concerns/blacklight/document/dublin_core.rb +2 -2
  49. data/app/models/concerns/blacklight/document.rb +1 -1
  50. data/app/models/concerns/blacklight/user.rb +36 -0
  51. data/app/presenters/blacklight/field_presenter.rb +1 -1
  52. data/app/presenters/blacklight/rendering/microdata.rb +1 -0
  53. data/app/services/blacklight/bookmarks_search_builder.rb +4 -4
  54. data/app/services/blacklight/search_service.rb +50 -35
  55. data/app/values/blacklight/types.rb +1 -1
  56. data/app/views/catalog/_email_form.html.erb +3 -3
  57. data/app/views/catalog/_home_text.html.erb +1 -1
  58. data/app/views/catalog/_sms_form.html.erb +4 -4
  59. data/app/views/catalog/index.rss.builder +4 -4
  60. data/app/views/catalog/opensearch.json.jbuilder +3 -0
  61. data/app/views/catalog/opensearch.xml.builder +2 -2
  62. data/app/views/layouts/blacklight/base.html.erb +13 -1
  63. data/app/views/shared/_user_util_links.html.erb +18 -5
  64. data/blacklight.gemspec +3 -3
  65. data/config/locales/blacklight.ar.yml +5 -0
  66. data/config/locales/blacklight.ca.yml +5 -0
  67. data/config/locales/blacklight.de.yml +6 -2
  68. data/config/locales/blacklight.en.yml +5 -0
  69. data/config/locales/blacklight.es.yml +5 -0
  70. data/config/locales/blacklight.fr.yml +5 -0
  71. data/config/locales/blacklight.hu.yml +5 -0
  72. data/config/locales/blacklight.it.yml +6 -2
  73. data/config/locales/blacklight.nl.yml +5 -0
  74. data/config/locales/blacklight.pt-BR.yml +6 -2
  75. data/config/locales/blacklight.sq.yml +5 -0
  76. data/config/locales/blacklight.zh.yml +5 -0
  77. data/lib/blacklight/component.rb +1 -1
  78. data/lib/blacklight/configuration/action_config_map_entry.rb +31 -0
  79. data/lib/blacklight/configuration/display_field.rb +1 -0
  80. data/lib/blacklight/configuration/field.rb +6 -6
  81. data/lib/blacklight/configuration/fields.rb +1 -1
  82. data/lib/blacklight/configuration/sort_field.rb +2 -2
  83. data/lib/blacklight/configuration.rb +30 -23
  84. data/lib/blacklight/parameters.rb +1 -1
  85. data/lib/blacklight/routes/searchable.rb +1 -1
  86. data/lib/blacklight/search_builder.rb +208 -10
  87. data/lib/blacklight/search_state.rb +4 -0
  88. data/lib/blacklight/solr/request.rb +8 -1
  89. data/lib/blacklight/solr/response/group_response.rb +1 -1
  90. data/lib/blacklight/solr/response/spelling.rb +8 -8
  91. data/lib/blacklight/solr/response.rb +2 -21
  92. data/lib/blacklight/solr/search_builder_behavior.rb +59 -16
  93. data/lib/blacklight.rb +2 -2
  94. data/lib/generators/blacklight/assets/importmap_generator.rb +2 -2
  95. data/lib/generators/blacklight/assets_generator.rb +1 -1
  96. data/lib/generators/blacklight/controller_generator.rb +1 -1
  97. data/lib/generators/blacklight/document_generator.rb +1 -1
  98. data/lib/generators/blacklight/install_generator.rb +6 -4
  99. data/lib/generators/blacklight/models_generator.rb +1 -1
  100. data/lib/generators/blacklight/search_builder_generator.rb +1 -1
  101. data/lib/generators/blacklight/solr_generator.rb +1 -1
  102. data/lib/generators/blacklight/templates/catalog_controller.rb +21 -2
  103. data/lib/generators/blacklight/templates/solr/conf/schema.xml +264 -178
  104. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +6 -14
  105. data/lib/generators/blacklight/test_support_generator.rb +1 -1
  106. data/lib/generators/blacklight/user_generator.rb +66 -5
  107. data/lib/railties/blacklight.rake +4 -4
  108. data/package.json +2 -2
  109. data/spec/components/blacklight/document/action_component_spec.rb +1 -1
  110. data/spec/components/blacklight/document/group_component_spec.rb +1 -1
  111. data/spec/components/blacklight/document_component_spec.rb +9 -9
  112. data/spec/components/blacklight/facet_component_spec.rb +2 -2
  113. data/spec/components/blacklight/facets/filters_component_spec.rb +1 -1
  114. data/spec/components/blacklight/facets/index_navigation_component_spec.rb +1 -2
  115. data/spec/components/blacklight/facets/list_component_spec.rb +1 -1
  116. data/spec/components/blacklight/facets/suggest_component_spec.rb +2 -3
  117. data/spec/components/blacklight/metadata_field_component_spec.rb +26 -0
  118. data/spec/components/blacklight/skip_link_component_spec.rb +2 -2
  119. data/spec/controllers/application_controller_spec.rb +71 -0
  120. data/spec/controllers/bookmarks_controller_spec.rb +18 -5
  121. data/spec/controllers/catalog_controller_spec.rb +7 -5
  122. data/spec/features/advanced_search_spec.rb +29 -16
  123. data/spec/features/alternate_controller_spec.rb +4 -4
  124. data/spec/features/axe_spec.rb +34 -22
  125. data/spec/features/bookmarks_spec.rb +13 -13
  126. data/spec/features/dark_mode_spec.rb +42 -0
  127. data/spec/features/did_you_mean_spec.rb +27 -27
  128. data/spec/features/facet_missing_spec.rb +3 -3
  129. data/spec/features/facets_spec.rb +9 -0
  130. data/spec/features/record_view_spec.rb +14 -14
  131. data/spec/features/search_context_spec.rb +8 -8
  132. data/spec/features/search_filters_spec.rb +16 -16
  133. data/spec/features/search_formats_spec.rb +2 -2
  134. data/spec/features/search_history_spec.rb +11 -11
  135. data/spec/features/search_pagination_spec.rb +17 -17
  136. data/spec/features/search_results_spec.rb +3 -3
  137. data/spec/features/search_sort_spec.rb +4 -4
  138. data/spec/features/search_spec.rb +20 -20
  139. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +15 -15
  140. data/spec/helpers/blacklight_helper_spec.rb +1 -1
  141. data/spec/helpers/catalog_helper_spec.rb +7 -7
  142. data/spec/integration/generators/blacklight/user_generator_spec.rb +60 -0
  143. data/spec/lib/blacklight/search_state/pivot_filter_field_spec.rb +1 -1
  144. data/spec/models/blacklight/configurable_spec.rb +1 -1
  145. data/spec/models/blacklight/configuration_spec.rb +0 -19
  146. data/spec/models/blacklight/document/dublin_core_spec.rb +2 -2
  147. data/spec/models/blacklight/facet_paginator_spec.rb +1 -1
  148. data/spec/models/blacklight/search_builder_spec.rb +26 -4
  149. data/spec/models/blacklight/solr/repository_spec.rb +10 -2
  150. data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +165 -7
  151. data/spec/models/blacklight/user_spec.rb +32 -5
  152. data/spec/models/bookmark_spec.rb +1 -1
  153. data/spec/models/record_mailer_spec.rb +8 -8
  154. data/spec/models/search_spec.rb +1 -1
  155. data/spec/models/solr_document_spec.rb +4 -0
  156. data/spec/presenters/blacklight/index_presenter_spec.rb +1 -0
  157. data/spec/presenters/blacklight/rendering/pipeline_spec.rb +1 -0
  158. data/spec/presenters/blacklight/show_presenter_spec.rb +1 -0
  159. data/spec/presenters/blacklight/thumbnail_presenter_spec.rb +1 -0
  160. data/spec/services/blacklight/search_service_spec.rb +7 -7
  161. data/spec/spec_helper.rb +3 -12
  162. data/spec/support/features/session_helpers.rb +13 -4
  163. data/spec/support/features/turbo_helpers.rb +13 -0
  164. data/spec/support/features.rb +2 -0
  165. data/spec/support/user_helpers.rb +24 -0
  166. data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
  167. data/spec/views/catalog/_document.html.erb_spec.rb +4 -4
  168. data/spec/views/catalog/_paginate_compact.html.erb_spec.rb +2 -2
  169. data/spec/views/catalog/_sort_and_per_page.html.erb_spec.rb +5 -5
  170. data/spec/views/catalog/index.html.erb_spec.rb +2 -2
  171. data/spec/views/catalog/show.html.erb_spec.rb +3 -4
  172. data/spec/views/shared/_user_util_links.html.erb_spec.rb +56 -0
  173. data/template.demo.rb +2 -1
  174. metadata +30 -29
  175. data/.hound.yml +0 -4
  176. data/.jshintrc +0 -22
  177. data/app/assets/images/blacklight/logo.png +0 -0
  178. data/app/controllers/concerns/blacklight/facetable.rb +0 -34
  179. data/app/models/facet_search_builder.rb +0 -5
  180. data/app/services/blacklight/facet_search_service.rb +0 -44
  181. data/lib/blacklight/abstract_search_builder.rb +0 -154
  182. data/lib/blacklight/facet_search_builder.rb +0 -18
  183. data/lib/blacklight/solr/facet_search_builder_behavior.rb +0 -62
  184. data/spec/models/blacklight/facet_search_builder_spec.rb +0 -19
  185. data/spec/models/blacklight/solr/facet_search_builder_behavior_spec.rb +0 -929
@@ -3,10 +3,16 @@
3
3
  # SearchService returns search results from the repository
4
4
  module Blacklight
5
5
  class SearchService
6
+ # @params [Blacklight::Configuration] config
7
+ # @params [Blacklight::SearchState] search_state
8
+ # @params [Class] search_builder_class a class that inherits from Blacklight::SearchBuilder
9
+ # @params [Hash] context any data the search builder needs to access. For example, the current user.
6
10
  def initialize(config:, search_state:, search_builder_class: config.search_builder_class, **context)
7
11
  @blacklight_config = config
8
12
  @search_state = search_state
9
- @user_params = @search_state.params
13
+ @user_params = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(@search_state.params,
14
+ 'Use @search_state.params instead of @user_params',
15
+ Blacklight.deprecation)
10
16
  @search_builder_class = search_builder_class
11
17
  @context = context
12
18
  end
@@ -15,15 +21,13 @@ module Blacklight
15
21
  attr_reader :blacklight_config, :context
16
22
 
17
23
  def search_builder
18
- search_builder_class.new(self)
24
+ search_builder_class.new(self, blacklight_config: blacklight_config)
19
25
  end
20
26
 
21
- def search_state_class
22
- @search_state.class
23
- end
24
-
25
- # a solr query method
26
- # @yield [search_builder] optional block yields configured SearchBuilder, caller can modify or create new SearchBuilder to be used. Block should return SearchBuilder to be used.
27
+ # Fetch query results from solr
28
+ # @yield [search_builder] optional block yields configured SearchBuilder, caller can modify or create new
29
+ # SearchBuilder to be used. Block should return SearchBuilder to be used.
30
+ # This is used in blacklight_range_limit
27
31
  # @return [Blacklight::Solr::Response] the solr response object
28
32
  def search_results
29
33
  builder = search_builder.with(search_state)
@@ -69,11 +73,24 @@ module Blacklight
69
73
 
70
74
  # Get the previous and next document from a search result
71
75
  # @return [Blacklight::Solr::Response, Array<Blacklight::SolrDocument>] the solr response and a list of the first and last document
72
- def previous_and_next_documents_for_search(index, request_params, extra_controller_params = {})
73
- p = previous_and_next_document_params(index)
74
- new_state = request_params.is_a?(Blacklight::SearchState) ? request_params : Blacklight::SearchState.new(request_params, blacklight_config)
75
- query = search_builder.with(new_state).start(p.delete(:start)).rows(p.delete(:rows)).merge(extra_controller_params).merge(p)
76
- response = repository.search(params: query)
76
+ def previous_and_next_documents_for_search(index, request_params, params: nil, **extra_controller_params)
77
+ unless params
78
+ new_state = request_params.is_a?(Blacklight::SearchState) ? request_params : Blacklight::SearchState.new(request_params, blacklight_config)
79
+ builder = search_builder.with(new_state)
80
+
81
+ search_service_params = Blacklight.deprecation.silence do
82
+ previous_and_next_document_params(index)
83
+ end
84
+
85
+ builder = if search_service_params.empty?
86
+ builder.for_previous_and_next_documents(index).merge(extra_controller_params)
87
+ else
88
+ Blacklight.deprecation.warn("SearchService#previous_and_next_document_params returned parameters. Implement customizations in SearchBuilder#for_previous_and_next_document instead")
89
+ builder.start(search_service_params.delete(:start)).rows(search_service_params.delete(:rows)).merge(extra_controller_params).merge(search_service_params)
90
+ end
91
+ end
92
+
93
+ response = repository.search(params: params || builder)
77
94
  document_list = response.documents
78
95
 
79
96
  # only get the previous doc if there is one
@@ -88,14 +105,16 @@ module Blacklight
88
105
  # the second item is an other array. This second array contains
89
106
  # all of the field values for each of the documents...
90
107
  # where the field is the "field" argument passed in.
108
+ # @deprecated
91
109
  def opensearch_response(field = nil, extra_controller_params = {})
92
110
  field ||= blacklight_config.view_config(:opensearch).title_field
93
111
 
94
112
  query = search_builder.with(search_state).merge(solr_opensearch_params(field)).merge(extra_controller_params)
95
- response = repository.search(query)
113
+ response = repository.search(params: query)
96
114
 
97
115
  [search_state.query_param, response.documents.flat_map { |doc| doc[field] }.uniq]
98
116
  end
117
+ Blacklight.deprecation.deprecate_methods Blacklight::SearchService, opensearch_response: "The opensearch_response method is deprecated without replacement."
99
118
 
100
119
  private
101
120
 
@@ -111,34 +130,20 @@ module Blacklight
111
130
 
112
131
  ##
113
132
  # Opensearch autocomplete parameters for plucking a field's value from the results
133
+ # @deprecated
114
134
  def solr_opensearch_params(field)
115
135
  solr_params = {}
116
136
  solr_params[:rows] ||= 10
117
137
  solr_params[:fl] = field || blacklight_config.view_config(:opensearch).title_field
118
138
  solr_params
119
139
  end
140
+ Blacklight.deprecation.deprecate_methods Blacklight::SearchService, solr_opensearch_params: "The solr_opensearch_params method is deprecated without replacement."
120
141
 
121
- ##
122
- # Pagination parameters for selecting the previous and next documents
123
- # out of a result set.
124
- def previous_and_next_document_params(index, window = 1)
125
- solr_params = blacklight_config.document_pagination_params.dup
126
-
127
- if solr_params.empty?
128
- solr_params[:fl] = blacklight_config.document_model.unique_key
129
- end
130
-
131
- if index > 0
132
- solr_params[:start] = index - window # get one before
133
- solr_params[:rows] = (2 * window) + 1 # and one after
134
- else
135
- solr_params[:start] = 0 # there is no previous doc
136
- solr_params[:rows] = 2 * window # but there should be one after
137
- end
138
-
139
- solr_params[:facet] = false
140
- solr_params
142
+ def previous_and_next_document_params(*, **)
143
+ {}
141
144
  end
145
+ Blacklight.deprecation.deprecate_methods(Blacklight::SearchService,
146
+ previous_and_next_document_params: "Use SearchBuilder#for_previous_and_next_documents instead of SearchService#previous_and_next_document_params")
142
147
 
143
148
  ##
144
149
  # Retrieve a set of documents by id
@@ -147,11 +152,20 @@ module Blacklight
147
152
  def fetch_many(ids, extra_controller_params)
148
153
  extra_controller_params ||= {}
149
154
 
155
+ requested_rows = extra_controller_params.delete(:rows)
156
+ if requested_rows
157
+ Blacklight.deprecation.warn("Passing :rows to fetch_many is deprecated. Create an issue in blacklight if you see this warning. " \
158
+ "Otherwise, :rows will be ignored in Blackight 10")
159
+ else
160
+ requested_rows = ids.count
161
+ end
162
+
150
163
  query = search_builder
151
164
  .with(search_state)
152
165
  .where(blacklight_config.document_model.unique_key => ids)
153
166
  .merge(blacklight_config.fetch_many_document_params)
154
167
  .merge(extra_controller_params)
168
+ query.rows(requested_rows)
155
169
 
156
170
  # find_many was introduced in Blacklight 8.4. Before that, we used the
157
171
  # regular search method (possibly with a find-many specific `qt` parameter).
@@ -160,7 +174,8 @@ module Blacklight
160
174
  solr_response = if repository.respond_to?(:find_many)
161
175
  repository.find_many(query)
162
176
  else
163
- repository.search(query)
177
+ Blacklight.deprecation.warn("Repository#find_many is not implemented. Falling back to Repository#search.")
178
+ repository.search(params: query)
164
179
  end
165
180
 
166
181
  solr_response.documents
@@ -88,7 +88,7 @@ module Blacklight
88
88
  def cast(input)
89
89
  value = super
90
90
 
91
- return value unless value.is_a?(String)
91
+ return value unless value.is_a?(::String)
92
92
 
93
93
  JSON.parse(value)
94
94
  end
@@ -6,7 +6,7 @@
6
6
 
7
7
  <div class="modal-body">
8
8
  <%= render '/shared/flash_msg' %>
9
- <div class="row">
9
+ <div class="row mb-3">
10
10
  <label class="col-form-label col-sm-2" for="to">
11
11
  <%= t('blacklight.email.form.to') %>
12
12
  </label>
@@ -15,7 +15,7 @@
15
15
  </div>
16
16
  </div>
17
17
 
18
- <div class="row">
18
+ <div class="row mb-3">
19
19
  <label class="col-form-label col-sm-2" for="message">
20
20
  <%= t('blacklight.email.form.message') %>
21
21
  </label>
@@ -25,7 +25,7 @@
25
25
  </div>
26
26
 
27
27
  <% @documents&.each do |doc| %>
28
- <%=hidden_field_tag "id[]", doc.id %>
28
+ <%= hidden_field_tag "id[]", doc.id %>
29
29
  <% end %>
30
30
  <%- if params[:sort] -%>
31
31
  <%= hidden_field_tag "sort", params[:sort] %>
@@ -1,4 +1,4 @@
1
- <div class="text-center p-5 mb-4 bg-light rounded-3">
1
+ <div class="text-center p-5 mb-4 bg-body-tertiary border rounded-3">
2
2
  <h1 class="fw-bold"><%= t('blacklight.welcome') %></h1>
3
3
 
4
4
  <p class="lead">Blacklight is a multi-institutional open-source collaboration building a better discovery platform framework.</p>
@@ -5,7 +5,7 @@
5
5
  method: :post do %>
6
6
  <div class="modal-body">
7
7
  <%= render '/shared/flash_msg' %>
8
- <div class="row">
8
+ <div class="row mb-3">
9
9
  <label class="col-form-label col-sm-2" for="to">
10
10
  <%= t('blacklight.sms.form.to') %>
11
11
  </label>
@@ -13,17 +13,17 @@
13
13
  <%= telephone_field_tag :to, params[:to], class: 'form-control', required: true %>
14
14
  </div>
15
15
  </div>
16
- <div class="row">
16
+ <div class="row mb-3">
17
17
  <label class="col-form-label col-sm-2" for="carrier">
18
18
  <%= t('blacklight.sms.form.carrier') %>
19
19
  </label>
20
20
  <div class="col-sm-10">
21
- <%= select_tag(:carrier, options_for_select(sms_mappings.to_a.sort.unshift([t('blacklight.sms.form.carrier_prompt'),'']), params[:carrier]), class: 'form-control') %><br/>
21
+ <%= select_tag(:carrier, options_for_select(sms_mappings.to_a.sort.unshift([t('blacklight.sms.form.carrier_prompt'),'']), params[:carrier]), class: 'form-control') %><br>
22
22
  </div>
23
23
 
24
24
  </div>
25
25
  <% @documents&.each do |doc| %>
26
- <%=hidden_field_tag "id[]", doc.id %>
26
+ <%= hidden_field_tag "id[]", doc.id %>
27
27
  <% end %>
28
28
  </div>
29
29
  <div class="modal-footer">
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  xml.instruct! :xml, version: "1.0"
4
- xml.rss(version: "2.0") {
5
- xml.channel {
4
+ xml.rss(version: "2.0") do
5
+ xml.channel do
6
6
  xml.title(t('blacklight.search.page_title.title', constraints: render_search_to_page_title(params), application_name: application_name))
7
7
  xml.link(search_action_url(search_state.to_h.merge(only_path: false)))
8
8
  xml.description(t('blacklight.search.page_title.title', constraints: render_search_to_page_title(params), application_name: application_name))
@@ -10,5 +10,5 @@ xml.rss(version: "2.0") {
10
10
  @response.documents.each_with_index do |document, document_counter|
11
11
  xml << render_xml_partials(document, blacklight_config.view_config(:rss).partials, document_counter: document_counter)
12
12
  end
13
- }
14
- }
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ json.array! [search_state.query_param] + @presenter.documents.map { |document| document_presenter(document).heading }.uniq
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  xml.instruct! :xml, version: '1.0'
4
- xml.OpenSearchDescription(xmlns: 'http://a9.com/-/spec/opensearch/1.1/') {
4
+ xml.OpenSearchDescription(xmlns: 'http://a9.com/-/spec/opensearch/1.1/') do
5
5
  xml.ShortName application_name
6
6
  xml.Description "#{application_name} Search"
7
7
  xml.Image asset_url('favicon.ico'), height: 16, width: 16, type: 'image/x-icon'
@@ -9,4 +9,4 @@ xml.OpenSearchDescription(xmlns: 'http://a9.com/-/spec/opensearch/1.1/') {
9
9
  xml.Url type: 'text/html', method: 'get', template: "#{url_for controller: 'catalog', only_path: false}?q={searchTerms}&amp;page={startPage?}"
10
10
  xml.Url type: 'application/rss+xml', method: 'get', template: "#{url_for controller: 'catalog', only_path: false}.rss?q={searchTerms}&amp;page={startPage?}"
11
11
  xml.Url type: 'application/x-suggestions+json', method: 'get', template: "#{url_for controller: 'catalog', action: 'opensearch', format: 'json', only_path: false}?q={searchTerms}"
12
- }
12
+ end
@@ -6,9 +6,21 @@
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7
7
 
8
8
  <title><%= render_page_title %></title>
9
+
10
+ <% if dark_mode_support? %>
9
11
  <script>
10
- document.querySelector('html').classList.remove('no-js');
12
+ (() => {
13
+ const theme = localStorage.getItem('theme') || 'auto';
14
+ if (theme === 'auto') {
15
+ document.documentElement.setAttribute('data-bs-theme', window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
16
+ } else {
17
+ document.documentElement.setAttribute('data-bs-theme', theme);
18
+ }
19
+ document.querySelector('html').classList.remove('no-js');
20
+ })();
11
21
  </script>
22
+ <% end %>
23
+
12
24
  <%= opensearch_description_tag application_name, opensearch_catalog_url(format: 'xml') %>
13
25
  <%= favicon_link_tag %>
14
26
  <%= stylesheet_link_tag "application", media: "all", "data-turbo-track": "reload" %>
@@ -4,19 +4,32 @@
4
4
  <% end %>
5
5
 
6
6
  <% if has_user_authentication_provider? %>
7
- <% if current_user %>
7
+ <% user = current_user if respond_to?(:current_user) %>
8
+ <% if user %>
9
+ <% if blacklight_logout_path %>
8
10
  <li class="nav-item">
9
- <%= link_to t('blacklight.header_links.logout'), destroy_user_session_path, class: 'nav-link' %>
11
+ <%= link_to t('blacklight.header_links.logout'), blacklight_logout_path, { class: 'nav-link' }.merge(blacklight_logout_link_options) %>
10
12
  </li>
11
- <% unless current_user.to_s.blank? -%>
13
+ <% end %>
14
+ <% if blacklight_account_path && user.to_s.present? -%>
12
15
  <li class="nav-item">
13
- <%= link_to current_user, edit_user_registration_path, class: 'nav-link' %>
16
+ <%= link_to user, blacklight_account_path, class: 'nav-link' %>
14
17
  </li>
15
18
  <% end %>
16
19
  <% else %>
20
+ <% if blacklight_login_path %>
17
21
  <li class="nav-item">
18
- <%= link_to t('blacklight.header_links.login'), new_user_session_path, class: 'nav-link' %>
22
+ <%= link_to t('blacklight.header_links.login'), blacklight_login_path, class: 'nav-link' %>
19
23
  </li>
20
24
  <% end %>
25
+ <% end %>
26
+ <% end %>
27
+
28
+ <% if dark_mode_support? %>
29
+ <li class="nav-item py-2 py-md-1 col-12 col-md-auto">
30
+ <div class="vr d-none d-md-flex h-100 mx-md-2 text-white"></div>
31
+ <hr class="d-md-none my-2 text-white-50">
32
+ </li>
33
+ <%= render Blacklight::ThemeSwitcherComponent.new %>
21
34
  <% end %>
22
35
  </ul>
data/blacklight.gemspec CHANGED
@@ -23,15 +23,15 @@ Gem::Specification.new do |s|
23
23
  s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
24
  s.require_paths = ["lib"]
25
25
 
26
- s.required_ruby_version = '>= 3.1'
26
+ s.required_ruby_version = '>= 3.3'
27
27
 
28
- s.add_dependency "rails", '>= 7.0', '< 9'
28
+ s.add_dependency "rails", '>= 7.2', '< 9'
29
29
  s.add_dependency "globalid"
30
30
  s.add_dependency "jbuilder", '~> 2.7'
31
31
  s.add_dependency "kaminari", ">= 0.15" # the pagination (page 1,2,3, etc..) of our search results
32
32
  s.add_dependency "i18n", '>= 1.7.0' # added named parameters
33
33
  s.add_dependency "ostruct", '>= 0.3.2'
34
- s.add_dependency "view_component", '>= 3.0', '< 5.0'
34
+ s.add_dependency "view_component", '~> 4.0'
35
35
  s.add_dependency "zeitwerk"
36
36
 
37
37
  s.add_development_dependency "rsolr", ">= 1.0.6", "< 3" # Library for interacting with rSolr.
@@ -212,6 +212,11 @@ ar:
212
212
  success: تم الإرسال كرسالة نصية قصيرة
213
213
  text:
214
214
  url: "الرابط: %{url}"
215
+ theme:
216
+ auto: تلقائي
217
+ dark: داكن
218
+ light: فاتح
219
+ toggle: تبديل المظهر
215
220
  tools:
216
221
  citation: استشهاد مرجعي
217
222
  clear: مسح
@@ -76,6 +76,11 @@ ca:
76
76
  forget: "oblida-ho"
77
77
  save: "desa-ho"
78
78
 
79
+ theme:
80
+ auto: Automàtic
81
+ dark: Fosc
82
+ light: Clar
83
+ toggle: Canvia el tema
79
84
  tools:
80
85
  title: "Eines"
81
86
  citation: "Citació"
@@ -91,8 +91,7 @@ de:
91
91
  group:
92
92
  close: Facetten ausblenden
93
93
  open: Facetten zeigen
94
- missing:
95
- - fehlt
94
+ missing: "[fehlt]"
96
95
  more_html: mehr <span class="visually-hidden">%{field_name}</span> »
97
96
  pivot:
98
97
  hide: Schließen
@@ -199,6 +198,11 @@ de:
199
198
  success: SMS verschickt
200
199
  text:
201
200
  url: "Link: %{url}"
201
+ theme:
202
+ auto: Automatisch
203
+ dark: Dunkel
204
+ light: Hell
205
+ toggle: Design umschalten
202
206
  tools:
203
207
  citation: Zitieren
204
208
  clear: Löschen
@@ -217,6 +217,11 @@ en:
217
217
  success: SMS Sent
218
218
  text:
219
219
  url: "Link: %{url}"
220
+ theme:
221
+ auto: Auto
222
+ dark: Dark
223
+ light: Light
224
+ toggle: Toggle theme
220
225
  tools:
221
226
  citation: Cite
222
227
  clear: Clear
@@ -198,6 +198,11 @@ es:
198
198
  success: SMS enviado
199
199
  text:
200
200
  url: "Link: %{url}"
201
+ theme:
202
+ auto: Automático
203
+ dark: Oscuro
204
+ light: Claro
205
+ toggle: Cambiar tema
201
206
  tools:
202
207
  citation: Cité
203
208
  clear: Borrar
@@ -198,6 +198,11 @@ fr:
198
198
  success: SMS envoyé
199
199
  text:
200
200
  url: "Lien : %{url}"
201
+ theme:
202
+ auto: Automatique
203
+ dark: Sombre
204
+ light: Clair
205
+ toggle: Changer le thème
201
206
  tools:
202
207
  citation: Citer
203
208
  clear: Effacer
@@ -196,6 +196,11 @@ hu:
196
196
  success: SMS elküldve
197
197
  text:
198
198
  url: "Link: %{url}"
199
+ theme:
200
+ auto: Automatikus
201
+ dark: Sötét
202
+ light: Világos
203
+ toggle: Téma váltása
199
204
  tools:
200
205
  citation: Hivatkozás
201
206
  clear: Eltávolítás
@@ -91,8 +91,7 @@ it:
91
91
  group:
92
92
  close: Nascondi sfaccettature
93
93
  open: Mostra sfaccettature
94
- missing:
95
- - Mancante
94
+ missing: "[Mancante]"
96
95
  more_html: altri <span class="visually-hidden">%{field_name}</span> »
97
96
  pivot:
98
97
  hide: Chiudi
@@ -199,6 +198,11 @@ it:
199
198
  success: SMS inviato
200
199
  text:
201
200
  url: "Link: %{url}"
201
+ theme:
202
+ auto: Automatico
203
+ dark: Scuro
204
+ light: Chiaro
205
+ toggle: Cambia tema
202
206
  tools:
203
207
  citation: Cita
204
208
  clear: Cancella
@@ -196,6 +196,11 @@ nl:
196
196
  success: SMS Verzonden
197
197
  text:
198
198
  url: "Link: %{url}"
199
+ theme:
200
+ auto: Automatisch
201
+ dark: Donker
202
+ light: Licht
203
+ toggle: Thema wisselen
199
204
  tools:
200
205
  citation: Citeer
201
206
  clear: Leeg maken
@@ -89,8 +89,7 @@ pt-BR:
89
89
  group:
90
90
  close: Ocultar facetas
91
91
  open: Mostrar facetas
92
- missing:
93
- - Ausência
92
+ missing: "[Ausência]"
94
93
  more_html: mais <span class="visually-hidden">%{field_name}</span> »
95
94
  pivot:
96
95
  hide: Fechar
@@ -197,6 +196,11 @@ pt-BR:
197
196
  success: SMS Enviado
198
197
  text:
199
198
  url: "Link: %{url}"
199
+ theme:
200
+ auto: Automático
201
+ dark: Escuro
202
+ light: Claro
203
+ toggle: Alternar tema
200
204
  tools:
201
205
  citation: Citar
202
206
  clear: Limpar
@@ -196,6 +196,11 @@ sq:
196
196
  success: SMS-i u dëgua
197
197
  text:
198
198
  url: "Link: %{url}"
199
+ theme:
200
+ auto: Automatik
201
+ dark: E errët
202
+ light: E çelët
203
+ toggle: Ndrysho temën
199
204
  tools:
200
205
  citation: Citati
201
206
  clear: Fshij
@@ -196,6 +196,11 @@ zh:
196
196
  success: 已发送短信
197
197
  text:
198
198
  url: "链接: %{url}"
199
+ theme:
200
+ auto: 自动
201
+ dark: 深色
202
+ light: 浅色
203
+ toggle: 切换主题
199
204
  tools:
200
205
  citation: 引用
201
206
  clear: 清除
@@ -15,7 +15,7 @@ module Blacklight
15
15
  # provided by Blacklight.
16
16
  def sidecar_files(*args, **kwargs)
17
17
  upstream_sidecar_files(*args, **kwargs).map do |path|
18
- components_path = ViewComponent::VERSION::MAJOR == 3 ? view_component_path : config.generate.path
18
+ components_path = config.generate.path
19
19
 
20
20
  app_path = Rails.root.join(path.slice(path.index(components_path)..-1).to_s).to_s
21
21
 
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class Configuration::ActionConfigMapEntry < OpenStructWithHashAccess
5
+ # @!attribute parent_action_key
6
+ # Pull in the configuration for this action from another action's config
7
+ # @return [Symbol]
8
+
9
+ def parent_config = parent_action_key
10
+
11
+ def parent_config=(value)
12
+ self.parent_action_key = value
13
+ end
14
+
15
+ #
16
+ # @!attribute blacklight_config_property
17
+ # Pull in the configuration for this action from a top-level config
18
+ # @return [Symbol]
19
+
20
+ def top_level_config = blacklight_config_property
21
+
22
+ def top_level_config=(value)
23
+ self.blacklight_config_property = value
24
+ end
25
+
26
+ #
27
+ # @!attribute default
28
+ # Pull in additional default configuration for this action from a top-level config
29
+ # @return [Array<Symbol>]
30
+ end
31
+ end
@@ -35,6 +35,7 @@ module Blacklight
35
35
  # @return [Blacklight::FieldPresenter]
36
36
  # @!attribute component
37
37
  # @return [Blacklight::MetadataFieldComponent]
38
+ # @!attribute layout_component
38
39
 
39
40
  ##
40
41
  # Default rendering pipeline:
@@ -17,20 +17,20 @@ module Blacklight
17
17
 
18
18
  def normalize! _blacklight_config = nil
19
19
  self.field ||= key
20
- self.key ||= self.field
20
+ self.key ||= field
21
21
 
22
22
  self.label ||= default_label
23
23
 
24
24
  self.if = true if self.if.nil?
25
25
  self.unless = false if self.unless.nil?
26
26
 
27
- self.field &&= self.field.to_s
27
+ self.field &&= field.to_s
28
28
 
29
29
  self
30
30
  end
31
31
 
32
32
  def validate!
33
- raise ArgumentError, "Must supply a field name" if self.field.nil?
33
+ raise ArgumentError, "Must supply a field name" if field.nil?
34
34
  end
35
35
 
36
36
  def display_label(context = nil, **)
@@ -44,10 +44,10 @@ module Blacklight
44
44
  end
45
45
 
46
46
  def default_label
47
- if self.key.respond_to?(:titleize)
48
- self.key.titleize
47
+ if key.respond_to?(:titleize)
48
+ key.titleize
49
49
  else
50
- self.key.to_s.titleize
50
+ key.to_s.titleize
51
51
  end
52
52
  end
53
53
 
@@ -146,7 +146,7 @@ module Blacklight
146
146
 
147
147
  @table[:reflected_fields] ||= Rails.cache.fetch("blacklight_configuration/admin/reflected_fields", expires_in: 1.hour) do
148
148
  repository.reflect_fields
149
- rescue => e
149
+ rescue StandardError => e
150
150
  Blacklight.logger&.warn "Error retrieving field metadata: #{e}"
151
151
  false
152
152
  end
@@ -10,13 +10,13 @@ module Blacklight
10
10
  self.field ||= label&.parameterize
11
11
  self.field ||= sort
12
12
 
13
- self.sort ||= self.field
13
+ self.sort ||= field
14
14
 
15
15
  self
16
16
  end
17
17
 
18
18
  def validate!
19
- raise ArgumentError.new, "Must supply a sort string" if self.sort.nil?
19
+ raise ArgumentError.new, "Must supply a sort string" if sort.nil?
20
20
  end
21
21
  end
22
22
  end