From e9ce9c1f471626e54ab82845bb87ed042a945e12 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 31 Jul 2024 17:01:26 +0800 Subject: [PATCH] feat: limit config --- .../list-filter/components/limit-config.tsx | 102 ++++++++++++++++++ .../workflow/nodes/list-filter/panel.tsx | 8 ++ .../workflow/nodes/list-filter/types.ts | 10 +- .../workflow/nodes/list-filter/use-config.ts | 12 ++- web/i18n/en-US/workflow.ts | 1 + web/i18n/zh-Hans/workflow.ts | 1 + 6 files changed, 128 insertions(+), 6 deletions(-) create mode 100644 web/app/components/workflow/nodes/list-filter/components/limit-config.tsx diff --git a/web/app/components/workflow/nodes/list-filter/components/limit-config.tsx b/web/app/components/workflow/nodes/list-filter/components/limit-config.tsx new file mode 100644 index 0000000000..6e40346e50 --- /dev/null +++ b/web/app/components/workflow/nodes/list-filter/components/limit-config.tsx @@ -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 = ({ + 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 ( +
+ + } + > + {payload && ( +
+ handleLimitSizeChange(e.target.value)} + onBlur={handleBlur} + disabled={readonly || !payload?.enabled} + /> + +
+ )} +
+
+ ) +} +export default React.memo(LimitConfig) diff --git a/web/app/components/workflow/nodes/list-filter/panel.tsx b/web/app/components/workflow/nodes/list-filter/panel.tsx index 2393255219..186fda5ae7 100644 --- a/web/app/components/workflow/nodes/list-filter/panel.tsx +++ b/web/app/components/workflow/nodes/list-filter/panel.tsx @@ -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> = ({ inputs, handleVarChanges, filterVar, + handleLimitChange, } = useConfig(id, data) return ( @@ -38,6 +40,12 @@ const Panel: FC> = ({ filterVar={filterVar} /> + +
diff --git a/web/app/components/workflow/nodes/list-filter/types.ts b/web/app/components/workflow/nodes/list-filter/types.ts index bbb4b24306..2e9459344c 100644 --- a/web/app/components/workflow/nodes/list-filter/types.ts +++ b/web/app/components/workflow/nodes/list-filter/types.ts @@ -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 } diff --git a/web/app/components/workflow/nodes/list-filter/use-config.ts b/web/app/components/workflow/nodes/list-filter/use-config.ts index 0dbf429057..a59b96c423 100644 --- a/web/app/components/workflow/nodes/list-filter/use-config.ts +++ b/web/app/components/workflow/nodes/list-filter/use-config.ts @@ -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, } } diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts index b2d9ca6c93..1c7db5d192 100644 --- a/web/i18n/en-US/workflow.ts +++ b/web/i18n/en-US/workflow.ts @@ -501,6 +501,7 @@ const translation = { }, listFilter: { inputVar: 'Input Variable', + limit: 'Limit', outputVars: { result: 'Filter result', first_record: 'First record', diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index 983acca290..359f95b89f 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -501,6 +501,7 @@ const translation = { }, listFilter: { inputVar: '输入变量', + limit: '限制', outputVars: { result: '过滤结果', first_record: '第一条记录',