@@ -42,6 +42,19 @@ export function useDuplicateFolder({
4242 const duplicateFolderMutation = useDuplicateFolderMutation ( )
4343 const [ isDuplicating , setIsDuplicating ] = useState ( false )
4444
45+ const generateDuplicateName = useCallback ( ( baseName : string , siblingNames : Set < string > ) => {
46+ const trimmedName = ( baseName || 'Untitled Folder' ) . trim ( )
47+ let candidate = `${ trimmedName } Copy`
48+ let counter = 2
49+
50+ while ( siblingNames . has ( candidate ) ) {
51+ candidate = `${ trimmedName } Copy ${ counter } `
52+ counter += 1
53+ }
54+
55+ return candidate
56+ } , [ ] )
57+
4558 /**
4659 * Duplicate the folder(s)
4760 */
@@ -62,10 +75,32 @@ export function useDuplicateFolder({
6275 const folderIdsToDuplicate = Array . isArray ( folderIdsOrId ) ? folderIdsOrId : [ folderIdsOrId ]
6376
6477 const duplicatedIds : string [ ] = [ ]
78+ const folderStore = useFolderStore . getState ( )
6579
6680 // Duplicate each folder sequentially
6781 for ( const folderId of folderIdsToDuplicate ) {
68- const result = await duplicateFolderMutation . mutateAsync ( { id : folderId , workspaceId } )
82+ const folder = folderStore . getFolderById ( folderId )
83+
84+ if ( ! folder ) {
85+ logger . warn ( 'Attempted to duplicate folder that no longer exists' , { folderId } )
86+ continue
87+ }
88+
89+ const siblingNames = new Set (
90+ folderStore . getChildFolders ( folder . parentId ) . map ( ( sibling ) => sibling . name )
91+ )
92+ // Avoid colliding with the original folder name
93+ siblingNames . add ( folder . name )
94+
95+ const duplicateName = generateDuplicateName ( folder . name , siblingNames )
96+
97+ const result = await duplicateFolderMutation . mutateAsync ( {
98+ id : folderId ,
99+ workspaceId,
100+ name : duplicateName ,
101+ parentId : folder . parentId ,
102+ color : folder . color ,
103+ } )
69104 const newFolderId = result ?. id
70105 if ( newFolderId ) {
71106 duplicatedIds . push ( newFolderId )
@@ -88,7 +123,14 @@ export function useDuplicateFolder({
88123 } finally {
89124 setIsDuplicating ( false )
90125 }
91- } , [ getFolderIds , isDuplicating , duplicateFolderMutation , workspaceId , onSuccess ] )
126+ } , [
127+ getFolderIds ,
128+ generateDuplicateName ,
129+ isDuplicating ,
130+ duplicateFolderMutation ,
131+ workspaceId ,
132+ onSuccess ,
133+ ] )
92134
93135 return {
94136 isDuplicating,
0 commit comments