mirror of
https://github.com/langgenius/dify.git
synced 2026-04-29 04:26:30 +08:00
type safe
This commit is contained in:
parent
b6e140f547
commit
9276f574c3
@ -1,4 +1,5 @@
|
|||||||
import type { AvailableNodesMetaData } from '@/app/components/workflow/hooks-store/store'
|
import type { AvailableNodesMetaData } from '@/app/components/workflow/hooks-store/store'
|
||||||
|
import type { I18nKeysWithPrefix } from '@/types/i18n'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { WORKFLOW_COMMON_NODES } from '@/app/components/workflow/constants/node'
|
import { WORKFLOW_COMMON_NODES } from '@/app/components/workflow/constants/node'
|
||||||
@ -42,8 +43,8 @@ export const useAvailableNodesMetaData = () => {
|
|||||||
|
|
||||||
const availableNodesMetaData = useMemo(() => mergedNodesMetaData.map((node) => {
|
const availableNodesMetaData = useMemo(() => mergedNodesMetaData.map((node) => {
|
||||||
const { metaData } = node
|
const { metaData } = node
|
||||||
const title = t(`blocks.${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 any, { ns: 'workflow' }) as string
|
const description = t(`blocksAbout.${metaData.type}` as I18nKeysWithPrefix<'workflow', 'blocksAbout.'>, { ns: 'workflow' })
|
||||||
const helpLinkPath = `guides/workflow/node/${metaData.helpLinkUri}`
|
const helpLinkPath = `guides/workflow/node/${metaData.helpLinkUri}`
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
|
|||||||
@ -18,7 +18,7 @@ export const useWorkflowTemplate = () => {
|
|||||||
data: {
|
data: {
|
||||||
...startDefault.defaultValue as StartNodeType,
|
...startDefault.defaultValue as StartNodeType,
|
||||||
type: startDefault.metaData.type,
|
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,
|
position: START_INITIAL_POSITION,
|
||||||
})
|
})
|
||||||
@ -34,7 +34,7 @@ export const useWorkflowTemplate = () => {
|
|||||||
},
|
},
|
||||||
selected: true,
|
selected: true,
|
||||||
type: llmDefault.metaData.type,
|
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: {
|
position: {
|
||||||
x: START_INITIAL_POSITION.x + NODE_WIDTH_X_OFFSET,
|
x: START_INITIAL_POSITION.x + NODE_WIDTH_X_OFFSET,
|
||||||
@ -48,7 +48,7 @@ export const useWorkflowTemplate = () => {
|
|||||||
...answerDefault.defaultValue,
|
...answerDefault.defaultValue,
|
||||||
answer: `{{#${llmNode.id}.text#}}`,
|
answer: `{{#${llmNode.id}.text#}}`,
|
||||||
type: answerDefault.metaData.type,
|
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: {
|
position: {
|
||||||
x: START_INITIAL_POSITION.x + NODE_WIDTH_X_OFFSET * 2,
|
x: START_INITIAL_POSITION.x + NODE_WIDTH_X_OFFSET * 2,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import type { NodeDefault } from '../types'
|
import type { NodeDefault } from '../types'
|
||||||
|
import type { BlockClassificationEnum } from './types'
|
||||||
import { groupBy } from 'es-toolkit/compat'
|
import { groupBy } from 'es-toolkit/compat'
|
||||||
import {
|
import {
|
||||||
memo,
|
memo,
|
||||||
@ -66,7 +67,7 @@ const Blocks = ({
|
|||||||
}, [blocks, searchText, availableBlocksTypes])
|
}, [blocks, searchText, availableBlocksTypes])
|
||||||
const isEmpty = Object.values(groups).every(list => !list.length)
|
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 list = groups[classification].sort((a, b) => (a.metaData.sort || 0) - (b.metaData.sort || 0))
|
||||||
const { getNodes } = store.getState()
|
const { getNodes } = store.getState()
|
||||||
const nodes = getNodes()
|
const nodes = getNodes()
|
||||||
@ -85,7 +86,7 @@ const Blocks = ({
|
|||||||
{
|
{
|
||||||
classification !== '-' && !!filteredList.length && (
|
classification !== '-' && !!filteredList.length && (
|
||||||
<div className="flex h-[22px] items-start px-3 text-xs font-medium text-text-tertiary">
|
<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>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,13 +2,13 @@ import type { Block } from '../types'
|
|||||||
import { BlockEnum } from '../types'
|
import { BlockEnum } from '../types'
|
||||||
import { BlockClassificationEnum } from './types'
|
import { BlockClassificationEnum } from './types'
|
||||||
|
|
||||||
export const BLOCK_CLASSIFICATIONS: string[] = [
|
export const BLOCK_CLASSIFICATIONS = [
|
||||||
BlockClassificationEnum.Default,
|
BlockClassificationEnum.Default,
|
||||||
BlockClassificationEnum.QuestionUnderstand,
|
BlockClassificationEnum.QuestionUnderstand,
|
||||||
BlockClassificationEnum.Logic,
|
BlockClassificationEnum.Logic,
|
||||||
BlockClassificationEnum.Transform,
|
BlockClassificationEnum.Transform,
|
||||||
BlockClassificationEnum.Utilities,
|
BlockClassificationEnum.Utilities,
|
||||||
]
|
] as const
|
||||||
|
|
||||||
export const DEFAULT_FILE_EXTENSIONS_IN_LOCAL_FILE_DATA_SOURCE = [
|
export const DEFAULT_FILE_EXTENSIONS_IN_LOCAL_FILE_DATA_SOURCE = [
|
||||||
'txt',
|
'txt',
|
||||||
@ -32,7 +32,7 @@ export const DEFAULT_FILE_EXTENSIONS_IN_LOCAL_FILE_DATA_SOURCE = [
|
|||||||
'md',
|
'md',
|
||||||
]
|
]
|
||||||
|
|
||||||
export const START_BLOCKS: Block[] = [
|
export const START_BLOCKS = [
|
||||||
{
|
{
|
||||||
classification: BlockClassificationEnum.Default,
|
classification: BlockClassificationEnum.Default,
|
||||||
type: BlockEnum.Start,
|
type: BlockEnum.Start,
|
||||||
@ -51,7 +51,7 @@ export const START_BLOCKS: Block[] = [
|
|||||||
title: 'Webhook Trigger',
|
title: 'Webhook Trigger',
|
||||||
description: 'HTTP callback trigger',
|
description: 'HTTP callback trigger',
|
||||||
},
|
},
|
||||||
]
|
] as const satisfies readonly Block[]
|
||||||
|
|
||||||
export const ENTRY_NODE_TYPES = [
|
export const ENTRY_NODE_TYPES = [
|
||||||
BlockEnum.Start,
|
BlockEnum.Start,
|
||||||
@ -60,7 +60,7 @@ export const ENTRY_NODE_TYPES = [
|
|||||||
BlockEnum.TriggerPlugin,
|
BlockEnum.TriggerPlugin,
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export const BLOCKS: Block[] = [
|
export const BLOCKS = [
|
||||||
{
|
{
|
||||||
classification: BlockClassificationEnum.Default,
|
classification: BlockClassificationEnum.Default,
|
||||||
type: BlockEnum.LLM,
|
type: BlockEnum.LLM,
|
||||||
@ -152,4 +152,4 @@ export const BLOCKS: Block[] = [
|
|||||||
type: BlockEnum.Agent,
|
type: BlockEnum.Agent,
|
||||||
title: 'Agent',
|
title: 'Agent',
|
||||||
},
|
},
|
||||||
]
|
] as const satisfies readonly Block[]
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export const useBlocks = () => {
|
|||||||
return BLOCKS.map((block) => {
|
return BLOCKS.map((block) => {
|
||||||
return {
|
return {
|
||||||
...block,
|
...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 START_BLOCKS.map((block) => {
|
||||||
return {
|
return {
|
||||||
...block,
|
...block,
|
||||||
title: t(`blocks.${block.type}` as any, { ns: 'workflow' }) as string,
|
title: t(`blocks.${block.type}`, { ns: 'workflow' }),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ const StartBlocks = ({
|
|||||||
if (blockType === BlockEnumValues.TriggerWebhook)
|
if (blockType === BlockEnumValues.TriggerWebhook)
|
||||||
return t('customWebhook', { ns: 'workflow' })
|
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) => {
|
return START_BLOCKS.filter((block) => {
|
||||||
@ -67,7 +67,7 @@ const StartBlocks = ({
|
|||||||
onContentStateChange?.(!isEmpty)
|
onContentStateChange?.(!isEmpty)
|
||||||
}, [isEmpty, onContentStateChange])
|
}, [isEmpty, onContentStateChange])
|
||||||
|
|
||||||
const renderBlock = useCallback((block: { type: BlockEnum, title: string, description?: string }) => (
|
const renderBlock = useCallback((block: typeof START_BLOCKS[number]) => (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
key={block.type}
|
key={block.type}
|
||||||
position="right"
|
position="right"
|
||||||
@ -83,10 +83,10 @@ const StartBlocks = ({
|
|||||||
<div className="system-md-medium mb-1 text-text-primary">
|
<div className="system-md-medium mb-1 text-text-primary">
|
||||||
{block.type === BlockEnumValues.TriggerWebhook
|
{block.type === BlockEnumValues.TriggerWebhook
|
||||||
? t('customWebhook', { ns: 'workflow' })
|
? t('customWebhook', { ns: 'workflow' })
|
||||||
: t(`blocks.${block.type}` as any, { ns: 'workflow' }) as string}
|
: t(`blocks.${block.type}`, { ns: 'workflow' })}
|
||||||
</div>
|
</div>
|
||||||
<div className="system-xs-regular text-text-secondary">
|
<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>
|
</div>
|
||||||
{(block.type === BlockEnumValues.TriggerWebhook || block.type === BlockEnumValues.TriggerSchedule) && (
|
{(block.type === BlockEnumValues.TriggerWebhook || block.type === BlockEnumValues.TriggerSchedule) && (
|
||||||
<div className="system-xs-regular mb-1 mt-1 text-text-tertiary">
|
<div className="system-xs-regular mb-1 mt-1 text-text-tertiary">
|
||||||
@ -107,7 +107,7 @@ const StartBlocks = ({
|
|||||||
type={block.type}
|
type={block.type}
|
||||||
/>
|
/>
|
||||||
<div className="flex w-0 grow items-center justify-between text-sm text-text-secondary">
|
<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 && (
|
{block.type === BlockEnumValues.Start && (
|
||||||
<span className="system-xs-regular ml-2 shrink-0 text-text-quaternary">{t('blocks.originalStartNode', { ns: 'workflow' })}</span>
|
<span className="system-xs-regular ml-2 shrink-0 text-text-quaternary">{t('blocks.originalStartNode', { ns: 'workflow' })}</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import type {
|
|||||||
} from '../types'
|
} from '../types'
|
||||||
import type { Emoji } from '@/app/components/tools/types'
|
import type { Emoji } from '@/app/components/tools/types'
|
||||||
import type { DataSet } from '@/models/datasets'
|
import type { DataSet } from '@/models/datasets'
|
||||||
|
import type { I18nKeysWithPrefix } from '@/types/i18n'
|
||||||
import {
|
import {
|
||||||
useCallback,
|
useCallback,
|
||||||
useMemo,
|
useMemo,
|
||||||
@ -237,8 +238,8 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
|
|||||||
list.push({
|
list.push({
|
||||||
id: `${type}-need-added`,
|
id: `${type}-need-added`,
|
||||||
type,
|
type,
|
||||||
title: 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 any, { ns: 'workflow' }) as string }),
|
errorMessage: t('common.needAdd', { ns: 'workflow', node: t(`blocks.${type}` as I18nKeysWithPrefix<'workflow', 'blocks.'>, { ns: 'workflow' }) }),
|
||||||
canNavigate: false,
|
canNavigate: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -409,7 +410,7 @@ export const useChecklistBeforePublish = () => {
|
|||||||
const type = isRequiredNodesType[i]
|
const type = isRequiredNodesType[i]
|
||||||
|
|
||||||
if (!filteredNodes.find(node => node.data.type === type)) {
|
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
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -978,6 +978,7 @@
|
|||||||
"singleRun.testRun": "Test Run",
|
"singleRun.testRun": "Test Run",
|
||||||
"singleRun.testRunIteration": "Test Run Iteration",
|
"singleRun.testRunIteration": "Test Run Iteration",
|
||||||
"singleRun.testRunLoop": "Test Run Loop",
|
"singleRun.testRunLoop": "Test Run Loop",
|
||||||
|
"tabs.-": "Default",
|
||||||
"tabs.addAll": "Add all",
|
"tabs.addAll": "Add all",
|
||||||
"tabs.agent": "Agent Strategy",
|
"tabs.agent": "Agent Strategy",
|
||||||
"tabs.allAdded": "All added",
|
"tabs.allAdded": "All added",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user