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/09/15 13:10:31 UTC
(rocketmq-dashboard) branch rocketmq-studio updated: fix(clients): reset column filters when the nameserver changes (#4240)
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: 烤化の初雪 <ya...@outlook.com>
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 <17...@users.noreply.github.com>
---
.../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('audit-svc-0@10.0.2.10: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: 'billing-svc-0@10.0.3.10: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('order-svc-0@10.0.1.12: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('order-svc-0@10.0.1.12: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('billing-svc-0@10.0.3.10:49155')).toBeInTheDocument();
+ await user.click(screen.getByRole('button', { name: '导出' }));
+ const blob = createObjectURL.mock.calls[0][0] as Blob;
+ await expect(blob.text()).resolves.toContain('billing-svc-0@10.0.3.10: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 };