File size: 4,925 Bytes
a8b3f00
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import { useCallback, useMemo } from 'react'
import produce from 'immer'
import { useStoreApi } from 'reactflow'
import { isEqual } from 'lodash-es'
import { VarType } from '../../types'
import type { ValueSelector, Var } from '../../types'
import { type AssignerNodeType, WriteMode } from './types'
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
import {
  useIsChatMode,
  useNodesReadOnly,
  useWorkflow,
  useWorkflowVariables,
} from '@/app/components/workflow/hooks'

const useConfig = (id: string, payload: AssignerNodeType) => {
  const { nodesReadOnly: readOnly } = useNodesReadOnly()
  const isChatMode = useIsChatMode()

  const store = useStoreApi()
  const { getBeforeNodesInSameBranch } = useWorkflow()

  const {
    getNodes,
  } = store.getState()
  const currentNode = getNodes().find(n => n.id === id)
  const isInIteration = payload.isInIteration
  const iterationNode = isInIteration ? getNodes().find(n => n.id === currentNode!.parentId) : null
  const availableNodes = useMemo(() => {
    return getBeforeNodesInSameBranch(id)
  }, [getBeforeNodesInSameBranch, id])
  const { inputs, setInputs } = useNodeCrud<AssignerNodeType>(id, payload)

  const { getCurrentVariableType } = useWorkflowVariables()
  const assignedVarType = getCurrentVariableType({
    parentNode: iterationNode,
    valueSelector: inputs.assigned_variable_selector || [],
    availableNodes,
    isChatMode,
    isConstant: false,
  })

  const isSupportAppend = useCallback((varType: VarType) => {
    return [VarType.arrayString, VarType.arrayNumber, VarType.arrayObject].includes(varType)
  }, [])

  const isCurrSupportAppend = useMemo(() => isSupportAppend(assignedVarType), [assignedVarType, isSupportAppend])

  const handleAssignedVarChanges = useCallback((variable: ValueSelector | string) => {
    const newInputs = produce(inputs, (draft) => {
      draft.assigned_variable_selector = variable as ValueSelector
      draft.input_variable_selector = []

      const newVarType = getCurrentVariableType({
        parentNode: iterationNode,
        valueSelector: draft.assigned_variable_selector || [],
        availableNodes,
        isChatMode,
        isConstant: false,
      })

      if (inputs.write_mode === WriteMode.Append && !isSupportAppend(newVarType))
        draft.write_mode = WriteMode.Overwrite
    })
    setInputs(newInputs)
  }, [inputs, setInputs, getCurrentVariableType, iterationNode, availableNodes, isChatMode, isSupportAppend])

  const writeModeTypes = [WriteMode.Overwrite, WriteMode.Append, WriteMode.Clear]

  const handleWriteModeChange = useCallback((writeMode: WriteMode) => {
    return () => {
      const newInputs = produce(inputs, (draft) => {
        draft.write_mode = writeMode
        if (inputs.write_mode === WriteMode.Clear)
          draft.input_variable_selector = []
      })
      setInputs(newInputs)
    }
  }, [inputs, setInputs])

  const toAssignedVarType = useMemo(() => {
    const { write_mode } = inputs
    if (write_mode === WriteMode.Overwrite)
      return assignedVarType
    if (write_mode === WriteMode.Append) {
      if (assignedVarType === VarType.arrayString)
        return VarType.string
      if (assignedVarType === VarType.arrayNumber)
        return VarType.number
      if (assignedVarType === VarType.arrayObject)
        return VarType.object
    }
    return VarType.string
  }, [assignedVarType, inputs])

  const filterAssignedVar = useCallback((varPayload: Var, selector: ValueSelector) => {
    return selector.join('.').startsWith('conversation')
  }, [])

  const filterToAssignedVar = useCallback((varPayload: Var, selector: ValueSelector) => {
    if (isEqual(selector, inputs.assigned_variable_selector))
      return false

    if (inputs.write_mode === WriteMode.Overwrite) {
      return varPayload.type === assignedVarType
    }
    else if (inputs.write_mode === WriteMode.Append) {
      switch (assignedVarType) {
        case VarType.arrayString:
          return varPayload.type === VarType.string
        case VarType.arrayNumber:
          return varPayload.type === VarType.number
        case VarType.arrayObject:
          return varPayload.type === VarType.object
        default:
          return false
      }
    }
    return true
  }, [inputs.assigned_variable_selector, inputs.write_mode, assignedVarType])

  const handleToAssignedVarChange = useCallback((value: ValueSelector | string) => {
    const newInputs = produce(inputs, (draft) => {
      draft.input_variable_selector = value as ValueSelector
    })
    setInputs(newInputs)
  }, [inputs, setInputs])

  return {
    readOnly,
    inputs,
    handleAssignedVarChanges,
    assignedVarType,
    isSupportAppend: isCurrSupportAppend,
    writeModeTypes,
    handleWriteModeChange,
    filterAssignedVar,
    filterToAssignedVar,
    handleToAssignedVarChange,
    toAssignedVarType,
  }
}

export default useConfig