Skip to content

feat: edit saved workout entries and recover sync conflicts - #203

Merged
DuarteSantos8 merged 2 commits into
DuarteSantos8:mainfrom
Space-Hermes:contrib/github-history-20260914
Sep 28, 2026
Merged

DuarteSantos8 merged 2 commits into
DuarteSantos8:mainfrom
Space-Hermes:contrib/github-history-20260914

Conversation

@Space-Hermes

@Space-Hermes Space-Hermes commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

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.

@giulioleuci

Copy link
Copy Markdown
Contributor

#229

@giulioleuci

Copy link
Copy Markdown
Contributor

#143

ilirhushi pushed a commit to ilirhushi/openGym that referenced this pull request Sep 20, 2026
…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.
@DuarteSantos8
DuarteSantos8 merged commit 3505be6 into DuarteSantos8:main Sep 28, 2026
4 checks passed
DuarteSantos8 added a commit that referenced this pull request Sep 28, 2026
…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.
DuarteSantos8 added a commit that referenced this pull request Sep 28, 2026
…te loading in its menu, as it showed no bar chip before the plate lines came in (#194, #203)
DuarteSantos8 added a commit that referenced this pull request Sep 28, 2026
…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.
DuarteSantos8 added a commit that referenced this pull request Sep 28, 2026
…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).
@DuarteSantos8

Copy link
Copy Markdown
Owner

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 (_ts), and a sync merge keeps the version edited last, the same rule routines follow. That covers your editor, #263's date moves, the duration edit and note edits in one place. If the workout was deleted on another device before you press Save, Save refuses and keeps your draft.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants