migrate to nuxt useClipboard (#268)

This commit is contained in:
formsdev 2024-01-05 14:29:53 +05:30 committed by GitHub
parent f87e3f1685
commit 2207c8cd90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 180 additions and 257 deletions

View File

@ -6,7 +6,7 @@
</p> </p>
</div> </div>
<div class="w-full sm:w-40 sm:ml-2 mt-2 sm:mt-0 shrink-0"> <div class="w-full sm:w-40 sm:ml-2 mt-2 sm:mt-0 shrink-0">
<v-button color="light-gray" class="w-full" @click="copyToClipboard(content)"> <v-button color="light-gray" class="w-full" @click="copyToClipboard">
<slot name="icon"> <slot name="icon">
<svg class="h-4 w-4 -mt-1 text-blue-600 inline mr-1" viewBox="0 0 20 20" fill="none" <svg class="h-4 w-4 -mt-1 text-blue-600 inline mr-1" viewBox="0 0 20 20" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg">
@ -21,10 +21,11 @@
</div> </div>
</template> </template>
<script> <script setup>
export default { import { defineProps } from 'vue'
name: 'CopyContent', const { copy } = useClipboard()
props: {
const props = defineProps({
content: { content: {
type: String, type: String,
required: true required: true
@ -32,36 +33,16 @@ export default {
isDraft: { isDraft: {
type: Boolean, type: Boolean,
default: false default: false
}, }
}, })
data() { const copyToClipboard = () => {
return {}
},
computed: {},
watch: {},
mounted() {
},
methods: {
copyToClipboard(str) {
if (process.server) return if (process.server) return
const el = document.createElement('textarea') copy(props.content)
el.value = str if(props.isDraft){
document.body.appendChild(el)
el.select()
document.execCommand('copy')
document.body.removeChild(el)
if(this.isDraft){
useAlert().warning('Copied! But other people won\'t be able to see the form since it\'s currently in draft mode') useAlert().warning('Copied! But other people won\'t be able to see the form since it\'s currently in draft mode')
} else { } else {
useAlert().success('Copied!') useAlert().success('Copied!')
} }
}
}
} }
</script> </script>

View File

@ -17,10 +17,11 @@
</div> </div>
</template> </template>
<script> <script setup>
export default { import { defineProps, computed } from 'vue'
name: 'FormUrlPrefill', const { copy } = useClipboard()
props: {
const props = defineProps({
form: { form: {
type: Object, type: Object,
required: true required: true
@ -33,56 +34,33 @@ export default {
type: String, type: String,
default: '' default: ''
} }
}, })
data () { const preFillUrl = computed(() => {
return {} const url = props.form.share_url
},
computed: {
preFillUrl () {
const url = this.form.share_url
const uriComponents = new URLSearchParams() const uriComponents = new URLSearchParams()
this.form.properties.filter((property) => { props.form.properties.filter((property) => {
return this.formData.hasOwnProperty(property.id) && this.formData[property.id] !== null return props.formData.hasOwnProperty(property.id) && props.formData[property.id] !== null
}).forEach((property) => { }).forEach((property) => {
if (Array.isArray(this.formData[property.id])) { if (Array.isArray(props.formData[property.id])) {
this.formData[property.id].forEach((value) => { props.formData[property.id].forEach((value) => {
uriComponents.append(property.id + '[]', value) uriComponents.append(property.id + '[]', value)
}) })
} else { } else {
uriComponents.append(property.id, this.formData[property.id]) uriComponents.append(property.id, props.formData[property.id])
} }
}) })
if(uriComponents.toString() !== ""){ if(uriComponents.toString() !== ""){
return (this.extraQueryParam) ? url + '?' + uriComponents + '&' + this.extraQueryParam : url + '?' + uriComponents return (props.extraQueryParam) ? url + '?' + uriComponents + '&' + props.extraQueryParam : url + '?' + uriComponents
}else{ }else{
return (this.extraQueryParam) ? url + '?' + this.extraQueryParam : url return (props.extraQueryParam) ? url + '?' + props.extraQueryParam : url
} }
} })
},
watch: {}, const copyToClipboard = () => {
mounted () {
},
methods: {
getPropertyUriComponent (property) {
const prefillValue = encodeURIComponent(this.formData[property.id])
return encodeURIComponent(property.id) + '=' + prefillValue
},
copyToClipboard () {
if (process.server) return if (process.server) return
const str = this.preFillUrl copy(preFillUrl.value)
const el = document.createElement('textarea') useAlert().success('Copied!')
el.value = str
document.body.appendChild(el)
el.select()
document.execCommand('copy')
document.body.removeChild(el)
}
}
} }
</script> </script>

View File

@ -59,7 +59,7 @@
</div> </div>
</div> </div>
<collapse class="py-5 w-full border rounded-md px-4" :model-value="false"> <collapse class="py-5 w-full border rounded-md px-4" :model-value="true">
<template #title> <template #title>
<div class="flex"> <div class="flex">
<h3 class="font-semibold block text-lg"> <h3 class="font-semibold block text-lg">
@ -101,69 +101,59 @@
</div> </div>
</template> </template>
<script> <script setup>
import Collapse from '~/components/global/Collapse.vue' import { ref, defineProps, computed } from 'vue'
export default { const { copy } = useClipboard()
name: 'EmbedFormAsPopupModal', const crisp = useCrisp()
components: { Collapse }, const props = defineProps({
props: {
form: { type: Object, required: true } form: { type: Object, required: true }
}, })
data: () => ({ const embedScriptUrl = '/widgets/embed-min.js'
showEmbedFormAsPopupModal: false, let showEmbedFormAsPopupModal = ref(false)
embedScriptUrl: 'widgets/embed-min.js', let advancedOptions = ref({
advancedOptions: {
hide_title: false, hide_title: false,
emoji: '💬', emoji: '💬',
position: 'right', position: 'right',
bgcolor: '#3B82F6', bgcolor: '#3B82F6',
width: '500' width: '500'
} })
}),
computed: { let hideTitleHelp = computed(() => {
hideTitleHelp () { return props.form.hide_title ? 'This option is disabled because the form title is already hidden' : null
return this.form.hide_title ? 'This option is disabled because the form title is already hidden' : null })
}, let shareUrl = computed(() => {
shareUrl () { return (advancedOptions.value.hide_title) ? props.form.share_url + '?hide_title=true' : props.form.share_url
return (this.advancedOptions.hide_title) ? this.form.share_url + '?hide_title=true' : this.form.share_url })
}, let embedPopupCode = computed(() => {
embedPopupCode () {
const nfData = { const nfData = {
formurl: this.shareUrl, formurl: shareUrl.value,
emoji: this.advancedOptions.emoji, emoji: advancedOptions.value.emoji,
position: this.advancedOptions.position, position: advancedOptions.value.position,
bgcolor: this.advancedOptions.bgcolor, bgcolor: advancedOptions.value.bgcolor,
width: this.advancedOptions.width width: advancedOptions.value.width
} }
this.previewPopup(nfData) previewPopup(nfData)
return '<script async data-nf=\'' + JSON.stringify(nfData) + '\' src=\'' + this.asset(this.embedScriptUrl) + '\'></scrip' + 't>' return '<script async data-nf=\'' + JSON.stringify(nfData) + '\' src=\'' + embedScriptUrl + '\'></scrip' + 't>'
})
onMounted(() => {
advancedOptions.value.bgcolor = props.form.color
})
const onClose = () => {
removePreview()
crisp.showChat()
showEmbedFormAsPopupModal.value = false
} }
}, const copyToClipboard = () => {
mounted () {
this.advancedOptions.bgcolor = this.form.color
},
methods: {
onClose () {
this.removePreview()
this.$crisp.push(['do', 'chat:show'])
this.showEmbedFormAsPopupModal = false
},
copyToClipboard () {
if (process.server) return if (process.server) return
const str = this.embedPopupCode copy(embedPopupCode.value)
const el = document.createElement('textarea') useAlert().success('Copied!')
el.value = str }
document.body.appendChild(el) const removePreview = () => {
el.select()
document.execCommand('copy')
document.body.removeChild(el)
},
removePreview () {
if (process.server) return if (process.server) return
const oldP = document.head.querySelector('#nf-popup-preview') const oldP = document.head.querySelector('#nf-popup-preview')
if (oldP) { if (oldP) {
@ -173,27 +163,25 @@ export default {
if (oldM) { if (oldM) {
oldM.remove() oldM.remove()
} }
}, }
previewPopup (nfData) { const previewPopup = (nfData) => {
if (process.server) return if (process.server) return
if (!this.showEmbedFormAsPopupModal) { if (!showEmbedFormAsPopupModal.value) {
return return
} }
// Remove old preview, if there // Remove old preview, if there
this.removePreview() removePreview()
// Hide crisp // Hide crisp
this.$crisp.push(['do', 'chat:hide']) crisp.hideChat()
// Add new preview // Add new preview
const el = document.createElement('script') const el = document.createElement('script')
el.id = 'nf-popup-preview' el.id = 'nf-popup-preview'
el.async = true el.async = true
el.src = this.asset(this.embedScriptUrl) el.src = embedScriptUrl
el.setAttribute('data-nf', JSON.stringify(nfData)) el.setAttribute('data-nf', JSON.stringify(nfData))
document.head.appendChild(el) document.head.appendChild(el)
} }
}
}
</script> </script>

View File

@ -138,70 +138,51 @@
</div> </div>
</template> </template>
<script> <script setup>
import { computed } from 'vue' import { ref, defineProps, computed } from 'vue'
import Dropdown from '~/components/global/Dropdown.vue' import Dropdown from '~/components/global/Dropdown.vue'
import FormTemplateModal from '../../../open/forms/components/templates/FormTemplateModal.vue' import FormTemplateModal from '../../../open/forms/components/templates/FormTemplateModal.vue'
export default { const { copy } = useClipboard()
name: 'ExtraMenu', const router = useRouter()
components: { Dropdown, FormTemplateModal },
props: { const props = defineProps({
form: { type: Object, required: true }, form: { type: Object, required: true },
isMainPage: { type: Boolean, required: false, default: false } isMainPage: { type: Boolean, required: false, default: false }
}, })
setup () {
const authStore = useAuthStore() const authStore = useAuthStore()
const formsStore = useFormsStore() const formsStore = useFormsStore()
return { const formEndpoint = '/open/forms/{id}'
formsStore, let user = computed(() => authStore.user)
user: computed(() => authStore.user),
useAlert: useAlert() let loadingDuplicate = ref(false)
let loadingDelete = ref(false)
let showDeleteFormModal = ref(false)
let showFormTemplateModal = ref(false)
const copyLink = () => {
copy(props.form.share_url)
useAlert().success('Copied!')
} }
}, const duplicateForm = () => {
if (loadingDuplicate.value) return
data: () => ({ loadingDuplicate.value = true
loadingDuplicate: false, opnFetch(formEndpoint.replace('{id}', props.form.id) + '/duplicate',{method: 'POST'}).then((data) => {
loadingDelete: false, formsStore.save(data.new_form)
showDeleteFormModal: false, router.push({ name: 'forms-slug-show', params: { slug: data.new_form.slug } })
showFormTemplateModal: false useAlert().success('Form was successfully duplicated.')
}), loadingDuplicate.value = false
computed: {
formEndpoint: () => '/open/forms/{id}'
},
methods: {
copyLink () {
const el = document.createElement('textarea')
el.value = this.form.share_url
document.body.appendChild(el)
el.select()
document.execCommand('copy')
document.body.removeChild(el)
this.useAlert.success('Copied!')
},
duplicateForm () {
if (this.loadingDuplicate) return
this.loadingDuplicate = true
opnFetch(this.formEndpoint.replace('{id}', this.form.id) + '/duplicate',{method: 'POST'}).then((data) => {
this.formsStore.save(data.new_form)
this.$router.push({ name: 'forms-show', params: { slug: data.new_form.slug } })
this.useAlert.success('Form was successfully duplicated.')
this.loadingDuplicate = false
})
},
deleteForm () {
if (this.loadingDelete) return
this.loadingDelete = true
opnFetch(this.formEndpoint.replace('{id}', this.form.id),{method:'DELETE'}).then(() => {
this.formsStore.remove(this.form)
this.$router.push({ name: 'home' })
this.useAlert.success('Form was deleted.')
this.loadingDelete = false
}) })
} }
} const deleteForm = () => {
if (loadingDelete.value) return
loadingDelete.value = true
opnFetch(formEndpoint.replace('{id}', props.form.id),{method:'DELETE'}).then(() => {
formsStore.remove(props.form)
router.push({ name: 'home' })
useAlert().success('Form was deleted.')
loadingDelete.value = false
})
} }
</script> </script>

View File

@ -205,6 +205,7 @@ defineRouteRules({
prerender: true prerender: true
}) })
const { copy } = useClipboard()
const authStore = useAuthStore() const authStore = useAuthStore()
const templatesStore = useTemplatesStore() const templatesStore = useTemplatesStore()
@ -255,13 +256,7 @@ const cleanQuotes = (str) => {
} }
const copyTemplateUrl = () => { const copyTemplateUrl = () => {
const str = template.value.share_url copy(template.value.share_url)
const el = document.createElement('textarea')
el.value = str
document.body.appendChild(el)
el.select()
document.execCommand('copy')
document.body.removeChild(el)
useAlert().success('Copied!') useAlert().success('Copied!')
} }