Fixed the router, and editable div

This commit is contained in:
Julien Nahum 2023-10-16 12:54:51 +02:00
parent 3d3759c58c
commit 199a0190ad
9 changed files with 318 additions and 281 deletions

38
package-lock.json generated
View File

@ -38,7 +38,7 @@
"vue-signature-pad": "^2.0.5",
"vue2-editor": "^2.10.3",
"vue3-vt-notifications": "^1.0.0",
"vuedraggable": "^2.24.3",
"vuedraggable": "^4.1.0",
"vuex": "^4.1.0"
},
"devDependencies": {
@ -9940,9 +9940,9 @@
}
},
"node_modules/object-inspect": {
"version": "1.12.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.0.tgz",
"integrity": "sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
@ -10941,6 +10941,19 @@
"vue-class-component": "*"
}
},
"node_modules/query-builder-vue/node_modules/vuedraggable": {
"version": "2.24.3",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
"integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
"dependencies": {
"sortablejs": "1.10.2"
}
},
"node_modules/query-builder-vue/node_modules/vuedraggable/node_modules/sortablejs": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
"integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
},
"node_modules/query-string": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
@ -13986,17 +13999,20 @@
}
},
"node_modules/vuedraggable": {
"version": "2.24.3",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
"integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz",
"integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==",
"dependencies": {
"sortablejs": "1.10.2"
"sortablejs": "1.14.0"
},
"peerDependencies": {
"vue": "^3.0.1"
}
},
"node_modules/vuedraggable/node_modules/sortablejs": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
"integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
"integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w=="
},
"node_modules/vuex": {
"version": "4.1.0",

View File

@ -38,7 +38,7 @@
"vue-signature-pad": "^2.0.5",
"vue2-editor": "^2.10.3",
"vue3-vt-notifications": "^1.0.0",
"vuedraggable": "^2.24.3",
"vuedraggable": "^4.1.0",
"vuex": "^4.1.0"
},
"devDependencies": {

View File

@ -1,12 +1,11 @@
<template>
<div ref="parent"
<div ref="parentRef"
tabindex="0"
:class="{
'hover:bg-gray-100 dark:hover:bg-gray-800 rounded px-2 cursor-pointer': !editing
}"
class="relative"
:style="{height: editing?(divHeight+'px'):'auto'}"
:style="{ height: editing ? divHeight + 'px' : 'auto' }"
@focus="startEditing"
>
<slot v-if="!editing" :content="content">
@ -15,43 +14,59 @@
</label>
</slot>
<div v-if="editing" class="absolute inset-0 border-2 transition-colors"
:class="{'border-transparent':!editing,'border-blue-500':editing}">
<input ref="editinput" v-model="content"
:class="{ 'border-transparent': !editing, 'border-blue-500': editing }"
>
<input ref="editInputRef" v-model="content"
class="absolute inset-0 focus:outline-none bg-white transition-colors"
:class="[{'bg-blue-50':editing},contentClass]" @blur="editing = false" @keyup.enter="editing = false"
:class="[{'bg-blue-50': editing}, contentClass]" @blur="editing = false" @keyup.enter="editing = false"
@input="handleInput"
>
</div>
</div>
</template>
<script>
export default {
props: {
value: {required: true},
textAlign: {type: String, default: 'left'},
contentClass: {type: String | Object, default: ''}
},
<script setup>
import { ref, onMounted, watch, nextTick, defineProps, defineEmits } from 'vue'
data() {
return {
content: this.value,
editing: false,
divHeight: 0
const props = defineProps({
modelValue: { type: String, required: true },
textAlign: { type: String, default: 'left' },
contentClass: { type: String, default: '' }
})
const emit = defineEmits()
const content = ref(props.modelValue)
const editing = ref(false)
const divHeight = ref(0)
const parentRef = ref(null) // Ref for parent element
const editInputRef = ref(null) // Ref for edit input element
const startEditing = () => {
if (parentRef.value) {
divHeight.value = parentRef.value.offsetHeight
editing.value = true
nextTick(() => {
if (editInputRef.value) {
editInputRef.value.focus()
}
},
methods: {
startEditing() {
this.divHeight = this.$refs.parent.offsetHeight
this.editing = true
this.$nextTick(() => {
this.$refs.editinput.focus()
})
},
handleInput(e) {
this.$emit('input', this.content)
}
}
}
const handleInput = () => {
emit('update:modelValue', content.value)
}
// Watch for changes in props.modelValue and update the local content
watch(() => props.modelValue, (newValue) => {
content.value = newValue
})
// Wait until the component is mounted to set the initial divHeight
onMounted(() => {
if (parentRef.value) {
divHeight.value = parentRef.value.offsetHeight
}
})
</script>

View File

@ -6,21 +6,18 @@
</div>
<form v-else-if="dataForm" @submit.prevent="">
<transition name="fade" mode="out-in" appear>
<template v-for="group, groupIndex in fieldGroups">
<div v-if="currentFieldGroupIndex===groupIndex"
:key="groupIndex"
class="form-group flex flex-wrap w-full"
>
<div :key="currentFieldGroupIndex" class="form-group flex flex-wrap w-full">
<draggable v-model="currentFields"
item-key="id"
class="flex flex-wrap transition-all"
:class="{'-m-6 p-2 bg-gray-50 rounded-md':dragging}"
ghost-class="ghost-item"
handle=".draggable" :animation="200"
@start="onDragStart" @end="onDragEnd"
>
<open-form-field v-for="field in group"
:key="field.id + formVersionId"
:field="field"
<template #item="{element}">
<open-form-field
:field="element"
:show-hidden="showHidden"
:form="form"
:data-form="dataForm"
@ -28,9 +25,9 @@
:theme="theme"
:admin-preview="adminPreview"
/>
</template>
</draggable>
</div>
</template>
</transition>
<!-- Captcha -->
@ -71,6 +68,9 @@ import FormLogicPropertyResolver from '../../../forms/FormLogicPropertyResolver.
import OpenFormField from './OpenFormField.vue'
import draggable from 'vuedraggable'
import FormPendingSubmissionKey from '../../../mixins/forms/form-pending-submission-key.js'
draggable.compatConfig = { MODE: 3 }
const VueHcaptcha = () => import('@hcaptcha/vue3-hcaptcha')
export default {
@ -290,7 +290,9 @@ export default {
}
},
async getSubmissionData () {
if (!this.form || !this.form.editable_submissions || !this.form.submission_id) { return null }
if (!this.form || !this.form.editable_submissions || !this.form.submission_id) {
return null
}
await this.$store.dispatch('open/records/loadRecord',
axios.get('/api/forms/' + this.form.slug + '/submissions/' + this.form.submission_id).then((response) => {
return { submission_id: this.form.submission_id, ...response.data.data }

View File

@ -2,78 +2,90 @@
<div>
<v-button v-if="formFields && formFields.length > 8"
class="w-full mb-3" color="light-gray"
@click="openAddFieldSidebar">
@click="openAddFieldSidebar"
>
<svg class="w-4 h-4 text-nt-blue inline mr-1 -mt-1" viewBox="0 0 14 14" fill="none"
xmlns="http://www.w3.org/2000/svg">
xmlns="http://www.w3.org/2000/svg"
>
<path d="M7.00001 1.1665V12.8332M1.16667 6.99984H12.8333" stroke="currentColor" stroke-width="1.67"
stroke-linecap="round" stroke-linejoin="round"/>
stroke-linecap="round" stroke-linejoin="round"
/>
</svg>
Add block
</v-button>
<draggable v-model="formFields"
item-key="id"
class="bg-white overflow-hidden dark:bg-notion-dark-light rounded-md w-full mx-auto border transition-colors"
ghost-class="bg-gray-50" handle=".draggable" :animation="200"
ghost-class="bg-gray-50"
handle=".draggable"
:animation="200"
>
<div v-for="(field,index) in formFields" :key="field.id"
class="w-full mx-auto transition-colors"
:class="{'bg-gray-100 dark:bg-gray-800':field.hidden,'bg-white dark:bg-notion-dark-light':!field.hidden && !field.type==='nf-page-break', 'border-b': (index!== formFields.length -1), 'bg-blue-50 dark:bg-blue-900':field && field.type==='nf-page-break'}"
<template #item="{element, index}">
<div class="w-full mx-auto transition-colors"
:class="{'bg-gray-100 dark:bg-gray-800':element.hidden,'bg-white dark:bg-notion-dark-light':!element.hidden && !element.type==='nf-page-break', 'border-b': (index!== formFields.length -1), 'bg-blue-50 dark:bg-blue-900':element && element.type==='nf-page-break'}"
>
<div v-if="field" class="flex items-center space-x-1 group py-2 pr-4 relative">
<div v-if="element" class="flex items-center space-x-1 group py-2 pr-4 relative">
<!-- Drag handler -->
<div class="cursor-move draggable p-2 -mr-2">
<svg class="h-4 w-4 text-gray-400" viewBox="0 0 18 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.5 1.0835H16.5M1.5 6.91683H16.5" stroke="currentColor" stroke-width="1.67"
stroke-linecap="round" stroke-linejoin="round"/>
stroke-linecap="round" stroke-linejoin="round"
/>
</svg>
</div>
<!-- Field name and type -->
<div class="flex flex-col flex-grow truncate">
<editable-div class="max-w-full flex items-center" :value="field.name" @input="onChangeName(field, $event)">
<editable-div class="max-w-full flex items-center" :model-value="element.name"
@update:model-value="onChangeName(element, $event)"
>
<div class="cursor-pointer max-w-full truncate">
{{ field.name }}
{{ element.name }}
</div>
</editable-div>
<p class="text-xs text-gray-400 w-full truncate pl-2">
<span class="capitalize">{{ formatType(field) }}</span>
<span class="capitalize">{{ formatType(element) }}</span>
</p>
<template slot="popover">
<p class="text-white">
{{ field.name }}
</p>
</template>
</div>
<template v-if="removing == field.id">
<template v-if="removing == element.id">
<div class="flex text-sm items-center">
Remove block?
<v-button class="inline ml-1" color="red" size="small" @click="removeBlock(index)">Yes</v-button>
<v-button @click="removing=false" class="inline ml-1" color="light-gray" size="small">No</v-button>
<v-button class="inline ml-1" color="red" size="small" @click="removeBlock(index)">
Yes
</v-button>
<v-button class="inline ml-1" color="light-gray" size="small" @click="removing=false">
No
</v-button>
</div>
</template>
<template v-else>
<button class="hover:bg-red-50 text-gray-500 hover:text-red-600 rounded transition-colors cursor-pointer p-2 hidden md:group-hover:block"
@click="removing=field.id"
<button
class="hover:bg-red-50 text-gray-500 hover:text-red-600 rounded transition-colors cursor-pointer p-2 hidden md:group-hover:block"
@click="removing=element.id"
>
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M3 6H5M5 6H21M5 6V20C5 20.5304 5.21071 21.0391 5.58579 21.4142C5.96086 21.7893 6.46957 22 7 22H17C17.5304 22 18.0391 21.7893 18.4142 21.4142C18.7893 21.0391 19 20.5304 19 20V6H5ZM8 6V4C8 3.46957 8.21071 2.96086 8.58579 2.58579C8.96086 2.21071 9.46957 2 10 2H14C14.5304 2 15.0391 2.21071 15.4142 2.58579C15.7893 2.96086 16 3.46957 16 4V6M10 11V17M14 11V17"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
/>
</svg>
</button>
<button class="hover:bg-nt-blue-lighter rounded transition-colors cursor-pointer p-2 hidden"
:class="{'text-blue-500': !field.hidden, 'text-gray-500': field.hidden, 'group-hover:md:block': !field.hidden, 'md:block':field.hidden}"
@click="toggleHidden(field)"
:class="{'text-blue-500': !element.hidden, 'text-gray-500': element.hidden, 'group-hover:md:block': !element.hidden, 'md:block':element.hidden}"
@click="toggleHidden(element)"
>
<template v-if="!field.hidden">
<template v-if="!element.hidden">
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 12C1 12 5 4 12 4C19 4 23 12 23 12C23 12 19 20 12 20C5 20 1 12 1 12Z" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1 12C1 12 5 4 12 4C19 4 23 12 23 12C23 12 19 20 12 20C5 20 1 12 1 12Z"
stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
/>
<path
d="M12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
/>
</svg>
</template>
<template v-else>
@ -81,46 +93,52 @@
<g clip-path="url(#clip0_1027_7292)">
<path
d="M9.9 4.24C10.5883 4.07888 11.2931 3.99834 12 4C19 4 23 12 23 12C22.393 13.1356 21.6691 14.2047 20.84 15.19M14.12 14.12C13.8454 14.4147 13.5141 14.6512 13.1462 14.8151C12.7782 14.9791 12.3809 15.0673 11.9781 15.0744C11.5753 15.0815 11.1752 15.0074 10.8016 14.8565C10.4281 14.7056 10.0887 14.481 9.80385 14.1962C9.51897 13.9113 9.29439 13.5719 9.14351 13.1984C8.99262 12.8248 8.91853 12.4247 8.92563 12.0219C8.93274 11.6191 9.02091 11.2218 9.18488 10.8538C9.34884 10.4859 9.58525 10.1546 9.88 9.88M1 1L23 23M17.94 17.94C16.2306 19.243 14.1491 19.9649 12 20C5 20 1 12 1 12C2.24389 9.6819 3.96914 7.65661 6.06 6.06L17.94 17.94Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
/>
</g>
<defs>
<clipPath id="clip0_1027_7292">
<rect width="24" height="24" fill="white"/>
<rect width="24" height="24" fill="white" />
</clipPath>
</defs>
</svg>
</template>
</button>
<button v-if="!field.type.startsWith('nf-')"
<button v-if="!element.type.startsWith('nf-')"
class="hover:bg-nt-blue-lighter rounded transition-colors cursor-pointer p-2 hidden"
@click="toggleRequired(field)" :class="{'group-hover:md:block': !field.required, 'md:block':field.required}"
:class="{'group-hover:md:block': !element.required, 'md:block':element.required}"
@click="toggleRequired(element)"
>
<div class="w-4 h-4 text-center font-bold text-3xl"
:class="{'text-red-500': field.required, 'text-gray-500': !field.required}"
:class="{'text-red-500': element.required, 'text-gray-500': !element.required}"
>
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M12 2V12M12 12V22M12 12L4.93 4.93M12 12L19.07 19.07M12 12H2M12 12H22M12 12L4.93 19.07M12 12L19.07 4.93"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
/>
</svg>
</div>
</button>
<button class="hover:bg-nt-blue-lighter rounded transition-colors cursor-pointer p-2"
@click="editOptions(index)">
@click="editOptions(index)"
>
<svg class="h-4 w-4 text-blue-600" width="24" height="24" viewBox="0 0 24 24" fill="none"
xmlns="http://www.w3.org/2000/svg">
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_1027_7210)">
<path
d="M12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
/>
<path
d="M19.4 15C19.2669 15.3016 19.2272 15.6362 19.286 15.9606C19.3448 16.285 19.4995 16.5843 19.73 16.82L19.79 16.88C19.976 17.0657 20.1235 17.2863 20.2241 17.5291C20.3248 17.7719 20.3766 18.0322 20.3766 18.295C20.3766 18.5578 20.3248 18.8181 20.2241 19.0609C20.1235 19.3037 19.976 19.5243 19.79 19.71C19.6043 19.896 19.3837 20.0435 19.1409 20.1441C18.8981 20.2448 18.6378 20.2966 18.375 20.2966C18.1122 20.2966 17.8519 20.2448 17.6091 20.1441C17.3663 20.0435 17.1457 19.896 16.96 19.71L16.9 19.65C16.6643 19.4195 16.365 19.2648 16.0406 19.206C15.7162 19.1472 15.3816 19.1869 15.08 19.32C14.7842 19.4468 14.532 19.6572 14.3543 19.9255C14.1766 20.1938 14.0813 20.5082 14.08 20.83V21C14.08 21.5304 13.8693 22.0391 13.4942 22.4142C13.1191 22.7893 12.6104 23 12.08 23C11.5496 23 11.0409 22.7893 10.6658 22.4142C10.2907 22.0391 10.08 21.5304 10.08 21V20.91C10.0723 20.579 9.96512 20.258 9.77251 19.9887C9.5799 19.7194 9.31074 19.5143 9 19.4C8.69838 19.2669 8.36381 19.2272 8.03941 19.286C7.71502 19.3448 7.41568 19.4995 7.18 19.73L7.12 19.79C6.93425 19.976 6.71368 20.1235 6.47088 20.2241C6.22808 20.3248 5.96783 20.3766 5.705 20.3766C5.44217 20.3766 5.18192 20.3248 4.93912 20.2241C4.69632 20.1235 4.47575 19.976 4.29 19.79C4.10405 19.6043 3.95653 19.3837 3.85588 19.1409C3.75523 18.8981 3.70343 18.6378 3.70343 18.375C3.70343 18.1122 3.75523 17.8519 3.85588 17.6091C3.95653 17.3663 4.10405 17.1457 4.29 16.96L4.35 16.9C4.58054 16.6643 4.73519 16.365 4.794 16.0406C4.85282 15.7162 4.81312 15.3816 4.68 15.08C4.55324 14.7842 4.34276 14.532 4.07447 14.3543C3.80618 14.1766 3.49179 14.0813 3.17 14.08H3C2.46957 14.08 1.96086 13.8693 1.58579 13.4942C1.21071 13.1191 1 12.6104 1 12.08C1 11.5496 1.21071 11.0409 1.58579 10.6658C1.96086 10.2907 2.46957 10.08 3 10.08H3.09C3.42099 10.0723 3.742 9.96512 4.0113 9.77251C4.28059 9.5799 4.48572 9.31074 4.6 9C4.73312 8.69838 4.77282 8.36381 4.714 8.03941C4.65519 7.71502 4.50054 7.41568 4.27 7.18L4.21 7.12C4.02405 6.93425 3.87653 6.71368 3.77588 6.47088C3.67523 6.22808 3.62343 5.96783 3.62343 5.705C3.62343 5.44217 3.67523 5.18192 3.77588 4.93912C3.87653 4.69632 4.02405 4.47575 4.21 4.29C4.39575 4.10405 4.61632 3.95653 4.85912 3.85588C5.10192 3.75523 5.36217 3.70343 5.625 3.70343C5.88783 3.70343 6.14808 3.75523 6.39088 3.85588C6.63368 3.95653 6.85425 4.10405 7.04 4.29L7.1 4.35C7.33568 4.58054 7.63502 4.73519 7.95941 4.794C8.28381 4.85282 8.61838 4.81312 8.92 4.68H9C9.29577 4.55324 9.54802 4.34276 9.72569 4.07447C9.90337 3.80618 9.99872 3.49179 10 3.17V3C10 2.46957 10.2107 1.96086 10.5858 1.58579C10.9609 1.21071 11.4696 1 12 1C12.5304 1 13.0391 1.21071 13.4142 1.58579C13.7893 1.96086 14 2.46957 14 3V3.09C14.0013 3.41179 14.0966 3.72618 14.2743 3.99447C14.452 4.26276 14.7042 4.47324 15 4.6C15.3016 4.73312 15.6362 4.77282 15.9606 4.714C16.285 4.65519 16.5843 4.50054 16.82 4.27L16.88 4.21C17.0657 4.02405 17.2863 3.87653 17.5291 3.77588C17.7719 3.67523 18.0322 3.62343 18.295 3.62343C18.5578 3.62343 18.8181 3.67523 19.0609 3.77588C19.3037 3.87653 19.5243 4.02405 19.71 4.21C19.896 4.39575 20.0435 4.61632 20.1441 4.85912C20.2448 5.10192 20.2966 5.36217 20.2966 5.625C20.2966 5.88783 20.2448 6.14808 20.1441 6.39088C20.0435 6.63368 19.896 6.85425 19.71 7.04L19.65 7.1C19.4195 7.33568 19.2648 7.63502 19.206 7.95941C19.1472 8.28381 19.1869 8.61838 19.32 8.92V9C19.4468 9.29577 19.6572 9.54802 19.9255 9.72569C20.1938 9.90337 20.5082 9.99872 20.83 10H21C21.5304 10 22.0391 10.2107 22.4142 10.5858C22.7893 10.9609 23 11.4696 23 12C23 12.5304 22.7893 13.0391 22.4142 13.4142C22.0391 13.7893 21.5304 14 21 14H20.91C20.5882 14.0013 20.2738 14.0966 20.0055 14.2743C19.7372 14.452 19.5268 14.7042 19.4 15Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
/>
</g>
<defs>
<clipPath id="clip0_1027_7210">
<rect width="24" height="24" fill="white"/>
<rect width="24" height="24" fill="white" />
</clipPath>
</defs>
</svg>
@ -128,19 +146,22 @@
</template>
</div>
</div>
</template>
</draggable>
<v-button
class="w-full mt-3" color="light-gray"
@click="openAddFieldSidebar">
@click="openAddFieldSidebar"
>
<svg class="w-4 h-4 text-nt-blue inline mr-1 -mt-1" viewBox="0 0 14 14" fill="none"
xmlns="http://www.w3.org/2000/svg">
xmlns="http://www.w3.org/2000/svg"
>
<path d="M7.00001 1.1665V12.8332M1.16667 6.99984H12.8333" stroke="currentColor" stroke-width="1.67"
stroke-linecap="round" stroke-linejoin="round"/>
stroke-linecap="round" stroke-linejoin="round"
/>
</svg>
Add block
</v-button>
</div>
</template>
@ -149,8 +170,9 @@ import draggable from 'vuedraggable'
import ProTag from '../../../common/ProTag.vue'
import clonedeep from 'clone-deep'
import EditableDiv from '../../../common/EditableDiv.vue'
import VButton from "../../../common/Button.vue";
import VButton from '../../../common/Button.vue'
draggable.compatConfig = { MODE: 3 }
export default {
name: 'FormFieldsEditor',
components: {
@ -160,7 +182,7 @@ export default {
EditableDiv
},
data() {
data () {
return {
formFields: [],
removing: null
@ -169,11 +191,11 @@ export default {
computed: {
form: {
get() {
get () {
return this.$store.state['open/working_form'].content
},
/* We add a setter */
set(value) {
set (value) {
this.$store.commit('open/working_form/set', value)
}
}
@ -182,14 +204,14 @@ export default {
watch: {
formFields: {
deep: true,
handler() {
handler () {
this.$set(this.form, 'properties', this.formFields)
}
},
'form.properties':{
'form.properties': {
deep: true,
handler() {
handler () {
// If different, then update
if (this.form.properties.length !== this.formFields.length ||
JSON.stringify(this.form.properties) !== JSON.stringify(this.formFields)) {
@ -200,15 +222,15 @@ export default {
},
mounted() {
mounted () {
this.init()
},
methods: {
onChangeName(field, newName) {
onChangeName (field, newName) {
this.$set(field, 'name', newName)
},
toggleHidden(field) {
toggleHidden (field) {
this.$set(field, 'hidden', !field.hidden)
if (field.hidden) {
this.$set(field, 'required', false)
@ -217,37 +239,37 @@ export default {
this.$set(field, 'generates_auto_increment_id', false)
}
},
toggleRequired(field) {
toggleRequired (field) {
this.$set(field, 'required', !field.required)
if (field.required) {
this.$set(field, 'hidden', false)
}
},
getDefaultFields() {
getDefaultFields () {
return [
{
"name": "Name",
"type": "text",
"hidden": false,
"required": true,
"id": this.generateUUID(),
name: 'Name',
type: 'text',
hidden: false,
required: true,
id: this.generateUUID()
},
{
"name": "Email",
"type": "email",
"hidden": false,
"id": this.generateUUID(),
name: 'Email',
type: 'email',
hidden: false,
id: this.generateUUID()
},
{
"name": "Message",
"type": "text",
"hidden": false,
"multi_lines": true,
"id": this.generateUUID(),
name: 'Message',
type: 'text',
hidden: false,
multi_lines: true,
id: this.generateUUID()
}
];
]
},
init() {
init () {
if (this.$route.name === 'forms.create' || this.$route.name === 'forms.create.guest') { // Set Default fields
this.formFields = (this.form.properties.length > 0) ? clonedeep(this.form.properties) : this.getDefaultFields()
} else {
@ -263,7 +285,7 @@ export default {
}
this.$set(this.form, 'properties', this.formFields)
},
generateUUID() {
generateUUID () {
let d = new Date().getTime()// Timestamp
let d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now() * 1000)) || 0// Time in microseconds since page-load or 0 if unsupported
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
@ -278,7 +300,7 @@ export default {
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
})
},
formatType(field) {
formatType (field) {
let type = field.type.replace('_', ' ')
if (!type.startsWith('nf')) {
type = type + ' Input'
@ -290,29 +312,21 @@ export default {
}
return type
},
editOptions(index) {
editOptions (index) {
this.$store.commit('open/working_form/openSettingsForField', index)
},
removeBlock(blockIndex) {
removeBlock (blockIndex) {
const newFields = clonedeep(this.formFields)
newFields.splice(blockIndex, 1)
this.$set(this, 'formFields', newFields)
this.closeSidebar()
},
closeSidebar() {
closeSidebar () {
this.$store.commit('open/working_form/closeEditFieldSidebar')
},
openAddFieldSidebar() {
openAddFieldSidebar () {
this.$store.commit('open/working_form/openAddFieldSidebar', null)
}
}
}
</script>
<style lang="scss">
.v-popover {
.trigger {
@apply truncate w-full;
}
}
</style>

View File

@ -1,9 +1,9 @@
<template>
<collapse class="p-4 w-full border-b" v-model="isCollapseOpen">
<collapse v-model="isCollapseOpen" class="p-4 w-full border-b">
<template #title>
<h3 id="v-step-0" class="font-semibold text-lg">
<svg class="h-5 w-5 inline mr-2 -mt-1 transition-colors" :class="{'text-blue-600':isCollapseOpen, 'text-gray-500':!isCollapseOpen}" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 13.3332V9.99984M10 6.6665H10.0083M18.3333 9.99984C18.3333 14.6022 14.6024 18.3332 10 18.3332C5.39763 18.3332 1.66667 14.6022 1.66667 9.99984C1.66667 5.39746 5.39763 1.6665 10 1.6665C14.6024 1.6665 18.3333 5.39746 18.3333 9.99984Z" stroke="currentColor" stroke-width="1.67" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10 13.3332V9.99984M10 6.6665H10.0083M18.3333 9.99984C18.3333 14.6022 14.6024 18.3332 10 18.3332C5.39763 18.3332 1.66667 14.6022 1.66667 9.99984C1.66667 5.39746 5.39763 1.6665 10 1.6665C14.6024 1.6665 18.3333 5.39746 18.3333 9.99984Z" stroke="currentColor" stroke-width="1.67" stroke-linecap="round" stroke-linejoin="round" />
</svg>
Information
@ -19,27 +19,27 @@
label="Description"
:required="false"
/>
<select-input name="tags" label="Tags" :form="form" class="mt-3 mb-6"
<select-input name="tags" label="Tags" :form="form" class="mt-4"
help="To organize your forms (hidden to respondents)"
placeholder="Select Tag(s)" :multiple="true" :allowCreation="true"
placeholder="Select Tag(s)" :multiple="true" :allow-creation="true"
:options="allTagsOptions"
/>
<select-input name="visibility" label="Visibility" :form="form" class="mt-3 mb-6"
<select-input name="visibility" label="Visibility" :form="form" class="mt-4"
help="Only public form will be accessible"
placeholder="Select Visibility" :required="true"
:options="visibilityOptions"
/>
<v-button color="light-gray" class="w-full" v-if="copyFormOptions.length > 0" @click="showCopyFormSettingsModal=true">
<v-button v-if="copyFormOptions.length > 0" color="light-gray" class="w-full mt-4" @click="showCopyFormSettingsModal=true">
<svg class="h-5 w-5 -mt-1 text-nt-blue inline mr-2" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.16667 12.4998C3.3901 12.4998 3.00182 12.4998 2.69553 12.373C2.28715 12.2038 1.9627 11.8794 1.79354 11.471C1.66667 11.1647 1.66667 10.7764 1.66667 9.99984V4.33317C1.66667 3.39975 1.66667 2.93304 1.84833 2.57652C2.00812 2.26292 2.26308 2.00795 2.57669 1.84816C2.93321 1.6665 3.39992 1.6665 4.33334 1.6665H10C10.7766 1.6665 11.1649 1.6665 11.4711 1.79337C11.8795 1.96253 12.204 2.28698 12.3731 2.69536C12.5 3.00165 12.5 3.38993 12.5 4.1665M10.1667 18.3332H15.6667C16.6001 18.3332 17.0668 18.3332 17.4233 18.1515C17.7369 17.9917 17.9919 17.7368 18.1517 17.4232C18.3333 17.0666 18.3333 16.5999 18.3333 15.6665V10.1665C18.3333 9.23308 18.3333 8.76637 18.1517 8.40985C17.9919 8.09625 17.7369 7.84128 17.4233 7.68149C17.0668 7.49984 16.6001 7.49984 15.6667 7.49984H10.1667C9.23325 7.49984 8.76654 7.49984 8.41002 7.68149C8.09642 7.84128 7.84145 8.09625 7.68166 8.40985C7.50001 8.76637 7.50001 9.23308 7.50001 10.1665V15.6665C7.50001 16.5999 7.50001 17.0666 7.68166 17.4232C7.84145 17.7368 8.09642 17.9917 8.41002 18.1515C8.76654 18.3332 9.23325 18.3332 10.1667 18.3332Z" stroke="currentColor" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.16667 12.4998C3.3901 12.4998 3.00182 12.4998 2.69553 12.373C2.28715 12.2038 1.9627 11.8794 1.79354 11.471C1.66667 11.1647 1.66667 10.7764 1.66667 9.99984V4.33317C1.66667 3.39975 1.66667 2.93304 1.84833 2.57652C2.00812 2.26292 2.26308 2.00795 2.57669 1.84816C2.93321 1.6665 3.39992 1.6665 4.33334 1.6665H10C10.7766 1.6665 11.1649 1.6665 11.4711 1.79337C11.8795 1.96253 12.204 2.28698 12.3731 2.69536C12.5 3.00165 12.5 3.38993 12.5 4.1665M10.1667 18.3332H15.6667C16.6001 18.3332 17.0668 18.3332 17.4233 18.1515C17.7369 17.9917 17.9919 17.7368 18.1517 17.4232C18.3333 17.0666 18.3333 16.5999 18.3333 15.6665V10.1665C18.3333 9.23308 18.3333 8.76637 18.1517 8.40985C17.9919 8.09625 17.7369 7.84128 17.4233 7.68149C17.0668 7.49984 16.6001 7.49984 15.6667 7.49984H10.1667C9.23325 7.49984 8.76654 7.49984 8.41002 7.68149C8.09642 7.84128 7.84145 8.09625 7.68166 8.40985C7.50001 8.76637 7.50001 9.23308 7.50001 10.1665V15.6665C7.50001 16.5999 7.50001 17.0666 7.68166 17.4232C7.84145 17.7368 8.09642 17.9917 8.41002 18.1515C8.76654 18.3332 9.23325 18.3332 10.1667 18.3332Z" stroke="currentColor" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round" />
</svg>
Copy another form's settings
</v-button>
<modal :show="showCopyFormSettingsModal" @close="showCopyFormSettingsModal=false" max-width="md">
<modal :show="showCopyFormSettingsModal" max-width="md" @close="showCopyFormSettingsModal=false">
<template #icon>
<svg class="w-10 h-10 text-blue" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17 27C16.0681 27 15.6022 27 15.2346 26.8478C14.7446 26.6448 14.3552 26.2554 14.1522 25.7654C14 25.3978 14 24.9319 14 24V17.2C14 16.0799 14 15.5198 14.218 15.092C14.4097 14.7157 14.7157 14.4097 15.092 14.218C15.5198 14 16.0799 14 17.2 14H24C24.9319 14 25.3978 14 25.7654 14.1522C26.2554 14.3552 26.6448 14.7446 26.8478 15.2346C27 15.6022 27 16.0681 27 17M24.2 34H30.8C31.9201 34 32.4802 34 32.908 33.782C33.2843 33.5903 33.5903 33.2843 33.782 32.908C34 32.4802 34 31.9201 34 30.8V24.2C34 23.0799 34 22.5198 33.782 22.092C33.5903 21.7157 33.2843 21.4097 32.908 21.218C32.4802 21 31.9201 21 30.8 21H24.2C23.0799 21 22.5198 21 22.092 21.218C21.7157 21.4097 21.4097 21.7157 21.218 22.092C21 22.5198 21 23.0799 21 24.2V30.8C21 31.9201 21 32.4802 21.218 32.908C21.4097 33.2843 21.7157 33.5903 22.092 33.782C22.5198 34 23.0799 34 24.2 34Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M17 27C16.0681 27 15.6022 27 15.2346 26.8478C14.7446 26.6448 14.3552 26.2554 14.1522 25.7654C14 25.3978 14 24.9319 14 24V17.2C14 16.0799 14 15.5198 14.218 15.092C14.4097 14.7157 14.7157 14.4097 15.092 14.218C15.5198 14 16.0799 14 17.2 14H24C24.9319 14 25.3978 14 25.7654 14.1522C26.2554 14.3552 26.6448 14.7446 26.8478 15.2346C27 15.6022 27 16.0681 27 17M24.2 34H30.8C31.9201 34 32.4802 34 32.908 33.782C33.2843 33.5903 33.5903 33.2843 33.782 32.908C34 32.4802 34 31.9201 34 30.8V24.2C34 23.0799 34 22.5198 33.782 22.092C33.5903 21.7157 33.2843 21.4097 32.908 21.218C32.4802 21 31.9201 21 30.8 21H24.2C23.0799 21 22.5198 21 22.092 21.218C21.7157 21.4097 21.4097 21.7157 21.218 22.092C21 22.5198 21 23.0799 21 24.2V30.8C21 31.9201 21 32.4802 21.218 32.908C21.4097 33.2843 21.7157 33.5903 22.092 33.782C22.5198 34 23.0799 34 24.2 34Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</template>
<template #title>
@ -84,16 +84,16 @@ export default {
copyFormId: null,
visibilityOptions: [
{
name: "Public",
value: "public"
name: 'Public',
value: 'public'
},
{
name: "Draft (form won't be accessible)",
value: "draft"
value: 'draft'
},
{
name: "Closed",
value: "closed"
name: 'Closed',
value: 'closed'
}
],
isCollapseOpen: true

View File

@ -77,7 +77,8 @@
<div v-else-if="field.type == 'nf-code'" class="border-b py-2 px-4">
<code-input name="content" :form="field" label="Content"
help="You can add any html code, including iframes" />
help="You can add any html code, including iframes"
/>
</div>
<div v-else class="border-b py-2 px-4">
@ -85,17 +86,17 @@
</div>
<!-- Logic Block -->
<form-block-logic-editor class="py-2 px-4 border-b" :form="form" :field="field" v-model="form"/>
<form-block-logic-editor class="py-2 px-4 border-b" :form="form" :field="field" />
</div>
</template>
<script>
const FormBlockLogicEditor = () => import('../../components/form-logic-components/FormBlockLogicEditor.vue')
import CodeInput from '../../../../forms/CodeInput.vue'
const FormBlockLogicEditor = () => import('../../components/form-logic-components/FormBlockLogicEditor.vue')
export default {
name: 'BlockOptions',
components: {FormBlockLogicEditor, CodeInput},
components: { FormBlockLogicEditor, CodeInput },
props: {
field: {
type: Object,
@ -106,10 +107,10 @@ export default {
required: false
}
},
data() {
data () {
return {
editorToolbarCustom: [
['bold', 'italic', 'underline', 'link'],
['bold', 'italic', 'underline', 'link']
]
}
},
@ -141,17 +142,17 @@ export default {
}
},
mounted() {},
mounted () {},
methods: {
onFieldHiddenChange(val) {
onFieldHiddenChange (val) {
this.$set(this.field, 'hidden', val)
if (this.field.hidden) {
this.$set(this.field, 'required', false)
}
},
onFieldHelpPositionChange (val) {
if(!val){
if (!val) {
this.$set(this.field, 'help_position', 'below_input')
}
}

View File

@ -355,7 +355,7 @@
</div>
<!-- Logic Block -->
<form-block-logic-editor v-model="form" class="py-2 px-4 border-b" :form="form" :field="field" />
<form-block-logic-editor class="py-2 px-4 border-b" :form="form" :field="field" />
</div>
</template>

View File

@ -47,7 +47,7 @@ async function getMatchedComponents (to) {
*/
async function beforeEach (to, from, next) {
// Sentry tracking
if (window.config.sentry_dsn) {
if (false && window.config.sentry_dsn) {
Sentry.configureScope((scope) => scope.setTransactionName(to?.name || 'Unknown route name'))
}
@ -163,18 +163,6 @@ function parseMiddleware (middleware) {
return { middleware: name, params }
}
/**
* Resolve async components.
*
* @param {Array} components
* @return {Array}
*/
function resolveComponents (components) {
return Promise.all(components.map(component => {
return typeof component === 'function' ? component() : component
}))
}
/**
* Merge the the global middleware with the components middleware.
*
@ -222,18 +210,7 @@ function scrollBehavior (to, from, savedPosition) {
if (to.hash) {
return { selector: to.hash }
}
const [component] = getMatchedComponents(to)
if (component && component.scrollToTop === false) {
return {}
}
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ left: 0, top: 0 })
}, 190)
})
}
/**
@ -250,3 +227,15 @@ function resolveMiddleware (requireContext) {
})
return middlewares
}
/**
* Resolve async components.
*
* @param {Array} components
* @return {Array}
*/
function resolveComponents (components) {
return Promise.all(components.map(component => {
return typeof component === 'function' ? component() : component
}))
}