diff --git a/web/app/components/base/prompt-editor/__tests__/sandbox-placeholder.spec.tsx b/web/app/components/base/prompt-editor/__tests__/sandbox-placeholder.spec.tsx
index 22d69cdd11..ed2927c7d0 100644
--- a/web/app/components/base/prompt-editor/__tests__/sandbox-placeholder.spec.tsx
+++ b/web/app/components/base/prompt-editor/__tests__/sandbox-placeholder.spec.tsx
@@ -1,16 +1,18 @@
-import type { ReactElement } from 'react'
-import { render, screen } from '@testing-library/react'
+import { render } from '@testing-library/react'
import SandboxPlaceholder from '../sandbox-placeholder'
vi.mock('react-i18next', () => ({
- Trans: ({ i18nKey, components = [] }: {
- i18nKey: string
- components?: ReactElement[]
- }) => (
-
- {components}
-
- ),
+ useTranslation: () => ({
+ t: (key: string) => {
+ const translations: Record = {
+ 'promptEditor.placeholderSandboxPrefix': 'Write instructions here, ',
+ 'promptEditor.placeholderSandboxInsert': 'insert',
+ 'promptEditor.placeholderSandboxSeparator': ', ',
+ 'promptEditor.placeholderSandboxTools': 'tools',
+ }
+ return translations[key] ?? key
+ },
+ }),
}))
describe('SandboxPlaceholder', () => {
@@ -24,10 +26,9 @@ describe('SandboxPlaceholder', () => {
const { container } = render()
expect(container).toBeEmptyDOMElement()
- expect(screen.queryByTestId('sandbox-placeholder-trans')).not.toBeInTheDocument()
})
- it('should render slash and insert tokens when tool blocks are disabled', () => {
+ it('should render only the insert pair when tool blocks are disabled', () => {
const { container } = render(
{
/>,
)
- 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')
+ expect(container).toHaveTextContent('Write instructions here, /insert')
+ expect(container.querySelector('.sandbox-placeholder-pair-insert')).toBeInTheDocument()
+ expect(container.querySelector('.sandbox-placeholder-pair-tools')).not.toBeInTheDocument()
+ expect(container.querySelector('.sandbox-placeholder-action-insert')).toHaveClass(
+ 'pointer-events-auto',
+ 'border-dotted',
+ )
})
- it('should render slash insert at and tools tokens when tool blocks are enabled', () => {
+ it('should render both insert and tools pairs with linked hover classes when tool blocks are enabled', () => {
const { container } = render()
- 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')
+ expect(container).toHaveTextContent('Write instructions here, /insert, @tools')
+ expect(container.querySelector('.sandbox-placeholder-kbd-insert')).toHaveTextContent('/')
+ expect(container.querySelector('.sandbox-placeholder-kbd-tools')).toHaveTextContent('@')
+ expect(container.querySelector('.sandbox-placeholder-action-insert')).toHaveTextContent('insert')
+ expect(container.querySelector('.sandbox-placeholder-action-tools')).toHaveTextContent('tools')
+ expect(container.querySelector('.sandbox-placeholder-pair-insert')).toHaveClass(
+ 'has-[.sandbox-placeholder-action-insert:hover]:[&_.sandbox-placeholder-kbd-insert]:bg-state-accent-hover-alt',
+ 'has-[.sandbox-placeholder-action-insert:hover]:[&_.sandbox-placeholder-action-insert]:bg-state-accent-hover',
+ 'has-[.sandbox-placeholder-action-insert:hover]:[&_.sandbox-placeholder-action-insert]:text-text-accent-secondary',
+ )
+ expect(container.querySelector('.sandbox-placeholder-pair-tools')).toHaveClass(
+ 'has-[.sandbox-placeholder-action-tools:hover]:[&_.sandbox-placeholder-kbd-tools]:bg-state-accent-hover-alt',
+ 'has-[.sandbox-placeholder-action-tools:hover]:[&_.sandbox-placeholder-action-tools]:bg-state-accent-hover',
+ 'has-[.sandbox-placeholder-action-tools:hover]:[&_.sandbox-placeholder-action-tools]:text-text-accent-secondary',
+ )
})
})
})
diff --git a/web/app/components/base/prompt-editor/sandbox-placeholder.tsx b/web/app/components/base/prompt-editor/sandbox-placeholder.tsx
index 5fb348bee0..4beab897af 100644
--- a/web/app/components/base/prompt-editor/sandbox-placeholder.tsx
+++ b/web/app/components/base/prompt-editor/sandbox-placeholder.tsx
@@ -1,22 +1,38 @@
-import type { FC, PropsWithChildren, ReactElement } from 'react'
-import { Trans } from 'react-i18next'
+import type { FC } from 'react'
+import { useTranslation } from 'react-i18next'
+import { cn } from '@/utils/classnames'
-type SandboxPlaceholderTokenProps = PropsWithChildren<{
- variant: 'kbd' | 'action'
-}>
-
-const SandboxPlaceholderToken: FC = ({ variant, children }) => {
- if (variant === 'kbd') {
- return (
-
- {children}
-
- )
- }
+type SandboxPlaceholderTokenProps = {
+ actionLabel?: string
+ shortcut: '/' | '@'
+}
+const SandboxPlaceholderToken: FC = ({
+ actionLabel,
+ shortcut,
+}) => {
return (
-
- {children}
+
+
+ {shortcut}
+
+
+ {actionLabel}
+
)
}
@@ -30,27 +46,28 @@ const SandboxPlaceholder: FC = ({
disableToolBlocks,
isSupportSandbox,
}) => {
+ const { t } = useTranslation()
+
if (!isSupportSandbox)
return null
- const components: ReactElement[] = [
- ,
- ,
- ]
-
- if (!disableToolBlocks) {
- components.push(
- ,
- ,
- )
- }
-
return (
-
+
+ {t('promptEditor.placeholderSandboxPrefix', { ns: 'common' })}
+
+ {!disableToolBlocks && (
+ <>
+ {t('promptEditor.placeholderSandboxSeparator', { ns: 'common' })}
+
+ >
+ )}
+
)
}
diff --git a/web/i18n/en-US/common.json b/web/i18n/en-US/common.json
index 84d695b85d..6342957230 100644
--- a/web/i18n/en-US/common.json
+++ b/web/i18n/en-US/common.json
@@ -549,8 +549,10 @@
"promptEditor.history.modal.title": "EXAMPLE",
"promptEditor.history.modal.user": "Hello",
"promptEditor.placeholder": "Write your prompt word here, enter '{' to insert a variable, enter '/' to insert a prompt content block",
- "promptEditor.placeholderSandbox": "Write instructions here, <0>/0> <1>insert1>, <2>@2> <3>tools3>",
- "promptEditor.placeholderSandboxNoTools": "Write instructions here, <0>/0> <1>insert1>",
+ "promptEditor.placeholderSandboxInsert": "insert",
+ "promptEditor.placeholderSandboxPrefix": "Write instructions here, ",
+ "promptEditor.placeholderSandboxSeparator": ", ",
+ "promptEditor.placeholderSandboxTools": "tools",
"promptEditor.query.item.desc": "Insert user query template",
"promptEditor.query.item.title": "Query",
"promptEditor.requestURL.item.desc": "Insert request URL",
diff --git a/web/i18n/ja-JP/common.json b/web/i18n/ja-JP/common.json
index 92bbbfee7d..2c833bd9c1 100644
--- a/web/i18n/ja-JP/common.json
+++ b/web/i18n/ja-JP/common.json
@@ -534,8 +534,10 @@
"promptEditor.history.modal.title": "例",
"promptEditor.history.modal.user": "こんにちは",
"promptEditor.placeholder": "ここにプロンプトワードを入力してください。変数を挿入するには「{」を、プロンプトコンテンツブロックを挿入するには「/」を入力します。",
- "promptEditor.placeholderSandbox": "ここに指示を書いて、<0>/0> <1>挿入1>、<2>@2> <3>ツール3>",
- "promptEditor.placeholderSandboxNoTools": "ここに指示を書いて、<0>/0> <1>挿入1>",
+ "promptEditor.placeholderSandboxInsert": "挿入",
+ "promptEditor.placeholderSandboxPrefix": "ここに指示を書いて、",
+ "promptEditor.placeholderSandboxSeparator": "、",
+ "promptEditor.placeholderSandboxTools": "ツール",
"promptEditor.query.item.desc": "ユーザークエリテンプレートを挿入",
"promptEditor.query.item.title": "クエリ",
"promptEditor.requestURL.item.desc": "リクエストURLを挿入",
diff --git a/web/i18n/zh-Hans/common.json b/web/i18n/zh-Hans/common.json
index 392958686e..6357c0f6e3 100644
--- a/web/i18n/zh-Hans/common.json
+++ b/web/i18n/zh-Hans/common.json
@@ -549,8 +549,10 @@
"promptEditor.history.modal.title": "示例",
"promptEditor.history.modal.user": "你好",
"promptEditor.placeholder": "在这里写你的提示词,输入'{' 插入变量、输入'/' 插入提示内容块",
- "promptEditor.placeholderSandbox": "在这里写你的指令,<0>/0> <1>插入1>,<2>@2> <3>工具3>",
- "promptEditor.placeholderSandboxNoTools": "在这里写你的指令,<0>/0> <1>插入1>",
+ "promptEditor.placeholderSandboxInsert": "插入",
+ "promptEditor.placeholderSandboxPrefix": "在这里写你的指令,",
+ "promptEditor.placeholderSandboxSeparator": ",",
+ "promptEditor.placeholderSandboxTools": "工具",
"promptEditor.query.item.desc": "插入用户查询模板",
"promptEditor.query.item.title": "查询内容",
"promptEditor.requestURL.item.desc": "插入请求 URL",
diff --git a/web/i18n/zh-Hant/common.json b/web/i18n/zh-Hant/common.json
index 471bf3fa00..47fe026a07 100644
--- a/web/i18n/zh-Hant/common.json
+++ b/web/i18n/zh-Hant/common.json
@@ -509,8 +509,10 @@
"promptEditor.history.modal.title": "示例",
"promptEditor.history.modal.user": "你好",
"promptEditor.placeholder": "在這裡寫你的提示詞,輸入'{' 插入變數、輸入'/' 插入提示內容塊",
- "promptEditor.placeholderSandbox": "在這裡寫你的指令,<0>/0> <1>插入1>,<2>@2> <3>工具3>",
- "promptEditor.placeholderSandboxNoTools": "在這裡寫你的指令,<0>/0> <1>插入1>",
+ "promptEditor.placeholderSandboxInsert": "插入",
+ "promptEditor.placeholderSandboxPrefix": "在這裡寫你的指令,",
+ "promptEditor.placeholderSandboxSeparator": ",",
+ "promptEditor.placeholderSandboxTools": "工具",
"promptEditor.query.item.desc": "插入使用者查詢模板",
"promptEditor.query.item.title": "查詢內容",
"promptEditor.requestURL.item.desc": "插入請求 URL",