@@ -18,6 +18,54 @@ import Loading from './components/Loading.tsx';
1818import Switch from "./components/switch.tsx" ;
1919import { useSearchParams } from 'react-router-dom' ;
2020
21+ // Helper function to parse and format filename for display
22+ const formatFileTitle = ( filename : string ) : string => {
23+ // Remove file extension
24+ const nameWithoutExt = filename . replace ( / \. ( c s v | C S V ) $ / , '' ) ;
25+
26+ // Split by hyphens and process each part
27+ const parts = nameWithoutExt . split ( '-' ) . map ( part => {
28+ // Handle specific abbreviations and terms
29+ switch ( part . toLowerCase ( ) ) {
30+ case 'er' :
31+ return 'Equivalent Ratios' ;
32+ case 'me' :
33+ return 'Means & Extremes' ;
34+ case 'groundtruth' :
35+ case 'ground_truth' :
36+ return 'Ground Truth' ;
37+ case 'successful' :
38+ return 'Successful' ;
39+ case 'unsuccessful' :
40+ return 'Unsuccessful' ;
41+ case 'strategies' :
42+ return 'Strategies' ;
43+ case 'match' :
44+ return 'Match' ;
45+ case 'allstrategies' :
46+ case 'all_strategies' :
47+ return 'All Strategies' ;
48+ case 'astra' :
49+ return 'ASTRA Generated' ;
50+ default :
51+ // Capitalize first letter of each word
52+ return part . charAt ( 0 ) . toUpperCase ( ) + part . slice ( 1 ) . toLowerCase ( ) ;
53+ }
54+ } ) ;
55+
56+ return parts . join ( ' ' ) ;
57+ } ;
58+
59+ // Helper function to get file type icon
60+ const getFileTypeIcon = ( filename : string ) : string => {
61+ if ( filename . includes ( 'astra' ) ) return '🤖' ; // AI/Astra generated
62+ if ( filename . includes ( 'successful' ) ) return '✅' ; // Successful strategies
63+ if ( filename . includes ( 'unsuccessful' ) ) return '❌' ; // Unsuccessful strategies
64+ if ( filename . includes ( 'ER' ) ) return '🔢' ; // Equivalent Ratios
65+ if ( filename . includes ( 'ME' ) ) return '✖️' ; // Means & Extremes
66+ return '📄' ; // Default file icon
67+ } ;
68+
2169function App ( ) {
2270 // State to hold the uploaded CSV data as a string
2371 // const [csvData, setCsvData] = useState<string>('');
@@ -27,6 +75,7 @@ function App() {
2775 const [ selfLoops , setSelfLoops ] = useState < boolean > ( true ) ;
2876 const [ errorMode , setErrorMode ] = useState < boolean > ( false ) ;
2977 const [ uniqueStudentMode , setUniqueStudentMode ] = useState < boolean > ( false ) ;
78+ const [ fileInfo , setFileInfo ] = useState < { filename : string , source : string } | null > ( null ) ;
3079 // State to manage the minimum number of visits for displaying edges in the graph
3180 const [ minVisitsPercentage , setMinVisitsPercentage ] = useState < number > ( 0 ) ;
3281 const {
@@ -64,6 +113,10 @@ function App() {
64113 // Only load from URL if no CSV data is currently loaded
65114 if ( csvData . length === 0 ) {
66115 if ( csvUrl ) {
116+ // Extract filename from URL
117+ const filename = csvUrl . split ( '/' ) . pop ( ) || 'Unknown File' ;
118+ setFileInfo ( { filename, source : 'Astra App' } ) ;
119+
67120 // Fetch CSV from URL
68121 fetch ( csvUrl )
69122 . then ( response => {
@@ -77,19 +130,29 @@ function App() {
77130 } )
78131 . catch ( error => {
79132 console . error ( 'Error fetching CSV from URL:' , error ) ;
133+ setFileInfo ( null ) ; // Clear file info on error
80134 } ) ;
81135 } else if ( csvDataParam ) {
82136 // Use CSV data directly from URL parameter
83137 try {
84138 const decodedData = decodeURIComponent ( csvDataParam ) ;
139+ setFileInfo ( { filename : 'URL Data' , source : 'URL Parameter' } ) ;
85140 handleDataProcessed ( decodedData ) ;
86141 } catch ( error ) {
87142 console . error ( 'Error decoding CSV data from URL:' , error ) ;
143+ setFileInfo ( null ) ;
88144 }
89145 }
90146 }
91147 } , [ searchParams ] ) ;
92148
149+ // Clear file info when CSV data is reset
150+ useEffect ( ( ) => {
151+ if ( csvData . length === 0 ) {
152+ setFileInfo ( null ) ;
153+ }
154+ } , [ csvData ] ) ;
155+
93156 const showControls = useMemo ( ( ) => {
94157 return ! loading && csvData . length > 0 ;
95158 } , [ loading , csvData ] ) ;
@@ -128,8 +191,15 @@ function App() {
128191 * Updates the `csvData` state with the uploaded CSV data when the file is processed.
129192 *
130193 * @param {string } uploadedCsvData - The CSV data from the uploaded file.
194+ * @param {string } filename - Optional filename for display purposes.
131195 */
132- const handleDataProcessed = ( uploadedCsvData : string ) => setCSVData ( uploadedCsvData ) ;
196+ const handleDataProcessed = ( uploadedCsvData : string , filename ?: string ) => {
197+ setCSVData ( uploadedCsvData ) ;
198+ // If filename is provided (from file upload), update file info
199+ if ( filename ) {
200+ setFileInfo ( { filename, source : 'File Upload' } ) ;
201+ }
202+ } ;
133203
134204 // Calculate actual min visits from percentage
135205 const minVisits = Math . round ( ( minVisitsPercentage / 100 ) * maxEdgeCount ) ;
@@ -162,7 +232,10 @@ function App() {
162232 < div className = "flex items-center space-x-4" >
163233 < Button
164234 variant = "destructive"
165- onClick = { resetData }
235+ onClick = { ( ) => {
236+ resetData ( ) ;
237+ setFileInfo ( null ) ;
238+ } }
166239 >
167240 Reset
168241 </ Button >
@@ -194,6 +267,28 @@ function App() {
194267 </ h2 >
195268 ) }
196269 </ div >
270+
271+ { /* File Information Display */ }
272+ { fileInfo && (
273+ < div className = "file-info-bar bg-blue-50 border border-blue-200 rounded-lg p-4 mb-4" >
274+ < div className = "flex items-center gap-3" >
275+ < span className = "text-2xl" > { getFileTypeIcon ( fileInfo . filename ) } </ span >
276+ < div className = "flex-1" >
277+ < h3 className = "text-lg font-semibold text-blue-900" >
278+ { formatFileTitle ( fileInfo . filename ) }
279+ </ h3 >
280+ < div className = "flex items-center gap-4 text-sm text-blue-700 mt-1" >
281+ < span className = "bg-blue-100 px-2 py-1 rounded text-xs font-medium" >
282+ { fileInfo . source }
283+ </ span >
284+ < span className = "font-mono text-xs" >
285+ { fileInfo . filename }
286+ </ span >
287+ </ div >
288+ </ div >
289+ </ div >
290+ </ div >
291+ ) }
197292 { /* Properties Button */ }
198293 < Popover >
199294 < PopoverTrigger
0 commit comments