hyrax 5.1.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 (561) hide show
  1. checksums.yaml +4 -4
  2. data/.dassie/.env +5 -1
  3. data/.dassie/Gemfile +5 -3
  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/application.rb +1 -1
  25. data/.dassie/config/browse_everything_providers.yml +1 -1
  26. data/.dassie/config/bulkrax_api.yml +86 -0
  27. data/.dassie/config/initializers/bulkrax.rb +92 -0
  28. data/.dassie/config/initializers/clamav.rb +2 -0
  29. data/.dassie/config/initializers/devise.rb +1 -0
  30. data/.dassie/config/initializers/hyrax.rb +7 -1
  31. data/.dassie/config/initializers/riiif.rb +4 -80
  32. data/.dassie/config/initializers/wings.rb +1 -1
  33. data/.dassie/config/metadata_profiles/m3_profile.yaml +929 -0
  34. data/.dassie/config/puma.rb +4 -2
  35. data/.dassie/config/routes.rb +7 -0
  36. data/.dassie/config/sidekiq.yml +17 -0
  37. data/.dassie/config/uv/uv.html +63 -81
  38. data/.dassie/db/migrate/20240606205215_create_hyrax_flexible_schemas.rb +9 -0
  39. data/.dassie/db/migrate/20240606205216_add_contexts_to_hyrax_flexible_schemas.rb +5 -0
  40. data/.dassie/db/migrate/20250826142438_create_bulkrax_importers.bulkrax.rb +19 -0
  41. data/.dassie/db/migrate/20250826142439_create_bulkrax_importer_runs.bulkrax.rb +17 -0
  42. data/.dassie/db/migrate/20250826142440_create_bulkrax_entries.bulkrax.rb +17 -0
  43. data/.dassie/db/migrate/20250826142441_add_status_to_entry.bulkrax.rb +10 -0
  44. data/.dassie/db/migrate/20250826142442_add_collections_to_importer_runs.bulkrax.rb +7 -0
  45. data/.dassie/db/migrate/20250826142443_change_collection_ids_on_entries.bulkrax.rb +6 -0
  46. data/.dassie/db/migrate/20250826142444_create_bulkrax_exporters.bulkrax.rb +20 -0
  47. data/.dassie/db/migrate/20250826142445_create_bulkrax_exporter_runs.bulkrax.rb +15 -0
  48. data/.dassie/db/migrate/20250826142446_change_importer_and_exporter_to_polymorphic.bulkrax.rb +19 -0
  49. data/.dassie/db/migrate/20250826142447_add_total_collection_records_to_importer_runs.bulkrax.rb +6 -0
  50. data/.dassie/db/migrate/20250826142448_add_children_to_importer_runs.bulkrax.rb +7 -0
  51. data/.dassie/db/migrate/20250826142449_change_total_records_to_total_work_entries.bulkrax.rb +7 -0
  52. data/.dassie/db/migrate/20250826142450_change_entry_last_error.bulkrax.rb +20 -0
  53. data/.dassie/db/migrate/20250826142451_add_validate_only_to_bulkrax_importers.bulkrax.rb +6 -0
  54. data/.dassie/db/migrate/20250826142452_add_status_to_importers.bulkrax.rb +10 -0
  55. data/.dassie/db/migrate/20250826142453_remove_foreign_key_from_bulkrax_entries.bulkrax.rb +6 -0
  56. data/.dassie/db/migrate/20250826142454_add_status_to_exporters.bulkrax.rb +8 -0
  57. data/.dassie/db/migrate/20250826142455_add_invalid_record_to_importer_run.bulkrax.rb +6 -0
  58. data/.dassie/db/migrate/20250826142456_create_bulkrax_statuses.bulkrax.rb +19 -0
  59. data/.dassie/db/migrate/20250826142457_move_to_statuses.bulkrax.rb +31 -0
  60. data/.dassie/db/migrate/20250826142458_add_date_filter_and_status_to_bulkrax_exporters.bulkrax.rb +8 -0
  61. data/.dassie/db/migrate/20250826142459_add_workflow_status_to_bulkrax_exporter.bulkrax.rb +6 -0
  62. data/.dassie/db/migrate/20250826142460_remove_unused_last_error.bulkrax.rb +8 -0
  63. data/.dassie/db/migrate/20250826142461_increase_text_sizes.bulkrax.rb +13 -0
  64. data/.dassie/db/migrate/20250826142462_change_bulkrax_statuses_error_message_column_type_to_text.bulkrax.rb +6 -0
  65. data/.dassie/db/migrate/20250826142463_rename_children_counters_to_relationships.bulkrax.rb +7 -0
  66. data/.dassie/db/migrate/20250826142464_add_file_set_counters_to_importer_runs.bulkrax.rb +8 -0
  67. data/.dassie/db/migrate/20250826142465_add_import_attempts_to_entries.bulkrax.rb +6 -0
  68. data/.dassie/db/migrate/20250826142466_add_work_counters_to_importer_runs.bulkrax.rb +7 -0
  69. data/.dassie/db/migrate/20250826142467_create_bulkrax_pending_relationships.bulkrax.rb +14 -0
  70. data/.dassie/db/migrate/20250826142468_add_order_to_bulkrax_pending_relationships.bulkrax.rb +6 -0
  71. data/.dassie/db/migrate/20250826142469_add_include_thumbnails_to_bulkrax_exporters.bulkrax.rb +6 -0
  72. data/.dassie/db/migrate/20250826142470_add_generated_metadata_to_bulkrax_exporters.bulkrax.rb +6 -0
  73. data/.dassie/db/migrate/20250826142471_rename_bulkrax_importer_run_to_importer_run.bulkrax.rb +18 -0
  74. data/.dassie/db/migrate/20250826142472_add_indices_to_bulkrax.bulkrax.rb +26 -0
  75. data/.dassie/db/migrate/20250826142473_denormalize_status_message.bulkrax.rb +8 -0
  76. data/.dassie/db/migrate/20250826142474_update_identifier_index.bulkrax.rb +7 -0
  77. data/.dassie/db/migrate/20250826142475_add_index_to_metadata_bulkrax_identifier.bulkrax.rb +19 -0
  78. data/.dassie/db/migrate/20250826142476_add_file_name_to_uploaded_files.bulkrax.rb +6 -0
  79. data/.dassie/db/migrate/20250826142477_add_error_tracking_to_pending_relationships.bulkrax.rb +6 -0
  80. data/.dassie/db/migrate/20250826142478_add_last_imported_at_to_bulkrax_importers.bulkrax.rb +6 -0
  81. data/.dassie/db/migrate/20250826142479_add_next_import_at_to_bulkrax_importers.bulkrax.rb +6 -0
  82. data/.dassie/db/migrate/20250826142480_entry_error_denormalization.bulkrax.rb +8 -0
  83. data/.dassie/db/migrate/20250826142481_faster_first_entry.bulkrax.rb +8 -0
  84. data/.dassie/db/migrate/20260430000001_create_hyrax_redirect_paths.hyrax.rb +13 -0
  85. data/.dassie/db/migrate/20260521003627_add_additional_redirect_info.hyrax.rb +32 -0
  86. data/.dassie/db/schema.rb +263 -109
  87. data/.dassie/package.json +1 -1
  88. data/.dassie/rspec_split_configuration.json +835 -0
  89. data/.dassie/solr/conf/solrconfig.xml +21 -5
  90. data/.github/{ISSUE_TEMPLATE.md → ISSUE_TEMPLATE/issue_template.md} +5 -0
  91. data/.github/workflows/lint-build-test.yml +6 -2
  92. data/.github/workflows/release-charts.yml +48 -0
  93. data/.gitignore +6 -0
  94. data/.koppie/.env +5 -1
  95. data/.koppie/Gemfile +3 -1
  96. data/.koppie/app/assets/images/bulkrax/removed.png +0 -0
  97. data/.koppie/app/assets/javascripts/application.js +2 -0
  98. data/.koppie/app/assets/stylesheets/application.css +1 -0
  99. data/.koppie/app/controllers/catalog_controller.rb +1 -1
  100. data/.koppie/app/forms/collection_resource_form.rb +5 -2
  101. data/.koppie/app/forms/file_set_form.rb +5 -0
  102. data/.koppie/app/forms/generic_work_form.rb +5 -3
  103. data/.koppie/app/forms/monograph_form.rb +5 -3
  104. data/.koppie/app/indexers/collection_resource_indexer.rb +5 -2
  105. data/.koppie/app/indexers/file_set_indexer.rb +7 -0
  106. data/.koppie/app/indexers/generic_work_indexer.rb +6 -3
  107. data/.koppie/app/indexers/monograph_indexer.rb +6 -2
  108. data/.koppie/app/models/ability.rb +8 -0
  109. data/.koppie/app/models/collection_resource.rb +4 -2
  110. data/.koppie/app/models/concerns/bulkrax/has_local_processing.rb +8 -0
  111. data/.koppie/app/models/generic_work.rb +5 -2
  112. data/.koppie/app/models/monograph.rb +5 -2
  113. data/.koppie/app/views/blacklight_dynamic_sitemap/sitemap/show.xml.builder +22 -0
  114. data/.koppie/bin/importer +142 -0
  115. data/.koppie/bin/web +4 -0
  116. data/.koppie/config/browse_everything_providers.yml +2 -0
  117. data/.koppie/config/bulkrax_api.yml +86 -0
  118. data/.koppie/config/initializers/bulkrax.rb +92 -0
  119. data/.koppie/config/initializers/clamav.rb +2 -0
  120. data/.koppie/config/initializers/devise.rb +1 -1
  121. data/.koppie/config/initializers/hyrax.rb +11 -3
  122. data/.koppie/config/initializers/riiif.rb +4 -82
  123. data/.koppie/config/metadata_profiles/m3_profile.yaml +930 -0
  124. data/.koppie/config/routes.rb +7 -0
  125. data/.koppie/config/sidekiq.yml +2 -0
  126. data/.koppie/config/uv/uv.html +63 -81
  127. data/.koppie/db/migrate/20240606205215_create_hyrax_flexible_schemas.rb +9 -0
  128. data/.koppie/db/migrate/20240606205216_add_contexts_to_hyrax_flexible_schemas.rb +5 -0
  129. data/.koppie/db/migrate/20250826142438_create_bulkrax_importers.bulkrax.rb +19 -0
  130. data/.koppie/db/migrate/20250826142439_create_bulkrax_importer_runs.bulkrax.rb +17 -0
  131. data/.koppie/db/migrate/20250826142440_create_bulkrax_entries.bulkrax.rb +17 -0
  132. data/.koppie/db/migrate/20250826142441_add_status_to_entry.bulkrax.rb +10 -0
  133. data/.koppie/db/migrate/20250826142442_add_collections_to_importer_runs.bulkrax.rb +7 -0
  134. data/.koppie/db/migrate/20250826142443_change_collection_ids_on_entries.bulkrax.rb +6 -0
  135. data/.koppie/db/migrate/20250826142444_create_bulkrax_exporters.bulkrax.rb +20 -0
  136. data/.koppie/db/migrate/20250826142445_create_bulkrax_exporter_runs.bulkrax.rb +15 -0
  137. data/.koppie/db/migrate/20250826142446_change_importer_and_exporter_to_polymorphic.bulkrax.rb +19 -0
  138. data/.koppie/db/migrate/20250826142447_add_total_collection_records_to_importer_runs.bulkrax.rb +6 -0
  139. data/.koppie/db/migrate/20250826142448_add_children_to_importer_runs.bulkrax.rb +7 -0
  140. data/.koppie/db/migrate/20250826142449_change_total_records_to_total_work_entries.bulkrax.rb +7 -0
  141. data/.koppie/db/migrate/20250826142450_change_entry_last_error.bulkrax.rb +20 -0
  142. data/.koppie/db/migrate/20250826142451_add_validate_only_to_bulkrax_importers.bulkrax.rb +6 -0
  143. data/.koppie/db/migrate/20250826142452_add_status_to_importers.bulkrax.rb +10 -0
  144. data/.koppie/db/migrate/20250826142453_remove_foreign_key_from_bulkrax_entries.bulkrax.rb +6 -0
  145. data/.koppie/db/migrate/20250826142454_add_status_to_exporters.bulkrax.rb +8 -0
  146. data/.koppie/db/migrate/20250826142455_add_invalid_record_to_importer_run.bulkrax.rb +6 -0
  147. data/.koppie/db/migrate/20250826142456_create_bulkrax_statuses.bulkrax.rb +19 -0
  148. data/.koppie/db/migrate/20250826142457_move_to_statuses.bulkrax.rb +31 -0
  149. data/.koppie/db/migrate/20250826142458_add_date_filter_and_status_to_bulkrax_exporters.bulkrax.rb +8 -0
  150. data/.koppie/db/migrate/20250826142459_add_workflow_status_to_bulkrax_exporter.bulkrax.rb +6 -0
  151. data/.koppie/db/migrate/20250826142460_remove_unused_last_error.bulkrax.rb +8 -0
  152. data/.koppie/db/migrate/20250826142461_increase_text_sizes.bulkrax.rb +13 -0
  153. data/.koppie/db/migrate/20250826142462_change_bulkrax_statuses_error_message_column_type_to_text.bulkrax.rb +6 -0
  154. data/.koppie/db/migrate/20250826142463_rename_children_counters_to_relationships.bulkrax.rb +7 -0
  155. data/.koppie/db/migrate/20250826142464_add_file_set_counters_to_importer_runs.bulkrax.rb +8 -0
  156. data/.koppie/db/migrate/20250826142465_add_import_attempts_to_entries.bulkrax.rb +6 -0
  157. data/.koppie/db/migrate/20250826142466_add_work_counters_to_importer_runs.bulkrax.rb +7 -0
  158. data/.koppie/db/migrate/20250826142467_create_bulkrax_pending_relationships.bulkrax.rb +14 -0
  159. data/.koppie/db/migrate/20250826142468_add_order_to_bulkrax_pending_relationships.bulkrax.rb +6 -0
  160. data/.koppie/db/migrate/20250826142469_add_include_thumbnails_to_bulkrax_exporters.bulkrax.rb +6 -0
  161. data/.koppie/db/migrate/20250826142470_add_generated_metadata_to_bulkrax_exporters.bulkrax.rb +6 -0
  162. data/.koppie/db/migrate/20250826142471_rename_bulkrax_importer_run_to_importer_run.bulkrax.rb +18 -0
  163. data/.koppie/db/migrate/20250826142472_add_indices_to_bulkrax.bulkrax.rb +26 -0
  164. data/.koppie/db/migrate/20250826142473_denormalize_status_message.bulkrax.rb +8 -0
  165. data/.koppie/db/migrate/20250826142474_update_identifier_index.bulkrax.rb +7 -0
  166. data/.koppie/db/migrate/20250826142475_add_index_to_metadata_bulkrax_identifier.bulkrax.rb +19 -0
  167. data/.koppie/db/migrate/20250826142476_add_file_name_to_uploaded_files.bulkrax.rb +6 -0
  168. data/.koppie/db/migrate/20250826142477_add_error_tracking_to_pending_relationships.bulkrax.rb +6 -0
  169. data/.koppie/db/migrate/20250826142478_add_last_imported_at_to_bulkrax_importers.bulkrax.rb +6 -0
  170. data/.koppie/db/migrate/20250826142479_add_next_import_at_to_bulkrax_importers.bulkrax.rb +6 -0
  171. data/.koppie/db/migrate/20250826142480_entry_error_denormalization.bulkrax.rb +8 -0
  172. data/.koppie/db/migrate/20250826142481_faster_first_entry.bulkrax.rb +8 -0
  173. data/.koppie/db/migrate/20260430000001_create_hyrax_redirect_paths.hyrax.rb +13 -0
  174. data/.koppie/db/migrate/20260521003627_add_additional_redirect_info.hyrax.rb +32 -0
  175. data/.koppie/db/schema.rb +154 -1
  176. data/.koppie/package.json +1 -1
  177. data/.koppie/rspec_split_configuration.json +835 -0
  178. data/.koppie/solr/conf/solrconfig.xml +0 -5
  179. data/.koppie/yarn.lock +5587 -752
  180. data/.rubocop.yml +1 -0
  181. data/CONTAINERS.md +12 -10
  182. data/Dockerfile +9 -22
  183. data/Gemfile +1 -1
  184. data/Gemfile.allinson +2 -0
  185. data/README.md +1 -2
  186. data/app/actors/hyrax/actors/file_actor.rb +2 -0
  187. data/app/actors/hyrax/actors/file_set_actor.rb +1 -1
  188. data/app/assets/javascripts/hyrax/app.js.erb +143 -10
  189. data/app/assets/javascripts/hyrax/collection_select.js +68 -0
  190. data/app/assets/javascripts/hyrax/copy_permalink_button.js +28 -0
  191. data/app/assets/javascripts/hyrax/redirects.js +45 -0
  192. data/app/assets/javascripts/hyrax/relationships/control.es6 +21 -1
  193. data/app/assets/javascripts/hyrax/select_work_type.es6 +7 -2
  194. data/app/assets/javascripts/hyrax.js +3 -1
  195. data/app/assets/stylesheets/hyrax/_file-show.scss +1 -0
  196. data/app/assets/stylesheets/hyrax/_viewer.scss +8 -0
  197. data/app/assets/stylesheets/hyrax/dashboard.scss +22 -1
  198. data/app/assets/stylesheets/hyrax/sidebar.scss +98 -3
  199. data/app/authorities/qa/authorities/collections.rb +9 -9
  200. data/app/controllers/concerns/hyrax/analytics_error_handling.rb +97 -0
  201. data/app/controllers/concerns/hyrax/collections_controller_behavior.rb +3 -1
  202. data/app/controllers/concerns/hyrax/ensure_migrated_behavior.rb +50 -0
  203. data/app/controllers/concerns/hyrax/flexible_catalog_behavior.rb +206 -0
  204. data/app/controllers/concerns/hyrax/flexible_schema_behavior.rb +17 -0
  205. data/app/controllers/concerns/hyrax/redirect_to_display_url.rb +54 -0
  206. data/app/controllers/concerns/hyrax/valkyrie_downloads_controller_behavior.rb +1 -0
  207. data/app/controllers/concerns/hyrax/works_controller_behavior.rb +54 -11
  208. data/app/controllers/hyrax/admin/admin_sets_controller.rb +21 -13
  209. data/app/controllers/hyrax/admin/analytics/collection_reports_controller.rb +2 -0
  210. data/app/controllers/hyrax/admin/analytics/work_reports_controller.rb +5 -4
  211. data/app/controllers/hyrax/admin/metadata_profiles_controller.rb +66 -0
  212. data/app/controllers/hyrax/batch_uploads_controller.rb +2 -0
  213. data/app/controllers/hyrax/dashboard/collections_controller.rb +27 -6
  214. data/app/controllers/hyrax/dashboard/nest_collections_controller.rb +2 -1
  215. data/app/controllers/hyrax/dashboard_controller.rb +2 -1
  216. data/app/controllers/hyrax/file_sets_controller.rb +20 -2
  217. data/app/controllers/hyrax/homepage_controller.rb +7 -0
  218. data/app/controllers/hyrax/my/works_controller.rb +2 -21
  219. data/app/controllers/hyrax/permissions_controller.rb +4 -2
  220. data/app/controllers/hyrax/redirects_controller.rb +56 -0
  221. data/app/controllers/hyrax/single_use_links_viewer_controller.rb +2 -1
  222. data/app/controllers/hyrax/transcripts_controller.rb +31 -0
  223. data/app/controllers/hyrax/uploads_controller.rb +18 -9
  224. data/app/forms/concerns/hyrax/based_near_field_behavior.rb +77 -0
  225. data/app/forms/concerns/hyrax/flexible_form_behavior.rb +37 -0
  226. data/app/forms/concerns/hyrax/redirects_field_behavior.rb +95 -0
  227. data/app/forms/concerns/hyrax/transcripts_behavior.rb +40 -0
  228. data/app/forms/hyrax/forms/admin_set_form.rb +1 -1
  229. data/app/forms/hyrax/forms/administrative_set_form.rb +3 -0
  230. data/app/forms/hyrax/forms/batch_edit_form.rb +1 -3
  231. data/app/forms/hyrax/forms/batch_upload_form.rb +14 -0
  232. data/app/forms/hyrax/forms/file_set_edit_form.rb +1 -1
  233. data/app/forms/hyrax/forms/file_set_form.rb +6 -7
  234. data/app/forms/hyrax/forms/pcdm_collection_form.rb +17 -5
  235. data/app/forms/hyrax/forms/pcdm_object_form.rb +11 -3
  236. data/app/forms/hyrax/forms/resource_batch_edit_form.rb +8 -22
  237. data/app/forms/hyrax/forms/resource_form.rb +110 -10
  238. data/app/forms/hyrax/forms.rb +1 -0
  239. data/app/helpers/hyrax/attributes_helper.rb +109 -0
  240. data/app/helpers/hyrax/blacklight_override.rb +26 -0
  241. data/app/helpers/hyrax/collections_helper.rb +2 -0
  242. data/app/helpers/hyrax/file_set_form_helper.rb +24 -0
  243. data/app/helpers/hyrax/hyrax_helper_behavior.rb +53 -4
  244. data/app/helpers/hyrax/iiif_helper.rb +11 -1
  245. data/app/helpers/hyrax/permalink_helper.rb +37 -0
  246. data/app/helpers/hyrax/redirects_tab_helper.rb +29 -0
  247. data/app/helpers/hyrax/trophy_helper.rb +1 -1
  248. data/app/helpers/hyrax/work_form_helper.rb +9 -5
  249. data/app/helpers/hyrax/works_helper.rb +14 -0
  250. data/app/indexers/concerns/hyrax/workflow_indexer.rb +30 -0
  251. data/app/indexers/hyrax/file_set_indexer.rb +1 -0
  252. data/app/indexers/hyrax/indexers/administrative_set_indexer.rb +2 -1
  253. data/app/indexers/hyrax/indexers/file_set_indexer.rb +6 -2
  254. data/app/indexers/hyrax/indexers/pcdm_collection_indexer.rb +11 -1
  255. data/app/indexers/hyrax/indexers/pcdm_object_indexer.rb +25 -4
  256. data/app/indexers/hyrax/indexers/redirects_indexer.rb +29 -0
  257. data/app/indexers/hyrax/indexers/resource_indexer.rb +4 -0
  258. data/app/indexers/hyrax/indexers.rb +2 -0
  259. data/app/inputs/controlled_vocabulary_input.rb +7 -1
  260. data/app/jobs/concerns/hyrax/queued_job_behavior.rb +22 -0
  261. data/app/jobs/content_deposit_error_event_job.rb +14 -0
  262. data/app/jobs/create_work_job.rb +2 -0
  263. data/app/jobs/hyrax/propagate_change_depositor_job.rb +1 -1
  264. data/app/jobs/hyrax/queued_delete_job.rb +11 -0
  265. data/app/jobs/hyrax/queued_indexing_job.rb +11 -0
  266. data/app/jobs/migrate_files_to_valkyrie_job.rb +39 -21
  267. data/app/jobs/migrate_sipity_entity_job.rb +21 -0
  268. data/app/models/batch_upload_item.rb +4 -0
  269. data/app/models/concerns/hyrax/ability/flexible_metadata_ability.rb +10 -0
  270. data/app/models/concerns/hyrax/ability.rb +7 -3
  271. data/app/models/concerns/hyrax/collection_behavior.rb +4 -0
  272. data/app/models/concerns/hyrax/file_set/transcripts.rb +16 -0
  273. data/app/models/concerns/hyrax/file_set_behavior.rb +9 -0
  274. data/app/models/concerns/hyrax/flexibility.rb +107 -0
  275. data/app/models/concerns/hyrax/redirects_normalization.rb +38 -0
  276. data/app/models/concerns/hyrax/solr_document/characterization.rb +1 -1
  277. data/app/models/concerns/hyrax/solr_document/metadata.rb +9 -0
  278. data/app/models/concerns/hyrax/solr_document/ordered_members.rb +4 -0
  279. data/app/models/concerns/hyrax/solr_document_behavior.rb +28 -3
  280. data/app/models/concerns/hyrax/suppressible.rb +1 -1
  281. data/app/models/concerns/hyrax/valkyrie_lazy_migration.rb +1 -1
  282. data/app/models/concerns/hyrax/with_embargoes_and_leases.rb +30 -0
  283. data/app/models/concerns/hyrax/work_behavior.rb +8 -0
  284. data/app/models/hyrax/administrative_set.rb +1 -1
  285. data/app/models/hyrax/change_set.rb +3 -1
  286. data/app/models/hyrax/embargo.rb +3 -1
  287. data/app/models/hyrax/file_metadata.rb +22 -7
  288. data/app/models/hyrax/file_set.rb +4 -2
  289. data/app/models/hyrax/flexible_schema.rb +219 -0
  290. data/app/models/hyrax/lease.rb +3 -1
  291. data/app/models/hyrax/pcdm_collection.rb +4 -1
  292. data/app/models/hyrax/redirect.rb +64 -0
  293. data/app/models/hyrax/redirect_path.rb +14 -0
  294. data/app/models/hyrax/resource.rb +22 -25
  295. data/app/models/hyrax/riiif/file.rb +43 -0
  296. data/app/models/hyrax/riiif/file_resolver.rb +65 -0
  297. data/app/models/hyrax/uploaded_file.rb +9 -0
  298. data/app/models/hyrax/virus_scanner.rb +16 -3
  299. data/app/models/hyrax/work.rb +4 -1
  300. data/app/models/job_io_wrapper.rb +12 -3
  301. data/app/models/user_mailbox.rb +3 -1
  302. data/app/presenters/hyrax/admin_set_presenter.rb +11 -0
  303. data/app/presenters/hyrax/annotates_content.rb +35 -0
  304. data/app/presenters/hyrax/collection_presenter.rb +5 -1
  305. data/app/presenters/hyrax/displays_content.rb +133 -0
  306. data/app/presenters/hyrax/displays_image.rb +11 -4
  307. data/app/presenters/hyrax/displays_transcripts.rb +59 -0
  308. data/app/presenters/hyrax/file_set_presenter.rb +8 -18
  309. data/app/presenters/hyrax/google_scholar_presenter.rb +39 -0
  310. data/app/presenters/hyrax/iiif_manifest_presenter.rb +22 -4
  311. data/app/presenters/hyrax/missing_method_behavior.rb +15 -0
  312. data/app/presenters/hyrax/pcdm_member_presenter_factory.rb +2 -4
  313. data/app/presenters/hyrax/work_show_presenter.rb +56 -14
  314. data/app/renderers/hyrax/renderers/attribute_renderer.rb +6 -2
  315. data/app/renderers/hyrax/renderers/license_attribute_renderer.rb +10 -10
  316. data/app/renderers/hyrax/renderers/redirects_label_attribute_renderer.rb +25 -0
  317. data/app/renderers/hyrax/renderers/rights_statement_attribute_renderer.rb +10 -11
  318. data/app/search_builders/hyrax/dashboard/nested_collections_search_builder.rb +1 -5
  319. data/app/search_builders/hyrax/filter_by_type.rb +1 -1
  320. data/app/services/hyrax/action/create_valkyrie_work.rb +3 -2
  321. data/app/services/hyrax/analytics/ga4/base.rb +1 -1
  322. data/app/services/hyrax/analytics/ga4.rb +5 -1
  323. data/app/services/hyrax/authority_rendering_helper.rb +28 -0
  324. data/app/services/hyrax/authority_service.rb +107 -0
  325. data/app/services/hyrax/callbacks.rb +2 -2
  326. data/app/services/hyrax/change_depositor_service.rb +1 -1
  327. data/app/services/hyrax/characterization/valkyrie_characterization_service.rb +21 -13
  328. data/app/services/hyrax/collections/nested_collection_query_service.rb +9 -3
  329. data/app/services/hyrax/collections_service.rb +17 -0
  330. data/app/services/hyrax/custom_queries/find_by_property_value.rb +89 -0
  331. data/app/services/hyrax/custom_queries/find_ids_by_model.rb +31 -6
  332. data/app/services/hyrax/edit_permissions_service.rb +11 -10
  333. data/app/services/hyrax/file_set_type_service.rb +12 -4
  334. data/app/services/hyrax/flexible_schema_validator_service.rb +153 -0
  335. data/app/services/hyrax/flexible_schema_validators/class_validator.rb +123 -0
  336. data/app/services/hyrax/flexible_schema_validators/core_metadata_validator.rb +211 -0
  337. data/app/services/hyrax/flexible_schema_validators/existing_records_validator.rb +83 -0
  338. data/app/services/hyrax/flexible_schema_validators/redirects_validator.rb +116 -0
  339. data/app/services/hyrax/flexible_schema_validators/schema_validator.rb +34 -0
  340. data/app/services/hyrax/flexible_schema_validators/sort_properties_validator.rb +54 -0
  341. data/app/services/hyrax/license_service.rb +1 -1
  342. data/app/services/hyrax/listeners/metadata_index_listener.rb +11 -0
  343. data/app/services/hyrax/m3_profile_editor.rb +32 -0
  344. data/app/services/hyrax/m3_schema_loader.rb +119 -0
  345. data/app/services/hyrax/manifest_builder_service.rb +18 -24
  346. data/app/services/hyrax/permalink_path.rb +25 -0
  347. data/app/services/hyrax/qa_select_service.rb +9 -5
  348. data/app/services/hyrax/redirect_path_normalizer.rb +58 -0
  349. data/app/services/hyrax/redirects_lookup.rb +59 -0
  350. data/app/services/hyrax/resource_permissions_visibility_propagator.rb +54 -0
  351. data/app/services/hyrax/resource_types_service.rb +3 -20
  352. data/app/services/hyrax/rights_statement_service.rb +1 -1
  353. data/app/services/hyrax/schema_loader.rb +205 -0
  354. data/app/services/hyrax/search_service.rb +1 -1
  355. data/app/services/hyrax/simple_schema_loader.rb +28 -127
  356. data/app/services/hyrax/solr_service.rb +39 -2
  357. data/app/services/hyrax/tolerant_select_service.rb +5 -3
  358. data/app/services/hyrax/valkyrie_upload.rb +2 -2
  359. data/app/services/hyrax/visibility_propagator.rb +4 -1
  360. data/app/services/hyrax/work_uploads_handler.rb +17 -9
  361. data/app/services/hyrax/workflow/workflow_factory.rb +5 -4
  362. data/app/services/migrate_resource_service.rb +8 -2
  363. data/app/uploaders/hyrax/uploaded_file_uploader.rb +2 -2
  364. data/app/utils/hyrax/data_destroyers/collection_branding_destroyer.rb +1 -1
  365. data/app/utils/hyrax/required_data_seeder.rb +1 -0
  366. data/app/utils/hyrax/required_data_seeders/collection_type_seeder.rb +1 -1
  367. data/app/utils/hyrax/required_data_seeders/flexible_profile_seeder.rb +28 -0
  368. data/app/validators/hyrax/controlled_vocabulary_validator.rb +64 -0
  369. data/app/validators/hyrax/redirect_validator.rb +128 -0
  370. data/app/views/_user_util_links.html.erb +2 -1
  371. data/app/views/catalog/_thumbnail_list_default.html.erb +2 -2
  372. data/app/views/collections/edit_fields/_schema_version.html.erb +1 -0
  373. data/app/views/hyrax/admin/admin_sets/_form_metadata.html.erb +24 -2
  374. data/app/views/hyrax/admin/admin_sets/_show_document_list_row.html.erb +1 -1
  375. data/app/views/hyrax/admin/admin_sets/show.html.erb +1 -1
  376. data/app/views/hyrax/admin/analytics/_analytics_error.html.erb +42 -0
  377. data/app/views/hyrax/admin/analytics/collection_reports/_top_collections.html.erb +3 -7
  378. data/app/views/hyrax/admin/analytics/collection_reports/index.html.erb +11 -9
  379. data/app/views/hyrax/admin/analytics/work_reports/_top_file_set_downloads.html.erb +3 -6
  380. data/app/views/hyrax/admin/analytics/work_reports/_top_works.html.erb +2 -3
  381. data/app/views/hyrax/admin/analytics/work_reports/_work_files.html.erb +1 -6
  382. data/app/views/hyrax/admin/analytics/work_reports/index.html.erb +60 -57
  383. data/app/views/hyrax/admin/features/index.html.erb +1 -1
  384. data/app/views/hyrax/admin/metadata_profiles/_import_modal.html.erb +20 -0
  385. data/app/views/hyrax/admin/metadata_profiles/index.html.erb +54 -0
  386. data/app/views/hyrax/base/_attribute_rows.html.erb +4 -21
  387. data/app/views/hyrax/base/_citations.html.erb +1 -0
  388. data/app/views/hyrax/base/_currently_shared.html.erb +2 -1
  389. data/app/views/hyrax/base/_file_manager_thumbnail.html.erb +1 -1
  390. data/app/views/hyrax/base/_form_member_of_collections.html.erb +6 -6
  391. data/app/views/hyrax/base/_form_redirects.html.erb +125 -0
  392. data/app/views/hyrax/base/_form_share.html.erb +7 -2
  393. data/app/views/hyrax/base/_member.html.erb +1 -1
  394. data/app/views/hyrax/base/_social_media.html.erb +3 -1
  395. data/app/views/hyrax/base/iiif_viewers/_universal_viewer.html.erb +1 -1
  396. data/app/views/hyrax/base/show.html.erb +3 -0
  397. data/app/views/hyrax/collections/_default_group.html.erb +3 -0
  398. data/app/views/hyrax/collections/_list_collections.html.erb +3 -0
  399. data/app/views/hyrax/collections/_list_works.html.erb +1 -1
  400. data/app/views/hyrax/collections/_show_document_list_row.html.erb +1 -1
  401. data/app/views/hyrax/collections/show.html.erb +4 -0
  402. data/app/views/hyrax/dashboard/_sidebar.html.erb +4 -2
  403. data/app/views/hyrax/dashboard/collections/_button_for_update_collection.html.erb +2 -1
  404. data/app/views/hyrax/dashboard/collections/_default_group.html.erb +3 -0
  405. data/app/views/hyrax/dashboard/collections/_form.html.erb +17 -0
  406. data/app/views/hyrax/dashboard/collections/_form_for_select_collection.html.erb +7 -10
  407. data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +3 -0
  408. data/app/views/hyrax/dashboard/collections/_list_works.html.erb +1 -1
  409. data/app/views/hyrax/dashboard/collections/_show_document_list_menu.html.erb +13 -12
  410. data/app/views/hyrax/dashboard/collections/_show_document_list_row.html.erb +1 -1
  411. data/app/views/hyrax/dashboard/profiles/_edit_primary.html.erb +1 -8
  412. data/app/views/hyrax/dashboard/profiles/_trophy_edit.html.erb +1 -1
  413. data/app/views/hyrax/dashboard/profiles/show.html.erb +5 -5
  414. data/app/views/hyrax/dashboard/sidebar/_metadata.html.erb +11 -0
  415. data/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb +1 -0
  416. data/app/views/hyrax/dashboard/works/_default_group.html.erb +3 -0
  417. data/app/views/hyrax/dashboard/works/_list_works.html.erb +4 -2
  418. data/app/views/hyrax/file_sets/_form.html.erb +16 -3
  419. data/app/views/hyrax/file_sets/_metadata.html.erb +35 -0
  420. data/app/views/hyrax/file_sets/_valkyrie_form.html.erb +37 -0
  421. data/app/views/hyrax/file_sets/edit.html.erb +14 -8
  422. data/app/views/hyrax/file_sets/media_display/_audio.html.erb +4 -0
  423. data/app/views/hyrax/file_sets/media_display/_image.html.erb +2 -2
  424. data/app/views/hyrax/file_sets/media_display/_video.html.erb +4 -0
  425. data/app/views/hyrax/homepage/_explore_collections.html.erb +1 -1
  426. data/app/views/hyrax/homepage/_featured_fields.html.erb +1 -1
  427. data/app/views/hyrax/homepage/_recent_document.html.erb +1 -1
  428. data/app/views/hyrax/homepage/robots.text.erb +17 -0
  429. data/app/views/hyrax/my/_admin_set_action_menu.html.erb +31 -27
  430. data/app/views/hyrax/my/_collection_action_menu.html.erb +40 -35
  431. data/app/views/hyrax/my/_work_action_menu.html.erb +23 -22
  432. data/app/views/hyrax/my/collections/_default_group.html.erb +3 -0
  433. data/app/views/hyrax/my/collections/_list_collections.html.erb +3 -0
  434. data/app/views/hyrax/my/collections/_modal_add_subcollection.html.erb +2 -2
  435. data/app/views/hyrax/my/collections/_modal_add_to_collection.html.erb +2 -2
  436. data/app/views/hyrax/my/works/_default_group.html.erb +3 -0
  437. data/app/views/hyrax/my/works/_list_works.html.erb +5 -2
  438. data/app/views/hyrax/shared/_copy_permalink.html.erb +10 -0
  439. data/app/views/hyrax/users/_user_info.html.erb +1 -6
  440. data/app/views/layouts/_head_tag_content.html.erb +2 -0
  441. data/app/views/layouts/hyrax/dashboard.html.erb +2 -1
  442. data/app/views/records/edit_fields/_contexts.html.erb +1 -0
  443. data/app/views/records/edit_fields/_license.html.erb +17 -5
  444. data/app/views/records/edit_fields/_resource_type.html.erb +16 -2
  445. data/app/views/records/edit_fields/_rights_statement.html.erb +17 -5
  446. data/app/views/records/edit_fields/_schema_version.html.erb +1 -0
  447. data/app/views/records/edit_fields/_transcript_ids.html.erb +18 -0
  448. data/app/views/records/show_fields/_rights.html.erb +1 -1
  449. data/app/views/shared/_citations.html.erb +46 -31
  450. data/app/views/shared/_schema_version.html.erb +38 -0
  451. data/bin/dev-entrypoint.sh +14 -4
  452. data/chart/hyrax/Chart.yaml +4 -4
  453. data/chart/hyrax/templates/ingress.yaml +3 -0
  454. data/chart/hyrax/values.yaml +10 -8
  455. data/config/features.rb +77 -40
  456. data/config/initializers/blacklight_dynamic_sitemap.rb +43 -0
  457. data/config/initializers/deprecation_patch.rb +27 -0
  458. data/config/initializers/hydra_works.rb +3 -0
  459. data/config/initializers/i18n_extensions.rb +197 -0
  460. data/config/initializers/indexing_adapter_initializer.rb +4 -0
  461. data/config/initializers/new_framework_defaults_7_2.rb +6 -4
  462. data/config/initializers/reform_rails_6_1_monkey_patch.rb +29 -0
  463. data/config/initializers/storage_adapter_initializer.rb +15 -9
  464. data/config/locales/hyrax.de.yml +172 -54
  465. data/config/locales/hyrax.en.yml +183 -66
  466. data/config/locales/hyrax.es.yml +174 -49
  467. data/config/locales/hyrax.fr.yml +169 -45
  468. data/config/locales/hyrax.it.yml +172 -48
  469. data/config/locales/hyrax.pt-BR.yml +172 -54
  470. data/config/locales/hyrax.zh.yml +145 -21
  471. data/config/metadata/basic_metadata.yaml +66 -0
  472. data/config/metadata/batch_edit_metadata.yaml +119 -0
  473. data/config/metadata/core_metadata.yaml +1 -0
  474. data/config/metadata/file_set_metadata.yaml +19 -0
  475. data/config/metadata/redirects.yaml +15 -0
  476. data/config/metadata_profiles/m3_json_schema.json +487 -0
  477. data/config/metadata_profiles/m3_profile.yaml +954 -0
  478. data/config/routes.rb +9 -0
  479. data/docker-compose-allinson.yml +176 -0
  480. data/docker-compose-dassie.yml +18 -10
  481. data/docker-compose-koppie.yml +18 -10
  482. data/docker-compose-sirenia.yml +20 -10
  483. data/documentation/copy_permalink.md +29 -0
  484. data/documentation/developing-your-hyrax-based-app.md +2 -2
  485. data/documentation/file-ingest-characterization.md +763 -0
  486. data/documentation/flexible_metadata.md +113 -0
  487. data/documentation/forms/field_behaviors.md +297 -0
  488. data/documentation/redirects.md +428 -0
  489. data/hyrax.gemspec +9 -4
  490. data/lib/freyja/metadata_adapter.rb +1 -1
  491. data/lib/freyja/persister.rb +36 -5
  492. data/lib/generators/hyrax/collection_resource/collection_resource_generator.rb +2 -2
  493. data/lib/generators/hyrax/collection_resource/templates/collection.rb.erb +5 -1
  494. data/lib/generators/hyrax/collection_resource/templates/collection_form.rb.erb +5 -1
  495. data/lib/generators/hyrax/collection_resource/templates/collection_indexer.rb.erb +6 -1
  496. data/lib/generators/hyrax/iiif_viewer/USAGE +22 -0
  497. data/lib/generators/hyrax/iiif_viewer/iiif_viewer_generator.rb +49 -0
  498. data/lib/generators/hyrax/iiif_viewer/templates/_clover.html.erb +7 -0
  499. data/lib/generators/hyrax/iiif_viewer/templates/clover/clover.css +3328 -0
  500. data/lib/generators/hyrax/iiif_viewer/templates/clover/clover.html +16 -0
  501. data/lib/generators/hyrax/iiif_viewer/templates/clover/clover.js +237 -0
  502. data/lib/generators/hyrax/install_generator.rb +25 -1
  503. data/lib/generators/hyrax/riiif_generator.rb +1 -1
  504. data/lib/generators/hyrax/templates/app/views/blacklight_dynamic_sitemap/sitemap/show.xml.builder +22 -0
  505. data/lib/generators/hyrax/templates/config/clamav.rb +2 -0
  506. data/lib/generators/hyrax/templates/config/initializers/riiif.rb +4 -80
  507. data/lib/generators/hyrax/templates/db/migrate/20240606205215_create_hyrax_flexible_schemas.rb.erb +9 -0
  508. data/lib/generators/hyrax/templates/db/migrate/20240606205216_add_contexts_to_hyrax_flexible_schemas.rb.erb +5 -0
  509. data/lib/generators/hyrax/templates/db/migrate/20260430000001_create_hyrax_redirect_paths.rb.erb +22 -0
  510. data/lib/generators/hyrax/templates/db/migrate/20260521003627_add_additional_redirect_info.rb.erb +39 -0
  511. data/lib/generators/hyrax/templates/package.json +1 -1
  512. data/lib/generators/hyrax/templates/uv.html +60 -82
  513. data/lib/generators/hyrax/work/templates/indexer.rb.erb +1 -1
  514. data/lib/generators/hyrax/work/templates/model.rb.erb +5 -1
  515. data/lib/generators/hyrax/work_resource/templates/form.rb.erb +5 -2
  516. data/lib/generators/hyrax/work_resource/templates/indexer.rb.erb +6 -2
  517. data/lib/generators/hyrax/work_resource/templates/work.rb.erb +5 -2
  518. data/lib/generators/hyrax/work_resource/work_resource_generator.rb +1 -0
  519. data/lib/hyrax/active_fedora_dummy_model.rb +6 -0
  520. data/lib/hyrax/configuration.rb +219 -10
  521. data/lib/hyrax/controlled_vocabulary/importer/language.rb +5 -1
  522. data/lib/hyrax/deprecation.rb +31 -0
  523. data/lib/hyrax/engine.rb +2 -0
  524. data/lib/hyrax/form_fields.rb +17 -5
  525. data/lib/hyrax/indexer.rb +31 -2
  526. data/lib/hyrax/resource_sync/resource_list_writer.rb +3 -0
  527. data/lib/hyrax/schema.rb +15 -4
  528. data/lib/hyrax/specs/shared_specs/factories/administrative_sets.rb +12 -0
  529. data/lib/hyrax/specs/shared_specs/factories/hyrax_embargo.rb +1 -1
  530. data/lib/hyrax/specs/shared_specs/factories/hyrax_file_set.rb +13 -0
  531. data/lib/hyrax/specs/shared_specs/factories/hyrax_lease.rb +5 -1
  532. data/lib/hyrax/specs/shared_specs/factories/hyrax_work.rb +14 -0
  533. data/lib/hyrax/specs/shared_specs/simple_work.rb +41 -0
  534. data/lib/hyrax/specs/shared_specs.rb +1 -0
  535. data/lib/hyrax/transactions/collection_create.rb +2 -1
  536. data/lib/hyrax/transactions/collection_destroy.rb +1 -0
  537. data/lib/hyrax/transactions/collection_update.rb +2 -1
  538. data/lib/hyrax/transactions/container.rb +28 -0
  539. data/lib/hyrax/transactions/steps/add_file_sets.rb +2 -1
  540. data/lib/hyrax/transactions/steps/apply_permission_template_on_update.rb +65 -0
  541. data/lib/hyrax/transactions/steps/apply_workflow_on_admin_set_change.rb +97 -0
  542. data/lib/hyrax/transactions/steps/ensure_admin_set.rb +1 -1
  543. data/lib/hyrax/transactions/steps/remove_redirect_paths.rb +35 -0
  544. data/lib/hyrax/transactions/steps/save.rb +10 -0
  545. data/lib/hyrax/transactions/steps/set_default_admin_set.rb +1 -1
  546. data/lib/hyrax/transactions/steps/sync_redirect_paths.rb +141 -0
  547. data/lib/hyrax/transactions/work_create.rb +2 -1
  548. data/lib/hyrax/transactions/work_destroy.rb +1 -0
  549. data/lib/hyrax/transactions/work_update.rb +4 -1
  550. data/lib/hyrax/version.rb +1 -1
  551. data/lib/hyrax.rb +62 -0
  552. data/lib/tasks/m3_profile_cleanup.rake +35 -0
  553. data/lib/valkyrie/indexing/redis_queue/indexing_adapter.rb +144 -0
  554. data/lib/wings/valkyrie/query_service.rb +3 -4
  555. data/template.rb +4 -1
  556. metadata +327 -25
  557. data/.dassie/public/robots.txt +0 -1
  558. data/.github/workflows/main.yml +0 -17
  559. data/.koppie/public/robots.txt +0 -1
  560. data/app/forms/concerns/hyrax/basic_metadata_form_fields_behavior.rb +0 -39
  561. data/app/views/catalog/_thumbnail_list_collection.html.erb +0 -4
@@ -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
@@ -36,6 +36,8 @@ module Hyrax
36
36
  require 'hyrax/transactions/steps/add_to_parent'
37
37
  require 'hyrax/transactions/steps/apply_collection_type_permissions'
38
38
  require 'hyrax/transactions/steps/apply_permission_template'
39
+ require 'hyrax/transactions/steps/apply_permission_template_on_update'
40
+ require 'hyrax/transactions/steps/apply_workflow_on_admin_set_change'
39
41
  require 'hyrax/transactions/steps/change_depositor'
40
42
  require 'hyrax/transactions/steps/check_for_default_admin_set'
41
43
  require 'hyrax/transactions/steps/check_for_empty_admin_set'
@@ -49,6 +51,7 @@ module Hyrax
49
51
  require 'hyrax/transactions/steps/set_collection_type_gid'
50
52
  require 'hyrax/transactions/steps/remove_file_set_from_work'
51
53
  require 'hyrax/transactions/steps/remove_from_membership'
54
+ require 'hyrax/transactions/steps/remove_redirect_paths'
52
55
  require 'hyrax/transactions/steps/save'
53
56
  require 'hyrax/transactions/steps/save_access_control'
54
57
  require 'hyrax/transactions/steps/save_collection_banner'
@@ -58,6 +61,7 @@ module Hyrax
58
61
  require 'hyrax/transactions/steps/set_uploaded_date_unless_present'
59
62
  require 'hyrax/transactions/steps/set_user_as_creator'
60
63
  require 'hyrax/transactions/steps/set_user_as_depositor'
64
+ require 'hyrax/transactions/steps/sync_redirect_paths'
61
65
  require 'hyrax/transactions/steps/update_work_members'
62
66
  require 'hyrax/transactions/steps/validate'
63
67
 
@@ -245,6 +249,14 @@ module Hyrax
245
249
  ops.register 'save_collection_logo' do
246
250
  Steps::SaveCollectionLogo.new
247
251
  end
252
+
253
+ ops.register 'sync_redirect_paths' do
254
+ Steps::SyncRedirectPaths.new
255
+ end
256
+
257
+ ops.register 'remove_redirect_paths' do
258
+ Steps::RemoveRedirectPaths.new
259
+ end
248
260
  end
249
261
 
250
262
  namespace 'work_resource' do |ops| # Hyrax::Work resource
@@ -260,6 +272,14 @@ module Hyrax
260
272
  Steps::ApplyPermissionTemplate.new
261
273
  end
262
274
 
275
+ ops.register 'apply_permission_template_on_update' do
276
+ Steps::ApplyPermissionTemplateOnUpdate.new
277
+ end
278
+
279
+ ops.register 'apply_workflow_on_admin_set_change' do
280
+ Steps::ApplyWorkflowOnAdminSetChange.new
281
+ end
282
+
263
283
  ops.register 'change_depositor' do
264
284
  Steps::ChangeDepositor.new
265
285
  end
@@ -287,6 +307,14 @@ module Hyrax
287
307
  ops.register 'update_work_members' do
288
308
  Steps::UpdateWorkMembers.new
289
309
  end
310
+
311
+ ops.register 'sync_redirect_paths' do
312
+ Steps::SyncRedirectPaths.new
313
+ end
314
+
315
+ ops.register 'remove_redirect_paths' do
316
+ Steps::RemoveRedirectPaths.new
317
+ end
290
318
  end
291
319
  # rubocop:enable Metrics/BlockLength
292
320
  end
@@ -20,10 +20,11 @@ module Hyrax
20
20
  ##
21
21
  # @param [Hyrax::Work] obj
22
22
  # @param [Enumerable<UploadedFile>] uploaded_files
23
- # @param [Enumerable<Hash>] file_set_params
23
+ # @param [Enumerable<Hash>] file_set_params or nil
24
24
  #
25
25
  # @return [Dry::Monads::Result]
26
26
  def call(obj, uploaded_files: [], file_set_params: [])
27
+ return Success(obj) if uploaded_files.empty? && file_set_params.blank? # Skip if no files to attach
27
28
  if @handler.new(work: obj).add(files: uploaded_files, file_set_params: file_set_params).attach
28
29
  file_sets = obj.member_ids.map do |member|
29
30
  Hyrax.query_service.find_by(id: member) if Hyrax.query_service.find_by(id: member).is_a? Hyrax::FileSet
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+ module Hyrax
3
+ module Transactions
4
+ module Steps
5
+ ##
6
+ # A `dry-transaction` step that applies a permission template to a work
7
+ # when its admin set has changed during an update.
8
+ #
9
+ # Removes grants from the old admin set's permission template that are not
10
+ # present in the new template, then applies the new template's grants.
11
+ # Manually added permissions and the depositor's access are preserved.
12
+ #
13
+ # @since 5.1.0
14
+ class ApplyPermissionTemplateOnUpdate
15
+ include Dry::Monads[:result]
16
+
17
+ ##
18
+ # @param [Hyrax::Work] object
19
+ #
20
+ # @return [Dry::Monads::Result]
21
+ def call(object)
22
+ return Success(object) unless object.respond_to?(:previous_admin_set_id)
23
+
24
+ old_template = Hyrax::PermissionTemplate.find_by(source_id: object.previous_admin_set_id)
25
+ new_template = Hyrax::PermissionTemplate.find_by(source_id: object.admin_set_id)
26
+
27
+ remove_old_grants(object, old_template, new_template) if old_template
28
+
29
+ if new_template
30
+ Hyrax::PermissionTemplateApplicator.apply(new_template).to(model: object)
31
+ else
32
+ Hyrax.logger.warn("At update time, #{object} doesn't have a " \
33
+ "PermissionTemplate for new AdministrativeSet " \
34
+ "#{object.admin_set_id}. Continuing without " \
35
+ "applying permissions.")
36
+ end
37
+
38
+ Success(object)
39
+ end
40
+
41
+ private
42
+
43
+ def remove_old_grants(object, old_template, new_template)
44
+ new_agents = agents_from_template(new_template)
45
+
46
+ object.edit_groups = object.edit_groups.to_a - (old_template.agent_ids_for(agent_type: 'group', access: 'manage') - new_agents[:manage_groups])
47
+ object.edit_users = object.edit_users.to_a - (old_template.agent_ids_for(agent_type: 'user', access: 'manage') - new_agents[:manage_users])
48
+ object.read_groups = object.read_groups.to_a - (old_template.agent_ids_for(agent_type: 'group', access: 'view') - new_agents[:view_groups])
49
+ object.read_users = object.read_users.to_a - (old_template.agent_ids_for(agent_type: 'user', access: 'view') - new_agents[:view_users])
50
+ end
51
+
52
+ def agents_from_template(template)
53
+ return { manage_groups: [], manage_users: [], view_groups: [], view_users: [] } if template.nil?
54
+
55
+ {
56
+ manage_groups: template.agent_ids_for(agent_type: 'group', access: 'manage').to_a,
57
+ manage_users: template.agent_ids_for(agent_type: 'user', access: 'manage').to_a,
58
+ view_groups: template.agent_ids_for(agent_type: 'group', access: 'view').to_a,
59
+ view_users: template.agent_ids_for(agent_type: 'user', access: 'view').to_a
60
+ }
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+ module Hyrax
3
+ module Transactions
4
+ module Steps
5
+ ##
6
+ # A `dry-transaction` step that moves a work's `Sipity::Entity` to the
7
+ # new admin set's active workflow when the admin set has changed during
8
+ # an update and both the old and new admin sets use workflow management.
9
+ #
10
+ # The entity's `workflow_state` is preserved by matching on state name:
11
+ # the new workflow's state with the same name is used when one exists,
12
+ # and the new workflow's initial state is used as a fallback (with a
13
+ # warning) when it does not.
14
+ #
15
+ # The depositor's existing `EntitySpecificResponsibility` is re-created
16
+ # against the new workflow's `depositing` role so it is not orphaned to
17
+ # a `WorkflowRole` from the prior workflow.
18
+ #
19
+ # No-ops when:
20
+ # * the admin set has not changed,
21
+ # * the new admin set has no active workflow (the entity is left in
22
+ # place, pointing at the prior workflow), or
23
+ # * the work has no `Sipity::Entity` yet (the prior admin set was not
24
+ # workflow-managed).
25
+ class ApplyWorkflowOnAdminSetChange
26
+ include Dry::Monads[:result]
27
+
28
+ ##
29
+ # @param [Hyrax::Work] object
30
+ #
31
+ # @return [Dry::Monads::Result]
32
+ def call(object)
33
+ return Success(object) unless object.respond_to?(:previous_admin_set_id)
34
+
35
+ entity = Sipity::Entity.find_by(proxy_for_global_id: Hyrax::GlobalID(object).to_s)
36
+ return Success(object) if entity.nil?
37
+
38
+ new_workflow = active_workflow_for(object.admin_set_id)
39
+ return Success(object) if new_workflow.nil?
40
+
41
+ move_entity_to_workflow(entity: entity, new_workflow: new_workflow, object: object)
42
+ reassign_depositor_responsibility(entity: entity, new_workflow: new_workflow, object: object)
43
+
44
+ Success(object)
45
+ end
46
+
47
+ private
48
+
49
+ def active_workflow_for(admin_set_id)
50
+ Sipity::Workflow.find_active_workflow_for(admin_set_id: admin_set_id)
51
+ rescue Sipity::Workflow::NoActiveWorkflowError
52
+ nil
53
+ end
54
+
55
+ def move_entity_to_workflow(entity:, new_workflow:, object:)
56
+ target_state = matching_state_on(new_workflow, entity.workflow_state_name) ||
57
+ fallback_initial_state(new_workflow, entity, object)
58
+ entity.update!(workflow: new_workflow, workflow_state: target_state)
59
+ end
60
+
61
+ def matching_state_on(workflow, state_name)
62
+ return nil if state_name.blank?
63
+ workflow.workflow_states.find_by(name: state_name)
64
+ end
65
+
66
+ def fallback_initial_state(new_workflow, entity, object)
67
+ Hyrax.logger.warn("Workflow state #{entity.workflow_state_name.inspect} from prior workflow " \
68
+ "does not exist on the new active workflow for AdministrativeSet " \
69
+ "#{object.admin_set_id}. Falling back to the initial state for work " \
70
+ "#{object.id}.")
71
+ new_workflow.initial_workflow_state
72
+ end
73
+
74
+ def reassign_depositor_responsibility(entity:, new_workflow:, object:)
75
+ depositor = ::User.find_by_user_key(object.depositor)
76
+ return if depositor.nil?
77
+
78
+ remove_stale_depositor_responsibility(entity: entity, new_workflow: new_workflow, depositor: depositor)
79
+
80
+ Hyrax::Workflow::PermissionGenerator.call(agents: depositor,
81
+ entity: entity,
82
+ roles: Hyrax::RoleRegistry::DEPOSITING,
83
+ workflow: new_workflow)
84
+ end
85
+
86
+ def remove_stale_depositor_responsibility(entity:, new_workflow:, depositor:)
87
+ depositor_agent = Sipity::Agent(depositor)
88
+ entity.entity_specific_responsibilities
89
+ .joins(:workflow_role)
90
+ .where(agent_id: depositor_agent.id)
91
+ .where.not(sipity_workflow_roles: { workflow_id: new_workflow.id })
92
+ .destroy_all
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -15,7 +15,7 @@ module Hyrax
15
15
  # @return [Dry::Monads::Result] `Failure` if there is no `AdminSet` for
16
16
  # the input; `Success(input)`, otherwise.
17
17
  def call(obj)
18
- obj.admin_set_id ? Success(obj) : Failure(:no_admin_set_id)
18
+ obj.admin_set_id.to_s.present? ? Success(obj) : Failure(:no_admin_set_id)
19
19
  end
20
20
  end
21
21
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ require 'dry/monads'
3
+
4
+ module Hyrax
5
+ module Transactions
6
+ module Steps
7
+ # A `dry-transaction` step that removes a resource's rows from the
8
+ # `hyrax_redirect_paths` redirects table. Runs as part of the destroy
9
+ # transactions so deleted resources don't leave dangling claims on
10
+ # redirect paths.
11
+ #
12
+ # See documentation/redirects.md.
13
+ class RemoveRedirectPaths
14
+ include Dry::Monads[:result]
15
+
16
+ # @param [Valkyrie::Resource] resource
17
+ # @return [Dry::Monads::Result]
18
+ def call(resource)
19
+ return Success(resource) unless removable?(resource)
20
+ Hyrax::RedirectPath.where(resource_id: resource.id.to_s).delete_all
21
+ Success(resource)
22
+ rescue ActiveRecord::StatementInvalid => e
23
+ Hyrax.logger.error("[redirects] remove_redirect_paths failed: #{e.message}")
24
+ Failure([:redirect_path_remove_error, e.message])
25
+ end
26
+
27
+ private
28
+
29
+ def removable?(resource)
30
+ Hyrax.config.redirects_enabled? && resource.respond_to?(:id) && resource.id.present?
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -35,6 +35,7 @@ module Hyrax
35
35
  valid_future_date?(change_set.lease, 'lease_expiration_date') if change_set.respond_to?(:lease) && change_set.lease
36
36
  valid_future_date?(change_set.embargo, 'embargo_release_date') if change_set.respond_to?(:embargo) && change_set.embargo
37
37
  new_collections = changed_collection_membership(change_set)
38
+ old_admin_set_id = changed_admin_set_id(change_set)
38
39
 
39
40
  unsaved = change_set.sync
40
41
  save_lease_or_embargo(unsaved)
@@ -50,6 +51,8 @@ module Hyrax
50
51
 
51
52
  user ||= ::User.find_by_user_key(saved.depositor)
52
53
 
54
+ saved.define_singleton_method(:previous_admin_set_id) { old_admin_set_id } if old_admin_set_id
55
+
53
56
  publish_changes(resource: saved, user: user, new: unsaved.new_record, new_collections: new_collections)
54
57
  Success(saved)
55
58
  end
@@ -83,6 +86,13 @@ module Hyrax
83
86
  change_set.member_of_collection_ids - change_set.model.member_of_collection_ids
84
87
  end
85
88
 
89
+ def changed_admin_set_id(change_set)
90
+ return nil unless change_set.respond_to?(:admin_set_id) &&
91
+ change_set.changed?(:admin_set_id)
92
+
93
+ change_set.model.admin_set_id
94
+ end
95
+
86
96
  def publish_changes(resource:, user:, new: false, new_collections: [])
87
97
  if resource.collection?
88
98
  @publisher.publish('collection.metadata.updated', collection: resource, user: user)
@@ -16,7 +16,7 @@ module Hyrax
16
16
  #
17
17
  # @return [Dry::Monads::Result]
18
18
  def call(obj)
19
- obj.admin_set_id ||= Hyrax::EnsureWellFormedAdminSetService.call
19
+ obj.admin_set_id = Hyrax::EnsureWellFormedAdminSetService.call if obj.admin_set_id.to_s.blank?
20
20
 
21
21
  Success(obj)
22
22
  end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+ require 'dry/monads'
3
+
4
+ module Hyrax
5
+ module Transactions
6
+ module Steps
7
+ # A `dry-transaction` step that mirrors a saved resource's `redirects`
8
+ # entries into the `hyrax_redirect_paths` redirects table. The unique
9
+ # index on `from_path` enforces global uniqueness at the DB level — if
10
+ # a concurrent save already claimed a path, the insert raises
11
+ # ActiveRecord::RecordNotUnique and this step returns Failure, which
12
+ # short-circuits the enclosing transaction.
13
+ #
14
+ # Every row carries the resource's canonical UUID URL in
15
+ # `permalink_path`. Column semantics:
16
+ #
17
+ # - `from_path` — the URL the visitor entered (an alias or the UUID
18
+ # URL itself).
19
+ # - `to_path` — the URL the address bar should display after the
20
+ # resolver routes the request. For the display row, equals its own
21
+ # `from_path` (the visitor stays at the display URL). For
22
+ # non-display rows, points at the display row's `from_path` (the
23
+ # visitor lands at the user-facing display URL). When no entry is
24
+ # marked, every alias's `to_path` is the UUID URL.
25
+ # - `permalink_path` — the resource's canonical UUID URL. Constant
26
+ # per resource across all rows.
27
+ #
28
+ # When a display URL is set, the sync step also writes an extra row
29
+ # with `from_path = permalink_path` so visitors hitting the bare
30
+ # UUID URL are routed to the display alias.
31
+ #
32
+ # No-op when the redirects feature is off (config or Flipflop) or when
33
+ # the resource doesn't carry the redirects attribute.
34
+ #
35
+ # See documentation/redirects.md.
36
+ class SyncRedirectPaths
37
+ include Dry::Monads[:result]
38
+
39
+ # @param [Valkyrie::Resource] object the saved resource (must have an id)
40
+ # @return [Dry::Monads::Result]
41
+ def call(object)
42
+ return Success(object) unless syncable?(object)
43
+ replace_rows(object, build_rows(object))
44
+ Success(object)
45
+ rescue ActiveRecord::RecordNotUnique => e
46
+ Failure([:redirect_path_collision, e.message])
47
+ rescue ActiveRecord::StatementInvalid => e
48
+ Hyrax.logger.error("[redirects] sync_redirect_paths failed: #{e.message}")
49
+ Failure([:redirect_path_sync_error, e.message])
50
+ end
51
+
52
+ private
53
+
54
+ def syncable?(object)
55
+ return false unless Hyrax.config.redirects_active?
56
+ object.respond_to?(:redirects) && object.respond_to?(:id) && object.id.present?
57
+ end
58
+
59
+ def build_rows(object)
60
+ permalink = Hyrax::PermalinkPath.call(object)
61
+ entries = entries_for(object)
62
+ display_path = entries.find { |e| e[:is_display_url] }&.dig(:from_path)
63
+ resource_id = object.id.to_s
64
+ now = Time.current
65
+ alias_rows = entries.map { |entry| build_alias_row(entry, resource_id, permalink, display_path, now) }
66
+ alias_rows << build_permalink_row(resource_id, permalink, display_path, now) if display_path
67
+ alias_rows
68
+ end
69
+
70
+ # Valkyrie's JSONValueMapper symbolizes hash keys on read; accept either.
71
+ # Paths are normalized at write time by Hyrax::RedirectsNormalization.
72
+ def entries_for(object)
73
+ seen = Set.new
74
+ Array(object.redirects).each_with_object([]) do |entry, acc|
75
+ path = entry['path'] || entry[:path]
76
+ next if path.blank? || seen.include?(path)
77
+ seen << path
78
+ acc << { from_path: path, is_display_url: display_url_flag(entry) }
79
+ end
80
+ end
81
+
82
+ # Boolean-cast the stored value so importer/console writes that leave a
83
+ # string like "false" or "0" in the JSONB hash don't end up as truthy.
84
+ # Returns false when the key is absent.
85
+ def display_url_flag(entry)
86
+ raw = if entry.key?('is_display_url')
87
+ entry['is_display_url']
88
+ elsif entry.key?(:is_display_url)
89
+ entry[:is_display_url]
90
+ end
91
+ ActiveModel::Type::Boolean.new.cast(raw) || false
92
+ end
93
+
94
+ def build_alias_row(entry, resource_id, permalink, display_path, now)
95
+ to_path = if entry[:is_display_url]
96
+ entry[:from_path]
97
+ elsif display_path
98
+ display_path
99
+ else
100
+ permalink
101
+ end
102
+ { from_path: entry[:from_path],
103
+ to_path: to_path,
104
+ permalink_path: permalink,
105
+ resource_id: resource_id,
106
+ is_display_url: entry[:is_display_url],
107
+ created_at: now, updated_at: now }
108
+ end
109
+
110
+ def build_permalink_row(resource_id, permalink, display_path, now)
111
+ { from_path: permalink,
112
+ to_path: display_path,
113
+ permalink_path: permalink,
114
+ resource_id: resource_id,
115
+ is_display_url: false,
116
+ created_at: now, updated_at: now }
117
+ end
118
+
119
+ # Replaces the resource's rows when the set differs from what's
120
+ # persisted. Skips the rewrite when the desired and existing rows
121
+ # match (the common case on an update that didn't touch the
122
+ # redirects attribute), to preserve `created_at` and avoid an
123
+ # unnecessary DB transaction.
124
+ def replace_rows(object, rows)
125
+ desired = rows.map { |r| [r[:from_path], r[:to_path], r[:is_display_url]] }.sort
126
+
127
+ Hyrax::RedirectPath.transaction do
128
+ existing = Hyrax::RedirectPath.where(resource_id: object.id.to_s)
129
+ .pluck(:from_path, :to_path, :is_display_url)
130
+ return if desired == existing.sort
131
+
132
+ Hyrax::RedirectPath.where(resource_id: object.id.to_s).delete_all
133
+ # rubocop:disable Rails/SkipsModelValidations -- the DB unique index on `from_path` is the validation we rely on; bulk insert is intentional
134
+ Hyrax::RedirectPath.insert_all!(rows) if rows.any?
135
+ # rubocop:enable Rails/SkipsModelValidations
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -16,7 +16,8 @@ module Hyrax
16
16
  'work_resource.save_acl',
17
17
  'work_resource.add_file_sets',
18
18
  'work_resource.change_depositor',
19
- 'work_resource.add_to_parent'].freeze
19
+ 'work_resource.add_to_parent',
20
+ 'work_resource.sync_redirect_paths'].freeze
20
21
 
21
22
  ##
22
23
  # @see Hyrax::Transactions::Transaction
@@ -10,6 +10,7 @@ module Hyrax
10
10
  class WorkDestroy < Transaction
11
11
  DEFAULT_STEPS = ['work_resource.delete_all_file_sets',
12
12
  'work_resource.delete_acl',
13
+ 'work_resource.remove_redirect_paths',
13
14
  'work_resource.delete'].freeze
14
15
 
15
16
  ##
@@ -5,9 +5,12 @@ module Hyrax
5
5
  # @since 3.4.0
6
6
  class WorkUpdate < Transaction
7
7
  DEFAULT_STEPS = ['change_set.apply',
8
+ 'work_resource.apply_permission_template_on_update',
9
+ 'work_resource.apply_workflow_on_admin_set_change',
8
10
  'work_resource.save_acl',
9
11
  'work_resource.add_file_sets',
10
- 'work_resource.update_work_members'].freeze
12
+ 'work_resource.update_work_members',
13
+ 'work_resource.sync_redirect_paths'].freeze
11
14
 
12
15
  ##
13
16
  # @see Hyrax::Transactions::Transaction
data/lib/hyrax/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Hyrax
3
- VERSION = '5.1.0'
3
+ VERSION = '5.3.0'
4
4
  end