Skip to content

Commit

Permalink
Merge pull request #4586 from consul/attach_with_keyboard
Browse files Browse the repository at this point in the history
Allow attaching files using the keyboard
  • Loading branch information
javierm committed Jul 14, 2021
2 parents a3324ca + cc6f939 commit b3104fa
Show file tree
Hide file tree
Showing 40 changed files with 324 additions and 450 deletions.
52 changes: 5 additions & 47 deletions app/assets/javascripts/documentable.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
App.Documentable.lockUploads();
}
});
App.Documentable.initializeRemoveCachedDocumentLinks();
},
initializeDirectUploadInput: function(input) {
var inputData;
inputData = this.buildData([], input);
this.initializeRemoveCachedDocumentLink(input, inputData);
$(input).fileupload({
paramName: "attachment",
formData: null,
Expand All @@ -45,7 +45,6 @@
App.Documentable.setInputErrors(data);
$(data.destroyAttachmentLinkContainer).find("a.delete:not(.remove-nested)").remove();
$(data.addAttachmentLabel).addClass("error");
$(data.addAttachmentLabel).show();
},
done: function(e, data) {
var destroyAttachmentLink;
Expand All @@ -54,16 +53,8 @@
App.Documentable.setProgressBar(data, "complete");
App.Documentable.setFilename(data, data.result.filename);
App.Documentable.clearInputErrors(data);
$(data.addAttachmentLabel).hide();
$(data.wrapper).find(".attachment-actions").removeClass("small-12").addClass("small-6 float-right");
$(data.wrapper).find(".attachment-actions .action-remove").removeClass("small-3").addClass("small-12");
destroyAttachmentLink = $(data.result.destroy_link);
$(data.destroyAttachmentLinkContainer).html(destroyAttachmentLink);
$(destroyAttachmentLink).on("click", function(event) {
event.preventDefault();
event.stopPropagation();
App.Documentable.doDeleteCachedAttachmentRequest(this.href, data);
});
if (input.lockUpload) {
App.Documentable.showNotice();
}
Expand All @@ -78,8 +69,6 @@
buildData: function(data, input) {
var wrapper;
wrapper = $(input).closest(".direct-upload");
data.input = input;
data.wrapper = wrapper;
data.progressBar = $(wrapper).find(".progress-bar-placeholder");
data.errorContainer = $(wrapper).find(".attachment-errors");
data.fileNameContainer = $(wrapper).find("p.file-name");
Expand All @@ -92,7 +81,6 @@
},
clearFilename: function(data) {
$(data.fileNameContainer).text("");
$(data.fileNameContainer).hide();
},
clearInputErrors: function(data) {
$(data.errorContainer).find("small.error").remove();
Expand All @@ -102,7 +90,6 @@
},
setFilename: function(data, file_name) {
$(data.fileNameContainer).text(file_name);
$(data.fileNameContainer).show();
},
setProgressBar: function(data, klass) {
$(data.progressBar).find(".loading-bar").addClass(klass);
Expand All @@ -127,39 +114,10 @@
showNotice: function() {
$("#max-documents-notice").removeClass("hide");
},
doDeleteCachedAttachmentRequest: function(url, data) {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {
"_method": "delete"
},
complete: function() {
$(data.cachedAttachmentField).val("");
$(data.addAttachmentLabel).show();
App.Documentable.clearFilename(data);
App.Documentable.clearInputErrors(data);
App.Documentable.clearProgressBar(data);
App.Documentable.unlockUploads();
$(data.wrapper).find(".attachment-actions").addClass("small-12").removeClass("small-6 float-right");
$(data.wrapper).find(".attachment-actions .action-remove").addClass("small-3").removeClass("small-12");
if ($(data.input).data("nested-document") === true) {
$(data.wrapper).remove();
} else {
$(data.wrapper).find("a.remove-cached-attachment").remove();
}
}
});
},
initializeRemoveCachedDocumentLink: function(input, data) {
var remove_document_link, wrapper;
wrapper = $(input).closest(".direct-upload");
remove_document_link = $(wrapper).find("a.remove-cached-attachment");
$(remove_document_link).on("click", function(e) {
e.preventDefault();
e.stopPropagation();
App.Documentable.doDeleteCachedAttachmentRequest(this.href, data);
initializeRemoveCachedDocumentLinks: function() {
$("#nested-documents").on("ajax:complete", "a.remove-cached-attachment", function() {
App.Documentable.unlockUploads();
$(this).closest(".direct-upload").remove();
});
},
removeDocument: function(id) {
Expand Down
55 changes: 5 additions & 50 deletions app/assets/javascripts/imageable.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,17 @@
$("#nested-image").on("cocoon:after-remove", function() {
$("#new_image_link").removeClass("hide");
});
$("#nested-image").on("cocoon:before-insert", function() {
$(".js-image-attachment").closest(".image").remove();
});
$("#nested-image").on("cocoon:after-insert", function(e, nested_image) {
var input;
$("#new_image_link").addClass("hide");
input = $(nested_image).find(".js-image-attachment");
App.Imageable.initializeDirectUploadInput(input);
});
App.Imageable.initializeRemoveCachedImageLinks();
},
initializeDirectUploadInput: function(input) {
var inputData;
inputData = this.buildData([], input);
this.initializeRemoveCachedImageLink(input, inputData);
$(input).fileupload({
paramName: "attachment",
formData: null,
Expand All @@ -46,7 +43,6 @@
App.Imageable.clearPreview(data);
$(data.destroyAttachmentLinkContainer).find("a.delete:not(.remove-nested)").remove();
$(data.addAttachmentLabel).addClass("error");
$(data.addAttachmentLabel).show();
},
done: function(e, data) {
var destroyAttachmentLink;
Expand All @@ -55,17 +51,9 @@
App.Imageable.setProgressBar(data, "complete");
App.Imageable.setFilename(data, data.result.filename);
App.Imageable.clearInputErrors(data);
$(data.addAttachmentLabel).hide();
$(data.wrapper).find(".attachment-actions").removeClass("small-12").addClass("small-6 float-right");
$(data.wrapper).find(".attachment-actions .action-remove").removeClass("small-3").addClass("small-12");
App.Imageable.setPreview(data);
destroyAttachmentLink = $(data.result.destroy_link);
$(data.destroyAttachmentLinkContainer).html(destroyAttachmentLink);
$(destroyAttachmentLink).on("click", function(event) {
event.preventDefault();
event.stopPropagation();
App.Imageable.doDeleteCachedAttachmentRequest(this.href, data);
});
},
progress: function(e, data) {
var progress;
Expand All @@ -77,7 +65,6 @@
buildData: function(data, input) {
var wrapper;
wrapper = $(input).closest(".direct-upload");
data.input = input;
data.wrapper = wrapper;
data.progressBar = $(wrapper).find(".progress-bar-placeholder");
data.preview = $(wrapper).find(".image-preview");
Expand All @@ -92,7 +79,6 @@
},
clearFilename: function(data) {
$(data.fileNameContainer).text("");
$(data.fileNameContainer).hide();
},
clearInputErrors: function(data) {
$(data.errorContainer).find("small.error").remove();
Expand All @@ -105,7 +91,6 @@
},
setFilename: function(data, file_name) {
$(data.fileNameContainer).text(file_name);
$(data.fileNameContainer).show();
},
setProgressBar: function(data, klass) {
$(data.progressBar).find(".loading-bar").addClass(klass);
Expand All @@ -130,40 +115,10 @@
data.preview = $(data.wrapper).find(".image-preview");
}
},
doDeleteCachedAttachmentRequest: function(url, data) {
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: {
"_method": "delete"
},
complete: function() {
$(data.cachedAttachmentField).val("");
$(data.addAttachmentLabel).show();
App.Imageable.clearFilename(data);
App.Imageable.clearInputErrors(data);
App.Imageable.clearProgressBar(data);
App.Imageable.clearPreview(data);
$("#new_image_link").removeClass("hide");
$(data.wrapper).find(".attachment-actions").addClass("small-12").removeClass("small-6 float-right");
$(data.wrapper).find(".attachment-actions .action-remove").addClass("small-3").removeClass("small-12");
if ($(data.input).data("nested-image") === true) {
$(data.wrapper).remove();
} else {
$(data.wrapper).find("a.remove-cached-attachment").remove();
}
}
});
},
initializeRemoveCachedImageLink: function(input, data) {
var remove_image_link, wrapper;
wrapper = $(input).closest(".direct-upload");
remove_image_link = $(wrapper).find("a.remove-cached-attachment");
$(remove_image_link).on("click", function(e) {
e.preventDefault();
e.stopPropagation();
App.Imageable.doDeleteCachedAttachmentRequest(this.href, data);
initializeRemoveCachedImageLinks: function() {
$("#nested-image").on("ajax:complete", "a.remove-cached-attachment", function() {
$("#new_image_link").removeClass("hide");
$(this).closest(".direct-upload").remove();
});
},
removeImage: function(id) {
Expand Down
16 changes: 15 additions & 1 deletion app/assets/stylesheets/mixins/uploads.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@
p {
margin-bottom: 0;
}

&:focus-within label {
outline: $outline-focus;
}
}

.attachment-errors {

> .js-image-attachment,
> .js-document-attachment {
display: none;
@include element-invisible;

~ .error {
display: inline-block;
Expand All @@ -41,7 +45,17 @@
}

.file-name {
padding-left: 0;
margin-top: 0;

&:empty {
display: none;
}

&:not(:empty) + .document-attachment,
&:not(:empty) + .image-attachment {
display: none;
}
}

.loading-bar {
Expand Down
2 changes: 1 addition & 1 deletion app/components/admin/budget_phases/form_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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 %>
Expand Down
2 changes: 1 addition & 1 deletion app/components/admin/budgets/form_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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 %>
Expand Down
4 changes: 2 additions & 2 deletions app/components/budgets/investments/form_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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 %>
Expand Down
28 changes: 28 additions & 0 deletions app/components/documents/fields_component.html.erb
Original file line number Diff line number Diff line change
@@ -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 changes: 54 additions & 0 deletions app/components/documents/fields_component.rb
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit b3104fa

Please sign in to comment.