2
0
Files
bot/apps/builder/layouts/results/SubmissionContent.tsx

183 lines
5.7 KiB
TypeScript
Raw Normal View History

2022-01-04 15:50:56 +01:00
import { Stack, useToast, Flex } from '@chakra-ui/react'
import { ResultsActionButtons } from 'components/results/ResultsActionButtons'
2021-12-24 10:08:41 +01:00
import { SubmissionsTable } from 'components/results/SubmissionsTable'
import React, { useCallback, useMemo, useState } from 'react'
2022-01-04 15:50:56 +01:00
import {
convertResultsToTableData,
deleteAllResults,
deleteResults,
getAllResults,
useResults,
2022-02-24 11:13:19 +01:00
} from 'services/typebots'
2022-01-04 15:50:56 +01:00
import { unparse } from 'papaparse'
import { UnlockProPlanInfo } from 'components/shared/Info'
2022-03-01 11:40:22 +01:00
import { LogsModal } from './LogsModal'
import { useTypebot } from 'contexts/TypebotContext'
import { isDefined, parseResultHeader } from 'utils'
2021-12-30 10:24:16 +01:00
type Props = {
typebotId: string
totalResults: number
totalHiddenResults?: number
onDeleteResults: (total: number) => void
}
export const SubmissionsContent = ({
typebotId,
totalResults,
totalHiddenResults,
onDeleteResults,
}: Props) => {
2022-03-09 15:12:00 +01:00
const { publishedTypebot, linkedTypebots } = useTypebot()
2022-01-04 15:50:56 +01:00
const [selectedIndices, setSelectedIndices] = useState<number[]>([])
2022-01-04 09:15:33 +01:00
const [isDeleteLoading, setIsDeleteLoading] = useState(false)
2022-01-04 15:50:56 +01:00
const [isExportLoading, setIsExportLoading] = useState(false)
2022-03-01 11:40:22 +01:00
const [inspectingLogsResultId, setInspectingLogsResultId] = useState<string>()
2021-12-30 10:24:16 +01:00
const toast = useToast({
position: 'top-right',
status: 'error',
})
2022-03-09 15:12:00 +01:00
const blocksAndVariables = {
blocks: [
...(publishedTypebot?.blocks ?? []),
...(linkedTypebots?.flatMap((t) => t.blocks) ?? []),
].filter(isDefined),
variables: [
...(publishedTypebot?.variables ?? []),
...(linkedTypebots?.flatMap((t) => t.variables) ?? []),
].filter(isDefined),
}
const resultHeader = parseResultHeader(blocksAndVariables)
const { data, mutate, setSize, hasMore } = useResults({
2021-12-30 10:24:16 +01:00
typebotId,
onError: (err) => toast({ title: err.name, description: err.message }),
})
const results = useMemo(() => data?.flatMap((d) => d.results), [data])
2022-01-04 15:50:56 +01:00
const handleNewSelection = (newSelectionIndices: number[]) => {
if (newSelectionIndices.length === selectedIndices.length) return
setSelectedIndices(newSelectionIndices)
2021-12-30 10:24:16 +01:00
}
2022-01-04 09:15:33 +01:00
const handleDeleteSelection = async () => {
setIsDeleteLoading(true)
2022-01-04 15:50:56 +01:00
const selectedIds = (results ?? [])
.filter((_, idx) => selectedIndices.includes(idx))
.map((result) => result.id)
const { error } =
totalSelected === totalResults
? await deleteAllResults(typebotId)
: await deleteResults(typebotId, selectedIds)
2022-01-04 09:15:33 +01:00
if (error) toast({ description: error.message, title: error.name })
else {
mutate(
totalSelected === totalResults
? []
: data?.map((d) => ({
results: d.results.filter((r) => !selectedIds.includes(r.id)),
}))
)
onDeleteResults(totalSelected)
}
2022-01-04 09:15:33 +01:00
setIsDeleteLoading(false)
}
const totalSelected =
selectedIndices.length > 0 && selectedIndices.length === results?.length
? totalResults - (totalHiddenResults ?? 0)
: selectedIndices.length
2021-12-24 10:08:41 +01:00
const handleScrolledToBottom = useCallback(
() => setSize((state) => state + 1),
[setSize]
)
2022-01-04 15:50:56 +01:00
const handleExportSelection = async () => {
setIsExportLoading(true)
const isSelectAll =
totalSelected === totalResults - (totalHiddenResults ?? 0)
2022-01-04 15:50:56 +01:00
const dataToUnparse = isSelectAll
? await getAllTableData()
: tableData.filter((_, idx) => selectedIndices.includes(idx))
2022-03-16 16:44:40 +01:00
const csvData = new Blob(
[
unparse({
data: dataToUnparse,
fields: resultHeader.map((h) => h.label),
}),
],
{
type: 'text/csv;charset=utf-8;',
}
)
2022-01-04 15:50:56 +01:00
const fileName =
`typebot-export_${new Date().toLocaleDateString().replaceAll('/', '-')}` +
(isSelectAll ? `_all` : ``)
const tempLink = document.createElement('a')
tempLink.href = window.URL.createObjectURL(csvData)
tempLink.setAttribute('download', `${fileName}.csv`)
tempLink.click()
setIsExportLoading(false)
}
const getAllTableData = async () => {
if (!publishedTypebot) return []
const results = await getAllResults(typebotId)
return convertResultsToTableData(results, resultHeader)
2022-01-04 15:50:56 +01:00
}
const tableData: { [key: string]: string }[] = useMemo(
() =>
publishedTypebot ? convertResultsToTableData(results, resultHeader) : [],
2022-01-04 15:50:56 +01:00
// eslint-disable-next-line react-hooks/exhaustive-deps
2022-05-13 09:18:25 -07:00
[publishedTypebot?.id, resultHeader.length, results]
2022-01-04 15:50:56 +01:00
)
2022-03-01 11:40:22 +01:00
const handleLogsModalClose = () => setInspectingLogsResultId(undefined)
const handleLogOpenIndex = (index: number) => () => {
if (!results) return
setInspectingLogsResultId(results[index].id)
}
2021-12-24 10:08:41 +01:00
return (
<Stack maxW="1200px" w="full" pb="28" px={['4', '0']} spacing="4">
{totalHiddenResults && (
<UnlockProPlanInfo
buttonLabel={`Unlock ${totalHiddenResults} results`}
contentLabel="You are seeing complete submissions only."
/>
)}
{publishedTypebot && (
<LogsModal
typebotId={publishedTypebot?.typebotId}
resultId={inspectingLogsResultId}
onClose={handleLogsModalClose}
/>
)}
2021-12-30 10:24:16 +01:00
<Flex w="full" justifyContent="flex-end">
2022-01-04 15:50:56 +01:00
<ResultsActionButtons
isDeleteLoading={isDeleteLoading}
isExportLoading={isExportLoading}
totalSelected={totalSelected}
onDeleteClick={handleDeleteSelection}
onExportClick={handleExportSelection}
/>
2021-12-30 10:24:16 +01:00
</Flex>
<SubmissionsTable
resultHeader={resultHeader}
2022-01-04 15:50:56 +01:00
data={tableData}
onNewSelection={handleNewSelection}
onScrollToBottom={handleScrolledToBottom}
hasMore={hasMore}
2022-03-01 11:40:22 +01:00
onLogOpenIndex={handleLogOpenIndex}
/>
2021-12-30 10:24:16 +01:00
</Stack>
2021-12-24 10:08:41 +01:00
)
}