mirror of https://github.com/langgenius/dify.git
feat: add picker shower
This commit is contained in:
parent
6caca3aaf7
commit
ada558bedc
|
|
@ -16,7 +16,7 @@ import {
|
|||
} from '@floating-ui/react'
|
||||
|
||||
import type { OffsetOptions, Placement } from '@floating-ui/react'
|
||||
|
||||
import cn from 'classnames'
|
||||
export type PortalToFollowElemOptions = {
|
||||
/*
|
||||
* top, bottom, left, right
|
||||
|
|
@ -129,7 +129,7 @@ React.HTMLProps<HTMLElement> & { asChild?: boolean }
|
|||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className='inline-block'
|
||||
className={cn('inline-block', props.className)}
|
||||
// The user can style the trigger based on the state
|
||||
data-state={context.open ? 'open' : 'closed'}
|
||||
{...context.getReferenceProps(props)}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,19 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import React, { useState } from 'react'
|
||||
import cn from 'classnames'
|
||||
import { mockNodesData } from '../../../mock'
|
||||
import { mockNodeOutputVars, mockNodesData } from '../../../mock'
|
||||
import VarReferencePopup from './var-reference-popup'
|
||||
import type { ValueSelector } from '@/app/components/workflow/types'
|
||||
import { VarBlockIcon } from '@/app/components/workflow/block-icon'
|
||||
import { Line3 } from '@/app/components/base/icons/src/public/common'
|
||||
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
|
||||
import {
|
||||
PortalToFollowElem,
|
||||
PortalToFollowElemContent,
|
||||
PortalToFollowElemTrigger,
|
||||
} from '@/app/components/base/portal-to-follow-elem'
|
||||
|
||||
type Props = {
|
||||
className?: string
|
||||
isShowNodeName: boolean
|
||||
|
|
@ -15,6 +22,14 @@ type Props = {
|
|||
onChange: (value: ValueSelector) => void
|
||||
}
|
||||
|
||||
// const toShowVarType = (type: string) => {
|
||||
// if (['text-input', 'paragraph', 'select', 'url'].includes(type))
|
||||
// return 'String'
|
||||
|
||||
// return type.charAt(0).toUpperCase() + type.substring(1)
|
||||
// }
|
||||
|
||||
// TODO: get data from context
|
||||
const getNodeInfoById = (id: string) => {
|
||||
return mockNodesData[id]
|
||||
}
|
||||
|
|
@ -25,6 +40,7 @@ const VarReferencePicker: FC<Props> = ({
|
|||
isShowNodeName,
|
||||
value,
|
||||
}) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
const hasValue = value.length > 0
|
||||
const node = hasValue ? getNodeInfoById(value[0]) : null
|
||||
const varName = hasValue ? value[value.length - 1] : ''
|
||||
|
|
@ -32,33 +48,48 @@ const VarReferencePicker: FC<Props> = ({
|
|||
const getVarType = () => {
|
||||
return 'string'
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(className, !readonly && 'cursor-pointer')}>
|
||||
<div className={cn('w-full h-8 p-1 rounded-lg bg-gray-100')}>
|
||||
<div className={cn('inline-flex h-full items-center px-1.5 rounded-[5px]', hasValue && 'bg-white')}>
|
||||
{hasValue && (
|
||||
<>
|
||||
{isShowNodeName && (
|
||||
<div className='flex items-center'>
|
||||
<div className='p-[1px]'>
|
||||
<VarBlockIcon
|
||||
className='!text-gray-900'
|
||||
type={node?.type}
|
||||
/>
|
||||
<PortalToFollowElem
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
placement='bottom-start'
|
||||
>
|
||||
<PortalToFollowElemTrigger onClick={() => setOpen(!open)} className='!flex'>
|
||||
<div className={cn('w-full h-8 p-1 rounded-lg bg-gray-100')}>
|
||||
<div className={cn('inline-flex h-full items-center px-1.5 rounded-[5px]', hasValue && 'bg-white')}>
|
||||
{hasValue && (
|
||||
<>
|
||||
{isShowNodeName && (
|
||||
<div className='flex items-center'>
|
||||
<div className='p-[1px]'>
|
||||
<VarBlockIcon
|
||||
className='!text-gray-900'
|
||||
type={node?.type}
|
||||
/>
|
||||
</div>
|
||||
<div className='mx-0.5 text-xs font-medium text-gray-700'>{node?.title}</div>
|
||||
<Line3 className='mr-0.5'></Line3>
|
||||
</div>
|
||||
)}
|
||||
<div className='flex items-center text-primary-600'>
|
||||
<Variable02 className='w-3.5 h-3.5' />
|
||||
<div className='ml-0.5 text-xs font-medium'>{varName}</div>
|
||||
</div>
|
||||
<div className='mx-0.5 text-xs font-medium text-gray-700'>{node?.title}</div>
|
||||
<Line3 className='mr-0.5'></Line3>
|
||||
</div>
|
||||
<div className='ml-0.5 text-xs font-normal text-gray-500'>{getVarType()}</div>
|
||||
</>
|
||||
)}
|
||||
<div className='flex items-center text-primary-600'>
|
||||
<Variable02 className='w-3.5 h-3.5' />
|
||||
<div className='ml-0.5 text-xs font-medium'>{varName}</div>
|
||||
</div>
|
||||
<div className='ml-0.5 text-xs font-normal text-gray-500'>{getVarType()}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent style={{
|
||||
zIndex: 100,
|
||||
width: 227,
|
||||
}}>
|
||||
<VarReferencePopup vars={mockNodeOutputVars} />
|
||||
</PortalToFollowElemContent>
|
||||
</PortalToFollowElem>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import type { NodeOutPutVar } from '@/app/components/workflow/types'
|
||||
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
|
||||
|
||||
type Props = {
|
||||
vars: NodeOutPutVar[]
|
||||
}
|
||||
|
||||
const VarReferencePopup: FC<Props> = ({
|
||||
vars,
|
||||
}) => {
|
||||
return (
|
||||
<div className='p-1 bg-white rounded-lg border border-gray-200 shadow-lg space-y-1'>
|
||||
{vars.map((item, i) => (
|
||||
<div key={i}>
|
||||
<div className='flex items-center h-[22px] px-3 text-xs font-medium text-gray-500 uppercase'>{item.title}</div>
|
||||
{item.vars.map((v, j) => (
|
||||
<div key={j} className='flex items-center h-6 pl-3 pr-[18px] rounded-md cursor-pointer hover:bg-gray-50'>
|
||||
<div className='flex items-center w-0 grow'>
|
||||
<Variable02 className='shrink-0 w-3.5 h-3.5 text-primary-500' />
|
||||
<div className='ml-1 w-0 grow text-ellipsis text-[13px] font-normal text-gray-900'>{v.variable}</div>
|
||||
</div>
|
||||
<div className='ml-1 shrink-0 text-xs font-normal text-gray-500'>{v.type}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default React.memo(VarReferencePopup)
|
||||
|
|
@ -2,7 +2,7 @@ import type { FC } from 'react'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import BasePanel from '../_base/panel'
|
||||
import VarList from '../_base/components/variable/var-list'
|
||||
import useInput from './use-input'
|
||||
import useConfig from './use-config'
|
||||
import { mockLLMNodeData } from './mock'
|
||||
import Field from '@/app/components/workflow/nodes/_base/components/field'
|
||||
import AddButton from '@/app/components/base/button/add-button'
|
||||
|
|
@ -23,10 +23,10 @@ const Panel: FC = () => {
|
|||
handleVarListChange,
|
||||
handleAddVariable,
|
||||
toggleContextEnabled,
|
||||
} = useInput(mockLLMNodeData)
|
||||
} = useConfig(mockLLMNodeData)
|
||||
const model = inputs.model
|
||||
const modelMode = inputs.model?.mode
|
||||
const isChatMode = modelMode === 'chat'
|
||||
// const modelMode = inputs.model?.mode
|
||||
// const isChatMode = modelMode === 'chat'
|
||||
|
||||
return (
|
||||
<BasePanel
|
||||
|
|
|
|||
|
|
@ -1,13 +1,43 @@
|
|||
import type { NodeOutPutVar } from '@/app/components/workflow/types'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
|
||||
export const mockNodesData: Record<string, any> = {
|
||||
aaa: {
|
||||
title: 'Start',
|
||||
type: BlockEnum.Start,
|
||||
|
||||
},
|
||||
bbb: {
|
||||
title: 'Knowledge',
|
||||
type: BlockEnum.KnowledgeRetrieval,
|
||||
},
|
||||
ccc: {
|
||||
title: 'Code',
|
||||
type: BlockEnum.Code,
|
||||
},
|
||||
}
|
||||
|
||||
export const mockNodeOutputVars: NodeOutPutVar[] = [
|
||||
{
|
||||
title: 'Start',
|
||||
vars: [
|
||||
{
|
||||
variable: 'query',
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
variable: 'age',
|
||||
type: 'number',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'LLM',
|
||||
vars: [
|
||||
{
|
||||
variable: 'usage',
|
||||
type: 'object',
|
||||
struct: ['token', 'value'],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -83,6 +83,15 @@ export type LLMNodeData = {
|
|||
}
|
||||
}
|
||||
|
||||
export type NodeOutPutVar = {
|
||||
title: string
|
||||
vars: {
|
||||
variable: string
|
||||
type: string
|
||||
struct?: string[]
|
||||
}[]
|
||||
}
|
||||
|
||||
export type Block = {
|
||||
classification?: string
|
||||
type: BlockEnum
|
||||
|
|
|
|||
Loading…
Reference in New Issue