feat: implement drag-and-drop for access management#3
feat: implement drag-and-drop for access management#3Lucas-Developer-Off wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds native HTML5 drag-and-drop interactions to the access management UI to allow reordering of roles and permissions within the access panel.
Changes:
- Added drag-start/drag-over/drop handling to reorder roles in-place.
- Added drag-start/drag-over/drop handling to reorder permissions in-place.
- Added visual drop indicators (per-row “drop-before” highlight and “drop-at-end” indicator).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| src/components/general/panels/access/LAccessRoles.vue | Adds draggable role rows, drag/drop handlers, and drop-zone styling for role reordering. |
| src/components/general/panels/access/LAccessPermissions.vue | Adds draggable permission rows, drag/drop handlers, and drop-zone styling for permission reordering. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| class="permission" | ||
| draggable="true" | ||
| :class="{ | ||
| dragging: draggingPermissionId === id, | ||
| 'drop-before': dropBeforePermissionId === id && draggingPermissionId !== id |
There was a problem hiding this comment.
Native HTML5 drag-and-drop (draggable=true on the entire row) is not keyboard-operable, and the new drag handle is a non-focusable with only a title tooltip. If this feature needs to meet WCAG 2.1 AA (and the PR description mentions a keyboard fallback), add an explicit keyboard-accessible reorder mechanism (e.g., Move up/down buttons or a focusable handle with key bindings) and expose accessible labels/instructions via ARIA (don’t rely on title).
| function moveRecordEntryBefore<T extends { id: string }>( | ||
| record: Record<string, T>, | ||
| sourceId: string, | ||
| beforeId: string | null | ||
| ) { | ||
| if (sourceId === beforeId) { | ||
| return; | ||
| } | ||
|
|
There was a problem hiding this comment.
moveRecordEntryBefore (and associated drag logic) is duplicated in both LAccessPermissions and LAccessRoles. This will be easy to accidentally diverge over time; consider extracting it into a shared utility/composable (e.g., useRecordDragReorder) used by both components.
| const entries = Object.entries(record); | ||
| const sourceIndex = entries.findIndex(([id]) => id === sourceId); | ||
| if (sourceIndex === -1) { | ||
| return; | ||
| } | ||
|
|
||
| const [sourceEntry] = entries.splice(sourceIndex, 1); | ||
| const insertionIndex = beforeId ? entries.findIndex(([id]) => id === beforeId) : entries.length; | ||
| const safeInsertionIndex = insertionIndex === -1 ? entries.length : insertionIndex; |
There was a problem hiding this comment.
This reordering relies on JavaScript object property enumeration order (Object.entries / Object.keys) as the source of truth. That order is not purely insertion-based for integer-like keys (e.g., an id of "1" will be sorted ahead of non-integer keys), which can make drag-reorder behave incorrectly. Consider storing an explicit ordered array (or order field) instead of relying on Record key order, or validate/normalize ids to avoid integer-like keys.
| class="role" | ||
| draggable="true" | ||
| :class="{ | ||
| dragging: draggingRoleId === id, | ||
| 'drop-before': dropBeforeRoleId === id && draggingRoleId !== id | ||
| }" |
There was a problem hiding this comment.
Native HTML5 drag-and-drop (draggable=true on the entire row) is not keyboard-operable, and the new drag handle is a non-focusable with only a title tooltip. If this feature needs to meet WCAG 2.1 AA (and the PR description mentions a keyboard fallback), add an explicit keyboard-accessible reorder mechanism (e.g., Move up/down buttons or a focusable handle with key bindings) and expose accessible labels/instructions via ARIA (don’t rely on title).
| function moveRecordEntryBefore<T extends { id: string }>( | ||
| record: Record<string, T>, | ||
| sourceId: string, | ||
| beforeId: string | null | ||
| ) { |
There was a problem hiding this comment.
moveRecordEntryBefore (and associated drag logic) is duplicated in both LAccessRoles and LAccessPermissions. Consider extracting into a shared helper/composable to avoid code drift and keep drag/drop behavior consistent.
| const entries = Object.entries(record); | ||
| const sourceIndex = entries.findIndex(([id]) => id === sourceId); | ||
| if (sourceIndex === -1) { | ||
| return; | ||
| } | ||
|
|
||
| const [sourceEntry] = entries.splice(sourceIndex, 1); | ||
| const insertionIndex = beforeId ? entries.findIndex(([id]) => id === beforeId) : entries.length; | ||
| const safeInsertionIndex = insertionIndex === -1 ? entries.length : insertionIndex; |
There was a problem hiding this comment.
This reordering depends on object key enumeration order (Object.entries / Object.keys). Enumeration order is not guaranteed to reflect insertion order for integer-like keys, so drag-reorder can behave unexpectedly if role ids are numeric strings. Prefer an explicit ordered array / order field, or ensure role ids cannot be integer-like keys.
Implement drag-and-drop functionality for permissions and roles management
Overview
Adds native drag-and-drop interactions to the access management workflow, enabling users to efficiently reorder and assign permissions and roles within the access panel.
Changes
Features
Technical Details
Testing