You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by li...@apache.org on 2026/10/19 11:56:13 UTC
(rocketmq-dashboard) branch rocketmq-studio updated: fix(dlq): scope the group search to the selected instance (#4577)
This is an automated email from the ASF dual-hosted git repository.
lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git
The following commit(s) were added to refs/heads/rocketmq-studio by this push:
new c702d3010 fix(dlq): scope the group search to the selected instance (#4577)
c702d3010 is described below
commit c702d301056c8aa3718a6f463fa43dcd416fd5a0
Author: Apulupie <16...@users.noreply.github.com>
AuthorDate: Mon Oct 19 19:56:07 2026 +0800
fix(dlq): scope the group search to the selected instance (#4577)
Verified against `rocketmq-studio` at 674e7017d before merging: the defect is still present on the
current trunk and the change merges cleanly.
Maintainer follow-ups on top of the contributor commit:
- fix(dlq): clear the search term only when the instance actually changes
Each follow-up commit message records the review finding it addresses.
Locally verified: targeted suites green on the integration branch; a full backend and frontend
build plus test pass runs on the trunk once this batch lands.
---
web/src/pages/instance/__tests__/DLQPage.test.tsx | 57 +++++++++++++++++++++++
web/src/pages/instance/dlq.tsx | 12 +++++
2 files changed, 69 insertions(+)
diff --git a/web/src/pages/instance/__tests__/DLQPage.test.tsx b/web/src/pages/instance/__tests__/DLQPage.test.tsx
index 71001b301..6b068a5ed 100644
--- a/web/src/pages/instance/__tests__/DLQPage.test.tsx
+++ b/web/src/pages/instance/__tests__/DLQPage.test.tsx
@@ -1097,6 +1097,63 @@ describe('DLQ page', () => {
expect(messageService.listDLQGroups).toHaveBeenCalledTimes(2);
});
+ it('clears the search term when the selected instance changes', async () => {
+ const user = userEvent.setup();
+ renderWithProviders(<DLQPage />);
+
+ await screen.findByText('cg-order');
+ const searchInput = screen.getByPlaceholderText('搜索 Group 名称或 DLQ Topic');
+ await user.type(searchInput, 'ord');
+ await waitFor(() =>
+ expect(messageService.listDLQGroups).toHaveBeenLastCalledWith('instance-1', 'ord', 1, 20),
+ );
+
+ await user.click(screen.getAllByRole('combobox')[0]);
+ await user.click(
+ await screen.findByText('instance-2', { selector: '.ant-select-item-option-content' }),
+ );
+
+ // The old term is meaningless for the new instance: it must not filter the
+ // next request, and the input has to show the cleared value.
+ await waitFor(() => {
+ expect(messageService.listDLQGroups).toHaveBeenLastCalledWith('instance-2', undefined, 1, 20);
+ });
+ expect(searchInput).toHaveDisplayValue('');
+ });
+
+ it('keeps the search term when a completed retry reloads the same instance', async () => {
+ vi.mocked(messageService.resendDLQ).mockResolvedValue({
+ matched: 1,
+ resent: 1,
+ failed: 0,
+ outcome: 'SUCCESS',
+ });
+ const user = userEvent.setup();
+ renderWithProviders(<DLQPage />);
+
+ await screen.findByText('cg-order');
+ const searchInput = screen.getByPlaceholderText('搜索 Group 名称或 DLQ Topic');
+ await user.type(searchInput, 'ord');
+ await waitFor(() =>
+ expect(messageService.listDLQGroups).toHaveBeenLastCalledWith('instance-1', 'ord', 1, 20),
+ );
+
+ const orderRow = screen.getByText('cg-order').closest('tr');
+ if (!orderRow) throw new Error('DLQ group row not found');
+ await user.click(within(orderRow).getByRole('button', { name: '重投消息' }));
+ await user.type(screen.getByPlaceholderText('输入目标 Topic 名称'), 'orders-retry');
+ await user.click(screen.getByRole('button', { name: '确认重投' }));
+
+ // A finished retry bumps `refreshKey`, which is part of the reset scope key.
+ // That reload still targets the same instance, so the term the user is
+ // working with has to survive both the request and the input.
+ await waitFor(() => expect(messageService.resendDLQ).toHaveBeenCalledTimes(1));
+ await waitFor(() =>
+ expect(messageService.listDLQGroups).toHaveBeenLastCalledWith('instance-1', 'ord', 1, 20),
+ );
+ expect(searchInput).toHaveDisplayValue('ord');
+ });
+
it('ignores a stale group response after changing instances', async () => {
let resolveFirstInstance!: (page: DLQGroupPage) => void;
vi.mocked(messageService.listDLQGroups)
diff --git a/web/src/pages/instance/dlq.tsx b/web/src/pages/instance/dlq.tsx
index a6cb0a8dc..566d2d780 100644
--- a/web/src/pages/instance/dlq.tsx
+++ b/web/src/pages/instance/dlq.tsx
@@ -170,6 +170,18 @@ const DLQPage = () => {
setLoading(true);
}
+ // The search term filters the group list of one instance only, so switching
+ // instances has to drop it — otherwise the first request for the new instance
+ // is filtered by a term that can never match there. Kept separate from the
+ // `scopeKey` block above on purpose: that key also moves when a completed
+ // retry bumps `refreshKey`, and a reload of the same instance must keep the
+ // term the user is still working with.
+ const [prevInstanceId, setPrevInstanceId] = useState(selectedInstanceId);
+ if (prevInstanceId !== selectedInstanceId) {
+ setPrevInstanceId(selectedInstanceId);
+ setSearch('');
+ }
+
useEffect(() => {
const requestId = ++groupRequestIdRef.current;