fix: hide checklist navigation for missing nodes

This commit is contained in:
lyzno1 2025-10-15 16:10:34 +08:00
parent bd31c6f90b
commit 4164e1191e
No known key found for this signature in database
2 changed files with 47 additions and 25 deletions

View File

@ -16,6 +16,7 @@ import {
useChecklist, useChecklist,
useNodesInteractions, useNodesInteractions,
} from '../hooks' } from '../hooks'
import type { ChecklistItem } from '../hooks/use-checklist'
import type { import type {
CommonEdgeType, CommonEdgeType,
CommonNodeType, CommonNodeType,
@ -45,6 +46,13 @@ const WorkflowChecklist = ({
const needWarningNodes = useChecklist(nodes, edges) const needWarningNodes = useChecklist(nodes, edges)
const { handleNodeSelect } = useNodesInteractions() const { handleNodeSelect } = useNodesInteractions()
const handleChecklistItemClick = (item: ChecklistItem) => {
if (!item.canNavigate)
return
handleNodeSelect(item.id)
setOpen(false)
}
return ( return (
<PortalToFollowElem <PortalToFollowElem
placement='bottom-end' placement='bottom-end'
@ -104,11 +112,11 @@ const WorkflowChecklist = ({
needWarningNodes.map(node => ( needWarningNodes.map(node => (
<div <div
key={node.id} key={node.id}
className='group mb-2 cursor-pointer rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xs last-of-type:mb-0' className={cn(
onClick={() => { 'group mb-2 rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xs last-of-type:mb-0',
handleNodeSelect(node.id) node.canNavigate ? 'cursor-pointer' : 'cursor-default opacity-80',
setOpen(false) )}
}} onClick={() => handleChecklistItemClick(node)}
> >
<div className='flex h-9 items-center p-2 text-xs font-medium text-text-secondary'> <div className='flex h-9 items-center p-2 text-xs font-medium text-text-secondary'>
<BlockIcon <BlockIcon
@ -119,12 +127,16 @@ const WorkflowChecklist = ({
<span className='grow truncate'> <span className='grow truncate'>
{node.title} {node.title}
</span> </span>
<div className='flex h-4 w-[60px] shrink-0 items-center justify-center gap-1 opacity-0 transition-opacity duration-200 group-hover:opacity-100'> {
<span className='whitespace-nowrap text-xs font-medium leading-4 text-primary-600'> node.canNavigate && (
{t('workflow.panel.goTo')} <div className='flex h-4 w-[60px] shrink-0 items-center justify-center gap-1 opacity-0 transition-opacity duration-200 group-hover:opacity-100'>
</span> <span className='whitespace-nowrap text-xs font-medium leading-4 text-primary-600'>
<IconR className='h-3.5 w-3.5 text-primary-600' /> {t('workflow.panel.goTo')}
</div> </span>
<IconR className='h-3.5 w-3.5 text-primary-600' />
</div>
)
}
</div> </div>
<div <div
className={cn( className={cn(

View File

@ -43,6 +43,23 @@ import { MAX_TREE_DEPTH } from '@/config'
import useNodesAvailableVarList, { useGetNodesAvailableVarList } from './use-nodes-available-var-list' import useNodesAvailableVarList, { useGetNodesAvailableVarList } from './use-nodes-available-var-list'
import { getNodeUsedVars, isSpecialVar } from '../nodes/_base/components/variable/utils' import { getNodeUsedVars, isSpecialVar } from '../nodes/_base/components/variable/utils'
export type ChecklistItem = {
id: string
type: BlockEnum | string
title: string
toolIcon?: string
unConnected?: boolean
errorMessage?: string
canNavigate: boolean
}
const START_NODE_TYPES: BlockEnum[] = [
BlockEnum.Start,
BlockEnum.TriggerSchedule,
BlockEnum.TriggerWebhook,
BlockEnum.TriggerPlugin,
]
export const useChecklist = (nodes: Node[], edges: Edge[]) => { export const useChecklist = (nodes: Node[], edges: Edge[]) => {
const { t } = useTranslation() const { t } = useTranslation()
const language = useGetLanguage() const language = useGetLanguage()
@ -74,8 +91,8 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
return checkData return checkData
}, [datasetsDetail]) }, [datasetsDetail])
const needWarningNodes = useMemo(() => { const needWarningNodes = useMemo<ChecklistItem[]>(() => {
const list = [] const list: ChecklistItem[] = []
const filteredNodes = nodes.filter(node => node.type === CUSTOM_NODE) const filteredNodes = nodes.filter(node => node.type === CUSTOM_NODE)
const { validNodes } = getValidTreeNodes(filteredNodes, edges) const { validNodes } = getValidTreeNodes(filteredNodes, edges)
@ -145,18 +162,14 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
toolIcon, toolIcon,
unConnected: isUnconnected && !isStartNode, unConnected: isUnconnected && !isStartNode,
errorMessage, errorMessage,
canNavigate: true,
}) })
} }
} }
} }
// Check for start nodes (including triggers) // Check for start nodes (including triggers)
const startNodesFiltered = nodes.filter(node => const startNodesFiltered = nodes.filter(node => START_NODE_TYPES.includes(node.data.type as BlockEnum))
node.data.type === BlockEnum.Start
|| node.data.type === BlockEnum.TriggerSchedule
|| node.data.type === BlockEnum.TriggerWebhook
|| node.data.type === BlockEnum.TriggerPlugin,
)
if (startNodesFiltered.length === 0) { if (startNodesFiltered.length === 0) {
list.push({ list.push({
@ -164,6 +177,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
type: BlockEnum.Start, type: BlockEnum.Start,
title: t('workflow.panel.startNode'), title: t('workflow.panel.startNode'),
errorMessage: t('workflow.common.needStartNode'), errorMessage: t('workflow.common.needStartNode'),
canNavigate: false,
}) })
} }
@ -176,6 +190,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
type, type,
title: t(`workflow.blocks.${type}`), title: t(`workflow.blocks.${type}`),
errorMessage: t('workflow.common.needAdd', { node: t(`workflow.blocks.${type}`) }), errorMessage: t('workflow.common.needAdd', { node: t(`workflow.blocks.${type}`) }),
canNavigate: false,
}) })
} }
}) })
@ -316,12 +331,7 @@ export const useChecklistBeforePublish = () => {
} }
} }
const startNodesFiltered = nodes.filter(node => const startNodesFiltered = nodes.filter(node => START_NODE_TYPES.includes(node.data.type as BlockEnum))
node.data.type === BlockEnum.Start
|| node.data.type === BlockEnum.TriggerSchedule
|| node.data.type === BlockEnum.TriggerWebhook
|| node.data.type === BlockEnum.TriggerPlugin,
)
if (startNodesFiltered.length === 0) { if (startNodesFiltered.length === 0) {
notify({ type: 'error', message: t('workflow.common.needStartNode') }) notify({ type: 'error', message: t('workflow.common.needStartNode') })