Repository navigation
fix(web): reliable start times and live duration in time-entry forms - #788
Merged
evilguy4000 merged 7 commits intoOct 16, 2026
Merged
Conversation
added 7 commits
October 16, 2026 15:58
The start-timer forms pre-filled the 'Start Time (Optional)' override with the time the form was opened. Users who take a few minutes to fill in the form then unknowingly start the timer in the past. Both the dashboard modal and the timer page now track whether the user edited the override field themselves; on submit an untouched field is refreshed to the current time, so a timer started without an explicit backdate always begins at the actual start moment. Manually entered times are preserved, and the 'Set to now' button continues to load the current time on click.
The modal's start-time control moved from a datetime field at the bottom of the form to a compact time chip next to the modal title: - shows the current time, ticks every 15s while the modal is open, and is submitted as-is — so a timer always starts at the time shown when Start is pressed - overwriting the chip backdates the entry within today (composed with today's date; future values are clamped to now) - the old datetime-local field was hidden by Flatpickr's altInput swap, so the previous 'Set to now' button updated an invisible input — the reason it appeared dead; the button is gone along with the field - hidden native input keeps the start_time_override form contract The timer page keeps its field but the same Flatpickr visibility fix is applied there: updates route through _flatpickr.setDate(), and its submit-time refresh compares against the last auto-set value so user backdates survive.
The native type=time input rendered in the browser locale (e.g. 12h AM/PM for en-US), ignoring the system-wide time format setting and the per-user profile override. Replace it with a text chip formatted and parsed via window.userPrefs.timeFormat, reusing the shared __parseUserTimeInput helper (accepts HH:MM, HHMM, and AM/PM input).
The edit form's duration label only listened for change events on the native date/time inputs, but those are Flatpickr-wrapped (altInput visible, native hidden), so typing never updated the label. Hook the Flatpickr instances and altInputs directly, include the break field in the calculation like the server does, and poll lightly as a safety net for late Flatpickr initialization.
The break field only accepted strict HH:MM; '0100' was silently treated as zero. Share one duration parser (HH:MM, compact HMM/HHMM, decimal hours with h suffix or separator, plain minutes) between the edit route, the manual-entry route and the live duration label, and document the accepted formats in the field hint.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two related usability bugs in the time-entry forms, both rooted in the same pattern: date/time inputs are Flatpickr-wrapped (Flatpickr hides the native input and shows its own altInput), so code that reads or writes the native input's
.valuesilently misses what the user sees.datetime-localoverride with the time the form was opened. Submitting minutes later started the timer at that stale time. Worse, the "Set to now" button updated the hidden native input only — the visible Flatpickr input never changed, so the button appeared dead.changeon the hidden native inputs, which don't fire while the user types into the Flatpickr altInput.Changes
Start Timer modal (dashboard)
14:30,1430,930, or2:45 PMwhen the profile uses 12h.userPrefs.timeFormat), not the browser locale — a nativetype=timechip rendered 12h AM/PM regardless of the system setting.1345normalize to13:45on blur.start_time_overrideform contract; no server changes needed for this part.Timer page
_flatpickr.setDate(), and the submit-time refresh compares against the last auto-set value so user-entered backdates survive.Edit form duration
config.onChange+ altInput events), includes the break field in the calculation like the server does, with a light 1s poll as a safety net for late Flatpickr initialization.Break duration parsing (server + client)
HH:MM;0100was silently stored as zero. A shared_parse_duration_to_seconds()parser now acceptsHH:MM, compactHMM/HHMM(0100= 1h), decimal hours (1h,1.5,1,5) and plain minutes (90), used by the edit route, the manual-entry route, and mirrored in the live label.Testing
node --checkon all touched files; parser unit-checked against0100,130,1:30,1.5h,1,5,45,0160(invalid), empty, garbagetests/test_routes.pytimer tests pass (4 passed)1345→13:45on blur; backdate composed correctly; edit-form duration updates live (14:35→16:30→01:55:00); break0100subtracts 1h live and persiststests/test_reconnect_on_resume.pyhas one failure on this branch (assert '5000'), but it fails identically ondevelop— it asserts the resume-probe backoff shipped separately in fix(web): suppress false offline errors and refetch data on tab resume #787