panel.tsx 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import type { FC } from 'react'
  2. import { memo } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import useConfig from './use-config'
  5. import ApiInput from './components/api-input'
  6. import KeyValue from './components/key-value'
  7. import EditBody from './components/edit-body'
  8. import AuthorizationModal from './components/authorization'
  9. import type { HttpNodeType } from './types'
  10. import Timeout from './components/timeout'
  11. import CurlPanel from './components/curl-panel'
  12. import cn from '@/utils/classnames'
  13. import Field from '@/app/components/workflow/nodes/_base/components/field'
  14. import Split from '@/app/components/workflow/nodes/_base/components/split'
  15. import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars'
  16. import { Settings01 } from '@/app/components/base/icons/src/vender/line/general'
  17. import { FileArrow01 } from '@/app/components/base/icons/src/vender/line/files'
  18. import type { NodePanelProps } from '@/app/components/workflow/types'
  19. import BeforeRunForm from '@/app/components/workflow/nodes/_base/components/before-run-form'
  20. import ResultPanel from '@/app/components/workflow/run/result-panel'
  21. import { useRetryDetailShowInSingleRun } from '@/app/components/workflow/nodes/_base/components/retry/hooks'
  22. const i18nPrefix = 'workflow.nodes.http'
  23. const Panel: FC<NodePanelProps<HttpNodeType>> = ({
  24. id,
  25. data,
  26. }) => {
  27. const { t } = useTranslation()
  28. const {
  29. readOnly,
  30. isDataReady,
  31. inputs,
  32. handleMethodChange,
  33. handleUrlChange,
  34. headers,
  35. setHeaders,
  36. addHeader,
  37. params,
  38. setParams,
  39. addParam,
  40. setBody,
  41. isShowAuthorization,
  42. showAuthorization,
  43. hideAuthorization,
  44. setAuthorization,
  45. setTimeout,
  46. // single run
  47. isShowSingleRun,
  48. hideSingleRun,
  49. runningStatus,
  50. handleRun,
  51. handleStop,
  52. varInputs,
  53. inputVarValues,
  54. setInputVarValues,
  55. runResult,
  56. isShowCurlPanel,
  57. showCurlPanel,
  58. hideCurlPanel,
  59. handleCurlImport,
  60. } = useConfig(id, data)
  61. const {
  62. retryDetails,
  63. handleRetryDetailsChange,
  64. } = useRetryDetailShowInSingleRun()
  65. // To prevent prompt editor in body not update data.
  66. if (!isDataReady)
  67. return null
  68. return (
  69. <div className='pt-2'>
  70. <div className='px-4 pb-4 space-y-4'>
  71. <Field
  72. title={t(`${i18nPrefix}.api`)}
  73. operations={
  74. <div className='flex'>
  75. <div
  76. onClick={showAuthorization}
  77. className={cn(!readOnly && 'cursor-pointer hover:bg-gray-50', 'flex items-center h-6 space-x-1 px-2 rounded-md ')}
  78. >
  79. {!readOnly && <Settings01 className='w-3 h-3 text-gray-500' />}
  80. <div className='text-xs font-medium text-gray-500'>
  81. {t(`${i18nPrefix}.authorization.authorization`)}
  82. <span className='ml-1 text-gray-700'>{t(`${i18nPrefix}.authorization.${inputs.authorization.type}`)}</span>
  83. </div>
  84. </div>
  85. <div
  86. onClick={showCurlPanel}
  87. className={cn(!readOnly && 'cursor-pointer hover:bg-gray-50', 'flex items-center h-6 space-x-1 px-2 rounded-md ')}
  88. >
  89. {!readOnly && <FileArrow01 className='w-3 h-3 text-gray-500' />}
  90. <div className='text-xs font-medium text-gray-500'>
  91. {t(`${i18nPrefix}.curl.title`)}
  92. </div>
  93. </div>
  94. </div>
  95. }
  96. >
  97. <ApiInput
  98. nodeId={id}
  99. readonly={readOnly}
  100. method={inputs.method}
  101. onMethodChange={handleMethodChange}
  102. url={inputs.url}
  103. onUrlChange={handleUrlChange}
  104. />
  105. </Field>
  106. <Field
  107. title={t(`${i18nPrefix}.headers`)}
  108. >
  109. <KeyValue
  110. nodeId={id}
  111. list={headers}
  112. onChange={setHeaders}
  113. onAdd={addHeader}
  114. readonly={readOnly}
  115. />
  116. </Field>
  117. <Field
  118. title={t(`${i18nPrefix}.params`)}
  119. >
  120. <KeyValue
  121. nodeId={id}
  122. list={params}
  123. onChange={setParams}
  124. onAdd={addParam}
  125. readonly={readOnly}
  126. />
  127. </Field>
  128. <Field
  129. title={t(`${i18nPrefix}.body`)}
  130. >
  131. <EditBody
  132. nodeId={id}
  133. readonly={readOnly}
  134. payload={inputs.body}
  135. onChange={setBody}
  136. />
  137. </Field>
  138. </div>
  139. <Split />
  140. <Timeout
  141. nodeId={id}
  142. readonly={readOnly}
  143. payload={inputs.timeout}
  144. onChange={setTimeout}
  145. />
  146. {(isShowAuthorization && !readOnly) && (
  147. <AuthorizationModal
  148. nodeId={id}
  149. isShow
  150. onHide={hideAuthorization}
  151. payload={inputs.authorization}
  152. onChange={setAuthorization}
  153. />
  154. )}
  155. <Split />
  156. <div className=''>
  157. <OutputVars>
  158. <>
  159. <VarItem
  160. name='body'
  161. type='string'
  162. description={t(`${i18nPrefix}.outputVars.body`)}
  163. />
  164. <VarItem
  165. name='status_code'
  166. type='number'
  167. description={t(`${i18nPrefix}.outputVars.statusCode`)}
  168. />
  169. <VarItem
  170. name='headers'
  171. type='object'
  172. description={t(`${i18nPrefix}.outputVars.headers`)}
  173. />
  174. <VarItem
  175. name='files'
  176. type='Array[File]'
  177. description={t(`${i18nPrefix}.outputVars.files`)}
  178. />
  179. </>
  180. </OutputVars>
  181. </div>
  182. {isShowSingleRun && (
  183. <BeforeRunForm
  184. nodeName={inputs.title}
  185. nodeType={inputs.type}
  186. onHide={hideSingleRun}
  187. forms={[
  188. {
  189. inputs: varInputs,
  190. values: inputVarValues,
  191. onChange: setInputVarValues,
  192. },
  193. ]}
  194. runningStatus={runningStatus}
  195. onRun={handleRun}
  196. onStop={handleStop}
  197. retryDetails={retryDetails}
  198. onRetryDetailBack={handleRetryDetailsChange}
  199. result={<ResultPanel {...runResult} showSteps={false} onShowRetryDetail={handleRetryDetailsChange} />}
  200. />
  201. )}
  202. {(isShowCurlPanel && !readOnly) && (
  203. <CurlPanel
  204. nodeId={id}
  205. isShow
  206. onHide={hideCurlPanel}
  207. handleCurlImport={handleCurlImport}
  208. />
  209. )}
  210. </div>
  211. )
  212. }
  213. export default memo(Panel)