feat: api support var logic

This commit is contained in:
Joel 2024-03-29 14:56:32 +08:00
parent 8d2ac8ff8f
commit 12ed31be4d
6 changed files with 133 additions and 28 deletions

View File

@ -51,6 +51,7 @@ import type {
export type PromptEditorProps = {
className?: string
placeholder?: string
style?: React.CSSProperties
value?: string
editable?: boolean
@ -99,6 +100,7 @@ export type PromptEditorProps = {
const PromptEditor: FC<PromptEditorProps> = ({
className,
placeholder,
style,
value,
editable = true,
@ -139,7 +141,7 @@ const PromptEditor: FC<PromptEditorProps> = ({
show: true,
selectable: true,
variables: [],
getWorkflowNode: () => {},
getWorkflowNode: () => { },
onInsert: () => { },
onDelete: () => { },
},
@ -189,7 +191,7 @@ const PromptEditor: FC<PromptEditorProps> = ({
<div className='relative'>
<RichTextPlugin
contentEditable={<ContentEditable className={`${className} outline-none text-sm text-gray-700 leading-6`} style={style || {}} />}
placeholder={<Placeholder />}
placeholder={<Placeholder value={placeholder} />}
ErrorBoundary={LexicalErrorBoundary}
/>
<ComponentPicker

View File

@ -1,11 +1,15 @@
import { useTranslation } from 'react-i18next'
const Placeholder = () => {
const Placeholder = ({
value,
}: {
value?: string
}) => {
const { t } = useTranslation()
return (
<div className='absolute top-0 left-0 h-full w-full text-sm text-gray-300 select-none pointer-events-none leading-6'>
{t('common.promptEditor.placeholder')}
{value || t('common.promptEditor.placeholder')}
</div>
)
}

View File

@ -0,0 +1,95 @@
'use client'
import type { FC } from 'react'
import React, { useEffect } from 'react'
import cn from 'classnames'
import { useBoolean } from 'ahooks'
import { useWorkflow } from '@/app/components/workflow/hooks'
import type { NodeOutPutVar } from '@/app/components/workflow/types'
import PromptEditor from '@/app/components/base/prompt-editor'
type Props = {
className?: string
placeholder?: string
promptMinHeightClassName?: string
value: string
onChange: (value: string) => void
onFocusChange?: (value: boolean) => void
readOnly?: boolean
justVar?: boolean
nodesOutputVars?: NodeOutPutVar[]
}
const Editor: FC<Props> = ({
className,
placeholder,
promptMinHeightClassName = 'min-h-[30px]',
value,
onChange,
onFocusChange,
readOnly,
nodesOutputVars,
}) => {
// const { t } = useTranslation()
const { getNode } = useWorkflow()
const [isFocus, {
setTrue: setFocus,
setFalse: setBlur,
}] = useBoolean(false)
useEffect(() => {
onFocusChange?.(isFocus)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFocus])
return (
<div className={cn(className, 'relative')}>
<>
<PromptEditor
className={cn(promptMinHeightClassName)}
// style={isExpand ? { height: editorExpandHeight - 5 } : {}}
placeholder={placeholder}
value={value}
outToolDisabled
canNotAddContext
contextBlock={{
show: false,
selectable: false,
datasets: [],
onAddContext: () => { },
}}
variableBlock={{
variables: [],
externalTools: [],
onAddExternalTool: () => { },
}}
historyBlock={{
show: false,
selectable: false,
history: {
user: 'Human',
assistant: 'Assistant',
},
onEditRole: () => { },
}}
queryBlock={{
show: false,
selectable: false,
}}
workflowVariableBlock={{
show: true,
selectable: true,
variables: nodesOutputVars || [],
getWorkflowNode: getNode,
}}
onChange={onChange}
editable={!readOnly}
onBlur={setBlur}
onFocus={setFocus}
/>
{/* to patch Editor not support dynamic change editable status */}
{readOnly && <div className='absolute inset-0 z-10'></div>}
</>
</div >
)
}
export default React.memo(Editor)

View File

@ -53,8 +53,6 @@ const Editor: FC<Props> = ({
const { t } = useTranslation()
const { getNode } = useWorkflow()
console.log(nodesOutputVars, '2')
const isShowHistory = !isChatModel && isChatApp
const isShowQuery = isShowHistory

View File

@ -1,12 +1,14 @@
'use client'
import type { FC } from 'react'
import React, { useCallback, useEffect, useRef } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import cn from 'classnames'
import { useBoolean } from 'ahooks'
import { Method } from '../types'
import Selector from '../../_base/components/selector'
import useAvailableVarList from '../../_base/hooks/use-available-var-list'
import { VarType } from '../../../types'
import type { Var } from '../../../types'
import Input from '@/app/components/workflow/nodes/_base/components/input-support-select-var'
import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows'
import SupportVarInput from '@/app/components/workflow/nodes/_base/components/support-var-input'
const MethodOptions = [
{ label: 'GET', value: Method.get },
@ -17,6 +19,7 @@ const MethodOptions = [
{ label: 'DELETE', value: Method.delete },
]
type Props = {
nodeId: string
readonly: boolean
method: Method
onMethodChange: (method: Method) => void
@ -25,27 +28,28 @@ type Props = {
}
const ApiInput: FC<Props> = ({
nodeId,
readonly,
method,
onMethodChange,
url,
onUrlChange,
}) => {
const handleUrlChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
onUrlChange(e.target.value)
}, [onUrlChange])
const inputRef = useRef<HTMLInputElement>(null)
const [isFocus, {
setTrue: onFocus,
setFalse: onBlur,
}] = useBoolean(false)
const [isFocus, setIsFocus] = useState(false)
const availableVarList = useAvailableVarList(nodeId, {
onlyLeafNodeVar: false,
filterVar: (varPayload: Var) => {
return [VarType.string, VarType.number].includes(varPayload.type)
},
})
useEffect(() => {
if (isFocus)
inputRef.current?.focus()
}, [isFocus])
return (
<div className='flex items-center h-8 rounded-lg bg-white border border-gray-200 shadow-xs'>
<div className='flex items-start space-x-1'>
<Selector
value={method}
onChange={onMethodChange}
@ -60,14 +64,8 @@ const ApiInput: FC<Props> = ({
showChecked
readonly={readonly}
/>
<SupportVarInput
isFocus={isFocus}
onFocus={onFocus}
value={url}
wrapClassName='flex h-[30px] items-center'
textClassName='!h-6 leading-6 px-2.5 text-gray-900 text-[13px]'
>
<input
{/* <input
type='text'
readOnly={readonly}
value={url}
@ -76,8 +74,15 @@ const ApiInput: FC<Props> = ({
onBlur={onBlur}
className='w-full h-6 leading-6 px-2.5 border-0 text-gray-900 text-[13px] placeholder:text-gray-400 focus:outline-none'
ref={inputRef}
/>
</SupportVarInput>
/> */}
<Input
className='w-0 grow rounded-lg px-3 bg-white border border-gray-200 shadow-xs'
value={url}
onChange={onUrlChange}
readOnly={readonly}
nodesOutputVars={availableVarList}
onFocusChange={setIsFocus}
/>
</div >
)
}

View File

@ -94,6 +94,7 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
}
>
<ApiInput
nodeId={id}
readonly={readOnly}
method={inputs.method}
onMethodChange={handleMethodChange}