Browse Source

Merge pull request #10016 from nocodb/nc-fix/nc-longtext-cell-focus-input-cell-issue

Nc fix/nc longtext cell focus input cell issue
pull/10015/head
Raju Udava 1 day ago committed by GitHub
parent
commit
da06438839
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      packages/nc-gui/components/cell/MultiSelect.vue
  2. 2
      packages/nc-gui/components/cell/Rating.vue
  3. 22
      packages/nc-gui/components/cell/TextArea.vue
  4. 2
      packages/nc-gui/components/cell/User.vue
  5. 20
      packages/nc-gui/components/smartsheet/grid/InfiniteTable.vue
  6. 20
      packages/nc-gui/components/smartsheet/grid/Table.vue
  7. 3
      packages/nc-gui/lib/types.ts
  8. 8
      packages/nc-gui/utils/cell.ts
  9. 26
      packages/nc-gui/utils/commonUtils.ts

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

@ -428,7 +428,7 @@ const onFocus = () => {
:style="{
'display': '-webkit-box',
'max-width': '100%',
'-webkit-line-clamp': rowHeightTruncateLines(rowHeight),
'-webkit-line-clamp': rowHeightTruncateLines(rowHeight, true),
'-webkit-box-orient': 'vertical',
'overflow': 'hidden',
}"

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

@ -72,7 +72,7 @@ watch(rateDomRef, () => {
'padding': isExpandedFormOpen ? '0px 8px' : '0px 2px',
'display': '-webkit-box',
'max-width': '100%',
'-webkit-line-clamp': rowHeightTruncateLines(rowHeight),
'-webkit-line-clamp': rowHeight === 6 ? 5 : rowHeightTruncateLines(rowHeight, true),
'-webkit-box-orient': 'vertical',
'overflow': 'hidden',
}"

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

@ -1,5 +1,4 @@
<script setup lang="ts">
import type { VNodeRef } from '@vue/runtime-core'
import type { AIRecordType } from 'nocodb-sdk'
const props = defineProps<{
@ -70,9 +69,6 @@ const mousePosition = ref<
const isDragging = ref(false)
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && !isForm.value && (el as HTMLTextAreaElement)?.focus()
const height = computed(() => {
if (isExpandedFormOpen.value) return 36 * 4
@ -326,6 +322,14 @@ watch(
immediate: true,
},
)
const textAreaRef = ref<HTMLTextAreaElement>()
watch(textAreaRef, (el) => {
if (el && !isExpandedFormOpen.value && !isEditColumn.value && !isForm.value) {
el.focus()
}
})
</script>
<template>
@ -394,7 +398,7 @@ watch(
}"
>
<textarea
:ref="focus"
ref="textAreaRef"
v-model="vModel"
:rows="isForm ? 5 : 4"
class="h-full w-full !outline-none nc-scrollbar-thin"
@ -511,14 +515,10 @@ watch(
:class="{
'right-1': isForm,
'right-0': !isForm,
'top-0': isGrid && !isExpandedFormOpen && !isForm && !(!rowHeight || rowHeight === 1),
'top-0 right-1': isGrid && !isExpandedFormOpen && !isForm,
'!right-2 top-2': isGrid && !isExpandedFormOpen && !isForm && ((editEnabled && !isVisible) || isForm),
'top-1': !(isGrid && !isExpandedFormOpen && !isForm),
}"
:style="
isGrid && !isExpandedFormOpen && !isForm && (!rowHeight || rowHeight === 1)
? { top: '50%', transform: 'translateY(-50%)' }
: undefined
"
>
<NcTooltip
v-if="!isVisible && !isForm && !readOnly && props.isAi && !isExpandedFormOpen && !isEditColumn"

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

@ -403,7 +403,7 @@ const isCollaborator = (userIdOrEmail) => {
:style="{
'display': '-webkit-box',
'max-width': '100%',
'-webkit-line-clamp': rowHeightTruncateLines(rowHeight),
'-webkit-line-clamp': rowHeightTruncateLines(rowHeight, true),
'-webkit-box-orient': 'vertical',
'overflow': 'hidden',
}"

20
packages/nc-gui/components/smartsheet/grid/InfiniteTable.vue

@ -195,6 +195,8 @@ const onXcResizing = (cn: string | undefined, event: any) => {
const size = event.detail.split('px')[0]
gridViewCols.value[cn].width = `${normalizedWidth(metaColumnById.value[cn], size)}px`
refreshFillHandle()
}
const onXcStartResizing = (cn: string | undefined, event: any) => {
@ -1434,7 +1436,7 @@ const leftOffset = computed(() => {
const fillHandleTop = ref()
const fillHandleLeft = ref()
const refreshFillHandle = () => {
function refreshFillHandle() {
const rowIndex = isNaN(selectedRange.end.row) ? activeCell.row : selectedRange.end.row
const colIndex = isNaN(selectedRange.end.col) ? activeCell.col : selectedRange.end.col
if (rowIndex !== null && colIndex !== null) {
@ -1896,7 +1898,7 @@ watch(vSelectedAllRecords, (selectedAll) => {
</template>
</th>
<th
v-if="fields[0] && fields[0].id"
v-if="fields?.[0]?.id"
ref="primaryColHeader"
v-xc-ver-resize
:data-col="fields[0].id"
@ -2724,10 +2726,18 @@ watch(vSelectedAllRecords, (selectedAll) => {
&.align-top {
@apply py-2;
&:has(.nc-cell.nc-cell-longtext textarea) {
@apply py-0 pr-0;
}
}
&.align-middle {
@apply py-0;
&:has(.nc-cell.nc-cell-longtext textarea) {
@apply pr-0;
}
}
& > div {
@ -2753,7 +2763,7 @@ watch(vSelectedAllRecords, (selectedAll) => {
.nc-cell-field,
input,
textarea {
@apply !text-small !p-0 m-0;
@apply !text-small !pl-0 !py-0 m-0;
}
&:not(.nc-display-value-cell) {
@ -2772,7 +2782,7 @@ watch(vSelectedAllRecords, (selectedAll) => {
a.nc-cell-field-link,
input,
textarea {
@apply !p-0 m-0;
@apply !pl-0 !py-0 m-0;
}
a.nc-cell-field-link {
@ -2786,7 +2796,7 @@ watch(vSelectedAllRecords, (selectedAll) => {
@apply leading-[18px];
textarea {
@apply pr-2;
@apply pr-8 !py-2;
}
}

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

@ -1214,6 +1214,8 @@ const onXcResizing = (cn: string | undefined, event: any) => {
const size = event.detail.split('px')[0]
gridViewCols.value[cn].width = `${normalizedWidth(metaColumnById.value[cn], size)}px`
refreshFillHandle()
}
const onXcStartResizing = (cn: string | undefined, event: any) => {
@ -1376,7 +1378,7 @@ const topOffset = computed(() => {
const fillHandleTop = ref()
const fillHandleLeft = ref()
const refreshFillHandle = () => {
function refreshFillHandle() {
nextTick(() => {
const rowIndex = isNaN(selectedRange.end.row) ? activeCell.row : selectedRange.end.row
const colIndex = isNaN(selectedRange.end.col) ? activeCell.col : selectedRange.end.col
@ -1834,7 +1836,7 @@ onKeyStroke('ArrowDown', onDown)
</div>
</th>
<th
v-if="fields[0] && fields[0].id"
v-if="fields?.[0]?.id"
v-xc-ver-resize
:data-col="fields[0].id"
:data-title="fields[0].title"
@ -2739,10 +2741,18 @@ onKeyStroke('ArrowDown', onDown)
&.align-top {
@apply py-2;
&:has(.nc-cell.nc-cell-longtext textarea) {
@apply py-0 pr-0;
}
}
&.align-middle {
@apply py-0;
&:has(.nc-cell.nc-cell-longtext textarea) {
@apply pr-0;
}
}
& > div {
@ -2768,7 +2778,7 @@ onKeyStroke('ArrowDown', onDown)
.nc-cell-field,
input,
textarea {
@apply !text-small !p-0 m-0;
@apply !text-small !pl-0 !py-0 m-0;
}
&:not(.nc-display-value-cell) {
@ -2787,7 +2797,7 @@ onKeyStroke('ArrowDown', onDown)
a.nc-cell-field-link,
input,
textarea {
@apply !p-0 m-0;
@apply !pl-0 !py-0 m-0;
}
a.nc-cell-field-link {
@ -2801,7 +2811,7 @@ onKeyStroke('ArrowDown', onDown)
@apply leading-[18px];
textarea {
@apply pr-2;
@apply pr-8 !py-2;
}
}

3
packages/nc-gui/lib/types.ts

@ -306,6 +306,8 @@ interface ProductFeedItem {
type SordDirectionType = 'asc' | 'desc' | undefined
type NestedArray<T> = T | NestedArray<T>[]
export type {
User,
ProjectMetaInfo,
@ -341,4 +343,5 @@ export type {
SordDirectionType,
ProductFeedItem,
Attachment,
NestedArray,
}

8
packages/nc-gui/utils/cell.ts

@ -107,14 +107,14 @@ export const rowHeightInPx: Record<string, number> = {
6: 120,
}
export const rowHeightTruncateLines = (rowHeight?: number) => {
export const rowHeightTruncateLines = (rowHeight?: number, isSelectOption = false) => {
switch (rowHeight) {
case 2:
return 3
return 2
case 4:
return 4
return isSelectOption ? 3 : 4
case 6:
return 6
return isSelectOption ? 4 : 6
default:
return 1
}

26
packages/nc-gui/utils/commonUtils.ts

@ -75,11 +75,12 @@ export const isUnicodeEmoji = (emoji: string) => {
/**
* Performs a case-insensitive search to check if the `query` exists within the `source`.
*
* - If `source` is an array, the function checks if any element (converted to a string) contains the `query`.
* - If `source` is a string or number, it checks if the `query` exists within `source` (case-insensitively).
* - If `source` or `query` is `undefined`, they are treated as empty strings.
* - Handles strings, numbers, and arrays (including nested arrays) of strings/numbers.
* - Treats `undefined` as an empty string.
*
* @param source - The value to search within. Can be a string, number, or an array of strings/numbers.
* @param source - The value to search within. Can be:
* - A string or number.
* - A single-level or nested array of strings/numbers.
* @param query - The value to search for. Treated as an empty string if `undefined`.
* @returns `true` if the `query` is found within the `source` (case-insensitively), otherwise `false`.
*
@ -87,27 +88,24 @@ export const isUnicodeEmoji = (emoji: string) => {
* ```typescript
* // Single string or number search
* searchCompare("Hello World", "world"); // true
* searchCompare("OpenAI ChatGPT", "gpt"); // true
* searchCompare("TypeScript", "JavaScript"); // false
* searchCompare(12345, "234"); // true
*
* // Array search
* searchCompare(["apple", "banana", "cherry"], "Banana"); // true
* searchCompare([123, 456, 789], "456"); // true
* searchCompare([null, undefined, "test"], "TEST"); // true
*
* // Nested array search
* searchCompare(["apple", ["banana", ["cherry"]]], "cherry"); // true
* searchCompare([123, [456, [789]]], "456"); // true
*
* // Handling undefined
* searchCompare(undefined, "test"); // false
* searchCompare("test", undefined); // true
* ```
*/
export const searchCompare = (source?: string | number | (string | number | undefined)[], query?: string): boolean => {
export const searchCompare = (source?: NestedArray<string | number | undefined>, query?: string): boolean => {
if (ncIsArray(source)) {
return source.some((item) => {
return (item || '')
.toString()
.toLowerCase()
.includes((query || '').toLowerCase())
})
return source.some((item) => searchCompare(item, query))
}
return (source || '')

Loading…
Cancel
Save