Feat: upgrade variable assigner (#11285)
Signed-off-by: -LAN- <laipz8200@outlook.com> Co-authored-by: -LAN- <laipz8200@outlook.com>
This commit is contained in:
@@ -33,6 +33,7 @@ export type Props = {
|
||||
showFileList?: boolean
|
||||
onGenerated?: (value: string) => void
|
||||
showCodeGenerator?: boolean
|
||||
className?: string
|
||||
}
|
||||
|
||||
export const languageMap = {
|
||||
@@ -67,6 +68,7 @@ const CodeEditor: FC<Props> = ({
|
||||
showFileList,
|
||||
onGenerated,
|
||||
showCodeGenerator = false,
|
||||
className,
|
||||
}) => {
|
||||
const [isFocus, setIsFocus] = React.useState(false)
|
||||
const [isMounted, setIsMounted] = React.useState(false)
|
||||
@@ -187,7 +189,7 @@ const CodeEditor: FC<Props> = ({
|
||||
)
|
||||
|
||||
return (
|
||||
<div className={cn(isExpand && 'h-full')}>
|
||||
<div className={cn(isExpand && 'h-full', className)}>
|
||||
{noWrapper
|
||||
? <div className='relative no-wrapper' style={{
|
||||
height: isExpand ? '100%' : (editorContentHeight) / 2 + CODE_EDITOR_LINE_HEIGHT, // In IDE, the last line can always be in lop line. So there is some blank space in the bottom.
|
||||
|
@@ -47,7 +47,6 @@ const Field: FC<Props> = ({
|
||||
triggerClassName='w-4 h-4 ml-1'
|
||||
/>
|
||||
)}
|
||||
|
||||
</div>
|
||||
<div className='flex'>
|
||||
{operations && <div>{operations}</div>}
|
||||
|
@@ -10,7 +10,7 @@ const ListNoDataPlaceholder: FC<Props> = ({
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<div className='flex rounded-md bg-gray-50 items-center min-h-[42px] justify-center leading-[18px] text-xs font-normal text-gray-500'>
|
||||
<div className='flex w-full rounded-[10px] bg-background-section items-center min-h-[42px] justify-center system-xs-regular text-text-tertiary'>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
@@ -0,0 +1,39 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import VarReferenceVars from './var-reference-vars'
|
||||
import type { NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types'
|
||||
import ListEmpty from '@/app/components/base/list-empty'
|
||||
|
||||
type Props = {
|
||||
vars: NodeOutPutVar[]
|
||||
onChange: (value: ValueSelector, varDetail: Var) => void
|
||||
itemWidth?: number
|
||||
}
|
||||
const AssignedVarReferencePopup: FC<Props> = ({
|
||||
vars,
|
||||
onChange,
|
||||
itemWidth,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
// max-h-[300px] overflow-y-auto todo: use portal to handle long list
|
||||
return (
|
||||
<div className='p-1 bg-components-panel-bg-bur rounded-lg border-[0.5px] border-components-panel-border shadow-lg w-[352px]' >
|
||||
{(!vars || vars.length === 0)
|
||||
? <ListEmpty
|
||||
title={t('workflow.nodes.assigner.noAssignedVars') || ''}
|
||||
description={t('workflow.nodes.assigner.assignedVarsDescription')}
|
||||
/>
|
||||
: <VarReferenceVars
|
||||
searchBoxClassName='mt-1'
|
||||
vars={vars}
|
||||
onChange={onChange}
|
||||
itemWidth={itemWidth}
|
||||
isSupportFileVar
|
||||
/>
|
||||
}
|
||||
</div >
|
||||
)
|
||||
}
|
||||
export default React.memo(AssignedVarReferencePopup)
|
@@ -60,6 +60,9 @@ type Props = {
|
||||
onRemove?: () => void
|
||||
typePlaceHolder?: string
|
||||
isSupportFileVar?: boolean
|
||||
placeholder?: string
|
||||
minWidth?: number
|
||||
popupFor?: 'assigned' | 'toAssigned'
|
||||
}
|
||||
|
||||
const VarReferencePicker: FC<Props> = ({
|
||||
@@ -83,6 +86,9 @@ const VarReferencePicker: FC<Props> = ({
|
||||
onRemove,
|
||||
typePlaceHolder,
|
||||
isSupportFileVar = true,
|
||||
placeholder,
|
||||
minWidth,
|
||||
popupFor,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const store = useStoreApi()
|
||||
@@ -261,7 +267,7 @@ const VarReferencePicker: FC<Props> = ({
|
||||
<AddButton onClick={() => { }}></AddButton>
|
||||
</div>
|
||||
)
|
||||
: (<div ref={!isSupportConstantValue ? triggerRef : null} className={cn((open || isFocus) ? 'border-gray-300' : 'border-gray-100', 'relative group/wrap flex items-center w-full h-8', !isSupportConstantValue && 'p-1 rounded-lg bg-gray-100 border', isInTable && 'bg-transparent border-none')}>
|
||||
: (<div ref={!isSupportConstantValue ? triggerRef : null} className={cn((open || isFocus) ? 'border-gray-300' : 'border-gray-100', 'relative group/wrap flex items-center w-full h-8', !isSupportConstantValue && 'p-1 rounded-lg bg-gray-100 border', isInTable && 'bg-transparent border-none', readonly && 'bg-components-input-bg-disabled')}>
|
||||
{isSupportConstantValue
|
||||
? <div onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
@@ -285,7 +291,7 @@ const VarReferencePicker: FC<Props> = ({
|
||||
/>
|
||||
</div>
|
||||
: (!hasValue && <div className='ml-1.5 mr-1'>
|
||||
<Variable02 className='w-3.5 h-3.5 text-gray-400' />
|
||||
<Variable02 className={`w-4 h-4 ${readonly ? 'text-components-input-text-disabled' : 'text-components-input-text-placeholder'}`} />
|
||||
</div>)}
|
||||
{isConstant
|
||||
? (
|
||||
@@ -329,17 +335,17 @@ const VarReferencePicker: FC<Props> = ({
|
||||
{!hasValue && <Variable02 className='w-3.5 h-3.5' />}
|
||||
{isEnv && <Env className='w-3.5 h-3.5 text-util-colors-violet-violet-600' />}
|
||||
{isChatVar && <BubbleX className='w-3.5 h-3.5 text-util-colors-teal-teal-700' />}
|
||||
<div className={cn('ml-0.5 text-xs font-medium truncate', (isEnv || isChatVar) && '!text-text-secondary')} title={varName} style={{
|
||||
<div className={cn('ml-0.5 text-xs font-medium truncate', isEnv && '!text-text-secondary', isChatVar && 'text-util-colors-teal-teal-700')} title={varName} style={{
|
||||
maxWidth: maxVarNameWidth,
|
||||
}}>{varName}</div>
|
||||
</div>
|
||||
<div className='ml-0.5 text-xs font-normal text-gray-500 capitalize truncate' title={type} style={{
|
||||
<div className='ml-0.5 capitalize truncate text-text-tertiary text-center system-xs-regular' title={type} style={{
|
||||
maxWidth: maxTypeWidth,
|
||||
}}>{type}</div>
|
||||
{!isValidVar && <RiErrorWarningFill className='ml-0.5 w-3 h-3 text-[#D92D20]' />}
|
||||
</>
|
||||
)
|
||||
: <div className='text-[13px] font-normal text-gray-400'>{t('workflow.common.setVarValuePlaceholder')}</div>}
|
||||
: <div className={`overflow-hidden ${readonly ? 'text-components-input-text-disabled' : 'text-components-input-text-placeholder'} text-ellipsis system-sm-regular`}>{placeholder ?? t('workflow.common.setVarValuePlaceholder')}</div>}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
@@ -378,12 +384,13 @@ const VarReferencePicker: FC<Props> = ({
|
||||
</WrapElem>
|
||||
<PortalToFollowElemContent style={{
|
||||
zIndex: 100,
|
||||
}}>
|
||||
}} className='mt-1'>
|
||||
{!isConstant && (
|
||||
<VarReferencePopup
|
||||
vars={outputVars}
|
||||
popupFor={popupFor}
|
||||
onChange={handleVarReferenceChange}
|
||||
itemWidth={isAddBtnTrigger ? 260 : triggerWidth}
|
||||
itemWidth={isAddBtnTrigger ? 260 : (minWidth || triggerWidth)}
|
||||
isSupportFileVar={isSupportFileVar}
|
||||
/>
|
||||
)}
|
||||
|
@@ -1,33 +1,64 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import VarReferenceVars from './var-reference-vars'
|
||||
import type { NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types'
|
||||
import ListEmpty from '@/app/components/base/list-empty'
|
||||
import { LanguagesSupported } from '@/i18n/language'
|
||||
import I18n from '@/context/i18n'
|
||||
|
||||
type Props = {
|
||||
vars: NodeOutPutVar[]
|
||||
popupFor?: 'assigned' | 'toAssigned'
|
||||
onChange: (value: ValueSelector, varDetail: Var) => void
|
||||
itemWidth?: number
|
||||
isSupportFileVar?: boolean
|
||||
}
|
||||
const VarReferencePopup: FC<Props> = ({
|
||||
vars,
|
||||
popupFor,
|
||||
onChange,
|
||||
itemWidth,
|
||||
isSupportFileVar = true,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { locale } = useContext(I18n)
|
||||
// max-h-[300px] overflow-y-auto todo: use portal to handle long list
|
||||
return (
|
||||
<div className='p-1 bg-white rounded-lg border border-gray-200 shadow-lg space-y-1' style={{
|
||||
width: itemWidth || 228,
|
||||
}}>
|
||||
<VarReferenceVars
|
||||
searchBoxClassName='mt-1'
|
||||
vars={vars}
|
||||
onChange={onChange}
|
||||
itemWidth={itemWidth}
|
||||
isSupportFileVar={isSupportFileVar}
|
||||
/>
|
||||
{((!vars || vars.length === 0) && popupFor)
|
||||
? (popupFor === 'toAssigned'
|
||||
? (
|
||||
<ListEmpty
|
||||
title={t('workflow.variableReference.noAvailableVars') || ''}
|
||||
description={<div className='text-text-tertiary system-xs-regular'>
|
||||
{t('workflow.variableReference.noVarsForOperation')}
|
||||
</div>}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<ListEmpty
|
||||
title={t('workflow.variableReference.noAssignedVars') || ''}
|
||||
description={<div className='text-text-tertiary system-xs-regular'>
|
||||
{t('workflow.variableReference.assignedVarsDescription')}
|
||||
<a target='_blank' rel='noopener noreferrer'
|
||||
className='text-text-accent-secondary'
|
||||
href={locale !== LanguagesSupported[1] ? 'https://docs.dify.ai/guides/workflow/variables#conversation-variables' : `https://docs.dify.ai/${locale.toLowerCase()}/guides/workflow/variables#hui-hua-bian-liang`}>{t('workflow.variableReference.conversationVars')}</a>
|
||||
</div>}
|
||||
/>
|
||||
))
|
||||
: <VarReferenceVars
|
||||
searchBoxClassName='mt-1'
|
||||
vars={vars}
|
||||
onChange={onChange}
|
||||
itemWidth={itemWidth}
|
||||
isSupportFileVar={isSupportFileVar}
|
||||
/>
|
||||
}
|
||||
</div >
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user