Skip to content

Commit 82f5a4c

Browse files
authored
Feat/infinity scroll (#412)
* increase overscan * add infinity scroll * add fakeData * add infinite scroll * fix typo * fix typo * add useScrollListner hook with ref to handler * add virtualize options * move listener inside useEffect
1 parent af5a5ac commit 82f5a4c

File tree

4 files changed

+157
-2
lines changed

4 files changed

+157
-2
lines changed

src/components/tableV2/core/fullTable.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const FullTable = ({
2121
testPrefixCallback,
2222
width,
2323
scrollParentRef,
24+
virtualizeOptions = {},
2425
}) => {
2526
return (
2627
<Table
@@ -54,6 +55,7 @@ const FullTable = ({
5455
table={table}
5556
testPrefix={testPrefix}
5657
testPrefixCallback={testPrefixCallback}
58+
{...virtualizeOptions}
5759
/>
5860
</Table.Body>
5961
</Table>

src/components/tableV2/core/rows.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const Rows = ({
1919
testPrefix,
2020
testPrefixCallback,
2121
scrollParentRef,
22+
overscan,
2223
}) => {
2324
const { state, updateState } = useSharedTable({})
2425
const { rows } = table.getRowModel()
@@ -27,7 +28,7 @@ const Rows = ({
2728
count: rows.length,
2829
getScrollElement: () => scrollParentRef.current,
2930
estimateSize: () => CELL_HEIGHT,
30-
overscan: 20,
31+
overscan: overscan || 30,
3132
})
3233

3334
const virtualRows = virtualizer.getVirtualItems()
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { useEffect, useMemo, useState, useRef } from "react"
2+
3+
//COMMENTS HERE ARE ONLY FOR TESTING REASONS THE ARE GOING TO BE REMOVED AFTER WE SEE THAT THE INFINITY WORKS AS EXPECTED
4+
5+
// const fakeData = () => [
6+
// {
7+
// nodes: "node51",
8+
// alerts: 15,
9+
// user: "mitsos",
10+
// disabled: true,
11+
// status: "stale",
12+
// untouchable: "true",
13+
// },
14+
// {
15+
// nodes: "node52",
16+
// alerts: 15,
17+
// user: "mitsos",
18+
// disabled: true,
19+
// status: "stale",
20+
// untouchable: "true",
21+
// },
22+
// {
23+
// nodes: "node53",
24+
// alerts: 15,
25+
// user: "mitsos",
26+
// disabled: true,
27+
// status: "stale",
28+
// untouchable: "true",
29+
// },
30+
// {
31+
// nodes: "node54",
32+
// alerts: 15,
33+
// user: "mitsos",
34+
// disabled: true,
35+
// status: "stale",
36+
// untouchable: "true",
37+
// },
38+
// {
39+
// nodes: "node55",
40+
// alerts: 15,
41+
// user: "mitsos",
42+
// disabled: true,
43+
// status: "stale",
44+
// untouchable: "true",
45+
// },
46+
// {
47+
// nodes: "node56",
48+
// alerts: 15,
49+
// user: "mitsos",
50+
// disabled: true,
51+
// status: "stale",
52+
// untouchable: "true",
53+
// },
54+
// ]
55+
56+
// function loadMoreItems(lastData) {
57+
// console.log(lastData)
58+
// return new Promise(resolve => {
59+
// setTimeout(() => {
60+
// resolve({
61+
// data: fakeData(),
62+
// })
63+
// }, 4000)
64+
// })
65+
// }
66+
67+
const useScrollListener = (target, handler) => {
68+
const listenerRef = useRef(handler)
69+
listenerRef.current = handler
70+
71+
useEffect(() => {
72+
const listener = () => listenerRef.current()
73+
74+
if (!target?.current) return
75+
target.current.addEventListener("scroll", listener)
76+
77+
return () => {
78+
if (!target.current) return
79+
target.current.removeEventListener("scroll", listener)
80+
}
81+
}, [target])
82+
}
83+
84+
const useIniniteScroll = ({
85+
service,
86+
target,
87+
onError,
88+
onSuccess,
89+
onDataEnd,
90+
updateTableData,
91+
threshold = 100,
92+
}) => {
93+
const [lastReceivedData, setLastReceivedData] = useState()
94+
const [loading, setLoading] = useState(false)
95+
96+
const hasDataEnded = useMemo(() => {
97+
if (!onDataEnd) return false
98+
return onDataEnd(lastReceivedData)
99+
}, [lastReceivedData])
100+
101+
const runService = async () => {
102+
try {
103+
const currentData = await service(lastReceivedData)
104+
105+
updateTableData(currentData.data)
106+
setLastReceivedData(currentData)
107+
onSuccess?.(currentData)
108+
setLoading(false)
109+
} catch (err) {
110+
onError?.(err)
111+
setLoading(false)
112+
}
113+
}
114+
115+
const loadMore = () => {
116+
if (hasDataEnded) return
117+
setLoading(true)
118+
runService()
119+
}
120+
const scrollMethod = () => {
121+
const el = target.current
122+
if (!el) {
123+
return
124+
}
125+
const scrollTop = el.scrollTop
126+
const scrollHeight = el.scrollHeight
127+
const clientHeight = el.clientHeight
128+
if (scrollHeight - scrollTop <= clientHeight + threshold) {
129+
loadMore()
130+
}
131+
}
132+
133+
useScrollListener(target, () => {
134+
if (loading || service) return
135+
scrollMethod()
136+
})
137+
}
138+
139+
export default useIniniteScroll

src/components/tableV2/netdataTable.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import MainTable from "./features/mainTable"
2525

2626
import { SharedTableProvider } from "./context/sharedTable"
2727

28+
import useInfiniteScroll from "./hooks/useInfiniteScroll"
29+
2830
const noop = () => {}
2931

3032
const NetdataTable = ({
@@ -56,6 +58,8 @@ const NetdataTable = ({
5658
enableColumnPinning = false,
5759
columnPinningOptions = {},
5860
enableResize = false,
61+
loadMoreOptions = {},
62+
virtualizeOptions = {},
5963
}) => {
6064
const [isColumnDropdownVisible, setIsColumnDropdownVisible] = useState(false)
6165
const [columnVisibility, setColumnVisibility] = useState(initialColumnVisibility)
@@ -69,9 +73,16 @@ const NetdataTable = ({
6973
pageIndex: paginationOptions.pageIndex,
7074
pageSize: paginationOptions.pageSize,
7175
})
76+
const [tableData, setTableData] = useState(data)
7277

7378
const scrollParentRef = useRef()
7479

80+
const updateTableData = useCallback(newData => {
81+
setTableData(oldData => [...oldData, ...newData])
82+
}, [])
83+
84+
useInfiniteScroll({ target: scrollParentRef, updateTableData, ...loadMoreOptions })
85+
7586
const handleGlobalSearch = useCallback(value => {
7687
onGlobalSearchChange?.(value)
7788
setGlobalFilter(String(value))
@@ -151,7 +162,7 @@ const NetdataTable = ({
151162

152163
const table = useReactTable({
153164
columns: [...makeSelectionColumn, ...makeDataColumns, ...makeActionsColumn],
154-
data: data,
165+
data: tableData,
155166
manualPagination: !enablePagination,
156167
columnResizeMode: enableResize ? "onEnd" : "",
157168
filterFns: {
@@ -223,6 +234,7 @@ const NetdataTable = ({
223234
flexRender={flexRender}
224235
onHoverRow={onHoverRow}
225236
scrollParentRef={scrollParentRef}
237+
virtualizeOptions={virtualizeOptions}
226238
/>
227239
)}
228240
<MainTable
@@ -239,6 +251,7 @@ const NetdataTable = ({
239251
testPrefix={testPrefix}
240252
flexRender={flexRender}
241253
onHoverRow={onHoverRow}
254+
virtualizeOptions={virtualizeOptions}
242255
/>
243256
</Flex>
244257
{enablePagination && makePagination({ table })}

0 commit comments

Comments
 (0)