Refactor inpus
This commit is contained in:
parent
47653ebe64
commit
0eea59c5ba
|
@ -39,7 +39,7 @@
|
||||||
"vue-signature-pad": "^3.0.2",
|
"vue-signature-pad": "^3.0.2",
|
||||||
"vue3-editor": "^0.1.1",
|
"vue3-editor": "^0.1.1",
|
||||||
"vue3-vt-notifications": "^1.0.0",
|
"vue3-vt-notifications": "^1.0.0",
|
||||||
"vuedraggable": "^4.1.0"
|
"vuedraggable": "next"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.12",
|
"@babel/core": "^7.20.12",
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
"vue-signature-pad": "^3.0.2",
|
"vue-signature-pad": "^3.0.2",
|
||||||
"vue3-editor": "^0.1.1",
|
"vue3-editor": "^0.1.1",
|
||||||
"vue3-vt-notifications": "^1.0.0",
|
"vue3-vt-notifications": "^1.0.0",
|
||||||
"vuedraggable": "^4.1.0"
|
"vuedraggable": "next"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.12",
|
"@babel/core": "^7.20.12",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<a v-if="href" :class="btnClasses" :href="href" :target="target">
|
<a v-if="href" :class="btnClasses" :href="href" :target="target">
|
||||||
<slot />
|
<slot />
|
||||||
</a>
|
</a>
|
||||||
<button v-else-if="!to" :type="nativeType" :disabled="loading" :class="btnClasses"
|
<button v-else-if="!to" :type="nativeType" :disabled="loading?true:null" :class="btnClasses"
|
||||||
@click="onClick($event)"
|
@click="onClick($event)"
|
||||||
>
|
>
|
||||||
<template v-if="!loading">
|
<template v-if="!loading">
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper v-bind="$props">
|
<input-wrapper v-bind="inputWrapperProps">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span />
|
<span />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<v-checkbox :id="id?id:name" v-model="compVal" :disabled="disabled" :name="name">
|
<v-checkbox :id="id?id:name" v-model="compVal" :disabled="disabled?true:null" :name="name">
|
||||||
<slot name="label">
|
<slot name="label">
|
||||||
{{ label }} <span v-if="required" class="text-red-500 required-dot">*</span>
|
{{ label }} <span v-if="required" class="text-red-500 required-dot">*</span>
|
||||||
</slot>
|
</slot>
|
||||||
|
@ -34,18 +34,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
<div
|
<div
|
||||||
:class="[theme.CodeInput.input,{ '!ring-red-500 !ring-2': hasError, '!cursor-not-allowed !bg-gray-200':disabled }]"
|
:class="[theme.CodeInput.input,{ '!ring-red-500 !ring-2': hasError, '!cursor-not-allowed !bg-gray-200':disabled }]"
|
||||||
>
|
>
|
||||||
<codemirror :id="id?id:name" v-model="compVal" :disabled="disabled"
|
<codemirror :id="id?id:name" v-model="compVal" :disabled="disabled?true:null"
|
||||||
:options="cmOptions"
|
:options="cmOptions"
|
||||||
:style="inputStyle" :name="name"
|
:style="inputStyle" :name="name"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
|
@ -44,18 +44,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper v-bind="$props">
|
<input-wrapper v-bind="inputWrapperProps">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span />
|
<span />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<input :id="id?id:name" v-model="compVal" :disabled="disabled"
|
<input :id="id?id:name" v-model="compVal" :disabled="disabled?true:null"
|
||||||
type="color" class="mr-2"
|
type="color" class="mr-2"
|
||||||
:name="name"
|
:name="name"
|
||||||
>
|
>
|
||||||
|
@ -37,13 +37,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const { compVal, inputStyle, hasValidation, hasError } = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,36 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="flex" v-if="!dateRange">
|
<div v-if="!dateRange" class="flex">
|
||||||
<input :type="useTime ? 'datetime-local' : 'date'" :id="id?id:name" v-model="fromDate" :class="inputClasses"
|
<input :id="id?id:name" v-model="fromDate" :type="useTime ? 'datetime-local' : 'date'" :class="inputClasses"
|
||||||
:disabled="disabled"
|
:disabled="disabled?true:null"
|
||||||
:style="inputStyle" :name="name" data-date-format="YYYY-MM-DD"
|
:style="inputStyle" :name="name" data-date-format="YYYY-MM-DD"
|
||||||
:min="setMinDate" :max="setMaxDate"
|
:min="setMinDate" :max="setMaxDate"
|
||||||
/>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div :class="inputClasses" v-else>
|
<div v-else :class="inputClasses">
|
||||||
<div class="flex -mx-2">
|
<div class="flex -mx-2">
|
||||||
<p class="text-gray-900 px-4">From</p>
|
<p class="text-gray-900 px-4">
|
||||||
<input :type="useTime ? 'datetime-local' : 'date'" :id="id?id:name" v-model="fromDate" :disabled="disabled"
|
From
|
||||||
|
</p>
|
||||||
|
<input :id="id?id:name" v-model="fromDate" :type="useTime ? 'datetime-local' : 'date'" :disabled="disabled?true:null"
|
||||||
:style="inputStyle" :name="name" data-date-format="YYYY-MM-DD"
|
:style="inputStyle" :name="name" data-date-format="YYYY-MM-DD"
|
||||||
class="flex-grow border-transparent focus:outline-none "
|
class="flex-grow border-transparent focus:outline-none "
|
||||||
:min="setMinDate" :max="setMaxDate"
|
:min="setMinDate" :max="setMaxDate"
|
||||||
/>
|
>
|
||||||
<p class="text-gray-900 px-4">To</p>
|
<p class="text-gray-900 px-4">
|
||||||
<input v-if="dateRange" :type="useTime ? 'datetime-local' : 'date'" :id="id?id:name" v-model="toDate"
|
To
|
||||||
:disabled="disabled"
|
</p>
|
||||||
|
<input v-if="dateRange" :id="id?id:name" v-model="toDate" :type="useTime ? 'datetime-local' : 'date'"
|
||||||
|
:disabled="disabled?true:null"
|
||||||
:style="inputStyle" :name="name" class="flex-grow border-transparent focus:outline-none"
|
:style="inputStyle" :name="name" class="flex-grow border-transparent focus:outline-none"
|
||||||
:min="setMinDate" :max="setMaxDate"
|
:min="setMinDate" :max="setMaxDate"
|
||||||
/>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -42,7 +46,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { inputProps, useFormInput } from './useFormInput.js'
|
import { inputProps, useFormInput } from './useFormInput.js'
|
||||||
import InputWrapper from './components/InputWrapper.vue'
|
import InputWrapper from './components/InputWrapper.vue'
|
||||||
import {fixedClasses} from '../../plugins/config/vue-tailwind/datePicker.js'
|
import { fixedClasses } from '../../plugins/config/vue-tailwind/datePicker.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DateInput',
|
name: 'DateInput',
|
||||||
|
@ -51,25 +55,15 @@ export default {
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
...inputProps,
|
...inputProps,
|
||||||
withTime: {type: Boolean, default: false},
|
withTime: { type: Boolean, default: false },
|
||||||
dateRange: {type: Boolean, default: false},
|
dateRange: { type: Boolean, default: false },
|
||||||
disablePastDates: {type: Boolean, default: false},
|
disablePastDates: { type: Boolean, default: false },
|
||||||
disableFutureDates: {type: Boolean, default: false}
|
disableFutureDates: { type: Boolean, default: false }
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -80,22 +74,22 @@ export default {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
inputClasses() {
|
inputClasses () {
|
||||||
let str = 'border border-gray-300 dark:bg-notion-dark-light dark:border-gray-600 dark:placeholder-gray-500 dark:text-gray-300 flex-1 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-opacity-100 placeholder-gray-400 px-4 py-2 rounded-lg shadow-sm text-base text-black text-gray-700'
|
let str = 'border border-gray-300 dark:bg-notion-dark-light dark:border-gray-600 dark:placeholder-gray-500 dark:text-gray-300 flex-1 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-opacity-100 placeholder-gray-400 px-4 py-2 rounded-lg shadow-sm text-base text-black text-gray-700'
|
||||||
str += this.dateRange ? ' w-50' : ' w-full'
|
str += this.dateRange ? ' w-50' : ' w-full'
|
||||||
str += this.disabled ? ' !cursor-not-allowed !bg-gray-200' : ''
|
str += this.disabled ? ' !cursor-not-allowed !bg-gray-200' : ''
|
||||||
return str
|
return str
|
||||||
},
|
},
|
||||||
useTime() {
|
useTime () {
|
||||||
return this.withTime && !this.dateRange
|
return this.withTime && !this.dateRange
|
||||||
},
|
},
|
||||||
setMinDate() {
|
setMinDate () {
|
||||||
if (this.disablePastDates) {
|
if (this.disablePastDates) {
|
||||||
return new Date().toISOString().split('T')[0]
|
return new Date().toISOString().split('T')[0]
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
setMaxDate() {
|
setMaxDate () {
|
||||||
if (this.disableFutureDates) {
|
if (this.disableFutureDates) {
|
||||||
return new Date().toISOString().split('T')[0]
|
return new Date().toISOString().split('T')[0]
|
||||||
}
|
}
|
||||||
|
@ -105,16 +99,16 @@ export default {
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
color: {
|
color: {
|
||||||
handler() {
|
handler () {
|
||||||
this.setInputColor()
|
this.setInputColor()
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true
|
||||||
},
|
},
|
||||||
fromDate: {
|
fromDate: {
|
||||||
handler(val) {
|
handler (val) {
|
||||||
if (this.dateRange) {
|
if (this.dateRange) {
|
||||||
if (!Array.isArray(this.compVal)) {
|
if (!Array.isArray(this.compVal)) {
|
||||||
this.compVal = [];
|
this.compVal = []
|
||||||
}
|
}
|
||||||
this.compVal[0] = this.dateToUTC(val)
|
this.compVal[0] = this.dateToUTC(val)
|
||||||
} else {
|
} else {
|
||||||
|
@ -124,10 +118,10 @@ export default {
|
||||||
immediate: false
|
immediate: false
|
||||||
},
|
},
|
||||||
toDate: {
|
toDate: {
|
||||||
handler(val) {
|
handler (val) {
|
||||||
if (this.dateRange) {
|
if (this.dateRange) {
|
||||||
if (!Array.isArray(this.compVal)) {
|
if (!Array.isArray(this.compVal)) {
|
||||||
this.compVal = [null];
|
this.compVal = [null]
|
||||||
}
|
}
|
||||||
this.compVal[1] = this.dateToUTC(val)
|
this.compVal[1] = this.dateToUTC(val)
|
||||||
} else {
|
} else {
|
||||||
|
@ -138,7 +132,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted () {
|
||||||
if (this.compVal) {
|
if (this.compVal) {
|
||||||
if (Array.isArray(this.compVal)) {
|
if (Array.isArray(this.compVal)) {
|
||||||
this.fromDate = this.compVal[0] ?? null
|
this.fromDate = this.compVal[0] ?? null
|
||||||
|
@ -158,17 +152,17 @@ export default {
|
||||||
* @param event
|
* @param event
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
onEnterPress(event) {
|
onEnterPress (event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
setInputColor() {
|
setInputColor () {
|
||||||
if (this.$refs.datepicker) {
|
if (this.$refs.datepicker) {
|
||||||
const dateInput = this.$refs.datepicker.$el.getElementsByTagName('input')[0]
|
const dateInput = this.$refs.datepicker.$el.getElementsByTagName('input')[0]
|
||||||
dateInput.style.setProperty('--tw-ring-color', this.color)
|
dateInput.style.setProperty('--tw-ring-color', this.color)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dateToUTC(val) {
|
dateToUTC (val) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -177,7 +171,7 @@ export default {
|
||||||
}
|
}
|
||||||
return new Date(val).toISOString()
|
return new Date(val).toISOString()
|
||||||
},
|
},
|
||||||
dateToLocal(val) {
|
dateToLocal (val) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -187,7 +181,7 @@ export default {
|
||||||
String(dateObj.getDate()).padStart(2, '0')
|
String(dateObj.getDate()).padStart(2, '0')
|
||||||
if (this.useTime) {
|
if (this.useTime) {
|
||||||
dateStr += 'T' + String(dateObj.getHours()).padStart(2, '0') + ':' +
|
dateStr += 'T' + String(dateObj.getHours()).padStart(2, '0') + ':' +
|
||||||
String(dateObj.getMinutes()).padStart(2, '0');
|
String(dateObj.getMinutes()).padStart(2, '0')
|
||||||
}
|
}
|
||||||
return dateStr
|
return dateStr
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
|
@ -94,18 +94,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
|
@ -51,18 +51,8 @@ export default {
|
||||||
multiple: { type: Boolean, default: false }
|
multiple: { type: Boolean, default: false }
|
||||||
},
|
},
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
|
@ -71,10 +61,10 @@ export default {
|
||||||
computed: {},
|
computed: {},
|
||||||
methods: {
|
methods: {
|
||||||
onSelect (value) {
|
onSelect (value) {
|
||||||
if(this.disabled){
|
if (this.disabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.multiple) {
|
if (this.multiple) {
|
||||||
const emitValue = Array.isArray(this.compVal) ? [...this.compVal] : []
|
const emitValue = Array.isArray(this.compVal) ? [...this.compVal] : []
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
|
@ -121,18 +121,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -155,8 +145,8 @@ export default {
|
||||||
showUploadModal: {
|
showUploadModal: {
|
||||||
handler (val) {
|
handler (val) {
|
||||||
document.removeEventListener('paste', this.onUploadPasteEvent)
|
document.removeEventListener('paste', this.onUploadPasteEvent)
|
||||||
if(this.showUploadModal){
|
if (this.showUploadModal) {
|
||||||
document.addEventListener("paste", this.onUploadPasteEvent)
|
document.addEventListener('paste', this.onUploadPasteEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +166,7 @@ export default {
|
||||||
this.droppedFiles(e.dataTransfer.files)
|
this.droppedFiles(e.dataTransfer.files)
|
||||||
},
|
},
|
||||||
onUploadPasteEvent (e) {
|
onUploadPasteEvent (e) {
|
||||||
if(!this.showUploadModal) return
|
if (!this.showUploadModal) return
|
||||||
this.uploadDragoverEvent = false
|
this.uploadDragoverEvent = false
|
||||||
this.uploadDragoverTracking = false
|
this.uploadDragoverTracking = false
|
||||||
this.droppedFiles(e.clipboardData.files)
|
this.droppedFiles(e.clipboardData.files)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
<div :id="id ? id : name" :name="name" :style="inputStyle" class="flex items-center">
|
<div :id="id ? id : name" :name="name" :style="inputStyle" class="flex items-center">
|
||||||
<v-select v-model="selectedCountryCode" class="w-[130px]" dropdown-class="w-[300px]" input-class="rounded-r-none"
|
<v-select v-model="selectedCountryCode" class="w-[130px]" dropdown-class="w-[300px]" input-class="rounded-r-none"
|
||||||
:data="countries"
|
:data="countries"
|
||||||
:disabled="disabled || countries.length===1" :searchable="true" :search-keys="['name']" :option-key="'code'" :color="color"
|
:disabled="(disabled || countries.length===1)?true:null" :searchable="true" :search-keys="['name']" :option-key="'code'" :color="color"
|
||||||
:has-error="hasValidation && form.errors.has(name)"
|
:has-error="hasValidation && form.errors.has(name)"
|
||||||
:placeholder="'Select a country'" :uppercase-labels="true" :theme="theme" @update:model-value="onChangeCountryCode"
|
:placeholder="'Select a country'" :uppercase-labels="true" :theme="theme" @update:model-value="onChangeCountryCode"
|
||||||
>
|
>
|
||||||
|
@ -27,9 +27,9 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</v-select>
|
</v-select>
|
||||||
<input v-model="inputVal" type="text" class="inline-flex-grow !border-l-0 !rounded-l-none" :disabled="disabled"
|
<input v-model="inputVal" type="text" class="inline-flex-grow !border-l-0 !rounded-l-none" :disabled="disabled?true:null"
|
||||||
:class="[theme.default.input, { '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200': disabled }]"
|
:class="[theme.default.input, { '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200': disabled }]"
|
||||||
:placeholder="placeholder" :style="inputStyle" @update:model-value="onInput"
|
:placeholder="placeholder" :style="inputStyle" @update:model-value="onInput"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@
|
||||||
<template #error>
|
<template #error>
|
||||||
<slot name="error" />
|
<slot name="error" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</input-wrapper>
|
</input-wrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -61,18 +60,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<div class="stars-outer">
|
<div class="stars-outer">
|
||||||
<div v-for="i in numberOfStars" :key="i"
|
<div v-for="i in numberOfStars" :key="i"
|
||||||
class="cursor-pointer inline-block text-gray-200 dark:text-gray-800"
|
class="cursor-pointer inline-block text-gray-200 dark:text-gray-800"
|
||||||
|
@ -46,22 +45,11 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
hoverRating: -1
|
hoverRating: -1
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<vue-editor :id="id?id:name" ref="editor" v-model="compVal" :disabled="disabled"
|
<vue-editor :id="id?id:name" ref="editor" v-model="compVal" :disabled="disabled?true:null"
|
||||||
:placeholder="placeholder" :class="[{ '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled }, theme.RichTextAreaInput.input]"
|
:placeholder="placeholder" :class="[{ '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled }, theme.RichTextAreaInput.input]"
|
||||||
:editor-toolbar="editorToolbar" class="rich-editor resize-y"
|
:editor-toolbar="editorToolbar" class="rich-editor resize-y"
|
||||||
:style="inputStyle"
|
:style="inputStyle"
|
||||||
|
@ -41,25 +41,15 @@ export default {
|
||||||
[{ header: 1 }, { header: 2 }],
|
[{ header: 1 }, { header: 2 }],
|
||||||
['bold', 'italic', 'underline', 'link'],
|
['bold', 'italic', 'underline', 'link'],
|
||||||
[{ list: 'ordered' }, { list: 'bullet' }],
|
[{ list: 'ordered' }, { list: 'bullet' }],
|
||||||
[{color: []}]
|
[{ color: [] }]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
|
@ -41,18 +41,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -62,7 +52,7 @@ export default {
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
scaleList () {
|
scaleList () {
|
||||||
let list = []
|
const list = []
|
||||||
for (let i = this.minScale; i <= this.maxScale; i += this.stepScale) {
|
for (let i = this.minScale; i <= this.maxScale; i += this.stepScale) {
|
||||||
list.push(i)
|
list.push(i)
|
||||||
}
|
}
|
||||||
|
@ -89,7 +79,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted () {
|
mounted () {
|
||||||
if (this.compVal && typeof this.compVal === 'string'){
|
if (this.compVal && typeof this.compVal === 'string') {
|
||||||
this.compVal = parseInt(this.compVal)
|
this.compVal = parseInt(this.compVal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
:theme="theme"
|
:theme="theme"
|
||||||
:has-error="hasValidation && form.errors.has(name)"
|
:has-error="hasValidation && form.errors.has(name)"
|
||||||
:allow-creation="allowCreation"
|
:allow-creation="allowCreation"
|
||||||
:disabled="disabled"
|
:disabled="disabled?true:null"
|
||||||
:help="help"
|
:help="help"
|
||||||
:help-position="helpPosition"
|
:help-position="helpPosition"
|
||||||
|
|
||||||
|
@ -97,20 +97,11 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
additionalOptions: []
|
additionalOptions: []
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
<a :class="theme.default.help" href="#" @click.prevent="clear">Clear</a>
|
<a :class="theme.default.help" href="#" @click.prevent="clear">Clear</a>
|
||||||
</small>
|
</small>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #error>
|
<template #error>
|
||||||
<slot name="error" />
|
<slot name="error" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -39,18 +39,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<textarea :id="id?id:name" v-model="compVal" :disabled="disabled"
|
<textarea :id="id?id:name" v-model="compVal" :disabled="disabled?true:null"
|
||||||
:class="[theme.default.input,{ '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled }]"
|
:class="[theme.default.input,{ '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200':disabled }]"
|
||||||
class="resize-y"
|
class="resize-y"
|
||||||
:name="name" :style="inputStyle"
|
:name="name" :style="inputStyle"
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<template v-if="maxCharLimit && showCharLimit" #bottom_after_help>
|
<template v-if="maxCharLimit && showCharLimit" #bottom_after_help>
|
||||||
<small :class="theme.default.help">
|
<small :class="theme.default.help">
|
||||||
{{ charCount }}/{{ maxCharLimit }}
|
{{ charCount }}/{{ maxCharLimit }}
|
||||||
</small>
|
</small>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -38,25 +38,17 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
...inputProps,
|
...inputProps,
|
||||||
maxCharLimit: { type: Number, required: false, default: null },
|
maxCharLimit: { type: Number, required: false, default: null },
|
||||||
showCharLimit: { type: Boolean, required: false, default: false },
|
showCharLimit: { type: Boolean, required: false, default: false }
|
||||||
},
|
},
|
||||||
setup (props, context) {
|
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context)
|
|
||||||
|
|
||||||
|
setup (props, context) {
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
charCount() {
|
charCount () {
|
||||||
return (this.compVal) ? this.compVal.length : 0
|
return (this.compVal) ? this.compVal.length : 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper
|
<input-wrapper
|
||||||
v-bind="$props"
|
v-bind="inputWrapperProps"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<slot name="label" />
|
<slot name="label" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<input :id="id?id:name" v-model="compVal" :disabled="disabled"
|
<input :id="id?id:name" v-model="compVal" :disabled="disabled?true:null"
|
||||||
:type="nativeType"
|
:type="nativeType"
|
||||||
:pattern="pattern"
|
:pattern="pattern"
|
||||||
:style="inputStyle"
|
:style="inputStyle"
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
<template v-if="maxCharLimit && showCharLimit" #bottom_after_help>
|
<template v-if="maxCharLimit && showCharLimit" #bottom_after_help>
|
||||||
<small :class="theme.default.help">
|
<small :class="theme.default.help">
|
||||||
{{ charCount }}/{{ maxCharLimit }}
|
{{ charCount }}/{{ maxCharLimit }}
|
||||||
</small>
|
</small>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -48,13 +48,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const {
|
|
||||||
compVal,
|
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
} = useFormInput(props, context, props.nativeType === 'file' ? 'file-' : null)
|
|
||||||
|
|
||||||
const onChange = (event) => {
|
const onChange = (event) => {
|
||||||
if (props.nativeType !== 'file') return
|
if (props.nativeType !== 'file') return
|
||||||
|
|
||||||
|
@ -69,10 +62,9 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context, props.nativeType === 'file' ? 'file-' : null),
|
||||||
inputStyle,
|
onEnterPress,
|
||||||
hasValidation,
|
onChange
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<input-wrapper v-bind="$props">
|
<input-wrapper v-bind="inputWrapperProps">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span />
|
<span />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<v-switch :id="id?id:name" v-model="compVal" class="inline-block mr-2" :disabled="disabled" />
|
<v-switch :id="id?id:name" v-model="compVal" class="inline-block mr-2" :disabled="disabled?true:null" />
|
||||||
<slot name="label">
|
<slot name="label">
|
||||||
<span>{{ label }} <span v-if="required" class="text-red-500 required-dot">*</span></span>
|
<span>{{ label }} <span v-if="required" class="text-red-500 required-dot">*</span></span>
|
||||||
</slot>
|
</slot>
|
||||||
|
@ -34,13 +34,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const { compVal, inputStyle, hasValidation, hasError } = useFormInput(props, context)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
compVal,
|
...useFormInput(props, context)
|
||||||
inputStyle,
|
|
||||||
hasValidation,
|
|
||||||
hasError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,12 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
id: { type: String, required: false },
|
id: { type: String, required: false },
|
||||||
name: { type: String, required: false },
|
name: { type: String, required: false },
|
||||||
theme: { type: Object, required: true },
|
label: { type: String, required: false },
|
||||||
form: { type: Object, required: false },
|
form: { type: Object, required: false },
|
||||||
|
theme: { type: Object, required: true },
|
||||||
wrapperClass: { type: String, required: false },
|
wrapperClass: { type: String, required: false },
|
||||||
inputStyle: { type: Object, required: false },
|
inputStyle: { type: Object, required: false },
|
||||||
help: { type: String, required: false },
|
help: { type: String, required: false },
|
||||||
label: { type: String, required: false },
|
|
||||||
helpPosition: { type: String, default: 'below_input' },
|
helpPosition: { type: String, default: 'below_input' },
|
||||||
uppercaseLabels: { type: Boolean, default: true },
|
uppercaseLabels: { type: Boolean, default: true },
|
||||||
hideFieldName: { type: Boolean, default: true },
|
hideFieldName: { type: Boolean, default: true },
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
:class="sizeClasses"
|
:class="sizeClasses"
|
||||||
class="rounded border-gray-500 cursor-pointer"
|
class="rounded border-gray-500 cursor-pointer"
|
||||||
:disabled="disabled"
|
:disabled="disabled?true:null"
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
<label :for="id || name" class="text-gray-700 dark:text-gray-300 ml-2" :class="{'!cursor-not-allowed':disabled}">
|
<label :for="id || name" class="text-gray-700 dark:text-gray-300 ml-2" :class="{'!cursor-not-allowed':disabled}">
|
||||||
|
|
|
@ -6,6 +6,7 @@ export const inputProps = {
|
||||||
name: { type: String, required: true },
|
name: { type: String, required: true },
|
||||||
label: { type: String, required: false },
|
label: { type: String, required: false },
|
||||||
form: { type: Object, required: false },
|
form: { type: Object, required: false },
|
||||||
|
theme: { type: Object, default: () => themes.default },
|
||||||
modelValue: { required: false },
|
modelValue: { required: false },
|
||||||
required: { type: Boolean, default: false },
|
required: { type: Boolean, default: false },
|
||||||
disabled: { type: Boolean, default: false },
|
disabled: { type: Boolean, default: false },
|
||||||
|
@ -14,7 +15,6 @@ export const inputProps = {
|
||||||
hideFieldName: { type: Boolean, default: false },
|
hideFieldName: { type: Boolean, default: false },
|
||||||
help: { type: String, default: null },
|
help: { type: String, default: null },
|
||||||
helpPosition: { type: String, default: 'below_input' },
|
helpPosition: { type: String, default: 'below_input' },
|
||||||
theme: { type: Object, default: () => themes.default },
|
|
||||||
color: { type: String, default: '#3B82F6' },
|
color: { type: String, default: '#3B82F6' },
|
||||||
wrapperClass: { type: String, default: 'relative mb-3' }
|
wrapperClass: { type: String, default: 'relative mb-3' }
|
||||||
}
|
}
|
||||||
|
@ -58,11 +58,21 @@ export function useFormInput (props, context, formPrefixKey = null) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const inputWrapperProps = computed(() => {
|
||||||
|
const wrapperProps = {}
|
||||||
|
Object.keys(inputProps).forEach((key) => {
|
||||||
|
if (!['modelValue', 'disabled', 'placeholder', 'color'].includes(key)) {
|
||||||
|
wrapperProps[key] = props[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return wrapperProps
|
||||||
|
})
|
||||||
|
|
||||||
// Watch for changes in props.modelValue and update the local content
|
// Watch for changes in props.modelValue and update the local content
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (content.value !== newValue){
|
if (content.value !== newValue) {
|
||||||
content.value = newValue
|
content.value = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,6 +82,7 @@ export function useFormInput (props, context, formPrefixKey = null) {
|
||||||
compVal,
|
compVal,
|
||||||
inputStyle,
|
inputStyle,
|
||||||
hasValidation,
|
hasValidation,
|
||||||
hasError
|
hasError,
|
||||||
|
inputWrapperProps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<button :type="nativeType" :disabled="loading" :class="`py-${sizes['p-y']} px-${sizes['p-x']} text-${sizes['font']} ${theme.Button.body}`" :style="buttonStyle"
|
<button :type="nativeType" :disabled="loading?true:null" :class="`py-${sizes['p-y']} px-${sizes['p-x']} text-${sizes['font']} ${theme.Button.body}`" :style="buttonStyle"
|
||||||
class="btn" @click="$emit('click',$event)"
|
class="btn" @click="$emit('click',$event)"
|
||||||
>
|
>
|
||||||
<template v-if="!loading">
|
<template v-if="!loading">
|
||||||
|
|
|
@ -12,8 +12,9 @@
|
||||||
@click.prevent="openAddFieldSidebar"
|
@click.prevent="openAddFieldSidebar"
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="3"
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="3"
|
||||||
stroke="currentColor" class="w-5 h-5">
|
stroke="currentColor" class="w-5 h-5"
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/>
|
>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-2 text-gray-300 hover:text-blue-500 cursor-pointer" role="button"
|
<div class="p-2 text-gray-300 hover:text-blue-500 cursor-pointer" role="button"
|
||||||
|
@ -50,7 +51,7 @@
|
||||||
</div>
|
</div>
|
||||||
<component :is="getFieldComponents" v-if="getFieldComponents"
|
<component :is="getFieldComponents" v-if="getFieldComponents"
|
||||||
v-bind="inputProperties(field)" :required="isFieldRequired"
|
v-bind="inputProperties(field)" :required="isFieldRequired"
|
||||||
:disabled="isFieldDisabled"
|
:disabled="isFieldDisabled?true:null"
|
||||||
/>
|
/>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div v-if="field.type === 'nf-text' && field.content" :id="field.id" :key="field.id"
|
<div v-if="field.type === 'nf-text' && field.content" :id="field.id" :key="field.id"
|
||||||
|
@ -79,7 +80,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useWorkingFormStore } from '../../../stores/working_form';
|
import { useWorkingFormStore } from '../../../stores/working_form'
|
||||||
import FormLogicPropertyResolver from '../../../forms/FormLogicPropertyResolver.js'
|
import FormLogicPropertyResolver from '../../../forms/FormLogicPropertyResolver.js'
|
||||||
import FormPendingSubmissionKey from '../../../mixins/forms/form-pending-submission-key.js'
|
import FormPendingSubmissionKey from '../../../mixins/forms/form-pending-submission-key.js'
|
||||||
|
|
||||||
|
@ -112,24 +113,24 @@ export default {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
adminPreview: {type: Boolean, default: false} // If used in FormEditorPreview
|
adminPreview: { type: Boolean, default: false } // If used in FormEditorPreview
|
||||||
},
|
},
|
||||||
|
|
||||||
setup () {
|
setup () {
|
||||||
const workingFormStore = useWorkingFormStore()
|
const workingFormStore = useWorkingFormStore()
|
||||||
return {
|
return {
|
||||||
workingFormStore,
|
workingFormStore,
|
||||||
selectedFieldIndex : computed(() => workingFormStore.selectedFieldIndex),
|
selectedFieldIndex: computed(() => workingFormStore.selectedFieldIndex),
|
||||||
showEditFieldSidebar : computed(() => workingFormStore.showEditFieldSidebar)
|
showEditFieldSidebar: computed(() => workingFormStore.showEditFieldSidebar)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data () {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
fieldComponents() {
|
fieldComponents () {
|
||||||
return {
|
return {
|
||||||
text: 'TextInput',
|
text: 'TextInput',
|
||||||
number: 'TextInput',
|
number: 'TextInput',
|
||||||
|
@ -146,7 +147,7 @@ export default {
|
||||||
/**
|
/**
|
||||||
* Get the right input component for the field/options combination
|
* Get the right input component for the field/options combination
|
||||||
*/
|
*/
|
||||||
getFieldComponents() {
|
getFieldComponents () {
|
||||||
const field = this.field
|
const field = this.field
|
||||||
if (field.type === 'text' && field.multi_lines) {
|
if (field.type === 'text' && field.multi_lines) {
|
||||||
return 'TextAreaInput'
|
return 'TextAreaInput'
|
||||||
|
@ -174,27 +175,27 @@ export default {
|
||||||
}
|
}
|
||||||
return this.fieldComponents[field.type]
|
return this.fieldComponents[field.type]
|
||||||
},
|
},
|
||||||
isPublicFormPage() {
|
isPublicFormPage () {
|
||||||
return this.$route.name === 'forms.show_public'
|
return this.$route.name === 'forms.show_public'
|
||||||
},
|
},
|
||||||
isFieldHidden() {
|
isFieldHidden () {
|
||||||
return !this.showHidden && this.shouldBeHidden
|
return !this.showHidden && this.shouldBeHidden
|
||||||
},
|
},
|
||||||
shouldBeHidden() {
|
shouldBeHidden () {
|
||||||
return (new FormLogicPropertyResolver(this.field, this.dataFormValue)).isHidden()
|
return (new FormLogicPropertyResolver(this.field, this.dataFormValue)).isHidden()
|
||||||
},
|
},
|
||||||
isFieldRequired() {
|
isFieldRequired () {
|
||||||
return (new FormLogicPropertyResolver(this.field, this.dataFormValue)).isRequired()
|
return (new FormLogicPropertyResolver(this.field, this.dataFormValue)).isRequired()
|
||||||
},
|
},
|
||||||
isFieldDisabled() {
|
isFieldDisabled () {
|
||||||
return (new FormLogicPropertyResolver(this.field, this.dataFormValue)).isDisabled()
|
return (new FormLogicPropertyResolver(this.field, this.dataFormValue)).isDisabled()
|
||||||
},
|
},
|
||||||
beingEdited() {
|
beingEdited () {
|
||||||
return this.adminPreview && this.showEditFieldSidebar && this.form.properties.findIndex((item) => {
|
return this.adminPreview && this.showEditFieldSidebar && this.form.properties.findIndex((item) => {
|
||||||
return item.id === this.field.id
|
return item.id === this.field.id
|
||||||
}) === this.selectedFieldIndex
|
}) === this.selectedFieldIndex
|
||||||
},
|
},
|
||||||
selectionFieldsOptions() {
|
selectionFieldsOptions () {
|
||||||
// For auto update hidden options
|
// For auto update hidden options
|
||||||
let fieldsOptions = []
|
let fieldsOptions = []
|
||||||
|
|
||||||
|
@ -209,27 +210,27 @@ export default {
|
||||||
|
|
||||||
return fieldsOptions
|
return fieldsOptions
|
||||||
},
|
},
|
||||||
fieldSideBarOpened() {
|
fieldSideBarOpened () {
|
||||||
return this.adminPreview && (this.form && this.selectedFieldIndex !== null) ? (this.form.properties[this.selectedFieldIndex] && this.showEditFieldSidebar) : false
|
return this.adminPreview && (this.form && this.selectedFieldIndex !== null) ? (this.form.properties[this.selectedFieldIndex] && this.showEditFieldSidebar) : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {},
|
watch: {},
|
||||||
|
|
||||||
mounted() {
|
mounted () {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
editFieldOptions() {
|
editFieldOptions () {
|
||||||
this.workingFormStore.openSettingsForField(this.field)
|
this.workingFormStore.openSettingsForField(this.field)
|
||||||
},
|
},
|
||||||
openAddFieldSidebar() {
|
openAddFieldSidebar () {
|
||||||
this.workingFormStore.openAddFieldSidebar(this.field)
|
this.workingFormStore.openAddFieldSidebar(this.field)
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Get the right input component for the field/options combination
|
* Get the right input component for the field/options combination
|
||||||
*/
|
*/
|
||||||
getFieldClasses() {
|
getFieldClasses () {
|
||||||
let classes = ''
|
let classes = ''
|
||||||
if (this.adminPreview) {
|
if (this.adminPreview) {
|
||||||
classes += '-mx-4 px-4 -my-1 py-1 group/nffield relative transition-colors'
|
classes += '-mx-4 px-4 -my-1 py-1 group/nffield relative transition-colors'
|
||||||
|
@ -240,7 +241,7 @@ export default {
|
||||||
}
|
}
|
||||||
return classes
|
return classes
|
||||||
},
|
},
|
||||||
getFieldWidthClasses(field) {
|
getFieldWidthClasses (field) {
|
||||||
if (!field.width || field.width === 'full') return 'w-full px-2'
|
if (!field.width || field.width === 'full') return 'w-full px-2'
|
||||||
else if (field.width === '1/2') {
|
else if (field.width === '1/2') {
|
||||||
return 'w-full sm:w-1/2 px-2'
|
return 'w-full sm:w-1/2 px-2'
|
||||||
|
@ -254,7 +255,7 @@ export default {
|
||||||
return 'w-full sm:w-3/4 px-2'
|
return 'w-full sm:w-3/4 px-2'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getFieldAlignClasses(field) {
|
getFieldAlignClasses (field) {
|
||||||
if (!field.align || field.align === 'left') return 'text-left'
|
if (!field.align || field.align === 'left') return 'text-left'
|
||||||
else if (field.align === 'right') {
|
else if (field.align === 'right') {
|
||||||
return 'text-right'
|
return 'text-right'
|
||||||
|
@ -267,7 +268,7 @@ export default {
|
||||||
/**
|
/**
|
||||||
* Get the right input component options for the field/options
|
* Get the right input component options for the field/options
|
||||||
*/
|
*/
|
||||||
inputProperties(field) {
|
inputProperties (field) {
|
||||||
const inputProperties = {
|
const inputProperties = {
|
||||||
key: field.id,
|
key: field.id,
|
||||||
name: field.id,
|
name: field.id,
|
||||||
|
@ -277,7 +278,7 @@ export default {
|
||||||
placeholder: field.placeholder,
|
placeholder: field.placeholder,
|
||||||
help: field.help,
|
help: field.help,
|
||||||
helpPosition: (field.help_position) ? field.help_position : 'below_input',
|
helpPosition: (field.help_position) ? field.help_position : 'below_input',
|
||||||
uppercaseLabels: this.form.uppercase_labels == 1 || this.form.uppercase_labels == true,
|
uppercaseLabels: this.form.uppercase_labels == 1 || this.form.uppercase_labels == true,
|
||||||
theme: this.theme,
|
theme: this.theme,
|
||||||
maxCharLimit: (field.max_char_limit) ? parseInt(field.max_char_limit) : 2000,
|
maxCharLimit: (field.max_char_limit) ? parseInt(field.max_char_limit) : 2000,
|
||||||
showCharLimit: field.show_char_limit || false
|
showCharLimit: field.show_char_limit || false
|
||||||
|
@ -309,7 +310,7 @@ export default {
|
||||||
} else if (field.type === 'files' || (field.type === 'url' && field.file_upload)) {
|
} else if (field.type === 'files' || (field.type === 'url' && field.file_upload)) {
|
||||||
inputProperties.multiple = (field.multiple !== undefined && field.multiple)
|
inputProperties.multiple = (field.multiple !== undefined && field.multiple)
|
||||||
inputProperties.mbLimit = 5
|
inputProperties.mbLimit = 5
|
||||||
inputProperties.accept = (this.form.is_pro && field.allowed_file_types) ? field.allowed_file_types : ""
|
inputProperties.accept = (this.form.is_pro && field.allowed_file_types) ? field.allowed_file_types : ''
|
||||||
} else if (field.type === 'number' && field.is_rating) {
|
} else if (field.type === 'number' && field.is_rating) {
|
||||||
inputProperties.numberOfStars = parseInt(field.rating_max_value)
|
inputProperties.numberOfStars = parseInt(field.rating_max_value)
|
||||||
} else if (field.type === 'number' && field.is_scale) {
|
} else if (field.type === 'number' && field.is_scale) {
|
||||||
|
@ -323,7 +324,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
return inputProperties
|
return inputProperties
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</template>
|
</template>
|
||||||
<toggle-switch-input :value="value.hide_title" name="hide_title" class="mt-4"
|
<toggle-switch-input :value="value.hide_title" name="hide_title" class="mt-4"
|
||||||
label="Hide Form Title"
|
label="Hide Form Title"
|
||||||
:disabled="form.hide_title===true"
|
:disabled="(form.hide_title===true)?true:null"
|
||||||
:help="hideTitleHelp"
|
:help="hideTitleHelp"
|
||||||
@update:model-value="onChangeHideTitle"
|
@update:model-value="onChangeHideTitle"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
Submission confirmation
|
Submission confirmation
|
||||||
<pro-tag />
|
<pro-tag />
|
||||||
</h2>
|
</h2>
|
||||||
<toggle-switch-input :disabled="emailSubmissionConfirmationField===null" name="send_submission_confirmation"
|
<toggle-switch-input :disabled="(emailSubmissionConfirmationField===null)?true:null" name="send_submission_confirmation"
|
||||||
:form="form" class="mt-4"
|
:form="form" class="mt-4"
|
||||||
label="Send submission confirmation" :help="emailSubmissionConfirmationHelp"
|
label="Send submission confirmation" :help="emailSubmissionConfirmationHelp"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<template v-if="hasInput">
|
<template v-if="hasInput">
|
||||||
<component :is="inputComponentData.component" v-model="content.value" class="w-full"
|
<component v-bind="inputComponentData" :is="inputComponentData.component" v-model="content.value" class="w-full"
|
||||||
:name="'value_'+property.id" v-bind="inputComponentData" placeholder="Filter Value"
|
:name="'value_'+property.id" placeholder="Filter Value"
|
||||||
@input="$emit('input',castContent(content))"
|
@input="$emit('input',castContent(content))"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
@ -62,7 +62,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['select', 'multi_select'].includes(this.property.type)) {
|
if (['select', 'multi_select'].includes(this.property.type)) {
|
||||||
componentData.multiple = false;
|
componentData.multiple = false
|
||||||
componentData.options = this.property[this.property.type].options.map(option => {
|
componentData.options = this.property[this.property.type].options.map(option => {
|
||||||
return {
|
return {
|
||||||
name: option.name,
|
name: option.name,
|
||||||
|
@ -97,7 +97,7 @@ export default {
|
||||||
|
|
||||||
this.content.property_meta = {
|
this.content.property_meta = {
|
||||||
id: this.property.id,
|
id: this.property.id,
|
||||||
type: this.property.type,
|
type: this.property.type
|
||||||
}
|
}
|
||||||
this.isMounted = true
|
this.isMounted = true
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
option-key="identifier"
|
option-key="identifier"
|
||||||
name="group-control-slot-rule"
|
name="group-control-slot-rule"
|
||||||
/>
|
/>
|
||||||
<v-button class="ml-1 mt-1" color="blue" size="small" :disabled="selectedRule === ''" @click="addRule">
|
<v-button class="ml-1 mt-1" color="blue" size="small" :disabled="(selectedRule === '')?true:null" @click="addRule">
|
||||||
Add Condition
|
Add Condition
|
||||||
</v-button>
|
</v-button>
|
||||||
<v-button class="ml-1 mt-1" color="outline-blue" size="small" @click="groupCtrl.newGroup">
|
<v-button class="ml-1 mt-1" color="outline-blue" size="small" @click="groupCtrl.newGroup">
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<modal :show="show" @close="$emit('close')" :closeable="!aiForm.busy">
|
<modal :show="show" :closeable="!aiForm.busy" @close="$emit('close')">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<template v-if="state=='default'">
|
<template v-if="state=='default'">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-10 h-10 text-blue">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-10 h-10 text-blue">
|
||||||
<path fill-rule="evenodd"
|
<path fill-rule="evenodd"
|
||||||
d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"
|
d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"
|
||||||
clip-rule="evenodd"/>
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="state=='ai'">
|
<template v-else-if="state=='ai'">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
|
||||||
<path fill-rule="evenodd"
|
<path fill-rule="evenodd"
|
||||||
d="M14.615 1.595a.75.75 0 01.359.852L12.982 9.75h7.268a.75.75 0 01.548 1.262l-10.5 11.25a.75.75 0 01-1.272-.71l1.992-7.302H3.75a.75.75 0 01-.548-1.262l10.5-11.25a.75.75 0 01.913-.143z"
|
d="M14.615 1.595a.75.75 0 01.359.852L12.982 9.75h7.268a.75.75 0 01.548 1.262l-10.5 11.25a.75.75 0 01-1.272-.71l1.992-7.302H3.75a.75.75 0 01-.548-1.262l10.5-11.25a.75.75 0 01.913-.143z"
|
||||||
clip-rule="evenodd"/>
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -24,38 +26,48 @@
|
||||||
AI-powered form generator
|
AI-powered form generator
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-8" v-if="state=='default'">
|
<div v-if="state=='default'" class="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-8">
|
||||||
<div class="rounded-md border p-4 flex flex-col items-center cursor-pointer hover:bg-gray-50"
|
<div v-track.select_form_base="{base:'contact-form'}"
|
||||||
@click="$emit('close')" v-track.select_form_base="{base:'contact-form'}">
|
class="rounded-md border p-4 flex flex-col items-center cursor-pointer hover:bg-gray-50" @click="$emit('close')"
|
||||||
|
>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
|
||||||
<path d="M1.5 8.67v8.58a3 3 0 003 3h15a3 3 0 003-3V8.67l-8.928 5.493a3 3 0 01-3.144 0L1.5 8.67z"/>
|
<path d="M1.5 8.67v8.58a3 3 0 003 3h15a3 3 0 003-3V8.67l-8.928 5.493a3 3 0 01-3.144 0L1.5 8.67z" />
|
||||||
<path d="M22.5 6.908V6.75a3 3 0 00-3-3h-15a3 3 0 00-3 3v.158l9.714 5.978a1.5 1.5 0 001.572 0L22.5 6.908z"/>
|
<path d="M22.5 6.908V6.75a3 3 0 00-3-3h-15a3 3 0 00-3 3v.158l9.714 5.978a1.5 1.5 0 001.572 0L22.5 6.908z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="font-medium">Start from a simple contact form</p>
|
<p class="font-medium">
|
||||||
|
Start from a simple contact form
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="aiFeaturesEnabled" v-track.select_form_base="{base:'ai'}"
|
<div v-if="aiFeaturesEnabled" v-track.select_form_base="{base:'ai'}"
|
||||||
class="rounded-md border p-4 flex flex-col items-center cursor-pointer hover:bg-gray-50" @click="state='ai'">
|
class="rounded-md border p-4 flex flex-col items-center cursor-pointer hover:bg-gray-50" @click="state='ai'"
|
||||||
|
>
|
||||||
<div class="p-4 relative">
|
<div class="p-4 relative">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
|
||||||
<path fill-rule="evenodd"
|
<path fill-rule="evenodd"
|
||||||
d="M14.615 1.595a.75.75 0 01.359.852L12.982 9.75h7.268a.75.75 0 01.548 1.262l-10.5 11.25a.75.75 0 01-1.272-.71l1.992-7.302H3.75a.75.75 0 01-.548-1.262l10.5-11.25a.75.75 0 01.913-.143z"
|
d="M14.615 1.595a.75.75 0 01.359.852L12.982 9.75h7.268a.75.75 0 01.548 1.262l-10.5 11.25a.75.75 0 01-1.272-.71l1.992-7.302H3.75a.75.75 0 01-.548-1.262l10.5-11.25a.75.75 0 01.913-.143z"
|
||||||
clip-rule="evenodd"/>
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="font-medium text-blue-700">Use our AI to create the form</p>
|
<p class="font-medium text-blue-700">
|
||||||
|
Use our AI to create the form
|
||||||
|
</p>
|
||||||
<span class="text-xs text-gray-500">(1 min)</span>
|
<span class="text-xs text-gray-500">(1 min)</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="rounded-md border p-4 flex flex-col items-center cursor-pointer hover:bg-gray-50 relative">
|
<div class="rounded-md border p-4 flex flex-col items-center cursor-pointer hover:bg-gray-50 relative">
|
||||||
<div class="p-4 relative">
|
<div class="p-4 relative">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
|
||||||
<path
|
<path
|
||||||
d="M11.25 5.337c0-.355-.186-.676-.401-.959a1.647 1.647 0 01-.349-1.003c0-1.036 1.007-1.875 2.25-1.875S15 2.34 15 3.375c0 .369-.128.713-.349 1.003-.215.283-.401.604-.401.959 0 .332.278.598.61.578 1.91-.114 3.79-.342 5.632-.676a.75.75 0 01.878.645 49.17 49.17 0 01.376 5.452.657.657 0 01-.66.664c-.354 0-.675-.186-.958-.401a1.647 1.647 0 00-1.003-.349c-1.035 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401.31 0 .557.262.534.571a48.774 48.774 0 01-.595 4.845.75.75 0 01-.61.61c-1.82.317-3.673.533-5.555.642a.58.58 0 01-.611-.581c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.035-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959a.641.641 0 01-.658.643 49.118 49.118 0 01-4.708-.36.75.75 0 01-.645-.878c.293-1.614.504-3.257.629-4.924A.53.53 0 005.337 15c-.355 0-.676.186-.959.401-.29.221-.634.349-1.003.349-1.036 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.369 0 .713.128 1.003.349.283.215.604.401.959.401a.656.656 0 00.659-.663 47.703 47.703 0 00-.31-4.82.75.75 0 01.83-.832c1.343.155 2.703.254 4.077.294a.64.64 0 00.657-.642z"/>
|
d="M11.25 5.337c0-.355-.186-.676-.401-.959a1.647 1.647 0 01-.349-1.003c0-1.036 1.007-1.875 2.25-1.875S15 2.34 15 3.375c0 .369-.128.713-.349 1.003-.215.283-.401.604-.401.959 0 .332.278.598.61.578 1.91-.114 3.79-.342 5.632-.676a.75.75 0 01.878.645 49.17 49.17 0 01.376 5.452.657.657 0 01-.66.664c-.354 0-.675-.186-.958-.401a1.647 1.647 0 00-1.003-.349c-1.035 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401.31 0 .557.262.534.571a48.774 48.774 0 01-.595 4.845.75.75 0 01-.61.61c-1.82.317-3.673.533-5.555.642a.58.58 0 01-.611-.581c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.035-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959a.641.641 0 01-.658.643 49.118 49.118 0 01-4.708-.36.75.75 0 01-.645-.878c.293-1.614.504-3.257.629-4.924A.53.53 0 005.337 15c-.355 0-.676.186-.959.401-.29.221-.634.349-1.003.349-1.036 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.369 0 .713.128 1.003.349.283.215.604.401.959.401a.656.656 0 00.659-.663 47.703 47.703 0 00-.31-4.82.75.75 0 01.83-.832c1.343.155 2.703.254 4.077.294a.64.64 0 00.657-.642z"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="font-medium">Start from a template</p>
|
<p class="font-medium">
|
||||||
<router-link :to="{name:'templates'}" v-track.select_form_base="{base:'template'}" class="absolute inset-0"/>
|
Start from a template
|
||||||
|
</p>
|
||||||
|
<router-link v-track.select_form_base="{base:'template'}" :to="{name:'templates'}" class="absolute inset-0" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="state=='ai'">
|
<div v-else-if="state=='ai'">
|
||||||
|
@ -65,26 +77,29 @@
|
||||||
</svg>
|
</svg>
|
||||||
Back
|
Back
|
||||||
</a>
|
</a>
|
||||||
<text-area-input label="Form Description" :disabled="loading" :form="aiForm" name="form_prompt" help="Give us a description of the form you want to build (the more details the better)"
|
<text-area-input label="Form Description" :disabled="loading?true:null" :form="aiForm" name="form_prompt" help="Give us a description of the form you want to build (the more details the better)"
|
||||||
placeholder="A simple contact form, with a name, email and message field" />
|
placeholder="A simple contact form, with a name, email and message field"
|
||||||
<v-button class="w-full" @click.prevent="generateForm" :loading="loading">
|
/>
|
||||||
|
<v-button class="w-full" :loading="loading" @click.prevent="generateForm">
|
||||||
Generate a form
|
Generate a form
|
||||||
</v-button>
|
</v-button>
|
||||||
<p class="text-gray-500 text-xs text-center mt-1">~60 sec</p>
|
<p class="text-gray-500 text-xs text-center mt-1">
|
||||||
|
~60 sec
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</modal>
|
</modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Loader from "../../../common/Loader.vue";
|
import Loader from '../../../common/Loader.vue'
|
||||||
import Form from "vform";
|
import Form from 'vform'
|
||||||
import axios from "axios";
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CreateFormBaseModal',
|
name: 'CreateFormBaseModal',
|
||||||
components: {Loader},
|
components: { Loader },
|
||||||
props: {
|
props: {
|
||||||
show: {type: Boolean, required: true},
|
show: { type: Boolean, required: true }
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
|
@ -92,17 +107,17 @@ export default {
|
||||||
aiForm: new Form({
|
aiForm: new Form({
|
||||||
form_prompt: ''
|
form_prompt: ''
|
||||||
}),
|
}),
|
||||||
loading: false,
|
loading: false
|
||||||
}),
|
}),
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
aiFeaturesEnabled() {
|
aiFeaturesEnabled () {
|
||||||
return window.config.ai_features_enabled
|
return window.config.ai_features_enabled
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
generateForm() {
|
generateForm () {
|
||||||
if (this.loading) return
|
if (this.loading) return
|
||||||
|
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
@ -115,7 +130,7 @@ export default {
|
||||||
this.state = 'default'
|
this.state = 'default'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
fetchGeneratedForm(generationId) {
|
fetchGeneratedForm (generationId) {
|
||||||
// check every 4 seconds if form is generated
|
// check every 4 seconds if form is generated
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
axios.get('/api/forms/ai/' + generationId).then(response => {
|
axios.get('/api/forms/ai/' + generationId).then(response => {
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
<div class="border-t mt-4 -mx-4" />
|
<div class="border-t mt-4 -mx-4" />
|
||||||
<toggle-switch-input v-model="advancedOptions.hide_title" name="hide_title" class="mt-4"
|
<toggle-switch-input v-model="advancedOptions.hide_title" name="hide_title" class="mt-4"
|
||||||
label="Hide Form Title"
|
label="Hide Form Title"
|
||||||
:disabled="form.hide_title===true"
|
:disabled="(form.hide_title===true)?true:null"
|
||||||
:help="hideTitleHelp"
|
:help="hideTitleHelp"
|
||||||
/>
|
/>
|
||||||
<color-input v-model="advancedOptions.bgcolor" name="bgcolor" class="mt-4"
|
<color-input v-model="advancedOptions.bgcolor" name="bgcolor" class="mt-4"
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
<modal :show="show" max-width="lg" @close="close">
|
<modal :show="show" max-width="lg" @close="close">
|
||||||
<text-input ref="companyName" label="Company Name" name="name" :required="true" :form="form" help="Name that will appear on invoices" />
|
<text-input ref="companyName" label="Company Name" name="name" :required="true" :form="form" help="Name that will appear on invoices" />
|
||||||
<text-input label="Email" name="email" native-type="email" :required="true" :form="form" help="Where invoices will be sent" />
|
<text-input label="Email" name="email" native-type="email" :required="true" :form="form" help="Where invoices will be sent" />
|
||||||
<v-button :loading="form.busy || loading" :disabled="form.busy || loading" class="mt-6 block mx-auto"
|
<v-button :loading="form.busy || loading" :disabled="(form.busy || loading)?true:null" class="mt-6 block mx-auto"
|
||||||
@click="saveDetails" :arrow="true"
|
:arrow="true" @click="saveDetails"
|
||||||
>
|
>
|
||||||
Go to checkout
|
Go to checkout
|
||||||
</v-button>
|
</v-button>
|
||||||
|
@ -38,7 +38,7 @@ export default {
|
||||||
setup () {
|
setup () {
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
return {
|
return {
|
||||||
user : computed(() => authStore.user)
|
user: computed(() => authStore.user)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -50,6 +50,8 @@ export default {
|
||||||
loading: false
|
loading: false
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
computed: {},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
user () {
|
user () {
|
||||||
this.updateUser()
|
this.updateUser()
|
||||||
|
@ -71,7 +73,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
updateUser() {
|
updateUser () {
|
||||||
if (this.user) {
|
if (this.user) {
|
||||||
this.form.name = this.user.name
|
this.form.name = this.user.name
|
||||||
this.form.email = this.user.email
|
this.form.email = this.user.email
|
||||||
|
@ -94,8 +96,6 @@ export default {
|
||||||
close () {
|
close () {
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
computed: {}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
<div class="flex bg-gray-50">
|
<div class="flex bg-gray-50">
|
||||||
<div class="w-full md:w-4/5 lg:w-3/5 md:mx-auto md:max-w-4xl px-4">
|
<div class="w-full md:w-4/5 lg:w-3/5 md:mx-auto md:max-w-4xl px-4">
|
||||||
<div class="pt-4 pb-0">
|
<div class="pt-4 pb-0">
|
||||||
<a href="#" @click.prevent="goBack" class="flex text-blue mb-2 font-semibold text-sm">
|
<a href="#" class="flex text-blue mb-2 font-semibold text-sm" @click.prevent="goBack">
|
||||||
<svg class="w-3 h-3 text-blue mt-1 mr-1" viewBox="0 0 6 10" fill="none"
|
<svg class="w-3 h-3 text-blue mt-1 mr-1" viewBox="0 0 6 10" fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
<path d="M5 9L1 5L5 1" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
|
<path d="M5 9L1 5L5 1" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
|
||||||
stroke-linejoin="round"/>
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
Go back
|
Go back
|
||||||
</a>
|
</a>
|
||||||
|
@ -20,24 +22,30 @@
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<extra-menu :form="form" />
|
<extra-menu :form="form" />
|
||||||
|
|
||||||
<v-button target="_blank" :to="{name:'forms.show_public', params: {slug: form.slug}}"
|
<v-button v-track.view_form_click="{form_id:form.id, form_slug:form.slug}" target="_blank"
|
||||||
color="white" class="mr-2 text-blue-600 hidden sm:block"
|
:to="{name:'forms.show_public', params: {slug: form.slug}}" color="white"
|
||||||
v-track.view_form_click="{form_id:form.id, form_slug:form.slug}">
|
class="mr-2 text-blue-600 hidden sm:block"
|
||||||
|
>
|
||||||
<svg class="w-6 h-6 inline -mt-1" viewBox="0 0 24 24" fill="none"
|
<svg class="w-6 h-6 inline -mt-1" viewBox="0 0 24 24" fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
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"
|
<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"/>
|
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
/>
|
||||||
<path
|
<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"
|
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>
|
</svg>
|
||||||
</v-button>
|
</v-button>
|
||||||
<v-button class="text-white" @click="openEdit">
|
<v-button class="text-white" @click="openEdit">
|
||||||
<svg class="inline mr-1 -mt-1" width="18" height="17" viewBox="0 0 18 17" fill="none"
|
<svg class="inline mr-1 -mt-1" width="18" height="17" viewBox="0 0 18 17" fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
d="M8.99998 15.6662H16.5M1.5 15.6662H2.89545C3.3031 15.6662 3.50693 15.6662 3.69874 15.6202C3.8688 15.5793 4.03138 15.512 4.1805 15.4206C4.34869 15.3175 4.49282 15.1734 4.78107 14.8852L15.25 4.4162C15.9404 3.72585 15.9404 2.60656 15.25 1.9162C14.5597 1.22585 13.4404 1.22585 12.75 1.9162L2.28105 12.3852C1.9928 12.6734 1.84867 12.8175 1.7456 12.9857C1.65422 13.1348 1.58688 13.2974 1.54605 13.4675C1.5 13.6593 1.5 13.8631 1.5 14.2708V15.6662Z"
|
d="M8.99998 15.6662H16.5M1.5 15.6662H2.89545C3.3031 15.6662 3.50693 15.6662 3.69874 15.6202C3.8688 15.5793 4.03138 15.512 4.1805 15.4206C4.34869 15.3175 4.49282 15.1734 4.78107 14.8852L15.25 4.4162C15.9404 3.72585 15.9404 2.60656 15.25 1.9162C14.5597 1.22585 13.4404 1.22585 12.75 1.9162L2.28105 12.3852C1.9928 12.6734 1.84867 12.8175 1.7456 12.9857C1.65422 13.1348 1.58688 13.2974 1.54605 13.4675C1.5 13.6593 1.5 13.8631 1.5 14.2708V15.6662Z"
|
||||||
stroke="currentColor" stroke-width="1.67" stroke-linecap="round" stroke-linejoin="round"/>
|
stroke="currentColor" stroke-width="1.67" stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
Edit form
|
Edit form
|
||||||
</v-button>
|
</v-button>
|
||||||
|
@ -52,16 +60,18 @@
|
||||||
<span>- Edited {{ form.last_edited_human }}</span>
|
<span>- Edited {{ form.last_edited_human }}</span>
|
||||||
</p>
|
</p>
|
||||||
<div v-if="['draft','closed'].includes(form.visibility) || (form.tags && form.tags.length > 0)" class="mt-2 flex items-center flex-wrap gap-3">
|
<div v-if="['draft','closed'].includes(form.visibility) || (form.tags && form.tags.length > 0)" class="mt-2 flex items-center flex-wrap gap-3">
|
||||||
<span v-if="form.visibility=='draft'"
|
<span v-if="form.visibility=='draft'"
|
||||||
class="inline-flex items-center rounded-full bg-yellow-100 px-2 py-1 text-xs font-medium text-yellow-600 ring-1 ring-inset ring-gray-500/10 dark:text-white dark:bg-gray-700">
|
class="inline-flex items-center rounded-full bg-yellow-100 px-2 py-1 text-xs font-medium text-yellow-600 ring-1 ring-inset ring-gray-500/10 dark:text-white dark:bg-gray-700"
|
||||||
|
>
|
||||||
Draft - not publicly accessible
|
Draft - not publicly accessible
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="form.visibility=='closed'"
|
<span v-else-if="form.visibility=='closed'"
|
||||||
class="inline-flex items-center rounded-full bg-yellow-100 px-2 py-1 text-xs font-medium text-yellow-600 ring-1 ring-inset ring-gray-500/10 dark:text-white dark:bg-gray-700">
|
class="inline-flex items-center rounded-full bg-yellow-100 px-2 py-1 text-xs font-medium text-yellow-600 ring-1 ring-inset ring-gray-500/10 dark:text-white dark:bg-gray-700"
|
||||||
|
>
|
||||||
Closed - won't accept new submissions
|
Closed - won't accept new submissions
|
||||||
</span>
|
</span>
|
||||||
<span v-for="(tag,i) in form.tags" :key="tag"
|
<span v-for="(tag,i) in form.tags" :key="tag"
|
||||||
class="inline-flex items-center rounded-full bg-gray-50 px-2 py-1 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10 dark:text-white dark:bg-gray-700"
|
class="inline-flex items-center rounded-full bg-gray-50 px-2 py-1 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10 dark:text-white dark:bg-gray-700"
|
||||||
>
|
>
|
||||||
{{ tag }}
|
{{ tag }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -69,14 +79,14 @@
|
||||||
|
|
||||||
<p v-if="form.closes_at" class="text-yellow-500">
|
<p v-if="form.closes_at" class="text-yellow-500">
|
||||||
<span v-if="form.is_closed"> This form stopped accepting submissions on the {{
|
<span v-if="form.is_closed"> This form stopped accepting submissions on the {{
|
||||||
displayClosesDate
|
displayClosesDate
|
||||||
}} </span>
|
}} </span>
|
||||||
<span v-else> This form will stop accepting submissions on the {{ displayClosesDate }} </span>
|
<span v-else> This form will stop accepting submissions on the {{ displayClosesDate }} </span>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="form.max_submissions_count > 0" class="text-yellow-500">
|
<p v-if="form.max_submissions_count > 0" class="text-yellow-500">
|
||||||
<span v-if="form.max_number_of_submissions_reached"> The form is now closed because it reached its limit of {{
|
<span v-if="form.max_number_of_submissions_reached"> The form is now closed because it reached its limit of {{
|
||||||
form.max_submissions_count
|
form.max_submissions_count
|
||||||
}} submissions. </span>
|
}} submissions. </span>
|
||||||
<span v-else> This form will stop accepting submissions after {{ form.max_submissions_count }} submissions. </span>
|
<span v-else> This form will stop accepting submissions after {{ form.max_submissions_count }} submissions. </span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -84,15 +94,16 @@
|
||||||
|
|
||||||
<div class="border-b border-gray-200 dark:border-gray-700">
|
<div class="border-b border-gray-200 dark:border-gray-700">
|
||||||
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center">
|
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center">
|
||||||
<li class="mr-6" v-for="(tab, i) in tabsList" :key="i+1">
|
<li v-for="(tab, i) in tabsList" :key="i+1" class="mr-6">
|
||||||
<router-link :to="{ name: tab.route }"
|
<router-link :to="{ name: tab.route }"
|
||||||
class="hover:no-underline inline-block py-4 rounded-t-lg border-b-2 text-gray-500 hover:text-gray-600"
|
class="hover:no-underline inline-block py-4 rounded-t-lg border-b-2 text-gray-500 hover:text-gray-600"
|
||||||
active-class="text-blue-600 hover:text-blue-900 dark:text-blue-500 dark:hover:text-blue-500 border-blue-600 dark:border-blue-500"
|
active-class="text-blue-600 hover:text-blue-900 dark:text-blue-500 dark:hover:text-blue-500 border-blue-600 dark:border-blue-500"
|
||||||
>{{tab.name}}</router-link>
|
>
|
||||||
|
{{ tab.name }}
|
||||||
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -100,14 +111,18 @@
|
||||||
<div class="w-full md:w-4/5 lg:w-3/5 md:mx-auto md:max-w-4xl px-4">
|
<div class="w-full md:w-4/5 lg:w-3/5 md:mx-auto md:max-w-4xl px-4">
|
||||||
<div class="py-4">
|
<div class="py-4">
|
||||||
<transition name="fade" mode="out-in">
|
<transition name="fade" mode="out-in">
|
||||||
<router-view :form="form" />
|
<router-view v-slot="{ Component }">
|
||||||
|
<transition name="page" mode="out-in">
|
||||||
|
<component :is="Component" :form="form" />
|
||||||
|
</transition>
|
||||||
|
</router-view>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-else-if="loading" class="text-center w-full p-5">
|
<div v-else-if="loading" class="text-center w-full p-5">
|
||||||
<loader class="h-6 w-6 mx-auto"/>
|
<loader class="h-6 w-6 mx-auto" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="text-center w-full p-5">
|
<div v-else class="text-center w-full p-5">
|
||||||
Form not found.
|
Form not found.
|
||||||
|
@ -123,7 +138,7 @@ import { useFormsStore } from '../../../stores/forms'
|
||||||
import { useWorkingFormStore } from '../../../stores/working_form'
|
import { useWorkingFormStore } from '../../../stores/working_form'
|
||||||
import { useWorkspacesStore } from '../../../stores/workspaces'
|
import { useWorkspacesStore } from '../../../stores/workspaces'
|
||||||
import ProTag from '../../../components/common/ProTag.vue'
|
import ProTag from '../../../components/common/ProTag.vue'
|
||||||
import VButton from "../../../components/common/Button.vue";
|
import VButton from '../../../components/common/Button.vue'
|
||||||
import ExtraMenu from '../../../components/pages/forms/show/ExtraMenu.vue'
|
import ExtraMenu from '../../../components/pages/forms/show/ExtraMenu.vue'
|
||||||
import SeoMeta from '../../../mixins/seo-meta.js'
|
import SeoMeta from '../../../mixins/seo-meta.js'
|
||||||
import FormCleanings from '../../../components/pages/forms/show/FormCleanings.vue'
|
import FormCleanings from '../../../components/pages/forms/show/FormCleanings.vue'
|
||||||
|
@ -147,12 +162,12 @@ export default {
|
||||||
},
|
},
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
|
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter (to, from, next) {
|
||||||
loadForms()
|
loadForms()
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeRouteLeave(to, from, next) {
|
beforeRouteLeave (to, from, next) {
|
||||||
this.workingForm = null
|
this.workingForm = null
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
@ -167,13 +182,13 @@ export default {
|
||||||
formsStore,
|
formsStore,
|
||||||
workingFormStore,
|
workingFormStore,
|
||||||
workspacesStore,
|
workspacesStore,
|
||||||
user : computed(() => authStore.user),
|
user: computed(() => authStore.user),
|
||||||
formsLoading : computed(() => formsStore.loading),
|
formsLoading: computed(() => formsStore.loading),
|
||||||
workspacesLoading : computed(() => workspacesStore.loading)
|
workspacesLoading: computed(() => workspacesStore.loading)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
metaTitle: 'Home',
|
metaTitle: 'Home',
|
||||||
tabsList: [
|
tabsList: [
|
||||||
|
@ -203,52 +218,52 @@ export default {
|
||||||
this.workingFormStore.set(value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
workspace() {
|
workspace () {
|
||||||
if (!this.form) return null
|
if (!this.form) return null
|
||||||
return this.workspacesStore.getById(this.form.workspace_id)
|
return this.workspacesStore.getById(this.form.workspace_id)
|
||||||
},
|
},
|
||||||
form() {
|
form () {
|
||||||
return this.formsStore.getBySlug(this.$route.params.slug)
|
return this.formsStore.getBySlug(this.$route.params.slug)
|
||||||
},
|
},
|
||||||
formEndpoint: () => '/api/open/forms/{id}',
|
formEndpoint: () => '/api/open/forms/{id}',
|
||||||
loading() {
|
loading () {
|
||||||
return this.formsLoading || this.workspacesLoading
|
return this.formsLoading || this.workspacesLoading
|
||||||
},
|
},
|
||||||
displayClosesDate() {
|
displayClosesDate () {
|
||||||
if (this.form.closes_at) {
|
if (this.form.closes_at) {
|
||||||
let dateObj = new Date(this.form.closes_at)
|
const dateObj = new Date(this.form.closes_at)
|
||||||
return dateObj.getFullYear() + "-" +
|
return dateObj.getFullYear() + '-' +
|
||||||
String(dateObj.getMonth() + 1).padStart(2, '0') + "-" +
|
String(dateObj.getMonth() + 1).padStart(2, '0') + '-' +
|
||||||
String(dateObj.getDate()).padStart(2, '0') + " " +
|
String(dateObj.getDate()).padStart(2, '0') + ' ' +
|
||||||
String(dateObj.getHours()).padStart(2, '0') + ":" +
|
String(dateObj.getHours()).padStart(2, '0') + ':' +
|
||||||
String(dateObj.getMinutes()).padStart(2, '0')
|
String(dateObj.getMinutes()).padStart(2, '0')
|
||||||
}
|
}
|
||||||
return "";
|
return ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
form() {
|
form () {
|
||||||
this.workingForm = new Form(this.form)
|
this.workingForm = new Form(this.form)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted () {
|
||||||
if (this.form) {
|
if (this.form) {
|
||||||
this.workingForm = new Form(this.form)
|
this.workingForm = new Form(this.form)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
openCrisp() {
|
openCrisp () {
|
||||||
window.$crisp.push(['do', 'chat:show'])
|
window.$crisp.push(['do', 'chat:show'])
|
||||||
window.$crisp.push(['do', 'chat:open'])
|
window.$crisp.push(['do', 'chat:open'])
|
||||||
},
|
},
|
||||||
goBack() {
|
goBack () {
|
||||||
this.$router.push({name: 'home'})
|
this.$router.push({ name: 'home' })
|
||||||
},
|
},
|
||||||
openEdit() {
|
openEdit () {
|
||||||
this.$router.push({name: 'forms.edit', params: {slug: this.form.slug}})
|
this.$router.push({ name: 'forms.edit', params: { slug: this.form.slug } })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,13 @@
|
||||||
|
|
||||||
<div class="mt-4 border-b border-gray-200 dark:border-gray-700">
|
<div class="mt-4 border-b border-gray-200 dark:border-gray-700">
|
||||||
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center">
|
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center">
|
||||||
<li class="mr-6" v-for="(tab, i) in tabsList" :key="i+1">
|
<li v-for="(tab, i) in tabsList" :key="i+1" class="mr-6">
|
||||||
<router-link :to="{ name: tab.route }"
|
<router-link :to="{ name: tab.route }"
|
||||||
class="hover:no-underline inline-block py-4 rounded-t-lg border-b-2 text-gray-500 hover:text-gray-600"
|
class="hover:no-underline inline-block py-4 rounded-t-lg border-b-2 text-gray-500 hover:text-gray-600"
|
||||||
active-class="text-blue-600 hover:text-blue-900 dark:text-blue-500 dark:hover:text-blue-500 border-blue-600 dark:border-blue-500"
|
active-class="text-blue-600 hover:text-blue-900 dark:text-blue-500 dark:hover:text-blue-500 border-blue-600 dark:border-blue-500"
|
||||||
>{{tab.name}}</router-link>
|
>
|
||||||
|
{{ tab.name }}
|
||||||
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,9 +30,11 @@
|
||||||
<div class="flex bg-white">
|
<div class="flex bg-white">
|
||||||
<div class="w-full md:w-4/5 lg:w-3/5 md:mx-auto md:max-w-4xl px-4">
|
<div class="w-full md:w-4/5 lg:w-3/5 md:mx-auto md:max-w-4xl px-4">
|
||||||
<div class="mt-8 pb-0">
|
<div class="mt-8 pb-0">
|
||||||
<transition name="fade" mode="out-in">
|
<router-view v-slot="{ Component }">
|
||||||
<router-view />
|
<transition name="page" mode="out-in">
|
||||||
</transition>
|
<component :is="Component" />
|
||||||
|
</transition>
|
||||||
|
</router-view>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -47,7 +51,7 @@ export default {
|
||||||
setup () {
|
setup () {
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
return {
|
return {
|
||||||
user : computed(() => authStore.user)
|
user: computed(() => authStore.user)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -84,7 +88,7 @@ export default {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.user.admin){
|
if (this.user.admin) {
|
||||||
tabs.push({
|
tabs.push({
|
||||||
name: 'Admin',
|
name: 'Admin',
|
||||||
route: 'settings.admin'
|
route: 'settings.admin'
|
||||||
|
|
Loading…
Reference in New Issue