blacklight-spotlight 4.7.1 → 5.0.0.pre.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -12
- data/Rakefile +8 -1
- data/app/assets/javascripts/spotlight/application.js +0 -1
- data/app/assets/javascripts/spotlight/spotlight.esm.js +3620 -3847
- data/app/assets/javascripts/spotlight/spotlight.esm.js.map +1 -1
- data/app/assets/javascripts/spotlight/spotlight.js +3620 -3852
- data/app/assets/javascripts/spotlight/spotlight.js.map +1 -1
- data/app/assets/stylesheets/spotlight/_accessibility.scss +0 -9
- data/app/assets/stylesheets/spotlight/_autocomplete.scss +49 -0
- data/app/assets/stylesheets/spotlight/_blacklight_configuration.scss +0 -1
- data/app/assets/stylesheets/spotlight/_blacklight_overrides.scss +1 -6
- data/app/assets/stylesheets/spotlight/_browse.scss +2 -2
- data/app/assets/stylesheets/spotlight/_catalog.scss +40 -41
- data/app/assets/stylesheets/spotlight/_curation.scss +1 -1
- data/app/assets/stylesheets/spotlight/_exhibit_admin.scss +7 -0
- data/app/assets/stylesheets/spotlight/_exhibits_index.scss +8 -5
- data/app/assets/stylesheets/spotlight/_featured_browse_categories_block.scss +3 -3
- data/app/assets/stylesheets/spotlight/_header.scss +13 -0
- data/app/assets/stylesheets/spotlight/_mixins.scss +3 -4
- data/app/assets/stylesheets/spotlight/_nestable.scss +2 -12
- data/app/assets/stylesheets/spotlight/_pages.scss +11 -9
- data/app/assets/stylesheets/spotlight/_report_a_problem.scss +1 -3
- data/app/assets/stylesheets/spotlight/_sir-trevor_overrides.scss +2 -2
- data/app/assets/stylesheets/spotlight/_spotlight.scss +2 -1
- data/app/assets/stylesheets/spotlight/_tag_selector.scss +34 -0
- data/app/assets/stylesheets/spotlight/_variables.scss +0 -8
- data/app/components/spotlight/analytics/dashboard_component.html.erb +3 -3
- data/app/components/spotlight/breadcrumbs_component.html.erb +13 -19
- data/app/components/spotlight/bulk_action_component.rb +1 -1
- data/app/components/spotlight/document_component.rb +1 -1
- data/app/components/spotlight/save_search_component.rb +1 -1
- data/app/components/spotlight/select_image_component.html.erb +17 -0
- data/app/components/spotlight/select_image_component.rb +24 -0
- data/app/components/spotlight/skip_link_component.rb +16 -0
- data/app/components/spotlight/tag_selector_component.html.erb +40 -0
- data/app/components/spotlight/tag_selector_component.rb +41 -0
- data/app/components/spotlight/tag_selector_component.yml +6 -0
- data/app/components/spotlight/title_component.html.erb +8 -0
- data/app/components/spotlight/title_component.rb +22 -0
- data/app/controllers/spotlight/accessibility_controller.rb +2 -2
- data/app/controllers/spotlight/catalog_controller.rb +7 -2
- data/app/controllers/spotlight/contact_email_controller.rb +8 -2
- data/app/controllers/spotlight/languages_controller.rb +9 -4
- data/app/helpers/spotlight/application_helper.rb +7 -0
- data/app/helpers/spotlight/crop_helper.rb +4 -0
- data/app/helpers/spotlight/meta_helper.rb +59 -36
- data/app/javascript/spotlight/admin/blacklight_configuration.js +1 -1
- data/app/javascript/spotlight/admin/block_mixins/autocompleteable.js +70 -34
- data/app/javascript/spotlight/admin/blocks/block.js +1 -0
- data/app/javascript/spotlight/admin/blocks/browse_block.js +8 -12
- data/app/javascript/spotlight/admin/blocks/browse_group_categories_block.js +14 -18
- data/app/javascript/spotlight/admin/blocks/pages_block.js +6 -10
- data/app/javascript/spotlight/admin/blocks/resources_block.js +33 -15
- data/app/javascript/spotlight/admin/blocks/solr_documents_base_block.js +11 -6
- data/app/javascript/spotlight/admin/blocks/solr_documents_embed_block.js +1 -0
- data/app/javascript/spotlight/admin/blocks/uploaded_items_block.js +4 -3
- data/app/javascript/spotlight/admin/copy_email_addresses.js +2 -0
- data/app/javascript/spotlight/admin/crop.js +45 -17
- data/app/javascript/spotlight/admin/croppable.js +8 -1
- data/app/javascript/spotlight/admin/croppable_modal.js +68 -0
- data/app/javascript/spotlight/admin/exhibits.js +15 -10
- data/app/javascript/spotlight/admin/form_observer.js +1 -1
- data/app/javascript/spotlight/admin/index.js +0 -10
- data/app/javascript/spotlight/admin/locks.js +15 -5
- data/app/javascript/spotlight/admin/pages.js +1 -1
- data/app/javascript/spotlight/admin/search_typeahead.js +62 -55
- data/app/javascript/spotlight/admin/spotlight_nestable.js +173 -50
- data/app/javascript/spotlight/admin/visibility_toggle.js +1 -11
- data/app/javascript/spotlight/controllers/index.js +8 -0
- data/app/javascript/spotlight/controllers/tag_selector_controller.js +203 -0
- data/app/javascript/spotlight/core.js +4 -6
- data/app/javascript/spotlight/index.js +2 -0
- data/app/javascript/spotlight/user/browse_group_categories.js +2 -0
- data/app/javascript/spotlight/user/carousel.js +3 -1
- data/app/javascript/spotlight/user/index.js +0 -2
- data/app/models/sir_trevor_rails/block.rb +5 -4
- data/app/models/sir_trevor_rails/blocks/solr_documents_block.rb +1 -1
- data/app/models/sir_trevor_rails/blocks/solr_documents_embed_block.rb +1 -1
- data/app/models/sir_trevor_rails/blocks/uploaded_items_block.rb +1 -1
- data/app/models/spotlight/page_configurations.rb +1 -1
- data/app/views/catalog/_add_tags.html.erb +2 -2
- data/app/views/catalog/_change_visibility.html.erb +1 -1
- data/app/views/catalog/_remove_tags.html.erb +2 -2
- data/app/views/layouts/spotlight/base.html.erb +24 -13
- data/app/views/layouts/spotlight/spotlight.html.erb +6 -6
- data/app/views/shared/_masthead.html.erb +4 -31
- data/app/views/shared/_site_sidebar.html.erb +1 -1
- data/app/views/shared/_user_util_links.html.erb +3 -1
- data/app/views/spotlight/accessibility/alt_text.html.erb +2 -2
- data/app/views/spotlight/admin_users/index.html.erb +3 -3
- data/app/views/spotlight/appearances/edit.html.erb +1 -1
- data/app/views/spotlight/browse/_search_box.html.erb +8 -8
- data/app/views/spotlight/browse/show.html.erb +1 -1
- data/app/views/spotlight/bulk_updates/_download.html.erb +1 -1
- data/app/views/spotlight/bulk_updates/_upload.html.erb +1 -1
- data/app/views/spotlight/catalog/_admin_header.html.erb +1 -1
- data/app/views/spotlight/catalog/_edit_default.html.erb +2 -1
- data/app/views/spotlight/catalog/select_image.html.erb +1 -0
- data/app/views/spotlight/contacts/_form.html.erb +1 -1
- data/app/views/spotlight/exhibits/_contact.html.erb +5 -6
- data/app/views/spotlight/exhibits/_delete.html.erb +1 -1
- data/app/views/spotlight/exhibits/_languages.html.erb +3 -2
- data/app/views/spotlight/featured_images/_form.html.erb +6 -2
- data/app/views/spotlight/featured_images/_upload_form.html.erb +1 -1
- data/app/views/spotlight/metadata_configurations/_metadata_field.html.erb +1 -1
- data/app/views/spotlight/metadata_configurations/edit.html.erb +6 -6
- data/app/views/spotlight/pages/show.html.erb +1 -1
- data/app/views/spotlight/resources/csv_upload/_form.html.erb +1 -1
- data/app/views/spotlight/resources/upload/_form.html.erb +1 -1
- data/app/views/spotlight/roles/index.html.erb +1 -1
- data/app/views/spotlight/searches/_form.html.erb +1 -1
- data/app/views/spotlight/shared/_dd3_item.html.erb +1 -1
- data/app/views/spotlight/sir_trevor/blocks/_browse_group_categories_block.html.erb +1 -1
- data/app/views/spotlight/sir_trevor/blocks/_solr_documents_block.html.erb +1 -1
- data/app/views/spotlight/sir_trevor/blocks/_solr_documents_carousel_block.html.erb +1 -1
- data/app/views/spotlight/sir_trevor/blocks/_uploaded_items_block.html.erb +1 -1
- data/app/views/spotlight/tags/index.html.erb +2 -3
- data/app/views/spotlight/translations/_import.html.erb +2 -2
- data/config/importmap.rb +5 -0
- data/config/locales/spotlight.en.yml +2 -0
- data/config/routes.rb +5 -3
- data/lib/generators/spotlight/assets/generator_common_utilities.rb +36 -0
- data/lib/generators/spotlight/assets/importmap_generator.rb +87 -0
- data/lib/generators/spotlight/assets/propshaft_generator.rb +96 -0
- data/lib/generators/spotlight/assets_generator.rb +22 -0
- data/lib/generators/spotlight/install_generator.rb +8 -36
- data/lib/generators/spotlight/scaffold_resource_generator.rb +1 -1
- data/lib/generators/spotlight/templates/assets/spotlight.scss +6 -0
- data/lib/generators/spotlight/templates/javascript/jquery-shim.js +1 -0
- data/lib/spotlight/engine.rb +7 -6
- data/lib/spotlight/version.rb +1 -1
- data/spec/support/features/capybara_wait_metadata_helper.rb +13 -0
- data/spec/support/features/test_features_helpers.rb +16 -30
- data/vendor/assets/javascripts/tiny-slider.js +3 -0
- metadata +35 -87
- data/app/assets/stylesheets/spotlight/#_accessibility.scss# +0 -12
- data/app/javascript/spotlight/admin/checkbox_submit.js +0 -75
- data/app/javascript/spotlight/admin/exhibit_tag_autocomplete.js +0 -39
- data/app/javascript/spotlight/user/report_a_problem.js +0 -30
- data/app/views/spotlight/browse/_tophat.html.erb +0 -1
- data/app/views/spotlight/catalog/_tophat_default.html.erb +0 -1
- data/app/views/spotlight/home_pages/_tophat.html.erb +0 -2
- data/app/views/spotlight/pages/_tophat.html.erb +0 -1
- data/lib/generators/spotlight/templates/spotlight.js +0 -1
- data/lib/generators/spotlight/templates/spotlight.scss +0 -5
- data/spec/support/features/capybara_default_max_wait_metadata_helper.rb +0 -20
- data/vendor/assets/javascripts/bootstrap-tagsinput.js +0 -530
- data/vendor/assets/javascripts/jquery.serializejson.js +0 -234
- data/vendor/assets/javascripts/nestable.js +0 -645
- data/vendor/assets/javascripts/sir-trevor.js +0 -23508
- data/vendor/assets/javascripts/typeahead.bundle.min.js +0 -7
- data/vendor/assets/stylesheets/bootstrap-tagsinput.css +0 -46
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spotlight
|
4
|
+
# Component to select section of image
|
5
|
+
class SelectImageComponent < ViewComponent::Base
|
6
|
+
def initialize(index_id, block_item_id)
|
7
|
+
super
|
8
|
+
@index_id = index_id
|
9
|
+
@block_item_id = block_item_id
|
10
|
+
end
|
11
|
+
|
12
|
+
def render?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def initial_crop_selection
|
17
|
+
Spotlight::Engine.config.thumbnail_initial_crop_selection
|
18
|
+
end
|
19
|
+
|
20
|
+
def help_text
|
21
|
+
t(:'spotlight.pages.form.instructions_html')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spotlight
|
4
|
+
# Blacklight Skip Link Component with conditional search link for Spotlight
|
5
|
+
class SkipLinkComponent < Blacklight::SkipLinkComponent
|
6
|
+
def initialize(render_search_link: true)
|
7
|
+
@render_search_link = render_search_link
|
8
|
+
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def link_to_search
|
13
|
+
super if @render_search_link
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<div data-controller="tag-selector" class="tag-selector" data-tag-selector-translations-value="<%= translation_data.to_json %>" data-tag-selector-tags-value="<%= selected_tags %>">
|
2
|
+
<% if form.nil? %>
|
3
|
+
<%= text_field_tag field_name, selected_tags_value, class: 'tag-selector-input', placeholder: t('.no_js_placeholder'), data: { tag_selector_target: "tagsField" } %>
|
4
|
+
<% else %>
|
5
|
+
<%= form.text_field field_name, value: selected_tags_value, class: 'tag-selector-input', placeholder: t('.no_js_placeholder'), data: { tag_selector_target: "tagsField" } %>
|
6
|
+
<% end %>
|
7
|
+
<input type="hidden" value="<%= selected_tags_value %>" data-tag-selector-target="initialTags">
|
8
|
+
|
9
|
+
<div class='mb-3'>
|
10
|
+
<div class="tag-selection-wrapper" data-tag-selector-target="tagControlWrapper">
|
11
|
+
<div class="dropdown w-100 mb-3 d-inline-block" data-action="click@window->tag-selector#clickOutside">
|
12
|
+
<div data-tag-selector-target="tagSearchDropdown">
|
13
|
+
<div data-tag-selector-target="selectedTags"></div>
|
14
|
+
<div data-tag-selector-target="tagSearchInputWrapper" class="border rounded-bottom tag-selection-search-bar d-flex">
|
15
|
+
<button type="button" aria-label="toggle dropdown" class="btn btn-link text-secondary me-1 px-2" data-action="click->tag-selector#tagDropdown">
|
16
|
+
<span><%= search_icon_svg %></span>
|
17
|
+
</button>
|
18
|
+
<input class="flex-grow-1" data-action="input->tag-selector#search input->tag-selector#updateSearchResultsPlaceholder input->tag-selector#updateTagToAdd focus->tag-selector#tagDropdown keydown->tag-selector#handleKeydown"
|
19
|
+
data-tag-selector-target="tagSearch" placeholder="<%= t('.search') %>" aria-label="<%= t('.search') %>">
|
20
|
+
<button type="button" aria-label="toggle dropdown" class="dropdown-toggle btn btn-link text-secondary" data-bs-toggle="dropdown" data-action="click->tag-selector#tagDropdown"></button>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
<div data-tag-selector-target="dropdownContent" class="dropdown-content d-none tags-group border rounded">
|
24
|
+
<% all_tags.each do |tag| %>
|
25
|
+
<label class="d-block">
|
26
|
+
<input type="checkbox" <%= 'checked' if selected?(tag) %> data-action="click->tag-selector#tagUpdate" data-tag-selector-target="searchResultTags" data-tag="<%= tag %>">
|
27
|
+
<%= tag %>
|
28
|
+
</label>
|
29
|
+
<% end %>
|
30
|
+
<% if all_tags.empty? %>
|
31
|
+
<label class="no-results"><%= t('.no_results') %></label>
|
32
|
+
<% end %>
|
33
|
+
<label class="d-none" data-tag-selector-target="addNewTagWrapper">
|
34
|
+
<input type="checkbox" disabled data-action="click->tag-selector#tagCreate" data-tag-selector-target="newTag" data-tag=""> Add new tag
|
35
|
+
</label>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</div>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spotlight
|
4
|
+
# Displays a tag selection input
|
5
|
+
# This uses a plain text input that acts-as-taggable-on expects.
|
6
|
+
class TagSelectorComponent < ViewComponent::Base
|
7
|
+
# selected_tags_value is a comma delimited string of tags
|
8
|
+
def initialize(field_name:, all_tags:, selected_tags_value: nil, form: nil)
|
9
|
+
@form = form
|
10
|
+
@field_name = field_name
|
11
|
+
@selected_tags_value = selected_tags_value || ''
|
12
|
+
@all_tags = all_tags&.sort_by { |tag| (tag.respond_to?(:name) ? tag.name : tag).downcase }
|
13
|
+
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def selected_tags
|
18
|
+
selected_tags_value.split(',').map(&:strip)
|
19
|
+
end
|
20
|
+
|
21
|
+
def search_icon_svg
|
22
|
+
render Blacklight::Icons::SearchComponent.new
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# To pass to the JS
|
28
|
+
def translation_data
|
29
|
+
{
|
30
|
+
add_new_tag: t('.add_new_tag'),
|
31
|
+
remove: t('.remove')
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def selected?(tag)
|
36
|
+
selected_tags.include?(tag.respond_to?(:name) ? tag.name : tag)
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :form, :field_name, :selected_tags_value, :all_tags
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div class="container site-title-container">
|
2
|
+
<div class="site-title-wrapper">
|
3
|
+
<a href="<%= helpers.current_exhibit ? helpers.spotlight.exhibit_path(helpers.current_exhibit) : helpers.spotlight.exhibits_path %>" class="link-unstyled">
|
4
|
+
<%= title %>
|
5
|
+
<%= subtitle %>
|
6
|
+
</a>
|
7
|
+
</div>
|
8
|
+
</div>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spotlight
|
4
|
+
# Draws the title in the masthead
|
5
|
+
class TitleComponent < ViewComponent::Base
|
6
|
+
def initialize(title:, subtitle:)
|
7
|
+
@title = title
|
8
|
+
@subtitle = subtitle
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def title
|
13
|
+
tag.h1 @title, class: 'site-title h2'
|
14
|
+
end
|
15
|
+
|
16
|
+
def subtitle
|
17
|
+
return unless @subtitle
|
18
|
+
|
19
|
+
tag.small(@subtitle, class: 'd-none d-md-block py-2 fs-4')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -9,7 +9,7 @@ module Spotlight
|
|
9
9
|
|
10
10
|
def alt_text
|
11
11
|
# Sort by newest except for the homepage, which is always first
|
12
|
-
pages_with_alt = @exhibit.pages.order(Arel.sql('id = 1 DESC, created_at DESC')).select { |elem| elem.content.any?(&:
|
12
|
+
pages_with_alt = @exhibit.pages.order(Arel.sql('id = 1 DESC, created_at DESC')).select { |elem| elem.content.any?(&:supports_alt_text?) }
|
13
13
|
@pages = pages_with_alt.map { |page| get_alt_info(page) }
|
14
14
|
@has_alt_text = @pages.sum { |page| page[:has_alt_text] }
|
15
15
|
@total_alt_items = @pages.sum { |page| page[:can_have_alt_text] }
|
@@ -23,7 +23,7 @@ module Spotlight
|
|
23
23
|
can_have_alt_text = 0
|
24
24
|
has_alt_text = 0
|
25
25
|
page.content.each do |content|
|
26
|
-
next unless content.
|
26
|
+
next unless content.supports_alt_text?
|
27
27
|
|
28
28
|
content.item&.each_value do |item|
|
29
29
|
can_have_alt_text += 1
|
@@ -30,7 +30,6 @@ module Spotlight
|
|
30
30
|
if Blacklight::VERSION > '8'
|
31
31
|
blacklight_config.show.document_component = Spotlight::DocumentComponent
|
32
32
|
else
|
33
|
-
blacklight_config.show.partials.unshift 'tophat'
|
34
33
|
blacklight_config.show.partials.unshift 'curation_mode_toggle'
|
35
34
|
end
|
36
35
|
end
|
@@ -135,6 +134,12 @@ module Spotlight
|
|
135
134
|
end
|
136
135
|
end
|
137
136
|
|
137
|
+
def select_image
|
138
|
+
@index_id = params[:index_id]
|
139
|
+
@block_item_id = params[:block_item_id]
|
140
|
+
respond_to :html
|
141
|
+
end
|
142
|
+
|
138
143
|
protected
|
139
144
|
|
140
145
|
def load_document
|
@@ -194,7 +199,7 @@ module Spotlight
|
|
194
199
|
def solr_document_params
|
195
200
|
params.require(:solr_document).permit(:exhibit_tag_list,
|
196
201
|
uploaded_resource: [:url],
|
197
|
-
sidecar: [:public, { data:
|
202
|
+
sidecar: [:public, { data: editable_solr_document_params }])
|
198
203
|
end
|
199
204
|
|
200
205
|
def editable_solr_document_params
|
@@ -12,13 +12,19 @@ module Spotlight
|
|
12
12
|
|
13
13
|
def destroy
|
14
14
|
@contact_email.destroy
|
15
|
-
|
15
|
+
respond_to do |format|
|
16
|
+
format.turbo_stream { render turbo_stream: turbo_stream.remove(@contact_email) }
|
17
|
+
format.json { render json: { success: true, error: nil } }
|
18
|
+
end
|
16
19
|
end
|
17
20
|
|
18
21
|
private
|
19
22
|
|
20
23
|
def record_not_found(_error)
|
21
|
-
|
24
|
+
respond_to do |format|
|
25
|
+
format.turbo_stream { head :not_found }
|
26
|
+
format.json { render json: { success: false, error: 'Not Found' }, status: :not_found }
|
27
|
+
end
|
22
28
|
end
|
23
29
|
end
|
24
30
|
end
|
@@ -33,10 +33,15 @@ module Spotlight
|
|
33
33
|
def destroy
|
34
34
|
@language.destroy
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
respond_to do |format|
|
37
|
+
format.turbo_stream { render turbo_stream: turbo_stream.remove(@language) }
|
38
|
+
format.html do
|
39
|
+
redirect_to(
|
40
|
+
spotlight.edit_exhibit_path(@exhibit, tab: 'language'),
|
41
|
+
notice: t(:'helpers.submit.language.destroyed', model: @language.model_name.human.downcase)
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
40
45
|
end
|
41
46
|
|
42
47
|
private
|
@@ -30,6 +30,13 @@ module Spotlight
|
|
30
30
|
current_site.title.presence
|
31
31
|
end
|
32
32
|
|
33
|
+
def content?(field)
|
34
|
+
return content_for?(field) unless Rails.configuration.action_view.annotate_rendered_view_with_filenames && content_for(field).present?
|
35
|
+
|
36
|
+
stripped_content = content_for(field).gsub(/<!-- BEGIN .+? -->/, '').gsub(/<!-- END .+? -->/, '').strip
|
37
|
+
stripped_content.present?
|
38
|
+
end
|
39
|
+
|
33
40
|
# Returns the url for the current page in the new locale. This may be
|
34
41
|
# overridden in downstream applications where our naive use of `url_for`
|
35
42
|
# is insufficient to generate the expected routes
|
@@ -3,17 +3,37 @@
|
|
3
3
|
module Spotlight
|
4
4
|
# HTML <meta> tag helpers
|
5
5
|
module MetaHelper
|
6
|
+
def description(description)
|
7
|
+
content_for(:meta) { ActionController::Base.helpers.tag.meta(name: 'description', content: description) } if description
|
8
|
+
end
|
9
|
+
|
10
|
+
def card(type, &block)
|
11
|
+
card = {}
|
12
|
+
block.call(card) if block_given?
|
13
|
+
content_for(:meta) { build_tags(card, type) }
|
14
|
+
end
|
15
|
+
|
16
|
+
# rubocop:disable Rails/OutputSafety
|
17
|
+
def build_tags(attributes, tag_field)
|
18
|
+
type_fields = { 'og' => 'property', 'twitter' => 'name' }
|
19
|
+
attributes.map do |key, value|
|
20
|
+
ActionController::Base.helpers.tag.meta("#{type_fields[tag_field]}": "#{tag_field}:#{key}", content: value) if value
|
21
|
+
end.compact.join("\n").html_safe
|
22
|
+
end
|
23
|
+
# rubocop:enable Rails/OutputSafety
|
24
|
+
|
6
25
|
def add_exhibit_meta_content
|
7
26
|
exhibit_twitter_card_content
|
8
27
|
exhibit_opengraph_content
|
9
28
|
end
|
10
29
|
|
11
30
|
def exhibit_twitter_card_content
|
12
|
-
|
13
|
-
card
|
14
|
-
card.
|
15
|
-
card
|
16
|
-
card
|
31
|
+
card('twitter') do |card|
|
32
|
+
card['card'] = 'summary'
|
33
|
+
card['url'] = spotlight.exhibit_root_url(current_exhibit)
|
34
|
+
card['title'] = current_exhibit.title
|
35
|
+
card['description'] = current_exhibit.subtitle
|
36
|
+
card['image'] = meta_image if current_exhibit.thumbnail
|
17
37
|
end
|
18
38
|
end
|
19
39
|
|
@@ -22,10 +42,10 @@ module Spotlight
|
|
22
42
|
end
|
23
43
|
|
24
44
|
def exhibit_opengraph_content
|
25
|
-
|
26
|
-
graph
|
27
|
-
graph
|
28
|
-
graph
|
45
|
+
card('og') do |graph|
|
46
|
+
graph['title'] = current_exhibit.title
|
47
|
+
graph['image'] = meta_image if current_exhibit.thumbnail
|
48
|
+
graph['site_name'] = site_title
|
29
49
|
end
|
30
50
|
end
|
31
51
|
|
@@ -35,20 +55,21 @@ module Spotlight
|
|
35
55
|
end
|
36
56
|
|
37
57
|
def page_twitter_card_content(page)
|
38
|
-
|
39
|
-
card
|
40
|
-
card
|
58
|
+
card('twitter') do |card|
|
59
|
+
card['card'] = 'summary_large_image'
|
60
|
+
card['title'] = page.title
|
61
|
+
card['image'] = page.thumbnail.iiif_url if page.thumbnail
|
41
62
|
end
|
42
63
|
end
|
43
64
|
|
44
65
|
def page_opengraph_content(page)
|
45
|
-
|
46
|
-
graph
|
47
|
-
graph
|
48
|
-
graph
|
49
|
-
graph
|
50
|
-
graph
|
51
|
-
graph
|
66
|
+
card('og') do |graph|
|
67
|
+
graph['type'] = 'article'
|
68
|
+
graph['site_name'] = application_name
|
69
|
+
graph['title'] = page.title
|
70
|
+
graph['image'] = page.thumbnail.iiif_url if page.thumbnail
|
71
|
+
graph['article:published_time'] = page.created_at.iso8601
|
72
|
+
graph['article:modified_time'] = page.updated_at.iso8601
|
52
73
|
end
|
53
74
|
end
|
54
75
|
|
@@ -58,20 +79,21 @@ module Spotlight
|
|
58
79
|
end
|
59
80
|
|
60
81
|
def browse_twitter_card_content(browse)
|
61
|
-
|
62
|
-
card
|
63
|
-
card
|
82
|
+
card('twitter') do |card|
|
83
|
+
card['card'] = 'summary_large_image'
|
84
|
+
card['title'] = browse.title
|
85
|
+
card['image'] = browse.thumbnail.iiif_url if browse.thumbnail
|
64
86
|
end
|
65
87
|
end
|
66
88
|
|
67
89
|
def browse_opengraph_content(browse)
|
68
|
-
|
69
|
-
graph
|
70
|
-
graph
|
71
|
-
graph
|
72
|
-
graph
|
73
|
-
graph
|
74
|
-
graph
|
90
|
+
card('og') do |graph|
|
91
|
+
graph['type'] = 'article'
|
92
|
+
graph['site_name'] = application_name
|
93
|
+
graph['title'] = browse.title
|
94
|
+
graph['image'] = browse.thumbnail.iiif_url if browse.thumbnail
|
95
|
+
graph['article:published_time'] = browse.created_at.iso8601
|
96
|
+
graph['article:modified_time'] = browse.updated_at.iso8601
|
75
97
|
end
|
76
98
|
end
|
77
99
|
|
@@ -83,19 +105,20 @@ module Spotlight
|
|
83
105
|
def document_twitter_card_content(document)
|
84
106
|
presenter = document_presenter(document)
|
85
107
|
|
86
|
-
|
87
|
-
card
|
88
|
-
card
|
108
|
+
card('twitter') do |card|
|
109
|
+
card['card'] = 'summary_large_image'
|
110
|
+
card['title'] = presenter.heading
|
111
|
+
card['image'] = document.first(blacklight_config.index.thumbnail_field)
|
89
112
|
end
|
90
113
|
end
|
91
114
|
|
92
115
|
def document_opengraph_content(document)
|
93
116
|
presenter = document_presenter(document)
|
94
117
|
|
95
|
-
|
96
|
-
graph
|
97
|
-
graph
|
98
|
-
graph
|
118
|
+
card('og') do |graph|
|
119
|
+
graph['site_name'] = application_name
|
120
|
+
graph['title'] = presenter.heading
|
121
|
+
graph['image'] = document.first(blacklight_config.index.thumbnail_field)
|
99
122
|
end
|
100
123
|
end
|
101
124
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import { fetchAutocompleteJSON } from 'spotlight/admin/search_typeahead';
|
2
|
+
|
1
3
|
(function ($){
|
2
4
|
SirTrevor.BlockMixins.Autocompleteable = {
|
3
5
|
mixinName: "Autocompleteable",
|
@@ -7,59 +9,93 @@
|
|
7
9
|
this.on("onRender", this.addAutocompletetoSirTrevorForm);
|
8
10
|
|
9
11
|
if (this['autocomplete_url'] === undefined) {
|
10
|
-
this.autocomplete_url = function() { return $('form[data-autocomplete-url]').data('autocomplete-url')
|
12
|
+
this.autocomplete_url = function() { return $('form[data-autocomplete-url]').data('autocomplete-url'); };
|
13
|
+
}
|
14
|
+
|
15
|
+
if (this['autocomplete_fetch'] === undefined) {
|
16
|
+
this.autocomplete_fetch = this.fetchAutocompleteResults;
|
11
17
|
}
|
12
18
|
|
13
19
|
if (this['transform_autocomplete_results'] === undefined) {
|
14
20
|
this.transform_autocomplete_results = (val) => val
|
15
21
|
}
|
16
22
|
|
23
|
+
if (this['highlight'] === undefined) {
|
24
|
+
this.highlight = function(value) {
|
25
|
+
if (!value) return '';
|
26
|
+
const queryValue = this.getQueryValue().trim();
|
27
|
+
return queryValue ? value.replace(new RegExp(queryValue, 'gi'), '<strong>$&</strong>') : value;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
17
31
|
if (this['autocomplete_control'] === undefined) {
|
18
|
-
this.autocomplete_control = function() {
|
32
|
+
this.autocomplete_control = function() {
|
33
|
+
const autocompleteID = this.autocompleteID();
|
34
|
+
return `
|
35
|
+
<auto-complete src="${this.autocomplete_url()}" for="${autocompleteID}-popup" fetch-on-empty>
|
36
|
+
<input type="text" name="${autocompleteID}" placeholder="${i18n.t("blocks:autocompleteable:placeholder")}" data-default-typeahead>
|
37
|
+
<ul id="${autocompleteID}-popup"></ul>
|
38
|
+
<div id="${autocompleteID}-popup-feedback" class="sr-only visually-hidden"></div>
|
39
|
+
</auto-complete>
|
40
|
+
` };
|
19
41
|
}
|
20
42
|
|
21
|
-
if (this['
|
22
|
-
this.
|
23
|
-
return {
|
24
|
-
|
25
|
-
url: this.autocomplete_url(),
|
26
|
-
filter: this.transform_autocomplete_results
|
27
|
-
}
|
28
|
-
};
|
29
|
-
};
|
43
|
+
if (this['autocomplete_element_template'] === undefined) {
|
44
|
+
this.autocomplete_element_template = function(item) {
|
45
|
+
return `<li role="option" data-autocomplete-value="${item.id}">${this.autocomplete_template(item)}</li>`
|
46
|
+
}
|
30
47
|
}
|
31
48
|
},
|
32
49
|
|
33
|
-
|
34
|
-
|
35
|
-
if($(this).val() === '') {
|
36
|
-
$(this).data().ttTypeahead.input.trigger('queryChanged', '');
|
37
|
-
}
|
38
|
-
});
|
50
|
+
queryTokenizer: function(query) {
|
51
|
+
return query.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
39
52
|
},
|
40
53
|
|
41
|
-
|
42
|
-
|
54
|
+
filterResults: function(data, query) {
|
55
|
+
const queryStrings = this.queryTokenizer(query);
|
56
|
+
return data.filter(item => {
|
57
|
+
const lowerTitle = item.title.toLowerCase();
|
58
|
+
return queryStrings.some(queryString => lowerTitle.includes(queryString));
|
59
|
+
});
|
60
|
+
},
|
43
61
|
|
44
|
-
|
45
|
-
|
46
|
-
|
62
|
+
fetchAutocompleteResults: async function(url) {
|
63
|
+
const result = await fetchAutocompleteJSON(url);
|
64
|
+
const transformed = this.transform_autocomplete_results(result);
|
65
|
+
this.fetchedData = {};
|
66
|
+
transformed.map(item => this.fetchedData[item.id] = item);
|
67
|
+
return transformed.map(item => this.autocomplete_element_template(item)).join('');
|
68
|
+
},
|
47
69
|
|
48
|
-
|
70
|
+
fetchOnceAndFilterLocalResults: async function(url) {
|
71
|
+
if (this.fetchedData === undefined) {
|
72
|
+
await this.fetchAutocompleteResults(url);
|
49
73
|
}
|
74
|
+
const query = url.searchParams.get('q');
|
75
|
+
const data = Object.values(this.fetchedData);
|
76
|
+
const filteredData = query ? this.filterResults(data, query) : data;
|
77
|
+
return filteredData.map(item => this.autocomplete_element_template(item)).join('');
|
78
|
+
},
|
79
|
+
|
80
|
+
autocompleteID: function() {
|
81
|
+
return this.blockID + '-autocomplete';
|
50
82
|
},
|
51
83
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
84
|
+
getQueryValue: function() {
|
85
|
+
const completer = this.inner.querySelector("auto-complete > input");
|
86
|
+
return completer.value;
|
87
|
+
},
|
88
|
+
|
89
|
+
addAutocompletetoSirTrevorForm: function() {
|
90
|
+
const completer = this.inner.querySelector("auto-complete");
|
91
|
+
completer.fetchResult = this.autocomplete_fetch.bind(this);
|
92
|
+
completer.addEventListener('auto-complete-change', (e) => {
|
93
|
+
const data = this.fetchedData[e.relatedTarget.value];
|
94
|
+
if (e.relatedTarget.value && data) {
|
95
|
+
e.value = e.relatedTarget.value = '';
|
96
|
+
this.createItemPanel({ ...data, display: "true" });
|
97
|
+
}
|
98
|
+
});
|
63
99
|
},
|
64
100
|
},
|
65
101
|
|
@@ -8,22 +8,18 @@ SirTrevor.Blocks.Browse = (function(){
|
|
8
8
|
icon_name: "browse",
|
9
9
|
|
10
10
|
autocomplete_url: function() {
|
11
|
-
return
|
11
|
+
return document.getElementById(this.instanceID).closest('form[data-autocomplete-exhibit-searches-path]').dataset.autocompleteExhibitSearchesPath;
|
12
|
+
},
|
13
|
+
|
14
|
+
autocomplete_fetch: function(url) {
|
15
|
+
return this.fetchOnceAndFilterLocalResults(url);
|
12
16
|
},
|
13
17
|
|
14
18
|
autocomplete_template: function(obj) {
|
15
19
|
const thumbnail = obj.thumbnail_image_url ? `<div class="document-thumbnail"><img class="img-thumbnail" src="${obj.thumbnail_image_url}" /></div>` : ''
|
20
|
+
const description = obj.description ? `<small> ${obj.description}</small>` : '';
|
16
21
|
return `<div class="autocomplete-item${!obj.published ? ' blacklight-private' : ''}">${thumbnail}
|
17
|
-
<span class="autocomplete-title">${obj.full_title}</span
|
18
|
-
},
|
19
|
-
|
20
|
-
bloodhoundOptions: function() {
|
21
|
-
return {
|
22
|
-
prefetch: {
|
23
|
-
url: this.autocomplete_url(),
|
24
|
-
ttl: 0
|
25
|
-
}
|
26
|
-
};
|
22
|
+
<span class="autocomplete-title">${this.highlight(obj.full_title)}</span>${description}</div>`;
|
27
23
|
},
|
28
24
|
|
29
25
|
_itemPanel: function(data) {
|
@@ -36,7 +32,7 @@ SirTrevor.Blocks.Browse = (function(){
|
|
36
32
|
}
|
37
33
|
var resource_id = data.slug || data.id;
|
38
34
|
var markup = `
|
39
|
-
<li class="field
|
35
|
+
<li class="field dd-item dd3-item" data-resource-id="${resource_id}" data-id="${index}" id="${this.formId(index)}">
|
40
36
|
<input type="hidden" name="item[${index}][id]" value="${resource_id}" />
|
41
37
|
<input type="hidden" name="item[${index}][full_title]" value="${(data.full_title || data.title)}" />
|
42
38
|
<input data-property="weight" type="hidden" name="item[${index}][weight]" value="${data.weight}" />
|