Commit dec60fdd authored by Joel's avatar Joel

feat: fin var assigner

parent 31930159
......@@ -4,24 +4,31 @@ import React from 'react'
import { useBoolean, useClickAway } from 'ahooks'
import cn from 'classnames'
import { ChevronSelectorVertical } from '@/app/components/base/icons/src/vender/line/arrows'
import { Check } from '@/app/components/base/icons/src/vender/line/general'
type Item = {
value: string
label: string
}
type Props = {
list: Item[]
trigger?: JSX.Element
options: Item[]
value: string
onChange: (value: any) => void
uppercase?: boolean
popupClassName?: string
readonly?: boolean
showChecked?: boolean
}
const TypeSelector: FC<Props> = ({
list,
trigger,
options: list,
value,
onChange,
uppercase,
popupClassName,
readonly,
showChecked,
}) => {
const item = list.find(item => item.value === value)
const [showOption, { setFalse: setHide, toggle: toggleShow }] = useBoolean(false)
......@@ -31,13 +38,24 @@ const TypeSelector: FC<Props> = ({
}, ref)
return (
<div className='relative left-[-8px]' ref={ref}>
<div
onClick={toggleShow}
className={cn(showOption && 'bg-black/5', 'flex items-center h-5 pl-1 pr-0.5 rounded-md text-xs font-semibold text-gray-700 cursor-pointer hover:bg-black/5')}>
<div className={cn('text-sm font-semibold', uppercase && 'uppercase')}>{item?.label}</div>
<ChevronSelectorVertical className='w-3 h-3 ' />
</div>
{showOption && (
{trigger
? (
<div
onClick={toggleShow}
>
{trigger}
</div>
)
: (
<div
onClick={toggleShow}
className={cn(showOption && 'bg-black/5', 'flex items-center h-5 pl-1 pr-0.5 rounded-md text-xs font-semibold text-gray-700 cursor-pointer hover:bg-black/5')}>
<div className={cn('text-sm font-semibold', uppercase && 'uppercase')}>{item?.label}</div>
<ChevronSelectorVertical className='w-3 h-3 ' />
</div>
)}
{(showOption && !readonly) && (
<div className={cn(popupClassName, 'absolute z-10 top-[24px] w-[120px] p-1 border border-gray-200 shadow-lg rounded-lg bg-white')}>
{list.map(item => (
<div
......@@ -46,8 +64,11 @@ const TypeSelector: FC<Props> = ({
setHide()
onChange(item.value)
}}
className={cn(uppercase && 'uppercase', 'flex items-center h-[30px] min-w-[44px] px-3 rounded-lg cursor-pointer text-[13px] font-medium text-gray-700 hover:bg-gray-50')}
>{item.label}</div>
className={cn(uppercase && 'uppercase', 'flex items-center h-[30px] justify-between min-w-[44px] px-3 rounded-lg cursor-pointer text-[13px] font-medium text-gray-700 hover:bg-gray-50')}
>
<div>{item.label}</div>
{showChecked && item.value === value && <Check className='text-primary-600 w-4 h-4' />}
</div>
))
}
</div>
......
......@@ -9,7 +9,7 @@ import AddButton from '@/app/components/base/button/add-button'
import Field from '@/app/components/workflow/nodes/_base/components/field'
import Split from '@/app/components/workflow/nodes/_base/components/split'
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
import TypeSelector from '@/app/components/workflow/nodes/_base/components/editor/type-selector'
import TypeSelector from '@/app/components/workflow/nodes/_base/components/selector'
const i18nPrefix = 'workflow.nodes.code'
const codeLanguages = [
......@@ -54,7 +54,7 @@ const Panel: FC = () => {
<CodeEditor
title={
<TypeSelector
list={codeLanguages}
options={codeLanguages}
value={inputs.code_language}
onChange={handleCodeLanguageChange}
/>
......
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import produce from 'immer'
import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker'
import type { ValueSelector } from '@/app/components/workflow/types'
import { Trash03 } from '@/app/components/base/icons/src/vender/line/general'
type Props = {
readonly: boolean
list: ValueSelector[]
onChange: (list: ValueSelector[]) => void
}
const VarList: FC<Props> = ({
readonly,
list,
onChange,
}) => {
const handleVarReferenceChange = useCallback((index: number) => {
return (value: ValueSelector) => {
const newList = produce(list, (draft) => {
draft[index] = value
})
onChange(newList)
}
}, [list, onChange])
const handleVarRemove = useCallback((index: number) => {
return () => {
const newList = produce(list, (draft) => {
draft.splice(index, 1)
})
onChange(newList)
}
}, [list, onChange])
return (
<div className='space-y-2'>
{list.map((item, index) => (
<div className='flex items-center space-x-1' key={index}>
<VarReferencePicker
readonly={readonly}
isShowNodeName
className='grow'
value={item}
onChange={handleVarReferenceChange(index)}
/>
<div
className='p-2 rounded-lg bg-gray-100 hover:bg-gray-200 cursor-pointer'
onClick={handleVarRemove(index)}
>
<Trash03 className='w-4 h-4 text-gray-500' />
</div>
</div>
))}
</div>
)
}
export default React.memo(VarList)
import { useCallback } from 'react'
import produce from 'immer'
import type { VariableAssignerNodeType } from './types'
import type { Variable } from '@/app/components/workflow/types'
import type { VariableAssignerNodeType } from '../../types'
import type { ValueSelector } from '@/app/components/workflow/types'
type Params = {
inputs: VariableAssignerNodeType
......@@ -11,15 +11,15 @@ function useVarList({
inputs,
setInputs,
}: Params) {
const handleVarListChange = useCallback((newList: Variable[]) => {
const newInputs = produce(inputs, (draft: any) => {
const handleVarListChange = useCallback((newList: ValueSelector[]) => {
const newInputs = produce(inputs, (draft) => {
draft.variables = newList
})
setInputs(newInputs)
}, [inputs, setInputs])
const handleAddVariable = useCallback(() => {
const newInputs = produce(inputs, (draft: any) => {
const newInputs = produce(inputs, (draft) => {
draft.variables.push([])
})
setInputs(newInputs)
......
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import useConfig from './use-config'
import { mockData } from './mock'
import VarList from './components/var-list'
import Field from '@/app/components/workflow/nodes/_base/components/field'
import Selector from '@/app/components/workflow/nodes/_base/components/selector'
import AddButton from '@/app/components/base/button/add-button'
import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows'
const i18nPrefix = 'workflow.nodes.variableAssigner'
const Panel: FC = () => {
const { t } = useTranslation()
const readOnly = false
const {
inputs,
handleOutputTypeChange,
handleVarListChange,
handleAddVariable,
} = useConfig(mockData)
const typeOptions = [
{ label: t(`${i18nPrefix}.type.string`), value: 'string' },
{ label: t(`${i18nPrefix}.type.number`), value: 'number' },
{ label: t(`${i18nPrefix}.type.object`), value: 'Object' },
{ label: t(`${i18nPrefix}.type.array`), value: 'array' },
]
return (
<div>start panel inputs</div>
<div className='mt-2'>
<div className='px-4 pb-4 space-y-4'>
<Field
title={t(`${i18nPrefix}.outputVarType`)}
>
<Selector
readonly={readOnly}
value={inputs.output_type}
options={typeOptions}
onChange={handleOutputTypeChange}
trigger={
<div className='flex items-center h-8 justify-between px-2.5 rounded-lg bg-gray-100 capitalize'>
<div className='text-[13px] font-normal text-gray-900'>{inputs.output_type}</div>
<ChevronDown className='w-3.5 h-3.5 text-gray-700' />
</div>
}
popupClassName='!top-[36px] !w-[387px]'
showChecked
/>
</Field>
<Field
title={t(`${i18nPrefix}.title`)}
operations={
<AddButton onClick={handleAddVariable} />
}
>
<VarList
readonly={readOnly}
list={inputs.variables}
onChange={handleVarListChange}
/>
</Field>
</div>
</div>
)
}
......
import { useCallback, useState } from 'react'
import produce from 'immer'
import useVarList from './use-var-list'
import useVarList from './components/var-list/use-var-list'
import type { VariableAssignerNodeType } from './types'
const useConfig = (initInputs: VariableAssignerNodeType) => {
......
......@@ -90,12 +90,13 @@ const translation = {
variableAssigner: {
title: 'Assign variables',
outputType: 'Output Type',
outputVarType: 'Output Variable Type',
varNotSet: 'Variable not set',
type: {
string: 'String',
number: 'Number',
object: 'Object',
arrayObject: 'Array[Object]',
array: 'Array',
},
},
},
......
......@@ -71,8 +71,8 @@ const translation = {
},
ifElse: {
conditions: '条件',
and: '',
or: '',
and: 'and',
or: 'or',
comparisonOperator: {
'contains': '包含',
'not contains': '不包含',
......@@ -89,12 +89,13 @@ const translation = {
variableAssigner: {
title: '变量赋值',
outputType: '输出类型',
outputVarType: '输出变量类型',
varNotSet: '未设置变量',
type: {
string: 'String',
number: 'Number',
object: 'Object',
arrayObject: 'Array[Object]',
array: 'Array',
},
},
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment