use-config.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import { useCallback, useMemo } from 'react'
  2. import produce from 'immer'
  3. import { useStoreApi } from 'reactflow'
  4. import type { ValueSelector, Var } from '../../types'
  5. import { VarType } from '../../types'
  6. import { getOperators } from '../if-else/utils'
  7. import { OrderBy } from './types'
  8. import type { Condition, Limit, ListFilterNodeType } from './types'
  9. import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
  10. import {
  11. useIsChatMode,
  12. useNodesReadOnly,
  13. useWorkflow,
  14. useWorkflowVariables,
  15. } from '@/app/components/workflow/hooks'
  16. const useConfig = (id: string, payload: ListFilterNodeType) => {
  17. const { nodesReadOnly: readOnly } = useNodesReadOnly()
  18. const isChatMode = useIsChatMode()
  19. const store = useStoreApi()
  20. const { getBeforeNodesInSameBranch } = useWorkflow()
  21. const {
  22. getNodes,
  23. } = store.getState()
  24. const currentNode = getNodes().find(n => n.id === id)
  25. const isInIteration = payload.isInIteration
  26. const iterationNode = isInIteration ? getNodes().find(n => n.id === currentNode!.parentId) : null
  27. const availableNodes = useMemo(() => {
  28. return getBeforeNodesInSameBranch(id)
  29. }, [getBeforeNodesInSameBranch, id])
  30. const { inputs, setInputs } = useNodeCrud<ListFilterNodeType>(id, payload)
  31. const { getCurrentVariableType } = useWorkflowVariables()
  32. const getType = useCallback((variable?: ValueSelector) => {
  33. const varType = getCurrentVariableType({
  34. parentNode: iterationNode,
  35. valueSelector: variable || inputs.variable || [],
  36. availableNodes,
  37. isChatMode,
  38. isConstant: false,
  39. })
  40. let itemVarType = VarType.string
  41. switch (varType) {
  42. case VarType.arrayNumber:
  43. itemVarType = VarType.number
  44. break
  45. case VarType.arrayString:
  46. itemVarType = VarType.string
  47. break
  48. case VarType.arrayFile:
  49. itemVarType = VarType.file
  50. break
  51. case VarType.arrayObject:
  52. itemVarType = VarType.object
  53. break
  54. default:
  55. itemVarType = varType
  56. }
  57. return { varType, itemVarType }
  58. }, [availableNodes, getCurrentVariableType, inputs.variable, isChatMode, iterationNode])
  59. const { varType, itemVarType } = getType()
  60. const itemVarTypeShowName = useMemo(() => {
  61. if (!inputs.variable)
  62. return '?'
  63. return [(itemVarType || VarType.string).substring(0, 1).toUpperCase(), (itemVarType || VarType.string).substring(1)].join('')
  64. }, [inputs.variable, itemVarType])
  65. const hasSubVariable = [VarType.arrayFile].includes(varType)
  66. const handleVarChanges = useCallback((variable: ValueSelector | string) => {
  67. const newInputs = produce(inputs, (draft) => {
  68. draft.variable = variable as ValueSelector
  69. const { varType, itemVarType } = getType(draft.variable)
  70. const isFileArray = varType === VarType.arrayFile
  71. draft.var_type = varType
  72. draft.item_var_type = itemVarType
  73. draft.filter_by.conditions = [{
  74. key: (isFileArray && !draft.filter_by.conditions[0]?.key) ? 'name' : '',
  75. comparison_operator: getOperators(itemVarType, isFileArray ? { key: 'name' } : undefined)[0],
  76. value: '',
  77. }]
  78. if (isFileArray && draft.order_by.enabled && !draft.order_by.key)
  79. draft.order_by.key = 'name'
  80. })
  81. setInputs(newInputs)
  82. }, [getType, inputs, setInputs])
  83. const filterVar = useCallback((varPayload: Var) => {
  84. // Don't know the item struct of VarType.arrayObject, so not support it
  85. return [VarType.arrayNumber, VarType.arrayString, VarType.arrayFile].includes(varPayload.type)
  86. }, [])
  87. const handleFilterEnabledChange = useCallback((enabled: boolean) => {
  88. const newInputs = produce(inputs, (draft) => {
  89. draft.filter_by.enabled = enabled
  90. if (enabled && !draft.filter_by.conditions)
  91. draft.filter_by.conditions = []
  92. })
  93. setInputs(newInputs)
  94. }, [hasSubVariable, inputs, setInputs])
  95. const handleFilterChange = useCallback((condition: Condition) => {
  96. const newInputs = produce(inputs, (draft) => {
  97. draft.filter_by.conditions[0] = condition
  98. })
  99. setInputs(newInputs)
  100. }, [inputs, setInputs])
  101. const handleLimitChange = useCallback((limit: Limit) => {
  102. const newInputs = produce(inputs, (draft) => {
  103. draft.limit = limit
  104. })
  105. setInputs(newInputs)
  106. }, [inputs, setInputs])
  107. const handleExtractsEnabledChange = useCallback((enabled: boolean) => {
  108. const newInputs = produce(inputs, (draft) => {
  109. draft.extract_by.enabled = enabled
  110. if (enabled)
  111. draft.extract_by.serial = '1'
  112. })
  113. setInputs(newInputs)
  114. }, [inputs, setInputs])
  115. const handleExtractsChange = useCallback((value: string) => {
  116. const newInputs = produce(inputs, (draft) => {
  117. draft.extract_by.serial = value
  118. })
  119. setInputs(newInputs)
  120. }, [inputs, setInputs])
  121. const handleOrderByEnabledChange = useCallback((enabled: boolean) => {
  122. const newInputs = produce(inputs, (draft) => {
  123. draft.order_by.enabled = enabled
  124. if (enabled) {
  125. draft.order_by.value = OrderBy.ASC
  126. if (hasSubVariable && !draft.order_by.key)
  127. draft.order_by.key = 'name'
  128. }
  129. })
  130. setInputs(newInputs)
  131. }, [hasSubVariable, inputs, setInputs])
  132. const handleOrderByKeyChange = useCallback((key: string) => {
  133. const newInputs = produce(inputs, (draft) => {
  134. draft.order_by.key = key
  135. })
  136. setInputs(newInputs)
  137. }, [inputs, setInputs])
  138. const handleOrderByTypeChange = useCallback((type: OrderBy) => {
  139. return () => {
  140. const newInputs = produce(inputs, (draft) => {
  141. draft.order_by.value = type
  142. })
  143. setInputs(newInputs)
  144. }
  145. }, [inputs, setInputs])
  146. return {
  147. readOnly,
  148. inputs,
  149. filterVar,
  150. varType,
  151. itemVarType,
  152. itemVarTypeShowName,
  153. hasSubVariable,
  154. handleVarChanges,
  155. handleFilterEnabledChange,
  156. handleFilterChange,
  157. handleLimitChange,
  158. handleOrderByEnabledChange,
  159. handleOrderByKeyChange,
  160. handleOrderByTypeChange,
  161. handleExtractsEnabledChange,
  162. handleExtractsChange,
  163. }
  164. }
  165. export default useConfig