refactor and fixes
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
:key="areaIndex"
|
||||
>
|
||||
<Teleport
|
||||
:to="`#page-${area.attachment_uuid}-${area.page}`"
|
||||
:to="findPageElementForArea(area)"
|
||||
>
|
||||
<FieldArea
|
||||
:ref="setAreaRef"
|
||||
@@ -78,10 +78,16 @@ export default {
|
||||
this.areaRefs = []
|
||||
},
|
||||
methods: {
|
||||
findPageElementForArea (area) {
|
||||
return (this.$root.$el?.parentNode?.getRootNode() || document).getElementById(`page-${area.attachment_uuid}-${area.page}`)
|
||||
},
|
||||
scrollIntoField (field) {
|
||||
this.areaRefs.find((area) => {
|
||||
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) {
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
/>
|
||||
<button
|
||||
v-if="!isFormVisible"
|
||||
class="btn btn-neutral text-white absolute rounded-none border-x-0 md:border md:rounded-full bottom-0 w-full md:mb-4 text-base"
|
||||
class="btn btn-neutral flex text-white absolute rounded-none border-x-0 md:border md:rounded-full bottom-0 w-full md:mb-4 text-base"
|
||||
@click.prevent="isFormVisible = true"
|
||||
>
|
||||
Submit Form
|
||||
@@ -194,7 +194,9 @@
|
||||
class="space-y-3.5 mx-auto"
|
||||
>
|
||||
<template v-if="isAnonymousChecboxes">
|
||||
Complete hightlighted checkboxes and click <span class="font-semibold">{{ stepFields.length === currentStep + 1 ? 'submit' : 'next' }}</span>.
|
||||
<span class="text-xl">
|
||||
Complete hightlighted checkboxes and click <span class="font-semibold">{{ stepFields.length === currentStep + 1 ? 'submit' : 'next' }}</span>.
|
||||
</span>
|
||||
<input
|
||||
v-for="field in currentStepFields"
|
||||
:key="field.uuid"
|
||||
@@ -290,6 +292,7 @@
|
||||
<FormCompleted
|
||||
v-else
|
||||
:is-demo="isDemo"
|
||||
:with-confetti="withConfetti"
|
||||
:can-send-email="canSendEmail"
|
||||
:submitter-slug="submitterSlug"
|
||||
/>
|
||||
@@ -331,6 +334,11 @@ export default {
|
||||
IconArrowsDiagonalMinimize2,
|
||||
FormCompleted
|
||||
},
|
||||
provide () {
|
||||
return {
|
||||
baseUrl: this.baseUrl
|
||||
}
|
||||
},
|
||||
props: {
|
||||
submitterSlug: {
|
||||
type: String,
|
||||
@@ -350,6 +358,16 @@ export default {
|
||||
required: false,
|
||||
default: () => []
|
||||
},
|
||||
withConfetti: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
baseUrl: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: ''
|
||||
},
|
||||
fields: {
|
||||
type: Array,
|
||||
required: false,
|
||||
@@ -357,16 +375,17 @@ export default {
|
||||
},
|
||||
authenticityToken: {
|
||||
type: String,
|
||||
required: true
|
||||
required: false,
|
||||
default: ''
|
||||
},
|
||||
isDirectUpload: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
isDemo: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
values: {
|
||||
@@ -429,10 +448,17 @@ export default {
|
||||
)
|
||||
|
||||
if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
|
||||
document.body.style.overflow = 'hidden'
|
||||
this.$nextTick(() => {
|
||||
const root = this.$root.$el.parentNode.getRootNode()
|
||||
const scrollbox = root.getElementById('scrollbox')
|
||||
const parent = root.body || root.querySelector('div')
|
||||
|
||||
window.scrollbox.classList.add('h-full', 'overflow-y-auto')
|
||||
window.scrollbox.parentNode.classList.add('h-screen', 'overflow-y-auto')
|
||||
parent.style.overflow = 'hidden'
|
||||
|
||||
scrollbox.classList.add('h-full', 'overflow-y-auto')
|
||||
scrollbox.parentNode.classList.add('h-screen', 'overflow-y-auto')
|
||||
scrollbox.parentNode.style.maxHeight = '-webkit-fill-available'
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -455,7 +481,7 @@ export default {
|
||||
if (this.isCompleted) {
|
||||
return Promise.resolve({})
|
||||
} else {
|
||||
return fetch(this.submitPath, {
|
||||
return fetch(this.baseUrl + this.submitPath, {
|
||||
method: 'POST',
|
||||
body: formData || new FormData(this.$refs.form)
|
||||
})
|
||||
|
||||
@@ -99,6 +99,7 @@ export default {
|
||||
IconTextSize,
|
||||
IconArrowsDiagonalMinimize2
|
||||
},
|
||||
inject: ['baseUrl'],
|
||||
props: {
|
||||
field: {
|
||||
type: Object,
|
||||
@@ -304,7 +305,7 @@ export default {
|
||||
file,
|
||||
'/direct_uploads'
|
||||
).create((_error, data) => {
|
||||
fetch('/api/attachments', {
|
||||
fetch(this.baseUrl + '/api/attachments', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
submitter_slug: this.submitterSlug,
|
||||
@@ -326,12 +327,12 @@ 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((attachment) => {
|
||||
this.$emit('update:model-value', attachment.uuid)
|
||||
this.$emit('attached', attachment)
|
||||
this.$emit('update:model-value', attachment.uuid)
|
||||
|
||||
return resolve(attachment)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user