2
0
Files
bot/apps/builder/components/results/SubmissionsTable/SubmissionsTable.tsx

186 lines
5.4 KiB
TypeScript
Raw Normal View History

2021-12-30 10:24:16 +01:00
/* eslint-disable @typescript-eslint/no-explicit-any */
2021-12-24 10:08:41 +01:00
/* eslint-disable react/jsx-key */
2022-03-01 11:40:22 +01:00
import { Button, chakra, Checkbox, Flex, HStack, Text } from '@chakra-ui/react'
import { AlignLeftTextIcon } from 'assets/icons'
2022-03-09 15:12:00 +01:00
import { PublicTypebot } from 'models'
2022-01-04 15:50:56 +01:00
import React, { useEffect, useMemo, useRef } from 'react'
2022-02-11 15:30:02 +01:00
import { Hooks, useRowSelect, useTable } from 'react-table'
2021-12-24 10:08:41 +01:00
import { parseSubmissionsColumns } from 'services/publicTypebot'
2021-12-30 10:24:16 +01:00
import { LoadingRows } from './LoadingRows'
2021-12-24 10:08:41 +01:00
2021-12-30 10:24:16 +01:00
type SubmissionsTableProps = {
2022-03-09 15:12:00 +01:00
blocksAndVariables: Pick<PublicTypebot, 'blocks' | 'variables'>
2022-01-04 15:50:56 +01:00
data?: any
hasMore?: boolean
2022-01-04 15:50:56 +01:00
onNewSelection: (indices: number[]) => void
onScrollToBottom: () => void
2022-03-01 11:40:22 +01:00
onLogOpenIndex: (index: number) => () => void
2021-12-30 10:24:16 +01:00
}
2021-12-24 10:08:41 +01:00
2021-12-30 10:24:16 +01:00
export const SubmissionsTable = ({
2022-03-09 15:12:00 +01:00
blocksAndVariables,
2022-01-04 15:50:56 +01:00
data,
hasMore,
2021-12-30 10:24:16 +01:00
onNewSelection,
onScrollToBottom,
2022-03-01 11:40:22 +01:00
onLogOpenIndex,
2021-12-30 10:24:16 +01:00
}: SubmissionsTableProps) => {
2022-01-04 15:50:56 +01:00
const columns: any = useMemo(
2022-03-09 15:12:00 +01:00
() => parseSubmissionsColumns(blocksAndVariables),
[blocksAndVariables]
2021-12-24 10:08:41 +01:00
)
const bottomElement = useRef<HTMLDivElement | null>(null)
const tableWrapper = useRef<HTMLDivElement | null>(null)
2021-12-30 10:24:16 +01:00
const {
getTableProps,
headerGroups,
rows,
prepareRow,
getTableBodyProps,
selectedFlatRows,
2022-02-11 15:30:02 +01:00
} = useTable({ columns, data }, useRowSelect, checkboxColumnHook) as any
2021-12-30 10:24:16 +01:00
useEffect(() => {
2022-01-04 15:50:56 +01:00
onNewSelection(selectedFlatRows.map((row: any) => row.index))
2021-12-30 10:24:16 +01:00
// 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()
}
2021-12-24 10:08:41 +01:00
return (
<Flex
maxW="full"
2022-02-11 15:30:02 +01:00
overflow="scroll"
ref={tableWrapper}
className="table-wrapper"
rounded="md"
>
2022-02-11 15:30:02 +01:00
<chakra.table rounded="md" {...getTableProps()}>
<thead>
2021-12-30 10:24:16 +01:00
{headerGroups.map((headerGroup: any) => {
2021-12-24 10:08:41 +01:00
return (
2022-02-11 15:30:02 +01:00
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column: any) => {
2021-12-24 10:08:41 +01:00
return (
2022-02-11 15:30:02 +01:00
<chakra.th
px="4"
py="2"
2021-12-24 10:08:41 +01:00
border="1px"
borderColor="gray.200"
fontWeight="normal"
2022-02-11 15:30:02 +01:00
whiteSpace="nowrap"
2021-12-24 10:08:41 +01:00
{...column.getHeaderProps()}
>
{column.render('Header')}
2022-02-11 15:30:02 +01:00
</chakra.th>
2021-12-24 10:08:41 +01:00
)
})}
2022-03-01 11:40:22 +01:00
<chakra.th
px="4"
py="2"
border="1px"
borderColor="gray.200"
fontWeight="normal"
whiteSpace="nowrap"
>
<HStack>
<AlignLeftTextIcon />
<Text>Logs</Text>
</HStack>
</chakra.th>
2022-02-11 15:30:02 +01:00
</tr>
2021-12-24 10:08:41 +01:00
)
})}
2022-02-11 15:30:02 +01:00
</thead>
2021-12-24 10:08:41 +01:00
2022-02-11 15:30:02 +01:00
<tbody {...getTableBodyProps()}>
{rows.map((row: any, idx: number) => {
2021-12-24 10:08:41 +01:00
prepareRow(row)
return (
2022-02-11 15:30:02 +01:00
<tr
{...row.getRowProps()}
ref={(ref) => {
2022-01-04 15:50:56 +01:00
if (idx === data.length - 10) bottomElement.current = ref
}}
>
2022-02-11 15:30:02 +01:00
{row.cells.map((cell: any) => {
2021-12-24 10:08:41 +01:00
return (
2022-02-11 15:30:02 +01:00
<chakra.td
px="4"
py="2"
2021-12-24 10:08:41 +01:00
border="1px"
borderColor="gray.200"
2022-02-11 15:30:02 +01:00
whiteSpace={
cell?.value?.length > 100 ? 'normal' : 'nowrap'
}
2021-12-24 10:08:41 +01:00
{...cell.getCellProps()}
>
{cell.render('Cell')}
2022-02-11 15:30:02 +01:00
</chakra.td>
2021-12-24 10:08:41 +01:00
)
})}
2022-03-01 11:40:22 +01:00
<chakra.td px="4" py="2" border="1px" borderColor="gray.200">
<Button size="sm" onClick={onLogOpenIndex(idx)}>
See logs
</Button>
</chakra.td>
2022-02-11 15:30:02 +01:00
</tr>
2021-12-24 10:08:41 +01:00
)
})}
2022-03-01 11:40:22 +01:00
{hasMore === true && (
<LoadingRows totalColumns={columns.length + 1} />
)}
2022-02-11 15:30:02 +01:00
</tbody>
</chakra.table>
2021-12-24 10:08:41 +01:00
</Flex>
)
}
2021-12-30 10:24:16 +01:00
const checkboxColumnHook = (hooks: Hooks<any>) => {
hooks.visibleColumns.push((columns) => [
{
id: 'selection',
Header: ({ getToggleAllRowsSelectedProps }: any) => (
<IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
),
Cell: ({ row }: any) => (
<IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
),
},
...columns,
])
}
const IndeterminateCheckbox = React.forwardRef(
({ indeterminate, checked, ...rest }: any, ref) => {
const defaultRef = React.useRef()
const resolvedRef: any = ref || defaultRef
return (
<Flex justify="center" data-testid="checkbox">
2022-02-11 15:30:02 +01:00
<Checkbox
ref={resolvedRef}
{...rest}
isIndeterminate={indeterminate}
isChecked={checked}
/>
</Flex>
2021-12-30 10:24:16 +01:00
)
}
)