From 9276f574c3d30709b366d0bab2915638203bc7cc Mon Sep 17 00:00:00 2001 From: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Date: Sat, 27 Dec 2025 00:11:57 +0800 Subject: [PATCH] type safe --- .../hooks/use-available-nodes-meta-data.ts | 5 +++-- .../workflow-app/hooks/use-workflow-template.ts | 6 +++--- .../components/workflow/block-selector/blocks.tsx | 5 +++-- .../components/workflow/block-selector/constants.tsx | 12 ++++++------ web/app/components/workflow/block-selector/hooks.ts | 4 ++-- .../workflow/block-selector/start-blocks.tsx | 10 +++++----- web/app/components/workflow/hooks/use-checklist.ts | 7 ++++--- web/i18n/en-US/workflow.json | 1 + 8 files changed, 27 insertions(+), 23 deletions(-) diff --git a/web/app/components/workflow-app/hooks/use-available-nodes-meta-data.ts b/web/app/components/workflow-app/hooks/use-available-nodes-meta-data.ts index d28a51f2d3..032cff54be 100644 --- a/web/app/components/workflow-app/hooks/use-available-nodes-meta-data.ts +++ b/web/app/components/workflow-app/hooks/use-available-nodes-meta-data.ts @@ -1,4 +1,5 @@ import type { AvailableNodesMetaData } from '@/app/components/workflow/hooks-store/store' +import type { I18nKeysWithPrefix } from '@/types/i18n' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import { WORKFLOW_COMMON_NODES } from '@/app/components/workflow/constants/node' @@ -42,8 +43,8 @@ export const useAvailableNodesMetaData = () => { const availableNodesMetaData = useMemo(() => mergedNodesMetaData.map((node) => { const { metaData } = node - const title = t(`blocks.${metaData.type}` as any, { ns: 'workflow' }) as string - const description = t(`blocksAbout.${metaData.type}` as any, { ns: 'workflow' }) as string + const title = t(`blocks.${metaData.type}` as I18nKeysWithPrefix<'workflow', 'blocks.'>, { ns: 'workflow' }) + const description = t(`blocksAbout.${metaData.type}` as I18nKeysWithPrefix<'workflow', 'blocksAbout.'>, { ns: 'workflow' }) const helpLinkPath = `guides/workflow/node/${metaData.helpLinkUri}` return { ...node, diff --git a/web/app/components/workflow-app/hooks/use-workflow-template.ts b/web/app/components/workflow-app/hooks/use-workflow-template.ts index d2930a5f3e..5a89d3b3e7 100644 --- a/web/app/components/workflow-app/hooks/use-workflow-template.ts +++ b/web/app/components/workflow-app/hooks/use-workflow-template.ts @@ -18,7 +18,7 @@ export const useWorkflowTemplate = () => { data: { ...startDefault.defaultValue as StartNodeType, type: startDefault.metaData.type, - title: t(`blocks.${startDefault.metaData.type}` as any, { ns: 'workflow' }) as string, + title: t(`blocks.${startDefault.metaData.type}`, { ns: 'workflow' }), }, position: START_INITIAL_POSITION, }) @@ -34,7 +34,7 @@ export const useWorkflowTemplate = () => { }, selected: true, type: llmDefault.metaData.type, - title: t(`blocks.${llmDefault.metaData.type}` as any, { ns: 'workflow' }) as string, + title: t(`blocks.${llmDefault.metaData.type}`, { ns: 'workflow' }), }, position: { x: START_INITIAL_POSITION.x + NODE_WIDTH_X_OFFSET, @@ -48,7 +48,7 @@ export const useWorkflowTemplate = () => { ...answerDefault.defaultValue, answer: `{{#${llmNode.id}.text#}}`, type: answerDefault.metaData.type, - title: t(`blocks.${answerDefault.metaData.type}` as any, { ns: 'workflow' }) as string, + title: t(`blocks.${answerDefault.metaData.type}`, { ns: 'workflow' }), }, position: { x: START_INITIAL_POSITION.x + NODE_WIDTH_X_OFFSET * 2, diff --git a/web/app/components/workflow/block-selector/blocks.tsx b/web/app/components/workflow/block-selector/blocks.tsx index f8464a44a6..96977500ee 100644 --- a/web/app/components/workflow/block-selector/blocks.tsx +++ b/web/app/components/workflow/block-selector/blocks.tsx @@ -1,4 +1,5 @@ import type { NodeDefault } from '../types' +import type { BlockClassificationEnum } from './types' import { groupBy } from 'es-toolkit/compat' import { memo, @@ -66,7 +67,7 @@ const Blocks = ({ }, [blocks, searchText, availableBlocksTypes]) const isEmpty = Object.values(groups).every(list => !list.length) - const renderGroup = useCallback((classification: string) => { + const renderGroup = useCallback((classification: BlockClassificationEnum) => { const list = groups[classification].sort((a, b) => (a.metaData.sort || 0) - (b.metaData.sort || 0)) const { getNodes } = store.getState() const nodes = getNodes() @@ -85,7 +86,7 @@ const Blocks = ({ { classification !== '-' && !!filteredList.length && (
- {t(`tabs.${classification}` as any, { ns: 'workflow' }) as string} + {t(`tabs.${classification}`, { ns: 'workflow' })}
) } diff --git a/web/app/components/workflow/block-selector/constants.tsx b/web/app/components/workflow/block-selector/constants.tsx index ec05985453..5ecce2aa49 100644 --- a/web/app/components/workflow/block-selector/constants.tsx +++ b/web/app/components/workflow/block-selector/constants.tsx @@ -2,13 +2,13 @@ import type { Block } from '../types' import { BlockEnum } from '../types' import { BlockClassificationEnum } from './types' -export const BLOCK_CLASSIFICATIONS: string[] = [ +export const BLOCK_CLASSIFICATIONS = [ BlockClassificationEnum.Default, BlockClassificationEnum.QuestionUnderstand, BlockClassificationEnum.Logic, BlockClassificationEnum.Transform, BlockClassificationEnum.Utilities, -] +] as const export const DEFAULT_FILE_EXTENSIONS_IN_LOCAL_FILE_DATA_SOURCE = [ 'txt', @@ -32,7 +32,7 @@ export const DEFAULT_FILE_EXTENSIONS_IN_LOCAL_FILE_DATA_SOURCE = [ 'md', ] -export const START_BLOCKS: Block[] = [ +export const START_BLOCKS = [ { classification: BlockClassificationEnum.Default, type: BlockEnum.Start, @@ -51,7 +51,7 @@ export const START_BLOCKS: Block[] = [ title: 'Webhook Trigger', description: 'HTTP callback trigger', }, -] +] as const satisfies readonly Block[] export const ENTRY_NODE_TYPES = [ BlockEnum.Start, @@ -60,7 +60,7 @@ export const ENTRY_NODE_TYPES = [ BlockEnum.TriggerPlugin, ] as const -export const BLOCKS: Block[] = [ +export const BLOCKS = [ { classification: BlockClassificationEnum.Default, type: BlockEnum.LLM, @@ -152,4 +152,4 @@ export const BLOCKS: Block[] = [ type: BlockEnum.Agent, title: 'Agent', }, -] +] as const satisfies readonly Block[] diff --git a/web/app/components/workflow/block-selector/hooks.ts b/web/app/components/workflow/block-selector/hooks.ts index a2804be526..ad21df1cb8 100644 --- a/web/app/components/workflow/block-selector/hooks.ts +++ b/web/app/components/workflow/block-selector/hooks.ts @@ -17,7 +17,7 @@ export const useBlocks = () => { return BLOCKS.map((block) => { return { ...block, - title: t(`blocks.${block.type}` as any, { ns: 'workflow' }) as string, + title: t(`blocks.${block.type}`, { ns: 'workflow' }), } }) } @@ -28,7 +28,7 @@ export const useStartBlocks = () => { return START_BLOCKS.map((block) => { return { ...block, - title: t(`blocks.${block.type}` as any, { ns: 'workflow' }) as string, + title: t(`blocks.${block.type}`, { ns: 'workflow' }), } }) } diff --git a/web/app/components/workflow/block-selector/start-blocks.tsx b/web/app/components/workflow/block-selector/start-blocks.tsx index 9c8ffc3e34..69d8989a07 100644 --- a/web/app/components/workflow/block-selector/start-blocks.tsx +++ b/web/app/components/workflow/block-selector/start-blocks.tsx @@ -43,7 +43,7 @@ const StartBlocks = ({ if (blockType === BlockEnumValues.TriggerWebhook) return t('customWebhook', { ns: 'workflow' }) - return t(`blocks.${blockType}` as any, { ns: 'workflow' }) as string + return t(`blocks.${blockType}`, { ns: 'workflow' }) } return START_BLOCKS.filter((block) => { @@ -67,7 +67,7 @@ const StartBlocks = ({ onContentStateChange?.(!isEmpty) }, [isEmpty, onContentStateChange]) - const renderBlock = useCallback((block: { type: BlockEnum, title: string, description?: string }) => ( + const renderBlock = useCallback((block: typeof START_BLOCKS[number]) => ( {block.type === BlockEnumValues.TriggerWebhook ? t('customWebhook', { ns: 'workflow' }) - : t(`blocks.${block.type}` as any, { ns: 'workflow' }) as string} + : t(`blocks.${block.type}`, { ns: 'workflow' })}
- {t(`blocksAbout.${block.type}` as any, { ns: 'workflow' }) as string} + {t(`blocksAbout.${block.type}`, { ns: 'workflow' })}
{(block.type === BlockEnumValues.TriggerWebhook || block.type === BlockEnumValues.TriggerSchedule) && (
@@ -107,7 +107,7 @@ const StartBlocks = ({ type={block.type} />
- {t(`blocks.${block.type}` as any, { ns: 'workflow' }) as string} + {t(`blocks.${block.type}`, { ns: 'workflow' })} {block.type === BlockEnumValues.Start && ( {t('blocks.originalStartNode', { ns: 'workflow' })} )} diff --git a/web/app/components/workflow/hooks/use-checklist.ts b/web/app/components/workflow/hooks/use-checklist.ts index b9157f202d..90d85e610b 100644 --- a/web/app/components/workflow/hooks/use-checklist.ts +++ b/web/app/components/workflow/hooks/use-checklist.ts @@ -13,6 +13,7 @@ import type { } from '../types' import type { Emoji } from '@/app/components/tools/types' import type { DataSet } from '@/models/datasets' +import type { I18nKeysWithPrefix } from '@/types/i18n' import { useCallback, useMemo, @@ -237,8 +238,8 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => { list.push({ id: `${type}-need-added`, type, - title: t(`blocks.${type}` as any, { ns: 'workflow' }) as string, - errorMessage: t('common.needAdd', { ns: 'workflow', node: t(`blocks.${type}` as any, { ns: 'workflow' }) as string }), + title: t(`blocks.${type}` as I18nKeysWithPrefix<'workflow', 'blocks.'>, { ns: 'workflow' }), + errorMessage: t('common.needAdd', { ns: 'workflow', node: t(`blocks.${type}` as I18nKeysWithPrefix<'workflow', 'blocks.'>, { ns: 'workflow' }) }), canNavigate: false, }) } @@ -409,7 +410,7 @@ export const useChecklistBeforePublish = () => { const type = isRequiredNodesType[i] if (!filteredNodes.find(node => node.data.type === type)) { - notify({ type: 'error', message: t('common.needAdd', { ns: 'workflow', node: t(`blocks.${type}` as any, { ns: 'workflow' }) as string }) }) + notify({ type: 'error', message: t('common.needAdd', { ns: 'workflow', node: t(`blocks.${type}` as I18nKeysWithPrefix<'workflow', 'blocks.'>, { ns: 'workflow' }) }) }) return false } } diff --git a/web/i18n/en-US/workflow.json b/web/i18n/en-US/workflow.json index 454b4a4253..6edbdb99f6 100644 --- a/web/i18n/en-US/workflow.json +++ b/web/i18n/en-US/workflow.json @@ -978,6 +978,7 @@ "singleRun.testRun": "Test Run", "singleRun.testRunIteration": "Test Run Iteration", "singleRun.testRunLoop": "Test Run Loop", + "tabs.-": "Default", "tabs.addAll": "Add all", "tabs.agent": "Agent Strategy", "tabs.allAdded": "All added",