2
0

🚸 (results) Show deleted block answers if any

Also remove useEffects in ResultsTable.
This commit is contained in:
Baptiste Arnaud
2023-02-10 15:50:25 +01:00
parent 51f76700b2
commit 3ab67902c0
5 changed files with 104 additions and 44 deletions

View File

@ -41,12 +41,17 @@ export const ResultsProvider = ({
}, },
}) })
const flatResults = useMemo(
() => data?.flatMap((d) => d.results) ?? [],
[data]
)
const resultHeader = useMemo( const resultHeader = useMemo(
() => () =>
publishedTypebot publishedTypebot
? parseResultHeader(publishedTypebot, linkedTypebots) ? parseResultHeader(publishedTypebot, linkedTypebots, flatResults)
: [], : [],
[linkedTypebots, publishedTypebot] [flatResults, linkedTypebots, publishedTypebot]
) )
const tableData = useMemo( const tableData = useMemo(
@ -64,7 +69,7 @@ export const ResultsProvider = ({
<resultsContext.Provider <resultsContext.Provider
value={{ value={{
resultsList: data, resultsList: data,
flatResults: data?.flatMap((d) => d.results) ?? [], flatResults,
hasNextPage: hasNextPage ?? true, hasNextPage: hasNextPage ?? true,
tableData, tableData,
resultHeader, resultHeader,

View File

@ -83,9 +83,9 @@ export const ColumnSettingsButton = ({
const { active, over } = event const { active, over } = event
if (active.id !== over?.id) { if (active.id !== over?.id) {
onColumnOrderChange
const oldIndex = columnOrder.indexOf(active.id as string) const oldIndex = columnOrder.indexOf(active.id as string)
const newIndex = columnOrder.indexOf(over?.id as string) const newIndex = columnOrder.indexOf(over?.id as string)
if (newIndex === -1 || oldIndex === -1) return
const newColumnOrder = arrayMove(columnOrder, oldIndex, newIndex) const newColumnOrder = arrayMove(columnOrder, oldIndex, newIndex)
onColumnOrderChange(newColumnOrder) onColumnOrderChange(newColumnOrder)
} }

View File

@ -15,12 +15,11 @@ import { LoadingRows } from './LoadingRows'
import { import {
useReactTable, useReactTable,
getCoreRowModel, getCoreRowModel,
ColumnOrderState,
ColumnDef, ColumnDef,
Updater,
} from '@tanstack/react-table' } from '@tanstack/react-table'
import { ColumnSettingsButton } from './ColumnsSettingsButton' import { ColumnSettingsButton } from './ColumnsSettingsButton'
import { useTypebot } from '@/features/editor' import { useTypebot } from '@/features/editor'
import { useDebounce } from 'use-debounce'
import { ResultsActionButtons } from './ResultsActionButtons' import { ResultsActionButtons } from './ResultsActionButtons'
import { Row } from './Row' import { Row } from './Row'
import { HeaderRow } from './HeaderRow' import { HeaderRow } from './HeaderRow'
@ -51,40 +50,53 @@ export const ResultsTable = ({
const background = useColorModeValue('white', colors.gray[900]) const background = useColorModeValue('white', colors.gray[900])
const { updateTypebot } = useTypebot() const { updateTypebot } = useTypebot()
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({}) const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({})
const [columnsVisibility, setColumnsVisibility] = useState<
Record<string, boolean>
>(preferences?.columnsVisibility || {})
const [columnsWidth, setColumnsWidth] = useState<Record<string, number>>(
preferences?.columnsWidth || {}
)
const [debouncedColumnsWidth] = useDebounce(columnsWidth, 500)
const [columnsOrder, setColumnsOrder] = useState<ColumnOrderState>([
'select',
...(preferences?.columnsOrder
? resultHeader
.map((h) => h.id)
.sort(
(a, b) =>
preferences?.columnsOrder.indexOf(a) -
preferences?.columnsOrder.indexOf(b)
)
: resultHeader.map((h) => h.id)),
'logs',
])
useEffect(() => {
updateTypebot({
resultsTablePreferences: {
columnsVisibility,
columnsOrder,
columnsWidth: debouncedColumnsWidth,
},
})
}, [columnsOrder, columnsVisibility, debouncedColumnsWidth, updateTypebot])
const bottomElement = useRef<HTMLDivElement | null>(null) const bottomElement = useRef<HTMLDivElement | null>(null)
const tableWrapper = useRef<HTMLDivElement | null>(null) const tableWrapper = useRef<HTMLDivElement | null>(null)
const {
columnsOrder = parseDefaultColumnOrder(resultHeader),
columnsVisibility = {},
columnsWidth = {},
} = preferences ?? {}
const changeColumnOrder = (newColumnOrder: string[]) => {
if (typeof newColumnOrder === 'function') return
console.log(newColumnOrder)
updateTypebot({
resultsTablePreferences: {
columnsOrder: newColumnOrder,
columnsVisibility,
columnsWidth,
},
})
}
const changeColumnVisibility = (
newColumnVisibility: Record<string, boolean>
) => {
if (typeof newColumnVisibility === 'function') return
updateTypebot({
resultsTablePreferences: {
columnsVisibility: newColumnVisibility,
columnsWidth,
columnsOrder,
},
})
}
const changeColumnSizing = (
newColumnSizing: Updater<Record<string, number>>
) => {
if (typeof newColumnSizing === 'object') return
updateTypebot({
resultsTablePreferences: {
columnsWidth: newColumnSizing(columnsWidth),
columnsVisibility,
columnsOrder,
},
})
}
const columns = React.useMemo<ColumnDef<TableData>[]>( const columns = React.useMemo<ColumnDef<TableData>[]>(
() => [ () => [
{ {
@ -160,9 +172,7 @@ export const ResultsTable = ({
getRowId: (row) => row.id.plainText, getRowId: (row) => row.id.plainText,
columnResizeMode: 'onChange', columnResizeMode: 'onChange',
onRowSelectionChange: setRowSelection, onRowSelectionChange: setRowSelection,
onColumnVisibilityChange: setColumnsVisibility, onColumnSizingChange: changeColumnSizing,
onColumnSizingChange: setColumnsWidth,
onColumnOrderChange: setColumnsOrder,
getCoreRowModel: getCoreRowModel(), getCoreRowModel: getCoreRowModel(),
}) })
@ -174,6 +184,7 @@ export const ResultsTable = ({
} }
const observer = new IntersectionObserver(handleObserver, options) const observer = new IntersectionObserver(handleObserver, options)
if (bottomElement.current) observer.observe(bottomElement.current) if (bottomElement.current) observer.observe(bottomElement.current)
return () => { return () => {
observer.disconnect() observer.disconnect()
} }
@ -202,9 +213,9 @@ export const ResultsTable = ({
<ColumnSettingsButton <ColumnSettingsButton
resultHeader={resultHeader} resultHeader={resultHeader}
columnVisibility={columnsVisibility} columnVisibility={columnsVisibility}
setColumnVisibility={setColumnsVisibility} setColumnVisibility={changeColumnVisibility}
columnOrder={columnsOrder} columnOrder={columnsOrder}
onColumnOrderChange={instance.setColumnOrder} onColumnOrderChange={changeColumnOrder}
/> />
</Flex> </Flex>
<Box <Box
@ -251,3 +262,9 @@ export const ResultsTable = ({
</Stack> </Stack>
) )
} }
const parseDefaultColumnOrder = (resultHeader: ResultHeaderCell[]) => [
'select',
...resultHeader.map((h) => h.id),
'logs',
]

View File

@ -1 +1,9 @@
export * from '@prisma/client' export * from '@prisma/client'
// Named export for enums to avoid vite barrel export bug (https://github.com/nrwl/nx/issues/13704)
export {
Plan,
WorkspaceRole,
GraphNavigation,
CollaborationType,
} from '@prisma/client'

View File

@ -7,12 +7,15 @@ import {
VariableWithValue, VariableWithValue,
Typebot, Typebot,
ResultWithAnswersInput, ResultWithAnswersInput,
ResultWithAnswers,
InputBlockType,
} from 'models' } from 'models'
import { isInputBlock, isDefined, byId } from './utils' import { isInputBlock, isDefined, byId, isNotEmpty } from './utils'
export const parseResultHeader = ( export const parseResultHeader = (
typebot: Pick<Typebot, 'groups' | 'variables'>, typebot: Pick<Typebot, 'groups' | 'variables'>,
linkedTypebots: Pick<Typebot, 'groups' | 'variables'>[] | undefined linkedTypebots: Pick<Typebot, 'groups' | 'variables'>[] | undefined,
results: ResultWithAnswers[] = []
): ResultHeaderCell[] => { ): ResultHeaderCell[] => {
const parsedGroups = [ const parsedGroups = [
...typebot.groups, ...typebot.groups,
@ -32,6 +35,7 @@ export const parseResultHeader = (
{ label: 'Submitted at', id: 'date' }, { label: 'Submitted at', id: 'date' },
...inputsResultHeader, ...inputsResultHeader,
...parseVariablesHeaders(parsedVariables, inputsResultHeader), ...parseVariablesHeaders(parsedVariables, inputsResultHeader),
...parseResultsFromPreviousBotVersions(results, inputsResultHeader),
] ]
} }
@ -168,6 +172,32 @@ const parseVariablesHeaders = (
return [...existingHeaders, newHeaderCell] return [...existingHeaders, newHeaderCell]
}, []) }, [])
const parseResultsFromPreviousBotVersions = (
results: ResultWithAnswers[],
existingInputResultHeaders: ResultHeaderCell[]
): ResultHeaderCell[] =>
results
.flatMap((result) => result.answers)
.filter(
(answer) =>
!answer.variableId &&
existingInputResultHeaders.every(
(header) => header.id !== answer.blockId
) &&
isNotEmpty(answer.content)
)
.map((answer) => ({
id: answer.blockId,
label: `Deleted block`,
blocks: [
{
id: answer.blockId,
groupId: answer.groupId,
},
],
blockType: InputBlockType.TEXT,
}))
export const parseAnswers = export const parseAnswers =
( (
typebot: Pick<Typebot, 'groups' | 'variables'>, typebot: Pick<Typebot, 'groups' | 'variables'>,