feat: support bool type variable frontend (#24437)
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { RiAddLine } from '@remixicon/react'
|
||||
import produce from 'immer'
|
||||
import RemoveButton from '@/app/components/workflow/nodes/_base/components/remove-button'
|
||||
import Button from '@/app/components/base/button'
|
||||
import BoolValue from './bool-value'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type Props = {
|
||||
className?: string
|
||||
list: boolean[]
|
||||
onChange: (list: boolean[]) => void
|
||||
}
|
||||
|
||||
const ArrayValueList: FC<Props> = ({
|
||||
className,
|
||||
list,
|
||||
onChange,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const handleChange = useCallback((index: number) => {
|
||||
return (value: boolean) => {
|
||||
const newList = produce(list, (draft: any[]) => {
|
||||
draft[index] = value
|
||||
})
|
||||
onChange(newList)
|
||||
}
|
||||
}, [list, onChange])
|
||||
|
||||
const handleItemRemove = useCallback((index: number) => {
|
||||
return () => {
|
||||
const newList = produce(list, (draft) => {
|
||||
draft.splice(index, 1)
|
||||
})
|
||||
onChange(newList)
|
||||
}
|
||||
}, [list, onChange])
|
||||
|
||||
const handleItemAdd = useCallback(() => {
|
||||
const newList = produce(list, (draft: any[]) => {
|
||||
draft.push(false)
|
||||
})
|
||||
onChange(newList)
|
||||
}, [list, onChange])
|
||||
|
||||
return (
|
||||
<div className={cn('w-full space-y-2', className)}>
|
||||
{list.map((item, index) => (
|
||||
<div className='flex items-center space-x-1' key={index}>
|
||||
<BoolValue
|
||||
value={item}
|
||||
onChange={handleChange(index)}
|
||||
/>
|
||||
|
||||
<RemoveButton
|
||||
className='!bg-gray-100 !p-2 hover:!bg-gray-200'
|
||||
onClick={handleItemRemove(index)}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
<Button variant='tertiary' className='w-full' onClick={handleItemAdd}>
|
||||
<RiAddLine className='mr-1 h-4 w-4' />
|
||||
<span>{t('workflow.chatVariable.modal.addArrayValue')}</span>
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default React.memo(ArrayValueList)
|
@@ -0,0 +1,37 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useCallback } from 'react'
|
||||
import OptionCard from '../../../nodes/_base/components/option-card'
|
||||
|
||||
type Props = {
|
||||
value: boolean
|
||||
onChange: (value: boolean) => void
|
||||
}
|
||||
|
||||
const BoolValue: FC<Props> = ({
|
||||
value,
|
||||
onChange,
|
||||
}) => {
|
||||
const booleanValue = value
|
||||
const handleChange = useCallback((newValue: boolean) => {
|
||||
return () => {
|
||||
onChange(newValue)
|
||||
}
|
||||
}, [onChange])
|
||||
|
||||
return (
|
||||
<div className='flex w-full space-x-1'>
|
||||
<OptionCard className='grow'
|
||||
selected={booleanValue}
|
||||
title='True'
|
||||
onSelect={handleChange(true)}
|
||||
/>
|
||||
<OptionCard className='grow'
|
||||
selected={!booleanValue}
|
||||
title='False'
|
||||
onSelect={handleChange(false)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default React.memo(BoolValue)
|
@@ -16,6 +16,15 @@ import type { ConversationVariable } from '@/app/components/workflow/types'
|
||||
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||
import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
|
||||
import cn from '@/utils/classnames'
|
||||
import BoolValue from './bool-value'
|
||||
import ArrayBoolList from './array-bool-list'
|
||||
import {
|
||||
arrayBoolPlaceholder,
|
||||
arrayNumberPlaceholder,
|
||||
arrayObjectPlaceholder,
|
||||
arrayStringPlaceholder,
|
||||
objectPlaceholder,
|
||||
} from '@/app/components/workflow/panel/chat-variable-panel/utils'
|
||||
import { checkKeys, replaceSpaceWithUnderscoreInVarNameInput } from '@/utils/var'
|
||||
|
||||
export type ModalPropsType = {
|
||||
@@ -33,39 +42,14 @@ type ObjectValueItem = {
|
||||
const typeList = [
|
||||
ChatVarType.String,
|
||||
ChatVarType.Number,
|
||||
ChatVarType.Boolean,
|
||||
ChatVarType.Object,
|
||||
ChatVarType.ArrayString,
|
||||
ChatVarType.ArrayNumber,
|
||||
ChatVarType.ArrayBoolean,
|
||||
ChatVarType.ArrayObject,
|
||||
]
|
||||
|
||||
const objectPlaceholder = `# example
|
||||
# {
|
||||
# "name": "ray",
|
||||
# "age": 20
|
||||
# }`
|
||||
const arrayStringPlaceholder = `# example
|
||||
# [
|
||||
# "value1",
|
||||
# "value2"
|
||||
# ]`
|
||||
const arrayNumberPlaceholder = `# example
|
||||
# [
|
||||
# 100,
|
||||
# 200
|
||||
# ]`
|
||||
const arrayObjectPlaceholder = `# example
|
||||
# [
|
||||
# {
|
||||
# "name": "ray",
|
||||
# "age": 20
|
||||
# },
|
||||
# {
|
||||
# "name": "lily",
|
||||
# "age": 18
|
||||
# }
|
||||
# ]`
|
||||
|
||||
const ChatVariableModal = ({
|
||||
chatVar,
|
||||
onClose,
|
||||
@@ -94,6 +78,8 @@ const ChatVariableModal = ({
|
||||
return arrayNumberPlaceholder
|
||||
if (type === ChatVarType.ArrayObject)
|
||||
return arrayObjectPlaceholder
|
||||
if (type === ChatVarType.ArrayBoolean)
|
||||
return arrayBoolPlaceholder
|
||||
return objectPlaceholder
|
||||
}, [type])
|
||||
const getObjectValue = useCallback(() => {
|
||||
@@ -122,12 +108,16 @@ const ChatVariableModal = ({
|
||||
return value || ''
|
||||
case ChatVarType.Number:
|
||||
return value || 0
|
||||
case ChatVarType.Boolean:
|
||||
return value === undefined ? true : value
|
||||
case ChatVarType.Object:
|
||||
return editInJSON ? value : formatValueFromObject(objectValue)
|
||||
case ChatVarType.ArrayString:
|
||||
case ChatVarType.ArrayNumber:
|
||||
case ChatVarType.ArrayObject:
|
||||
return value?.filter(Boolean) || []
|
||||
case ChatVarType.ArrayBoolean:
|
||||
return value || []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +147,10 @@ const ChatVariableModal = ({
|
||||
setEditInJSON(true)
|
||||
if (v === ChatVarType.String || v === ChatVarType.Number || v === ChatVarType.Object)
|
||||
setEditInJSON(false)
|
||||
if(v === ChatVarType.Boolean)
|
||||
setValue(false)
|
||||
if (v === ChatVarType.ArrayBoolean)
|
||||
setValue([false])
|
||||
setType(v)
|
||||
}
|
||||
|
||||
@@ -202,6 +196,11 @@ const ChatVariableModal = ({
|
||||
setValue(value?.length ? value : [undefined])
|
||||
}
|
||||
}
|
||||
|
||||
if(type === ChatVarType.ArrayBoolean) {
|
||||
if(editInJSON)
|
||||
setEditorContent(JSON.stringify(value.map((item: boolean) => item ? 'True' : 'False')))
|
||||
}
|
||||
setEditInJSON(editInJSON)
|
||||
}
|
||||
|
||||
@@ -213,7 +212,16 @@ const ChatVariableModal = ({
|
||||
else {
|
||||
setEditorContent(content)
|
||||
try {
|
||||
const newValue = JSON.parse(content)
|
||||
let newValue = JSON.parse(content)
|
||||
if(type === ChatVarType.ArrayBoolean) {
|
||||
newValue = newValue.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)
|
||||
}
|
||||
setValue(newValue)
|
||||
}
|
||||
catch {
|
||||
@@ -304,7 +312,7 @@ const ChatVariableModal = ({
|
||||
<div className='mb-4'>
|
||||
<div className='system-sm-semibold mb-1 flex h-6 items-center justify-between text-text-secondary'>
|
||||
<div>{t('workflow.chatVariable.modal.value')}</div>
|
||||
{(type === ChatVarType.ArrayString || type === ChatVarType.ArrayNumber) && (
|
||||
{(type === ChatVarType.ArrayString || type === ChatVarType.ArrayNumber || type === ChatVarType.ArrayBoolean) && (
|
||||
<Button
|
||||
variant='ghost'
|
||||
size='small'
|
||||
@@ -345,6 +353,12 @@ const ChatVariableModal = ({
|
||||
type='number'
|
||||
/>
|
||||
)}
|
||||
{type === ChatVarType.Boolean && (
|
||||
<BoolValue
|
||||
value={value}
|
||||
onChange={setValue}
|
||||
/>
|
||||
)}
|
||||
{type === ChatVarType.Object && !editInJSON && (
|
||||
<ObjectValueList
|
||||
list={objectValue}
|
||||
@@ -365,6 +379,13 @@ const ChatVariableModal = ({
|
||||
onChange={setValue}
|
||||
/>
|
||||
)}
|
||||
{type === ChatVarType.ArrayBoolean && !editInJSON && (
|
||||
<ArrayBoolList
|
||||
list={value || [true]}
|
||||
onChange={setValue}
|
||||
/>
|
||||
)}
|
||||
|
||||
{editInJSON && (
|
||||
<div className='w-full rounded-[10px] bg-components-input-bg-normal py-2 pl-3 pr-1' style={{ height: editorMinHeight }}>
|
||||
<CodeEditor
|
||||
|
@@ -1,8 +1,10 @@
|
||||
export enum ChatVarType {
|
||||
Number = 'number',
|
||||
String = 'string',
|
||||
Boolean = 'boolean',
|
||||
Object = 'object',
|
||||
ArrayString = 'array[string]',
|
||||
ArrayNumber = 'array[number]',
|
||||
ArrayBoolean = 'array[boolean]',
|
||||
ArrayObject = 'array[object]',
|
||||
}
|
||||
|
@@ -0,0 +1,35 @@
|
||||
export const objectPlaceholder = `# example
|
||||
# {
|
||||
# "name": "ray",
|
||||
# "age": 20
|
||||
# }`
|
||||
|
||||
export const arrayStringPlaceholder = `# example
|
||||
# [
|
||||
# "value1",
|
||||
# "value2"
|
||||
# ]`
|
||||
|
||||
export const arrayNumberPlaceholder = `# example
|
||||
# [
|
||||
# 100,
|
||||
# 200
|
||||
# ]`
|
||||
|
||||
export const arrayObjectPlaceholder = `# example
|
||||
# [
|
||||
# {
|
||||
# "name": "ray",
|
||||
# "age": 20
|
||||
# },
|
||||
# {
|
||||
# "name": "lily",
|
||||
# "age": 18
|
||||
# }
|
||||
# ]`
|
||||
|
||||
export const arrayBoolPlaceholder = `# example
|
||||
# [
|
||||
# "True",
|
||||
# "False"
|
||||
# ]`
|
Reference in New Issue
Block a user