2
0

⚗️ Add infinite scroll in results table

This commit is contained in:
Baptiste Arnaud
2022-01-04 12:25:48 +01:00
parent 8ddf608c9e
commit 72454c0f68
9 changed files with 200 additions and 98 deletions

View File

@ -3,7 +3,7 @@
import { Box, Checkbox, Flex } from '@chakra-ui/react'
import { Answer, Result } from 'bot-engine'
import { useTypebot } from 'contexts/TypebotContext'
import React, { useEffect } from 'react'
import React, { useEffect, useRef } from 'react'
import { Hooks, useFlexLayout, useRowSelect, useTable } from 'react-table'
import { parseSubmissionsColumns } from 'services/publicTypebot'
import { parseDateToReadable } from 'services/results'
@ -13,12 +13,16 @@ const defaultCellWidth = 180
type SubmissionsTableProps = {
results?: (Result & { answers: Answer[] })[]
hasMore?: boolean
onNewSelection: (selection: string[]) => void
onScrollToBottom: () => void
}
export const SubmissionsTable = ({
results,
hasMore,
onNewSelection,
onScrollToBottom,
}: SubmissionsTableProps) => {
const { publishedTypebot } = useTypebot()
const columns: any = React.useMemo(
@ -34,8 +38,11 @@ export const SubmissionsTable = ({
{}
),
})),
[results]
// eslint-disable-next-line react-hooks/exhaustive-deps
[results?.length]
)
const bottomElement = useRef<HTMLDivElement | null>(null)
const tableWrapper = useRef<HTMLDivElement | null>(null)
const {
getTableProps,
@ -57,10 +64,35 @@ export const SubmissionsTable = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedFlatRows])
useEffect(() => {
if (!bottomElement.current) return
const options: IntersectionObserverInit = {
root: tableWrapper.current,
threshold: 0,
}
const observer = new IntersectionObserver(handleObserver, options)
if (bottomElement.current) observer.observe(bottomElement.current)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [bottomElement.current])
const handleObserver = (entities: any[]) => {
const target = entities[0]
if (target.isIntersecting) onScrollToBottom()
}
return (
<Flex overflowX="scroll" maxW="full" className="table-wrapper" rounded="md">
<Box as="table" rounded="md" {...getTableProps()} w="full">
<Box as="thead">
<Flex
overflow="scroll"
maxW="full"
maxH="full"
className="table-wrapper"
rounded="md"
data-testid="table-wrapper"
pb="20"
ref={tableWrapper}
>
<Box as="table" rounded="md" {...getTableProps()} w="full" h="full">
<Box as="thead" pos="sticky" top="0" zIndex={2}>
{headerGroups.map((headerGroup: any) => {
return (
<Flex as="tr" {...headerGroup.getHeaderGroupProps()}>
@ -75,6 +107,7 @@ export const SubmissionsTable = ({
color="gray.500"
fontWeight="normal"
textAlign="left"
bgColor={'white'}
{...column.getHeaderProps()}
style={{
width: idx === 0 ? '50px' : `${defaultCellWidth}px`,
@ -90,13 +123,17 @@ export const SubmissionsTable = ({
</Box>
<Box as="tbody" {...getTableBodyProps()}>
{results === undefined && (
<LoadingRows totalColumns={columns.length} />
)}
{rows.map((row: any) => {
{rows.map((row: any, idx: number) => {
prepareRow(row)
return (
<Flex as="tr" {...row.getRowProps()}>
<Flex
as="tr"
{...row.getRowProps()}
ref={(ref) => {
if (results && idx === results.length - 10)
bottomElement.current = ref
}}
>
{row.cells.map((cell: any, idx: number) => {
return (
<Flex
@ -105,6 +142,7 @@ export const SubmissionsTable = ({
border="1px"
as="td"
borderColor="gray.200"
bgColor={'white'}
{...cell.getCellProps()}
style={{
width: idx === 0 ? '50px' : `${defaultCellWidth}px`,
@ -117,6 +155,9 @@ export const SubmissionsTable = ({
</Flex>
)
})}
{(results === undefined || hasMore === true) && (
<LoadingRows totalColumns={columns.length} />
)}
</Box>
</Box>
</Flex>