@@ -24,30 +24,35 @@ import TextIcon from "@mui/icons-material/Description";
2424import { fetchDatasets } from "../../actions/dataset" ;
2525import { V2 } from "../../openapi" ;
2626
27- // Define the file details
28- interface FileDetails {
29- fileId : string ;
30- fileName : string ;
27+ interface SelectionDetails {
28+ selectionID : string ;
29+ selectionName : string ;
30+ selectionType : string ;
31+ datasetId ?: string ;
3132}
3233
33- // Define the RecursiveComponent component with props type
3434interface RecursiveComponentProps {
3535 item : FSItem ;
3636 depth ?: number ;
37- onSelectFile : ( fileId : string , fileName : string ) => void ;
37+ onHighlightSelection : (
38+ selectionID : string ,
39+ selectionName : string ,
40+ datasetId : string ,
41+ selectionType : string
42+ ) => void ;
43+ highlightedSelectionId : string ;
44+ selectFolder : boolean ;
3845}
3946
40- // Define a type for items in the directory structure
4147interface FSItem {
4248 datasetId : string ;
4349 id ?: string ;
4450 label : string ;
4551 children ?: FSItem [ ] | undefined ;
46- type : string ; // A FSItem can be a folder or a file,
52+ type : string ;
4753 content_type ?: string ;
4854}
4955
50- // Function to fetch children of a folder
5156async function fetchFolderFiles (
5257 datasetid : string ,
5358 folderId : string | undefined
@@ -57,7 +62,6 @@ async function fetchFolderFiles(
5762 await V2 . DatasetsService . getDatasetFoldersAndFilesApiV2DatasetsDatasetIdFoldersAndFilesGet (
5863 datasetid ,
5964 folderId ,
60- // TODO: Remove hardcoded values
6165 0 ,
6266 3000
6367 ) ;
@@ -85,13 +89,15 @@ async function fetchFolderFiles(
8589const RecursiveComponent : React . FC < RecursiveComponentProps > = ( {
8690 item,
8791 depth = 0 ,
88- onSelectFile,
92+ onHighlightSelection,
93+ highlightedSelectionId,
94+ selectFolder,
8995} ) => {
9096 const [ expanded , setExpanded ] = useState ( false ) ;
9197 const [ children , setChildren ] = useState < FSItem [ ] | undefined > ( item . children ) ;
9298 const isFolderOrDataset = item . type === "folder" || item . type === "dataset" ;
99+ const isHighlighted = item . id === highlightedSelectionId ;
93100
94- // Function to generate Icon based on item type
95101 const getIcon = ( ) => {
96102 if ( item . type === "folder" ) {
97103 return < FolderIcon /> ;
@@ -112,32 +118,35 @@ const RecursiveComponent: React.FC<RecursiveComponentProps> = ({
112118 }
113119 } ;
114120
115- // Function to handle selection of folder or file
116- const onSelect = ( ) => {
121+ const expandFolder = ( ) => {
117122 if ( isFolderOrDataset ) {
118- if ( ! expanded ) {
119- fetchFolderFiles ( item . datasetId , item . id ) . then ( ( data ) => {
120- setChildren ( data ) ;
121- } ) ;
122- }
123+ fetchFolderFiles ( item . datasetId , item . id ) . then ( ( data ) => {
124+ setChildren ( data ) ;
125+ } ) ;
123126 setExpanded ( ! expanded ) ;
124- } else {
125- if ( item . id !== undefined ) {
126- onSelectFile ( item . id , item . label ) ;
127- }
127+ }
128+ } ;
129+
130+ const onSelect = ( ) => {
131+ if ( item . id !== undefined ) {
132+ onHighlightSelection ( item . id , item . label , item . datasetId , item . type ) ;
128133 }
129134 } ;
130135
131136 return (
132137 < List disablePadding >
133- { /* Indentation of item proportional to depth */ }
134138 < ListItem
135139 sx = { {
136140 pl : depth * 2 ,
137141 borderBottom : "none" ,
138142 py : 0.5 ,
143+ backgroundColor : isHighlighted
144+ ? "rgba(25, 118, 210, 0.12)"
145+ : "transparent" ,
139146 "&:hover" : {
140- backgroundColor : "rgba(0, 0, 0, 0.1)" , // or any other color
147+ backgroundColor : isHighlighted
148+ ? "rgba(25, 118, 210, 0.2)"
149+ : "rgba(0, 0, 0, 0.1)" ,
141150 cursor : "pointer" ,
142151 } ,
143152 } }
@@ -147,6 +156,7 @@ const RecursiveComponent: React.FC<RecursiveComponentProps> = ({
147156 < IconButton
148157 size = "small"
149158 sx = { { visibility : isFolderOrDataset ? "visible" : "hidden" } }
159+ onClick = { expandFolder }
150160 >
151161 < ExpandMoreIcon
152162 style = { {
@@ -166,7 +176,9 @@ const RecursiveComponent: React.FC<RecursiveComponentProps> = ({
166176 key = { child . id }
167177 item = { child }
168178 depth = { depth + 1 }
169- onSelectFile = { onSelectFile }
179+ onHighlightSelection = { onHighlightSelection }
180+ highlightedSelectionId = { highlightedSelectionId }
181+ selectFolder = { selectFolder }
170182 />
171183 ) ) }
172184 </ Box >
@@ -177,22 +189,26 @@ const RecursiveComponent: React.FC<RecursiveComponentProps> = ({
177189} ;
178190
179191const FileSystemViewer : React . FC < {
180- onSelectFile : ( fileId : string , fileName : string ) => void ;
181- } > = ( { onSelectFile } ) => {
192+ onHighlightSelection : (
193+ selectionID : string ,
194+ selectionName : string ,
195+ datasetId : string ,
196+ selectionType : string
197+ ) => void ;
198+ highlightedSelectionId : string ;
199+ selectFolder : boolean ;
200+ } > = ( { onHighlightSelection, highlightedSelectionId, selectFolder } ) => {
182201 const dispatch = useDispatch ( ) ;
183202 const datasets = useSelector ( ( state : any ) => state . dataset . datasets ) ;
184203 const [ FSItems , setFSItems ] = useState < FSItem [ ] > ( [ ] ) ;
185204
186- // API function call to get Datasets
187205 const listDatasets = ( skip ?: number , limit ?: number , mine ?: boolean ) => {
188206 dispatch ( fetchDatasets ( skip , limit , mine ) ) ;
189207 } ;
190208
191- // Fetch datasets on component mount
192209 useEffect ( ( ) => {
193- // TODO: Remove hardcoded values for skip and limit
194210 listDatasets ( 0 , 3000 , true ) ;
195- } , [ ] ) ; //
211+ } , [ ] ) ;
196212
197213 useEffect ( ( ) => {
198214 if ( datasets . data ) {
@@ -225,20 +241,33 @@ const FileSystemViewer: React.FC<{
225241 < RecursiveComponent
226242 key = { FSItem . id }
227243 item = { FSItem }
228- onSelectFile = { onSelectFile }
244+ onHighlightSelection = { onHighlightSelection }
245+ highlightedSelectionId = { highlightedSelectionId }
246+ selectFolder = { selectFolder }
229247 />
230248 ) ) }
231249 </ Box >
232250 ) : null ;
233251} ;
234252
235253const DatasetFileViewer : React . FC < {
236- onSelectFile : ( fileId : string , fileName : string ) => void ;
254+ onHighlightSelection : (
255+ selectionID : string ,
256+ selectionName : string ,
257+ datasetId : string ,
258+ selectionType : string
259+ ) => void ;
260+ highlightedSelectionId : string ;
237261 datasetId : string ;
238- } > = ( { onSelectFile, datasetId } ) => {
262+ selectFolder : boolean ;
263+ } > = ( {
264+ onHighlightSelection,
265+ highlightedSelectionId,
266+ datasetId,
267+ selectFolder,
268+ } ) => {
239269 const [ FSItems , setFSItems ] = useState < FSItem [ ] > ( [ ] ) ;
240270
241- // Only display contents of the passed dataset
242271 useEffect ( ( ) => {
243272 fetchFolderFiles ( datasetId , undefined ) . then ( ( data ) => {
244273 setFSItems ( data ) ;
@@ -263,46 +292,90 @@ const DatasetFileViewer: React.FC<{
263292 < RecursiveComponent
264293 key = { FSItem . id }
265294 item = { FSItem }
266- onSelectFile = { onSelectFile }
295+ onHighlightSelection = { onHighlightSelection }
296+ highlightedSelectionId = { highlightedSelectionId }
297+ selectFolder = { selectFolder }
267298 />
268299 ) ) }
269300 </ Box >
270301 ) : null ;
271302} ;
272303
273- const FileSelector : React . FC < {
304+ const FileSystemSelector : React . FC < {
274305 showOnlyDatasetFiles : boolean ;
306+ selectFolder : boolean ;
275307 datasetId : string | undefined ;
276- onChange : ( fileId : string ) => void ;
277- } > = ( { showOnlyDatasetFiles, datasetId, onChange } ) => {
308+ onChange : ( SelectionDetails : string ) => void ;
309+ } > = ( { showOnlyDatasetFiles, selectFolder , datasetId, onChange } ) => {
278310 const [ open , setOpen ] = useState ( false ) ;
279- const [ selectedFile , setSelectedFile ] = useState < FileDetails > ( {
280- fileId : "" ,
281- fileName : "" ,
311+ const [ selection , setSelection ] = useState < SelectionDetails > ( {
312+ selectionID : "" ,
313+ selectionName : "" ,
314+ datasetId : "" ,
315+ selectionType : "" ,
282316 } ) ;
317+ const [ highlightedSelection , setHighlightedFile ] = useState < SelectionDetails > (
318+ {
319+ selectionID : "" ,
320+ selectionName : "" ,
321+ datasetId : "" ,
322+ selectionType : "" ,
323+ }
324+ ) ;
283325
284326 const handleOpen = ( ) => setOpen ( true ) ;
285- const handleClose = ( ) => setOpen ( false ) ;
327+ const handleClose = ( ) => {
328+ setHighlightedFile ( {
329+ selectionID : "" ,
330+ selectionName : "" ,
331+ selectionType : "" ,
332+ } ) ;
333+ setOpen ( false ) ;
334+ } ;
286335
287- const handleFileSelect = ( fileId : string , fileName : string ) => {
288- setSelectedFile ( { fileId : fileId , fileName : fileName } ) ;
289- onChange ( fileId ) ;
290- handleClose ( ) ;
336+ const handleHighlight = (
337+ selectionID : string ,
338+ selectionName : string ,
339+ datasetId : string ,
340+ selectionType : string
341+ ) => {
342+ setHighlightedFile ( {
343+ selectionID,
344+ selectionName,
345+ datasetId,
346+ selectionType,
347+ } ) ;
348+ } ;
349+
350+ const handleConfirmSelection = ( ) => {
351+ if ( highlightedSelection . selectionID ) {
352+ setSelection ( highlightedSelection ) ;
353+ const selection = {
354+ selectionID : highlightedSelection . selectionID ,
355+ selectionName : highlightedSelection . selectionName ,
356+ datasetId : highlightedSelection . datasetId ,
357+ selectionType : highlightedSelection . selectionType ,
358+ }
359+ // Convert to string
360+ const selectionString = JSON . stringify ( selection ) ;
361+ onChange ( selectionString ) ;
362+ handleClose ( ) ;
363+ }
291364 } ;
292365
293366 return (
294367 < Box sx = { { display : "flex" , alignItems : "center" , gap : 2 , p : 2 } } >
295- { selectedFile . fileName && (
368+ { selection . selectionName && (
296369 < Typography variant = "subtitle1" sx = { { ml : 2 } } >
297- { selectedFile . fileName }
370+ { selection . selectionName }
298371 </ Typography >
299372 ) }
300373 < Button
301374 variant = "outlined"
302375 onClick = { handleOpen }
303376 startIcon = { < InsertDriveFileIcon /> }
304377 >
305- Choose File
378+ { selectFolder ? "Select Folder" : "Select File" }
306379 </ Button >
307380 < Modal
308381 open = { open }
@@ -324,16 +397,35 @@ const FileSelector: React.FC<{
324397 >
325398 { showOnlyDatasetFiles ? (
326399 < DatasetFileViewer
327- onSelectFile = { handleFileSelect }
400+ onHighlightSelection = { handleHighlight }
401+ highlightedSelectionId = { highlightedSelection . selectionID }
328402 datasetId = { datasetId as string }
403+ selectFolder = { selectFolder }
329404 />
330405 ) : (
331- < FileSystemViewer onSelectFile = { handleFileSelect } />
406+ < FileSystemViewer
407+ onHighlightSelection = { handleHighlight }
408+ highlightedSelectionId = { highlightedSelection . selectionID }
409+ selectFolder = { selectFolder }
410+ />
332411 ) }
412+ < Box sx = { { display : "flex" , justifyContent : "flex-end" , mt : 2 } } >
413+ < Button
414+ variant = "contained"
415+ onClick = { handleConfirmSelection }
416+ disabled = {
417+ selectFolder
418+ ? highlightedSelection . selectionType !== "folder"
419+ : highlightedSelection . selectionType !== "file"
420+ }
421+ >
422+ Select
423+ </ Button >
424+ </ Box >
333425 </ Box >
334426 </ Modal >
335427 </ Box >
336428 ) ;
337429} ;
338430
339- export default FileSelector ;
431+ export default FileSystemSelector ;
0 commit comments