diff --git a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardFetchMoreInViewTriggerComponent.tsx b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardFetchMoreInViewTriggerComponent.tsx index 1d763f52b5..ca0bfc75f2 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardFetchMoreInViewTriggerComponent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardFetchMoreInViewTriggerComponent.tsx @@ -2,15 +2,19 @@ import { styled } from '@linaria/react'; import { useEffect } from 'react'; import { useInView } from 'react-intersection-observer'; +import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader'; import { RECORD_BOARD_COLUMN_PADDING_AND_BORDER_WIDTH } from '@/object-record/record-board/constants/RecordBoardColumnPaddingAndBorderWidth'; import { RECORD_BOARD_COLUMN_WIDTH } from '@/object-record/record-board/constants/RecordBoardColumnWidth'; +import { RECORD_BOARD_QUERY_PAGE_SIZE } from '@/object-record/record-board/constants/RecordBoardQueryPageSize'; import { recordBoardIsFetchingMoreComponentState } from '@/object-record/record-board/states/recordBoardIsFetchingMoreComponentState'; import { recordBoardShouldFetchMoreComponentState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreComponentState'; +import { visibleRecordFieldsComponentSelector } from '@/object-record/record-field/states/visibleRecordFieldsComponentSelector'; import { visibleRecordGroupIdsComponentFamilySelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentFamilySelector'; import { recordIndexRecordGroupsAreInInitialLoadingComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupsAreInInitialLoadingComponentState'; import { useScrollWrapperHTMLElement } from '@/ui/utilities/scroll/hooks/useScrollWrapperHTMLElement'; import { useAtomComponentFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilySelectorValue'; +import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue'; import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; import { ViewType } from '@/views/types/ViewType'; @@ -20,6 +24,16 @@ const StyledFetchMoreTriggerDiv = styled.div<{ width: number }>` min-width: ${({ width }) => width}px; `; +// RecordCardHeaderContainer: height (24px) + padding top spacing(2) + padding bottom spacing(1) +const BOARD_CARD_HEADER_HEIGHT = 24 + 8 + 4; + +// Per field row: skeleton height + RecordCardBodyContainer padding-bottom spacing(2) + StyledBodyContainer gap spacing(0.5) +const BOARD_CARD_FIELD_ROW_HEIGHT = + SKELETON_LOADER_HEIGHT_SIZES.standard.s + 8 + 2; + +// StyledBodyContainer padding (4+4) + card border (2×1px) + StyledSkeletonCardContainer margin-bottom spacing(2) +const BOARD_CARD_CHROME_HEIGHT = 8 + 2 + 8; + export const RecordBoardFetchMoreInViewTriggerComponent = () => { const [recordBoardShouldFetchMore, setRecordBoardShouldFetchMore] = useAtomComponentState(recordBoardShouldFetchMoreComponentState); @@ -32,10 +46,21 @@ export const RecordBoardFetchMoreInViewTriggerComponent = () => { recordBoardIsFetchingMoreComponentState, ); + const visibleRecordFields = useAtomComponentSelectorValue( + visibleRecordFieldsComponentSelector, + ); + + const estimatedCardHeight = + BOARD_CARD_HEADER_HEIGHT + + visibleRecordFields.length * BOARD_CARD_FIELD_ROW_HEIGHT + + BOARD_CARD_CHROME_HEIGHT; + + const rootMargin = `${estimatedCardHeight * RECORD_BOARD_QUERY_PAGE_SIZE * 2}px`; + const { scrollWrapperHTMLElement } = useScrollWrapperHTMLElement(); const { ref, inView } = useInView({ - rootMargin: '1600px', + rootMargin, root: scrollWrapperHTMLElement, }); diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardFetchMore.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardFetchMore.ts index d186ce2a10..d7b1e61e4d 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardFetchMore.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardFetchMore.ts @@ -7,6 +7,7 @@ import { RECORD_BOARD_QUERY_PAGE_SIZE } from '@/object-record/record-board/const import { recordBoardCurrentGroupByQueryOffsetComponentState } from '@/object-record/record-board/states/recordBoardCurrentGroupByQueryOffsetComponentState'; import { recordBoardIsFetchingMoreComponentState } from '@/object-record/record-board/states/recordBoardIsFetchingMoreComponentState'; +import { recordBoardShouldFetchMoreComponentState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreComponentState'; import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState'; import { recordGroupDefinitionsComponentSelector } from '@/object-record/record-group/states/selectors/recordGroupDefinitionsComponentSelector'; import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext'; @@ -66,6 +67,11 @@ export const useTriggerRecordBoardFetchMore = () => { recordBoardIsFetchingMoreComponentState, ); + const recordBoardShouldFetchMoreCallbackState = + useAtomComponentStateCallbackState( + recordBoardShouldFetchMoreComponentState, + ); + const triggerRecordBoardFetchMore = useCallback(async () => { const isAlreadyFetchingMore = store.get(recordBoardIsFetchingMore); @@ -97,6 +103,7 @@ export const useTriggerRecordBoardFetchMore = () => { .filter(isDefined); if (!isNonEmptyArray(recordGroupValuesThatShouldBeFetched)) { + store.set(recordBoardShouldFetchMoreCallbackState, false); cleanStateBeforeExit(); return; @@ -217,6 +224,7 @@ export const useTriggerRecordBoardFetchMore = () => { recordBoardIsFetchingMore, recordBoardCurrentGroupByQueryOffsetCallbackState, recordBoardShouldFetchMoreInColumnFamilyCallbackState, + recordBoardShouldFetchMoreCallbackState, combinedFilters, recordIndexGroupFieldMetadataItem, ]);