diff --git a/web/apps/web/src/components/app/node-form/widgets/state-selector.tsx b/web/apps/web/src/components/app/node-form/widgets/state-selector.tsx index 05acf505..8e5d3591 100644 --- a/web/apps/web/src/components/app/node-form/widgets/state-selector.tsx +++ b/web/apps/web/src/components/app/node-form/widgets/state-selector.tsx @@ -1,5 +1,8 @@ import { useReactFlowStore, NodeTypeEnum } from '@shellagent/flow-engine'; import { Select } from '@shellagent/ui'; +import { useMemo } from 'react'; + +import { useAppState } from '@/stores/app/use-app-state'; interface StateSelectorProps { value: string; @@ -16,20 +19,42 @@ export const StateSelector = ({ excludeTargets = [], disabled = false, }: StateSelectorProps) => { - const { nodes } = useReactFlowStore(state => ({ + const { nodes, edges } = useReactFlowStore(state => ({ nodes: state.nodes, + edges: state.edges, + })); + + const { currentEdgeId } = useAppState(state => ({ + currentEdgeId: state.currentEdgeId, })); - const options = nodes - .filter( - node => - node.data.type !== NodeTypeEnum.start && - !excludeTargets.includes(node.id), - ) - .map(node => ({ - label: node.data.display_name || 'Untitled State', - value: node.id, - })); + const options = useMemo(() => { + const currentEdgeSource = edges.find(e => e.id === currentEdgeId)?.source; + + return nodes + .filter(node => { + const baseConditions = + node.data.type !== NodeTypeEnum.start && + node.data.type !== NodeTypeEnum.intro && + !excludeTargets.includes(node.id); + + if (node.id === value) { + return baseConditions; + } + + return ( + baseConditions && + !edges.some( + edge => + edge.source === currentEdgeSource && edge.target === node.id, + ) + ); + }) + .map(node => ({ + label: node.data.display_name || 'Untitled State', + value: node.id, + })); + }, [nodes, edges, value, excludeTargets]); return (
diff --git a/web/apps/web/src/components/app/node-form/widgets/transition-condition-editor.tsx b/web/apps/web/src/components/app/node-form/widgets/transition-condition-editor.tsx index 824774b4..3b897850 100644 --- a/web/apps/web/src/components/app/node-form/widgets/transition-condition-editor.tsx +++ b/web/apps/web/src/components/app/node-form/widgets/transition-condition-editor.tsx @@ -4,7 +4,6 @@ import { Cog8ToothIcon, ArrowRightIcon, } from '@heroicons/react/24/outline'; -import { useReactFlowStore } from '@shellagent/flow-engine'; import { Button, Input, IconButton, Drawer } from '@shellagent/ui'; import { produce } from 'immer'; import { useInjection } from 'inversify-react'; @@ -49,7 +48,7 @@ const ConditionItem = ({ }; const excludeTargets = conditions - .slice(0, index) + .filter((_, i) => i !== index) .map(condition => condition.target); return ( @@ -142,15 +141,12 @@ const TransitionConditionEditor = ({ ); }; - const { nodes } = useReactFlowStore(state => ({ - nodes: state.nodes, - })); - return (
{value?.map?.((condition, index) => ( handleChange(index, v)} onDelete={handleDelete} diff --git a/web/apps/web/src/components/home/detail-form/index.tsx b/web/apps/web/src/components/home/detail-form/index.tsx index f849b36f..9d7a535c 100644 --- a/web/apps/web/src/components/home/detail-form/index.tsx +++ b/web/apps/web/src/components/home/detail-form/index.tsx @@ -44,7 +44,7 @@ export default function DetailForm({ default: 'chat_bot', 'x-component-props': { options: [ - { label: 'ChatBot', value: 'chat_bot' }, + { label: 'Chatbot', value: 'chat_bot' }, { label: 'X Bot', value: 'x_bot' }, ], }, diff --git a/web/apps/web/src/components/home/filter-tabs/index.tsx b/web/apps/web/src/components/home/filter-tabs/index.tsx index 70a6e688..c8d5bcf9 100644 --- a/web/apps/web/src/components/home/filter-tabs/index.tsx +++ b/web/apps/web/src/components/home/filter-tabs/index.tsx @@ -11,7 +11,7 @@ import { cn } from '@/utils/cn'; const FILTER_OPTIONS: { value: AppType; label: string }[] = [ { value: 'all', label: 'All' }, - { value: 'chat_bot', label: 'ChatBot' }, + { value: 'chat_bot', label: 'Chatbot' }, { value: 'x_bot', label: 'X Bot' }, ];