fix: 🐛 Display file URL in CSV export
This commit is contained in:
@@ -6,6 +6,7 @@ import { ResultHeaderCell } from 'models'
|
|||||||
import React, { useEffect, useMemo, useRef } from 'react'
|
import React, { useEffect, useMemo, useRef } from 'react'
|
||||||
import { Hooks, useRowSelect, useTable } from 'react-table'
|
import { Hooks, useRowSelect, useTable } from 'react-table'
|
||||||
import { parseSubmissionsColumns } from 'services/typebots'
|
import { parseSubmissionsColumns } from 'services/typebots'
|
||||||
|
import { isNotDefined } from 'utils'
|
||||||
import { LoadingRows } from './LoadingRows'
|
import { LoadingRows } from './LoadingRows'
|
||||||
|
|
||||||
type SubmissionsTableProps = {
|
type SubmissionsTableProps = {
|
||||||
@@ -130,7 +131,9 @@ export const SubmissionsTable = ({
|
|||||||
}
|
}
|
||||||
{...cell.getCellProps()}
|
{...cell.getCellProps()}
|
||||||
>
|
>
|
||||||
{cell.render('Cell')}
|
{isNotDefined(cell.value)
|
||||||
|
? cell.render('Cell')
|
||||||
|
: cell.value.element ?? cell.value.plainText}
|
||||||
</chakra.td>
|
</chakra.td>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -108,7 +108,13 @@ export const SubmissionsContent = ({
|
|||||||
const csvData = new Blob(
|
const csvData = new Blob(
|
||||||
[
|
[
|
||||||
unparse({
|
unparse({
|
||||||
data: dataToUnparse,
|
data: dataToUnparse.map<{ [key: string]: string }>((data) => {
|
||||||
|
const newObject: { [key: string]: string } = {}
|
||||||
|
Object.keys(data).forEach((key) => {
|
||||||
|
newObject[key] = data[key].plainText
|
||||||
|
})
|
||||||
|
return newObject
|
||||||
|
}),
|
||||||
fields: resultHeader.map((h) => h.label),
|
fields: resultHeader.map((h) => h.label),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@@ -132,7 +138,9 @@ export const SubmissionsContent = ({
|
|||||||
return convertResultsToTableData(results, resultHeader)
|
return convertResultsToTableData(results, resultHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
const tableData: { [key: string]: string | JSX.Element }[] = useMemo(
|
const tableData: {
|
||||||
|
[key: string]: { plainText: string; element?: JSX.Element }
|
||||||
|
}[] = useMemo(
|
||||||
() =>
|
() =>
|
||||||
publishedTypebot ? convertResultsToTableData(results, resultHeader) : [],
|
publishedTypebot ? convertResultsToTableData(results, resultHeader) : [],
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
|||||||
@@ -154,11 +154,13 @@ const HeaderIcon = ({ header }: { header: ResultHeaderCell }) =>
|
|||||||
export const convertResultsToTableData = (
|
export const convertResultsToTableData = (
|
||||||
results: ResultWithAnswers[] | undefined,
|
results: ResultWithAnswers[] | undefined,
|
||||||
headerCells: ResultHeaderCell[]
|
headerCells: ResultHeaderCell[]
|
||||||
): { [key: string]: JSX.Element | string }[] =>
|
): { [key: string]: { element?: JSX.Element; plainText: string } }[] =>
|
||||||
(results ?? []).map((result) => ({
|
(results ?? []).map((result) => ({
|
||||||
'Submitted at': parseDateToReadable(result.createdAt),
|
'Submitted at': {
|
||||||
|
plainText: parseDateToReadable(result.createdAt),
|
||||||
|
},
|
||||||
...[...result.answers, ...result.variables].reduce<{
|
...[...result.answers, ...result.variables].reduce<{
|
||||||
[key: string]: JSX.Element | string
|
[key: string]: { element?: JSX.Element; plainText: string }
|
||||||
}>((o, answerOrVariable) => {
|
}>((o, answerOrVariable) => {
|
||||||
if ('groupId' in answerOrVariable) {
|
if ('groupId' in answerOrVariable) {
|
||||||
const answer = answerOrVariable as Answer
|
const answer = answerOrVariable as Answer
|
||||||
@@ -168,19 +170,28 @@ export const convertResultsToTableData = (
|
|||||||
if (!header || !header.blockId || !header.blockType) return o
|
if (!header || !header.blockId || !header.blockType) return o
|
||||||
return {
|
return {
|
||||||
...o,
|
...o,
|
||||||
[header.label]: parseContent(answer.content, header.blockType),
|
[header.label]: {
|
||||||
|
element: parseContent(answer.content, header.blockType),
|
||||||
|
plainText: answer.content,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const variable = answerOrVariable as VariableWithValue
|
const variable = answerOrVariable as VariableWithValue
|
||||||
if (isDefined(o[variable.id])) return o
|
if (isDefined(o[variable.id])) return o
|
||||||
const key = headerCells.find((h) => h.variableId === variable.id)?.label
|
const key = headerCells.find((h) => h.variableId === variable.id)?.label
|
||||||
if (!key) return o
|
if (!key) return o
|
||||||
return { ...o, [key]: variable.value }
|
return {
|
||||||
|
...o,
|
||||||
|
[key]: { plainText: variable.value },
|
||||||
|
}
|
||||||
}, {}),
|
}, {}),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const parseContent = (str: string, blockType: InputBlockType) =>
|
const parseContent = (
|
||||||
blockType === InputBlockType.FILE ? parseFileContent(str) : str
|
str: string,
|
||||||
|
blockType: InputBlockType
|
||||||
|
): JSX.Element | undefined =>
|
||||||
|
blockType === InputBlockType.FILE ? parseFileContent(str) : undefined
|
||||||
|
|
||||||
const parseFileContent = (str: string) => {
|
const parseFileContent = (str: string) => {
|
||||||
const fileNames = str.split(', ')
|
const fileNames = str.split(', ')
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import test, { expect } from '@playwright/test'
|
import test, { expect } from '@playwright/test'
|
||||||
import cuid from 'cuid'
|
import cuid from 'cuid'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import { parse } from 'papaparse'
|
||||||
import { typebotViewer } from '../services/selectorUtils'
|
import { typebotViewer } from '../services/selectorUtils'
|
||||||
import { importTypebotInDatabase } from '../services/database'
|
import { importTypebotInDatabase } from '../services/database'
|
||||||
|
import { readFileSync } from 'fs'
|
||||||
|
|
||||||
test('should work as expected', async ({ page, context }) => {
|
test('should work as expected', async ({ page, context }) => {
|
||||||
const typebotId = cuid()
|
const typebotId = cuid()
|
||||||
@@ -36,4 +38,16 @@ test('should work as expected', async ({ page, context }) => {
|
|||||||
'href',
|
'href',
|
||||||
/.+\/api\.json/
|
/.+\/api\.json/
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await page.click('[data-testid="checkbox"] >> nth=0')
|
||||||
|
const [download] = await Promise.all([
|
||||||
|
page.waitForEvent('download'),
|
||||||
|
page.locator('button:has-text("Export1")').click(),
|
||||||
|
])
|
||||||
|
const downloadPath = await download.path()
|
||||||
|
expect(path).toBeDefined()
|
||||||
|
const file = readFileSync(downloadPath as string).toString()
|
||||||
|
const { data } = parse(file)
|
||||||
|
expect(data).toHaveLength(2)
|
||||||
|
expect((data[1] as unknown[])[1]).toContain('http://localhost:9000')
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user