Extract ajax upload and destroy_upload actions from images and documents controllers and place them at new controllers to manage direct uploads
This commit is contained in:
@@ -64,6 +64,7 @@
|
||||
//= require flaggable
|
||||
//= require documentable
|
||||
//= require imageable
|
||||
//= require direct_uploads
|
||||
//= require tree_navigator
|
||||
//= require custom
|
||||
//= require tag_autocomplete
|
||||
|
||||
98
app/assets/javascripts/direct_uploads.js.coffee
Normal file
98
app/assets/javascripts/direct_uploads.js.coffee
Normal file
@@ -0,0 +1,98 @@
|
||||
App.DirectUploads =
|
||||
|
||||
progressBarTemplate: '<div class="progress-bar"><div class="loading-bar uploading"></div></div>'
|
||||
|
||||
buildData: (e, data) ->
|
||||
wrapper = $(e.target).closest('.direct-upload')
|
||||
data.wrapper = wrapper
|
||||
data.preview = $(wrapper).find('.image-preview')
|
||||
data.progressBar = $(wrapper).find('.progress-bar-placeholder').html(App.DirectUploads.progressBarTemplate)
|
||||
data.errorContainer = $(wrapper).find('.attachment-errors')
|
||||
data.fileNameContainer = $(wrapper).find('p.file-name')
|
||||
data.destroyAttachmentLinkContainer = $(wrapper).find('.action-remove')
|
||||
data.addAttachmentLabel = $(wrapper).find('.action-add label')
|
||||
data.cachedAttachmentField = $(wrapper).find("#" + $(e.target).data('cached-attachment-input-field'))
|
||||
data.titleField = $(wrapper).find("#" + $(e.target).data('title-input-field'))
|
||||
$(wrapper).find('.progress-bar-placeholder').css('display', 'block')
|
||||
return data
|
||||
|
||||
remove_cached_attachment: (e, data) ->
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
$.ajax
|
||||
type: "POST"
|
||||
url: e.target.href
|
||||
dataType: "json"
|
||||
data: {"_method":"delete"}
|
||||
complete: ->
|
||||
console.log data
|
||||
$(data.cachedAttachmentField).val("")
|
||||
$(data.addAttachmentLabel).show()
|
||||
$(data.destroyAttachmentLinkContainer).find('a.delete').remove()
|
||||
$(data.fileNameContainer).text('')
|
||||
$(data.fileNameContainer).hide()
|
||||
$(data.errorContainer).find('small.error').remove()
|
||||
$(data.progressBar).find('.loading-bar').removeClass('complete errors uploading').css('width', "0px").css('display', "none")
|
||||
$(data.wrapper).find(".image-preview").remove()
|
||||
$(data.preview).html('')
|
||||
|
||||
initialize: ->
|
||||
|
||||
$('.action-remove a.delete').on 'click', (e) ->
|
||||
data = App.DirectUploads.buildData(e, [])
|
||||
App.DirectUploads.remove_cached_attachment(e, data)
|
||||
$(data.wrapper).find('small.error').remove()
|
||||
$(data.wrapper).find('label.error').removeClass('error')
|
||||
|
||||
$('input.direct_upload_attachment[type=file]').fileupload
|
||||
|
||||
paramName: "attachment"
|
||||
|
||||
formData: null
|
||||
|
||||
add: (e, data) ->
|
||||
data = App.DirectUploads.buildData(e, data)
|
||||
data.submit()
|
||||
|
||||
change: (e, data) ->
|
||||
$.each data.files, (index, file) ->
|
||||
$(e.target).closest('.direct-upload').find('p.file-name').text(file.name)
|
||||
$(e.target).closest('.direct-upload').find('p.file-name').show()
|
||||
|
||||
fail: (e, data) ->
|
||||
$(data.cachedAttachmentField).val("")
|
||||
$(data.progressBar).find('.loading-bar').addClass('errors')
|
||||
$(data.errorContainer).find('small.error').remove()
|
||||
$(data.errorContainer).append('<small class="error">' + data.jqXHR.responseJSON.errors + '</small>')
|
||||
$(data.fileNameContainer).text('')
|
||||
$(data.fileNameContainer).hide()
|
||||
$(data.destroyAttachmentLinkContainer).find("a.delete").remove()
|
||||
$(data.addAttachmentLabel).show()
|
||||
$(data.wrapper).find(".image-preview").remove()
|
||||
|
||||
done: (e, data) ->
|
||||
$(data.cachedAttachmentField).val(data.result.cached_attachment)
|
||||
if $(data.titleField).val() == ""
|
||||
$(data.titleField).val(data.result.filename)
|
||||
$(data.progressBar).find('.loading-bar').addClass('complete')
|
||||
$(data.fileNameContainer).text(data.result.filename)
|
||||
$(data.fileNameContainer).show()
|
||||
$(data.errorContainer).find('small.error').remove()
|
||||
$(data.destroyAttachmentLinkContainer).html(data.result.destroy_link)
|
||||
data.destroyAttachmentLinkContainer = $(data.wrapper).find('.action-remove')
|
||||
$(data.addAttachmentLabel).hide()
|
||||
if data.result.is_image
|
||||
image = '<div class="small-12 column text-center image-preview"><figure><img src="' + data.result.attachment_url + '" class="cached-image"/></figure></div>'
|
||||
if $('.image-preview').length > 0
|
||||
$('.image-preview').replaceWith(image)
|
||||
else
|
||||
$(image).insertBefore($(data.wrapper).find(".attachment-actions"))
|
||||
|
||||
$(data.destroyAttachmentLinkContainer).on 'click', (e) ->
|
||||
App.DirectUploads.remove_cached_attachment(e, data)
|
||||
|
||||
|
||||
progress: (e, data) ->
|
||||
progress = parseInt(data.loaded / data.total * 100, 10)
|
||||
$(data.progressBar).find('.loading-bar').css 'width', progress + '%'
|
||||
return
|
||||
@@ -8,7 +8,7 @@ App.Documentable =
|
||||
|
||||
$('input.js-document-attachment[type=file]').fileupload
|
||||
|
||||
paramName: "document[attachment]"
|
||||
paramName: "direct_upload[attachment]"
|
||||
|
||||
formData: null
|
||||
|
||||
@@ -20,7 +20,7 @@ App.Documentable =
|
||||
data.progressBar = $(wrapper).find('.progress-bar-placeholder').html('<div class="progress-bar"><div class="loading-bar uploading"></div></div>')
|
||||
$(wrapper).find('.progress-bar-placeholder').css('display','block')
|
||||
data.formData = {
|
||||
"document[title]": $(wrapper).find('input.document-title').val() || data.files[0].name
|
||||
"direct_upload[title]": $(wrapper).find('inputdirect_upload-title').val() || data.files[0].name
|
||||
"index": index,
|
||||
"nested_document": is_nested_document
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
background-color: $light-gray;
|
||||
}
|
||||
|
||||
.js-document-attachment {
|
||||
.js-document-attachment,
|
||||
input.direct_upload_attachment[type=file] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
background-color: $light-gray;
|
||||
}
|
||||
|
||||
input.image_ajax_attachment[type=file]{
|
||||
input.image_ajax_attachment[type=file],
|
||||
input.direct_upload_attachment[type=file] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +1,53 @@
|
||||
class DirectUploadsController < ApplicationController
|
||||
include DirectUploadsHelper
|
||||
include ActionView::Helpers::UrlHelper
|
||||
before_action :authenticate_user!
|
||||
|
||||
def destroy_upload
|
||||
@document = Document.new(cached_attachment: params[:path])
|
||||
@document.set_attachment_from_cached_attachment
|
||||
@document.cached_attachment = nil
|
||||
@document.documentable = @documentable
|
||||
load_and_authorize_resource except: :create
|
||||
skip_authorization_check only: :create
|
||||
|
||||
if @document.attachment.destroy
|
||||
flash.now[:notice] = t "documents.actions.destroy.notice"
|
||||
helper_method :render_destroy_upload_link
|
||||
|
||||
# It should return cached attachment path or attachment errors
|
||||
def create
|
||||
@direct_upload = DirectUpload.new(direct_upload_params.merge(user: current_user, attachment: params[:attachment]))
|
||||
|
||||
if @direct_upload.valid?
|
||||
@direct_upload.save_attachment
|
||||
@direct_upload.relation.set_cached_attachment_from_attachment(URI(request.url))
|
||||
render json: { cached_attachment: @direct_upload.relation.cached_attachment,
|
||||
filename: @direct_upload.relation.attachment.original_filename,
|
||||
destroy_link: render_destroy_upload_link(@direct_upload).html_safe,
|
||||
attachment_url: @direct_upload.relation.attachment.url,
|
||||
is_image: Image::ACCEPTED_CONTENT_TYPE.include?(@direct_upload.relation.attachment_content_type)
|
||||
}
|
||||
else
|
||||
flash.now[:alert] = t "documents.actions.destroy.alert"
|
||||
@direct_upload.destroy_attachment
|
||||
render json: { errors: @direct_upload.errors[:attachment].join(", ") },
|
||||
status: 422
|
||||
end
|
||||
render :destroy
|
||||
end
|
||||
|
||||
def upload
|
||||
@document = Document.new(document_params.merge(user: current_user))
|
||||
@document.documentable = @documentable
|
||||
@document.valid?
|
||||
def destroy
|
||||
@direct_upload = DirectUpload.new(direct_upload_params.merge(user: current_user) )
|
||||
|
||||
if @document.valid?
|
||||
@document.attachment.save
|
||||
@document.set_cached_attachment_from_attachment(URI(request.url))
|
||||
@direct_upload.relation.set_attachment_from_cached_attachment
|
||||
|
||||
if @direct_upload.destroy_attachment
|
||||
render json: :ok
|
||||
else
|
||||
@document.attachment.destroy
|
||||
render json: :error
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def direct_upload_params
|
||||
params.require(:direct_upload)
|
||||
.permit(:resource, :resource_type, :resource_id, :resource_relation,
|
||||
:attachment, :cached_attachment, attachment_attributes: [])
|
||||
end
|
||||
|
||||
def set_attachment_container_resource
|
||||
@container_resource = params[:resource_type]
|
||||
end
|
||||
|
||||
15
app/helpers/direct_uploads_helper.rb
Normal file
15
app/helpers/direct_uploads_helper.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
module DirectUploadsHelper
|
||||
|
||||
def render_destroy_upload_link(direct_upload)
|
||||
link_to t('documents.form.delete_button'),
|
||||
direct_upload_destroy_url("direct_upload[resource_type]": direct_upload.resource_type,
|
||||
"direct_upload[resource_id]": direct_upload.resource_id,
|
||||
"direct_upload[resource_relation]": direct_upload.resource_relation,
|
||||
"direct_upload[cached_attachment]": direct_upload.relation.cached_attachment,
|
||||
format: :json),
|
||||
method: :delete,
|
||||
remote: true,
|
||||
class: "delete float-right"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,5 +1,10 @@
|
||||
module DocumentsHelper
|
||||
|
||||
def document_note(document)
|
||||
t "documents.new.#{document.documentable.class.name.parameterize.underscore}.note",
|
||||
title: document.documentable.title
|
||||
end
|
||||
|
||||
def document_attachment_file_name(document)
|
||||
document.attachment_file_name
|
||||
end
|
||||
|
||||
@@ -75,6 +75,7 @@ module Abilities
|
||||
|
||||
can [:create, :destroy], Document
|
||||
can [:create, :destroy], Image
|
||||
can [:create, :destroy], DirectUpload
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,6 +43,8 @@ module Abilities
|
||||
can [:create, :destroy, :new], Image, imageable: { author_id: user.id }
|
||||
can [:new_nested, :upload, :destroy_upload], Image
|
||||
|
||||
can [:create, :destroy], DirectUpload
|
||||
|
||||
unless user.organization?
|
||||
can :vote, Debate
|
||||
can :vote, Comment
|
||||
|
||||
@@ -1,27 +1,53 @@
|
||||
class DirectUpload
|
||||
include ActiveModel::Validations
|
||||
include ActiveModel::Conversion
|
||||
extend ActiveModel::Naming
|
||||
|
||||
attr_accessor :resource, :resource_type, :resource_id, :resource_relation,
|
||||
:attachment, :cached_attachment
|
||||
attr_accessor :resource, :resource_type, :resource_id,
|
||||
:relation, :resource_relation,
|
||||
:attachment, :cached_attachment, :user
|
||||
|
||||
validates_presence_of :attachment, :resource_type, :resource_relation
|
||||
validate :parent_resource_attachment_validations,
|
||||
if: -> { attachment.present? && resource_type.present? && resource_relation.present? }
|
||||
|
||||
def parent_resource_attachment_validations
|
||||
# Proposal or Budget::Investment
|
||||
resource = resource_type.constantize.find_or_initialize_by(id: resource_id)
|
||||
|
||||
# Document or Image
|
||||
relation = if resource.class.reflections[resource_relation].macro == :has_one
|
||||
resource.send("build_#{resource_relation}", attachment: attachment)
|
||||
else
|
||||
resource.send(resource_relation).build(attachment: attachment)
|
||||
def save_attachment
|
||||
@relation.attachment.save
|
||||
end
|
||||
relation.valid?
|
||||
|
||||
if relation.errors.has_key? :attachment
|
||||
errors[:attachment] = relation.errors[:attachment]
|
||||
def destroy_attachment
|
||||
@relation.attachment.destroy
|
||||
end
|
||||
|
||||
def persisted?
|
||||
false
|
||||
end
|
||||
|
||||
def initialize(attributes = {})
|
||||
attributes.each do |name, value|
|
||||
send("#{name}=", value)
|
||||
end
|
||||
|
||||
if @resource_type.present?
|
||||
@resource = @resource_type.constantize.find_or_initialize_by(id: @resource_id)
|
||||
end
|
||||
|
||||
if @resource.class.reflections[@resource_relation].macro == :has_one
|
||||
@relation = @resource.send("build_#{resource_relation}", attachment: @attachment, cached_attachment: @cached_attachment)
|
||||
else
|
||||
@relation = @resource.send(resource_relation).build(attachment: @attachment, cached_attachment: @cached_attachment)
|
||||
end
|
||||
|
||||
@relation.user = user
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parent_resource_attachment_validations
|
||||
@relation.valid?
|
||||
|
||||
if @relation.errors.has_key? :attachment
|
||||
errors[:attachment] = @relation.errors[:attachment]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
0
app/views/direct_uploads/_attachment.html.erb
Normal file
0
app/views/direct_uploads/_attachment.html.erb
Normal file
@@ -4,14 +4,57 @@
|
||||
documentable_id: @document.documentable_id,
|
||||
from: params[:from]
|
||||
),
|
||||
html: { multipart: true, class: "documentable"},
|
||||
data: { direct_upload_url: upload_documents_url(documentable_type: @document.documentable_type, documentable_id: @document.documentable_id) } do |f| %>
|
||||
html: { multipart: true, class: "documentable" } do |f| %>
|
||||
|
||||
<%= render 'shared/errors', resource: @document %>
|
||||
|
||||
<div class="row">
|
||||
<div class="row document direct-upload">
|
||||
|
||||
<%= render 'plain_fields', document: @document %>
|
||||
<%= f.hidden_field :cached_attachment %>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.text_field :title %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column actions">
|
||||
<div class="small-6 column action-add attachment-errors">
|
||||
<%= f.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %>
|
||||
<%= f.file_field :attachment,
|
||||
accept: accepted_content_types_extensions(@document.documentable.class),
|
||||
label: false,
|
||||
class: 'js-document-attachment',
|
||||
data: {
|
||||
url: direct_uploads_url("direct_upload[resource_type]": @document.documentable_type,
|
||||
"direct_upload[resource_id]": @document.documentable_id,
|
||||
"direct_upload[resource_relation]": "documents"),
|
||||
cached_attachment_input_field: "document_cached_attachment",
|
||||
title_input_field: "document_title"
|
||||
} %>
|
||||
|
||||
</div>
|
||||
<div class="small-6 column action-remove">
|
||||
<% if @document.cached_attachment.present? %>
|
||||
<%= link_to t('documents.form.delete_button'),
|
||||
direct_upload_destroy_url("direct_upload[resource_type]": @document.documentable_type,
|
||||
"direct_upload[resource_id]": @document.documentable_id,
|
||||
"direct_upload[resource_relation]": "documents",
|
||||
"direct_upload[cached_attachment]": @document.cached_attachment),
|
||||
method: :delete,
|
||||
remote: true,
|
||||
class: "delete float-right" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<p class="file-name">
|
||||
<%= document_attachment_file_name(@document) %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<div class="progress-bar-placeholder"><div class="loading-bar"></div></div>
|
||||
</div>
|
||||
|
||||
<div class="actions small-12 medium-6 large-4 end column">
|
||||
<%= f.submit(t("documents.form.submit_button"), class: "button expanded") %>
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
<div id="plain_document_fields" class="document">
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= label_tag :document_title, t("activerecord.attributes.document.title") %>
|
||||
<%= text_field_tag :document_title,
|
||||
document.errors.has_key?(:attachment) ? "" : document.title,
|
||||
name: "document[title]",
|
||||
class: "document-title" %>
|
||||
<% if document.errors.has_key?(:title) %>
|
||||
<small class="error"><%= document.errors[:title].join(", ") %></small>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= hidden_field_tag :cached_attachment, document.cached_attachment, name: "document[cached_attachment]" %>
|
||||
<%= file_field_tag :attachment,
|
||||
accept: accepted_content_types_extensions(document.documentable.class),
|
||||
label: false,
|
||||
class: 'js-document-attachment',
|
||||
data: {
|
||||
url: upload_documents_url(documentable_type: document.documentable_type, documentable_id: document.documentable_id),
|
||||
cached_attachment_input_field: "document_cached_attachment",
|
||||
multiple: false,
|
||||
nested_document: false
|
||||
},
|
||||
id: "document_attachment",
|
||||
name: "document[attachment]" %>
|
||||
|
||||
<% if document.cached_attachment.blank? %>
|
||||
<%= label_tag :document_attachment, t("documents.form.attachment_label"), class: 'button hollow' %>
|
||||
<% else %>
|
||||
<%= link_to t('documents.form.delete_button'),
|
||||
destroy_upload_documents_path(path: document.cached_attachment,
|
||||
nested_document: false,
|
||||
documentable_type: document.documentable_type,
|
||||
documentable_id: document.documentable_id),
|
||||
method: :delete,
|
||||
remote: true,
|
||||
class: "delete float-right" %>
|
||||
<% end %>
|
||||
|
||||
<% if document.errors.has_key?(:attachment) %>
|
||||
<div class="small-12 column source-option-file">
|
||||
<div class="attachment-errors">
|
||||
<small class="error"><%= document_errors_on_attachment(document) %></small>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<p class="file-name"><%= document_attachment_file_name(document) %></p>
|
||||
<div class="progress-bar-placeholder"><div class="loading-bar"></div></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -3,6 +3,7 @@
|
||||
<div class="small-12 medium-9 column">
|
||||
<%= back_link_to params[:from] %>
|
||||
<h1><%= t("documents.new.title") %></h1>
|
||||
<p><%= document_note(@document) %></p>
|
||||
<%= render "documents/form", form_url: documents_url %>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,17 +4,63 @@
|
||||
imageable_id: @image.imageable_id,
|
||||
from: params[:from]
|
||||
),
|
||||
html: { multipart: true, class: "imageable"},
|
||||
data: { direct_upload_url: upload_images_url(imageable_type: @image.imageable_type, imageable_id: @image.imageable_id) } do |f| %>
|
||||
html: { multipart: true, class: "imageable" } do |f| %>
|
||||
|
||||
<%= render 'shared/errors', resource: @image %>
|
||||
|
||||
<div class="row">
|
||||
<div class="row image direct-upload">
|
||||
|
||||
<%= render 'plain_fields', image: @image %>
|
||||
<%= f.hidden_field :cached_attachment %>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.text_field :title, placeholder: t("images.new.form.title_placeholder") %>
|
||||
</div>
|
||||
|
||||
<%= render_image(@image, :thumb, false) if @image.attachment.exists? %>
|
||||
|
||||
<div class="small-12 column attachment-actions">
|
||||
<div class="small-6 column action-add attachment-errors">
|
||||
<%= f.label :attachment, t("images.form.attachment_label"), class: 'button hollow' %>
|
||||
<%= f.file_field :attachment,
|
||||
accept: imageable_accepted_content_types_extensions,
|
||||
label: false,
|
||||
class: 'direct_upload_attachment',
|
||||
data: {
|
||||
url: direct_uploads_url("direct_upload[resource_type]": @image.imageable_type,
|
||||
"direct_upload[resource_id]": @image.imageable_id,
|
||||
"direct_upload[resource_relation]": "image"),
|
||||
cached_attachment_input_field: "image_cached_attachment",
|
||||
title_input_field: "image_title",
|
||||
multiple: false
|
||||
} %>
|
||||
</div>
|
||||
<div class="small-6 column action-remove">
|
||||
<% if @image.cached_attachment.present? %>
|
||||
<%= link_to t('images.form.delete_button'),
|
||||
direct_upload_destroy_url("direct_upload[resource_type]": @image.imageable_type,
|
||||
"direct_upload[resource_id]": @image.imageable_id,
|
||||
"direct_upload[resource_relation]": "image",
|
||||
"direct_upload[cached_attachment]": @image.cached_attachment),
|
||||
method: :delete,
|
||||
remote: true,
|
||||
class: "delete float-right" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<p class="file-name">
|
||||
<%= image_attachment_file_name(@image) %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<div class="progress-bar-placeholder"><div class="loading-bar"></div></div>
|
||||
</div>
|
||||
|
||||
<div class="actions small-12 medium-6 large-4 end column">
|
||||
<%= f.submit(t("images.form.submit_button"), class: "button expanded") %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<div class="row">
|
||||
<div class="small-12 column text-center">
|
||||
<div class="small-12 column text-center image-preview">
|
||||
<figure>
|
||||
<%= image_tag image.attachment.url(version),
|
||||
class: image_class(image),
|
||||
@@ -15,5 +14,4 @@
|
||||
<hr>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,52 +0,0 @@
|
||||
<div id="plain_image_fields" class="image">
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= label_tag :image_title, t("activerecord.attributes.image.title") %>
|
||||
<%= text_field_tag :image_title, image.title, placeholder: t("images.new.form.title_placeholder"), name: "image[title]", class: "image-title" %>
|
||||
<% if image.errors.has_key?(:title) %>
|
||||
<small class="error"><%= image.errors[:title].join(", ") %></small>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= render_image(image, :thumb, false) if image.attachment.exists? %>
|
||||
|
||||
<%= hidden_field_tag :cached_attachment, image.cached_attachment, name: "image[cached_attachment]" %>
|
||||
<%= file_field_tag :attachment,
|
||||
accept: imageable_accepted_content_types_extensions,
|
||||
label: false,
|
||||
class: 'image_ajax_attachment',
|
||||
data: {
|
||||
url: upload_images_url(imageable_type: image.imageable_type, imageable_id: image.imageable_id),
|
||||
cached_attachment_input_field: "image_cached_attachment",
|
||||
multiple: false,
|
||||
nested_image: false
|
||||
},
|
||||
id: "image_attachment",
|
||||
name: "image[attachment]" %>
|
||||
|
||||
<% if image.cached_attachment.blank? %>
|
||||
<%= label_tag :image_attachment, t("images.form.attachment_label"), class: 'button hollow' %>
|
||||
<% else %>
|
||||
<%= link_to t('images.form.delete_button'),
|
||||
destroy_upload_images_path(path: image.cached_attachment,
|
||||
nested_image: false,
|
||||
imageable_type: image.imageable_type,
|
||||
imageable_id: image.imageable_id),
|
||||
method: :delete,
|
||||
remote: true,
|
||||
class: "delete float-right" %>
|
||||
<% end %>
|
||||
|
||||
<% if image.errors.has_key?(:attachment) %>
|
||||
<div class="small-12 column source-option-file">
|
||||
<div class="attachment-errors">
|
||||
<small class="error"><%= image_errors_on_attachment(image) %></small>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<p class="file-name"><%= image_attachment_file_name(image) %></p>
|
||||
<div class="progress-bar-placeholder"><div class="loading-bar"></div></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -4,6 +4,7 @@ en:
|
||||
no_documents: Don't have uploaded documents
|
||||
upload_document: Upload document
|
||||
max_documents_allowed_reached_html: You have reached the maximum number of documents allowed! <strong>You have to delete one before you can upload another.</strong>
|
||||
|
||||
form:
|
||||
title: Documents
|
||||
attachment_label: Choose document
|
||||
@@ -11,8 +12,13 @@ en:
|
||||
delete_button: Remove document
|
||||
note: "You can upload up to a maximum of %{max_documents_allowed} documents of following content types: %{accepted_content_types}, up to %{max_file_size} MB per file."
|
||||
add_new_document: Add new document
|
||||
|
||||
new:
|
||||
title: Upload document
|
||||
budget_investment:
|
||||
note: 'Add new document to your investment project: %{title}'
|
||||
proposal:
|
||||
note: 'Add new document to your proposal: %{title}'
|
||||
recommendations_title: File upload tips
|
||||
recommendation_one_html: You can upload up to a <strong>maximum of %{max_documents_allowed} documents</strong>.
|
||||
recommendation_two_html: You can upload <strong>%{accepted_content_types}</strong> files.
|
||||
|
||||
@@ -4,6 +4,7 @@ es:
|
||||
no_documents: No hay documentos subidos
|
||||
upload_document: Subir documento
|
||||
max_documents_allowed_reached_html: ¡Has alcanzado el número máximo de documentos permitidos! <strong>Tienes que eliminar uno antes de poder subir otro.</strong>
|
||||
|
||||
form:
|
||||
title: Documentos
|
||||
attachment_label: Selecciona un documento
|
||||
@@ -11,12 +12,18 @@ es:
|
||||
delete_button: Eliminar documento
|
||||
note: "Puedes subir hasta un máximo de %{max_documents_allowed} documentos en los formatos: %{accepted_content_types}, y de hasta %{max_file_size} MB por archivo."
|
||||
add_new_document: Añadir nuevo documento
|
||||
|
||||
new:
|
||||
title: Subir un documento
|
||||
budget_investment:
|
||||
note: 'Añade un documento la propuesta de inversión: %{title}.'
|
||||
proposal:
|
||||
note: 'Añade un documento a la propuesta: %{title}.'
|
||||
recommendations_title: Consejos para subir archivos
|
||||
recommendation_one_html: Puedes subir hasta un máximo de <strong>%{max_documents_allowed} documentos</strong>
|
||||
recommendation_two_html: Sólo puedes subir <strong>archivos %{accepted_content_types}</strong>.
|
||||
recommendation_three_html: Puedes subir archivos de hasta <strong>%{max_file_size} MB</strong>
|
||||
|
||||
actions:
|
||||
create:
|
||||
notice: "El documento se ha creado correctamente."
|
||||
|
||||
@@ -181,6 +181,7 @@ es:
|
||||
signature_sheet: la hoja de firmas
|
||||
document: el documento
|
||||
topic: Tema
|
||||
image: Imagen
|
||||
geozones:
|
||||
none: Toda la ciudad
|
||||
all: Todos los ámbitos de actuación
|
||||
|
||||
@@ -101,21 +101,16 @@ Rails.application.routes.draw do
|
||||
resources :follows, only: [:create, :destroy]
|
||||
|
||||
resources :documents, only: [:new, :create, :destroy] do
|
||||
collection do
|
||||
get :new_nested
|
||||
delete :destroy_upload
|
||||
post :upload
|
||||
end
|
||||
get :new_nested, on: :collection
|
||||
end
|
||||
|
||||
resources :images, only: [:new, :create, :destroy] do
|
||||
collection do
|
||||
get :new_nested
|
||||
delete :destroy_upload
|
||||
post :upload
|
||||
end
|
||||
get :new_nested, on: :collection
|
||||
end
|
||||
|
||||
resources :direct_uploads, only: [:create]
|
||||
delete "direct_uploads/destroy", to: "direct_uploads#destroy", as: :direct_upload_destroy
|
||||
|
||||
resources :stats, only: [:index]
|
||||
|
||||
resources :legacy_legislations, only: [:show], path: 'legislations'
|
||||
|
||||
@@ -474,7 +474,7 @@ feature 'Budget Investments' do
|
||||
"Create Investment",
|
||||
"Budget Investment created successfully."
|
||||
|
||||
it_behaves_like "documentable", "budget_investment", "budget_investment_path", {"budget_id": "budget_id", "id": "id"}
|
||||
it_behaves_like "documentable", "budget_investment", "budget_investment_path", { "budget_id": "budget_id", "id": "id" }
|
||||
|
||||
it_behaves_like "nested documentable",
|
||||
"budget_investment",
|
||||
|
||||
@@ -213,14 +213,24 @@ shared_examples "documentable" do |documentable_factory_name, documentable_path,
|
||||
expect(page).to have_selector ".loading-bar.errors"
|
||||
end
|
||||
|
||||
scenario "Should update document title with attachment original file name after file selection if no title defined by user", :js do
|
||||
scenario "Should update document title with attachment original file name after valid upload if no title defined by user", :js do
|
||||
login_as documentable.author
|
||||
visit new_document_path(documentable_type: documentable.class.name,
|
||||
documentable_id: documentable.id)
|
||||
|
||||
attach_document("spec/fixtures/files/empty.pdf", true)
|
||||
|
||||
expect(page).to have_css("input[name='document[title]'][value='empty.pdf']")
|
||||
expect(find("input#document_title").value).to eq("empty.pdf")
|
||||
end
|
||||
|
||||
scenario "Should update document title with attachment original file name after invalid upload if no title defined by user", :js do
|
||||
login_as documentable.author
|
||||
visit new_document_path(documentable_type: documentable.class.name,
|
||||
documentable_id: documentable.id)
|
||||
|
||||
attach_document("spec/fixtures/files/logo_header.png", false)
|
||||
|
||||
expect(find("input#document_title").value).to be_empty
|
||||
end
|
||||
|
||||
scenario "Should not update document title with attachment original file name after file selection when title already defined by user", :js do
|
||||
@@ -429,8 +439,8 @@ end
|
||||
def attach_document(path, success = true)
|
||||
attach_file :document_attachment, path, make_visible: true
|
||||
if success
|
||||
have_css ".loading-bar.complete"
|
||||
expect(page).to have_css ".loading-bar.complete"
|
||||
else
|
||||
have_css ".loading-bar.errors"
|
||||
expect(page).to have_css ".loading-bar.errors"
|
||||
end
|
||||
end
|
||||
@@ -127,7 +127,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
|
||||
visit new_image_path(imageable_type: imageable.class.name,
|
||||
imageable_id: imageable.id)
|
||||
|
||||
attach_file :image_attachment, "spec/fixtures/files/logo_header.png", make_visible: true
|
||||
attach_image("spec/fixtures/files/logo_header.png", false)
|
||||
|
||||
expect(page).to have_css "small.error"
|
||||
end
|
||||
@@ -147,9 +147,8 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
|
||||
visit new_image_path(imageable_type: imageable.class.name,
|
||||
imageable_id: imageable.id)
|
||||
|
||||
attach_file :image_attachment, "spec/fixtures/files/clippy.png", make_visible: true
|
||||
attach_image("spec/fixtures/files/logo_header.png", false)
|
||||
|
||||
expect(page).to have_css ".loading-bar.errors"
|
||||
expect(page).not_to have_content "clippy.png"
|
||||
end
|
||||
|
||||
@@ -158,7 +157,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
|
||||
visit new_image_path(imageable_type: imageable.class.name,
|
||||
imageable_id: imageable.id)
|
||||
|
||||
attach_file :image_attachment, "spec/fixtures/files/clippy.jpg", make_visible: true
|
||||
attach_image("spec/fixtures/files/clippy.jpg", true)
|
||||
|
||||
expect(page).to have_css("figure img")
|
||||
expect(page).not_to have_css("figure figcaption")
|
||||
@@ -169,7 +168,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
|
||||
visit new_image_path(imageable_type: imageable.class.name,
|
||||
imageable_id: imageable.id)
|
||||
|
||||
attach_file :image_attachment, "spec/fixtures/files/clippy.jpg", make_visible: true
|
||||
attach_image("spec/fixtures/files/clippy.jpg", true)
|
||||
|
||||
expect(page).to have_selector ".loading-bar.complete"
|
||||
end
|
||||
@@ -179,7 +178,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
|
||||
visit new_image_path(imageable_type: imageable.class.name,
|
||||
imageable_id: imageable.id)
|
||||
|
||||
attach_file :image_attachment, "spec/fixtures/files/logo_header.png", make_visible: true
|
||||
attach_image("spec/fixtures/files/logo_header.png", false)
|
||||
|
||||
expect(page).to have_selector ".loading-bar.errors"
|
||||
end
|
||||
@@ -189,9 +188,9 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
|
||||
visit new_image_path(imageable_type: imageable.class.name,
|
||||
imageable_id: imageable.id)
|
||||
|
||||
attach_file :image_attachment, "spec/fixtures/files/clippy.jpg", make_visible: true
|
||||
attach_image("spec/fixtures/files/clippy.jpg")
|
||||
|
||||
expect(page).to have_css("input[name='image[title]'][value='clippy.jpg']", visible: false)
|
||||
expect(find('input#image_title').value).to eq('clippy.jpg')
|
||||
end
|
||||
|
||||
scenario "Should not update image title with attachment original file name after valid image upload when title already defined by user", :js do
|
||||
@@ -200,10 +199,9 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
|
||||
imageable_id: imageable.id)
|
||||
|
||||
fill_in :image_title, with: "My custom title"
|
||||
attach_file :image_attachment, "spec/fixtures/files/clippy.jpg", make_visible: true
|
||||
attach_image("spec/fixtures/files/clippy.jpg")
|
||||
|
||||
expect(page).to have_selector ".loading-bar.complete"
|
||||
expect(page).to have_css("input[name='image[title]'][value='My custom title']", visible: false)
|
||||
expect(find('input#image_title').value).to eq('My custom title')
|
||||
end
|
||||
|
||||
scenario "Should update image cached_attachment field after valid file upload", :js do
|
||||
@@ -211,7 +209,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
|
||||
visit new_image_path(imageable_type: imageable.class.name,
|
||||
imageable_id: imageable.id)
|
||||
|
||||
attach_file :image_attachment, "spec/fixtures/files/clippy.jpg", make_visible: true
|
||||
attach_image("spec/fixtures/files/clippy.jpg", true)
|
||||
|
||||
expect(page).to have_css("input[name='image[cached_attachment]'][value$='clippy.jpg']", visible: false)
|
||||
end
|
||||
@@ -221,7 +219,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
|
||||
visit new_image_path(imageable_type: imageable.class.name,
|
||||
imageable_id: imageable.id)
|
||||
|
||||
attach_file :image_attachment, "spec/fixtures/files/logo_header.png", make_visible: true
|
||||
attach_image("spec/fixtures/files/logo_header.png", false)
|
||||
|
||||
expect(page).to have_selector ".loading-bar.errors"
|
||||
expect(find("input[name='image[cached_attachment]']", visible: false).value).to eq("")
|
||||
@@ -342,3 +340,12 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def attach_image(path, success = true)
|
||||
attach_file :image_attachment, path, make_visible: true
|
||||
if success
|
||||
expect(page).to have_css ".loading-bar.complete"
|
||||
else
|
||||
expect(page).to have_css ".loading-bar.errors"
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user