feat: redesign NodeFormDecision to label-only options, remove NodePicker
Users now type answer labels only. Stub nodes are created automatically by TreeCanvas when the decision node is saved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import { Play } from 'lucide-react'
|
import { Play } from 'lucide-react'
|
||||||
import { DynamicArrayField } from './DynamicArrayField'
|
import { DynamicArrayField } from './DynamicArrayField'
|
||||||
import { NodePicker } from './NodePicker'
|
|
||||||
import { useTreeEditorStore } from '@/store/treeEditorStore'
|
import { useTreeEditorStore } from '@/store/treeEditorStore'
|
||||||
import type { TreeStructure, TreeOption } from '@/types'
|
import type { TreeStructure, TreeOption } from '@/types'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
@@ -147,52 +146,34 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
|
|||||||
const optionLabelError = validationErrors.find(
|
const optionLabelError = validationErrors.find(
|
||||||
e => e.nodeId === node.id && e.field === `options[${index}].label`
|
e => e.nodeId === node.id && e.field === `options[${index}].label`
|
||||||
)
|
)
|
||||||
const optionNextError = validationErrors.find(
|
|
||||||
e => e.nodeId === node.id && e.field === `options[${index}].next_node_id`
|
|
||||||
)
|
|
||||||
const letter = indexToLetter(index)
|
const letter = indexToLetter(index)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rounded-md border border-border bg-accent/50 p-3">
|
<div className="flex items-center gap-2">
|
||||||
<div className="mb-2 flex items-center gap-2">
|
<span className={cn(
|
||||||
{/* Letter badge */}
|
'flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-bold',
|
||||||
<span className={cn(
|
isRootNode ? 'bg-blue-500/20 text-blue-400' : 'bg-accent text-muted-foreground'
|
||||||
'flex h-6 w-6 items-center justify-center rounded-full text-xs font-bold',
|
)}>
|
||||||
isRootNode
|
{letter}
|
||||||
? 'bg-blue-500/20 text-blue-400'
|
</span>
|
||||||
: 'bg-accent text-muted-foreground'
|
<div className="flex-1">
|
||||||
)}>
|
|
||||||
{letter}
|
|
||||||
</span>
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={option.label}
|
value={option.label}
|
||||||
onChange={(e) => handleUpdateOption(index, { label: e.target.value })}
|
onChange={(e) => handleUpdateOption(index, { label: e.target.value })}
|
||||||
placeholder={isRootNode
|
placeholder={isRootNode
|
||||||
? `Branch ${letter}: e.g., "Network Issues", "Application Errors"...`
|
? `Branch ${letter}: e.g., "Network Issues"...`
|
||||||
: `Option ${letter} label`}
|
: `Option ${letter} label`}
|
||||||
className={cn(
|
className={cn(
|
||||||
'block flex-1 rounded-md border px-3 py-2 text-sm',
|
'block w-full rounded-md border px-3 py-2 text-sm',
|
||||||
'bg-background text-foreground placeholder:text-muted-foreground',
|
'bg-background text-foreground placeholder:text-muted-foreground',
|
||||||
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary',
|
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary',
|
||||||
optionLabelError ? 'border-red-400' : 'border-border'
|
optionLabelError ? 'border-red-400' : 'border-border'
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
{optionLabelError && (
|
||||||
{optionLabelError && (
|
<p className="mt-1 text-xs text-red-400">{optionLabelError.message}</p>
|
||||||
<p className="mb-2 text-xs text-red-400">{optionLabelError.message}</p>
|
)}
|
||||||
)}
|
|
||||||
<div className="pl-8">
|
|
||||||
<NodePicker
|
|
||||||
value={option.next_node_id}
|
|
||||||
onChange={(nodeId) => handleUpdateOption(index, { next_node_id: nodeId })}
|
|
||||||
parentNodeId={node.id}
|
|
||||||
excludeNodeId={node.id}
|
|
||||||
placeholder={isRootNode
|
|
||||||
? `What happens when user selects "${option.label || `Branch ${letter}`}"?`
|
|
||||||
: "Select or create next node..."}
|
|
||||||
error={optionNextError?.message}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user