2
0

🚸 (results) Remove useless scrollbars and make header sticky

Closes #297
This commit is contained in:
Baptiste Arnaud
2023-02-10 16:33:18 +01:00
parent 3ab67902c0
commit b98aef53fd
7 changed files with 90 additions and 81 deletions

View File

@ -8,6 +8,7 @@ type Props = {
cell: CellProps<TableData, unknown>
size: number
isExpandButtonVisible: boolean
rowIndex: number
cellIndex: number
isSelected: boolean
onExpandButtonClick: () => void
@ -17,6 +18,7 @@ const Cell = ({
cell,
size,
isExpandButtonVisible,
rowIndex,
cellIndex,
onExpandButtonClick,
}: Props) => {
@ -25,7 +27,7 @@ const Cell = ({
key={cell.id}
px="4"
py="2"
border="1px"
borderWidth={rowIndex === 0 ? '0 1px 1px 1px' : '1px'}
borderColor={useColorModeValue('gray.200', 'gray.700')}
whiteSpace="nowrap"
wordBreak="normal"

View File

@ -96,66 +96,68 @@ export const ColumnSettingsButton = ({
<PopoverTrigger>
<Button leftIcon={<ToolIcon />}>Columns</Button>
</PopoverTrigger>
<PopoverContent w="400px">
<PopoverBody
as={Stack}
spacing="4"
p="4"
maxH="450px"
overflowY="scroll"
>
<Stack>
<Text fontWeight="semibold" fontSize="sm">
Shown in table:
</Text>
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
>
<SortableContext
items={columnOrder}
strategy={verticalListSortingStrategy}
>
{visibleHeaders.map((header) => (
<SortableColumns
key={header.id}
header={header}
onEyeClick={onEyeClick}
/>
))}
</SortableContext>
<Portal>
<DragOverlay dropAnimation={{ duration: 0 }}>
{draggingColumnId ? <Flex /> : null}
</DragOverlay>
</Portal>
</DndContext>
</Stack>
{hiddenHeaders.length > 0 && (
<Portal>
<PopoverContent w="400px">
<PopoverBody
as={Stack}
spacing="4"
p="4"
maxH="450px"
overflowY="scroll"
>
<Stack>
<Text fontWeight="semibold" fontSize="sm">
Hidden in table:
Shown in table:
</Text>
{hiddenHeaders.map((header) => (
<Flex key={header.id} justify="space-between">
<HStack>
<HeaderIcon header={header} />
<Text>{header.label}</Text>
</HStack>
<IconButton
icon={<EyeOffIcon />}
size="sm"
aria-label={'Hide column'}
onClick={onEyeClick(header.id)}
/>
</Flex>
))}
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
>
<SortableContext
items={columnOrder}
strategy={verticalListSortingStrategy}
>
{visibleHeaders.map((header) => (
<SortableColumns
key={header.id}
header={header}
onEyeClick={onEyeClick}
/>
))}
</SortableContext>
<Portal>
<DragOverlay dropAnimation={{ duration: 0 }}>
{draggingColumnId ? <Flex /> : null}
</DragOverlay>
</Portal>
</DndContext>
</Stack>
)}
</PopoverBody>
</PopoverContent>
{hiddenHeaders.length > 0 && (
<Stack>
<Text fontWeight="semibold" fontSize="sm">
Hidden in table:
</Text>
{hiddenHeaders.map((header) => (
<Flex key={header.id} justify="space-between">
<HStack>
<HeaderIcon header={header} />
<Text>{header.label}</Text>
</HStack>
<IconButton
icon={<EyeOffIcon />}
size="sm"
aria-label={'Hide column'}
onClick={onEyeClick(header.id)}
/>
</Flex>
))}
</Stack>
)}
</PopoverBody>
</PopoverContent>
</Portal>
</Popover>
)
}

View File

@ -1,3 +1,4 @@
import { colors } from '@/lib/theme'
import { Box, BoxProps, chakra, useColorModeValue } from '@chakra-ui/react'
import { flexRender, HeaderGroup } from '@tanstack/react-table'
import React from 'react'
@ -5,10 +6,13 @@ import { TableData } from '../../types'
type Props = {
headerGroup: HeaderGroup<TableData>
isTableScrolled: boolean
}
export const HeaderRow = ({ headerGroup }: Props) => {
const borderColor = useColorModeValue('gray.200', 'gray.700')
export const HeaderRow = ({ headerGroup, isTableScrolled }: Props) => {
const borderColor = useColorModeValue(colors.gray[200], colors.gray[700])
const backgroundColor = useColorModeValue('white', colors.gray[900])
return (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => {
@ -16,14 +20,18 @@ export const HeaderRow = ({ headerGroup }: Props) => {
<chakra.th
key={header.id}
px="4"
py="2"
pos="relative"
border="1px"
py="3"
borderX="1px"
borderColor={borderColor}
backgroundColor={isTableScrolled ? backgroundColor : undefined}
zIndex={10}
pos="sticky"
top="0"
fontWeight="normal"
whiteSpace="nowrap"
wordBreak="normal"
colSpan={header.colSpan}
shadow={`inset 0 1px 0 ${borderColor}, inset 0 -1px 0 ${borderColor}; `}
style={{
minWidth: header.getSize(),
maxWidth: header.getSize(),

View File

@ -50,6 +50,7 @@ export const ResultsTable = ({
const background = useColorModeValue('white', colors.gray[900])
const { updateTypebot } = useTypebot()
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({})
const [isTableScrolled, setIsTableScrolled] = useState(false)
const bottomElement = useRef<HTMLDivElement | null>(null)
const tableWrapper = useRef<HTMLDivElement | null>(null)
@ -197,13 +198,7 @@ export const ResultsTable = ({
}
return (
<Stack
maxW="1600px"
px="4"
overflow="scroll"
spacing={6}
ref={tableWrapper}
>
<Stack maxW="1600px" px="4" overflowY="hidden" spacing={6}>
<Flex w="full" justifyContent="flex-end">
<ResultsActionButtons
selectedResultsId={Object.keys(rowSelection)}
@ -219,6 +214,7 @@ export const ResultsTable = ({
/>
</Flex>
<Box
ref={tableWrapper}
overflow="scroll"
rounded="md"
data-testid="results-table"
@ -227,11 +223,18 @@ export const ResultsTable = ({
backgroundRepeat="no-repeat"
backgroundSize="30px 100%, 30px 100%, 15px 100%, 15px 100%"
backgroundAttachment="local, local, scroll, scroll"
onScroll={(e) =>
setIsTableScrolled((e.target as HTMLElement).scrollTop > 0)
}
>
<chakra.table rounded="md">
<thead>
{instance.getHeaderGroups().map((headerGroup) => (
<HeaderRow key={headerGroup.id} headerGroup={headerGroup} />
<HeaderRow
key={headerGroup.id}
headerGroup={headerGroup}
isTableScrolled={isTableScrolled}
/>
))}
</thead>

View File

@ -38,6 +38,7 @@ export const Row = ({
cell={cell}
size={cell.column.getSize()}
isExpandButtonVisible={isExpandButtonVisible}
rowIndex={row.index}
cellIndex={cellIndex}
onExpandButtonClick={onExpandButtonClick}
isSelected={isSelected}

View File

@ -1 +1 @@
export { ResultsTable as SubmissionsTable } from './ResultsTable'
export { ResultsTable } from './ResultsTable'

View File

@ -4,7 +4,7 @@ import { LogsModal } from './LogsModal'
import { useTypebot } from '@/features/editor'
import { useResults } from '../ResultsProvider'
import { ResultModal } from './ResultModal'
import { SubmissionsTable } from './ResultsTable'
import { ResultsTable } from './ResultsTable'
export const ResultsTableContainer = () => {
const {
@ -35,14 +35,7 @@ export const ResultsTableContainer = () => {
setExpandedResultIndex(index)
return (
<Stack
pb="28"
px={['4', '0']}
spacing="4"
maxW="1600px"
overflow="scroll"
w="full"
>
<Stack pb="28" px={['4', '0']} spacing="4" maxW="1600px" w="full">
{publishedTypebot && (
<LogsModal
typebotId={publishedTypebot?.typebotId}
@ -56,7 +49,7 @@ export const ResultsTableContainer = () => {
/>
{typebot && (
<SubmissionsTable
<ResultsTable
preferences={typebot.resultsTablePreferences ?? undefined}
resultHeader={resultHeader}
data={tableData}