migrate to nuxt useClipboard (#268)
This commit is contained in:
parent
f87e3f1685
commit
2207c8cd90
|
@ -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,47 +21,28 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
export default {
|
import { defineProps } from 'vue'
|
||||||
name: 'CopyContent',
|
const { copy } = useClipboard()
|
||||||
props: {
|
|
||||||
content: {
|
const props = defineProps({
|
||||||
type: String,
|
content: {
|
||||||
required: true
|
type: String,
|
||||||
},
|
required: true
|
||||||
isDraft: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
isDraft: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
data() {
|
const copyToClipboard = () => {
|
||||||
return {}
|
if (process.server) return
|
||||||
},
|
copy(props.content)
|
||||||
|
if(props.isDraft){
|
||||||
computed: {},
|
useAlert().warning('Copied! But other people won\'t be able to see the form since it\'s currently in draft mode')
|
||||||
|
} else {
|
||||||
watch: {},
|
useAlert().success('Copied!')
|
||||||
|
|
||||||
mounted() {
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
copyToClipboard(str) {
|
|
||||||
if (process.server) return
|
|
||||||
const el = document.createElement('textarea')
|
|
||||||
el.value = str
|
|
||||||
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')
|
|
||||||
} else {
|
|
||||||
useAlert().success('Copied!')
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -17,72 +17,50 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
export default {
|
import { defineProps, computed } from 'vue'
|
||||||
name: 'FormUrlPrefill',
|
const { copy } = useClipboard()
|
||||||
props: {
|
|
||||||
form: {
|
const props = defineProps({
|
||||||
type: Object,
|
form: {
|
||||||
required: true
|
type: Object,
|
||||||
},
|
required: true
|
||||||
formData: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
extraQueryParam: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
formData: {
|
||||||
data () {
|
type: Object,
|
||||||
return {}
|
required: true
|
||||||
},
|
},
|
||||||
|
extraQueryParam: {
|
||||||
computed: {
|
type: String,
|
||||||
preFillUrl () {
|
default: ''
|
||||||
const url = this.form.share_url
|
|
||||||
const uriComponents = new URLSearchParams()
|
|
||||||
this.form.properties.filter((property) => {
|
|
||||||
return this.formData.hasOwnProperty(property.id) && this.formData[property.id] !== null
|
|
||||||
}).forEach((property) => {
|
|
||||||
if (Array.isArray(this.formData[property.id])) {
|
|
||||||
this.formData[property.id].forEach((value) => {
|
|
||||||
uriComponents.append(property.id + '[]', value)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uriComponents.append(property.id, this.formData[property.id])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if(uriComponents.toString() !== ""){
|
|
||||||
return (this.extraQueryParam) ? url + '?' + uriComponents + '&' + this.extraQueryParam : url + '?' + uriComponents
|
|
||||||
}else{
|
|
||||||
return (this.extraQueryParam) ? url + '?' + this.extraQueryParam : url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {},
|
|
||||||
|
|
||||||
mounted () {
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
getPropertyUriComponent (property) {
|
|
||||||
const prefillValue = encodeURIComponent(this.formData[property.id])
|
|
||||||
return encodeURIComponent(property.id) + '=' + prefillValue
|
|
||||||
},
|
|
||||||
copyToClipboard () {
|
|
||||||
if (process.server) return
|
|
||||||
const str = this.preFillUrl
|
|
||||||
const el = document.createElement('textarea')
|
|
||||||
el.value = str
|
|
||||||
document.body.appendChild(el)
|
|
||||||
el.select()
|
|
||||||
document.execCommand('copy')
|
|
||||||
document.body.removeChild(el)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const preFillUrl = computed(() => {
|
||||||
|
const url = props.form.share_url
|
||||||
|
const uriComponents = new URLSearchParams()
|
||||||
|
props.form.properties.filter((property) => {
|
||||||
|
return props.formData.hasOwnProperty(property.id) && props.formData[property.id] !== null
|
||||||
|
}).forEach((property) => {
|
||||||
|
if (Array.isArray(props.formData[property.id])) {
|
||||||
|
props.formData[property.id].forEach((value) => {
|
||||||
|
uriComponents.append(property.id + '[]', value)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uriComponents.append(property.id, props.formData[property.id])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if(uriComponents.toString() !== ""){
|
||||||
|
return (props.extraQueryParam) ? url + '?' + uriComponents + '&' + props.extraQueryParam : url + '?' + uriComponents
|
||||||
|
}else{
|
||||||
|
return (props.extraQueryParam) ? url + '?' + props.extraQueryParam : url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const copyToClipboard = () => {
|
||||||
|
if (process.server) return
|
||||||
|
copy(preFillUrl.value)
|
||||||
|
useAlert().success('Copied!')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -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,99 +101,87 @@
|
||||||
</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: shareUrl.value,
|
||||||
formurl: this.shareUrl,
|
emoji: advancedOptions.value.emoji,
|
||||||
emoji: this.advancedOptions.emoji,
|
position: advancedOptions.value.position,
|
||||||
position: this.advancedOptions.position,
|
bgcolor: advancedOptions.value.bgcolor,
|
||||||
bgcolor: this.advancedOptions.bgcolor,
|
width: advancedOptions.value.width
|
||||||
width: this.advancedOptions.width
|
}
|
||||||
}
|
previewPopup(nfData)
|
||||||
this.previewPopup(nfData)
|
return '<script async data-nf=\'' + JSON.stringify(nfData) + '\' src=\'' + embedScriptUrl + '\'></scrip' + 't>'
|
||||||
return '<script async data-nf=\'' + JSON.stringify(nfData) + '\' src=\'' + this.asset(this.embedScriptUrl) + '\'></scrip' + 't>'
|
})
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted () {
|
onMounted(() => {
|
||||||
this.advancedOptions.bgcolor = this.form.color
|
advancedOptions.value.bgcolor = props.form.color
|
||||||
},
|
})
|
||||||
|
|
||||||
methods: {
|
|
||||||
onClose () {
|
|
||||||
this.removePreview()
|
|
||||||
this.$crisp.push(['do', 'chat:show'])
|
|
||||||
this.showEmbedFormAsPopupModal = false
|
|
||||||
},
|
|
||||||
copyToClipboard () {
|
|
||||||
if (process.server) return
|
|
||||||
const str = this.embedPopupCode
|
|
||||||
const el = document.createElement('textarea')
|
|
||||||
el.value = str
|
|
||||||
document.body.appendChild(el)
|
|
||||||
el.select()
|
|
||||||
document.execCommand('copy')
|
|
||||||
document.body.removeChild(el)
|
|
||||||
},
|
|
||||||
removePreview () {
|
|
||||||
if (process.server) return
|
|
||||||
const oldP = document.head.querySelector('#nf-popup-preview')
|
|
||||||
if (oldP) {
|
|
||||||
oldP.remove()
|
|
||||||
}
|
|
||||||
const oldM = document.body.querySelector('.nf-main')
|
|
||||||
if (oldM) {
|
|
||||||
oldM.remove()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
previewPopup (nfData) {
|
|
||||||
if (process.server) return
|
|
||||||
if (!this.showEmbedFormAsPopupModal) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove old preview, if there
|
const onClose = () => {
|
||||||
this.removePreview()
|
removePreview()
|
||||||
|
crisp.showChat()
|
||||||
// Hide crisp
|
showEmbedFormAsPopupModal.value = false
|
||||||
this.$crisp.push(['do', 'chat:hide'])
|
}
|
||||||
|
const copyToClipboard = () => {
|
||||||
// Add new preview
|
if (process.server) return
|
||||||
const el = document.createElement('script')
|
copy(embedPopupCode.value)
|
||||||
el.id = 'nf-popup-preview'
|
useAlert().success('Copied!')
|
||||||
el.async = true
|
}
|
||||||
el.src = this.asset(this.embedScriptUrl)
|
const removePreview = () => {
|
||||||
el.setAttribute('data-nf', JSON.stringify(nfData))
|
if (process.server) return
|
||||||
document.head.appendChild(el)
|
const oldP = document.head.querySelector('#nf-popup-preview')
|
||||||
}
|
if (oldP) {
|
||||||
|
oldP.remove()
|
||||||
|
}
|
||||||
|
const oldM = document.body.querySelector('.nf-main')
|
||||||
|
if (oldM) {
|
||||||
|
oldM.remove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const previewPopup = (nfData) => {
|
||||||
|
if (process.server) return
|
||||||
|
if (!showEmbedFormAsPopupModal.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove old preview, if there
|
||||||
|
removePreview()
|
||||||
|
|
||||||
|
// Hide crisp
|
||||||
|
crisp.hideChat()
|
||||||
|
|
||||||
|
// Add new preview
|
||||||
|
const el = document.createElement('script')
|
||||||
|
el.id = 'nf-popup-preview'
|
||||||
|
el.async = true
|
||||||
|
el.src = embedScriptUrl
|
||||||
|
el.setAttribute('data-nf', JSON.stringify(nfData))
|
||||||
|
document.head.appendChild(el)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -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: {
|
|
||||||
form: { type: Object, required: true },
|
|
||||||
isMainPage: { type: Boolean, required: false, default: false }
|
|
||||||
},
|
|
||||||
|
|
||||||
setup () {
|
const props = defineProps({
|
||||||
const authStore = useAuthStore()
|
form: { type: Object, required: true },
|
||||||
const formsStore = useFormsStore()
|
isMainPage: { type: Boolean, required: false, default: false }
|
||||||
return {
|
})
|
||||||
formsStore,
|
|
||||||
user: computed(() => authStore.user),
|
|
||||||
useAlert: useAlert()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
data: () => ({
|
const authStore = useAuthStore()
|
||||||
loadingDuplicate: false,
|
const formsStore = useFormsStore()
|
||||||
loadingDelete: false,
|
const formEndpoint = '/open/forms/{id}'
|
||||||
showDeleteFormModal: false,
|
let user = computed(() => authStore.user)
|
||||||
showFormTemplateModal: false
|
|
||||||
}),
|
|
||||||
|
|
||||||
computed: {
|
let loadingDuplicate = ref(false)
|
||||||
formEndpoint: () => '/open/forms/{id}'
|
let loadingDelete = ref(false)
|
||||||
},
|
let showDeleteFormModal = ref(false)
|
||||||
|
let showFormTemplateModal = ref(false)
|
||||||
|
|
||||||
methods: {
|
const copyLink = () => {
|
||||||
copyLink () {
|
copy(props.form.share_url)
|
||||||
const el = document.createElement('textarea')
|
useAlert().success('Copied!')
|
||||||
el.value = this.form.share_url
|
}
|
||||||
document.body.appendChild(el)
|
const duplicateForm = () => {
|
||||||
el.select()
|
if (loadingDuplicate.value) return
|
||||||
document.execCommand('copy')
|
loadingDuplicate.value = true
|
||||||
document.body.removeChild(el)
|
opnFetch(formEndpoint.replace('{id}', props.form.id) + '/duplicate',{method: 'POST'}).then((data) => {
|
||||||
this.useAlert.success('Copied!')
|
formsStore.save(data.new_form)
|
||||||
},
|
router.push({ name: 'forms-slug-show', params: { slug: data.new_form.slug } })
|
||||||
duplicateForm () {
|
useAlert().success('Form was successfully duplicated.')
|
||||||
if (this.loadingDuplicate) return
|
loadingDuplicate.value = false
|
||||||
this.loadingDuplicate = true
|
})
|
||||||
opnFetch(this.formEndpoint.replace('{id}', this.form.id) + '/duplicate',{method: 'POST'}).then((data) => {
|
}
|
||||||
this.formsStore.save(data.new_form)
|
const deleteForm = () => {
|
||||||
this.$router.push({ name: 'forms-show', params: { slug: data.new_form.slug } })
|
if (loadingDelete.value) return
|
||||||
this.useAlert.success('Form was successfully duplicated.')
|
loadingDelete.value = true
|
||||||
this.loadingDuplicate = false
|
opnFetch(formEndpoint.replace('{id}', props.form.id),{method:'DELETE'}).then(() => {
|
||||||
})
|
formsStore.remove(props.form)
|
||||||
},
|
router.push({ name: 'home' })
|
||||||
deleteForm () {
|
useAlert().success('Form was deleted.')
|
||||||
if (this.loadingDelete) return
|
loadingDelete.value = false
|
||||||
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
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -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!')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue