import { useEffect, useMemo, useState } from 'react'; import { chakra, Table, Thead, Tbody, Tr, Th, Td, Text, TableContainer, Flex, Checkbox, Button, Spacer, IconButton, Select, Input, Divider, } from '@chakra-ui/react'; import { createColumnHelper, useReactTable, flexRender, getCoreRowModel, SortingState, getSortedRowModel, PaginationState, } from '@tanstack/react-table'; import { VscTriangleDown, VscTriangleUp } from 'react-icons/vsc'; import { useNavigate } from 'react-router-dom'; import { Session, EventName } from '~/types'; import Channel from '~/utils/channel'; import { deleteSessions, getAllSessions } from '~/utils/storage'; import { FiChevronLeft, FiChevronRight, FiChevronsLeft, FiChevronsRight, } from 'react-icons/fi'; const columnHelper = createColumnHelper(); const channel = new Channel(); export function SessionList() { const [sessions, setSessions] = useState([]); const navigate = useNavigate(); const [sorting, setSorting] = useState([ { id: 'createTimestamp', desc: true, }, ]); const [rowSelection, setRowSelection] = useState({}); const [{ pageIndex, pageSize }, setPagination] = useState({ pageIndex: 0, pageSize: 10, }); const fetchDataOptions = { pageIndex, pageSize, }; const fetchData = (options: { pageIndex: number; pageSize: number }) => { return { rows: sessions.slice( options.pageIndex * options.pageSize, (options.pageIndex + 1) * options.pageSize, ), pageCount: Math.ceil(sessions.length / options.pageSize), }; }; const pagination = useMemo( () => ({ pageIndex, pageSize, }), [pageIndex, pageSize], ); const columns = useMemo( () => [ columnHelper.display({ id: 'select', header: ({ table }) => ( ), cell: ({ row }) => ( ), }), columnHelper.accessor((row) => row.name, { cell: (info) => info.getValue(), header: 'Name', }), columnHelper.accessor((row) => row.createTimestamp, { id: 'createTimestamp', cell: (info) => new Date(info.getValue()).toLocaleString(), header: 'Created Time', sortDescFirst: true, }), columnHelper.accessor((row) => row.recorderVersion, { cell: (info) => info.getValue(), header: 'RRWEB Version', }), ], [], ); const table = useReactTable({ columns, data: fetchData(fetchDataOptions).rows, getCoreRowModel: getCoreRowModel(), onPaginationChange: setPagination, onRowSelectionChange: setRowSelection, onSortingChange: setSorting, getSortedRowModel: getSortedRowModel(), state: { pagination, sorting, rowSelection, }, manualPagination: true, pageCount: fetchData(fetchDataOptions).pageCount, }); const updateSessions = async () => { const sessions = await getAllSessions(); setSessions(sessions); }; useEffect(() => { void updateSessions(); channel.on(EventName.SessionUpdated, () => { void updateSessions(); }); }, []); return ( <> {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { const meta = header.column.columnDef.meta as | { isNumeric: boolean; } | undefined; return ( ); })} ))} {table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell, index) => { const meta = cell.column.columnDef.meta as | { isNumeric: boolean; } | undefined; return ( ); })} ))}
{flexRender( header.column.columnDef.header, header.getContext(), )} {{ asc: ( ), desc: ( ), }[header.column.getIsSorted() as string] ?? null}
{ if (index !== 0) navigate(`/session/${row.original.id}`); }} > {flexRender( cell.column.columnDef.cell, cell.getContext(), )}
table.setPageIndex(0)} disabled={!table.getCanPreviousPage()} > table.previousPage()} disabled={!table.getCanPreviousPage()} > Page {`${ table.getState().pagination.pageIndex + 1 } of ${table.getPageCount()}`} Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0; table.setPageIndex(page); }} /> table.nextPage()} disabled={!table.getCanNextPage()} > table.setPageIndex(table.getPageCount() - 1)} disabled={!table.getCanNextPage()} > {Object.keys(rowSelection).length > 0 && ( )} ); }