♻️ Re-organize workspace folders
This commit is contained in:
102
packages/deprecated/bot-engine/src/providers/AnswersProvider.tsx
Normal file
102
packages/deprecated/bot-engine/src/providers/AnswersProvider.tsx
Normal 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)
|
||||
@@ -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)
|
||||
197
packages/deprecated/bot-engine/src/providers/TypebotProvider.tsx
Normal file
197
packages/deprecated/bot-engine/src/providers/TypebotProvider.tsx
Normal 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)
|
||||
Reference in New Issue
Block a user