feat: Unsaved changes indicator with review dialog on Edit Task screen#524
feat: Unsaved changes indicator with review dialog on Edit Task screen#524mulikruchi07 wants to merge 3 commits intoCCExtractor:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements an unsaved changes indicator on the Edit Task screen. When a user modifies any task attribute, a floating action button with a save icon appears in the bottom-right corner. Clicking it opens a review dialog showing the changes (old vs new values), where the user can either submit or cancel. The save button automatically disappears when all changes are reverted to their original values, ensuring accurate change tracking.
Key changes include:
- Enhanced priority widget to normalize null/empty values to display as 'X' and cycle through priority levels (X → H → M → L → X)
- Refactored the save flow by extracting the review dialog into a separate method with improved user feedback via SnackBar
- Updated change tracking logic to reflect real changes only by checking
modify.changes.isNotEmpty
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
lib/app/modules/detailRoute/views/priority_widget.dart |
Adds null/empty value normalization to 'X' for display, implements priority cycling logic with editable state handling |
lib/app/modules/detailRoute/views/detail_route_view.dart |
Refactors floating action button to use observable pattern, extracts review dialog to separate method, adds SnackBar feedback after save |
lib/app/modules/detailRoute/controllers/detail_route_controller.dart |
Updates onEdit flag logic to track real changes by checking modify.changes.isNotEmpty after setAttribute and saveChanges operations |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| callback('L'); | ||
| break; | ||
| case 'L': | ||
| callback('X'); |
There was a problem hiding this comment.
The callback should be called with null instead of 'X'. The value 'X' is a display-only representation for null priority, but the underlying Task model expects priority to be null, 'H', 'M', or 'L'. Passing 'X' as a string will not be recognized as a valid priority value and may cause issues with the task data model.
| callback('X'); | |
| callback(null); |
| onPressed: () { | ||
| Get.back(); | ||
| controller.saveChanges(); | ||
|
|
||
| ScaffoldMessenger.of(context).showSnackBar( | ||
| SnackBar( | ||
| content: Text(sentences.taskUpdated), | ||
| behavior: SnackBarBehavior.floating, | ||
| duration: const Duration(seconds: 2), | ||
| ), | ||
| ); |
There was a problem hiding this comment.
The navigation flow is broken. When the dialog is closed with Get.back() at line 225, and then controller.saveChanges() is called which contains another Get.back() at line 84 of detail_route_controller.dart, this will navigate back twice. The second Get.back() in saveChanges() will close the detail route view itself instead of just the dialog. Additionally, the SnackBar at lines 228-234 will be displayed after the view has already been popped, which may not work correctly. Consider removing the Get.back() call from the controller's saveChanges() method or restructuring this flow.
|
|
||
| ScaffoldMessenger.of(context).showSnackBar( | ||
| SnackBar( | ||
| content: Text(sentences.taskUpdated), | ||
| behavior: SnackBarBehavior.floating, | ||
| duration: const Duration(seconds: 2), | ||
| ), | ||
| ); |
There was a problem hiding this comment.
Duplicate SnackBar notifications will be shown to the user. The controller.saveChanges() method already displays a SnackBar (lines 76-81 in detail_route_controller.dart), and this code adds another SnackBar at lines 228-234. This will result in two "Task Updated" messages appearing to the user, creating a confusing experience. Consider either removing the SnackBar from the controller's saveChanges() method or removing it from this location.
| ScaffoldMessenger.of(context).showSnackBar( | |
| SnackBar( | |
| content: Text(sentences.taskUpdated), | |
| behavior: SnackBarBehavior.floating, | |
| duration: const Duration(seconds: 2), | |
| ), | |
| ); |
| modify.set(name, newValue); | ||
| onEdit.value = true; | ||
|
|
||
| // onEdit must reflect REAL changes only |
There was a problem hiding this comment.
The comment should be properly formatted with consistent spacing. Comments should start with a space after the double-slash to follow Dart style conventions.
| // onEdit must reflect REAL changes only | |
| // onEdit must reflect REAL changes only |
Description
This PR adds a visual indicator for unsaved changes on the Edit Task screen.
When a user modifies any task attribute, a Save button appears at the bottom-right.
Clicking Save opens a review dialog that clearly shows previous vs updated values,
allowing the user to either submit or cancel the changes.
The Save indicator automatically disappears if all changes are reverted back to their original values, ensuring accurate change tracking and preventing empty review dialogs.
Fixes #523
Screenshots
enh_after_524.mp4
Checklist