mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 09:58:04 +08:00
Merge branch 'main' into feat/grouping-branching
This commit is contained in:
@ -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,
|
||||
@ -170,7 +171,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
|
||||
// Check if plugin is installed for plugin-dependent nodes first
|
||||
let errorMessage: string | undefined
|
||||
if (isPluginMissing)
|
||||
errorMessage = t('workflow.nodes.common.pluginNotInstalled')
|
||||
errorMessage = t('nodes.common.pluginNotInstalled', { ns: 'workflow' })
|
||||
else if (validator)
|
||||
errorMessage = validator(checkData, t, moreDataForCheckValid).errorMessage
|
||||
|
||||
@ -184,10 +185,10 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
|
||||
if (usedNode) {
|
||||
const usedVar = usedNode.vars.find(v => v.variable === variable?.[1])
|
||||
if (!usedVar)
|
||||
errorMessage = t('workflow.errorMsg.invalidVariable')
|
||||
errorMessage = t('errorMsg.invalidVariable', { ns: 'workflow' })
|
||||
}
|
||||
else {
|
||||
errorMessage = t('workflow.errorMsg.invalidVariable')
|
||||
errorMessage = t('errorMsg.invalidVariable', { ns: 'workflow' })
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -223,8 +224,8 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
|
||||
list.push({
|
||||
id: 'start-node-required',
|
||||
type: BlockEnum.Start,
|
||||
title: t('workflow.panel.startNode'),
|
||||
errorMessage: t('workflow.common.needStartNode'),
|
||||
title: t('panel.startNode', { ns: 'workflow' }),
|
||||
errorMessage: t('common.needStartNode', { ns: 'workflow' }),
|
||||
canNavigate: false,
|
||||
})
|
||||
}
|
||||
@ -237,8 +238,11 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
|
||||
list.push({
|
||||
id: `${type}-need-added`,
|
||||
type,
|
||||
title: t(`workflow.blocks.${type}`),
|
||||
errorMessage: t('workflow.common.needAdd', { node: t(`workflow.blocks.${type}`) }),
|
||||
// We don't have enough type info for t() here
|
||||
|
||||
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,
|
||||
})
|
||||
}
|
||||
@ -310,7 +314,7 @@ export const useChecklistBeforePublish = () => {
|
||||
const { validNodes, maxDepth } = getValidTreeNodes(filteredNodes, edges)
|
||||
|
||||
if (maxDepth > MAX_TREE_DEPTH) {
|
||||
notify({ type: 'error', message: t('workflow.common.maxTreeDepth', { depth: MAX_TREE_DEPTH }) })
|
||||
notify({ type: 'error', message: t('common.maxTreeDepth', { ns: 'workflow', depth: MAX_TREE_DEPTH }) })
|
||||
return false
|
||||
}
|
||||
// Before publish, we need to fetch datasets detail, in case of the settings of datasets have been changed
|
||||
@ -374,12 +378,12 @@ export const useChecklistBeforePublish = () => {
|
||||
if (usedNode) {
|
||||
const usedVar = usedNode.vars.find(v => v.variable === variable?.[1])
|
||||
if (!usedVar) {
|
||||
notify({ type: 'error', message: `[${node.data.title}] ${t('workflow.errorMsg.invalidVariable')}` })
|
||||
notify({ type: 'error', message: `[${node.data.title}] ${t('errorMsg.invalidVariable', { ns: 'workflow' })}` })
|
||||
return false
|
||||
}
|
||||
}
|
||||
else {
|
||||
notify({ type: 'error', message: `[${node.data.title}] ${t('workflow.errorMsg.invalidVariable')}` })
|
||||
notify({ type: 'error', message: `[${node.data.title}] ${t('errorMsg.invalidVariable', { ns: 'workflow' })}` })
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -390,7 +394,7 @@ export const useChecklistBeforePublish = () => {
|
||||
const isUnconnected = !validNodes.find(n => n.id === node.id)
|
||||
|
||||
if (isUnconnected && !canSkipConnectionCheck) {
|
||||
notify({ type: 'error', message: `[${node.data.title}] ${t('workflow.common.needConnectTip')}` })
|
||||
notify({ type: 'error', message: `[${node.data.title}] ${t('common.needConnectTip', { ns: 'workflow' })}` })
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -398,7 +402,7 @@ export const useChecklistBeforePublish = () => {
|
||||
if (shouldCheckStartNode) {
|
||||
const startNodesFiltered = nodes.filter(node => START_NODE_TYPES.includes(node.data.type as BlockEnum))
|
||||
if (startNodesFiltered.length === 0) {
|
||||
notify({ type: 'error', message: t('workflow.common.needStartNode') })
|
||||
notify({ type: 'error', message: t('common.needStartNode', { ns: 'workflow' }) })
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -409,7 +413,7 @@ export const useChecklistBeforePublish = () => {
|
||||
const type = isRequiredNodesType[i]
|
||||
|
||||
if (!filteredNodes.find(node => node.data.type === type)) {
|
||||
notify({ type: 'error', message: t('workflow.common.needAdd', { node: t(`workflow.blocks.${type}`) }) })
|
||||
notify({ type: 'error', message: t('common.needAdd', { ns: 'workflow', node: t(`blocks.${type}` as I18nKeysWithPrefix<'workflow', 'blocks.'>, { ns: 'workflow' }) }) })
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -431,7 +435,7 @@ export const useWorkflowRunValidation = () => {
|
||||
|
||||
const validateBeforeRun = useCallback(() => {
|
||||
if (needWarningNodes.length > 0) {
|
||||
notify({ type: 'error', message: t('workflow.panel.checklistTip') })
|
||||
notify({ type: 'error', message: t('panel.checklistTip', { ns: 'workflow' }) })
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@ -34,7 +34,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
||||
userInput = {
|
||||
id: node.id,
|
||||
type: TriggerType.UserInput,
|
||||
name: nodeData.title || t('workflow.blocks.start'),
|
||||
name: nodeData.title || t('blocks.start', { ns: 'workflow' }),
|
||||
icon: (
|
||||
<BlockIcon
|
||||
type={BlockEnum.Start}
|
||||
@ -49,7 +49,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
||||
allTriggers.push({
|
||||
id: node.id,
|
||||
type: TriggerType.Schedule,
|
||||
name: nodeData.title || t('workflow.blocks.trigger-schedule'),
|
||||
name: nodeData.title || t('blocks.trigger-schedule', { ns: 'workflow' }),
|
||||
icon: (
|
||||
<BlockIcon
|
||||
type={BlockEnum.TriggerSchedule}
|
||||
@ -64,7 +64,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
||||
allTriggers.push({
|
||||
id: node.id,
|
||||
type: TriggerType.Webhook,
|
||||
name: nodeData.title || t('workflow.blocks.trigger-webhook'),
|
||||
name: nodeData.title || t('blocks.trigger-webhook', { ns: 'workflow' }),
|
||||
icon: (
|
||||
<BlockIcon
|
||||
type={BlockEnum.TriggerWebhook}
|
||||
@ -94,7 +94,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
||||
allTriggers.push({
|
||||
id: node.id,
|
||||
type: TriggerType.Plugin,
|
||||
name: nodeData.title || (nodeData as any).plugin_name || t('workflow.blocks.trigger-plugin'),
|
||||
name: nodeData.title || (nodeData as any).plugin_name || t('blocks.trigger-plugin', { ns: 'workflow' }),
|
||||
icon,
|
||||
nodeId: node.id,
|
||||
enabled: true,
|
||||
@ -108,7 +108,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
||||
userInput = {
|
||||
id: startNode.id,
|
||||
type: TriggerType.UserInput,
|
||||
name: (startNode.data as CommonNodeType)?.title || t('workflow.blocks.start'),
|
||||
name: (startNode.data as CommonNodeType)?.title || t('blocks.start', { ns: 'workflow' }),
|
||||
icon: (
|
||||
<BlockIcon
|
||||
type={BlockEnum.Start}
|
||||
@ -129,7 +129,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
||||
? {
|
||||
id: 'run-all',
|
||||
type: TriggerType.All,
|
||||
name: t('workflow.common.runAllTriggers'),
|
||||
name: t('common.runAllTriggers', { ns: 'workflow' }),
|
||||
icon: (
|
||||
<div className="flex h-6 w-6 items-center justify-center rounded-lg border-[0.5px] border-white/2 bg-util-colors-purple-purple-500 text-white shadow-md">
|
||||
<TriggerAll className="h-4.5 w-4.5" />
|
||||
|
||||
@ -824,8 +824,8 @@ export const useNodesInteractions = () => {
|
||||
|
||||
if (!showConfirm) {
|
||||
setShowConfirm({
|
||||
title: t('workflow.nodes.iteration.deleteTitle'),
|
||||
desc: t('workflow.nodes.iteration.deleteDesc') || '',
|
||||
title: t('nodes.iteration.deleteTitle', { ns: 'workflow' }),
|
||||
desc: t('nodes.iteration.deleteDesc', { ns: 'workflow' }) || '',
|
||||
onConfirm: () => {
|
||||
iterationChildren.forEach((child) => {
|
||||
handleNodeDelete(child.id)
|
||||
@ -864,8 +864,8 @@ export const useNodesInteractions = () => {
|
||||
|
||||
if (!showConfirm) {
|
||||
setShowConfirm({
|
||||
title: t('workflow.nodes.loop.deleteTitle'),
|
||||
desc: t('workflow.nodes.loop.deleteDesc') || '',
|
||||
title: t('nodes.loop.deleteTitle', { ns: 'workflow' }),
|
||||
desc: t('nodes.loop.deleteDesc', { ns: 'workflow' }) || '',
|
||||
onConfirm: () => {
|
||||
loopChildren.forEach((child) => {
|
||||
handleNodeDelete(child.id)
|
||||
@ -1265,7 +1265,7 @@ export const useNodesInteractions = () => {
|
||||
|
||||
const afterNodesInSameBranch = getAfterNodesInSameBranch(nextNodeId!)
|
||||
const afterNodesInSameBranchIds = afterNodesInSameBranch.map(
|
||||
node => node.id,
|
||||
(node: Node) => node.id,
|
||||
)
|
||||
const newNodes = produce(nodes, (draft) => {
|
||||
draft.forEach((node) => {
|
||||
@ -1509,7 +1509,7 @@ export const useNodesInteractions = () => {
|
||||
|
||||
const afterNodesInSameBranch = getAfterNodesInSameBranch(nextNodeId!)
|
||||
const afterNodesInSameBranchIds = afterNodesInSameBranch.map(
|
||||
node => node.id,
|
||||
(node: Node) => node.id,
|
||||
)
|
||||
const newNodes = produce(nodes, (draft) => {
|
||||
draft.forEach((node) => {
|
||||
@ -2415,7 +2415,7 @@ export const useNodesInteractions = () => {
|
||||
const { x: minX, y: minY } = getTopLeftNodePosition(bundledNodes)
|
||||
|
||||
const groupNodeData: GroupNodeData = {
|
||||
title: t('workflow.operator.makeGroup'),
|
||||
title: t('operator.makeGroup', { ns: 'workflow' }),
|
||||
desc: '',
|
||||
type: BlockEnum.Group,
|
||||
members,
|
||||
|
||||
@ -3,7 +3,7 @@ import type {
|
||||
Node,
|
||||
} from '../types'
|
||||
import ELK from 'elkjs/lib/elk.bundled.js'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { cloneDeep } from 'es-toolkit/compat'
|
||||
import { useCallback } from 'react'
|
||||
import {
|
||||
useReactFlow,
|
||||
|
||||
@ -66,6 +66,11 @@ export const useShortcuts = (): void => {
|
||||
return !isEventTargetInputArea(e.target as HTMLElement)
|
||||
}, [])
|
||||
|
||||
const shouldHandleCopy = useCallback(() => {
|
||||
const selection = document.getSelection()
|
||||
return !selection || selection.isCollapsed
|
||||
}, [])
|
||||
|
||||
useKeyPress(['delete', 'backspace'], (e) => {
|
||||
if (shouldHandleShortcut(e)) {
|
||||
e.preventDefault()
|
||||
@ -77,7 +82,7 @@ export const useShortcuts = (): void => {
|
||||
useKeyPress(`${getKeyboardKeyCodeBySystem('ctrl')}.c`, (e) => {
|
||||
const { showDebugAndPreviewPanel } = workflowStore.getState()
|
||||
// Only intercept when nodes are selected via box selection
|
||||
if (shouldHandleShortcut(e) && !showDebugAndPreviewPanel && hasBundledNodes()) {
|
||||
if (shouldHandleShortcut(e) && shouldHandleCopy() && !showDebugAndPreviewPanel && hasBundledNodes()) {
|
||||
e.preventDefault()
|
||||
handleNodesCopy()
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { WorkflowHistoryEventMeta } from '../workflow-history-store'
|
||||
import { debounce } from 'lodash-es'
|
||||
import { debounce } from 'es-toolkit/compat'
|
||||
import {
|
||||
useCallback,
|
||||
useRef,
|
||||
@ -111,33 +111,33 @@ export const useWorkflowHistory = () => {
|
||||
const getHistoryLabel = useCallback((event: WorkflowHistoryEventT) => {
|
||||
switch (event) {
|
||||
case WorkflowHistoryEvent.NodeTitleChange:
|
||||
return t('workflow.changeHistory.nodeTitleChange')
|
||||
return t('changeHistory.nodeTitleChange', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.NodeDescriptionChange:
|
||||
return t('workflow.changeHistory.nodeDescriptionChange')
|
||||
return t('changeHistory.nodeDescriptionChange', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.LayoutOrganize:
|
||||
case WorkflowHistoryEvent.NodeDragStop:
|
||||
return t('workflow.changeHistory.nodeDragStop')
|
||||
return t('changeHistory.nodeDragStop', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.NodeChange:
|
||||
return t('workflow.changeHistory.nodeChange')
|
||||
return t('changeHistory.nodeChange', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.NodeConnect:
|
||||
return t('workflow.changeHistory.nodeConnect')
|
||||
return t('changeHistory.nodeConnect', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.NodePaste:
|
||||
return t('workflow.changeHistory.nodePaste')
|
||||
return t('changeHistory.nodePaste', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.NodeDelete:
|
||||
return t('workflow.changeHistory.nodeDelete')
|
||||
return t('changeHistory.nodeDelete', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.NodeAdd:
|
||||
return t('workflow.changeHistory.nodeAdd')
|
||||
return t('changeHistory.nodeAdd', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.EdgeDelete:
|
||||
case WorkflowHistoryEvent.EdgeDeleteByDeleteBranch:
|
||||
return t('workflow.changeHistory.edgeDelete')
|
||||
return t('changeHistory.edgeDelete', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.NodeResize:
|
||||
return t('workflow.changeHistory.nodeResize')
|
||||
return t('changeHistory.nodeResize', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.NoteAdd:
|
||||
return t('workflow.changeHistory.noteAdd')
|
||||
return t('changeHistory.noteAdd', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.NoteChange:
|
||||
return t('workflow.changeHistory.noteChange')
|
||||
return t('changeHistory.noteChange', { ns: 'workflow' })
|
||||
case WorkflowHistoryEvent.NoteDelete:
|
||||
return t('workflow.changeHistory.noteDelete')
|
||||
return t('changeHistory.noteDelete', { ns: 'workflow' })
|
||||
default:
|
||||
return 'Unknown Event'
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import type {
|
||||
Node,
|
||||
ValueSelector,
|
||||
} from '../types'
|
||||
import { uniqBy } from 'lodash-es'
|
||||
import { uniqBy } from 'es-toolkit/compat'
|
||||
import {
|
||||
useCallback,
|
||||
} from 'react'
|
||||
|
||||
Reference in New Issue
Block a user