node selector of base field

This commit is contained in:
JzoNg 2025-09-15 15:39:46 +08:00
parent 612112c919
commit 2cd9d1066f
4 changed files with 89 additions and 6 deletions

View File

@ -33,6 +33,7 @@ import PromptGeneratorBtn from '@/app/components/workflow/nodes/llm/components/p
import Slider from '@/app/components/base/slider'
import Tooltip from '@/app/components/base/tooltip'
import Switch from '../../../switch'
import NodeSelector from '@/app/components/workflow/panel/chat-variable-panel/components/node-selector'
export type BaseFieldProps = {
fieldClassName?: string
@ -168,7 +169,7 @@ const BaseField = ({
<RiArrowDownSFill
className={cn(
'h-4 w-4 text-text-quaternary',
value && '-rotate-90',
!value && '-rotate-90',
)}
/>
)
@ -412,6 +413,14 @@ const BaseField = ({
/>
)
}
{
type === FormTypeEnum.nodeSelector && (
<NodeSelector
value={value}
onChange={handleChange}
/>
)
}
{
type === FormTypeEnum.boolean && (
<Radio.Group

View File

@ -42,6 +42,7 @@ export enum FormTypeEnum {
boolean = 'boolean',
booleanList = 'boolean-list',
switch = 'switch',
nodeSelector = 'node-selector', // used in memory variable form
}
export type FormOption = {

View File

@ -0,0 +1,55 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import {
useNodes,
} from 'reactflow'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import type {
CommonNodeType,
} from '@/app/components/workflow/types'
import { BlockEnum } from '@/app/components/workflow/types'
type Props = {
value: boolean
onChange: (value: boolean) => void
nodeType?: BlockEnum
}
const NodeSelector: FC<Props> = ({
value,
onChange,
nodeType = BlockEnum.LLM,
}) => {
const [open, setOpen] = useState(false)
const nodes = useNodes<CommonNodeType>()
const filteredNodes = nodeType ? nodes.filter(node => node.data?.type === nodeType) : nodes
return (
<PortalToFollowElem
open={open}
onOpenChange={setOpen}
placement='bottom-end'
offset={4}
>
<PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
<span>Select Node</span>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[25]'>
<div className='rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg p-1 shadow-lg'>
{filteredNodes.map(node => (
<div key={node.id} className=''>
{node.data?.title}
</div>
))}
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)
}
export default React.memo(NodeSelector)

View File

@ -94,14 +94,14 @@ export const useMemorySchema = () => {
fieldClassName: 'flex justify-between',
inputClassName: 'w-[102px]',
options: [
{
label: 'Conversation',
value: 'conversation',
},
{
label: 'App',
value: 'app',
},
{
label: 'Node',
value: 'node',
},
],
show_on: [
{
@ -113,6 +113,24 @@ export const useMemorySchema = () => {
withTopDivider: true,
},
},
{
name: 'node',
label: 'Node',
type: FormTypeEnum.nodeSelector,
fieldClassName: 'flex justify-between',
inputClassName: 'w-[102px]',
default: '',
show_on: [
{
variable: 'value_type',
value: [ChatVarType.Memory],
},
{
variable: 'scope',
value: 'node',
},
],
},
{
name: 'term',
label: 'Term',
@ -216,7 +234,7 @@ export const useMemoryDefaultValues = () => {
instruction: '',
strategy: 'on_turns',
update_turns: 0,
scope: 'conversation',
scope: 'app',
term: 'session',
more: false,
model: '',