hyrax 3.0.1 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (388) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +49 -19
  3. data/.dassie/.env +1 -2
  4. data/.dassie/Gemfile +18 -9
  5. data/.dassie/app/controllers/catalog_controller.rb +6 -0
  6. data/.dassie/app/models/user.rb +0 -2
  7. data/.dassie/config/analytics.yml +12 -5
  8. data/.dassie/config/environments/development.rb +2 -0
  9. data/.dassie/config/initializers/hyrax.rb +7 -0
  10. data/.dassie/config/role_map.yml +2 -0
  11. data/.dassie/db/migrate/20210921150120_enable_uuid_extension.valkyrie_engine.rb +7 -0
  12. data/.dassie/db/migrate/20210921150121_create_orm_resources.valkyrie_engine.rb +19 -0
  13. data/.dassie/db/migrate/20210921150122_add_model_type_to_orm_resources.valkyrie_engine.rb +7 -0
  14. data/.dassie/db/migrate/20210921150123_change_model_type_to_internal_model.valkyrie_engine.rb +7 -0
  15. data/.dassie/db/migrate/20210921150124_create_path_gin_index.valkyrie_engine.rb +7 -0
  16. data/.dassie/db/migrate/20210921150125_create_internal_resource_index.valkyrie_engine.rb +7 -0
  17. data/.dassie/db/migrate/20210921150126_create_updated_at_index.valkyrie_engine.rb +7 -0
  18. data/.dassie/db/migrate/20210921150127_add_optimistic_locking_to_orm_resources.valkyrie_engine.rb +7 -0
  19. data/.dassie/db/migrate/20211130181150_create_default_administrative_set.rb +8 -0
  20. data/.dassie/db/schema.rb +20 -1
  21. data/.dassie/db/seeds.rb +1 -1
  22. data/.dockerignore +3 -0
  23. data/.env +8 -6
  24. data/.github/workflows/main.yml +17 -0
  25. data/.github/workflows/release.yml +17 -0
  26. data/.gitignore +1 -0
  27. data/.regen +1 -1
  28. data/.rubocop.yml +4 -0
  29. data/CONTAINERS.md +33 -10
  30. data/Dockerfile +14 -9
  31. data/Gemfile +21 -27
  32. data/README.md +37 -0
  33. data/app/actors/hyrax/actors/base_actor.rb +2 -2
  34. data/app/actors/hyrax/actors/collections_membership_actor.rb +3 -3
  35. data/app/actors/hyrax/actors/create_with_remote_files_actor.rb +85 -63
  36. data/app/actors/hyrax/actors/create_with_remote_files_ordered_members_actor.rb +7 -42
  37. data/app/actors/hyrax/actors/file_set_actor.rb +12 -5
  38. data/app/assets/javascripts/hyrax/admin/graphs.es6 +34 -37
  39. data/app/assets/javascripts/hyrax/analytics_events.js +69 -0
  40. data/app/assets/javascripts/hyrax/collapse.js +24 -0
  41. data/app/assets/javascripts/hyrax/collections.js +1 -2
  42. data/app/assets/javascripts/hyrax/ga_events.js +2 -8
  43. data/app/assets/javascripts/hyrax/reports-buttons.js +33 -0
  44. data/app/assets/javascripts/hyrax.js +2 -1
  45. data/app/assets/stylesheets/_bootstrap-default-overrides.scss +9 -0
  46. data/app/assets/stylesheets/hyrax/_styles.scss +5 -0
  47. data/app/authorities/qa/authorities/collections.rb +4 -5
  48. data/app/authorities/qa/authorities/find_works.rb +1 -1
  49. data/app/controllers/concerns/hyrax/breadcrumbs_for_collection_analytics.rb +26 -0
  50. data/app/controllers/concerns/hyrax/breadcrumbs_for_works_analytics.rb +26 -0
  51. data/app/controllers/concerns/hyrax/collections_controller_behavior.rb +30 -10
  52. data/app/controllers/concerns/hyrax/controller.rb +35 -2
  53. data/app/controllers/concerns/hyrax/embargoes_controller_behavior.rb +21 -9
  54. data/app/controllers/concerns/hyrax/leases_controller_behavior.rb +14 -5
  55. data/app/controllers/concerns/hyrax/works_controller_behavior.rb +22 -3
  56. data/app/controllers/hyrax/admin/admin_sets_controller.rb +2 -19
  57. data/app/controllers/hyrax/admin/analytics/analytics_controller.rb +40 -0
  58. data/app/controllers/hyrax/admin/analytics/collection_reports_controller.rb +61 -0
  59. data/app/controllers/hyrax/admin/analytics/work_reports_controller.rb +122 -0
  60. data/app/controllers/hyrax/admin/permission_template_accesses_controller.rb +5 -6
  61. data/app/controllers/hyrax/admin/workflows_controller.rb +8 -2
  62. data/app/controllers/hyrax/collections_controller.rb +6 -1
  63. data/app/controllers/hyrax/dashboard/collection_members_controller.rb +24 -17
  64. data/app/controllers/hyrax/dashboard/collections_controller.rb +112 -37
  65. data/app/controllers/hyrax/dashboard/nest_collections_controller.rb +75 -39
  66. data/app/controllers/hyrax/dashboard_controller.rb +8 -0
  67. data/app/controllers/hyrax/file_sets_controller.rb +49 -13
  68. data/app/controllers/hyrax/my_controller.rb +4 -4
  69. data/app/controllers/hyrax/permissions_controller.rb +3 -4
  70. data/app/controllers/hyrax/stats_controller.rb +3 -1
  71. data/app/controllers/hyrax/workflow_actions_controller.rb +11 -6
  72. data/app/forms/hyrax/forms/administrative_set_form.rb +62 -0
  73. data/app/forms/hyrax/forms/collection_form.rb +9 -5
  74. data/app/forms/hyrax/forms/dashboard/nest_collection_form.rb +38 -6
  75. data/app/forms/hyrax/forms/file_set_form.rb +46 -0
  76. data/app/forms/hyrax/forms/pcdm_collection_form.rb +67 -0
  77. data/app/forms/hyrax/forms/permission.rb +23 -0
  78. data/app/forms/hyrax/forms/permission_template_form.rb +8 -2
  79. data/app/forms/hyrax/forms/resource_form.rb +34 -26
  80. data/app/forms/hyrax/forms/work_form.rb +5 -2
  81. data/app/forms/hyrax/forms/workflow_action_form.rb +4 -0
  82. data/app/helpers/hyrax/batch_edits_helper.rb +3 -1
  83. data/app/helpers/hyrax/collections_helper.rb +88 -2
  84. data/app/helpers/hyrax/dashboard_helper_behavior.rb +16 -5
  85. data/app/helpers/hyrax/embargo_helper.rb +4 -0
  86. data/app/helpers/hyrax/file_set_helper.rb +25 -6
  87. data/app/helpers/hyrax/hyrax_helper_behavior.rb +9 -0
  88. data/app/helpers/hyrax/lease_helper.rb +4 -0
  89. data/app/helpers/hyrax/url_helper.rb +4 -1
  90. data/app/helpers/hyrax/work_form_helper.rb +53 -0
  91. data/app/indexers/hyrax/administrative_set_indexer.rb +18 -0
  92. data/app/indexers/hyrax/pcdm_collection_indexer.rb +2 -0
  93. data/app/indexers/hyrax/valkyrie_file_set_indexer.rb +3 -1
  94. data/app/indexers/hyrax/valkyrie_indexer.rb +3 -3
  95. data/app/indexers/hyrax/valkyrie_work_indexer.rb +1 -1
  96. data/app/inputs/controlled_vocabulary_input.rb +2 -5
  97. data/app/jobs/attach_files_to_work_job.rb +19 -10
  98. data/app/jobs/attach_files_to_work_with_ordered_members_job.rb +6 -5
  99. data/app/jobs/characterize_job.rb +28 -1
  100. data/app/jobs/ingest_local_file_job.rb +18 -2
  101. data/app/jobs/inherit_permissions_job.rb +9 -5
  102. data/app/jobs/valkyrie_ingest_job.rb +56 -0
  103. data/app/models/admin_set.rb +22 -30
  104. data/app/models/collection_branding_info.rb +25 -9
  105. data/app/models/concerns/hyrax/ability/admin_set_ability.rb +31 -7
  106. data/app/models/concerns/hyrax/ability/collection_ability.rb +35 -20
  107. data/app/models/concerns/hyrax/ability/collection_type_ability.rb +1 -1
  108. data/app/models/concerns/hyrax/ability.rb +31 -8
  109. data/app/models/concerns/hyrax/collection_behavior.rb +17 -44
  110. data/app/models/concerns/hyrax/embargoable.rb +24 -0
  111. data/app/models/concerns/hyrax/file_set/characterization.rb +18 -12
  112. data/app/models/concerns/hyrax/solr_document/metadata.rb +1 -0
  113. data/app/models/concerns/hyrax/solr_document_behavior.rb +11 -54
  114. data/app/models/concerns/hyrax/suppressible.rb +5 -0
  115. data/app/models/concerns/hyrax/user.rb +9 -3
  116. data/app/models/concerns/hyrax/work_behavior.rb +1 -1
  117. data/app/models/file_download_stat.rb +4 -4
  118. data/app/models/hyrax/administrative_set.rb +7 -1
  119. data/app/models/hyrax/default_administrative_set.rb +42 -0
  120. data/app/models/hyrax/file_set.rb +6 -0
  121. data/app/models/hyrax/pcdm_collection.rb +1 -0
  122. data/app/models/hyrax/permission.rb +1 -1
  123. data/app/models/hyrax/permission_template.rb +112 -12
  124. data/app/models/hyrax/statistic.rb +31 -4
  125. data/app/models/hyrax/virus_scanner.rb +27 -18
  126. data/app/models/hyrax/work.rb +1 -0
  127. data/app/models/hyrax/workflow_action_info.rb +16 -0
  128. data/app/models/sipity/agent.rb +1 -0
  129. data/app/models/sipity/comment.rb +17 -0
  130. data/app/models/sipity/entity.rb +30 -8
  131. data/app/models/sipity/workflow.rb +1 -0
  132. data/app/models/sipity.rb +53 -2
  133. data/app/presenters/hyrax/admin/dashboard_presenter.rb +8 -6
  134. data/app/presenters/hyrax/admin/repository_growth_presenter.rb +10 -5
  135. data/app/presenters/hyrax/admin/user_activity_presenter.rb +8 -12
  136. data/app/presenters/hyrax/admin_set_options_presenter.rb +12 -8
  137. data/app/presenters/hyrax/admin_set_presenter.rb +13 -4
  138. data/app/presenters/hyrax/admin_set_selection_presenter.rb +116 -0
  139. data/app/presenters/hyrax/collection_presenter.rb +34 -9
  140. data/app/presenters/hyrax/file_set_presenter.rb +8 -1
  141. data/app/presenters/hyrax/file_usage.rb +3 -2
  142. data/app/presenters/hyrax/menu_presenter.rb +4 -0
  143. data/app/presenters/hyrax/pcdm_member_presenter_factory.rb +119 -0
  144. data/app/presenters/hyrax/stats_usage_presenter.rb +2 -1
  145. data/app/presenters/hyrax/trophy_presenter.rb +33 -4
  146. data/app/presenters/hyrax/user_profile_presenter.rb +11 -1
  147. data/app/presenters/hyrax/version_list_presenter.rb +19 -0
  148. data/app/presenters/hyrax/version_presenter.rb +3 -2
  149. data/app/presenters/hyrax/work_show_presenter.rb +37 -8
  150. data/app/presenters/hyrax/work_usage.rb +6 -3
  151. data/app/renderers/hyrax/renderers/attribute_renderer.rb +10 -2
  152. data/app/search_builders/hyrax/README.md +1 -1
  153. data/app/search_builders/hyrax/abstract_type_relation.rb +4 -2
  154. data/app/search_builders/hyrax/admin_set_search_builder.rb +1 -1
  155. data/app/search_builders/hyrax/collection_member_search_builder.rb +6 -1
  156. data/app/search_builders/hyrax/dashboard/collections_search_builder.rb +1 -1
  157. data/app/search_builders/hyrax/exposed_models_relation.rb +1 -1
  158. data/app/search_builders/hyrax/filter_by_type.rb +1 -2
  159. data/app/search_builders/hyrax/my/collections_search_builder.rb +2 -2
  160. data/app/search_builders/hyrax/nested_collections_parent_search_builder.rb +1 -1
  161. data/app/search_builders/hyrax/single_collection_search_builder.rb +1 -1
  162. data/app/services/hyrax/admin_set_create_service.rb +199 -53
  163. data/app/services/hyrax/analytics/google/events.rb +37 -0
  164. data/app/services/hyrax/analytics/google/events_daily.rb +72 -0
  165. data/app/services/hyrax/analytics/google/visits.rb +44 -0
  166. data/app/services/hyrax/analytics/google/visits_daily.rb +49 -0
  167. data/app/services/hyrax/analytics/google.rb +204 -0
  168. data/app/services/hyrax/analytics/matomo.rb +193 -0
  169. data/app/services/hyrax/analytics/results.rb +79 -0
  170. data/app/services/hyrax/analytics.rb +12 -82
  171. data/app/services/hyrax/characterization/valkyrie_characterization_service.rb +134 -0
  172. data/app/services/hyrax/collection_types/permissions_service.rb +1 -1
  173. data/app/services/hyrax/collections/collection_member_search_service.rb +72 -0
  174. data/app/services/hyrax/collections/collection_member_service.rb +122 -27
  175. data/app/services/hyrax/collections/migration_service.rb +4 -2
  176. data/app/services/hyrax/collections/nested_collection_persistence_service.rb +12 -13
  177. data/app/services/hyrax/collections/nested_collection_query_service.rb +10 -3
  178. data/app/services/hyrax/collections/permissions_create_service.rb +82 -78
  179. data/app/services/hyrax/collections/permissions_service.rb +1 -1
  180. data/app/services/hyrax/contextual_path.rb +24 -1
  181. data/app/services/hyrax/curation_concern.rb +24 -2
  182. data/app/services/hyrax/custom_queries/find_file_metadata.rb +7 -5
  183. data/app/services/hyrax/custom_queries/navigators/parent_collections_navigator.rb +46 -0
  184. data/app/services/hyrax/default_middleware_stack.rb +11 -0
  185. data/app/services/hyrax/edit_permissions_service.rb +74 -41
  186. data/app/services/hyrax/ensure_well_formed_admin_set_service.rb +3 -3
  187. data/app/services/hyrax/find_objects_via_solr_service.rb +31 -0
  188. data/app/services/hyrax/listeners/acl_index_listener.rb +3 -1
  189. data/app/services/hyrax/listeners/active_fedora_acl_index_listener.rb +4 -1
  190. data/app/services/hyrax/listeners/batch_notification_listener.rb +3 -1
  191. data/app/services/hyrax/listeners/file_metadata_listener.rb +19 -0
  192. data/app/services/hyrax/listeners/file_set_lifecycle_listener.rb +6 -2
  193. data/app/services/hyrax/listeners/file_set_lifecycle_notification_listener.rb +6 -2
  194. data/app/services/hyrax/listeners/member_cleanup_listener.rb +3 -0
  195. data/app/services/hyrax/listeners/metadata_index_listener.rb +33 -11
  196. data/app/services/hyrax/listeners/object_lifecycle_listener.rb +9 -3
  197. data/app/services/hyrax/listeners/proxy_deposit_listener.rb +3 -1
  198. data/app/services/hyrax/listeners/trophy_cleanup_listener.rb +3 -0
  199. data/app/services/hyrax/listeners/workflow_listener.rb +3 -1
  200. data/app/services/hyrax/listeners.rb +8 -0
  201. data/app/services/hyrax/multiple_membership_checker.rb +53 -29
  202. data/app/services/hyrax/permission_manager.rb +4 -4
  203. data/app/services/hyrax/resource_status.rb +7 -0
  204. data/app/services/hyrax/restriction_service.rb +4 -0
  205. data/app/services/hyrax/search_service.rb +4 -2
  206. data/app/services/hyrax/solr_query_builder_service.rb +45 -8
  207. data/app/services/hyrax/solr_query_service.rb +224 -0
  208. data/app/services/hyrax/solr_service.rb +9 -2
  209. data/app/services/hyrax/statistics/collections/over_time.rb +2 -1
  210. data/app/services/hyrax/statistics/depositors/summary.rb +2 -1
  211. data/app/services/hyrax/statistics/users/over_time.rb +8 -5
  212. data/app/services/hyrax/statistics/works/over_time.rb +10 -0
  213. data/app/services/hyrax/visibility_intention.rb +20 -2
  214. data/app/services/hyrax/work_uploads_handler.rb +21 -3
  215. data/app/services/hyrax/workflow/abstract_notification.rb +2 -2
  216. data/app/services/hyrax/workflow/action_taken_service.rb +16 -4
  217. data/app/services/hyrax/workflow/actionable_objects.rb +70 -0
  218. data/app/services/hyrax/workflow/activate_object.rb +5 -4
  219. data/app/services/hyrax/workflow/changes_required_notification.rb +5 -4
  220. data/app/services/hyrax/workflow/deactivate_object.rb +7 -5
  221. data/app/services/hyrax/workflow/deposited_notification.rb +8 -4
  222. data/app/services/hyrax/workflow/grant_edit_to_depositor.rb +7 -3
  223. data/app/services/hyrax/workflow/grant_read_to_depositor.rb +10 -3
  224. data/app/services/hyrax/workflow/object_in_workflow_decorator.rb +31 -0
  225. data/app/services/hyrax/workflow/revoke_edit_from_depositor.rb +8 -2
  226. data/app/services/hyrax/workflow/status_list_service.rb +43 -13
  227. data/app/services/hyrax/workflow/workflow_action_service.rb +4 -1
  228. data/app/views/hyrax/admin/admin_sets/_form.html.erb +1 -1
  229. data/app/views/hyrax/admin/analytics/_date_range_form.html.erb +11 -0
  230. data/app/views/hyrax/admin/analytics/collection_reports/_custom_range.html.erb +39 -0
  231. data/app/views/hyrax/admin/analytics/collection_reports/_monthly_summary.html.erb +48 -0
  232. data/app/views/hyrax/admin/analytics/collection_reports/_summary.html.erb +55 -0
  233. data/app/views/hyrax/admin/analytics/collection_reports/_top_collections.html.erb +55 -0
  234. data/app/views/hyrax/admin/analytics/collection_reports/index.html.erb +70 -0
  235. data/app/views/hyrax/admin/analytics/collection_reports/show.html.erb +94 -0
  236. data/app/views/hyrax/admin/analytics/work_reports/_custom_range.html.erb +43 -0
  237. data/app/views/hyrax/admin/analytics/work_reports/_monthly_summary.html.erb +35 -0
  238. data/app/views/hyrax/admin/analytics/work_reports/_summary.html.erb +60 -0
  239. data/app/views/hyrax/admin/analytics/work_reports/_top_file_set_downloads.html.erb +33 -0
  240. data/app/views/hyrax/admin/analytics/work_reports/_top_works.html.erb +40 -0
  241. data/app/views/hyrax/admin/analytics/work_reports/_work_counts.html.erb +18 -0
  242. data/app/views/hyrax/admin/analytics/work_reports/_work_files.html.erb +41 -0
  243. data/app/views/hyrax/admin/analytics/work_reports/index.html.erb +77 -0
  244. data/app/views/hyrax/admin/analytics/work_reports/show.html.erb +90 -0
  245. data/app/views/hyrax/admin/stats/show.html.erb +1 -1
  246. data/app/views/hyrax/base/_form_child_work_relationships.html.erb +1 -1
  247. data/app/views/hyrax/base/_form_relationships.html.erb +1 -2
  248. data/app/views/hyrax/base/_form_rendering.html.erb +1 -1
  249. data/app/views/hyrax/base/_form_representative.html.erb +1 -1
  250. data/app/views/hyrax/base/_form_thumbnail.html.erb +1 -1
  251. data/app/views/hyrax/base/_form_visibility_error.html.erb +2 -0
  252. data/app/views/hyrax/base/_guts4form.html.erb +3 -3
  253. data/app/views/hyrax/base/_relationships_parent_row.html.erb +0 -1
  254. data/app/views/hyrax/base/_representative_media.html.erb +1 -1
  255. data/app/views/hyrax/base/_show_actions.html.erb +2 -2
  256. data/app/views/hyrax/base/_work_button_row.html.erb +1 -1
  257. data/app/views/hyrax/base/show.html.erb +6 -0
  258. data/app/views/hyrax/batch_uploads/_form.html.erb +1 -1
  259. data/app/views/hyrax/collections/show.html.erb +4 -0
  260. data/app/views/hyrax/dashboard/_repository_growth.html.erb +5 -5
  261. data/app/views/hyrax/dashboard/_resource_type_graph.html.erb +41 -0
  262. data/app/views/hyrax/dashboard/_sidebar.html.erb +4 -1
  263. data/app/views/hyrax/dashboard/_tabs.html.erb +11 -0
  264. data/app/views/hyrax/dashboard/_user_activity.html.erb +17 -23
  265. data/app/views/hyrax/dashboard/_user_activity_graph.html.erb +55 -0
  266. data/app/views/hyrax/dashboard/_visibility_graph.html.erb +31 -0
  267. data/app/views/hyrax/dashboard/_work_type_graph.html.erb +41 -0
  268. data/app/views/hyrax/dashboard/collections/_collection_title.html.erb +1 -1
  269. data/app/views/hyrax/dashboard/collections/_form.html.erb +6 -5
  270. data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +1 -1
  271. data/app/views/hyrax/dashboard/collections/_sort_and_per_page.html.erb +1 -1
  272. data/app/views/hyrax/dashboard/collections/edit.html.erb +4 -2
  273. data/app/views/hyrax/dashboard/collections/new.html.erb +4 -2
  274. data/app/views/hyrax/dashboard/collections/show.html.erb +1 -1
  275. data/app/views/hyrax/dashboard/show_admin.html.erb +24 -45
  276. data/app/views/hyrax/dashboard/sidebar/_activity.html.erb +22 -0
  277. data/app/views/hyrax/file_sets/_actions.html.erb +4 -3
  278. data/app/views/hyrax/file_sets/edit.html.erb +1 -1
  279. data/app/views/hyrax/file_sets/media_display/_audio.html.erb +1 -1
  280. data/app/views/hyrax/file_sets/media_display/_default.html.erb +1 -1
  281. data/app/views/hyrax/file_sets/media_display/_image.html.erb +1 -1
  282. data/app/views/hyrax/file_sets/media_display/_office_document.html.erb +1 -1
  283. data/app/views/hyrax/file_sets/media_display/_pdf.html.erb +1 -1
  284. data/app/views/hyrax/file_sets/media_display/_video.html.erb +1 -1
  285. data/app/views/hyrax/file_sets/show.html.erb +7 -1
  286. data/app/views/hyrax/homepage/index.html.erb +1 -1
  287. data/app/views/hyrax/my/_admin_set_action_menu.html.erb +0 -11
  288. data/app/views/hyrax/my/_collection_action_menu.html.erb +1 -2
  289. data/app/views/hyrax/my/collections/_list_collections.html.erb +1 -1
  290. data/app/views/hyrax/my/collections/_modal_add_subcollection.html.erb +3 -5
  291. data/app/views/hyrax/my/collections/_modal_collection_types_to_create.html.erb +1 -1
  292. data/app/views/hyrax/my/collections/index.html.erb +1 -1
  293. data/app/views/hyrax/stats/_downloads.html.erb +18 -0
  294. data/app/views/hyrax/stats/_pageviews.html.erb +18 -0
  295. data/app/views/hyrax/stats/work.html.erb +17 -9
  296. data/app/views/layouts/_head_tag_content.html.erb +7 -2
  297. data/app/views/layouts/hyrax/dashboard.html.erb +1 -0
  298. data/app/views/layouts/hyrax.html.erb +1 -0
  299. data/app/views/{_ga.html.erb → shared/_ga.html.erb} +3 -7
  300. data/app/views/shared/_matomo.html.erb +15 -0
  301. data/app/views/shared/_read_only.html.erb +5 -0
  302. data/bin/db-migrate-seed.sh +3 -1
  303. data/bin/hyrax-entrypoint.sh +0 -14
  304. data/bin/solrcloud-assign-configset.sh +11 -3
  305. data/bin/solrcloud-upload-configset.sh +17 -6
  306. data/chart/hyrax/Chart.yaml +9 -5
  307. data/chart/hyrax/README.md +52 -5
  308. data/chart/hyrax/templates/_helpers.tpl +15 -1
  309. data/chart/hyrax/templates/branding-pvc.yaml +2 -2
  310. data/chart/hyrax/templates/configmap-env.yaml +6 -2
  311. data/chart/hyrax/templates/deployment-worker.yaml +42 -5
  312. data/chart/hyrax/templates/deployment.yaml +53 -0
  313. data/chart/hyrax/templates/derivatives-pvc.yaml +2 -2
  314. data/chart/hyrax/templates/ingress.yaml +13 -4
  315. data/chart/hyrax/templates/secrets.yaml +8 -0
  316. data/chart/hyrax/templates/uploads-pvc.yaml +2 -2
  317. data/chart/hyrax/values.yaml +84 -2
  318. data/config/brakeman.ignore +2 -2
  319. data/config/features.rb +3 -0
  320. data/config/i18n-tasks.yml +2 -2
  321. data/config/initializers/1_healthz.rb +1 -0
  322. data/config/initializers/listeners.rb +5 -4
  323. data/config/initializers/valkryrie_storage.rb +7 -0
  324. data/config/locales/hyrax.de.yml +195 -1
  325. data/config/locales/hyrax.en.yml +192 -13
  326. data/config/locales/hyrax.es.yml +195 -1
  327. data/config/locales/hyrax.fr.yml +195 -1
  328. data/config/locales/hyrax.it.yml +195 -1
  329. data/config/locales/hyrax.pt-BR.yml +195 -1
  330. data/config/locales/hyrax.zh.yml +195 -1
  331. data/config/routes.rb +4 -0
  332. data/db/seeds.rb +1 -1
  333. data/docker-compose.yml +42 -9
  334. data/documentation/developing-your-hyrax-based-app.md +4 -4
  335. data/documentation/legacyREADME.md +4 -4
  336. data/hyrax.gemspec +4 -2
  337. data/lib/generators/hyrax/templates/catalog_controller.rb +3 -1
  338. data/lib/generators/hyrax/templates/config/analytics.yml +13 -7
  339. data/lib/generators/hyrax/templates/config/initializers/hyrax.rb +15 -13
  340. data/lib/generators/hyrax/templates/db/migrate/20211130181150_create_default_administrative_set.rb.erb +8 -0
  341. data/lib/generators/hyrax/work/templates/feature_spec.rb.erb +4 -2
  342. data/lib/generators/hyrax/work_resource/templates/indexer_spec.rb.erb +1 -0
  343. data/lib/hyrax/active_fedora_dummy_model.rb +62 -0
  344. data/lib/hyrax/collection_name.rb +6 -2
  345. data/lib/hyrax/configuration.rb +114 -4
  346. data/lib/hyrax/engine.rb +9 -6
  347. data/lib/hyrax/errors.rb +2 -0
  348. data/lib/hyrax/form_fields.rb +1 -0
  349. data/lib/hyrax/publisher.rb +16 -0
  350. data/lib/hyrax/resource_name.rb +1 -0
  351. data/lib/hyrax/resource_sync/change_list_writer.rb +2 -2
  352. data/lib/hyrax/resource_sync/resource_list_writer.rb +2 -2
  353. data/lib/hyrax/specs/capybara.rb +5 -3
  354. data/lib/hyrax/specs/shared_specs/hydra_works.rb +2 -0
  355. data/lib/hyrax/specs/shared_specs/indexers.rb +6 -0
  356. data/lib/hyrax/specs/shared_specs/valkyrie_storage_versions.rb +9 -0
  357. data/lib/hyrax/transactions/admin_set_create.rb +22 -0
  358. data/lib/hyrax/transactions/collection_create.rb +25 -0
  359. data/lib/hyrax/transactions/collection_update.rb +20 -0
  360. data/lib/hyrax/transactions/container.rb +58 -0
  361. data/lib/hyrax/transactions/file_set_destroy.rb +21 -0
  362. data/lib/hyrax/transactions/steps/add_file_sets.rb +3 -2
  363. data/lib/hyrax/transactions/steps/add_to_collections.rb +13 -1
  364. data/lib/hyrax/transactions/steps/add_to_parent.rb +36 -0
  365. data/lib/hyrax/transactions/steps/apply_collection_type_permissions.rb +29 -0
  366. data/lib/hyrax/transactions/steps/remove_file_set_from_work.rb +47 -0
  367. data/lib/hyrax/transactions/steps/save.rb +18 -6
  368. data/lib/hyrax/transactions/steps/set_collection_type_gid.rb +35 -0
  369. data/lib/hyrax/transactions/work_create.rb +2 -1
  370. data/lib/hyrax/valkyrie_can_can_adapter.rb +1 -0
  371. data/lib/hyrax/valkyrie_simple_path_generator.rb +20 -0
  372. data/lib/hyrax/version.rb +1 -1
  373. data/lib/hyrax.rb +9 -0
  374. data/lib/tasks/collection_type_global_id.rake +1 -1
  375. data/lib/tasks/default_admin_set.rake +12 -11
  376. data/lib/tasks/regenerate_derivatives.rake +12 -0
  377. data/lib/wings/active_fedora_converter/default_work.rb +15 -0
  378. data/lib/wings/model_transformer.rb +17 -1
  379. data/lib/wings/orm_converter.rb +18 -2
  380. data/lib/wings/setup.rb +17 -0
  381. data/lib/wings/valkyrie/persister.rb +16 -0
  382. data/lib/wings/valkyrie/storage.rb +56 -1
  383. data/lib/wings.rb +0 -21
  384. data/template.rb +1 -1
  385. data/vendor/assets/javascripts/morris/morris.min.js +1 -7
  386. data/vendor/assets/stylesheets/morris.js/0.5.1/morris.css +1 -1
  387. metadata +120 -17
  388. data/app/views/hyrax/dashboard/_repository_objects.html.erb +0 -28
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+ module Hyrax
3
+ module Admin
4
+ module Analytics
5
+ class AnalyticsController < ApplicationController
6
+ include Hyrax::SingularSubresourceController
7
+ before_action :set_months
8
+ before_action :set_date_range
9
+ before_action :set_document, only: [:show]
10
+ with_themed_layout 'dashboard'
11
+
12
+ def set_document
13
+ @document = ::SolrDocument.find(params[:id])
14
+ end
15
+
16
+ def set_months
17
+ @month_names = 12.downto(1).map { |n| DateTime::ABBR_MONTHNAMES.drop(1)[(Time.zone.today.month - n) % 12] }.reverse
18
+ end
19
+
20
+ def set_date_range
21
+ @start_date = params[:start_date] || Hyrax.config.analytics_start_date
22
+ @end_date = params[:end_date] || Time.zone.today + 1.day
23
+ end
24
+
25
+ def date_range
26
+ "#{@start_date},#{@end_date}"
27
+ end
28
+
29
+ def paginate(results_array, rows: 10)
30
+ return if results_array.nil?
31
+
32
+ total_pages = (results_array.size.to_f / rows.to_f).ceil
33
+ page = request.params[:page].nil? ? 1 : request.params[:page].to_i
34
+ current_page = page > total_pages ? total_pages : page
35
+ Kaminari.paginate_array(results_array, total_count: results_array.size).page(current_page).per(rows)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ module Hyrax
3
+ module Admin
4
+ module Analytics
5
+ class CollectionReportsController < AnalyticsController
6
+ include Hyrax::BreadcrumbsForCollectionAnalytics
7
+ def index
8
+ return unless Hyrax.config.analytics?
9
+
10
+ @pageviews = Hyrax::Analytics.daily_events('collection-page-view')
11
+ @work_page_views = Hyrax::Analytics.daily_events('work-in-collection-view')
12
+ @downloads = Hyrax::Analytics.daily_events('work-in-collection-download')
13
+ @all_top_collections = Hyrax::Analytics.top_events('work-in-collection-view', date_range)
14
+ @top_collections = paginate(@all_top_collections, rows: 10)
15
+ @top_downloads = Hyrax::Analytics.top_events('work-in-collection-download', date_range)
16
+ @top_collection_pages = Hyrax::Analytics.top_events('collection-page-view', date_range)
17
+ respond_to do |format|
18
+ format.html
19
+ format.csv { export_data }
20
+ end
21
+ end
22
+
23
+ def show
24
+ return unless Hyrax.config.analytics?
25
+ @document = ::SolrDocument.find(params[:id])
26
+ @pageviews = Hyrax::Analytics.daily_events_for_id(@document.id, 'collection-page-view')
27
+ @work_page_views = Hyrax::Analytics.daily_events_for_id(@document.id, 'work-in-collection-view')
28
+ @uniques = Hyrax::Analytics.unique_visitors_for_id(@document.id)
29
+ @downloads = Hyrax::Analytics.daily_events_for_id(@document.id, 'work-in-collection-download')
30
+ respond_to do |format|
31
+ format.html
32
+ format.csv { export_data }
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ # rubocop:disable Metrics/MethodLength
39
+ def export_data
40
+ csv_row = CSV.generate do |csv|
41
+ csv << ["Name", "ID", "View of Works In Collection", "Downloads of Works In Collection", "Collection Page Views"]
42
+ @all_top_collections.each do |collection|
43
+ document = begin
44
+ ::SolrDocument.find(collection[0])
45
+ rescue
46
+ "Collection deleted"
47
+ end
48
+ download_match = @top_downloads.detect { |a, _b| a == collection[0] }
49
+ download_count = download_match ? download_match[1] : 0
50
+ collection_match = @top_collection_pages.detect { |a, _b| a == collection[0] }
51
+ collection_count = collection_match ? collection_match[1] : 0
52
+ csv << [document, collection[0], collection[1], download_count, collection_count]
53
+ end
54
+ end
55
+ send_data csv_row, filename: "#{@start_date}-#{@end_date}-collections.csv"
56
+ end
57
+ # rubocop:enable Metrics/MethodLength
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+ module Hyrax
3
+ module Admin
4
+ module Analytics
5
+ class WorkReportsController < AnalyticsController
6
+ include Hyrax::BreadcrumbsForWorksAnalytics
7
+
8
+ def index
9
+ return unless Hyrax.config.analytics?
10
+
11
+ @accessible_works ||= accessible_works
12
+ @accessible_file_sets ||= accessible_file_sets
13
+ @works_count = @accessible_works.count
14
+ @top_works = paginate(top_works_list, rows: 10)
15
+ @top_file_set_downloads = paginate(top_files_list, rows: 10)
16
+
17
+ if current_user.ability.admin?
18
+ @pageviews = Hyrax::Analytics.daily_events('work-view')
19
+ @downloads = Hyrax::Analytics.daily_events('file-set-download')
20
+ end
21
+
22
+ respond_to do |format|
23
+ format.html
24
+ format.csv { export_data }
25
+ end
26
+ end
27
+
28
+ def show
29
+ @pageviews = Hyrax::Analytics.daily_events_for_id(@document.id, 'work-view')
30
+ @uniques = Hyrax::Analytics.unique_visitors_for_id(@document.id)
31
+ @downloads = Hyrax::Analytics.daily_events_for_id(@document.id, 'file_set_in_work_download')
32
+ @files = paginate(@document._source["file_set_ids_ssim"], rows: 5)
33
+ respond_to do |format|
34
+ format.html
35
+ format.csv { export_data }
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def accessible_works
42
+ models = Hyrax.config.curation_concerns.map { |m| "\"#{m}\"" }
43
+ if current_user.ability.admin?
44
+ ActiveFedora::SolrService.query("has_model_ssim:(#{models.join(' OR ')})",
45
+ fl: 'title_tesim, id, member_of_collections',
46
+ rows: 50_000)
47
+ else
48
+ ActiveFedora::SolrService.query(
49
+ "edit_access_person_ssim:#{current_user} AND has_model_ssim:(#{models.join(' OR ')})",
50
+ fl: 'title_tesim, id, member_of_collections',
51
+ rows: 50_000
52
+ )
53
+ end
54
+ end
55
+
56
+ def accessible_file_sets
57
+ if current_user.ability.admin?
58
+ ActiveFedora::SolrService.query(
59
+ "has_model_ssim:FileSet",
60
+ fl: 'title_tesim, id',
61
+ rows: 50_000
62
+ )
63
+ else
64
+ ActiveFedora::SolrService.query(
65
+ "edit_access_person_ssim:#{current_user} AND has_model_ssim:FileSet",
66
+ fl: 'title_tesim, id',
67
+ rows: 50_000
68
+ )
69
+ end
70
+ end
71
+
72
+ def top_analytics_works
73
+ @top_analytics_works ||= Hyrax::Analytics.top_events('work-view', date_range)
74
+ end
75
+
76
+ def top_analytics_downloads
77
+ @top_analytics_downloads ||= Hyrax::Analytics.top_events('file-set-in-work-download', date_range)
78
+ end
79
+
80
+ def top_analytics_file_sets
81
+ @top_analytics_file_sets ||= Hyrax::Analytics.top_events('file-set-download', date_range)
82
+ end
83
+
84
+ def top_works_list
85
+ list = []
86
+ top_analytics_works
87
+ top_analytics_downloads
88
+ @accessible_works.each do |doc|
89
+ views_match = @top_analytics_works.detect { |id, _count| id == doc["id"] }
90
+ @view_count = views_match ? views_match[1] : 0
91
+ downloads_match = @top_analytics_downloads.detect { |id, _count| id == doc["id"] }
92
+ @download_count = downloads_match ? downloads_match[1] : 0
93
+ list.push([doc["id"], doc["title_tesim"].join(''), @view_count, @download_count, doc["member_of_collections"]])
94
+ end
95
+ list.sort_by { |l| -l[2] }
96
+ end
97
+
98
+ def top_files_list
99
+ list = []
100
+ top_analytics_file_sets
101
+ @accessible_file_sets.each do |doc|
102
+ downloads_match = @top_analytics_file_sets.detect { |id, _count| id == doc["id"] }
103
+ @download_count = downloads_match ? downloads_match[1] : 0
104
+ list.push([doc["id"], doc["title_tesim"].join(''), @download_count]) if doc["title_tesim"].present?
105
+ end
106
+ list.sort_by { |l| -l[2] }
107
+ end
108
+
109
+ def export_data
110
+ data = top_works_list
111
+ csv_row = CSV.generate do |csv|
112
+ csv << ["Name", "ID", "Work Page Views", "Total Downloads of File Sets In Work", "Collections"]
113
+ data.each do |d|
114
+ csv << [d[0], d[1], d[2], d[3], d[4]]
115
+ end
116
+ end
117
+ send_data csv_row, filename: "#{params[:start_date]}-#{params[:end_date]}-works.csv"
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -30,16 +30,12 @@ module Hyrax
30
30
  false
31
31
  end
32
32
 
33
- def update_access(manage_changed:)
34
- permission_template_form.update_access(manage_changed: manage_changed)
35
- end
36
-
37
33
  def after_destroy_success
38
34
  if source.admin_set?
39
35
  redirect_to hyrax.edit_admin_admin_set_path(source_id,
40
36
  anchor: 'participants'),
41
37
  notice: translate('participants', scope: 'hyrax.admin.admin_sets.form.permission_update_notices')
42
- elsif source.collection?
38
+ else
43
39
  redirect_to hyrax.edit_dashboard_collection_path(source_id,
44
40
  anchor: 'sharing'),
45
41
  notice: translate('sharing', scope: 'hyrax.dashboard.collections.form.permission_update_notices')
@@ -51,7 +47,7 @@ module Hyrax
51
47
  redirect_to hyrax.edit_admin_admin_set_path(source_id,
52
48
  anchor: 'participants'),
53
49
  alert: @permission_template_access.errors.full_messages.to_sentence
54
- elsif source.collection?
50
+ else
55
51
  redirect_to hyrax.edit_dashboard_collection_path(source_id,
56
52
  anchor: 'sharing'),
57
53
  alert: @permission_template_access.errors.full_messages.to_sentence
@@ -60,6 +56,9 @@ module Hyrax
60
56
 
61
57
  delegate :source_id, to: :permission_template
62
58
 
59
+ ##
60
+ # @todo can we avoid querying solr to deciede where to redirect? we
61
+ # otherwise don't need this data at all.
63
62
  def source
64
63
  @source ||= ::SolrDocument.find(source_id)
65
64
  end
@@ -15,8 +15,9 @@ module Hyrax
15
15
  add_breadcrumb t(:'hyrax.dashboard.breadcrumbs.admin'), hyrax.dashboard_path
16
16
  add_breadcrumb t(:'hyrax.admin.sidebar.tasks'), '#'
17
17
  add_breadcrumb t(:'hyrax.admin.sidebar.workflow_review'), request.path
18
- @status_list = Hyrax::Workflow::StatusListService.new(self, "-workflow_state_name_ssim:#{deposited_workflow_state_name}")
19
- @published_list = Hyrax::Workflow::StatusListService.new(self, "workflow_state_name_ssim:#{deposited_workflow_state_name}")
18
+
19
+ @status_list = actionable_objects.reject(&:published?)
20
+ @published_list = actionable_objects.select(&:published?)
20
21
  end
21
22
 
22
23
  private
@@ -24,5 +25,10 @@ module Hyrax
24
25
  def ensure_authorized!
25
26
  authorize! :review, :submissions
26
27
  end
28
+
29
+ def actionable_objects
30
+ @actionable_objects ||=
31
+ Hyrax::Workflow::ActionableObjects.new(user: current_user)
32
+ end
27
33
  end
28
34
  end
@@ -4,7 +4,12 @@ module Hyrax
4
4
  include CollectionsControllerBehavior
5
5
  include BreadcrumbsForCollections
6
6
  with_themed_layout :decide_layout
7
- load_and_authorize_resource except: [:index, :show, :create], instance_name: :collection
7
+ load_and_authorize_resource except: [:index],
8
+ instance_name: :collection,
9
+ class: Hyrax.config.collection_model
10
+
11
+ skip_load_resource only: :create if
12
+ Hyrax.config.collection_class < ActiveFedora::Base
8
13
 
9
14
  # Renders a JSON response with a list of files in this collection
10
15
  # This is used by the edit form to populate the thumbnail_id dropdown
@@ -7,6 +7,10 @@ module Hyrax
7
7
 
8
8
  include Hyrax::Collections::AcceptsBatches
9
9
 
10
+ load_resource only: :update_members,
11
+ instance_name: :collection,
12
+ class: Hyrax.config.collection_model
13
+
10
14
  def after_update
11
15
  respond_to do |format|
12
16
  format.html { redirect_to success_return_path, notice: t('hyrax.dashboard.my.action.collection_update_success') }
@@ -21,30 +25,37 @@ module Hyrax
21
25
  end
22
26
  end
23
27
 
24
- def update_members
28
+ def update_members # rubocop:disable Metrics/MethodLength
25
29
  err_msg = validate
26
30
  after_update_error(err_msg) if err_msg.present?
27
31
  return if err_msg.present?
28
32
 
29
- collection.reindex_extent = Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX
30
- members = collection.add_member_objects batch_ids
31
- messages = members.collect { |member| member.errors.full_messages }.flatten
32
- if messages.size == members.size
33
- after_update_error(messages.uniq.join(', '))
34
- elsif messages.present?
35
- flash[:error] = messages.uniq.join(', ')
36
- after_update
37
- else
33
+ @collection.try(:reindex_extent=, Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX)
34
+ begin
35
+ Hyrax::Collections::CollectionMemberService.add_members_by_ids(collection_id: collection_id,
36
+ new_member_ids: batch_ids,
37
+ user: current_user)
38
38
  after_update
39
+ rescue Hyrax::SingleMembershipError => err
40
+ messages = JSON.parse(err.message)
41
+ if messages.size == batch_ids.size
42
+ after_update_error(messages.uniq.join(', '))
43
+ elsif messages.present?
44
+ flash[:error] = messages.uniq.join(', ')
45
+ after_update
46
+ end
39
47
  end
40
48
  end
41
49
 
42
50
  private
43
51
 
44
52
  def validate
45
- return t('hyrax.dashboard.my.action.members_no_access') if batch_ids.blank?
46
- return t('hyrax.dashboard.my.action.collection_deny_add_members') unless current_ability.can?(:deposit, collection)
47
- return t('hyrax.dashboard.my.action.add_to_collection_only') unless member_action == "add" # should never happen
53
+ return t('hyrax.dashboard.my.action.members_no_access') if
54
+ batch_ids.blank?
55
+ return t('hyrax.dashboard.my.action.collection_deny_add_members') unless
56
+ current_ability.can?(:deposit, @collection)
57
+ return t('hyrax.dashboard.my.action.add_to_collection_only') unless
58
+ member_action == "add" # should never happen
48
59
  end
49
60
 
50
61
  def success_return_path
@@ -59,10 +70,6 @@ module Hyrax
59
70
  params[:id]
60
71
  end
61
72
 
62
- def collection
63
- @collection ||= ::Collection.find(collection_id)
64
- end
65
-
66
73
  def batch_ids
67
74
  params[:batch_document_ids]
68
75
  end
@@ -41,9 +41,14 @@ module Hyrax
41
41
  # The search builder to find the collection
42
42
  self.single_item_search_builder_class = SingleCollectionSearchBuilder
43
43
  # The search builder to find the collections' members
44
- self.membership_service_class = Collections::CollectionMemberService
44
+ self.membership_service_class = Collections::CollectionMemberSearchService
45
45
 
46
- load_and_authorize_resource except: [:index, :create], instance_name: :collection
46
+ load_and_authorize_resource except: [:index],
47
+ instance_name: :collection,
48
+ class: Hyrax.config.collection_model
49
+
50
+ skip_load_resource only: :create if
51
+ Hyrax.config.collection_class < ActiveFedora::Base
47
52
 
48
53
  def deny_collection_access(exception)
49
54
  if exception.action == :edit
@@ -63,14 +68,14 @@ module Hyrax
63
68
  @collection.collection_type_gid = CollectionType.find(collection_type_id).to_global_id
64
69
  add_breadcrumb t(:'hyrax.controls.home'), root_path
65
70
  add_breadcrumb t(:'hyrax.dashboard.breadcrumbs.admin'), hyrax.dashboard_path
66
- add_breadcrumb t('.header', type_title: @collection.collection_type.title), request.path
67
- @collection.apply_depositor_metadata(current_user.user_key)
71
+ add_breadcrumb t('.header', type_title: collection_type.title), request.path
72
+ @collection.try(:apply_depositor_metadata, current_user.user_key)
68
73
  form
69
74
  end
70
75
 
71
76
  def show
72
77
  # @todo: remove this unused assignment in 4.0.0
73
- @banner_file = presenter.banner_file if @collection.collection_type.brandable?
78
+ @banner_file = presenter.banner_file if collection_type.brandable?
74
79
 
75
80
  presenter
76
81
  query_collection_members
@@ -81,11 +86,13 @@ module Hyrax
81
86
  end
82
87
 
83
88
  def after_create
84
- form
85
- set_default_permissions
86
- # if we are creating the new collection as a subcollection (via the nested collections controller),
87
- # we pass the parent_id through a hidden field in the form and link the two after the create.
88
- link_parent_collection(params[:parent_id]) unless params[:parent_id].nil?
89
+ if @collection.is_a?(ActiveFedora::Base)
90
+ form
91
+ set_default_permissions
92
+ # if we are creating the new collection as a subcollection (via the nested collections controller),
93
+ # we pass the parent_id through a hidden field in the form and link the two after the create.
94
+ link_parent_collection(params[:parent_id]) unless params[:parent_id].nil?
95
+ end
89
96
  respond_to do |format|
90
97
  Hyrax::SolrService.commit
91
98
  format.html { redirect_to edit_dashboard_collection_path(@collection), notice: t('hyrax.dashboard.my.action.collection_create_success') }
@@ -102,20 +109,21 @@ module Hyrax
102
109
  end
103
110
 
104
111
  def create
112
+ return valkyrie_create if @collection.is_a?(Valkyrie::Resource)
105
113
  # Manual load and authorize necessary because Cancan will pass in all
106
114
  # form attributes. When `permissions_attributes` are present the
107
115
  # collection is saved without a value for `has_model.`
108
- @collection = ::Collection.new
116
+ @collection = Hyrax.config.collection_class.new
109
117
  authorize! :create, @collection
110
118
  # Coming from the UI, a collection type gid should always be present. Coming from the API, if a collection type gid is not specified,
111
119
  # use the default collection type (provides backward compatibility with versions < Hyrax 2.1.0)
112
120
  @collection.collection_type_gid = params[:collection_type_gid].presence || default_collection_type.to_global_id
113
121
  @collection.attributes = collection_params.except(:members, :parent_id, :collection_type_gid)
114
122
  @collection.apply_depositor_metadata(current_user.user_key)
115
- add_members_to_collection unless batch.empty?
116
123
  @collection.visibility = Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE unless @collection.discoverable?
117
124
  if @collection.save
118
125
  after_create
126
+ add_members_to_collection unless batch.empty?
119
127
  else
120
128
  after_create_error
121
129
  end
@@ -143,6 +151,9 @@ module Hyrax
143
151
  end
144
152
 
145
153
  process_member_changes
154
+
155
+ return valkyrie_update if @collection.is_a?(Valkyrie::Resource)
156
+
146
157
  @collection.visibility = Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE unless @collection.discoverable?
147
158
  # we don't have to reindex the full graph when updating collection
148
159
  @collection.reindex_extent = Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX
@@ -175,11 +186,20 @@ module Hyrax
175
186
  end
176
187
 
177
188
  def destroy
178
- if @collection.destroy
189
+ case @collection
190
+ when Valkyrie::Resource
191
+ Hyrax.persister.delete(resource: @collection)
179
192
  after_destroy(params[:id])
180
193
  else
181
- after_destroy_error(params[:id])
194
+ if @collection.destroy
195
+ after_destroy(params[:id])
196
+ else
197
+ after_destroy_error(params[:id])
198
+ end
182
199
  end
200
+ rescue StandardError => err
201
+ Rails.logger.error(err)
202
+ after_destroy_error(params[:id])
183
203
  end
184
204
 
185
205
  def collection
@@ -197,13 +217,47 @@ module Hyrax
197
217
 
198
218
  private
199
219
 
220
+ def valkyrie_create
221
+ form.validate(collection_params) &&
222
+ @collection = transactions['change_set.create_collection']
223
+ .with_step_args(
224
+ 'change_set.set_user_as_depositor' => { user: current_user },
225
+ 'change_set.add_to_collections' => { collection_ids: Array(params[:parent_id]) },
226
+ 'collection_resource.apply_collection_type_permissions' => { user: current_user }
227
+ )
228
+ .call(form)
229
+ .value_or { return after_create_error }
230
+
231
+ after_create
232
+ add_members_to_collection unless batch.empty?
233
+ @collection
234
+ end
235
+
236
+ def valkyrie_update
237
+ form.validate(collection_params) &&
238
+ @collection = transactions['change_set.update_collection']
239
+ .call(form)
240
+ .value_or { return after_update_error }
241
+ after_update
242
+ end
243
+
200
244
  def default_collection_type
201
245
  Hyrax::CollectionType.find_or_create_default_collection_type
202
246
  end
203
247
 
248
+ def default_collection_type_gid
249
+ default_collection_type.to_global_id.to_s
250
+ end
251
+
252
+ def collection_type
253
+ @collection_type ||= CollectionType.find_by_gid!(collection.collection_type_gid)
254
+ end
255
+
204
256
  def link_parent_collection(parent_id)
205
- parent = Hyrax.query_service.find_by_alternate_identifier(alternate_identifier: parent_id, use_valkyrie: false)
206
- Hyrax::Collections::NestedCollectionPersistenceService.persist_nested_collection_for(parent: parent, child: @collection)
257
+ child = collection.respond_to?(:valkyrie_resource) ? collection.valkyrie_resource : collection
258
+ Hyrax::Collections::CollectionMemberService.add_member(collection_id: parent_id,
259
+ new_member: child,
260
+ user: current_user)
207
261
  end
208
262
 
209
263
  def uploaded_files(uploaded_file_ids)
@@ -339,8 +393,15 @@ module Hyrax
339
393
  deprecation_deprecate :single_item_search_builder
340
394
 
341
395
  def collection_params
342
- @participants = extract_old_style_permission_attributes(params[:collection])
343
- form_class.model_attributes(params[:collection])
396
+ if Hyrax.config.collection_class < ActiveFedora::Base
397
+ @participants = extract_old_style_permission_attributes(params[:collection])
398
+ form_class.model_attributes(params[:collection])
399
+ else
400
+ params.permit(collection: {})[:collection]
401
+ .merge(params.permit(:collection_type_gid)
402
+ .with_defaults(collection_type_gid: default_collection_type_gid))
403
+ .merge(member_of_collection_ids: Array(params[:parent_id]))
404
+ end
344
405
  end
345
406
 
346
407
  def extract_old_style_permission_attributes(attributes)
@@ -377,28 +438,36 @@ module Hyrax
377
438
  end
378
439
  end
379
440
 
380
- def add_members_to_collection(collection = nil)
381
- collection ||= @collection
382
- collection.add_member_objects batch
441
+ def add_members_to_collection(collection = nil, collection_id: nil)
442
+ collection_id ||= (collection.try(:id) || @collection.id)
443
+
444
+ Hyrax::Collections::CollectionMemberService
445
+ .add_members_by_ids(collection_id: collection_id,
446
+ new_member_ids: batch,
447
+ user: current_user)
383
448
  end
384
449
 
385
450
  def remove_members_from_collection
386
- batch.each do |pid|
387
- work = Hyrax.query_service.find_by_alternate_identifier(alternate_identifier: pid, use_valkyrie: false)
388
- work.member_of_collections.delete @collection
389
- work.save!
390
- end
451
+ Hyrax::Collections::CollectionMemberService
452
+ .remove_members_by_ids(collection_id: @collection.id,
453
+ member_ids: batch,
454
+ user: current_user)
391
455
  end
392
456
 
393
457
  def move_members_between_collections
394
- destination_collection = ::Collection.find(params[:destination_collection_id])
395
458
  remove_members_from_collection
396
- add_members_to_collection(destination_collection)
397
- if destination_collection.save
398
- flash[:notice] = "Successfully moved #{batch.count} files to #{destination_collection.title} Collection."
399
- else
400
- flash[:error] = "An error occured. Files were not moved to #{destination_collection.title} Collection."
401
- end
459
+ add_members_to_collection(collection_id: params[:destination_collection_id])
460
+
461
+ destination_title =
462
+ Hyrax.query_service.find_by(id: params[:destination_collection_id]).title.first ||
463
+ params[:destination_collection_id]
464
+ flash[:notice] = "Successfully moved #{batch.count} files to #{destination_title} Collection."
465
+ rescue StandardError => err
466
+ Rails.logger.error(err)
467
+ destination_title =
468
+ Hyrax.query_service.find_by(id: params[:destination_collection_id]).title.first ||
469
+ destination_id
470
+ flash[:error] = "An error occured. Files were not moved to #{destination_title} Collection."
402
471
  end
403
472
 
404
473
  # Include 'catalog' and 'hyrax/base' in the search path for views, while prefering
@@ -418,7 +487,13 @@ module Hyrax
418
487
  end
419
488
 
420
489
  def form
421
- @form ||= form_class.new(@collection, current_ability, repository)
490
+ @form ||=
491
+ case @collection
492
+ when Valkyrie::Resource
493
+ Hyrax::Forms::ResourceForm.for(@collection)
494
+ else
495
+ form_class.new(@collection, current_ability, repository)
496
+ end
422
497
  end
423
498
 
424
499
  def set_default_permissions
@@ -428,8 +503,8 @@ module Hyrax
428
503
 
429
504
  def query_collection_members
430
505
  member_works
431
- member_subcollections if collection.collection_type.nestable?
432
- parent_collections if collection.collection_type.nestable? && action_name == 'show'
506
+ member_subcollections if collection_type.nestable?
507
+ parent_collections if collection_type.nestable? && action_name == 'show'
433
508
  end
434
509
 
435
510
  # Instantiate the membership query service
@@ -457,7 +532,7 @@ module Hyrax
457
532
  end
458
533
 
459
534
  def collection_object
460
- action_name == 'show' ? ::Collection.find(collection.id) : collection
535
+ @collection
461
536
  end
462
537
 
463
538
  # You can override this method if you need to provide additional