Fix: Preserve task selection when duplicating time entriesWhen duplicating a time entry with an assigned task, the task was notbeing pre-selected in the duplicate form. This was caused by thetemplate application code interfering with the duplication logic.The template code would run after duplication data was set, overwritingthe `data-selected-task-id` attribute and clearing the task selectioneven when no template was being applied.Changes:- Added isDuplicating flag check in manual_entry.html to prevent template application code from running during duplication- Template functionality continues to work normally for non-duplicate manual entries- Added comprehensive test to verify task pre-selection is preserved- Updated documentation with fix notes and changelog entryImpact:- Users can now duplicate time entries with tasks and the task will be correctly pre-selected, saving time and improving UX- No breaking changes - all existing tests pass (54/54)- Clean separation between duplication and template featuresTests:- test_duplicate_with_task_not_overridden_by_template_code (new)- All 22 duplication tests passing- All 32 template tests passing
8.8 KiB
Time Entry Duplication Feature
Overview
The Time Entry Duplication feature allows users to quickly copy existing time entries with pre-filled data. This significantly speeds up time tracking workflows when working on similar tasks or projects repeatedly.
User Stories
- As a user, I want to duplicate a previous time entry so that I can quickly log similar work without re-entering all the details.
- As a user, I want the duplicated entry to preserve my project, task, notes, tags, and billable settings from the original entry.
- As a user, I want to be able to adjust the times for the duplicated entry before saving it.
Features
Quick Access
- Duplicate buttons are available in multiple locations:
- Dashboard: Next to each time entry in the "Recent Entries" table
- Edit Entry Page: Alongside the "Back" button for easy access when viewing an entry
Pre-filled Data
When duplicating an entry, the following fields are automatically populated:
- Project: The same project as the original entry
- Task: The same task (if any) as the original entry
- Notes: The same notes/description from the original entry
- Tags: The same comma-separated tags from the original entry
- Billable Status: The same billable flag as the original entry
User Control
- Users can modify any pre-filled field before creating the duplicate
- Start and end times are not copied - users must set new times for the duplicate entry
- This ensures users consciously choose when the work was done
Visual Feedback
- A blue information banner shows details about the original entry being duplicated
- The page title changes to "Duplicate Time Entry" to clearly indicate the action
- Original entry details (project, task, duration) are displayed for reference
Technical Details
Backend Implementation
Route
@timer_bp.route('/timer/duplicate/<int:timer_id>')
@login_required
def duplicate_timer(timer_id):
"""Duplicate an existing time entry - opens manual entry form with pre-filled data"""
URL Pattern: /timer/duplicate/<id>
Method: GET
Authentication: Required
Process Flow
- User clicks duplicate button
- System retrieves the original time entry
- Permission check: User must own the entry or be an admin
- Manual entry form is rendered with pre-filled data
- User adjusts times and modifies fields as needed
- User submits the form to create the new entry
Security
- Permission Check: Users can only duplicate their own entries
- Admin Override: Administrators can duplicate any user's entries
- 404 Handling: Non-existent entries return a 404 error
Analytics
- Event tracking for duplication actions:
- Event name:
timer.duplicated - Tracked properties: entry ID, project ID, task ID, has_notes, has_tags
- Event name:
Frontend Implementation
Dashboard Button
<a href="{{ url_for('timer.duplicate_timer', timer_id=entry.id) }}"
class="text-blue-600 hover:text-blue-800"
title="{{ _('Duplicate entry') }}">
<i class="fas fa-copy"></i>
</a>
Edit Page Button
<a href="{{ url_for('timer.duplicate_timer', timer_id=timer.id) }}"
class="btn btn-outline-primary">
<i class="fas fa-copy me-1"></i>{{ _('Duplicate') }}
</a>
Information Banner
Displays when duplicating an entry:
<div class="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 ...">
<p>Duplicating entry: [Project Name] - [Task Name]</p>
<p>Original: [Start Time] to [End Time] ([Duration])</p>
</div>
Template Variables
The manual entry template accepts these additional variables for duplication:
is_duplicate(boolean): Indicates this is a duplication actionoriginal_entry(TimeEntry): The entry being duplicatedselected_project_id(int): Pre-selects the project dropdownselected_task_id(int): Pre-selects the task dropdownprefill_notes(string): Pre-fills the notes textareaprefill_tags(string): Pre-fills the tags inputprefill_billable(boolean): Pre-checks the billable checkbox
Use Cases
1. Daily Recurring Work
Scenario: A developer logs 2 hours of code review every morning.
Workflow:
- Click duplicate on yesterday's code review entry
- Adjust start/end times to today
- Submit the form
- Entry is created in seconds instead of minutes
2. Similar Tasks Across Projects
Scenario: A consultant has similar meeting entries across different projects.
Workflow:
- Duplicate a meeting entry from Project A
- Change the project to Project B
- Adjust times and notes as needed
- Submit to create entry for Project B
3. Template-like Entries
Scenario: A designer regularly logs similar "Client Feedback" entries.
Workflow:
- Find any previous "Client Feedback" entry
- Click duplicate
- Update times and any client-specific notes
- Submit quickly with consistent tags and structure
Testing
Test Coverage
The feature includes comprehensive test coverage:
- Unit Tests: Route access, authentication, permission checks
- Integration Tests: Pre-fill functionality, form rendering, data accuracy
- Security Tests: User isolation, admin privileges
- Smoke Tests: Button visibility, basic workflows
- Model Tests: Field availability, duplication mechanics
- Edge Cases: Missing fields, inactive projects, minimal entries
Test File
Location: tests/test_time_entry_duplication.py
Run tests:
# Run all duplication tests
pytest tests/test_time_entry_duplication.py -v
# Run specific test categories
pytest tests/test_time_entry_duplication.py -v -m unit
pytest tests/test_time_entry_duplication.py -v -m integration
pytest tests/test_time_entry_duplication.py -v -m smoke
pytest tests/test_time_entry_duplication.py -v -m security
Internationalization
All user-facing text uses Flask-Babel for internationalization:
- Button labels
- Page titles
- Information messages
- Form labels
Keys to translate:
Duplicate entryDuplicate Time EntryCreate a copy of a previous entry with new timesDuplicating entryOriginal
Future Enhancements
Potential Improvements
- Quick Duplicate: Add a "Duplicate & Edit Times" modal for even faster duplication
- Bulk Duplicate: Duplicate an entry across multiple dates at once
- Smart Defaults: Auto-fill times based on user's typical work patterns
- Favorite Entries: Mark entries as favorites for quick access when duplicating
- Duplicate to Today: One-click duplicate with today's date and current time
API Endpoint
Consider adding an API endpoint for programmatic duplication:
POST /api/timer/duplicate/<id>
{
"start_time": "2024-01-15T09:00:00",
"end_time": "2024-01-15T11:00:00"
}
Related Features
- Time Entry Templates: For completely reusable entry templates (different use case)
- Manual Entry: The form used after clicking duplicate
- Bulk Entry: For creating multiple similar entries across date ranges
- Edit Entry: For modifying existing entries
Troubleshooting
Common Issues
Issue: Duplicate button not visible
- Cause: Entry may be from another user (non-admin)
- Solution: Ensure you're viewing your own entries or have admin privileges
Issue: Task not pre-selected after duplication
- Cause: Tasks are loaded dynamically via JavaScript
- Solution: Wait for the page to fully load; the task should auto-select
- Note: This issue has been resolved in the latest version - template code no longer interferes with task pre-selection during duplication
Issue: Cannot duplicate inactive project entry
- Cause: Project status changed to inactive after entry creation
- Solution: Form will render, but you may need to select an active project
Issue: Permission denied when duplicating
- Cause: Attempting to duplicate another user's entry
- Solution: Only duplicate your own entries, or request admin assistance
Changelog
Version 1.1 (2025-10-31)
- Bug Fix: Fixed issue where duplicated time entries with assigned tasks would not have the task pre-selected
- Technical: Template application code now properly checks for duplication mode and doesn't interfere with pre-filled task data
- Testing: Added comprehensive test to ensure task pre-selection is preserved during duplication
Version 1.0 (2024-10-23)
- Initial implementation of time entry duplication
- Duplicate buttons on dashboard and edit pages
- Pre-filled form with all relevant fields
- Comprehensive test suite
- Documentation and user guides
- Analytics tracking for duplication events
Support
For questions or issues with the Time Entry Duplication feature:
- Check this documentation
- Review the test cases for examples
- Check the application logs for errors
- Contact your system administrator
License
This feature is part of the TimeTracker application and follows the same license terms.