blacklight 8.0.0.beta1 → 8.0.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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/.env +1 -0
  3. data/.github/workflows/ruby.yml +6 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop_todo.yml +3 -1
  6. data/README.md +1 -1
  7. data/Rakefile +18 -0
  8. data/VERSION +1 -1
  9. data/app/assets/config/blacklight/manifest.js +3 -0
  10. data/app/assets/javascripts/blacklight/blacklight.esm.js +132 -140
  11. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  12. data/app/assets/javascripts/blacklight/blacklight.js +132 -140
  13. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  14. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +1 -1
  15. data/app/assets/stylesheets/blacklight/_facets.scss +32 -5
  16. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +1 -1
  17. data/app/components/blacklight/advanced_search_form_component.rb +3 -3
  18. data/app/components/blacklight/document/actions_component.rb +1 -1
  19. data/app/components/blacklight/document/show_tools_component.html.erb +12 -0
  20. data/app/components/blacklight/document/show_tools_component.rb +23 -0
  21. data/app/components/blacklight/document_component.rb +48 -20
  22. data/app/components/blacklight/document_metadata_component.html.erb +4 -2
  23. data/app/components/blacklight/document_metadata_component.rb +8 -2
  24. data/app/components/blacklight/facet_field_checkboxes_component.html.erb +2 -2
  25. data/app/components/blacklight/facet_field_list_component.html.erb +2 -2
  26. data/app/components/blacklight/metadata_field_component.html.erb +2 -2
  27. data/app/components/blacklight/metadata_field_layout_component.rb +7 -4
  28. data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +17 -0
  29. data/app/components/blacklight/response/facet_group_component.html.erb +2 -1
  30. data/app/components/blacklight/response/facet_group_component.rb +1 -1
  31. data/app/components/blacklight/response/sort_component.rb +1 -1
  32. data/app/components/blacklight/response/spellcheck_component.rb +1 -1
  33. data/app/components/blacklight/response/view_type_button_component.rb +1 -1
  34. data/app/components/blacklight/response/view_type_component.rb +2 -2
  35. data/app/components/blacklight/search/sidebar_component.html.erb +1 -1
  36. data/app/components/blacklight/search_context/server_applied_params_component.html.erb +4 -0
  37. data/app/components/blacklight/search_context/server_applied_params_component.rb +13 -0
  38. data/app/components/blacklight/search_context/server_item_pagination_component.rb +71 -0
  39. data/app/components/blacklight/system/dropdown_component.rb +3 -3
  40. data/app/components/blacklight/system/flash_message_component.rb +2 -2
  41. data/app/components/blacklight/system/modal_component.rb +1 -1
  42. data/app/components/blacklight/top_navbar_component.html.erb +1 -1
  43. data/app/components/blacklight/top_navbar_component.rb +4 -0
  44. data/app/controllers/concerns/blacklight/bookmarks.rb +1 -1
  45. data/app/controllers/concerns/blacklight/search_context.rb +46 -6
  46. data/app/helpers/blacklight/blacklight_helper_behavior.rb +0 -101
  47. data/app/helpers/blacklight/catalog_helper_behavior.rb +27 -54
  48. data/app/helpers/blacklight/component_helper_behavior.rb +0 -11
  49. data/app/helpers/blacklight/document_helper_behavior.rb +76 -0
  50. data/app/helpers/blacklight/layout_helper_behavior.rb +59 -0
  51. data/app/helpers/blacklight/render_partials_helper_behavior.rb +1 -0
  52. data/app/helpers/blacklight/url_helper_behavior.rb +11 -3
  53. data/app/javascript/blacklight/bookmark_toggle.js +8 -15
  54. data/app/javascript/blacklight/button_focus.js +10 -10
  55. data/app/javascript/blacklight/index.js +6 -5
  56. data/app/javascript/blacklight/modal.js +24 -24
  57. data/app/javascript/blacklight/search_context.js +51 -57
  58. data/app/models/concerns/blacklight/document.rb +11 -0
  59. data/app/models/record_mailer.rb +19 -15
  60. data/app/presenters/blacklight/document_presenter.rb +13 -11
  61. data/app/presenters/blacklight/index_presenter.rb +1 -1
  62. data/app/presenters/blacklight/rendering/abstract_step.rb +4 -0
  63. data/app/presenters/blacklight/rendering/join.rb +7 -1
  64. data/app/presenters/blacklight/rendering/link_to_facet.rb +1 -1
  65. data/app/presenters/blacklight/rendering/microdata.rb +1 -1
  66. data/app/services/blacklight/search_service.rb +2 -1
  67. data/app/views/catalog/_document.atom.builder +1 -1
  68. data/app/views/catalog/_document.html.erb +3 -8
  69. data/app/views/catalog/_document_list.html.erb +2 -1
  70. data/app/views/catalog/_facet_layout.html.erb +2 -2
  71. data/app/views/catalog/_show_main_content.html.erb +5 -11
  72. data/app/views/catalog/_show_tools.html.erb +1 -14
  73. data/app/views/catalog/facet.html.erb +3 -3
  74. data/app/views/catalog/index.html.erb +3 -0
  75. data/app/views/catalog/show.html.erb +1 -6
  76. data/app/views/layouts/blacklight/base.html.erb +4 -5
  77. data/app/views/record_mailer/email_record.text.erb +4 -3
  78. data/app/views/record_mailer/sms_record.text.erb +4 -4
  79. data/blacklight.gemspec +2 -2
  80. data/config/importmap.rb +1 -1
  81. data/config/locales/blacklight.ar.yml +209 -232
  82. data/config/locales/blacklight.ca.yml +0 -6
  83. data/config/locales/blacklight.de.yml +197 -215
  84. data/config/locales/blacklight.en.yml +2 -6
  85. data/config/locales/blacklight.es.yml +196 -215
  86. data/config/locales/blacklight.fr.yml +196 -219
  87. data/config/locales/blacklight.hu.yml +193 -212
  88. data/config/locales/blacklight.it.yml +197 -215
  89. data/config/locales/blacklight.nl.yml +193 -212
  90. data/config/locales/blacklight.pt-BR.yml +195 -215
  91. data/config/locales/blacklight.sq.yml +193 -212
  92. data/config/locales/blacklight.zh.yml +194 -213
  93. data/docker-compose.yml +1 -0
  94. data/lib/blacklight/configuration/session_tracking_config.rb +45 -0
  95. data/lib/blacklight/configuration/view_config.rb +0 -4
  96. data/lib/blacklight/configuration.rb +8 -4
  97. data/lib/blacklight/engine.rb +6 -7
  98. data/lib/blacklight/routes/searchable.rb +1 -0
  99. data/lib/generators/blacklight/assets/importmap_generator.rb +9 -8
  100. data/lib/generators/blacklight/assets/propshaft_generator.rb +11 -2
  101. data/lib/generators/blacklight/assets/sprockets_generator.rb +2 -0
  102. data/lib/generators/blacklight/assets_generator.rb +3 -1
  103. data/lib/generators/blacklight/install_generator.rb +3 -1
  104. data/lib/generators/blacklight/templates/solr_document.rb +0 -6
  105. data/package.json +7 -4
  106. data/rollup.config.js +11 -1
  107. data/spec/components/blacklight/document_component_spec.rb +66 -15
  108. data/spec/components/blacklight/header_component_spec.rb +20 -0
  109. data/spec/components/blacklight/response/view_type_component_spec.rb +17 -0
  110. data/spec/components/blacklight/search_bar_component_spec.rb +1 -1
  111. data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +29 -0
  112. data/spec/components/blacklight/{search_context_component_spec.rb → search_context/server_item_pagination_component_spec.rb} +15 -4
  113. data/spec/controllers/bookmarks_controller_spec.rb +1 -1
  114. data/spec/controllers/catalog_controller_spec.rb +18 -6
  115. data/spec/features/component_template_override_spec.rb +8 -0
  116. data/spec/features/modal_spec.rb +12 -0
  117. data/spec/features/sitelinks_search_box_spec.rb +13 -0
  118. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +1 -1
  119. data/spec/helpers/blacklight_helper_spec.rb +0 -56
  120. data/spec/helpers/catalog_helper_spec.rb +56 -0
  121. data/spec/lib/blacklight/configuration/session_tracking_config_spec.rb +38 -0
  122. data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +2 -2
  123. data/spec/models/blacklight/configuration_spec.rb +2 -2
  124. data/spec/models/blacklight/icon_spec.rb +0 -2
  125. data/spec/models/blacklight/search_builder_spec.rb +3 -3
  126. data/spec/models/blacklight/solr/request_spec.rb +2 -2
  127. data/spec/models/record_mailer_spec.rb +36 -23
  128. data/spec/presenters/blacklight/document_presenter_spec.rb +1 -0
  129. data/spec/presenters/blacklight/field_presenter_spec.rb +2 -2
  130. data/spec/presenters/blacklight/index_presenter_spec.rb +1 -0
  131. data/spec/presenters/blacklight/show_presenter_spec.rb +1 -0
  132. data/spec/presenters/pipeline_spec.rb +13 -2
  133. data/spec/routing/catalog_routing_spec.rb +4 -0
  134. data/spec/spec_helper.rb +1 -1
  135. data/spec/support/view_component_test_helpers.rb +21 -0
  136. data/spec/test_app_templates/Gemfile.extra +4 -0
  137. data/spec/test_app_templates/lib/generators/test_app_generator.rb +8 -0
  138. data/spec/views/catalog/_document.html.erb_spec.rb +22 -1
  139. data/spec/views/catalog/_document_list.html.erb_spec.rb +7 -2
  140. data/spec/views/catalog/_show_tools.html.erb_spec.rb +2 -2
  141. data/spec/views/catalog/index.json.jbuilder_spec.rb +1 -1
  142. data/tasks/blacklight.rake +1 -1
  143. metadata +39 -21
  144. data/app/components/blacklight/search_context_component.rb +0 -68
  145. data/app/models/concerns/blacklight/document/email.rb +0 -27
  146. data/app/models/concerns/blacklight/document/sms.rb +0 -25
  147. data/spec/features/sitelinks_search_box.rb +0 -13
  148. data/spec/models/blacklight/document/email_spec.rb +0 -57
  149. data/spec/models/blacklight/document/sms_spec.rb +0 -58
  150. data/spec/support/view_component_capybara_test_helpers.rb +0 -8
  151. /data/app/components/blacklight/{search_context_component.html.erb → search_context/server_item_pagination_component.html.erb} +0 -0
@@ -6,8 +6,6 @@ module Blacklight::BlacklightHelperBehavior
6
6
  include Blacklight::LayoutHelperBehavior
7
7
  include Blacklight::IconHelperBehavior
8
8
 
9
- # @!group Layout helpers
10
-
11
9
  ##
12
10
  # Get the name of this application from an i18n string
13
11
  # key: blacklight.application_name
@@ -23,63 +21,6 @@ module Blacklight::BlacklightHelperBehavior
23
21
  end
24
22
  end
25
23
 
26
- ##
27
- # Get the page's HTML title
28
- #
29
- # @return [String]
30
- def render_page_title
31
- (content_for(:page_title) if content_for?(:page_title)) || @page_title || application_name
32
- end
33
-
34
- ##
35
- # Create <link rel="alternate"> links from a documents dynamically
36
- # provided export formats.
37
- #
38
- # Returns empty string if no links available.
39
- #
40
- # @param [SolrDocument] document
41
- # @param [Hash] options
42
- # @option options [Boolean] :unique ensures only one link is output for every
43
- # content type, e.g. as required by atom
44
- # @option options [Array<String>] :exclude array of format shortnames to not include in the output
45
- # @return [String]
46
- def render_link_rel_alternates(document = @document, options = {})
47
- return if document.nil?
48
-
49
- document_presenter(document).link_rel_alternates(options)
50
- end
51
-
52
- ##
53
- # Render classes for the <body> element
54
- # @return [String]
55
- def render_body_class
56
- extra_body_classes.join " "
57
- end
58
-
59
- ##
60
- # List of classes to be applied to the <body> element
61
- # @see render_body_class
62
- # @return [Array<String>]
63
- def extra_body_classes
64
- @extra_body_classes ||= ["blacklight-#{controller.controller_name}", "blacklight-#{[controller.controller_name, controller.action_name].join('-')}"]
65
- end
66
-
67
- ##
68
- # Get the current "view type" (and ensure it is a valid type)
69
- #
70
- # @param [Hash] query_params the query parameters to check
71
- # @return [Symbol]
72
- def document_index_view_type query_params = params
73
- view_param = query_params[:view]
74
- view_param ||= session[:preferred_view]
75
- if view_param && document_index_views.key?(view_param.to_sym)
76
- view_param.to_sym
77
- else
78
- default_document_index_view_type
79
- end
80
- end
81
-
82
- # @!group Search result helpers
83
24
  ##
84
25
  # Render a partial of an arbitrary format inside a
85
26
  # template of a different format. (e.g. render an HTML
@@ -96,46 +37,4 @@ module Blacklight::BlacklightHelperBehavior
96
37
  self.formats = old_formats
97
38
  nil
98
39
  end
99
-
100
- ##
101
- # Should we render a grouped response (because the response
102
- # contains a grouped response instead of the normal response)
103
- #
104
- # Default to false if there's no response object available (sometimes the case
105
- # for tests, but might happen in other circumstances too..)
106
- # @return [Boolean]
107
- def render_grouped_response? response = @response
108
- response&.grouped?
109
- end
110
-
111
- ##
112
- # Returns a document presenter for the given document
113
- def document_presenter(document)
114
- document_presenter_class(document).new(document, self)
115
- end
116
-
117
- ##
118
- # Override this method if you want to use a differnet presenter for your documents
119
- # @param [Blacklight::Document] _document optional, here for extension + backwards compatibility only
120
- def document_presenter_class(_document = nil)
121
- case action_name
122
- when 'show', 'citation'
123
- blacklight_config.view_config(:show, action_name: action_name).document_presenter_class
124
- else
125
- blacklight_config.view_config(document_index_view_type, action_name: action_name).document_presenter_class
126
- end
127
- end
128
-
129
- # @return [Class]
130
- def search_bar_presenter_class
131
- blacklight_config.view_config(action_name: :index).search_bar_presenter_class
132
- end
133
-
134
- # @!group Layout helpers
135
- ##
136
- # Open Search discovery tag for HTML <head> links
137
- # @return [String]
138
- def opensearch_description_tag title, href
139
- tag :link, href: href, title: title, type: "application/opensearchdescription+xml", rel: "search"
140
- end
141
40
  end
@@ -4,6 +4,7 @@
4
4
  module Blacklight::CatalogHelperBehavior
5
5
  include Blacklight::ConfigurationHelperBehavior
6
6
  include Blacklight::ComponentHelperBehavior
7
+ include Blacklight::DocumentHelperBehavior
7
8
  include Blacklight::FacetsHelperBehavior
8
9
  include Blacklight::RenderPartialsHelperBehavior
9
10
 
@@ -113,40 +114,6 @@ module Blacklight::CatalogHelperBehavior
113
114
  (@response.rows if @response && @response.rows > 0) || params.fetch(:per_page, blacklight_config.default_per_page).to_i
114
115
  end
115
116
 
116
- ##
117
- # Get the classes to add to a document's div
118
- #
119
- # @param [Blacklight::Document] document
120
- # @return [String]
121
- def render_document_class(document = @document)
122
- types = document_presenter(document).display_type
123
- return if types.blank?
124
-
125
- Array(types).compact.map do |t|
126
- "#{document_class_prefix}#{t.try(:parameterize) || t}"
127
- end.join(' ')
128
- end
129
-
130
- ##
131
- # Return a prefix for the document classes infered from the document
132
- # @see #render_document_class
133
- # @return [String]
134
- def document_class_prefix
135
- 'blacklight-'
136
- end
137
-
138
- ##
139
- # Render the sidebar partial for a document
140
- # This is used as an integration point by downstream apps to add to the
141
- # default sidebar.
142
- # See: https://github.com/geoblacklight/geoblacklight/blob/7d3c31c7af3362879b97e2c1351a2496c728c59c/app/helpers/blacklight_helper.rb#L7
143
- #
144
- # @param [SolrDocument] document
145
- # @return [String]
146
- def render_document_sidebar_partial(document)
147
- render 'show_sidebar', document: document
148
- end
149
-
150
117
  ##
151
118
  # Should we display the sort and per page widget?
152
119
  #
@@ -167,26 +134,6 @@ module Blacklight::CatalogHelperBehavior
167
134
  response.limit_value > 0
168
135
  end
169
136
 
170
- ##
171
- # return the Bookmarks on a set of documents (all bookmarks on the page)
172
- # @private
173
- # @return [Enumerable<Bookmark>]
174
- def current_bookmarks
175
- @current_bookmarks ||= begin
176
- documents = @document.presence || @response.documents
177
- current_or_guest_user.bookmarks_for_documents(Array(documents)).to_a
178
- end
179
- end
180
- private :current_bookmarks
181
-
182
- ##
183
- # Check if the document is in the user's bookmarks
184
- # @param [Blacklight::Document] document
185
- # @return [Boolean]
186
- def bookmarked? document
187
- current_bookmarks.any? { |x| x.document_id == document.id && x.document_type == document.class }
188
- end
189
-
190
137
  # Render an html <title> appropriate string for a selected facet field and values
191
138
  #
192
139
  # @see #render_search_to_page_title
@@ -233,6 +180,32 @@ module Blacklight::CatalogHelperBehavior
233
180
  constraints.join(' / ')
234
181
  end
235
182
 
183
+ ##
184
+ # Should we render a grouped response (because the response
185
+ # contains a grouped response instead of the normal response)
186
+ #
187
+ # Default to false if there's no response object available (sometimes the case
188
+ # for tests, but might happen in other circumstances too..)
189
+ # @return [Boolean]
190
+ def render_grouped_response? response = @response
191
+ response&.grouped?
192
+ end
193
+
194
+ ##
195
+ # Get the current "view type" (and ensure it is a valid type)
196
+ #
197
+ # @param [Hash] query_params the query parameters to check
198
+ # @return [Symbol]
199
+ def document_index_view_type query_params = params || {}
200
+ view_param = query_params[:view]
201
+ view_param ||= session[:preferred_view] if respond_to?(:session)
202
+ if view_param && document_index_views.key?(view_param.to_sym)
203
+ view_param.to_sym
204
+ else
205
+ default_document_index_view_type
206
+ end
207
+ end
208
+
236
209
  private
237
210
 
238
211
  # @param [String] format
@@ -2,17 +2,6 @@
2
2
 
3
3
  module Blacklight
4
4
  module ComponentHelperBehavior
5
- ##
6
- # Render "document actions" area for navigation header
7
- # (normally renders "Saved Searches", "History", "Bookmarks")
8
- # These things are added by add_nav_action
9
- #
10
- # @param [Hash] options
11
- # @return [String]
12
- def render_nav_actions(options = {}, &block)
13
- render_filtered_partials(blacklight_config.navbar.partials, options, &block)
14
- end
15
-
16
5
  ##
17
6
  # Render "document actions" area for search results view
18
7
  # (normally renders next to title in the list view)
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Helper methods for catalog-like controllers that work with documents
4
+ module Blacklight::DocumentHelperBehavior
5
+ ##
6
+ # Get the classes to add to a document's div
7
+ #
8
+ # @param [Blacklight::Document] document
9
+ # @return [String]
10
+ def render_document_class(document = @document)
11
+ types = document_presenter(document).display_type
12
+ return if types.blank?
13
+
14
+ Array(types).compact.map do |t|
15
+ "#{document_class_prefix}#{t.try(:parameterize) || t}"
16
+ end.join(' ')
17
+ end
18
+
19
+ ##
20
+ # Return a prefix for the document classes infered from the document
21
+ # @see #render_document_class
22
+ # @return [String]
23
+ def document_class_prefix
24
+ 'blacklight-'
25
+ end
26
+
27
+ ##
28
+ # Render the sidebar partial for a document
29
+ # This is used as an integration point by downstream apps to add to the
30
+ # default sidebar.
31
+ # See: https://github.com/geoblacklight/geoblacklight/blob/7d3c31c7af3362879b97e2c1351a2496c728c59c/app/helpers/blacklight_helper.rb#L7
32
+ #
33
+ # @param [SolrDocument] document
34
+ # @return [String]
35
+ def render_document_sidebar_partial(document)
36
+ render 'show_sidebar', document: document
37
+ end
38
+
39
+ ##
40
+ # return the Bookmarks on a set of documents (all bookmarks on the page)
41
+ # @private
42
+ # @return [Enumerable<Bookmark>]
43
+ def current_bookmarks
44
+ @current_bookmarks ||= begin
45
+ documents = @document.presence || @response.documents
46
+ current_or_guest_user.bookmarks_for_documents(Array(documents)).to_a
47
+ end
48
+ end
49
+ private :current_bookmarks
50
+
51
+ ##
52
+ # Check if the document is in the user's bookmarks
53
+ # @param [Blacklight::Document] document
54
+ # @return [Boolean]
55
+ def bookmarked? document
56
+ current_bookmarks.any? { |x| x.document_id == document.id && x.document_type == document.class }
57
+ end
58
+
59
+ ##
60
+ # Returns a document presenter for the given document
61
+ def document_presenter(document)
62
+ document_presenter_class(document).new(document, self)
63
+ end
64
+
65
+ ##
66
+ # Override this method if you want to use a differnet presenter for your documents
67
+ # @param [Blacklight::Document] _document optional, here for extension + backwards compatibility only
68
+ def document_presenter_class(_document = nil)
69
+ case action_name
70
+ when 'show', 'citation'
71
+ blacklight_config.view_config(:show, action_name: action_name).document_presenter_class
72
+ else
73
+ blacklight_config.view_config(document_index_view_type, action_name: action_name).document_presenter_class
74
+ end
75
+ end
76
+ end
@@ -47,5 +47,64 @@ module Blacklight
47
47
  def container_classes
48
48
  'container'
49
49
  end
50
+
51
+ ##
52
+ # Render "document actions" area for navigation header
53
+ # (normally renders "Saved Searches", "History", "Bookmarks")
54
+ # These things are added by add_nav_action
55
+ #
56
+ # @param [Hash] options
57
+ # @return [String]
58
+ def render_nav_actions(options = {}, &block)
59
+ render_filtered_partials(blacklight_config.navbar.partials, options, &block)
60
+ end
61
+
62
+ ##
63
+ # Open Search discovery tag for HTML <head> links
64
+ # @return [String]
65
+ def opensearch_description_tag title, href
66
+ tag :link, href: href, title: title, type: "application/opensearchdescription+xml", rel: "search"
67
+ end
68
+
69
+ ##
70
+ # Get the page's HTML title
71
+ #
72
+ # @return [String]
73
+ def render_page_title
74
+ (content_for(:page_title) if content_for?(:page_title)) || @page_title || application_name
75
+ end
76
+
77
+ ##
78
+ # Create <link rel="alternate"> links from a documents dynamically
79
+ # provided export formats.
80
+ #
81
+ # Returns empty string if no links available.
82
+ #
83
+ # @param [SolrDocument] document
84
+ # @param [Hash] options
85
+ # @option options [Boolean] :unique ensures only one link is output for every
86
+ # content type, e.g. as required by atom
87
+ # @option options [Array<String>] :exclude array of format shortnames to not include in the output
88
+ # @return [String]
89
+ def render_link_rel_alternates(document = @document, options = {})
90
+ return if document.nil?
91
+
92
+ document_presenter(document).link_rel_alternates(options)
93
+ end
94
+
95
+ ##
96
+ # Render classes for the <body> element
97
+ # @return [String]
98
+ def render_body_class
99
+ extra_body_classes.join " "
100
+ end
101
+
102
+ ##
103
+ # List of classes to be applied to the <body> element
104
+ # @see render_body_class
105
+ # @return [Array<String>]
106
+ def extra_body_classes
107
+ @extra_body_classes ||= ["blacklight-#{controller.controller_name}", "blacklight-#{[controller.controller_name, controller.action_name].join('-')}"]
108
+ end
50
109
  end
51
110
  end
@@ -59,6 +59,7 @@ render document_component.new(presenter: document_presenter(document), component
59
59
  if template
60
60
  template.render(self, locals.merge(document: doc))
61
61
  else
62
+ logger.warn("No template was found for base_name: '#{base_name}', view_type: '#{view_type}' in render_document_partial")
62
63
  ''
63
64
  end
64
65
  end
@@ -43,16 +43,22 @@ module Blacklight::UrlHelperBehavior
43
43
  # session_tracking_params(SolrDocument.new(id: 123), 7)
44
44
  # => { data: { context_href: '/catalog/123/track?counter=7&search_id=999' } }
45
45
  def session_tracking_params document, counter, per_page: search_session['per_page'], search_id: current_search_session&.id
46
- path = session_tracking_path(document, per_page: params.fetch(:per_page, per_page), counter: counter, search_id: search_id, document_id: document&.id)
46
+ path_params = { per_page: params.fetch(:per_page, per_page), counter: counter, search_id: search_id }
47
+ if blacklight_config.track_search_session.storage == 'server'
48
+ path_params[:document_id] = document&.id
49
+ path_params[:search_id] = search_id
50
+ end
51
+ path = session_tracking_path(document, path_params)
47
52
  return {} if path.nil?
48
53
 
49
- { data: { context_href: path } }
54
+ context_method = blacklight_config.track_search_session.storage == 'client' ? 'get' : 'post'
55
+ { data: { context_href: path, context_method: context_method } }
50
56
  end
51
57
 
52
58
  ##
53
59
  # Get the URL for tracking search sessions across pages using polymorphic routing
54
60
  def session_tracking_path document, params = {}
55
- return if document.nil? || !blacklight_config&.track_search_session
61
+ return if document.nil? || !blacklight_config.track_search_session.storage
56
62
 
57
63
  if main_app.respond_to?(controller_tracking_method)
58
64
  return main_app.public_send(controller_tracking_method, params.merge(id: document))
@@ -63,6 +69,8 @@ module Blacklight::UrlHelperBehavior
63
69
  end
64
70
 
65
71
  def controller_tracking_method
72
+ return blacklight_config.track_search_session.url_helper if blacklight_config.track_search_session.url_helper
73
+
66
74
  "track_#{controller_name}_path"
67
75
  end
68
76
 
@@ -1,19 +1,12 @@
1
- import Blacklight from './core'
2
- import CheckboxSubmit from './checkbox_submit'
1
+ import CheckboxSubmit from 'blacklight/checkbox_submit'
3
2
 
4
- const BookmarkToggle = (() => {
5
- // change form submit toggle to checkbox
6
- Blacklight.doBookmarkToggleBehavior = function() {
7
- document.addEventListener('click', (e) => {
8
- if (e.target.matches('[data-checkboxsubmit-target="checkbox"]')) {
9
- const form = e.target.closest('form')
10
- if (form) new CheckboxSubmit(form).clicked(e);
11
- }
12
- });
13
- };
14
- Blacklight.doBookmarkToggleBehavior.selector = 'form.bookmark-toggle';
3
+ const BookmarkToggle = (e) => {
4
+ if (e.target.matches('[data-checkboxsubmit-target="checkbox"]')) {
5
+ const form = e.target.closest('form')
6
+ if (form) new CheckboxSubmit(form).clicked(e);
7
+ }
8
+ };
15
9
 
16
- Blacklight.doBookmarkToggleBehavior();
17
- })()
10
+ document.addEventListener('click', BookmarkToggle);
18
11
 
19
12
  export default BookmarkToggle
@@ -1,12 +1,12 @@
1
- const ButtonFocus = (() => {
2
- document.addEventListener('click', (e) => {
3
- // Button clicks should change focus. As of 10/3/19, Firefox for Mac and
4
- // Safari both do not set focus to a button on button click.
5
- // See https://zellwk.com/blog/inconsistent-button-behavior/ for background information
6
- if (e.target.matches('[data-toggle="collapse"]') || e.target.matches('[data-bs-toggle="collapse"]')) {
7
- e.target.focus()
8
- }
9
- })
10
- })()
1
+ const ButtonFocus = (e) => {
2
+ // Button clicks should change focus. As of 10/3/19, Firefox for Mac and
3
+ // Safari both do not set focus to a button on button click.
4
+ // See https://zellwk.com/blog/inconsistent-button-behavior/ for background information
5
+ if (e.target.matches('[data-toggle="collapse"]') || e.target.matches('[data-bs-toggle="collapse"]')) {
6
+ e.target.focus()
7
+ }
8
+ }
9
+
10
+ document.addEventListener('click', ButtonFocus)
11
11
 
12
12
  export default ButtonFocus
@@ -1,13 +1,14 @@
1
- import BookmarkToggle from './bookmark_toggle'
2
- import ButtonFocus from './button_focus'
3
- import Modal from './modal'
4
- import SearchContext from './search_context'
5
- import Core from './core'
1
+ import BookmarkToggle from 'blacklight/bookmark_toggle'
2
+ import ButtonFocus from 'blacklight/button_focus'
3
+ import Modal from 'blacklight/modal'
4
+ import SearchContext from 'blacklight/search_context'
5
+ import Core from 'blacklight/core'
6
6
 
7
7
  export default {
8
8
  BookmarkToggle,
9
9
  ButtonFocus,
10
10
  Modal,
11
11
  SearchContext,
12
+ Core,
12
13
  onLoad: Core.onLoad
13
14
  }
@@ -32,7 +32,7 @@
32
32
 
33
33
  <div data-blacklight-modal="container">
34
34
  <div class="modal-header">
35
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
35
+ <button type="button" class="close" data-bl-dismiss="modal" aria-hidden="true">×</button>
36
36
  <h3 class="modal-title">Request Placed</h3>
37
37
  </div>
38
38
 
@@ -43,7 +43,7 @@
43
43
 
44
44
 
45
45
  <div class="modal-footer">
46
- <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
46
+ <button type="button" class="btn btn-secondary" data-bl-dismiss="modal">Close</button>
47
47
  </div>
48
48
  </div>
49
49
 
@@ -52,17 +52,10 @@
52
52
  can be a turbo-stream that defines some HTML fragementsand where on the page to put them:
53
53
  https://turbo.hotwired.dev/handbook/streams
54
54
  */
55
- import Blacklight from './core'
56
- import ModalForm from './modalForm'
55
+ import ModalForm from 'blacklight/modalForm'
57
56
 
58
57
  const Modal = (() => {
59
- // We keep all our data in Blacklight.modal object.
60
- // Create lazily if someone else created first.
61
- if (Blacklight.modal === undefined) {
62
- Blacklight.modal = {};
63
- }
64
-
65
- const modal = Blacklight.modal
58
+ const modal = {}
66
59
 
67
60
  // a Bootstrap modal div that should be already on the page hidden
68
61
  modal.modalSelector = '#blacklight-modal';
@@ -83,20 +76,19 @@ const Modal = (() => {
83
76
  modal.containerSelector = '[data-blacklight-modal~=container]';
84
77
 
85
78
  // Called on fatal failure of ajax load, function returns content
86
- // to show to user in modal. Right now called only for extreme
87
- // network errors.
88
- modal.onFailure = function (jqXHR, textStatus, errorThrown) {
89
- console.error('Server error:', this.url, jqXHR.status, errorThrown);
79
+ // to show to user in modal. Right now called only for network errors.
80
+ modal.onFailure = function (error) {
81
+ console.error('Server error:', this.url, error);
90
82
 
91
83
  const contents = `<div class="modal-header">
92
84
  <div class="modal-title">There was a problem with your request.</div>
93
- <button type="button" class="blacklight-modal-close btn-close close" data-dismiss="modal" data-bs-dismiss="modal" aria-label="Close">
94
- <span aria-hidden="true">&times;</span>
85
+ <button type="button" class="blacklight-modal-close btn-close close" data-bl-dismiss="modal" aria-label="Close">
86
+ <span aria-hidden="true" class="visually-hidden">&times;</span>
95
87
  </button>
96
88
  </div>
97
89
  <div class="modal-body">
98
90
  <p>Expected a successful response from the server, but got an error</p>
99
- <pre>${this.type} ${this.url}\n${jqXHR.status}: ${errorThrown}</pre>
91
+ <pre>${this.url}\n${error}</pre>
100
92
  </div>`
101
93
 
102
94
  document.querySelector(`${modal.modalSelector} .modal-content`).innerHTML = contents
@@ -105,10 +97,16 @@ const Modal = (() => {
105
97
  }
106
98
 
107
99
  // Add the passed in contents to the modal and display it.
108
- modal.receiveAjax = function (contents) {
100
+ modal.receiveAjax = function (contents) {
109
101
  const domparser = new DOMParser();
110
102
  const dom = domparser.parseFromString(contents, "text/html")
111
- const elements = dom.querySelectorAll(`${modal.containerSelector} > *`)
103
+ // If there is a containerSelector on the document, use its children.
104
+ let elements = dom.querySelectorAll(`${modal.containerSelector} > *`)
105
+ if (elements.length == 0) {
106
+ // If the containerSelector wasn't found, use the whole document
107
+ elements = dom.body.childNodes
108
+ }
109
+
112
110
  document.querySelector(`${modal.modalSelector} .modal-content`).replaceChildren(...elements)
113
111
 
114
112
  modal.show();
@@ -134,28 +132,30 @@ modal.receiveAjax = function (contents) {
134
132
  // into one selector with a comma, so if something matches BOTH selectors, it
135
133
  // still only gets the event handler called once.
136
134
  document.addEventListener('click', (e) => {
137
- if (e.target.matches(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))
135
+ if (e.target.closest(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))
138
136
  modal.modalAjaxLinkClick(e)
139
- else if (e.target.matches('[data-bl-dismiss="modal"]'))
137
+ else if (e.target.closest('[data-bl-dismiss="modal"]'))
140
138
  modal.hide()
141
139
  })
142
140
  };
143
141
 
144
142
  modal.hide = function (el) {
145
- const dom = document.querySelector(Blacklight.modal.modalSelector)
143
+ const dom = document.querySelector(modal.modalSelector)
146
144
 
147
145
  if (!dom.open) return
148
146
  dom.close()
149
147
  }
150
148
 
151
149
  modal.show = function(el) {
152
- const dom = document.querySelector(Blacklight.modal.modalSelector)
150
+ const dom = document.querySelector(modal.modalSelector)
153
151
 
154
152
  if (dom.open) return
155
153
  dom.showModal()
156
154
  }
157
155
 
158
156
  modal.setupModal()
157
+
158
+ return modal;
159
159
  })()
160
160
 
161
161
  export default Modal