-
Notifications
You must be signed in to change notification settings - Fork 106
[MBL-17287][Teacher] Add dashboard card reordering functionality #3358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MBL-17287][Teacher] Add dashboard card reordering functionality #3358
Conversation
Implemented drag-and-drop reordering for dashboard cards in Teacher app, matching the Student app functionality. Cards can be reordered by dragging, and positions persist across app restarts via API persistence and cache invalidation. Changes: - DashboardFragment: Added ItemTouchHelper for drag-and-drop, cancelCardDrag() safety method to handle tab switching during drag - DashboardPresenter: Added moveCourse() for local reordering, saveDashboardPositions() for API persistence with cache invalidation, isOnline() check to disable dragging when offline - DashboardPresenterFactory: Updated to inject UserAPI and NetworkStateProvider - InitActivity: Added call to cancelCardDrag() when switching bottom nav tabs to prevent UI glitches Key features: - Drag-and-drop only enabled when online - Position persistence via API with cache invalidation strategy - Cancel drag gesture when switching tabs for clean UX - Error handling with toast notification on save failure Test plan: - Verify cards can be dragged and reordered in grid/list views - Verify positions persist after app restart - Verify dragging is disabled when offline - Verify switching tabs while dragging cancels the gesture cleanly - Verify error toast appears if position save fails 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Review Summary
This PR implements drag-and-drop reordering for dashboard cards in the Teacher app. The implementation is generally well-structured with proper dependency injection using Hilt. Here are my findings:
Positives
✅ Good use of Hilt for dependency injection
✅ Proper bounds checking in moveCourse()
✅ Network connectivity check before enabling drag
✅ Online/offline state handling
✅ Clean separation of concerns between Fragment and Presenter
Areas for Improvement
Code Quality:
- Performance issue with
notifyDataSetChanged()after move (consider removing) GlobalScope.launchusage in presenter should be replaced with lifecycle-aware scope- Missing error logging when dashboard position save fails
Potential Bugs:
- Possible race condition with
draggedFromPosition(likely safe but needs verification) - No null safety comment for fragment lookup in
InitActivity MotionEvent.obtain()could potentially leak native memory withoutrecycle()
Testing:
- Need unit tests for
moveCourse()andsaveDashboardPositions() - UI tests for drag-and-drop would prevent regressions
The drag-and-drop feature looks solid overall. The main concerns are the performance optimization opportunity and ensuring proper coroutine lifecycle management. The functionality should work correctly but could be refined for better performance and maintainability.
apps/teacher/src/main/java/com/instructure/teacher/activities/InitActivity.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Outdated
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/presenters/DashboardPresenter.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/presenters/DashboardPresenter.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements drag-and-drop reordering functionality for dashboard course cards in the Teacher app, allowing users to manually reorganize their course cards and persist the new order to the backend.
- Added dependency injection support via Hilt to the DashboardFragment and DashboardPresenter
- Implemented ItemTouchHelper for drag-and-drop course card reordering with visual feedback
- Integrated API calls to save dashboard positions to the server after reordering
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| DashboardPresenter.kt | Added constructor parameters for UserAPI and NetworkStateProvider; implemented course movement logic and dashboard position persistence |
| DashboardFragment.kt | Added Hilt annotations, ItemTouchHelper for drag-and-drop, and touch cancellation for tab switching |
| DashboardPresenterFactory.kt | Updated to pass injected dependencies to DashboardPresenter constructor |
| InitActivity.kt | Added logic to cancel active drag operations when switching tabs |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Outdated
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Show resolved
Hide resolved
📊 Code Coverage Report✅ Student
|
- Remove unnecessary notifyDataSetChanged() call after drag (performance) - Properly recycle MotionEvent to prevent memory leak - Add early return for same position in moveCourse - Combine validation checks into single if statement 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall Review Summary
This PR implements drag-and-drop reordering for dashboard course cards. The implementation is solid overall with good use of modern Android patterns like Hilt dependency injection and coroutines. Here are the key findings:
✅ Strengths
- Good architecture: Proper separation of concerns with presenter pattern
- Modern Android practices: Uses Hilt for DI, coroutines for async operations
- Defensive programming: Good null checks and validation
- User experience: Disables dragging when offline and cancels drag on tab switch
⚠️ Areas for Improvement
High Priority:
- Potential duplicate ItemTouchHelper attachments -
addItemTouchHelperForCardReorder()could be called multiple times (DashboardFragment.kt:170) - Inconsistent state on API failure - If the API call fails, the local UI remains reordered but the server state doesn't match (DashboardFragment.kt:323)
- Memory leak risk - MotionEvent not properly recycled if exception occurs (DashboardFragment.kt:338)
Medium Priority:
4. Performance concern - Using notifyDataSetChanged() after drag may cause unnecessary rebinding (DashboardFragment.kt:321)
5. Side effects in presenter - Cache clearing happens inside saveDashboardPositions() which may have unintended consequences (DashboardPresenter.kt:147)
Low Priority:
6. Consider adding user feedback when dragging is disabled due to offline status
7. Add documentation for thread safety assumptions around draggedFromPosition
🧪 Testing Recommendations
- Test fragment recreation scenarios (rotation, background/foreground)
- Test rapid tab switching during drag operations
- Test network failure scenarios to ensure UI consistency
- Test with large course lists for performance
- Verify cache clearing doesn't cause excessive network requests
Overall, this is well-structured code that follows good practices. The inline comments provide specific suggestions for addressing the identified issues.
apps/teacher/src/main/java/com/instructure/teacher/activities/InitActivity.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/factory/DashboardPresenterFactory.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/fragments/DashboardFragment.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/presenters/DashboardPresenter.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/presenters/DashboardPresenter.kt
Show resolved
Hide resolved
apps/teacher/src/main/java/com/instructure/teacher/presenters/DashboardPresenter.kt
Show resolved
Hide resolved
tamaskozmer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QA + 1
adamNagy56
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QA +1
refs: MBL-17287
affects: Teacher
release note: Teachers can now reorder their dashboard cards by dragging them.
Summary
Adds drag-and-drop reordering functionality for dashboard cards in the Teacher app, matching the Student app implementation.
Changes
Test plan
Drag and reorder dashboard cards, verify positions persist after app restart and dragging is disabled offline.
🤖 Generated with Claude Code