2
0
Files
bot/packages/results/convertResultsToTableData.ts

97 lines
2.9 KiB
TypeScript
Raw Normal View History

import {
ResultWithAnswers,
ResultHeaderCell,
VariableWithValue,
Answer,
TableData,
} from '@typebot.io/schemas'
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
import { isDefined } from '../lib/utils'
type CellParser = (
content: VariableWithValue['value'],
blockType?: InputBlockType
) => { element?: React.JSX.Element; plainText: string }
const defaultCellParser: CellParser = (content, blockType) => {
if (!content) return { plainText: '' }
if (Array.isArray(content))
return {
plainText: content.join(', '),
}
return blockType === InputBlockType.FILE
? { plainText: content }
: { plainText: content.toString() }
}
type Props = {
results: ResultWithAnswers[] | undefined
headerCells: ResultHeaderCell[]
cellParser?: CellParser
blockIdVariableIdMap: Record<string, string>
}
export const convertResultsToTableData = ({
results,
headerCells,
cellParser = defaultCellParser,
blockIdVariableIdMap,
}: Props): TableData[] =>
(results ?? []).map((result) => ({
id: { plainText: result.id },
date: {
plainText: convertDateToReadable(result.createdAt),
},
...[...result.answers, ...result.variables].reduce<{
[key: string]: { element?: JSX.Element; plainText: string }
}>((tableData, answerOrVariable) => {
if ('blockId' in answerOrVariable) {
const answer = answerOrVariable satisfies Pick<
Answer,
'blockId' | 'content'
>
const answerVariableId = blockIdVariableIdMap[answer.blockId]
const header = answerVariableId
? headerCells.find((headerCell) =>
headerCell.variableIds?.includes(answerVariableId)
)
: headerCells.find((headerCell) =>
headerCell.blocks?.some((block) => block.id === answer.blockId)
)
if (!header || !header.blocks || !header.blockType) return tableData
return {
...tableData,
[header.id]: cellParser(answer.content, header.blockType),
}
}
const variable = answerOrVariable satisfies VariableWithValue
if (variable.value === null) return tableData
const headerId = headerCells.find((headerCell) =>
headerCell.variableIds?.includes(variable.id)
)?.id
if (!headerId) return tableData
if (isDefined(tableData[headerId])) return tableData
return {
...tableData,
[headerId]: cellParser(variable.value),
}
}, {}),
}))
const convertDateToReadable = (date: Date): string => {
const isThisYear = new Date().getFullYear() === date.getFullYear()
const dateString = date.toLocaleDateString('default', {
month: 'short',
day: 'numeric',
year: isThisYear ? undefined : 'numeric', // Only show the year if it's not the current year
})
const timeString = date.toLocaleTimeString('default', {
hour: '2-digit',
minute: '2-digit',
})
return `${dateString}, ${timeString}`
}