@@ -44,6 +44,7 @@ const DnDFlow = () => {
4444 const [ copyFeedback , setCopyFeedback ] = useState ( '' ) ;
4545 const ref = useRef ( null ) ;
4646 const [ csvData , setCsvData ] = useState ( null ) ;
47+ const [ htmlData , setHtmlData ] = useState ( null ) ;
4748 const reactFlowWrapper = useRef ( null ) ;
4849 // const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
4950 // const [edges, setEdges, onEdgesChange] = useEdgesState([]);
@@ -481,6 +482,39 @@ const DnDFlow = () => {
481482 }
482483 } ;
483484
485+ const downloadHtml = async ( ) => {
486+ const blob = new Blob ( [ htmlData ] , { type : "text/html" } ) ;
487+ const filename = `simulation_${ new Date ( ) . toISOString ( ) . replace ( / [: .] / g, "-" ) } .html` ;
488+
489+ try {
490+ if ( "showSaveFilePicker" in window ) {
491+ const options = {
492+ suggestedName : filename ,
493+ types : [ {
494+ description : "HTML File" ,
495+ accept : { "text/html" : [ ".html" ] }
496+ } ]
497+ } ;
498+
499+ const handle = await window . showSaveFilePicker ( options ) ;
500+ const writable = await handle . createWritable ( ) ;
501+ await writable . write ( blob ) ;
502+ await writable . close ( ) ;
503+ } else {
504+ throw new Error ( "showSaveFilePicker not supported" ) ;
505+ }
506+ } catch ( err ) {
507+ console . warn ( "Falling back to automatic download:" , err ) ;
508+ const a = document . createElement ( "a" ) ;
509+ a . href = URL . createObjectURL ( blob ) ;
510+ a . download = filename ;
511+ document . body . appendChild ( a ) ;
512+ a . click ( ) ;
513+ document . body . removeChild ( a ) ;
514+ URL . revokeObjectURL ( a . href ) ;
515+ }
516+ } ;
517+
484518
485519
486520 // Allows user to save to python script
@@ -581,6 +615,7 @@ const DnDFlow = () => {
581615 // Store results and switch to results tab
582616 setSimulationResults ( result . plot ) ;
583617 setCsvData ( result . csv_data ) ;
618+ setHtmlData ( result . html ) ;
584619 setActiveTab ( 'results' ) ;
585620 alert ( 'Pathsim simulation completed successfully! Check the Results tab.' ) ;
586621 } else {
@@ -1664,6 +1699,19 @@ const DnDFlow = () => {
16641699 { simulationResults ? (
16651700 < >
16661701 < div style = { { textAlign : 'right' , padding : '0 20px 10px 20px' } } >
1702+ < button
1703+ style = { {
1704+ backgroundColor : '#78A083' ,
1705+ color : 'white' ,
1706+ border : 'none' ,
1707+ borderRadius : 5 ,
1708+ cursor : 'pointer' ,
1709+ marginRight : '10px' ,
1710+ } }
1711+ onClick = { downloadHtml }
1712+ >
1713+ Download HTML
1714+ </ button >
16671715 < button
16681716 style = { {
16691717 backgroundColor : '#78A083' ,
0 commit comments