Skip to content

Commit d13dc9a

Browse files
committed
Address review comments: Fixed async pagination race risk, refactored PaginationControls to be generic, Moved error checks before the initial skeleton fallback
1 parent b290778 commit d13dc9a

5 files changed

Lines changed: 44 additions & 51 deletions

File tree

src/sections/dataset/dataset-versions/DatasetVersions.tsx

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export function DatasetVersions({
8989

9090
void fetchSummaries(paginationInfoToFetch).then((totalCount) => {
9191
if (typeof totalCount === 'number') {
92-
setPaginationInfo(paginationInfoToDisplay.withTotal(totalCount))
92+
setPaginationInfo((currentPaginationInfo) => currentPaginationInfo.withTotal(totalCount))
9393
}
9494
})
9595
}
@@ -99,14 +99,14 @@ export function DatasetVersions({
9999
setSelectedVersions([])
100100
}, [paginationInfo.page, paginationInfo.pageSize])
101101

102-
if (!datasetVersionSummaries) {
103-
return <DatasetVersionsLoadingSkeleton />
104-
}
105-
106102
if (error) {
107103
return <Alert variant="danger">Error loading dataset versions</Alert>
108104
}
109105

106+
if (!datasetVersionSummaries) {
107+
return <DatasetVersionsLoadingSkeleton />
108+
}
109+
110110
return (
111111
<>
112112
{selectedVersions.length === 2 && (
@@ -217,15 +217,7 @@ export function DatasetVersions({
217217
</div>
218218
<PaginationControls
219219
initialPaginationInfo={paginationInfo}
220-
onPaginationInfoChange={(newPaginationInfo) =>
221-
setPaginationInfo(
222-
new DatasetVersionPaginationInfo(
223-
newPaginationInfo.page,
224-
newPaginationInfo.pageSize,
225-
newPaginationInfo.totalItems
226-
)
227-
)
228-
}
220+
onPaginationInfoChange={setPaginationInfo}
229221
/>
230222
</>
231223
)

src/sections/dataset/dataset-versions/useGetDatasetVersionsSummaries.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useEffect, useState } from 'react'
1+
import { useCallback, useEffect, useRef, useState } from 'react'
22
import { DatasetVersionSummaryInfo } from '@/dataset/domain/models/DatasetVersionSummaryInfo'
33
import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository'
44
import { getDatasetVersionsSummaries } from '@/dataset/domain/useCases/getDatasetVersionsSummaries'
@@ -25,9 +25,12 @@ export const useGetDatasetVersionsSummaries = ({
2525
const [summaries, setSummaries] = useState<DatasetVersionSummaryInfo[]>()
2626
const [isLoading, setIsLoading] = useState<boolean>(autoFetch)
2727
const [error, setError] = useState<string | null>(null)
28+
const latestRequestId = useRef(0)
2829

2930
const fetchSummaries = useCallback(
3031
async (paginationInfo?: DatasetVersionPaginationInfo) => {
32+
const requestId = latestRequestId.current + 1
33+
latestRequestId.current = requestId
3134
setIsLoading(true)
3235
setError(null)
3336

@@ -37,17 +40,25 @@ export const useGetDatasetVersionsSummaries = ({
3740
persistentId,
3841
paginationInfo
3942
)
43+
if (requestId !== latestRequestId.current) {
44+
return undefined
45+
}
4046
setSummaries(versionSummaries.summaries)
4147
return versionSummaries.totalCount
4248
} catch (err) {
49+
if (requestId !== latestRequestId.current) {
50+
return undefined
51+
}
4352
const errorMessage =
4453
err instanceof Error && err.message
4554
? err.message
4655
: 'Something went wrong getting the information from the dataset versions summaries. Try again later.'
4756
setError(errorMessage)
4857
return undefined
4958
} finally {
50-
setIsLoading(false)
59+
if (requestId === latestRequestId.current) {
60+
setIsLoading(false)
61+
}
5162
}
5263
},
5364
[datasetRepository, persistentId]

src/sections/file/file-version/FileVersions.tsx

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,20 @@ export function FileVersions({
5353

5454
void fetchSummaries(paginationInfoToFetch).then((totalCount) => {
5555
if (typeof totalCount === 'number') {
56-
setPaginationInfo(paginationInfoToFetch.withTotal(totalCount))
56+
setPaginationInfo((currentPaginationInfo) => currentPaginationInfo.withTotal(totalCount))
5757
}
5858
})
5959
}
6060
}, [isInView, fetchSummaries, paginationInfo.page, paginationInfo.pageSize])
6161

62-
if (!fileVersionSummaries) {
63-
return <FileVersionsLoadingSkeleton />
64-
}
65-
6662
if (error) {
6763
return <Alert variant="danger">{t('fileVersion.error')}</Alert>
6864
}
6965

66+
if (!fileVersionSummaries) {
67+
return <FileVersionsLoadingSkeleton />
68+
}
69+
7070
const datasetVersionDisplayMap: Record<string, string> = {
7171
[DatasetNonNumericVersion.DRAFT]: DatasetNonNumericVersionSearchParam.DRAFT
7272
}
@@ -144,15 +144,7 @@ export function FileVersions({
144144
</div>
145145
<PaginationControls
146146
initialPaginationInfo={paginationInfo}
147-
onPaginationInfoChange={(newPaginationInfo) =>
148-
setPaginationInfo(
149-
new FileVersionPaginationInfo(
150-
newPaginationInfo.page,
151-
newPaginationInfo.pageSize,
152-
newPaginationInfo.totalItems
153-
)
154-
)
155-
}
147+
onPaginationInfoChange={setPaginationInfo}
156148
/>
157149
</>
158150
)

src/sections/file/file-version/useGetFileVersionsSummaries.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useEffect, useState } from 'react'
1+
import { useCallback, useEffect, useRef, useState } from 'react'
22
import { FileVersionSummaryInfo } from '@/files/domain/models/FileVersionSummaryInfo'
33
import { FileRepository } from '@/files/domain/repositories/FileRepository'
44
import { getFileVersionSummaries } from '@/files/domain/useCases/getFileVersionSummaries'
@@ -25,9 +25,12 @@ export const useGetFileVersionsSummaries = ({
2525
const [summaries, setSummaries] = useState<FileVersionSummaryInfo[]>()
2626
const [isLoading, setIsLoading] = useState<boolean>(autoFetch)
2727
const [error, setError] = useState<string | null>(null)
28+
const latestRequestId = useRef(0)
2829

2930
const fetchSummaries = useCallback(
3031
async (paginationInfo?: FileVersionPaginationInfo) => {
32+
const requestId = latestRequestId.current + 1
33+
latestRequestId.current = requestId
3134
setIsLoading(true)
3235
setError(null)
3336
try {
@@ -36,17 +39,25 @@ export const useGetFileVersionsSummaries = ({
3639
fileId,
3740
paginationInfo
3841
)
42+
if (requestId !== latestRequestId.current) {
43+
return undefined
44+
}
3945
setSummaries(versionSummaries.summaries)
4046
return versionSummaries.totalCount
4147
} catch (err) {
48+
if (requestId !== latestRequestId.current) {
49+
return undefined
50+
}
4251
const errorMessage =
4352
err instanceof Error && err.message
4453
? err.message
4554
: 'Something went wrong getting the information from the file versions summaries. Try again later.'
4655
setError(errorMessage)
4756
return undefined
4857
} finally {
49-
setIsLoading(false)
58+
if (requestId === latestRequestId.current) {
59+
setIsLoading(false)
60+
}
5061
}
5162
},
5263
[fileRepository, fileId]

src/sections/shared/pagination/PaginationControls.tsx

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,19 @@ import { PageSizeSelector } from './PageSizeSelector'
44
import styles from './Pagination.module.scss'
55
import { PaginationInfo } from '../../../shared/pagination/domain/models/PaginationInfo'
66
import { useEffect, useState } from 'react'
7-
import { FilePaginationInfo } from '../../../files/domain/models/FilePaginationInfo'
8-
import { DatasetPaginationInfo } from '../../../dataset/domain/models/DatasetPaginationInfo'
9-
import { NotificationsPaginationInfo } from '@/notifications/domain/models/NotificationsPaginationInfo'
10-
import { DatasetVersionPaginationInfo } from '@/dataset/domain/models/DatasetVersionPaginationInfo'
11-
import { FileVersionPaginationInfo } from '@/files/domain/models/FileVersionPaginationInfo'
127

13-
type SupportedPaginationInfo =
14-
| DatasetPaginationInfo
15-
| FilePaginationInfo
16-
| NotificationsPaginationInfo
17-
| DatasetVersionPaginationInfo
18-
| FileVersionPaginationInfo
19-
20-
interface PaginationProps {
21-
onPaginationInfoChange: (paginationInfo: PaginationInfo<SupportedPaginationInfo>) => void
22-
initialPaginationInfo: PaginationInfo<SupportedPaginationInfo>
8+
interface PaginationProps<T extends PaginationInfo<T>> {
9+
onPaginationInfoChange: (paginationInfo: T) => void
10+
initialPaginationInfo: T
2311
showPageSizeSelector?: boolean
2412
}
2513
const MINIMUM_NUMBER_OF_PAGES_TO_DISPLAY_PAGINATION = 2
26-
export function PaginationControls({
14+
export function PaginationControls<T extends PaginationInfo<T>>({
2715
onPaginationInfoChange,
2816
initialPaginationInfo,
2917
showPageSizeSelector = true
30-
}: PaginationProps) {
31-
const [paginationInfo, setPaginationInfo] =
32-
useState<SupportedPaginationInfo>(initialPaginationInfo)
18+
}: PaginationProps<T>) {
19+
const [paginationInfo, setPaginationInfo] = useState<T>(initialPaginationInfo)
3320
const goToPage = (newPage: number) => {
3421
setPaginationInfo(paginationInfo.goToPage(newPage))
3522
}

0 commit comments

Comments
 (0)