blacklight-spotlight 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/spotlight/check_user_existence.js +16 -9
  3. data/app/assets/javascripts/spotlight/tabs.js +6 -0
  4. data/app/assets/javascripts/spotlight/users.js +1 -1
  5. data/app/assets/stylesheets/spotlight/_upload.scss +0 -5
  6. data/app/controllers/spotlight/admin_users_controller.rb +49 -0
  7. data/app/controllers/spotlight/catalog_controller.rb +0 -7
  8. data/app/controllers/spotlight/concerns/user_existable.rb +24 -0
  9. data/app/controllers/spotlight/concerns/user_invitable.rb +30 -0
  10. data/app/controllers/spotlight/exhibits_controller.rb +3 -0
  11. data/app/controllers/spotlight/resources/csv_upload_controller.rb +42 -0
  12. data/app/controllers/spotlight/resources/upload_controller.rb +2 -27
  13. data/app/controllers/spotlight/resources_controller.rb +7 -24
  14. data/app/controllers/spotlight/roles_controller.rb +2 -29
  15. data/app/models/spotlight/exhibit.rb +2 -0
  16. data/app/models/spotlight/resource.rb +0 -14
  17. data/app/views/devise/mailer/invitation_instructions.html.erb +11 -4
  18. data/app/views/shared/_site_sidebar.html.erb +2 -1
  19. data/app/views/spotlight/admin_users/index.html.erb +57 -0
  20. data/app/views/spotlight/catalog/_admin_header.html.erb +3 -9
  21. data/app/views/spotlight/exhibits/_tags.html.erb +11 -0
  22. data/app/views/spotlight/exhibits/index.html.erb +12 -3
  23. data/app/views/spotlight/home_pages/_empty.html.erb +2 -2
  24. data/app/views/spotlight/resources/_external_resources_form.html.erb +20 -0
  25. data/app/views/spotlight/resources/_missing_external_resources_partials.html.erb +5 -0
  26. data/app/views/spotlight/resources/{upload/_multi_item_form.html.erb → csv_upload/_form.html.erb} +1 -1
  27. data/app/views/spotlight/resources/new.html.erb +18 -3
  28. data/app/views/spotlight/resources/upload/{_single_item_form.html.erb → _form.html.erb} +0 -0
  29. data/config/locales/spotlight.en.yml +40 -12
  30. data/config/routes.rb +18 -6
  31. data/lib/spotlight/engine.rb +2 -3
  32. data/lib/spotlight/version.rb +1 -1
  33. data/spec/controllers/spotlight/admin_users_controller_spec.rb +83 -0
  34. data/spec/controllers/spotlight/catalog_controller_spec.rb +0 -11
  35. data/spec/controllers/spotlight/resources/csv_upload_controller_spec.rb +59 -0
  36. data/spec/controllers/spotlight/resources/upload_controller_spec.rb +1 -51
  37. data/spec/controllers/spotlight/resources_controller_spec.rb +0 -12
  38. data/spec/controllers/spotlight/roles_controller_spec.rb +1 -1
  39. data/spec/features/{upload_non_repository_item_spec.rb → add_items_spec.rb} +28 -16
  40. data/spec/features/exhibits_index_spec.rb +31 -0
  41. data/spec/features/site_admin_management_spec.rb +67 -0
  42. data/spec/models/spotlight/resource_spec.rb +0 -9
  43. data/spec/views/spotlight/catalog/admin.html.erb_spec.rb +7 -8
  44. data/spec/views/spotlight/exhibits/index.html.erb_spec.rb +47 -1
  45. data/spec/views/spotlight/home_pages/_empty.html.erb_spec.rb +4 -3
  46. data/spec/views/spotlight/resources/_external_resources_form.html.erb_spec.rb +23 -0
  47. data/spec/views/spotlight/{catalog → resources}/new.html.erb_spec.rb +2 -2
  48. metadata +26 -19
  49. data/app/models/spotlight/resource_provider.rb +0 -24
  50. data/app/views/layouts/spotlight/popup.html.erb +0 -52
  51. data/app/views/spotlight/catalog/new.html.erb +0 -7
  52. data/app/views/spotlight/resources/_bookmarklet.html.erb +0 -5
  53. data/app/views/spotlight/resources/_form.html.erb +0 -23
  54. data/app/views/spotlight/resources/upload/new.html.erb +0 -22
  55. data/spec/features/add_item_bookmarklet_spec.rb +0 -33
  56. data/spec/models/spotlight/resource_provider_spec.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2b45039dfeb64f44d24665c3b2fbabef264eca86
4
- data.tar.gz: 8d3f3015e3b61bbd5d185903b82af1c17a3c302a
3
+ metadata.gz: 8cddcc5a9f2a5d68c50a7092eec103a1fd4e4ff2
4
+ data.tar.gz: a368d7becced90f589111c22c2dbf2b5311d1aa8
5
5
  SHA512:
6
- metadata.gz: 2d146ecf16f66315c47f81ef1e1f7a5a911cc0cb9989955a30bb64707e2a9a4b762b849578481ff0021b78d44998382265718f1c13e9af92e5a6a63482a23891
7
- data.tar.gz: 14e5e9cb7329342bc6c8ed68cdd2bfae3e22f8e0efcc66d1c4297a26bb7b49a88924ba7f6a6ad0b51f4e37c05292354cc9ccfb12ffc427a2b03a769b2c59efa0
6
+ metadata.gz: b39192c1b349d0b10f7f9968ee2683e6c62aadb203069e28eb41cf9165a6dbf527bf2870a06639298ba52cbacd29a0e6b042e43be5a7136a956ebeaf6ef3a818
7
+ data.tar.gz: 113f4f169e3a1ea853e39417e5a96c49e2b3492c311f3f161d35187b917d759a5b999886f44df3cce2abfe36b1b07a597bebea6e85dcdfe4f4ba432425c68724
@@ -10,8 +10,7 @@
10
10
 
11
11
  function checkIfUserExists() {
12
12
  target = $(this);
13
- var form = target.closest('form');
14
- if (target.val() !== '' && form[0].checkValidity()) {
13
+ if (target.val() !== '' && form()[0].checkValidity()) {
15
14
  $.ajax(userExistsUrl())
16
15
  .success(userExists)
17
16
  .fail(userDoesNotExist);
@@ -42,26 +41,34 @@
42
41
  var link = noUserNote().find('a');
43
42
  var originalHref = link.data('inviteUrl');
44
43
  var userName = target.val();
45
- var role = roleSelect().val();
46
44
  link.attr(
47
45
  'href',
48
- originalHref + '?user=' + encodeURIComponent(userName) + '&role=' + encodeURIComponent(role)
46
+ originalHref + '?user=' + encodeURIComponent(userName) + '&role=' + encodeURIComponent(roleValue())
49
47
  );
50
48
  }
51
49
 
50
+ function roleValue() {
51
+ if (roleSelect().length > 0) {
52
+ return roleSelect().val();
53
+ } else {
54
+ return target.closest('tr').find('[data-user-role]').data('userRole');
55
+ }
56
+ }
57
+
52
58
  function roleSelect() {
53
59
  return target.closest('tr').find('select');
54
60
  }
55
61
 
56
62
  function noUserNote() {
57
- return target.closest('td')
58
- .find('[data-behavior="no-user-note"]');
63
+ return form().find('[data-behavior="no-user-note"]');
59
64
  }
60
65
 
61
66
  function submitButton() {
62
- return target.closest('tr')
63
- .next('tr')
64
- .find('input[type="submit"]');
67
+ return form().find('input[type="submit"]');
68
+ }
69
+
70
+ function form() {
71
+ return target.closest('form');
65
72
  }
66
73
 
67
74
  function userExistsUrl() {
@@ -0,0 +1,6 @@
1
+ Spotlight.onLoad(function(){
2
+ if ($('[role=tabpanel]').length > 0 && window.location.hash) {
3
+ var tabpanel = $(window.location.hash).closest('[role=tabpanel]');
4
+ $('a[role=tab][href=#'+tabpanel.attr('id')+']').tab('show');
5
+ }
6
+ });
@@ -75,5 +75,5 @@
75
75
 
76
76
 
77
77
  Spotlight.onLoad(function() {
78
- $('.edit_exhibit').spotlight_users();
78
+ $('.edit_exhibit, .admin-users').spotlight_users();
79
79
  });
@@ -1,5 +0,0 @@
1
- .item-upload-tabs {
2
- .tab-content {
3
- margin-top: $padding-large-vertical;
4
- }
5
- }
@@ -0,0 +1,49 @@
1
+ module Spotlight
2
+ ##
3
+ # A controller to handle the adminstration of site admin users
4
+ class AdminUsersController < Spotlight::ApplicationController
5
+ include Spotlight::Concerns::UserExistable
6
+ include Spotlight::Concerns::UserInvitable
7
+
8
+ before_action :authenticate_user!
9
+ before_action :load_site
10
+ load_and_authorize_resource :site, class: 'Spotlight::Site'
11
+
12
+ def index
13
+ end
14
+
15
+ def create
16
+ if update_roles
17
+ flash[:notice] = t('spotlight.admin_users.create.success')
18
+ else
19
+ flash[:error] = t('spotlight.admin_users.create.error')
20
+ end
21
+ redirect_to spotlight.admin_users_path
22
+ end
23
+
24
+ def destroy
25
+ user = Spotlight::Engine.user_class.find(params[:id])
26
+ if user.roles.where(resource: @site).first.destroy
27
+ flash[:notice] = t('spotlight.admin_users.destroy.success')
28
+ else
29
+ flash[:error] = t('spotlight.admin_users.destroy.error')
30
+ end
31
+ redirect_to spotlight.admin_users_path
32
+ end
33
+
34
+ private
35
+
36
+ def load_site
37
+ @site ||= Spotlight::Site.instance
38
+ end
39
+
40
+ def create_params
41
+ params.require(:user).permit(:email)
42
+ end
43
+
44
+ def update_roles
45
+ user = Spotlight::Engine.user_class.where(email: create_params[:email]).first
46
+ Spotlight::Role.create(user: user, role: 'admin', resource: @site).save
47
+ end
48
+ end
49
+ end
@@ -36,13 +36,6 @@ module Spotlight
36
36
  blacklight_config.view.edit.partials.insert(2, :edit)
37
37
  end
38
38
 
39
- def new
40
- add_breadcrumb t(:'spotlight.curation.sidebar.header'), exhibit_dashboard_path(@exhibit)
41
- add_breadcrumb t(:'spotlight.curation.sidebar.items'), admin_exhibit_catalog_index_path(@exhibit)
42
- add_breadcrumb t(:'spotlight.catalog.new.header'), new_exhibit_catalog_path(@exhibit)
43
- @resource = @exhibit.resources.build
44
- end
45
-
46
39
  def show
47
40
  super
48
41
 
@@ -0,0 +1,24 @@
1
+ module Spotlight
2
+ module Concerns
3
+ ###
4
+ # Mixin to be included into controllers that provides a
5
+ # method to check if a particular user exists in the site
6
+ module UserExistable
7
+ def exists
8
+ # note: the messages returned are not shown to users and really only useful for debug, hence no translation necessary
9
+ # app uses html status code to act on response
10
+ if Spotlight::Engine.user_class.where(email: exists_params).present?
11
+ render json: { message: 'User exists' }
12
+ else
13
+ render json: { message: 'User does not exist' }, status: :not_found
14
+ end
15
+ end
16
+
17
+ protected
18
+
19
+ def exists_params
20
+ params.require(:user)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ module Spotlight
2
+ module Concerns
3
+ ###
4
+ # Mixin to be included into controllers that provides an action which
5
+ # allows admins and curators to invite users and assign them a role.
6
+ module UserInvitable
7
+ def invite
8
+ # skip_invitation stops the immediate delivery of the invitation
9
+ user = Spotlight::Engine.user_class.invite!(email: invite_params[:user], skip_invitation: true)
10
+ role = Spotlight::Role.create(resource: exhibit_or_site, user: user, role: invite_params[:role])
11
+ if role.save
12
+ user.deliver_invitation # now deliver it when we have saved the role
13
+ redirect_to :back, notice: t(:'helpers.submit.invite.invited')
14
+ else
15
+ redirect_to :back, alert: t(:'helpers.submit.role.batch_error')
16
+ end
17
+ end
18
+
19
+ protected
20
+
21
+ def invite_params
22
+ params.permit(:user, :role)
23
+ end
24
+
25
+ def exhibit_or_site
26
+ current_exhibit || @site
27
+ end
28
+ end
29
+ end
30
+ end
@@ -8,6 +8,9 @@ module Spotlight
8
8
  load_and_authorize_resource
9
9
 
10
10
  def index
11
+ @published_exhibits = @exhibits.published.page(params[:page])
12
+ @published_exhibits = @published_exhibits.tagged_with(params[:tag]) if params[:tag]
13
+
11
14
  if @exhibits.one?
12
15
  redirect_to @exhibits.first
13
16
  else
@@ -0,0 +1,42 @@
1
+ require 'csv'
2
+
3
+ module Spotlight
4
+ module Resources
5
+ ##
6
+ # Creating new exhibit items from single-item entry forms
7
+ # or batch CSV upload
8
+ class CsvUploadController < ApplicationController
9
+ helper :all
10
+
11
+ before_action :authenticate_user!
12
+
13
+ load_and_authorize_resource :exhibit, class: Spotlight::Exhibit
14
+
15
+ def create
16
+ file = csv_params[:url]
17
+ csv = CSV.parse(file.read, headers: true, return_headers: false, encoding: 'utf-8').map(&:to_hash)
18
+ Spotlight::AddUploadsFromCSV.perform_later(csv, current_exhibit, current_user)
19
+ flash[:notice] = t('spotlight.resources.upload.csv.success', file_name: file.original_filename)
20
+ redirect_to :back
21
+ end
22
+
23
+ def template
24
+ render text: CSV.generate { |csv| csv << data_param_keys.unshift(:url) }, content_type: 'text/csv'
25
+ end
26
+
27
+ private
28
+
29
+ def build_resource
30
+ @resource ||= Spotlight::Resources::Upload.new exhibit: current_exhibit
31
+ end
32
+
33
+ def csv_params
34
+ params.require(:resources_csv_upload).permit(:url)
35
+ end
36
+
37
+ def data_param_keys
38
+ Spotlight::Resources::Upload.fields(current_exhibit).map(&:field_name) + current_exhibit.custom_fields.map(&:field)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,6 +1,3 @@
1
- # encoding: utf-8
2
- require 'csv'
3
-
4
1
  module Spotlight
5
2
  module Resources
6
3
  ##
@@ -12,15 +9,9 @@ module Spotlight
12
9
  before_action :authenticate_user!
13
10
 
14
11
  load_and_authorize_resource :exhibit, class: Spotlight::Exhibit
15
- before_action :build_resource, only: [:new, :create, :template]
12
+ before_action :build_resource
16
13
 
17
14
  load_and_authorize_resource class: 'Spotlight::Resources::Upload', through_association: 'exhibit.resources', instance_name: 'resource'
18
- def new
19
- add_breadcrumb t(:'spotlight.exhibits.breadcrumb', title: @exhibit.title), exhibit_root_path(@exhibit)
20
- add_breadcrumb t(:'spotlight.curation.sidebar.header'), exhibit_dashboard_path(@exhibit)
21
- add_breadcrumb t(:'spotlight.curation.sidebar.items'), admin_exhibit_catalog_index_path(@exhibit)
22
- add_breadcrumb t(:'spotlight.resources.upload.new.header'), new_exhibit_resources_upload_path(@exhibit)
23
- end
24
15
 
25
16
  # rubocop:disable Metrics/MethodLength
26
17
  def create
@@ -29,7 +20,7 @@ module Spotlight
29
20
  if @resource.save_and_index
30
21
  flash[:notice] = t('spotlight.resources.upload.success')
31
22
  if params['add-and-continue']
32
- redirect_to new_exhibit_resources_upload_path(@resource.exhibit)
23
+ redirect_to new_exhibit_resource_path(@resource.exhibit, anchor: :new_resources_upload)
33
24
  else
34
25
  redirect_to admin_exhibit_catalog_index_path(@resource.exhibit, sort: :timestamp)
35
26
  end
@@ -40,28 +31,12 @@ module Spotlight
40
31
  end
41
32
  # rubocop:enable Metrics/MethodLength
42
33
 
43
- def csv_upload
44
- file = csv_params[:url]
45
- csv = CSV.parse(file.read, headers: true, return_headers: false, encoding: 'utf-8').map(&:to_hash)
46
- Spotlight::AddUploadsFromCSV.perform_later(csv, current_exhibit, current_user)
47
- flash[:notice] = t('spotlight.resources.upload.csv.success', file_name: file.original_filename)
48
- redirect_to :back
49
- end
50
-
51
- def template
52
- render text: CSV.generate { |csv| csv << data_param_keys.unshift(:url) }, content_type: 'text/csv'
53
- end
54
-
55
34
  private
56
35
 
57
36
  def build_resource
58
37
  @resource ||= Spotlight::Resources::Upload.new exhibit: current_exhibit
59
38
  end
60
39
 
61
- def csv_params
62
- params.require(:resources_csv_upload).permit(:url)
63
- end
64
-
65
40
  def resource_params
66
41
  params.require(:resources_upload).permit(:url, data: data_param_keys)
67
42
  end
@@ -8,36 +8,23 @@ module Spotlight
8
8
  before_action :build_resource, only: [:create]
9
9
 
10
10
  load_and_authorize_resource through: :exhibit
11
- helper_method :from_popup?
12
11
 
13
12
  def new
14
- @resource.attributes = resource_params if params[:resource]
15
- @resource = @resource.becomes_provider
13
+ add_breadcrumb t(:'spotlight.exhibits.breadcrumb', title: @exhibit.title), exhibit_root_path(@exhibit)
14
+ add_breadcrumb t(:'spotlight.curation.sidebar.header'), exhibit_dashboard_path(@exhibit)
15
+ add_breadcrumb t(:'spotlight.curation.sidebar.items'), admin_exhibit_catalog_index_path(@exhibit)
16
+ add_breadcrumb t(:'spotlight.resources.new.header'), new_exhibit_resource_path(@exhibit)
16
17
 
17
- ## TODO: in Rails 4.1, replace this with a variant
18
- if from_popup?
19
- render layout: 'spotlight/popup'
20
- else
21
- render
22
- end
18
+ render
23
19
  end
24
20
 
25
- # rubocop:disable Metrics/MethodLength
26
21
  def create
27
- @resource.attributes = resource_params
28
- @resource = @resource.becomes_provider
29
-
30
22
  if @resource.save_and_index
31
- if from_popup?
32
- render layout: false, text: '<html><script>window.close();</script></html>'
33
- else
34
- redirect_to admin_exhibit_catalog_index_path(@resource.exhibit, sort: :timestamp)
35
- end
23
+ redirect_to admin_exhibit_catalog_index_path(@resource.exhibit, sort: :timestamp)
36
24
  else
37
25
  render action: 'new'
38
26
  end
39
27
  end
40
- # rubocop:enable Metrics/MethodLength
41
28
 
42
29
  def monitor
43
30
  render json: current_exhibit.reindex_progress
@@ -56,11 +43,7 @@ module Spotlight
56
43
  end
57
44
 
58
45
  def build_resource
59
- @resource ||= @exhibit.resources.build(resource_params).becomes_provider
60
- end
61
-
62
- def from_popup?
63
- params.fetch(:popup, false)
46
+ @resource ||= @exhibit.resources.build(resource_params)
64
47
  end
65
48
  end
66
49
  end
@@ -3,6 +3,8 @@ module Spotlight
3
3
  # CRUD actions for assigning exhibit roles to
4
4
  # existing users
5
5
  class RolesController < Spotlight::ApplicationController
6
+ include Spotlight::Concerns::UserExistable
7
+ include Spotlight::Concerns::UserInvitable
6
8
  before_action :authenticate_user!
7
9
  load_and_authorize_resource :exhibit, class: Spotlight::Exhibit
8
10
  load_and_authorize_resource through: :exhibit, except: [:update_all]
@@ -30,41 +32,12 @@ module Spotlight
30
32
  end
31
33
  end
32
34
 
33
- def exists
34
- # note: the messages returned are not shown to users and really only useful for debug, hence no translation necessary
35
- # app uses html status code to act on response
36
- if Spotlight::Engine.user_class.where(email: exists_params).present?
37
- render json: { message: 'User exists' }
38
- else
39
- render json: { message: 'User does not exist' }, status: :not_found
40
- end
41
- end
42
-
43
- def invite
44
- user = Spotlight::Engine.user_class.invite!(email: invite_params[:user], skip_invitation: true) # don't deliver the invitation yet
45
- role = Spotlight::Role.create(resource: current_exhibit, user: user, role: invite_params[:role])
46
- if role.save
47
- user.deliver_invitation # now deliver it when we have saved the role
48
- redirect_to :back, notice: t(:'helpers.submit.role.updated')
49
- else
50
- redirect_to :back, alert: t(:'helpers.submit.role.batch_error')
51
- end
52
- end
53
-
54
35
  protected
55
36
 
56
37
  def exhibit_params
57
38
  params.require(:exhibit).permit(roles_attributes: [:id, :user_key, :role, :_destroy])
58
39
  end
59
40
 
60
- def invite_params
61
- params.permit(:user, :role)
62
- end
63
-
64
- def exists_params
65
- params.require(:user)
66
- end
67
-
68
41
  # When nested attributes are passed in, ensure we have authorization to update each row.
69
42
  # @param attr [Hash,Array] the nested attributes
70
43
  # @param klass [Class] the class that is getting created
@@ -10,6 +10,8 @@ module Spotlight
10
10
  scope :published, -> { where(published: true) }
11
11
  scope :unpublished, -> { where(published: false) }
12
12
 
13
+ paginates_per 50
14
+
13
15
  extend FriendlyId
14
16
  friendly_id :title, use: [:slugged, :finders]
15
17
  validates :title, presence: true
@@ -24,20 +24,6 @@ module Spotlight
24
24
  after_index :commit
25
25
  after_index :completed!
26
26
 
27
- def becomes_provider
28
- klass = Spotlight::ResourceProvider.for_resource(self)
29
-
30
- if klass
31
- self.becomes! klass
32
- else
33
- self
34
- end
35
- end
36
-
37
- def needs_provider?
38
- type.blank?
39
- end
40
-
41
27
  ##
42
28
  # Persist the record to the database, and trigger a reindex to solr
43
29
  #