run-and-history.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import type { FC } from 'react'
  2. import { memo } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import {
  5. RiLoader2Line,
  6. RiPlayLargeLine,
  7. } from '@remixicon/react'
  8. import { useStore } from '../store'
  9. import {
  10. useIsChatMode,
  11. useNodesReadOnly,
  12. useWorkflowRun,
  13. useWorkflowStartRun,
  14. } from '../hooks'
  15. import { WorkflowRunningStatus } from '../types'
  16. import ViewHistory from './view-history'
  17. import Checklist from './checklist'
  18. import cn from '@/utils/classnames'
  19. import {
  20. StopCircle,
  21. } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
  22. import { useAppDetailContext } from '@/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main'
  23. const RunMode = memo(() => {
  24. const { t } = useTranslation()
  25. const { handleWorkflowStartRunInWorkflow } = useWorkflowStartRun()
  26. const { handleStopRun } = useWorkflowRun()
  27. const workflowRunningData = useStore(s => s.workflowRunningData)
  28. const isRunning = workflowRunningData?.result.status === WorkflowRunningStatus.Running
  29. return (
  30. <>
  31. <div
  32. className={cn(
  33. 'flex h-7 items-center rounded-md px-2.5 text-[13px] font-medium text-components-button-secondary-accent-text',
  34. 'cursor-pointer hover:bg-state-accent-hover',
  35. isRunning && '!cursor-not-allowed bg-state-accent-hover',
  36. )}
  37. onClick={() => {
  38. handleWorkflowStartRunInWorkflow()
  39. }}
  40. >
  41. {
  42. isRunning
  43. ? (
  44. <>
  45. <RiLoader2Line className='mr-1 h-4 w-4 animate-spin' />
  46. {t('workflow.common.running')}
  47. </>
  48. )
  49. : (
  50. <>
  51. <RiPlayLargeLine className='mr-1 h-4 w-4' />
  52. {t('workflow.common.run')}
  53. </>
  54. )
  55. }
  56. </div>
  57. {
  58. isRunning && (
  59. <div
  60. className='ml-0.5 flex h-7 w-7 cursor-pointer items-center justify-center rounded-md hover:bg-black/5'
  61. onClick={() => handleStopRun(workflowRunningData?.task_id || '')}
  62. >
  63. <StopCircle className='h-4 w-4 text-components-button-ghost-text' />
  64. </div>
  65. )
  66. }
  67. </>
  68. )
  69. })
  70. RunMode.displayName = 'RunMode'
  71. const PreviewMode = memo(() => {
  72. const { t } = useTranslation()
  73. const { handleWorkflowStartRunInChatflow } = useWorkflowStartRun()
  74. return (
  75. <div
  76. className={cn(
  77. 'flex h-7 items-center rounded-md px-2.5 text-[13px] font-medium text-components-button-secondary-accent-text',
  78. 'cursor-pointer hover:bg-state-accent-hover',
  79. )}
  80. onClick={() => handleWorkflowStartRunInChatflow()}
  81. >
  82. <RiPlayLargeLine className='mr-1 h-4 w-4' />
  83. {t('workflow.common.debugAndPreview')}
  84. </div>
  85. )
  86. })
  87. PreviewMode.displayName = 'PreviewMode'
  88. const RunAndHistory: FC = () => {
  89. const isChatMode = useIsChatMode()
  90. const { nodesReadOnly } = useNodesReadOnly()
  91. const { detail, isCreate, isEdit, isOperation } = useAppDetailContext()
  92. return (
  93. <div className='flex h-8 items-center rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-0.5 shadow-xs'>
  94. {
  95. !isChatMode && <RunMode />
  96. }
  97. {
  98. isChatMode && <PreviewMode />
  99. }
  100. {
  101. isEdit && (<>
  102. <div className='mx-0.5 h-3.5 w-[1px] bg-divider-regular'></div>
  103. <ViewHistory />
  104. <Checklist disabled={nodesReadOnly} />
  105. </>)
  106. }
  107. </div>
  108. )
  109. }
  110. export default memo(RunAndHistory)