|
@@ -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])
|
|
|
}
|