Skip to content

feat: add navigation-safe frontend reorder coordinator and save-state UX - #995

Open
devin-ai-integration[bot] wants to merge 3 commits into
devin/1785262304-tile-orderfrom
devin/1785276696-reorder-coordinator
Open

feat: add navigation-safe frontend reorder coordinator and save-state UX#995
devin-ai-integration[bot] wants to merge 3 commits into
devin/1785262304-tile-orderfrom
devin/1785276696-reorder-coordinator

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Closes #979. Part of epic #975.

Summary

Replaces Browse's component-local reorder persistence with a navigation-safe coordinator (frontend/src/tileOrdering.ts) owned above SortableTileGrid, plus a save-state indicator.

  • Coordinator (TileOrderingCoordinator, module-level singleton): per-scope state machine idle → dirty → saving → (dirty-while-saving) → saved | conflict | error. Every accepted drag applies locally and is reported; drops during an active save are queued and coalesced to the newest snapshot — never discarded. Persists via the atomic PUT /api/tile-order CAS contract from Implement an atomic, revisioned tile-order API with set-based updates #978, seeding the revision with a deduped GET on first save (scope enters saving during seeding; seed failures emit failed telemetry).
  • Conflict handling: 409 surfaces "Order changed elsewhere" with the authoritative order; a 400 membership rejection is treated the same way (refreshed via GET) instead of retrying stale membership forever. Failures keep the newest local intent retryable; success applies the authoritative response directly (no category-tree refresh) and never shows "saved" while newer local changes exist.
  • Navigation safety: state survives grid unmount/remount; per-scope generation fencing (claimGeneration) prevents an unmounted grid's callbacks from overwriting its replacement; a beforeunload guard warns while unsaved order exists.
  • UI: ReorderStatusIndicator (Unsaved order / Saving order… / Order saved / Order changed elsewhere → Refresh / Could not save order → Retry) rendered above the Browse grid; useTileOrdering React binding via useSyncExternalStore.
  • Grid: optional tileOrdering prop — coordinator mode applies drags locally and reports refs; legacy persistence untouched when absent (Manage Categories stays legacy until Migrate Manage Categories to the shared ordering workflow and complete end-to-end verification #982). No collision-detection changes.
  • Telemetry: emits queued/coalesced/submitted/committed/conflicted/failed per the Add reorder operation correlation, timing, and diagnostic telemetry #977 contract.
  • Docs: frontend coordinator section added to docs/tile-ordering.md.

Testing

  • npm test: 88 files, 1358 passed (3 expected fail).
  • New tests: tests/tileOrdering.test.ts (14 coordinator tests incl. queue-during-save, coalescing, unmount/remount survival, generation fencing, 409 and 400 conflict paths, seeding failure telemetry, 20 rapid reorders), tests/components/SortableTileGridCoordinator.test.tsx (4), tests/components/ReorderStatusIndicator.test.tsx (7).
  • npm run lint, npm run build, prettier clean.

Needs human verification

Link to Devin session: https://app.devin.ai/sessions/414754bd88374dc693f47100ac269e78

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration
devin-ai-integration Bot requested a review from kphunter as a code owner July 28, 2026 22:12
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 7 potential issues.

Open in Devin Review

Comment thread frontend/src/tileOrdering.ts
Comment thread frontend/src/components/ReorderStatusIndicator.tsx
Comment thread frontend/src/useTileOrdering.ts
Comment thread frontend/src/components/SortableTileGrid.tsx
Comment thread frontend/src/tileOrdering.ts
Comment thread frontend/src/tileOrdering.ts
Comment thread frontend/src/App.tsx Outdated
…rdinator UX

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 new potential issues.

Open in Devin Review

Comment thread frontend/src/tileOrdering.ts
Comment thread frontend/src/tileOrdering.ts
Comment thread frontend/src/components/SortableTileGrid.tsx
…n seeding

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 new potential issues.

Open in Devin Review

Comment thread frontend/src/components/SortableTileGrid.tsx
Comment thread frontend/src/components/SortableTileGrid.tsx
Comment thread frontend/src/tileOrdering.ts
Comment thread frontend/src/tileOrdering.ts
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.

0 participants