Skip to content

Commit 691fbbe

Browse files
authored
Fix show page navigation bugs (#9199)
Fixes total count bug that was -1 the total count Fixes a bug when trying to go from first to last or the other way around Fixes a React array key bug Follow-up issue (non critical) : https://github.com/twentyhq/twenty/issues/9197
1 parent 6abe735 commit 691fbbe

File tree

2 files changed

+53
-22
lines changed

2 files changed

+53
-22
lines changed

packages/twenty-front/src/modules/action-menu/components/RecordShowActionMenuButtons.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ export const RecordShowActionMenuButtons = () => {
1515
return (
1616
<>
1717
{!isMobile &&
18-
pinnedEntries.map((entry, index) =>
18+
pinnedEntries.map((entry) =>
1919
entry.shortLabel ? (
2020
<Button
21-
key={index}
21+
key={entry.key}
2222
Icon={entry.Icon}
2323
size="small"
2424
variant="secondary"
@@ -29,6 +29,7 @@ export const RecordShowActionMenuButtons = () => {
2929
/>
3030
) : (
3131
<IconButton
32+
key={entry.key}
3233
Icon={entry.Icon}
3334
size="small"
3435
variant="secondary"

packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts

+50-20
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const useRecordShowPagePagination = (
2121
objectNameSingular: paramObjectNameSingular,
2222
objectRecordId: paramObjectRecordId,
2323
} = useParams();
24+
2425
const navigate = useNavigate();
2526
const [searchParams] = useSearchParams();
2627
const viewIdQueryParam = searchParams.get('view');
@@ -53,7 +54,7 @@ export const useRecordShowPagePagination = (
5354
recordGqlFields: { id: true },
5455
});
5556

56-
const cursorFromRequest = currentRecordsPageInfo?.endCursor;
57+
const currentRecordCursorFromRequest = currentRecordsPageInfo?.endCursor;
5758

5859
const [totalCountBefore, setTotalCountBefore] = useState<number>(0);
5960
const [totalCountAfter, setTotalCountAfter] = useState<number>(0);
@@ -67,10 +68,10 @@ export const useRecordShowPagePagination = (
6768
id: { neq: objectRecordId },
6869
},
6970
orderBy,
70-
cursorFilter: isNonEmptyString(cursorFromRequest)
71+
cursorFilter: isNonEmptyString(currentRecordCursorFromRequest)
7172
? {
7273
cursorDirection: 'before',
73-
cursor: cursorFromRequest,
74+
cursor: currentRecordCursorFromRequest,
7475
limit: 1,
7576
}
7677
: undefined,
@@ -90,10 +91,10 @@ export const useRecordShowPagePagination = (
9091
},
9192
fetchPolicy: 'network-only',
9293
orderBy,
93-
cursorFilter: cursorFromRequest
94+
cursorFilter: currentRecordCursorFromRequest
9495
? {
9596
cursorDirection: 'after',
96-
cursor: cursorFromRequest,
97+
cursor: currentRecordCursorFromRequest,
9798
limit: 1,
9899
}
99100
: undefined,
@@ -109,6 +110,9 @@ export const useRecordShowPagePagination = (
109110
const recordBefore = recordsBefore[0];
110111
const recordAfter = recordsAfter[0];
111112

113+
const isFirstRecord = !loading && !isDefined(recordBefore);
114+
const isLastRecord = !loading && !isDefined(recordAfter);
115+
112116
const { recordIdsInCache } = useRecordIdsFromFindManyCacheRootQuery({
113117
objectNamePlural: objectMetadataItem.namePlural,
114118
fieldVariables: {
@@ -117,32 +121,56 @@ export const useRecordShowPagePagination = (
117121
},
118122
});
119123

124+
const cacheIsAvailableForNavigation =
125+
!loading &&
126+
(totalCountAfter > 0 || totalCountBefore > 0) &&
127+
recordIdsInCache.length > 0;
128+
129+
const canNavigateToPreviousRecord =
130+
!isFirstRecord || (isFirstRecord && cacheIsAvailableForNavigation);
131+
120132
const navigateToPreviousRecord = () => {
121-
if (isDefined(recordBefore)) {
133+
if (isFirstRecord) {
134+
if (cacheIsAvailableForNavigation) {
135+
const lastRecordIdFromCache =
136+
recordIdsInCache[recordIdsInCache.length - 1];
137+
138+
navigate(
139+
buildShowPageURL(
140+
objectNameSingular,
141+
lastRecordIdFromCache,
142+
viewIdQueryParam,
143+
),
144+
);
145+
}
146+
} else {
122147
navigate(
123148
buildShowPageURL(objectNameSingular, recordBefore.id, viewIdQueryParam),
124149
);
125150
}
126-
if (!loadingRecordBefore && !isDefined(recordBefore)) {
127-
const firstRecordId = recordIdsInCache[recordIdsInCache.length - 1];
128-
navigate(
129-
buildShowPageURL(objectNameSingular, firstRecordId, viewIdQueryParam),
130-
);
131-
}
132151
};
133152

153+
const canNavigateToNextRecord =
154+
!isLastRecord || (isLastRecord && cacheIsAvailableForNavigation);
155+
134156
const navigateToNextRecord = () => {
135-
if (isDefined(recordAfter)) {
157+
if (isLastRecord) {
158+
if (cacheIsAvailableForNavigation) {
159+
const firstRecordIdFromCache = recordIdsInCache[0];
160+
161+
navigate(
162+
buildShowPageURL(
163+
objectNameSingular,
164+
firstRecordIdFromCache,
165+
viewIdQueryParam,
166+
),
167+
);
168+
}
169+
} else {
136170
navigate(
137171
buildShowPageURL(objectNameSingular, recordAfter.id, viewIdQueryParam),
138172
);
139173
}
140-
if (!loadingRecordAfter && !isDefined(recordAfter)) {
141-
const lastRecordId = recordIdsInCache[0];
142-
navigate(
143-
buildShowPageURL(objectNameSingular, lastRecordId, viewIdQueryParam),
144-
);
145-
}
146174
};
147175

148176
const navigateToIndexView = () => {
@@ -162,7 +190,7 @@ export const useRecordShowPagePagination = (
162190

163191
const objectLabel = capitalize(objectMetadataItem.labelPlural);
164192

165-
const totalCount = Math.max(1, totalCountBefore, totalCountAfter);
193+
const totalCount = 1 + Math.max(totalCountBefore, totalCountAfter);
166194

167195
const viewNameWithCount = rankFoundInView
168196
? `${rankInView + 1} of ${totalCount} in ${objectLabel}`
@@ -174,5 +202,7 @@ export const useRecordShowPagePagination = (
174202
navigateToPreviousRecord,
175203
navigateToNextRecord,
176204
navigateToIndexView,
205+
canNavigateToNextRecord,
206+
canNavigateToPreviousRecord,
177207
};
178208
};

0 commit comments

Comments
 (0)