diff --git a/app/assets/javascripts/documentable.js.coffee b/app/assets/javascripts/documentable.js.coffee index ba4154266..b4c9139f9 100644 --- a/app/assets/javascripts/documentable.js.coffee +++ b/app/assets/javascripts/documentable.js.coffee @@ -1,17 +1,26 @@ App.Documentable = initialize: -> + @initializeDirectUploads() + @initializeInterface() + + initializeDirectUploads: -> $('input.document_ajax_attachment[type=file]').fileupload - paramName : "document[attachment]" + paramName: "document[attachment]" formData: null add: (e, data) -> wrapper = $(e.target).parent() + index = $(e.target).data('index') $(wrapper).find('.progress-bar-placeholder').empty() data.progressBar = $(wrapper).find('.progress-bar-placeholder').html('
') + data.formData = { + "document[title]": $(wrapper).find('input.document-title').val() || data.files[0].name + "index": index + } data.submit() change: (e, data) -> @@ -25,15 +34,51 @@ App.Documentable = $(data.progressBar).find('.loading-bar').css 'width', progress + '%' return - done: (e, data) -> - result = data.response().result - if result.status == 200 - $(data.progressBar).find('.loading-bar').removeClass 'uploading' - $(data.progressBar).find('.loading-bar').addClass 'complete' - inputId = '#' + $(e.target).data('cached-attachment-input-field') - $(inputId).val result.attachment - else - $(data.progressBar).find('.loading-bar').addClass 'errors' - $(data.progressBar).prepend("" + result.msg + "") - return + initializeInterface: -> + input_files = $('input.document_ajax_attachment[type=file]') + $.each input_files, (index, file) -> + wrapper = $(file).parent() + App.Documentable.watchRemoveDocumentbutton(wrapper) + + watchRemoveDocumentbutton: (wrapper) -> + remove_document_button = $(wrapper).find('.remove-document') + $(remove_document_button).on 'click', (e) -> + e.preventDefault() + $(wrapper).remove() + $('#new_document_link').show() + $('.max-documents-notice').hide() + + upload: (id, nested_document, result) -> + $('#' + id).replaceWith(nested_document) + if result + $('#' + id).find('.loading-bar').addClass 'complete' + else + $('#' + id).find('.loading-bar').addClass 'errors' + @initialize() + + new: (nested_fields) -> + $(".documents-list").append(nested_fields) + @initialize() + + destroy: (id, notice) -> + $('#' + id).remove() + @updateNotice(notice) + + updateNotice: (notice) -> + if $('[data-alert]').length > 0 + $('[data-alert]').replaceWith(notice) + else + $("body").append(notice) + + updateNewDocumentButton: (link) -> + if $('.document').length >= $('.documents').data('max-documents') + $('#new_document_link').hide() + $('.max-documents-notice').removeClass('hide') + $('.max-documents-notice').show() + else if $('#new_document_link').length > 0 + $('#new_document_link').replaceWith(link) + $('.max-documents-notice').hide() + else + $('.max-documents-notice').hide() + $(link).insertBefore('.documents hr:last') diff --git a/app/assets/javascripts/forms.js.coffee b/app/assets/javascripts/forms.js.coffee index 1c4cee919..4750c1172 100644 --- a/app/assets/javascripts/forms.js.coffee +++ b/app/assets/javascripts/forms.js.coffee @@ -28,7 +28,7 @@ App.Forms = i = 0 while i < element.length element[i].addEventListener 'change', -> - $(element).parent().find('.file-name').text(@files[0].name) + $(element).parent().find('.file-name').text(@files[i].name) return i++ diff --git a/app/assets/stylesheets/documentable.scss b/app/assets/stylesheets/documentable.scss index 9015409b0..5efcd1c24 100644 --- a/app/assets/stylesheets/documentable.scss +++ b/app/assets/stylesheets/documentable.scss @@ -18,9 +18,11 @@ } &.complete{ background-color: #0f0; + width: 100%; } &.errors{ background-color: #f00; + width: 100%; } } diff --git a/app/controllers/concerns/commentable_actions.rb b/app/controllers/concerns/commentable_actions.rb index cdd2da4ae..e1e153495 100644 --- a/app/controllers/concerns/commentable_actions.rb +++ b/app/controllers/concerns/commentable_actions.rb @@ -28,7 +28,6 @@ module CommentableActions def new @resource = resource_model.new - prepare_new_resource_documents(@resource) set_geozone set_resource_instance end @@ -55,12 +54,12 @@ module CommentableActions end def edit - prepare_edit_resource_documents(resource) end def update resource.assign_attributes(strong_params) - parse_documents(resource) + recover_documents_from_cache(resource) + if resource.save redirect_to resource, notice: t("flash.actions.update.#{resource_name.underscore}") else @@ -113,28 +112,12 @@ module CommentableActions nil end - def prepare_new_resource_documents(resource) + def recover_documents_from_cache(resource) return false unless resource.try(:documents) - (1..resource.class.max_documents_allowed).each do - resource.documents.build - end - end - - def prepare_edit_resource_documents(resource) - return false unless resource.try(:documents) - (resource.documents.size + 1 .. resource.class.max_documents_allowed).each do - resource.documents.build - end - resource - end - - def parse_documents(resource) - return false unless resource.try(:documents) - resource.documents.each do |document| - document.user = current_user - end resource.documents = resource.documents.each do |document| - document.attachment = File.open(document.cached_attachment) if document.cached_attachment.present? + if document.cached_attachment.present? && File.exists?(document.cached_attachment) + document.attachment = File.open(document.cached_attachment) + end end end diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb index 2558b3310..bfafb2a34 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -1,6 +1,6 @@ class DocumentsController < ApplicationController before_action :authenticate_user! - before_filter :find_documentable, except: :destroy + before_filter :find_documentable, except: [:destroy] before_filter :prepare_new_document, only: :new before_filter :prepare_document_for_creation, only: :create @@ -22,37 +22,61 @@ class DocumentsController < ApplicationController end def destroy - if @document.destroy - flash[:notice] = t "documents.actions.destroy.notice" - else - flash[:alert] = t "documents.actions.destroy.alert" + respond_to do |format| + format.html do + if @document.destroy + flash[:notice] = t "documents.actions.destroy.notice" + else + flash[:alert] = t "documents.actions.destroy.alert" + end + redirect_to params[:from] + end + format.js do + if @document.destroy + flash.now[:notice] = t "documents.actions.destroy.notice" + else + flash.now[:alert] = t "documents.actions.destroy.alert" + end + end end - redirect_to params[:from] + end + + def destroy_upload + @document = Document.new(attachment: File.open(params[:path])) + @document.documentable = @documentable + + if @document.attachment.destroy + flash.now[:notice] = t "documents.actions.destroy.notice" + else + flash.now[:alert] = t "documents.actions.destroy.alert" + end + render:destroy end def upload - attachment = params[:document][:attachment] - document = Document.new(documentable: @documentable, attachment: attachment.tempfile, title: "faketitle", user: current_user ) - # We only are intested in attachment validators. We set some fake data to get attachment errors only - document.valid? - if document.errors[:attachment].empty? - # Move image from tmp to cache - msg = { status: 200, attachment: attachment.tempfile.path } + @document = Document.new(document_params.merge(user: current_user)) + @document.documentable = @documentable + if @document.valid? + @document.attachment.save + @document.cached_attachment = @document.attachment.path else - attachment.tempfile.delete - msg = { status: 422, msg: document.errors[:attachment].join(', ') } + @document.attachment.destroy end - render :json => msg end private + def document_params + params.require(:document).permit(:title, :documentable_type, :documentable_id, + :attachment, :cached_attachment, :user_id) + end + def find_documentable @documentable = params[:documentable_type].constantize.find_or_initialize_by(id: params[:documentable_id]) end def prepare_new_document - @document = Document.new(documentable: @documentable, user_id: @documentable.author_id) + @document = Document.new(documentable: @documentable, user_id: current_user.id) end def prepare_document_for_creation @@ -61,11 +85,6 @@ class DocumentsController < ApplicationController @document.user = current_user end - def document_params - params.require(:document).permit(:title, :documentable_type, :documentable_id, - :attachment, :cached_attachment) - end - def recover_attachment_from_cache if @document.attachment.blank? && @document.cached_attachment.present? @document.attachment = File.open(@document.cached_attachment) diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index 5a40d955b..cedc4e8ef 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -25,12 +25,11 @@ class ProposalsController < ApplicationController def create @proposal = Proposal.new(proposal_params.merge(author: current_user)) - parse_documents(@proposal) + recover_documents_from_cache(@proposal) if @proposal.save redirect_to share_proposal_path(@proposal), notice: I18n.t('flash.actions.create.proposal') else - @proposal = prepare_edit_resource_documents(@proposal) render :new end end @@ -79,7 +78,7 @@ class ProposalsController < ApplicationController def proposal_params params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url, :responsible_name, :tag_list, :terms_of_service, :geozone_id, - documents_attributes: [:id, :title, :attachment, :cached_attachment ] ) + documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id] ) end def retired_params diff --git a/app/helpers/documentables_helper.rb b/app/helpers/documentables_helper.rb index c6804f20a..90b185152 100644 --- a/app/helpers/documentables_helper.rb +++ b/app/helpers/documentables_helper.rb @@ -16,8 +16,8 @@ module DocumentablesHelper documentable.class.accepted_content_types end - def accepted_content_types_extensions(documentable) - documentable.class.accepted_content_types + def accepted_content_types_extensions(documentable_class) + documentable_class.accepted_content_types .collect{ |content_type| ".#{content_type.split("/").last}" } .join(",") end @@ -28,4 +28,10 @@ module DocumentablesHelper .join(", ") end + def documentables_note(documentable) + t "documents.form.note", max_documents_allowed: max_documents_allowed(documentable), + accepted_content_types: humanized_accepted_content_types(documentable), + max_file_size: max_file_size(documentable) + end + end \ No newline at end of file diff --git a/app/helpers/documents_helper.rb b/app/helpers/documents_helper.rb index 60c486d52..ec2541aaa 100644 --- a/app/helpers/documents_helper.rb +++ b/app/helpers/documents_helper.rb @@ -1,7 +1,7 @@ module DocumentsHelper def document_attachment_file_name(document) - document.attachment_file_name if document.attachment.exists? + document.attachment_file_name end def errors_on_attachment(document) @@ -22,4 +22,18 @@ module DocumentsHelper bytes / Numeric::MEGABYTE end + def document_nested_field_name(document, index, field) + parent = document.documentable_type.constantize.name.downcase + "#{parent}[documents_attributes][#{index}][#{field}]" + end + + def document_nested_field_id(document, index, field) + parent = document.documentable_type.constantize.name.downcase + "#{parent}_documents_attributes_#{index}_#{field}" + end + + def document_nested_field_wrapper_id(index) + "document_#{index}" + end + end diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index 4eb202332..34ee06f23 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -37,6 +37,7 @@ module Abilities can [:create, :destroy], Follow can [:create, :destroy], Document, documentable: { author_id: user.id } + can [:new, :destroy_upload], Document unless user.organization? can :vote, Debate diff --git a/app/models/document.rb b/app/models/document.rb index abe9c6643..0aafcfecc 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -16,7 +16,7 @@ class Document < ActiveRecord::Base validate :validate_attachment_content_type, if: -> { attachment.present? } validate :validate_attachment_size, if: -> { attachment.present? } validates :title, presence: true - validates :user, presence: true + validates :user_id, presence: true # validates :documentable_id, presence: true # validates :documentable_type, presence: true diff --git a/app/views/documents/_document.html.erb b/app/views/documents/_document.html.erb index f9f3b3d9e..c4ead4c65 100644 --- a/app/views/documents/_document.html.erb +++ b/app/views/documents/_document.html.erb @@ -13,7 +13,7 @@ <% if can? :destroy, Document %> <%= link_to t('documents.buttons.destroy_document'), document_path(document, from: request.url), method: :delete, - data: { confirm: t('documents.actions.destroy.alert') }, + data: { confirm: t('documents.actions.destroy.confirm') }, class: 'button hollow alert' %> <% end %> diff --git a/app/views/documents/_form.html.erb b/app/views/documents/_form.html.erb index 2e648a3da..f4dd49ded 100644 --- a/app/views/documents/_form.html.erb +++ b/app/views/documents/_form.html.erb @@ -18,7 +18,7 @@<%= document_attachment_file_name(document) %>
+<%= documentables_note(resource) %>
+ + <% resource.documents.each_with_index do |document, index| %> + <%= render 'documents/nested_document', document: document, index: index, resource: resource %> + <% end %> +Aquí puedes añadir hasta 3 doucmentos en formato PDF
-<% documents.each_with_index do |document, index| %> -<%= document_attachment_file_name(document) %>
- <% if document.errors[:attachment].any? %> -<%= t("proposals.form.proposal_video_url_note") %>
@@ -47,8 +46,8 @@ <%= f.text_field :external_url, placeholder: t("proposals.form.proposal_external_url"), label: false %>