hyrax 2.1.0.rc2 → 2.1.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/assets/stylesheets/hyrax/_work-show.scss +11 -2
  4. data/app/controllers/hyrax/admin/admin_sets_controller.rb +22 -1
  5. data/app/jobs/import_url_job.rb +50 -18
  6. data/app/models/concerns/hyrax/ability/admin_set_ability.rb +1 -1
  7. data/app/presenters/hyrax/file_set_presenter.rb +4 -0
  8. data/app/presenters/hyrax/work_show_presenter.rb +2 -2
  9. data/app/services/hyrax/collections/permissions_create_service.rb +23 -0
  10. data/app/services/hyrax/collections/permissions_service.rb +17 -11
  11. data/app/views/hyrax/base/_items.html.erb +3 -1
  12. data/app/views/hyrax/collections/_show_document_list_row.html.erb +0 -19
  13. data/app/views/hyrax/file_sets/_actions.html.erb +38 -36
  14. data/app/views/hyrax/file_sets/media_display/_image.html.erb +1 -1
  15. data/config/features.rb +2 -2
  16. data/config/locales/hyrax.de.yml +13 -1
  17. data/config/locales/hyrax.en.yml +12 -0
  18. data/config/locales/hyrax.es.yml +12 -0
  19. data/config/locales/hyrax.fr.yml +12 -0
  20. data/config/locales/hyrax.it.yml +12 -0
  21. data/config/locales/hyrax.pt-BR.yml +12 -0
  22. data/config/locales/hyrax.zh.yml +12 -0
  23. data/lib/hyrax/version.rb +1 -1
  24. data/spec/abilities/admin_set_ability_spec.rb +5 -0
  25. data/spec/controllers/hyrax/admin/admin_sets_controller_spec.rb +71 -2
  26. data/spec/jobs/import_url_job_spec.rb +53 -0
  27. data/spec/models/flipflop_spec.rb +2 -2
  28. data/spec/presenters/hyrax/file_set_presenter_spec.rb +24 -0
  29. data/spec/presenters/hyrax/work_show_presenter_spec.rb +10 -0
  30. data/spec/services/hyrax/collections/permissions_create_service_spec.rb +23 -0
  31. data/spec/services/hyrax/collections/permissions_service_spec.rb +92 -8
  32. data/spec/views/hyrax/base/_items.html.erb_spec.rb +23 -45
  33. data/spec/views/hyrax/base/_member.html.erb_spec.rb +1 -1
  34. data/spec/views/hyrax/collections/_show_document_list_row.html.erb_spec.rb +1 -0
  35. data/spec/views/hyrax/dashboard/collections/_show_document_list_row.html.erb_spec.rb +1 -0
  36. data/spec/views/hyrax/file_sets/_actions.html.erb_spec.rb +30 -9
  37. data/template.rb +1 -1
  38. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2f567b87262e35a9cb150d7155519d89714b19b0
4
- data.tar.gz: 1ba5abb5d18be1edaacdb1bceb77030e1dfa1c66
3
+ metadata.gz: 025cc22285626454040035c0cf14f5d89d818fa8
4
+ data.tar.gz: 5669ec53c680bfe657ba9f1064102b43c5cd6efd
5
5
  SHA512:
6
- metadata.gz: b72273e1c7ecb34223b97e5839232fcdcb5f26d036903bdb2e50f2ec45d437a52edcf88012fc88f2d6c0c14a4a7ac9bd46965b3cdeada506d6e553352f38418f
7
- data.tar.gz: 389b8b29eee7704e80cf71cdceb6ed8f8e96c0bde66a312bb06f31a73cf3996f0e4afbeba6ae132b7f04132a15b036b6ba06e14385ec7c51ff90c8fab65572dd
6
+ metadata.gz: a301edaa82e5823d68d31c7e4dd547848fbac537ae1e30ff6db7de2fc45897d7a2b3171560a1a8f62f242e921d259f5e0ab1a682ff4e7393ba9f446c17745b6e
7
+ data.tar.gz: b034075731f730600bb4415a273e9ae2ed641615052275a91e6d15e52a77af64c15d55687a6922cab802e6cf64118fc365b0e00ab245aafbe0c5014611b2fc0c
data/README.md CHANGED
@@ -63,7 +63,7 @@ The Samvera community is here to help. Please see our [support guide](./.github/
63
63
  # Getting started
64
64
 
65
65
  This document contains instructions specific to setting up an app with __Hyrax
66
- v2.1.0.rc2__. If you are looking for instructions on installing a different
66
+ v2.1.0.rc3__. If you are looking for instructions on installing a different
67
67
  version, be sure to select the appropriate branch or tag from the drop-down
68
68
  menu above.
69
69
 
@@ -162,7 +162,7 @@ NOTE: The steps need to be done in order to create a new Hyrax based app.
162
162
  Generate a new Rails application using the template.
163
163
 
164
164
  ```
165
- rails _5.1.6_ new my_app -m https://raw.githubusercontent.com/samvera/hyrax/v2.1.0.rc2/template.rb
165
+ rails _5.1.6_ new my_app -m https://raw.githubusercontent.com/samvera/hyrax/v2.1.0.rc3/template.rb
166
166
  ```
167
167
 
168
168
  Generating a new Rails application using Hyrax's template above takes cares of a number of steps for you, including:
@@ -4,7 +4,8 @@
4
4
  }
5
5
  }
6
6
 
7
- .no-preview, .social-media {
7
+ .no-preview,
8
+ .social-media {
8
9
  padding: $panel-body-padding;
9
10
  }
10
11
 
@@ -17,7 +18,8 @@ header > h1 .label {
17
18
  padding: $panel-body-padding;
18
19
  }
19
20
 
20
- .relationships, .attributes {
21
+ .relationships,
22
+ .attributes {
21
23
  tbody th {
22
24
  width: 20%;
23
25
  }
@@ -52,6 +54,13 @@ ul.tabular {
52
54
  .work-type {
53
55
  margin-bottom: 18px;
54
56
  margin-top: -8px;
57
+
58
+ .panel-body {
59
+ .work_description,
60
+ li.attribute {
61
+ word-break: break-word;
62
+ }
63
+ }
55
64
  }
56
65
 
57
66
  .panel-workflow {
@@ -2,8 +2,13 @@ module Hyrax
2
2
  class Admin::AdminSetsController < ApplicationController
3
3
  include Hyrax::CollectionsControllerBehavior
4
4
 
5
- before_action :ensure_manager!
5
+ before_action :authenticate_user!
6
+ before_action :ensure_manager!, except: [:show]
6
7
  load_and_authorize_resource
8
+ before_action :ensure_viewer!, only: [:show]
9
+
10
+ # Catch permission errors
11
+ rescue_from Hydra::AccessDenied, CanCan::AccessDenied, with: :deny_adminset_access
7
12
 
8
13
  with_themed_layout 'dashboard'
9
14
  self.presenter_class = Hyrax::AdminSetPresenter
@@ -19,6 +24,15 @@ module Hyrax
19
24
  class_attribute :admin_set_create_service
20
25
  self.admin_set_create_service = AdminSetCreateService
21
26
 
27
+ def deny_adminset_access(exception)
28
+ if current_user && current_user.persisted?
29
+ redirect_to root_url, alert: exception.message
30
+ else
31
+ session['user_return_to'] = request.url
32
+ redirect_to main_app.new_user_session_url, alert: exception.message
33
+ end
34
+ end
35
+
22
36
  def show
23
37
  add_breadcrumb I18n.t('hyrax.controls.home'), hyrax.root_path
24
38
  add_breadcrumb t(:'hyrax.dashboard.title'), hyrax.dashboard_path
@@ -92,11 +106,18 @@ module Hyrax
92
106
  end
93
107
 
94
108
  def ensure_manager!
109
+ # TODO: Review for possible removal. Doesn't appear to apply anymore.
95
110
  # Even though the user can view this admin set, they may not be able to view
96
111
  # it on the admin page.
97
112
  authorize! :manage_any, AdminSet
98
113
  end
99
114
 
115
+ def ensure_viewer!
116
+ # Even though the user can view this admin set, they may not be able to view
117
+ # it on the admin page if access is granted as a public or registered user only.
118
+ authorize! :view_admin_show, @admin_set
119
+ end
120
+
100
121
  def create_admin_set
101
122
  admin_set_create_service.call(admin_set: @admin_set, creating_user: current_user)
102
123
  end
@@ -8,22 +8,27 @@ require 'browse_everything/retriever'
8
8
  # and CreateWithRemoteFilesActor when files are located in some other service.
9
9
  class ImportUrlJob < Hyrax::ApplicationJob
10
10
  queue_as Hyrax.config.ingest_queue_name
11
+ attr_reader :file_set, :operation
11
12
 
12
13
  before_enqueue do |job|
14
+ operation = job.arguments[1]
13
15
  operation.pending_job(job)
14
16
  end
15
17
 
16
- # Retrieves the operation for the job
17
- def operation
18
- arguments.reduce(:merge).fetch(:operation)
19
- end
20
-
21
18
  # @param [FileSet] file_set
22
19
  # @param [Hyrax::BatchCreateOperation] operation
23
20
  def perform(file_set, operation, headers = {})
24
21
  operation.performing!
25
22
  user = User.find_by_user_key(file_set.depositor)
26
23
  uri = URI(file_set.import_url)
24
+ @file_set = file_set
25
+ @operation = operation
26
+
27
+ unless HTTParty.head(file_set.import_url).success?
28
+ send_error('Expired URL')
29
+ return false
30
+ end
31
+
27
32
  # @todo Use Hydra::Works::AddExternalFileToFileSet instead of manually
28
33
  # copying the file here. This will be gnarly.
29
34
  copy_remote_file(uri, headers) do |f|
@@ -33,13 +38,7 @@ class ImportUrlJob < Hyrax::ApplicationJob
33
38
  # FileSetActor operates synchronously so that this tempfile is available.
34
39
  # If asynchronous, the job might be invoked on a machine that did not have this temp file on its file system!
35
40
  # NOTE: The return status may be successful even if the content never attaches.
36
- if Hyrax::Actors::FileSetActor.new(file_set, user).create_content(f, from_url: true)
37
- operation.success!
38
- else
39
- # send message to user on download failure
40
- Hyrax.config.callback.run(:after_import_url_failure, file_set, user)
41
- operation.fail!(file_set.errors.full_messages.join(' '))
42
- end
41
+ log_import_status(uri, f, user)
43
42
  end
44
43
  end
45
44
 
@@ -57,14 +56,47 @@ class ImportUrlJob < Hyrax::ApplicationJob
57
56
  Rails.logger.debug("ImportUrlJob: Copying <#{uri}> to #{dir}")
58
57
 
59
58
  File.open(File.join(dir, filename), 'wb') do |f|
60
- retriever = BrowseEverything::Retriever.new
61
- uri_spec = { 'url' => uri }.merge(headers)
62
- retriever.retrieve(uri_spec) do |chunk|
63
- f.write(chunk)
59
+ begin
60
+ write_file(uri, f, headers)
61
+ yield f
62
+ rescue StandardError => e
63
+ send_error(e.message)
64
64
  end
65
- f.rewind
66
- yield f
67
65
  end
68
66
  Rails.logger.debug("ImportUrlJob: Closing #{File.join(dir, filename)}")
69
67
  end
68
+
69
+ # Send message to user on download failure
70
+ # @param filename [String] the filename of the file to download
71
+ # @param error_message [String] the download error message
72
+ def send_error(error_message)
73
+ user = User.find_by_user_key(file_set.depositor)
74
+ @file_set.errors.add('Error:', error_message)
75
+ Hyrax.config.callback.run(:after_import_url_failure, @file_set, user)
76
+ @operation.fail!(@file_set.errors.full_messages.join(' '))
77
+ end
78
+
79
+ # Write file to the stream
80
+ # @param uri [URI] the uri of the file to download
81
+ # @param f [IO] the stream to write to
82
+ def write_file(uri, f, headers)
83
+ retriever = BrowseEverything::Retriever.new
84
+ uri_spec = { 'url' => uri }.merge(headers)
85
+ retriever.retrieve(uri_spec) do |chunk|
86
+ f.write(chunk)
87
+ end
88
+ f.rewind
89
+ end
90
+
91
+ # Set the import operation status
92
+ # @param uri [URI] the uri of the file to download
93
+ # @param f [IO] the stream to write to
94
+ # @param user [User]
95
+ def log_import_status(uri, f, user)
96
+ if Hyrax::Actors::FileSetActor.new(@file_set, user).create_content(f, from_url: true)
97
+ operation.success!
98
+ else
99
+ send_error(uri.path, nil)
100
+ end
101
+ end
70
102
  end
@@ -9,7 +9,7 @@ module Hyrax
9
9
  can :view_admin_show_any, AdminSet
10
10
  else
11
11
  can :manage_any, AdminSet if Hyrax::Collections::PermissionsService.can_manage_any_admin_set?(ability: self)
12
- can :create_any, AdminSet if Hyrax::CollectionTypes::PermissionsService.can_create_admin_set_collection_type?(ability: self)
12
+ can [:create_any, :create], AdminSet if Hyrax::CollectionTypes::PermissionsService.can_create_admin_set_collection_type?(ability: self)
13
13
  can :view_admin_show_any, AdminSet if Hyrax::Collections::PermissionsService.can_view_admin_show_for_any_admin_set?(ability: self)
14
14
 
15
15
  can [:edit, :update, :destroy], AdminSet do |admin_set| # for test by solr_doc, see solr_document_ability.rb
@@ -90,6 +90,10 @@ module Hyrax
90
90
  presenter_args: current_ability).first
91
91
  end
92
92
 
93
+ def user_can_perform_any_action?
94
+ current_ability.can?(:edit, id) || current_ability.can?(:destroy, id) || current_ability.can?(:download, id)
95
+ end
96
+
93
97
  private
94
98
 
95
99
  def link_presenter_class
@@ -155,8 +155,8 @@ module Hyrax
155
155
 
156
156
  delegate :member_presenters, :file_set_presenters, :work_presenters, to: :member_presenter_factory
157
157
 
158
- def exclude_unauthorized_file_sets
159
- member_presenters.delete_if { |m| m.is_a?(Hyrax::FileSetPresenter) && !current_ability.can?(:read, m.id) }
158
+ def exclude_unauthorized_members
159
+ member_presenters.delete_if { |m| !current_ability.can?(:read, m.id) }
160
160
  end
161
161
 
162
162
  def manifest_url
@@ -17,6 +17,29 @@ module Hyrax
17
17
  collection.reset_access_controls!
18
18
  end
19
19
 
20
+ # @api public
21
+ #
22
+ # Add access grants to a collection
23
+ #
24
+ # @param collection_id [String] id of a collection
25
+ # @param grants [Array<Hash>] array of grants to add to the collection
26
+ # @example grants
27
+ # [ { agent_type: Hyrax::PermissionTemplateAccess::GROUP,
28
+ # agent_id: 'my_group_name',
29
+ # access: Hyrax::PermissionTemplateAccess::DEPOSIT } ]
30
+ # @see Hyrax::PermissionTemplateAccess for valid values for agent_type and access
31
+ def self.add_access(collection_id:, grants:)
32
+ collection = Collection.find(collection_id)
33
+ template = Hyrax::PermissionTemplate.find_by!(source_id: collection_id)
34
+ grants.each do |grant|
35
+ Hyrax::PermissionTemplateAccess.find_or_create_by(permission_template_id: template.id,
36
+ agent_type: grant[:agent_type],
37
+ agent_id: grant[:agent_id],
38
+ access: grant[:access])
39
+ end
40
+ collection.reset_access_controls!
41
+ end
42
+
20
43
  # @api private
21
44
  #
22
45
  # Gather the default permissions needed for a new collection
@@ -170,9 +170,11 @@ module Hyrax
170
170
  # @return [Boolean] true if the user has permission to view the admin show page for the collection
171
171
  # @note Several checks get the user's groups from the user's ability. The same values can be retrieved directly from a passed in ability.
172
172
  def self.can_view_admin_show_for_collection?(collection_id:, ability:)
173
- deposit_access_to_collection?(collection_id: collection_id, ability: ability) ||
174
- manage_access_to_collection?(collection_id: collection_id, ability: ability) ||
175
- view_access_to_collection?(collection_id: collection_id, ability: ability)
173
+ exclude_groups = [::Ability.registered_group_name,
174
+ ::Ability.public_group_name]
175
+ manage_access_to_collection?(collection_id: collection_id, ability: ability) ||
176
+ deposit_access_to_collection?(collection_id: collection_id, ability: ability, exclude_groups: exclude_groups) ||
177
+ view_access_to_collection?(collection_id: collection_id, ability: ability, exclude_groups: exclude_groups)
176
178
  end
177
179
 
178
180
  # @api private
@@ -181,10 +183,11 @@ module Hyrax
181
183
  #
182
184
  # @param collection_id [String] id of the collection we are checking permissions on
183
185
  # @param ability [Ability] the ability coming from cancan ability check
186
+ # @param exclude_groups [Array<String>] name of groups to exclude from the results
184
187
  # @return [Boolean] true if the user has :deposit access to the collection
185
188
  # @note Several checks get the user's groups from the user's ability. The same values can be retrieved directly from a passed in ability.
186
- def self.deposit_access_to_collection?(collection_id:, ability: nil)
187
- access_to_collection?(collection_id: collection_id, access: 'deposit', ability: ability)
189
+ def self.deposit_access_to_collection?(collection_id:, ability: nil, exclude_groups: [])
190
+ access_to_collection?(collection_id: collection_id, access: 'deposit', ability: ability, exclude_groups: exclude_groups)
188
191
  end
189
192
  private_class_method :deposit_access_to_collection?
190
193
 
@@ -194,10 +197,11 @@ module Hyrax
194
197
  #
195
198
  # @param collection_id [String] id of the collection we are checking permissions on
196
199
  # @param ability [Ability] the ability coming from cancan ability check
200
+ # @param exclude_groups [Array<String>] name of groups to exclude from the results
197
201
  # @return [Boolean] true if the user has :manage access to the collection
198
202
  # @note Several checks get the user's groups from the user's ability. The same values can be retrieved directly from a passed in ability.
199
- def self.manage_access_to_collection?(collection_id:, ability:)
200
- access_to_collection?(collection_id: collection_id, access: 'manage', ability: ability)
203
+ def self.manage_access_to_collection?(collection_id:, ability:, exclude_groups: [])
204
+ access_to_collection?(collection_id: collection_id, access: 'manage', ability: ability, exclude_groups: exclude_groups)
201
205
  end
202
206
  private_class_method :manage_access_to_collection?
203
207
 
@@ -207,10 +211,11 @@ module Hyrax
207
211
  #
208
212
  # @param collection_id [String] id of the collection we are checking permissions on
209
213
  # @param ability [Ability] the ability coming from cancan ability check
214
+ # @param exclude_groups [Array<String>] name of groups to exclude from the results
210
215
  # @return [Boolean] true if the user has permission to view the collection
211
216
  # @note Several checks get the user's groups from the user's ability. The same values can be retrieved directly from a passed in ability.
212
- def self.view_access_to_collection?(collection_id:, ability:)
213
- access_to_collection?(collection_id: collection_id, access: 'view', ability: ability)
217
+ def self.view_access_to_collection?(collection_id:, ability:, exclude_groups: [])
218
+ access_to_collection?(collection_id: collection_id, access: 'view', ability: ability, exclude_groups: exclude_groups)
214
219
  end
215
220
  private_class_method :view_access_to_collection?
216
221
 
@@ -221,13 +226,14 @@ module Hyrax
221
226
  # @param collection_id [String] id of the collection we are checking permissions on
222
227
  # @param access [Symbol] the access level to check
223
228
  # @param ability [Ability] the ability coming from cancan ability check
229
+ # @param exclude_groups [Array<String>] name of groups to exclude from the results
224
230
  # @return [Boolean] true if the user has permission to view the collection
225
231
  # @note Several checks get the user's groups from the user's ability. The same values can be retrieved directly from a passed in ability.
226
- def self.access_to_collection?(collection_id:, access:, ability:)
232
+ def self.access_to_collection?(collection_id:, access:, ability:, exclude_groups: [])
227
233
  return false unless collection_id
228
234
  template = Hyrax::PermissionTemplate.find_by!(source_id: collection_id)
229
235
  return true if ([ability.current_user.user_key] & template.agent_ids_for(agent_type: 'user', access: access)).present?
230
- return true if (ability.user_groups & template.agent_ids_for(agent_type: 'group', access: access)).present?
236
+ return true if (ability.user_groups & (template.agent_ids_for(agent_type: 'group', access: access) - exclude_groups)).present?
231
237
  false
232
238
  end
233
239
  private_class_method :access_to_collection?
@@ -1,5 +1,5 @@
1
1
  <h2><%= t('.header') %></h2>
2
- <% members = Flipflop.hide_private_files? ? presenter.exclude_unauthorized_file_sets : presenter.member_presenters %>
2
+ <% members = Flipflop.hide_private_items? ? presenter.exclude_unauthorized_members : presenter.member_presenters %>
3
3
  <% if members.present? %>
4
4
  <table class="table table-striped related-files">
5
5
  <thead>
@@ -17,4 +17,6 @@
17
17
  </table>
18
18
  <% elsif can? :edit, presenter.id %>
19
19
  <div class="alert alert-warning" role="alert"><%= t('.empty', type: presenter.human_readable_type) %></div>
20
+ <% else %>
21
+ <div class="alert alert-warning" role="alert"><%= t('.unauthorized', type: presenter.human_readable_type) %></div>
20
22
  <% end %>
@@ -13,7 +13,6 @@
13
13
  <div class="media-body">
14
14
  <p class="media-heading">
15
15
  <strong><%= link_to document.title_or_label, [main_app, document], id: "src_copy_link#{id}", class: "#{'document-title' if document.title_or_label == document.label}" %></strong>
16
- <a href="#" class="small" title="Click for more details"><i id="expand_<%= id %>" class="glyphicon glyphicon-chevron-right"></i></a>
17
16
  </p>
18
17
  <%= render_collection_links(document) %>
19
18
  </div>
@@ -24,21 +23,3 @@
24
23
  <%= render_visibility_link(document) %>
25
24
  </td>
26
25
  </tr>
27
- <tr id="detail_<%= id %>"> <!-- document detail"> -->
28
- <td colspan="6">
29
- <dl class="expanded-details row">
30
- <dt class="col-xs-3 col-lg-2">Creator:</dt>
31
- <dd class="col-xs-9 col-lg-4"><%= document.creator.to_a.to_sentence %></dd>
32
- <dt class="col-xs-3 col-lg-2">Depositor:</dt>
33
- <dd class="col-xs-9 col-lg-4"><%= link_to_profile document.depositor %></dd>
34
- <dt class="col-xs-3 col-lg-2">Edit Access:</dt>
35
- <dd class="col-xs-9 col-lg-10">
36
- <% if document.edit_groups.present? %>
37
- Groups: <%= document.edit_groups.join(', ') %>
38
- <br />
39
- <% end %>
40
- Users: <%= document.edit_people.join(', ') %>
41
- </dd>
42
- </dl>
43
- </td>
44
- </tr>
@@ -1,42 +1,44 @@
1
- <div class="btn-group">
1
+ <% if file_set.user_can_perform_any_action? %>
2
+ <div class="btn-group">
2
3
 
3
- <button class="btn btn-default dropdown-toggle" data-toggle="dropdown" type="button" id="dropdownMenu_<%= file_set.id %>" aria-haspopup="true">
4
- <span class="sr-only">Press to </span>
5
- Select an action
6
- <span class="caret" aria-hidden="true"></span>
7
- </button>
4
+ <button class="btn btn-default dropdown-toggle" data-toggle="dropdown" type="button" id="dropdownMenu_<%= file_set.id %>" aria-haspopup="true">
5
+ <span class="sr-only">Press to </span>
6
+ <%= t('.header') %>
7
+ <span class="caret" aria-hidden="true"></span>
8
+ </button>
8
9
 
9
- <ul role="menu" class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenu_<%= file_set.id %>">
10
- <% if can?(:edit, file_set.id) %>
11
- <li role="menuitem" tabindex="-1">
12
- <%= link_to 'Edit', edit_polymorphic_path([main_app, file_set]),
13
- { title: "Edit #{file_set}" } %>
14
- </li>
10
+ <ul role="menu" class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenu_<%= file_set.id %>">
11
+ <% if can?(:edit, file_set.id) %>
12
+ <li role="menuitem" tabindex="-1">
13
+ <%= link_to t('.edit'), edit_polymorphic_path([main_app, file_set]),
14
+ { title: t('.edit_title', file_set: file_set) } %>
15
+ </li>
15
16
 
16
- <li role="menuitem" tabindex="-1">
17
- <%= link_to 'Versions', edit_polymorphic_path([main_app, file_set], anchor: 'versioning_display'),
18
- { title: "Display previous versions" } %>
19
- </li>
20
- <% end %>
17
+ <li role="menuitem" tabindex="-1">
18
+ <%= link_to t('.versions'), edit_polymorphic_path([main_app, file_set], anchor: 'versioning_display'),
19
+ { title: t('.versions_title') } %>
20
+ </li>
21
+ <% end %>
21
22
 
22
- <% if can?(:destroy, file_set.id) %>
23
- <li role="menuitem" tabindex="-1">
24
- <%= link_to 'Delete', polymorphic_path([main_app, file_set]),
25
- method: :delete, title: "Delete #{file_set}",
26
- data: {confirm: "Deleting #{file_set} from #{application_name} is permanent. Click OK to delete this from #{application_name}, or Cancel to cancel this operation"} %>
27
- </li>
28
- <% end %>
23
+ <% if can?(:destroy, file_set.id) %>
24
+ <li role="menuitem" tabindex="-1">
25
+ <%= link_to t('.delete'), polymorphic_path([main_app, file_set]),
26
+ method: :delete, title: t('.delete_title', file_set: file_set),
27
+ data: { confirm: t('.delete_confirm', file_set: file_set, application_name: application_name) } %>
28
+ </li>
29
+ <% end %>
29
30
 
30
- <% if can?(:download, file_set.id) %>
31
- <li role="menuitem" tabindex="-1">
32
- <%= link_to 'Download',
33
- hyrax.download_path(file_set),
34
- title: "Download #{file_set.to_s.inspect}",
35
- target: "_blank",
36
- id: "file_download",
37
- data: { label: file_set.id } %>
38
- </li>
39
- <% end %>
31
+ <% if can?(:download, file_set.id) %>
32
+ <li role="menuitem" tabindex="-1">
33
+ <%= link_to t('.download'),
34
+ hyrax.download_path(file_set),
35
+ title: t('.download_title', file_set: file_set),
36
+ target: "_blank",
37
+ id: "file_download",
38
+ data: { label: file_set.id } %>
39
+ </li>
40
+ <% end %>
40
41
 
41
- </ul>
42
- </div>
42
+ </ul>
43
+ </div>
44
+ <% end %>