upload template from URL

pull/133/head
DocuSeal 2 years ago
parent b48615df3f
commit ddb557ebef

@ -75,3 +75,6 @@ Rails/SkipsModelValidations:
Rails/ApplicationController: Rails/ApplicationController:
Enabled: false Enabled: false
Capybara/ClickLinkOrButtonStyle:
Enabled: false

@ -98,7 +98,6 @@ GEM
faraday_middleware (~> 1.0, >= 1.0.0.rc1) faraday_middleware (~> 1.0, >= 1.0.0.rc1)
net-http-persistent (~> 4.0) net-http-persistent (~> 4.0)
nokogiri (~> 1, >= 1.10.8) nokogiri (~> 1, >= 1.10.8)
base64 (0.1.1)
bcrypt (3.1.19) bcrypt (3.1.19)
better_html (2.0.2) better_html (2.0.2)
actionview (>= 6.0) actionview (>= 6.0)
@ -345,7 +344,7 @@ GEM
os (1.1.4) os (1.1.4)
pagy (6.0.4) pagy (6.0.4)
parallel (1.23.0) parallel (1.23.0)
parser (3.2.2.3) parser (3.2.2.4)
ast (~> 2.4.1) ast (~> 2.4.1)
racc racc
pdf-reader (2.11.0) pdf-reader (2.11.0)
@ -418,7 +417,7 @@ GEM
rake (13.0.6) rake (13.0.6)
redis-client (0.16.0) redis-client (0.16.0)
connection_pool connection_pool
regexp_parser (2.8.1) regexp_parser (2.8.2)
reline (0.3.8) reline (0.3.8)
io-console (~> 0.5) io-console (~> 0.5)
representable (3.2.0) representable (3.2.0)
@ -455,19 +454,18 @@ GEM
rspec-mocks (~> 3.12) rspec-mocks (~> 3.12)
rspec-support (~> 3.12) rspec-support (~> 3.12)
rspec-support (3.12.1) rspec-support (3.12.1)
rubocop (1.56.1) rubocop (1.57.2)
base64 (~> 0.1.1)
json (~> 2.3) json (~> 2.3)
language_server-protocol (>= 3.17.0) language_server-protocol (>= 3.17.0)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 3.2.2.3) parser (>= 3.2.2.4)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0) regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0) rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.28.1, < 2.0) rubocop-ast (>= 1.28.1, < 2.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0) unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.29.0) rubocop-ast (1.30.0)
parser (>= 3.2.1.0) parser (>= 3.2.1.0)
rubocop-capybara (2.18.0) rubocop-capybara (2.18.0)
rubocop (~> 1.41) rubocop (~> 1.41)
@ -537,7 +535,7 @@ GEM
tzinfo-data (1.2023.3) tzinfo-data (1.2023.3)
tzinfo (>= 1.0.0) tzinfo (>= 1.0.0)
uber (0.1.0) uber (0.1.0)
unicode-display_width (2.4.2) unicode-display_width (2.5.0)
uniform_notifier (1.16.0) uniform_notifier (1.16.0)
version_gem (1.1.3) version_gem (1.1.3)
warden (1.2.9) warden (1.2.9)

@ -3,20 +3,55 @@
class TemplatesUploadsController < ApplicationController class TemplatesUploadsController < ApplicationController
load_and_authorize_resource :template, parent: false load_and_authorize_resource :template, parent: false
layout 'plain'
def show; end
def create def create
url_params = create_file_params_from_url if params[:url].present?
@template.account = current_account @template.account = current_account
@template.author = current_user @template.author = current_user
@template.folder = TemplateFolders.find_or_create_by_name(current_user, params[:folder_name]) @template.folder = TemplateFolders.find_or_create_by_name(current_user, params[:folder_name])
@template.name = File.basename(params[:files].first.original_filename, '.*') @template.name = File.basename((url_params || params)[:files].first.original_filename, '.*')
@template.save! @template.save!
documents = Templates::CreateAttachments.call(@template, params) documents = Templates::CreateAttachments.call(@template, url_params || params)
schema = documents.map { |doc| { attachment_uuid: doc.uuid, name: doc.filename.base } } schema = documents.map { |doc| { attachment_uuid: doc.uuid, name: doc.filename.base } }
@template.update!(schema:) @template.update!(schema:)
redirect_to edit_template_path(@template) redirect_to edit_template_path(@template)
rescue StandardError => e
Rollbar.error(e) if defined?(Rollbar)
redirect_to root_path, alert: 'Unable to upload file'
end
private
def create_file_params_from_url
tempfile = Tempfile.new
tempfile.binmode
tempfile.write(conn.get(params[:url]).body)
tempfile.rewind
file = ActionDispatch::Http::UploadedFile.new(
tempfile:,
filename: File.basename(
URI.decode_www_form_component(params[:filename].presence || params[:url])
),
type: Marcel::MimeType.for(tempfile)
)
{ files: [file] }
end
def conn
Faraday.new do |faraday|
faraday.response :follow_redirects
end
end end
end end

@ -18,6 +18,7 @@ import AutoresizeTextarea from './elements/autoresize_textarea'
import SubmittersAutocomplete from './elements/submitter_autocomplete' import SubmittersAutocomplete from './elements/submitter_autocomplete'
import FolderAutocomplete from './elements/folder_autocomplete' import FolderAutocomplete from './elements/folder_autocomplete'
import SignatureForm from './elements/signature_form' import SignatureForm from './elements/signature_form'
import SubmitForm from './elements/submit_form'
import * as TurboInstantClick from './lib/turbo_instant_click' import * as TurboInstantClick from './lib/turbo_instant_click'
@ -49,6 +50,7 @@ window.customElements.define('autoresize-textarea', AutoresizeTextarea)
window.customElements.define('submitters-autocomplete', SubmittersAutocomplete) window.customElements.define('submitters-autocomplete', SubmittersAutocomplete)
window.customElements.define('folder-autocomplete', FolderAutocomplete) window.customElements.define('folder-autocomplete', FolderAutocomplete)
window.customElements.define('signature-form', SignatureForm) window.customElements.define('signature-form', SignatureForm)
window.customElements.define('submit-form', SubmitForm)
document.addEventListener('turbo:before-fetch-request', encodeMethodIntoRequestBody) document.addEventListener('turbo:before-fetch-request', encodeMethodIntoRequestBody)
document.addEventListener('turbo:submit-end', async (event) => { document.addEventListener('turbo:submit-end', async (event) => {

@ -0,0 +1,5 @@
export default class extends HTMLElement {
connectedCallback () {
this.querySelector('form').requestSubmit()
}
}

@ -31,6 +31,7 @@
:href="`/templates/${template.id}/submissions/new`" :href="`/templates/${template.id}/submissions/new`"
data-turbo-frame="modal" data-turbo-frame="modal"
class="btn btn-primary text-base" class="btn btn-primary text-base"
@click="maybeShowEmptyTemplateAlert"
> >
<IconUsersPlus <IconUsersPlus
width="20" width="20"
@ -691,14 +692,25 @@ export default {
this.save() this.save()
}, },
maybeShowEmptyTemplateAlert (e) {
if (!this.template.fields.length) {
e.preventDefault()
alert('Please draw fields to prepare the document.')
}
},
onSaveClick () { onSaveClick () {
this.isSaving = true if (this.template.fields.length) {
this.isSaving = true
this.save().then(() => { this.save().then(() => {
window.Turbo.visit(`/templates/${this.template.id}`) window.Turbo.visit(`/templates/${this.template.id}`)
}).finally(() => { }).finally(() => {
this.isSaving = false this.isSaving = false
}) })
} else {
alert('Please draw fields to prepare the document.')
}
}, },
scrollToArea (area) { scrollToArea (area) {
const documentRef = this.documentRefs.find((a) => a.document.uuid === area.attachment_uuid) const documentRef = this.documentRefs.find((a) => a.document.uuid === area.attachment_uuid)

@ -0,0 +1,19 @@
<div class="h-screen">
<div
class="text-center p-8 h-full flex items-center justify-center"
>
<div>
<%= render 'shared/logo', width: 50, height: 50, class: 'mx-auto animate-bounce' %>
<span>
Processing...
</span>
</div>
</div>
</div>
<submit-form>
<%= form_for '', url: templates_upload_path, method: :post, class: 'hidden' do %>
<button type="submit"></button>
<input name="url" value="<%= params[:url] %>">
<input name="filename" value="<%= params[:filename] %>">
<% end %>
</submit-form>

@ -58,6 +58,9 @@ Rails.application.routes.draw do
resources :submissions, only: %i[show destroy] resources :submissions, only: %i[show destroy]
resources :console_redirect, only: %i[index] resources :console_redirect, only: %i[index]
resource :templates_upload, only: %i[create] resource :templates_upload, only: %i[create]
authenticated do
resource :templates_upload, only: %i[show], path: 'new'
end
resources :templates_archived, only: %i[index], path: 'archived' resources :templates_archived, only: %i[index], path: 'archived'
resources :folders, only: %i[show edit update destroy], controller: 'template_folders' resources :folders, only: %i[show edit update destroy], controller: 'template_folders'
resources :templates, only: %i[new create edit show destroy] do resources :templates, only: %i[new create edit show destroy] do

@ -20,7 +20,7 @@ class AddFolderIdToTemplates < ActiveRecord::Migration[7.0]
def up def up
add_reference :templates, :folder, foreign_key: { to_table: :template_folders }, index: true, null: true add_reference :templates, :folder, foreign_key: { to_table: :template_folders }, index: true, null: true
MigrationAccount.all.pluck(:id).each do |account_id| MigrationAccount.pluck(:id).each do |account_id|
author_id = MigrationUser.where(account_id:).minimum(:id) author_id = MigrationUser.where(account_id:).minimum(:id)
next if author_id.blank? next if author_id.blank?

@ -2,7 +2,7 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe 'App Setup', js: true do RSpec.describe 'App Setup' do
let(:form_data) do let(:form_data) do
{ {
first_name: 'John', first_name: 'John',

Loading…
Cancel
Save