mirror of
https://github.com/langgenius/dify.git
synced 2026-09-02 06:03:18 +08:00
chore: add copy action to workflow log errors (#40011)
This commit is contained in:
parent
7dd7b3dfa8
commit
72b30ff313
@ -21,8 +21,16 @@ vi.mock('@/app/components/base/markdown', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/workflow/run/status-container', () => ({
|
||||
default: ({ status, children }: { status: string; children?: React.ReactNode }) => (
|
||||
<div data-status={status} data-testid="status-container">
|
||||
default: ({
|
||||
status,
|
||||
children,
|
||||
copyContent,
|
||||
}: {
|
||||
status: string
|
||||
children?: React.ReactNode
|
||||
copyContent?: string
|
||||
}) => (
|
||||
<div data-copy-content={copyContent} data-status={status} data-testid="status-container">
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
@ -62,6 +70,10 @@ describe('OutputPanel', () => {
|
||||
render(<OutputPanel error="Execution failed" />)
|
||||
|
||||
expect(screen.getByTestId('status-container')).toHaveAttribute('data-status', 'failed')
|
||||
expect(screen.getByTestId('status-container')).toHaveAttribute(
|
||||
'data-copy-content',
|
||||
'Execution failed',
|
||||
)
|
||||
expect(screen.getByText('Execution failed')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
|
||||
@ -1,8 +1,18 @@
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import useTheme from '@/hooks/use-theme'
|
||||
import { Theme } from '@/types/app'
|
||||
import StatusContainer from '../status-container'
|
||||
|
||||
const copy = vi.fn()
|
||||
|
||||
vi.mock('foxact/use-clipboard', () => ({
|
||||
useClipboard: () => ({
|
||||
copied: false,
|
||||
copy,
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/hooks/use-theme', () => ({
|
||||
default: vi.fn(),
|
||||
}))
|
||||
@ -34,4 +44,19 @@ describe('StatusContainer', () => {
|
||||
).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
it('copies the supplied content from the status action', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<StatusContainer status="failed" copyContent="Execution failed">
|
||||
Execution failed
|
||||
</StatusContainer>,
|
||||
)
|
||||
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: 'appOverview.overview.appInfo.embedded.copy' }),
|
||||
)
|
||||
|
||||
expect(copy).toHaveBeenCalledWith('Execution failed')
|
||||
})
|
||||
})
|
||||
|
||||
@ -53,7 +53,9 @@ const OutputPanel: FC<OutputPanelProps> = ({ isRunning, outputs, error, height }
|
||||
)}
|
||||
{!isRunning && error && (
|
||||
<div className="px-4">
|
||||
<StatusContainer status="failed">{error}</StatusContainer>
|
||||
<StatusContainer status="failed" copyContent={error}>
|
||||
{error}
|
||||
</StatusContainer>
|
||||
</div>
|
||||
)}
|
||||
{!isRunning && !outputs && (
|
||||
|
||||
@ -1,22 +1,26 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import CopyFeedback from '@/app/components/base/copy-feedback'
|
||||
import useTheme from '@/hooks/use-theme'
|
||||
import { Theme } from '@/types/app'
|
||||
|
||||
type Props = {
|
||||
readonly status: string
|
||||
readonly children?: React.ReactNode
|
||||
readonly copyContent?: string
|
||||
}
|
||||
|
||||
const StatusContainer: FC<Props> = ({ status, children }) => {
|
||||
const StatusContainer: FC<Props> = ({ status, children, copyContent }) => {
|
||||
const { theme } = useTheme()
|
||||
const isCopyable = copyContent !== undefined
|
||||
|
||||
return (
|
||||
<div
|
||||
role="status"
|
||||
className={cn(
|
||||
'relative rounded-lg border border-workflow-display-disabled-border-1 px-3 py-2.5 system-xs-regular break-all',
|
||||
'group/status relative rounded-lg border border-workflow-display-disabled-border-1 px-3 py-2.5 system-xs-regular break-all',
|
||||
isCopyable && 'focus-within:pr-10 hover:pr-10 [@media(hover:none)]:pr-10',
|
||||
status === 'succeeded' &&
|
||||
'border-[rgba(23,178,106,0.8)] bg-workflow-display-success-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-success.svg)] text-text-success',
|
||||
status === 'succeeded' &&
|
||||
@ -69,13 +73,18 @@ const StatusContainer: FC<Props> = ({ status, children }) => {
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
'absolute top-0 left-0 h-12.5 w-[65%] bg-no-repeat',
|
||||
'pointer-events-none absolute top-0 left-0 h-12.5 w-[65%] bg-no-repeat',
|
||||
theme === Theme.light && 'bg-[url(~@/app/components/workflow/run/assets/highlight.svg)]',
|
||||
theme === Theme.dark &&
|
||||
'bg-[url(~@/app/components/workflow/run/assets/highlight-dark.svg)]',
|
||||
)}
|
||||
></div>
|
||||
{children}
|
||||
{isCopyable && (
|
||||
<div className="pointer-events-none absolute top-1.5 right-1.5 z-10 opacity-0 transition-opacity group-focus-within/status:pointer-events-auto group-focus-within/status:opacity-100 group-hover/status:pointer-events-auto group-hover/status:opacity-100 [@media(hover:none)]:pointer-events-auto [@media(hover:none)]:opacity-100">
|
||||
<CopyFeedback content={copyContent} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user