refactor: revamp picker block (#4227)
Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com>
This commit is contained in:
@@ -15,8 +15,9 @@ import { INSERT_HISTORY_BLOCK_COMMAND } from '../history-block'
|
||||
import { INSERT_QUERY_BLOCK_COMMAND } from '../query-block'
|
||||
import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '../variable-block'
|
||||
import { $createCustomTextNode } from '../custom-text/node'
|
||||
import { PromptOption } from './prompt-option'
|
||||
import { VariableOption } from './variable-option'
|
||||
import { PromptMenuItem } from './prompt-option'
|
||||
import { VariableMenuItem } from './variable-option'
|
||||
import { PickerBlockMenuOption } from './menu'
|
||||
import { File05 } from '@/app/components/base/icons/src/vender/solid/files'
|
||||
import {
|
||||
MessageClockCircle,
|
||||
@@ -35,62 +36,111 @@ export const usePromptOptions = (
|
||||
const { t } = useTranslation()
|
||||
const [editor] = useLexicalComposerContext()
|
||||
|
||||
return useMemo(() => {
|
||||
return [
|
||||
...contextBlock?.show
|
||||
? [
|
||||
new PromptOption(t('common.promptEditor.context.item.title'), {
|
||||
icon: <File05 className='w-4 h-4 text-[#6938EF]' />,
|
||||
onSelect: () => {
|
||||
if (!contextBlock?.selectable)
|
||||
return
|
||||
editor.dispatchCommand(INSERT_CONTEXT_BLOCK_COMMAND, undefined)
|
||||
},
|
||||
disabled: !contextBlock?.selectable,
|
||||
}),
|
||||
]
|
||||
: [],
|
||||
...queryBlock?.show
|
||||
? [
|
||||
new PromptOption(t('common.promptEditor.query.item.title'), {
|
||||
icon: <UserEdit02 className='w-4 h-4 text-[#FD853A]' />,
|
||||
onSelect: () => {
|
||||
if (!queryBlock?.selectable)
|
||||
return
|
||||
editor.dispatchCommand(INSERT_QUERY_BLOCK_COMMAND, undefined)
|
||||
},
|
||||
disabled: !queryBlock?.selectable,
|
||||
}),
|
||||
]
|
||||
: [],
|
||||
...historyBlock?.show
|
||||
? [
|
||||
new PromptOption(t('common.promptEditor.history.item.title'), {
|
||||
icon: <MessageClockCircle className='w-4 h-4 text-[#DD2590]' />,
|
||||
onSelect: () => {
|
||||
if (!historyBlock?.selectable)
|
||||
return
|
||||
editor.dispatchCommand(INSERT_HISTORY_BLOCK_COMMAND, undefined)
|
||||
},
|
||||
disabled: !historyBlock?.selectable,
|
||||
}),
|
||||
]
|
||||
: [],
|
||||
]
|
||||
}, [contextBlock, editor, historyBlock, queryBlock, t])
|
||||
const promptOptions: PickerBlockMenuOption[] = []
|
||||
if (contextBlock?.show) {
|
||||
promptOptions.push(new PickerBlockMenuOption({
|
||||
key: t('common.promptEditor.context.item.title'),
|
||||
group: 'prompt context',
|
||||
render: ({ isSelected, onSelect, onSetHighlight }) => {
|
||||
return <PromptMenuItem
|
||||
title={t('common.promptEditor.context.item.title')}
|
||||
icon={<File05 className='w-4 h-4 text-[#6938EF]' />}
|
||||
disabled={!contextBlock.selectable}
|
||||
isSelected={isSelected}
|
||||
onClick={onSelect}
|
||||
onMouseEnter={onSetHighlight}
|
||||
/>
|
||||
},
|
||||
onSelect: () => {
|
||||
if (!contextBlock?.selectable)
|
||||
return
|
||||
editor.dispatchCommand(INSERT_CONTEXT_BLOCK_COMMAND, undefined)
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
if (queryBlock?.show) {
|
||||
promptOptions.push(
|
||||
new PickerBlockMenuOption({
|
||||
key: t('common.promptEditor.query.item.title'),
|
||||
group: 'prompt query',
|
||||
render: ({ isSelected, onSelect, onSetHighlight }) => {
|
||||
return (
|
||||
<PromptMenuItem
|
||||
title={t('common.promptEditor.query.item.title')}
|
||||
icon={<UserEdit02 className='w-4 h-4 text-[#FD853A]' />}
|
||||
disabled={!queryBlock.selectable}
|
||||
isSelected={isSelected}
|
||||
onClick={onSelect}
|
||||
onMouseEnter={onSetHighlight}
|
||||
/>
|
||||
)
|
||||
},
|
||||
onSelect: () => {
|
||||
if (!queryBlock?.selectable)
|
||||
return
|
||||
editor.dispatchCommand(INSERT_QUERY_BLOCK_COMMAND, undefined)
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
if (historyBlock?.show) {
|
||||
promptOptions.push(
|
||||
new PickerBlockMenuOption({
|
||||
key: t('common.promptEditor.history.item.title'),
|
||||
group: 'prompt history',
|
||||
render: ({ isSelected, onSelect, onSetHighlight }) => {
|
||||
return (
|
||||
<PromptMenuItem
|
||||
title={t('common.promptEditor.history.item.title')}
|
||||
icon={<MessageClockCircle className='w-4 h-4 text-[#DD2590]' />}
|
||||
disabled={!historyBlock.selectable
|
||||
}
|
||||
isSelected={isSelected}
|
||||
onClick={onSelect}
|
||||
onMouseEnter={onSetHighlight}
|
||||
/>
|
||||
)
|
||||
},
|
||||
onSelect: () => {
|
||||
if (!historyBlock?.selectable)
|
||||
return
|
||||
editor.dispatchCommand(INSERT_HISTORY_BLOCK_COMMAND, undefined)
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
return promptOptions
|
||||
}
|
||||
|
||||
export const useVariableOptions = (
|
||||
variableBlock?: VariableBlockType,
|
||||
queryString?: string,
|
||||
) => {
|
||||
): PickerBlockMenuOption[] => {
|
||||
const { t } = useTranslation()
|
||||
const [editor] = useLexicalComposerContext()
|
||||
|
||||
const options = useMemo(() => {
|
||||
const baseOptions = (variableBlock?.variables || []).map((item) => {
|
||||
return new VariableOption(item.value, {
|
||||
icon: <BracketsX className='w-[14px] h-[14px] text-[#2970FF]' />,
|
||||
if (!variableBlock?.variables)
|
||||
return []
|
||||
|
||||
const baseOptions = (variableBlock.variables).map((item) => {
|
||||
return new PickerBlockMenuOption({
|
||||
key: item.value,
|
||||
group: 'prompt variable',
|
||||
render: ({ queryString, isSelected, onSelect, onSetHighlight }) => {
|
||||
return (
|
||||
<VariableMenuItem
|
||||
title={item.value}
|
||||
icon={<BracketsX className='w-[14px] h-[14px] text-[#2970FF]' />}
|
||||
queryString={queryString}
|
||||
isSelected={isSelected}
|
||||
onClick={onSelect}
|
||||
onMouseEnter={onSetHighlight}
|
||||
/>
|
||||
)
|
||||
},
|
||||
onSelect: () => {
|
||||
editor.dispatchCommand(INSERT_VARIABLE_VALUE_BLOCK_COMMAND, `{{${item.value}}}`)
|
||||
},
|
||||
@@ -101,12 +151,25 @@ export const useVariableOptions = (
|
||||
|
||||
const regex = new RegExp(queryString, 'i')
|
||||
|
||||
return baseOptions.filter(option => regex.test(option.title) || option.keywords.some(keyword => regex.test(keyword)))
|
||||
return baseOptions.filter(option => regex.test(option.key))
|
||||
}, [editor, queryString, variableBlock])
|
||||
|
||||
const addOption = useMemo(() => {
|
||||
return new VariableOption(t('common.promptEditor.variable.modal.add'), {
|
||||
icon: <BracketsX className='mr-2 w-[14px] h-[14px] text-[#2970FF]' />,
|
||||
return new PickerBlockMenuOption({
|
||||
key: t('common.promptEditor.variable.modal.add'),
|
||||
group: 'prompt variable',
|
||||
render: ({ queryString, isSelected, onSelect, onSetHighlight }) => {
|
||||
return (
|
||||
<VariableMenuItem
|
||||
title={t('common.promptEditor.variable.modal.add')}
|
||||
icon={<BracketsX className='mr-2 w-[14px] h-[14px] text-[#2970FF]' />}
|
||||
queryString={queryString}
|
||||
isSelected={isSelected}
|
||||
onClick={onSelect}
|
||||
onMouseEnter={onSetHighlight}
|
||||
/>
|
||||
)
|
||||
},
|
||||
onSelect: () => {
|
||||
editor.update(() => {
|
||||
const prefixNode = $createCustomTextNode('{{')
|
||||
@@ -131,16 +194,31 @@ export const useExternalToolOptions = (
|
||||
const [editor] = useLexicalComposerContext()
|
||||
|
||||
const options = useMemo(() => {
|
||||
const baseToolOptions = (externalToolBlockType?.externalTools || []).map((item) => {
|
||||
return new VariableOption(item.name, {
|
||||
icon: (
|
||||
<AppIcon
|
||||
className='!w-[14px] !h-[14px]'
|
||||
icon={item.icon}
|
||||
background={item.icon_background}
|
||||
/>
|
||||
),
|
||||
extraElement: <div className='text-xs text-gray-400'>{item.variableName}</div>,
|
||||
if (!externalToolBlockType?.externalTools)
|
||||
return []
|
||||
const baseToolOptions = (externalToolBlockType.externalTools).map((item) => {
|
||||
return new PickerBlockMenuOption({
|
||||
key: item.name,
|
||||
group: 'external tool',
|
||||
render: ({ queryString, isSelected, onSelect, onSetHighlight }) => {
|
||||
return (
|
||||
<VariableMenuItem
|
||||
title={item.name}
|
||||
icon={
|
||||
<AppIcon
|
||||
className='!w-[14px] !h-[14px]'
|
||||
icon={item.icon}
|
||||
background={item.icon_background}
|
||||
/>
|
||||
}
|
||||
extraElement={<div className='text-xs text-gray-400'>{item.variableName}</div>}
|
||||
queryString={queryString}
|
||||
isSelected={isSelected}
|
||||
onClick={onSelect}
|
||||
onMouseEnter={onSetHighlight}
|
||||
/>
|
||||
)
|
||||
},
|
||||
onSelect: () => {
|
||||
editor.dispatchCommand(INSERT_VARIABLE_VALUE_BLOCK_COMMAND, `{{${item.variableName}}}`)
|
||||
},
|
||||
@@ -151,16 +229,28 @@ export const useExternalToolOptions = (
|
||||
|
||||
const regex = new RegExp(queryString, 'i')
|
||||
|
||||
return baseToolOptions.filter(option => regex.test(option.title) || option.keywords.some(keyword => regex.test(keyword)))
|
||||
return baseToolOptions.filter(option => regex.test(option.key))
|
||||
}, [editor, queryString, externalToolBlockType])
|
||||
|
||||
const addOption = useMemo(() => {
|
||||
return new VariableOption(t('common.promptEditor.variable.modal.addTool'), {
|
||||
icon: <Tool03 className='mr-2 w-[14px] h-[14px] text-[#444CE7]' />,
|
||||
extraElement: <ArrowUpRight className='w-3 h-3 text-gray-400' />,
|
||||
return new PickerBlockMenuOption({
|
||||
key: t('common.promptEditor.variable.modal.addTool'),
|
||||
group: 'external tool',
|
||||
render: ({ queryString, isSelected, onSelect, onSetHighlight }) => {
|
||||
return (
|
||||
<VariableMenuItem
|
||||
title={t('common.promptEditor.variable.modal.addTool')}
|
||||
icon={<Tool03 className='mr-2 w-[14px] h-[14px] text-[#444CE7]' />}
|
||||
extraElement={< ArrowUpRight className='w-3 h-3 text-gray-400' />}
|
||||
queryString={queryString}
|
||||
isSelected={isSelected}
|
||||
onClick={onSelect}
|
||||
onMouseEnter={onSetHighlight}
|
||||
/>
|
||||
)
|
||||
},
|
||||
onSelect: () => {
|
||||
if (externalToolBlockType?.onAddExternalTool)
|
||||
externalToolBlockType.onAddExternalTool()
|
||||
externalToolBlockType?.onAddExternalTool?.()
|
||||
},
|
||||
})
|
||||
}, [externalToolBlockType, t])
|
||||
@@ -191,11 +281,8 @@ export const useOptions = (
|
||||
|
||||
return useMemo(() => {
|
||||
return {
|
||||
promptOptions,
|
||||
variableOptions,
|
||||
externalToolOptions,
|
||||
workflowVariableOptions,
|
||||
allOptions: [...promptOptions, ...variableOptions, ...externalToolOptions],
|
||||
allFlattenOptions: [...promptOptions, ...variableOptions, ...externalToolOptions],
|
||||
}
|
||||
}, [promptOptions, variableOptions, externalToolOptions, workflowVariableOptions])
|
||||
}
|
||||
|
Reference in New Issue
Block a user