fix(folders): duplicate (#1996)

This commit is contained in:
Vikhyath Mondreti
2025-11-14 15:50:00 -08:00
committed by GitHub
parent ec430abca2
commit c2ccd51b3e
2 changed files with 54 additions and 4 deletions

View File

@@ -42,6 +42,19 @@ export function useDuplicateFolder({
const duplicateFolderMutation = useDuplicateFolderMutation()
const [isDuplicating, setIsDuplicating] = useState(false)
const generateDuplicateName = useCallback((baseName: string, siblingNames: Set<string>) => {
const trimmedName = (baseName || 'Untitled Folder').trim()
let candidate = `${trimmedName} Copy`
let counter = 2
while (siblingNames.has(candidate)) {
candidate = `${trimmedName} Copy ${counter}`
counter += 1
}
return candidate
}, [])
/**
* Duplicate the folder(s)
*/
@@ -62,10 +75,32 @@ export function useDuplicateFolder({
const folderIdsToDuplicate = Array.isArray(folderIdsOrId) ? folderIdsOrId : [folderIdsOrId]
const duplicatedIds: string[] = []
const folderStore = useFolderStore.getState()
// Duplicate each folder sequentially
for (const folderId of folderIdsToDuplicate) {
const result = await duplicateFolderMutation.mutateAsync({ id: folderId, workspaceId })
const folder = folderStore.getFolderById(folderId)
if (!folder) {
logger.warn('Attempted to duplicate folder that no longer exists', { folderId })
continue
}
const siblingNames = new Set(
folderStore.getChildFolders(folder.parentId).map((sibling) => sibling.name)
)
// Avoid colliding with the original folder name
siblingNames.add(folder.name)
const duplicateName = generateDuplicateName(folder.name, siblingNames)
const result = await duplicateFolderMutation.mutateAsync({
id: folderId,
workspaceId,
name: duplicateName,
parentId: folder.parentId,
color: folder.color,
})
const newFolderId = result?.id
if (newFolderId) {
duplicatedIds.push(newFolderId)
@@ -88,7 +123,14 @@ export function useDuplicateFolder({
} finally {
setIsDuplicating(false)
}
}, [getFolderIds, isDuplicating, duplicateFolderMutation, workspaceId, onSuccess])
}, [
getFolderIds,
generateDuplicateName,
isDuplicating,
duplicateFolderMutation,
workspaceId,
onSuccess,
])
return {
isDuplicating,

View File

@@ -79,6 +79,9 @@ interface DeleteFolderVariables {
interface DuplicateFolderVariables {
workspaceId: string
id: string
name: string
parentId?: string | null
color?: string
}
export function useCreateFolder() {
@@ -160,11 +163,16 @@ export function useDuplicateFolderMutation() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async ({ id, workspaceId }: DuplicateFolderVariables) => {
mutationFn: async ({ id, workspaceId, name, parentId, color }: DuplicateFolderVariables) => {
const response = await fetch(`/api/folders/${id}/duplicate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ workspaceId }),
body: JSON.stringify({
workspaceId,
name,
parentId: parentId ?? null,
color,
}),
})
if (!response.ok) {