result-panel.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. 'use client'
  2. import type { FC } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import {
  5. RiArrowRightSLine,
  6. RiRestartFill,
  7. } from '@remixicon/react'
  8. import StatusPanel from './status'
  9. import MetaData from './meta'
  10. import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
  11. import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
  12. import ErrorHandleTip from '@/app/components/workflow/nodes/_base/components/error-handle/error-handle-tip'
  13. import type { NodeTracing } from '@/types/workflow'
  14. import Button from '@/app/components/base/button'
  15. type ResultPanelProps = {
  16. inputs?: string
  17. process_data?: string
  18. outputs?: string
  19. status: string
  20. error?: string
  21. elapsed_time?: number
  22. total_tokens?: number
  23. created_at?: number
  24. created_by?: string
  25. finished_at?: number
  26. steps?: number
  27. showSteps?: boolean
  28. exceptionCounts?: number
  29. execution_metadata?: any
  30. retry_events?: NodeTracing[]
  31. onShowRetryDetail?: (retries: NodeTracing[]) => void
  32. }
  33. const ResultPanel: FC<ResultPanelProps> = ({
  34. inputs,
  35. process_data,
  36. outputs,
  37. status,
  38. error,
  39. elapsed_time,
  40. total_tokens,
  41. created_at,
  42. created_by,
  43. steps,
  44. showSteps,
  45. exceptionCounts,
  46. execution_metadata,
  47. retry_events,
  48. onShowRetryDetail,
  49. }) => {
  50. const { t } = useTranslation()
  51. return (
  52. <div className='bg-components-panel-bg py-2'>
  53. <div className='px-4 py-2'>
  54. <StatusPanel
  55. status={status}
  56. time={elapsed_time}
  57. tokens={total_tokens}
  58. error={error}
  59. exceptionCounts={exceptionCounts}
  60. />
  61. </div>
  62. {
  63. retry_events?.length && onShowRetryDetail && (
  64. <div className='px-4'>
  65. <Button
  66. className='flex items-center justify-between w-full'
  67. variant='tertiary'
  68. onClick={() => onShowRetryDetail(retry_events)}
  69. >
  70. <div className='flex items-center'>
  71. <RiRestartFill className='mr-0.5 w-4 h-4 text-components-button-tertiary-text flex-shrink-0' />
  72. {t('workflow.nodes.common.retry.retries', { num: retry_events?.length })}
  73. </div>
  74. <RiArrowRightSLine className='w-4 h-4 text-components-button-tertiary-text flex-shrink-0' />
  75. </Button>
  76. </div>
  77. )
  78. }
  79. <div className='px-4 py-2 flex flex-col gap-2'>
  80. <CodeEditor
  81. readOnly
  82. title={<div>{t('workflow.common.input').toLocaleUpperCase()}</div>}
  83. language={CodeLanguage.json}
  84. value={inputs}
  85. isJSONStringifyBeauty
  86. />
  87. {process_data && (
  88. <CodeEditor
  89. readOnly
  90. title={<div>{t('workflow.common.processData').toLocaleUpperCase()}</div>}
  91. language={CodeLanguage.json}
  92. value={process_data}
  93. isJSONStringifyBeauty
  94. />
  95. )}
  96. {(outputs || status === 'running') && (
  97. <CodeEditor
  98. readOnly
  99. title={<div>{t('workflow.common.output').toLocaleUpperCase()}</div>}
  100. language={CodeLanguage.json}
  101. value={outputs}
  102. isJSONStringifyBeauty
  103. tip={<ErrorHandleTip type={execution_metadata?.error_strategy} />}
  104. />
  105. )}
  106. </div>
  107. <div className='px-4 py-2'>
  108. <div className='h-[0.5px] divider-subtle' />
  109. </div>
  110. <div className='px-4 py-2'>
  111. <MetaData
  112. status={status}
  113. executor={created_by}
  114. startTime={created_at}
  115. time={elapsed_time}
  116. tokens={total_tokens}
  117. steps={steps}
  118. showSteps={showSteps}
  119. />
  120. </div>
  121. </div>
  122. )
  123. }
  124. export default ResultPanel