diff --git a/.rubocop.yml b/.rubocop.yml index bcb65cd4..5e4b6895 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -75,3 +75,6 @@ Rails/SkipsModelValidations: Rails/ApplicationController: Enabled: false + +Capybara/ClickLinkOrButtonStyle: + Enabled: false diff --git a/Gemfile.lock b/Gemfile.lock index 9ab1ed46..deb490f9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -98,7 +98,6 @@ GEM faraday_middleware (~> 1.0, >= 1.0.0.rc1) net-http-persistent (~> 4.0) nokogiri (~> 1, >= 1.10.8) - base64 (0.1.1) bcrypt (3.1.19) better_html (2.0.2) actionview (>= 6.0) @@ -345,7 +344,7 @@ GEM os (1.1.4) pagy (6.0.4) parallel (1.23.0) - parser (3.2.2.3) + parser (3.2.2.4) ast (~> 2.4.1) racc pdf-reader (2.11.0) @@ -418,7 +417,7 @@ GEM rake (13.0.6) redis-client (0.16.0) connection_pool - regexp_parser (2.8.1) + regexp_parser (2.8.2) reline (0.3.8) io-console (~> 0.5) representable (3.2.0) @@ -455,19 +454,18 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) rspec-support (3.12.1) - rubocop (1.56.1) - base64 (~> 0.1.1) + rubocop (1.57.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.3) + parser (>= 3.2.2.4) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) rubocop-ast (>= 1.28.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.29.0) + rubocop-ast (1.30.0) parser (>= 3.2.1.0) rubocop-capybara (2.18.0) rubocop (~> 1.41) @@ -537,7 +535,7 @@ GEM tzinfo-data (1.2023.3) tzinfo (>= 1.0.0) uber (0.1.0) - unicode-display_width (2.4.2) + unicode-display_width (2.5.0) uniform_notifier (1.16.0) version_gem (1.1.3) warden (1.2.9) diff --git a/app/controllers/templates_uploads_controller.rb b/app/controllers/templates_uploads_controller.rb index 07d0e4d2..7a41c1c2 100644 --- a/app/controllers/templates_uploads_controller.rb +++ b/app/controllers/templates_uploads_controller.rb @@ -3,20 +3,55 @@ class TemplatesUploadsController < ApplicationController load_and_authorize_resource :template, parent: false + layout 'plain' + + def show; end + def create + url_params = create_file_params_from_url if params[:url].present? + @template.account = current_account @template.author = current_user @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! - 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 } } @template.update!(schema:) 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 diff --git a/app/javascript/application.js b/app/javascript/application.js index 33eb93de..da94ac1f 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -18,6 +18,7 @@ import AutoresizeTextarea from './elements/autoresize_textarea' import SubmittersAutocomplete from './elements/submitter_autocomplete' import FolderAutocomplete from './elements/folder_autocomplete' import SignatureForm from './elements/signature_form' +import SubmitForm from './elements/submit_form' 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('folder-autocomplete', FolderAutocomplete) window.customElements.define('signature-form', SignatureForm) +window.customElements.define('submit-form', SubmitForm) document.addEventListener('turbo:before-fetch-request', encodeMethodIntoRequestBody) document.addEventListener('turbo:submit-end', async (event) => { diff --git a/app/javascript/elements/submit_form.js b/app/javascript/elements/submit_form.js new file mode 100644 index 00000000..4b5969e5 --- /dev/null +++ b/app/javascript/elements/submit_form.js @@ -0,0 +1,5 @@ +export default class extends HTMLElement { + connectedCallback () { + this.querySelector('form').requestSubmit() + } +} diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue index c22afd02..7db5b4a5 100644 --- a/app/javascript/template_builder/builder.vue +++ b/app/javascript/template_builder/builder.vue @@ -31,6 +31,7 @@ :href="`/templates/${template.id}/submissions/new`" data-turbo-frame="modal" class="btn btn-primary text-base" + @click="maybeShowEmptyTemplateAlert" > { - window.Turbo.visit(`/templates/${this.template.id}`) - }).finally(() => { - this.isSaving = false - }) + this.save().then(() => { + window.Turbo.visit(`/templates/${this.template.id}`) + }).finally(() => { + this.isSaving = false + }) + } else { + alert('Please draw fields to prepare the document.') + } }, scrollToArea (area) { const documentRef = this.documentRefs.find((a) => a.document.uuid === area.attachment_uuid) diff --git a/app/views/templates_uploads/show.html.erb b/app/views/templates_uploads/show.html.erb new file mode 100644 index 00000000..614a4b5d --- /dev/null +++ b/app/views/templates_uploads/show.html.erb @@ -0,0 +1,19 @@ +
+
+
+ <%= render 'shared/logo', width: 50, height: 50, class: 'mx-auto animate-bounce' %> + + Processing... + +
+
+
+ + <%= form_for '', url: templates_upload_path, method: :post, class: 'hidden' do %> + + + + <% end %> + diff --git a/config/routes.rb b/config/routes.rb index 571f8eed..a4699051 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -58,6 +58,9 @@ Rails.application.routes.draw do resources :submissions, only: %i[show destroy] resources :console_redirect, only: %i[index] 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 :folders, only: %i[show edit update destroy], controller: 'template_folders' resources :templates, only: %i[new create edit show destroy] do diff --git a/db/migrate/20230920202947_add_folder_id_to_templates.rb b/db/migrate/20230920202947_add_folder_id_to_templates.rb index 370b25c4..adc47800 100644 --- a/db/migrate/20230920202947_add_folder_id_to_templates.rb +++ b/db/migrate/20230920202947_add_folder_id_to_templates.rb @@ -20,7 +20,7 @@ class AddFolderIdToTemplates < ActiveRecord::Migration[7.0] def up 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) next if author_id.blank? diff --git a/spec/system/setup_spec.rb b/spec/system/setup_spec.rb index 378b548e..c11413bf 100644 --- a/spec/system/setup_spec.rb +++ b/spec/system/setup_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe 'App Setup', js: true do +RSpec.describe 'App Setup' do let(:form_data) do { first_name: 'John',