type safe

This commit is contained in:
Stephen Zhou 2025-12-27 00:11:57 +08:00
parent b6e140f547
commit 9276f574c3
No known key found for this signature in database
8 changed files with 27 additions and 23 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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 && (
<div className="flex h-[22px] items-start px-3 text-xs font-medium text-text-tertiary">
{t(`tabs.${classification}` as any, { ns: 'workflow' }) as string}
{t(`tabs.${classification}`, { ns: 'workflow' })}
</div>
)
}

View File

@ -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[]

View File

@ -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' }),
}
})
}

View File

@ -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]) => (
<Tooltip
key={block.type}
position="right"
@ -83,10 +83,10 @@ const StartBlocks = ({
<div className="system-md-medium mb-1 text-text-primary">
{block.type === BlockEnumValues.TriggerWebhook
? t('customWebhook', { ns: 'workflow' })
: t(`blocks.${block.type}` as any, { ns: 'workflow' }) as string}
: t(`blocks.${block.type}`, { ns: 'workflow' })}
</div>
<div className="system-xs-regular text-text-secondary">
{t(`blocksAbout.${block.type}` as any, { ns: 'workflow' }) as string}
{t(`blocksAbout.${block.type}`, { ns: 'workflow' })}
</div>
{(block.type === BlockEnumValues.TriggerWebhook || block.type === BlockEnumValues.TriggerSchedule) && (
<div className="system-xs-regular mb-1 mt-1 text-text-tertiary">
@ -107,7 +107,7 @@ const StartBlocks = ({
type={block.type}
/>
<div className="flex w-0 grow items-center justify-between text-sm text-text-secondary">
<span className="truncate">{t(`blocks.${block.type}` as any, { ns: 'workflow' }) as string}</span>
<span className="truncate">{t(`blocks.${block.type}`, { ns: 'workflow' })}</span>
{block.type === BlockEnumValues.Start && (
<span className="system-xs-regular ml-2 shrink-0 text-text-quaternary">{t('blocks.originalStartNode', { ns: 'workflow' })}</span>
)}

View File

@ -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
}
}

View File

@ -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",