mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-15 19:05:58 +08:00
feat: support copy run text result in debug panel in workflow (#4300)
This commit is contained in:
parent
c01c95d77f
commit
4af00e4a45
@ -267,6 +267,8 @@ const GenerationItem: FC<IGenerationItemProps> = ({
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const [currentTab, setCurrentTab] = useState<string>('DETAIL')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref} className={cn(className, isTop ? `rounded-xl border ${!isError ? 'border-gray-200 bg-white' : 'border-[#FECDCA] bg-[#FEF3F2]'} ` : 'rounded-br-xl !mt-0')}
|
<div ref={ref} className={cn(className, isTop ? `rounded-xl border ${!isError ? 'border-gray-200 bg-white' : 'border-[#FECDCA] bg-[#FEF3F2]'} ` : 'rounded-br-xl !mt-0')}
|
||||||
style={isTop
|
style={isTop
|
||||||
@ -296,7 +298,7 @@ const GenerationItem: FC<IGenerationItemProps> = ({
|
|||||||
<WorkflowProcessItem grayBg hideInfo data={workflowProcessData} expand={workflowProcessData.expand} hideProcessDetail={hideProcessDetail} />
|
<WorkflowProcessItem grayBg hideInfo data={workflowProcessData} expand={workflowProcessData.expand} hideProcessDetail={hideProcessDetail} />
|
||||||
)}
|
)}
|
||||||
{workflowProcessData && !isError && (
|
{workflowProcessData && !isError && (
|
||||||
<ResultTab data={workflowProcessData} content={content} />
|
<ResultTab data={workflowProcessData} content={content} currentTab={currentTab} onCurrentTabChange={setCurrentTab} />
|
||||||
)}
|
)}
|
||||||
{isError && (
|
{isError && (
|
||||||
<div className='text-gray-400 text-sm'>{t('share.generation.batchFailed.outputPlaceholder')}</div>
|
<div className='text-gray-400 text-sm'>{t('share.generation.batchFailed.outputPlaceholder')}</div>
|
||||||
@ -320,19 +322,23 @@ const GenerationItem: FC<IGenerationItemProps> = ({
|
|||||||
</SimpleBtn>
|
</SimpleBtn>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<SimpleBtn
|
{currentTab === 'RESULT' && (
|
||||||
isDisabled={isError || !messageId}
|
<SimpleBtn
|
||||||
className={cn(isMobile && '!px-1.5', 'space-x-1')}
|
isDisabled={isError || !messageId}
|
||||||
onClick={() => {
|
className={cn(isMobile && '!px-1.5', 'space-x-1')}
|
||||||
if (typeof content === 'string')
|
onClick={() => {
|
||||||
copy(content)
|
const content = workflowProcessData?.resultText
|
||||||
else
|
if (typeof content === 'string')
|
||||||
copy(JSON.stringify(content))
|
copy(content)
|
||||||
Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') })
|
else
|
||||||
}}>
|
copy(JSON.stringify(content))
|
||||||
<Clipboard className='w-3.5 h-3.5' />
|
Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') })
|
||||||
{!isMobile && <div>{t('common.operation.copy')}</div>}
|
}}>
|
||||||
</SimpleBtn>
|
<Clipboard className='w-3.5 h-3.5' />
|
||||||
|
{!isMobile && <div>{t('common.operation.copy')}</div>}
|
||||||
|
</SimpleBtn>
|
||||||
|
)}
|
||||||
|
|
||||||
{isInWebApp && (
|
{isInWebApp && (
|
||||||
<>
|
<>
|
||||||
{!isWorkflow && (
|
{!isWorkflow && (
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
memo,
|
memo,
|
||||||
useEffect,
|
useEffect,
|
||||||
// useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -16,15 +14,18 @@ import type { WorkflowProcess } from '@/app/components/base/chat/types'
|
|||||||
const ResultTab = ({
|
const ResultTab = ({
|
||||||
data,
|
data,
|
||||||
content,
|
content,
|
||||||
|
currentTab,
|
||||||
|
onCurrentTabChange,
|
||||||
}: {
|
}: {
|
||||||
data?: WorkflowProcess
|
data?: WorkflowProcess
|
||||||
content: any
|
content: any
|
||||||
|
currentTab: string
|
||||||
|
onCurrentTabChange: (tab: string) => void
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [currentTab, setCurrentTab] = useState<string>('DETAIL')
|
|
||||||
|
|
||||||
const switchTab = async (tab: string) => {
|
const switchTab = async (tab: string) => {
|
||||||
setCurrentTab(tab)
|
onCurrentTabChange(tab)
|
||||||
}
|
}
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.resultText)
|
if (data?.resultText)
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
} from 'react'
|
} from 'react'
|
||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import copy from 'copy-to-clipboard'
|
||||||
import ResultText from '../run/result-text'
|
import ResultText from '../run/result-text'
|
||||||
import ResultPanel from '../run/result-panel'
|
import ResultPanel from '../run/result-panel'
|
||||||
import TracingPanel from '../run/tracing-panel'
|
import TracingPanel from '../run/tracing-panel'
|
||||||
@ -16,9 +17,12 @@ import { useStore } from '../store'
|
|||||||
import {
|
import {
|
||||||
WorkflowRunningStatus,
|
WorkflowRunningStatus,
|
||||||
} from '../types'
|
} from '../types'
|
||||||
|
import { SimpleBtn } from '../../app/text-generate/item'
|
||||||
|
import Toast from '../../base/toast'
|
||||||
import InputsPanel from './inputs-panel'
|
import InputsPanel from './inputs-panel'
|
||||||
import Loading from '@/app/components/base/loading'
|
import Loading from '@/app/components/base/loading'
|
||||||
import { XClose } from '@/app/components/base/icons/src/vender/line/general'
|
import { XClose } from '@/app/components/base/icons/src/vender/line/general'
|
||||||
|
import { Clipboard } from '@/app/components/base/icons/src/vender/line/files'
|
||||||
|
|
||||||
const WorkflowPreview = () => {
|
const WorkflowPreview = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
@ -108,12 +112,28 @@ const WorkflowPreview = () => {
|
|||||||
<InputsPanel onRun={() => switchTab('RESULT')} />
|
<InputsPanel onRun={() => switchTab('RESULT')} />
|
||||||
)}
|
)}
|
||||||
{currentTab === 'RESULT' && (
|
{currentTab === 'RESULT' && (
|
||||||
<ResultText
|
<>
|
||||||
isRunning={workflowRunningData?.result?.status === WorkflowRunningStatus.Running || !workflowRunningData?.result}
|
<ResultText
|
||||||
outputs={workflowRunningData?.resultText}
|
isRunning={workflowRunningData?.result?.status === WorkflowRunningStatus.Running || !workflowRunningData?.result}
|
||||||
error={workflowRunningData?.result?.error}
|
outputs={workflowRunningData?.resultText}
|
||||||
onClick={() => switchTab('DETAIL')}
|
error={workflowRunningData?.result?.error}
|
||||||
/>
|
onClick={() => switchTab('DETAIL')}
|
||||||
|
/>
|
||||||
|
<SimpleBtn
|
||||||
|
isDisabled={workflowRunningData?.result.status !== WorkflowRunningStatus.Succeeded}
|
||||||
|
className={cn('ml-4 mb-4 inline-flex space-x-1')}
|
||||||
|
onClick={() => {
|
||||||
|
const content = workflowRunningData?.resultText
|
||||||
|
if (typeof content === 'string')
|
||||||
|
copy(content)
|
||||||
|
else
|
||||||
|
copy(JSON.stringify(content))
|
||||||
|
Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') })
|
||||||
|
}}>
|
||||||
|
<Clipboard className='w-3.5 h-3.5' />
|
||||||
|
<div>{t('common.operation.copy')}</div>
|
||||||
|
</SimpleBtn>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{currentTab === 'DETAIL' && (
|
{currentTab === 'DETAIL' && (
|
||||||
<ResultPanel
|
<ResultPanel
|
||||||
@ -143,6 +163,7 @@ const WorkflowPreview = () => {
|
|||||||
<Loading />
|
<Loading />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user