Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

panel.tsx 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import type { FC } from 'react'
  2. import React, { useMemo } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import { RiAddLine } from '@remixicon/react'
  5. import Split from '../_base/components/split'
  6. import ResultPanel from '../../run/result-panel'
  7. import InputNumberWithSlider from '../_base/components/input-number-with-slider'
  8. import type { LoopNodeType } from './types'
  9. import useConfig from './use-config'
  10. import ConditionWrap from './components/condition-wrap'
  11. import LoopVariable from './components/loop-variables'
  12. import type { NodePanelProps } from '@/app/components/workflow/types'
  13. import Field from '@/app/components/workflow/nodes/_base/components/field'
  14. import BeforeRunForm from '@/app/components/workflow/nodes/_base/components/before-run-form'
  15. import formatTracing from '@/app/components/workflow/run/utils/format-log'
  16. import { useLogs } from '@/app/components/workflow/run/hooks'
  17. import { LOOP_NODE_MAX_COUNT } from '@/config'
  18. const i18nPrefix = 'workflow.nodes.loop'
  19. const Panel: FC<NodePanelProps<LoopNodeType>> = ({
  20. id,
  21. data,
  22. }) => {
  23. const { t } = useTranslation()
  24. const {
  25. readOnly,
  26. inputs,
  27. childrenNodeVars,
  28. loopChildrenNodes,
  29. isShowSingleRun,
  30. hideSingleRun,
  31. runningStatus,
  32. handleRun,
  33. handleStop,
  34. runResult,
  35. loopRunResult,
  36. handleAddCondition,
  37. handleUpdateCondition,
  38. handleRemoveCondition,
  39. handleToggleConditionLogicalOperator,
  40. handleAddSubVariableCondition,
  41. handleRemoveSubVariableCondition,
  42. handleUpdateSubVariableCondition,
  43. handleToggleSubVariableConditionLogicalOperator,
  44. handleUpdateLoopCount,
  45. handleAddLoopVariable,
  46. handleRemoveLoopVariable,
  47. handleUpdateLoopVariable,
  48. } = useConfig(id, data)
  49. const nodeInfo = useMemo(() => {
  50. const formattedNodeInfo = formatTracing(loopRunResult, t)[0]
  51. if (runResult && formattedNodeInfo) {
  52. return {
  53. ...formattedNodeInfo,
  54. execution_metadata: {
  55. ...runResult.execution_metadata,
  56. ...formattedNodeInfo.execution_metadata,
  57. },
  58. }
  59. }
  60. return formattedNodeInfo
  61. }, [runResult, loopRunResult, t])
  62. const logsParams = useLogs()
  63. return (
  64. <div className='mt-2'>
  65. <div>
  66. <Field
  67. title={<div className='pl-3'>{t('workflow.nodes.loop.loopVariables')}</div>}
  68. operations={
  69. <div
  70. className='mr-4 flex h-5 w-5 cursor-pointer items-center justify-center'
  71. onClick={handleAddLoopVariable}
  72. >
  73. <RiAddLine className='h-4 w-4 text-text-tertiary' />
  74. </div>
  75. }
  76. >
  77. <div className='px-4'>
  78. <LoopVariable
  79. variables={inputs.loop_variables}
  80. nodeId={id}
  81. handleRemoveLoopVariable={handleRemoveLoopVariable}
  82. handleUpdateLoopVariable={handleUpdateLoopVariable}
  83. />
  84. </div>
  85. </Field>
  86. <Split className='my-2' />
  87. <Field
  88. title={<div className='pl-3'>{t(`${i18nPrefix}.breakCondition`)}</div>}
  89. tooltip={t(`${i18nPrefix}.breakConditionTip`)}
  90. >
  91. <ConditionWrap
  92. nodeId={id}
  93. readOnly={readOnly}
  94. handleAddCondition={handleAddCondition}
  95. handleRemoveCondition={handleRemoveCondition}
  96. handleUpdateCondition={handleUpdateCondition}
  97. handleToggleConditionLogicalOperator={handleToggleConditionLogicalOperator}
  98. handleAddSubVariableCondition={handleAddSubVariableCondition}
  99. handleRemoveSubVariableCondition={handleRemoveSubVariableCondition}
  100. handleUpdateSubVariableCondition={handleUpdateSubVariableCondition}
  101. handleToggleSubVariableConditionLogicalOperator={handleToggleSubVariableConditionLogicalOperator}
  102. availableNodes={loopChildrenNodes}
  103. availableVars={childrenNodeVars}
  104. conditions={inputs.break_conditions || []}
  105. logicalOperator={inputs.logical_operator!}
  106. />
  107. </Field>
  108. <Split className='mt-2' />
  109. <div className='mt-2'>
  110. <Field
  111. title={<div className='pl-3'>{t(`${i18nPrefix}.loopMaxCount`)}</div>}
  112. >
  113. <div className='px-3 py-2'>
  114. <InputNumberWithSlider
  115. min={1}
  116. max={LOOP_NODE_MAX_COUNT}
  117. value={inputs.loop_count}
  118. onChange={(val) => {
  119. const roundedVal = Math.round(val)
  120. handleUpdateLoopCount(Number.isNaN(roundedVal) ? 1 : roundedVal)
  121. }}
  122. />
  123. </div>
  124. </Field>
  125. </div>
  126. </div>
  127. {/* Error handling for the Loop node is currently not considered. */}
  128. {/* <div className='px-4 py-2'>
  129. <Field title={t(`${i18nPrefix}.errorResponseMethod`)} >
  130. <Select items={responseMethod} defaultValue={inputs.error_handle_mode} onSelect={changeErrorResponseMode} allowSearch={false}>
  131. </Select>
  132. </Field>
  133. </div> */}
  134. {isShowSingleRun && (
  135. <BeforeRunForm
  136. nodeName={inputs.title}
  137. onHide={hideSingleRun}
  138. forms={[]}
  139. runningStatus={runningStatus}
  140. onRun={handleRun}
  141. onStop={handleStop}
  142. {...logsParams}
  143. result={
  144. <ResultPanel {...runResult} showSteps={false} nodeInfo={nodeInfo} {...logsParams} />
  145. }
  146. />
  147. )}
  148. </div>
  149. )
  150. }
  151. export default React.memo(Panel)