Skip to content

Refuse a sort whose range reaches a live block (#235) - #238

Merged
SuruchBoss merged 2 commits into
mainfrom
claude/new-session-m6mehm
Oct 5, 2026
Merged

SuruchBoss merged 2 commits into
mainfrom
claude/new-session-m6mehm

Conversation

@SuruchBoss

Copy link
Copy Markdown
Owner

What this changes

Closes #235. Next in the sprint-final queue: #219 → #59.

The bug: a sort whose range covered a live block moved the block's rows along with everything else and was announced as done. The next refresh wrote the block back in the source's order, while the columns the person had typed beside it stayed sorted. Notes ended up on another product's row, with no message.

The fix:

  • sortSelection runs the check [area:live-data] Pasting over a live-data cell is accepted and announced, then the next refresh wipes it without a word #232 added, refusedWrite, over the detected sort range before anything moves. If the range reaches a live cell, nothing is sorted. The same note goes under the cursor's cell and names the live cells, for example "A2:G6 is live data, so nothing was changed — press "Remove" first to edit it yourself". The sort is not announced.
  • Every way into a sort goes through it: the toolbar's ascending and descending buttons, and the "sort anyway" button of the risky-sort dialog.
  • A range that does not reach the block sorts as before. For example, a multi-row selection inside the person's own columns, or a table on rows the block does not occupy.

Reproduced on main first

Steps, from the issue:

  1. Use the sample live source at A1:G6.
  2. Type notes in H2:H6.
  3. Sort from D2 (the issue sorts descending; the e2e flow sorts ascending, with the same result).
main this PR
Right after the sort rows move, "sorted column D" announced nothing moves, the note under D2 names A2:G6
After the next refresh (e2e run) all 5 notes on another product's row every note on its own product

How it was verified

Gate Result
lint · check:readme · check:screens pass
check:deps every advisory fixed or accounted for
test 2021 passed (2010 by the README's static count)
check:mutants 32/32 killed
build · check:bundle 3804/4200 KB, largest chunk 934/1300 KB
check:a11y 121 checks passed
check:e2e 60 flows passed
  • New e2e flow "sorting next to a live block is refused whole and said, and every note stays on its product ([area:live-data] Sorting a range that includes a live block: the next refresh puts the live columns back, and the columns typed beside them end up on the wrong rows #235)". It runs on a production build. It places the sample source through the real form, types a note per row in H, sorts from D2 with the toolbar button, and waits past the 5-second refresh. With main's sheetStore.ts, 4 of its 5 checks fail: there is no note, "sorted" is announced, the rows move, and after the refresh all 5 notes are on another product.

  • store/liveSortRefused.test.ts (new, 3):

    • a sort from a live column, with a refresh afterwards;
    • a sort from the person's own column beside the block;
    • a range that does not reach the block still sorting.

    The first two fail on main's store.

  • READMEs and AGENTS.md, both languages:

    • a live-data bullet for the sort;
    • the e2e flow count 59 → 60 and its list;
    • the new test row.
  • Recounted: 2010 tests in 145 files. Picture 27 retaken in both languages and checked by eye, blessed after the retake. Social card rebuilt and checked by eye.

For PO

  • Templates were already refused. A sort on a template sheet is refused by the existing structure check with its browser alert, before this check runs, so I left that path as it is. Moving it to the note would be a small follow-up if you want it consistent with Refuse a paste, fill, cut or delete that reaches live data, and say so (#232) #234.
  • The detected range spans whole rows. A single-cell sort grows across every column of the contiguous rows, as before. So a table typed beside a live block, on the same rows, is refused from a single cell too, because sorting it would carry the block's rows with it. Selecting just the table's own columns sorts it.

The branch

This is the session's branch claude/new-session-m6mehm. The work was written on a local branch on top of #51 (a314bbd), with main b8837a9 (#236) merged in.

🤖 Generated with Claude Code

https://claude.ai/code/session_013pmWZsbmugfpqtYazrzfjj


Generated by Claude Code

claude added 2 commits October 5, 2026 03:38
A sort that covered a live block moved its rows and said it was done; the
next refresh wrote the block back in the source's order while the columns
typed beside it stayed sorted, so notes landed on other products' rows
without a word. sortSelection now runs the same refusedWrite check #232
added, over the detected sort range, before anything moves: the sort is
refused whole and the note under the cursor names the live cells. A range
that does not reach the block sorts as before.

Adds store/liveSortRefused.test.ts (3, two red on the old store) and an
e2e flow that sorts next to the sample live source and waits out a
refresh (4 checks red on the old store). Recounted to 2010 tests; picture
27 retaken in both languages and the social card rebuilt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013pmWZsbmugfpqtYazrzfjj
@vercel

vercel Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
excel-to-go Ready Ready Preview Oct 5, 2026 3:55am UTC

@SuruchBoss
SuruchBoss merged commit 03b2ac2 into main Oct 5, 2026
18 checks passed

Copy link
Copy Markdown
Owner Author

PO review — merged at 5f12e3a (main 03b2ac2).

Verify (local, full): green — 2021 tests, mutants 32/32, a11y 121, e2e 60. CI 17/17 green on the same head.

Tried as a user on a production build, the exact repro from #235 (live sales block A1:G6, notes typed in H2:H6, D2 selected, "เรียงจากมากไปน้อย"):

  • Nothing moves; the note under D2 reads "A2:G6 เป็นข้อมูลสด จึงไม่ได้เปลี่ยนอะไร — กด "เอาออก" ก่อนถ้าจะแก้เอง" and is announced once.
  • After the next refresh every note is still on its own product (0 mismatched; it was 2 on main).
  • A sort on A11:A13, below the block, still sorts (3,1,2 → 1,2,3) and leaves the block alone.
  • No page errors, no alerts. Screenshot checked by eye.

Hold set left: #219 → #59.


Generated by Claude Code

This branch was successfully deployed

1 active deployment
Preview — 5f12e3a5 Deployed Oct 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants