diff --git a/app/controllers/api/attachments_controller.rb b/app/controllers/api/attachments_controller.rb index d255d5da..d61867f2 100644 --- a/app/controllers/api/attachments_controller.rb +++ b/app/controllers/api/attachments_controller.rb @@ -7,20 +7,7 @@ module Api def create submitter = Submitter.find_by!(slug: params[:submitter_slug]) - blob = - if (file = params[:file]) - ActiveStorage::Blob.create_and_upload!(io: file.open, - filename: file.original_filename, - content_type: file.content_type) - else - ActiveStorage::Blob.find_signed(params[:blob_signed_id]) - end - - attachment = ActiveStorage::Attachment.create!( - blob:, - name: params[:name], - record: submitter - ) + attachment = Submitters.create_attachment!(submitter, params) render json: attachment.as_json(only: %i[uuid], methods: %i[url filename content_type]) end diff --git a/app/controllers/api/templates_controller.rb b/app/controllers/api/templates_controller.rb index 0412a14a..de6811a3 100644 --- a/app/controllers/api/templates_controller.rb +++ b/app/controllers/api/templates_controller.rb @@ -9,7 +9,8 @@ module Api end def show - render json: @template.as_json(include: { author: { only: %i[id email first_name last_name] } }) + render json: @template.as_json(include: { author: { only: %i[id email first_name last_name] }, + documents: { only: %i[id filename uuid], methods: %i[url] } }) end def update diff --git a/app/controllers/submit_form_controller.rb b/app/controllers/submit_form_controller.rb index dea2bb87..13dd8c22 100644 --- a/app/controllers/submit_form_controller.rb +++ b/app/controllers/submit_form_controller.rb @@ -18,23 +18,7 @@ class SubmitFormController < ApplicationController def update submitter = Submitter.find_by!(slug: params[:slug]) - update_submitter!(submitter) - - Submissions.update_template_fields!(submitter.submission) if submitter.submission.template_fields.blank? - - submitter.submission.save! - - if submitter.completed_at? - GenerateSubmitterResultAttachmentsJob.perform_later(submitter) - - if submitter.account.encrypted_configs.exists?(key: EncryptedConfig::WEBHOOK_URL_KEY) - SendWebhookRequestJob.perform_later(submitter) - end - - submitter.submission.template.account.users.active.each do |user| - SubmitterMailer.completed_email(submitter, user).deliver_later! - end - end + Submitters::SubmitValues.call(submitter, params) head :ok end @@ -42,26 +26,4 @@ class SubmitFormController < ApplicationController def completed @submitter = Submitter.find_by!(slug: params[:submit_form_slug]) end - - private - - def update_submitter!(submitter) - submitter.values.merge!(normalized_values) - submitter.completed_at = Time.current if params[:completed] == 'true' - submitter.opened_at ||= Time.current - - submitter.save! - - submitter - end - - def normalized_values - params.fetch(:values, {}).to_unsafe_h.transform_values do |v| - if params[:cast_boolean] == 'true' - v == 'true' - else - v.is_a?(Array) ? v.compact_blank : v - end - end - end end diff --git a/app/javascript/form.js b/app/javascript/form.js index ca38da31..943c4384 100644 --- a/app/javascript/form.js +++ b/app/javascript/form.js @@ -15,6 +15,7 @@ window.customElements.define('submission-form', class extends HTMLElement { canSendEmail: this.dataset.canSendEmail === 'true', isDirectUpload: this.dataset.isDirectUpload === 'true', isDemo: this.dataset.isDemo === 'true', + withConfetti: true, values: reactive(JSON.parse(this.dataset.values)), attachments: reactive(JSON.parse(this.dataset.attachments)), fields: JSON.parse(this.dataset.fields) diff --git a/app/javascript/submission_form/areas.vue b/app/javascript/submission_form/areas.vue index 2cbc8fe4..0cf3b825 100644 --- a/app/javascript/submission_form/areas.vue +++ b/app/javascript/submission_form/areas.vue @@ -12,7 +12,7 @@ :key="areaIndex" > { if (area.field === field) { - if (document.body.style.overflow === 'hidden') { + const root = this.$root.$el.parentNode.getRootNode() + const container = root.body || root.querySelector('div') + + if (container.style.overflow === 'hidden') { this.scrollInContainer(area.$el) } else { area.$refs.scrollToElem.scrollIntoView({ behavior: 'smooth', block: 'start' }) @@ -94,13 +100,19 @@ export default { }) }, scrollInContainer (target) { + const root = this.$root.$el.parentNode.getRootNode() + + const scrollbox = root.getElementById('scrollbox') + const formContainer = root.getElementById('form_container') + const container = root.body || root.querySelector('div') + const padding = 64 - const boxRect = window.scrollbox.children[0].getBoundingClientRect() + const boxRect = scrollbox.children[0].getBoundingClientRect() const targetRect = target.getBoundingClientRect() const targetTopRelativeToBox = targetRect.top - boxRect.top - window.scrollbox.scrollTop = targetTopRelativeToBox - document.body.offsetHeight + window.form_container.offsetHeight + target.offsetHeight + padding + scrollbox.scrollTop = targetTopRelativeToBox - container.offsetHeight + formContainer.offsetHeight + target.offsetHeight + padding }, setAreaRef (el) { if (el) { diff --git a/app/javascript/submission_form/completed.vue b/app/javascript/submission_form/completed.vue index f66ab76d..990949e3 100644 --- a/app/javascript/submission_form/completed.vue +++ b/app/javascript/submission_form/completed.vue @@ -86,6 +86,7 @@ export default { IconLogin, IconDownload }, + inject: ['baseUrl'], props: { submitterSlug: { type: String, @@ -96,6 +97,11 @@ export default { required: false, default: false }, + withConfetti: { + type: Boolean, + required: false, + default: false + }, canSendEmail: { type: Boolean, required: false, @@ -109,19 +115,21 @@ export default { } }, async mounted () { - const { default: confetti } = await import('canvas-confetti') + if (this.withConfetti) { + const { default: confetti } = await import('canvas-confetti') - confetti({ - particleCount: 50, - startVelocity: 30, - spread: 140 - }) + confetti({ + particleCount: 50, + startVelocity: 30, + spread: 140 + }) + } }, methods: { sendCopyToEmail () { this.isSendingCopy = true - fetch(`/send_submission_email.json?submitter_slug=${this.submitterSlug}`, { + fetch(this.baseUrl + `/send_submission_email.json?submitter_slug=${this.submitterSlug}`, { method: 'POST' }).then(() => { alert('Email has been sent') @@ -132,7 +140,7 @@ export default { download () { this.isDownloading = true - fetch(`/submitters/${this.submitterSlug}/download`).then((response) => response.json()).then((urls) => { + fetch(this.baseUrl + `/submitters/${this.submitterSlug}/download`).then((response) => response.json()).then((urls) => { const fileRequests = urls.map((url) => { return () => { return fetch(url).then(async (resp) => { diff --git a/app/javascript/submission_form/dropzone.vue b/app/javascript/submission_form/dropzone.vue index 39fe5759..ad9fdd33 100644 --- a/app/javascript/submission_form/dropzone.vue +++ b/app/javascript/submission_form/dropzone.vue @@ -55,6 +55,7 @@ export default { IconCloudUpload, IconInnerShadowTop }, + inject: ['baseUrl'], props: { message: { type: String, @@ -141,7 +142,7 @@ export default { return await Promise.all( blobs.map((blob) => { - return fetch('/api/attachments', { + return fetch(this.baseUrl + '/api/attachments', { method: 'POST', body: JSON.stringify({ name: 'attachments', @@ -166,7 +167,7 @@ export default { formData.append('submitter_slug', this.submitterSlug) formData.append('name', 'attachments') - return fetch('/api/attachments', { + return fetch(this.baseUrl + '/api/attachments', { method: 'POST', body: formData }).then(resp => resp.json()).then((data) => { diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue index 7711dc0b..cfa3a64d 100644 --- a/app/javascript/submission_form/form.vue +++ b/app/javascript/submission_form/form.vue @@ -10,7 +10,7 @@ />