module Plutonium module SimpleForm module AttachmentComponent def attachment(_wrapper_options = nil) maybe_setup_direct_uploads template.content_tag :div, class: "attachment-input-previews" do # This is a hack to support the removal of has_one_attached attachments # Usually, no hidden field is inserted for these # By inserting one, with a value of nil, when the form is submitted, # the autogenerated setter will remove the attachment for us. template.concat @builder.hidden_field(attribute_name, value: nil, multiple: multiple?) next if value.nil? template.concat begin template.display_attachment_value value, identity_class: input_class, caption: caption? do |attachment| [ # These hidden fields allow us to preserve the already uploaded files. # For has_one_attached, it overrides the hidden field previously added # (if the same input exists, the more recent one wins) # # For has_many_attached, the generated setter replaces all the existing files when the form is submitted # By adding hidden fields for the existing files, it allows us to append the new files @builder.hidden_field(attribute_name, multiple: multiple?, value: attachment.signed_id), # By removing this component, the hidden field is gone, which allows us to remove the files from active storage template.content_tag(:p, class: "text-danger m-0", role: :button, data: {action: "click->attachment-preview#remove"}) do template.content_tag :span, " Delete", class: "bi bi-trash" end ] end end end end private def value @value ||= object.send(attribute_name) if object&.respond_to?(attribute_name) end def multiple? options[:input_html] && options[:input_html][:multiple] end def caption? options.key?(:caption) ? options[:caption] : true end def maybe_setup_direct_uploads return unless options[:direct_upload] direct_upload_options = { data: { controller: :"attachment-input", attachment_input_identifier_value: input_class, attachment_input_attachment_preview_outlet: ".#{input_class}.attachment-preview", attachment_input_attachment_preview_container_outlet: ".#{input_class}.attachment-preview-container" } } { max_file_size: nil, min_file_size: nil, max_total_size: nil, max_file_num: multiple? ? nil : 1, min_file_num: nil, allowed_file_types: nil, required_meta_fields: nil }.each do |key, default_value| value = options.key?(key) ? options.delete(key) : default_value direct_upload_options[:data][:"attachment_input_#{key}_value"] = value end input_html_options.merge! direct_upload_options end end end end # Register with simple_form SimpleForm.include_component(Plutonium::SimpleForm::AttachmentComponent)