Merge pull request #4586 from consul/attach_with_keyboard
Allow attaching files using the keyboard
This commit is contained in:
@@ -57,7 +57,7 @@
|
||||
|
||||
<% if feature?(:allow_images) %>
|
||||
<div class="images small-12 column">
|
||||
<%= render "images/nested_image", imageable: @phase, f: f %>
|
||||
<%= render "images/nested_image", f: f %>
|
||||
<p class="help-text"><%= t("admin.budget_phases.edit.image_description") %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
<% if feature?(:allow_images) %>
|
||||
<div class="images small-12 column">
|
||||
<%= render "/images/nested_image", imageable: budget, f: f %>
|
||||
<%= render "/images/nested_image", f: f %>
|
||||
<p class="help-text"><%= t("admin.budgets.edit.image_description") %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
|
||||
<% if feature?(:allow_images) %>
|
||||
<div class="images">
|
||||
<%= render "images/nested_image", imageable: investment, f: f %>
|
||||
<%= render "images/nested_image", f: f %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if feature?(:allow_attached_documents) %>
|
||||
<div class="documents">
|
||||
<%= render "documents/nested_documents", documentable: investment, f: f %>
|
||||
<%= render "documents/nested_documents", f: f %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
28
app/components/documents/fields_component.html.erb
Normal file
28
app/components/documents/fields_component.html.erb
Normal file
@@ -0,0 +1,28 @@
|
||||
<div class="document direct-upload document-fields nested-fields">
|
||||
<%= f.hidden_field :id %>
|
||||
<%= f.hidden_field :user_id, value: current_user.id %>
|
||||
<%= f.hidden_field :cached_attachment %>
|
||||
|
||||
<div class="small-12 column title">
|
||||
<%= f.text_field :title, placeholder: t("documents.form.title_placeholder") %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column attachment-actions">
|
||||
<p class="file-name small-9 column"><%= file_name %></p>
|
||||
|
||||
<div class="small-9 column action-add attachment-errors document-attachment">
|
||||
<%= file_field %>
|
||||
</div>
|
||||
|
||||
<div class="small-3 column action-remove text-right">
|
||||
<%= destroy_link %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<div class="progress-bar-placeholder"><div class="loading-bar"></div></div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
</div>
|
||||
54
app/components/documents/fields_component.rb
Normal file
54
app/components/documents/fields_component.rb
Normal file
@@ -0,0 +1,54 @@
|
||||
class Documents::FieldsComponent < ApplicationComponent
|
||||
attr_reader :f
|
||||
delegate :current_user, to: :helpers
|
||||
|
||||
def initialize(f)
|
||||
@f = f
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def document
|
||||
f.object
|
||||
end
|
||||
|
||||
def file_name
|
||||
document.attachment_file_name
|
||||
end
|
||||
|
||||
def destroy_link
|
||||
if !document.persisted? && document.cached_attachment.present?
|
||||
link_to t("documents.form.delete_button"),
|
||||
direct_upload_destroy_path(
|
||||
"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 remove-cached-attachment"
|
||||
else
|
||||
link_to_remove_association document.new_record? ? t("documents.form.cancel_button") : t("documents.form.delete_button"), f, class: "delete remove-document"
|
||||
end
|
||||
end
|
||||
|
||||
def file_field
|
||||
klass = document.persisted? || document.cached_attachment.present? ? " hide" : ""
|
||||
f.file_field :attachment,
|
||||
label_options: { class: "button hollow #{klass}" },
|
||||
accept: accepted_content_types_extensions,
|
||||
class: "js-document-attachment",
|
||||
data: { url: direct_upload_path }
|
||||
end
|
||||
|
||||
def direct_upload_path
|
||||
direct_uploads_path("direct_upload[resource_type]": document.documentable_type,
|
||||
"direct_upload[resource_id]": document.documentable_id,
|
||||
"direct_upload[resource_relation]": "documents")
|
||||
end
|
||||
|
||||
def accepted_content_types_extensions
|
||||
Setting.accepted_content_types_for("documents").map { |content_type| ".#{content_type}" }.join(",")
|
||||
end
|
||||
end
|
||||
24
app/components/documents/nested_component.html.erb
Normal file
24
app/components/documents/nested_component.html.erb
Normal file
@@ -0,0 +1,24 @@
|
||||
<fieldset class="documents-list">
|
||||
<legend><%= t("documents.form.title") %></legend>
|
||||
<p class="help-text"><%= note %></p>
|
||||
|
||||
<div id="nested-documents" data-max-documents-allowed="<%= max_documents_allowed %>">
|
||||
<%= f.fields_for :documents do |documents_builder| %>
|
||||
<%= render Documents::FieldsComponent.new(documents_builder) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= link_to_add_association t("documents.form.add_new_document"), f, :documents,
|
||||
partial: "documents/document_fields",
|
||||
id: "new_document_link",
|
||||
class: "button upload-document
|
||||
#{"hide" if max_documents_allowed?}",
|
||||
data: {
|
||||
association_insertion_node: "#nested-documents",
|
||||
association_insertion_method: "append"
|
||||
} %>
|
||||
|
||||
<div id="max-documents-notice" class="max-documents-notice callout primary text-center <%= "hide" unless max_documents_allowed? %>">
|
||||
<%= sanitize(t("documents.max_documents_allowed_reached")) %>
|
||||
</div>
|
||||
</fieldset>
|
||||
28
app/components/documents/nested_component.rb
Normal file
28
app/components/documents/nested_component.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
class Documents::NestedComponent < ApplicationComponent
|
||||
attr_reader :f
|
||||
delegate :documentable_humanized_accepted_content_types, :max_file_size, to: :helpers
|
||||
|
||||
def initialize(f)
|
||||
@f = f
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def documentable
|
||||
f.object
|
||||
end
|
||||
|
||||
def max_documents_allowed
|
||||
documentable.class.max_documents_allowed
|
||||
end
|
||||
|
||||
def note
|
||||
t "documents.form.note", max_documents_allowed: max_documents_allowed,
|
||||
accepted_content_types: documentable_humanized_accepted_content_types(documentable.class),
|
||||
max_file_size: max_file_size(documentable.class)
|
||||
end
|
||||
|
||||
def max_documents_allowed?
|
||||
documentable.documents.count >= max_documents_allowed
|
||||
end
|
||||
end
|
||||
29
app/components/images/fields_component.html.erb
Normal file
29
app/components/images/fields_component.html.erb
Normal file
@@ -0,0 +1,29 @@
|
||||
<div class="image direct-upload nested-fields">
|
||||
<%= f.hidden_field :id %>
|
||||
<%= f.hidden_field :user_id, value: current_user.id %>
|
||||
<%= f.hidden_field :cached_attachment %>
|
||||
|
||||
<div class="small-12 margin-top title">
|
||||
<%= f.text_field :title, placeholder: t("images.form.title_placeholder") %>
|
||||
</div>
|
||||
|
||||
<%= render_image(image, :thumb, false) if image.attachment.exists? %>
|
||||
|
||||
<div class="small-12 column attachment-actions">
|
||||
<p class="file-name small-9 column"><%= file_name %></p>
|
||||
|
||||
<div class="small-9 column action-add attachment-errors image-attachment">
|
||||
<%= file_field %>
|
||||
</div>
|
||||
|
||||
<div class="small-3 column action-remove text-right">
|
||||
<%= destroy_link %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<div class="progress-bar-placeholder"><div class="loading-bar"></div></div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
</div>
|
||||
61
app/components/images/fields_component.rb
Normal file
61
app/components/images/fields_component.rb
Normal file
@@ -0,0 +1,61 @@
|
||||
class Images::FieldsComponent < ApplicationComponent
|
||||
attr_reader :f, :imageable
|
||||
delegate :current_user, :render_image, to: :helpers
|
||||
|
||||
def initialize(f, imageable:)
|
||||
@f = f
|
||||
@imageable = imageable
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def image
|
||||
f.object
|
||||
end
|
||||
|
||||
def file_name
|
||||
image.attachment_file_name
|
||||
end
|
||||
|
||||
def destroy_link
|
||||
if !image.persisted? && image.cached_attachment.present?
|
||||
link_to t("images.form.delete_button"),
|
||||
direct_upload_destroy_path(
|
||||
"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 remove-cached-attachment"
|
||||
else
|
||||
link_to_remove_association t("images.form.delete_button"), f, class: "delete remove-image"
|
||||
end
|
||||
end
|
||||
|
||||
def file_field
|
||||
klass = image.persisted? || image.cached_attachment.present? ? " hide" : ""
|
||||
f.file_field :attachment,
|
||||
label_options: { class: "button hollow #{klass}" },
|
||||
accept: accepted_content_types_extensions,
|
||||
class: "js-image-attachment",
|
||||
data: { url: direct_upload_path }
|
||||
end
|
||||
|
||||
def direct_upload_path
|
||||
direct_uploads_path("direct_upload[resource_type]": imageable.class.name,
|
||||
"direct_upload[resource_id]": imageable.id,
|
||||
"direct_upload[resource_relation]": "image")
|
||||
end
|
||||
|
||||
def accepted_content_types_extensions
|
||||
Setting.accepted_content_types_for("images").map do |content_type|
|
||||
if content_type == "jpg"
|
||||
".jpg,.jpeg"
|
||||
else
|
||||
".#{content_type}"
|
||||
end
|
||||
end.join(",")
|
||||
end
|
||||
end
|
||||
24
app/components/images/nested_component.html.erb
Normal file
24
app/components/images/nested_component.html.erb
Normal file
@@ -0,0 +1,24 @@
|
||||
<fieldset>
|
||||
<legend><%= t("images.form.title") %></legend>
|
||||
<p class="help-text"><%= note %></p>
|
||||
|
||||
<div id="nested-image">
|
||||
<%= f.fields_for image_fields do |image_builder| %>
|
||||
<%= render Images::FieldsComponent.new(image_builder, imageable: imageable) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= link_to_add_association t("images.form.add_new_image"), f, image_fields,
|
||||
force_non_association_create: true,
|
||||
partial: "images/image_fields",
|
||||
id: "new_image_link",
|
||||
class: "button upload-image
|
||||
#{"hide" if image_fields == :image && imageable.image.present?}",
|
||||
render_options: {
|
||||
locals: { imageable: imageable }
|
||||
},
|
||||
data: {
|
||||
association_insertion_node: "#nested-image",
|
||||
association_insertion_method: "append"
|
||||
} %>
|
||||
</fieldset>
|
||||
20
app/components/images/nested_component.rb
Normal file
20
app/components/images/nested_component.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
class Images::NestedComponent < ApplicationComponent
|
||||
attr_reader :f, :image_fields
|
||||
delegate :imageable_humanized_accepted_content_types, :imageable_max_file_size, to: :helpers
|
||||
|
||||
def initialize(f, image_fields: :image)
|
||||
@f = f
|
||||
@image_fields = image_fields
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def imageable
|
||||
f.object
|
||||
end
|
||||
|
||||
def note
|
||||
t "images.form.note", accepted_content_types: imageable_humanized_accepted_content_types,
|
||||
max_file_size: imageable_max_file_size
|
||||
end
|
||||
end
|
||||
@@ -39,13 +39,13 @@
|
||||
|
||||
<% if feature?(:allow_images) %>
|
||||
<div class="images">
|
||||
<%= render "images/nested_image", imageable: proposal, f: f %>
|
||||
<%= render "images/nested_image", f: f %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if feature?(:allow_attached_documents) %>
|
||||
<div class="documents">
|
||||
<%= render "documents/nested_documents", documentable: proposal, f: f %>
|
||||
<%= render "documents/nested_documents", f: f %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user