hyrax 5.2.0 → 5.3.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 (527) hide show
  1. checksums.yaml +4 -4
  2. data/.dassie/.env +5 -1
  3. data/.dassie/Gemfile +4 -2
  4. data/.dassie/app/assets/images/bulkrax/removed.png +0 -0
  5. data/.dassie/app/assets/javascripts/application.js +2 -0
  6. data/.dassie/app/assets/stylesheets/application.css +1 -0
  7. data/.dassie/app/controllers/catalog_controller.rb +1 -0
  8. data/.dassie/app/forms/admin_set_resource_form.rb +6 -0
  9. data/.dassie/app/forms/collection_resource_form.rb +5 -2
  10. data/.dassie/app/forms/generic_work_resource_form.rb +5 -2
  11. data/.dassie/app/forms/monograph_form.rb +5 -3
  12. data/.dassie/app/indexers/admin_set_resource_indexer.rb +5 -0
  13. data/.dassie/app/indexers/collection_resource_indexer.rb +3 -3
  14. data/.dassie/app/indexers/generic_work_resource_indexer.rb +6 -3
  15. data/.dassie/app/indexers/monograph_indexer.rb +6 -2
  16. data/.dassie/app/models/ability.rb +8 -0
  17. data/.dassie/app/models/collection_resource.rb +4 -2
  18. data/.dassie/app/models/concerns/bulkrax/has_local_processing.rb +8 -0
  19. data/.dassie/app/models/generic_work_resource.rb +5 -2
  20. data/.dassie/app/models/monograph.rb +5 -2
  21. data/.dassie/app/views/blacklight_dynamic_sitemap/sitemap/show.xml.builder +22 -0
  22. data/.dassie/bin/importer +142 -0
  23. data/.dassie/bin/web +4 -0
  24. data/.dassie/config/browse_everything_providers.yml +1 -1
  25. data/.dassie/config/bulkrax_api.yml +86 -0
  26. data/.dassie/config/initializers/bulkrax.rb +92 -0
  27. data/.dassie/config/initializers/clamav.rb +2 -0
  28. data/.dassie/config/initializers/hyrax.rb +7 -1
  29. data/.dassie/config/initializers/riiif.rb +4 -80
  30. data/.dassie/config/initializers/wings.rb +1 -1
  31. data/.dassie/config/metadata_profiles/m3_profile.yaml +929 -0
  32. data/.dassie/config/puma.rb +4 -2
  33. data/.dassie/config/routes.rb +7 -0
  34. data/.dassie/config/sidekiq.yml +17 -0
  35. data/.dassie/config/uv/uv.html +63 -81
  36. data/.dassie/db/migrate/20240606205215_create_hyrax_flexible_schemas.rb +9 -0
  37. data/.dassie/db/migrate/20240606205216_add_contexts_to_hyrax_flexible_schemas.rb +5 -0
  38. data/.dassie/db/migrate/20250826142438_create_bulkrax_importers.bulkrax.rb +19 -0
  39. data/.dassie/db/migrate/20250826142439_create_bulkrax_importer_runs.bulkrax.rb +17 -0
  40. data/.dassie/db/migrate/20250826142440_create_bulkrax_entries.bulkrax.rb +17 -0
  41. data/.dassie/db/migrate/20250826142441_add_status_to_entry.bulkrax.rb +10 -0
  42. data/.dassie/db/migrate/20250826142442_add_collections_to_importer_runs.bulkrax.rb +7 -0
  43. data/.dassie/db/migrate/20250826142443_change_collection_ids_on_entries.bulkrax.rb +6 -0
  44. data/.dassie/db/migrate/20250826142444_create_bulkrax_exporters.bulkrax.rb +20 -0
  45. data/.dassie/db/migrate/20250826142445_create_bulkrax_exporter_runs.bulkrax.rb +15 -0
  46. data/.dassie/db/migrate/20250826142446_change_importer_and_exporter_to_polymorphic.bulkrax.rb +19 -0
  47. data/.dassie/db/migrate/20250826142447_add_total_collection_records_to_importer_runs.bulkrax.rb +6 -0
  48. data/.dassie/db/migrate/20250826142448_add_children_to_importer_runs.bulkrax.rb +7 -0
  49. data/.dassie/db/migrate/20250826142449_change_total_records_to_total_work_entries.bulkrax.rb +7 -0
  50. data/.dassie/db/migrate/20250826142450_change_entry_last_error.bulkrax.rb +20 -0
  51. data/.dassie/db/migrate/20250826142451_add_validate_only_to_bulkrax_importers.bulkrax.rb +6 -0
  52. data/.dassie/db/migrate/20250826142452_add_status_to_importers.bulkrax.rb +10 -0
  53. data/.dassie/db/migrate/20250826142453_remove_foreign_key_from_bulkrax_entries.bulkrax.rb +6 -0
  54. data/.dassie/db/migrate/20250826142454_add_status_to_exporters.bulkrax.rb +8 -0
  55. data/.dassie/db/migrate/20250826142455_add_invalid_record_to_importer_run.bulkrax.rb +6 -0
  56. data/.dassie/db/migrate/20250826142456_create_bulkrax_statuses.bulkrax.rb +19 -0
  57. data/.dassie/db/migrate/20250826142457_move_to_statuses.bulkrax.rb +31 -0
  58. data/.dassie/db/migrate/20250826142458_add_date_filter_and_status_to_bulkrax_exporters.bulkrax.rb +8 -0
  59. data/.dassie/db/migrate/20250826142459_add_workflow_status_to_bulkrax_exporter.bulkrax.rb +6 -0
  60. data/.dassie/db/migrate/20250826142460_remove_unused_last_error.bulkrax.rb +8 -0
  61. data/.dassie/db/migrate/20250826142461_increase_text_sizes.bulkrax.rb +13 -0
  62. data/.dassie/db/migrate/20250826142462_change_bulkrax_statuses_error_message_column_type_to_text.bulkrax.rb +6 -0
  63. data/.dassie/db/migrate/20250826142463_rename_children_counters_to_relationships.bulkrax.rb +7 -0
  64. data/.dassie/db/migrate/20250826142464_add_file_set_counters_to_importer_runs.bulkrax.rb +8 -0
  65. data/.dassie/db/migrate/20250826142465_add_import_attempts_to_entries.bulkrax.rb +6 -0
  66. data/.dassie/db/migrate/20250826142466_add_work_counters_to_importer_runs.bulkrax.rb +7 -0
  67. data/.dassie/db/migrate/20250826142467_create_bulkrax_pending_relationships.bulkrax.rb +14 -0
  68. data/.dassie/db/migrate/20250826142468_add_order_to_bulkrax_pending_relationships.bulkrax.rb +6 -0
  69. data/.dassie/db/migrate/20250826142469_add_include_thumbnails_to_bulkrax_exporters.bulkrax.rb +6 -0
  70. data/.dassie/db/migrate/20250826142470_add_generated_metadata_to_bulkrax_exporters.bulkrax.rb +6 -0
  71. data/.dassie/db/migrate/20250826142471_rename_bulkrax_importer_run_to_importer_run.bulkrax.rb +18 -0
  72. data/.dassie/db/migrate/20250826142472_add_indices_to_bulkrax.bulkrax.rb +26 -0
  73. data/.dassie/db/migrate/20250826142473_denormalize_status_message.bulkrax.rb +8 -0
  74. data/.dassie/db/migrate/20250826142474_update_identifier_index.bulkrax.rb +7 -0
  75. data/.dassie/db/migrate/20250826142475_add_index_to_metadata_bulkrax_identifier.bulkrax.rb +19 -0
  76. data/.dassie/db/migrate/20250826142476_add_file_name_to_uploaded_files.bulkrax.rb +6 -0
  77. data/.dassie/db/migrate/20250826142477_add_error_tracking_to_pending_relationships.bulkrax.rb +6 -0
  78. data/.dassie/db/migrate/20250826142478_add_last_imported_at_to_bulkrax_importers.bulkrax.rb +6 -0
  79. data/.dassie/db/migrate/20250826142479_add_next_import_at_to_bulkrax_importers.bulkrax.rb +6 -0
  80. data/.dassie/db/migrate/20250826142480_entry_error_denormalization.bulkrax.rb +8 -0
  81. data/.dassie/db/migrate/20250826142481_faster_first_entry.bulkrax.rb +8 -0
  82. data/.dassie/db/migrate/20260430000001_create_hyrax_redirect_paths.hyrax.rb +13 -0
  83. data/.dassie/db/migrate/20260521003627_add_additional_redirect_info.hyrax.rb +32 -0
  84. data/.dassie/db/schema.rb +154 -1
  85. data/.dassie/package.json +1 -1
  86. data/.dassie/rspec_split_configuration.json +835 -0
  87. data/.dassie/solr/conf/solrconfig.xml +21 -5
  88. data/.github/{ISSUE_TEMPLATE.md → ISSUE_TEMPLATE/issue_template.md} +5 -0
  89. data/.github/workflows/lint-build-test.yml +5 -1
  90. data/.github/workflows/release-charts.yml +48 -0
  91. data/.gitignore +6 -0
  92. data/.koppie/.env +5 -1
  93. data/.koppie/Gemfile +3 -1
  94. data/.koppie/app/assets/images/bulkrax/removed.png +0 -0
  95. data/.koppie/app/assets/javascripts/application.js +2 -0
  96. data/.koppie/app/assets/stylesheets/application.css +1 -0
  97. data/.koppie/app/controllers/catalog_controller.rb +1 -1
  98. data/.koppie/app/forms/collection_resource_form.rb +5 -2
  99. data/.koppie/app/forms/file_set_form.rb +5 -0
  100. data/.koppie/app/forms/generic_work_form.rb +5 -3
  101. data/.koppie/app/forms/monograph_form.rb +5 -3
  102. data/.koppie/app/indexers/collection_resource_indexer.rb +5 -2
  103. data/.koppie/app/indexers/file_set_indexer.rb +7 -0
  104. data/.koppie/app/indexers/generic_work_indexer.rb +6 -3
  105. data/.koppie/app/indexers/monograph_indexer.rb +6 -2
  106. data/.koppie/app/models/ability.rb +8 -0
  107. data/.koppie/app/models/collection_resource.rb +4 -2
  108. data/.koppie/app/models/concerns/bulkrax/has_local_processing.rb +8 -0
  109. data/.koppie/app/models/generic_work.rb +5 -2
  110. data/.koppie/app/models/monograph.rb +5 -2
  111. data/.koppie/app/views/blacklight_dynamic_sitemap/sitemap/show.xml.builder +22 -0
  112. data/.koppie/bin/importer +142 -0
  113. data/.koppie/bin/web +4 -0
  114. data/.koppie/config/browse_everything_providers.yml +2 -0
  115. data/.koppie/config/bulkrax_api.yml +86 -0
  116. data/.koppie/config/initializers/bulkrax.rb +92 -0
  117. data/.koppie/config/initializers/clamav.rb +2 -0
  118. data/.koppie/config/initializers/hyrax.rb +11 -3
  119. data/.koppie/config/initializers/riiif.rb +4 -82
  120. data/.koppie/config/metadata_profiles/m3_profile.yaml +930 -0
  121. data/.koppie/config/routes.rb +7 -0
  122. data/.koppie/config/sidekiq.yml +2 -0
  123. data/.koppie/config/uv/uv.html +63 -81
  124. data/.koppie/db/migrate/20240606205215_create_hyrax_flexible_schemas.rb +9 -0
  125. data/.koppie/db/migrate/20240606205216_add_contexts_to_hyrax_flexible_schemas.rb +5 -0
  126. data/.koppie/db/migrate/20250826142438_create_bulkrax_importers.bulkrax.rb +19 -0
  127. data/.koppie/db/migrate/20250826142439_create_bulkrax_importer_runs.bulkrax.rb +17 -0
  128. data/.koppie/db/migrate/20250826142440_create_bulkrax_entries.bulkrax.rb +17 -0
  129. data/.koppie/db/migrate/20250826142441_add_status_to_entry.bulkrax.rb +10 -0
  130. data/.koppie/db/migrate/20250826142442_add_collections_to_importer_runs.bulkrax.rb +7 -0
  131. data/.koppie/db/migrate/20250826142443_change_collection_ids_on_entries.bulkrax.rb +6 -0
  132. data/.koppie/db/migrate/20250826142444_create_bulkrax_exporters.bulkrax.rb +20 -0
  133. data/.koppie/db/migrate/20250826142445_create_bulkrax_exporter_runs.bulkrax.rb +15 -0
  134. data/.koppie/db/migrate/20250826142446_change_importer_and_exporter_to_polymorphic.bulkrax.rb +19 -0
  135. data/.koppie/db/migrate/20250826142447_add_total_collection_records_to_importer_runs.bulkrax.rb +6 -0
  136. data/.koppie/db/migrate/20250826142448_add_children_to_importer_runs.bulkrax.rb +7 -0
  137. data/.koppie/db/migrate/20250826142449_change_total_records_to_total_work_entries.bulkrax.rb +7 -0
  138. data/.koppie/db/migrate/20250826142450_change_entry_last_error.bulkrax.rb +20 -0
  139. data/.koppie/db/migrate/20250826142451_add_validate_only_to_bulkrax_importers.bulkrax.rb +6 -0
  140. data/.koppie/db/migrate/20250826142452_add_status_to_importers.bulkrax.rb +10 -0
  141. data/.koppie/db/migrate/20250826142453_remove_foreign_key_from_bulkrax_entries.bulkrax.rb +6 -0
  142. data/.koppie/db/migrate/20250826142454_add_status_to_exporters.bulkrax.rb +8 -0
  143. data/.koppie/db/migrate/20250826142455_add_invalid_record_to_importer_run.bulkrax.rb +6 -0
  144. data/.koppie/db/migrate/20250826142456_create_bulkrax_statuses.bulkrax.rb +19 -0
  145. data/.koppie/db/migrate/20250826142457_move_to_statuses.bulkrax.rb +31 -0
  146. data/.koppie/db/migrate/20250826142458_add_date_filter_and_status_to_bulkrax_exporters.bulkrax.rb +8 -0
  147. data/.koppie/db/migrate/20250826142459_add_workflow_status_to_bulkrax_exporter.bulkrax.rb +6 -0
  148. data/.koppie/db/migrate/20250826142460_remove_unused_last_error.bulkrax.rb +8 -0
  149. data/.koppie/db/migrate/20250826142461_increase_text_sizes.bulkrax.rb +13 -0
  150. data/.koppie/db/migrate/20250826142462_change_bulkrax_statuses_error_message_column_type_to_text.bulkrax.rb +6 -0
  151. data/.koppie/db/migrate/20250826142463_rename_children_counters_to_relationships.bulkrax.rb +7 -0
  152. data/.koppie/db/migrate/20250826142464_add_file_set_counters_to_importer_runs.bulkrax.rb +8 -0
  153. data/.koppie/db/migrate/20250826142465_add_import_attempts_to_entries.bulkrax.rb +6 -0
  154. data/.koppie/db/migrate/20250826142466_add_work_counters_to_importer_runs.bulkrax.rb +7 -0
  155. data/.koppie/db/migrate/20250826142467_create_bulkrax_pending_relationships.bulkrax.rb +14 -0
  156. data/.koppie/db/migrate/20250826142468_add_order_to_bulkrax_pending_relationships.bulkrax.rb +6 -0
  157. data/.koppie/db/migrate/20250826142469_add_include_thumbnails_to_bulkrax_exporters.bulkrax.rb +6 -0
  158. data/.koppie/db/migrate/20250826142470_add_generated_metadata_to_bulkrax_exporters.bulkrax.rb +6 -0
  159. data/.koppie/db/migrate/20250826142471_rename_bulkrax_importer_run_to_importer_run.bulkrax.rb +18 -0
  160. data/.koppie/db/migrate/20250826142472_add_indices_to_bulkrax.bulkrax.rb +26 -0
  161. data/.koppie/db/migrate/20250826142473_denormalize_status_message.bulkrax.rb +8 -0
  162. data/.koppie/db/migrate/20250826142474_update_identifier_index.bulkrax.rb +7 -0
  163. data/.koppie/db/migrate/20250826142475_add_index_to_metadata_bulkrax_identifier.bulkrax.rb +19 -0
  164. data/.koppie/db/migrate/20250826142476_add_file_name_to_uploaded_files.bulkrax.rb +6 -0
  165. data/.koppie/db/migrate/20250826142477_add_error_tracking_to_pending_relationships.bulkrax.rb +6 -0
  166. data/.koppie/db/migrate/20250826142478_add_last_imported_at_to_bulkrax_importers.bulkrax.rb +6 -0
  167. data/.koppie/db/migrate/20250826142479_add_next_import_at_to_bulkrax_importers.bulkrax.rb +6 -0
  168. data/.koppie/db/migrate/20250826142480_entry_error_denormalization.bulkrax.rb +8 -0
  169. data/.koppie/db/migrate/20250826142481_faster_first_entry.bulkrax.rb +8 -0
  170. data/.koppie/db/migrate/20260430000001_create_hyrax_redirect_paths.hyrax.rb +13 -0
  171. data/.koppie/db/migrate/20260521003627_add_additional_redirect_info.hyrax.rb +32 -0
  172. data/.koppie/db/schema.rb +154 -1
  173. data/.koppie/package.json +1 -1
  174. data/.koppie/rspec_split_configuration.json +835 -0
  175. data/.koppie/solr/conf/solrconfig.xml +0 -5
  176. data/.koppie/yarn.lock +5587 -752
  177. data/.rubocop.yml +1 -0
  178. data/CONTAINERS.md +2 -0
  179. data/Dockerfile +9 -22
  180. data/Gemfile +0 -1
  181. data/Gemfile.allinson +2 -0
  182. data/README.md +1 -2
  183. data/app/actors/hyrax/actors/file_actor.rb +2 -0
  184. data/app/actors/hyrax/actors/file_set_actor.rb +1 -1
  185. data/app/assets/javascripts/hyrax/app.js.erb +143 -10
  186. data/app/assets/javascripts/hyrax/collection_select.js +68 -0
  187. data/app/assets/javascripts/hyrax/copy_permalink_button.js +28 -0
  188. data/app/assets/javascripts/hyrax/redirects.js +45 -0
  189. data/app/assets/javascripts/hyrax/relationships/control.es6 +21 -1
  190. data/app/assets/javascripts/hyrax/select_work_type.es6 +7 -2
  191. data/app/assets/javascripts/hyrax.js +3 -1
  192. data/app/assets/stylesheets/hyrax/_file-show.scss +1 -0
  193. data/app/assets/stylesheets/hyrax/_viewer.scss +8 -0
  194. data/app/assets/stylesheets/hyrax/dashboard.scss +22 -1
  195. data/app/assets/stylesheets/hyrax/sidebar.scss +98 -3
  196. data/app/authorities/qa/authorities/collections.rb +9 -9
  197. data/app/controllers/concerns/hyrax/analytics_error_handling.rb +97 -0
  198. data/app/controllers/concerns/hyrax/collections_controller_behavior.rb +3 -1
  199. data/app/controllers/concerns/hyrax/ensure_migrated_behavior.rb +50 -0
  200. data/app/controllers/concerns/hyrax/flexible_catalog_behavior.rb +206 -0
  201. data/app/controllers/concerns/hyrax/flexible_schema_behavior.rb +17 -0
  202. data/app/controllers/concerns/hyrax/redirect_to_display_url.rb +54 -0
  203. data/app/controllers/concerns/hyrax/works_controller_behavior.rb +52 -10
  204. data/app/controllers/hyrax/admin/admin_sets_controller.rb +21 -13
  205. data/app/controllers/hyrax/admin/analytics/collection_reports_controller.rb +2 -0
  206. data/app/controllers/hyrax/admin/analytics/work_reports_controller.rb +1 -0
  207. data/app/controllers/hyrax/admin/metadata_profiles_controller.rb +66 -0
  208. data/app/controllers/hyrax/batch_uploads_controller.rb +2 -0
  209. data/app/controllers/hyrax/dashboard/collections_controller.rb +27 -6
  210. data/app/controllers/hyrax/dashboard/nest_collections_controller.rb +2 -1
  211. data/app/controllers/hyrax/dashboard_controller.rb +2 -1
  212. data/app/controllers/hyrax/file_sets_controller.rb +19 -1
  213. data/app/controllers/hyrax/homepage_controller.rb +7 -0
  214. data/app/controllers/hyrax/my/works_controller.rb +2 -21
  215. data/app/controllers/hyrax/permissions_controller.rb +4 -2
  216. data/app/controllers/hyrax/redirects_controller.rb +56 -0
  217. data/app/controllers/hyrax/single_use_links_viewer_controller.rb +2 -1
  218. data/app/controllers/hyrax/transcripts_controller.rb +31 -0
  219. data/app/controllers/hyrax/uploads_controller.rb +18 -9
  220. data/app/forms/concerns/hyrax/based_near_field_behavior.rb +77 -0
  221. data/app/forms/concerns/hyrax/flexible_form_behavior.rb +37 -0
  222. data/app/forms/concerns/hyrax/redirects_field_behavior.rb +95 -0
  223. data/app/forms/concerns/hyrax/transcripts_behavior.rb +40 -0
  224. data/app/forms/hyrax/forms/admin_set_form.rb +1 -1
  225. data/app/forms/hyrax/forms/administrative_set_form.rb +3 -0
  226. data/app/forms/hyrax/forms/batch_edit_form.rb +1 -3
  227. data/app/forms/hyrax/forms/batch_upload_form.rb +14 -0
  228. data/app/forms/hyrax/forms/file_set_edit_form.rb +1 -1
  229. data/app/forms/hyrax/forms/file_set_form.rb +6 -7
  230. data/app/forms/hyrax/forms/pcdm_collection_form.rb +17 -5
  231. data/app/forms/hyrax/forms/pcdm_object_form.rb +11 -3
  232. data/app/forms/hyrax/forms/resource_batch_edit_form.rb +8 -22
  233. data/app/forms/hyrax/forms/resource_form.rb +110 -10
  234. data/app/forms/hyrax/forms.rb +1 -0
  235. data/app/helpers/hyrax/attributes_helper.rb +109 -0
  236. data/app/helpers/hyrax/blacklight_override.rb +26 -0
  237. data/app/helpers/hyrax/collections_helper.rb +2 -0
  238. data/app/helpers/hyrax/file_set_form_helper.rb +24 -0
  239. data/app/helpers/hyrax/hyrax_helper_behavior.rb +51 -2
  240. data/app/helpers/hyrax/iiif_helper.rb +11 -1
  241. data/app/helpers/hyrax/permalink_helper.rb +37 -0
  242. data/app/helpers/hyrax/redirects_tab_helper.rb +29 -0
  243. data/app/helpers/hyrax/work_form_helper.rb +9 -5
  244. data/app/helpers/hyrax/works_helper.rb +14 -0
  245. data/app/indexers/concerns/hyrax/workflow_indexer.rb +30 -0
  246. data/app/indexers/hyrax/file_set_indexer.rb +1 -0
  247. data/app/indexers/hyrax/indexers/administrative_set_indexer.rb +2 -1
  248. data/app/indexers/hyrax/indexers/file_set_indexer.rb +6 -2
  249. data/app/indexers/hyrax/indexers/pcdm_collection_indexer.rb +11 -1
  250. data/app/indexers/hyrax/indexers/pcdm_object_indexer.rb +25 -4
  251. data/app/indexers/hyrax/indexers/redirects_indexer.rb +29 -0
  252. data/app/indexers/hyrax/indexers/resource_indexer.rb +4 -0
  253. data/app/indexers/hyrax/indexers.rb +2 -0
  254. data/app/inputs/controlled_vocabulary_input.rb +7 -1
  255. data/app/jobs/content_deposit_error_event_job.rb +14 -0
  256. data/app/jobs/create_work_job.rb +2 -0
  257. data/app/jobs/migrate_files_to_valkyrie_job.rb +7 -1
  258. data/app/models/batch_upload_item.rb +4 -0
  259. data/app/models/concerns/hyrax/ability/flexible_metadata_ability.rb +10 -0
  260. data/app/models/concerns/hyrax/ability.rb +3 -1
  261. data/app/models/concerns/hyrax/collection_behavior.rb +4 -0
  262. data/app/models/concerns/hyrax/file_set/transcripts.rb +16 -0
  263. data/app/models/concerns/hyrax/file_set_behavior.rb +9 -0
  264. data/app/models/concerns/hyrax/flexibility.rb +107 -0
  265. data/app/models/concerns/hyrax/redirects_normalization.rb +38 -0
  266. data/app/models/concerns/hyrax/solr_document/characterization.rb +1 -1
  267. data/app/models/concerns/hyrax/solr_document/metadata.rb +9 -0
  268. data/app/models/concerns/hyrax/solr_document/ordered_members.rb +4 -0
  269. data/app/models/concerns/hyrax/solr_document_behavior.rb +28 -6
  270. data/app/models/concerns/hyrax/suppressible.rb +1 -1
  271. data/app/models/concerns/hyrax/valkyrie_lazy_migration.rb +1 -1
  272. data/app/models/concerns/hyrax/with_embargoes_and_leases.rb +30 -0
  273. data/app/models/concerns/hyrax/work_behavior.rb +8 -0
  274. data/app/models/hyrax/administrative_set.rb +1 -1
  275. data/app/models/hyrax/change_set.rb +3 -1
  276. data/app/models/hyrax/embargo.rb +3 -1
  277. data/app/models/hyrax/file_set.rb +4 -2
  278. data/app/models/hyrax/flexible_schema.rb +219 -0
  279. data/app/models/hyrax/lease.rb +3 -1
  280. data/app/models/hyrax/pcdm_collection.rb +4 -1
  281. data/app/models/hyrax/redirect.rb +64 -0
  282. data/app/models/hyrax/redirect_path.rb +14 -0
  283. data/app/models/hyrax/resource.rb +22 -25
  284. data/app/models/hyrax/riiif/file.rb +43 -0
  285. data/app/models/hyrax/riiif/file_resolver.rb +65 -0
  286. data/app/models/hyrax/uploaded_file.rb +9 -0
  287. data/app/models/hyrax/virus_scanner.rb +16 -3
  288. data/app/models/hyrax/work.rb +4 -1
  289. data/app/models/job_io_wrapper.rb +12 -3
  290. data/app/models/user_mailbox.rb +3 -1
  291. data/app/presenters/hyrax/admin_set_presenter.rb +11 -0
  292. data/app/presenters/hyrax/annotates_content.rb +35 -0
  293. data/app/presenters/hyrax/collection_presenter.rb +5 -1
  294. data/app/presenters/hyrax/displays_content.rb +133 -0
  295. data/app/presenters/hyrax/displays_image.rb +11 -4
  296. data/app/presenters/hyrax/displays_transcripts.rb +59 -0
  297. data/app/presenters/hyrax/file_set_presenter.rb +8 -18
  298. data/app/presenters/hyrax/google_scholar_presenter.rb +39 -0
  299. data/app/presenters/hyrax/iiif_manifest_presenter.rb +22 -4
  300. data/app/presenters/hyrax/missing_method_behavior.rb +15 -0
  301. data/app/presenters/hyrax/pcdm_member_presenter_factory.rb +2 -4
  302. data/app/presenters/hyrax/work_show_presenter.rb +56 -14
  303. data/app/renderers/hyrax/renderers/attribute_renderer.rb +6 -2
  304. data/app/renderers/hyrax/renderers/license_attribute_renderer.rb +10 -10
  305. data/app/renderers/hyrax/renderers/redirects_label_attribute_renderer.rb +25 -0
  306. data/app/renderers/hyrax/renderers/rights_statement_attribute_renderer.rb +10 -11
  307. data/app/search_builders/hyrax/dashboard/nested_collections_search_builder.rb +1 -5
  308. data/app/search_builders/hyrax/filter_by_type.rb +1 -1
  309. data/app/services/hyrax/action/create_valkyrie_work.rb +3 -2
  310. data/app/services/hyrax/authority_rendering_helper.rb +28 -0
  311. data/app/services/hyrax/authority_service.rb +107 -0
  312. data/app/services/hyrax/callbacks.rb +2 -2
  313. data/app/services/hyrax/collections/nested_collection_query_service.rb +9 -3
  314. data/app/services/hyrax/collections_service.rb +17 -0
  315. data/app/services/hyrax/custom_queries/find_by_property_value.rb +89 -0
  316. data/app/services/hyrax/edit_permissions_service.rb +4 -4
  317. data/app/services/hyrax/file_set_type_service.rb +12 -4
  318. data/app/services/hyrax/flexible_schema_validator_service.rb +153 -0
  319. data/app/services/hyrax/flexible_schema_validators/class_validator.rb +123 -0
  320. data/app/services/hyrax/flexible_schema_validators/core_metadata_validator.rb +211 -0
  321. data/app/services/hyrax/flexible_schema_validators/existing_records_validator.rb +83 -0
  322. data/app/services/hyrax/flexible_schema_validators/redirects_validator.rb +116 -0
  323. data/app/services/hyrax/flexible_schema_validators/schema_validator.rb +34 -0
  324. data/app/services/hyrax/flexible_schema_validators/sort_properties_validator.rb +54 -0
  325. data/app/services/hyrax/license_service.rb +1 -1
  326. data/app/services/hyrax/listeners/metadata_index_listener.rb +11 -0
  327. data/app/services/hyrax/m3_profile_editor.rb +32 -0
  328. data/app/services/hyrax/m3_schema_loader.rb +119 -0
  329. data/app/services/hyrax/manifest_builder_service.rb +18 -24
  330. data/app/services/hyrax/permalink_path.rb +25 -0
  331. data/app/services/hyrax/qa_select_service.rb +9 -5
  332. data/app/services/hyrax/redirect_path_normalizer.rb +58 -0
  333. data/app/services/hyrax/redirects_lookup.rb +59 -0
  334. data/app/services/hyrax/resource_permissions_visibility_propagator.rb +54 -0
  335. data/app/services/hyrax/resource_types_service.rb +3 -20
  336. data/app/services/hyrax/rights_statement_service.rb +1 -1
  337. data/app/services/hyrax/schema_loader.rb +205 -0
  338. data/app/services/hyrax/search_service.rb +1 -1
  339. data/app/services/hyrax/simple_schema_loader.rb +28 -127
  340. data/app/services/hyrax/solr_service.rb +39 -2
  341. data/app/services/hyrax/tolerant_select_service.rb +5 -3
  342. data/app/services/hyrax/valkyrie_upload.rb +2 -2
  343. data/app/services/hyrax/visibility_propagator.rb +4 -1
  344. data/app/services/hyrax/work_uploads_handler.rb +17 -9
  345. data/app/services/hyrax/workflow/workflow_factory.rb +5 -4
  346. data/app/services/migrate_resource_service.rb +7 -1
  347. data/app/uploaders/hyrax/uploaded_file_uploader.rb +2 -2
  348. data/app/utils/hyrax/data_destroyers/collection_branding_destroyer.rb +1 -1
  349. data/app/utils/hyrax/required_data_seeder.rb +1 -0
  350. data/app/utils/hyrax/required_data_seeders/collection_type_seeder.rb +1 -1
  351. data/app/utils/hyrax/required_data_seeders/flexible_profile_seeder.rb +28 -0
  352. data/app/validators/hyrax/controlled_vocabulary_validator.rb +64 -0
  353. data/app/validators/hyrax/redirect_validator.rb +128 -0
  354. data/app/views/catalog/_thumbnail_list_default.html.erb +2 -2
  355. data/app/views/collections/edit_fields/_schema_version.html.erb +1 -0
  356. data/app/views/hyrax/admin/admin_sets/_form_metadata.html.erb +24 -2
  357. data/app/views/hyrax/admin/admin_sets/_show_document_list_row.html.erb +1 -1
  358. data/app/views/hyrax/admin/admin_sets/show.html.erb +1 -1
  359. data/app/views/hyrax/admin/analytics/_analytics_error.html.erb +42 -0
  360. data/app/views/hyrax/admin/analytics/collection_reports/index.html.erb +11 -9
  361. data/app/views/hyrax/admin/analytics/work_reports/index.html.erb +60 -57
  362. data/app/views/hyrax/admin/features/index.html.erb +1 -1
  363. data/app/views/hyrax/admin/metadata_profiles/_import_modal.html.erb +20 -0
  364. data/app/views/hyrax/admin/metadata_profiles/index.html.erb +54 -0
  365. data/app/views/hyrax/base/_attribute_rows.html.erb +4 -21
  366. data/app/views/hyrax/base/_citations.html.erb +1 -0
  367. data/app/views/hyrax/base/_currently_shared.html.erb +2 -1
  368. data/app/views/hyrax/base/_file_manager_thumbnail.html.erb +1 -1
  369. data/app/views/hyrax/base/_form_member_of_collections.html.erb +6 -6
  370. data/app/views/hyrax/base/_form_redirects.html.erb +125 -0
  371. data/app/views/hyrax/base/_form_share.html.erb +7 -2
  372. data/app/views/hyrax/base/_member.html.erb +1 -1
  373. data/app/views/hyrax/base/_social_media.html.erb +1 -1
  374. data/app/views/hyrax/base/iiif_viewers/_universal_viewer.html.erb +1 -1
  375. data/app/views/hyrax/base/show.html.erb +3 -0
  376. data/app/views/hyrax/collections/_default_group.html.erb +3 -0
  377. data/app/views/hyrax/collections/_list_collections.html.erb +3 -0
  378. data/app/views/hyrax/collections/_list_works.html.erb +1 -1
  379. data/app/views/hyrax/collections/_show_document_list_row.html.erb +1 -1
  380. data/app/views/hyrax/collections/show.html.erb +4 -0
  381. data/app/views/hyrax/dashboard/_sidebar.html.erb +4 -2
  382. data/app/views/hyrax/dashboard/collections/_button_for_update_collection.html.erb +2 -1
  383. data/app/views/hyrax/dashboard/collections/_default_group.html.erb +3 -0
  384. data/app/views/hyrax/dashboard/collections/_form.html.erb +17 -0
  385. data/app/views/hyrax/dashboard/collections/_form_for_select_collection.html.erb +7 -10
  386. data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +3 -0
  387. data/app/views/hyrax/dashboard/collections/_list_works.html.erb +1 -1
  388. data/app/views/hyrax/dashboard/collections/_show_document_list_row.html.erb +1 -1
  389. data/app/views/hyrax/dashboard/profiles/_edit_primary.html.erb +1 -8
  390. data/app/views/hyrax/dashboard/profiles/_trophy_edit.html.erb +1 -1
  391. data/app/views/hyrax/dashboard/profiles/show.html.erb +5 -5
  392. data/app/views/hyrax/dashboard/sidebar/_metadata.html.erb +11 -0
  393. data/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb +1 -0
  394. data/app/views/hyrax/dashboard/works/_default_group.html.erb +3 -0
  395. data/app/views/hyrax/dashboard/works/_list_works.html.erb +4 -2
  396. data/app/views/hyrax/file_sets/_form.html.erb +16 -3
  397. data/app/views/hyrax/file_sets/_metadata.html.erb +35 -0
  398. data/app/views/hyrax/file_sets/_valkyrie_form.html.erb +37 -0
  399. data/app/views/hyrax/file_sets/edit.html.erb +14 -8
  400. data/app/views/hyrax/file_sets/media_display/_audio.html.erb +4 -0
  401. data/app/views/hyrax/file_sets/media_display/_image.html.erb +2 -2
  402. data/app/views/hyrax/file_sets/media_display/_video.html.erb +4 -0
  403. data/app/views/hyrax/homepage/_explore_collections.html.erb +1 -1
  404. data/app/views/hyrax/homepage/_featured_fields.html.erb +1 -1
  405. data/app/views/hyrax/homepage/_recent_document.html.erb +1 -1
  406. data/app/views/hyrax/homepage/robots.text.erb +17 -0
  407. data/app/views/hyrax/my/collections/_default_group.html.erb +3 -0
  408. data/app/views/hyrax/my/collections/_list_collections.html.erb +3 -0
  409. data/app/views/hyrax/my/collections/_modal_add_subcollection.html.erb +2 -2
  410. data/app/views/hyrax/my/collections/_modal_add_to_collection.html.erb +2 -2
  411. data/app/views/hyrax/my/works/_default_group.html.erb +3 -0
  412. data/app/views/hyrax/my/works/_list_works.html.erb +5 -2
  413. data/app/views/hyrax/shared/_copy_permalink.html.erb +10 -0
  414. data/app/views/hyrax/users/_user_info.html.erb +1 -6
  415. data/app/views/layouts/_head_tag_content.html.erb +2 -0
  416. data/app/views/layouts/hyrax/dashboard.html.erb +2 -1
  417. data/app/views/records/edit_fields/_contexts.html.erb +1 -0
  418. data/app/views/records/edit_fields/_license.html.erb +17 -5
  419. data/app/views/records/edit_fields/_resource_type.html.erb +16 -2
  420. data/app/views/records/edit_fields/_rights_statement.html.erb +17 -5
  421. data/app/views/records/edit_fields/_schema_version.html.erb +1 -0
  422. data/app/views/records/edit_fields/_transcript_ids.html.erb +18 -0
  423. data/app/views/records/show_fields/_rights.html.erb +1 -1
  424. data/app/views/shared/_citations.html.erb +46 -31
  425. data/app/views/shared/_schema_version.html.erb +38 -0
  426. data/bin/dev-entrypoint.sh +14 -4
  427. data/chart/hyrax/Chart.yaml +4 -4
  428. data/chart/hyrax/templates/ingress.yaml +3 -0
  429. data/chart/hyrax/values.yaml +10 -8
  430. data/config/features.rb +27 -0
  431. data/config/initializers/blacklight_dynamic_sitemap.rb +43 -0
  432. data/config/initializers/deprecation_patch.rb +27 -0
  433. data/config/initializers/hydra_works.rb +3 -0
  434. data/config/initializers/i18n_extensions.rb +197 -0
  435. data/config/initializers/storage_adapter_initializer.rb +15 -9
  436. data/config/locales/hyrax.de.yml +172 -54
  437. data/config/locales/hyrax.en.yml +183 -66
  438. data/config/locales/hyrax.es.yml +174 -49
  439. data/config/locales/hyrax.fr.yml +169 -45
  440. data/config/locales/hyrax.it.yml +172 -48
  441. data/config/locales/hyrax.pt-BR.yml +172 -54
  442. data/config/locales/hyrax.zh.yml +145 -21
  443. data/config/metadata/basic_metadata.yaml +66 -0
  444. data/config/metadata/batch_edit_metadata.yaml +119 -0
  445. data/config/metadata/file_set_metadata.yaml +19 -0
  446. data/config/metadata/redirects.yaml +15 -0
  447. data/config/metadata_profiles/m3_json_schema.json +487 -0
  448. data/config/metadata_profiles/m3_profile.yaml +954 -0
  449. data/config/routes.rb +9 -0
  450. data/docker-compose-allinson.yml +176 -0
  451. data/docker-compose-dassie.yml +14 -6
  452. data/docker-compose-koppie.yml +18 -10
  453. data/docker-compose-sirenia.yml +20 -10
  454. data/documentation/copy_permalink.md +29 -0
  455. data/documentation/developing-your-hyrax-based-app.md +2 -2
  456. data/documentation/file-ingest-characterization.md +763 -0
  457. data/documentation/flexible_metadata.md +113 -0
  458. data/documentation/forms/field_behaviors.md +297 -0
  459. data/documentation/redirects.md +428 -0
  460. data/hyrax.gemspec +7 -2
  461. data/lib/freyja/metadata_adapter.rb +1 -1
  462. data/lib/freyja/persister.rb +25 -1
  463. data/lib/generators/hyrax/collection_resource/collection_resource_generator.rb +2 -2
  464. data/lib/generators/hyrax/collection_resource/templates/collection.rb.erb +5 -1
  465. data/lib/generators/hyrax/collection_resource/templates/collection_form.rb.erb +5 -1
  466. data/lib/generators/hyrax/collection_resource/templates/collection_indexer.rb.erb +6 -1
  467. data/lib/generators/hyrax/iiif_viewer/USAGE +22 -0
  468. data/lib/generators/hyrax/iiif_viewer/iiif_viewer_generator.rb +49 -0
  469. data/lib/generators/hyrax/iiif_viewer/templates/_clover.html.erb +7 -0
  470. data/lib/generators/hyrax/iiif_viewer/templates/clover/clover.css +3328 -0
  471. data/lib/generators/hyrax/iiif_viewer/templates/clover/clover.html +16 -0
  472. data/lib/generators/hyrax/iiif_viewer/templates/clover/clover.js +237 -0
  473. data/lib/generators/hyrax/install_generator.rb +25 -1
  474. data/lib/generators/hyrax/riiif_generator.rb +1 -1
  475. data/lib/generators/hyrax/templates/app/views/blacklight_dynamic_sitemap/sitemap/show.xml.builder +22 -0
  476. data/lib/generators/hyrax/templates/config/clamav.rb +2 -0
  477. data/lib/generators/hyrax/templates/config/initializers/riiif.rb +4 -80
  478. data/lib/generators/hyrax/templates/db/migrate/20240606205215_create_hyrax_flexible_schemas.rb.erb +9 -0
  479. data/lib/generators/hyrax/templates/db/migrate/20240606205216_add_contexts_to_hyrax_flexible_schemas.rb.erb +5 -0
  480. data/lib/generators/hyrax/templates/db/migrate/20260430000001_create_hyrax_redirect_paths.rb.erb +22 -0
  481. data/lib/generators/hyrax/templates/db/migrate/20260521003627_add_additional_redirect_info.rb.erb +39 -0
  482. data/lib/generators/hyrax/templates/package.json +1 -1
  483. data/lib/generators/hyrax/templates/uv.html +60 -82
  484. data/lib/generators/hyrax/work/templates/indexer.rb.erb +1 -1
  485. data/lib/generators/hyrax/work/templates/model.rb.erb +5 -1
  486. data/lib/generators/hyrax/work_resource/templates/form.rb.erb +5 -2
  487. data/lib/generators/hyrax/work_resource/templates/indexer.rb.erb +6 -2
  488. data/lib/generators/hyrax/work_resource/templates/work.rb.erb +5 -2
  489. data/lib/generators/hyrax/work_resource/work_resource_generator.rb +1 -0
  490. data/lib/hyrax/active_fedora_dummy_model.rb +6 -0
  491. data/lib/hyrax/configuration.rb +197 -3
  492. data/lib/hyrax/deprecation.rb +31 -0
  493. data/lib/hyrax/engine.rb +2 -0
  494. data/lib/hyrax/form_fields.rb +17 -5
  495. data/lib/hyrax/indexer.rb +31 -2
  496. data/lib/hyrax/resource_sync/resource_list_writer.rb +3 -0
  497. data/lib/hyrax/schema.rb +15 -4
  498. data/lib/hyrax/specs/shared_specs/factories/administrative_sets.rb +12 -0
  499. data/lib/hyrax/specs/shared_specs/factories/hyrax_embargo.rb +1 -1
  500. data/lib/hyrax/specs/shared_specs/factories/hyrax_file_set.rb +13 -0
  501. data/lib/hyrax/specs/shared_specs/factories/hyrax_lease.rb +5 -1
  502. data/lib/hyrax/specs/shared_specs/factories/hyrax_work.rb +14 -0
  503. data/lib/hyrax/specs/shared_specs/simple_work.rb +41 -0
  504. data/lib/hyrax/specs/shared_specs.rb +1 -0
  505. data/lib/hyrax/transactions/collection_create.rb +2 -1
  506. data/lib/hyrax/transactions/collection_destroy.rb +1 -0
  507. data/lib/hyrax/transactions/collection_update.rb +2 -1
  508. data/lib/hyrax/transactions/container.rb +28 -0
  509. data/lib/hyrax/transactions/steps/apply_permission_template_on_update.rb +65 -0
  510. data/lib/hyrax/transactions/steps/apply_workflow_on_admin_set_change.rb +97 -0
  511. data/lib/hyrax/transactions/steps/ensure_admin_set.rb +1 -1
  512. data/lib/hyrax/transactions/steps/remove_redirect_paths.rb +35 -0
  513. data/lib/hyrax/transactions/steps/save.rb +10 -0
  514. data/lib/hyrax/transactions/steps/set_default_admin_set.rb +1 -1
  515. data/lib/hyrax/transactions/steps/sync_redirect_paths.rb +141 -0
  516. data/lib/hyrax/transactions/work_create.rb +2 -1
  517. data/lib/hyrax/transactions/work_destroy.rb +1 -0
  518. data/lib/hyrax/transactions/work_update.rb +4 -1
  519. data/lib/hyrax/version.rb +1 -1
  520. data/lib/hyrax.rb +61 -0
  521. data/lib/tasks/m3_profile_cleanup.rake +35 -0
  522. data/template.rb +4 -1
  523. metadata +313 -19
  524. data/.dassie/public/robots.txt +0 -1
  525. data/.koppie/public/robots.txt +0 -1
  526. data/app/forms/concerns/hyrax/basic_metadata_form_fields_behavior.rb +0 -39
  527. data/app/views/catalog/_thumbnail_list_collection.html.erb +0 -4
@@ -308,6 +308,19 @@ module Hyrax
308
308
  file_set_model.constantize
309
309
  end
310
310
 
311
+ def valkyrie_file_set_class
312
+ file_set_class.ancestors.include?(ActiveFedora::Base) ? Hyrax::FileSet : file_set_class
313
+ end
314
+
315
+ ##
316
+ # @!attribute [rw] file_set_include_metadata
317
+ # @return [Boolean] whether to include static metadata for file_sets
318
+ attr_writer :file_set_include_metadata
319
+ def file_set_include_metadata
320
+ @file_set_include_metadata ||= disable_include_metadata ? false : true
321
+ end
322
+ alias file_set_include_metadata? file_set_include_metadata
323
+
311
324
  ##
312
325
  # @!attribute [rw] file_set_file_service
313
326
  # @return [Class] implementer of {Hyrax::FileSetFileService}
@@ -321,6 +334,105 @@ module Hyrax
321
334
  @fixity_service ||= Hyrax::Fixity::ActiveFedoraFixityService
322
335
  end
323
336
 
337
+ # This value determines whether to use flexible metadata / m3 profile ui or not
338
+ attr_writer :flexible
339
+ def flexible
340
+ @flexible ||=
341
+ ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYRAX_FLEXIBLE', false))
342
+ end
343
+ alias flexible? flexible
344
+
345
+ # See documentation/redirects.md for the redirects feature.
346
+ attr_writer :redirects_enabled
347
+ def redirects_enabled?
348
+ return @redirects_enabled if defined?(@redirects_enabled) && !@redirects_enabled.nil?
349
+ @redirects_enabled = ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYRAX_REDIRECTS_ENABLED', false))
350
+ end
351
+ alias redirects_enabled redirects_enabled?
352
+
353
+ # @return [Boolean] true when both feature gates are open. Single
354
+ # source of truth for "is the redirects feature actively in use
355
+ # right now?". Short-circuits on the config so the Flipflop call
356
+ # is safe (the :redirects feature is only registered when the
357
+ # config is on; calling Flipflop.redirects? otherwise raises).
358
+ def redirects_active?
359
+ redirects_enabled? && Flipflop.redirects?
360
+ end
361
+
362
+ # Path prefixes that may not be claimed as redirect aliases (Hyrax::RedirectValidator
363
+ # rejects any redirect path equal to or starting with one of these). Defaults to the
364
+ # routes Hyrax itself reserves; adopters can extend the list to cover host-app routes:
365
+ #
366
+ # Hyrax.config do |config|
367
+ # config.reserved_redirect_prefixes += ['/single_signon', '/some_host_route']
368
+ # end
369
+ #
370
+ # See documentation/redirects.md for the redirects feature.
371
+ attr_writer :reserved_redirect_prefixes
372
+ def reserved_redirect_prefixes # rubocop:disable Metrics/MethodLength
373
+ @reserved_redirect_prefixes ||= %w[
374
+ /.well-known
375
+ /admin
376
+ /api
377
+ /assets
378
+ /batch_edits
379
+ /batch_uploads
380
+ /capabilitylist
381
+ /catalog
382
+ /changelist
383
+ /collections
384
+ /concern
385
+ /content_blocks
386
+ /dashboard
387
+ /downloads
388
+ /embargoes
389
+ /featured_works
390
+ /files
391
+ /leases
392
+ /notifications
393
+ /pages
394
+ /proxies
395
+ /rails
396
+ /resourcelist
397
+ /uploads
398
+ /users
399
+ ]
400
+ end
401
+
402
+ # This value determines whether to use m3 flexible metadata for core classes or not
403
+ attr_writer :flexible_classes
404
+ def flexible_classes
405
+ flexible_env = ENV.fetch('HYRAX_FLEXIBLE_CLASSES', nil)
406
+ flexible_env = flexible_env.split(',').map(&:strip) if flexible_env
407
+ flexible_env ||= if flexible?
408
+ [
409
+ Hyrax.config.collection_model,
410
+ Hyrax.config.file_set_model,
411
+ Hyrax.config.admin_set_model
412
+ ]
413
+ else
414
+ []
415
+ end
416
+ @flexible_classes ||= flexible_env
417
+ end
418
+
419
+ def admin_set_flexible?
420
+ flexible_classes.include?(admin_set_model) || (admin_set_class.respond_to?(:flexible?) && admin_set_class.flexible?)
421
+ end
422
+
423
+ def collection_flexible?
424
+ flexible_classes.include?(collection_model) || (collection_class.respond_to?(:flexible?) && collection_class.flexible?)
425
+ end
426
+
427
+ def file_set_flexible?
428
+ flexible_classes.include?(file_set_model) || (file_set_class.respond_to?(:flexible?) && file_set_class.flexible?)
429
+ end
430
+
431
+ attr_writer :disable_include_metadata
432
+ def disable_include_metadata
433
+ @disable_include_metadata ||= ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYRAX_DISABLE_INCLUDE_METADATA', false))
434
+ end
435
+
324
436
  # This value determines whether to use load the Freyja adapter in dassie
325
437
  attr_writer :valkyrie_transition
326
438
  attr_reader :valkyrie_transition
@@ -333,6 +445,16 @@ module Hyrax
333
445
  def max_days_between_fixity_checks
334
446
  @max_days_between_fixity_checks ||= 7
335
447
  end
448
+
449
+ attr_writer :solr_rows_per_request
450
+ def solr_rows_per_request
451
+ @solr_rows_per_request ||= 1_000
452
+ end
453
+
454
+ attr_writer :solr_max_results
455
+ def solr_max_results
456
+ @solr_max_results ||= 10_000
457
+ end
336
458
  # @!endgroup
337
459
  # @!group Groups
338
460
 
@@ -402,6 +524,8 @@ module Hyrax
402
524
  attr_writer :iiif_info_url_builder
403
525
  attr_writer :iiif_metadata_fields
404
526
  attr_writer :iiif_manifest_cache_duration
527
+ attr_writer :iiif_manifest_factory
528
+ attr_writer :iiif_av_viewer
405
529
  attr_writer :rendering_predicate
406
530
 
407
531
  # Enable IIIF image service. This is required to use the
@@ -469,6 +593,25 @@ module Hyrax
469
593
  @iiif_manifest_cache_duration ||= 30.days.to_i
470
594
  end
471
595
 
596
+ ##
597
+ # Factory class for generating IIIF manifests
598
+ #
599
+ # @see Hyrax::ManifestBuilderService
600
+ #
601
+ # @return [Class]
602
+ def iiif_manifest_factory
603
+ @iiif_manifest_factory ||= ::IIIFManifest::ManifestFactory
604
+ end
605
+
606
+ ##
607
+ # A symbol that represents the viewer to render for AV items.
608
+ # Defaults to :universal_viewer but hopefully we can develop more options
609
+ #
610
+ # @return [:symbol] viewer partial name
611
+ def iiif_av_viewer
612
+ @iiif_av_viewer ||= :universal_viewer
613
+ end
614
+
472
615
  ##
473
616
  # Set predicate for rendering to dc:hasFormat as defined in
474
617
  # IIIF Presentation API context: http://iiif.io/api/presentation/2/context.json
@@ -872,6 +1015,35 @@ module Hyrax
872
1015
  @admin_set_predicate ||= ::RDF::Vocab::DC.isPartOf
873
1016
  end
874
1017
 
1018
+ ##
1019
+ # @!attribute [rw] work_include_metadata
1020
+ # @return [Boolean] whether to include static metadata for works
1021
+ attr_writer :work_include_metadata
1022
+ def work_include_metadata
1023
+ @work_include_metadata ||= disable_include_metadata ? false : true
1024
+ end
1025
+ alias work_include_metadata? work_include_metadata
1026
+
1027
+ ##
1028
+ # @!attribute [rw] work_default_metadata
1029
+ # this is deprecated and will be removed in a future release
1030
+ # @return [Boolean] whether to include static metadata for works
1031
+ attr_writer :work_default_metadata
1032
+ def work_default_metadata
1033
+ return @work_default_metadata if @work_default_metadata
1034
+ @work_default_metadata ||= flexible? ? false : true
1035
+ if @work_default_metadata
1036
+ warning = <<-WARN
1037
+ globally including `Hyrax::Schema(:core_metadata)` at the work level is deprecated.
1038
+ Add `include Hyrax::Schema(:core_metadata)` to your individual work classes or set
1039
+ up flexible metadata, then set `work_default_metadata = false` in config/hyrax.rb to remove this warning.
1040
+ WARN
1041
+ Deprecation.warn warning
1042
+ end
1043
+ @work_default_metadata
1044
+ end
1045
+ alias work_default_metadata? work_default_metadata
1046
+
875
1047
  attr_writer :work_requires_files
876
1048
  def work_requires_files?
877
1049
  return true if @work_requires_files.nil?
@@ -920,6 +1092,15 @@ module Hyrax
920
1092
  collection_model.safe_constantize
921
1093
  end
922
1094
 
1095
+ ##
1096
+ # @!attribute [rw] collection_include_metadata
1097
+ # @return [Boolean] whether to include static metadata for collections
1098
+ attr_writer :collection_include_metadata
1099
+ def collection_include_metadata
1100
+ @collection_include_metadata ||= disable_include_metadata ? false : true
1101
+ end
1102
+ alias collection_include_metadata? collection_include_metadata
1103
+
923
1104
  ##
924
1105
  # @api private
925
1106
  #
@@ -964,6 +1145,15 @@ module Hyrax
964
1145
  Hyrax::AdministrativeSet
965
1146
  end
966
1147
 
1148
+ ##
1149
+ # @!attribute [rw] admin_set_include_metadata
1150
+ # @return [Boolean] whether to include static metadata for admin_sets
1151
+ attr_writer :admin_set_include_metadata
1152
+ def admin_set_include_metadata
1153
+ @admin_set_include_metadata ||= disable_include_metadata ? false : true
1154
+ end
1155
+ alias admin_set_include_metadata? admin_set_include_metadata
1156
+
967
1157
  ##
968
1158
  # @return [String] the default admin set id
969
1159
  def default_admin_set_id
@@ -1170,7 +1360,9 @@ module Hyrax
1170
1360
  @visibility_map ||= Hyrax::VisibilityMap.instance
1171
1361
  end
1172
1362
 
1173
- attr_writer :simple_schema_loader_config_search_paths
1363
+ attr_writer :schema_loader_config_search_paths
1364
+ alias simple_schema_loader_config_search_paths= schema_loader_config_search_paths=
1365
+ alias m3_schema_loader_config_search_paths= schema_loader_config_search_paths=
1174
1366
  # A configuration for modifying the SimpleSchemaLoader#config_search_paths
1175
1367
  # which will allow gems to add their own metadata yaml files and easily keep
1176
1368
  # them within the gem.
@@ -1184,9 +1376,11 @@ module Hyrax
1184
1376
  #
1185
1377
  # Hyrax.config.simple_schema_loader_config_search_paths
1186
1378
  # => [#<Pathname:/app/samvera>, #<Pathname:/app/samvera/hyrax-webapp>, #<Pathname:/app/samvera/hyrax-webapp/gems/hyrax>]
1187
- def simple_schema_loader_config_search_paths
1188
- @simple_schema_loader_config_search_paths ||= [Rails.root, Hyrax::Engine.root]
1379
+ def schema_loader_config_search_paths
1380
+ @schema_loader_config_search_paths ||= [Rails.root, Hyrax::Engine.root]
1189
1381
  end
1382
+ alias simple_schema_loader_config_search_paths schema_loader_config_search_paths
1383
+ alias m3_schema_loader_config_search_paths schema_loader_config_search_paths
1190
1384
 
1191
1385
  private
1192
1386
 
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyrax
4
+ # Provides version-specific deprecators for Hyrax
5
+ #
6
+ # @example Standard usage for next major version
7
+ # Hyrax.deprecator.warn("This will be removed in Hyrax 6.0")
8
+ #
9
+ # @example Specific version targeting
10
+ # Hyrax.deprecator(7).warn("This will be removed in Hyrax 7.0")
11
+ #
12
+ # @example Marking technical debt
13
+ # Hyrax.deprecator(4).warn("This should have been removed in Hyrax 4.0")
14
+ def self.deprecator(major_version = nil)
15
+ @deprecators ||= {}
16
+
17
+ # Default to next major version if not specified
18
+ major_version ||= 6 # Update this when 6.0 is released
19
+
20
+ @deprecators[major_version] ||= begin
21
+ dep = ActiveSupport::Deprecation.new("#{major_version}.0", "Hyrax")
22
+ dep.behavior = Rails.application.config.active_support.deprecation
23
+ dep
24
+ end
25
+ end
26
+
27
+ # Alias for backwards compatibility
28
+ def self.deprecation
29
+ deprecator
30
+ end
31
+ end
data/lib/hyrax/engine.rb CHANGED
@@ -5,6 +5,7 @@ module Hyrax
5
5
 
6
6
  require 'almond-rails'
7
7
  require 'awesome_nested_set'
8
+ require 'blacklight_dynamic_sitemap'
8
9
  require 'breadcrumbs_on_rails'
9
10
  require 'clipboard/rails'
10
11
  require 'draper'
@@ -21,6 +22,7 @@ module Hyrax
21
22
  require 'valkyrie'
22
23
  require 'cancancan'
23
24
  require 'blacklight'
25
+ require 'json_schemer'
24
26
 
25
27
  require 'hydra/derivatives'
26
28
  require 'hyrax/active_fedora_dummy_model'
@@ -16,7 +16,7 @@ module Hyrax
16
16
  #
17
17
  # @see .FormFields
18
18
  class FormFields < Module
19
- attr_reader :name
19
+ attr_reader :name, :version, :contexts
20
20
 
21
21
  ##
22
22
  # @api private
@@ -25,15 +25,17 @@ module Hyrax
25
25
  # @param [#form_definitions_for] definition_loader
26
26
  #
27
27
  # @note use Hyrax::FormFields(:my_schema) instead
28
- def initialize(schema_name, definition_loader: SimpleSchemaLoader.new)
29
- @name = schema_name
28
+ def initialize(schema_name, definition_loader: SimpleSchemaLoader.new, version: 1, contexts: nil)
29
+ @contexts = contexts
30
30
  @definition_loader = definition_loader
31
+ @name = schema_name
32
+ @version = version
31
33
  end
32
34
 
33
35
  ##
34
36
  # @return [Hash{Symbol => Hash{Symbol => Object}}]
35
37
  def form_field_definitions
36
- @definition_loader.form_definitions_for(schema: name)
38
+ @definition_loader.form_definitions_for(schema: name, version:, contexts:)
37
39
  end
38
40
 
39
41
  ##
@@ -44,8 +46,10 @@ module Hyrax
44
46
 
45
47
  private
46
48
 
49
+ # rubocop:disable Metrics/MethodLength
47
50
  def included(descendant)
48
51
  super
52
+ return if @definition_loader.is_a?(Hyrax::M3SchemaLoader)
49
53
  form_field_definitions.each do |field_name, options|
50
54
  descendant.property field_name.to_sym, options.merge(display: options.fetch(:display, true), default: [])
51
55
  descendant.validates field_name.to_sym, presence: true if options.fetch(:required, false)
@@ -54,7 +58,15 @@ module Hyrax
54
58
  schema_name = name.to_s.camelcase
55
59
  behavior = "#{schema_name}FormFieldsBehavior".safe_constantize ||
56
60
  "Hyrax::#{schema_name}FormFieldsBehavior".safe_constantize
57
- descendant.include(behavior) if behavior
61
+ return unless behavior
62
+ warning = <<-WARN
63
+ Auto including a FormFieldsBehavior class based on name of the schema is depreciated.
64
+ We are removing it from Hyrax as it has proven hard to debug or trace.
65
+ Please include form field behaviors in your form classes directly.
66
+ WARN
67
+ Deprecation.warn warning
68
+ descendant.include(behavior)
58
69
  end
70
+ # rubocop:enable Metrics/MethodLength
59
71
  end
60
72
  end
data/lib/hyrax/indexer.rb CHANGED
@@ -18,9 +18,15 @@ module Hyrax
18
18
  # include Hyrax::Indexer(:core_metadata)
19
19
  # end
20
20
  #
21
+ # @example building a module as a mixin with flexible metadata
22
+ #
23
+ # class MyIndexer < Hyrax::Indexers::ResourceIndexer
24
+ # include Hyrax::Indexer(:MyResource, index_loader: M3SchemaLoader.new)
25
+ # end
26
+ #
21
27
  # @since 3.0.0
22
28
  def self.Indexer(schema_name, index_loader: SimpleSchemaLoader.new)
23
- Indexer.new(index_loader.index_rules_for(schema: schema_name))
29
+ Indexer.new(schema_name: schema_name, index_loader: index_loader)
24
30
  end
25
31
 
26
32
  ##
@@ -28,11 +34,34 @@ module Hyrax
28
34
  #
29
35
  # @see .Indexer
30
36
  class Indexer < Module
37
+ attr_accessor :schema_name, :index_loader
38
+
31
39
  ##
32
40
  # @param [Hash{Symbol => Symbol}] rules
33
- def initialize(rules)
41
+ # @param [Symbol] schema_name
42
+ # @param [#index_rule_for] index_loader
43
+ #
44
+ # @return [Module]
45
+ def initialize(rules = nil, schema_name: nil, index_loader: nil)
46
+ super()
47
+ @schema_name = schema_name
48
+ @index_loader = index_loader
49
+ @rules = rules
50
+ define_solr_method(schema_name:, index_loader:)
51
+ end
52
+
53
+ def define_solr_method(schema_name:, index_loader:) # rubocop:disable Metrics/MethodLength
34
54
  define_method :to_solr do |*args|
35
55
  super(*args).tap do |document|
56
+ schema_args = if index_loader.is_a?(Hyrax::M3SchemaLoader)
57
+ document['schema_version_ssi'] = resource.schema_version
58
+ document['contexts_ssim'] = resource.contexts
59
+ { schema: resource.class.name, version: resource.schema_version, contexts: resource.contexts }
60
+ else
61
+ { schema: schema_name }
62
+ end
63
+ rules = @rules || index_loader.index_rules_for(**schema_args)
64
+
36
65
  rules.each do |index_key, method|
37
66
  document[index_key] = resource.try(method)
38
67
  end
@@ -6,9 +6,12 @@ module Hyrax
6
6
  # items, so if we require more than that, we must have multiple Resource
7
7
  # lists and add a Resource List Index to point to all of them.
8
8
  class ResourceListWriter
9
+ Hyrax.deprecator.deprecate_methods(self, write: "Use BlacklightDynamicSitemap instead.")
9
10
  attr_reader :resource_host, :capability_list_url
10
11
 
11
12
  def initialize(resource_host:, capability_list_url:)
13
+ Hyrax.deprecator.warn("Hyrax::ResourceSync::ResourceListWriter is deprecated. Use BlacklightDynamicSitemap instead.")
14
+
12
15
  @resource_host = resource_host
13
16
  @capability_list_url = capability_list_url
14
17
  end
data/lib/hyrax/schema.rb CHANGED
@@ -56,7 +56,16 @@ module Hyrax
56
56
  ##
57
57
  # @!attribute [r] name
58
58
  # @return [Symbol]
59
- attr_reader :name
59
+ attr_reader :name, :version, :contexts
60
+
61
+ ##
62
+ def self.m3_schema_loader
63
+ M3SchemaLoader.new
64
+ end
65
+
66
+ def self.simple_schema_loader
67
+ SimpleSchemaLoader.new
68
+ end
60
69
 
61
70
  ##
62
71
  # @param [Symbol] schema_name
@@ -64,15 +73,17 @@ module Hyrax
64
73
  # @note use Hyrax::Schema(:my_schema) instead
65
74
  #
66
75
  # @api private
67
- def initialize(schema_name, schema_loader: SimpleSchemaLoader.new)
68
- @name = schema_name
76
+ def initialize(schema_name, schema_loader: Hyrax::Schema.simple_schema_loader, schema_version: nil, contexts: [])
77
+ @name = schema_name.to_s
78
+ @version = schema_version || schema_loader.current_version
69
79
  @schema_loader = schema_loader
80
+ @contexts = contexts
70
81
  end
71
82
 
72
83
  ##
73
84
  # @return [Hash{Symbol => Dry::Types::Type}]
74
85
  def attributes
75
- @schema_loader.attributes_for(schema: name)
86
+ @schema_loader.attributes_for(schema: name, version:, contexts:)
76
87
  end
77
88
 
78
89
  ##
@@ -15,6 +15,7 @@ FactoryBot.define do
15
15
 
16
16
  transient do
17
17
  with_permission_template { false }
18
+ with_active_workflow { false }
18
19
  user { FactoryBot.create(:user) }
19
20
  access_grants { [] }
20
21
  with_index { true }
@@ -34,6 +35,12 @@ FactoryBot.define do
34
35
 
35
36
  if evaluator.with_permission_template
36
37
  template = Hyrax::PermissionTemplate.find_or_create_by(source_id: admin_set.id.to_s)
38
+
39
+ if evaluator.with_active_workflow
40
+ workflow = create(:workflow, active: true, permission_template: template)
41
+ create(:workflow_action, workflow: workflow) # Need to create a single action that can be taken
42
+ end
43
+
37
44
  evaluator.access_grants.each do |grant|
38
45
  Hyrax::PermissionTemplateAccess.find_or_create_by(permission_template_id: template.id,
39
46
  agent_type: grant[:agent_type],
@@ -59,6 +66,11 @@ FactoryBot.define do
59
66
  end
60
67
  end
61
68
 
69
+ trait :with_active_workflow do
70
+ with_active_workflow { true }
71
+ with_permission_template
72
+ end
73
+
62
74
  factory :invalid_hyrax_admin_set, class: 'Hyrax::AdministrativeSet' do
63
75
  # Title is required. Without title, the admin set is invalid.
64
76
  end
@@ -16,7 +16,7 @@ FactoryBot.define do
16
16
  end
17
17
 
18
18
  trait :expired do
19
- embargo_release_date { (Time.zone.today - 1).to_datetime }
19
+ embargo_release_date { (Time.zone.today).to_datetime }
20
20
  end
21
21
  end
22
22
  end
@@ -77,6 +77,19 @@ FactoryBot.define do
77
77
  end
78
78
  end
79
79
 
80
+ trait :with_expiring_enforced_lease do
81
+ after(:build) do |fs, _evaluator|
82
+ fs.lease = FactoryBot.valkyrie_create(:hyrax_lease, :expiring)
83
+ end
84
+
85
+ after(:create) do |fs, _evaluator|
86
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_return(10.days.ago)
87
+ Hyrax::LeaseManager.new(resource: fs).apply
88
+ fs.permission_manager.acl.save
89
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_call_original
90
+ end
91
+ end
92
+
80
93
  trait :with_expired_enforced_lease do
81
94
  after(:build) do |fs, _evaluator|
82
95
  fs.lease = FactoryBot.valkyrie_create(:hyrax_lease, :expired)
@@ -15,8 +15,12 @@ FactoryBot.define do
15
15
  saved_instance
16
16
  end
17
17
 
18
+ trait :expiring do
19
+ lease_expiration_date { (Time.zone.today + 1).to_datetime }
20
+ end
21
+
18
22
  trait :expired do
19
- lease_expiration_date { (Time.zone.today - 2).to_datetime }
23
+ lease_expiration_date { (Time.zone.today - 1.day).to_datetime }
20
24
  end
21
25
  end
22
26
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  ##
4
4
  # Use this factory for generic Hyrax/HydraWorks Works in valkyrie.
5
+ # rubocop:disable Metrics/BlockLength
5
6
  FactoryBot.define do
6
7
  factory :hyrax_work, class: 'Hyrax::Test::SimpleWork' do
7
8
  trait :under_embargo do
@@ -35,6 +36,19 @@ FactoryBot.define do
35
36
  end
36
37
  end
37
38
 
39
+ trait :with_expiring_enforced_lease do
40
+ after(:build) do |work, _evaluator|
41
+ work.lease = FactoryBot.valkyrie_create(:hyrax_lease, :expiring)
42
+ end
43
+
44
+ after(:create) do |work, _evaluator|
45
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_return(10.days.ago)
46
+ Hyrax::LeaseManager.new(resource: work).apply
47
+ work.permission_manager.acl.save
48
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_call_original
49
+ end
50
+ end
51
+
38
52
  trait :with_expired_enforced_lease do
39
53
  after(:build) do |work, _evaluator|
40
54
  work.lease = FactoryBot.valkyrie_create(:hyrax_lease, :expired)
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyrax
4
+ module Test
5
+ ##
6
+ # A generic PCDM Work, with only Hyrax "core" (required) metadata.
7
+ #
8
+ # @example building with FactoryBot
9
+ # work = FactoryBot.build(:hyrax_work, :public, title: ['Comet in Moominland'])
10
+ #
11
+ # @example creating with FactoryBot
12
+ # work = FactoryBot.valkyrie_create(:hyrax_work, :public, title: ['Comet in Moominland'])
13
+ class SimpleWork < Hyrax::Work
14
+ if Hyrax.config.work_include_metadata?
15
+ include Hyrax::Schema(:core_metadata)
16
+ include Hyrax::Schema(:basic_metadata)
17
+ include Hyrax::Schema(:monograph)
18
+ end
19
+ end
20
+
21
+ class SimpleWorkLegacy < ActiveFedora::Base
22
+ include WorkBehavior
23
+ include CoreMetadata
24
+ end
25
+
26
+ class SimpleWorkSearchBuilder < Hyrax::WorkSearchBuilder
27
+ def work_types
28
+ [Hyrax::Test::SimpleWorkLegacy]
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ if defined?(Wings)
35
+ Wings::ModelRegistry.register(Hyrax::Test::SimpleWork, Hyrax::Test::SimpleWorkLegacy)
36
+ elsif defined?(ActiveFedora) && ENV.key?('FCREPO_BASE_PATH') && Hyrax.config.valkyrie_transition
37
+ # We do not want to add the lazy migration for ActiveFedora to Valkyrie when we don't have a valid
38
+ # Fedora end-point. Now what is the best way to see if we have a valid and configured fedora
39
+ # connection?
40
+ Hyrax::ValkyrieLazyMigration.migrating(Hyrax::Test::SimpleWork, from: Hyrax::Test::SimpleWorkLegacy)
41
+ end
@@ -4,3 +4,4 @@ require 'hyrax/specs/shared_specs/indexers'
4
4
  require 'hyrax/specs/shared_specs/metadata'
5
5
  require 'hyrax/specs/shared_specs/hydra_works'
6
6
  require 'hyrax/specs/shared_specs/workflow_method'
7
+ require 'hyrax/specs/shared_specs/simple_work'
@@ -13,7 +13,8 @@ module Hyrax
13
13
  'change_set.add_to_collections',
14
14
  'change_set.apply',
15
15
  'collection_resource.apply_collection_type_permissions',
16
- 'collection_resource.save_acl'].freeze
16
+ 'collection_resource.save_acl',
17
+ 'collection_resource.sync_redirect_paths'].freeze
17
18
 
18
19
  ##
19
20
  # @see Hyrax::Transactions::Transaction
@@ -11,6 +11,7 @@ module Hyrax
11
11
  # TODO: Add step that checks if collection is empty for collections of types that require it
12
12
  DEFAULT_STEPS = ['collection_resource.delete_acl',
13
13
  'collection_resource.remove_from_membership',
14
+ 'collection_resource.remove_redirect_paths',
14
15
  'collection_resource.delete',
15
16
  'collection_resource.delete_permission_template'].freeze.freeze
16
17
 
@@ -11,7 +11,8 @@ module Hyrax
11
11
  DEFAULT_STEPS = ['change_set.apply',
12
12
  'collection_resource.save_collection_banner',
13
13
  'collection_resource.save_collection_logo',
14
- 'collection_resource.save_acl'].freeze
14
+ 'collection_resource.save_acl',
15
+ 'collection_resource.sync_redirect_paths'].freeze
15
16
 
16
17
  ##
17
18
  # @see Hyrax::Transactions::Transaction