mirror of https://github.com/langgenius/dify.git
feat: in placeholder choose var
This commit is contained in:
parent
e5a2172a85
commit
fda19d3f0e
|
|
@ -37,6 +37,10 @@ const InputField: React.FC<Props> = ({
|
|||
if (!draft.placeholder)
|
||||
draft.placeholder = { type: 'const', selector: [], value: '' }
|
||||
draft.placeholder[key] = value
|
||||
if(key === 'selector')
|
||||
draft.placeholder.type = 'variable'
|
||||
else if(key === 'value')
|
||||
draft.placeholder.type = 'const'
|
||||
})
|
||||
setTempPayload(nextValue)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,11 @@ type Props = {
|
|||
const i18nPrefix = 'workflow.nodes.humanInput.insertInputField'
|
||||
|
||||
type PlaceholderProps = {
|
||||
varPickerProps: any
|
||||
onTypeClick: (isVariable: boolean) => void
|
||||
}
|
||||
const Placeholder = ({
|
||||
varPickerProps,
|
||||
onTypeClick,
|
||||
}: PlaceholderProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
|
@ -35,7 +37,12 @@ const Placeholder = ({
|
|||
i18nKey={`${i18nPrefix}.prePopulateFieldPlaceholder`}
|
||||
components={{
|
||||
staticContent: <TagLabel type='edit' className='mx-1' onClick={() => onTypeClick(false)}>{t(`${i18nPrefix}.staticContent`)}</TagLabel>,
|
||||
variable: <TagLabel type='variable' className='mx-1' onClick={() => onTypeClick(true)}>{t(`${i18nPrefix}.variable`)}</TagLabel>,
|
||||
variable: <VarReferencePicker
|
||||
{...varPickerProps}
|
||||
trigger={
|
||||
<TagLabel type='variable' className='mx-1'>{t(`${i18nPrefix}.variable`)}</TagLabel>
|
||||
}
|
||||
/>,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -60,19 +67,23 @@ const PrePopulate: FC<Props> = ({
|
|||
|
||||
const [isFocus, setIsFocus] = useState(false)
|
||||
|
||||
const varPickerProps = {
|
||||
nodeId,
|
||||
value: valueSelector || [],
|
||||
onChange: onValueSelectorChange!,
|
||||
readonly: false,
|
||||
zIndex: 1000,
|
||||
}
|
||||
|
||||
const isShowPlaceholder = !onPlaceholderClicked && (isVariable ? (!valueSelector || valueSelector.length === 0) : !value)
|
||||
if (isShowPlaceholder)
|
||||
return <Placeholder onTypeClick={handleTypeChange} />
|
||||
return <Placeholder varPickerProps={varPickerProps} onTypeClick={handleTypeChange} />
|
||||
|
||||
if (isVariable) {
|
||||
return (
|
||||
<div>
|
||||
<VarReferencePicker
|
||||
nodeId={nodeId}
|
||||
value={valueSelector || []}
|
||||
onChange={onValueSelectorChange!}
|
||||
readonly={false}
|
||||
zIndex={1000}
|
||||
{...varPickerProps}
|
||||
/>
|
||||
<TypeSwitch isVariable={isVariable} onIsVariableChange={handleTypeChange} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ type Props = {
|
|||
filterVar?: (payload: Var, valueSelector: ValueSelector) => boolean
|
||||
availableNodes?: Node[]
|
||||
availableVars?: NodeOutPutVar[]
|
||||
trigger?: React.ReactNode
|
||||
isAddBtnTrigger?: boolean
|
||||
schema?: Partial<CredentialFormSchema>
|
||||
valueTypePlaceHolder?: string
|
||||
|
|
@ -92,6 +93,7 @@ const VarReferencePicker: FC<Props> = ({
|
|||
filterVar = () => true,
|
||||
availableNodes: passedInAvailableNodes,
|
||||
availableVars: passedInAvailableVars,
|
||||
trigger,
|
||||
isAddBtnTrigger,
|
||||
schema,
|
||||
valueTypePlaceHolder,
|
||||
|
|
@ -392,156 +394,159 @@ const VarReferencePicker: FC<Props> = ({
|
|||
onOpenChange={setOpen}
|
||||
placement={isAddBtnTrigger ? 'bottom-end' : 'bottom-start'}
|
||||
>
|
||||
<WrapElem onClick={() => {
|
||||
if (readonly)
|
||||
return
|
||||
!isConstant ? setOpen(!open) : setControlFocus(Date.now())
|
||||
}} className='group/picker-trigger-wrap relative !flex'>
|
||||
<>
|
||||
{isAddBtnTrigger
|
||||
? (
|
||||
<div>
|
||||
<AddButton onClick={noop}></AddButton>
|
||||
</div>
|
||||
)
|
||||
: (<div ref={!isSupportConstantValue ? triggerRef : null} className={cn((open || isFocus) ? 'border-gray-300' : 'border-gray-100', 'group/wrap relative flex h-8 w-full items-center', !isSupportConstantValue && 'rounded-lg bg-components-input-bg-normal p-1', isInTable && 'border-none bg-transparent', readonly && 'bg-components-input-bg-disabled')}>
|
||||
{isSupportConstantValue
|
||||
? <div onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
setOpen(false)
|
||||
setControlFocus(Date.now())
|
||||
}} className='mr-1 flex h-full items-center space-x-1'>
|
||||
<TypeSelector
|
||||
noLeft
|
||||
trigger={
|
||||
<div className='radius-md flex h-8 items-center bg-components-input-bg-normal px-2'>
|
||||
<div className='system-sm-regular mr-1 text-components-input-text-filled'>{varKindTypes.find(item => item.value === varKindType)?.label}</div>
|
||||
<RiArrowDownSLine className='h-4 w-4 text-text-quaternary' />
|
||||
</div>
|
||||
}
|
||||
popupClassName='top-8'
|
||||
readonly={readonly}
|
||||
value={varKindType}
|
||||
options={varKindTypes}
|
||||
onChange={handleVarKindTypeChange}
|
||||
showChecked
|
||||
/>
|
||||
{trigger && <PortalToFollowElemTrigger onClick={() => setOpen(!open)}>{trigger}</PortalToFollowElemTrigger>}
|
||||
{!trigger && (
|
||||
<WrapElem onClick={() => {
|
||||
if (readonly)
|
||||
return
|
||||
!isConstant ? setOpen(!open) : setControlFocus(Date.now())
|
||||
}} className='group/picker-trigger-wrap relative !flex'>
|
||||
<>
|
||||
{isAddBtnTrigger
|
||||
? (
|
||||
<div>
|
||||
<AddButton onClick={noop}></AddButton>
|
||||
</div>
|
||||
: (!hasValue && <div className='ml-1.5 mr-1'>
|
||||
<Variable02 className={`h-4 w-4 ${readonly ? 'text-components-input-text-disabled' : 'text-components-input-text-placeholder'}`} />
|
||||
</div>)}
|
||||
{isConstant
|
||||
? (
|
||||
<ConstantField
|
||||
value={value as string}
|
||||
onChange={onChange as ((value: string | number, varKindType: VarKindType, varInfo?: Var) => void)}
|
||||
schema={schemaWithDynamicSelect as CredentialFormSchema}
|
||||
readonly={readonly}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<VarPickerWrap
|
||||
onClick={() => {
|
||||
if (readonly)
|
||||
return
|
||||
!isConstant ? setOpen(!open) : setControlFocus(Date.now())
|
||||
}}
|
||||
className='h-full grow'
|
||||
>
|
||||
<div ref={isSupportConstantValue ? triggerRef : null} className={cn('h-full', isSupportConstantValue && 'flex items-center rounded-lg bg-components-panel-bg py-1 pl-1')}>
|
||||
<Tooltip noDecoration={isShowAPart} popupContent={tooltipPopup}>
|
||||
<div className={cn('h-full items-center rounded-[5px] px-1.5', hasValue ? 'inline-flex bg-components-badge-white-to-dark' : 'flex')}>
|
||||
{hasValue
|
||||
? (
|
||||
<>
|
||||
{isShowNodeName && !isEnv && !isChatVar && (
|
||||
<div className='flex items-center' onClick={(e) => {
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
e.stopPropagation()
|
||||
handleVariableJump(outputVarNode?.id)
|
||||
}
|
||||
}}>
|
||||
<div className='h-3 px-[1px]'>
|
||||
{outputVarNode?.type && <VarBlockIcon
|
||||
className='!text-text-primary'
|
||||
type={outputVarNode.type}
|
||||
/>}
|
||||
</div>
|
||||
<div className='mx-0.5 truncate text-xs font-medium text-text-secondary' title={outputVarNode?.title} style={{
|
||||
maxWidth: maxNodeNameWidth,
|
||||
}}>{outputVarNode?.title}</div>
|
||||
<Line3 className='mr-0.5'></Line3>
|
||||
</div>
|
||||
)}
|
||||
{isShowAPart && (
|
||||
<div className='flex items-center'>
|
||||
<RiMoreLine className='h-3 w-3 text-text-secondary' />
|
||||
<Line3 className='mr-0.5 text-divider-deep'></Line3>
|
||||
</div>
|
||||
)}
|
||||
<div className='flex items-center text-text-accent'>
|
||||
{isLoading && <RiLoader4Line className='h-3.5 w-3.5 animate-spin text-text-secondary' />}
|
||||
<VariableIconWithColor
|
||||
variableCategory={variableCategory}
|
||||
isExceptionVariable={isException}
|
||||
/>
|
||||
<div className={cn('ml-0.5 truncate text-xs font-medium', isEnv && '!text-text-secondary', isChatVar && 'text-util-colors-teal-teal-700', isException && 'text-text-warning')} title={varName} style={{
|
||||
maxWidth: maxVarNameWidth,
|
||||
}}>{varName}</div>
|
||||
</div>
|
||||
<div className='system-xs-regular ml-0.5 truncate text-center capitalize text-text-tertiary' title={type} style={{
|
||||
maxWidth: maxTypeWidth,
|
||||
}}>{type}</div>
|
||||
{!isValidVar && <RiErrorWarningFill className='ml-0.5 h-3 w-3 text-text-destructive' />}
|
||||
</>
|
||||
)
|
||||
: <div className={`overflow-hidden ${readonly ? 'text-components-input-text-disabled' : 'text-components-input-text-placeholder'} system-sm-regular text-ellipsis`}>
|
||||
{isLoading ? (
|
||||
<div className='flex items-center'>
|
||||
<RiLoader4Line className='mr-1 h-3.5 w-3.5 animate-spin text-text-secondary' />
|
||||
<span>{placeholder ?? t('workflow.common.setVarValuePlaceholder')}</span>
|
||||
</div>
|
||||
) : (
|
||||
placeholder ?? t('workflow.common.setVarValuePlaceholder')
|
||||
)}
|
||||
</div>}
|
||||
)
|
||||
: (<div ref={!isSupportConstantValue ? triggerRef : null} className={cn((open || isFocus) ? 'border-gray-300' : 'border-gray-100', 'group/wrap relative flex h-8 w-full items-center', !isSupportConstantValue && 'rounded-lg bg-components-input-bg-normal p-1', isInTable && 'border-none bg-transparent', readonly && 'bg-components-input-bg-disabled')}>
|
||||
{isSupportConstantValue
|
||||
? <div onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
setOpen(false)
|
||||
setControlFocus(Date.now())
|
||||
}} className='mr-1 flex h-full items-center space-x-1'>
|
||||
<TypeSelector
|
||||
noLeft
|
||||
trigger={
|
||||
<div className='radius-md flex h-8 items-center bg-components-input-bg-normal px-2'>
|
||||
<div className='system-sm-regular mr-1 text-components-input-text-filled'>{varKindTypes.find(item => item.value === varKindType)?.label}</div>
|
||||
<RiArrowDownSLine className='h-4 w-4 text-text-quaternary' />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
}
|
||||
popupClassName='top-8'
|
||||
readonly={readonly}
|
||||
value={varKindType}
|
||||
options={varKindTypes}
|
||||
onChange={handleVarKindTypeChange}
|
||||
showChecked
|
||||
/>
|
||||
</div>
|
||||
: (!hasValue && <div className='ml-1.5 mr-1'>
|
||||
<Variable02 className={`h-4 w-4 ${readonly ? 'text-components-input-text-disabled' : 'text-components-input-text-placeholder'}`} />
|
||||
</div>)}
|
||||
{isConstant
|
||||
? (
|
||||
<ConstantField
|
||||
value={value as string}
|
||||
onChange={onChange as ((value: string | number, varKindType: VarKindType, varInfo?: Var) => void)}
|
||||
schema={schemaWithDynamicSelect as CredentialFormSchema}
|
||||
readonly={readonly}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<VarPickerWrap
|
||||
onClick={() => {
|
||||
if (readonly)
|
||||
return
|
||||
!isConstant ? setOpen(!open) : setControlFocus(Date.now())
|
||||
}}
|
||||
className='h-full grow'
|
||||
>
|
||||
<div ref={isSupportConstantValue ? triggerRef : null} className={cn('h-full', isSupportConstantValue && 'flex items-center rounded-lg bg-components-panel-bg py-1 pl-1')}>
|
||||
<Tooltip noDecoration={isShowAPart} popupContent={tooltipPopup}>
|
||||
<div className={cn('h-full items-center rounded-[5px] px-1.5', hasValue ? 'inline-flex bg-components-badge-white-to-dark' : 'flex')}>
|
||||
{hasValue
|
||||
? (
|
||||
<>
|
||||
{isShowNodeName && !isEnv && !isChatVar && (
|
||||
<div className='flex items-center' onClick={(e) => {
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
e.stopPropagation()
|
||||
handleVariableJump(outputVarNode?.id)
|
||||
}
|
||||
}}>
|
||||
<div className='h-3 px-[1px]'>
|
||||
{outputVarNode?.type && <VarBlockIcon
|
||||
className='!text-text-primary'
|
||||
type={outputVarNode.type}
|
||||
/>}
|
||||
</div>
|
||||
<div className='mx-0.5 truncate text-xs font-medium text-text-secondary' title={outputVarNode?.title} style={{
|
||||
maxWidth: maxNodeNameWidth,
|
||||
}}>{outputVarNode?.title}</div>
|
||||
<Line3 className='mr-0.5'></Line3>
|
||||
</div>
|
||||
)}
|
||||
{isShowAPart && (
|
||||
<div className='flex items-center'>
|
||||
<RiMoreLine className='h-3 w-3 text-text-secondary' />
|
||||
<Line3 className='mr-0.5 text-divider-deep'></Line3>
|
||||
</div>
|
||||
)}
|
||||
<div className='flex items-center text-text-accent'>
|
||||
{isLoading && <RiLoader4Line className='h-3.5 w-3.5 animate-spin text-text-secondary' />}
|
||||
<VariableIconWithColor
|
||||
variableCategory={variableCategory}
|
||||
isExceptionVariable={isException}
|
||||
/>
|
||||
<div className={cn('ml-0.5 truncate text-xs font-medium', isEnv && '!text-text-secondary', isChatVar && 'text-util-colors-teal-teal-700', isException && 'text-text-warning')} title={varName} style={{
|
||||
maxWidth: maxVarNameWidth,
|
||||
}}>{varName}</div>
|
||||
</div>
|
||||
<div className='system-xs-regular ml-0.5 truncate text-center capitalize text-text-tertiary' title={type} style={{
|
||||
maxWidth: maxTypeWidth,
|
||||
}}>{type}</div>
|
||||
{!isValidVar && <RiErrorWarningFill className='ml-0.5 h-3 w-3 text-text-destructive' />}
|
||||
</>
|
||||
)
|
||||
: <div className={`overflow-hidden ${readonly ? 'text-components-input-text-disabled' : 'text-components-input-text-placeholder'} system-sm-regular text-ellipsis`}>
|
||||
{isLoading ? (
|
||||
<div className='flex items-center'>
|
||||
<RiLoader4Line className='mr-1 h-3.5 w-3.5 animate-spin text-text-secondary' />
|
||||
<span>{placeholder ?? t('workflow.common.setVarValuePlaceholder')}</span>
|
||||
</div>
|
||||
) : (
|
||||
placeholder ?? t('workflow.common.setVarValuePlaceholder')
|
||||
)}
|
||||
</div>}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
</VarPickerWrap>
|
||||
</VarPickerWrap>
|
||||
)}
|
||||
{(hasValue && !readonly && !isInTable) && (<div
|
||||
className='group invisible absolute right-1 top-[50%] h-5 translate-y-[-50%] cursor-pointer rounded-md p-1 hover:bg-state-base-hover group-hover/wrap:visible'
|
||||
onClick={handleClearVar}
|
||||
>
|
||||
<RiCloseLine className='h-3.5 w-3.5 text-text-tertiary group-hover:text-text-secondary' />
|
||||
</div>)}
|
||||
{!hasValue && valueTypePlaceHolder && (
|
||||
<Badge
|
||||
className=' absolute right-1 top-[50%] translate-y-[-50%] capitalize'
|
||||
text={valueTypePlaceHolder}
|
||||
uppercase={false}
|
||||
/>
|
||||
)}
|
||||
{(hasValue && !readonly && !isInTable) && (<div
|
||||
className='group invisible absolute right-1 top-[50%] h-5 translate-y-[-50%] cursor-pointer rounded-md p-1 hover:bg-state-base-hover group-hover/wrap:visible'
|
||||
onClick={handleClearVar}
|
||||
>
|
||||
<RiCloseLine className='h-3.5 w-3.5 text-text-tertiary group-hover:text-text-secondary' />
|
||||
</div>)}
|
||||
{!hasValue && valueTypePlaceHolder && (
|
||||
<Badge
|
||||
className=' absolute right-1 top-[50%] translate-y-[-50%] capitalize'
|
||||
text={valueTypePlaceHolder}
|
||||
uppercase={false}
|
||||
/>
|
||||
)}
|
||||
</div>)}
|
||||
{!readonly && isInTable && (
|
||||
<RemoveButton
|
||||
className='absolute right-1 top-0.5 hidden group-hover/picker-trigger-wrap:block'
|
||||
onClick={() => onRemove?.()}
|
||||
/>
|
||||
)}
|
||||
{!readonly && isInTable && (
|
||||
<RemoveButton
|
||||
className='absolute right-1 top-0.5 hidden group-hover/picker-trigger-wrap:block'
|
||||
onClick={() => onRemove?.()}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!hasValue && typePlaceHolder && (
|
||||
<Badge
|
||||
className='absolute right-2 top-1.5'
|
||||
text={typePlaceHolder}
|
||||
uppercase={false}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
</WrapElem>
|
||||
{!hasValue && typePlaceHolder && (
|
||||
<Badge
|
||||
className='absolute right-2 top-1.5'
|
||||
text={typePlaceHolder}
|
||||
uppercase={false}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
</WrapElem>
|
||||
)}
|
||||
<PortalToFollowElemContent style={{
|
||||
zIndex: zIndex || 100,
|
||||
}} className='mt-1'>
|
||||
|
|
|
|||
Loading…
Reference in New Issue