Browse Source

Merge pull request #6500 from nocodb/fix/frm

fix: form view UI fixes
pull/6538/head
Raju Udava 1 year ago committed by GitHub
parent
commit
e6410d5289
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      packages/nc-gui/components/cell/Checkbox.vue
  2. 3
      packages/nc-gui/components/cell/Integer.vue
  3. 2
      packages/nc-gui/components/cell/MultiSelect.vue
  4. 1
      packages/nc-gui/components/cell/SingleSelect.vue
  5. 10
      packages/nc-gui/components/cell/TextArea.vue
  6. 15
      packages/nc-gui/components/cell/attachment/utils.ts
  7. 2
      packages/nc-gui/components/nc/Button.vue
  8. 9
      packages/nc-gui/components/smartsheet/Cell.vue
  9. 36
      packages/nc-gui/components/smartsheet/Form.vue
  10. 2
      packages/nc-gui/components/smartsheet/column/DefaultValue.vue
  11. 8
      packages/nc-gui/components/smartsheet/grid/Table.vue
  12. 15
      packages/nc-gui/components/smartsheet/header/Cell.vue
  13. 2
      packages/nc-gui/composables/useSharedFormViewStore.ts
  14. 7
      packages/nc-gui/lang/en.json
  15. 20
      packages/nc-gui/pages/index/[typeOrId]/form/[viewId]/index/index.vue
  16. 22
      packages/nc-gui/pages/index/[typeOrId]/form/[viewId]/index/survey.vue

4
packages/nc-gui/components/cell/Checkbox.vue

@ -80,7 +80,7 @@ useSelectedCellKeyupListener(active, (e) => {
<template>
<div
class="flex cursor-pointer w-full h-full"
class="flex cursor-pointer w-full h-full items-center"
:class="{
'justify-center': !isForm || !isGallery,
'w-full flex-start': isForm || isGallery,
@ -89,7 +89,7 @@ useSelectedCellKeyupListener(active, (e) => {
}"
@click="onClick(false, $event)"
>
<div class="items-center py-2" :class="{ 'w-full justify-start': isEditColumnMenu || isGallery }" @click="onClick(true)">
<div class="items-center" :class="{ 'w-full justify-start': isEditColumnMenu || isGallery || isForm }" @click="onClick(true)">
<Transition name="layout" mode="out-in" :duration="100">
<component
:is="getMdiIcon(vModel ? checkboxMeta.icon.checked : checkboxMeta.icon.unchecked)"

3
packages/nc-gui/components/cell/Integer.vue

@ -87,6 +87,9 @@ function onKeyDown(e: any) {
v-model="vModel"
class="outline-none py-2 px-1 border-none w-full h-full text-sm"
type="number"
:class="{
'pl-2': isExpandedFormOpen,
}"
style="letter-spacing: 0.06rem"
:placeholder="isEditColumn ? $t('labels.optional') : ''"
@blur="editEnabled = false"

2
packages/nc-gui/components/cell/MultiSelect.vue

@ -321,6 +321,8 @@ const handleClose = (e: MouseEvent) => {
!aselect.value.$el.contains(e.target) &&
!document.querySelector('.nc-dropdown-multi-select-cell.active')?.contains(e.target as Node)
) {
// loose focus when clicked outside
isEditable.value = false
isOpen.value = false
}
}

1
packages/nc-gui/components/cell/SingleSelect.vue

@ -217,6 +217,7 @@ const onKeydown = (e: KeyboardEvent) => {
const onSelect = () => {
isOpen.value = false
isEditable.value = false
}
const cellClickHook = inject(CellClickHookInj, null)

10
packages/nc-gui/components/cell/TextArea.vue

@ -28,6 +28,8 @@ const isEditColumn = inject(EditColumnInj, ref(false))
const rowHeight = inject(RowHeightInj, ref(1 as const))
const isForm = inject(IsFormInj, ref(false))
const { showNull } = useGlobal()
const vModel = useVModel(props, 'modelValue', emits, { defaultValue: '' })
@ -68,10 +70,11 @@ onClickOutside(inputWrapperRef, (e) => {
<template>
<NcDropdown v-model:visible="isVisible" class="overflow-visible" :trigger="[]" placement="bottomLeft">
<div
class="flex flex-row pt-0.5"
class="flex flex-row pt-0.5 w-full"
:class="{
'min-h-10': rowHeight !== 1,
'min-h-6.5': rowHeight === 1,
'h-full': isForm,
}"
>
<textarea
@ -80,7 +83,10 @@ onClickOutside(inputWrapperRef, (e) => {
v-model="vModel"
rows="4"
class="h-full w-full outline-none border-none"
:class="`${editEnabled ? 'p-2' : ''}`"
:class="{
'p-2': editEnabled,
'py-1 h-full': isForm,
}"
:style="{
minHeight: `${height}px`,
}"

15
packages/nc-gui/components/cell/attachment/utils.ts

@ -33,6 +33,8 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
(updateModelValue: (data: string | Record<string, any>[]) => void) => {
const isReadonly = inject(ReadonlyInj, ref(false))
const { t } = useI18n()
const isPublic = inject(IsPublicInj, ref(false))
const isForm = inject(IsFormInj, ref(false))
@ -61,8 +63,6 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
const { appInfo } = useGlobal()
const { t } = useI18n()
const { getAttachmentSrc } = useAttachment()
const defaultAttachmentMeta = {
@ -138,7 +138,16 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
continue
}
}
// this prevent file with same names
const isFileNameAlreadyExist = attachments.value.some((el) => el.title === file.name)
if (isFileNameAlreadyExist) {
message.error(
t('labels.duplicateAttachment', {
filename: file.name,
}),
)
return
}
files.push(file)
}

2
packages/nc-gui/components/nc/Button.vue

@ -17,7 +17,7 @@ import type { NcButtonSize } from '~/lib'
interface Props {
loading?: boolean
disabled?: boolean
type?: ButtonType | 'danger' | undefined
type?: ButtonType | 'danger' | 'secondary' | undefined
size?: NcButtonSize
centered?: boolean
}

9
packages/nc-gui/components/smartsheet/Cell.vue

@ -48,7 +48,6 @@ import {
useDebounceFn,
useProject,
useSmartsheetRowStoreOrThrow,
useVModel,
} from '#imports'
interface Props {
@ -73,7 +72,9 @@ const readOnly = toRef(props, 'readOnly', false)
provide(ColumnInj, column)
provide(EditModeInj, useVModel(props, 'editEnabled', emit))
const editEnabled = useVModel(props, 'editEnabled', emit)
provide(EditModeInj, editEnabled)
provide(ActiveCellInj, active)
@ -203,8 +204,10 @@ onUnmounted(() => {
{
'text-brand-500': isPrimary(column) && !props.virtual && !isForm,
'nc-grid-numeric-cell-right': isGrid && isNumericField && !isEditColumnMenu && !isForm && !isExpandedFormOpen,
'h-[40px]': !props.editEnabled && isForm && !isSurveyForm && !isAttachment(column) && !props.virtual,
'h-10': isForm && !isSurveyForm && !isAttachment(column) && !props.virtual,
'nc-grid-numeric-cell-left': (isForm && isNumericField && isExpandedFormOpen) || isEditColumnMenu,
'!min-h-30 resize-y': isTextArea(column) && (isForm || isSurveyForm),
'!border-2 !border-brand-500': props.editEnabled && (isSurveyForm || isForm),
},
]"
@keydown.enter.exact="navigate(NavigateDir.NEXT, $event)"

36
packages/nc-gui/components/smartsheet/Form.vue

@ -428,27 +428,27 @@ watch(view, (nextView) => {
</div>
<div class="flex flex-wrap gap-2 mb-4">
<button
<NcButton
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"
type="secondary"
class="nc-form-add-all"
data-testid="nc-form-add-all"
@click="addAllColumns"
>
<!-- Add all -->
{{ $t('general.addAll') }}
</button>
</NcButton>
<button
<NcButton
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"
type="secondary"
class="nc-form-remove-all"
data-testid="nc-form-remove-all"
@click="removeAllColumns"
>
<!-- Remove all -->
{{ $t('general.removeAll') }}
</button>
</NcButton>
</div>
</div>
@ -552,10 +552,11 @@ watch(view, (nextView) => {
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',
'height': '70px',
'max-height': '250px',
'resize': 'vertical',
}"
autosize
size="large"
hide-details
placeholder="Form Title"
@ -581,6 +582,7 @@ watch(view, (nextView) => {
'resize': 'vertical',
}"
size="large"
autosize
hide-details
:placeholder="$t('msg.info.formDesc')"
:bordered="false"
@ -689,7 +691,7 @@ watch(view, (nextView) => {
</a-input>
</a-form-item>
<a-form-item class="mt-2 mb-0 w-1/2 !mb-1">
<a-form-item class="mt-2 mb-0 w-1/2">
<a-input
v-model:value="element.description"
type="text"
@ -768,7 +770,7 @@ watch(view, (nextView) => {
</LazySmartsheetDivDataCell>
</a-form-item>
<div class="nc-form-help-text text-gray-500 text-xs" data-testid="nc-form-input-help-text-label">
<div class="nc-form-help-text text-gray-500 text-xs truncate" data-testid="nc-form-input-help-text-label">
{{ element.description }}
</div>
</div>
@ -785,15 +787,16 @@ watch(view, (nextView) => {
</Draggable>
<div class="justify-center flex mt-6">
<button
type="submit"
<NcButton
html-type="submit"
type="primary"
:disabled="!isUIAllowed('dataInsert')"
class="uppercase scaling-btn nc-form-submit"
class="nc-form-submit"
data-testid="nc-form-submit"
@click="submitForm"
>
{{ $t('general.submit') }}
</button>
</NcButton>
</div>
</a-card>
</a-form>
@ -898,7 +901,6 @@ watch(view, (nextView) => {
.nc-form-help-text,
.nc-input-required-error {
max-width: 100%;
word-break: break-all;
white-space: pre-line;
}

2
packages/nc-gui/components/smartsheet/column/DefaultValue.vue

@ -49,7 +49,7 @@ useProvideSmartsheetRowStore(vModel, rowRef)
<div class="!my-3 text-xs">{{ $t('placeholder.defaultValue') }}</div>
<div class="flex flex-row gap-2">
<div class="border-1 flex items-center w-full px-3 my-[-4px] border-gray-300 rounded-md">
<LazySmartsheetCell :column="vModel" :model-value="cdfValue" :edit-enabled="true" />
<LazySmartsheetCell :column="vModel" :model-value="cdfValue" :edit-enabled="true" class="!border-none" />
<component
:is="iconMap.close"
v-if="vModel.uidt !== UITypes.Year"

8
packages/nc-gui/components/smartsheet/grid/Table.vue

@ -1599,8 +1599,12 @@ const handleCellClick = (event: MouseEvent, row: number, col: number) => {
{{ $t('activity.deleteRow') }}
</NcMenuItem>
<div v-else-if="contextMenuTarget && deleteRangeOfRows">
<NcMenuItem v-e="['a:row:delete']" class="nc-project-menu-item text-red-600" @click="deleteSelectedRangeOfRows">
<GeneralIcon icon="delete" class="text-gray-500 text-error" />
<NcMenuItem
v-e="['a:row:delete']"
class="nc-project-menu-item !text-red-600 !hover:bg-red-50"
@click="deleteSelectedRangeOfRows"
>
<GeneralIcon icon="delete" class="text-gray-500 text-red-600" />
<!-- Delete Rows -->
{{ $t('activity.deleteRows') }}
</NcMenuItem>

15
packages/nc-gui/components/smartsheet/header/Cell.vue

@ -17,6 +17,8 @@ const hideMenu = toRef(props, 'hideMenu')
const isForm = inject(IsFormInj, ref(false))
const isSurveyForm = inject(IsSurveyFormInj, ref(false))
const isExpandedForm = inject(IsExpandedFormOpenInj, ref(false))
const isDropDownOpen = ref(false)
@ -63,12 +65,16 @@ const openDropDown = () => {
@click.right="openDropDown"
@click="isDropDownOpen = false"
>
<SmartsheetHeaderCellIcon v-if="column && !props.hideIcon" />
<SmartsheetHeaderCellIcon
v-if="column && !props.hideIcon"
:class="{
'self-start': isForm || isSurveyForm,
}"
/>
<div
v-if="column"
class="name pl-1 !truncate"
class="name pl-1"
:class="{ 'cursor-pointer pt-0.25': !isForm && isUIAllowed('fieldEdit') && !hideMenu }"
style="white-space: pre-line"
:title="column.title"
>
{{ column.title }}
@ -114,6 +120,7 @@ const openDropDown = () => {
<style scoped>
.name {
max-width: calc(100% - 10px);
word-break: break-all;
word-break: break-word;
white-space: pre-line;
}
</style>

2
packages/nc-gui/composables/useSharedFormViewStore.ts

@ -213,8 +213,6 @@ const [useProvideSharedFormStore, useSharedFormStore] = useInjectionState((share
submitted.value = true
progress.value = false
await message.success(sharedFormView.value?.success_msg || 'Saved successfully.')
} catch (e: any) {
console.log(e)
await message.error(await extractSdkResponseErrorMsg(e))

7
packages/nc-gui/lang/en.json

@ -299,7 +299,7 @@
"noFieldsFound": "No fields found",
"displayValue": "Display Value",
"expand": "Expand",
"hideAll":"Hide all",
"hideAll": "Hide all",
"hideSystemFields": "hideSystemFields",
"removeFile": "Remove File",
"hasMany": "Has Many",
@ -385,6 +385,7 @@
}
},
"labels": {
"duplicateAttachment": "File with name {filename} already attached",
"toAddress": "To Address",
"subject": "Subject",
"body": "Body",
@ -809,7 +810,7 @@
"selectBarcodeFormat": "Select a Barcode format",
"projName": "Enter Project Name",
"selectGroupField": "Select a Grouping Field",
"selectGroupFieldNotFound" : "No Single Select Field can be found. Please create one first.",
"selectGroupFieldNotFound": "No Single Select Field can be found. Please create one first.",
"selectGeoField": "Select a GeoData Field",
"selectGeoFieldNotFound": "No GeoData Field can be found. Please create one first.",
"password": {
@ -844,7 +845,7 @@
"key": "Key"
},
"msg": {
"enterPassword":"Enter password",
"enterPassword": "Enter password",
"bySigningUp": "By signing up, you agree to the",
"subscribeToOurWeeklyNewsletter": "Subscribe to our weekly newsletter",
"verifyingPassword": "Verifying Password",

20
packages/nc-gui/pages/index/[typeOrId]/form/[viewId]/index/index.vue

@ -72,17 +72,16 @@ const onDecode = async (scannedCodeValue: string) => {
<template>
<div class="h-full flex flex-col items-center">
<div
class="color-transition relative flex flex-col justify-center gap-2 w-full max-w-[max(33%,600px)] m-auto py-4 pb-8 px-16 md:(bg-white dark:bg-slate-700 rounded-lg border-1 border-gray-200 shadow-xl)"
class="color-transition flex flex-col justify-center gap-2 w-full max-w-[max(33%,600px)] m-auto py-4 pb-8 px-16 md:(bg-white dark:bg-slate-700 rounded-lg border-1 border-gray-200 shadow-xl)"
>
<template v-if="sharedFormView">
<h1 class="prose-2xl font-bold self-center my-4" style="word-break: break-all">
<h1 class="prose-2xl font-bold self-center my-4 break-words">
{{ sharedFormView.heading }}
</h1>
<h2
v-if="sharedFormView.subheading"
class="prose-lg text-slate-500 dark:text-slate-300 self-center mb-4 leading-6"
style="word-break: break-all"
class="prose-lg text-slate-500 dark:text-slate-300 self-center mb-4 leading-6 break-words"
>
{{ sharedFormView.subheading }}
</h2>
@ -187,8 +186,8 @@ const onDecode = async (scannedCodeValue: string) => {
</LazySmartsheetDivDataCell>
<div
class="flex flex-col gap-2 text-slate-500 dark:text-slate-300 text-[0.75rem] my-2 px-1"
style="word-break: break-all"
class="flex flex-col gap-2 text-slate-500 dark:text-slate-300 text-[0.75rem] my-2 px-1 leading-[18px]"
style="word-break: break-word"
>
<div v-for="error of v$.localState[field.title]?.$errors" :key="error" class="text-red-500">
{{ error.$message }}
@ -201,14 +200,9 @@ const onDecode = async (scannedCodeValue: string) => {
</div>
<div class="text-center mt-4">
<button
type="submit"
class="uppercase scaling-btn prose-sm"
data-testid="shared-form-submit-button"
@click="submitForm"
>
<NcButton type="primary" html-type="submit" data-testid="shared-form-submit-button" @click="submitForm">
{{ $t('general.submit') }}
</button>
</NcButton>
</div>
</div>
</div>

22
packages/nc-gui/pages/index/[typeOrId]/form/[viewId]/index/survey.vue

@ -244,14 +244,13 @@ onMounted(() => {
class="max-w-[max(33%,600px)] mx-auto flex flex-col justify-end"
>
<div class="px-4 md:px-0 flex flex-col justify-end">
<h1 class="prose-2xl font-bold self-center my-4" data-testid="nc-survey-form__heading" style="word-break: break-all">
<h1 class="prose-2xl font-bold self-center my-4" data-testid="nc-survey-form__heading">
{{ sharedFormView.heading }}
</h1>
<h2
v-if="sharedFormView.subheading && sharedFormView.subheading !== ''"
class="prose-lg text-slate-500 dark:text-slate-300 self-center mb-4 leading-6"
style="word-break: break-all"
data-testid="nc-survey-form__sub-heading"
>
{{ sharedFormView?.subheading }}
@ -306,10 +305,7 @@ onMounted(() => {
@update:edit-enabled="editEnabled[index] = $event"
/>
<div
class="flex flex-col gap-2 text-slate-500 dark:text-slate-300 text-[0.75rem] my-2 px-1"
style="word-break: break-all"
>
<div class="flex flex-col gap-2 text-slate-500 dark:text-slate-300 text-[0.75rem] my-2 px-1">
<div v-for="error of v$.localState[field.title]?.$errors" :key="error" class="text-red-500">
{{ error.$message }}
</div>
@ -354,8 +350,7 @@ onMounted(() => {
:mouse-leave-delay="0"
>
<!-- Ok button for question -->
<button
class="bg-opacity-100 scaling-btn flex items-center gap-1"
<NcButton
data-testid="nc-survey-form__btn-next"
:class="[
v$.localState[field.title]?.$error || columnValidationError ? 'after:!bg-gray-100 after:!ring-red-500' : '',
@ -377,7 +372,7 @@ onMounted(() => {
/>
<component :is="iconMap.check" v-else class="text-white md:text-md" />
</Transition>
</button>
</NcButton>
</a-tooltip>
<!-- todo: i18n -->
@ -410,14 +405,9 @@ onMounted(() => {
</p>
<div v-if="sharedFormView?.submit_another_form" class="text-center">
<button
type="button"
class="scaling-btn bg-opacity-100"
data-testid="nc-survey-form__btn-submit-another-form"
@click="resetForm"
>
<NcButton type="primary" data-testid="nc-survey-form__btn-submit-another-form" @click="resetForm">
Submit Another Form
</button>
</NcButton>
</div>
</div>
</div>

Loading…
Cancel
Save