@@ -88,41 +88,43 @@ const DatasetDetailPage: React.FC = () => {
8888 const [ expandedPaths , setExpandedPaths ] = useState < string [ ] > ( [ ] ) ;
8989 const [ originalTextMap , setOriginalTextMap ] = useState < Map < HTMLElement , string > > ( new Map ( ) ) ;
9090 const [ jsonViewerKey , setJsonViewerKey ] = useState ( 0 ) ;
91-
91+ const [ jsonSize , setJsonSize ] = useState < number > ( 0 ) ;
92+ const [ transformedDataset , setTransformedDataset ] = useState < any > ( null ) ;
9293
9394
9495 // Recursive function to find `_DataLink_`
9596 const extractDataLinks = ( obj : any , path : string ) : ExternalDataLink [ ] => {
9697 const links : ExternalDataLink [ ] = [ ] ;
97-
98- if ( typeof obj === "object" && obj !== null ) {
99- for ( const key in obj ) {
100- if ( obj . hasOwnProperty ( key ) ) {
101- if ( key === "_DataLink_" && typeof obj [ key ] === "string" ) {
102- let correctedUrl = obj [ key ] . replace ( / : \$ .* $ / , "" ) ;
103-
104- const sizeMatch = obj [ key ] . match ( / s i z e = ( \d + ) / ) ;
98+
99+ const traverse = ( node : any , currentPath : string ) => {
100+ if ( typeof node === "object" && node !== null ) {
101+ for ( const key in node ) {
102+ if ( key === "_DataLink_" && typeof node [ key ] === "string" ) {
103+ let correctedUrl = node [ key ] . replace ( / : \$ .* $ / , "" ) ;
104+
105+ const sizeMatch = node [ key ] . match ( / s i z e = ( \d + ) / ) ;
105106 const size = sizeMatch
106107 ? `${ ( parseInt ( sizeMatch [ 1 ] , 10 ) / 1024 / 1024 ) . toFixed ( 2 ) } MB`
107108 : "Unknown Size" ;
108-
109- const subMatch = path . match ( / s u b - \d + / ) ;
109+
110+ const subMatch = currentPath . match ( / s u b - \d + / ) ;
110111 const subPath = subMatch ? subMatch [ 0 ] : "Unknown Sub" ;
111-
112+
112113 links . push ( {
113- name : `${ path . split ( "/" ) . pop ( ) || "ExternalData" } (${ size } ) [/${ subPath } ]` ,
114+ name : `${ currentPath . split ( "/" ) . pop ( ) || "ExternalData" } (${ size } ) [/${ subPath } ]` ,
114115 size,
115- path : subPath ,
116+ path : currentPath , // keep full JSON path for file placement
116117 url : correctedUrl ,
117118 index : links . length ,
118119 } ) ;
119- } else if ( typeof obj [ key ] === "object" ) {
120- links . push ( ... extractDataLinks ( obj [ key ] , `${ path } /${ key } ` ) ) ;
120+ } else if ( typeof node [ key ] === "object" ) {
121+ traverse ( node [ key ] , `${ currentPath } /${ key } ` ) ;
121122 }
122123 }
123124 }
124- }
125-
125+ } ;
126+
127+ traverse ( obj , path ) ;
126128 return links ;
127129 } ;
128130
@@ -210,9 +212,24 @@ const DatasetDetailPage: React.FC = () => {
210212
211213 setExternalLinks ( links ) ;
212214 setInternalLinks ( internalData ) ;
215+ const transformed = transformJsonForDisplay ( datasetDocument ) ;
216+ setTransformedDataset ( transformed ) ;
217+
218+ const blob = new Blob ( [ JSON . stringify ( datasetDocument , null , 2 ) ] , { type : "application/json" } ) ;
219+ setJsonSize ( blob . size ) ;
220+
221+ // // ✅ Construct download script dynamically
222+ let script = `curl -L --create-dirs "https://neurojson.io:7777/${ dbName } /${ docId } " -o "${ docId } .json"\n` ;
223+
224+
225+ externalLinks . forEach ( ( link ) => {
226+ const url = link . url ;
227+ const match = url . match ( / f i l e = ( [ ^ & ] + ) / ) ;
228+ const filename = match ? decodeURIComponent ( match [ 1 ] ) : `file-${ link . index } ` ;
229+ const outputPath = `$HOME/.neurojson/io/${ dbName } /${ docId } /${ filename } ` ;
213230
214- // ✅ Construct download script dynamically
215- const script = `curl -L --create-dirs "https://neurojson.io:7777/ ${ dbName } / ${ docId } " -o " ${ docId } .json"` ;
231+ script += `curl -L --create-dirs " ${ url } " -o " ${ outputPath } "\n` ;
232+ } ) ;
216233 setDownloadScript ( script ) ;
217234 }
218235 } , [ datasetDocument ] ) ;
@@ -582,7 +599,7 @@ const DatasetDetailPage: React.FC = () => {
582599 "&:hover" : { backgroundColor : "#ff9100" } ,
583600 } }
584601 >
585- Script to Download All Files (138 Bytes) (links: 0 )
602+ Script to Download All Files ({ downloadScript . length } Bytes) (links: { externalLinks . length } )
586603 </ Button >
587604
588605 < Box display = "flex" alignItems = "center" gap = { 1 } sx = { { ml : "auto" } } >
0 commit comments