|
|
|
@ -36,7 +36,7 @@ const hiddenCols = ['created_at', 'updated_at']
|
|
|
|
|
|
|
|
|
|
const hiddenColTypes = [UITypes.Rollup, UITypes.Lookup, UITypes.Formula, UITypes.QrCode, UITypes.Barcode, UITypes.SpecificDBType] |
|
|
|
|
|
|
|
|
|
const state = useGlobal() |
|
|
|
|
const { isMobileMode, user } = useGlobal() |
|
|
|
|
|
|
|
|
|
const formRef = ref() |
|
|
|
|
|
|
|
|
@ -281,7 +281,7 @@ function setFormData() {
|
|
|
|
|
data = JSON.parse(formViewData.value?.email || '') || {} |
|
|
|
|
} catch (e) {} |
|
|
|
|
|
|
|
|
|
emailMe.value = data[state.user.value?.email as string] |
|
|
|
|
emailMe.value = data[user.value?.email as string] |
|
|
|
|
|
|
|
|
|
localColumns.value = col |
|
|
|
|
.filter((f) => f.show && !hiddenColTypes.includes(f.uidt)) |
|
|
|
@ -314,7 +314,7 @@ async function updateEmail() {
|
|
|
|
|
if (!(await checkSMTPStatus())) return |
|
|
|
|
|
|
|
|
|
const data = formViewData.value?.email ? JSON.parse(formViewData.value?.email) : {} |
|
|
|
|
data[state.user.value?.email as string] = emailMe.value |
|
|
|
|
data[user.value?.email as string] = emailMe.value |
|
|
|
|
formViewData.value!.email = JSON.stringify(data) |
|
|
|
|
} catch (e) {} |
|
|
|
|
} |
|
|
|
@ -387,458 +387,480 @@ watch(view, (nextView) => {
|
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
|
<a-row v-if="submitted" class="h-full" data-testid="nc-form-wrapper-submit"> |
|
|
|
|
<a-col :span="24"> |
|
|
|
|
<div v-if="formViewData" class="items-center justify-center text-center mt-2"> |
|
|
|
|
<a-alert type="success"> |
|
|
|
|
<template #message> |
|
|
|
|
<div class="text-center">{{ formViewData.success_msg || 'Successfully submitted form data' }}</div> |
|
|
|
|
</template> |
|
|
|
|
</a-alert> |
|
|
|
|
<template v-if="isMobileMode"> |
|
|
|
|
<div class="pl-6 pr-[120px] py-6 bg-white flex-col justify-start items-start gap-2.5 inline-flex"> |
|
|
|
|
<div class="text-gray-500 text-5xl font-semibold leading-16">Available<br />in Desktop</div> |
|
|
|
|
<div class="text-gray-500 text-base font-medium leading-normal">Form View is currently not supported on mobile.</div> |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
|
<template v-else> |
|
|
|
|
<a-row v-if="submitted" class="h-full" data-testid="nc-form-wrapper-submit"> |
|
|
|
|
<a-col :span="24"> |
|
|
|
|
<div v-if="formViewData" class="items-center justify-center text-center mt-2"> |
|
|
|
|
<a-alert type="success"> |
|
|
|
|
<template #message> |
|
|
|
|
<div class="text-center">{{ formViewData.success_msg || 'Successfully submitted form data' }}</div> |
|
|
|
|
</template> |
|
|
|
|
</a-alert> |
|
|
|
|
|
|
|
|
|
<div v-if="formViewData.show_blank_form" class="text-gray-400 mt-4"> |
|
|
|
|
New form will be loaded after {{ secondsRemain }} seconds |
|
|
|
|
</div> |
|
|
|
|
<div v-if="formViewData.show_blank_form" class="text-gray-400 mt-4"> |
|
|
|
|
New form will be loaded after {{ secondsRemain }} seconds |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div v-if="formViewData.submit_another_form || !isPublic" class="text-center mt-4"> |
|
|
|
|
<a-button type="primary" size="large" @click="submitted = false"> Submit Another Form</a-button> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</a-col> |
|
|
|
|
</a-row> |
|
|
|
|
|
|
|
|
|
<a-row v-else class="h-full flex" data-testid="nc-form-wrapper"> |
|
|
|
|
<a-col v-if="isEditable" :span="8" class="shadow p-2 md:p-4 h-full overflow-auto scrollbar-thin-dull nc-form-left-drawer"> |
|
|
|
|
<div class="flex flex-wrap gap-2"> |
|
|
|
|
<div class="flex-1 text-lg"> |
|
|
|
|
{{ $t('objects.fields') }} |
|
|
|
|
<div v-if="formViewData.submit_another_form || !isPublic" class="text-center mt-4"> |
|
|
|
|
<a-button type="primary" size="large" @click="submitted = false"> Submit Another Form</a-button> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</a-col> |
|
|
|
|
</a-row> |
|
|
|
|
|
|
|
|
|
<a-row v-else class="h-full flex" data-testid="nc-form-wrapper"> |
|
|
|
|
<a-col v-if="isEditable" :span="8" class="shadow p-2 md:p-4 h-full overflow-auto scrollbar-thin-dull nc-form-left-drawer"> |
|
|
|
|
<div class="flex flex-wrap gap-2"> |
|
|
|
|
<div class="flex-1 text-lg"> |
|
|
|
|
{{ $t('objects.fields') }} |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="flex flex-wrap gap-2 mb-4"> |
|
|
|
|
<button |
|
|
|
|
v-if="hiddenColumns.length" |
|
|
|
|
type="button" |
|
|
|
|
class="nc-form-add-all color-transition bg-white transform hover:(text-primary ring ring-accent ring-opacity-100) active:translate-y-[1px] px-2 py-1 shadow-md rounded" |
|
|
|
|
data-testid="nc-form-add-all" |
|
|
|
|
@click="addAllColumns" |
|
|
|
|
> |
|
|
|
|
<!-- Add all --> |
|
|
|
|
{{ $t('general.addAll') }} |
|
|
|
|
</button> |
|
|
|
|
|
|
|
|
|
<button |
|
|
|
|
v-if="localColumns.length" |
|
|
|
|
type="button" |
|
|
|
|
class="nc-form-remove-all color-transition bg-white transform hover:(text-primary ring ring-accent ring-opacity-100) active:translate-y-[1px] px-2 py-1 shadow-md rounded" |
|
|
|
|
data-testid="nc-form-remove-all" |
|
|
|
|
@click="removeAllColumns" |
|
|
|
|
> |
|
|
|
|
<!-- Remove all --> |
|
|
|
|
{{ $t('general.removeAll') }} |
|
|
|
|
</button> |
|
|
|
|
<div class="flex flex-wrap gap-2 mb-4"> |
|
|
|
|
<button |
|
|
|
|
v-if="hiddenColumns.length" |
|
|
|
|
type="button" |
|
|
|
|
class="nc-form-add-all color-transition bg-white transform hover:(text-primary ring ring-accent ring-opacity-100) active:translate-y-[1px] px-2 py-1 shadow-md rounded" |
|
|
|
|
data-testid="nc-form-add-all" |
|
|
|
|
@click="addAllColumns" |
|
|
|
|
> |
|
|
|
|
<!-- Add all --> |
|
|
|
|
{{ $t('general.addAll') }} |
|
|
|
|
</button> |
|
|
|
|
|
|
|
|
|
<button |
|
|
|
|
v-if="localColumns.length" |
|
|
|
|
type="button" |
|
|
|
|
class="nc-form-remove-all color-transition bg-white transform hover:(text-primary ring ring-accent ring-opacity-100) active:translate-y-[1px] px-2 py-1 shadow-md rounded" |
|
|
|
|
data-testid="nc-form-remove-all" |
|
|
|
|
@click="removeAllColumns" |
|
|
|
|
> |
|
|
|
|
<!-- Remove all --> |
|
|
|
|
{{ $t('general.removeAll') }} |
|
|
|
|
</button> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<Draggable |
|
|
|
|
:list="hiddenColumns" |
|
|
|
|
item-key="id" |
|
|
|
|
draggable=".item" |
|
|
|
|
group="form-inputs" |
|
|
|
|
class="flex flex-col gap-2" |
|
|
|
|
@start="drag = true" |
|
|
|
|
@end="drag = false" |
|
|
|
|
> |
|
|
|
|
<template #item="{ element, index }"> |
|
|
|
|
<a-card |
|
|
|
|
size="small" |
|
|
|
|
class="!border-0 color-transition cursor-pointer item hover:(bg-primary ring-1 ring-accent ring-opacity-100) bg-opacity-10 !rounded !shadow-lg" |
|
|
|
|
:data-testid="`nc-form-hidden-column-${element.label || element.title}`" |
|
|
|
|
@mousedown="moved = false" |
|
|
|
|
@mousemove="moved = false" |
|
|
|
|
@mouseup="handleMouseUp(element, index)" |
|
|
|
|
> |
|
|
|
|
<div class="flex"> |
|
|
|
|
<div class="flex flex-1"> |
|
|
|
|
<LazySmartsheetHeaderVirtualCell |
|
|
|
|
v-if="isVirtualCol(element)" |
|
|
|
|
:column="{ ...element, title: element.label || element.title }" |
|
|
|
|
:required="isRequired(element, element.required)" |
|
|
|
|
:hide-menu="true" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<LazySmartsheetHeaderCell |
|
|
|
|
v-else |
|
|
|
|
:column="{ ...element, title: element.label || element.title }" |
|
|
|
|
:required="isRequired(element, element.required)" |
|
|
|
|
:hide-menu="true" |
|
|
|
|
/> |
|
|
|
|
<Draggable |
|
|
|
|
:list="hiddenColumns" |
|
|
|
|
item-key="id" |
|
|
|
|
draggable=".item" |
|
|
|
|
group="form-inputs" |
|
|
|
|
class="flex flex-col gap-2" |
|
|
|
|
@start="drag = true" |
|
|
|
|
@end="drag = false" |
|
|
|
|
> |
|
|
|
|
<template #item="{ element, index }"> |
|
|
|
|
<a-card |
|
|
|
|
size="small" |
|
|
|
|
class="!border-0 color-transition cursor-pointer item hover:(bg-primary ring-1 ring-accent ring-opacity-100) bg-opacity-10 !rounded !shadow-lg" |
|
|
|
|
:data-testid="`nc-form-hidden-column-${element.label || element.title}`" |
|
|
|
|
@mousedown="moved = false" |
|
|
|
|
@mousemove="moved = false" |
|
|
|
|
@mouseup="handleMouseUp(element, index)" |
|
|
|
|
> |
|
|
|
|
<div class="flex"> |
|
|
|
|
<div class="flex flex-1"> |
|
|
|
|
<LazySmartsheetHeaderVirtualCell |
|
|
|
|
v-if="isVirtualCol(element)" |
|
|
|
|
:column="{ ...element, title: element.label || element.title }" |
|
|
|
|
:required="isRequired(element, element.required)" |
|
|
|
|
:hide-menu="true" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<LazySmartsheetHeaderCell |
|
|
|
|
v-else |
|
|
|
|
:column="{ ...element, title: element.label || element.title }" |
|
|
|
|
:required="isRequired(element, element.required)" |
|
|
|
|
:hide-menu="true" |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</a-card> |
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
<template #footer> |
|
|
|
|
<div |
|
|
|
|
class="my-4 select-none border-dashed border-2 border-gray-400 py-3 text-gray-400 text-center nc-drag-n-drop-to-hide" |
|
|
|
|
data-testid="nc-drag-n-drop-to-hide" |
|
|
|
|
> |
|
|
|
|
<!-- Drag and drop fields here to hide --> |
|
|
|
|
{{ $t('msg.info.dragDropHide') }} |
|
|
|
|
</div> |
|
|
|
|
</a-card> |
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
<template #footer> |
|
|
|
|
<div |
|
|
|
|
class="my-4 select-none border-dashed border-2 border-gray-400 py-3 text-gray-400 text-center nc-drag-n-drop-to-hide" |
|
|
|
|
data-testid="nc-drag-n-drop-to-hide" |
|
|
|
|
> |
|
|
|
|
<!-- Drag and drop fields here to hide --> |
|
|
|
|
{{ $t('msg.info.dragDropHide') }} |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<a-dropdown v-model:visible="showColumnDropdown" :trigger="['click']" overlay-class-name="nc-dropdown-form-add-column"> |
|
|
|
|
<button type="button" class="group w-full mt-2" @click.stop="showColumnDropdown = true"> |
|
|
|
|
<span class="flex items-center flex-wrap justify-center gap-2 prose-sm text-gray-400"> |
|
|
|
|
<component :is="iconMap.plus" class="color-transition transform group-hover:(text-accent scale-125)" /> |
|
|
|
|
<!-- Add new field to this table --> |
|
|
|
|
<span class="color-transition group-hover:text-primary break-words"> |
|
|
|
|
{{ $t('activity.addField') }} |
|
|
|
|
<a-dropdown |
|
|
|
|
v-model:visible="showColumnDropdown" |
|
|
|
|
:trigger="['click']" |
|
|
|
|
overlay-class-name="nc-dropdown-form-add-column" |
|
|
|
|
> |
|
|
|
|
<button type="button" class="group w-full mt-2" @click.stop="showColumnDropdown = true"> |
|
|
|
|
<span class="flex items-center flex-wrap justify-center gap-2 prose-sm text-gray-400"> |
|
|
|
|
<component :is="iconMap.plus" class="color-transition transform group-hover:(text-accent scale-125)" /> |
|
|
|
|
<!-- Add new field to this table --> |
|
|
|
|
<span class="color-transition group-hover:text-primary break-words"> |
|
|
|
|
{{ $t('activity.addField') }} |
|
|
|
|
</span> |
|
|
|
|
</span> |
|
|
|
|
</span> |
|
|
|
|
</button> |
|
|
|
|
</button> |
|
|
|
|
|
|
|
|
|
<template #overlay> |
|
|
|
|
<SmartsheetColumnEditOrAddProvider |
|
|
|
|
v-if="showColumnDropdown" |
|
|
|
|
@submit="submitCallback" |
|
|
|
|
@cancel="showColumnDropdown = false" |
|
|
|
|
@click.stop |
|
|
|
|
@keydown.stop |
|
|
|
|
/> |
|
|
|
|
</template> |
|
|
|
|
</a-dropdown> |
|
|
|
|
</template> |
|
|
|
|
</Draggable> |
|
|
|
|
</a-col> |
|
|
|
|
|
|
|
|
|
<a-col v-if="formViewData" :span="isEditable ? 16 : 24" class="h-full overflow-auto scrollbar-thin-dull"> |
|
|
|
|
<div class="h-[200px] bg-primary bg-opacity-75"> |
|
|
|
|
<!-- for future implementation of cover image --> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<a-card |
|
|
|
|
class="p-4 border-none" |
|
|
|
|
:body-style="{ |
|
|
|
|
maxWidth: 'max(50vw, 700px)', |
|
|
|
|
margin: '0 auto', |
|
|
|
|
marginTop: '-200px', |
|
|
|
|
padding: '0px', |
|
|
|
|
}" |
|
|
|
|
> |
|
|
|
|
<a-form ref="formRef" :model="formState" class="nc-form" no-style> |
|
|
|
|
<a-card class="!rounded !shadow !m-2 md:(!m-4) xl:(!m-8)" :body-style="{ paddingLeft: '0px', paddingRight: '0px' }"> |
|
|
|
|
<!-- Header --> |
|
|
|
|
<div v-if="isEditable" class="px-4 lg:px-12"> |
|
|
|
|
<a-form-item v-if="isEditable"> |
|
|
|
|
<a-textarea |
|
|
|
|
v-model:value="formViewData.heading" |
|
|
|
|
class="w-full !font-bold !text-4xl !border-0 !border-b-1 !border-dashed !rounded-none !border-gray-400" |
|
|
|
|
:style="{ 'borderRightWidth': '0px !important', 'height': '54px', 'min-height': '54px', 'resize': 'vertical' }" |
|
|
|
|
size="large" |
|
|
|
|
hide-details |
|
|
|
|
placeholder="Form Title" |
|
|
|
|
:bordered="false" |
|
|
|
|
data-testid="nc-form-heading" |
|
|
|
|
@blur="updateView" |
|
|
|
|
@keydown.enter="updateView" |
|
|
|
|
/> |
|
|
|
|
</a-form-item> |
|
|
|
|
</div> |
|
|
|
|
<div v-else class="px-4 ml-3 w-full text-bold text-4xl">{{ formViewData.heading }}</div> |
|
|
|
|
|
|
|
|
|
<!-- Sub Header --> |
|
|
|
|
<div v-if="isEditable" class="px-4 lg:px-12"> |
|
|
|
|
<a-form-item> |
|
|
|
|
<a-textarea |
|
|
|
|
v-model:value="formViewData.subheading" |
|
|
|
|
class="w-full !border-0 !border-b-1 !border-dashed !rounded-none !border-gray-400" |
|
|
|
|
:style="{ 'borderRightWidth': '0px !important', 'height': '40px', 'min-height': '40px', 'resize': 'vertical' }" |
|
|
|
|
size="large" |
|
|
|
|
hide-details |
|
|
|
|
:placeholder="$t('msg.info.formDesc')" |
|
|
|
|
:bordered="false" |
|
|
|
|
:disabled="!isEditable" |
|
|
|
|
data-testid="nc-form-sub-heading" |
|
|
|
|
@blur="updateView" |
|
|
|
|
@click="updateView" |
|
|
|
|
<template #overlay> |
|
|
|
|
<SmartsheetColumnEditOrAddProvider |
|
|
|
|
v-if="showColumnDropdown" |
|
|
|
|
@submit="submitCallback" |
|
|
|
|
@cancel="showColumnDropdown = false" |
|
|
|
|
@click.stop |
|
|
|
|
@keydown.stop |
|
|
|
|
/> |
|
|
|
|
</a-form-item> |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
|
</a-dropdown> |
|
|
|
|
</template> |
|
|
|
|
</Draggable> |
|
|
|
|
</a-col> |
|
|
|
|
|
|
|
|
|
<div v-else class="px-4 ml-3 w-full text-bold text-md">{{ formViewData.subheading || '---' }}</div> |
|
|
|
|
|
|
|
|
|
<Draggable |
|
|
|
|
ref="draggableRef" |
|
|
|
|
:list="localColumns" |
|
|
|
|
item-key="fk_column_id" |
|
|
|
|
draggable=".item" |
|
|
|
|
group="form-inputs" |
|
|
|
|
class="h-full" |
|
|
|
|
:move="onMoveCallback" |
|
|
|
|
@change="onMove($event)" |
|
|
|
|
@start="drag = true" |
|
|
|
|
@end="drag = false" |
|
|
|
|
> |
|
|
|
|
<template #item="{ element, index }"> |
|
|
|
|
<div |
|
|
|
|
class="color-transition nc-editable item cursor-pointer hover:(bg-primary bg-opacity-10 ring-1 ring-accent ring-opacity-100) px-4 lg:px-12 py-4 relative" |
|
|
|
|
:class="[ |
|
|
|
|
`nc-form-drag-${element.title.replaceAll(' ', '')}`, |
|
|
|
|
{ |
|
|
|
|
'bg-primary bg-opacity-5 ring-0.5 ring-accent ring-opacity-100': activeRow === element.title, |
|
|
|
|
}, |
|
|
|
|
]" |
|
|
|
|
data-testid="nc-form-fields" |
|
|
|
|
@click="activeRow = element.title" |
|
|
|
|
> |
|
|
|
|
<a-col v-if="formViewData" :span="isEditable ? 16 : 24" class="h-full overflow-auto scrollbar-thin-dull"> |
|
|
|
|
<div class="h-[200px] bg-primary bg-opacity-75"> |
|
|
|
|
<!-- for future implementation of cover image --> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<a-card |
|
|
|
|
class="p-4 border-none" |
|
|
|
|
:body-style="{ |
|
|
|
|
maxWidth: 'max(50vw, 700px)', |
|
|
|
|
margin: '0 auto', |
|
|
|
|
marginTop: '-200px', |
|
|
|
|
padding: '0px', |
|
|
|
|
}" |
|
|
|
|
> |
|
|
|
|
<a-form ref="formRef" :model="formState" class="nc-form" no-style> |
|
|
|
|
<a-card class="!rounded !shadow !m-2 md:(!m-4) xl:(!m-8)" :body-style="{ paddingLeft: '0px', paddingRight: '0px' }"> |
|
|
|
|
<!-- Header --> |
|
|
|
|
<div v-if="isEditable" class="px-4 lg:px-12"> |
|
|
|
|
<a-form-item v-if="isEditable"> |
|
|
|
|
<a-textarea |
|
|
|
|
v-model:value="formViewData.heading" |
|
|
|
|
class="w-full !font-bold !text-4xl !border-0 !border-b-1 !border-dashed !rounded-none !border-gray-400" |
|
|
|
|
:style="{ |
|
|
|
|
'borderRightWidth': '0px !important', |
|
|
|
|
'height': '54px', |
|
|
|
|
'min-height': '54px', |
|
|
|
|
'resize': 'vertical', |
|
|
|
|
}" |
|
|
|
|
size="large" |
|
|
|
|
hide-details |
|
|
|
|
placeholder="Form Title" |
|
|
|
|
:bordered="false" |
|
|
|
|
data-testid="nc-form-heading" |
|
|
|
|
@blur="updateView" |
|
|
|
|
@keydown.enter="updateView" |
|
|
|
|
/> |
|
|
|
|
</a-form-item> |
|
|
|
|
</div> |
|
|
|
|
<div v-else class="px-4 ml-3 w-full text-bold text-4xl">{{ formViewData.heading }}</div> |
|
|
|
|
|
|
|
|
|
<!-- Sub Header --> |
|
|
|
|
<div v-if="isEditable" class="px-4 lg:px-12"> |
|
|
|
|
<a-form-item> |
|
|
|
|
<a-textarea |
|
|
|
|
v-model:value="formViewData.subheading" |
|
|
|
|
class="w-full !border-0 !border-b-1 !border-dashed !rounded-none !border-gray-400" |
|
|
|
|
:style="{ |
|
|
|
|
'borderRightWidth': '0px !important', |
|
|
|
|
'height': '40px', |
|
|
|
|
'min-height': '40px', |
|
|
|
|
'resize': 'vertical', |
|
|
|
|
}" |
|
|
|
|
size="large" |
|
|
|
|
hide-details |
|
|
|
|
:placeholder="$t('msg.info.formDesc')" |
|
|
|
|
:bordered="false" |
|
|
|
|
:disabled="!isEditable" |
|
|
|
|
data-testid="nc-form-sub-heading" |
|
|
|
|
@blur="updateView" |
|
|
|
|
@click="updateView" |
|
|
|
|
/> |
|
|
|
|
</a-form-item> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div v-else class="px-4 ml-3 w-full text-bold text-md">{{ formViewData.subheading || '---' }}</div> |
|
|
|
|
|
|
|
|
|
<Draggable |
|
|
|
|
ref="draggableRef" |
|
|
|
|
:list="localColumns" |
|
|
|
|
item-key="fk_column_id" |
|
|
|
|
draggable=".item" |
|
|
|
|
group="form-inputs" |
|
|
|
|
class="h-full" |
|
|
|
|
:move="onMoveCallback" |
|
|
|
|
@change="onMove($event)" |
|
|
|
|
@start="drag = true" |
|
|
|
|
@end="drag = false" |
|
|
|
|
> |
|
|
|
|
<template #item="{ element, index }"> |
|
|
|
|
<div |
|
|
|
|
v-if="isUIAllowed('viewFieldEdit') && !isRequired(element, element.required)" |
|
|
|
|
class="absolute flex top-2 right-2" |
|
|
|
|
class="color-transition nc-editable item cursor-pointer hover:(bg-primary bg-opacity-10 ring-1 ring-accent ring-opacity-100) px-4 lg:px-12 py-4 relative" |
|
|
|
|
:class="[ |
|
|
|
|
`nc-form-drag-${element.title.replaceAll(' ', '')}`, |
|
|
|
|
{ |
|
|
|
|
'bg-primary bg-opacity-5 ring-0.5 ring-accent ring-opacity-100': activeRow === element.title, |
|
|
|
|
}, |
|
|
|
|
]" |
|
|
|
|
data-testid="nc-form-fields" |
|
|
|
|
@click="activeRow = element.title" |
|
|
|
|
> |
|
|
|
|
<component |
|
|
|
|
:is="iconMap.eyeSlash" |
|
|
|
|
class="opacity-0 nc-field-remove-icon" |
|
|
|
|
data-testid="nc-field-remove-icon" |
|
|
|
|
@click.stop="hideColumn(index)" |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div v-if="activeRow === element.title" class="flex flex-col gap-3 mb-3"> |
|
|
|
|
<div class="flex gap-2 items-center"> |
|
|
|
|
<span |
|
|
|
|
class="text-gray-500 mr-2 nc-form-input-required" |
|
|
|
|
data-testid="nc-form-input-required" |
|
|
|
|
@click=" |
|
|
|
|
() => { |
|
|
|
|
element.required = !element.required |
|
|
|
|
updateColMeta(element) |
|
|
|
|
} |
|
|
|
|
" |
|
|
|
|
> |
|
|
|
|
{{ $t('general.required') }} |
|
|
|
|
</span> |
|
|
|
|
|
|
|
|
|
<a-switch |
|
|
|
|
v-model:checked="element.required" |
|
|
|
|
v-e="['a:form-view:field:mark-required']" |
|
|
|
|
size="small" |
|
|
|
|
@change="updateColMeta(element)" |
|
|
|
|
<div |
|
|
|
|
v-if="isUIAllowed('viewFieldEdit') && !isRequired(element, element.required)" |
|
|
|
|
class="absolute flex top-2 right-2" |
|
|
|
|
> |
|
|
|
|
<component |
|
|
|
|
:is="iconMap.eyeSlash" |
|
|
|
|
class="opacity-0 nc-field-remove-icon" |
|
|
|
|
data-testid="nc-field-remove-icon" |
|
|
|
|
@click.stop="hideColumn(index)" |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<a-form-item v-if="columnSupportsScanning(element.uidt)" class="my-0 w-1/2 !mb-1"> |
|
|
|
|
<div v-if="activeRow === element.title" class="flex flex-col gap-3 mb-3"> |
|
|
|
|
<div class="flex gap-2 items-center"> |
|
|
|
|
<span |
|
|
|
|
class="text-gray-500 mr-2 nc-form-input-required" |
|
|
|
|
data-testid="nc-form-input-enable-scanner" |
|
|
|
|
data-testid="nc-form-input-required" |
|
|
|
|
@click=" |
|
|
|
|
() => { |
|
|
|
|
element.general.enable_scanner = !element.general.enable_scanner |
|
|
|
|
element.required = !element.required |
|
|
|
|
updateColMeta(element) |
|
|
|
|
} |
|
|
|
|
" |
|
|
|
|
> |
|
|
|
|
{{ $t('general.enableScanner') }} |
|
|
|
|
{{ $t('general.required') }} |
|
|
|
|
</span> |
|
|
|
|
|
|
|
|
|
<a-switch |
|
|
|
|
v-model:checked="element.enable_scanner" |
|
|
|
|
v-e="['a:form-view:field:mark-enable-scaner']" |
|
|
|
|
v-model:checked="element.required" |
|
|
|
|
v-e="['a:form-view:field:mark-required']" |
|
|
|
|
size="small" |
|
|
|
|
@change="updateColMeta(element)" |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
<a-form-item class="my-0 w-1/2 !mb-1"> |
|
|
|
|
<a-input |
|
|
|
|
v-model:value="element.label" |
|
|
|
|
type="text" |
|
|
|
|
class="form-meta-input nc-form-input-label" |
|
|
|
|
<a-form-item v-if="columnSupportsScanning(element.uidt)" class="my-0 w-1/2 !mb-1"> |
|
|
|
|
<div class="flex gap-2 items-center"> |
|
|
|
|
<span |
|
|
|
|
class="text-gray-500 mr-2 nc-form-input-required" |
|
|
|
|
data-testid="nc-form-input-enable-scanner" |
|
|
|
|
@click=" |
|
|
|
|
() => { |
|
|
|
|
element.general.enable_scanner = !element.general.enable_scanner |
|
|
|
|
updateColMeta(element) |
|
|
|
|
} |
|
|
|
|
" |
|
|
|
|
> |
|
|
|
|
{{ $t('general.enableScanner') }} |
|
|
|
|
</span> |
|
|
|
|
|
|
|
|
|
<a-switch |
|
|
|
|
v-model:checked="element.enable_scanner" |
|
|
|
|
v-e="['a:form-view:field:mark-enable-scaner']" |
|
|
|
|
size="small" |
|
|
|
|
@change="updateColMeta(element)" |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
<a-form-item class="my-0 w-1/2 !mb-1"> |
|
|
|
|
<a-input |
|
|
|
|
v-model:value="element.label" |
|
|
|
|
type="text" |
|
|
|
|
class="form-meta-input nc-form-input-label" |
|
|
|
|
data-testid="nc-form-input-label" |
|
|
|
|
:placeholder="$t('msg.info.formInput')" |
|
|
|
|
@change="updateColMeta(element)" |
|
|
|
|
> |
|
|
|
|
</a-input> |
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
<a-form-item class="mt-2 mb-0 w-1/2 !mb-1"> |
|
|
|
|
<a-input |
|
|
|
|
v-model:value="element.description" |
|
|
|
|
type="text" |
|
|
|
|
class="form-meta-input text-sm nc-form-input-help-text" |
|
|
|
|
data-testid="nc-form-input-help-text" |
|
|
|
|
:placeholder="$t('msg.info.formHelpText')" |
|
|
|
|
@change="updateColMeta(element)" |
|
|
|
|
/> |
|
|
|
|
</a-form-item> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div> |
|
|
|
|
<LazySmartsheetHeaderVirtualCell |
|
|
|
|
v-if="isVirtualCol(element)" |
|
|
|
|
:column="{ ...element, title: element.label || element.title }" |
|
|
|
|
:required="isRequired(element, element.required)" |
|
|
|
|
:hide-menu="true" |
|
|
|
|
data-testid="nc-form-input-label" |
|
|
|
|
:placeholder="$t('msg.info.formInput')" |
|
|
|
|
@change="updateColMeta(element)" |
|
|
|
|
> |
|
|
|
|
</a-input> |
|
|
|
|
</a-form-item> |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<a-form-item class="mt-2 mb-0 w-1/2 !mb-1"> |
|
|
|
|
<a-input |
|
|
|
|
v-model:value="element.description" |
|
|
|
|
type="text" |
|
|
|
|
class="form-meta-input text-sm nc-form-input-help-text" |
|
|
|
|
data-testid="nc-form-input-help-text" |
|
|
|
|
:placeholder="$t('msg.info.formHelpText')" |
|
|
|
|
@change="updateColMeta(element)" |
|
|
|
|
<LazySmartsheetHeaderCell |
|
|
|
|
v-else |
|
|
|
|
:column="{ ...element, title: element.label || element.title }" |
|
|
|
|
:required="isRequired(element, element.required)" |
|
|
|
|
:hide-menu="true" |
|
|
|
|
data-testid="nc-form-input-label" |
|
|
|
|
/> |
|
|
|
|
</a-form-item> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div> |
|
|
|
|
<LazySmartsheetHeaderVirtualCell |
|
|
|
|
<a-form-item |
|
|
|
|
v-if="isVirtualCol(element)" |
|
|
|
|
:column="{ ...element, title: element.label || element.title }" |
|
|
|
|
:required="isRequired(element, element.required)" |
|
|
|
|
:hide-menu="true" |
|
|
|
|
data-testid="nc-form-input-label" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<LazySmartsheetHeaderCell |
|
|
|
|
v-else |
|
|
|
|
:column="{ ...element, title: element.label || element.title }" |
|
|
|
|
:required="isRequired(element, element.required)" |
|
|
|
|
:hide-menu="true" |
|
|
|
|
data-testid="nc-form-input-label" |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<a-form-item |
|
|
|
|
v-if="isVirtualCol(element)" |
|
|
|
|
:name="element.title" |
|
|
|
|
class="!mb-0 nc-input-required-error" |
|
|
|
|
:rules="[ |
|
|
|
|
{ |
|
|
|
|
required: isRequired(element, element.required), |
|
|
|
|
message: `${element.label || element.title} is required`, |
|
|
|
|
}, |
|
|
|
|
]" |
|
|
|
|
> |
|
|
|
|
<LazySmartsheetVirtualCell |
|
|
|
|
v-model="formState[element.title]" |
|
|
|
|
:row="row" |
|
|
|
|
class="nc-input" |
|
|
|
|
:class="`nc-form-input-${element.title.replaceAll(' ', '')}`" |
|
|
|
|
:data-testid="`nc-form-input-${element.title.replaceAll(' ', '')}`" |
|
|
|
|
:column="element" |
|
|
|
|
@click.stop.prevent |
|
|
|
|
/> |
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
<a-form-item |
|
|
|
|
v-else |
|
|
|
|
:name="element.title" |
|
|
|
|
class="!mb-0 nc-input-required-error" |
|
|
|
|
:rules="[ |
|
|
|
|
{ |
|
|
|
|
required: isRequired(element, element.required), |
|
|
|
|
message: `${element.label || element.title} is required`, |
|
|
|
|
}, |
|
|
|
|
]" |
|
|
|
|
> |
|
|
|
|
<LazySmartsheetDivDataCell class="relative"> |
|
|
|
|
<LazySmartsheetCell |
|
|
|
|
:name="element.title" |
|
|
|
|
class="!mb-0 nc-input-required-error" |
|
|
|
|
:rules="[ |
|
|
|
|
{ |
|
|
|
|
required: isRequired(element, element.required), |
|
|
|
|
message: `${element.label || element.title} is required`, |
|
|
|
|
}, |
|
|
|
|
]" |
|
|
|
|
> |
|
|
|
|
<LazySmartsheetVirtualCell |
|
|
|
|
v-model="formState[element.title]" |
|
|
|
|
class="nc-input truncate" |
|
|
|
|
:row="row" |
|
|
|
|
class="nc-input" |
|
|
|
|
:class="`nc-form-input-${element.title.replaceAll(' ', '')}`" |
|
|
|
|
:data-testid="`nc-form-input-${element.title.replaceAll(' ', '')}`" |
|
|
|
|
:column="element" |
|
|
|
|
:edit-enabled="editEnabled[index]" |
|
|
|
|
@click="editEnabled[index] = true" |
|
|
|
|
@cancel="editEnabled[index] = false" |
|
|
|
|
@update:edit-enabled="editEnabled[index] = $event" |
|
|
|
|
@click.stop.prevent |
|
|
|
|
/> |
|
|
|
|
</LazySmartsheetDivDataCell> |
|
|
|
|
</a-form-item> |
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
<div class="nc-form-help-text text-gray-500 text-xs" data-testid="nc-form-input-help-text-label"> |
|
|
|
|
{{ element.description }} |
|
|
|
|
<a-form-item |
|
|
|
|
v-else |
|
|
|
|
:name="element.title" |
|
|
|
|
class="!mb-0 nc-input-required-error" |
|
|
|
|
:rules="[ |
|
|
|
|
{ |
|
|
|
|
required: isRequired(element, element.required), |
|
|
|
|
message: `${element.label || element.title} is required`, |
|
|
|
|
}, |
|
|
|
|
]" |
|
|
|
|
> |
|
|
|
|
<LazySmartsheetDivDataCell class="relative"> |
|
|
|
|
<LazySmartsheetCell |
|
|
|
|
v-model="formState[element.title]" |
|
|
|
|
class="nc-input truncate" |
|
|
|
|
:class="`nc-form-input-${element.title.replaceAll(' ', '')}`" |
|
|
|
|
:data-testid="`nc-form-input-${element.title.replaceAll(' ', '')}`" |
|
|
|
|
:column="element" |
|
|
|
|
:edit-enabled="editEnabled[index]" |
|
|
|
|
@click="editEnabled[index] = true" |
|
|
|
|
@cancel="editEnabled[index] = false" |
|
|
|
|
@update:edit-enabled="editEnabled[index] = $event" |
|
|
|
|
@click.stop.prevent |
|
|
|
|
/> |
|
|
|
|
</LazySmartsheetDivDataCell> |
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
<div class="nc-form-help-text text-gray-500 text-xs" data-testid="nc-form-input-help-text-label"> |
|
|
|
|
{{ element.description }} |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
<template #footer> |
|
|
|
|
<div |
|
|
|
|
v-if="!localColumns.length" |
|
|
|
|
class="mt-4 border-dashed border-2 border-gray-400 py-3 text-gray-400 text-center" |
|
|
|
|
<template #footer> |
|
|
|
|
<div |
|
|
|
|
v-if="!localColumns.length" |
|
|
|
|
class="mt-4 border-dashed border-2 border-gray-400 py-3 text-gray-400 text-center" |
|
|
|
|
> |
|
|
|
|
Drag and drop fields here to add |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
|
</Draggable> |
|
|
|
|
|
|
|
|
|
<div class="justify-center flex mt-6"> |
|
|
|
|
<button |
|
|
|
|
type="submit" |
|
|
|
|
:disabled="!isUIAllowed('dataInsert')" |
|
|
|
|
class="uppercase scaling-btn nc-form-submit" |
|
|
|
|
data-testid="nc-form-submit" |
|
|
|
|
@click="submitForm" |
|
|
|
|
> |
|
|
|
|
Drag and drop fields here to add |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
|
</Draggable> |
|
|
|
|
|
|
|
|
|
<div class="justify-center flex mt-6"> |
|
|
|
|
<button |
|
|
|
|
type="submit" |
|
|
|
|
:disabled="!isUIAllowed('dataInsert')" |
|
|
|
|
class="uppercase scaling-btn nc-form-submit" |
|
|
|
|
data-testid="nc-form-submit" |
|
|
|
|
@click="submitForm" |
|
|
|
|
> |
|
|
|
|
{{ $t('general.submit') }} |
|
|
|
|
</button> |
|
|
|
|
{{ $t('general.submit') }} |
|
|
|
|
</button> |
|
|
|
|
</div> |
|
|
|
|
</a-card> |
|
|
|
|
</a-form> |
|
|
|
|
|
|
|
|
|
<a-divider /> |
|
|
|
|
|
|
|
|
|
<div v-if="isEditable" class="px-4 flex flex-col gap-2"> |
|
|
|
|
<!-- After form is submitted --> |
|
|
|
|
<div class="text-lg text-gray-700"> |
|
|
|
|
{{ $t('msg.info.afterFormSubmitted') }} |
|
|
|
|
</div> |
|
|
|
|
</a-card> |
|
|
|
|
</a-form> |
|
|
|
|
|
|
|
|
|
<a-divider /> |
|
|
|
|
<!-- Show this message --> |
|
|
|
|
<div class="text-gray-500 text-bold">{{ $t('msg.info.showMessage') }}:</div> |
|
|
|
|
<a-textarea |
|
|
|
|
v-model:value="formViewData.success_msg" |
|
|
|
|
:rows="3" |
|
|
|
|
hide-details |
|
|
|
|
class="nc-form-after-submit-msg" |
|
|
|
|
data-testid="nc-form-after-submit-msg" |
|
|
|
|
@change="updateView" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<!-- Other options --> |
|
|
|
|
<div class="flex flex-col gap-2 mt-4"> |
|
|
|
|
<div class="flex items-center"> |
|
|
|
|
<!-- Show "Submit Another Form" button --> |
|
|
|
|
<a-switch |
|
|
|
|
v-model:checked="formViewData.submit_another_form" |
|
|
|
|
v-e="[`a:form-view:submit-another-form`]" |
|
|
|
|
size="small" |
|
|
|
|
class="nc-form-checkbox-submit-another-form" |
|
|
|
|
data-testid="nc-form-checkbox-submit-another-form" |
|
|
|
|
@change="updateView" |
|
|
|
|
/> |
|
|
|
|
<span class="ml-4">{{ $t('msg.info.submitAnotherForm') }}</span> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div v-if="isEditable" class="px-4 flex flex-col gap-2"> |
|
|
|
|
<!-- After form is submitted --> |
|
|
|
|
<div class="text-lg text-gray-700"> |
|
|
|
|
{{ $t('msg.info.afterFormSubmitted') }} |
|
|
|
|
</div> |
|
|
|
|
<div class="flex items-center"> |
|
|
|
|
<!-- Show a blank form after 5 seconds --> |
|
|
|
|
<a-switch |
|
|
|
|
v-model:checked="formViewData.show_blank_form" |
|
|
|
|
v-e="[`a:form-view:show-blank-form`]" |
|
|
|
|
size="small" |
|
|
|
|
class="nc-form-checkbox-show-blank-form" |
|
|
|
|
data-testid="nc-form-checkbox-show-blank-form" |
|
|
|
|
@change="updateView" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<!-- Show this message --> |
|
|
|
|
<div class="text-gray-500 text-bold">{{ $t('msg.info.showMessage') }}:</div> |
|
|
|
|
<a-textarea |
|
|
|
|
v-model:value="formViewData.success_msg" |
|
|
|
|
:rows="3" |
|
|
|
|
hide-details |
|
|
|
|
class="nc-form-after-submit-msg" |
|
|
|
|
data-testid="nc-form-after-submit-msg" |
|
|
|
|
@change="updateView" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<!-- Other options --> |
|
|
|
|
<div class="flex flex-col gap-2 mt-4"> |
|
|
|
|
<div class="flex items-center"> |
|
|
|
|
<!-- Show "Submit Another Form" button --> |
|
|
|
|
<a-switch |
|
|
|
|
v-model:checked="formViewData.submit_another_form" |
|
|
|
|
v-e="[`a:form-view:submit-another-form`]" |
|
|
|
|
size="small" |
|
|
|
|
class="nc-form-checkbox-submit-another-form" |
|
|
|
|
data-testid="nc-form-checkbox-submit-another-form" |
|
|
|
|
@change="updateView" |
|
|
|
|
/> |
|
|
|
|
<span class="ml-4">{{ $t('msg.info.submitAnotherForm') }}</span> |
|
|
|
|
</div> |
|
|
|
|
<span class="ml-4">{{ $t('msg.info.showBlankForm') }}</span> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="flex items-center"> |
|
|
|
|
<!-- Show a blank form after 5 seconds --> |
|
|
|
|
<a-switch |
|
|
|
|
v-model:checked="formViewData.show_blank_form" |
|
|
|
|
v-e="[`a:form-view:show-blank-form`]" |
|
|
|
|
size="small" |
|
|
|
|
class="nc-form-checkbox-show-blank-form" |
|
|
|
|
data-testid="nc-form-checkbox-show-blank-form" |
|
|
|
|
@change="updateView" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<span class="ml-4">{{ $t('msg.info.showBlankForm') }}</span> |
|
|
|
|
</div> |
|
|
|
|
<div class="mb-12 flex items-center"> |
|
|
|
|
<a-switch |
|
|
|
|
v-model:checked="emailMe" |
|
|
|
|
v-e="[`a:form-view:email-me`]" |
|
|
|
|
size="small" |
|
|
|
|
class="nc-form-checkbox-send-email" |
|
|
|
|
data-testid="nc-form-checkbox-send-email" |
|
|
|
|
@change="onEmailChange" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<div class="mb-12 flex items-center"> |
|
|
|
|
<a-switch |
|
|
|
|
v-model:checked="emailMe" |
|
|
|
|
v-e="[`a:form-view:email-me`]" |
|
|
|
|
size="small" |
|
|
|
|
class="nc-form-checkbox-send-email" |
|
|
|
|
data-testid="nc-form-checkbox-send-email" |
|
|
|
|
@change="onEmailChange" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<!-- Email me at <email> --> |
|
|
|
|
<span class="ml-4"> |
|
|
|
|
{{ $t('msg.info.emailForm') }} <span class="text-bold text-gray-600">{{ state.user.value?.email }}</span> |
|
|
|
|
</span> |
|
|
|
|
<!-- Email me at <email> --> |
|
|
|
|
<span class="ml-4"> |
|
|
|
|
{{ $t('msg.info.emailForm') }} <span class="text-bold text-gray-600">{{ user?.email }}</span> |
|
|
|
|
</span> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</a-card> |
|
|
|
|
</a-col> |
|
|
|
|
</a-row> |
|
|
|
|
</a-card> |
|
|
|
|
</a-col> |
|
|
|
|
</a-row> |
|
|
|
|
</template> |
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
<style scoped lang="scss"> |
|
|
|
|