11import { type ProjectDirectoryEntry , type ProjectEntry } from "@okcode/contracts" ;
2- import { useQuery } from "@tanstack/react-query" ;
2+ import { useQuery , useQueryClient } from "@tanstack/react-query" ;
33import {
44 ChevronRightIcon ,
55 FolderClosedIcon ,
@@ -27,9 +27,9 @@ import { toastManager } from "./ui/toast";
2727
2828const TREE_ROW_LEFT_PADDING = 8 ;
2929const TREE_ROW_DEPTH_OFFSET = 14 ;
30- type WorkspaceFileAction = "open" | "open-in-editor" | "reveal-in-finder" | "copy-path" ;
31- type WorkspaceDirectoryAction = "expand" | "collapse" | "open-in-finder" | "copy-path" ;
32- type WorkspaceSearchDirectoryAction = "reveal-in-tree" | "open-in-finder" | "copy-path" ;
30+ type WorkspaceFileAction = "open" | "open-in-editor" | "reveal-in-finder" | "copy-path" | "delete" ;
31+ type WorkspaceDirectoryAction = "expand" | "collapse" | "open-in-finder" | "copy-path" | "delete" ;
32+ type WorkspaceSearchDirectoryAction = "reveal-in-tree" | "open-in-finder" | "copy-path" | "delete" ;
3333
3434export const WorkspaceFileTree = memo ( function WorkspaceFileTree ( props : {
3535 cwd : string ;
@@ -205,6 +205,30 @@ export const WorkspaceFileTree = memo(function WorkspaceFileTree(props: {
205205 setFiltersOpen ( false ) ;
206206 } , [ ] ) ;
207207
208+ const queryClient = useQueryClient ( ) ;
209+ const deleteEntry = useCallback (
210+ async ( pathValue : string ) => {
211+ const api = readNativeApi ( ) ;
212+ if ( ! api ) return ;
213+ const name = basenameOfPath ( pathValue ) ;
214+ const confirmed = await api . dialog . confirm ( `Are you sure you want to delete "${ name } "?` ) ;
215+ if ( ! confirmed ) return ;
216+ try {
217+ await api . projects . deleteEntry ( { cwd : props . cwd , relativePath : pathValue } ) ;
218+ toastManager . add ( { type : "success" , title : `Deleted ${ name } ` } ) ;
219+ void queryClient . invalidateQueries ( { queryKey : [ "projectListDirectory" ] } ) ;
220+ void queryClient . invalidateQueries ( { queryKey : [ "projectSearchEntries" ] } ) ;
221+ } catch ( error ) {
222+ toastManager . add ( {
223+ type : "error" ,
224+ title : "Failed to delete" ,
225+ description : error instanceof Error ? error . message : "An error occurred." ,
226+ } ) ;
227+ }
228+ } ,
229+ [ props . cwd , queryClient ] ,
230+ ) ;
231+
208232 return (
209233 < div className = { cn ( "space-y-2" , props . className ) } >
210234 < div className = "space-y-1.5 px-2" >
@@ -273,6 +297,7 @@ export const WorkspaceFileTree = memo(function WorkspaceFileTree(props: {
273297 isLoading = { searchResultsQuery . isLoading }
274298 fileManagerName = { fileManagerName }
275299 onCopyPath = { copyWorkspacePath }
300+ onDeleteEntry = { deleteEntry }
276301 onOpenDirectoryInFileManager = { openDirectoryInFileManager }
277302 onOpenFileInEditor = { openFileInNativeEditor }
278303 onOpenFile = { openFile }
@@ -288,6 +313,7 @@ export const WorkspaceFileTree = memo(function WorkspaceFileTree(props: {
288313 expandedDirectories = { expandedDirectories }
289314 fileManagerName = { fileManagerName }
290315 onCopyPath = { copyWorkspacePath }
316+ onDeleteEntry = { deleteEntry }
291317 onOpenDirectoryInFileManager = { openDirectoryInFileManager }
292318 onOpenFileInEditor = { openFileInNativeEditor }
293319 onOpenFile = { openFile }
@@ -310,6 +336,7 @@ const WorkspaceSearchResults = memo(function WorkspaceSearchResults(props: {
310336 truncated : boolean ;
311337 resolvedTheme : "light" | "dark" ;
312338 onCopyPath : ( pathValue : string ) => void ;
339+ onDeleteEntry : ( pathValue : string ) => void ;
313340 onOpenDirectoryInFileManager : ( pathValue : string ) => void ;
314341 onOpenFileInEditor : ( pathValue : string ) => void ;
315342 onOpenFile : ( pathValue : string , event ?: { metaKey ?: boolean ; ctrlKey ?: boolean } ) => void ;
@@ -344,6 +371,7 @@ const WorkspaceSearchResults = memo(function WorkspaceSearchResults(props: {
344371 entry = { entry }
345372 fileManagerName = { props . fileManagerName }
346373 onCopyPath = { props . onCopyPath }
374+ onDeleteEntry = { props . onDeleteEntry }
347375 onOpenDirectoryInFileManager = { props . onOpenDirectoryInFileManager }
348376 onOpenFileInEditor = { props . onOpenFileInEditor }
349377 onOpenFile = { props . onOpenFile }
@@ -367,6 +395,7 @@ const WorkspaceSearchResultRow = memo(function WorkspaceSearchResultRow(props: {
367395 fileManagerName : string ;
368396 resolvedTheme : "light" | "dark" ;
369397 onCopyPath : ( pathValue : string ) => void ;
398+ onDeleteEntry : ( pathValue : string ) => void ;
370399 onOpenDirectoryInFileManager : ( pathValue : string ) => void ;
371400 onOpenFileInEditor : ( pathValue : string ) => void ;
372401 onOpenFile : ( pathValue : string , event ?: { metaKey ?: boolean ; ctrlKey ?: boolean } ) => void ;
@@ -387,6 +416,7 @@ const WorkspaceSearchResultRow = memo(function WorkspaceSearchResultRow(props: {
387416 { id : "reveal-in-tree" , label : "Reveal in tree" } ,
388417 { id : "open-in-finder" , label : `Open in ${ props . fileManagerName } ` } ,
389418 { id : "copy-path" , label : "Copy path" } ,
419+ { id : "delete" , label : "Delete" , destructive : true } ,
390420 ] ,
391421 { x : event . clientX , y : event . clientY } ,
392422 ) ;
@@ -396,6 +426,8 @@ const WorkspaceSearchResultRow = memo(function WorkspaceSearchResultRow(props: {
396426 props . onOpenDirectoryInFileManager ( props . entry . path ) ;
397427 } else if ( clicked === "copy-path" ) {
398428 props . onCopyPath ( props . entry . path ) ;
429+ } else if ( clicked === "delete" ) {
430+ props . onDeleteEntry ( props . entry . path ) ;
399431 }
400432 return ;
401433 }
@@ -406,6 +438,7 @@ const WorkspaceSearchResultRow = memo(function WorkspaceSearchResultRow(props: {
406438 { id : "open-in-editor" , label : "Open in editor" } ,
407439 { id : "reveal-in-finder" , label : `Reveal in ${ props . fileManagerName } ` } ,
408440 { id : "copy-path" , label : "Copy path" } ,
441+ { id : "delete" , label : "Delete" , destructive : true } ,
409442 ] ,
410443 { x : event . clientX , y : event . clientY } ,
411444 ) ;
@@ -418,6 +451,8 @@ const WorkspaceSearchResultRow = memo(function WorkspaceSearchResultRow(props: {
418451 props . onRevealFileInFileManager ( props . entry . path ) ;
419452 } else if ( clicked === "copy-path" ) {
420453 props . onCopyPath ( props . entry . path ) ;
454+ } else if ( clicked === "delete" ) {
455+ props . onDeleteEntry ( props . entry . path ) ;
421456 }
422457 } ,
423458 [ isDirectory , props ] ,
@@ -468,6 +503,7 @@ const WorkspaceFileTreeDirectory = memo(function WorkspaceFileTreeDirectory(prop
468503 fileManagerName : string ;
469504 resolvedTheme : "light" | "dark" ;
470505 onCopyPath : ( pathValue : string ) => void ;
506+ onDeleteEntry : ( pathValue : string ) => void ;
471507 onOpenDirectoryInFileManager : ( pathValue : string ) => void ;
472508 onOpenFileInEditor : ( pathValue : string ) => void ;
473509 onToggleDirectory : ( pathValue : string ) => void ;
@@ -521,6 +557,7 @@ const WorkspaceFileTreeDirectory = memo(function WorkspaceFileTreeDirectory(prop
521557 fileManagerName = { props . fileManagerName }
522558 isExpanded = { isExpanded }
523559 onCopyPath = { props . onCopyPath }
560+ onDeleteEntry = { props . onDeleteEntry }
524561 onOpenDirectoryInFileManager = { props . onOpenDirectoryInFileManager }
525562 onToggleDirectory = { props . onToggleDirectory }
526563 />
@@ -532,6 +569,7 @@ const WorkspaceFileTreeDirectory = memo(function WorkspaceFileTreeDirectory(prop
532569 expandedDirectories = { props . expandedDirectories }
533570 fileManagerName = { props . fileManagerName }
534571 onCopyPath = { props . onCopyPath }
572+ onDeleteEntry = { props . onDeleteEntry }
535573 onOpenDirectoryInFileManager = { props . onOpenDirectoryInFileManager }
536574 onOpenFileInEditor = { props . onOpenFileInEditor }
537575 onOpenFile = { props . onOpenFile }
@@ -551,6 +589,7 @@ const WorkspaceFileTreeDirectory = memo(function WorkspaceFileTreeDirectory(prop
551589 entry = { entry }
552590 fileManagerName = { props . fileManagerName }
553591 onCopyPath = { props . onCopyPath }
592+ onDeleteEntry = { props . onDeleteEntry }
554593 onOpenFileInEditor = { props . onOpenFileInEditor }
555594 onOpenFile = { props . onOpenFile }
556595 onRevealFileInFileManager = { props . onRevealFileInFileManager }
@@ -573,6 +612,7 @@ const WorkspaceDirectoryRow = memo(function WorkspaceDirectoryRow(props: {
573612 fileManagerName : string ;
574613 isExpanded : boolean ;
575614 onCopyPath : ( pathValue : string ) => void ;
615+ onDeleteEntry : ( pathValue : string ) => void ;
576616 onOpenDirectoryInFileManager : ( pathValue : string ) => void ;
577617 onToggleDirectory : ( pathValue : string ) => void ;
578618} ) {
@@ -590,6 +630,7 @@ const WorkspaceDirectoryRow = memo(function WorkspaceDirectoryRow(props: {
590630 } ,
591631 { id : "open-in-finder" , label : `Open in ${ props . fileManagerName } ` } ,
592632 { id : "copy-path" , label : "Copy path" } ,
633+ { id : "delete" , label : "Delete" , destructive : true } ,
593634 ] ,
594635 { x : event . clientX , y : event . clientY } ,
595636 ) ;
@@ -599,6 +640,8 @@ const WorkspaceDirectoryRow = memo(function WorkspaceDirectoryRow(props: {
599640 props . onOpenDirectoryInFileManager ( props . entry . path ) ;
600641 } else if ( clicked === "copy-path" ) {
601642 props . onCopyPath ( props . entry . path ) ;
643+ } else if ( clicked === "delete" ) {
644+ props . onDeleteEntry ( props . entry . path ) ;
602645 }
603646 } ,
604647 [ props ] ,
@@ -649,6 +692,7 @@ const WorkspaceFileRow = memo(function WorkspaceFileRow(props: {
649692 fileManagerName : string ;
650693 resolvedTheme : "light" | "dark" ;
651694 onCopyPath : ( pathValue : string ) => void ;
695+ onDeleteEntry : ( pathValue : string ) => void ;
652696 onOpenFileInEditor : ( pathValue : string ) => void ;
653697 onOpenFile : ( pathValue : string , event ?: { metaKey ?: boolean ; ctrlKey ?: boolean } ) => void ;
654698 onRevealFileInFileManager : ( pathValue : string ) => void ;
@@ -665,6 +709,7 @@ const WorkspaceFileRow = memo(function WorkspaceFileRow(props: {
665709 { id : "open-in-editor" , label : "Open in editor" } ,
666710 { id : "reveal-in-finder" , label : `Reveal in ${ props . fileManagerName } ` } ,
667711 { id : "copy-path" , label : "Copy path" } ,
712+ { id : "delete" , label : "Delete" , destructive : true } ,
668713 ] ,
669714 { x : event . clientX , y : event . clientY } ,
670715 ) ;
@@ -676,6 +721,8 @@ const WorkspaceFileRow = memo(function WorkspaceFileRow(props: {
676721 props . onRevealFileInFileManager ( props . entry . path ) ;
677722 } else if ( clicked === "copy-path" ) {
678723 props . onCopyPath ( props . entry . path ) ;
724+ } else if ( clicked === "delete" ) {
725+ props . onDeleteEntry ( props . entry . path ) ;
679726 }
680727 } ,
681728 [ props ] ,
0 commit comments