feat: limit config

This commit is contained in:
Joel 2024-07-31 17:01:26 +08:00
parent 944fea4cc9
commit e9ce9c1f47
6 changed files with 128 additions and 6 deletions

View File

@ -0,0 +1,102 @@
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import type { Limit } from '../types'
import cn from '@/utils/classnames'
import Field from '@/app/components/workflow/nodes/_base/components/field'
import Switch from '@/app/components/base/switch'
import Slider from '@/app/components/base/slider'
const i18nPrefix = 'workflow.nodes.listFilter'
const LIMIT_SIZE_MIN = 1
const LIMIT_SIZE_MAX = 20
const LIMIT_SIZE_DEFAULT = 10
type Props = {
className?: string
readonly: boolean
config: Limit
onChange: (limit: Limit) => void
canSetRoleName?: boolean
}
const LIMIT_DEFAULT: Limit = {
enabled: false,
size: LIMIT_SIZE_DEFAULT,
}
const LimitConfig: FC<Props> = ({
className,
readonly,
config = LIMIT_DEFAULT,
onChange,
}) => {
const { t } = useTranslation()
const payload = config
const handleLimitEnabledChange = useCallback((enabled: boolean) => {
onChange({
...config,
enabled,
})
}, [config, onChange])
const handleLimitSizeChange = useCallback((size: number | string) => {
onChange({
...config,
size: parseInt(size as string),
})
}, [onChange, config])
const handleBlur = useCallback(() => {
const payload = config
if (!payload)
return
if (payload.size === undefined || payload.size === null)
handleLimitSizeChange(LIMIT_SIZE_DEFAULT)
}, [handleLimitSizeChange, config])
return (
<div className={cn(className)}>
<Field
title={t(`${i18nPrefix}.limit`)}
operations={
<Switch
defaultValue={payload.enabled}
onChange={handleLimitEnabledChange}
size='md'
disabled={readonly}
/>
}
>
{payload && (
<div className='flex justify-between items-center h-8 space-x-2'>
<input
value={(payload?.size || LIMIT_SIZE_DEFAULT) as number}
className='shrink-0 block pl-3 w-12 h-8 appearance-none outline-none rounded-lg bg-gray-100 text-[13px] text-gra-900'
type='number'
min={LIMIT_SIZE_MIN}
max={LIMIT_SIZE_MAX}
step={1}
onChange={e => handleLimitSizeChange(e.target.value)}
onBlur={handleBlur}
disabled={readonly || !payload?.enabled}
/>
<Slider
className='grow'
value={(payload?.size || LIMIT_SIZE_DEFAULT) as number}
min={LIMIT_SIZE_MIN}
max={LIMIT_SIZE_MAX}
step={1}
onChange={handleLimitSizeChange}
disabled={readonly || !payload?.enabled}
/>
</div>
)}
</Field>
</div>
)
}
export default React.memo(LimitConfig)

View File

@ -5,6 +5,7 @@ import VarReferencePicker from '../_base/components/variable/var-reference-picke
import OutputVars, { VarItem } from '../_base/components/output-vars'
import useConfig from './use-config'
import type { ListFilterNodeType } from './types'
import LimitConfig from './components/limit-config'
import Field from '@/app/components/workflow/nodes/_base/components/field'
import { type NodePanelProps } from '@/app/components/workflow/types'
@ -21,6 +22,7 @@ const Panel: FC<NodePanelProps<ListFilterNodeType>> = ({
inputs,
handleVarChanges,
filterVar,
handleLimitChange,
} = useConfig(id, data)
return (
@ -38,6 +40,12 @@ const Panel: FC<NodePanelProps<ListFilterNodeType>> = ({
filterVar={filterVar}
/>
</Field>
<LimitConfig
config={inputs.limit}
onChange={handleLimitChange}
readonly={readOnly}
/>
</div>
<div className='px-4 pt-4 pb-2'>
<OutputVars>

View File

@ -5,6 +5,11 @@ export enum OrderBy {
DESC = 'desc',
}
export type Limit = {
enabled: boolean
size?: number
}
export type ListFilterNodeType = CommonNodeType & {
variable: ValueSelector
filterBy: []
@ -13,8 +18,5 @@ export type ListFilterNodeType = CommonNodeType & {
key: ValueSelector | string
value: OrderBy
}
limit: {
enabled: boolean
value: number
}
limit: Limit
}

View File

@ -2,7 +2,7 @@ import { useCallback } from 'react'
import produce from 'immer'
import type { ValueSelector, Var } from '../../types'
import { VarType } from '../../types'
import { type ListFilterNodeType } from './types'
import type { Limit, type ListFilterNodeType } from './types'
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
import {
useNodesReadOnly,
@ -21,14 +21,22 @@ const useConfig = (id: string, payload: ListFilterNodeType) => {
}, [inputs, setInputs])
const filterVar = useCallback((varPayload: Var) => {
return varPayload.type !== VarType.file
return [VarType.arrayNumber, VarType.arrayString, VarType.arrayFile, VarType.arrayObject].includes(varPayload.type)
}, [])
const handleLimitChange = useCallback((limit: Limit) => {
const newInputs = produce(inputs, (draft) => {
draft.limit = limit
})
setInputs(newInputs)
}, [inputs, setInputs])
return {
readOnly,
inputs,
filterVar,
handleVarChanges,
handleLimitChange,
}
}

View File

@ -501,6 +501,7 @@ const translation = {
},
listFilter: {
inputVar: 'Input Variable',
limit: 'Limit',
outputVars: {
result: 'Filter result',
first_record: 'First record',

View File

@ -501,6 +501,7 @@ const translation = {
},
listFilter: {
inputVar: '输入变量',
limit: '限制',
outputVars: {
result: '过滤结果',
first_record: '第一条记录',