tju-yxq opened a new issue, #5409:
URL: https://github.com/apache/rocketmq-dashboard/issues/5409

   ## Problem
   
   The AI conversation history modal's delete tracking breaks the moment two 
deletes overlap. `remove()` records its in-flight ids by **replacing the whole 
`deletingIds` array** (`setDeletingIds(ids)` at entry, `setDeletingIds([])` at 
exit), so a row delete confirmed while a batch delete is still looping:
   
   - instantly wipes the batch rows' spinners and re-enables their delete 
buttons mid-request (`loading={deletingIds.includes(row.id)}` goes false for 
every id the new call did not name), and
   - is itself wiped when the batch's exit runs `setDeletingIds([])`.
   
   Re-clicking a re-enabled batch row re-POSTs `deleteConversation` for a 
conversation the batch has already deleted (or is about to); the duplicate 404 
lands in the batch's `failed` list and the operator is shown a "partial 
failure" warning for conversations that were in fact deleted. The toolbar 
buttons lose their spinner the same way.
   
   ## What did you do (steps to reproduce)?
   
   1. Open the AI conversation history modal with at least three conversations.
   2. Select two rows and confirm 删除所选 — the batch deletes them one request at 
a time.
   3. While the batch is running, confirm a row delete on a third conversation.
   4. The two batch rows' spinners disappear and their delete buttons become 
clickable again; clicking one re-submits a delete for an id the batch already 
owns.
   5. When the batch finishes, its `failed` count includes the duplicate, 
producing a misleading partial-failure toast.
   
   ## What did you expect to see?
   
   Concurrent deletes keep independent spinners, a row whose delete is queued 
is never re-submitted, and each call's toast reports what that call actually 
attempted.
   
   ## What did you see instead?
   
   A single shared array clobbered by whichever remove started last, 
re-enabling in-flight rows and double-POSTing deletes.
   
   ## Root cause
   
   `web/src/pages/ai/components/ConversationListModal.tsx`, `remove` (lines 
210-224):
   
   ```tsx
   setDeletingIds(ids);      // replaces the whole array
   ...
   setDeletingIds([]);       // clears ids another in-flight remove still owns
   ```
   
   The sibling handler in the same file already has the correct pattern — 
`toggleArchive` (lines 185-198) merges with `setArchivingIds((ids) => [...ids, 
id])` and removes only its own id on exit, precisely so concurrent archive 
toggles keep independent spinners.
   
   ## Expected behavior
   
   - `remove` merges its ids into the in-flight set and clears only its own ids 
on exit (the `archivingIds` pattern).
   - Ids already queued by another in-flight remove are skipped, so a repeated 
confirmation never double-POSTs.
   - Row spinners and the toolbar `deleting` state stay accurate across 
overlapping removes.
   - The per-call success/partial-failure toast and the selection cleanup 
reflect the ids that call actually attempted.
   - Single-delete, batch-selected and delete-page flows are otherwise 
unchanged.
   
   ## Acceptance criteria
   
   - [ ] Regression proof: on the current code, a row delete started during a 
batch clears the batch rows' `ant-btn-loading` state; with the fix both stay 
loading.
   - [ ] A conversation whose delete is already queued is never passed to 
`deleteConversation` twice.
   - [ ] Letting all pending deletes finish removes every row exactly once.
   - [ ] All existing modal tests (single delete, selected delete, delete page, 
failed-keep-selected, active-conversation deletion, page-step-back) stay green.
   
   ## Environment
   
   Branch `rocketmq-studio` at `6a68042f`; file: 
`web/src/pages/ai/components/ConversationListModal.tsx`.
   
   ## Duplicate check
   
   Searched open and closed issues for `conversation delete`: #3566 (closed — 
the original "cannot delete individual conversations" feature gap this builds 
on) does not cover the concurrent-state defect. The open Loyal-Young issues 
(#5371 AI key save, #5367 alert delivery retry) are different flows.
   


-- 
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