feat(engine): ✨ Link typebot step
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { PublicTypebot, Typebot } from 'models'
|
||||
import { Block, PublicTypebot, Typebot, Variable } from 'models'
|
||||
import shortId from 'short-uuid'
|
||||
import { HStack, Text } from '@chakra-ui/react'
|
||||
import { CalendarIcon, CodeIcon } from 'assets/icons'
|
||||
@ -18,8 +18,8 @@ export const parseTypebotToPublicTypebot = (
|
||||
theme: typebot.theme,
|
||||
variables: typebot.variables,
|
||||
customDomain: typebot.customDomain,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
})
|
||||
|
||||
export const parsePublicTypebotToTypebot = (
|
||||
@ -64,10 +64,11 @@ type HeaderCell = {
|
||||
accessor: string
|
||||
}
|
||||
|
||||
export const parseSubmissionsColumns = (
|
||||
typebot: PublicTypebot
|
||||
): HeaderCell[] => {
|
||||
const parsedBlocks = parseBlocksHeaders(typebot)
|
||||
export const parseSubmissionsColumns = (blocksAndVariables: {
|
||||
blocks: Block[]
|
||||
variables: Variable[]
|
||||
}): HeaderCell[] => {
|
||||
const parsedBlocks = parseBlocksHeaders(blocksAndVariables)
|
||||
return [
|
||||
{
|
||||
Header: (
|
||||
@ -79,13 +80,19 @@ export const parseSubmissionsColumns = (
|
||||
accessor: 'Submitted at',
|
||||
},
|
||||
...parsedBlocks,
|
||||
...parseVariablesHeaders(typebot, parsedBlocks),
|
||||
...parseVariablesHeaders(blocksAndVariables.variables, parsedBlocks),
|
||||
]
|
||||
}
|
||||
|
||||
const parseBlocksHeaders = (typebot: PublicTypebot) =>
|
||||
typebot.blocks
|
||||
.filter((block) => typebot && block.steps.some((step) => isInputStep(step)))
|
||||
const parseBlocksHeaders = ({
|
||||
blocks,
|
||||
variables,
|
||||
}: {
|
||||
blocks: Block[]
|
||||
variables: Variable[]
|
||||
}) =>
|
||||
blocks
|
||||
.filter((block) => block.steps.some((step) => isInputStep(step)))
|
||||
.reduce<HeaderCell[]>((headers, block) => {
|
||||
const inputStep = block.steps.find((step) => isInputStep(step))
|
||||
if (
|
||||
@ -94,13 +101,13 @@ const parseBlocksHeaders = (typebot: PublicTypebot) =>
|
||||
headers.find(
|
||||
(h) =>
|
||||
h.accessor ===
|
||||
typebot.variables.find(byId(inputStep.options.variableId))?.name
|
||||
variables.find(byId(inputStep.options.variableId))?.name
|
||||
)
|
||||
)
|
||||
return headers
|
||||
const matchedVariableName =
|
||||
inputStep.options.variableId &&
|
||||
typebot.variables.find(byId(inputStep.options.variableId))?.name
|
||||
variables.find(byId(inputStep.options.variableId))?.name
|
||||
return [
|
||||
...headers,
|
||||
{
|
||||
@ -123,13 +130,13 @@ const parseBlocksHeaders = (typebot: PublicTypebot) =>
|
||||
}, [])
|
||||
|
||||
const parseVariablesHeaders = (
|
||||
typebot: PublicTypebot,
|
||||
variables: Variable[],
|
||||
parsedBlocks: {
|
||||
Header: JSX.Element
|
||||
accessor: string
|
||||
}[]
|
||||
) =>
|
||||
typebot.variables.reduce<HeaderCell[]>((headers, v) => {
|
||||
variables.reduce<HeaderCell[]>((headers, v) => {
|
||||
if (parsedBlocks.find((b) => b.accessor === v.name)) return headers
|
||||
return [
|
||||
...headers,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { PublicTypebot, ResultWithAnswers, VariableWithValue } from 'models'
|
||||
import { Block, ResultWithAnswers, Variable, VariableWithValue } from 'models'
|
||||
import useSWRInfinite from 'swr/infinite'
|
||||
import { stringify } from 'qs'
|
||||
import { Answer } from 'db'
|
||||
@ -96,7 +96,7 @@ export const parseDateToReadable = (dateStr: string): string => {
|
||||
}
|
||||
|
||||
export const convertResultsToTableData =
|
||||
({ variables, blocks }: PublicTypebot) =>
|
||||
({ variables, blocks }: { variables: Variable[]; blocks: Block[] }) =>
|
||||
(results: ResultWithAnswers[] | undefined) =>
|
||||
(results ?? []).map((result) => ({
|
||||
'Submitted at': parseDateToReadable(result.createdAt),
|
||||
|
@ -56,12 +56,14 @@ export type TypebotInDashboard = Pick<
|
||||
>
|
||||
export const useTypebots = ({
|
||||
folderId,
|
||||
allFolders,
|
||||
onError,
|
||||
}: {
|
||||
folderId?: string
|
||||
allFolders?: boolean
|
||||
onError: (error: Error) => void
|
||||
}) => {
|
||||
const params = stringify({ folderId })
|
||||
const params = stringify({ folderId, allFolders })
|
||||
const { data, error, mutate } = useSWR<
|
||||
{ typebots: TypebotInDashboard[] },
|
||||
Error
|
||||
@ -229,6 +231,8 @@ const parseDefaultStepOptions = (type: StepWithOptionsType): StepOptions => {
|
||||
return defaultRedirectOptions
|
||||
case LogicStepType.CODE:
|
||||
return defaultCodeOptions
|
||||
case LogicStepType.TYPEBOT_LINK:
|
||||
return {}
|
||||
case IntegrationStepType.GOOGLE_SHEETS:
|
||||
return defaultGoogleSheetsOptions
|
||||
case IntegrationStepType.GOOGLE_ANALYTICS:
|
||||
|
@ -8,12 +8,14 @@ enum ActionType {
|
||||
Undo = 'UNDO',
|
||||
Redo = 'REDO',
|
||||
Set = 'SET',
|
||||
Flush = 'FLUSH',
|
||||
}
|
||||
|
||||
export interface Actions<T> {
|
||||
set: (newPresent: T) => void
|
||||
set: (newPresent: T | ((current: T) => T)) => void
|
||||
undo: () => void
|
||||
redo: () => void
|
||||
flush: () => void
|
||||
canUndo: boolean
|
||||
canRedo: boolean
|
||||
presentRef: React.MutableRefObject<T>
|
||||
@ -85,7 +87,7 @@ const reducer = <T>(state: State<T>, action: Action<T>) => {
|
||||
// console.log(
|
||||
// diff(
|
||||
// JSON.parse(JSON.stringify(newPresent)),
|
||||
// JSON.parse(JSON.stringify(present))
|
||||
// present ? JSON.parse(JSON.stringify(present)) : {}
|
||||
// )
|
||||
// )
|
||||
return {
|
||||
@ -94,6 +96,9 @@ const reducer = <T>(state: State<T>, action: Action<T>) => {
|
||||
future: [],
|
||||
}
|
||||
}
|
||||
|
||||
case ActionType.Flush:
|
||||
return { ...initialState, present }
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,22 +111,33 @@ const useUndo = <T>(initialPresent: T): [State<T>, Actions<T>] => {
|
||||
|
||||
const canUndo = state.past.length !== 0
|
||||
const canRedo = state.future.length !== 0
|
||||
|
||||
const undo = useCallback(() => {
|
||||
if (canUndo) {
|
||||
dispatch({ type: ActionType.Undo })
|
||||
}
|
||||
}, [canUndo])
|
||||
|
||||
const redo = useCallback(() => {
|
||||
if (canRedo) {
|
||||
dispatch({ type: ActionType.Redo })
|
||||
}
|
||||
}, [canRedo])
|
||||
const set = useCallback((newPresent: T) => {
|
||||
presentRef.current = newPresent
|
||||
dispatch({ type: ActionType.Set, newPresent })
|
||||
|
||||
const set = useCallback((newPresent: T | ((current: T) => T)) => {
|
||||
const updatedTypebot =
|
||||
'id' in newPresent
|
||||
? newPresent
|
||||
: (newPresent as (current: T) => T)(presentRef.current)
|
||||
presentRef.current = updatedTypebot
|
||||
dispatch({ type: ActionType.Set, newPresent: updatedTypebot })
|
||||
}, [])
|
||||
|
||||
return [state, { set, undo, redo, canUndo, canRedo, presentRef }]
|
||||
const flush = useCallback(() => {
|
||||
dispatch({ type: ActionType.Flush })
|
||||
}, [])
|
||||
|
||||
return [state, { set, undo, redo, flush, canUndo, canRedo, presentRef }]
|
||||
}
|
||||
|
||||
export default useUndo
|
||||
|
Reference in New Issue
Block a user