mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-20 02:29:05 +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'>
|
<div className='group text-gray-800'>
|
||||||
{allowSearch
|
{allowSearch
|
||||||
? <Combobox.Input
|
? <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) => {
|
onChange={(event) => {
|
||||||
if (!disabled)
|
if (!disabled)
|
||||||
setQuery(event.target.value)
|
setQuery(event.target.value)
|
||||||
@ -200,7 +200,7 @@ const SimpleSelect: FC<ISelectProps> = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={classNames('relative h-9', wrapperClassName)}>
|
<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={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">
|
<span className="absolute inset-y-0 right-0 flex items-center pr-2">
|
||||||
{selectedItem
|
{selectedItem
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
import {
|
import {
|
||||||
useCallback,
|
useCallback,
|
||||||
|
useMemo,
|
||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
import { RiDeleteBinLine } from '@remixicon/react'
|
import { RiDeleteBinLine } from '@remixicon/react'
|
||||||
import type { VarType as NumberVarType } from '../../../tool/types'
|
import type { VarType as NumberVarType } from '../../../tool/types'
|
||||||
import type {
|
import type {
|
||||||
ComparisonOperator,
|
|
||||||
Condition,
|
Condition,
|
||||||
HandleRemoveCondition,
|
HandleRemoveCondition,
|
||||||
HandleUpdateCondition,
|
HandleUpdateCondition,
|
||||||
} from '../../types'
|
} from '../../types'
|
||||||
|
import {
|
||||||
|
ComparisonOperator,
|
||||||
|
} from '../../types'
|
||||||
import { comparisonOperatorNotRequireValue } from '../../utils'
|
import { comparisonOperatorNotRequireValue } from '../../utils'
|
||||||
import ConditionNumberInput from '../condition-number-input'
|
import ConditionNumberInput from '../condition-number-input'
|
||||||
|
import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from '../../default'
|
||||||
import ConditionOperator from './condition-operator'
|
import ConditionOperator from './condition-operator'
|
||||||
import ConditionInput from './condition-input'
|
import ConditionInput from './condition-input'
|
||||||
import VariableTag from '@/app/components/workflow/nodes/_base/components/variable-tag'
|
import VariableTag from '@/app/components/workflow/nodes/_base/components/variable-tag'
|
||||||
@ -21,6 +26,9 @@ import type {
|
|||||||
} from '@/app/components/workflow/types'
|
} from '@/app/components/workflow/types'
|
||||||
import { VarType } from '@/app/components/workflow/types'
|
import { VarType } from '@/app/components/workflow/types'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
import { SimpleSelect as Select } from '@/app/components/base/select'
|
||||||
|
|
||||||
|
const optionNameI18NPrefix = 'workflow.nodes.ifElse.optionName'
|
||||||
|
|
||||||
type ConditionItemProps = {
|
type ConditionItemProps = {
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
@ -44,6 +52,8 @@ const ConditionItem = ({
|
|||||||
availableNodes,
|
availableNodes,
|
||||||
numberVariables,
|
numberVariables,
|
||||||
}: ConditionItemProps) => {
|
}: ConditionItemProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const [isHovered, setIsHovered] = useState(false)
|
const [isHovered, setIsHovered] = useState(false)
|
||||||
|
|
||||||
const handleUpdateConditionOperator = useCallback((value: ComparisonOperator) => {
|
const handleUpdateConditionOperator = useCallback((value: ComparisonOperator) => {
|
||||||
@ -71,6 +81,26 @@ const ConditionItem = ({
|
|||||||
onUpdateCondition(caseId, condition.id, newCondition)
|
onUpdateCondition(caseId, condition.id, newCondition)
|
||||||
}, [caseId, condition, onUpdateCondition])
|
}, [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 (
|
return (
|
||||||
<div className='flex mb-1 last-of-type:mb-0'>
|
<div className='flex mb-1 last-of-type:mb-0'>
|
||||||
<div className={cn(
|
<div className={cn(
|
||||||
@ -94,7 +124,7 @@ const ConditionItem = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</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'>
|
<div className='px-2 py-1 max-h-[100px] border-t border-t-divider-subtle overflow-y-auto'>
|
||||||
<ConditionInput
|
<ConditionInput
|
||||||
disabled={disabled}
|
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'>
|
<div className='px-2 py-1 pt-[3px] border-t border-t-divider-subtle'>
|
||||||
<ConditionNumberInput
|
<ConditionNumberInput
|
||||||
numberVarType={condition.numberVarType}
|
numberVarType={condition.numberVarType}
|
||||||
@ -119,6 +149,19 @@ const ConditionItem = ({
|
|||||||
</div>
|
</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>
|
||||||
<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'
|
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 { BlockEnum, type NodeDefault } from '../../types'
|
||||||
import { type IfElseNodeType, LogicalOperator } from './types'
|
import { type IfElseNodeType, LogicalOperator } from './types'
|
||||||
import { isEmptyRelatedOperator } from './utils'
|
import { isEmptyRelatedOperator } from './utils'
|
||||||
|
import { TransferMethod } from '@/types/app'
|
||||||
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
|
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
|
||||||
const i18nPrefix = 'workflow.errorMsg'
|
const i18nPrefix = 'workflow.errorMsg'
|
||||||
|
|
||||||
@ -61,3 +62,15 @@ const nodeDefault: NodeDefault<IfElseNodeType> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default nodeDefault
|
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,
|
ComparisonOperator.notEmpty,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
return []
|
||||||
}
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VarType.string:
|
case VarType.string:
|
||||||
|
@ -390,6 +390,14 @@ const translation = {
|
|||||||
'in': 'in',
|
'in': 'in',
|
||||||
'not in': 'not in',
|
'not in': 'not in',
|
||||||
},
|
},
|
||||||
|
optionName: {
|
||||||
|
image: 'Image',
|
||||||
|
doc: 'Doc',
|
||||||
|
audio: 'Audio',
|
||||||
|
video: 'Video',
|
||||||
|
localUpload: 'Local Upload',
|
||||||
|
url: 'URL',
|
||||||
|
},
|
||||||
enterValue: 'Enter value',
|
enterValue: 'Enter value',
|
||||||
addCondition: 'Add Condition',
|
addCondition: 'Add Condition',
|
||||||
conditionNotSetup: 'Condition NOT setup',
|
conditionNotSetup: 'Condition NOT setup',
|
||||||
|
@ -390,6 +390,14 @@ const translation = {
|
|||||||
'in': '在',
|
'in': '在',
|
||||||
'not in': '不在',
|
'not in': '不在',
|
||||||
},
|
},
|
||||||
|
optionName: {
|
||||||
|
image: '图片',
|
||||||
|
doc: '文档',
|
||||||
|
audio: '音频',
|
||||||
|
video: '视频',
|
||||||
|
localUpload: '本地上传',
|
||||||
|
url: 'URL',
|
||||||
|
},
|
||||||
enterValue: '输入值',
|
enterValue: '输入值',
|
||||||
addCondition: '添加条件',
|
addCondition: '添加条件',
|
||||||
conditionNotSetup: '条件未设置',
|
conditionNotSetup: '条件未设置',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user