Preview human input field types in markdown

This commit is contained in:
JzoNg 2026-04-22 07:54:30 +08:00
parent ccf61c0372
commit 85d05f5113
2 changed files with 55 additions and 6 deletions

View File

@ -64,10 +64,14 @@ vi.mock('../variable-in-markdown', () => ({
rehypeNotes: vi.fn(),
rehypeVariable: vi.fn(),
Variable: ({ path }: { path: string }) => <div data-testid="variable-path">{path}</div>,
Note: ({ defaultInput, nodeName }: {
defaultInput: { selector: string[] }
Note: ({ input, nodeName }: {
input: { type: string, default?: { selector: string[] }, option_source?: { selector: string[] } }
nodeName: (nodeId: string) => string
}) => <div data-testid="note">{nodeName(defaultInput.selector[0]!)}</div>,
}) => (
<div data-testid="note">
{input.default?.selector?.length ? nodeName(input.default.selector[0]!) : input.option_source?.selector?.join('.') || input.type}
</div>
),
}))
describe('FormContentPreview', () => {
@ -131,4 +135,25 @@ describe('FormContentPreview', () => {
expect(onClose).toHaveBeenCalledTimes(1)
})
it('should pass non-paragraph inputs through the preview note renderer', () => {
render(
<FormContentPreview
content="content"
formInputs={[{
type: 'select' as never,
output_variable_name: 'field_1',
option_source: {
type: 'variable',
selector: ['node-1', 'items'],
value: [],
},
}]}
userActions={[]}
onClose={onClose}
/>,
)
expect(screen.getByTestId('note')).toHaveTextContent('node-1.items')
})
})

View File

@ -1,6 +1,6 @@
import type * as React from 'react'
import type { FormInputItem } from '../types'
import { isParagraphFormInput } from '../types'
import { isFileFormInput, isFileListFormInput, isSelectFormInput } from '../types'
const variableRegex = /\{\{#(.+?)#\}\}/g
const noteRegex = /\{\{#\$(.+?)#\}\}/g
@ -134,10 +134,34 @@ export const Variable: React.FC<{ path: string }> = ({ path }) => {
}
export const Note: React.FC<{ input: FormInputItem, nodeName: (nodeId: string) => string }> = ({ input, nodeName }) => {
if (!isParagraphFormInput(input)) {
if (isSelectFormInput(input)) {
const isVariable = input.option_source.type === 'variable'
const path = `{{#${input.option_source.selector.join('.')}#}}`
const newPath = path ? replaceNodeIdsWithNames(path, nodeName) : path
return (
<div className="my-3 rounded-[10px] bg-components-input-bg-normal px-2.5 py-2">
<span>{input.type}</span>
{isVariable ? <Variable path={newPath} /> : <span>{input.option_source.value.join(', ') || input.type}</span>}
</div>
)
}
if (isFileFormInput(input)) {
return (
<div className="my-3 rounded-[10px] bg-components-input-bg-normal px-2.5 py-2">
<span>{input.allowed_file_types.join(', ') || input.type}</span>
</div>
)
}
if (isFileListFormInput(input)) {
const summary = [
input.allowed_file_types.join(', '),
input.max_upload_count ? `max ${input.max_upload_count}` : null,
].filter(Boolean).join(' · ')
return (
<div className="my-3 rounded-[10px] bg-components-input-bg-normal px-2.5 py-2">
<span>{summary || input.type}</span>
</div>
)
}