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' },
];