2
0

🐛 (results) Fix bug preventing user from seeing linked typebots results

This commit is contained in:
Baptiste Arnaud
2022-11-06 09:57:08 +01:00
parent 63845effaf
commit 6dd7bd9562
18 changed files with 234 additions and 151 deletions

View File

@ -6,90 +6,173 @@ import {
ResultWithAnswers,
Answer,
VariableWithValue,
Typebot,
} from 'models'
import { isInputBlock, isDefined, byId } from './utils'
export const parseResultHeader = ({
groups,
variables,
}: {
groups: Group[]
variables: Variable[]
}): ResultHeaderCell[] => {
const parsedGroups = parseInputsResultHeader({ groups, variables })
export const parseResultHeader = (
typebot: Pick<Typebot, 'groups' | 'variables'>,
linkedTypebots: Pick<Typebot, 'groups' | 'variables'>[] | undefined
): ResultHeaderCell[] => {
const parsedGroups = [
...typebot.groups,
...(linkedTypebots ?? []).flatMap((linkedTypebot) => linkedTypebot.groups),
]
const parsedVariables = [
...typebot.variables,
...(linkedTypebots ?? []).flatMap(
(linkedTypebot) => linkedTypebot.variables
),
]
const inputsResultHeader = parseInputsResultHeader({
groups: parsedGroups,
variables: parsedVariables,
})
return [
{ label: 'Submitted at', id: 'date' },
...parsedGroups,
...parseVariablesHeaders(variables, parsedGroups),
...inputsResultHeader,
...parseVariablesHeaders(parsedVariables, inputsResultHeader),
]
}
type ResultHeaderCellWithBlock = Omit<ResultHeaderCell, 'blocks'> & {
blocks: NonNullable<ResultHeaderCell['blocks']>
}
const parseInputsResultHeader = ({
groups,
variables,
}: {
groups: Group[]
variables: Variable[]
}): ResultHeaderCell[] =>
}): ResultHeaderCellWithBlock[] =>
(
groups
.flatMap((g) =>
g.blocks.map((s) => ({
...s,
blockTitle: g.title,
.flatMap((group) =>
group.blocks.map((block) => ({
...block,
groupTitle: group.title,
}))
)
.filter((block) => isInputBlock(block)) as (InputBlock & {
blockTitle: string
groupTitle: string
})[]
).reduce<ResultHeaderCell[]>((headers, inputBlock) => {
).reduce<ResultHeaderCellWithBlock[]>((existingHeaders, inputBlock) => {
if (
headers.find(
(h) =>
isDefined(h.variableId) &&
h.variableId ===
variables.find(byId(inputBlock.options.variableId))?.id
existingHeaders.some(
(existingHeader) =>
inputBlock.options.variableId &&
existingHeader.variableIds?.includes(inputBlock.options.variableId)
)
)
return headers
return existingHeaders
const matchedVariableName =
inputBlock.options.variableId &&
variables.find(byId(inputBlock.options.variableId))?.name
let label = matchedVariableName ?? inputBlock.blockTitle
const totalPrevious = headers.filter((h) => h.label.includes(label)).length
if (totalPrevious > 0) label = label + ` (${totalPrevious})`
return [
...headers,
{
id: inputBlock.id,
blockType: inputBlock.type,
blockId: inputBlock.id,
variableId: inputBlock.options.variableId,
label,
isLong: 'isLong' in inputBlock.options && inputBlock.options.isLong,
},
]
let label = matchedVariableName ?? inputBlock.groupTitle
const existingHeader = existingHeaders.find((h) => h.label === label)
if (existingHeader) {
if (
existingHeader.blocks?.some(
(block) => block.groupId === inputBlock.groupId
)
) {
const totalPrevious = existingHeaders.filter((h) =>
h.label.includes(label)
).length
const newHeaderCell: ResultHeaderCellWithBlock = {
id: inputBlock.id,
label: label + ` (${totalPrevious})`,
blocks: [
{
id: inputBlock.id,
groupId: inputBlock.groupId,
},
],
blockType: inputBlock.type,
variableIds: inputBlock.options.variableId
? [inputBlock.options.variableId]
: undefined,
}
return [...existingHeaders, newHeaderCell]
}
const updatedHeaderCell: ResultHeaderCellWithBlock = {
...existingHeader,
variableIds:
existingHeader.variableIds && inputBlock.options.variableId
? existingHeader.variableIds.concat([inputBlock.options.variableId])
: undefined,
blocks: existingHeader.blocks.concat({
id: inputBlock.id,
groupId: inputBlock.groupId,
}),
}
return [
...existingHeaders.filter(
(existingHeader) => existingHeader.label !== label
),
updatedHeaderCell,
]
}
const newHeaderCell: ResultHeaderCellWithBlock = {
id: inputBlock.id,
label,
blocks: [
{
id: inputBlock.id,
groupId: inputBlock.groupId,
},
],
blockType: inputBlock.type,
variableIds: inputBlock.options.variableId
? [inputBlock.options.variableId]
: undefined,
}
return [...existingHeaders, newHeaderCell]
}, [])
const parseVariablesHeaders = (
variables: Variable[],
blockResultHeader: ResultHeaderCell[]
existingInputResultHeaders: ResultHeaderCell[]
) =>
variables.reduce<ResultHeaderCell[]>((headers, v) => {
if (blockResultHeader.find((h) => h.variableId === v.id)) return headers
return [
...headers,
{
id: v.id,
label: v.name,
variableId: v.id,
},
]
variables.reduce<ResultHeaderCell[]>((existingHeaders, variable) => {
if (
existingInputResultHeaders.some((existingInputResultHeader) =>
existingInputResultHeader.variableIds?.includes(variable.id)
)
)
return existingHeaders
const headerCellWithSameLabel = existingHeaders.find(
(existingHeader) => existingHeader.label === variable.name
)
if (headerCellWithSameLabel) {
const updatedHeaderCell: ResultHeaderCell = {
...headerCellWithSameLabel,
variableIds: headerCellWithSameLabel.variableIds?.concat([variable.id]),
}
return [
...existingHeaders.filter((h) => h.label !== variable.name),
updatedHeaderCell,
]
}
const newHeaderCell: ResultHeaderCell = {
id: variable.id,
label: variable.name,
variableIds: [variable.id],
}
return [...existingHeaders, newHeaderCell]
}, [])
export const parseAnswers =
({ groups, variables }: { groups: Group[]; variables: Variable[] }) =>
(
typebot: Pick<Typebot, 'groups' | 'variables'>,
linkedTypebots: Pick<Typebot, 'groups' | 'variables'>[] | undefined
) =>
({
createdAt,
answers,
@ -97,7 +180,7 @@ export const parseAnswers =
}: Pick<ResultWithAnswers, 'createdAt' | 'answers' | 'variables'>): {
[key: string]: string
} => {
const header = parseResultHeader({ groups, variables })
const header = parseResultHeader(typebot, linkedTypebots)
return {
submittedAt: createdAt,
...[...answers, ...resultVariables].reduce<{
@ -106,9 +189,14 @@ export const parseAnswers =
if ('blockId' in answerOrVariable) {
const answer = answerOrVariable as Answer
const key = answer.variableId
? header.find((cell) => cell.variableId === answer.variableId)
?.label
: header.find((cell) => cell.blockId === answer.blockId)?.label
? header.find(
(cell) =>
answer.variableId &&
cell.variableIds?.includes(answer.variableId)
)?.label
: header.find((cell) =>
cell.blocks?.some((block) => block.id === answer.blockId)
)?.label
if (!key) return o
return {
...o,