|
|
|
@@ -1,36 +1,60 @@ |
|
|
|
'use client' |
|
|
|
import type { FC } from 'react' |
|
|
|
import React, { useCallback, useMemo } from 'react' |
|
|
|
import React, { useCallback, useMemo, useState } from 'react' |
|
|
|
import { useTranslation } from 'react-i18next' |
|
|
|
import ConditionOperator from '../../if-else/components/condition-list/condition-operator' |
|
|
|
import { VarType } from '../../../types' |
|
|
|
import type { Condition } from '../types' |
|
|
|
import { ComparisonOperator } from '../../if-else/types' |
|
|
|
import { comparisonOperatorNotRequireValue, getOperators } from '../../if-else/utils' |
|
|
|
import SubVariablePicker from './sub-variable-picker' |
|
|
|
import Input from '@/app/components/base/input' |
|
|
|
import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from '@/app/components/workflow/nodes/constants' |
|
|
|
import { SimpleSelect as Select } from '@/app/components/base/select' |
|
|
|
import Input from '@/app/components/workflow/nodes/_base/components/input-support-select-var' |
|
|
|
import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list' |
|
|
|
import cn from '@/utils/classnames' |
|
|
|
import { VarType } from '../../../types' |
|
|
|
|
|
|
|
const optionNameI18NPrefix = 'workflow.nodes.ifElse.optionName' |
|
|
|
|
|
|
|
const VAR_INPUT_SUPPORTED_KEYS: Record<string, VarType> = { |
|
|
|
name: VarType.string, |
|
|
|
url: VarType.string, |
|
|
|
extension: VarType.string, |
|
|
|
mime_type: VarType.string, |
|
|
|
related_id: VarType.number, |
|
|
|
} |
|
|
|
|
|
|
|
type Props = { |
|
|
|
condition: Condition |
|
|
|
onChange: (condition: Condition) => void |
|
|
|
varType: VarType |
|
|
|
hasSubVariable: boolean |
|
|
|
readOnly: boolean |
|
|
|
nodeId: string |
|
|
|
} |
|
|
|
|
|
|
|
const FilterCondition: FC<Props> = ({ |
|
|
|
condition = { key: '', comparison_operator: ComparisonOperator.equal, value: '' }, |
|
|
|
varType, |
|
|
|
onChange, |
|
|
|
hasSubVariable, |
|
|
|
readOnly, |
|
|
|
nodeId, |
|
|
|
}) => { |
|
|
|
const { t } = useTranslation() |
|
|
|
const [isFocus, setIsFocus] = useState(false) |
|
|
|
|
|
|
|
const expectedVarType = VAR_INPUT_SUPPORTED_KEYS[condition.key] |
|
|
|
const supportVariableInput = !!expectedVarType |
|
|
|
|
|
|
|
const { availableVars, availableNodesWithParent } = useAvailableVarList(nodeId, { |
|
|
|
onlyLeafNodeVar: false, |
|
|
|
filterVar: (varPayload) => { |
|
|
|
return expectedVarType ? varPayload.type === expectedVarType : true |
|
|
|
}, |
|
|
|
}) |
|
|
|
|
|
|
|
const isSelect = [ComparisonOperator.in, ComparisonOperator.notIn, ComparisonOperator.allOf].includes(condition.comparison_operator) |
|
|
|
const isArrayValue = condition.key === 'transfer_method' || condition.key === 'type' |
|
|
|
|
|
|
|
const selectOptions = useMemo(() => { |
|
|
|
if (isSelect) { |
|
|
|
if (condition.key === 'type' || condition.comparison_operator === ComparisonOperator.allOf) { |
|
|
|
@@ -49,6 +73,7 @@ const FilterCondition: FC<Props> = ({ |
|
|
|
} |
|
|
|
return [] |
|
|
|
}, [condition.comparison_operator, condition.key, isSelect, t]) |
|
|
|
|
|
|
|
const handleChange = useCallback((key: string) => { |
|
|
|
return (value: any) => { |
|
|
|
onChange({ |
|
|
|
@@ -59,12 +84,14 @@ const FilterCondition: FC<Props> = ({ |
|
|
|
}, [condition, onChange, isArrayValue]) |
|
|
|
|
|
|
|
const handleSubVariableChange = useCallback((value: string) => { |
|
|
|
const operators = getOperators(expectedVarType ?? VarType.string, { key: value }) |
|
|
|
const newOperator = operators.length > 0 ? operators[0] : ComparisonOperator.equal |
|
|
|
onChange({ |
|
|
|
key: value, |
|
|
|
comparison_operator: getOperators(varType, { key: value })[0], |
|
|
|
comparison_operator: newOperator, |
|
|
|
value: '', |
|
|
|
}) |
|
|
|
}, [onChange, varType]) |
|
|
|
}, [onChange, expectedVarType]) |
|
|
|
|
|
|
|
return ( |
|
|
|
<div> |
|
|
|
@@ -78,7 +105,7 @@ const FilterCondition: FC<Props> = ({ |
|
|
|
<div className='flex space-x-1'> |
|
|
|
<ConditionOperator |
|
|
|
className='h-8 bg-components-input-bg-normal' |
|
|
|
varType={varType} |
|
|
|
varType={expectedVarType ?? VarType.string} |
|
|
|
value={condition.comparison_operator} |
|
|
|
onSelect={handleChange('comparison_operator')} |
|
|
|
file={hasSubVariable ? { key: condition.key } : undefined} |
|
|
|
@@ -86,7 +113,7 @@ const FilterCondition: FC<Props> = ({ |
|
|
|
/> |
|
|
|
{!comparisonOperatorNotRequireValue(condition.comparison_operator) && ( |
|
|
|
<> |
|
|
|
{isSelect && ( |
|
|
|
{isSelect ? ( |
|
|
|
<Select |
|
|
|
items={selectOptions} |
|
|
|
defaultValue={isArrayValue ? (condition.value as string[])[0] : condition.value as string} |
|
|
|
@@ -95,13 +122,31 @@ const FilterCondition: FC<Props> = ({ |
|
|
|
wrapperClassName='grow h-8' |
|
|
|
placeholder='Select value' |
|
|
|
/> |
|
|
|
)} |
|
|
|
{!isSelect && ( |
|
|
|
) : supportVariableInput ? ( |
|
|
|
<Input |
|
|
|
type={((hasSubVariable && condition.key === 'size') || (!hasSubVariable && varType === VarType.number)) ? 'number' : 'text'} |
|
|
|
className='grow' |
|
|
|
instanceId='filter-condition-input' |
|
|
|
className={cn( |
|
|
|
isFocus |
|
|
|
? 'border-components-input-border-active bg-components-input-bg-active shadow-xs' |
|
|
|
: 'border-components-input-border-hover bg-components-input-bg-normal', |
|
|
|
'w-0 grow rounded-lg border px-3 py-[6px]', |
|
|
|
)} |
|
|
|
value={condition.value} |
|
|
|
onChange={handleChange('value')} |
|
|
|
readOnly={readOnly} |
|
|
|
nodesOutputVars={availableVars} |
|
|
|
availableNodes={availableNodesWithParent} |
|
|
|
onFocusChange={setIsFocus} |
|
|
|
placeholder={!readOnly ? t('workflow.nodes.http.extractListPlaceholder')! : ''} |
|
|
|
placeholderClassName='!leading-[21px]' |
|
|
|
/> |
|
|
|
) : ( |
|
|
|
<input |
|
|
|
type={(condition.key === 'size' || expectedVarType === VarType.number) ? 'number' : 'text'} |
|
|
|
className='grow rounded-lg border border-components-input-border-hover bg-components-input-bg-normal px-3 py-[6px]' |
|
|
|
value={condition.value} |
|
|
|
onChange={e => handleChange('value')(e.target.value)} |
|
|
|
readOnly={readOnly} |
|
|
|
/> |
|
|
|
)} |
|
|
|
</> |
|
|
|
@@ -110,4 +155,5 @@ const FilterCondition: FC<Props> = ({ |
|
|
|
</div> |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
export default React.memo(FilterCondition) |