(selectedFolder)
| 2612 | Main: loadFolderTree |
| 2613 | ----------------------*/ |
| 2614 | export async function loadFolderTree(selectedFolder) { |
| 2615 | try { |
| 2616 | await checkUserFolderPermission(); |
| 2617 | const username = localStorage.getItem("username") || "root"; |
| 2618 | let effectiveRoot = "root"; |
| 2619 | let effectiveLabel = getRootLabel(); |
| 2620 | if (window.userFolderOnly && username) { |
| 2621 | effectiveRoot = username; |
| 2622 | effectiveLabel = getRootLabel(); |
| 2623 | setLastOpenedFolder(username); |
| 2624 | window.currentFolder = username; |
| 2625 | } else { |
| 2626 | window.currentFolder = getLastOpenedFolder() || "root"; |
| 2627 | } |
| 2628 | |
| 2629 | const container = document.getElementById("folderTreeContainer"); |
| 2630 | if (!container) return; |
| 2631 | |
| 2632 | const state0 = loadFolderTreeState(); |
| 2633 | const rootOpen = state0[effectiveRoot] !== 'none'; |
| 2634 | |
| 2635 | let html = ` |
| 2636 | <div id="rootRow" class="folder-row" role="treeitem" aria-expanded="${String(rootOpen)}"> |
| 2637 | <button type="button" class="folder-toggle" data-folder="${effectiveRoot}" aria-label="${rootOpen ? 'Collapse' : 'Expand'}"></button> |
| 2638 | <span class="folder-option root-folder-option" data-folder="${effectiveRoot}"> |
| 2639 | <span class="folder-icon" aria-hidden="true" data-kind="empty">${folderSVG('empty')}</span> |
| 2640 | <span class="folder-label">${escapeHTML(effectiveLabel)}</span> |
| 2641 | </span> |
| 2642 | </div> |
| 2643 | <ul id="rootChildren" class="folder-tree ${rootOpen ? 'expanded' : 'collapsed'}" role="group"></ul> |
| 2644 | `; |
| 2645 | container.innerHTML = html; |
| 2646 | |
| 2647 | // Add 3-dot actions button for root |
| 2648 | const rootRow = document.getElementById('rootRow'); |
| 2649 | if (rootRow) { |
| 2650 | addFolderActionButton(rootRow, effectiveRoot); |
| 2651 | } |
| 2652 | |
| 2653 | // Determine root's lock state |
| 2654 | const rootOpt = container.querySelector('.root-folder-option'); |
| 2655 | let rootLocked = false; |
| 2656 | try { |
| 2657 | const caps = await getFolderCapabilities(effectiveRoot); |
| 2658 | const canView = !!(caps?.canView ?? caps?.canRead ?? caps?.canReadOwn ?? caps?.isAdmin); |
| 2659 | rootLocked = !canView; |
| 2660 | } catch (e) {} |
| 2661 | if (rootOpt && rootLocked) markOptionLocked(rootOpt, true); |
| 2662 | applyFolderCapabilities(effectiveRoot); |
| 2663 | // Root DnD + prime icon/chevron |
| 2664 | { |
| 2665 | const ro = rootOpt; |
| 2666 | if (ro) { |
| 2667 | const isLocked = ro.classList.contains('locked'); |
| 2668 | if (!isLocked) { |
| 2669 | ro.addEventListener('dragover', folderDragOverHandler); |
| 2670 | ro.addEventListener('dragleave', folderDragLeaveHandler); |
| 2671 | ro.addEventListener('drop', (e) => handleDropOnFolder(e, effectiveRoot)); |
no test coverage detected