|
|
@ -454,353 +454,364 @@ const onFormItemClick = (element: any) => { |
|
|
|
<div v-else class="h-full w-full flex" data-testid="nc-form-wrapper"> |
|
|
|
<div v-else class="h-full w-full flex" data-testid="nc-form-wrapper"> |
|
|
|
<div |
|
|
|
<div |
|
|
|
v-if="formViewData" |
|
|
|
v-if="formViewData" |
|
|
|
class="flex-1 h-full overflow-y-auto nc-form-scrollbar p-6 bg-gray-50" |
|
|
|
class="flex-1 h-full overflow-auto nc-form-scrollbar p-6 bg-gray-50" |
|
|
|
:style="{background:(formViewData?.meta as Record<string,any>).theme_color}" |
|
|
|
:style="{background:(formViewData?.meta as Record<string,any>).theme_color}" |
|
|
|
> |
|
|
|
> |
|
|
|
<div class="h-[160px] bg-primary bg-opacity-75 border-gray-200 rounded-3xl"> |
|
|
|
<div :class="isEditable ? 'min-w-[616px] overflow-x-auto nc-form-scrollbar' : ''"> |
|
|
|
<!-- for future implementation of cover image --> |
|
|
|
<div class="h-[160px] bg-primary bg-opacity-75 border-gray-200 rounded-3xl"> |
|
|
|
<LazyNuxtImg |
|
|
|
<!-- for future implementation of cover image --> |
|
|
|
class="h-full" |
|
|
|
<LazyNuxtImg |
|
|
|
:src=" |
|
|
|
class="h-full" |
|
|
|
formViewData.banner_image_url ?? |
|
|
|
:src=" |
|
|
|
'http://localhost:8080/dltemp/KBFMWX8l0BIabZ6E/1708117800000/noco/pr5u10r2vcqirf2/mua2zr4vlyv3524/cvncb31si72grpm/X3yt8PX8ZFQEM5mluk.png' |
|
|
|
formViewData.banner_image_url ?? |
|
|
|
" |
|
|
|
'http://localhost:8080/dltemp/KBFMWX8l0BIabZ6E/1708117800000/noco/pr5u10r2vcqirf2/mua2zr4vlyv3524/cvncb31si72grpm/X3yt8PX8ZFQEM5mluk.png' |
|
|
|
alt="form-banner'" |
|
|
|
" |
|
|
|
placeholder |
|
|
|
alt="form-banner'" |
|
|
|
quality="75" |
|
|
|
placeholder |
|
|
|
/> |
|
|
|
quality="75" |
|
|
|
</div> |
|
|
|
/> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<a-card |
|
|
|
<a-card |
|
|
|
class="!py-8 !lg:py-12 border-gray-200 !rounded-3xl !mt-6 max-w-[688px] !mx-auto" |
|
|
|
class="!py-8 !lg:py-12 border-gray-200 !rounded-3xl !mt-6 max-w-[688px] !mx-auto" |
|
|
|
:body-style="{ |
|
|
|
:body-style="{ |
|
|
|
margin: '0 auto', |
|
|
|
margin: '0 auto', |
|
|
|
padding: '0px !important', |
|
|
|
padding: '0px !important', |
|
|
|
}" |
|
|
|
}" |
|
|
|
> |
|
|
|
> |
|
|
|
<a-form ref="formRef" :model="formState" class="nc-form" no-style> |
|
|
|
<a-form ref="formRef" :model="formState" class="nc-form" no-style> |
|
|
|
<!-- form header --> |
|
|
|
<!-- form header --> |
|
|
|
<div class="flex flex-col gap-4 px-8 lg:px-12"> |
|
|
|
<div class="flex flex-col gap-4 px-8 lg:px-12"> |
|
|
|
<!-- Form logo --> |
|
|
|
<!-- Form logo --> |
|
|
|
<div v-if="isEditable"> |
|
|
|
<div v-if="isEditable"> |
|
|
|
<div class="inline-block rounded-xl bg-gray-100 p-3"> |
|
|
|
<div class="inline-block rounded-xl bg-gray-100 p-3"> |
|
|
|
<NcButton type="secondary" size="small" class="nc-form-upload-logo" data-testid="nc-form-upload-log"> |
|
|
|
<NcButton type="secondary" size="small" class="nc-form-upload-logo" data-testid="nc-form-upload-log"> |
|
|
|
<div class="flex gap-2 items-center"> |
|
|
|
<div class="flex gap-2 items-center"> |
|
|
|
<component :is="iconMap.upload" class="w-4 h-4" /> |
|
|
|
<component :is="iconMap.upload" class="w-4 h-4" /> |
|
|
|
<span> Upload Logo </span> |
|
|
|
<span> Upload Logo </span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</NcButton> |
|
|
|
</NcButton> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<!-- form title --> |
|
|
|
<!-- form title --> |
|
|
|
|
|
|
|
|
|
|
|
<a-form-item v-if="isEditable"> |
|
|
|
<a-form-item v-if="isEditable"> |
|
|
|
<a-textarea |
|
|
|
<a-textarea |
|
|
|
v-model:value="formViewData.heading" |
|
|
|
v-model:value="formViewData.heading" |
|
|
|
class="w-full !font-bold !text-4xl !border-0 !border-b-1 !border-dashed !rounded-none !border-gray-400" |
|
|
|
class="w-full !font-bold !text-4xl !border-0 !border-b-1 !border-dashed !rounded-none !border-gray-400" |
|
|
|
:style="{ |
|
|
|
:style="{ |
|
|
|
'borderRightWidth': '0px !important', |
|
|
|
'borderRightWidth': '0px !important', |
|
|
|
'height': '70px', |
|
|
|
'height': '70px', |
|
|
|
'max-height': '250px', |
|
|
|
'max-height': '250px', |
|
|
|
'resize': 'vertical', |
|
|
|
'resize': 'vertical', |
|
|
|
}" |
|
|
|
}" |
|
|
|
autosize |
|
|
|
autosize |
|
|
|
size="large" |
|
|
|
size="large" |
|
|
|
hide-details |
|
|
|
hide-details |
|
|
|
:disabled="isLocked" |
|
|
|
:disabled="isLocked" |
|
|
|
placeholder="Form Title" |
|
|
|
placeholder="Form Title" |
|
|
|
:bordered="false" |
|
|
|
:bordered="false" |
|
|
|
data-testid="nc-form-heading" |
|
|
|
data-testid="nc-form-heading" |
|
|
|
@blur="updateView" |
|
|
|
@blur="updateView" |
|
|
|
@keydown.enter="updateView" |
|
|
|
@keydown.enter="updateView" |
|
|
|
/> |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div v-else class="w-full text-bold text-4xl"> |
|
|
|
<div v-else class="w-full text-bold text-4xl"> |
|
|
|
{{ formViewData.heading }} |
|
|
|
{{ formViewData.heading }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<!-- form description --> |
|
|
|
<!-- form description --> |
|
|
|
<a-form-item v-if="isEditable" class="w-full"> |
|
|
|
<a-form-item v-if="isEditable" class="w-full"> |
|
|
|
<a-textarea |
|
|
|
<a-textarea |
|
|
|
v-model:value="formViewData.subheading" |
|
|
|
v-model:value="formViewData.subheading" |
|
|
|
class="w-full !border-0 !border-b-1 !border-dashed !rounded-none !border-gray-400" |
|
|
|
class="w-full !border-0 !border-b-1 !border-dashed !rounded-none !border-gray-400" |
|
|
|
:style="{ |
|
|
|
:style="{ |
|
|
|
'borderRightWidth': '0px !important', |
|
|
|
'borderRightWidth': '0px !important', |
|
|
|
'height': '40px', |
|
|
|
'height': '40px', |
|
|
|
'min-height': '40px', |
|
|
|
'min-height': '40px', |
|
|
|
'resize': 'vertical', |
|
|
|
'resize': 'vertical', |
|
|
|
}" |
|
|
|
}" |
|
|
|
size="large" |
|
|
|
size="large" |
|
|
|
autosize |
|
|
|
autosize |
|
|
|
hide-details |
|
|
|
hide-details |
|
|
|
:placeholder="$t('msg.info.formDesc')" |
|
|
|
:placeholder="$t('msg.info.formDesc')" |
|
|
|
:bordered="false" |
|
|
|
:bordered="false" |
|
|
|
:disabled="!isEditable || isLocked" |
|
|
|
:disabled="!isEditable || isLocked" |
|
|
|
data-testid="nc-form-sub-heading" |
|
|
|
data-testid="nc-form-sub-heading" |
|
|
|
@blur="updateView" |
|
|
|
@blur="updateView" |
|
|
|
@click="updateView" |
|
|
|
@click="updateView" |
|
|
|
/> |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
|
|
<div v-else class="px-4 ml-3 w-full text-bold text-md"> |
|
|
|
<div v-else class="px-4 ml-3 w-full text-bold text-md"> |
|
|
|
{{ formViewData.subheading || '---' }} |
|
|
|
{{ formViewData.subheading || '---' }} |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<Draggable |
|
|
|
|
|
|
|
ref="draggableRef" |
|
|
|
|
|
|
|
:list="visibleColumns" |
|
|
|
|
|
|
|
item-key="fk_column_id" |
|
|
|
|
|
|
|
draggable=".item" |
|
|
|
|
|
|
|
group="form-inputs" |
|
|
|
|
|
|
|
class="h-full px-4 lg:px-6" |
|
|
|
|
|
|
|
:move="onMoveCallback" |
|
|
|
|
|
|
|
:disabled="isLocked" |
|
|
|
|
|
|
|
@change="onMove($event)" |
|
|
|
|
|
|
|
@start="drag = true" |
|
|
|
|
|
|
|
@end="drag = false" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<template #item="{ element, index }"> |
|
|
|
|
|
|
|
<div |
|
|
|
|
|
|
|
class="nc-editable item cursor-pointer relative bg-white" |
|
|
|
|
|
|
|
:class="[ |
|
|
|
|
|
|
|
`nc-form-drag-${element.title.replaceAll(' ', '')}`, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
'rounded-2xl overflow-hidden border-2': editEnabled, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
'border-transparent hover:(bg-gray-50) p-4 lg:p-6': activeRow !== element.title, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
'border-brand-500 my-1': activeRow === element.title, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
'!hover:bg-white !ring-0 !cursor-auto': isLocked, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
]" |
|
|
|
|
|
|
|
data-testid="nc-form-fields" |
|
|
|
|
|
|
|
@click="onFormItemClick(element)" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<div v-if="activeRow !== element.title"> |
|
|
|
|
|
|
|
<div> |
|
|
|
|
|
|
|
<span data-testid="nc-form-field-title"> |
|
|
|
|
|
|
|
{{ element.label || element.title }} |
|
|
|
|
|
|
|
</span> |
|
|
|
|
|
|
|
<span v-if="element.required" class="text-red-500"> *</span> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="nc-form-help-text text-gray-500 text-sm mt-2" data-testid="nc-form-help-text"> |
|
|
|
|
|
|
|
{{ element.description }} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Field Header --> |
|
|
|
|
|
|
|
<div v-if="activeRow === element.title" class="flex gap-3 items-center px-3 py-2 bg-gray-50"> |
|
|
|
|
|
|
|
<component :is="iconMap.drag" class="flex-none cursor-move !h-4 !w-4 text-gray-600" /> |
|
|
|
|
|
|
|
<div class="flex-1 flex items-center"> |
|
|
|
|
|
|
|
<SmartsheetHeaderVirtualCellIcon v-if="element && isVirtualCol(element)" :column-meta="element" /> |
|
|
|
|
|
|
|
<SmartsheetHeaderCellIcon v-else :column-meta="element" /> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<NcTooltip class="truncate flex-1" show-on-truncate-only> |
|
|
|
<Draggable |
|
|
|
<template #title> {{ element.label || element.title }} </template> |
|
|
|
ref="draggableRef" |
|
|
|
|
|
|
|
:list="visibleColumns" |
|
|
|
|
|
|
|
item-key="fk_column_id" |
|
|
|
|
|
|
|
draggable=".item" |
|
|
|
|
|
|
|
handle=".nc-form-field-drag-handler" |
|
|
|
|
|
|
|
group="form-inputs" |
|
|
|
|
|
|
|
ghost-class="nc-form-field-ghost" |
|
|
|
|
|
|
|
class="h-full px-4 lg:px-6" |
|
|
|
|
|
|
|
:move="onMoveCallback" |
|
|
|
|
|
|
|
:disabled="isLocked" |
|
|
|
|
|
|
|
@change="onMove($event)" |
|
|
|
|
|
|
|
@start="drag = true" |
|
|
|
|
|
|
|
@end="drag = false" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<template #item="{ element, index }"> |
|
|
|
|
|
|
|
<div |
|
|
|
|
|
|
|
class="nc-editable item cursor-pointer relative bg-white my-1" |
|
|
|
|
|
|
|
:class="[ |
|
|
|
|
|
|
|
`nc-form-drag-${element.title.replaceAll(' ', '')}`, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
'rounded-2xl overflow-hidden border-2': editEnabled, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
'nc-form-field-drag-handler border-transparent hover:(bg-gray-50) p-4 lg:p-6': |
|
|
|
|
|
|
|
activeRow !== element.title, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
'border-brand-500': activeRow === element.title, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
'!hover:bg-white !ring-0 !cursor-auto': isLocked, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
]" |
|
|
|
|
|
|
|
:style="{ |
|
|
|
|
|
|
|
transition: 'height 1s ease-in', |
|
|
|
|
|
|
|
}" |
|
|
|
|
|
|
|
data-testid="nc-form-fields" |
|
|
|
|
|
|
|
@click="onFormItemClick(element)" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<div v-if="activeRow !== element.title"> |
|
|
|
|
|
|
|
<div> |
|
|
|
<span data-testid="nc-form-field-title"> |
|
|
|
<span data-testid="nc-form-field-title"> |
|
|
|
{{ element.label || element.title }} |
|
|
|
{{ element.label || element.title }} |
|
|
|
</span> |
|
|
|
</span> |
|
|
|
<span v-if="element.required" class="text-red-500"> *</span> |
|
|
|
<span v-if="element.required" class="text-red-500"> *</span> |
|
|
|
</NcTooltip> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="nc-form-help-text text-gray-500 text-sm mt-2" data-testid="nc-form-help-text"> |
|
|
|
|
|
|
|
{{ element.description }} |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="flex gap-2 items-center"> |
|
|
|
|
|
|
|
<span |
|
|
|
<!-- Field Header --> |
|
|
|
class="text-gray-500 mr-2 nc-form-input-required" |
|
|
|
<div v-if="activeRow === element.title" class="w-full flex gap-3 items-center px-3 py-2 bg-gray-50"> |
|
|
|
data-testid="nc-form-input-required" |
|
|
|
<component |
|
|
|
@click=" |
|
|
|
:is="iconMap.drag" |
|
|
|
() => { |
|
|
|
class="nc-form-field-drag-handler flex-none cursor-move !h-4 !w-4 text-gray-600" |
|
|
|
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 class="flex-1 flex items-center max-w-[calc(100%_-_152px)]"> |
|
|
|
|
|
|
|
<SmartsheetHeaderVirtualCellIcon v-if="element && isVirtualCol(element)" :column-meta="element" /> |
|
|
|
|
|
|
|
<SmartsheetHeaderCellIcon v-else :column-meta="element" /> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<NcTooltip class="truncate" show-on-truncate-only> |
|
|
|
|
|
|
|
<template #title> {{ element.label || element.title }} </template> |
|
|
|
|
|
|
|
<span data-testid="nc-form-field-title"> |
|
|
|
|
|
|
|
{{ element.label || element.title }} |
|
|
|
|
|
|
|
</span> |
|
|
|
|
|
|
|
</NcTooltip> |
|
|
|
|
|
|
|
<span v-if="element.required" class="text-red-500"> *</span> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<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> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Field Body --> |
|
|
|
<!-- Field Body --> |
|
|
|
|
|
|
|
|
|
|
|
<div class="nc-form-field-body" :class="activeRow === element.title ? 'p-4 lg:p-6' : ''"> |
|
|
|
<div class="nc-form-field-body" :class="activeRow === element.title ? 'p-4 lg:p-6' : ''"> |
|
|
|
<template v-if="activeRow === element.title"> |
|
|
|
<template v-if="activeRow === element.title"> |
|
|
|
<a-form-item v-if="columnSupportsScanning(element.uidt)" class="my-0 !mb-1"> |
|
|
|
<a-form-item v-if="columnSupportsScanning(element.uidt)" class="my-0 !mb-1"> |
|
|
|
<div class="flex gap-2 items-center"> |
|
|
|
<div class="flex gap-2 items-center"> |
|
|
|
<span |
|
|
|
<span |
|
|
|
class="text-gray-500 mr-2 nc-form-input-required" |
|
|
|
class="text-gray-500 mr-2 nc-form-input-required" |
|
|
|
data-testid="nc-form-input-enable-scanner" |
|
|
|
data-testid="nc-form-input-enable-scanner" |
|
|
|
@click=" |
|
|
|
@click=" |
|
|
|
() => { |
|
|
|
() => { |
|
|
|
element.general.enable_scanner = !element.general.enable_scanner |
|
|
|
element.general.enable_scanner = !element.general.enable_scanner |
|
|
|
updateColMeta(element) |
|
|
|
updateColMeta(element) |
|
|
|
} |
|
|
|
} |
|
|
|
" |
|
|
|
" |
|
|
|
> |
|
|
|
> |
|
|
|
{{ $t('general.enableScanner') }} |
|
|
|
{{ $t('general.enableScanner') }} |
|
|
|
</span> |
|
|
|
</span> |
|
|
|
|
|
|
|
|
|
|
|
<a-switch |
|
|
|
<a-switch |
|
|
|
v-model:checked="element.enable_scanner" |
|
|
|
v-model:checked="element.enable_scanner" |
|
|
|
v-e="['a:form-view:field:mark-enable-scaner']" |
|
|
|
v-e="['a:form-view:field:mark-enable-scaner']" |
|
|
|
size="small" |
|
|
|
size="small" |
|
|
|
|
|
|
|
@change="updateColMeta(element)" |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a-form-item class="my-0 !mb-2"> |
|
|
|
|
|
|
|
<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="!my-0 !mb-3"> |
|
|
|
|
|
|
|
<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)" |
|
|
|
@change="updateColMeta(element)" |
|
|
|
/> |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</a-form-item> |
|
|
|
</a-form-item> |
|
|
|
</template> |
|
|
|
|
|
|
|
<div :class="activeRow !== element.title ? 'mt-2' : ''"> |
|
|
|
<a-form-item class="my-0 !mb-2"> |
|
|
|
<a-form-item |
|
|
|
<a-input |
|
|
|
v-if="isVirtualCol(element)" |
|
|
|
v-model:value="element.label" |
|
|
|
:name="element.title" |
|
|
|
type="text" |
|
|
|
class="!my-0 nc-input-required-error nc-form-input-item" |
|
|
|
class="form-meta-input nc-form-input-label" |
|
|
|
:rules="[ |
|
|
|
data-testid="nc-form-input-label" |
|
|
|
{ |
|
|
|
:placeholder="$t('msg.info.formInput')" |
|
|
|
required: isRequired(element, element.required), |
|
|
|
@change="updateColMeta(element)" |
|
|
|
message: `${element.label || element.title} is required`, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
]" |
|
|
|
> |
|
|
|
> |
|
|
|
</a-input> |
|
|
|
<LazySmartsheetVirtualCell |
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a-form-item class="!my-0 !mb-3"> |
|
|
|
|
|
|
|
<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> |
|
|
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
<div :class="activeRow !== element.title ? 'mt-2' : ''"> |
|
|
|
|
|
|
|
<a-form-item |
|
|
|
|
|
|
|
v-if="isVirtualCol(element)" |
|
|
|
|
|
|
|
:name="element.title" |
|
|
|
|
|
|
|
class="!my-0 nc-input-required-error nc-form-input-item" |
|
|
|
|
|
|
|
: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="!my-0 nc-input-required-error nc-form-input-item" |
|
|
|
|
|
|
|
:rules="[ |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
required: isRequired(element, element.required), |
|
|
|
|
|
|
|
message: `${element.label || element.title} is required`, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
]" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<LazySmartsheetDivDataCell class="relative"> |
|
|
|
|
|
|
|
<LazySmartsheetCell |
|
|
|
|
|
|
|
v-model="formState[element.title]" |
|
|
|
v-model="formState[element.title]" |
|
|
|
class="nc-input truncate" |
|
|
|
:row="row" |
|
|
|
|
|
|
|
class="nc-input" |
|
|
|
:class="`nc-form-input-${element.title.replaceAll(' ', '')}`" |
|
|
|
:class="`nc-form-input-${element.title.replaceAll(' ', '')}`" |
|
|
|
:data-testid="`nc-form-input-${element.title.replaceAll(' ', '')}`" |
|
|
|
:data-testid="`nc-form-input-${element.title.replaceAll(' ', '')}`" |
|
|
|
:column="element" |
|
|
|
:column="element" |
|
|
|
:edit-enabled="editEnabled[index]" |
|
|
|
|
|
|
|
@click="editEnabled[index] = true" |
|
|
|
|
|
|
|
@cancel="editEnabled[index] = false" |
|
|
|
|
|
|
|
@update:edit-enabled="editEnabled[index] = $event" |
|
|
|
|
|
|
|
@click.stop.prevent |
|
|
|
@click.stop.prevent |
|
|
|
/> |
|
|
|
/> |
|
|
|
</LazySmartsheetDivDataCell> |
|
|
|
</a-form-item> |
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
|
|
<a-form-item |
|
|
|
|
|
|
|
v-else |
|
|
|
|
|
|
|
:name="element.title" |
|
|
|
|
|
|
|
class="!my-0 nc-input-required-error nc-form-input-item" |
|
|
|
|
|
|
|
: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> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Field Settings --> |
|
|
|
|
|
|
|
<div |
|
|
|
|
|
|
|
v-if="activeRow === element.title && false" |
|
|
|
|
|
|
|
class="nc-form-field-settings border-t border-gray-200 p-4 lg:p-6" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<!-- Todo: Show on conditions, options limit,... --> |
|
|
|
|
|
|
|
<div class="flex items-start gap-3 px-3 py-2 border-1 border-gray-200 rounded-lg"> |
|
|
|
|
|
|
|
<a-switch v-e="['a:form-view:field:show-on-condition']" size="small" /> |
|
|
|
|
|
|
|
<div> |
|
|
|
|
|
|
|
<div class="font-medium text-gray-800">Show on condtions</div> |
|
|
|
|
|
|
|
<div class="text-gray-500">Shows field only when conditions are met</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
<!-- Field Settings --> |
|
|
|
<template #footer> |
|
|
|
<div |
|
|
|
<div |
|
|
|
v-if="activeRow === element.title && false" |
|
|
|
v-if="!visibleColumns.length" |
|
|
|
class="nc-form-field-settings border-t border-gray-200 p-4 lg:p-6" |
|
|
|
class="mt-4 border-dashed border-2 border-gray-400 py-3 text-gray-400 text-center" |
|
|
|
> |
|
|
|
> |
|
|
|
<!-- Todo: Show on conditions, options limit,... --> |
|
|
|
Select fields from right panel to add here |
|
|
|
<div class="flex items-start gap-3 px-3 py-2 border-1 border-gray-200 rounded-lg"> |
|
|
|
|
|
|
|
<a-switch v-e="['a:form-view:field:show-on-condition']" size="small" /> |
|
|
|
|
|
|
|
<div> |
|
|
|
|
|
|
|
<div class="font-medium text-gray-800">Show on condtions</div> |
|
|
|
|
|
|
|
<div class="text-gray-500">Shows field only when conditions are met</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
</Draggable> |
|
|
|
|
|
|
|
|
|
|
|
<template #footer> |
|
|
|
<div class="flex justify-between items-center mt-6 !px-8 !lg:px-12"> |
|
|
|
<div |
|
|
|
<NcButton |
|
|
|
v-if="!visibleColumns.length" |
|
|
|
html-type="reset" |
|
|
|
class="mt-4 border-dashed border-2 border-gray-400 py-3 text-gray-400 text-center" |
|
|
|
type="secondary" |
|
|
|
|
|
|
|
size="small" |
|
|
|
|
|
|
|
:disabled="!isUIAllowed('dataInsert')" |
|
|
|
|
|
|
|
class="nc-form-clear" |
|
|
|
|
|
|
|
data-testid="nc-form-clear" |
|
|
|
> |
|
|
|
> |
|
|
|
Select fields from right panel to add here |
|
|
|
Crear Form |
|
|
|
</div> |
|
|
|
</NcButton> |
|
|
|
</template> |
|
|
|
<NcButton |
|
|
|
</Draggable> |
|
|
|
html-type="submit" |
|
|
|
|
|
|
|
type="primary" |
|
|
|
<div class="flex justify-between items-center mt-6 !px-8 !lg:px-12"> |
|
|
|
size="small" |
|
|
|
<NcButton |
|
|
|
:disabled="!isUIAllowed('dataInsert')" |
|
|
|
html-type="reset" |
|
|
|
class="nc-form-submit" |
|
|
|
type="secondary" |
|
|
|
data-testid="nc-form-submit" |
|
|
|
size="small" |
|
|
|
@click="submitForm" |
|
|
|
:disabled="!isUIAllowed('dataInsert')" |
|
|
|
> |
|
|
|
class="nc-form-clear" |
|
|
|
{{ $t('general.submit') }} |
|
|
|
data-testid="nc-form-clear" |
|
|
|
</NcButton> |
|
|
|
> |
|
|
|
</div> |
|
|
|
Crear Form |
|
|
|
</a-form> |
|
|
|
</NcButton> |
|
|
|
|
|
|
|
<NcButton |
|
|
|
<div v-if="!parseProp(formViewData?.meta).hide_branding" class="px-8 lg:px-12"> |
|
|
|
html-type="submit" |
|
|
|
<a-divider v-if="!isLocked" class="!my-8" /> |
|
|
|
type="primary" |
|
|
|
<!-- Nocodb Branding --> |
|
|
|
size="small" |
|
|
|
<div class="flex items-center gap-3"> |
|
|
|
:disabled="!isUIAllowed('dataInsert')" |
|
|
|
<!-- Todo: add new NocoDB icon --> |
|
|
|
class="nc-form-submit" |
|
|
|
<img src="~assets/img/icons/64x64.png" alt="NocoDB" class="w-6" /> |
|
|
|
data-testid="nc-form-submit" |
|
|
|
<div class="text-sm text-gray-700">NocoDB Forms</div> |
|
|
|
@click="submitForm" |
|
|
|
</div> |
|
|
|
> |
|
|
|
|
|
|
|
{{ $t('general.submit') }} |
|
|
|
|
|
|
|
</NcButton> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</a-form> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div v-if="!parseProp(formViewData?.meta).hide_branding" class="px-8 lg:px-12"> |
|
|
|
|
|
|
|
<a-divider v-if="!isLocked" class="!my-8" /> |
|
|
|
|
|
|
|
<!-- Nocodb Branding --> |
|
|
|
|
|
|
|
<div class="flex items-center gap-3"> |
|
|
|
|
|
|
|
<!-- Todo: add new NocoDB icon --> |
|
|
|
|
|
|
|
<img src="~assets/img/icons/64x64.png" alt="NocoDB" class="w-6" /> |
|
|
|
|
|
|
|
<div class="text-sm text-gray-700">NocoDB Forms</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</a-card> |
|
|
|
</a-card> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div v-if="isEditable" class="h-full w-full max-w-[384px] nc-form-left-drawer border-l border-gray-200"> |
|
|
|
<div v-if="isEditable" class="h-full w-full max-w-[384px] nc-form-left-drawer border-l border-gray-200"> |
|
|
|
<Splitpanes horizontal class="w-full nc-form-right-splitpane"> |
|
|
|
<Splitpanes horizontal class="w-full nc-form-right-splitpane"> |
|
|
|
<Pane min-size="30" size="50" class="nc-form-right-splitpane-item p-2 md:p-4 flex flex-col space-y-4 !min-h-200px"> |
|
|
|
<Pane min-size="30" size="50" class="nc-form-right-splitpane-item p-4 flex flex-col space-y-4 !min-h-200px"> |
|
|
|
<div class="flex flex-wrap justify-between items-center gap-2"> |
|
|
|
<div class="flex flex-wrap justify-between items-center gap-2"> |
|
|
|
<div class="flex gap-3"> |
|
|
|
<div class="flex gap-3"> |
|
|
|
<div class="text-base font-bold text-gray-900"> |
|
|
|
<div class="text-base font-bold text-gray-900"> |
|
|
@ -883,7 +894,7 @@ const onFormItemClick = (element: any) => { |
|
|
|
<Draggable |
|
|
|
<Draggable |
|
|
|
v-model="localColumns" |
|
|
|
v-model="localColumns" |
|
|
|
item-key="id" |
|
|
|
item-key="id" |
|
|
|
class="" |
|
|
|
ghost-class="nc-form-field-ghost" |
|
|
|
:style="{ height: 'calc(100% - 64px)' }" |
|
|
|
:style="{ height: 'calc(100% - 64px)' }" |
|
|
|
@change="onMove($event)" |
|
|
|
@change="onMove($event)" |
|
|
|
> |
|
|
|
> |
|
|
@ -891,27 +902,26 @@ const onFormItemClick = (element: any) => { |
|
|
|
<div |
|
|
|
<div |
|
|
|
v-if="field.title.toLowerCase().includes(searchQuery.toLowerCase())" |
|
|
|
v-if="field.title.toLowerCase().includes(searchQuery.toLowerCase())" |
|
|
|
:key="field.id" |
|
|
|
:key="field.id" |
|
|
|
class="p-2 flex flex-row items-center border-b-1 last:border-none border-gray-200 hover:bg-gray-50" |
|
|
|
class="w-full p-2 flex flex-row items-center border-b-1 last:border-none border-gray-200 hover:bg-gray-50" |
|
|
|
:data-testid="`nc-form-field-item-${field.title}`" |
|
|
|
:data-testid="`nc-form-field-item-${field.title}`" |
|
|
|
> |
|
|
|
> |
|
|
|
<component :is="iconMap.drag" class="flex-none cursor-move !h-4 !w-4 text-gray-600 mr-1" /> |
|
|
|
<component :is="iconMap.drag" class="flex-none cursor-move !h-4 !w-4 text-gray-600 mr-1" /> |
|
|
|
<div |
|
|
|
<div |
|
|
|
class="flex-1 flex items-center justify-between cursor-pointer" |
|
|
|
class="flex-1 flex items-center justify-between space-x-2 cursor-pointer max-w-[calc(100%_-_20px)]" |
|
|
|
@click="showOrHideColumn(field, !field.show, true)" |
|
|
|
@click="showOrHideColumn(field, !field.show, true)" |
|
|
|
> |
|
|
|
> |
|
|
|
<div class="flex-1 flex items-center"> |
|
|
|
<div class="flex-1 flex items-center max-w-[calc(100%_-_40px)]"> |
|
|
|
<SmartsheetHeaderVirtualCellIcon v-if="field && isVirtualCol(field)" :column-meta="field" /> |
|
|
|
<SmartsheetHeaderVirtualCellIcon v-if="field && isVirtualCol(field)" :column-meta="field" /> |
|
|
|
<SmartsheetHeaderCellIcon v-else :column-meta="field" /> |
|
|
|
<SmartsheetHeaderCellIcon v-else :column-meta="field" /> |
|
|
|
|
|
|
|
|
|
|
|
<NcTooltip class="truncate flex-1 ml-1" show-on-truncate-only> |
|
|
|
<NcTooltip class="truncate ml-1" show-on-truncate-only> |
|
|
|
<template #title> {{ field.title }} </template> |
|
|
|
<template #title> {{ field.label || field.title }} </template> |
|
|
|
<span data-testid="nc-field-title"> |
|
|
|
<span data-testid="nc-field-title"> |
|
|
|
{{ field.title }} |
|
|
|
{{ field.label || field.title }} |
|
|
|
</span> |
|
|
|
</span> |
|
|
|
<span v-if="field.required" class="text-red-500"> *</span> |
|
|
|
|
|
|
|
</NcTooltip> |
|
|
|
</NcTooltip> |
|
|
|
|
|
|
|
<span v-if="field.required" class="text-red-500"> *</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<NcSwitch :checked="!!field.show" :disabled="field.required" /> |
|
|
|
<NcSwitch :checked="!!field.show" :disabled="field.required" /> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -1131,4 +1141,7 @@ const onFormItemClick = (element: any) => { |
|
|
|
:deep(.nc-form-field-body .nc-cell) { |
|
|
|
:deep(.nc-form-field-body .nc-cell) { |
|
|
|
@apply my-0; |
|
|
|
@apply my-0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.nc-form-field-ghost { |
|
|
|
|
|
|
|
@apply bg-gray-50; |
|
|
|
|
|
|
|
} |
|
|
|
</style> |
|
|
|
</style> |
|
|
|