mirror of
https://github.com/langgenius/dify.git
synced 2026-04-21 03:07:39 +08:00
chore: refactor sandbox placeholder
This commit is contained in:
@ -0,0 +1,59 @@
|
||||
import type { ReactElement } from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import SandboxPlaceholder from '../sandbox-placeholder'
|
||||
|
||||
vi.mock('react-i18next', () => ({
|
||||
Trans: ({ i18nKey, components = [] }: {
|
||||
i18nKey: string
|
||||
components?: ReactElement[]
|
||||
}) => (
|
||||
<div data-i18n-key={i18nKey} data-testid="sandbox-placeholder-trans">
|
||||
{components}
|
||||
</div>
|
||||
),
|
||||
}))
|
||||
|
||||
describe('SandboxPlaceholder', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
// Rendering branches for sandbox availability and tool-block support.
|
||||
describe('Rendering', () => {
|
||||
it('should render nothing when sandbox is not supported', () => {
|
||||
const { container } = render(<SandboxPlaceholder isSupportSandbox={false} />)
|
||||
|
||||
expect(container).toBeEmptyDOMElement()
|
||||
expect(screen.queryByTestId('sandbox-placeholder-trans')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render slash and insert tokens when tool blocks are disabled', () => {
|
||||
const { container } = render(
|
||||
<SandboxPlaceholder
|
||||
disableToolBlocks
|
||||
isSupportSandbox
|
||||
/>,
|
||||
)
|
||||
|
||||
expect(screen.getByTestId('sandbox-placeholder-trans')).toHaveAttribute('data-i18n-key', 'promptEditor.placeholderSandboxNoTools')
|
||||
|
||||
const spans = container.querySelectorAll('span')
|
||||
expect(spans).toHaveLength(2)
|
||||
expect(spans[0]).toHaveClass('inline-flex', 'bg-components-kbd-bg-gray', 'system-kbd')
|
||||
expect(spans[1]).toHaveClass('border-b', 'border-dotted', 'border-current')
|
||||
})
|
||||
|
||||
it('should render slash insert at and tools tokens when tool blocks are enabled', () => {
|
||||
const { container } = render(<SandboxPlaceholder isSupportSandbox />)
|
||||
|
||||
expect(screen.getByTestId('sandbox-placeholder-trans')).toHaveAttribute('data-i18n-key', 'promptEditor.placeholderSandbox')
|
||||
|
||||
const spans = container.querySelectorAll('span')
|
||||
expect(spans).toHaveLength(4)
|
||||
expect(spans[0]).toHaveClass('inline-flex', 'bg-components-kbd-bg-gray', 'system-kbd')
|
||||
expect(spans[1]).toHaveClass('border-b', 'border-dotted', 'border-current')
|
||||
expect(spans[2]).toHaveClass('inline-flex', 'bg-components-kbd-bg-gray', 'system-kbd')
|
||||
expect(spans[3]).toHaveClass('border-b', 'border-dotted', 'border-current')
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -39,7 +39,6 @@ import {
|
||||
} from 'lexical'
|
||||
import * as React from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { WorkflowContext } from '@/app/components/workflow/context'
|
||||
import { HooksStoreContext } from '@/app/components/workflow/hooks-store/provider'
|
||||
import { FileReferenceNode } from '@/app/components/workflow/skill/editor/skill-editor/plugins/file-reference-block/node'
|
||||
@ -118,6 +117,7 @@ import {
|
||||
WorkflowVariableBlockNode,
|
||||
WorkflowVariableBlockReplacementBlock,
|
||||
} from './plugins/workflow-variable-block'
|
||||
import SandboxPlaceholder from './sandbox-placeholder'
|
||||
import { textToEditorState } from './utils'
|
||||
|
||||
const ValueSyncPlugin: FC<{ value?: string }> = ({ value }) => {
|
||||
@ -342,50 +342,6 @@ const PromptEditorContent: FC<PromptEditorContentProps> = ({
|
||||
enabled: Boolean(isSupportSandbox),
|
||||
}), [isSupportSandbox])
|
||||
|
||||
const sandboxPlaceHolder = React.useMemo(() => {
|
||||
if (!isSupportSandbox)
|
||||
return null
|
||||
const i18nKey = disableToolBlocks
|
||||
? 'promptEditor.placeholderSandboxNoTools'
|
||||
: 'promptEditor.placeholderSandbox'
|
||||
const components = disableToolBlocks
|
||||
? [
|
||||
<span
|
||||
key="slash"
|
||||
className="inline-flex h-5 min-w-5 items-center justify-center rounded-[4px] bg-components-kbd-bg-gray px-1 text-text-tertiary system-kbd"
|
||||
/>,
|
||||
<span
|
||||
key="insert"
|
||||
className="border-b border-dotted border-current"
|
||||
/>,
|
||||
]
|
||||
: [
|
||||
<span
|
||||
key="slash"
|
||||
className="inline-flex h-5 min-w-5 items-center justify-center rounded-[4px] bg-components-kbd-bg-gray px-1 text-text-tertiary system-kbd"
|
||||
/>,
|
||||
<span
|
||||
key="insert"
|
||||
className="border-b border-dotted border-current"
|
||||
/>,
|
||||
<span
|
||||
key="at"
|
||||
className="inline-flex h-5 min-w-5 items-center justify-center rounded-[4px] bg-components-kbd-bg-gray px-1 text-text-tertiary system-kbd"
|
||||
/>,
|
||||
<span
|
||||
key="tools"
|
||||
className="border-b border-dotted border-current"
|
||||
/>,
|
||||
]
|
||||
return (
|
||||
<Trans
|
||||
i18nKey={i18nKey}
|
||||
ns="common"
|
||||
components={components}
|
||||
/>
|
||||
)
|
||||
}, [disableToolBlocks, isSupportSandbox])
|
||||
|
||||
const [floatingAnchorElem, setFloatingAnchorElem] = useState<HTMLDivElement | null>(null)
|
||||
|
||||
const onRef = (floatingAnchorElement: HTMLDivElement | null) => {
|
||||
@ -415,7 +371,12 @@ const PromptEditorContent: FC<PromptEditorContentProps> = ({
|
||||
)}
|
||||
placeholder={(
|
||||
<Placeholder
|
||||
value={placeholder || sandboxPlaceHolder}
|
||||
value={placeholder || (
|
||||
<SandboxPlaceholder
|
||||
disableToolBlocks={disableToolBlocks}
|
||||
isSupportSandbox={isSupportSandbox}
|
||||
/>
|
||||
)}
|
||||
className={cn('truncate', placeholderClassName)}
|
||||
compact={compact}
|
||||
/>
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
import type { FC, PropsWithChildren, ReactElement } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
|
||||
type SandboxPlaceholderTokenProps = PropsWithChildren<{
|
||||
variant: 'kbd' | 'action'
|
||||
}>
|
||||
|
||||
const SandboxPlaceholderToken: FC<SandboxPlaceholderTokenProps> = ({ variant, children }) => {
|
||||
if (variant === 'kbd') {
|
||||
return (
|
||||
<span className="inline-flex h-5 min-w-5 items-center justify-center rounded-[4px] bg-components-kbd-bg-gray px-1 text-text-tertiary system-kbd">
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="border-b border-dotted border-current">
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
type SandboxPlaceholderProps = {
|
||||
disableToolBlocks?: boolean
|
||||
isSupportSandbox?: boolean
|
||||
}
|
||||
|
||||
const SandboxPlaceholder: FC<SandboxPlaceholderProps> = ({
|
||||
disableToolBlocks,
|
||||
isSupportSandbox,
|
||||
}) => {
|
||||
if (!isSupportSandbox)
|
||||
return null
|
||||
|
||||
const components: ReactElement[] = [
|
||||
<SandboxPlaceholderToken key="slash" variant="kbd" />,
|
||||
<SandboxPlaceholderToken key="insert" variant="action" />,
|
||||
]
|
||||
|
||||
if (!disableToolBlocks) {
|
||||
components.push(
|
||||
<SandboxPlaceholderToken key="at" variant="kbd" />,
|
||||
<SandboxPlaceholderToken key="tools" variant="action" />,
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Trans
|
||||
i18nKey={disableToolBlocks ? 'promptEditor.placeholderSandboxNoTools' : 'promptEditor.placeholderSandbox'}
|
||||
ns="common"
|
||||
components={components}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default SandboxPlaceholder
|
||||
Reference in New Issue
Block a user