mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-19 09:15:52 +08:00
feat: files attr select
This commit is contained in:
parent
ae098ad121
commit
6549519fa5
@ -96,7 +96,7 @@ const Select: FC<ISelectProps> = ({
|
||||
<div className='group text-gray-800'>
|
||||
{allowSearch
|
||||
? <Combobox.Input
|
||||
className={`w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200 cursor-not-allowed`}
|
||||
className={classNames('w-full rounded-lg border-0 py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200 cursor-not-allowed', bgClassName)}
|
||||
onChange={(event) => {
|
||||
if (!disabled)
|
||||
setQuery(event.target.value)
|
||||
@ -200,7 +200,7 @@ const SimpleSelect: FC<ISelectProps> = ({
|
||||
}}
|
||||
>
|
||||
<div className={classNames('relative h-9', wrapperClassName)}>
|
||||
<Listbox.Button className={`flex items-center w-full h-full rounded-lg border-0 bg-gray-100 pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200 ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'} ${className}`}>
|
||||
<Listbox.Button className={classNames(`flex items-center w-full h-full rounded-lg border-0 bg-gray-100 pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200 ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`, className)}>
|
||||
<span className={classNames('block truncate text-left', !selectedItem?.name && 'text-gray-400')}>{selectedItem?.name ?? localPlaceholder}</span>
|
||||
<span className="absolute inset-y-0 right-0 flex items-center pr-2">
|
||||
{selectedItem
|
||||
|
@ -1,17 +1,22 @@
|
||||
import {
|
||||
useCallback,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { RiDeleteBinLine } from '@remixicon/react'
|
||||
import type { VarType as NumberVarType } from '../../../tool/types'
|
||||
import type {
|
||||
ComparisonOperator,
|
||||
Condition,
|
||||
HandleRemoveCondition,
|
||||
HandleUpdateCondition,
|
||||
} from '../../types'
|
||||
import {
|
||||
ComparisonOperator,
|
||||
} from '../../types'
|
||||
import { comparisonOperatorNotRequireValue } from '../../utils'
|
||||
import ConditionNumberInput from '../condition-number-input'
|
||||
import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from '../../default'
|
||||
import ConditionOperator from './condition-operator'
|
||||
import ConditionInput from './condition-input'
|
||||
import VariableTag from '@/app/components/workflow/nodes/_base/components/variable-tag'
|
||||
@ -21,6 +26,9 @@ import type {
|
||||
} from '@/app/components/workflow/types'
|
||||
import { VarType } from '@/app/components/workflow/types'
|
||||
import cn from '@/utils/classnames'
|
||||
import { SimpleSelect as Select } from '@/app/components/base/select'
|
||||
|
||||
const optionNameI18NPrefix = 'workflow.nodes.ifElse.optionName'
|
||||
|
||||
type ConditionItemProps = {
|
||||
disabled?: boolean
|
||||
@ -44,6 +52,8 @@ const ConditionItem = ({
|
||||
availableNodes,
|
||||
numberVariables,
|
||||
}: ConditionItemProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [isHovered, setIsHovered] = useState(false)
|
||||
|
||||
const handleUpdateConditionOperator = useCallback((value: ComparisonOperator) => {
|
||||
@ -71,6 +81,26 @@ const ConditionItem = ({
|
||||
onUpdateCondition(caseId, condition.id, newCondition)
|
||||
}, [caseId, condition, onUpdateCondition])
|
||||
|
||||
const isSelect = condition.comparison_operator && [ComparisonOperator.in, ComparisonOperator.notIn].includes(condition.comparison_operator)
|
||||
const selectOptions = useMemo(() => {
|
||||
if (isSelect) {
|
||||
if (file?.key === 'type') {
|
||||
return FILE_TYPE_OPTIONS.map(item => ({
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}`),
|
||||
value: item.value,
|
||||
}))
|
||||
}
|
||||
if (file?.key === 'transfer_method') {
|
||||
return TRANSFER_METHOD.map(item => ({
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}`),
|
||||
value: item.value,
|
||||
}))
|
||||
}
|
||||
return []
|
||||
}
|
||||
return []
|
||||
}, [file?.key, isSelect, t])
|
||||
|
||||
return (
|
||||
<div className='flex mb-1 last-of-type:mb-0'>
|
||||
<div className={cn(
|
||||
@ -94,7 +124,7 @@ const ConditionItem = ({
|
||||
/>
|
||||
</div>
|
||||
{
|
||||
!comparisonOperatorNotRequireValue(condition.comparison_operator) && condition.varType !== VarType.number && (
|
||||
!comparisonOperatorNotRequireValue(condition.comparison_operator) && !isSelect && condition.varType !== VarType.number && (
|
||||
<div className='px-2 py-1 max-h-[100px] border-t border-t-divider-subtle overflow-y-auto'>
|
||||
<ConditionInput
|
||||
disabled={disabled}
|
||||
@ -107,7 +137,7 @@ const ConditionItem = ({
|
||||
)
|
||||
}
|
||||
{
|
||||
!comparisonOperatorNotRequireValue(condition.comparison_operator) && condition.varType === VarType.number && (
|
||||
!comparisonOperatorNotRequireValue(condition.comparison_operator) && !isSelect && condition.varType === VarType.number && (
|
||||
<div className='px-2 py-1 pt-[3px] border-t border-t-divider-subtle'>
|
||||
<ConditionNumberInput
|
||||
numberVarType={condition.numberVarType}
|
||||
@ -119,6 +149,19 @@ const ConditionItem = ({
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
!comparisonOperatorNotRequireValue(condition.comparison_operator) && isSelect && (
|
||||
<div className='p-1'>
|
||||
<Select
|
||||
wrapperClassName='h-6'
|
||||
className='pl-0 text-xs'
|
||||
defaultValue={condition.value}
|
||||
items={selectOptions}
|
||||
onSelect={item => handleUpdateConditionValue(item.value as string)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div
|
||||
className='shrink-0 flex items-center justify-center ml-1 mt-1 w-6 h-6 rounded-lg cursor-pointer hover:bg-state-destructive-hover text-text-tertiary hover:text-text-destructive'
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { BlockEnum, type NodeDefault } from '../../types'
|
||||
import { type IfElseNodeType, LogicalOperator } from './types'
|
||||
import { isEmptyRelatedOperator } from './utils'
|
||||
import { TransferMethod } from '@/types/app'
|
||||
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
|
||||
const i18nPrefix = 'workflow.errorMsg'
|
||||
|
||||
@ -61,3 +62,15 @@ const nodeDefault: NodeDefault<IfElseNodeType> = {
|
||||
}
|
||||
|
||||
export default nodeDefault
|
||||
|
||||
export const FILE_TYPE_OPTIONS = [
|
||||
{ value: 'image', i18nKey: 'image' },
|
||||
{ value: 'doc', i18nKey: 'doc' },
|
||||
{ value: 'audio', i18nKey: 'audio' },
|
||||
{ value: 'video', i18nKey: 'video' },
|
||||
]
|
||||
|
||||
export const TRANSFER_METHOD = [
|
||||
{ value: TransferMethod.local_file, i18nKey: 'localUpload' },
|
||||
{ value: TransferMethod.remote_url, i18nKey: 'url' },
|
||||
]
|
||||
|
@ -82,6 +82,7 @@ export const getOperators = (type?: VarType, file?: { key: string }) => {
|
||||
ComparisonOperator.notEmpty,
|
||||
]
|
||||
}
|
||||
return []
|
||||
}
|
||||
switch (type) {
|
||||
case VarType.string:
|
||||
|
@ -390,6 +390,14 @@ const translation = {
|
||||
'in': 'in',
|
||||
'not in': 'not in',
|
||||
},
|
||||
optionName: {
|
||||
image: 'Image',
|
||||
doc: 'Doc',
|
||||
audio: 'Audio',
|
||||
video: 'Video',
|
||||
localUpload: 'Local Upload',
|
||||
url: 'URL',
|
||||
},
|
||||
enterValue: 'Enter value',
|
||||
addCondition: 'Add Condition',
|
||||
conditionNotSetup: 'Condition NOT setup',
|
||||
|
@ -390,6 +390,14 @@ const translation = {
|
||||
'in': '在',
|
||||
'not in': '不在',
|
||||
},
|
||||
optionName: {
|
||||
image: '图片',
|
||||
doc: '文档',
|
||||
audio: '音频',
|
||||
video: '视频',
|
||||
localUpload: '本地上传',
|
||||
url: 'URL',
|
||||
},
|
||||
enterValue: '输入值',
|
||||
addCondition: '添加条件',
|
||||
conditionNotSetup: '条件未设置',
|
||||
|
Loading…
x
Reference in New Issue
Block a user