refactor(graph): ♻️ Add Edges table in Typebot
This commit is contained in:
@@ -4,7 +4,7 @@ import { TransitionGroup, CSSTransition } from 'react-transition-group'
|
||||
import { ChatStep } from './ChatStep'
|
||||
import { AvatarSideContainer } from './AvatarSideContainer'
|
||||
import { HostAvatarsContext } from '../../contexts/HostAvatarsContext'
|
||||
import { Step, Target } from 'models'
|
||||
import { Edge, Step, Target } from 'models'
|
||||
import { useTypebot } from '../../contexts/TypebotContext'
|
||||
import {
|
||||
isChoiceInput,
|
||||
@@ -20,7 +20,7 @@ import { executeIntegration } from 'services/integration'
|
||||
type ChatBlockProps = {
|
||||
stepIds: string[]
|
||||
startStepId?: string
|
||||
onBlockEnd: (target?: Target) => void
|
||||
onBlockEnd: (edgeId?: string) => void
|
||||
}
|
||||
|
||||
export const ChatBlock = ({
|
||||
@@ -46,20 +46,20 @@ export const ChatBlock = ({
|
||||
const currentStep = [...displayedSteps].pop()
|
||||
if (!currentStep) return
|
||||
if (isLogicStep(currentStep)) {
|
||||
const target = executeLogic(
|
||||
const nextEdgeId = executeLogic(
|
||||
currentStep,
|
||||
typebot.variables,
|
||||
updateVariableValue
|
||||
)
|
||||
target ? onBlockEnd(target) : displayNextStep()
|
||||
nextEdgeId ? onBlockEnd(nextEdgeId) : displayNextStep()
|
||||
}
|
||||
if (isIntegrationStep(currentStep)) {
|
||||
const target = await executeIntegration(
|
||||
const nextEdgeId = await executeIntegration(
|
||||
currentStep,
|
||||
typebot.variables,
|
||||
updateVariableValue
|
||||
)
|
||||
target ? onBlockEnd(target) : displayNextStep()
|
||||
nextEdgeId ? onBlockEnd(nextEdgeId) : displayNextStep()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,11 +90,8 @@ export const ChatBlock = ({
|
||||
answerContent
|
||||
)
|
||||
)
|
||||
if (
|
||||
currentStep?.target?.blockId ||
|
||||
displayedSteps.length === stepIds.length
|
||||
)
|
||||
return onBlockEnd(currentStep?.target)
|
||||
if (currentStep?.edgeId || displayedSteps.length === stepIds.length)
|
||||
return onBlockEnd(currentStep.edgeId)
|
||||
}
|
||||
const nextStep = typebot.steps.byId[stepIds[displayedSteps.length]]
|
||||
if (nextStep) setDisplayedSteps([...displayedSteps, nextStep])
|
||||
|
||||
@@ -5,11 +5,11 @@ import { useFrame } from 'react-frame-component'
|
||||
import { setCssVariablesValue } from '../services/theme'
|
||||
import { useAnswers } from '../contexts/AnswersContext'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { Answer, Block, PublicTypebot, Target } from 'models'
|
||||
import { Answer, Block, Edge, PublicTypebot } from 'models'
|
||||
|
||||
type Props = {
|
||||
typebot: PublicTypebot
|
||||
onNewBlockVisible: (blockId: string) => void
|
||||
onNewBlockVisible: (edgeId: string) => void
|
||||
onNewAnswer: (answer: Answer) => void
|
||||
onCompleted: () => void
|
||||
}
|
||||
@@ -27,22 +27,24 @@ export const ConversationContainer = ({
|
||||
const { answers } = useAnswers()
|
||||
const bottomAnchor = useRef<HTMLDivElement | null>(null)
|
||||
|
||||
const displayNextBlock = (target?: Target) => {
|
||||
if (!target) return onCompleted()
|
||||
const displayNextBlock = (edgeId?: string) => {
|
||||
const edge = typebot.edges.byId[edgeId ?? '']
|
||||
if (!edge) return onCompleted()
|
||||
const nextBlock = {
|
||||
block: typebot.blocks.byId[target.blockId],
|
||||
startStepId: target.stepId,
|
||||
block: typebot.blocks.byId[edge.to.blockId],
|
||||
startStepId: edge.to.stepId,
|
||||
}
|
||||
if (!nextBlock) return onCompleted()
|
||||
onNewBlockVisible(target.blockId)
|
||||
onNewBlockVisible(edge.id)
|
||||
setDisplayedBlocks([...displayedBlocks, nextBlock])
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const blocks = typebot.blocks
|
||||
const firstTarget =
|
||||
typebot.steps.byId[blocks.byId[blocks.allIds[0]].stepIds[0]].target
|
||||
if (firstTarget) displayNextBlock(firstTarget)
|
||||
const firstEdgeId =
|
||||
typebot.steps.byId[blocks.byId[blocks.allIds[0]].stepIds[0]].edgeId
|
||||
if (!firstEdgeId) return
|
||||
displayNextBlock(firstEdgeId)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Answer, BackgroundType, PublicTypebot } from 'models'
|
||||
|
||||
export type TypebotViewerProps = {
|
||||
typebot: PublicTypebot
|
||||
onNewBlockVisible?: (blockId: string) => void
|
||||
onNewBlockVisible?: (edgeId: string) => void
|
||||
onNewAnswer?: (answer: Answer) => void
|
||||
onCompleted?: () => void
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ export const getSingleChoiceTargetId = (
|
||||
currentStep: ChoiceInputStep,
|
||||
choiceItems: Table<ChoiceItem>,
|
||||
answerContent?: string
|
||||
): Target | undefined => {
|
||||
): string | undefined => {
|
||||
const itemId = currentStep.options.itemIds.find(
|
||||
(itemId) => choiceItems.byId[itemId].content === answerContent
|
||||
)
|
||||
if (!itemId) throw new Error('itemId should exist')
|
||||
return choiceItems.byId[itemId].target ?? currentStep.target
|
||||
return choiceItems.byId[itemId].edgeId ?? currentStep.edgeId
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ const executeGoogleSheetIntegration = async (
|
||||
variables: Table<Variable>,
|
||||
updateVariableValue: (variableId: string, value: string) => void
|
||||
) => {
|
||||
if (!step.options) return step.target
|
||||
if (!step.options) return step.edgeId
|
||||
switch (step.options?.action) {
|
||||
case GoogleSheetsAction.INSERT_ROW:
|
||||
await insertRowInGoogleSheets(step.options, variables)
|
||||
@@ -56,7 +56,7 @@ const executeGoogleSheetIntegration = async (
|
||||
await getRowFromGoogleSheets(step.options, variables, updateVariableValue)
|
||||
break
|
||||
}
|
||||
return step.target
|
||||
return step.edgeId
|
||||
}
|
||||
|
||||
const insertRowInGoogleSheets = async (
|
||||
|
||||
@@ -15,7 +15,7 @@ export const executeLogic = (
|
||||
step: LogicStep,
|
||||
variables: Table<Variable>,
|
||||
updateVariableValue: (variableId: string, expression: string) => void
|
||||
): Target | undefined => {
|
||||
): string | undefined => {
|
||||
switch (step.type) {
|
||||
case LogicStepType.SET_VARIABLE: {
|
||||
if (!step.options?.variableId || !step.options.expressionToEvaluate)
|
||||
@@ -36,7 +36,7 @@ export const executeLogic = (
|
||||
: step.options?.comparisons.allIds.some(
|
||||
executeComparison(step, variables)
|
||||
)
|
||||
return isConditionPassed ? step.trueTarget : step.falseTarget
|
||||
return isConditionPassed ? step.trueEdgeId : step.falseEdgeId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ model Typebot {
|
||||
steps Json
|
||||
choiceItems Json
|
||||
variables Json
|
||||
edges Json
|
||||
theme Json
|
||||
settings Json
|
||||
publicId String? @unique
|
||||
@@ -124,6 +125,7 @@ model PublicTypebot {
|
||||
steps Json
|
||||
choiceItems Json
|
||||
variables Json
|
||||
edges Json
|
||||
theme Json
|
||||
settings Json
|
||||
publicId String? @unique
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PublicTypebot as PublicTypebotFromPrisma } from 'db'
|
||||
import { Block, ChoiceItem, Settings, Step, Theme } from './typebot'
|
||||
import { Block, ChoiceItem, Edge, Settings, Step, Theme } from './typebot'
|
||||
import { Variable } from './typebot/variable'
|
||||
import { Table } from './utils'
|
||||
|
||||
@@ -17,6 +17,7 @@ export type PublicTypebot = Omit<
|
||||
steps: Table<Step>
|
||||
choiceItems: Table<ChoiceItem>
|
||||
variables: Table<Variable>
|
||||
edges: Table<Edge>
|
||||
theme: Theme
|
||||
settings: Settings
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Target } from '.'
|
||||
import { StepBase } from './steps'
|
||||
|
||||
export type InputStep =
|
||||
@@ -66,7 +65,7 @@ export type ChoiceItem = {
|
||||
id: string
|
||||
stepId: string
|
||||
content?: string
|
||||
target?: Target
|
||||
edgeId?: string
|
||||
}
|
||||
|
||||
type OptionBase = { variableId?: string }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { StepBase, Target } from '.'
|
||||
import { StepBase } from '.'
|
||||
import { Table } from '../..'
|
||||
|
||||
export type LogicStep = SetVariableStep | ConditionStep
|
||||
@@ -32,8 +32,8 @@ export enum ComparisonOperators {
|
||||
export type ConditionStep = StepBase & {
|
||||
type: LogicStepType.CONDITION
|
||||
options: ConditionOptions
|
||||
trueTarget?: Target
|
||||
falseTarget?: Target
|
||||
trueEdgeId?: string
|
||||
falseEdgeId?: string
|
||||
}
|
||||
|
||||
export type ConditionOptions = {
|
||||
|
||||
@@ -36,11 +36,9 @@ export type StepOptions =
|
||||
| LogicStepOptions
|
||||
| IntegrationStepOptions
|
||||
|
||||
export type StepBase = { id: string; blockId: string; target?: Target }
|
||||
export type StepBase = { id: string; blockId: string; edgeId?: string }
|
||||
|
||||
export type StartStep = StepBase & {
|
||||
type: 'start'
|
||||
label: string
|
||||
}
|
||||
|
||||
export type Target = { blockId: string; stepId?: string }
|
||||
|
||||
@@ -14,6 +14,7 @@ export type Typebot = Omit<
|
||||
steps: Table<Step>
|
||||
choiceItems: Table<ChoiceItem>
|
||||
variables: Table<Variable>
|
||||
edges: Table<Edge>
|
||||
theme: Theme
|
||||
settings: Settings
|
||||
}
|
||||
@@ -27,3 +28,16 @@ export type Block = {
|
||||
}
|
||||
stepIds: string[]
|
||||
}
|
||||
|
||||
export type Source = {
|
||||
blockId: string
|
||||
stepId: string
|
||||
nodeId?: string
|
||||
conditionType?: 'true' | 'false'
|
||||
}
|
||||
export type Target = { blockId: string; stepId?: string }
|
||||
export type Edge = {
|
||||
id: string
|
||||
from: Source
|
||||
to: Target
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user