mirror of https://github.com/langgenius/dify.git
type safe
This commit is contained in:
parent
89a1d15da3
commit
8698d4f0e6
|
|
@ -8,17 +8,17 @@ type OptionItem = {
|
|||
i18nKey: I18nKeysByPrefix<'workflow', 'nodes.ifElse.optionName.'>
|
||||
}
|
||||
|
||||
export const FILE_TYPE_OPTIONS: OptionItem[] = [
|
||||
export const FILE_TYPE_OPTIONS = [
|
||||
{ value: 'image', i18nKey: 'image' },
|
||||
{ value: 'document', i18nKey: 'doc' },
|
||||
{ value: 'audio', i18nKey: 'audio' },
|
||||
{ value: 'video', i18nKey: 'video' },
|
||||
]
|
||||
] as const satisfies readonly OptionItem[]
|
||||
|
||||
export const TRANSFER_METHOD: OptionItem[] = [
|
||||
export const TRANSFER_METHOD = [
|
||||
{ value: TransferMethod.local_file, i18nKey: 'localUpload' },
|
||||
{ value: TransferMethod.remote_url, i18nKey: 'url' },
|
||||
]
|
||||
] as const satisfies readonly OptionItem[]
|
||||
|
||||
export const SUB_VARIABLES = ['type', 'size', 'name', 'url', 'extension', 'mime_type', 'transfer_method', 'related_id']
|
||||
export const OUTPUT_FILE_SUB_VARIABLES = SUB_VARIABLES.filter(key => key !== 'transfer_method')
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ import ConditionInput from './condition-input'
|
|||
import ConditionOperator from './condition-operator'
|
||||
import ConditionVarSelector from './condition-var-selector'
|
||||
|
||||
const optionNameI18NPrefix = 'nodes.ifElse.optionName'
|
||||
const optionNameI18NPrefix = 'nodes.ifElse.optionName' as const
|
||||
|
||||
type ConditionItemProps = {
|
||||
className?: string
|
||||
|
|
@ -168,13 +168,13 @@ const ConditionItem = ({
|
|||
if (isSelect) {
|
||||
if (fileAttr?.key === 'type' || condition.comparison_operator === ComparisonOperator.allOf) {
|
||||
return FILE_TYPE_OPTIONS.map(item => ({
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}` as any, { ns: 'workflow' }) as string,
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}`, { ns: 'workflow' }),
|
||||
value: item.value,
|
||||
}))
|
||||
}
|
||||
if (fileAttr?.key === 'transfer_method') {
|
||||
return TRANSFER_METHOD.map(item => ({
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}` as any, { ns: 'workflow' }) as string,
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}`, { ns: 'workflow' }),
|
||||
value: item.value,
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const ConditionOperator = ({
|
|||
const options = useMemo(() => {
|
||||
return getOperators(varType, file).map((o) => {
|
||||
return {
|
||||
label: isComparisonOperatorNeedTranslate(o) ? t(`${i18nPrefix}.comparisonOperator.${o}` as any, { ns: 'workflow' }) as string : o,
|
||||
label: isComparisonOperatorNeedTranslate(o) ? t(`${i18nPrefix}.comparisonOperator.${o}`, { ns: 'workflow' }) : o,
|
||||
value: o,
|
||||
}
|
||||
})
|
||||
|
|
@ -65,7 +65,7 @@ const ConditionOperator = ({
|
|||
{
|
||||
selectedOption
|
||||
? selectedOption.label
|
||||
: t(`${i18nPrefix}.select` as any, { ns: 'workflow' }) as string
|
||||
: t(`${i18nPrefix}.select`, { ns: 'workflow' })
|
||||
}
|
||||
<RiArrowDownSLine className="ml-1 h-3.5 w-3.5" />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const ConditionValue = ({
|
|||
const { t } = useTranslation()
|
||||
const nodes = useNodes()
|
||||
const variableName = labelName || (isSystemVar(variableSelector) ? variableSelector.slice(0).join('.') : variableSelector.slice(1).join('.'))
|
||||
const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`nodes.ifElse.comparisonOperator.${operator}` as any, { ns: 'workflow' }) as string : operator
|
||||
const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`nodes.ifElse.comparisonOperator.${operator}`, { ns: 'workflow' }) : operator
|
||||
const notHasValue = comparisonOperatorNotRequireValue(operator)
|
||||
const node: Node<CommonNodeType> | undefined = nodes.find(n => n.id === variableSelector[0]) as Node<CommonNodeType>
|
||||
const isException = isExceptionVariable(variableName, node?.data.type)
|
||||
|
|
@ -63,7 +63,7 @@ const ConditionValue = ({
|
|||
if (isSelect) {
|
||||
const name = [...FILE_TYPE_OPTIONS, ...TRANSFER_METHOD].filter(item => item.value === (Array.isArray(value) ? value[0] : value))[0]
|
||||
return name
|
||||
? (t(`nodes.ifElse.optionName.${name.i18nKey}` as any, { ns: 'workflow' }) as string).replace(/\{\{#([^#]*)#\}\}/g, (a, b) => {
|
||||
? t(`nodes.ifElse.optionName.${name.i18nKey}`, { ns: 'workflow' }).replace(/\{\{#([^#]*)#\}\}/g, (a, b) => {
|
||||
const arr: string[] = b.split('.')
|
||||
if (isSystemVar(arr))
|
||||
return `{{${b}}}`
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ export const useNodeIterationInteractions = () => {
|
|||
_isBundled: false,
|
||||
_connectedSourceHandleIds: [],
|
||||
_connectedTargetHandleIds: [],
|
||||
title: nodesWithSameType.length > 0 ? `${t(`blocks.${childNodeType}` as any, { ns: 'workflow' }) as string} ${childNodeTypeCount[childNodeType]}` : t(`blocks.${childNodeType}` as any, { ns: 'workflow' }) as string,
|
||||
title: nodesWithSameType.length > 0 ? `${t(`blocks.${childNodeType}`, { ns: 'workflow' })} ${childNodeTypeCount[childNodeType]}` : t(`blocks.${childNodeType}`, { ns: 'workflow' }),
|
||||
iteration_id: newNodeId,
|
||||
type: childNodeType,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ const ConditionOperator = ({
|
|||
const options = useMemo(() => {
|
||||
return getOperators(variableType).map((o) => {
|
||||
return {
|
||||
label: isComparisonOperatorNeedTranslate(o) ? t(`${i18nPrefix}.comparisonOperator.${o}` as any, { ns: 'workflow' }) as string : o,
|
||||
label: isComparisonOperatorNeedTranslate(o) ? t(`${i18nPrefix}.comparisonOperator.${o}`, { ns: 'workflow' }) : o,
|
||||
value: o,
|
||||
}
|
||||
})
|
||||
|
|
@ -68,7 +68,7 @@ const ConditionOperator = ({
|
|||
{
|
||||
selectedOption
|
||||
? selectedOption.label
|
||||
: t(`${i18nPrefix}.select` as any, { ns: 'workflow' }) as string
|
||||
: t(`${i18nPrefix}.select`, { ns: 'workflow' })
|
||||
}
|
||||
<RiArrowDownSLine className="ml-1 h-3.5 w-3.5" />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -14,12 +14,17 @@ const notTranslateKey = [
|
|||
ComparisonOperator.largerThanOrEqual,
|
||||
ComparisonOperator.lessThan,
|
||||
ComparisonOperator.lessThanOrEqual,
|
||||
]
|
||||
] as const
|
||||
|
||||
export const isComparisonOperatorNeedTranslate = (operator?: ComparisonOperator) => {
|
||||
type NotTranslateOperator = typeof notTranslateKey[number]
|
||||
export type TranslatableComparisonOperator = Exclude<ComparisonOperator, NotTranslateOperator>
|
||||
|
||||
export function isComparisonOperatorNeedTranslate(operator: ComparisonOperator): operator is TranslatableComparisonOperator
|
||||
export function isComparisonOperatorNeedTranslate(operator?: ComparisonOperator): operator is TranslatableComparisonOperator
|
||||
export function isComparisonOperatorNeedTranslate(operator?: ComparisonOperator): operator is TranslatableComparisonOperator {
|
||||
if (!operator)
|
||||
return false
|
||||
return !notTranslateKey.includes(operator)
|
||||
return !(notTranslateKey as readonly ComparisonOperator[]).includes(operator)
|
||||
}
|
||||
|
||||
export const getOperators = (type?: MetadataFilteringVariableType) => {
|
||||
|
|
|
|||
|
|
@ -66,13 +66,13 @@ const FilterCondition: FC<Props> = ({
|
|||
if (isSelect) {
|
||||
if (condition.key === 'type' || condition.comparison_operator === ComparisonOperator.allOf) {
|
||||
return FILE_TYPE_OPTIONS.map(item => ({
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}` as any, { ns: 'workflow' }) as string,
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}`, { ns: 'workflow' }),
|
||||
value: item.value,
|
||||
}))
|
||||
}
|
||||
if (condition.key === 'transfer_method') {
|
||||
return TRANSFER_METHOD.map(item => ({
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}` as any, { ns: 'workflow' }) as string,
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}`, { ns: 'workflow' }),
|
||||
value: item.value,
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ const ConfigPromptItem: FC<Props> = ({
|
|||
|
||||
<Tooltip
|
||||
popupContent={
|
||||
<div className="max-w-[180px]">{t(`${i18nPrefix}.roleDescription.${payload.role}` as any, { ns: 'workflow' }) as string}</div>
|
||||
<div className="max-w-[180px]">{payload.role && t(`${i18nPrefix}.roleDescription.${payload.role}`, { ns: 'workflow' })}</div>
|
||||
}
|
||||
triggerClassName="w-4 h-4"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ const ConditionValue = ({
|
|||
|
||||
const variableSelector = variable_selector as ValueSelector
|
||||
|
||||
const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`nodes.ifElse.comparisonOperator.${operator}` as any, { ns: 'workflow' }) as string : operator
|
||||
const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`nodes.ifElse.comparisonOperator.${operator}`, { ns: 'workflow' }) : operator
|
||||
const formatValue = useCallback((c: Condition) => {
|
||||
const notHasValue = comparisonOperatorNotRequireValue(c.comparison_operator)
|
||||
if (notHasValue)
|
||||
|
|
@ -59,7 +59,7 @@ const ConditionValue = ({
|
|||
if (isSelect) {
|
||||
const name = [...FILE_TYPE_OPTIONS, ...TRANSFER_METHOD].filter(item => item.value === (Array.isArray(c.value) ? c.value[0] : c.value))[0]
|
||||
return name
|
||||
? (t(`nodes.ifElse.optionName.${name.i18nKey}` as any, { ns: 'workflow' }) as string).replace(/\{\{#([^#]*)#\}\}/g, (a: string, b: string) => {
|
||||
? t(`nodes.ifElse.optionName.${name.i18nKey}`, { ns: 'workflow' }).replace(/\{\{#([^#]*)#\}\}/g, (a: string, b: string) => {
|
||||
const arr: string[] = b.split('.')
|
||||
if (isSystemVar(arr))
|
||||
return `{{${b}}}`
|
||||
|
|
@ -91,9 +91,9 @@ const ConditionValue = ({
|
|||
sub_variable_condition?.conditions.map((c: Condition, index) => (
|
||||
<div className="relative flex h-6 items-center space-x-1" key={c.id}>
|
||||
<div className="system-xs-medium text-text-accent">{c.key}</div>
|
||||
<div className="system-xs-medium text-text-primary">{isComparisonOperatorNeedTranslate(c.comparison_operator) ? t(`nodes.ifElse.comparisonOperator.${c.comparison_operator}` as any, { ns: 'workflow' }) as string : c.comparison_operator}</div>
|
||||
<div className="system-xs-medium text-text-primary">{isComparisonOperatorNeedTranslate(c.comparison_operator) ? t(`nodes.ifElse.comparisonOperator.${c.comparison_operator}`, { ns: 'workflow' }) : c.comparison_operator}</div>
|
||||
{c.comparison_operator && !isEmptyRelatedOperator(c.comparison_operator) && <div className="system-xs-regular text-text-secondary">{isSelect(c) ? selectName(c) : formatValue(c)}</div>}
|
||||
{index !== sub_variable_condition.conditions.length - 1 && (<div className="absolute bottom-[-10px] right-1 z-10 text-[10px] font-medium uppercase leading-4 text-text-accent">{t(`${i18nPrefix}.${sub_variable_condition.logical_operator}` as any, { ns: 'workflow' }) as string}</div>)}
|
||||
{index !== sub_variable_condition.conditions.length - 1 && (<div className="absolute bottom-[-10px] right-1 z-10 text-[10px] font-medium uppercase leading-4 text-text-accent">{t(`${i18nPrefix}.${sub_variable_condition.logical_operator}`, { ns: 'workflow' })}</div>)}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,13 +145,13 @@ const ConditionItem = ({
|
|||
if (isSelect) {
|
||||
if (fileAttr?.key === 'type' || condition.comparison_operator === ComparisonOperator.allOf) {
|
||||
return FILE_TYPE_OPTIONS.map(item => ({
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}` as any, { ns: 'workflow' }) as string,
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}`, { ns: 'workflow' }),
|
||||
value: item.value,
|
||||
}))
|
||||
}
|
||||
if (fileAttr?.key === 'transfer_method') {
|
||||
return TRANSFER_METHOD.map(item => ({
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}` as any, { ns: 'workflow' }) as string,
|
||||
name: t(`${optionNameI18NPrefix}.${item.i18nKey}`, { ns: 'workflow' }),
|
||||
value: item.value,
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const ConditionOperator = ({
|
|||
const options = useMemo(() => {
|
||||
return getOperators(varType, file).map((o) => {
|
||||
return {
|
||||
label: isComparisonOperatorNeedTranslate(o) ? t(`${i18nPrefix}.comparisonOperator.${o}` as any, { ns: 'workflow' }) as string : o,
|
||||
label: isComparisonOperatorNeedTranslate(o) ? t(`${i18nPrefix}.comparisonOperator.${o}`, { ns: 'workflow' }) : o,
|
||||
value: o,
|
||||
}
|
||||
})
|
||||
|
|
@ -65,7 +65,7 @@ const ConditionOperator = ({
|
|||
{
|
||||
selectedOption
|
||||
? selectedOption.label
|
||||
: t(`${i18nPrefix}.select` as any, { ns: 'workflow' }) as string
|
||||
: t(`${i18nPrefix}.select`, { ns: 'workflow' })
|
||||
}
|
||||
<RiArrowDownSLine className="ml-1 h-3.5 w-3.5" />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ const ConditionValue = ({
|
|||
value,
|
||||
}: ConditionValueProps) => {
|
||||
const { t } = useTranslation()
|
||||
const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`nodes.ifElse.comparisonOperator.${operator}` as any, { ns: 'workflow' }) as string : operator
|
||||
const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`nodes.ifElse.comparisonOperator.${operator}`, { ns: 'workflow' }) : operator
|
||||
const notHasValue = comparisonOperatorNotRequireValue(operator)
|
||||
const formatValue = useMemo(() => {
|
||||
if (notHasValue)
|
||||
|
|
@ -50,7 +50,7 @@ const ConditionValue = ({
|
|||
if (isSelect) {
|
||||
const name = [...FILE_TYPE_OPTIONS, ...TRANSFER_METHOD].filter(item => item.value === (Array.isArray(value) ? value[0] : value))[0]
|
||||
return name
|
||||
? (t(`nodes.ifElse.optionName.${name.i18nKey}` as any, { ns: 'workflow' }) as string).replace(/\{\{#([^#]*)#\}\}/g, (a, b) => {
|
||||
? t(`nodes.ifElse.optionName.${name.i18nKey}`, { ns: 'workflow' }).replace(/\{\{#([^#]*)#\}\}/g, (a, b) => {
|
||||
const arr: string[] = b.split('.')
|
||||
if (isSystemVar(arr))
|
||||
return `{{${b}}}`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import type { NodeDefault } from '../../types'
|
||||
import type { LoopNodeType } from './types'
|
||||
import type { I18nKeysByPrefix } from '@/types/i18n'
|
||||
import { BlockClassificationEnum } from '@/app/components/workflow/block-selector/types'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import { genNodeMetaData } from '@/app/components/workflow/utils'
|
||||
|
|
@ -79,17 +80,22 @@ const nodeDefault: NodeDefault<LoopNodeType> = {
|
|||
},
|
||||
}
|
||||
|
||||
type OptionItem = {
|
||||
value: string
|
||||
i18nKey: I18nKeysByPrefix<'workflow', 'nodes.ifElse.optionName.'>
|
||||
}
|
||||
|
||||
export const FILE_TYPE_OPTIONS = [
|
||||
{ value: 'image', i18nKey: 'image' },
|
||||
{ value: 'document', i18nKey: 'doc' },
|
||||
{ value: 'audio', i18nKey: 'audio' },
|
||||
{ value: 'video', i18nKey: 'video' },
|
||||
]
|
||||
] as const satisfies readonly OptionItem[]
|
||||
|
||||
export const TRANSFER_METHOD = [
|
||||
{ value: TransferMethod.local_file, i18nKey: 'localUpload' },
|
||||
{ value: TransferMethod.remote_url, i18nKey: 'url' },
|
||||
]
|
||||
] as const satisfies readonly OptionItem[]
|
||||
|
||||
export const SUB_VARIABLES = ['type', 'size', 'name', 'url', 'extension', 'mime_type', 'transfer_method', 'related_id']
|
||||
export const OUTPUT_FILE_SUB_VARIABLES = SUB_VARIABLES.filter(key => key !== 'transfer_method')
|
||||
|
|
|
|||
|
|
@ -13,12 +13,17 @@ const notTranslateKey = [
|
|||
ComparisonOperator.largerThanOrEqual,
|
||||
ComparisonOperator.lessThan,
|
||||
ComparisonOperator.lessThanOrEqual,
|
||||
]
|
||||
] as const
|
||||
|
||||
export const isComparisonOperatorNeedTranslate = (operator?: ComparisonOperator) => {
|
||||
type NotTranslateOperator = typeof notTranslateKey[number]
|
||||
export type TranslatableComparisonOperator = Exclude<ComparisonOperator, NotTranslateOperator>
|
||||
|
||||
export function isComparisonOperatorNeedTranslate(operator: ComparisonOperator): operator is TranslatableComparisonOperator
|
||||
export function isComparisonOperatorNeedTranslate(operator?: ComparisonOperator): operator is TranslatableComparisonOperator
|
||||
export function isComparisonOperatorNeedTranslate(operator?: ComparisonOperator): operator is TranslatableComparisonOperator {
|
||||
if (!operator)
|
||||
return false
|
||||
return !notTranslateKey.includes(operator)
|
||||
return !(notTranslateKey as readonly ComparisonOperator[]).includes(operator)
|
||||
}
|
||||
|
||||
export const getOperators = (type?: VarType, file?: { key: string }) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue