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 e826ba921 fix(clients): reset column filters when the nameserver
changes (#4240)
e826ba921 is described below
commit e826ba9219505869f9c2e9fd0367729f18a882a1
Author: 烤化の初雪 <[email protected]>
AuthorDate: Tue Sep 15 21:10:25 2026 +0800
fix(clients): reset column filters when the nameserver changes (#4240)
(cherry picked from commit 64df3418c9a43c38c4d7190cc95d63140a43b831)
Co-authored-by: unbridled-41
<[email protected]>
---
.../pages/cluster/__tests__/ClientsPage.test.tsx | 57 ++++++++++++++++++++++
web/src/pages/cluster/clients.tsx | 7 +++
2 files changed, 64 insertions(+)
diff --git a/web/src/pages/cluster/__tests__/ClientsPage.test.tsx
b/web/src/pages/cluster/__tests__/ClientsPage.test.tsx
index e338a4f14..cfa478a5a 100644
--- a/web/src/pages/cluster/__tests__/ClientsPage.test.tsx
+++ b/web/src/pages/cluster/__tests__/ClientsPage.test.tsx
@@ -470,6 +470,63 @@ describe('Clients page', () => {
expect(csv).toContain('[email protected]:49154');
});
+ it('clears column filters when the nameserver changes', async () => {
+ const createObjectURL = vi.fn((blob: Blob | MediaSource) => {
+ expect(blob).toBeInstanceOf(Blob);
+ return 'blob:nameserver-switch-connections';
+ });
+ Object.defineProperty(URL, 'createObjectURL', {
+ writable: true,
+ value: createObjectURL,
+ });
+ Object.defineProperty(URL, 'revokeObjectURL', {
+ writable: true,
+ value: vi.fn(),
+ });
+ vi.spyOn(HTMLAnchorElement.prototype, 'click').mockImplementation(() =>
{});
+ const user = userEvent.setup();
+ const billingConnections: ClientConnection[] = [
+ {
+ clientId: '[email protected]:49155',
+ type: 'Producer',
+ groupOrTopic: 'billing-producer',
+ protocol: 'gRPC',
+ address: '10.0.3.10:49155',
+ language: 'Java',
+ version: '5.0.7',
+ connectedAt: '2026-07-02 09:00:00',
+ clusterName: 'ns-audit',
+ },
+ ];
+ vi.mocked(connectionsService.listConnections).mockImplementation((query) =>
+ query?.namesrvAddr === 'namesrv-2:9876'
+ ? Promise.resolve(billingConnections)
+ : Promise.resolve(connections),
+ );
+ renderWithProviders(<ClientsPage />);
+
+ await screen.findByText('[email protected]:49152');
+ const filterTriggers =
document.querySelectorAll<HTMLElement>('.ant-table-filter-trigger');
+ await user.click(filterTriggers[1]);
+ const filterDropdown =
document.querySelector<HTMLElement>('.ant-table-filter-dropdown');
+ expect(filterDropdown).not.toBeNull();
+ await user.click(within(filterDropdown!).getByText('Consumer'));
+ await user.click(within(filterDropdown!).getByRole('button', { name: 'OK'
}));
+
expect(screen.queryByText('[email protected]:49152')).not.toBeInTheDocument();
+
+ await user.click(screen.getByRole('combobox', { name: 'NameServer' }));
+ await user.click(
+ await screen.findByText('rocketmq2 (namesrv-2:9876)', {
+ selector: '.ant-select-item-option-content',
+ }),
+ );
+
+ expect(await
screen.findByText('[email protected]:49155')).toBeInTheDocument();
+ await user.click(screen.getByRole('button', { name: '导出' }));
+ const blob = createObjectURL.mock.calls[0][0] as Blob;
+ await
expect(blob.text()).resolves.toContain('[email protected]:49155');
+ });
+
it('renders empty distributions when no connections are available', async ()
=> {
vi.mocked(connectionsService.listConnections).mockResolvedValue([]);
renderWithProviders(<ClientsPage />);
diff --git a/web/src/pages/cluster/clients.tsx
b/web/src/pages/cluster/clients.tsx
index 2e5022976..9ceaebfe6 100644
--- a/web/src/pages/cluster/clients.tsx
+++ b/web/src/pages/cluster/clients.tsx
@@ -191,6 +191,9 @@ const ClientsPage = () => {
setSelectedEndpoint(endpoint);
setConnections([]);
setClusterFilter('ALL');
+ // Column filters describe the previous endpoint's rows; keeping them (or
antd's
+ // uncontrolled internal filter state) would hide every row of the new
endpoint.
+ setColumnFilters({});
setSelectedConnection(null);
setLoadError(null);
setLoading(true);
@@ -383,6 +386,7 @@ const ClientsPage = () => {
filters: clusterOptions
.filter((option) => option.value !== 'ALL')
.map((option) => ({ text: option.label, value: option.value })),
+ filteredValue: columnFilters.clusterName ?? null,
onFilter: (value, record) => record.clusterName === value,
render: (name: string) => <Text style={{ fontSize: 14 }}>{name}</Text>,
},
@@ -415,6 +419,7 @@ const ClientsPage = () => {
{ text: 'Producer', value: 'Producer' },
{ text: 'Consumer', value: 'Consumer' },
],
+ filteredValue: columnFilters.type ?? null,
onFilter: (value, record) => record.type === value,
render: (type: string) => {
const cfg = typeConfig[type] ?? { label: type };
@@ -442,6 +447,7 @@ const ClientsPage = () => {
{ text: 'gRPC', value: 'gRPC' },
{ text: 'Remoting', value: 'Remoting' },
],
+ filteredValue: columnFilters.protocol ?? null,
onFilter: (value, record) => record.protocol === value,
render: (protocol: string) => {
const cfg = protocolConfig[protocol] ?? { color: 'default', label:
protocol };
@@ -466,6 +472,7 @@ const ClientsPage = () => {
text: config.label,
value,
})),
+ filteredValue: columnFilters.language ?? null,
onFilter: (value, record) => record.language === value,
render: (lang: string) => {
const cfg = languageConfig[lang] ?? { color: 'default', label: lang };