@@ -78,8 +78,10 @@ import { useContextMenu } from '@/hooks/use-context-menu'
7878import { useDebouncedSearchSetter } from '@/hooks/use-debounced-search-setter'
7979import { useFileListRoom } from '@/hooks/use-file-list-room'
8080import { useInlineRename } from '@/hooks/use-inline-rename'
81+ import { useSearchFilterValue } from '@/hooks/use-search-filter-value'
8182import { useUrlSort } from '@/hooks/use-url-sort'
8283
84+ const FILES_SEARCH_DEBOUNCE_MS = 200
8385const COLUMNS : ResourceColumn [ ] = [ ...FILE_BROWSER_COLUMNS ]
8486
8587interface ProjectFilesProps {
@@ -118,10 +120,11 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
118120 const sort = useUrlSort ( filesSortParams , filesFilterUrlKeys )
119121 const [ { scope } , setScope ] = useQueryStates ( projectFilesScopeParsers )
120122 const archived = scope === 'archived'
123+ const searchFilter = useSearchFilterValue ( search , FILES_SEARCH_DEBOUNCE_MS )
121124 const list = useProjectFiles ( project . id , {
122125 scope,
123- folderId : search || archived ? undefined : ( folderId ?? undefined ) ,
124- search : search || undefined ,
126+ folderId : searchFilter || archived ? undefined : ( folderId ?? undefined ) ,
127+ search : searchFilter || undefined ,
125128 types,
126129 sizes,
127130 creatorIds,
@@ -132,6 +135,7 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
132135 const folders = useProjectFileFolders ( project . id , scope )
133136 const detail = useProjectFile ( project . id , fileId )
134137 const historyFile = useProjectFile ( project . id , historyFileId ?? undefined )
138+ const sharedFile = useProjectFile ( project . id , shareFileId ?? undefined )
135139 const [ copySource , setCopySource ] = useState < FileCopySource | null > ( null )
136140 const createFile = useCreateProjectFile ( project . id )
137141 const createFolder = useCreateProjectFileFolder ( project . id )
@@ -162,11 +166,7 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
162166 const filesById = new Map ( files . map ( ( file ) => [ file . id , file ] ) )
163167 const items = list . data ?. pages . flatMap ( ( page ) => page . items ) ?? [ ]
164168 const creators = list . data ?. pages [ 0 ] ?. creators ?? [ ]
165- const shareFile = shareFileId
166- ? file ?. id === shareFileId
167- ? file
168- : files . find ( ( item ) => item . id === shareFileId )
169- : undefined
169+ const shareFile = sharedFile . isError ? undefined : sharedFile . data ?. file
170170 const allFolders = folders . data ?. folders ?? [ ]
171171 const folderById = useMemo (
172172 ( ) => new Map ( allFolders . map ( ( folder ) => [ folder . id , folder ] ) ) ,
@@ -188,9 +188,19 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
188188 ( value , options ) => {
189189 void setFilters ( { search : value } , options )
190190 } ,
191- { debounceMs : 200 }
191+ { debounceMs : FILES_SEARCH_DEBOUNCE_MS }
192192 )
193193
194+ function navigateToFolder ( nextFolderId : string | null ) {
195+ if ( fileId ) {
196+ const folderQuery = nextFolderId ? `&folderId=${ encodeURIComponent ( nextFolderId ) } ` : ''
197+ navigation . navigate ( `${ base } ?${ ownerQuery } ${ folderQuery } ` )
198+ return
199+ }
200+ searchSetter ( '' )
201+ void setNavigation ( { folderId : nextFolderId , new : null } )
202+ }
203+
194204 function openFile ( id : string ) {
195205 const target = filesById . get ( id )
196206 if ( target && isArchiveFileName ( target . name ) && canWrite && ! archived ) {
@@ -267,7 +277,7 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
267277 async function addFolder ( ) {
268278 try {
269279 const result = await createFolder . mutateAsync ( { name : 'New Folder' , parentId : folderId } )
270- void setNavigation ( { folderId : result . folder . id } )
280+ navigateToFolder ( result . folder . id )
271281 } catch ( error ) {
272282 toast . error ( getErrorMessage ( error , 'Unable to create this folder' ) )
273283 }
@@ -321,8 +331,8 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
321331 }
322332
323333 const breadcrumbs : BreadcrumbItem [ ] = [
324- { label : project . name , onClick : ( ) => navigation . navigate ( ` ${ base } ? ${ ownerQuery } ` ) } ,
325- { label : 'Files' , folderId : null , onClick : ( ) => navigation . navigate ( ` ${ base } ? ${ ownerQuery } ` ) } ,
334+ { label : project . name , onClick : ( ) => navigateToFolder ( null ) } ,
335+ { label : 'Files' , folderId : null , onClick : ( ) => navigateToFolder ( null ) } ,
326336 ]
327337 const ancestors : BreadcrumbItem [ ] = [ ]
328338 const visited = new Set < string > ( )
@@ -333,8 +343,7 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
333343 ancestors . unshift ( {
334344 label : ancestor . name ,
335345 folderId : id ,
336- onClick : ( ) =>
337- navigation . navigate ( `${ base } ?${ ownerQuery } &folderId=${ encodeURIComponent ( id ) } ` ) ,
346+ onClick : ( ) => navigateToFolder ( id ) ,
338347 } )
339348 ancestor = ancestor . parentId ? folderById . get ( ancestor . parentId ) : undefined
340349 }
@@ -435,7 +444,13 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
435444 }
436445 } )
437446
438- const visibleRowIds = useMemo ( ( ) => rows . map ( ( row ) => row . id ) , [ rows ] )
447+ const visibleRowIds = useMemo (
448+ ( ) =>
449+ list . data ?. pages . flatMap ( ( page ) =>
450+ page . items . map ( ( item ) => ( item . kind === 'folder' ? `folder:${ item . id } ` : item . id ) )
451+ ) ?? [ ] ,
452+ [ list . data ?. pages ]
453+ )
439454 const { selectedRowIds, selectable, clearSelection, replaceSelection } = useResourceRowSelection ( {
440455 visibleRowIds,
441456 isKeyboardBlocked : ( ) => Boolean ( fileId || rename . editingId || deleteTarget || archived ) ,
@@ -475,7 +490,7 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
475490 selection : { selectedRowIds, visibleRowIds, replaceSelection } ,
476491 onSpringOpenFolder : ( folderId , options ) => void setNavigation ( { folderId } , options ) ,
477492 currentFolderId : folderId ,
478- bodyDropFolderId : search ? undefined : folderId ,
493+ bodyDropFolderId : searchFilter ? undefined : folderId ,
479494 externalDrop : {
480495 matches : hasExternalFiles ,
481496 onDropIntoFolder : ( dataTransfer , targetFolderId ) => {
@@ -619,7 +634,7 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
619634 archived
620635 ? undefined
621636 : id . startsWith ( 'folder:' )
622- ? void setNavigation ( { folderId : id . slice ( 'folder:' . length ) } )
637+ ? navigateToFolder ( id . slice ( 'folder:' . length ) )
623638 : openFile ( id )
624639 }
625640 onRowContextMenu = {
@@ -686,7 +701,7 @@ function ProjectFilesContent({ project, workspaceId }: ProjectFilesProps) {
686701 position = { menu . position }
687702 onClose = { menu . closeMenu }
688703 onOpen = { ( ) => {
689- if ( contextItem ?. kind === 'folder' ) void setNavigation ( { folderId : contextItem . id } )
704+ if ( contextItem ?. kind === 'folder' ) navigateToFolder ( contextItem . id )
690705 else if ( contextItem ) openFile ( contextItem . id )
691706 } }
692707 onShare = {
0 commit comments