2
0

fix(results): 🐛 Loading rows

This commit is contained in:
Baptiste Arnaud
2022-02-11 15:30:02 +01:00
parent 901e2f39b0
commit 93fed893c0
13 changed files with 85 additions and 90 deletions

View File

@@ -1,6 +1,6 @@
DATABASE_URL=postgresql://postgres:@localhost:5432/typebot
SECRET=q3t6v9y$B&E)H@McQfTjWnZr4u7x!z%C #256-bits secret (can be generated here: https://www.allkeysgenerator.com/Random/Security-Encryption-Key-Generator.aspx)
ENCRYPTION_SECRET=q3t6v9y$B&E)H@McQfTjWnZr4u7x!z%C #256-bits secret (can be generated here: https://www.allkeysgenerator.com/Random/Security-Encryption-Key-Generator.aspx)
NEXTAUTH_URL=http://localhost:3000
# Used for email auth and email notifications

View File

@@ -1,4 +1,4 @@
import { Checkbox, Flex, Skeleton } from '@chakra-ui/react'
import { chakra, Checkbox, Flex, Skeleton } from '@chakra-ui/react'
import React from 'react'
type LoadingRowsProps = {
@@ -9,35 +9,32 @@ export const LoadingRows = ({ totalColumns }: LoadingRowsProps) => {
return (
<>
{Array.from(Array(3)).map((row, idx) => (
<Flex as="tr" key={idx}>
<Flex
key={idx}
py={2}
px={4}
<tr key={idx}>
<chakra.td
px="4"
py="2"
border="1px"
as="td"
borderColor="gray.200"
width="50px"
>
<Flex>
<Checkbox isDisabled />
</Flex>
</chakra.td>
{Array.from(Array(totalColumns)).map((cell, idx) => {
return (
<Flex
<chakra.td
key={idx}
py={2}
px={4}
px="4"
py="2"
border="1px"
as="td"
borderColor="gray.200"
width="180px"
align="center"
>
<Skeleton height="5px" w="full" />
</Flex>
</chakra.td>
)
})}
</Flex>
</tr>
))}
</>
)

View File

@@ -1,14 +1,12 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable react/jsx-key */
import { Box, Checkbox, Flex } from '@chakra-ui/react'
import { chakra, Checkbox, Flex } from '@chakra-ui/react'
import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
import React, { useEffect, useMemo, useRef } from 'react'
import { Hooks, useFlexLayout, useRowSelect, useTable } from 'react-table'
import { Hooks, useRowSelect, useTable } from 'react-table'
import { parseSubmissionsColumns } from 'services/publicTypebot'
import { LoadingRows } from './LoadingRows'
const defaultCellWidth = 180
type SubmissionsTableProps = {
data?: any
hasMore?: boolean
@@ -38,12 +36,7 @@ export const SubmissionsTable = ({
prepareRow,
getTableBodyProps,
selectedFlatRows,
} = useTable(
{ columns, data, defaultColumn: { width: defaultCellWidth } },
useRowSelect,
checkboxColumnHook,
useFlexLayout
) as any
} = useTable({ columns, data }, useRowSelect, checkboxColumnHook) as any
useEffect(() => {
onNewSelection(selectedFlatRows.map((row: any) => row.index))
@@ -68,81 +61,69 @@ export const SubmissionsTable = ({
return (
<Flex
overflow="scroll"
maxW="full"
maxH="full"
overflow="scroll"
ref={tableWrapper}
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}>
<chakra.table rounded="md" {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup: any) => {
return (
<Flex as="tr" {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column: any, idx: number) => {
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column: any) => {
return (
<Flex
py={2}
px={4}
<chakra.th
px="4"
py="2"
border="1px"
borderColor="gray.200"
as="th"
color="gray.500"
fontWeight="normal"
textAlign="left"
bgColor={'white'}
whiteSpace="nowrap"
{...column.getHeaderProps()}
style={{
width: idx === 0 ? '50px' : `${defaultCellWidth}px`,
}}
>
{column.render('Header')}
</Flex>
</chakra.th>
)
})}
</Flex>
</tr>
)
})}
</Box>
</thead>
<Box as="tbody" {...getTableBodyProps()}>
<tbody {...getTableBodyProps()}>
{rows.map((row: any, idx: number) => {
prepareRow(row)
return (
<Flex
as="tr"
<tr
{...row.getRowProps()}
ref={(ref) => {
if (idx === data.length - 10) bottomElement.current = ref
}}
>
{row.cells.map((cell: any, idx: number) => {
{row.cells.map((cell: any) => {
return (
<Flex
py={2}
px={4}
<chakra.td
px="4"
py="2"
border="1px"
as="td"
borderColor="gray.200"
bgColor={'white'}
whiteSpace={
cell?.value?.length > 100 ? 'normal' : 'nowrap'
}
{...cell.getCellProps()}
style={{
width: idx === 0 ? '50px' : `${defaultCellWidth}px`,
}}
>
{cell.render('Cell')}
</Flex>
</chakra.td>
)
})}
</Flex>
</tr>
)
})}
{hasMore === true && <LoadingRows totalColumns={columns.length} />}
</Box>
</Box>
</tbody>
</chakra.table>
</Flex>
)
}
@@ -168,12 +149,14 @@ const IndeterminateCheckbox = React.forwardRef(
const resolvedRef: any = ref || defaultRef
return (
<Flex justify="center">
<Checkbox
ref={resolvedRef}
{...rest}
isIndeterminate={indeterminate}
isChecked={checked}
/>
</Flex>
)
}
)

View File

@@ -106,11 +106,11 @@ export const SubmissionsContent = ({
const tableData: { [key: string]: string }[] = useMemo(
() => convertResultsToTableData(results),
// eslint-disable-next-line react-hooks/exhaustive-deps
[results?.length]
[results]
)
return (
<Stack maxW="1200px" w="full">
<Stack maxW="1200px" w="full" pb="28">
<Flex w="full" justifyContent="flex-end">
<ResultsActionButtons
isDeleteLoading={isDeleteLoading}

View File

@@ -7,8 +7,8 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "dotenv -e ./playwright/.env -- yarn playwright test",
"test:open": "dotenv -e ./playwright/.env -v PWDEBUG=1 -- yarn playwright test"
"test": "dotenv -e ./playwright/.env -e .env.local -- yarn playwright test",
"test:open": "dotenv -e ./playwright/.env -e .env.local -v PWDEBUG=1 -- yarn playwright test"
},
"dependencies": {
"@chakra-ui/css-reset": "^1.1.1",

View File

@@ -49,13 +49,13 @@ if (process.env.FACEBOOK_CLIENT_ID && process.env.FACEBOOK_CLIENT_SECRET)
const handler = (req: NextApiRequest, res: NextApiResponse) => {
NextAuth(req, res, {
adapter: PrismaAdapter(prisma),
secret: process.env.SECRET,
secret: process.env.ENCRYPTION_SECRET,
providers,
session: {
strategy: 'database',
},
callbacks: {
session: async ({ session, user }) => ({ ...session, user }),
session: ({ session, user }) => ({ ...session, user }),
},
})
}

View File

@@ -4,7 +4,7 @@ import path from 'path'
const config: PlaywrightTestConfig = {
globalSetup: require.resolve(path.join(__dirname, 'playwright/global-setup')),
testDir: path.join(__dirname, 'playwright/tests'),
timeout: 10 * 1000,
timeout: 10 * 2000,
expect: {
timeout: 5000,
},

View File

@@ -1,6 +1,6 @@
import test, { expect, Page } from '@playwright/test'
import { readFileSync } from 'fs'
import { InputStepType } from 'models'
import { defaultTextInputOptions, InputStepType } from 'models'
import { parse } from 'papaparse'
import { generate } from 'short-uuid'
import {
@@ -17,7 +17,10 @@ test.describe('Results page', () => {
await createTypebots([
{
id: typebotId,
...parseDefaultBlockWithStep({ type: InputStepType.TEXT }),
...parseDefaultBlockWithStep({
type: InputStepType.TEXT,
options: defaultTextInputOptions,
}),
},
])
await createResults({ typebotId })

View File

@@ -78,18 +78,25 @@ export const parseSubmissionsColumns = (
(block) => typebot && block.steps.some((step) => isInputStep(step))
)
.map((block) => {
const inputStep = block.steps.find((step) =>
isInputStep(step)
) as InputStep
const inputStep = block.steps.find((step) => isInputStep(step))
if (!inputStep || !isInputStep(inputStep)) return
return {
Header: (
<HStack>
<HStack
minW={
'isLong' in inputStep.options && inputStep.options.isLong
? '400px'
: '150px'
}
maxW="500px"
>
<StepIcon type={inputStep.type} />
<Text>{block.title}</Text>
</HStack>
),
accessor: block.id,
}
}),
})
.filter(isDefined),
]
}

View File

@@ -5,6 +5,8 @@ import { stringify } from 'qs'
import { Answer } from 'db'
import { sendRequest } from 'utils'
const paginationLimit = 50
const getKey = (
typebotId: string,
pageIndex: number,
@@ -16,7 +18,7 @@ const getKey = (
if (pageIndex === 0) return `/api/typebots/${typebotId}/results?limit=50`
return `/api/typebots/${typebotId}/results?lastResultId=${
previousPageData.results[previousPageData.results.length - 1].id
}&limit=50`
}&limit=${paginationLimit}`
}
export type ResultWithAnswers = Result & { answers: Answer[] }
@@ -49,7 +51,10 @@ export const useResults = ({
setSize,
size,
hasMore:
data && data.length > 0 && data[data.length - 1].results.length > 0,
data &&
data.length > 0 &&
data[data.length - 1].results.length > 0 &&
data.length === paginationLimit,
}
}

View File

@@ -1,3 +1,4 @@
ENCRYPTION_SECRET=
NEXT_PUBLIC_VIEWER_HOST=http://localhost:3001
DATABASE_URL=postgresql://postgres:@localhost:5432/typebot

View File

@@ -76,7 +76,6 @@ export const ChatBlock = ({
const displayNextStep = (answerContent?: string, isRetry?: boolean) => {
const currentStep = [...displayedSteps].pop()
console.log(currentStep)
if (currentStep) {
if (isRetry && stepCanBeRetried(currentStep))
return setDisplayedSteps([

View File

@@ -1,7 +1,7 @@
import { randomBytes, createCipheriv, createDecipheriv } from 'crypto'
const algorithm = 'aes-256-gcm'
const secretKey = process.env.SECRET
const secretKey = process.env.ENCRYPTION_SECRET
export const encrypt = (
data: object