blacklight-spotlight 5.3.2 → 6.0.0.rc2

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 (211) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -4
  3. data/Rakefile +1 -2
  4. data/app/assets/javascripts/spotlight/spotlight.esm.js +2168 -4560
  5. data/app/assets/javascripts/spotlight/spotlight.esm.js.map +1 -1
  6. data/app/assets/javascripts/spotlight/spotlight.js +2167 -4559
  7. data/app/assets/javascripts/spotlight/spotlight.js.map +1 -1
  8. data/app/assets/stylesheets/spotlight/_blacklight_overrides.scss +4 -0
  9. data/app/assets/stylesheets/spotlight/_browse.scss +0 -4
  10. data/app/assets/stylesheets/spotlight/{_collapse_toggle.scss → _collapse_toggle.css} +2 -2
  11. data/app/assets/stylesheets/spotlight/_exhibit_admin.scss +8 -0
  12. data/app/assets/stylesheets/spotlight/_exhibits_index.scss +2 -1
  13. data/app/assets/stylesheets/spotlight/_footer.scss +2 -2
  14. data/app/assets/stylesheets/spotlight/_header.scss +8 -8
  15. data/app/assets/stylesheets/spotlight/_pages.scss +1 -1
  16. data/app/assets/stylesheets/spotlight/_slideshow_block.scss +15 -0
  17. data/app/assets/stylesheets/spotlight/_spotlight.scss +1 -1
  18. data/app/assets/stylesheets/spotlight/_translations.scss +3 -3
  19. data/app/assets/stylesheets/spotlight/_uploaded_items_block.css +7 -0
  20. data/app/assets/stylesheets/spotlight/_variables.css +15 -0
  21. data/app/assets/stylesheets/spotlight/browse_group_categories_block.scss +0 -76
  22. data/app/components/blacklight/icons/pause_component.rb +15 -0
  23. data/app/components/blacklight/icons/play_arrow_component.rb +15 -0
  24. data/app/components/spotlight/analytics/dashboard_component.html.erb +1 -1
  25. data/app/components/spotlight/custom_field_form_group_component.rb +40 -0
  26. data/app/components/spotlight/document_admin_table_component.html.erb +2 -2
  27. data/app/components/spotlight/edit_sidecar_component.html.erb +18 -0
  28. data/app/components/spotlight/edit_sidecar_component.rb +41 -0
  29. data/app/components/spotlight/masthead_component.html.erb +18 -0
  30. data/app/components/spotlight/masthead_component.rb +46 -0
  31. data/app/components/spotlight/save_search_component.html.erb +1 -1
  32. data/app/components/spotlight/sidecar_form_field_component.html.erb +18 -0
  33. data/app/components/spotlight/sidecar_form_field_component.rb +71 -0
  34. data/app/components/spotlight/solr_document_legacy_embed_component.html.erb +0 -4
  35. data/app/components/spotlight/solr_document_legacy_embed_component.rb +2 -2
  36. data/app/components/spotlight/tag_selector_component.html.erb +1 -1
  37. data/app/components/spotlight/tag_selector_component.rb +3 -2
  38. data/app/components/spotlight/upload_field_form_group_component.rb +33 -0
  39. data/app/controllers/concerns/spotlight/controller.rb +15 -14
  40. data/app/controllers/concerns/spotlight/search_helper.rb +2 -5
  41. data/app/controllers/spotlight/browse_controller.rb +1 -6
  42. data/app/controllers/spotlight/catalog_controller.rb +2 -3
  43. data/app/controllers/spotlight/concerns/application_controller.rb +4 -6
  44. data/app/controllers/spotlight/exhibits_controller.rb +22 -10
  45. data/app/controllers/spotlight/lock_controller.rb +1 -1
  46. data/app/controllers/spotlight/pages_controller.rb +11 -11
  47. data/app/controllers/spotlight/resources/upload_controller.rb +1 -1
  48. data/app/controllers/spotlight/resources_controller.rb +1 -1
  49. data/app/controllers/spotlight/solr_controller.rb +5 -1
  50. data/app/helpers/spotlight/application_helper.rb +14 -26
  51. data/app/helpers/spotlight/crud_link_helpers.rb +0 -12
  52. data/app/helpers/spotlight/main_app_helpers.rb +2 -2
  53. data/app/javascript/spotlight/admin/add_another.js +37 -25
  54. data/app/javascript/spotlight/admin/add_image_selector.js +43 -26
  55. data/app/javascript/spotlight/admin/add_new_button.js +51 -36
  56. data/app/javascript/spotlight/admin/blacklight_configuration.js +76 -54
  57. data/app/javascript/spotlight/admin/block_mixins/autocompleteable.js +102 -101
  58. data/app/javascript/spotlight/admin/block_mixins/formable.js +91 -75
  59. data/app/javascript/spotlight/admin/block_mixins/plustextable.js +46 -48
  60. data/app/javascript/spotlight/admin/blocks/block.js +27 -28
  61. data/app/javascript/spotlight/admin/blocks/browse_block.js +14 -10
  62. data/app/javascript/spotlight/admin/blocks/browse_group_categories_block.js +14 -10
  63. data/app/javascript/spotlight/admin/blocks/pages_block.js +5 -4
  64. data/app/javascript/spotlight/admin/blocks/resources_block.js +61 -41
  65. data/app/javascript/spotlight/admin/blocks/search_result_block.js +24 -7
  66. data/app/javascript/spotlight/admin/blocks/solr_documents_base_block.js +103 -50
  67. data/app/javascript/spotlight/admin/blocks/solr_documents_carousel_block.js +50 -26
  68. data/app/javascript/spotlight/admin/blocks/solr_documents_features_block.js +47 -23
  69. data/app/javascript/spotlight/admin/blocks/uploaded_items_block.js +35 -19
  70. data/app/javascript/spotlight/admin/crop.js +146 -66
  71. data/app/javascript/spotlight/admin/croppable.js +5 -4
  72. data/app/javascript/spotlight/admin/croppable_modal.js +67 -32
  73. data/app/javascript/spotlight/admin/edit_in_place.js +69 -54
  74. data/app/javascript/spotlight/admin/exhibits.js +92 -45
  75. data/app/javascript/spotlight/admin/form_observer.js +92 -78
  76. data/app/javascript/spotlight/admin/multi_image_selector.js +201 -153
  77. data/app/javascript/spotlight/admin/pages.js +13 -7
  78. data/app/javascript/spotlight/admin/progress_monitor.js +65 -50
  79. data/app/javascript/spotlight/admin/readonly_checkbox.js +7 -3
  80. data/app/javascript/spotlight/admin/search_typeahead.js +20 -11
  81. data/app/javascript/spotlight/admin/select_related_input.js +23 -23
  82. data/app/javascript/spotlight/admin/serialize_json.js +120 -0
  83. data/app/javascript/spotlight/admin/sir-trevor/block_controls.js +24 -11
  84. data/app/javascript/spotlight/admin/sir-trevor/block_limits.js +9 -6
  85. data/app/javascript/spotlight/admin/sir-trevor/locales.js +2 -2
  86. data/app/javascript/spotlight/admin/spotlight_nestable.js +2 -5
  87. data/app/javascript/spotlight/admin/translation_progress.js +18 -13
  88. data/app/javascript/spotlight/admin/users.js +151 -64
  89. data/app/javascript/spotlight/user/carousel.js +104 -32
  90. data/app/javascript/spotlight/user/clear_form_button.js +24 -14
  91. data/app/javascript/spotlight/user/index.js +0 -2
  92. data/app/javascript/spotlight/user/zpr_links.js +99 -40
  93. data/app/jobs/concerns/spotlight/gather_documents.rb +1 -1
  94. data/app/jobs/spotlight/add_uploads_from_csv.rb +31 -8
  95. data/app/jobs/spotlight/cleanup_job_trackers_job.rb +5 -3
  96. data/app/models/concerns/spotlight/access_controls_enforcement_search_builder.rb +13 -2
  97. data/app/models/concerns/spotlight/browse_category_search_builder.rb +3 -3
  98. data/app/models/concerns/spotlight/exhibit_documents.rb +2 -2
  99. data/app/models/concerns/spotlight/sitemap.rb +2 -2
  100. data/app/models/concerns/spotlight/solr_document/finder.rb +2 -2
  101. data/app/models/concerns/spotlight/solr_document.rb +1 -47
  102. data/app/models/sir_trevor_rails/blocks/browse_block.rb +0 -4
  103. data/app/models/sir_trevor_rails/blocks/solr_documents_block.rb +2 -1
  104. data/app/models/spotlight/blacklight_configuration.rb +5 -3
  105. data/app/models/spotlight/contact_email.rb +2 -2
  106. data/app/models/spotlight/custom_field.rb +17 -0
  107. data/app/models/spotlight/exhibit.rb +28 -0
  108. data/app/models/spotlight/featured_image.rb +1 -1
  109. data/app/models/spotlight/field_metadata.rb +10 -5
  110. data/app/models/spotlight/job_tracker.rb +0 -18
  111. data/app/models/spotlight/main_navigation.rb +2 -2
  112. data/app/models/spotlight/page.rb +3 -3
  113. data/app/models/spotlight/resources/iiif_harvester.rb +7 -4
  114. data/app/models/spotlight/resources/iiif_manifest.rb +0 -4
  115. data/app/models/spotlight/resources/iiif_manifest_metadata.rb +1 -3
  116. data/app/models/spotlight/resources/iiif_service.rb +21 -6
  117. data/app/models/spotlight/resources/upload.rb +6 -0
  118. data/app/models/spotlight/search.rb +5 -9
  119. data/app/models/spotlight/solr_document_sidecar.rb +18 -0
  120. data/app/services/spotlight/bulk_updates_csv_template_service.rb +1 -1
  121. data/app/services/spotlight/etl/pipeline.rb +2 -2
  122. data/app/services/spotlight/etl/step.rb +2 -2
  123. data/app/views/catalog/_remove_tags.html.erb +2 -2
  124. data/app/views/layouts/spotlight/base.html.erb +3 -6
  125. data/app/views/layouts/spotlight/spotlight.html.erb +2 -2
  126. data/app/views/shared/_analytics.html.erb +4 -3
  127. data/app/views/shared/_masthead.html.erb +2 -18
  128. data/app/views/spotlight/about_pages/_empty.html.erb +1 -1
  129. data/app/views/spotlight/about_pages/_sidebar.html.erb +10 -8
  130. data/app/views/spotlight/browse/_search.html.erb +2 -2
  131. data/app/views/spotlight/browse/_search_box.html.erb +6 -14
  132. data/app/views/spotlight/browse/index.html.erb +1 -1
  133. data/app/views/spotlight/browse/show.html.erb +1 -1
  134. data/app/views/spotlight/catalog/_document_admin_table.html.erb +1 -1
  135. data/app/views/spotlight/catalog/_edit_default.html.erb +1 -1
  136. data/app/views/spotlight/catalog/edit.html.erb +1 -1
  137. data/app/views/spotlight/dashboards/_page.html.erb +1 -1
  138. data/app/views/spotlight/exhibits/_exhibit_card.html.erb +3 -1
  139. data/app/views/spotlight/exhibits/_export.html.erb +17 -1
  140. data/app/views/spotlight/exhibits/_form.html.erb +20 -4
  141. data/app/views/spotlight/exhibits/_missing_exhibits.html.erb +3 -3
  142. data/app/views/spotlight/exhibits/index.html.erb +21 -8
  143. data/app/views/spotlight/feature_pages/_empty.html.erb +1 -1
  144. data/app/views/spotlight/feature_pages/_sidebar.html.erb +17 -15
  145. data/app/views/spotlight/home_pages/_empty.html.erb +7 -7
  146. data/app/views/spotlight/pages/show.html.erb +1 -0
  147. data/app/views/spotlight/resources/upload/_form.html.erb +2 -2
  148. data/app/views/spotlight/sir_trevor/blocks/_browse_group_categories_block.html.erb +5 -16
  149. data/app/views/spotlight/sir_trevor/blocks/_embedded_document.html.erb +3 -5
  150. data/app/views/spotlight/sir_trevor/blocks/_link_to_search_block.html.erb +1 -1
  151. data/app/views/spotlight/sir_trevor/blocks/_solr_documents_carousel_block.html.erb +11 -2
  152. data/app/views/spotlight/sites/_exhibit.html.erb +1 -1
  153. data/config/i18n-tasks.yml +1 -1
  154. data/config/locales/spotlight.ar.yml +1 -2
  155. data/config/locales/spotlight.de.yml +1 -2
  156. data/config/locales/spotlight.en.yml +39 -10
  157. data/config/locales/spotlight.es.yml +1 -2
  158. data/config/locales/spotlight.fr.yml +1 -2
  159. data/config/locales/spotlight.it.yml +1 -2
  160. data/config/locales/spotlight.ja.yml +39 -0
  161. data/config/locales/spotlight.zh.yml +1 -2
  162. data/db/migrate/20261007133748_add_discovery_enabled_to_spotlight_exhibits.rb +5 -0
  163. data/lib/generators/spotlight/assets/importmap_generator.rb +2 -10
  164. data/lib/generators/spotlight/assets/propshaft_generator.rb +5 -4
  165. data/lib/generators/spotlight/install_generator.rb +2 -4
  166. data/lib/generators/spotlight/templates/catalog_controller.rb +0 -1
  167. data/lib/generators/spotlight/templates/config/initializers/spotlight_initializer.rb +26 -4
  168. data/lib/generators/spotlight/templates/solr/conf/schema.xml +4 -3
  169. data/lib/generators/spotlight/templates/solr/conf/solrconfig.xml +3 -8
  170. data/lib/migration/page_language.rb +0 -2
  171. data/lib/spotlight/engine.rb +28 -9
  172. data/lib/spotlight/search_state.rb +7 -11
  173. data/lib/spotlight/upload_field_config.rb +19 -1
  174. data/lib/spotlight/version.rb +1 -1
  175. data/lib/spotlight.rb +1 -1
  176. data/spec/support/features/capybara_wait_metadata_helper.rb +3 -1
  177. data/spec/support/features/test_features_helpers.rb +24 -1
  178. data/spec/support/iiif_manifest_fixtures.rb +33 -0
  179. data/spec/support/stub_dns_resolution.rb +12 -0
  180. metadata +50 -80
  181. data/app/assets/stylesheets/spotlight/_uploaded_items_block.scss +0 -7
  182. data/app/assets/stylesheets/spotlight/_variables.scss +0 -13
  183. data/app/components/blacklight/icons/arrow_alt_circle_left_component.rb +0 -15
  184. data/app/components/blacklight/icons/arrow_alt_circle_right_component.rb +0 -15
  185. data/app/components/blacklight/icons/info_component.rb +0 -15
  186. data/app/components/blacklight/icons/zoom_in_component.rb +0 -15
  187. data/app/components/blacklight/icons/zoom_out_component.rb +0 -15
  188. data/app/components/spotlight/icon_component.rb +0 -13
  189. data/app/javascript/spotlight/user/browse_group_categories.js +0 -54
  190. data/app/mailers/spotlight/invitation_mailer.rb +0 -21
  191. data/app/models/concerns/spotlight/resources/web.rb +0 -38
  192. data/app/services/spotlight/iiif_resource_resolver.rb +0 -78
  193. data/app/views/catalog/_image_default.html.erb +0 -6
  194. data/app/views/shared/_exhibit_navbar.html.erb +0 -2
  195. data/app/views/shared/_header_navbar.html.erb +0 -6
  196. data/app/views/spotlight/catalog/_admin_index_header_default.html.erb +0 -23
  197. data/app/views/spotlight/catalog/_admin_thumbnail_default.html.erb +0 -7
  198. data/app/views/spotlight/catalog/_curation_mode_toggle_default.html.erb +0 -1
  199. data/app/views/spotlight/catalog/_document_row.html.erb +0 -2
  200. data/app/views/spotlight/catalog/_edit_sidecar.html.erb +0 -24
  201. data/app/views/spotlight/catalog/_index_compact_default.html.erb +0 -21
  202. data/app/views/spotlight/custom_fields/form_group/_text.html.erb +0 -23
  203. data/app/views/spotlight/custom_fields/form_group/_vocab.html.erb +0 -23
  204. data/app/views/spotlight/invitation_mailer/exhibit_invitation_notification.html.erb +0 -12
  205. data/lib/generators/spotlight/templates/javascript/jquery-shim.js +0 -1
  206. data/vendor/assets/javascripts/tiny-slider.js +0 -3221
  207. data/vendor/assets/stylesheets/tiny-slider.css +0 -1
  208. /data/app/assets/stylesheets/spotlight/{_breadcrumbs.scss → _breadcrumbs.css} +0 -0
  209. /data/app/assets/stylesheets/spotlight/{_croppable.scss → _croppable.css} +0 -0
  210. /data/app/assets/stylesheets/spotlight/{_modals.scss → _modals.css} +0 -0
  211. /data/app/assets/stylesheets/spotlight/{_utilities.scss → _utilities.css} +0 -0
@@ -33,8 +33,7 @@ it:
33
33
  reset: Cancella la casella di ricerca
34
34
  submit: Ricerca all'interno dell'indice
35
35
  success:
36
- expand_html: Puoi anche cercare tutti gli elementi del percorso per <a href="%{expand_search_url}">"%{browse_query}"</a>.
37
36
  result_number_html: La tua ricerca ha trovato <strong> %{search_size} di %{parent_search_count} elementi</strong> in questo indice di ricerca.
37
+ view_search: Visualizza questo indice con più opzioni di ricerca e filtro
38
38
  zero_results:
39
- expand_html: Puoi <a href="%{clear_search_url}">cancellare questa ricerca</a> o <a href="%{expand_search_url}">provare a cercare tutti gli elementi del percorso per "%{browse_query}"</a>.
40
39
  result_number: La tua ricerca in questo indice non ha prodotto alcun risultato.
@@ -0,0 +1,39 @@
1
+ ja:
2
+ activemodel:
3
+ attributes:
4
+ spotlight/contact_form:
5
+ email: メールアドレス
6
+ message: お問い合わせ内容
7
+ name: お名前
8
+ helpers:
9
+ action:
10
+ cancel: キャンセル
11
+ submit:
12
+ contact_form:
13
+ create: 送信
14
+ created: 送信しました。ご意見ありがとうございます。
15
+ spotlight:
16
+ about_pages:
17
+ contacts:
18
+ header: 連絡先
19
+ browse:
20
+ search:
21
+ item_count:
22
+ one: "%{count} 件"
23
+ other: "%{count} 件"
24
+ search_box:
25
+ label: このカテゴリ内を検索
26
+ placeholder: 検索…
27
+ reset: 検索ボックスをクリア
28
+ submit: このカテゴリ内を検索
29
+ success:
30
+ result_number_html: このカテゴリ内の <strong>%{parent_search_count} 件中 %{search_size} 件</strong>が検索条件に一致しました。
31
+ view_search: より多くの検索・絞り込みオプションでこのカテゴリを表示
32
+ zero_results:
33
+ result_number: このカテゴリ内に検索条件と一致する資料はありませんでした。
34
+ header_links:
35
+ contact: ご意見・お問い合わせ
36
+ shared:
37
+ report_a_problem:
38
+ honeypot_field_explanation: この入力欄は無視してください。スパム判定のために使用しています。ここに入力するとメッセージは送信されません。
39
+ title: お問い合わせ
@@ -33,8 +33,7 @@ zh:
33
33
  reset: 清除
34
34
  submit: 检索所有资料
35
35
  success:
36
- expand_html: <a href="%{expand_search_url}">您也可检索所有资料 "%{browse_query}"</a>.
37
36
  result_number_html: 您的检索在本专题 <strong> %{search_size} of %{parent_search_count} 条资料中检索到</strong> 条.
37
+ view_search: 使用更多检索和筛选选项查看该类资料
38
38
  zero_results:
39
- expand_html: <a href="%{clear_search_url}">您可取消本次专题检索</a> 或检索所有资料 <a href="%{expand_search_url}">"%{browse_query}"</a>.
40
39
  result_number: 找到0条结果
@@ -0,0 +1,5 @@
1
+ class AddDiscoveryEnabledToSpotlightExhibits < ActiveRecord::Migration[7.1]
2
+ def change
3
+ add_column :spotlight_exhibits, :discovery_enabled, :boolean, default: true, null: false
4
+ end
5
+ end
@@ -26,9 +26,7 @@ module Spotlight
26
26
  DESCRIPTION
27
27
 
28
28
  def add_stylesheet_dependencies
29
- run "yarn add blacklight-frontend@#{blacklight_yarn_version}"
30
29
  run "yarn add bootstrap@\"^#{bootstrap_yarn_version}\""
31
- run 'yarn add leaflet'
32
30
  end
33
31
 
34
32
  # Needed for the stylesheets
@@ -37,6 +35,8 @@ module Spotlight
37
35
  run "yarn add file:#{Spotlight::Engine.root}"
38
36
  elsif options[:test]
39
37
  run 'yarn link spotlight-frontend'
38
+ # yarn link doesn't install the linked package's dependencies; the stylesheets need leaflet
39
+ run 'yarn add leaflet'
40
40
 
41
41
  # If a branch was specified (e.g. you are running a template.rb build
42
42
  # against a test branch), use the latest version available on npm
@@ -74,14 +74,6 @@ module Spotlight
74
74
  CONTENT
75
75
  end
76
76
  end
77
-
78
- private
79
-
80
- def bootstrap_frontend_version
81
- yarn_lock = File.read('yarn.lock')
82
- bootstrap_entry = yarn_lock.match(/^"?bootstrap@.+:\n version "(.+)"/)
83
- bootstrap_entry ? bootstrap_entry[1] : nil
84
- end
85
77
  end
86
78
  end
87
79
  end
@@ -60,7 +60,6 @@ module Spotlight
60
60
  end
61
61
 
62
62
  def add_javascript
63
- copy_file 'javascript/jquery-shim.js', 'app/javascript/jquery-shim.js'
64
63
  gsub_file 'app/javascript/application.js', 'import "controllers"', '// import "controllers"'
65
64
 
66
65
  # This may have been added from Blacklight, but it is a Spotlight dependency so ensure it is present.
@@ -83,9 +82,11 @@ module Spotlight
83
82
  end
84
83
 
85
84
  def configure_esbuild
86
- # The main-fields option resolves a bundling issue with bootstrap/popper on esbuild.
87
- custom_options = '--main-fields=main,module --alias:jquery=./app/javascript/jquery-shim.js'
88
- custom_options = "#{custom_options} --preserve-symlinks" if options[:test]
85
+ return unless options[:test]
86
+
87
+ # A linked spotlight-frontend resolves imports from the Spotlight checkout's node_modules first.
88
+ # Its bootstrap would be a second copy, which causes issues (e.g., a click on a dropdown causes two competing actions)
89
+ custom_options = '--preserve-symlinks --alias:bootstrap=./node_modules/bootstrap'
89
90
  gsub_file 'package.json',
90
91
  'esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets',
91
92
  "esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets #{custom_options}"
@@ -113,7 +113,7 @@ module Spotlight
113
113
 
114
114
  def add_osd_viewer
115
115
  unless Bundler.locked_gems.dependencies.key? 'blacklight-gallery'
116
- gem 'blacklight-gallery', '~> 4.0'
116
+ gem 'blacklight-gallery', '>= 5.1', '< 7'
117
117
  bundle_install
118
118
  end
119
119
  generate 'blacklight_gallery:install'
@@ -182,9 +182,7 @@ module Spotlight
182
182
  private
183
183
 
184
184
  def bundle_install
185
- inside destination_root do
186
- Bundler.with_unbundled_env { run 'bundle install' }
187
- end
185
+ Bundler.with_original_env { system 'bundle install' }
188
186
  end
189
187
  end
190
188
  end
@@ -8,7 +8,6 @@ class CatalogController < ApplicationController
8
8
  configure_blacklight do |config|
9
9
  ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params
10
10
  config.default_solr_params = {
11
- qt: 'search',
12
11
  rows: 10,
13
12
  fl: '*'
14
13
  }
@@ -37,10 +37,18 @@
37
37
  # Spotlight::Engine.config.solr_fields.string_suffix = '_ssim'.freeze
38
38
  # Spotlight::Engine.config.solr_fields.text_suffix = '_tesim'.freeze
39
39
  # Spotlight::Engine.config.resource_global_id_field = :"#{config.solr_fields.prefix}spotlight_resource_id#{config.solr_fields.string_suffix}"
40
+ # Exhibit custom field types; `form_field_type` and `component` control how the field renders on the upload and edit forms
41
+ # Spotlight::Engine.config.custom_field_types = {
42
+ # vocab: { suffix: '_ssim', facetable: true },
43
+ # text: { suffix: '_tesim', form_field_type: :text_area, component: 'Spotlight::SidecarFormFieldComponent' }
44
+ # }
40
45
  # Spotlight::Engine.config.full_image_field = :full_image_url_ssm
41
46
  # Spotlight::Engine.config.thumbnail_field = :thumbnail_url_ssm
42
47
 
43
48
  # ==> Uploaded item configuration
49
+ # Add `is_multiple: true` to Spotlight::UploadFieldConfig arguments to allow for multivalued field data
50
+ # Add `component: MyFieldComponent` to render the field with a custom component (default: Spotlight::SidecarFormFieldComponent)
51
+ # If is_multiple is enabled, Spotlight will send the field to Solr as an array, so ensure that your Solr configurations support this
44
52
  # Spotlight::Engine.config.upload_fields = [
45
53
  # Spotlight::UploadFieldConfig.new(
46
54
  # field_name: Spotlight::Engine.config.upload_description_field,
@@ -60,6 +68,9 @@
60
68
  # Spotlight::Engine.config.uploader_storage = :file
61
69
  # Spotlight::Engine.config.allowed_upload_extensions = %w(jpg jpeg png)
62
70
 
71
+ # Set a delimiter character for multivalued fields in CSV uploads (ex. "|") - disabled by default
72
+ # Spotlight::Engine.config.csv_upload_multivalued_field_delimiter = nil
73
+
63
74
  # Spotlight::Engine.config.featured_image_thumb_size = [400, 300]
64
75
  # Spotlight::Engine.config.featured_image_square_size = [400, 400]
65
76
 
@@ -69,15 +80,16 @@
69
80
  # b) generate and download the JSON key and make it accessible to your application
70
81
  # (https://console.cloud.google.com/iam-admin/iam -> Service accounts -> click on service account -> keys)
71
82
  # c) set ga_property_id below to your site's property id (located in admin -> Property -> Property details upper right hand corner)
72
- # d) Set the ga_web_property_id. (located in admin -> Data collection and modification -> Web stream details and begins with G-)
83
+ # d) Set the ga_measurement_id. (located in admin -> Data collection and modification -> Data Streams -> Web stream details and begins with G-)
73
84
  # e) (optional) set ga_date_range. This allows you throttle the dates the user can filter by.
74
85
  # ga_date_range values should use a Date object i.e. (Date.new(YYYY, MM, DD)).
75
- # ga_property_id is used for fetching analytics data from google's api, ga_web_property_id is used for sending events to GA analtyics
76
- # ga_web_property_id will probably change in V5 to ga_measurement_id for clarity
86
+ # ga_measurement_id is used for sending events to GA analtyics
87
+ # ga_web_property_id is deprecated, use ga_measurement_id instead
88
+ # ga_property_id is used for fetching analytics data from google's api
77
89
  # Rails.application.config.to_prepare do
78
90
  # Spotlight::Engine.config.analytics_provider = Spotlight::Analytics::Ga
79
91
  # Spotlight::Engine.config.ga_json_key_path = nil
80
- # Spotlight::Engine.config.ga_web_property_id = 'G-XXXXXXXXXX'
92
+ # Spotlight::Engine.config.ga_measurement_id = 'G-XXXXXXXXXX'
81
93
  # Spotlight::Engine.config.ga_property_id = '12345678'
82
94
  # Spotlight::Engine.config.ga_date_range = { 'start_date' => nil, 'end_date' => nil }
83
95
  # Spotlight::Engine.config.ga_analytics_options = {}
@@ -103,3 +115,13 @@
103
115
  # Spotlight::Engine.config.page_configurations = {
104
116
  # 'my-local-config': ->(context) { context.my_custom_data_path(context.current_exhibit) }
105
117
  # }
118
+ #
119
+ # ==> Export Configuration
120
+ # This determines what data is exported when a admin uses the exhibit export feature.
121
+ # Spotlight::Engine.config.exports = {
122
+ # attachments: true,
123
+ # blacklight_configuration: true,
124
+ # config: true,
125
+ # pages: true,
126
+ # resources: false
127
+ # }
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <schema name="Hydra" version="1.5">
2
+ <schema name="Spotlight-default" version="1.6">
3
3
  <!-- NOTE: various comments and unused configuration possibilities have been purged
4
4
  from this file. Please refer to http://wiki.apache.org/solr/SchemaXml,
5
5
  as well as the default schema file included with Solr -->
@@ -190,11 +190,12 @@
190
190
  <copyField source="id" dest="id_ng" maxChars="3000"/>
191
191
  <copyField source="full_title_tesim" dest="full_title_ng" maxChars="3000"/>
192
192
  <copyField source="*_tesim" dest="all_text_timv" maxChars="3000"/>
193
+ <copyField source="*_tags_ssim" dest="all_text_timv" maxChars="3000"/>
193
194
 
194
195
  <types>
195
196
  <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
196
197
  <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
197
- <fieldType name="rand" class="solr.RandomSortField" omitNorms="true"/>
198
+ <fieldType name="rand" class="solr.RandomSortField"/>
198
199
 
199
200
  <!-- Default numeric field types. -->
200
201
  <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
@@ -236,7 +237,7 @@
236
237
  <fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
237
238
  geo="true" distErrPct="0.025" maxDistErr="0.000009" distanceUnits="degrees" />
238
239
 
239
- <fieldType name="text" class="solr.TextField" omitNorms="false">
240
+ <fieldType name="text" class="solr.TextField">
240
241
  <analyzer>
241
242
  <tokenizer class="solr.ICUTokenizerFactory"/>
242
243
  <filter class="solr.ICUFoldingFilterFactory"/> <!-- NFKC, case folding, diacritics removed -->
@@ -6,7 +6,7 @@
6
6
 
7
7
  <abortOnConfigurationError>${solr.abortOnConfigurationError:true}</abortOnConfigurationError>
8
8
 
9
- <luceneMatchVersion>6.1.0</luceneMatchVersion>
9
+ <luceneMatchVersion>9.0.0</luceneMatchVersion>
10
10
 
11
11
  <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>
12
12
 
@@ -16,14 +16,9 @@
16
16
  </updateLog>
17
17
  </updateHandler>
18
18
 
19
- <!-- solr lib dirs: needed for Solr 8 compatibility but ignored in solr 9.8 and above -->
20
- <lib dir="${solr.install.dir:../../../..}/modules/analysis-extras/lib" />
21
- <lib dir="${solr.install.dir:../../../..}/contrib/analysis-extras/lib" />
22
- <lib dir="${solr.install.dir:../../../..}/contrib/analysis-extras/lucene-libs" />
23
-
24
19
  <dataDir>${solr.data.dir:}</dataDir>
25
20
 
26
- <requestHandler name="search" class="solr.SearchHandler" default="true">
21
+ <requestHandler name="/select" class="solr.SearchHandler">
27
22
  <!-- default values for query parameters can be specified, these
28
23
  will be overridden by parameters in the request
29
24
  -->
@@ -188,7 +183,7 @@
188
183
 
189
184
  <requestHandler name="/replication" class="solr.ReplicationHandler" startup="lazy" />
190
185
 
191
- <requestDispatcher handleSelect="true" >
186
+ <requestDispatcher>
192
187
  <requestParsers enableRemoteStreaming="true" multipartUploadLimitInKB="2048" />
193
188
  </requestDispatcher>
194
189
 
@@ -9,8 +9,6 @@ module Migration
9
9
  new.run
10
10
  end
11
11
 
12
- def initialize; end
13
-
14
12
  def run
15
13
  migrate_pages
16
14
  end
@@ -8,8 +8,6 @@ require 'devise_invitable'
8
8
 
9
9
  require 'activejob-status'
10
10
  require 'blacklight'
11
- require 'faraday'
12
- require 'faraday/follow_redirects'
13
11
  require 'friendly_id'
14
12
  require 'i18n/active_record'
15
13
  require 'paper_trail'
@@ -119,10 +117,13 @@ module Spotlight
119
117
  config.solr_fields.string_suffix = '_ssim'
120
118
  config.solr_fields.text_suffix = '_tesim'
121
119
 
122
- # Suffixes for exhibit-specific solr fields
120
+ # Suffixes for exhibit-specific solr fields. Each type may also set:
121
+ # form_field_type: the form builder method used for the input (default: :text_field)
122
+ # component: the component used to render the field on the upload and edit forms
123
+ # (default: Spotlight::SidecarFormFieldComponent)
123
124
  config.custom_field_types = {
124
125
  vocab: { suffix: '_ssim', facetable: true },
125
- text: { suffix: '_tesim' }
126
+ text: { suffix: '_tesim', form_field_type: :text_area }
126
127
  }
127
128
 
128
129
  config.resource_global_id_field = :"#{config.solr_fields.prefix}spotlight_resource_id#{config.solr_fields.string_suffix}"
@@ -132,6 +133,9 @@ module Spotlight
132
133
  config.full_image_field = :full_image_url_ssm
133
134
  config.thumbnail_field = :thumbnail_url_ssm
134
135
 
136
+ # Set delimiter character for multivalued fields in CSV uploads
137
+ config.csv_upload_multivalued_field_delimiter = nil
138
+
135
139
  Spotlight::Engine.config.site_tags = nil
136
140
 
137
141
  # Defaults to the blacklight_config.index.title_field:
@@ -197,10 +201,12 @@ module Spotlight
197
201
  # b) generate and download the JSON key and make it accessible to your application
198
202
  # (https://console.cloud.google.com/iam-admin/iam -> Service accounts -> click on service account -> keys)
199
203
  # c) set ga_property_id below to your site's property id (located in admin -> Property -> Property details upper right hand corner)
200
- # d) Set the ga_web_property_id. (located in admin -> Data collection and modification -> Web stream details and begins with G-)
201
- # ga_property_id is used for fetching analytics data from google's api, ga_web_property_id is used for sending events to GA analtyics
202
- # ga_web_property_id will probably change in V5 to ga_measurement_id for clarity
204
+ # d) Set the ga_measurement_id. (located in admin -> Data collection and modification -> Data Streams -> Web stream details and begins with G-)
205
+ # ga_measurement_id is used for sending events to GA analytics
206
+ # ga_web_property_id is deprecated, use ga_measurement_id instead
207
+ # ga_property_id is used for fetching analytics data from google's api
203
208
  config.ga_json_key_path = nil
209
+ config.ga_measurement_id = nil
204
210
  config.ga_web_property_id = nil
205
211
  config.ga_property_id = nil
206
212
  config.ga_analytics_options = {}
@@ -208,6 +214,16 @@ module Spotlight
208
214
  config.ga_date_range = { 'start_date' => nil, 'end_date' => nil }
209
215
  config.ga_debug_mode = false
210
216
 
217
+ # Remove this in a future release
218
+ config.after_initialize do
219
+ if Spotlight::Engine.config.ga_web_property_id.present?
220
+ Spotlight.deprecator.warn(
221
+ 'Spotlight::Engine.config.ga_web_property_id is deprecated and will be removed in a future version. ' \
222
+ 'Use Spotlight::Engine.config.ga_measurement_id instead.'
223
+ )
224
+ end
225
+ end
226
+
211
227
  config.max_pages = 1000
212
228
 
213
229
  Blacklight::Engine.config.inject_blacklight_helpers = false
@@ -223,7 +239,8 @@ module Spotlight
223
239
  nl: 'Nederlands',
224
240
  'pt-BR': 'Português brasileiro',
225
241
  sq: 'Shqip',
226
- zh: '中文'
242
+ zh: '中文',
243
+ ja: '日本語'
227
244
  }
228
245
 
229
246
  # Whitelisting the available_locales is necessary here, as any dependency we
@@ -272,6 +289,8 @@ module Spotlight
272
289
  Blacklight::Configuration.default_values[:search_state_fields] ||= []
273
290
  Blacklight::Configuration.default_values[:search_state_fields] += %i[id exhibit_id browse_category_id]
274
291
  Blacklight::Configuration.default_values[:skip_link_component] = Spotlight::SkipLinkComponent
292
+ Blacklight::Configuration.default_values[:header_component] = Spotlight::HeaderComponent
293
+ Blacklight::Configuration.property :exhibit_navbar_component, default: Spotlight::ExhibitNavbarComponent
275
294
  end
276
295
 
277
296
  # make blacklight configuration play nice with bootstrap_form
@@ -301,7 +320,7 @@ module Spotlight
301
320
  blacklight_configuration: true,
302
321
  config: true,
303
322
  pages: true,
304
- resources: true
323
+ resources: false # see https://github.com/projectblacklight/spotlight/issues/3641
305
324
  }
306
325
 
307
326
  config.reindexing_batch_size = nil
@@ -1,19 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spotlight
4
- # Override Blacklight::SearchState to use exhibit-specific routes for documents
5
- class SearchState < SimpleDelegator
6
- attr_reader :current_exhibit
7
-
8
- def initialize(search_state, current_exhibit)
9
- super(search_state)
10
- @current_exhibit = current_exhibit
11
- end
12
-
4
+ # Override Blacklight::SearchState to use exhibit-specific routes for documents.
5
+ #
6
+ # This must remain the app's search_state_class (set in Spotlight::Controller) for
7
+ # url_for_document to add exhibit context to document routes.
8
+ class SearchState < Blacklight::SearchState
13
9
  def url_for_document(document, options = {})
14
- return super unless current_exhibit
10
+ return super unless controller.respond_to?(:current_exhibit) && controller.current_exhibit
15
11
 
16
- [controller.spotlight, current_exhibit, document]
12
+ [controller.spotlight, controller.current_exhibit, document]
17
13
  end
18
14
  end
19
15
  end
@@ -9,13 +9,18 @@ module Spotlight
9
9
  class UploadFieldConfig
10
10
  attr_reader :blacklight_options, :field_name, :form_field_type
11
11
 
12
- def initialize(field_name:, blacklight_options: {}, form_field_type: :text_field, label: nil, solr_fields: nil)
12
+ # rubocop:disable Metrics/ParameterLists
13
+ def initialize(field_name:, blacklight_options: {}, form_field_type: :text_field, solr_fields: nil, label: nil, is_multiple: false,
14
+ component: nil)
13
15
  @blacklight_options = blacklight_options
14
16
  @field_name = field_name
15
17
  @form_field_type = form_field_type
16
18
  @solr_fields = solr_fields
17
19
  @label = label || field_name
20
+ @is_multiple = is_multiple
21
+ @component = component
18
22
  end
23
+ # rubocop:enable Metrics/ParameterLists
19
24
 
20
25
  # Allows a proc to be set as the label
21
26
  def label
@@ -24,6 +29,19 @@ module Spotlight
24
29
  @label
25
30
  end
26
31
 
32
+ # rubocop:disable Naming/PredicatePrefix
33
+ def is_multiple?
34
+ @is_multiple
35
+ end
36
+ # rubocop:enable Naming/PredicatePrefix
37
+
38
+ # The component used to render the field on the upload and edit forms
39
+ def component
40
+ return Spotlight::SidecarFormFieldComponent if @component.blank?
41
+
42
+ @component.is_a?(String) ? @component.constantize : @component
43
+ end
44
+
27
45
  # aliasing for backwards compatability and consistency with blacklight config
28
46
  alias solr_field field_name
29
47
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spotlight
4
- VERSION = '5.3.2'
4
+ VERSION = '6.0.0.rc2'
5
5
  end
data/lib/spotlight.rb CHANGED
@@ -7,6 +7,6 @@ require 'spotlight/engine'
7
7
  # Spotlight
8
8
  module Spotlight
9
9
  def self.deprecator
10
- @deprecator ||= ActiveSupport::Deprecation.new('6.0', 'blacklight-spotlight')
10
+ @deprecator ||= ActiveSupport::Deprecation.new('7.0', 'blacklight-spotlight')
11
11
  end
12
12
  end
@@ -5,7 +5,9 @@ module CapybaraWaitMetadataHelper
5
5
 
6
6
  included do
7
7
  around do |example|
8
- using_wait_time example.metadata[:max_wait_time] || Capybara.default_max_wait_time do
8
+ next example.run unless example.metadata.key?(:max_wait_time)
9
+
10
+ using_wait_time example.metadata[:max_wait_time] do
9
11
  example.run
10
12
  end
11
13
  end
@@ -51,11 +51,34 @@ module Spotlight
51
51
  expect(page).to have_css('.st-blocks.st-ready')
52
52
  end
53
53
 
54
+ # Run the block (e.g. submitting a form) and wait for Turbo to render the
55
+ # new page, so later steps don't act on the old one. Waiting for something
56
+ # like an enabled submit button isn't enough: Turbo disables the submitter
57
+ # only while the request is in flight, so the old page can satisfy the
58
+ # check before the submission starts and again after it finishes. Turbo
59
+ # replaces the body on every render, so wait for the marked body to go
60
+ # away.
61
+ def expect_new_page
62
+ page.execute_script("document.body.setAttribute('data-previous-page', '')")
63
+ yield
64
+ expect(page).to have_no_css('body[data-previous-page]')
65
+ expect(page).to have_no_css('html[aria-busy]')
66
+ end
67
+
68
+ # Headless Chrome blocks real clipboard access, so replace writeText
69
+ # with a shim that stashes its argument on window for assertion.
70
+ def stub_clipboard
71
+ page.execute_script(<<~JS)
72
+ window.__copied = null
73
+ navigator.clipboard.writeText = (text) => { window.__copied = text; return Promise.resolve() }
74
+ JS
75
+ end
76
+
54
77
  def save_page_changes
55
78
  click_button('Save changes')
56
79
  # verify that the page was created.
57
80
  expect(page).to have_css('.alert-info', text: 'was successfully updated')
58
- expect(page).to have_no_selector('.alert-danger')
81
+ expect(page).to have_no_css('.alert-danger')
59
82
  end
60
83
 
61
84
  # Capybara's HTML5 drag emulation sends the drag events to a given element. This drags
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # JavaScript feature specs load IIIF manifests from the browser, which WebMock
4
+ # can't intercept. Serve fixture manifests from the Capybara app server instead
5
+ # so specs don't depend on network access to external IIIF servers.
6
+ module IiifManifestFixtures
7
+ PATH = '/iiif_manifest_fixtures'
8
+ DIR = File.expand_path('../fixtures/iiif_manifests', __dir__)
9
+
10
+ # Point the autocomplete responses for documents that have a fixture manifest
11
+ # (spec/fixtures/iiif_manifests/<document_id>.json) at that fixture. The controller
12
+ # instance is created by the app server, so it can only be reached with any_instance.
13
+ def stub_iiif_manifests
14
+ allow_any_instance_of(Spotlight::CatalogController).to( # rubocop:disable RSpec/AnyInstance
15
+ receive(:autocomplete_json_response_for_document).and_wrap_original do |original, doc|
16
+ response = original.call(doc)
17
+ response[:iiif_manifest] = "#{PATH}/#{doc.id}.json" if response[:iiif_manifest] && File.exist?(File.join(DIR, "#{doc.id}.json"))
18
+ response
19
+ end
20
+ )
21
+ end
22
+ end
23
+
24
+ app = Capybara.app
25
+ Capybara.app = Rack::Builder.new do
26
+ map(IiifManifestFixtures::PATH) { run Rack::Files.new(IiifManifestFixtures::DIR) }
27
+ run app
28
+ end
29
+
30
+ RSpec.configure do |config|
31
+ config.include IiifManifestFixtures, type: :feature
32
+ config.before(type: :feature, js: true) { stub_iiif_manifests }
33
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Avoid real DNS lookups when SsrfFilter checks IIIF URLs. Hostnames resolve to
4
+ # an arbitrary public address (WebMock intercepts the request, so nothing
5
+ # connects to it); IP literals resolve to themselves.
6
+ RSpec.configure do |config|
7
+ config.before do
8
+ stub_const('SsrfFilter::DEFAULT_RESOLVER', lambda do |host|
9
+ [IPAddr.new(host.match?(Resolv::AddressRegex) ? host : '1.1.1.1')]
10
+ end)
11
+ end
12
+ end