unbridled-41 opened a new pull request, #5070:
URL: https://github.com/apache/rocketmq-dashboard/pull/5070

   ## Problem
   
   The AI history modal (会话历史) keeps its ticked rows when the operator changes 
the page, the search or the active/archived scope, so the batch delete acts on 
conversations that are no longer on screen.
   
   `ConversationListPanel` owns `selectedRowKeys` 
(`ConversationListModal.tsx:170`) and only ever prunes the keys whose delete 
failed (`:224`). Nothing clears them on a scope change, and the toolbar's 
destructive button is rendered on the selection alone (`:427`), confirming with 
`remove(selectedRowKeys.map(Number))` (`:434`) — while antd renders the 
checkbox column for the rows it is given (`rowSelection={{ selectedRowKeys, 
onChange: setSelectedRowKeys }}`, `:483`).
   
   Concretely: tick row A on page 1, click page 2. Page 2 shows nothing ticked, 
but the toolbar still reads `删除 (1)`; confirming it issues `DELETE 
/api/ai/conversations/{A}` for a row on another page. The delete is a hard 
delete — it stops any active run, clears three tables and unlinks the agent 
workspace.
   
   The component's own comment two lines above that button states the property 
the code was breaking: "the checkbox column antd renders selects the current 
page only — so the two never disagree about what 'all' means" (`:424-426`).
   
   ## Evidence
   
   Pre-fix, on base `a562601d`, with the three new tests in place and only 
`ConversationListModal.tsx` at its base revision:
   
   ```
   $ cd web && npx vitest run 
src/pages/ai/components/__tests__/ConversationListModal.test.tsx
    × dropsTheSelectionWhenThePageChangesTest
    × dropsTheSelectionWhenTheSearchChangesTest
    × dropsTheSelectionWhenTheScopeChangesTest
    Test Files  1 failed (1)
         Tests  3 failed | 19 passed (22)
   
   FAIL  … > dropsTheSelectionWhenThePageChangesTest
   Error: expect(element).not.toBeInTheDocument()
   expected document not to contain element, found <button
     class="ant-btn … ant-btn-dangerous …"
     data-testid="ai-conversation-selected-delete"
     type="button"><span>删除 (1)
   ```
   
   Reachability is a plain user path on `/ai` → 历史: tick a row, page (or type a 
search, or switch to 已归档), press the red button.
   
   ## Root cause
   
   The selection survived a change of query identity. The panel clears it after 
a delete and for the conversation it knows left the list, but the three 
handlers that move the window — `onSearch` (`:411`), the scope 
`Segmented.onChange` (`:416`) and the pager's `onChange: list.setPage` (`:491`) 
— did not.
   
   ## Fix
   
   One `clearSelection` callback, called from those three handlers, mirroring 
the merged fix for the same defect class on the topic and consumer group lists 
(commit `1172d859`, "#4473 clear hidden resource selections", issue #4465). The 
hook's setters are untouched: the selection is the modal's state, so the modal 
is where the scope change is observable.
   
   ## Score
   
   `PRIORITY = 72` (impact 30: a hard delete of conversations the operator 
cannot see, irreversible and stopping a running agent run; scope 12: one page's 
modal, but every user of the AI console; reproducibility 18: the three tests 
decide it deterministically; maintenance value 12: the same defect class was 
already fixed twice in this repository, and the file's own comment pins the 
invariant).
   `FIX_CONFIDENCE = 88`.
   
   ## Tests
   
   ```
   $ cd web && npx vitest run 
src/pages/ai/components/__tests__/ConversationListModal.test.tsx   # post-fix
    ✓ src/pages/ai/components/__tests__/ConversationListModal.test.tsx (22 
tests)
    Test Files  1 passed (1)
         Tests  22 passed (22)
   
   $ cd web && npx tsc --noEmit -p tsconfig.json      # no output, exit 0
   $ cd web && npx eslint src/pages/ai/components/ConversationListModal.tsx \
         src/pages/ai/components/__tests__/ConversationListModal.test.tsx       
   # exit 0
   ```
   
   The pre-fix run of the same file (only the production file reverted to 
`a562601d`, tests kept) is the failure quoted under Evidence. Each of the three 
tests asserts both that the toolbar button is gone and that the new page's row 
checkbox is unticked, so the fix is covered for all three setters rather than 
for one representative.
   
   ## Risk
   
   Low. The only behaviour change is that a selection does not survive a window 
change, which is what the button's own copy ("删除本页全部 N 条会话?" / "删除 (N)") 
already implies. The after-delete pruning is untouched, so the "keeps the rows 
whose delete failed selected" behaviour still holds (its test passes 
unchanged). No API, hook or payload change.
   
   ## Dedup
   
   - `gh search issues --repo apache/rocketmq-dashboard "clear hidden resource 
selections"` → #4465 (closed, Topic/Consumer), #2427/#2428 (closed, instance 
list); `gh search prs` → #4473/#2433 (merged, 
`pages/instance/{topic,consumer}.tsx` only), #4471 (closed).
   - `gh search prs "conversation list selection"`, `"delete selected 
conversations"` → no results.
   - `grep -F ConversationListModal /tmp/open_pr_files.txt 
/tmp/frun1na_files.txt /tmp/my_open_pr_files.txt` (the file lists of all 231 
open PRs) → no match.
   - `git log --oneline a562601d -- 
web/src/pages/ai/components/ConversationListModal.tsx` → `1ef5d860` (console 
polish) and `5b761df8` (introduction); neither touches the selection.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to