sufia 7.0.0.beta4 → 7.0.0.rc1

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 (164) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -1
  3. data/.rubocop_todo.yml +1 -2
  4. data/.travis.yml +1 -0
  5. data/Gemfile +18 -9
  6. data/README.md +23 -3
  7. data/app/assets/javascripts/sufia.js +4 -1
  8. data/app/assets/javascripts/sufia/app.js +15 -3
  9. data/app/assets/javascripts/sufia/autocomplete.es6 +51 -0
  10. data/app/assets/javascripts/sufia/autocomplete/language.es6 +25 -0
  11. data/app/assets/javascripts/sufia/autocomplete/location.es6 +24 -0
  12. data/app/assets/javascripts/sufia/autocomplete/subject.es6 +26 -0
  13. data/app/assets/javascripts/sufia/batch_edit.js +8 -5
  14. data/app/assets/javascripts/sufia/permissions/control.es6 +7 -3
  15. data/app/assets/javascripts/sufia/save_work/required_fields.es6 +10 -4
  16. data/app/assets/javascripts/sufia/save_work/save_work_control.es6 +14 -4
  17. data/app/assets/stylesheets/sufia/_fixedsticky.scss +23 -21
  18. data/app/assets/stylesheets/sufia/_form-progress.scss +16 -7
  19. data/app/assets/stylesheets/sufia/_header.scss +2 -1
  20. data/app/assets/stylesheets/sufia/_settings.scss +4 -0
  21. data/app/controllers/api/items_controller.rb +2 -2
  22. data/app/controllers/api/zotero_controller.rb +1 -1
  23. data/app/controllers/citations_controller.rb +0 -2
  24. data/app/controllers/concerns/sufia/batch_edits_controller_behavior.rb +7 -7
  25. data/app/controllers/concerns/sufia/batch_uploads_controller_behavior.rb +9 -3
  26. data/app/controllers/concerns/sufia/singular_subresource_controller.rb +6 -1
  27. data/app/controllers/concerns/sufia/transfers_controller_behavior.rb +1 -1
  28. data/app/controllers/concerns/sufia/users_controller_behavior.rb +3 -3
  29. data/app/controllers/concerns/sufia/works_controller_behavior.rb +11 -4
  30. data/app/controllers/my/highlights_controller.rb +1 -1
  31. data/app/forms/sufia/forms/batch_edit_form.rb +10 -6
  32. data/app/forms/sufia/forms/batch_upload_form.rb +2 -2
  33. data/app/forms/sufia/forms/collection_form.rb +4 -0
  34. data/app/forms/sufia/forms/work_form.rb +4 -0
  35. data/app/helpers/sufia/blacklight_override.rb +0 -20
  36. data/app/helpers/sufia/collections_helper.rb +12 -0
  37. data/app/helpers/sufia/sufia_helper_behavior.rb +84 -56
  38. data/app/jobs/batch_create_job.rb +18 -2
  39. data/app/jobs/content_depositor_change_event_job.rb +13 -6
  40. data/app/jobs/create_work_job.rb +6 -2
  41. data/app/models/batch_upload_item.rb +15 -0
  42. data/app/models/concerns/sufia/ability.rb +7 -4
  43. data/app/models/concerns/sufia/user.rb +0 -11
  44. data/app/models/concerns/sufia/work_behavior.rb +1 -0
  45. data/app/models/concerns/sufia/works/featured.rb +23 -0
  46. data/app/models/file_download_stat.rb +9 -12
  47. data/app/models/file_view_stat.rb +5 -15
  48. data/app/models/proxy_deposit_request.rb +11 -7
  49. data/app/models/sufia/statistic.rb +65 -0
  50. data/app/models/work_view_stat.rb +5 -16
  51. data/app/presenters/file_usage.rb +3 -4
  52. data/app/presenters/sufia/file_set_presenter.rb +1 -3
  53. data/app/presenters/sufia/trophy_presenter.rb +28 -0
  54. data/app/presenters/sufia/user_profile_presenter.rb +1 -1
  55. data/app/presenters/work_usage.rb +5 -4
  56. data/app/search_builders/deposit_search_builder.rb +4 -3
  57. data/app/search_builders/parent_collection_search_builder.rb +1 -1
  58. data/app/services/sufia/collection_member_service.rb +1 -1
  59. data/app/services/sufia/user_stat_importer.rb +11 -6
  60. data/app/views/_controls.html.erb +11 -9
  61. data/app/views/batch_edits/edit.html.erb +8 -2
  62. data/app/views/catalog/_index_list_default.html.erb +2 -1
  63. data/app/views/curation_concerns/base/_form_metadata.html.erb +1 -1
  64. data/app/views/curation_concerns/base/_form_progress.html.erb +1 -1
  65. data/app/views/curation_concerns/base/_form_relationships.html.erb +1 -1
  66. data/app/views/curation_concerns/base/_guts4form.html.erb +6 -2
  67. data/app/views/curation_concerns/base/_items.html.erb +1 -1
  68. data/app/views/curation_concerns/base/edit.html.erb +1 -1
  69. data/app/views/curation_concerns/base/new.html.erb +1 -1
  70. data/app/views/curation_concerns/file_sets/_permission.html.erb +5 -1
  71. data/app/views/curation_concerns/file_sets/media_display/_default.html.erb +1 -1
  72. data/app/views/curation_concerns/file_sets/show.html.erb +1 -1
  73. data/app/views/dashboard/_index_partials/_heading_actions.html.erb +1 -1
  74. data/app/views/{error → errors}/404.html.erb +0 -0
  75. data/app/views/records/edit_fields/_based_near.html.erb +8 -0
  76. data/app/views/records/edit_fields/_language.html.erb +8 -0
  77. data/app/views/records/edit_fields/_subject.html.erb +8 -0
  78. data/app/views/stats/work.html.erb +1 -1
  79. data/app/views/sufia/batch_uploads/_form.html.erb +1 -1
  80. data/app/views/sufia/homepage/_home_header.html.erb +1 -1
  81. data/app/views/sufia/homepage/_sortable_featured.html.erb +1 -1
  82. data/app/views/transfers/new.html.erb +3 -1
  83. data/app/views/users/_contributions.html.erb +1 -1
  84. data/config/locales/sufia.en.yml +3 -2
  85. data/config/routes.rb +0 -7
  86. data/lib/generators/sufia/install_generator.rb +0 -24
  87. data/lib/generators/sufia/templates/catalog_controller.rb +4 -3
  88. data/lib/generators/sufia/templates/config/sufia.rb +4 -2
  89. data/lib/generators/sufia/upgrade700_generator.rb +7 -9
  90. data/lib/generators/sufia/work_generator.rb +56 -0
  91. data/lib/sufia.rb +4 -1
  92. data/lib/sufia/arkivo/actor.rb +1 -1
  93. data/lib/sufia/configuration.rb +15 -3
  94. data/lib/sufia/engine.rb +1 -10
  95. data/lib/sufia/version.rb +1 -1
  96. data/spec/controllers/api/items_controller_spec.rb +20 -7
  97. data/spec/controllers/sufia/batch_uploads_controller_spec.rb +4 -3
  98. data/spec/controllers/transfers_controller_spec.rb +3 -11
  99. data/spec/controllers/users_controller_spec.rb +2 -1
  100. data/spec/features/batch_edit_spec.rb +17 -2
  101. data/spec/forms/sufia/forms/batch_edit_form_spec.rb +2 -0
  102. data/spec/forms/sufia/forms/batch_upload_form_spec.rb +1 -1
  103. data/spec/helpers/blacklight_helper_spec.rb +36 -26
  104. data/spec/helpers/{generic_work_helper_spec.rb → sufia/collections_helper_spec.rb} +1 -1
  105. data/spec/helpers/sufia_helper_spec.rb +70 -32
  106. data/spec/javascripts/autocomplete_spec.js.coffee +7 -7
  107. data/spec/javascripts/save_work_spec.js +20 -20
  108. data/spec/lib/sufia/configuration_spec.rb +30 -0
  109. data/spec/lib/sufia/user_stat_importer_spec.rb +21 -36
  110. data/spec/models/file_download_stat_spec.rb +8 -8
  111. data/spec/models/file_view_stat_spec.rb +8 -8
  112. data/spec/models/generic_work_spec.rb +24 -0
  113. data/spec/models/proxy_deposit_request_spec.rb +2 -4
  114. data/spec/models/sufia/ability_spec.rb +7 -13
  115. data/spec/models/user_spec.rb +0 -14
  116. data/spec/models/work_view_stat_spec.rb +22 -8
  117. data/spec/presenters/sufia/file_usage_spec.rb +0 -4
  118. data/spec/presenters/sufia/trophy_presenter_spec.rb +46 -0
  119. data/spec/presenters/sufia/user_profile_presenter_spec.rb +4 -1
  120. data/spec/presenters/sufia/work_usage_spec.rb +8 -17
  121. data/spec/routing/route_spec.rb +0 -6
  122. data/spec/spec_helper.rb +8 -2
  123. data/spec/test_app_templates/lib/generators/test_app_generator.rb +4 -0
  124. data/spec/views/batch_edits/edit.html.erb_spec.rb +8 -2
  125. data/spec/views/catalog/_index_list_default.html.erb_spec.rb +8 -6
  126. data/spec/views/curation_concerns/base/_form.html.erb_spec.rb +3 -0
  127. data/spec/views/curation_concerns/file_sets/_permission.html.erb_spec.rb +16 -0
  128. data/spec/views/curation_concerns/file_sets/show.html.erb_spec.rb +0 -2
  129. data/spec/views/records/edit_fields/_based_near.html.erb_spec.rb +20 -0
  130. data/spec/views/records/edit_fields/_language.html.erb_spec.rb +20 -0
  131. data/spec/views/records/edit_fields/_subject.html.erb_spec.rb +20 -0
  132. data/spec/views/{homepage → sufia/homepage}/_announcement.html.erb_spec.rb +0 -0
  133. data/spec/views/{homepage → sufia/homepage}/_featured_works.html.erb_spec.rb +0 -0
  134. data/spec/views/{homepage → sufia/homepage}/_home_header.html.erb_spec.rb +0 -0
  135. data/spec/views/sufia/homepage/_sortable_featured.html.erb_spec.rb +21 -0
  136. data/spec/views/users/edit.html.erb_spec.rb +5 -5
  137. data/spec/views/users/show.html.erb_spec.rb +5 -3
  138. data/sufia.gemspec +4 -3
  139. data/tasks/noid.rake +2 -2
  140. data/tasks/sufia-dev.rake +1 -1
  141. metadata +73 -68
  142. data/app/assets/javascripts/sufia/edit_metadata.js +0 -87
  143. data/app/controllers/authorities_controller.rb +0 -19
  144. data/app/helpers/generic_work_helper.rb +0 -10
  145. data/app/helpers/sufia_url_helper.rb +0 -14
  146. data/app/models/concerns/sufia/file_stat_utils.rb +0 -33
  147. data/app/models/concerns/sufia/work_stat_utils.rb +0 -33
  148. data/app/models/geo_names_resource.rb +0 -18
  149. data/app/models/local_authority.rb +0 -101
  150. data/app/models/local_authority_entry.rb +0 -3
  151. data/app/models/subject_local_authority_entry.rb +0 -2
  152. data/app/views/curation_concerns/generic_works/_generic_work.html.erb +0 -3
  153. data/app/views/error/401.html.erb +0 -18
  154. data/app/views/error/500.html.erb +0 -9
  155. data/app/views/error/single_use_error.html.erb +0 -19
  156. data/lib/generators/sufia/geonames_username_config_generator.rb +0 -20
  157. data/spec/controllers/authorities_controller_spec.rb +0 -18
  158. data/spec/fixtures/cities15000.tsv +0 -149
  159. data/spec/fixtures/genreForms.nt +0 -471
  160. data/spec/fixtures/lexvo.rdf +0 -3108
  161. data/spec/helpers/sufia_url_helper_spec.rb +0 -18
  162. data/spec/models/geo_names_resource_spec.rb +0 -30
  163. data/spec/models/local_authority_spec.rb +0 -108
  164. data/vendor/assets/javascripts/almond.js +0 -430
@@ -1,26 +1,28 @@
1
- .fixedsticky {
2
- position: -webkit-sticky;
3
- position: -moz-sticky;
4
- position: -ms-sticky;
5
- position: -o-sticky;
6
- position: sticky;
7
- }
1
+ @media (min-width: $screen-sm-min) {
2
+ .fixedsticky {
3
+ position: -webkit-sticky;
4
+ position: -moz-sticky;
5
+ position: -ms-sticky;
6
+ position: -o-sticky;
7
+ position: sticky;
8
+ }
8
9
 
9
- /* When position: sticky is supported but native behavior is ignored */
10
- .fixedsticky-withoutfixedfixed .fixedsticky-off,
11
- .fixed-supported .fixedsticky-off {
12
- position: static;
13
- }
10
+ /* When position: sticky is supported but native behavior is ignored */
11
+ .fixedsticky-withoutfixedfixed .fixedsticky-off,
12
+ .fixed-supported .fixedsticky-off {
13
+ position: static;
14
+ }
14
15
 
15
- .fixedsticky-withoutfixedfixed .fixedsticky-on,
16
- .fixed-supported .fixedsticky-on {
17
- position: fixed;
18
- }
16
+ .fixedsticky-withoutfixedfixed .fixedsticky-on,
17
+ .fixed-supported .fixedsticky-on {
18
+ position: fixed;
19
+ }
19
20
 
20
- .fixedsticky-dummy {
21
- display: none;
22
- }
21
+ .fixedsticky-dummy {
22
+ display: none;
23
+ }
23
24
 
24
- .fixedsticky-on + .fixedsticky-dummy {
25
- display: block;
25
+ .fixedsticky-on + .fixedsticky-dummy {
26
+ display: block;
27
+ }
26
28
  }
@@ -1,12 +1,21 @@
1
- .fixedsticky {
2
- top: 0; /* Required to get consistent results in Safari and Chrome */
1
+ @media (min-width: $screen-xs-min) {
2
+ .fixedsticky {
3
+ margin-top: 1em;
4
+ }
3
5
  }
4
6
 
5
- .fixedsticky-withoutfixedfixed .fixedsticky-on,
6
- .fixed-supported .fixedsticky-on {
7
- left: $save-viz-widget-left;
8
- /* Required so that the widget doesn't pop back to top when public desc long */
9
- bottom: $save-viz-widget-bottom;
7
+ @media (min-width: $screen-sm-min) {
8
+ .fixedsticky {
9
+ margin-top: 0;
10
+ top: 0; /* Required to get consistent results in Safari and Chrome */
11
+ }
12
+
13
+ .fixedsticky-withoutfixedfixed .fixedsticky-on,
14
+ .fixed-supported .fixedsticky-on {
15
+ left: $save-viz-widget-left;
16
+ /* Required so that the widget doesn't pop back to top when public desc long */
17
+ bottom: $save-viz-widget-bottom;
18
+ }
10
19
  }
11
20
 
12
21
  aside.form-progress {
@@ -1,5 +1,6 @@
1
1
  #search-form-header {
2
- margin-top: 6px;
2
+ margin-top: $search-bar-margin-top;
3
+ margin-right: $search-bar-margin-right;
3
4
  }
4
5
 
5
6
  #masthead {
@@ -6,6 +6,10 @@
6
6
  $classic-white: #FFF !default;
7
7
  $vermilion: #F30 !default;
8
8
 
9
+ // Nav and Search Bar
10
+ $search-bar-margin-top: 0.50em;
11
+ $search-bar-margin-right: 0.95em;
12
+
9
13
  // Dashboard
10
14
  $dashboard-border-color: $gray-lighter !default;
11
15
 
@@ -1,7 +1,7 @@
1
1
  module API
2
2
  # Adds an endpoint that consumes and RESTfully emits JSON from Arkivo
3
3
  # representing new and updated Zotero-managed publications. An item in the
4
- # Zotero parlance is mapped to a GenericWork in Sufia.
4
+ # Zotero parlance is mapped to a work in Sufia.
5
5
  class ItemsController < ApplicationController
6
6
  skip_before_action :verify_authenticity_token
7
7
  before_action :validate_item, only: [:create, :update]
@@ -31,7 +31,7 @@ module API
31
31
  private
32
32
 
33
33
  def my_load_and_authorize_resource
34
- @work = GenericWork.find(params[:id])
34
+ @work = CurationConcerns::WorkRelation.new.find(params[:id])
35
35
 
36
36
  unless user.can? :edit, @work
37
37
  return render plain: "#{user} lacks access to #{@work}", status: :unauthorized
@@ -34,7 +34,7 @@ module API
34
34
  private
35
35
 
36
36
  def authorize_user!
37
- authorize! :create, ::GenericWork
37
+ authorize! :create, Sufia.primary_work_type
38
38
  rescue CanCan::AccessDenied
39
39
  return redirect_to root_url, alert: 'You are not authorized to perform this operation'
40
40
  end
@@ -6,13 +6,11 @@ class CitationsController < ApplicationController
6
6
  before_action :build_breadcrumbs, only: [:work, :file]
7
7
 
8
8
  def work
9
- @curation_concern_type = GenericWork
10
9
  @presenter_class = Sufia::WorkShowPresenter
11
10
  show
12
11
  end
13
12
 
14
13
  def file
15
- @curation_concern_type = FileSet
16
14
  @presenter_class = Sufia::FileSetPresenter
17
15
  show
18
16
  end
@@ -10,9 +10,9 @@ module Sufia
10
10
 
11
11
  def edit
12
12
  super
13
- generic_work = ::GenericWork.new
14
- generic_work.depositor = current_user.user_key
15
- @form = form_class.new(generic_work, current_user, batch)
13
+ work = form_class.model_class.new
14
+ work.depositor = current_user.user_key
15
+ @form = form_class.new(work, current_user, batch)
16
16
  end
17
17
 
18
18
  def after_update
@@ -27,7 +27,7 @@ module Sufia
27
27
  end
28
28
 
29
29
  def update_document(obj)
30
- obj.attributes = generic_work_params
30
+ obj.attributes = work_params
31
31
  obj.date_modified = Time.current.ctime
32
32
  obj.visibility = params[:visibility]
33
33
  end
@@ -65,9 +65,9 @@ module Sufia
65
65
  form_class.terms
66
66
  end
67
67
 
68
- def generic_work_params
69
- generic_work_params = params[:generic_work] || ActionController::Parameters.new
70
- form_class.model_attributes(generic_work_params)
68
+ def work_params
69
+ work_params = params[form_class.model_name.param_key] || ActionController::Parameters.new
70
+ form_class.model_attributes(work_params)
71
71
  end
72
72
 
73
73
  def redirect_to_return_controller
@@ -6,22 +6,28 @@ module Sufia
6
6
 
7
7
  included do
8
8
  layout "sufia-one-column"
9
- self.curation_concern_type = GenericWork
9
+ self.curation_concern_type = form_class.model_class
10
10
  end
11
11
 
12
12
  def create
13
13
  authenticate_user!
14
14
  create_update_job
15
- flash[:notice] = t('sufia.generic_works.new.after_create_html', application_name: view_context.application_name)
15
+ flash[:notice] = t('sufia.works.new.after_create_html', application_name: view_context.application_name)
16
16
  redirect_after_update
17
17
  end
18
18
 
19
+ module ClassMethods
20
+ def form_class
21
+ ::Sufia::Forms::BatchUploadForm
22
+ end
23
+ end
24
+
19
25
  protected
20
26
 
21
27
  # Gives the class of the form.
22
28
  # This overrides CurationConcerns
23
29
  def form_class
24
- ::Sufia::Forms::BatchUploadForm
30
+ self.class.form_class
25
31
  end
26
32
 
27
33
  def redirect_after_update
@@ -2,8 +2,9 @@ module Sufia::SingularSubresourceController
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  included do
5
+ before_action :find_work, only: :work
6
+ load_and_authorize_resource :work, only: :work
5
7
  load_and_authorize_resource :file, class: 'FileSet', only: :file, id_param: :id
6
- load_and_authorize_resource :work, class: 'GenericWork', only: :work, id_param: :id
7
8
  end
8
9
 
9
10
  # Overriding the default behavior from Hydra::Core::ControllerBehavior
@@ -15,4 +16,8 @@ module Sufia::SingularSubresourceController
15
16
  redirect_to new_user_session_path, alert: exception.message
16
17
  end
17
18
  end
19
+
20
+ def find_work
21
+ @work = CurationConcerns::WorkRelation.new.find(params[:id])
22
+ end
18
23
  end
@@ -20,7 +20,7 @@ module Sufia
20
20
  end
21
21
 
22
22
  def new
23
- @generic_work = ::GenericWork.load_instance_from_solr(@id)
23
+ @work = CurationConcerns::WorkRelation.new.find(params[:id])
24
24
  end
25
25
 
26
26
  def create
@@ -5,9 +5,9 @@ module Sufia::UsersControllerBehavior
5
5
  include Blacklight::SearchContext
6
6
  layout "sufia-one-column"
7
7
  prepend_before_action :find_user, except: [:index, :search, :notifications_number]
8
- before_action :authenticate_user!, only: [:edit, :update, :follow, :unfollow, :toggle_trophy]
8
+ before_action :authenticate_user!, only: [:edit, :update, :follow, :unfollow]
9
9
  before_action :user_not_current_user, only: [:follow, :unfollow]
10
- authorize_resource only: [:edit, :update, :toggle_trophy]
10
+ authorize_resource only: [:edit, :update]
11
11
  # Catch permission errors
12
12
  rescue_from CanCan::AccessDenied, with: :deny_access
13
13
  end
@@ -33,7 +33,7 @@ module Sufia::UsersControllerBehavior
33
33
 
34
34
  # Display form for users to edit their profile information
35
35
  def edit
36
- @trophies = @user.trophy_works
36
+ @trophies = Sufia::TrophyPresenter.find_by_user(@user)
37
37
  end
38
38
 
39
39
  # Process changes from profile form
@@ -6,12 +6,19 @@ module Sufia
6
6
  include CurationConcerns::CurationConcernController
7
7
 
8
8
  included do
9
- before_action :build_breadcrumbs, only: [:edit, :show]
10
- self.curation_concern_type = GenericWork
11
9
  self.show_presenter = Sufia::WorkShowPresenter
12
10
  layout "sufia-one-column"
13
11
  end
14
12
 
13
+ module ClassMethods
14
+ # We don't want the breadcrumb action to occur until after the concern has
15
+ # been loaded and authorized
16
+ def curation_concern_type=(curation_concern_type)
17
+ super
18
+ before_action :build_breadcrumbs, only: [:edit, :show]
19
+ end
20
+ end
21
+
15
22
  def new
16
23
  curation_concern.depositor = current_user.user_key
17
24
  super
@@ -46,7 +53,7 @@ module Sufia
46
53
  def after_create_response
47
54
  respond_to do |wants|
48
55
  wants.html do
49
- flash[:notice] = t('sufia.generic_works.new.after_create_html', application_name: view_context.application_name)
56
+ flash[:notice] = t('sufia.works.new.after_create_html', application_name: view_context.application_name)
50
57
  redirect_to [main_app, curation_concern]
51
58
  end
52
59
  wants.json { render :show, status: :created, location: polymorphic_path([main_app, curation_concern]) }
@@ -65,7 +72,7 @@ module Sufia
65
72
  def add_breadcrumb_for_action
66
73
  case action_name
67
74
  when 'edit'.freeze
68
- add_breadcrumb I18n.t("sufia.work.browse_view"), main_app.curation_concerns_generic_work_path(params["id"])
75
+ add_breadcrumb I18n.t("sufia.work.browse_view"), main_app.polymorphic_path(curation_concern)
69
76
  when 'show'.freeze
70
77
  add_breadcrumb presenter.to_s, main_app.polymorphic_path(presenter)
71
78
  end
@@ -16,7 +16,7 @@ module My
16
16
  end
17
17
 
18
18
  def query_solr
19
- return empty_search_result if @user.trophy_works.count == 0
19
+ return empty_search_result if Sufia::TrophyPresenter.find_by_user(@user).count == 0
20
20
  super
21
21
  end
22
22
 
@@ -2,14 +2,17 @@ module Sufia
2
2
  module Forms
3
3
  class BatchEditForm < Sufia::Forms::WorkForm
4
4
  self.terms = [:creator, :contributor, :description,
5
- :keyword, :rights, :publisher, :date_created,
5
+ :keyword, :resource_type, :rights, :publisher, :date_created,
6
6
  :subject, :language, :identifier, :based_near,
7
7
  :related_url]
8
8
  self.required_fields = []
9
- self.model_class = ::GenericWork
9
+ self.model_class = Sufia.primary_work_type
10
10
 
11
11
  attr_accessor :names
12
12
 
13
+ # @param [ActiveFedora::Base] model the model backing the form
14
+ # @param [Ability] current_ability the user authorization model
15
+ # @param [Array<String>] batch a list of document ids in the batch
13
16
  def initialize(model, current_ability, batch)
14
17
  super(model, current_ability)
15
18
  @names = []
@@ -19,18 +22,19 @@ module Sufia
19
22
  private
20
23
 
21
24
  # override this method if you need to initialize more complex RDF assertions (b-nodes)
25
+ # @param [Array<String>] batch a list of document ids in the batch
22
26
  def initialize_combined_fields(batch)
23
27
  combined_attributes = {}
24
28
  permissions = []
25
29
  # For each of the files in the batch, set the attributes to be the concatination of all the attributes
26
30
  batch.each do |doc_id|
27
- gw = ::GenericWork.load_instance_from_solr(doc_id)
31
+ work = model_class.load_instance_from_solr(doc_id)
28
32
  terms.each do |key|
29
33
  combined_attributes[key] ||= []
30
- combined_attributes[key] = (combined_attributes[key] + gw[key]).uniq
34
+ combined_attributes[key] = (combined_attributes[key] + work[key]).uniq
31
35
  end
32
- names << gw.to_s
33
- permissions = (permissions + gw.permissions).uniq
36
+ names << work.to_s
37
+ permissions = (permissions + work.permissions).uniq
34
38
  end
35
39
 
36
40
  terms.each do |key|
@@ -1,13 +1,13 @@
1
1
  module Sufia
2
2
  module Forms
3
3
  class BatchUploadForm < Sufia::Forms::WorkForm
4
- self.model_class = ::GenericWork
4
+ self.model_class = BatchUploadItem
5
5
  include HydraEditor::Form::Permissions
6
6
 
7
7
  self.terms -= [:title, :resource_type]
8
8
 
9
9
  # The WorkForm delegates `#depositor` to `:model`, but `:model` in the
10
- # BatchUpload context is a blank GenericWork with a `nil` depositor
10
+ # BatchUpload context is a blank work with a `nil` depositor
11
11
  # value. This causes the "Sharing With" widget to display the Depositor as
12
12
  # "()". We should be able to reliably pull back the depositor of the new
13
13
  # batch of works by asking the form's Ability what its `current_user` is.
@@ -2,6 +2,10 @@ module Sufia::Forms
2
2
  class CollectionForm < CurationConcerns::Forms::CollectionEditForm
3
3
  delegate :id, to: :model
4
4
 
5
+ # TODO: remove this when https://github.com/projecthydra/hydra-editor/pull/115
6
+ # is merged and hydra-editor 3.0.0 is released
7
+ delegate :model_name, to: :model
8
+
5
9
  def primary_terms
6
10
  [:title]
7
11
  end
@@ -3,6 +3,10 @@ module Sufia::Forms
3
3
  delegate :depositor, :on_behalf_of, :permissions, to: :model
4
4
  include HydraEditor::Form::Permissions
5
5
 
6
+ # TODO: remove this when https://github.com/projecthydra/hydra-editor/pull/115
7
+ # is merged and hydra-editor 3.0.0 is released
8
+ delegate :model_name, to: :model
9
+
6
10
  attr_reader :agreement_accepted
7
11
 
8
12
  self.terms += [:collection_ids]
@@ -1,25 +1,5 @@
1
1
  module Sufia
2
2
  module BlacklightOverride
3
- # TODO: we can remove this override when we can depend on https://github.com/projecthydra-labs/curation_concerns/pull/711
4
- def render_constraints_query(localized_params = params)
5
- # So simple don't need a view template, we can just do it here.
6
- return "".html_safe if localized_params[:q].blank?
7
-
8
- render_constraint_element(constraint_query_label(localized_params),
9
- localized_params[:q],
10
- classes: ["query"],
11
- remove: remove_constraint_url(localized_params))
12
- end
13
-
14
- # TODO: we can remove this override when we can depend on https://github.com/projecthydra-labs/curation_concerns/pull/711
15
- def remove_constraint_url(localized_params)
16
- scope = localized_params.delete(:route_set) || self
17
- options = localized_params.merge(q: nil, action: 'index')
18
- .except(*fields_to_exclude_from_constraint_element)
19
- options.permit!
20
- scope.url_for(options)
21
- end
22
-
23
3
  # This overrides curation_concerns so we aren't removing any fields.
24
4
  # @return [Array<Symbol>] a list of fields to remove on the render_constraint_element
25
5
  # You can override this if you have different fields to remove
@@ -0,0 +1,12 @@
1
+ module Sufia
2
+ module CollectionsHelper
3
+ def render_collection_links(solr_doc)
4
+ collection_list = Sufia::CollectionMemberService.run(solr_doc)
5
+ return if collection_list.empty?
6
+ links = collection_list.map do |collection|
7
+ link_to collection.title_or_label, collection_path(collection.id)
8
+ end
9
+ content_tag :span, safe_join([t('sufia.collection.is_part_of'), ': '] + links)
10
+ end
11
+ end
12
+ end
@@ -1,6 +1,7 @@
1
1
  module Sufia
2
2
  module SufiaHelperBehavior
3
3
  include Sufia::CitationsBehavior
4
+ include ERB::Util # provides html_escape
4
5
 
5
6
  def application_name
6
7
  t('sufia.product_name', default: super)
@@ -28,39 +29,34 @@ module Sufia
28
29
  end
29
30
 
30
31
  # Only Chrome supports this
32
+ # @return [Boolean]
33
+ # @todo Replace uses with more granular client-side detection (as jQuery-fileuploader already does)
31
34
  def browser_supports_directory_upload?
32
35
  user_agent.include? 'Chrome'
33
36
  end
34
37
 
35
- # @param [Hash] options a list of options that blacklight passes from helper_method
36
- # invocation.
37
- def human_readable_date(options)
38
- Date.parse(options[:value]).to_formatted_s(:standard)
39
- end
40
-
41
38
  def error_messages_for(object)
42
- if object.try(:errors) && object.errors.full_messages.any?
43
- content_tag(:div, class: 'alert alert-block alert-error validation-errors') do
44
- content_tag(:h4, I18n.t('sufia.errors.header', model: object.class.model_name.human.downcase), class: 'alert-heading') +
45
- content_tag(:ul) do
46
- object.errors.full_messages.map do |message|
47
- content_tag(:li, message)
48
- end.join('').html_safe
49
- end
50
- end
51
- else
52
- '' # return empty string
39
+ return '' unless object.try(:errors) && object.errors.full_messages.any?
40
+ content_tag(:div, class: 'alert alert-block alert-error validation-errors') do
41
+ content_tag(:h4, I18n.t('sufia.errors.header', model: object.class.model_name.human.downcase), class: 'alert-heading') +
42
+ content_tag(:ul) do
43
+ object.errors.full_messages.map do |message|
44
+ content_tag(:li, message)
45
+ end.join('').html_safe
46
+ end
53
47
  end
54
48
  end
55
49
 
50
+ # @param [ProxyDepositRequest] req
56
51
  def show_transfer_request_title(req)
57
52
  if req.deleted_work? || req.canceled?
58
53
  req.to_s
59
54
  else
60
- link_to(req.to_s, curation_concerns_generic_work_path(req.work_id))
55
+ link_to(req.to_s, req.work)
61
56
  end
62
57
  end
63
58
 
59
+ # @return [Boolean]
64
60
  def has_collection_search_parameters?
65
61
  !params[:cq].blank?
66
62
  end
@@ -69,21 +65,31 @@ module Sufia
69
65
  ActiveFedora::Base.where(DepositSearchBuilder.depositor_field => user.user_key).count
70
66
  end
71
67
 
72
- def link_to_facet(field, field_string)
73
- path = search_action_path(search_state.add_facet_params_and_redirect(field_string, field))
74
- link_to(field, path)
68
+ # @param item [Object]
69
+ # @param field [String]
70
+ # @return [ActiveSupport::SafeBuffer] the html_safe link
71
+ def link_to_facet(item, field)
72
+ path = search_action_path(search_state.add_facet_params_and_redirect(field, item))
73
+ link_to(item, path)
75
74
  end
76
75
 
77
- # @param values [Array] The values to display
78
- # @param solr_field [String] The name of the solr field to link to without its suffix (:facetable)
79
- # @param empty_message [String] ('No value entered') The message to display if no values are passed in.
80
- # @param separator [String] (', ') The value to join with.
81
- def link_to_facet_list(values, solr_field, empty_message = "No value entered", separator = ", ")
76
+ # @param values [Array{String}] strings to display
77
+ # @param solr_field [String] name of the solr field to link to, without its suffix (:facetable)
78
+ # @param empty_message [String] message to display if no values are passed in
79
+ # @param separator [String] value to join with
80
+ # @return [ActiveSupport::SafeBuffer] the html_safe link
81
+ def link_to_facet_list(values, solr_field, empty_message = "No value entered".html_safe, separator = ", ")
82
82
  return empty_message if values.blank?
83
83
  facet_field = Solrizer.solr_name(solr_field, :facetable)
84
84
  safe_join(values.map { |item| link_to_facet(item, facet_field) }, separator)
85
85
  end
86
86
 
87
+ # @param name [String] field name
88
+ # @param value [String] field value
89
+ # @param label [String] defaults to value
90
+ # @param facet_hash [Hash] first argument to Blacklight::SearchState.new
91
+ # @return [ActiveSupport::SafeBuffer] the html_safe link
92
+ # @see Blacklight::SearchState#initialize
87
93
  def link_to_field(name, value, label = nil, facet_hash = {})
88
94
  label ||= value
89
95
  params = { search_field: 'advanced', name => "\"#{value}\"" }
@@ -91,30 +97,57 @@ module Sufia
91
97
  link_to(label, main_app.search_catalog_path(state))
92
98
  end
93
99
 
94
- def index_field_link(options = {})
95
- field_name = options[:config][:field_name]
96
- values = options[:value]
97
- safe_join(values.map { |item| link_to_index_field(item, field_name) }, ", ")
98
- end
100
+ ## GROUP: helper_methods
99
101
 
100
- def link_to_index_field(name, value)
101
- params = { search_field: 'advanced', name => "\"#{value}\"" }
102
- state = search_state.params_for_search(params)
103
- link_to(name, main_app.search_catalog_path(state))
102
+ # A Blacklight helper_method
103
+ # @param [Hash] options from blacklight invocation of helper_method
104
+ # @see #index_field_link params
105
+ # @return [Date]
106
+ def human_readable_date(options)
107
+ Date.parse(options[:value]).to_formatted_s(:standard)
104
108
  end
105
109
 
106
- # @param [String,Hash] text either the string to escape or a hash containing the
107
- # string to escape under the :value key.
108
- def iconify_auto_link(text, showLink = true)
109
- text = presenter(text[:document]).render_values(text[:value], text[:config]) if text.is_a? Hash
110
+ # A Blacklight helper_method
111
+ # @param options [Hash{Symbol=>Object}] Blacklight sends :document, :field, :config, :value and whatever else was in options
112
+ # @option options [Array{String}] :value
113
+ # @option options [Hash] :config including {:field_name => "my_name"}
114
+ # @option options [Hash] :document
115
+ # @option options [Array{String}] :value the strings you might otherwise have passed to this method singly
116
+ # @return [ActiveSupport::SafeBuffer] the html_safe link
117
+ def index_field_link(options)
118
+ raise ArgumentError unless options[:config] && options[:config][:field_name]
119
+ name = options[:config][:field_name]
120
+ values = options[:value]
121
+ safe_join(values.map { |item| link_to_field(name, item, item) }, ", ".html_safe)
122
+ end
123
+
124
+ # Uses Rails auto_link to add links to fields
125
+ #
126
+ # @param field [String,Hash] string to format and escape, or a hash as per helper_method
127
+ # @option field [SolrDocument] :document
128
+ # @option field [String] :field name of the solr field
129
+ # @option field [Blacklight::Configuration::IndexField, Blacklight::Configuration::ShowField] :config
130
+ # @option field [Array] :value array of values for the field
131
+ # @param show_link [Boolean]
132
+ # @return [ActiveSupport::SafeBuffer]
133
+ # @todo stop being a helper_method, start being part of the Blacklight render stack?
134
+ def iconify_auto_link(field, show_link = true)
135
+ if field.is_a? Hash
136
+ options = field[:config].separator_options || {}
137
+ text = field[:value].to_sentence(options)
138
+ else
139
+ text = field
140
+ end
110
141
  # this block is only executed when a link is inserted;
111
142
  # if we pass text containing no links, it just returns text.
112
143
  auto_link(html_escape(text)) do |value|
113
- "<span class='glyphicon glyphicon-new-window'></span>#{('&nbsp;' + value) if showLink}"
144
+ "<span class='glyphicon glyphicon-new-window'></span>#{('&nbsp;' + value) if show_link}"
114
145
  end
115
146
  end
116
147
 
117
- # @param [String,User,Hash] args if a hash, the user_key must be under :value
148
+ # *Sometimes* a Blacklight helper_method
149
+ # @param [String,User,Hash{Symbol=>Array}] args if a hash, the user_key must be under :value
150
+ # @return [ActiveSupport::SafeBuffer] the html_safe link
118
151
  def link_to_profile(args)
119
152
  user_or_key = args.is_a?(Hash) ? args[:value].first : args
120
153
  user = case user_or_key
@@ -124,19 +157,14 @@ module Sufia
124
157
  ::User.find_by_user_key(user_or_key)
125
158
  end
126
159
  return user_or_key if user.nil?
127
-
128
- text = if user.respond_to? :name
129
- user.name
130
- else
131
- user_or_key
132
- end
133
-
160
+ text = user.respond_to?(:name) ? user.name : user_or_key
134
161
  link_to text, Sufia::Engine.routes.url_helpers.profile_path(user)
135
162
  end
136
163
 
137
- # @param [Hash] options hash from blacklight passes from helper_method
138
- # invocation. Maps rights URIs to links with labels.
139
- def rights_statement_links(options = {})
164
+ # A Blacklight helper_method
165
+ # @param [Hash] options from blacklight helper_method invocation. Maps rights URIs to links with labels.
166
+ # @return [ActiveSupport::SafeBuffer] rights statement links, html_safe
167
+ def rights_statement_links(options)
140
168
  options[:value].map { |right| link_to RightsService.label(right), right }.to_sentence.html_safe
141
169
  end
142
170
 
@@ -146,15 +174,13 @@ module Sufia
146
174
  end
147
175
 
148
176
  # Only display the current search parameters if the user is not in the dashboard.
149
- # If they are in the dashboard, then the search defaults to the user's works and not
150
- # all of Sufia.
177
+ # Otherwise, search defaults to the user's works and not all of Sufia.
151
178
  def current_search_parameters
152
179
  return if on_the_dashboard?
153
180
  params[:q]
154
181
  end
155
182
 
156
- # Depending on which page we're landed on, we'll need to set the appropriate action url for
157
- # our search form.
183
+ # @return [String] the appropriate action url for our search form (depending on our current page)
158
184
  def search_form_action
159
185
  if on_the_dashboard?
160
186
  search_action_for_dashboard
@@ -174,7 +200,6 @@ module Sufia
174
200
  def user_display_name_and_key(user_key)
175
201
  user = ::User.find_by_user_key(user_key)
176
202
  return user_key if user.nil?
177
-
178
203
  user.respond_to?(:name) ? "#{user.name} (#{user_key})" : user_key
179
204
  end
180
205
 
@@ -213,6 +238,9 @@ module Sufia
213
238
  end
214
239
  end
215
240
 
241
+ # @param [ActionController::Parameters] params first argument for Blacklight::SearchState.new
242
+ # @param [Hash] facet
243
+ # @note Ignores all but the first facet. Probably a bug.
216
244
  def search_state_with_facets(params, facet = {})
217
245
  state = Blacklight::SearchState.new(params, CatalogController.blacklight_config)
218
246
  return state.params if facet.none?