2
0

🧐 Add exportResults script

This commit is contained in:
Baptiste Arnaud
2024-01-12 10:16:01 +01:00
parent 5d088b1e64
commit 69b113fc85
32 changed files with 319 additions and 332 deletions

View File

@ -0,0 +1,8 @@
export const parseUniqueKey = (
key: string,
existingKeys: string[],
count = 0
): string => {
if (!existingKeys.includes(key)) return key
return parseUniqueKey(`${key} (${count + 1})`, existingKeys, count + 1)
}

View File

@ -0,0 +1,79 @@
import {
ResultWithAnswers,
ResultHeaderCell,
VariableWithValue,
Answer,
TableData,
} from '@typebot.io/schemas'
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
import { isDefined } from '../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() }
}
export const convertResultsToTableData = (
results: ResultWithAnswers[] | undefined,
headerCells: ResultHeaderCell[],
cellParser: CellParser = defaultCellParser
): 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 ('groupId' in answerOrVariable) {
const answer = answerOrVariable satisfies Answer
const header = answer.variableId
? headerCells.find((headerCell) =>
headerCell.variableIds?.includes(answer.variableId as string)
)
: headerCells.find((headerCell) =>
headerCell.blocks?.some((block) => block.id === answer.blockId)
)
if (!header || !header.blocks || !header.blockType) return tableData
const variableValue = result.variables.find(
(variable) => variable.id === answer.variableId
)?.value
const content = variableValue ?? answer.content
return {
...tableData,
[header.id]: cellParser(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 =>
date.toDateString().split(' ').slice(1, 3).join(' ') +
', ' +
date.toLocaleTimeString([], {
hour: '2-digit',
minute: '2-digit',
})

View File

@ -0,0 +1,39 @@
import {
AnswerInSessionState,
Variable,
VariableWithValue,
} from '@typebot.io/schemas'
import { isDefined, isEmpty } from '../utils'
export const parseAnswers = ({
answers,
variables: resultVariables,
}: {
answers: AnswerInSessionState[]
variables: Variable[]
}): {
[key: string]: string
} => {
const variablesWithValues = resultVariables.filter((variable) =>
isDefined(variable.value)
) as VariableWithValue[]
return {
submittedAt: new Date().toISOString(),
...[...answers, ...variablesWithValues].reduce<{
[key: string]: string
}>((o, answerOrVariable) => {
if ('id' in answerOrVariable) {
const variable = answerOrVariable
if (variable.value === null) return o
return { ...o, [variable.name]: variable.value.toString() }
}
const answer = answerOrVariable as AnswerInSessionState
if (isEmpty(answer.key)) return o
return {
...o,
[answer.key]: answer.value,
}
}, {}),
}
}

View File

@ -0,0 +1,15 @@
import { ResultHeaderCell } from '@typebot.io/schemas'
export const parseColumnsOrder = (
existingOrder: string[] | undefined,
resultHeader: ResultHeaderCell[]
) =>
existingOrder
? [
...existingOrder.slice(0, -1),
...resultHeader
.filter((header) => !existingOrder.includes(header.id))
.map((h) => h.id),
'logs',
]
: ['select', ...resultHeader.map((h) => h.id), 'logs']

View File

@ -1,15 +1,13 @@
import {
ResultWithAnswers,
ResultHeaderCell,
Group,
Variable,
InputBlock,
ResultHeaderCell,
VariableWithValue,
Typebot,
ResultWithAnswers,
AnswerInSessionState,
} from '@typebot.io/schemas'
import { isInputBlock, isDefined, byId, isNotEmpty, isEmpty } from './utils'
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
import { isInputBlock, byId, isNotEmpty } from '../utils'
export const parseResultHeader = (
typebot: Pick<Typebot, 'groups' | 'variables'>,
@ -212,37 +210,3 @@ const parseResultsFromPreviousBotVersions = (
},
]
}, [])
export const parseAnswers = ({
answers,
variables: resultVariables,
}: {
answers: AnswerInSessionState[]
variables: VariableWithValue[]
}): {
[key: string]: string
} => {
return {
submittedAt: new Date().toISOString(),
...[...answers, ...resultVariables].reduce<{
[key: string]: string
}>((o, answerOrVariable) => {
if ('id' in answerOrVariable) {
const variable = answerOrVariable
if (variable.value === null) return o
return { ...o, [variable.name]: variable.value.toString() }
}
const answer = answerOrVariable as AnswerInSessionState
if (isEmpty(answer.key)) return o
return {
...o,
[answer.key]: answer.value,
}
}, {}),
}
}
export const getDefinedVariables = (variables: Variable[]) =>
variables.filter((variable) =>
isDefined(variable.value)
) as VariableWithValue[]