diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts
index 7758ca97f..c81c341a0 100644
--- a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts
+++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts
@@ -4,16 +4,17 @@ import { isLastRecordBoardColumnComponentFamilyState } from '@/object-record/rec
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
import { isRecordBoardCompactModeActiveComponentState } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveComponentState';
import { isRecordBoardFetchingRecordsComponentState } from '@/object-record/record-board/states/isRecordBoardFetchingRecordsComponentState';
-import { onRecordBoardFetchMoreVisibilityChangeComponentState } from '@/object-record/record-board/states/onRecordBoardFetchMoreVisibilityChangeComponentState';
import { recordBoardColumnIdsComponentState } from '@/object-record/record-board/states/recordBoardColumnIdsComponentState';
import { recordBoardFieldDefinitionsComponentState } from '@/object-record/record-board/states/recordBoardFieldDefinitionsComponentState';
import { recordBoardFiltersComponentState } from '@/object-record/record-board/states/recordBoardFiltersComponentState';
import { recordBoardKanbanFieldMetadataNameComponentState } from '@/object-record/record-board/states/recordBoardKanbanFieldMetadataNameComponentState';
import { recordBoardObjectSingularNameComponentState } from '@/object-record/record-board/states/recordBoardObjectSingularNameComponentState';
import { recordBoardRecordIdsByColumnIdComponentFamilyState } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdComponentFamilyState';
+import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
import { recordBoardSortsComponentState } from '@/object-record/record-board/states/recordBoardSortsComponentState';
import { recordBoardColumnsComponentFamilySelector } from '@/object-record/record-board/states/selectors/recordBoardColumnsComponentFamilySelector';
import { recordBoardSelectedRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardSelectedRecordIdsComponentSelector';
+import { recordBoardShouldFetchMoreComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardShouldFetchMoreComponentFamilySelector';
import { recordBoardVisibleFieldDefinitionsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardVisibleFieldDefinitionsComponentSelector';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getScopeIdOrUndefinedFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdOrUndefinedFromComponentId';
@@ -90,8 +91,12 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
scopeId,
),
- onFetchMoreVisibilityChangeState: extractComponentState(
- onRecordBoardFetchMoreVisibilityChangeComponentState,
+ shouldFetchMoreInColumnFamilyState: extractComponentFamilyState(
+ recordBoardShouldFetchMoreInColumnComponentFamilyState,
+ scopeId,
+ ),
+ shouldFetchMoreSelector: extractComponentReadOnlySelector(
+ recordBoardShouldFetchMoreComponentSelector,
scopeId,
),
};
diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts
index 25a358e7a..c8f57c6ab 100644
--- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts
+++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts
@@ -11,8 +11,8 @@ export const useRecordBoard = (recordBoardId?: string) => {
objectSingularNameState,
selectedRecordIdsSelector,
isCompactModeActiveState,
- onFetchMoreVisibilityChangeState,
kanbanFieldMetadataNameState,
+ shouldFetchMoreSelector,
} = useRecordBoardStates(recordBoardId);
const { setColumns } = useSetRecordBoardColumns(recordBoardId);
@@ -32,6 +32,6 @@ export const useRecordBoard = (recordBoardId?: string) => {
setKanbanFieldMetadataName,
selectedRecordIdsSelector,
isCompactModeActiveState,
- onFetchMoreVisibilityChangeState,
+ shouldFetchMoreSelector,
};
};
diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnFetchMoreLoader.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnFetchMoreLoader.tsx
index 56127562c..98dc26d7a 100644
--- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnFetchMoreLoader.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnFetchMoreLoader.tsx
@@ -1,8 +1,10 @@
+import { useContext, useEffect } from 'react';
import { useInView } from 'react-intersection-observer';
import styled from '@emotion/styled';
-import { useRecoilValue } from 'recoil';
+import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
+import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
import { GRAY_SCALE } from '@/ui/theme/constants/GrayScale';
const StyledText = styled.div`
@@ -16,17 +18,20 @@ const StyledText = styled.div`
`;
export const RecordBoardColumnFetchMoreLoader = () => {
- const { isFetchingRecordState, onFetchMoreVisibilityChangeState } =
+ const { columnDefinition } = useContext(RecordBoardColumnContext);
+ const { isFetchingRecordState, shouldFetchMoreInColumnFamilyState } =
useRecordBoardStates();
const isFetchingRecord = useRecoilValue(isFetchingRecordState);
- const onFetchMoreVisibilityChange = useRecoilValue(
- onFetchMoreVisibilityChangeState,
+ const shouldFetchMore = useSetRecoilState(
+ shouldFetchMoreInColumnFamilyState(columnDefinition.id),
);
- const { ref } = useInView({
- onChange: onFetchMoreVisibilityChange,
- });
+ const { ref, inView } = useInView();
+
+ useEffect(() => {
+ shouldFetchMore(inView);
+ }, [shouldFetchMore, inView]);
return (
diff --git a/packages/twenty-front/src/modules/object-record/record-board/states/onRecordBoardFetchMoreVisibilityChangeComponentState.ts b/packages/twenty-front/src/modules/object-record/record-board/states/onRecordBoardFetchMoreVisibilityChangeComponentState.ts
deleted file mode 100644
index c977c8851..000000000
--- a/packages/twenty-front/src/modules/object-record/record-board/states/onRecordBoardFetchMoreVisibilityChangeComponentState.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
-
-export const onRecordBoardFetchMoreVisibilityChangeComponentState =
- createComponentState<(visbility: boolean) => void>({
- key: 'onRecordBoardFetchMoreVisibilityChangeComponentState',
- defaultValue: () => {},
- });
diff --git a/packages/twenty-front/src/modules/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState.ts b/packages/twenty-front/src/modules/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState.ts
new file mode 100644
index 000000000..01dd19099
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState.ts
@@ -0,0 +1,7 @@
+import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
+
+export const recordBoardShouldFetchMoreInColumnComponentFamilyState =
+ createComponentFamilyState({
+ key: 'onRecordBoardFetchMoreIrecordBoardShouldFetchMoreInColumnComponentFamilyStatesVisibleComponentFamilyState',
+ defaultValue: false,
+ });
diff --git a/packages/twenty-front/src/modules/object-record/record-board/states/selectors/recordBoardShouldFetchMoreComponentFamilySelector.ts b/packages/twenty-front/src/modules/object-record/record-board/states/selectors/recordBoardShouldFetchMoreComponentFamilySelector.ts
new file mode 100644
index 000000000..225ffafac
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-board/states/selectors/recordBoardShouldFetchMoreComponentFamilySelector.ts
@@ -0,0 +1,28 @@
+import { recordBoardColumnIdsComponentState } from '@/object-record/record-board/states/recordBoardColumnIdsComponentState';
+import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
+import { createComponentReadOnlySelector } from '@/ui/utilities/state/component-state/utils/createComponentReadOnlySelector';
+
+export const recordBoardShouldFetchMoreComponentSelector =
+ createComponentReadOnlySelector({
+ key: 'recordBoardShouldFetchMoreComponentSelector',
+ get:
+ ({ scopeId }: { scopeId: string }) =>
+ ({ get }) => {
+ const columnIds = get(
+ recordBoardColumnIdsComponentState({
+ scopeId,
+ }),
+ );
+
+ const shouldFetchMoreInColumns = columnIds.map((columnId) => {
+ return get(
+ recordBoardShouldFetchMoreInColumnComponentFamilyState({
+ scopeId,
+ familyKey: columnId,
+ }),
+ );
+ });
+
+ return shouldFetchMoreInColumns.some(Boolean);
+ },
+ });
diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx
index 4a755169d..d2e0d279a 100644
--- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx
@@ -1,6 +1,6 @@
import { useCallback, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
-import { useRecoilValue, useSetRecoilState } from 'recoil';
+import { useRecoilValue } from 'recoil';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useRecordActionBar } from '@/object-record/record-action-bar/hooks/useRecordActionBar';
@@ -33,7 +33,7 @@ export const RecordIndexBoardContainerEffect = ({
setObjectSingularName,
selectedRecordIdsSelector,
setFieldDefinitions,
- onFetchMoreVisibilityChangeState,
+ shouldFetchMoreSelector,
setKanbanFieldMetadataName,
} = useRecordBoard(recordBoardId);
@@ -43,28 +43,31 @@ export const RecordIndexBoardContainerEffect = ({
viewBarId,
});
- const setOnFetchMoreVisibilityChange = useSetRecoilState(
- onFetchMoreVisibilityChangeState,
- );
-
const recordIndexKanbanFieldMetadataId = useRecoilValue(
recordIndexKanbanFieldMetadataIdState,
);
- useEffect(() => {
- setOnFetchMoreVisibilityChange(() => () => {
- if (!loading) {
- fetchMoreRecords?.();
- }
- });
- }, [fetchMoreRecords, loading, setOnFetchMoreVisibilityChange]);
-
const navigate = useNavigate();
const navigateToSelectSettings = useCallback(() => {
navigate(`/settings/objects/${objectMetadataItem.namePlural}`);
}, [navigate, objectMetadataItem.namePlural]);
+ const columnDefinitions =
+ computeRecordBoardColumnDefinitionsFromObjectMetadata(
+ objectMetadataItem,
+ recordIndexKanbanFieldMetadataId ?? '',
+ navigateToSelectSettings,
+ );
+
+ const shouldFetchMore = useRecoilValue(shouldFetchMoreSelector());
+
+ useEffect(() => {
+ if (!loading && shouldFetchMore) {
+ fetchMoreRecords?.();
+ }
+ }, [columnDefinitions, fetchMoreRecords, loading, shouldFetchMore]);
+
const { resetRecordSelection } = useRecordBoardSelection(recordBoardId);
useEffect(() => {
diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditContent.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditContent.tsx
index 127e64400..8a1dc16e2 100644
--- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditContent.tsx
+++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditContent.tsx
@@ -166,7 +166,10 @@ export const ViewPickerCreateOrEditContent = () => {
label="Stages"
fullWidth
value={viewPickerKanbanFieldMetadataId}
- onChange={(value) => setViewPickerKanbanFieldMetadataId(value)}
+ onChange={(value) => {
+ setViewPickerIsDirty(true);
+ setViewPickerKanbanFieldMetadataId(value);
+ }}
options={
availableFieldsForKanban.length > 0
? availableFieldsForKanban.map((field) => ({
diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditContentEffect.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditContentEffect.tsx
index 45c143222..6124063e0 100644
--- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditContentEffect.tsx
+++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditContentEffect.tsx
@@ -64,10 +64,14 @@ export const ViewPickerCreateOrEditContentEffect = () => {
]);
useEffect(() => {
- if (availableFieldsForKanban.length > 0) {
+ if (availableFieldsForKanban.length > 0 && !viewPickerIsDirty) {
setViewPickerKanbanFieldMetadataId(availableFieldsForKanban[0].id);
}
- }, [availableFieldsForKanban, setViewPickerKanbanFieldMetadataId]);
+ }, [
+ availableFieldsForKanban,
+ setViewPickerKanbanFieldMetadataId,
+ viewPickerIsDirty,
+ ]);
return <>>;
};