Repository navigation
feat: edit saved workout entries and recover sync conflicts - #203
DuarteSantos8 merged 2 commits into
Conversation
…eSantos8#218) A workout typed in from another app, or logged on the wrong day, could only be deleted and re-entered. The workout detail sheet now offers "Change date & time": the sets, volume and notes are the record and are never touched, the session keeps the length it had, and it is re-filed where its new date and start time put it. Re-filing matters beyond display order — lastEntryFor() walks the array backwards rather than comparing dates, so "last time" would otherwise read from the wrong session. Three things a naive date move gets wrong, all handled in lib/workout-date.js as pure helpers with tests beside them: - PR badges. `prs` is written once at finish against bestWeightFor(), which is all-time and date-agnostic; it only reads as chronological because history normally grows forwards. rebuildPrHistory() re-derives it, and the rule is deliberately asymmetric: a move can revoke a badge whose claim the new order breaks, but only the session that moved can gain one. Imports and backfilled sessions are filed with `prs: []` on purpose, so awarding badges by pure chronology would make a year of imported history sprout trophies the first time one date was nudged. Revoking a falsified claim is a correction; handing out new ones is an invention. - Legacy sync keys. sync-merge keys a workout by `id ?? d|start`, so moving a pre-id record changes its identity and the other device's untouched copy comes back from the merge as a second workout. A fresh uid() does not help — it shares nothing with that copy. retimeWorkout() freezes the old `d|start` as the id, so both sides agree and the union lets the newer copy win. Both the fix and the duplication it avoids are covered in sync-merge.test.js. - The session note. It is written on blur, so a note typed and left focused is flushed before the move rather than by the unmount hook afterwards, which would miss a record that has just been re-keyed. Future dates are refused the way "Log a past workout" refuses them. exWeights is deliberately untouched: the heaviest weight lifted does not change when a session moves, and only `.w` is read for decisions. Scope is date and start time only, so it does not overlap DuarteSantos8#203 (entry corrections, which leaves dates, start times and durations unchanged). 14 locales updated.
…every device, through the sync the app now has The editor stays as #203 built it. Its own conflict recovery is replaced by the sync core: the pending-edit receipts in localStorage, the 409 path that turned a saved edit back into a draft and could hold the push back, and the refusal to save over a record another device had touched are gone. Instead a workout changed after it was logged carries the time of the change, and a merge keeps the version edited last, the rule routines already follow. That covers every such change: sets edited, moved to another day, the session note written in the detail sheet. - An edit saved offline goes with the next push; a 409 merges it over the server's old copy. - A device still holding the old copy takes the edit on its next pull or conflict, even when its own copy is newer as a whole. - A workout deleted elsewhere: when the deletion arrives first, Save keeps the draft and says so; when the edit was saved first, the merge keeps the edited workout rather than lose it. - Save rebuilds the badges by the date move's rule, lowers a kept working weight only when it came from this session and the edit took it away, and a kept edit does the same in a merge. - A workout logged before ids can be edited, and keeps its old key as its id.
…orkout, so an injury day stays out of the next session's numbers; every exercise shows the marker, a second tap counts them again, an exercise or routine added afterwards stays out too, and it works in the saved-workout editor (Discord asierlama, #203) It stamps every entry's noProg, the flag the exercise ⋯ menu sets for one exercise, so the finished workout saves exactly like one whose exercises were each kept out by hand: noProg on every entry and excludeFromProgression on the workout (finish-workout.js), which the history and the next prescription already read past. The running session remembers the choice as active.noProg (never saved), which is what the menu shows as on and what later additions join. Switching it off leaves a deload or rehab routine's own exercises out, and one card's Undo ends the whole-workout choice. A saved workout kept out as a whole opens in the editor with it on.
…nger keeps an empty workout in the history; it asks to delete the workout instead, with Keep editing to go back (#203) lib/session-edit.js: editLeftEmpty tells such a draft apart (no set with completed work, which is what Save would keep), saveWorkoutEdit refuses one, and deleteEditedWorkout removes the record the editor opened, matched the way Save matches it. A kept working weight that came from the deleted workout is lowered the way Save lowers one an edit took away, so a typed 1000 does not stay behind as the next start. The editor's Save and the close button's Save changes both go through the existing confirm sheet (danger).
|
Thanks @Space-Hermes, editing saved workouts was the most requested thing on the tracker and it's in v1.3.9, together with #263 (date and start time) and a duration edit. I kept your editor and changed one thing underneath it: instead of the separate pending-edit recovery, every saved workout now carries its own edit stamp ( Two more behaviours worth knowing: a kept working weight is only lowered when it came from the edited session and the edit removed it, and PR badges follow #263's rule (the edited session can earn one, other sessions can only lose theirs). An edit that leaves no sets now offers "Delete workout". Released in v1.3.9: https://github.com/DuarteSantos8/openGym/releases/tag/v1.3.9 |
Saved workouts can now be reopened in the workout editor to correct completed exercise entries. Saving replaces the original record, recalculates volume and personal-best history, and retains combined-routine and superset occurrence metadata. Leaving the editor offers Save, Don't save and Keep editing.
Offline corrections remain recoverable if another device changes or deletes the original record before sync. A conflicting saved correction becomes an editable local draft instead of silently overwriting newer server history.
This is the focused GitHub successor to GitLab !127, refreshed onto v1.3.8 main (
f91cde15). Related to #143 and the contribution review in #140. Dates, start times and durations remain unchanged, so this does not complete the wider date/time-editing request in #143. The separate date/time proposal in #263 is not included here. Assisted-exercise personal bests retain the lower-assistance ordering from v1.3.8.Validation: all 1,604 frontend tests pass across 127 files, including deleted/changed originals, offline/retry/in-flight sync, per-side and combined-workout history. Production build passes. All 11 new strings are present in all 14 locale packs. Earlier browser verification covered editing a completed set, recalculated volume after save/reload, preserved date/duration and occurrence metadata, cancellation, and the editor at 390px width. Existing Vite bundle-size/dynamic-import warnings remain; native device validation is still separate.