@@ -25,6 +25,7 @@ import { MediaManager } from './MediaManager';
2525import { GraphScore } from './GraphScore' ;
2626import { CompactScoreDisplay } from './CompactScoreDisplay' ;
2727import { SlideShow } from './SlideShow' ;
28+ import { DraggableModal } from './DraggableModal' ;
2829import { calculateGraphScore } from './utils/graphScoring' ;
2930import { ensureDescriptionBlocks , extractDescriptionsForAnalysis , debugDescriptions } from './utils/cnlProcessor' ;
3031import { analyzeMultipleTexts , type NLPAnalysisResult , type NLPAnalysisError } from './services/nlpAnalysisService' ;
@@ -128,6 +129,7 @@ function App({ onLogout, onGoToDashboard, user }: AppProps) {
128129 const [ attributeTypes , setAttributeTypes ] = useState < AttributeType [ ] > ( [ ] ) ;
129130 const [ nodeTypes , setNodeTypes ] = useState < any [ ] > ( [ ] ) ;
130131 const [ selectedNodeId , setSelectedNodeId ] = useState < string | null > ( null ) ;
132+ const [ isNodeCardOpen , setIsNodeCardOpen ] = useState < boolean > ( false ) ;
131133 const [ graphMode , setGraphMode ] = useState < 'markdown' | 'mindmap' | 'richgraph' | 'strictgraph' > ( 'richgraph' ) ;
132134 // Single CNL text for the current graph
133135 const [ cnlText , setCnlText ] = useState < string > ( '' ) ;
@@ -178,6 +180,45 @@ function App({ onLogout, onGoToDashboard, user }: AppProps) {
178180 alert ( `Failed to change morph: ${ error . message } ` ) ;
179181 }
180182 } ;
183+
184+ // Transition simulation handler
185+ const handleTransitionSimulate = async ( transitionId : string ) => {
186+ try {
187+ console . log ( `[App] Simulating transition ${ transitionId } ` ) ;
188+
189+ // For now, we'll just show an alert. In the future, this could:
190+ // 1. Call a backend API to simulate the transition
191+ // 2. Update node states based on the transition
192+ // 3. Show animation or visual feedback
193+
194+ const transitionNode = nodes . find ( n => n . id === transitionId ) ;
195+ if ( transitionNode ) {
196+ alert ( `Simulating transition: ${ transitionNode . name } \n\nThis would transform the prior states into post states according to the transition rules.` ) ;
197+ }
198+
199+ } catch ( error ) {
200+ console . error ( '[App] Error simulating transition:' , error ) ;
201+ alert ( 'Failed to simulate transition. See console for details.' ) ;
202+ }
203+ } ;
204+
205+ // Enhanced node selection handler
206+ const handleNodeSelect = ( nodeId : string | null ) => {
207+ if ( nodeId ) {
208+ // Clicking on a node: select it and open/keep modal open
209+ setSelectedNodeId ( nodeId ) ;
210+ setIsNodeCardOpen ( true ) ;
211+ } else {
212+ // Clicking on empty space: close modal but keep selected node for reference
213+ setIsNodeCardOpen ( false ) ;
214+ }
215+ } ;
216+
217+ // Handler for closing the modal
218+ const handleCloseNodeCard = ( ) => {
219+ setIsNodeCardOpen ( false ) ;
220+ setSelectedNodeId ( null ) ;
221+ } ;
181222 const [ isWordNetLoading , setIsWordNetLoading ] = useState ( false ) ;
182223 const [ wordNetError , setWordNetError ] = useState < string | null > ( null ) ;
183224 const [ strictMode , setStrictMode ] = useState < boolean > ( false ) ;
@@ -741,24 +782,30 @@ function App({ onLogout, onGoToDashboard, user }: AppProps) {
741782 />
742783 ) : (
743784 < >
744- < Visualization nodes = { nodes } relations = { relations } attributes = { attributes } onNodeSelect = { setSelectedNodeId } onMorphChange = { handleMorphChange } graphMode = { graphMode === 'strictgraph' ? 'richgraph' : graphMode } />
745- { selectedNode && (
746- < div className = { styles . selectedNodeCard } >
785+ < Visualization nodes = { nodes } relations = { relations } attributes = { attributes } onNodeSelect = { handleNodeSelect } onMorphChange = { handleMorphChange } graphMode = { graphMode === 'strictgraph' ? 'richgraph' : graphMode } />
786+ < DraggableModal
787+ isOpen = { isNodeCardOpen && ! ! selectedNode }
788+ onClose = { handleCloseNodeCard }
789+ title = { selectedNode ? `${ selectedNode . name } ${ selectedNode . role === 'Transition' ? '(Transition)' : '' } ` : '' }
790+ initialPosition = { { x : 100 , y : 100 } }
791+ >
792+ { selectedNode && (
747793 < NodeCard
748794 node = { selectedNode }
749795 allNodes = { nodes }
750796 allRelations = { relations }
751- attributes = { attributeTypes }
797+ attributes = { attributes }
752798 isActive = { false }
753799 onSelectNode = { ( nodeId ) => console . log ( 'Node selected:' , nodeId ) }
754800 onImportContext = { ( nodeId ) => console . log ( 'Import context:' , nodeId ) }
755801 nodeRegistry = { { } }
756802 isPublic = { false }
757803 graphId = { activeGraphId || undefined }
758804 onMorphChange = { handleMorphChange }
805+ onTransitionSimulate = { handleTransitionSimulate }
759806 />
760- </ div >
761- ) }
807+ ) }
808+ </ DraggableModal >
762809 </ >
763810 ) }
764811 </ div >
@@ -824,22 +871,30 @@ function App({ onLogout, onGoToDashboard, user }: AppProps) {
824871 ) }
825872 { viewMode === 'visualization' && (
826873 < div className = { styles . visualizationWrapper } >
827- < Visualization nodes = { nodes } relations = { relations } attributes = { attributes } onNodeSelect = { setSelectedNodeId } onMorphChange = { handleMorphChange } graphMode = { graphMode === 'strictgraph' ? 'richgraph' : ( graphMode === 'markdown' ? 'richgraph' : graphMode ) } />
828- { selectedNode && (
829- < div className = { styles . selectedNodeCard } >
874+ < Visualization nodes = { nodes } relations = { relations } attributes = { attributes } onNodeSelect = { handleNodeSelect } onMorphChange = { handleMorphChange } graphMode = { graphMode === 'strictgraph' ? 'richgraph' : ( graphMode === 'markdown' ? 'richgraph' : graphMode ) } />
875+ < DraggableModal
876+ isOpen = { isNodeCardOpen && ! ! selectedNode }
877+ onClose = { handleCloseNodeCard }
878+ title = { selectedNode ? `${ selectedNode . name } ${ selectedNode . role === 'Transition' ? '(Transition)' : '' } ` : '' }
879+ initialPosition = { { x : 150 , y : 150 } }
880+ >
881+ { selectedNode && (
830882 < NodeCard
831883 node = { selectedNode }
832884 allNodes = { nodes }
833885 allRelations = { relations }
834- attributes = { attributeTypes }
886+ attributes = { attributes }
835887 isActive = { false }
836888 onSelectNode = { ( nodeId ) => console . log ( 'Node selected:' , nodeId ) }
837889 onImportContext = { ( nodeId ) => console . log ( 'Import context:' , nodeId ) }
838890 nodeRegistry = { { } }
839891 isPublic = { false }
892+ graphId = { activeGraphId || undefined }
893+ onMorphChange = { handleMorphChange }
894+ onTransitionSimulate = { handleTransitionSimulate }
840895 />
841- </ div >
842- ) }
896+ ) }
897+ </ DraggableModal >
843898 </ div >
844899 ) }
845900 { viewMode === 'slideshow' && (
0 commit comments