blacklight-spotlight 3.0.0.alpha.1 → 3.0.0.alpha.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f01691bf97fbfeae90a4f5d12da7fc7ab256a9b47ba5e80b6b9cc30c06fb3d16
4
- data.tar.gz: 8d033238da5914280b8e4b0307fabe79d57de50041123e77d573843b5aa87dc7
3
+ metadata.gz: 2faee384954ac8cb3de9ce3fedee4c5b9dcb8d7d8f28161a41182bbbd3cb06f1
4
+ data.tar.gz: bb80b682dab6d85a1195eb09259371032f120b55053c1f1d4d138b77eeb238f8
5
5
  SHA512:
6
- metadata.gz: 112798c03866efb84b4b67e121aac6144ccb6eedd0f1b3e2259d92a338828841cf1e3951eeb9008f26c0cd2c21d8e399475747a972d4296689efc562f89d6d64
7
- data.tar.gz: '0781a517029421e6c39415921ae7c7fe51abde6c78d4287e7928a42cf6a5d2b251a2be3514efe42ceedf87082af16a96c3eca1c8a42f34331a418d9c579ae5c8'
6
+ metadata.gz: 9008ca36a6e8ca50111935a5b69eb7b74c6f3b5114a594d8e31981bfbf525cf634bded7ee98accdce79cf4862433b8091ceba0f5e17f3464dd24f7b0b6d2f79d
7
+ data.tar.gz: 1be3d1bf193d008f940de66eba4838b479bd61cbb5b18840dc9de11965b706330991bb96241b01a82b1d3cbd2add7b4b811a530b8a67e9f6159f32dcf899ed41
@@ -4,6 +4,7 @@
4
4
  margin-bottom: 2rem;
5
5
  // image width + gutter + border (x2)
6
6
  max-width: $exhibit-card-image-size + $exhibit-card-gutter + 2px;
7
+ padding-right: ($exhibit-card-gutter / 2) !important;
7
8
  perspective: 1000; // for flip animation
8
9
  position: relative;
9
10
 
@@ -54,10 +55,10 @@
54
55
  width: 100%;
55
56
  }
56
57
 
57
- .card-title {
58
+ .exhibit-card-title {
59
+ @extend .h5;
58
60
  padding-left: $padding-small-horizontal;
59
61
  padding-right: $padding-small-horizontal;
60
- padding-top: $padding-large-vertical;
61
62
  }
62
63
 
63
64
  .unpublished {
@@ -68,10 +69,6 @@
68
69
  margin-top: -1em;
69
70
  position: relative;
70
71
  width: 15ch;
71
-
72
- + .card-title {
73
- padding-top: 0;
74
- }
75
72
  }
76
73
  }
77
74
 
@@ -81,21 +78,24 @@
81
78
  transform: rotateY(-180deg);
82
79
 
83
80
  .card-title {
81
+ @extend .h5;
84
82
  @extend .text-center;
85
83
  border-bottom: 1px dotted $exhibit-card-border;
86
84
  line-height: $headings-line-height;
87
85
  margin-bottom: $padding-base-vertical;
88
86
  padding-bottom: $padding-base-vertical;
87
+ padding-top: $padding-base-vertical;
89
88
  }
90
89
 
91
90
  .subtitle {
92
91
  @extend .h5;
93
92
  @extend .text-center;
93
+ font-size: 0.875rem;
94
94
  line-height: $headings-line-height;
95
95
  }
96
96
 
97
97
  .description {
98
- font-size: $h6-font-size;
98
+ font-size: 0.75rem;
99
99
  }
100
100
 
101
101
  .visit-exhibit {
@@ -104,10 +104,6 @@
104
104
  }
105
105
  }
106
106
 
107
- .nav.tags {
108
- display: inline-block;
109
- }
110
-
111
107
  // between the small and medium breakpoints, reduce the size of the image by a little bit
112
108
  @media (min-width: breakpoint-min("sm")) and (max-width: breakpoint-max("lg")) {
113
109
 
@@ -70,19 +70,22 @@ module Spotlight
70
70
 
71
71
  html_options ||= {}
72
72
 
73
- nav_link_html_options = html_options.merge(class: [html_options[:class], 'nav-link', ('active' if current_page?(options))].join(' '))
74
-
75
73
  content_tag(:li, class: 'nav-item') do
76
74
  if block_given?
77
- link_to(options, nav_link_html_options, &block)
75
+ link_to(options, nav_link_html_options(options, html_options), &block)
78
76
  else
79
- link_to(name, options, nav_link_html_options, &block)
77
+ link_to(name, options, nav_link_html_options(options, html_options), &block)
80
78
  end
81
79
  end
82
80
  end
83
81
 
84
82
  private
85
83
 
84
+ def nav_link_html_options(options, html_options)
85
+ active = html_options.key?(:active) ? html_options[:active] : current_page?(options)
86
+ html_options.merge(class: [html_options[:class], 'nav-link', ('active' if active)].join(' '))
87
+ end
88
+
86
89
  # rubocop:disable Metrics/MethodLength
87
90
  def action_default_value(object, key = nil)
88
91
  object_model = convert_to_model(object)
@@ -50,7 +50,7 @@ module Spotlight
50
50
  end
51
51
 
52
52
  def update(current_exhibit, new_attributes)
53
- attributes = new_attributes.stringify_keys
53
+ attributes = convert_incoming_attributes(new_attributes)
54
54
 
55
55
  custom_data = attributes.delete('sidecar')
56
56
  tags = attributes.delete('exhibit_tag_list')
@@ -141,6 +141,48 @@ module Spotlight
141
141
  "#{Spotlight::Engine.config.solr_fields.prefix}spotlight_exhibit_slugs#{Spotlight::Engine.config.solr_fields.string_suffix}" => slugs
142
142
  }
143
143
  end
144
+
145
+ def convert_incoming_attributes(attributes)
146
+ attributes = attributes.stringify_keys
147
+
148
+ # convert blank strings to nil
149
+ attributes = deep_transform_values(attributes, &:presence)
150
+
151
+ # trim excess nils from arrays
152
+ deep_compact(attributes)
153
+ end
154
+
155
+ def deep_transform_values(object, &block)
156
+ # Available in Rails 6
157
+ if object.respond_to?(:deep_transform_values)
158
+ object.deep_transform_values(&block)
159
+ else
160
+ _deep_transform_values(object, &block)
161
+ end
162
+ end
163
+
164
+ # Shimmed from Rails 6
165
+ def _deep_transform_values(object, &block)
166
+ case object
167
+ when Hash
168
+ object.transform_values { |value| deep_transform_values(value, &block) }
169
+ when Array
170
+ object.map { |e| deep_transform_values(e, &block) }
171
+ else
172
+ yield(object)
173
+ end
174
+ end
175
+
176
+ def deep_compact(object)
177
+ case object
178
+ when Hash
179
+ object.transform_values { |value| deep_compact(value) }
180
+ when Array
181
+ object.compact
182
+ else
183
+ object
184
+ end
185
+ end
144
186
  end
145
187
  end
146
188
 
@@ -60,19 +60,19 @@ module Spotlight
60
60
  def localized_start_time
61
61
  return unless started_at
62
62
 
63
- I18n.l(started_at, format: :short)
63
+ I18n.l(started_at, format: :long)
64
64
  end
65
65
 
66
66
  def localized_finish_time
67
67
  return unless finished_at
68
68
 
69
- I18n.l(finished_at, format: :short)
69
+ I18n.l(finished_at, format: :long)
70
70
  end
71
71
 
72
72
  def localized_updated_time
73
73
  return unless updated_at
74
74
 
75
- I18n.l(updated_at, format: :short)
75
+ I18n.l(updated_at, format: :long)
76
76
  end
77
77
  end
78
78
  end
@@ -44,7 +44,7 @@ module Spotlight
44
44
  blacklight_config.document_model
45
45
  end
46
46
 
47
- protected
47
+ private
48
48
 
49
49
  def visibility_field
50
50
  blacklight_config.document_model.visibility_field(exhibit)
@@ -63,7 +63,7 @@ module Spotlight
63
63
  custom_field = custom_fields[key]
64
64
  field_name = custom_field.solr_field if custom_field
65
65
  field_name ||= key
66
- solr_hash[field_name] = value
66
+ solr_hash[field_name] = convert_stored_value_to_solr(value)
67
67
  end
68
68
  end
69
69
 
@@ -75,10 +75,10 @@ module Spotlight
75
75
  next unless configured_fields && configured_fields[field_name].present?
76
76
 
77
77
  value = configured_fields[field_name]
78
- field_data = field.data_to_solr(value)
78
+ field_data = field.data_to_solr(convert_stored_value_to_solr(value))
79
79
 
80
80
  # merge duplicate field mappings into a multivalued field
81
- solr_hash.merge!(field_data) { |_key, v1, v2| Array(v1) + Array(v2) }
81
+ solr_hash.merge!(field_data) { |_key, v1, v2| (Array(v1) + Array(v2)).reject(&:blank?) }
82
82
  end
83
83
  end
84
84
 
@@ -94,5 +94,15 @@ module Spotlight
94
94
  hash[custom_field.field] = custom_field
95
95
  end
96
96
  end
97
+
98
+ def convert_stored_value_to_solr(value)
99
+ if value.blank?
100
+ nil
101
+ elsif value.is_a? Enumerable
102
+ value.reject(&:blank?)
103
+ else
104
+ value
105
+ end
106
+ end
97
107
  end
98
108
  end
@@ -2,7 +2,7 @@
2
2
  <% if published_top_level_feature_pages.present? %>
3
3
  <% if published_top_level_feature_pages.many? %>
4
4
  <li class="nav-item dropdown">
5
- <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown"><%= navigation.label_or_default %> <b class="caret"></b></a>
5
+ <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown"><%= navigation.label_or_default %></a>
6
6
  <ul class="dropdown-menu">
7
7
  <% published_top_level_feature_pages.each do |page| %>
8
8
  <li><%= link_to page.title, [spotlight, page.exhibit, page], class: 'dropdown-item' %></li>
@@ -8,7 +8,7 @@
8
8
  <%= render '/spotlight/shared/locale_picker' %>
9
9
  <% if current_user %>
10
10
  <li class="nav-item dropdown">
11
- <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown"><%=current_user%> <b class="caret"></b></a>
11
+ <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown"><%=current_user%></a>
12
12
  <ul class="dropdown-menu">
13
13
  <% if can? :manage, Spotlight::Site.instance %>
14
14
  <li><%= link_to t(:'spotlight.header_links.edit_site'), spotlight.edit_site_path, class: 'dropdown-item' %></li>
@@ -12,5 +12,5 @@
12
12
  </div>
13
13
  </td>
14
14
  <td class="col-4"><%= page.last_edited_by.to_s if page.last_edited_by %></td>
15
- <td class="col-2"><%= l page.updated_at, format: :short %></td>
15
+ <td class="col-2"><%= l page.updated_at, format: :long %></td>
16
16
  </tr>
@@ -14,7 +14,7 @@
14
14
  <tbody>
15
15
  <% @recent_reindexing.each do |log_entry| %>
16
16
  <tr class="d-flex">
17
- <td class="col-3"><%= l log_entry.start_time, format: :short if log_entry.start_time %></td>
17
+ <td class="col-3"><%= l log_entry.start_time, format: :long if log_entry.start_time %></td>
18
18
  <td class="col-3"><%= log_entry.user.email if log_entry.user %></td>
19
19
  <td class="col-1"><%= log_entry.items_reindexed_count %></td>
20
20
  <td class="col-3"><%= distance_of_time_in_words log_entry.duration, 0, include_seconds: true if log_entry.duration %></td>
@@ -10,8 +10,8 @@
10
10
  <p class="description">
11
11
  <%= truncated_description = exhibit.description.truncate(168, omission: '', separator: ' ') %>
12
12
  <% if exhibit.description.length > 168 %>
13
- <%= content_tag(:span,"&hellip;".html_safe, class: "visible-sm visible-md") %>
14
- <span class="hidden-sm hidden-md">
13
+ <%= content_tag(:span,"&hellip;".html_safe, class: "d-sm-block d-md-block") %>
14
+ <span class="d-sm-none d-md-none">
15
15
  <%= exhibit.description.slice(truncated_description.length, exhibit.description.length) %>
16
16
  </span>
17
17
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <% exhibits.each_slice(3).each do |row| %>
2
- <div class="row"><!-- start main content row -->
2
+ <div class="row no-gutters"><!-- start main content row -->
3
3
  <%= render collection: row, partial: 'exhibit_card', as: 'exhibit' %>
4
4
  </div>
5
5
  <% end %>
@@ -1,13 +1,9 @@
1
1
  <% if tags.any? %>
2
- <div class="row">
3
- <div class="col-md-12 text-center">
4
- <ul class="nav nav-pills tags">
5
- <li class="<%= 'active' if params[:tag].blank? %>"><%= link_to t('.all'), exhibits_path %></li>
2
+ <ul class="nav nav-pills tags justify-content-center">
3
+ <%= nav_link t('.all'), exhibits_path, active: params[:tag].blank? %>
6
4
 
7
- <% tags.sort_by(&:name).each do |tag| %>
8
- <li class="<%= 'active' if params[:tag] == tag.name %>"><%= link_to tag.name, exhibits_path(tag: tag.name) %></li>
9
- <% end %>
10
- </ul>
11
- </div>
12
- </div>
5
+ <% tags.sort_by(&:name).each do |tag| %>
6
+ <%= nav_link tag.name, exhibits_path(tag: tag.name), active: params[:tag] == tag.name %>
7
+ <% end %>
8
+ </ul>
13
9
  <% end %>
@@ -1,7 +1,7 @@
1
1
  <% if current_exhibit && current_exhibit.languages.accessible_by(current_ability).any? %>
2
2
  <li class="nav-item dropdown">
3
3
  <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
4
- <%= Spotlight::Language.new(locale: I18n.locale).to_native %> <b class="caret"></b>
4
+ <%= Spotlight::Language.new(locale: I18n.locale).to_native %>
5
5
  </a>
6
6
  <ul class="dropdown-menu">
7
7
  <% locale_selecter_dropown_options.each do |language| %>
@@ -13,6 +13,6 @@
13
13
  </td>
14
14
  <td class="text-right"><%= exhibit.published? ? t(:'.published') : t(:'.unpublished') %></td>
15
15
  <td class="text-right"><%= exhibit.requested_by %></td>
16
- <td class="text-right"><%= l exhibit.created_at, format: :short %></td>
17
- <td class="text-right"><%= l exhibit.updated_at, format: :short %></td>
16
+ <td class="text-right"><%= l exhibit.created_at, format: :long %></td>
17
+ <td class="text-right"><%= l exhibit.updated_at, format: :long %></td>
18
18
  </tr>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spotlight
4
- VERSION = '3.0.0.alpha.1'
4
+ VERSION = '3.0.0.alpha.2'
5
5
  end
@@ -146,5 +146,15 @@ describe Spotlight::CrudLinkHelpers, type: :helper do
146
146
  rendered = Capybara.string(helper.nav_link('Some link', root_url))
147
147
  expect(rendered).to have_css('.nav-link.active')
148
148
  end
149
+
150
+ it 'accepts an active argument to toggle the active class without regard for the current page' do
151
+ rendered = Capybara.string(helper.nav_link('Some link', root_url, active: true))
152
+ expect(rendered).to have_css('.nav-link.active')
153
+
154
+ allow(helper).to receive(:current_page?).with(root_url).and_return(true)
155
+
156
+ rendered = Capybara.string(helper.nav_link('Some link', root_url, active: false))
157
+ expect(rendered).not_to have_css('.nav-link.active')
158
+ end
149
159
  end
150
160
  end
@@ -73,10 +73,25 @@ describe SolrDocument, type: :model do
73
73
  expect(mock_sidecar).to receive(:update).with(data: { 'a' => 1 })
74
74
  subject.update exhibit, sidecar: { data: { 'a' => 1 } }
75
75
  end
76
+
76
77
  it 'stores tags' do
77
78
  subject.update exhibit, exhibit_tag_list: 'paris, normandy'
78
79
  expect(subject.sidecar(exhibit).tags_from(exhibit)).to eq %w(paris normandy)
79
80
  end
81
+
82
+ it 'converts empty strings to nil' do
83
+ mock_sidecar = double
84
+ allow(subject).to receive_messages(sidecar: mock_sidecar)
85
+ expect(mock_sidecar).to receive(:update).with(data: { 'a' => nil })
86
+ subject.update exhibit, sidecar: { data: { 'a' => '' } }
87
+ end
88
+
89
+ it 'compacts arrays of empty or nil values' do
90
+ mock_sidecar = double
91
+ allow(subject).to receive_messages(sidecar: mock_sidecar)
92
+ expect(mock_sidecar).to receive(:update).with(data: { 'a' => ['a'] })
93
+ subject.update exhibit, sidecar: { data: { 'a' => ['', nil, 'a'] } }
94
+ end
80
95
  end
81
96
 
82
97
  describe '#to_solr' do
@@ -53,9 +53,9 @@ describe Spotlight::ReindexProgress, type: :model do
53
53
  it 'returns a hash with values for current_log_entry via the various helper methods' do
54
54
  expect(subject.as_json).to eq(
55
55
  recently_in_progress: subject.recently_in_progress?,
56
- started_at: I18n.l(reindexing_log_entry.start_time, format: :short),
57
- finished_at: I18n.l(reindexing_log_entry.end_time, format: :short),
58
- updated_at: I18n.l(reindexing_log_entry.updated_at, format: :short),
56
+ started_at: I18n.l(reindexing_log_entry.start_time, format: :long),
57
+ finished_at: I18n.l(reindexing_log_entry.end_time, format: :long),
58
+ updated_at: I18n.l(reindexing_log_entry.updated_at, format: :long),
59
59
  total: subject.total,
60
60
  completed: subject.completed,
61
61
  errored: subject.errored?,
@@ -28,5 +28,19 @@ describe Spotlight::SolrDocumentSidecar, type: :model do
28
28
 
29
29
  its(:to_solr) { should include 'the_solr_field' => 'some value' }
30
30
  end
31
+
32
+ context 'with blank fields' do
33
+ before do
34
+ subject.data = {
35
+ 'a_blank_field' => '',
36
+ 'a_blank_multivalued_field' => ['', ''],
37
+ 'a_multivalued_field_with_some_blanks' => ['', 'a']
38
+ }
39
+ end
40
+
41
+ its(:to_solr) { should include 'a_blank_field' => nil }
42
+ its(:to_solr) { should include 'a_blank_multivalued_field' => [] }
43
+ its(:to_solr) { should include 'a_multivalued_field_with_some_blanks' => ['a'] }
44
+ end
31
45
  end
32
46
  end
@@ -43,8 +43,8 @@ describe 'spotlight/dashboards/_reindexing_activity.html.erb', type: :view do
43
43
  end
44
44
 
45
45
  it 'formats the start time correctly' do
46
- expect(rendered).to have_css('table.table-striped td', text: '05 Jan 23:00', count: 1)
47
- expect(rendered).to have_css('table.table-striped td', text: '10 Jan 23:00', count: 1)
46
+ expect(rendered).to have_css('table.table-striped td', text: 'January 05, 2017 23:00', count: 1)
47
+ expect(rendered).to have_css('table.table-striped td', text: 'January 10, 2017 23:00', count: 1)
48
48
  end
49
49
 
50
50
  it 'displays the user that initiated the reindexing' do
@@ -80,7 +80,7 @@ describe 'spotlight/dashboards/_reindexing_activity.html.erb', type: :view do
80
80
 
81
81
  # we expect one blank table cell for the user, and values for everything else
82
82
  expect(rendered).to have_css('table.table-striped td', text: /^$/, count: 1)
83
- expect(rendered).to have_css('table.table-striped td', text: '05 Jan 23:00', count: 1)
83
+ expect(rendered).to have_css('table.table-striped td', text: 'January 05, 2017 23:00', count: 1)
84
84
  expect(rendered).to have_css('table.table-striped td', text: /^10$/, count: 1)
85
85
  expect(rendered).to have_css('table.table-striped td', text: '5 minutes', count: 1)
86
86
  expect(rendered).to have_css('table.table-striped td', text: 'Successful', count: 1)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blacklight-spotlight
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.alpha.1
4
+ version: 3.0.0.alpha.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Beer
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2020-01-15 00:00:00.000000000 Z
14
+ date: 2020-01-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rails