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 ddd6c5af [ISSUE #1597] Scope Dashboard data to the selected instance
(#1602)
ddd6c5af is described below
commit ddd6c5af342ad5d52b314c66afd3c20e165fcad7
Author: youngkermit8-coder <[email protected]>
AuthorDate: Tue Aug 11 20:29:31 2026 +0800
[ISSUE #1597] Scope Dashboard data to the selected instance (#1602)
Signed-off-by: youngkermit8-coder <[email protected]>
---
web/src/pages/home/__tests__/DashboardPage.test.tsx | 19 +++++++++++++++++++
web/src/pages/home/dashboard.tsx | 11 ++++++++---
2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/web/src/pages/home/__tests__/DashboardPage.test.tsx
b/web/src/pages/home/__tests__/DashboardPage.test.tsx
index 85e847d2..37942ba3 100644
--- a/web/src/pages/home/__tests__/DashboardPage.test.tsx
+++ b/web/src/pages/home/__tests__/DashboardPage.test.tsx
@@ -119,6 +119,25 @@ beforeEach(() => {
});
describe('DashboardPage', () => {
+ it('does not show dashboard data from the previous instance while loading a
new selection', async () => {
+ const instanceA = deferred<DashboardData>();
+ vi.mocked(dashboardService.getDashboard)
+ .mockResolvedValueOnce(dashboard('initial-cluster'))
+ .mockReturnValueOnce(instanceA.promise);
+ const user = userEvent.setup();
+ renderWithProviders(<DashboardPage />);
+
+ await screen.findByText('initial-cluster');
+ const selector = screen.getByRole('combobox', { name: 'Dashboard instance'
});
+ await user.click(selector);
+ await user.click(await screen.findByText('Instance A', { selector:
'.ant-select-item-option-content' }));
+ await waitFor(() =>
expect(dashboardService.getDashboard).toHaveBeenCalledWith('instance-a'));
+
+ expect(screen.queryByText('initial-cluster')).not.toBeInTheDocument();
+ instanceA.resolve(dashboard('instance-a-cluster'));
+ await screen.findByText('instance-a-cluster');
+ });
+
it('does not let a stale instance response overwrite the latest selection',
async () => {
const instanceA = deferred<DashboardData>();
const instanceB = deferred<DashboardData>();
diff --git a/web/src/pages/home/dashboard.tsx b/web/src/pages/home/dashboard.tsx
index 4affb23f..bb172e16 100644
--- a/web/src/pages/home/dashboard.tsx
+++ b/web/src/pages/home/dashboard.tsx
@@ -33,6 +33,7 @@ const DashboardPage = () => {
const navigate = useNavigate();
const { t } = useLang();
const [dashboard, setDashboard] = useState<DashboardData | null>(null);
+ const [dashboardInstanceId, setDashboardInstanceId] = useState<string>();
const [instances, setInstances] = useState<Instance[]>([]);
const [selectedInstanceId, setSelectedInstanceId] = useState<string>();
const [loading, setLoading] = useState(true);
@@ -50,6 +51,7 @@ const DashboardPage = () => {
const nextDashboard = await getDashboard(selectedInstanceId);
if (requestId === dashboardRequestIdRef.current) {
setDashboard(nextDashboard);
+ setDashboardInstanceId(selectedInstanceId);
}
} catch {
if (requestId === dashboardRequestIdRef.current) {
@@ -80,6 +82,9 @@ const DashboardPage = () => {
void Promise.resolve().then(loadDashboard);
}, [loadDashboard]);
+ const visibleDashboard =
+ dashboardInstanceId === selectedInstanceId ? dashboard : null;
+
const dashboardHeader = (
<PageHeader
title={t('dashboard.title')}
@@ -103,7 +108,7 @@ const DashboardPage = () => {
/>
);
- if (loading && !dashboard) {
+ if (loading && !visibleDashboard) {
return (
<div style={{ padding: 24 }}>
{dashboardHeader}
@@ -112,7 +117,7 @@ const DashboardPage = () => {
);
}
- if (loadError || !dashboard) {
+ if (loadError || !visibleDashboard) {
return (
<div style={{ padding: 24 }}>
{dashboardHeader}
@@ -131,7 +136,7 @@ const DashboardPage = () => {
);
}
- const { stats, clusters } = dashboard;
+ const { stats, clusters } = visibleDashboard;
const statCards = [
{