(oldFolder, newBaseName, opts = {})
| 3477 | Rename / Delete / Create hooks |
| 3478 | ----------------------*/ |
| 3479 | export async function renameFolderInline(oldFolder, newBaseName, opts = {}) { |
| 3480 | const selectedFolder = oldFolder || window.currentFolder || "root"; |
| 3481 | if (!selectedFolder || selectedFolder === "root") { |
| 3482 | if (!opts.silent) showToast(t('select_folder_rename'), 'warning'); |
| 3483 | return { success: false, error: "invalid_folder" }; |
| 3484 | } |
| 3485 | |
| 3486 | const newNameBasename = String(newBaseName || "").trim(); |
| 3487 | const currentBase = selectedFolder.split("/").pop() || ""; |
| 3488 | if (!newNameBasename || newNameBasename === currentBase) { |
| 3489 | if (!opts.silent) showToast(t('enter_new_folder_name'), 'warning'); |
| 3490 | return { success: false, error: "invalid_name" }; |
| 3491 | } |
| 3492 | |
| 3493 | const parentPath = getParentFolder(selectedFolder); |
| 3494 | const newFolderFull = parentPath === "root" ? newNameBasename : parentPath + "/" + newNameBasename; |
| 3495 | |
| 3496 | try { |
| 3497 | const res = await fetchWithCsrf("/api/folder/renameFolder.php", { |
| 3498 | method: "POST", |
| 3499 | headers: { "Content-Type": "application/json" }, |
| 3500 | credentials: "include", |
| 3501 | body: JSON.stringify({ oldFolder: selectedFolder, newFolder: newFolderFull }) |
| 3502 | }); |
| 3503 | const data = await safeJson(res); |
| 3504 | if (!data.success) { |
| 3505 | const msg = data.error || t('rename_folder_error_default'); |
| 3506 | if (!opts.silent) showToast(t('rename_folder_error', { error: msg }), 'error'); |
| 3507 | return { success: false, error: msg }; |
| 3508 | } |
| 3509 | |
| 3510 | if (!opts.silent) showToast(t('rename_folder_success'), 'success'); |
| 3511 | |
| 3512 | const oldPath = selectedFolder; |
| 3513 | const newPath = newFolderFull; |
| 3514 | |
| 3515 | // carry color on rename as well |
| 3516 | await carryFolderColor(oldPath, newPath); |
| 3517 | |
| 3518 | // migrate expansion state like move and keep parent open |
| 3519 | migrateExpansionStateOnMove(oldPath, newPath, [parentPath]); |
| 3520 | |
| 3521 | // refresh parent list incrementally (preserves other branches) |
| 3522 | invalidateFolderCaches(parentPath); |
| 3523 | clearPeekCache([parentPath, oldPath, newPath]); |
| 3524 | const ul = getULForFolder(parentPath); |
| 3525 | if (ul) { ul._renderedOnce = false; ul.innerHTML = ""; await ensureChildrenLoaded(parentPath, ul); } |
| 3526 | if (parentPath === 'root') placeRecycleBinNode(); |
| 3527 | |
| 3528 | // restore any open nodes we had saved |
| 3529 | await expandAndLoadSavedState(); |
| 3530 | |
| 3531 | // update currentFolder if we renamed the open folder or its descendants |
| 3532 | let currentUpdated = false; |
| 3533 | if (window.currentFolder === oldPath) { |
| 3534 | window.currentFolder = newPath; |
| 3535 | currentUpdated = true; |
| 3536 | } else if (window.currentFolder && window.currentFolder.startsWith(oldPath + '/')) { |
no test coverage detected