Files
dify/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.helpers.ts
Coding On Star 449d8c7768 test(workflow-app): enhance unit tests for workflow components and hooks (#34065)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: lif <1835304752@qq.com>
Co-authored-by: hjlarry <hjlarry@163.com>
Co-authored-by: Stephen Zhou <hi@hyoban.cc>
Co-authored-by: tmimmanuel <14046872+tmimmanuel@users.noreply.github.com>
Co-authored-by: Desel72 <pedroluiscolmenares722@gmail.com>
Co-authored-by: Renzo <170978465+RenzoMXD@users.noreply.github.com>
Co-authored-by: Krishna Chaitanya <krishnabkc15@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-25 18:34:32 +08:00

175 lines
4.9 KiB
TypeScript

import type { ReactNode } from 'react'
import type { ChatVarType } from '../type'
import type { ConversationVariable } from '@/app/components/workflow/types'
import { checkKeys } from '@/utils/var'
import { ChatVarType as ChatVarTypeEnum } from '../type'
import {
arrayBoolPlaceholder,
arrayNumberPlaceholder,
arrayObjectPlaceholder,
arrayStringPlaceholder,
objectPlaceholder,
} from '../utils'
import { DEFAULT_OBJECT_VALUE } from './object-value-item'
export type ObjectValueItem = {
key: string
type: ChatVarType
value: string | number | undefined
}
export type ToastPayload = {
type?: 'success' | 'error' | 'warning' | 'info'
size?: 'md' | 'sm'
duration?: number
message: string
children?: ReactNode
onClose?: () => void
className?: string
customComponent?: ReactNode
}
export const typeList = [
ChatVarTypeEnum.String,
ChatVarTypeEnum.Number,
ChatVarTypeEnum.Boolean,
ChatVarTypeEnum.Object,
ChatVarTypeEnum.ArrayString,
ChatVarTypeEnum.ArrayNumber,
ChatVarTypeEnum.ArrayBoolean,
ChatVarTypeEnum.ArrayObject,
]
export const getEditorMinHeight = (type: ChatVarType) =>
type === ChatVarTypeEnum.ArrayObject ? '240px' : '120px'
export const getPlaceholderByType = (type: ChatVarType) => {
if (type === ChatVarTypeEnum.ArrayString)
return arrayStringPlaceholder
if (type === ChatVarTypeEnum.ArrayNumber)
return arrayNumberPlaceholder
if (type === ChatVarTypeEnum.ArrayObject)
return arrayObjectPlaceholder
if (type === ChatVarTypeEnum.ArrayBoolean)
return arrayBoolPlaceholder
return objectPlaceholder
}
export const buildObjectValueItems = (chatVar?: ConversationVariable): ObjectValueItem[] => {
if (!chatVar || !chatVar.value || Object.keys(chatVar.value).length === 0)
return [DEFAULT_OBJECT_VALUE]
return Object.keys(chatVar.value).map((key) => {
const itemValue = chatVar.value[key]
return {
key,
type: typeof itemValue === 'string' ? ChatVarTypeEnum.String : ChatVarTypeEnum.Number,
value: itemValue,
}
})
}
export const formatObjectValueFromList = (list: ObjectValueItem[]) => {
return list.reduce<Record<string, string | number | null>>((acc, curr) => {
if (curr.key)
acc[curr.key] = curr.value === '' || curr.value === undefined ? null : curr.value
return acc
}, {})
}
export const formatChatVariableValue = ({
editInJSON,
objectValue,
type,
value,
}: {
editInJSON: boolean
objectValue: ObjectValueItem[]
type: ChatVarType
value: unknown
}) => {
const compactArrayValue = (items: unknown[]) =>
items.filter(item => item !== null && item !== undefined && item !== '')
switch (type) {
case ChatVarTypeEnum.String:
return value || ''
case ChatVarTypeEnum.Number:
return value || 0
case ChatVarTypeEnum.Boolean:
return value === undefined ? true : value
case ChatVarTypeEnum.Object:
return editInJSON ? value : formatObjectValueFromList(objectValue)
case ChatVarTypeEnum.ArrayString:
case ChatVarTypeEnum.ArrayNumber:
case ChatVarTypeEnum.ArrayObject:
return Array.isArray(value) ? compactArrayValue(value) : []
case ChatVarTypeEnum.ArrayBoolean:
return value || []
}
}
export const validateVariableName = ({
name,
notify,
t,
}: {
name: string
notify: (props: ToastPayload) => void
t: (key: string, options?: Record<string, unknown>) => string
}) => {
const { isValid, errorMessageKey } = checkKeys([name], false)
if (!isValid) {
notify({
type: 'error',
message: t(`varKeyError.${errorMessageKey}`, { ns: 'appDebug', key: t('env.modal.name', { ns: 'workflow' }) }),
})
return false
}
return true
}
export const getTypeChangeState = (nextType: ChatVarType) => {
return {
editInJSON: nextType === ChatVarTypeEnum.ArrayObject,
editorContent: undefined as string | undefined,
objectValue: nextType === ChatVarTypeEnum.Object ? [DEFAULT_OBJECT_VALUE] : undefined,
value:
nextType === ChatVarTypeEnum.Boolean
? false
: nextType === ChatVarTypeEnum.ArrayBoolean
? [false]
: undefined,
}
}
export const parseEditorContent = ({
content,
type,
}: {
content: string
type: ChatVarType
}) => {
const parsed = JSON.parse(content)
if (type !== ChatVarTypeEnum.ArrayBoolean)
return parsed
if (!Array.isArray(parsed))
throw new TypeError('ArrayBoolean editor content must be a JSON array')
return parsed
.map((item: string | boolean) => {
if (item === 'True' || item === 'true' || item === true)
return true
if (item === 'False' || item === 'false' || item === false)
return false
return undefined
})
.filter((item?: boolean) => item !== undefined)
}
export const getEditorToggleLabelKey = (type: ChatVarType, editInJSON: boolean) => {
if (type === ChatVarTypeEnum.Object)
return editInJSON ? 'chatVariable.modal.editInForm' : 'chatVariable.modal.editInJSON'
return editInJSON ? 'chatVariable.modal.oneByOne' : 'chatVariable.modal.editInJSON'
}