Skip to content

Smooth the roadmap pace slider and keep points whole - #918

Merged
github-actions[bot] merged 1 commit into
mainfrom
claude/slider-smoothness-sync-c881a8
Oct 1, 2026
Merged

github-actions[bot] merged 1 commit into
mainfrom
claude/slider-smoothness-sync-c881a8

Conversation

@JSdotNet

@JSdotNet JSdotNet commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Summary

Setting a band's pace with the roadmap slider stuttered:

  • Too many saves and reads. Releasing the thumb saved the pace file twice. Every pace control on the page, plus the band, re-read the whole backlog for each save. With 3 repositories that was 21 backlog reads per release.
  • Snap-back. The slider was handed the old pace while all that ran, so the thumb snapped back before settling.
  • Track resizing during a drag. The figure beside the slider changed width with its digits (94.75 → 95), which resized the slider track under the pointer.

This PR also makes the pace whole points and moves the info mark onto the band name's line, as asked in review.

Changes

  • One save per release. New IPlanningVelocitySettings.SetOwn (PlanningVelocitySettingsStore.SetOwn) writes the pace and the Set choice as one change, raising Changed once. PlanningPace.SetOwn delegates to it. The pace document still travels as one version per change (local ADR 0018).
  • One read per band load. IPlanningPace exposes ReadPacesInUseAsync. RoadmapBand.Load reads every band's pace from one read of the finished work instead of one per repository.
  • One redraw. The band no longer listens to the controls' OnPaceChanged as well as Paces.Changed; both reported the same save. RoadmapTypedPace only does its before/after reads when someone listens.
  • No snap-back. RoadmapPaceControl holds the slider at the released value until the saved pace is read back.
  • No track resizing. .roadmap-pace__value has a fixed width, so the track keeps its length during a drag.
  • Whole points. PaceSliderRange steps by 1, with ends on whole points and never below 1. Every pace figure in the pace control (figure, hint, notes) and in the forecast tooltip is rounded to a whole number. The heading's typed "Mine" field is unchanged and still accepts decimals.
  • Info mark beside the band name. The mark is right-aligned on the band name's line. Its bubble opens below the band's pace controls, and a long name is cut short before the mark.

Reviewer note: the harness links app.css with no fingerprint. A browser holding the previous stylesheet shows the info mark on its own line under the name; a hard refresh fixes it.

Testing

  • TDD. The new band tests failed on the old code:
    • Read count for one release with 3 bands: expected 5, the old code made 21. With this change it is 6 (each band's control, the heading's typed-pace field, the released control's own read-back, and one band redraw).
    • Snap-back with the read-back held: the figure showed 7 pt/wk instead of the released value.
  • New tests:
    • Store SetOwn: one Changed, and refusals choose nothing.
    • PlanningPace one-change test.
    • PaceSliderRange whole-point rules.
  • Full suite, CI command (Backlog.WithoutAppHeads.slnf, Release, -p:TreatWarningsAsErrors=true):
    • Build: 0 warnings.
    • Tests: 10457 total, 0 failed, 1 skipped.
    • Windows head: Release build passes.
  • Targeted QA in the desktop web harness (Playwright, Aspire logs), 5/5 scenarios passed:
    • Drag: one track width throughout, max frame gap 19 ms, all values whole.
    • Release: bars redraw once, ~40 ms after mouseup; the thumb stays steady (163/163 samples).
    • Info mark: vertical centre 0 px from the band name on every band, 8 px from the right edge, bubble fully visible.
    • Measured / Reset: both work.
    • Console and harness logs had no errors.

Related

No issue. It came from an ad-hoc report that the pace slider is not smooth. The shared InfoHint keeps aria-expanded="false" while pinned open; that predates this PR and is not changed here.

Checklist

  • Scope is focused and excludes unrelated changes
  • Documentation or instruction files were updated when governance or behavior changed (component and CSS comments updated; no governed chapter changes)
  • Running Aspire instances for this checkout were stopped before PR creation (aspire stop --apphost for this worktree)
  • Follow-up work is captured when the implementation is intentionally partial (n/a)
  • Issues this PR closes are linked with a closing keyword, or there are none

🤖 Generated with Claude Code

Releasing a band's pace slider saved the pace twice, made every pace
on the roadmap re-read the whole backlog for each save, redrew the band
twice, and let the thumb snap back to the old pace while that ran. The
figure beside the slider also changed width with its digits, so the
track resized under the pointer during a drag.

- One save per release: IPlanningVelocitySettings.SetOwn writes the
  pace and the Set choice together, raising Changed once.
- The band reads every band's pace from one backlog read
  (IPlanningPace.ReadPacesInUseAsync) and redraws once, on the pace's
  own change notice.
- The slider holds the released value until the save is read back.
- The figure has a fixed width, so the track keeps its length.
- Points are whole: the slider steps by one and every pace figure in
  the band's pace control and the forecast is rounded.
- The info mark sits at the right end of the band's name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions
github-actions Bot merged commit 033ea3d into main Oct 1, 2026
9 checks passed
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.

1 participant