2
0

♻️ Re-organize workspace folders

This commit is contained in:
Baptiste Arnaud
2023-03-15 08:35:16 +01:00
parent 25c367901f
commit cbc8194f19
987 changed files with 2716 additions and 2770 deletions

View File

@@ -0,0 +1,102 @@
import { safeStringify } from '@/features/variables'
import {
AnswerInput,
ResultValuesInput,
Variable,
VariableWithUnknowValue,
VariableWithValue,
} from '@typebot.io/schemas'
import { createContext, ReactNode, useContext, useState } from 'react'
import { isDefined } from '@typebot.io/lib'
const answersContext = createContext<{
resultId?: string
resultValues: ResultValuesInput
addAnswer: (
existingVariables: Variable[]
) => (
answer: AnswerInput & { uploadedFiles: boolean }
) => Promise<void> | undefined
updateVariables: (variables: VariableWithUnknowValue[]) => void
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
}>({})
export const AnswersProvider = ({
children,
resultId,
onNewAnswer,
onVariablesUpdated,
}: {
resultId?: string
onNewAnswer: (
answer: AnswerInput & { uploadedFiles: boolean }
) => Promise<void> | undefined
onVariablesUpdated?: (variables: VariableWithValue[]) => void
children: ReactNode
}) => {
const [resultValues, setResultValues] = useState<ResultValuesInput>({
answers: [],
variables: [],
createdAt: new Date(),
})
const addAnswer =
(existingVariables: Variable[]) =>
(answer: AnswerInput & { uploadedFiles: boolean }) => {
if (answer.variableId)
updateVariables([
{
id: answer.variableId,
value: answer.content,
name:
existingVariables.find(
(existingVariable) => existingVariable.id === answer.variableId
)?.name ?? '',
},
])
setResultValues((resultValues) => ({
...resultValues,
answers: [...resultValues.answers, answer],
}))
return onNewAnswer && onNewAnswer(answer)
}
const updateVariables = (newVariables: VariableWithUnknowValue[]) => {
const serializedNewVariables = newVariables.map((variable) => ({
...variable,
value: safeStringify(variable.value),
}))
setResultValues((resultValues) => {
const updatedVariables = [
...resultValues.variables.filter((v) =>
serializedNewVariables.every(
(variable) => variable.id !== v.id || variable.name !== v.name
)
),
...serializedNewVariables,
].filter((variable) => isDefined(variable.value)) as VariableWithValue[]
if (onVariablesUpdated) onVariablesUpdated(updatedVariables)
return {
...resultValues,
variables: updatedVariables,
}
})
}
return (
<answersContext.Provider
value={{
resultId,
resultValues,
addAnswer,
updateVariables,
}}
>
{children}
</answersContext.Provider>
)
}
export const useAnswers = () => useContext(answersContext)

View File

@@ -0,0 +1,28 @@
import React, { createContext, ReactNode, useContext } from 'react'
const chatContext = createContext<{
scroll: () => void
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
}>({})
export const ChatProvider = ({
children,
onScroll,
}: {
children: ReactNode
onScroll: () => void
}) => {
const scroll = onScroll
return (
<chatContext.Provider
value={{
scroll,
}}
>
{children}
</chatContext.Provider>
)
}
export const useChat = () => useContext(chatContext)

View File

@@ -0,0 +1,197 @@
import { TypebotViewerProps } from '@/components/TypebotViewer'
import { safeStringify } from '@/features/variables'
import { sendEventToParent } from '@/utils/chat'
import { Log } from '@typebot.io/prisma'
import { Edge, PublicTypebot, Typebot, Variable } from '@typebot.io/schemas'
import {
createContext,
ReactNode,
useContext,
useEffect,
useState,
} from 'react'
import { isDefined } from '@typebot.io/lib'
export type LinkedTypebot = Pick<
PublicTypebot | Typebot,
'id' | 'groups' | 'variables' | 'edges'
>
export type LinkedTypebotQueue = {
typebotId: string
edgeId: string
}[]
const typebotContext = createContext<{
currentTypebotId: string
typebot: TypebotViewerProps['typebot']
linkedTypebots: LinkedTypebot[]
apiHost: string
isPreview: boolean
linkedBotQueue: LinkedTypebotQueue
isLoading: boolean
parentTypebotIds: string[]
setCurrentTypebotId: (id: string) => void
updateVariableValue: (variableId: string, value: unknown) => void
createEdge: (edge: Edge) => void
injectLinkedTypebot: (typebot: Typebot | PublicTypebot) => LinkedTypebot
pushParentTypebotId: (typebotId: string) => void
popEdgeIdFromLinkedTypebotQueue: () => void
pushEdgeIdInLinkedTypebotQueue: (bot: {
typebotId: string
edgeId: string
}) => void
onNewLog: (log: Omit<Log, 'id' | 'createdAt' | 'resultId'>) => void
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
}>({})
export const TypebotProvider = ({
children,
typebot,
apiHost,
isPreview,
isLoading,
onNewLog,
}: {
children: ReactNode
typebot: TypebotViewerProps['typebot']
apiHost: string
isLoading: boolean
isPreview: boolean
onNewLog: (log: Omit<Log, 'id' | 'createdAt' | 'resultId'>) => void
}) => {
const [localTypebot, setLocalTypebot] =
useState<TypebotViewerProps['typebot']>(typebot)
const [linkedTypebots, setLinkedTypebots] = useState<LinkedTypebot[]>([])
const [currentTypebotId, setCurrentTypebotId] = useState(typebot.typebotId)
const [linkedBotQueue, setLinkedBotQueue] = useState<LinkedTypebotQueue>([])
const [parentTypebotIds, setParentTypebotIds] = useState<string[]>([])
useEffect(() => {
setLocalTypebot((localTypebot) => ({
...localTypebot,
theme: typebot.theme,
settings: typebot.settings,
}))
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [typebot.theme, typebot.settings])
const updateVariableValue = (variableId: string, value: unknown) => {
const formattedValue = safeStringify(value)
sendEventToParent({
newVariableValue: {
name:
localTypebot.variables.find((variable) => variable.id === variableId)
?.name ?? '',
value: formattedValue ?? '',
},
})
const variable = localTypebot.variables.find((v) => v.id === variableId)
const otherVariablesWithSameName = localTypebot.variables.filter(
(v) => v.name === variable?.name && v.id !== variableId
)
const variablesToUpdate = [variable, ...otherVariablesWithSameName].filter(
isDefined
)
setLocalTypebot((typebot) => ({
...typebot,
variables: typebot.variables.map((variable) =>
variablesToUpdate.some(
(variableToUpdate) => variableToUpdate.id === variable.id
)
? { ...variable, value: formattedValue }
: variable
),
}))
}
const createEdge = (edge: Edge) => {
setLocalTypebot((typebot) => ({
...typebot,
edges: [...typebot.edges, edge],
}))
}
const injectLinkedTypebot = (typebot: Typebot | PublicTypebot) => {
const newVariables = fillVariablesWithExistingValues(
typebot.variables,
localTypebot.variables
)
const typebotToInject = {
id: 'typebotId' in typebot ? typebot.typebotId : typebot.id,
groups: typebot.groups,
edges: typebot.edges,
variables: newVariables,
}
setLinkedTypebots((typebots) => [...typebots, typebotToInject])
const updatedTypebot = {
...localTypebot,
groups: [...localTypebot.groups, ...typebotToInject.groups],
variables: [...localTypebot.variables, ...typebotToInject.variables],
edges: [...localTypebot.edges, ...typebotToInject.edges],
}
setLocalTypebot(updatedTypebot)
return typebotToInject
}
const fillVariablesWithExistingValues = (
variables: Variable[],
variablesWithValues: Variable[]
): Variable[] =>
variables.map((variable) => {
const matchedVariable = variablesWithValues.find(
(variableWithValue) => variableWithValue.name === variable.name
)
return {
...variable,
value: matchedVariable?.value ?? variable.value,
}
})
const pushParentTypebotId = (typebotId: string) => {
setParentTypebotIds((ids) => [...ids, typebotId])
}
const pushEdgeIdInLinkedTypebotQueue = (bot: {
typebotId: string
edgeId: string
}) => setLinkedBotQueue((queue) => [...queue, bot])
const popEdgeIdFromLinkedTypebotQueue = () => {
setLinkedBotQueue((queue) => queue.slice(1))
setParentTypebotIds((ids) => ids.slice(1))
setCurrentTypebotId(linkedBotQueue[0].typebotId)
}
return (
<typebotContext.Provider
value={{
typebot: localTypebot,
linkedTypebots,
apiHost,
isPreview,
updateVariableValue,
createEdge,
injectLinkedTypebot,
onNewLog,
linkedBotQueue,
isLoading,
parentTypebotIds,
pushParentTypebotId,
pushEdgeIdInLinkedTypebotQueue,
popEdgeIdFromLinkedTypebotQueue,
currentTypebotId,
setCurrentTypebotId,
}}
>
{children}
</typebotContext.Provider>
)
}
export const useTypebot = () => useContext(typebotContext)