Form editor v2 (#579)

* Form editor v2

* fix template test

* setFormDefaults when save

* fix form cleaning dark mode

* improvements on open sidebar

* UI polish

* Fix change type button

---------

Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
Chirag Chhatrala
2024-09-23 23:32:38 +05:30
committed by GitHub
parent 47ae11bc58
commit d6181cd249
61 changed files with 2576 additions and 2661 deletions

View File

@@ -14,7 +14,11 @@
:name="name"
>
<slot name="label">
<span>{{ label }}
<span
:class="[
theme.SelectInput.fontSize,
]"
>{{ label }}
<span
v-if="required"
class="text-red-500 required-dot"

View File

@@ -201,7 +201,7 @@ const formattedDate = (value) => {
try {
return format(new Date(value), props.dateFormat + (props.timeFormat == 12 ? ' p':' HH:mm'))
} catch (e) {
console.log('Error formatting date', e)
console.error('Error formatting date', e)
return ''
}
}

View File

@@ -98,35 +98,14 @@
</template>
</div>
<div class="w-full items-center justify-center mt-2 hidden sm:flex">
<open-form-button
<UButton
v-if="cameraUpload"
native-type="button"
icon="i-heroicons-camera"
:loading="loading"
:theme="theme"
:color="color"
class="py-2 p-1 px-2"
color="white"
class="px-2"
@click.stop="openWebcam"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0ZM18.75 10.5h.008v.008h-.008V10.5Z"
/>
</svg>
</open-form-button>
/>
</div>
</div>
@@ -143,13 +122,12 @@
import {inputProps, useFormInput} from './useFormInput.js'
import InputWrapper from './components/InputWrapper.vue'
import UploadedFile from './components/UploadedFile.vue'
import OpenFormButton from '../open/forms/OpenFormButton.vue'
import CameraUpload from './components/CameraUpload.vue'
import {storeFile} from "~/lib/file-uploads.js"
export default {
name: 'FileInput',
components: {InputWrapper, UploadedFile, OpenFormButton},
components: {InputWrapper, UploadedFile, CameraUpload},
mixins: [],
props: {
...inputProps,

View File

@@ -109,7 +109,8 @@ export default {
loading: {type: Boolean, default: false},
multiple: { type: Boolean, default: false },
disableOptions: { type: Array, default: () => [] },
disableOptionsTooltip: {type: String, default: "Not allowed"},
disableOptionsTooltip: { type: String, default: "Not allowed" },
clearable: { type: Boolean, default: false },
},
setup(props, context) {
return {
@@ -129,11 +130,11 @@ export default {
if (this.multiple) {
const emitValue = Array.isArray(this.compVal) ? [...this.compVal] : []
// Already in value, remove it
// Already in value, remove it only if clearable or not the last item
if (this.isSelected(value)) {
this.compVal = emitValue.filter((item) => {
return item !== value
})
if (this.clearable || emitValue.length > 1) {
this.compVal = emitValue.filter((item) => item !== value)
}
return
}
@@ -141,7 +142,10 @@ export default {
emitValue.push(value)
this.compVal = emitValue
} else {
this.compVal = this.compVal === value ? null : value
// For single select, only change value if it's different or clearable
if (this.compVal !== value || this.clearable) {
this.compVal = this.compVal === value && this.clearable ? null : value
}
}
},
isSelected(value) {

View File

@@ -41,6 +41,7 @@
<VueSignaturePad
v-else
ref="signaturePad"
class="not-draggable"
:class="[
theme.SignatureInput.input,
theme.SignatureInput.spacing.horizontal,

View File

@@ -1,7 +1,7 @@
<template>
<div
v-if="shouldRender"
class="flex mb-1 input-help"
class="flex input-help"
>
<small
:class="helpClasses"
@@ -16,7 +16,10 @@
</slot>
</small>
<slot name="after-help">
<small class="flex-grow" />
<small
v-if="shouldRender || (!!slots.default)"
class="flex-grow"
/>
</slot>
</div>
</template>

View File

@@ -78,7 +78,7 @@
</span>
</button>
<button
v-if="clearable && !isEmpty"
v-if="clearable && showClearButton && !isEmpty"
class="hover:bg-gray-50 dark:hover:bg-gray-900 border-l px-2"
:class="[theme.SelectInput.spacing.vertical]"
@click.prevent="clear()"
@@ -223,7 +223,8 @@ export default {
emitKey: {type: String, default: null},
color: {type: String, default: '#3B82F6'},
placeholder: {type: String, default: null},
uppercaseLabels: {type: Boolean, default: true},
uppercaseLabels: { type: Boolean, default: true },
showClearButton: { type: Boolean, default: true },
theme: {
type: Object, default: () => {
const theme = inject("theme", null)
@@ -334,22 +335,24 @@ export default {
const emitValue = Array.isArray(this.modelValue) ? [...this.modelValue] : []
if (this.isSelected(value)) {
this.$emit('update:modelValue', emitValue.filter((item) => {
if (this.emitKey) {
return item !== value
}
return item[this.optionKey] !== value && item[this.optionKey] !== value[this.optionKey]
}))
// Only remove if clearable or not the last item
if (this.clearable || emitValue.length > 1) {
this.$emit('update:modelValue', emitValue.filter((item) => {
if (this.emitKey) {
return item !== value
}
return item[this.optionKey] !== value && item[this.optionKey] !== value[this.optionKey]
}))
}
return
}
emitValue.push(value)
this.$emit('update:modelValue', emitValue)
} else {
if (this.modelValue === value) {
this.$emit('update:modelValue', this.defaultValue ?? null)
} else {
this.$emit('update:modelValue', value)
// For single select, only change value if it's different or clearable
if (this.modelValue !== value || this.clearable) {
this.$emit('update:modelValue', this.modelValue === value && this.clearable ? null : value)
}
}
},