blacklight-spotlight 3.6.0.beta6 → 3.6.0.beta7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -7
- data/app/assets/javascripts/spotlight/spotlight.esm.js +18 -13
- data/app/assets/javascripts/spotlight/spotlight.esm.js.map +1 -1
- data/app/assets/javascripts/spotlight/spotlight.js +18 -13
- data/app/assets/javascripts/spotlight/spotlight.js.map +1 -1
- data/app/controllers/spotlight/tags_controller.rb +1 -1
- data/app/javascript/spotlight/admin/blocks/solr_documents_base_block.js +18 -13
- data/app/models/concerns/spotlight/browse_category_search_builder.rb +10 -1
- data/app/models/spotlight/blacklight_configuration.rb +9 -9
- data/app/models/spotlight/contact.rb +1 -1
- data/app/models/spotlight/contact_form.rb +1 -1
- data/app/models/spotlight/custom_field.rb +1 -1
- data/app/models/spotlight/custom_search_field.rb +1 -1
- data/app/models/spotlight/event.rb +1 -1
- data/app/models/spotlight/exhibit.rb +1 -1
- data/app/models/spotlight/job_tracker.rb +1 -1
- data/app/models/spotlight/resource.rb +1 -1
- data/app/models/spotlight/solr_document_sidecar.rb +5 -3
- data/app/services/spotlight/etl/executor.rb +1 -1
- data/app/services/spotlight/etl/solr_loader.rb +1 -1
- data/app/services/spotlight/invite_users_service.rb +1 -1
- data/lib/migration/iiif.rb +3 -3
- data/lib/spotlight/engine.rb +17 -4
- data/lib/spotlight/version.rb +1 -1
- data/lib/tasks/spotlight_tasks.rake +1 -1
- data/spec/factories/searches.rb +12 -0
- data/spec/support/features/test_features_helpers.rb +1 -1
- metadata +7 -21
@@ -38,7 +38,7 @@ module Spotlight
|
|
38
38
|
|
39
39
|
def update_all
|
40
40
|
tags_to_rename = batch_update_params['owned_tags_attributes'].values.select do |tag|
|
41
|
-
tag[:name]
|
41
|
+
tag[:name].present? && tag[:current_name]&.strip != tag[:name]&.strip
|
42
42
|
end
|
43
43
|
|
44
44
|
rename_tags_later!(tags_to_rename)
|
@@ -48,19 +48,24 @@ SirTrevor.Blocks.SolrDocumentsBase = (function(){
|
|
48
48
|
</div>
|
49
49
|
`},
|
50
50
|
|
51
|
-
|
51
|
+
// Sets the first version of the IIIF information from autocomplete data.
|
52
|
+
_itemPanelIiifFields: function(index, autocomplete_data) {
|
52
53
|
return [
|
53
54
|
// '<input type="hidden" name="item[' + index + '][iiif_region]" value="' + (data.iiif_region) + '"/>',
|
54
55
|
// for legacy compatiblity:
|
55
|
-
'<input type="hidden" name="item[' + index + '][thumbnail_image_url]" value="' + (
|
56
|
-
'<input type="hidden" name="item[' + index + '][full_image_url]" value="' + (
|
57
|
-
'<input type="hidden" name="item[' + index + '][iiif_tilesource]" value="' + (
|
58
|
-
'<input type="hidden" name="item[' + index + '][iiif_manifest_url]" value="' + (
|
59
|
-
'<input type="hidden" name="item[' + index + '][iiif_canvas_id]" value="' + (
|
60
|
-
'<input type="hidden" name="item[' + index + '][iiif_image_id]" value="' + (
|
56
|
+
'<input type="hidden" name="item[' + index + '][thumbnail_image_url]" value="' + (autocomplete_data.thumbnail_image_url || autocomplete_data.thumbnail || "") + '"/>',
|
57
|
+
'<input type="hidden" name="item[' + index + '][full_image_url]" value="' + (autocomplete_data.full_image_url || autocomplete_data.thumbnail_image_url || autocomplete_data.thumbnail || "") + '"/>',
|
58
|
+
'<input type="hidden" name="item[' + index + '][iiif_tilesource]" value="' + (autocomplete_data.iiif_tilesource) + '"/>',
|
59
|
+
'<input type="hidden" name="item[' + index + '][iiif_manifest_url]" value="' + (autocomplete_data.iiif_manifest_url) + '"/>',
|
60
|
+
'<input type="hidden" name="item[' + index + '][iiif_canvas_id]" value="' + (autocomplete_data.iiif_canvas_id) + '"/>',
|
61
|
+
'<input type="hidden" name="item[' + index + '][iiif_image_id]" value="' + (autocomplete_data.iiif_image_id) + '"/>',
|
61
62
|
].join("\n");
|
62
63
|
},
|
63
|
-
|
64
|
+
// Overwrites the hidden inputs from _itemPanelIiifFields with data from the
|
65
|
+
// manifest. Called by afterPanelRender - the manifest_data here is built
|
66
|
+
// from canvases in the manifest, transformed by spotlight/admin/iiif.js in
|
67
|
+
// the #images method.
|
68
|
+
setIiifFields: function(panel, manifest_data, initialize) {
|
64
69
|
var legacyThumbnailField = $(panel).find('[name$="[thumbnail_image_url]"]')
|
65
70
|
var legacyFullField = $(panel).find('[name$="[full_image_url]"]')
|
66
71
|
|
@@ -70,11 +75,11 @@ SirTrevor.Blocks.SolrDocumentsBase = (function(){
|
|
70
75
|
|
71
76
|
legacyThumbnailField.val("");
|
72
77
|
legacyFullField.val("");
|
73
|
-
$(panel).find('[name$="[iiif_image_id]"]').val(
|
74
|
-
$(panel).find('[name$="[iiif_tilesource]"]').val(
|
75
|
-
$(panel).find('[name$="[iiif_manifest_url]"]').val(
|
76
|
-
$(panel).find('[name$="[iiif_canvas_id]"]').val(
|
77
|
-
$(panel).find('img.img-thumbnail').attr('src',
|
78
|
+
$(panel).find('[name$="[iiif_image_id]"]').val(manifest_data.imageId);
|
79
|
+
$(panel).find('[name$="[iiif_tilesource]"]').val(manifest_data.tilesource);
|
80
|
+
$(panel).find('[name$="[iiif_manifest_url]"]').val(manifest_data.manifest);
|
81
|
+
$(panel).find('[name$="[iiif_canvas_id]"]').val(manifest_data.canvasId);
|
82
|
+
$(panel).find('img.img-thumbnail').attr('src', manifest_data.thumbnail_image_url || manifest_data.tilesource.replace("/info.json", "/full/100,100/0/default.jpg"));
|
78
83
|
},
|
79
84
|
afterPanelRender: function(data, panel) {
|
80
85
|
var context = this;
|
@@ -31,12 +31,21 @@ module Spotlight
|
|
31
31
|
|
32
32
|
solr_params.append_query(query) if query.present?
|
33
33
|
|
34
|
+
# for a browse category formed from a saved search, the query syntax reads as two "must" values
|
35
|
+
# e.g. "json"=>{"query"=>{"bool"=>{"must"=>["savedsearchterm", "browsecategorysearchterm"]}}}}
|
36
|
+
must_values = solr_params.dig(:json, :query, :bool, :must)
|
37
|
+
|
38
|
+
return unless must_values&.any?
|
39
|
+
|
40
|
+
# this type of query must be parsed by lucene to function
|
41
|
+
solr_params[:defType] = 'lucene'
|
42
|
+
|
34
43
|
# This replicates existing spotlight 2.x search behavior, more or less. It
|
35
44
|
# doesn't take into account the possibility that the browse category query
|
36
45
|
# could use a different search field (which.. doesn't have an existing UI
|
37
46
|
# control.. and may require additional upstream work to properly encapsulate
|
38
47
|
# the two query parameters)
|
39
|
-
|
48
|
+
must_values.map! do |q|
|
40
49
|
q.is_a?(String) ? { edismax: { query: q } } : q
|
41
50
|
end
|
42
51
|
end
|
@@ -10,15 +10,15 @@ module Spotlight
|
|
10
10
|
has_paper_trail
|
11
11
|
|
12
12
|
belongs_to :exhibit, touch: true, optional: true
|
13
|
-
serialize :facet_fields, Hash
|
14
|
-
serialize :index_fields, Hash
|
15
|
-
serialize :search_fields, Hash
|
16
|
-
serialize :sort_fields, Hash
|
17
|
-
serialize :default_solr_params, Hash
|
18
|
-
serialize :show, Hash
|
19
|
-
serialize :index, Hash
|
20
|
-
serialize :per_page, Array
|
21
|
-
serialize :document_index_view_types, Array
|
13
|
+
serialize :facet_fields, Hash, coder: YAML
|
14
|
+
serialize :index_fields, Hash, coder: YAML
|
15
|
+
serialize :search_fields, Hash, coder: YAML
|
16
|
+
serialize :sort_fields, Hash, coder: YAML
|
17
|
+
serialize :default_solr_params, Hash, coder: YAML
|
18
|
+
serialize :show, Hash, coder: YAML
|
19
|
+
serialize :index, Hash, coder: YAML
|
20
|
+
serialize :per_page, Array, coder: YAML
|
21
|
+
serialize :document_index_view_types, Array, coder: YAML
|
22
22
|
|
23
23
|
include Spotlight::BlacklightConfigurationDefaults
|
24
24
|
|
@@ -7,7 +7,7 @@ module Spotlight
|
|
7
7
|
belongs_to :exhibit, touch: true, optional: true
|
8
8
|
scope :published, -> { where(show_in_sidebar: true) }
|
9
9
|
default_scope { order('weight ASC') }
|
10
|
-
serialize :contact_info, Hash
|
10
|
+
serialize :contact_info, Hash, coder: YAML
|
11
11
|
|
12
12
|
extend FriendlyId
|
13
13
|
friendly_id :name, use: %i[slugged scoped finders], scope: :exhibit
|
@@ -8,7 +8,7 @@ module Spotlight
|
|
8
8
|
|
9
9
|
attr_accessor :current_exhibit, :name, :email, Spotlight::Engine.config.spambot_honeypot_email_field, :message, :current_url, :request
|
10
10
|
|
11
|
-
validates :email, format: { with: /\A([\w
|
11
|
+
validates :email, format: { with: /\A([\w.%+-]+)@([\w-]+\.)+(\w{2,})\z/i }
|
12
12
|
|
13
13
|
# the spambot_honeypot_email_field field is intended to be hidden visually from the user,
|
14
14
|
# in hope that a spam bot filling out the form will enter a value, whereas a human with a
|
@@ -35,7 +35,7 @@ module Spotlight
|
|
35
35
|
acts_as_tagger
|
36
36
|
acts_as_taggable
|
37
37
|
delegate :blacklight_config, to: :blacklight_configuration
|
38
|
-
serialize :facets, Array
|
38
|
+
serialize :facets, Array, coder: YAML
|
39
39
|
|
40
40
|
# NOTE: friendly id associations need to be 'destroy'ed to reap the slug history
|
41
41
|
has_many :about_pages, -> { for_default_locale }, extend: FriendlyId::FinderMethods
|
@@ -14,7 +14,7 @@ module Spotlight
|
|
14
14
|
has_many :job_trackers, as: :on, dependent: Rails.version > '6.1' ? :destroy_async : :destroy
|
15
15
|
has_many :subevents, through: :job_trackers, source: :events
|
16
16
|
|
17
|
-
serialize :data
|
17
|
+
serialize :data, coder: YAML
|
18
18
|
|
19
19
|
after_initialize do
|
20
20
|
self.data ||= {}
|
@@ -11,8 +11,8 @@ module Spotlight
|
|
11
11
|
belongs_to :exhibit, optional: false
|
12
12
|
belongs_to :resource, optional: true
|
13
13
|
belongs_to :document, optional: false, polymorphic: true
|
14
|
-
serialize :data, Hash
|
15
|
-
serialize :index_status, Hash
|
14
|
+
serialize :data, Hash, coder: YAML
|
15
|
+
serialize :index_status, Hash, coder: YAML
|
16
16
|
|
17
17
|
delegate :has_key?, :key?, to: :data
|
18
18
|
|
@@ -101,8 +101,10 @@ module Spotlight
|
|
101
101
|
def convert_stored_value_to_solr(value)
|
102
102
|
if value.blank?
|
103
103
|
nil
|
104
|
-
elsif value.is_a?
|
104
|
+
elsif value.is_a? Array
|
105
105
|
value.reject(&:blank?)
|
106
|
+
elsif value.is_a? Hash
|
107
|
+
value.values.reject(&:blank?)
|
106
108
|
else
|
107
109
|
value
|
108
110
|
end
|
@@ -56,7 +56,7 @@ module Spotlight
|
|
56
56
|
# @private
|
57
57
|
# @yield Logger
|
58
58
|
def with_logger
|
59
|
-
logger =
|
59
|
+
logger = context&.logger || Rails.logger
|
60
60
|
logger.tagged(pipeline.class) do
|
61
61
|
logger.tagged("#<#{source.class} id=#{source&.id if source.respond_to?(:id)}>") do
|
62
62
|
@logger = logger
|
@@ -7,7 +7,7 @@ module Spotlight
|
|
7
7
|
# need to be persisted in order to generate the appropriate content in the invitation email.
|
8
8
|
class InviteUsersService
|
9
9
|
def self.call(resource:)
|
10
|
-
resource.roles.includes(:user).
|
10
|
+
resource.roles.includes(:user).find_each do |role|
|
11
11
|
user = role.user
|
12
12
|
|
13
13
|
user.deliver_invitation if user.created_by_invite? && user.invitation_sent_at.blank?
|
data/lib/migration/iiif.rb
CHANGED
@@ -23,21 +23,21 @@ module Migration
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def migrate_featured_images
|
26
|
-
Spotlight::FeaturedImage.all.
|
26
|
+
Spotlight::FeaturedImage.all.find_each do |image|
|
27
27
|
update_iiif_url(image)
|
28
28
|
copy_exhibit_thumbnail_from_featured_image(image)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
def migrate_contact_avatars
|
33
|
-
Spotlight::Contact.all.
|
33
|
+
Spotlight::Contact.all.find_each do |contact|
|
34
34
|
avatar = copy_contact_image_to_avatar(contact)
|
35
35
|
contact.update(avatar: avatar) if avatar
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
def migrate_upload_images
|
40
|
-
Spotlight::Resources::Upload.all.
|
40
|
+
Spotlight::Resources::Upload.all.find_each do |upload|
|
41
41
|
copy_upload_to_featured_image(upload)
|
42
42
|
end
|
43
43
|
end
|
data/lib/spotlight/engine.rb
CHANGED
@@ -334,10 +334,23 @@ module Spotlight
|
|
334
334
|
config.assign_default_roles_to_first_user = true
|
335
335
|
|
336
336
|
config.exhibit_roles = %w[admin curator viewer]
|
337
|
-
|
338
|
-
if ActiveRecord.respond_to?(:yaml_column_permitted_classes)
|
339
|
-
|
340
|
-
|
337
|
+
# PaperTrail serializes objects to YAML, so we need to permit these classes to be deserialized
|
338
|
+
if ActiveRecord.respond_to?(:yaml_column_permitted_classes)
|
339
|
+
# Rails >= 7.0
|
340
|
+
ActiveRecord.yaml_column_permitted_classes ||= []
|
341
|
+
ActiveRecord.yaml_column_permitted_classes += [Symbol,
|
342
|
+
ActiveSupport::HashWithIndifferentAccess,
|
343
|
+
ActiveSupport::TimeWithZone,
|
344
|
+
ActiveSupport::TimeZone,
|
345
|
+
Time]
|
346
|
+
elsif ActiveRecord::Base.respond_to?(:yaml_column_permitted_classes)
|
347
|
+
# Rails 6.1
|
348
|
+
ActiveRecord::Base.yaml_column_permitted_classes ||= []
|
349
|
+
ActiveRecord::Base.yaml_column_permitted_classes += [Symbol,
|
350
|
+
ActiveSupport::HashWithIndifferentAccess,
|
351
|
+
ActiveSupport::TimeWithZone,
|
352
|
+
ActiveSupport::TimeZone,
|
353
|
+
Time]
|
341
354
|
end
|
342
355
|
end
|
343
356
|
# rubocop:enable Metrics/ClassLength
|
data/lib/spotlight/version.rb
CHANGED
data/spec/factories/searches.rb
CHANGED
@@ -30,4 +30,16 @@ FactoryBot.define do
|
|
30
30
|
|
31
31
|
after(:build) { |search| search.thumbnail = FactoryBot.create(:featured_image) }
|
32
32
|
end
|
33
|
+
|
34
|
+
factory :search_field_search, class: 'Spotlight::Search' do
|
35
|
+
exhibit
|
36
|
+
title { 'Based on a search field' }
|
37
|
+
query_params { { 'search_field' => 'search', 'q' => 'model' } }
|
38
|
+
end
|
39
|
+
|
40
|
+
factory :facet_search, class: 'Spotlight::Search' do
|
41
|
+
exhibit
|
42
|
+
title { 'Based on a facet' }
|
43
|
+
query_params { { 'f' => { 'language_ssim' => 'Latin' } } }
|
44
|
+
end
|
33
45
|
end
|
@@ -60,7 +60,7 @@ module Spotlight
|
|
60
60
|
EOF
|
61
61
|
click_button('Save changes')
|
62
62
|
# verify that the page was created
|
63
|
-
expect(page).
|
63
|
+
expect(page).to have_no_selector('.alert-danger')
|
64
64
|
expect(page).to have_selector('.alert-info', text: 'page was successfully updated')
|
65
65
|
end
|
66
66
|
|
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.6.0.
|
4
|
+
version: 3.6.0.beta7
|
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:
|
14
|
+
date: 2024-01-30 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activejob-status
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
version: '5.0'
|
37
37
|
- - "<"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
39
|
+
version: '11'
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
version: '5.0'
|
47
47
|
- - "<"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
49
|
+
version: '11'
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: autoprefixer-rails
|
52
52
|
requirement: !ruby/object:Gem::Requirement
|
@@ -436,7 +436,7 @@ dependencies:
|
|
436
436
|
version: '11.0'
|
437
437
|
- - "<"
|
438
438
|
- !ruby/object:Gem::Version
|
439
|
-
version: '
|
439
|
+
version: '16'
|
440
440
|
type: :runtime
|
441
441
|
prerelease: false
|
442
442
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -446,7 +446,7 @@ dependencies:
|
|
446
446
|
version: '11.0'
|
447
447
|
- - "<"
|
448
448
|
- !ruby/object:Gem::Version
|
449
|
-
version: '
|
449
|
+
version: '16'
|
450
450
|
- !ruby/object:Gem::Dependency
|
451
451
|
name: rails
|
452
452
|
requirement: !ruby/object:Gem::Requirement
|
@@ -809,20 +809,6 @@ dependencies:
|
|
809
809
|
- - ">="
|
810
810
|
- !ruby/object:Gem::Version
|
811
811
|
version: '0'
|
812
|
-
- !ruby/object:Gem::Dependency
|
813
|
-
name: webdrivers
|
814
|
-
requirement: !ruby/object:Gem::Requirement
|
815
|
-
requirements:
|
816
|
-
- - ">="
|
817
|
-
- !ruby/object:Gem::Version
|
818
|
-
version: '0'
|
819
|
-
type: :development
|
820
|
-
prerelease: false
|
821
|
-
version_requirements: !ruby/object:Gem::Requirement
|
822
|
-
requirements:
|
823
|
-
- - ">="
|
824
|
-
- !ruby/object:Gem::Version
|
825
|
-
version: '0'
|
826
812
|
- !ruby/object:Gem::Dependency
|
827
813
|
name: webmock
|
828
814
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1564,7 +1550,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1564
1550
|
- !ruby/object:Gem::Version
|
1565
1551
|
version: 1.3.1
|
1566
1552
|
requirements: []
|
1567
|
-
rubygems_version: 3.
|
1553
|
+
rubygems_version: 3.4.10
|
1568
1554
|
signing_key:
|
1569
1555
|
specification_version: 4
|
1570
1556
|
summary: Enable librarians, curators, and others who are responsible for digital collections
|