77 CloudArrowUpIcon ,
88 DocumentPlusIcon ,
99 TrashIcon ,
10- XMarkIcon ,
10+ MagnifyingGlassIcon ,
1111} from '@heroicons/react/24/outline'
1212import { Dialog , Transition } from '@headlessui/react'
1313import { UploadResult , UploadFile , useFiles } from '@/hooks/useFiles'
@@ -45,6 +45,8 @@ export default function Files(props: Props) {
4545 props . workspaceId
4646 )
4747
48+ const [ search , setSearch ] = useState ( '' )
49+
4850 const onUseInPython = useCallback (
4951 ( file : BrieferFile ) => {
5052 if ( ! props . yDoc || ! props . executionQueue ) {
@@ -55,13 +57,13 @@ export default function Files(props: Props) {
5557 file . mimeType === 'application/json'
5658 ? 'json'
5759 : file . mimeType === 'text/csv'
58- ? 'csv'
59- : file . mimeType === 'application/vnd.ms-excel'
60- ? 'xls'
61- : file . mimeType ===
62- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
63- ? 'xlsx'
64- : ''
60+ ? 'csv'
61+ : file . mimeType === 'application/vnd.ms-excel'
62+ ? 'xls'
63+ : file . mimeType ===
64+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
65+ ? 'xlsx'
66+ : ''
6567
6668 const source =
6769 fileExtension !== ''
98100 }
99101 )
100102 } ,
101- [ props . yDoc , props . executionQueue , environmentStartedAt ]
103+ [ props . yDoc , props . executionQueue , props . userId , environmentStartedAt ]
102104 )
103105
104106 const onUseInSQL = useCallback (
@@ -152,7 +154,7 @@ file`
152154 }
153155 )
154156 } ,
155- [ props . yDoc , props . executionQueue , environmentStartedAt ]
157+ [ props . yDoc , props . executionQueue , props . userId , environmentStartedAt ]
156158 )
157159
158160 const [
@@ -190,21 +192,27 @@ file`
190192
191193 const actualFiles = useMemo (
192194 ( ) =>
193- files . filter ( ( f ) => {
195+ files . filter ( ( file ) => {
196+ const s = search . trim ( )
197+ if ( s !== '' ) {
198+ const name = file . name . trim ( )
199+ return name . toLowerCase ( ) . includes ( s . toLowerCase ( ) )
200+ }
201+
194202 if ( upload . _tag === 'idle' ) {
195203 return true
196204 }
197205
198206 if (
199- upload . current . file . name === f . relCwdPath &&
207+ upload . current . file . name === file . relCwdPath &&
200208 upload . current . status === 'uploading'
201209 ) {
202210 return false
203211 }
204212
205213 return true
206214 } ) ,
207- [ files , upload ]
215+ [ files , upload , search ]
208216 )
209217
210218 const results = useMemo (
@@ -313,6 +321,16 @@ file`
313321 < InformationCircleIcon className = "w-4 h-4 text-gray-300" />
314322 </ Tooltip >
315323 </ div >
324+ < div className = "px-4 py-0 flex items-center border-b border-gray-200 group focus-within:border-blue-300" >
325+ < MagnifyingGlassIcon className = "h-3.5 w-3.5 text-gray-400 group-focus-within:text-blue-500" />
326+ < input
327+ type = "text"
328+ placeholder = "Search..."
329+ className = "w-full h-8 border-0 placeholder-gray-400 text-xs text-gray-600 focus:outline-none focus:ring-0 pl-2"
330+ onChange = { ( e ) => setSearch ( e . target . value ) }
331+ value = { search }
332+ />
333+ </ div >
316334 { actualFiles . length > 0 ? (
317335 < ul
318336 role = "list"
@@ -621,7 +639,8 @@ function ReplaceDialog(props: ReplaceDialogProps) {
621639 if ( props . fileName !== '' && props . fileName !== fileName ) {
622640 setFileName ( props . fileName )
623641 }
624- } , [ props . fileName ] )
642+ } , [ props . fileName , fileName ] )
643+
625644 return (
626645 < Transition show = { props . open } >
627646 < Dialog onClose = { props . onReplaceNo } className = "relative z-[100]" >
0 commit comments