diff --git a/CHANGELOG.md b/CHANGELOG.md index db9a0b1..d1f2d63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,55 @@ # Changelog +## Changes 10/25/2025 (v1.6.7) + +release(v1.6.7): Folder Move feature, stable DnD persistence, safer uploads, and ACL/UI polish + +### 📂 Folder Move (new major feature) + +**Drag & Drop to move folder, use context menu or Move Folder button** + +- Added **Move Folder** support across backend and UI. + - New API endpoint: `public/api/folder/moveFolder.php` + - Controller and ACL updates to validate scope, ownership, and permissions. + - Non-admins can only move within folders they own. + - `ACL::renameTree()` re-keys all subtree ACLs on folder rename/move. +- Introduced new capabilities: + - `canMoveFolder` + - `canMove` (UI alias for backward compatibility) +- New “Move Folder” button + modal in the UI with full i18n strings (`i18n.js`). +- Action button styling and tooltip consistency for all folder actions. + +### 🧱 Drag & Drop / Layout Improvements + +- Fixed **random sidebar → top zone jumps** on refresh. +- Cards/panels now **persist exactly where you placed them** (`userZonesSnapshot`) + — no unwanted repositioning unless the window is resized below the small-screen threshold. +- Added hysteresis around the 1205 px breakpoint to prevent flicker when resizing. +- Eliminated the 50 px “ghost” gutter with `clampSidebarWhenEmpty()`: + - Sidebar no longer reserves space when collapsed or empty. + - Temporarily “unclamps” during drag so drop targets remain accurate and full-width. +- Removed forced 800 px height on drag highlight; uses natural flex layout now. +- General layout polish — smoother transitions when toggling *Hide/Show Panels*. + +### ☁️ Uploads & UX + +- Stronger folder sanitization and safer base-path handling. +- Fixed subfolder creation when uploading directories (now builds under correct parent). +- Improved chunk error handling and metadata key correctness. +- Clearer success/failure toasts and accurate filename display from server responses. + +### 🔐 Permissions / ACL + +- Simplified file rename checks — now rely solely on granular `ACL::canRename()`. +- Updated capability lists to include move/rename operations consistently. + +### 🌐 UI / i18n Enhancements + +- Added i18n strings for new “Move Folder” prompts, modals, and tooltips. +- Minor UI consistency tweaks: button alignment, focus states, reduced-motion support. + +--- + ## Changes 10/24/2025 (v1.6.6) release(v1.6.6): header-mounted toggle, dark-mode polish, persistent layout, and ACL fix diff --git a/public/api/folder/capabilities.php b/public/api/folder/capabilities.php index 4952bd0..3f75b1d 100644 --- a/public/api/folder/capabilities.php +++ b/public/api/folder/capabilities.php @@ -185,6 +185,7 @@ $canDelete = $gDeleteBase && !$readOnly && $inScope; $canReceive = ($gUploadBase || $gCreateBase || $canManageBase) && !$readOnly && $inScope; // Back-compat: expose as canMoveIn (used by toolbar/context-menu/drag&drop) $canMoveIn = $canReceive; +$canMoveAlias = $canMoveIn; $canEdit = $gEditBase && !$readOnly && $inScope; $canCopy = $gCopyBase && !$readOnly && $inScope; $canExtract = $gExtractBase && !$readOnly && $inScope; @@ -200,6 +201,12 @@ if ($isRoot) { $canRename = false; $canDelete = false; $canShareFoldEff = false; + $canMoveFolder = false; +} + +if (!$isRoot) { + $canMoveFolder = (ACL::canManage($username, $perms, $folder) || ACL::isOwner($username, $perms, $folder)) + && !$readOnly; } $owner = null; @@ -225,6 +232,8 @@ echo json_encode([ 'canRename' => $canRename, 'canDelete' => $canDelete, 'canMoveIn' => $canMoveIn, + 'canMove' => $canMoveAlias, + 'canMoveFolder'=> $canMoveFolder, 'canEdit' => $canEdit, 'canCopy' => $canCopy, 'canExtract' => $canExtract, diff --git a/public/api/folder/moveFolder.php b/public/api/folder/moveFolder.php new file mode 100644 index 0000000..a259abf --- /dev/null +++ b/public/api/folder/moveFolder.php @@ -0,0 +1,9 @@ +moveFolder(); diff --git a/public/css/styles.css b/public/css/styles.css index 686f699..d125d36 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -1046,11 +1046,6 @@ label { display: none; } -#createFolderBtn { - margin-top: 0px !important; - height: 40px !important; - font-size: 1rem; -} .folder-actions { display: flex; @@ -1058,6 +1053,7 @@ label { padding-left: 8px; align-items: center; white-space: nowrap; + padding-top: 10px; } @media (min-width: 600px) and (max-width: 992px) { @@ -1066,6 +1062,70 @@ label { } } +.folder-actions .btn { + padding: 10px 12px; + font-size: 0.85rem; + line-height: 1.1; + border-radius: 6px; +} + +.folder-actions .material-icons { + font-size: 24px; + vertical-align: -2px; +} + +.folder-actions .btn + .btn { + margin-left: 6px; +} + +.folder-actions .btn { + padding: 10px 12px; + font-size: 0.85rem; + line-height: 1.1; + border-radius: 6px; + + transform: scale(1); + transform-origin: center; + transition: transform 120ms ease, box-shadow 120ms ease; + will-change: transform; +} + + +.folder-actions .material-icons { + font-size: 24px; + vertical-align: -2px; + transition: transform 120ms ease; +} + +.folder-actions .btn:hover, +.folder-actions .btn:focus-visible { + transform: scale(1.06); + box-shadow: 0 2px 8px rgba(0,0,0,0.12); +} + +.folder-actions .btn:hover .material-icons, +.folder-actions .btn:focus-visible .material-icons { + transform: scale(1.05); +} + +.folder-actions .btn:focus-visible { + outline: 2px solid rgba(33,150,243,0.6); + outline-offset: 2px; +} + +@media (prefers-reduced-motion: reduce) { + .folder-actions .btn, + .folder-actions .material-icons { + transition: none; + } +} + +#moveFolderBtn { + background-color: #ff9800; + border-color: #ff9800; + color: #fff; +} + .row-selected { background-color: #f2f2f2 !important; } diff --git a/public/index.html b/public/index.html index 533c996..567ebac 100644 --- a/public/index.html +++ b/public/index.html @@ -286,9 +286,27 @@ + + +
Select a destination folder to move the current folder + into:
+ +