Skip to content

Commit

Permalink
Merge pull request #2206 from samvera/i205-upload-collection-thumbnails
Browse files Browse the repository at this point in the history
🚧 i205 - add ability to upload collection thumbnails
  • Loading branch information
Shana Moore authored May 21, 2024
2 parents 1de2d9c + e4ac14b commit 7b10d06
Show file tree
Hide file tree
Showing 19 changed files with 520 additions and 32 deletions.
9 changes: 9 additions & 0 deletions app/assets/javascripts/hyrax/fileupload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//= require hyrax/uploader
// This file is the default initialization of the fileupload. If you want to call
// hyraxUploader with other options (like afterSubmit), then override this file.
Blacklight.onLoad(function() {
var options = {};
$('#fileupload').hyraxUploader(options);
$('#fileuploadlogo').hyraxUploader({downloadTemplateId: 'logo-template-download'});
$('#fileuploadthumbnail').hyraxUploader({downloadTemplateId: 'thumbnail-template-download'});
});
24 changes: 24 additions & 0 deletions app/assets/stylesheets/hyku.scss
Original file line number Diff line number Diff line change
Expand Up @@ -645,3 +645,27 @@ span.constraint-value p, .facet-values p {
tr[data-feature="use-iiif-print"] {
display: none;
}

// collection branding thumbnail
.branding-thumbnail-row {
border-top: solid 1px #dddddd;
padding-top: 10px;
}

.branding-thumbnail-input {
text-align: right;
width: 250px;

input {
text-align: left;
}
}

.branding-thumbnail-remove,
.branding-thumbnail-remove:hover {
background-color: #ffffff;
border-color: #ffffff;
color: $brand-danger;
font-weight: normal;
text-decoration: underline;
}
21 changes: 21 additions & 0 deletions app/controllers/concerns/hyku/collection_branding_behavior.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module Hyku
module CollectionBrandingBehavior
# This is used for saving the CollectionBrandingInfo files to 'public/uploads' directory.
#
# Originally, when `f.file_url` is called, there's a string sub that happens in
# CarrierWave that puts it into the 'uploads' dir instead. We want it in the 'public/uploads' dir instead
# @see https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/uploader/url.rb#L24
def process_file_location(f)
if /^http/.match?(f.file_url)
f.file.download!(f.file_url)
f.file_url
elsif %r{^\/}.match?(f.file_url)
f.file.path
else
f.file_url
end
end
end
end
68 changes: 40 additions & 28 deletions app/controllers/hyrax/dashboard/collections_controller_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,52 @@
# OVERRIDE Hyrax v5.0.0rc2
# - Fix file upload in logo and banner
# - Use work titles for collection thumbnail select & to add an option to reset to the default thumbnail

# OVERRIDE Hyrax v5.0.0 to add the ability to upload a collection thumbnail

module Hyrax
module Dashboard
## Shows a list of all collections to the admins
# rubocop:disable Metrics/ModuleLength
module CollectionsControllerDecorator
include Hyku::CollectionBrandingBehavior

def show
configure_show_sort_fields

super
end

private

def configure_show_sort_fields
# In the CollectionsControllerDecorator, we clear the sort fields and add our own to have
# the ability to sort the index with custom fields. However, this also affects the show page.
# Here we set the sort fields back to the defaults for the show page.
blacklight_config.sort_fields = CatalogController.blacklight_config.sort_fields
# OVERRIDE Hyrax v5.0.0 to add the ability to upload a collection thumbnail - START
def process_branding
process_banner_input
process_logo_input
process_thumbnail_input
end

public
# rubocop:disable Metrics/AbcSize
def update_valkyrie_collection
return after_update_errors(form_err_msg(form)) unless form.validate(collection_params)

result = transactions['change_set.update_collection']
.with_step_args(
'collection_resource.save_collection_banner' => { update_banner_file_ids: params["banner_files"],
banner_unchanged_indicator: params["banner_unchanged"] },
'collection_resource.save_collection_logo' => { update_logo_file_ids: params["logo_files"],
alttext_values: params["alttext"],
linkurl_values: params["linkurl"] },
'collection_resource.save_collection_thumbnail' => { update_thumbnail_file_ids: params["thumbnail_files"],
thumbnail_unchanged_indicator: params["thumbnail_unchanged"],
alttext_values: params["thumbnail_text"] }
)
.call(form)
@collection = result.value_or { return after_update_errors(result.failure.first) }

process_member_changes
after_update_response
end
# rubocop:enable Metrics/AbcSize
# OVERRIDE Hyrax v5.0.0 to add the ability to upload a collection thumbnail - END

def edit
form
Expand All @@ -47,13 +72,6 @@ def update
super
end

def process_branding
super

# TODO: does this still work?
process_uploaded_thumbnail(params[:collection][:thumbnail_upload]) if params[:collection][:thumbnail_upload]
end

# Deletes any previous thumbnails. The thumbnail indexer (see services/hyrax/indexes_thumbnails)
# checks if an uploaded thumbnail exists in the public folder before indexing the thumbnail path.
def delete_uploaded_thumbnail
Expand Down Expand Up @@ -99,6 +117,13 @@ def files

private

def configure_show_sort_fields
# In the CollectionsControllerDecorator, we clear the sort fields and add our own to have
# the ability to sort the index with custom fields. However, this also affects the show page.
# Here we set the sort fields back to the defaults for the show page.
blacklight_config.sort_fields = CatalogController.blacklight_config.sort_fields
end

# branding specific methods
def process_banner_input
return update_existing_banner if params["banner_unchanged"] == "true"
Expand Down Expand Up @@ -166,19 +191,6 @@ def process_uploaded_thumbnail(uploaded_file)
File.chmod(0o664, "#{dir_name}/#{@collection.id}_card.jpg")
end
# rubocop:enable Metrics/MethodLength

## OVERRIDE Hyrax v5.0.0rc2 handle file locations
def process_file_location(f)
if /^http/.match?(f.file_url)
f.file.download!(f.file_url)
f.file_url
elsif %r{^\/}.match?(f.file_url)
f.file.path
else
f.file_url
end
end
## END OVERRIDE
end
end
end
Expand Down
18 changes: 18 additions & 0 deletions app/forms/hyrax/forms/pcdm_collection_form_decorator.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
# frozen_string_literal: true
# OVERRIDE Hyraxv5.0.0 to add the ability to upload a collection thumbnail

Hyrax::Forms::PcdmCollectionForm.class_eval do
include Hyrax::FormFields(:basic_metadata)
include Hyrax::FormFields(:bulkrax_metadata)
include CollectionAccessFiltering

ThumbnailInfoPrepopulator = lambda do |_options = nil|
self.thumbnail_info ||= begin
thumbnail_info = CollectionBrandingInfo.where(collection_id: id.to_s, role: "thumbnail").first
if thumbnail_info
thumbnail_file = File.split(thumbnail_info.local_path).last
alttext = thumbnail_info.alt_text
file_location = thumbnail_info.local_path
relative_path = "/" + thumbnail_info.local_path.split("/")[-4..-1].join("/")
{ file: thumbnail_file, full_path: file_location, relative_path:, alttext: }
else
{} # Always return at least an empty hash
end
end
end

property :thumbnail_info, virtual: true, prepopulator: ThumbnailInfoPrepopulator
end
3 changes: 2 additions & 1 deletion app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ def group_navigation_presenter
@group_navigation_presenter ||= Hyku::Admin::Group::NavigationPresenter.new(params:)
end

def collection_thumbnail(_document, _image_options = {}, _url_options = {})
def collection_thumbnail(document, _image_options = {}, _url_options = {})
return image_tag(document['thumbnail_path_ss']) if document['thumbnail_path_ss'].present?
return super if Site.instance.default_collection_image.blank?

image_tag(Site.instance.default_collection_image&.url)
Expand Down
10 changes: 10 additions & 0 deletions app/presenters/hyrax/collection_presenter_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ def banner_file
end
end

def thumbnail_file
@thumbnail_file ||= CollectionBrandingInfo.where(collection_id: id, role: "thumbnail")
.select(:local_path, :alt_text, :target_url).map do |thumbnail|
{ alttext: thumbnail.alt_text,
file: File.split(thumbnail.local_path).last,
file_location: "/#{thumbnail.local_path.split('/')[-4..-1].join('/')}",
linkurl: thumbnail.target_url }
end
end

# Begin Featured Collections Methods
def collection_featurable?
user_can_feature_collection? && solr_document.public?
Expand Down
9 changes: 9 additions & 0 deletions app/services/hyrax/thumbnail_path_service_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

module Hyrax
module ThumbnailPathServiceDecorator
def call(object)
return super unless object.try(:collection?)

collection_thumbnail = CollectionBrandingInfo.where(collection_id: object.id.to_s, role: "thumbnail").first
return collection_thumbnail.local_path.gsub(Rails.public_path.to_s, '') if collection_thumbnail

default_image
end

def default_image
Site.instance.default_work_image&.url || super
end
Expand Down
77 changes: 77 additions & 0 deletions app/views/hyrax/dashboard/collections/_form_branding.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,81 @@
</div> <!-- end col-12 -->
</div> <!-- end row branding-logo-list -->
</div> <!-- end fileuploadlogo -->

<label><strong><%= t('.thumbnail.label') %></strong></label>
<p><%= t('.thumbnail.description') %></p>

<div id="fileuploadthumbnail">
<!-- Redirect browsers with JavaScript disabled to the origin page -->
<noscript><input type="hidden" name="redirect" value="<%= main_app.root_path %>" /></noscript>
<!-- The table listing the files available for upload/download -->

<!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
<div class="row fileupload-buttonbar">
<div class="col-4">
<!-- The fileinput-button span is used to style the file input field as button -->
<span class="btn btn-success fileinput-button">
<span class="fa fa-plus"></span>
<span><%= t('.choose_file') %></span>
<input type="file" name="files[]" single />
</span>
</div> <!-- end col-4 -->

<!-- The global progress state -->
<div class="col-8 fileupload-progress branding-thumbnail-progress fade">
<!-- The global progress bar -->
<div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar progress-bar-striped progress-bar-animated bg-success" style="width:0%;"></div>
</div>
<!-- The extended global progress state -->
<div class="progress-extended">&nbsp;</div>
</div> <!-- end col-8 fileupload-progress fade -->
</div> <!-- end row fileupload-buttonbar -->

<div class="row branding-thumbnail-list">
<div class="col-12">
<div class="container">
<%# Where the request to display the branding comes from. %>
<% if f.object.thumbnail_info[:file] %>
<div id="thumbnail">
<div class="row branding-thumbnail-row">
<div class="col-sm-3">
<span class="name">
<i><%= image_tag(f.object.thumbnail_info[:relative_path],
height: "36",
alt: f.object.thumbnail_info[:alttext].presence || f.object.thumbnail_info[:file]) %></i>
<span><%= f.object.thumbnail_info[:file] %></span>
<input type="hidden" name="thumbnail_unchanged" value="true" />
</span>
</div>
<div class="col-sm-4 branding-thumbnail-input">
<label for="thumbnail_text"><%= t('.alt_text') %>
<input id="thumbnail_text" class="branding-thumbnail-input" type="text" name="thumbnail_text[]" value="<%= f.object.thumbnail_info[:alttext] %>" />
</label>
</div>

<div class="col-sm-2">
<button class="btn btn-danger delete branding-thumbnail-remove" data-type="DELETE" data-url="/" onclick=$("#thumbnail").remove();>
<span class="fa fa-times"></span>
<span class="controls-remove-text"><%= t('.remove') %></span>
<span class="sr-only">
<%= t('.previous') %>
<span class="controls-field-name-text"><%= t('.remove_current_thumbnail') %></span>
</span>
</button>
</div> <!-- end col-sm-2 -->
</div> <!-- row branding-thumbnail-row -->
</div> <!-- end thumbnail -->
<div role="presentation" class="table table-striped"><span class="files"></span></div>
<% else %>
<div role="presentation" class="table table-striped"><span class="files"></span></div>
<% end %>

<!-- The global file processing state -->
<span class="fileupload-process"></span>
</div> <!-- end container -->
</div> <!-- end row branding-thumbnail-list -->
</div> <!-- end row branding-thumbnail-list -->
</div> <!-- fileuploadthumbnail -->

</div> <!-- end set-access-controls -->
2 changes: 1 addition & 1 deletion app/views/hyrax/my/collections/_list_collections.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<span class="<%= Hyrax::ModelIcon.css_class_for(::Collection) %> collection-icon-small"></span>
<% else %>
<%# OVERRIDE begin %>
<%= image_tag(collection_presenter.thumbnail_path, alt: block_for(name: 'default_collection_image_text') || "#{collection_presenter.title_or_label} #{t('hyrax.dashboard.my.sr.thumbnail')}") %>
<%= image_tag(collection_presenter.thumbnail_path, alt: collection_presenter.thumbnail_file.first&.[](:alttext) || block_for(name: 'default_collection_image_text') || "#{collection_presenter.title_or_label} #{t('hyrax.dashboard.my.sr.thumbnail')}") %>
<%# OVERRIDE end %>
<% end %>
</div>
Expand Down
37 changes: 37 additions & 0 deletions app/views/hyrax/uploads/_js_templates_branding.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,40 @@
</span>
{% } %}
</script>

<!-- The template to display thumbnail in the table once upload is complete -->
<script id="thumbnail-template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<span class="template-download fade show">
<div id="thumbnail">
<div class="row branding-thumbnail-row">
<div class="col-sm-3">
<span class="name">
<span>{%=file.name%}</span>
<input type="hidden" name="thumbnail_files[]" value="{%=file.id%}">
</span>
{% if (file.error) { %}
<span><span class="badge badge-danger"><%= t('.error') %></span> {%=file.error%}</span>
{% } %}
</div>

<div class="col-sm-4 branding-thumbnail-input">
<label for="thumbnail_text"><%= t('.alt_text') %></label>
<input id="thumbnail_text" type="text" name="thumbnail_text[]" class="form-control branding-thumbnail-input" single>
</div>

<div class="col-sm-2">
<button class="btn btn-link remove branding-thumbnail-remove" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}" onclick=$("#thumbnail").remove(); {% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
<span class="fa fa-times"></span>
<span class="controls-remove-text"><%= t('.remove') %></span>
<span class="sr-only">
<%= t('.previous') %>
<span class="controls-field-name-text"><%= t('.remove_new_thumbnail') %></span>
</span>
</button>
</div> <!-- end col-sm-2 -->
</div> <!-- row branding-thumbnail-row -->
</div> <!-- end container thumbnail -->
</span>
{% } $("div#thumbnail").remove(); %}
</script>
Loading

0 comments on commit 7b10d06

Please sign in to comment.