blacklight-spotlight 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/spotlight/_exhibits_index.scss +16 -0
  3. data/app/assets/stylesheets/spotlight/_nestable.scss +10 -10
  4. data/app/controllers/spotlight/catalog_controller.rb +10 -7
  5. data/app/controllers/spotlight/concerns/catalog_search_context.rb +15 -2
  6. data/app/controllers/spotlight/exhibits_controller.rb +1 -0
  7. data/app/helpers/spotlight/application_helper.rb +1 -1
  8. data/app/models/concerns/spotlight/solr_document.rb +20 -20
  9. data/app/models/concerns/spotlight/user.rb +1 -0
  10. data/app/models/spotlight/blacklight_configuration.rb +10 -4
  11. data/app/models/spotlight/custom_field.rb +5 -1
  12. data/app/models/spotlight/exhibit.rb +1 -1
  13. data/app/models/spotlight/resource.rb +1 -1
  14. data/app/models/spotlight/search.rb +1 -1
  15. data/app/models/spotlight/solr_document_sidecar.rb +1 -1
  16. data/app/views/layouts/spotlight/spotlight.html.erb +1 -1
  17. data/app/views/spotlight/exhibits/_exhibit_card.html.erb +3 -0
  18. data/app/views/spotlight/exhibits/index.html.erb +40 -15
  19. data/config/locales/spotlight.en.yml +4 -1
  20. data/lib/spotlight/catalog.rb +14 -11
  21. data/lib/spotlight/catalog/access_controls_enforcement.rb +2 -1
  22. data/lib/spotlight/engine.rb +5 -0
  23. data/lib/spotlight/version.rb +1 -1
  24. data/spec/controllers/spotlight/about_pages_controller_spec.rb +1 -1
  25. data/spec/controllers/spotlight/appearances_controller_spec.rb +10 -8
  26. data/spec/controllers/spotlight/browse_controller_spec.rb +3 -3
  27. data/spec/controllers/spotlight/catalog_controller_spec.rb +88 -7
  28. data/spec/controllers/spotlight/confirmations_controller_spec.rb +7 -4
  29. data/spec/controllers/spotlight/contact_forms_controller_spec.rb +1 -1
  30. data/spec/controllers/spotlight/exhibits_controller_spec.rb +25 -21
  31. data/spec/controllers/spotlight/home_pages_controller_spec.rb +23 -24
  32. data/spec/controllers/spotlight/metadata_configurations_controller_spec.rb +17 -13
  33. data/spec/controllers/spotlight/resources/upload_controller_spec.rb +1 -1
  34. data/spec/controllers/spotlight/resources_controller_spec.rb +3 -3
  35. data/spec/controllers/spotlight/roles_controller_spec.rb +5 -3
  36. data/spec/controllers/spotlight/search_configurations_controller_spec.rb +10 -8
  37. data/spec/controllers/spotlight/searches_controller_spec.rb +12 -8
  38. data/spec/controllers/spotlight/solr_controller_spec.rb +34 -29
  39. data/spec/controllers/spotlight/versions_controller_spec.rb +2 -2
  40. data/spec/controllers/spotlight/view_configurations_controller_spec.rb +7 -5
  41. data/spec/helpers/spotlight/application_helper_spec.rb +1 -1
  42. data/spec/helpers/spotlight/pages_helper_spec.rb +2 -2
  43. data/spec/models/solr_document_spec.rb +5 -5
  44. data/spec/models/spotlight/custom_field_spec.rb +8 -9
  45. data/spec/models/spotlight/resources/open_graph_spec.rb +1 -1
  46. data/spec/models/spotlight/search_spec.rb +10 -0
  47. data/spec/models/spotlight/sitemap_spec.rb +1 -1
  48. data/spec/models/spotlight/solr_document/atomic_updates_spec.rb +1 -1
  49. data/spec/models/spotlight/solr_document/uploaded_resource_spec.rb +6 -6
  50. data/spec/views/spotlight/exhibits/index.html.erb_spec.rb +35 -6
  51. data/spec/views/spotlight/sir_trevor/blocks/_solr_documents_block.html.erb_spec.rb +1 -1
  52. data/spec/views/spotlight/sir_trevor/blocks/_solr_documents_carousel_block.html.erb_spec.rb +5 -1
  53. data/spec/views/spotlight/sir_trevor/blocks/_solr_documents_embed_block.html.erb_spec.rb +1 -1
  54. data/spec/views/spotlight/sir_trevor/blocks/_solr_documents_features_block.html.erb_spec.rb +3 -3
  55. data/spec/views/spotlight/sir_trevor/blocks/_solr_documents_grid_block.html.erb_spec.rb +5 -1
  56. metadata +2 -5
  57. data/app/views/shared/_flash_messages.html.erb +0 -7
  58. data/app/views/spotlight/exhibits/_exhibit_list.html.erb +0 -3
  59. data/db/migrate/20151210073829_create_spotlight_configuration.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 04eb98fbaa9f7a11fbebb777f034d1537773bd2f
4
- data.tar.gz: 8ced6a8356a1cb65c3ce5bbbf941108444b0fb7f
3
+ metadata.gz: 1e1e38c99f14e8cbfe3482e6d4adb02adc7dd6cd
4
+ data.tar.gz: e7c12eb9e49ecf927dd98f9331d363d796bc4825
5
5
  SHA512:
6
- metadata.gz: d9b5ea84c1d186ec0aab2fd47b59099c832caffd05ae6e151ab2088c71012ec76fec695cfaac258927ffb9cfaee9c2af388b11a3da06d704b8c251a984113294
7
- data.tar.gz: 02290a5d60fc130bb1bbf96f335cd66e503a323436c48e207a631f468009d9ed5728911bfed807e5a818f8754eccaf16d4feffd2a47b796bf535036c37cbd3e6
6
+ metadata.gz: 3bea84a5474d94a0fe33b0d041675c2dd1647dfb4ab2968638bb70563eaad164a2e46dd1655893a99e30bbee06a59cd2eca5ceec758aca930b1dcf765906663d
7
+ data.tar.gz: f94dbfd2a1507db4e4938144c1c65a1f13995aea9113792eabe15589affd017433dfbbca4b5b1424c5988daf34f4bf7f7dcf9308a65071344ec0c5f261976c3c
@@ -41,6 +41,7 @@
41
41
  @extend .text-center;
42
42
 
43
43
  font-size: $font-size-h4;
44
+ line-height: 1.2;
44
45
  }
45
46
 
46
47
  .card-front {
@@ -54,8 +55,23 @@
54
55
  }
55
56
 
56
57
  .card-title {
58
+ padding-left: $padding-small-horizontal;
59
+ padding-right: $padding-small-horizontal;
57
60
  padding-top: $padding-large-vertical;
58
61
  }
62
+
63
+ .unpublished {
64
+ @extend .center-block;
65
+
66
+ font-size: $font-size-base;
67
+ margin-top: -1em;
68
+ position: relative;
69
+ width: 15ch;
70
+
71
+ + .card-title {
72
+ padding-top: 0;
73
+ }
74
+ }
59
75
  }
60
76
 
61
77
  .card-back {
@@ -36,9 +36,9 @@ tr.dd-item {
36
36
 
37
37
  .dd-handle { display: block; height: 100%; margin: 5px 0; padding: 5px 10px; color: #333; text-decoration: none; font-weight: bold; border: 1px solid #ccc;
38
38
  background: #fafafa;
39
- background: -webkit-linear-gradient(top, #fafafa 0%, #eee 100%);
40
- background: -moz-linear-gradient(top, #fafafa 0%, #eee 100%);
41
- background: linear-gradient(top, #fafafa 0%, #eee 100%);
39
+ background: -webkit-linear-gradient(to bottom, #fafafa 0%, #eee 100%);
40
+ background: -moz-linear-gradient(to bottom, #fafafa 0%, #eee 100%);
41
+ background: linear-gradient(to bottom, #fafafa 0%, #eee 100%);
42
42
  -webkit-border-radius: 3px;
43
43
  border-radius: 3px;
44
44
  box-sizing: border-box; -moz-box-sizing: border-box;
@@ -84,9 +84,9 @@ tr.dd-item {
84
84
 
85
85
  .dd3-content { display: block; margin: 5px 0; padding: 0 0 0 30px;
86
86
  background: #fafafa;
87
- background: -webkit-linear-gradient(top, #fafafa 0%, #eee 100%);
88
- background: -moz-linear-gradient(top, #fafafa 0%, #eee 100%);
89
- background: linear-gradient(top, #fafafa 0%, #eee 100%);
87
+ background: -webkit-linear-gradient(to bottom, #fafafa 0%, #eee 100%);
88
+ background: -moz-linear-gradient(to bottom, #fafafa 0%, #eee 100%);
89
+ background: linear-gradient(to bottom, #fafafa 0%, #eee 100%);
90
90
  -webkit-border-radius: 3px;
91
91
  border-radius: 3px;
92
92
  box-sizing: border-box; -moz-box-sizing: border-box;
@@ -99,15 +99,15 @@ tr.dd-item {
99
99
 
100
100
  .dd3-item > button { margin-left: 30px; }
101
101
 
102
- .dd3-handle {
102
+ .dd3-handle {
103
103
  position: absolute; margin: 0; left: 0; top: 0; cursor: pointer; width: 30px;
104
104
  text-indent: 100px;
105
105
  white-space: nowrap; overflow: hidden;
106
106
  border: 1px solid #aaa;
107
107
  background: #ddd;
108
- background: -webkit-linear-gradient(top, #ddd 0%, #bbb 100%);
109
- background: -moz-linear-gradient(top, #ddd 0%, #bbb 100%);
110
- background: linear-gradient(top, #ddd 0%, #bbb 100%);
108
+ background: -webkit-linear-gradient(to bottom, #ddd 0%, #bbb 100%);
109
+ background: -moz-linear-gradient(to bottom, #ddd 0%, #bbb 100%);
110
+ background: linear-gradient(to bottom, #ddd 0%, #bbb 100%);
111
111
  border-top-right-radius: 0;
112
112
  border-bottom-right-radius: 0;
113
113
  }
@@ -136,9 +136,9 @@ module Spotlight
136
136
  # Override Blacklight's #setup_next_and_previous_documents to handle
137
137
  # browse categories too
138
138
  def setup_next_and_previous_documents
139
- if current_browse_category
140
- setup_next_and_previous_documents_from_browse_category
141
- elsif current_page_context
139
+ if current_search_session_from_browse_category?
140
+ setup_next_and_previous_documents_from_browse_category if current_browse_category
141
+ elsif current_search_session_from_page? || current_search_session_from_home_page?
142
142
  # TODO: figure out how to construct previous/next documents
143
143
  else
144
144
  super
@@ -147,10 +147,13 @@ module Spotlight
147
147
 
148
148
  def setup_next_and_previous_documents_from_browse_category
149
149
  index = search_session['counter'].to_i - 1
150
- response, documents = get_previous_and_next_documents_for_search index, current_browse_category.query_params.with_indifferent_access
150
+ response, _docs = get_previous_and_next_documents_for_search index, current_browse_category.query_params.with_indifferent_access
151
+
152
+ return unless response
153
+
151
154
  search_session['total'] = response.total
152
- @previous_document = documents.first
153
- @next_document = documents.last
155
+ @previous_document = response.documents.first
156
+ @next_document = response.documents.last
154
157
  end
155
158
 
156
159
  def _prefixes
@@ -206,7 +209,7 @@ module Spotlight
206
209
  elsif current_page_context && current_page_context.title.present? && !current_page_context.is_a?(Spotlight::HomePage)
207
210
  add_breadcrumb current_page_context.title, [current_page_context.exhibit, current_page_context]
208
211
  elsif current_search_session
209
- add_breadcrumb t(:'spotlight.catalog.breadcrumb.index'), search_action_url(current_search_session[:query_params])
212
+ add_breadcrumb t(:'spotlight.catalog.breadcrumb.index'), search_action_url(current_search_session.query_params)
210
213
  end
211
214
 
212
215
  add_breadcrumb Array(document[blacklight_config.view_config(:show).title_field]).join(', '), exhibit_catalog_path(current_exhibit, document)
@@ -9,9 +9,11 @@ module Spotlight
9
9
  @current_page_context ||= if current_search_session_from_home_page?
10
10
  current_exhibit.home_page if can? :read, current_exhibit.home_page
11
11
  elsif current_search_session_from_page?
12
- page_id = current_search_session.query_params['id']
13
- current_exhibit.pages.accessible_by(current_ability).find(page_id) if page_id
12
+ current_search_session_page_context
14
13
  end
14
+ rescue ActiveRecord::RecordNotFound => e
15
+ Rails.logger.debug "Unable to get current page context from #{current_search_session.inspect}: #{e}"
16
+ nil
15
17
  end
16
18
 
17
19
  def current_browse_category
@@ -19,6 +21,9 @@ module Spotlight
19
21
  search_id = current_search_session.query_params['id']
20
22
  current_exhibit.searches.accessible_by(current_ability).find(search_id)
21
23
  end
24
+ rescue ActiveRecord::RecordNotFound => e
25
+ Rails.logger.debug "Unable to get current page context from #{current_search_session.inspect}: #{e}"
26
+ nil
22
27
  end
23
28
 
24
29
  def current_search_session_from_browse_category?
@@ -39,6 +44,14 @@ module Spotlight
39
44
  current_search_session.query_params['action'] == 'show' &&
40
45
  current_search_session.query_params['controller'] == 'spotlight/home_pages'
41
46
  end
47
+
48
+ def current_search_session_page_context
49
+ page_id = current_search_session.query_params['id']
50
+
51
+ return unless page_id
52
+
53
+ current_exhibit.pages.accessible_by(current_ability).find(page_id)
54
+ end
42
55
  end
43
56
  end
44
57
  end
@@ -32,6 +32,7 @@ module Spotlight
32
32
  @exhibit.attributes = exhibit_params
33
33
 
34
34
  if @exhibit.save
35
+ @exhibit.roles.create user: current_user, role: 'admin' if current_user
35
36
  redirect_to spotlight.exhibit_dashboard_path(@exhibit), notice: t(:'helpers.submit.exhibit.created', model: @exhibit.class.model_name.human.downcase)
36
37
  else
37
38
  render action: :new
@@ -60,7 +60,7 @@ module Spotlight
60
60
  # Helper to turn tag data into facets
61
61
  def url_to_tag_facet(tag)
62
62
  if current_exhibit
63
- search_action_url(add_facet_params(Spotlight::SolrDocument.solr_field_for_tagger(current_exhibit), tag, {}))
63
+ search_action_url(add_facet_params(blacklight_config.document_model.solr_field_for_tagger(current_exhibit), tag, {}))
64
64
  else
65
65
  search_action_url(q: tag)
66
66
  end
@@ -34,6 +34,22 @@ module Spotlight
34
34
  def reindex_all
35
35
  find_each(&:reindex)
36
36
  end
37
+
38
+ def solr_field_for_tagger(tagger)
39
+ :"#{solr_field_prefix(tagger)}tags#{Spotlight::Engine.config.solr_fields.string_suffix}"
40
+ end
41
+
42
+ def visibility_field(exhibit)
43
+ :"#{solr_field_prefix(exhibit)}public#{Spotlight::Engine.config.solr_fields.boolean_suffix}"
44
+ end
45
+
46
+ def resource_type_field
47
+ :"#{Spotlight::Engine.config.solr_fields.prefix}spotlight_resource_type#{Spotlight::Engine.config.solr_fields.string_suffix}"
48
+ end
49
+
50
+ def solr_field_prefix(exhibit)
51
+ "#{Spotlight::Engine.config.solr_fields.prefix}#{exhibit.class.model_name.param_key}_#{exhibit.to_param}_"
52
+ end
37
53
  end
38
54
 
39
55
  def update(current_exhibit, new_attributes)
@@ -68,22 +84,6 @@ module Spotlight
68
84
  { self.class.unique_key.to_sym => id }.reverse_merge(sidecars.inject({}) { |a, e| a.merge(e.to_solr) }).merge(tags_to_solr)
69
85
  end
70
86
 
71
- def self.solr_field_for_tagger(tagger)
72
- :"#{solr_field_prefix(tagger)}tags#{Spotlight::Engine.config.solr_fields.string_suffix}"
73
- end
74
-
75
- def self.visibility_field(exhibit)
76
- :"#{solr_field_prefix(exhibit)}public#{Spotlight::Engine.config.solr_fields.boolean_suffix}"
77
- end
78
-
79
- def self.resource_type_field
80
- :"#{Spotlight::Engine.config.solr_fields.prefix}spotlight_resource_type#{Spotlight::Engine.config.solr_fields.string_suffix}"
81
- end
82
-
83
- def self.solr_field_prefix(exhibit)
84
- "#{Spotlight::Engine.config.solr_fields.prefix}#{exhibit.class.model_name.param_key}_#{exhibit.to_param}_"
85
- end
86
-
87
87
  def make_public!(exhibit)
88
88
  sidecar(exhibit).public!
89
89
  end
@@ -101,8 +101,8 @@ module Spotlight
101
101
  end
102
102
 
103
103
  def uploaded_resource?
104
- self[Spotlight::SolrDocument.resource_type_field].present? &&
105
- self[Spotlight::SolrDocument.resource_type_field].include?('spotlight/resources/uploads')
104
+ self[self.class.resource_type_field].present? &&
105
+ self[self.class.resource_type_field].include?('spotlight/resources/uploads')
106
106
  end
107
107
 
108
108
  def attribute_present?(*_args)
@@ -117,11 +117,11 @@ module Spotlight
117
117
  # Adding a placeholder entry in case the last tag for an exhibit
118
118
  # is removed, so we clear out the solr field too.
119
119
  Spotlight::Exhibit.find_each do |exhibit|
120
- h[Spotlight::SolrDocument.solr_field_for_tagger(exhibit)] = nil
120
+ h[self.class.solr_field_for_tagger(exhibit)] = nil
121
121
  end
122
122
 
123
123
  taggings.includes(:tag, :tagger).map do |tagging|
124
- key = Spotlight::SolrDocument.solr_field_for_tagger(tagging.tagger)
124
+ key = self.class.solr_field_for_tagger(tagging.tagger)
125
125
  h[key] ||= []
126
126
  h[key] << tagging.tag.name
127
127
  end
@@ -5,6 +5,7 @@ module Spotlight
5
5
  extend ActiveSupport::Concern
6
6
  included do
7
7
  has_many :roles, class_name: 'Spotlight::Role', dependent: :destroy
8
+ has_many :exhibits, class_name: 'Spotlight::Exhibit', through: :roles
8
9
 
9
10
  before_create :add_default_roles
10
11
  end
@@ -19,6 +19,8 @@ module Spotlight
19
19
  include Spotlight::BlacklightConfigurationDefaults
20
20
  include Spotlight::ImageDerivatives
21
21
 
22
+ delegate :document_model, to: :default_blacklight_config
23
+
22
24
  # get rid of empty values
23
25
  before_validation do |model|
24
26
  model.index_fields.each do |_k, v|
@@ -190,14 +192,18 @@ module Spotlight
190
192
 
191
193
  def custom_index_fields
192
194
  Hash[exhibit.custom_fields.map do |x|
193
- field = Blacklight::Configuration::IndexField.new x.configuration.merge(key: x.field, field: x.solr_field)
195
+ field = Blacklight::Configuration::IndexField.new x.configuration.merge(
196
+ key: x.field, field: x.solr_field
197
+ )
194
198
  [x.field, field]
195
199
  end]
196
200
  end
197
201
 
198
202
  def custom_facet_fields
199
203
  Hash[exhibit.custom_fields.vocab.map do |x|
200
- field = Blacklight::Configuration::FacetField.new x.configuration.merge(key: x.field, field: x.solr_field, show: false)
204
+ field = Blacklight::Configuration::FacetField.new x.configuration.merge(
205
+ key: x.field, field: x.solr_field, show: false
206
+ )
201
207
  [x.field, field]
202
208
  end]
203
209
  end
@@ -252,11 +258,11 @@ module Spotlight
252
258
  def add_exhibit_tags_fields(config)
253
259
  # rubocop:disable Style/GuardClause
254
260
  unless config.show_fields.include? :exhibit_tags
255
- config.add_show_field :exhibit_tags, field: Spotlight::SolrDocument.solr_field_for_tagger(exhibit), link_to_search: true
261
+ config.add_show_field :exhibit_tags, field: config.document_model.solr_field_for_tagger(exhibit), link_to_search: true
256
262
  end
257
263
 
258
264
  unless config.facet_fields.include? :exhibit_tags
259
- config.add_facet_field :exhibit_tags, field: Spotlight::SolrDocument.solr_field_for_tagger(exhibit)
265
+ config.add_facet_field :exhibit_tags, field: config.document_model.solr_field_for_tagger(exhibit)
260
266
  end
261
267
  # rubocop:enable Style/GuardClause
262
268
  end
@@ -81,7 +81,7 @@ module Spotlight
81
81
  end
82
82
 
83
83
  def solr_field_prefix
84
- Spotlight::SolrDocument.solr_field_prefix(exhibit)
84
+ document_model.solr_field_prefix(exhibit)
85
85
  end
86
86
 
87
87
  def field_suffix
@@ -130,5 +130,9 @@ module Spotlight
130
130
 
131
131
  Spotlight::RenameSidecarFieldJob.perform_later(exhibit, old_field, self.field)
132
132
  end
133
+
134
+ def document_model
135
+ blacklight_configuration.document_model
136
+ end
133
137
  end
134
138
  end
@@ -74,7 +74,7 @@ module Spotlight
74
74
  end
75
75
 
76
76
  def solr_data
77
- { :"#{Spotlight::Engine.config.solr_fields.prefix}spotlight_exhibit_slug_#{slug}#{Spotlight::Engine.config.solr_fields.boolean_suffix}" => true }
77
+ Spotlight::Engine.config.exhibit_filter.call(self)
78
78
  end
79
79
 
80
80
  def reindex_later
@@ -102,7 +102,7 @@ module Spotlight
102
102
  def spotlight_resource_metadata_for_solr
103
103
  {
104
104
  Spotlight::Engine.config.resource_global_id_field => (to_global_id.to_s if persisted?),
105
- Spotlight::SolrDocument.resource_type_field => self.class.to_s.tableize
105
+ document_model.resource_type_field => self.class.to_s.tableize
106
106
  }
107
107
  end
108
108
 
@@ -82,7 +82,7 @@ module Spotlight
82
82
  end
83
83
 
84
84
  def repository
85
- Blacklight.default_index
85
+ @repository ||= Blacklight::Solr::Repository.new(blacklight_config)
86
86
  end
87
87
 
88
88
  def default_search_fields
@@ -36,7 +36,7 @@ module Spotlight
36
36
  protected
37
37
 
38
38
  def visibility_field
39
- Spotlight::SolrDocument.visibility_field(exhibit)
39
+ blacklight_config.document_model.visibility_field(exhibit)
40
40
  end
41
41
 
42
42
  def blacklight_config
@@ -37,7 +37,7 @@
37
37
  <%= render partial: 'shared/ajax_modal' %>
38
38
 
39
39
  <div id="main-container" class="container">
40
- <%= render partial: 'shared/flash_messages' %>
40
+ <%= render partial: '/flash_msg', layout: 'shared/flash_messages' %>
41
41
 
42
42
  <div class="row">
43
43
  <%= content_for?(:content) ? yield(:content) : yield %>
@@ -2,6 +2,9 @@
2
2
  <div class="flipper">
3
3
  <div class="card-front card-face">
4
4
  <%= image_tag(exhibit.thumbnail.image.square.url) if exhibit.thumbnail.present? %>
5
+ <% unless exhibit.published? %>
6
+ <div class="label label-warning unpublished"><%= t('.unpublished') %></div>
7
+ <% end %>
5
8
  <h2 class="card-title"><%= exhibit.title %></h2>
6
9
  </div>
7
10
  <div class="card-back card-face">
@@ -1,24 +1,49 @@
1
1
  <div class="col-md-9">
2
- <% if @exhibits.published.none? %>
3
- <%= render 'missing_exhibits' %>
2
+ <% if (current_user && current_user.exhibits.any?) || can?(:manage, Spotlight::Exhibit) %>
3
+ <ul class="nav nav-tabs" role="tablist">
4
+ <li role="presentation" class="active"><a href="#published" aria-controls="published" role="tab" data-toggle="tab"><%= t('.published') %></a></li>
5
+ <% if can?(:manage, Spotlight::Exhibit) %>
6
+ <li role="presentation"><a href="#unpublished" aria-controls="unpublished" role="tab" data-toggle="tab"><%= t('.unpublished') %></a></li>
7
+ <% end %>
8
+ <li role="presentation"><a href="#user" aria-controls="user" role="tab" data-toggle="tab"><%= t('.user') %></a></li>
9
+ </ul>
4
10
  <% end %>
5
11
 
6
- <%= cache cache_key_for_spotlight_exhibits do %>
7
- <% @exhibits.published.each_slice(3).each do |row| %>
8
- <div class="row"><!-- start main content row -->
9
- <%= render collection: row, partial: 'exhibit_card', as: 'exhibit' %>
12
+ <div class="tab-content">
13
+ <div role="tabpanel" class="tab-pane active" id="published">
14
+ <% if @exhibits.published.none? %>
15
+ <%= render 'missing_exhibits' %>
16
+ <% end %>
17
+
18
+ <%= cache cache_key_for_spotlight_exhibits do %>
19
+ <% @exhibits.published.each_slice(3).each do |row| %>
20
+ <div class="row"><!-- start main content row -->
21
+ <%= render collection: row, partial: 'exhibit_card', as: 'exhibit' %>
22
+ </div>
23
+ <% end %>
24
+ <% end %>
10
25
  </div>
11
- <% end %>
12
- <% end %>
13
26
 
14
- <% private_exhibits = @exhibits.unpublished.accessible_by(current_ability) %>
27
+ <% if @exhibits.unpublished.accessible_by(current_ability).any? %>
28
+ <div role="tabpanel" class="tab-pane" id="unpublished">
29
+ <% @exhibits.unpublished.accessible_by(current_ability).each_slice(3).each do |row| %>
30
+ <div class="row"><!-- start main content row -->
31
+ <%= render collection: row, partial: 'exhibit_card', as: 'exhibit' %>
32
+ </div>
33
+ <% end %>
34
+ </div>
35
+ <% end %>
15
36
 
16
- <% if private_exhibits.any? %>
17
- <h2><%= t(:'.private') %></h2>
18
- <ul>
19
- <%= render collection: private_exhibits, partial: 'exhibit_list', as: 'exhibit' %>
20
- </ul>
21
- <% end %>
37
+ <% if current_user && current_user.exhibits.any? %>
38
+ <div role="tabpanel" class="tab-pane" id="user">
39
+ <% current_user.exhibits.each_slice(3).each do |row| %>
40
+ <div class="row"><!-- start main content row -->
41
+ <%= render collection: row, partial: 'exhibit_card', as: 'exhibit' %>
42
+ </div>
43
+ <% end %>
44
+ </div>
45
+ <% end %>
46
+ </div>
22
47
  </div>
23
48
 
24
49
  <aside class="col-md-3">