import type { BlockEnum, CommonNodeType } from '../types'
import type { TriggerDefaultValue } from './types'
import {
PreviewCard,
PreviewCardContent,
PreviewCardTrigger,
} from '@langgenius/dify-ui/preview-card'
import {
memo,
useCallback,
useEffect,
useMemo,
} from 'react'
import { useTranslation } from 'react-i18next'
import useNodes from '@/app/components/workflow/store/workflow/use-nodes'
import BlockIcon from '../block-icon'
import { BlockEnum as BlockEnumValues } from '../types'
// import { useNodeMetaData } from '../hooks'
import { START_BLOCKS } from './constants'
type StartBlocksProps = {
searchText: string
onSelect: (type: BlockEnum, triggerDefaultValue?: TriggerDefaultValue) => void
availableBlocksTypes?: BlockEnum[]
onContentStateChange?: (hasContent: boolean) => void
hideUserInput?: boolean
}
const StartBlocks = ({
searchText,
onSelect,
availableBlocksTypes = [],
onContentStateChange,
hideUserInput = false, // Allow parent to explicitly hide Start node option (e.g. when one already exists).
}: StartBlocksProps) => {
const { t } = useTranslation()
const nodes = useNodes()
// const nodeMetaData = useNodeMetaData()
const filteredBlocks = useMemo(() => {
// Check if Start node already exists in workflow
const hasStartNode = nodes.some(node => (node.data as CommonNodeType)?.type === BlockEnumValues.Start)
const normalizedSearch = searchText.toLowerCase()
const getDisplayName = (blockType: BlockEnum) => {
if (blockType === BlockEnumValues.TriggerWebhook)
return t('customWebhook', { ns: 'workflow' })
return t(`blocks.${blockType}`, { ns: 'workflow' })
}
return START_BLOCKS.filter((block) => {
// Hide User Input (Start) if it already exists in workflow or if hideUserInput is true
if (block.type === BlockEnumValues.Start && (hasStartNode || hideUserInput))
return false
// Filter by search text
const displayName = getDisplayName(block.type).toLowerCase()
if (!displayName.includes(normalizedSearch) && !block.title.toLowerCase().includes(normalizedSearch))
return false
// availableBlocksTypes now contains properly filtered entry node types from parent
return availableBlocksTypes.includes(block.type)
})
}, [searchText, availableBlocksTypes, nodes, t, hideUserInput])
const isEmpty = filteredBlocks.length === 0
useEffect(() => {
onContentStateChange?.(!isEmpty)
}, [isEmpty, onContentStateChange])
// Preview is supplementary: the block icon, title and description all become
// reachable from the inspector + canvas once the row is clicked to insert
// the start node, so hover/focus-only activation is a11y-safe. See
// packages/dify-ui/AGENTS.md → Overlay Primitive Selection.
const renderBlock = useCallback((block: typeof START_BLOCKS[number]) => (