Skip to content

Review-driven improvements: correctness, UX, accessibility, and tests - #3

Merged
sgjholt merged 4 commits into
mainfrom
claude/review-and-improve-gAk3y
Apr 18, 2026
Merged

Review-driven improvements: correctness, UX, accessibility, and tests#3
sgjholt merged 4 commits into
mainfrom
claude/review-and-improve-gAk3y

Conversation

@sgjholt

@sgjholt sgjholt commented Apr 18, 2026

Copy link
Copy Markdown
Owner

Correctness:

  • Sanitize meta values in serialiseMD to prevent --> from breaking HTML comment structure
  • Fix dueBadgeHTML to use Date.UTC to avoid timezone/DST off-by-one errors
  • Add derivePhaseStatuses() called from parseMD so stale phase status in hand-edited .md files is auto-corrected on load

UX:

  • Ctrl+S / Cmd+S saves the active board
  • Ctrl+Tab / Ctrl+Shift+Tab cycles between open tabs
  • Add beforeunload warning when closing the browser tab with unsaved changes
  • Tab bar overflow fade gradient via #tab-bar-right::before

Accessibility:

  • Feature cards get role="button", tabindex="0", aria-label, and onkeydown (Enter/Space) handler
  • Drag handle marked aria-hidden="true" to reduce screen reader noise
  • Phase status badge gets aria-label="Phase status: ..."
  • Toast gets role="alert" and aria-live="polite" for screen reader announcements

Tests:

  • 6 new parse.test.js cases: malformed meta, invalid date format, empty phase, phase status auto-correction (2 cases), plus zero-feature phase
  • helpers.js: add window.addEventListener stub to support new beforeunload listener
  • 3 new E2E tests: ARIA attribute presence, feature drag-and-drop reorder, phase drag-and-drop reorder

https://claude.ai/code/session_018ZdAC8waAK19WE1ReL9UGc

claude added 4 commits April 18, 2026 17:53
Correctness:
- Sanitize meta values in serialiseMD to prevent --> from breaking HTML comment structure
- Fix dueBadgeHTML to use Date.UTC to avoid timezone/DST off-by-one errors
- Add derivePhaseStatuses() called from parseMD so stale phase status in hand-edited .md files is auto-corrected on load

UX:
- Ctrl+S / Cmd+S saves the active board
- Ctrl+Tab / Ctrl+Shift+Tab cycles between open tabs
- Add beforeunload warning when closing the browser tab with unsaved changes
- Tab bar overflow fade gradient via #tab-bar-right::before

Accessibility:
- Feature cards get role="button", tabindex="0", aria-label, and onkeydown (Enter/Space) handler
- Drag handle marked aria-hidden="true" to reduce screen reader noise
- Phase status badge gets aria-label="Phase status: ..."
- Toast gets role="alert" and aria-live="polite" for screen reader announcements

Tests:
- 6 new parse.test.js cases: malformed meta, invalid date format, empty phase, phase status auto-correction (2 cases), plus zero-feature phase
- helpers.js: add window.addEventListener stub to support new beforeunload listener
- 3 new E2E tests: ARIA attribute presence, feature drag-and-drop reorder, phase drag-and-drop reorder

https://claude.ai/code/session_018ZdAC8waAK19WE1ReL9UGc
…AUDE.md

- Footer now shows Ctrl+S and Ctrl+Tab hints with styled <kbd> tags
- Save button gets title="Save (Ctrl+S)" for hover discoverability
- README gains a Keyboard shortcuts table covering all four shortcuts
- CLAUDE.md gains a Documentation requirements section requiring README
  and in-app hint updates alongside every user-facing feature change

https://claude.ai/code/session_018ZdAC8waAK19WE1ReL9UGc
Both drag tests broke in CI:

1. Feature reorder: targetPosition.y received a Promise instead of a
   number because dst.boundingBox() is async and wasn't awaited.

2. Phase reorder: relied on Playwright's synthetic dragTo triggering
   ondragover on the parent .phase-card via event bubbling, which
   isn't reliable — DRAG_OVER was never set so onPhaseDrop returned
   early without swapping.

Fix: both tests now directly invoke the drop handler functions via
page.evaluate(), setting DRAG and DRAG_OVER explicitly. This is
consistent with how all other tests in this file exercise app logic
and avoids the known fragility of HTML5 drag event simulation.

https://claude.ai/code/session_018ZdAC8waAK19WE1ReL9UGc
The to-- index adjustment was copied from the feature drop logic, which
needs it to offset the above/below insertion position. Phase drop has no
such offset, so the adjustment cancelled out every forward drag (pi=0
onto pi=1 would splice and re-insert at the same position).

Fix: use DRAG_OVER.pi directly as the insertion index — after splicing
out the dragged phase, JavaScript's splice correctly handles all
orderings without any manual compensation.

https://claude.ai/code/session_018ZdAC8waAK19WE1ReL9UGc
@sgjholt
sgjholt merged commit f6bdf85 into main Apr 18, 2026
2 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.

2 participants