feat: files attr select

This commit is contained in:
Joel 2024-08-13 13:59:19 +08:00
parent ae098ad121
commit 6549519fa5
6 changed files with 78 additions and 5 deletions

View File

@ -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

View File

@ -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'

View File

@ -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' },
]

View File

@ -82,6 +82,7 @@ export const getOperators = (type?: VarType, file?: { key: string }) => {
ComparisonOperator.notEmpty,
]
}
return []
}
switch (type) {
case VarType.string:

View File

@ -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',

View File

@ -390,6 +390,14 @@ const translation = {
'in': '在',
'not in': '不在',
},
optionName: {
image: '图片',
doc: '文档',
audio: '音频',
video: '视频',
localUpload: '本地上传',
url: 'URL',
},
enterValue: '输入值',
addCondition: '添加条件',
conditionNotSetup: '条件未设置',