|
|
@ -44,6 +44,7 @@ import { |
|
|
|
useViewData, |
|
|
|
useViewData, |
|
|
|
watch, |
|
|
|
watch, |
|
|
|
} from '#imports' |
|
|
|
} from '#imports' |
|
|
|
|
|
|
|
import type { ImageCropperConfig } from '~/lib' |
|
|
|
|
|
|
|
|
|
|
|
provide(IsFormInj, ref(true)) |
|
|
|
provide(IsFormInj, ref(true)) |
|
|
|
provide(IsGalleryInj, ref(false)) |
|
|
|
provide(IsGalleryInj, ref(false)) |
|
|
@ -64,6 +65,11 @@ const hiddenColTypes = [ |
|
|
|
UITypes.LastModifiedBy, |
|
|
|
UITypes.LastModifiedBy, |
|
|
|
] |
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const enum NcForm { |
|
|
|
|
|
|
|
heading = 'nc-form-heading', |
|
|
|
|
|
|
|
subheading = 'nc-form-sub-heading', |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const { isMobileMode, user } = useGlobal() |
|
|
|
const { isMobileMode, user } = useGlobal() |
|
|
|
|
|
|
|
|
|
|
|
const formRef = ref() |
|
|
|
const formRef = ref() |
|
|
@ -140,9 +146,7 @@ const imageCropperData = ref<{ |
|
|
|
type: string |
|
|
|
type: string |
|
|
|
name: string |
|
|
|
name: string |
|
|
|
} |
|
|
|
} |
|
|
|
cropperConfig: { |
|
|
|
cropperConfig: ImageCropperConfig |
|
|
|
aspectRatio?: number |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
uploadConfig?: { |
|
|
|
uploadConfig?: { |
|
|
|
path?: string |
|
|
|
path?: string |
|
|
|
} |
|
|
|
} |
|
|
@ -153,7 +157,12 @@ const imageCropperData = ref<{ |
|
|
|
type: '', |
|
|
|
type: '', |
|
|
|
name: '', |
|
|
|
name: '', |
|
|
|
}, |
|
|
|
}, |
|
|
|
cropperConfig: {}, |
|
|
|
cropperConfig: { |
|
|
|
|
|
|
|
stencilProps: {}, |
|
|
|
|
|
|
|
minHeight: 0, |
|
|
|
|
|
|
|
minWidth: 0, |
|
|
|
|
|
|
|
imageRestriction: 'none', |
|
|
|
|
|
|
|
}, |
|
|
|
uploadConfig: { |
|
|
|
uploadConfig: { |
|
|
|
path: '', |
|
|
|
path: '', |
|
|
|
}, |
|
|
|
}, |
|
|
@ -273,22 +282,26 @@ async function onMove(event: any, isVisibleFormFields = false) { |
|
|
|
visibleColumns.value[newIndex > oldIndex ? newIndex - 1 : newIndex < oldIndex ? newIndex + 1 : newIndex].fk_column_id, |
|
|
|
visibleColumns.value[newIndex > oldIndex ? newIndex - 1 : newIndex < oldIndex ? newIndex + 1 : newIndex].fk_column_id, |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!localColumns.value.length || localColumns.value.length === 1) { |
|
|
|
if (!localColumns.value.length || localColumns.value.length === 1) { |
|
|
|
element.order = 1 |
|
|
|
element.order = 1 |
|
|
|
} else if (localColumns.value.length - 1 === newIndex) { |
|
|
|
} else if (localColumns.value.length - 1 === newIndex) { |
|
|
|
element.order = (localColumns.value[newIndex - 1]?.order || 0) + 1 |
|
|
|
element.order = Math.max(...localColumns.value.map((e) => e?.order ?? 0)) + 1 |
|
|
|
} else if (newIndex === 0) { |
|
|
|
} else if (newIndex === 0) { |
|
|
|
element.order = (localColumns.value[1]?.order || 0) / 2 |
|
|
|
element.order = Math.min(...localColumns.value.map((e) => e?.order ?? 0)) / 2 |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
element.order = ((localColumns.value[newIndex - 1]?.order || 0) + (localColumns.value[newIndex + 1].order || 0)) / 2 |
|
|
|
element.order = ((localColumns.value[newIndex - 1]?.order ?? 0) + (localColumns.value[newIndex + 1].order ?? 0)) / 2 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
await $api.dbView.formColumnUpdate(element.id, element) |
|
|
|
await $api.dbView.formColumnUpdate(element.id, element) |
|
|
|
|
|
|
|
|
|
|
|
fields.value[fieldIndex] = element as any |
|
|
|
fields.value[fieldIndex] = element as any |
|
|
|
|
|
|
|
|
|
|
|
// saveOrUpdate(element, fieldIndex) |
|
|
|
localColumns.value = localColumns.value.sort((a, b) => { |
|
|
|
|
|
|
|
if (a.order !== undefined && b.order !== undefined) { |
|
|
|
|
|
|
|
return a.order - b.order |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return 0 |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
$e('a:form-view:reorder') |
|
|
|
$e('a:form-view:reorder') |
|
|
|
} |
|
|
|
} |
|
|
@ -304,7 +317,6 @@ async function showOrHideColumn(column: Record<string, any>, show: boolean, isSi |
|
|
|
const fieldIndex = fields.value?.findIndex((f) => f?.fk_column_id === column.fk_column_id) |
|
|
|
const fieldIndex = fields.value?.findIndex((f) => f?.fk_column_id === column.fk_column_id) |
|
|
|
|
|
|
|
|
|
|
|
if (fieldIndex !== -1 && fieldIndex !== undefined && fields.value?.[fieldIndex]) { |
|
|
|
if (fieldIndex !== -1 && fieldIndex !== undefined && fields.value?.[fieldIndex]) { |
|
|
|
console.log('column', column) |
|
|
|
|
|
|
|
column.show = show |
|
|
|
column.show = show |
|
|
|
await $api.dbView.formColumnUpdate(column.id, column) |
|
|
|
await $api.dbView.formColumnUpdate(column.id, column) |
|
|
|
|
|
|
|
|
|
|
@ -333,7 +345,7 @@ function shouldSkipColumn(col: Record<string, any>) { |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function handleAddOrRemoveAllColumns(value: boolean) { |
|
|
|
async function handleAddOrRemoveAllColumns<T>(value: T) { |
|
|
|
if (isLocked.value || !isEditable) return |
|
|
|
if (isLocked.value || !isEditable) return |
|
|
|
|
|
|
|
|
|
|
|
if (value) { |
|
|
|
if (value) { |
|
|
@ -381,6 +393,7 @@ function setFormData() { |
|
|
|
meta: { |
|
|
|
meta: { |
|
|
|
hide_branding: false, |
|
|
|
hide_branding: false, |
|
|
|
background_color: '#F9F9FA', |
|
|
|
background_color: '#F9F9FA', |
|
|
|
|
|
|
|
hide_banner: false, |
|
|
|
...(parseProp(formViewData.value?.meta) ?? {}), |
|
|
|
...(parseProp(formViewData.value?.meta) ?? {}), |
|
|
|
}, |
|
|
|
}, |
|
|
|
} |
|
|
|
} |
|
|
@ -464,19 +477,29 @@ const handleChangeBackground = (color: string) => { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const openUploadImage = (isUploadBanner: boolean) => { |
|
|
|
const openUploadImage = (isUploadBanner: boolean) => { |
|
|
|
if (!isEditable) return |
|
|
|
if (!isEditable || !isEeUI) return |
|
|
|
|
|
|
|
|
|
|
|
imageCropperData.value.uploadConfig = { |
|
|
|
imageCropperData.value.uploadConfig = { |
|
|
|
path: [NOCO, base.value.id, meta.value?.id, formViewData.value?.id].join('/'), |
|
|
|
path: [NOCO, base.value.id, meta.value?.id, formViewData.value?.id].join('/'), |
|
|
|
} |
|
|
|
} |
|
|
|
if (isUploadBanner) { |
|
|
|
if (isUploadBanner) { |
|
|
|
imageCropperData.value.cropperConfig = { |
|
|
|
imageCropperData.value.cropperConfig = { |
|
|
|
|
|
|
|
...imageCropperData.value.cropperConfig, |
|
|
|
|
|
|
|
stencilProps: { |
|
|
|
aspectRatio: 4 / 1, |
|
|
|
aspectRatio: 4 / 1, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
minHeight: 100, |
|
|
|
|
|
|
|
minWidth: 0, |
|
|
|
} |
|
|
|
} |
|
|
|
imageCropperData.value.cropFor = 'banner' |
|
|
|
imageCropperData.value.cropFor = 'banner' |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
imageCropperData.value.cropperConfig = { |
|
|
|
imageCropperData.value.cropperConfig = { |
|
|
|
|
|
|
|
...imageCropperData.value.cropperConfig, |
|
|
|
|
|
|
|
stencilProps: { |
|
|
|
aspectRatio: undefined, |
|
|
|
aspectRatio: undefined, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
minHeight: 150, |
|
|
|
|
|
|
|
minWidth: 150, |
|
|
|
} |
|
|
|
} |
|
|
|
imageCropperData.value.cropFor = 'logo' |
|
|
|
imageCropperData.value.cropFor = 'logo' |
|
|
|
} |
|
|
|
} |
|
|
@ -516,7 +539,7 @@ const handleOnUploadImage = (data: AttachmentResType = null) => { |
|
|
|
onClickOutside(draggableRef, (e) => { |
|
|
|
onClickOutside(draggableRef, (e) => { |
|
|
|
if ( |
|
|
|
if ( |
|
|
|
(e.target as HTMLElement)?.closest( |
|
|
|
(e.target as HTMLElement)?.closest( |
|
|
|
'.nc-dropdown-single-select-cell, .nc-dropdown-multi-select-cell, .nc-dropdown-user-select-cell', |
|
|
|
'.nc-dropdown-single-select-cell, .nc-dropdown-multi-select-cell, .nc-dropdown-user-select-cell, .nc-form-rich-text-field', |
|
|
|
) |
|
|
|
) |
|
|
|
) { |
|
|
|
) { |
|
|
|
return |
|
|
|
return |
|
|
@ -589,9 +612,13 @@ useEventListener( |
|
|
|
(e: FocusEvent) => { |
|
|
|
(e: FocusEvent) => { |
|
|
|
const nextActiveFieldTitle = |
|
|
|
const nextActiveFieldTitle = |
|
|
|
(e?.relatedTarget as HTMLElement)?.getAttribute('data-title') || |
|
|
|
(e?.relatedTarget as HTMLElement)?.getAttribute('data-title') || |
|
|
|
(e?.relatedTarget as HTMLElement)?.offsetParent?.closest('.nc-form-focus-element')?.getAttribute('data-title') |
|
|
|
(e?.relatedTarget as HTMLElement)?.offsetParent?.closest('.nc-form-focus-element')?.getAttribute('data-title') || |
|
|
|
|
|
|
|
(e?.relatedTarget as HTMLElement)?.closest('.nc-form-focus-element')?.getAttribute('data-title') |
|
|
|
if (activeRow.value && nextActiveFieldTitle && activeRow.value !== nextActiveFieldTitle) { |
|
|
|
if ( |
|
|
|
|
|
|
|
(activeRow.value || [NcForm.heading, NcForm.subheading].includes(nextActiveFieldTitle as NcForm)) && |
|
|
|
|
|
|
|
nextActiveFieldTitle && |
|
|
|
|
|
|
|
activeRow.value !== nextActiveFieldTitle |
|
|
|
|
|
|
|
) { |
|
|
|
if (isTabPressed.value) { |
|
|
|
if (isTabPressed.value) { |
|
|
|
activeRow.value = nextActiveFieldTitle |
|
|
|
activeRow.value = nextActiveFieldTitle |
|
|
|
} |
|
|
|
} |
|
|
@ -613,6 +640,30 @@ useEventListener( |
|
|
|
}, |
|
|
|
}, |
|
|
|
true, |
|
|
|
true, |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEventListener( |
|
|
|
|
|
|
|
document, |
|
|
|
|
|
|
|
'keydown', |
|
|
|
|
|
|
|
(e: KeyboardEvent) => { |
|
|
|
|
|
|
|
const cmdOrCtrl = isMac() ? e.metaKey : e.ctrlKey |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (e.key.toLowerCase()) { |
|
|
|
|
|
|
|
case 's': |
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
cmdOrCtrl && |
|
|
|
|
|
|
|
!( |
|
|
|
|
|
|
|
['input', 'textarea'].includes((e.target as any).nodeName.toLowerCase()) || |
|
|
|
|
|
|
|
(e.target as any)?.getAttribute('contenteditable') |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
e.preventDefault() |
|
|
|
|
|
|
|
updateView() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
true, |
|
|
|
|
|
|
|
) |
|
|
|
</script> |
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
<template> |
|
|
@ -634,29 +685,45 @@ useEventListener( |
|
|
|
:style="{ background: parseProp(formViewData?.meta)?.background_color || '#F9F9FA' }" |
|
|
|
:style="{ background: parseProp(formViewData?.meta)?.background_color || '#F9F9FA' }" |
|
|
|
data-testid="nc-form-wrapper-submit" |
|
|
|
data-testid="nc-form-wrapper-submit" |
|
|
|
> |
|
|
|
> |
|
|
|
<GeneralFormBanner :banner-image-url="formViewData?.banner_image_url" /> |
|
|
|
<div class="max-w-[max(33%,688px)] mx-auto"> |
|
|
|
|
|
|
|
<GeneralFormBanner |
|
|
|
|
|
|
|
v-if="!parseProp(formViewData?.meta).hide_banner" |
|
|
|
|
|
|
|
:banner-image-url="formViewData?.banner_image_url" |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
|
|
<div |
|
|
|
<div |
|
|
|
class="transition-all duration-300 ease-in relative max-w-[max(33%,688px)] mx-auto my-6 bg-white rounded-3xl border-1 border-gray-200 px-4 py-8 lg:p-12 md:(p-8 dark:bg-slate-700)" |
|
|
|
class="transition-all duration-300 ease-in relative my-6 bg-white rounded-3xl border-1 border-gray-200 px-4 py-8 lg:p-12 md:(p-8 dark:bg-slate-700)" |
|
|
|
> |
|
|
|
> |
|
|
|
<div v-if="formViewData" class="items-center justify-center text-center mt-2"> |
|
|
|
<div v-if="formViewData" class="items-center justify-center text-left mt-2"> |
|
|
|
<div> |
|
|
|
<div> |
|
|
|
<h1 class="text-2xl font-bold text-gray-900 mb-4"> |
|
|
|
<h1 class="text-2xl font-bold text-gray-900 mb-4"> |
|
|
|
{{ formViewData.heading }} |
|
|
|
{{ formViewData.heading }} |
|
|
|
</h1> |
|
|
|
</h1> |
|
|
|
|
|
|
|
|
|
|
|
<h2 v-if="formViewData.subheading" class="font-medium text-base text-gray-500 mb-4"> |
|
|
|
<div v-if="formViewData.subheading?.trim()"> |
|
|
|
{{ formViewData.subheading }} |
|
|
|
<LazyCellRichText |
|
|
|
</h2> |
|
|
|
:value="formViewData.subheading" |
|
|
|
|
|
|
|
class="font-medium text-base text-gray-500 !h-auto mb-4 -ml-1" |
|
|
|
|
|
|
|
is-form-field |
|
|
|
|
|
|
|
read-only |
|
|
|
|
|
|
|
sync-value-change |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div class="flex justify-center"> |
|
|
|
<div class="flex justify-center"> |
|
|
|
<div class="w-full lg:w-[95%]"> |
|
|
|
<div class="w-full"> |
|
|
|
<a-alert type="success" class="!my-4 text-center !rounded-lg"> |
|
|
|
<a-alert class="!my-4 !py-4 text-left !rounded-lg" type="success" outlined> |
|
|
|
<template #message> |
|
|
|
<template #message> |
|
|
|
<div class="text-center"> |
|
|
|
<LazyCellRichText |
|
|
|
{{ formViewData.success_msg || $t('msg.successfullySubmittedFormData') }} |
|
|
|
v-if="formViewData?.success_msg?.trim()" |
|
|
|
</div> |
|
|
|
:value="formViewData?.success_msg" |
|
|
|
|
|
|
|
class="!h-auto -ml-1" |
|
|
|
|
|
|
|
is-form-field |
|
|
|
|
|
|
|
read-only |
|
|
|
|
|
|
|
sync-value-change |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
<span v-else> {{ $t('msg.successfullySubmittedFormData') }} </span> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
</a-alert> |
|
|
|
</a-alert> |
|
|
|
|
|
|
|
|
|
|
@ -668,7 +735,7 @@ useEventListener( |
|
|
|
}} |
|
|
|
}} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div v-if="formViewData.submit_another_form || !isPublic" class="text-center mt-4"> |
|
|
|
<div v-if="formViewData.submit_another_form || !isPublic" class="text-right mt-4"> |
|
|
|
<NcButton type="primary" size="medium" @click="submitted = false"> |
|
|
|
<NcButton type="primary" size="medium" @click="submitted = false"> |
|
|
|
{{ $t('activity.submitAnotherForm') }} |
|
|
|
{{ $t('activity.submitAnotherForm') }} |
|
|
|
</NcButton> |
|
|
|
</NcButton> |
|
|
@ -678,11 +745,19 @@ useEventListener( |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div v-else class="h-full w-full flex" data-testid="nc-form-wrapper"> |
|
|
|
<div v-else class="nc-form-wrapper h-full w-full flex relative" data-testid="nc-form-wrapper"> |
|
|
|
<div v-if="isLoadingFormView" class="flex-1"></div> |
|
|
|
<div v-if="isLoadingFormView" class="flex-1 flex items-center justify-center text-center h-full"> |
|
|
|
|
|
|
|
<div> |
|
|
|
|
|
|
|
<GeneralLoader size="xlarge" /> |
|
|
|
|
|
|
|
<div class="mt-2"> |
|
|
|
|
|
|
|
{{ $t('general.loading') }} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<template v-else-if="formViewData"> |
|
|
|
<div |
|
|
|
<div |
|
|
|
v-else-if="formViewData" |
|
|
|
|
|
|
|
class="flex-1 h-full overflow-auto nc-form-scrollbar p-6" |
|
|
|
class="flex-1 h-full overflow-auto nc-form-scrollbar p-6" |
|
|
|
:style="{background:(formViewData?.meta as Record<string,any>).background_color || '#F9F9FA'}" |
|
|
|
:style="{background:(formViewData?.meta as Record<string,any>).background_color || '#F9F9FA'}" |
|
|
|
> |
|
|
|
> |
|
|
@ -696,15 +771,23 @@ useEventListener( |
|
|
|
@submit="handleOnUploadImage" |
|
|
|
@submit="handleOnUploadImage" |
|
|
|
></GeneralImageCropper> |
|
|
|
></GeneralImageCropper> |
|
|
|
<!-- cover image --> |
|
|
|
<!-- cover image --> |
|
|
|
<div class="group relative max-w-[max(33%,688px)] mx-auto"> |
|
|
|
<div v-if="!parseProp(formViewData?.meta).hide_banner" class="group relative max-w-[max(33%,688px)] mx-auto"> |
|
|
|
<GeneralFormBanner :banner-image-url="formViewData.banner_image_url" /> |
|
|
|
<GeneralFormBanner :banner-image-url="formViewData.banner_image_url" /> |
|
|
|
<div class="absolute bottom-0 right-0 hidden group-hover:block"> |
|
|
|
<div class="absolute bottom-0 right-0 hidden group-hover:block"> |
|
|
|
<div class="flex items-center space-x-1 m-2"> |
|
|
|
<div class="flex items-center space-x-1 m-2"> |
|
|
|
|
|
|
|
<NcTooltip :disabled="isEeUI"> |
|
|
|
|
|
|
|
<template #title> |
|
|
|
|
|
|
|
<div class="text-center"> |
|
|
|
|
|
|
|
{{ $t('msg.info.thisFeatureIsOnlyAvailableInEnterpriseEdition') }} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
<NcButton |
|
|
|
<NcButton |
|
|
|
type="secondary" |
|
|
|
type="secondary" |
|
|
|
size="small" |
|
|
|
size="small" |
|
|
|
class="nc-form-upload-banner-btn" |
|
|
|
class="nc-form-upload-banner-btn" |
|
|
|
data-testid="nc-form-upload-banner-btn" |
|
|
|
data-testid="nc-form-upload-banner-btn" |
|
|
|
|
|
|
|
:disabled="!isEeUI" |
|
|
|
@click="openUploadImage(true)" |
|
|
|
@click="openUploadImage(true)" |
|
|
|
> |
|
|
|
> |
|
|
|
<div class="flex gap-2 items-center"> |
|
|
|
<div class="flex gap-2 items-center"> |
|
|
@ -715,7 +798,8 @@ useEventListener( |
|
|
|
</span> |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</NcButton> |
|
|
|
</NcButton> |
|
|
|
<NcTooltip v-if="formViewData.banner_image_url"> |
|
|
|
</NcTooltip> |
|
|
|
|
|
|
|
<NcTooltip v-if="isEeUI && formViewData.banner_image_url"> |
|
|
|
<template #title> {{ $t('general.delete') }} {{ $t('general.banner') }} </template> |
|
|
|
<template #title> {{ $t('general.delete') }} {{ $t('general.banner') }} </template> |
|
|
|
<NcButton |
|
|
|
<NcButton |
|
|
|
type="secondary" |
|
|
|
type="secondary" |
|
|
@ -752,25 +836,36 @@ useEventListener( |
|
|
|
<!-- Form logo --> |
|
|
|
<!-- Form logo --> |
|
|
|
<div class="mb-4"> |
|
|
|
<div class="mb-4"> |
|
|
|
<div |
|
|
|
<div |
|
|
|
class="nc-form-logo-wrapper mx-6 group relative rounded-xl inline-block h-56px max-w-189px overflow-hidden" |
|
|
|
class="nc-form-logo-wrapper mx-6 group relative inline-block h-56px overflow-hidden flex items-center" |
|
|
|
:class="formViewData.logo_url ? 'hover:(w-full bg-gray-100)' : 'bg-gray-100'" |
|
|
|
:class=" |
|
|
|
|
|
|
|
formViewData.logo_url |
|
|
|
|
|
|
|
? 'max-w-189px hover:(w-full bg-gray-100 rounded-xl) ' |
|
|
|
|
|
|
|
: 'bg-gray-100 max-w-147px rounded-xl' |
|
|
|
|
|
|
|
" |
|
|
|
style="transition: all 0.3s ease-in" |
|
|
|
style="transition: all 0.3s ease-in" |
|
|
|
> |
|
|
|
> |
|
|
|
<LazyCellAttachmentImage |
|
|
|
<LazyCellAttachmentImage |
|
|
|
v-if="formViewData.logo_url" |
|
|
|
v-if="formViewData.logo_url" |
|
|
|
:srcs="getPossibleAttachmentSrc(parseProp(formViewData.logo_url))" |
|
|
|
:srcs="getPossibleAttachmentSrc(parseProp(formViewData.logo_url))" |
|
|
|
class="nc-form-logo !object-contain object-left max-h-full max-w-full !m-0 rounded-xl" |
|
|
|
class="flex-none nc-form-logo !object-contain object-left max-h-full max-w-full !m-0" |
|
|
|
/> |
|
|
|
/> |
|
|
|
<div |
|
|
|
<div |
|
|
|
class="items-center space-x-1 flex-nowrap m-3" |
|
|
|
class="items-center space-x-1 flex-nowrap m-3" |
|
|
|
:class="formViewData.logo_url ? 'hidden absolute top-0 left-0 group-hover:flex' : 'flex'" |
|
|
|
:class="formViewData.logo_url ? 'hidden absolute top-0 left-0 group-hover:flex' : 'flex'" |
|
|
|
> |
|
|
|
> |
|
|
|
|
|
|
|
<NcTooltip :disabled="isEeUI"> |
|
|
|
|
|
|
|
<template #title> |
|
|
|
|
|
|
|
<div class="text-center"> |
|
|
|
|
|
|
|
{{ $t('msg.info.thisFeatureIsOnlyAvailableInEnterpriseEdition') }} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</template> |
|
|
|
<NcButton |
|
|
|
<NcButton |
|
|
|
v-if="isEditable" |
|
|
|
v-if="isEditable" |
|
|
|
type="secondary" |
|
|
|
type="secondary" |
|
|
|
size="small" |
|
|
|
size="small" |
|
|
|
class="nc-form-upload-logo-btn" |
|
|
|
class="nc-form-upload-logo-btn" |
|
|
|
data-testid="nc-form-upload-log-btn" |
|
|
|
data-testid="nc-form-upload-log-btn" |
|
|
|
|
|
|
|
:disabled="!isEeUI" |
|
|
|
@click="openUploadImage(false)" |
|
|
|
@click="openUploadImage(false)" |
|
|
|
> |
|
|
|
> |
|
|
|
<div class="flex gap-2 items-center"> |
|
|
|
<div class="flex gap-2 items-center"> |
|
|
@ -778,7 +873,8 @@ useEventListener( |
|
|
|
<span> {{ formViewData.logo_url ? $t('general.replace') : $t('general.upload') }} Logo</span> |
|
|
|
<span> {{ formViewData.logo_url ? $t('general.replace') : $t('general.upload') }} Logo</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</NcButton> |
|
|
|
</NcButton> |
|
|
|
<NcTooltip v-if="formViewData.logo_url"> |
|
|
|
</NcTooltip> |
|
|
|
|
|
|
|
<NcTooltip v-if="isEeUI && formViewData.logo_url"> |
|
|
|
<template #title> {{ $t('general.delete') }} {{ $t('general.logo') }} </template> |
|
|
|
<template #title> {{ $t('general.delete') }} {{ $t('general.logo') }} </template> |
|
|
|
<NcButton |
|
|
|
<NcButton |
|
|
|
type="secondary" |
|
|
|
type="secondary" |
|
|
@ -814,16 +910,16 @@ useEventListener( |
|
|
|
'mb-4 py-0 lg:py-0': !isEditable, |
|
|
|
'mb-4 py-0 lg:py-0': !isEditable, |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
{ |
|
|
|
'hover:bg-gray-50': activeRow !== 'nc-form-heading' && isEditable, |
|
|
|
'hover:bg-gray-50': activeRow !== NcForm.heading && isEditable, |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
{ |
|
|
|
'bg-gray-50': activeRow === 'nc-form-heading' && isEditable, |
|
|
|
'bg-gray-50': activeRow === NcForm.heading && isEditable, |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
{ |
|
|
|
'!hover:bg-white !ring-0 !cursor-auto': isLocked, |
|
|
|
'!hover:bg-white !ring-0 !cursor-auto': isLocked, |
|
|
|
}, |
|
|
|
}, |
|
|
|
]" |
|
|
|
]" |
|
|
|
@click.stop="onFormItemClick({ title: 'nc-form-heading' })" |
|
|
|
@click.stop="onFormItemClick({ title: NcForm.heading })" |
|
|
|
> |
|
|
|
> |
|
|
|
<a-form-item v-if="isEditable" class="!my-0"> |
|
|
|
<a-form-item v-if="isEditable" class="!my-0"> |
|
|
|
<a-textarea |
|
|
|
<a-textarea |
|
|
@ -841,8 +937,8 @@ useEventListener( |
|
|
|
:disabled="isLocked" |
|
|
|
:disabled="isLocked" |
|
|
|
placeholder="Form Title" |
|
|
|
placeholder="Form Title" |
|
|
|
:bordered="false" |
|
|
|
:bordered="false" |
|
|
|
data-testid="nc-form-heading" |
|
|
|
:data-testid="NcForm.heading" |
|
|
|
data-title="nc-form-heading" |
|
|
|
:data-title="NcForm.heading" |
|
|
|
@blur="updateView" |
|
|
|
@blur="updateView" |
|
|
|
@keydown.enter="updateView" |
|
|
|
@keydown.enter="updateView" |
|
|
|
/> |
|
|
|
/> |
|
|
@ -864,41 +960,36 @@ useEventListener( |
|
|
|
'mb-4 py-0 lg:py-0': !isEditable, |
|
|
|
'mb-4 py-0 lg:py-0': !isEditable, |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
{ |
|
|
|
'hover:bg-gray-50': activeRow !== 'nc-form-sub-heading' && isEditable, |
|
|
|
'hover:bg-gray-50': activeRow !== NcForm.subheading && isEditable, |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
{ |
|
|
|
'bg-gray-50': activeRow === 'nc-form-sub-heading' && isEditable, |
|
|
|
'bg-gray-50': activeRow === NcForm.subheading && isEditable, |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
{ |
|
|
|
'!hover:bg-white !ring-0 !cursor-auto': isLocked, |
|
|
|
'!hover:bg-white !ring-0 !cursor-auto': isLocked, |
|
|
|
}, |
|
|
|
}, |
|
|
|
]" |
|
|
|
]" |
|
|
|
@click.stop="onFormItemClick({ title: 'nc-form-sub-heading' })" |
|
|
|
@click.stop="onFormItemClick({ title: NcForm.subheading })" |
|
|
|
> |
|
|
|
> |
|
|
|
<a-form-item v-if="isEditable" class="w-full !my-0"> |
|
|
|
<LazyCellRichText |
|
|
|
<a-textarea |
|
|
|
v-if="isEditable && !isLocked" |
|
|
|
v-model:value="formViewData.subheading" |
|
|
|
v-model:value="formViewData.subheading" |
|
|
|
class="nc-form-focus-element w-full !px-0 !m-0 !border-0 !rounded-none font-medium text-base !text-gray-500" |
|
|
|
|
|
|
|
:style="{ |
|
|
|
|
|
|
|
borderRightWidth: '0px !important', |
|
|
|
|
|
|
|
resize: 'vertical', |
|
|
|
|
|
|
|
}" |
|
|
|
|
|
|
|
size="large" |
|
|
|
|
|
|
|
auto-size |
|
|
|
|
|
|
|
hide-details |
|
|
|
|
|
|
|
:placeholder="$t('msg.info.formDesc')" |
|
|
|
:placeholder="$t('msg.info.formDesc')" |
|
|
|
:bordered="false" |
|
|
|
class="nc-form-focus-element font-medium text-base !text-gray-500 -ml-1" |
|
|
|
:disabled="!isEditable || isLocked" |
|
|
|
is-form-field |
|
|
|
data-testid="nc-form-sub-heading" |
|
|
|
:autofocus="activeRow === NcForm.subheading" |
|
|
|
data-title="nc-form-sub-heading" |
|
|
|
:data-testid="NcForm.subheading" |
|
|
|
@blur="updateView" |
|
|
|
:data-title="NcForm.subheading" |
|
|
|
@click="updateView" |
|
|
|
@update:value="updateView" |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
<LazyCellRichText |
|
|
|
|
|
|
|
v-else-if="formViewData.subheading" |
|
|
|
|
|
|
|
:value="formViewData.subheading" |
|
|
|
|
|
|
|
class="font-medium text-base !text-gray-500 -ml-1" |
|
|
|
|
|
|
|
is-form-field |
|
|
|
|
|
|
|
read-only |
|
|
|
|
|
|
|
sync-value-change |
|
|
|
/> |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div v-else class="font-medium text-base text-gray-500"> |
|
|
|
|
|
|
|
{{ formViewData.subheading || '---' }} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
@ -938,9 +1029,6 @@ useEventListener( |
|
|
|
'!hover:bg-white !ring-0 !cursor-auto': isLocked, |
|
|
|
'!hover:bg-white !ring-0 !cursor-auto': isLocked, |
|
|
|
}, |
|
|
|
}, |
|
|
|
]" |
|
|
|
]" |
|
|
|
:style="{ |
|
|
|
|
|
|
|
transition: 'height 1s ease-in', |
|
|
|
|
|
|
|
}" |
|
|
|
|
|
|
|
:data-title="element.title" |
|
|
|
:data-title="element.title" |
|
|
|
data-testid="nc-form-fields" |
|
|
|
data-testid="nc-form-fields" |
|
|
|
@click.stop="onFormItemClick(element)" |
|
|
|
@click.stop="onFormItemClick(element)" |
|
|
@ -955,9 +1043,16 @@ useEventListener( |
|
|
|
> |
|
|
|
> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div class="nc-form-help-text text-gray-500 text-sm mt-2" data-testid="nc-form-help-text"> |
|
|
|
<LazyCellRichText |
|
|
|
{{ element.description }} |
|
|
|
v-if="element.description" |
|
|
|
</div> |
|
|
|
:value="element.description" |
|
|
|
|
|
|
|
is-form-field |
|
|
|
|
|
|
|
read-only |
|
|
|
|
|
|
|
sync-value-change |
|
|
|
|
|
|
|
class="nc-form-help-text text-gray-500 text-sm mt-2 -ml-1" |
|
|
|
|
|
|
|
data-testid="nc-form-help-text" |
|
|
|
|
|
|
|
@update:value="updateColMeta(element)" |
|
|
|
|
|
|
|
/> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<!-- Field Header --> |
|
|
|
<!-- Field Header --> |
|
|
@ -971,7 +1066,11 @@ useEventListener( |
|
|
|
<SmartsheetHeaderCellIcon v-else :column-meta="element" /> |
|
|
|
<SmartsheetHeaderCellIcon v-else :column-meta="element" /> |
|
|
|
|
|
|
|
|
|
|
|
<NcTooltip class="truncate max-w-3/5" show-on-truncate-only> |
|
|
|
<NcTooltip class="truncate max-w-3/5" show-on-truncate-only> |
|
|
|
<template #title> {{ element.title }} </template> |
|
|
|
<template #title> |
|
|
|
|
|
|
|
<div class="text-center"> |
|
|
|
|
|
|
|
{{ element.title }} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</template> |
|
|
|
<span data-testid="nc-form-input-label"> |
|
|
|
<span data-testid="nc-form-input-label"> |
|
|
|
{{ element.title }} |
|
|
|
{{ element.title }} |
|
|
|
</span> |
|
|
|
</span> |
|
|
@ -1023,19 +1122,16 @@ useEventListener( |
|
|
|
/> |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
|
|
<a-form-item class="!my-0 !mb-3"> |
|
|
|
<a-form-item class="my-0 !mb-3"> |
|
|
|
<a-textarea |
|
|
|
<LazyCellRichText |
|
|
|
v-model:value="element.description" |
|
|
|
v-model:value="element.description" |
|
|
|
:rows="1" |
|
|
|
:placeholder="$t('msg.info.formHelpText')" |
|
|
|
auto-size |
|
|
|
|
|
|
|
hide-details |
|
|
|
|
|
|
|
class="form-meta-input nc-form-input-help-text" |
|
|
|
class="form-meta-input nc-form-input-help-text" |
|
|
|
|
|
|
|
is-form-field |
|
|
|
data-testid="nc-form-input-help-text" |
|
|
|
data-testid="nc-form-input-help-text" |
|
|
|
:placeholder="$t('msg.info.formHelpText')" |
|
|
|
@update:value="updateColMeta(element)" |
|
|
|
@keydown.enter.prevent |
|
|
|
/></a-form-item> |
|
|
|
@change="updateColMeta(element)" |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
<a-form-item |
|
|
|
<a-form-item |
|
|
|
v-if="columnSupportsScanning(element.uidt)" |
|
|
|
v-if="columnSupportsScanning(element.uidt)" |
|
|
|
class="!my-0 !mb-3 nc-form-input-enable-scanner-form-item" |
|
|
|
class="!my-0 !mb-3 nc-form-input-enable-scanner-form-item" |
|
|
@ -1112,7 +1208,7 @@ useEventListener( |
|
|
|
|
|
|
|
|
|
|
|
<!-- Field Settings --> |
|
|
|
<!-- Field Settings --> |
|
|
|
<div |
|
|
|
<div |
|
|
|
v-if="activeRow === element.title" |
|
|
|
v-if="activeRow === element.title && isSelectTypeCol(element.uidt)" |
|
|
|
class="nc-form-field-settings border-t border-gray-200 p-4 lg:p-6 flex flex-col gap-3" |
|
|
|
class="nc-form-field-settings border-t border-gray-200 p-4 lg:p-6 flex flex-col gap-3" |
|
|
|
> |
|
|
|
> |
|
|
|
<!-- Layout --> |
|
|
|
<!-- Layout --> |
|
|
@ -1120,9 +1216,14 @@ useEventListener( |
|
|
|
<div>Layout</div> |
|
|
|
<div>Layout</div> |
|
|
|
|
|
|
|
|
|
|
|
<a-radio-group |
|
|
|
<a-radio-group |
|
|
|
v-model:value="element.meta.isList" |
|
|
|
:value="!!element.meta.isList" |
|
|
|
class="nc-form-field-layout !mt-2" |
|
|
|
class="nc-form-field-layout !mt-2" |
|
|
|
@change="updateColMeta(element)" |
|
|
|
@update:value=" |
|
|
|
|
|
|
|
(value) => { |
|
|
|
|
|
|
|
element.meta.isList = value |
|
|
|
|
|
|
|
updateColMeta(element) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
" |
|
|
|
> |
|
|
|
> |
|
|
|
<a-radio :value="false">{{ $t('general.dropdown') }}</a-radio> |
|
|
|
<a-radio :value="false">{{ $t('general.dropdown') }}</a-radio> |
|
|
|
<a-radio :value="true">{{ $t('general.list') }}</a-radio> |
|
|
|
<a-radio :value="true">{{ $t('general.list') }}</a-radio> |
|
|
@ -1131,7 +1232,7 @@ useEventListener( |
|
|
|
<!-- Todo: Show on conditions,... --> |
|
|
|
<!-- Todo: Show on conditions,... --> |
|
|
|
<!-- eslint-disable vue/no-constant-condition --> |
|
|
|
<!-- eslint-disable vue/no-constant-condition --> |
|
|
|
<div v-if="false" class="flex items-start gap-3 px-3 py-2 border-1 border-gray-200 rounded-lg"> |
|
|
|
<div v-if="false" 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" /> |
|
|
|
<a-switch v-e="['a:form-view:field:show-on-condition']" size="small" class="nc-form-switch-focus" /> |
|
|
|
<div> |
|
|
|
<div> |
|
|
|
<div class="font-medium text-gray-800">{{ $t('labels.showOnConditions') }}</div> |
|
|
|
<div class="font-medium text-gray-800">{{ $t('labels.showOnConditions') }}</div> |
|
|
|
<div class="text-gray-500">{{ $t('labels.showFieldOnConditionsMet') }}</div> |
|
|
|
<div class="text-gray-500">{{ $t('labels.showFieldOnConditionsMet') }}</div> |
|
|
@ -1145,6 +1246,7 @@ useEventListener( |
|
|
|
v-model:checked="element.meta.isLimitOption" |
|
|
|
v-model:checked="element.meta.isLimitOption" |
|
|
|
v-e="['a:form-view:field:limit-options']" |
|
|
|
v-e="['a:form-view:field:limit-options']" |
|
|
|
size="small" |
|
|
|
size="small" |
|
|
|
|
|
|
|
class="nc-form-switch-focus" |
|
|
|
@change="updateColMeta(element)" |
|
|
|
@change="updateColMeta(element)" |
|
|
|
/> |
|
|
|
/> |
|
|
|
<div class="font-medium text-gray-800">{{ $t('labels.limitOptions') }}</div> |
|
|
|
<div class="font-medium text-gray-800">{{ $t('labels.limitOptions') }}</div> |
|
|
@ -1155,6 +1257,7 @@ useEventListener( |
|
|
|
<LazySmartsheetFormLimitOptions |
|
|
|
<LazySmartsheetFormLimitOptions |
|
|
|
v-model:model-value="element.meta.limitOptions" |
|
|
|
v-model:model-value="element.meta.limitOptions" |
|
|
|
:column="element" |
|
|
|
:column="element" |
|
|
|
|
|
|
|
:is-required="isRequired(element, element.required)" |
|
|
|
@update:model-value="updateColMeta(element)" |
|
|
|
@update:model-value="updateColMeta(element)" |
|
|
|
></LazySmartsheetFormLimitOptions> |
|
|
|
></LazySmartsheetFormLimitOptions> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -1291,8 +1394,10 @@ useEventListener( |
|
|
|
<div class="flex-1 flex flex-row items-center truncate cursor-pointer"> |
|
|
|
<div class="flex-1 flex flex-row items-center truncate cursor-pointer"> |
|
|
|
<div class="flex-1 font-base my-1.5">{{ $t('activity.selectAllFields') }}</div> |
|
|
|
<div class="flex-1 font-base my-1.5">{{ $t('activity.selectAllFields') }}</div> |
|
|
|
<div class="flex items-center px-2"> |
|
|
|
<div class="flex items-center px-2"> |
|
|
|
<NcSwitch |
|
|
|
<a-switch |
|
|
|
:checked="visibleColumns.length === localColumns.length" |
|
|
|
:checked="visibleColumns.length === localColumns.length" |
|
|
|
|
|
|
|
size="small" |
|
|
|
|
|
|
|
class="nc-switch" |
|
|
|
@change="handleAddOrRemoveAllColumns" |
|
|
|
@change="handleAddOrRemoveAllColumns" |
|
|
|
/> |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -1331,7 +1436,9 @@ useEventListener( |
|
|
|
<div class="ml-1 inline-block max-w-1/2"> |
|
|
|
<div class="ml-1 inline-block max-w-1/2"> |
|
|
|
<NcTooltip class="truncate text-sm" :disabled="drag" show-on-truncate-only> |
|
|
|
<NcTooltip class="truncate text-sm" :disabled="drag" show-on-truncate-only> |
|
|
|
<template #title> |
|
|
|
<template #title> |
|
|
|
|
|
|
|
<div class="text-center"> |
|
|
|
{{ field.title }} |
|
|
|
{{ field.title }} |
|
|
|
|
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
<span data-testid="nc-field-title"> {{ field.title }} </span> |
|
|
|
<span data-testid="nc-field-title"> {{ field.title }} </span> |
|
|
|
</NcTooltip> |
|
|
|
</NcTooltip> |
|
|
@ -1340,16 +1447,25 @@ useEventListener( |
|
|
|
<span> (</span> |
|
|
|
<span> (</span> |
|
|
|
<NcTooltip class="truncate" :disabled="drag" show-on-truncate-only> |
|
|
|
<NcTooltip class="truncate" :disabled="drag" show-on-truncate-only> |
|
|
|
<template #title> |
|
|
|
<template #title> |
|
|
|
|
|
|
|
<div class="text-center"> |
|
|
|
{{ field.label }} |
|
|
|
{{ field.label }} |
|
|
|
|
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
<span data-testid="nc-field-title ">{{ field.label?.trim() }}</span> |
|
|
|
<span data-testid="nc-field-title ">{{ field.label?.trim() }}</span> |
|
|
|
</NcTooltip> |
|
|
|
</NcTooltip> |
|
|
|
<span>)</span> |
|
|
|
<span>)</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<span v-if="isRequired(field, field.required)" class="text-red-500 text-sm align-top"> *</span> |
|
|
|
<span v-if="isRequired(field, field.required)" class="text-red-500 text-sm align-top" |
|
|
|
|
|
|
|
> *</span |
|
|
|
|
|
|
|
> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<NcSwitch :checked="!!field.show" :disabled="field.required || isLocked || !isEditable" /> |
|
|
|
<a-switch |
|
|
|
|
|
|
|
:checked="!!field.show" |
|
|
|
|
|
|
|
:disabled="field.required || isLocked || !isEditable" |
|
|
|
|
|
|
|
class="nc-switch" |
|
|
|
|
|
|
|
size="small" |
|
|
|
|
|
|
|
/> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</template> |
|
|
@ -1408,7 +1524,7 @@ useEventListener( |
|
|
|
<!-- Hide NocoDB Branding --> |
|
|
|
<!-- Hide NocoDB Branding --> |
|
|
|
<a-switch |
|
|
|
<a-switch |
|
|
|
v-if="isEeUI" |
|
|
|
v-if="isEeUI" |
|
|
|
v-e="[`a:form-view:submit-another-form`]" |
|
|
|
v-e="[`a:form-view:hide-branding`]" |
|
|
|
:checked="parseProp(formViewData.meta)?.hide_branding" |
|
|
|
:checked="parseProp(formViewData.meta)?.hide_branding" |
|
|
|
size="small" |
|
|
|
size="small" |
|
|
|
class="nc-form-hide-branding" |
|
|
|
class="nc-form-hide-branding" |
|
|
@ -1423,14 +1539,37 @@ useEventListener( |
|
|
|
} |
|
|
|
} |
|
|
|
" |
|
|
|
" |
|
|
|
/> |
|
|
|
/> |
|
|
|
<a-tooltip v-else placement="top"> |
|
|
|
<NcTooltip v-else placement="top"> |
|
|
|
<template #title> |
|
|
|
<template #title> |
|
|
|
{{ $t('msg.info.upgradeToEnterpriseEdition', { extraInfo: `to ${$t('labels.hideNocodbBranding')}` }) }} |
|
|
|
<div class="text-center"> |
|
|
|
|
|
|
|
{{ $t('msg.info.thisFeatureIsOnlyAvailableInEnterpriseEdition') }} |
|
|
|
|
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
<a-switch :checked="false" size="small" :disabled="true" /> |
|
|
|
<a-switch :checked="false" size="small" :disabled="true" /> |
|
|
|
</a-tooltip> |
|
|
|
</NcTooltip> |
|
|
|
<span class="ml-4">{{ $t('labels.hideNocodbBranding') }}</span> |
|
|
|
<span class="ml-4">{{ $t('labels.hideNocodbBranding') }}</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="flex items-center"> |
|
|
|
|
|
|
|
<!-- Hide Banner --> |
|
|
|
|
|
|
|
<a-switch |
|
|
|
|
|
|
|
v-e="[`a:form-view:hide-banner`]" |
|
|
|
|
|
|
|
:checked="parseProp(formViewData.meta)?.hide_banner" |
|
|
|
|
|
|
|
size="small" |
|
|
|
|
|
|
|
class="nc-form-hide-banner" |
|
|
|
|
|
|
|
data-testid="nc-form-hide-banner" |
|
|
|
|
|
|
|
:disabled="isLocked || !isEditable" |
|
|
|
|
|
|
|
@change=" |
|
|
|
|
|
|
|
(value) => { |
|
|
|
|
|
|
|
if (isLocked || !isEditable) return |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(formViewData!.meta as Record<string,any>).hide_banner = value |
|
|
|
|
|
|
|
updateView() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
" |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<span class="ml-4">{{ $t('general.hide') }} {{ $t('general.banner') }}</span> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div class="p-4 flex flex-col space-y-4"> |
|
|
|
<div class="p-4 flex flex-col space-y-4"> |
|
|
@ -1444,15 +1583,22 @@ useEventListener( |
|
|
|
<div class="text-gray-800 mb-2"> |
|
|
|
<div class="text-gray-800 mb-2"> |
|
|
|
{{ $t('msg.info.formDisplayMessage') }} |
|
|
|
{{ $t('msg.info.formDisplayMessage') }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<a-textarea |
|
|
|
<a-form-item class="!my-0"> |
|
|
|
|
|
|
|
<LazyCellRichText |
|
|
|
|
|
|
|
v-if="!isLocked && isEditable" |
|
|
|
v-model:value="formViewData.success_msg" |
|
|
|
v-model:value="formViewData.success_msg" |
|
|
|
:rows="3" |
|
|
|
class="nc-form-after-submit-msg" |
|
|
|
hide-details |
|
|
|
:is-form-field="true" |
|
|
|
class="nc-form-after-submit-msg !rounded-lg !px-3 !py-1" |
|
|
|
|
|
|
|
data-testid="nc-form-after-submit-msg" |
|
|
|
data-testid="nc-form-after-submit-msg" |
|
|
|
:disabled="isLocked || !isEditable" |
|
|
|
@update:value="updateView" /> |
|
|
|
@change="updateView" |
|
|
|
<LazyCellRichText |
|
|
|
/> |
|
|
|
v-else |
|
|
|
|
|
|
|
:value="formViewData.success_msg" |
|
|
|
|
|
|
|
class="nc-form-after-submit-msg" |
|
|
|
|
|
|
|
is-form-field |
|
|
|
|
|
|
|
read-only |
|
|
|
|
|
|
|
data-testid="nc-form-after-submit-msg" |
|
|
|
|
|
|
|
/></a-form-item> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<!-- Other options --> |
|
|
|
<!-- Other options --> |
|
|
@ -1508,6 +1654,7 @@ useEventListener( |
|
|
|
</Pane> |
|
|
|
</Pane> |
|
|
|
</Splitpanes> |
|
|
|
</Splitpanes> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
</template> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
<div |
|
|
|
<div |
|
|
@ -1538,7 +1685,7 @@ useEventListener( |
|
|
|
.nc-input { |
|
|
|
.nc-input { |
|
|
|
@apply appearance-none w-full; |
|
|
|
@apply appearance-none w-full; |
|
|
|
&:not(.layout-list) { |
|
|
|
&:not(.layout-list) { |
|
|
|
@apply !bg-white rounded-lg border-solid border-1 border-gray-200 focus-within:border-brand-500; |
|
|
|
@apply !bg-white rounded-lg border-solid border-1 border-gray-200 !focus-within:border-brand-500; |
|
|
|
} |
|
|
|
} |
|
|
|
&.layout-list { |
|
|
|
&.layout-list { |
|
|
|
@apply h-auto !pl-0 !py-1; |
|
|
|
@apply h-auto !pl-0 !py-1; |
|
|
@ -1556,10 +1703,6 @@ useEventListener( |
|
|
|
} |
|
|
|
} |
|
|
|
&:not(.nc-cell-longtext) { |
|
|
|
&:not(.nc-cell-longtext) { |
|
|
|
@apply px-2 py-2; |
|
|
|
@apply px-2 py-2; |
|
|
|
|
|
|
|
|
|
|
|
:deep(textarea) { |
|
|
|
|
|
|
|
@apply !p-2; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
&.nc-cell-json { |
|
|
|
&.nc-cell-json { |
|
|
@ -1568,20 +1711,17 @@ useEventListener( |
|
|
|
@apply w-full; |
|
|
|
@apply w-full; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.form-meta-input { |
|
|
|
:deep(.ant-picker) { |
|
|
|
@apply !rounded-lg !text-sm; |
|
|
|
@apply !py-0; |
|
|
|
&::placeholder { |
|
|
|
} |
|
|
|
@apply !text-gray-500; |
|
|
|
:deep(input.nc-cell-field) { |
|
|
|
|
|
|
|
@apply !py-0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.nc-form-input-label { |
|
|
|
.nc-form-input-label { |
|
|
|
@apply !px-4 !py-2 font-semibold text-gray-800; |
|
|
|
@apply !px-4 !py-2 font-semibold text-gray-800 !rounded-lg !text-sm; |
|
|
|
} |
|
|
|
|
|
|
|
.nc-form-input-help-text { |
|
|
|
|
|
|
|
@apply !px-4 !py-1 text-gray-700; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.nc-form-help-text, |
|
|
|
.nc-form-help-text, |
|
|
@ -1655,6 +1795,9 @@ useEventListener( |
|
|
|
:deep(.nc-form-input-required + button):focus { |
|
|
|
:deep(.nc-form-input-required + button):focus { |
|
|
|
box-shadow: 0 0 0 2px #fff, 0 0 0 4px #3366ff; |
|
|
|
box-shadow: 0 0 0 2px #fff, 0 0 0 4px #3366ff; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
:deep(.nc-form-switch-focus):focus { |
|
|
|
|
|
|
|
box-shadow: 0 0 0 2px #fff, 0 0 0 4px #3366ff; |
|
|
|
|
|
|
|
} |
|
|
|
.nc-form-field-layout { |
|
|
|
.nc-form-field-layout { |
|
|
|
@apply !flex !items-center w-full space-x-3; |
|
|
|
@apply !flex !items-center w-full space-x-3; |
|
|
|
|
|
|
|
|
|
|
@ -1662,6 +1805,43 @@ useEventListener( |
|
|
|
@apply border-1 border-gray-200 rounded-lg !py-2 !px-3 basis-full !mr-0 !items-center; |
|
|
|
@apply border-1 border-gray-200 rounded-lg !py-2 !px-3 basis-full !mr-0 !items-center; |
|
|
|
.ant-radio { |
|
|
|
.ant-radio { |
|
|
|
@apply !top-0; |
|
|
|
@apply !top-0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:focus-within .ant-radio-inner { |
|
|
|
|
|
|
|
box-shadow: 0 0 0 2px #fff, 0 0 0 4px #3366ff; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.nc-form-wrapper { |
|
|
|
|
|
|
|
.ant-switch:focus, |
|
|
|
|
|
|
|
.ant-switch-checked:focus { |
|
|
|
|
|
|
|
box-shadow: 0 0 0 2px #fff, 0 0 0 4px #3366ff; |
|
|
|
|
|
|
|
&:hover { |
|
|
|
|
|
|
|
box-shadow: none; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
</style> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss"> |
|
|
|
|
|
|
|
.form-meta-input { |
|
|
|
|
|
|
|
.nc-textarea-rich-editor { |
|
|
|
|
|
|
|
@apply pl-3 pr-4 !rounded-lg !text-sm border-1 border-gray-200 focus-within:border-brand-500; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.nc-form-input-label .nc-textarea-rich-editor { |
|
|
|
|
|
|
|
@apply pt-2 pb-1 font-semibold text-gray-800; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
&.nc-form-input-help-text .nc-textarea-rich-editor { |
|
|
|
|
|
|
|
@apply pt-1 text-gray-700; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
.nc-form-after-submit-msg { |
|
|
|
|
|
|
|
.nc-textarea-rich-editor { |
|
|
|
|
|
|
|
@apply pl-1 pr-2 pt-2 pb-1 !rounded-lg !text-sm border-1 border-gray-200 focus-within:border-brand-500; |
|
|
|
|
|
|
|
.ProseMirror { |
|
|
|
|
|
|
|
min-height: 5rem; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|