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 d388bc43d fix(metrics): keep the current data source when cancelling 
the auth dialog (#4643)
d388bc43d is described below

commit d388bc43dac1048a1f98f3097d4c777d07dfaeca
Author: Apulupie <[email protected]>
AuthorDate: Mon Sep 21 21:08:25 2026 +0800

    fix(metrics): keep the current data source when cancelling the auth dialog 
(#4643)
    
    `restoreProtectedDataSource` in `MetricsExplorer.tsx` applied the 
data-source switch before the credential dialog was even shown: it nulled 
`dataSourceCredentialsRef.current` and pointed both `dataSourceKeyRef.current` 
— the field queries actually read — and the `dataSourceKey` state at the 
protected source. `handleAuthCancel` only clears the pending-auth refs and the 
form, so cancelling left the explorer on a data source it has no credentials 
for and every later query went to an unau [...]
    
    Those three eager writes are gone; the function now only records 
`pendingAuthReplayRef` and `setPendingDataSource`, and `handleAuthSubmit` 
performs the switch through `activateDataSource`, which was already writing all 
three. That matches how `handleDataSourceChange` behaves when a source needs 
auth, and no effect depends on the range or profile ids, so nothing fires a 
query in between.
    
    Cancelling still leaves the range and profile the history record set, since 
`handleRestoreHistory` writes those before the dialog. That predates this 
change; rolling it back too would mean extending `PendingAuthReplay`.
    
    Fixes #4644
---
 web/src/components/MetricsExplorer.tsx             |  6 +--
 .../components/__tests__/MetricsExplorer.test.tsx  | 43 ++++++++++++++++++++++
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/web/src/components/MetricsExplorer.tsx 
b/web/src/components/MetricsExplorer.tsx
index 0145316ec..4d9761987 100644
--- a/web/src/components/MetricsExplorer.tsx
+++ b/web/src/components/MetricsExplorer.tsx
@@ -1041,10 +1041,10 @@ const MetricsExplorer = ({ instanceId }: 
MetricsExplorerProps) => {
     range: RangeOption,
     customPromqlToRun?: string,
   ) => {
-    dataSourceCredentialsRef.current = null;
-    dataSourceKeyRef.current = dataSource.key;
+    // The data source switch itself is deferred to handleAuthSubmit: the 
current source stays
+    // active while credentials are being asked for, so cancelling the dialog 
leaves the
+    // explorer exactly where it was instead of stranded on an unauthenticated 
source.
     pendingAuthReplayRef.current = { profile, range, customPromql: 
customPromqlToRun };
-    setDataSourceKey(dataSource.key);
     setPendingDataSource(dataSource);
     void message.info(copy.protectedHistory);
   };
diff --git a/web/src/components/__tests__/MetricsExplorer.test.tsx 
b/web/src/components/__tests__/MetricsExplorer.test.tsx
index 374024071..acf5704f9 100644
--- a/web/src/components/__tests__/MetricsExplorer.test.tsx
+++ b/web/src/components/__tests__/MetricsExplorer.test.tsx
@@ -921,6 +921,49 @@ describe('MetricsExplorer', () => {
     expect(screen.getByText('Consumer Lag Messages')).toBeInTheDocument();
   });
 
+  it('keeps the current data source when cancelling a protected history 
restore', async () => {
+    const user = userEvent.setup();
+    vi.mocked(listDataSources).mockResolvedValue([
+      {
+        key: 'ds-basic',
+        name: 'Protected Prometheus',
+        type: 'Prometheus',
+        url: '',
+        auth: 'Basic Auth',
+        status: 'healthy',
+      },
+    ]);
+    localStorage.setItem(
+      METRICS_QUERY_HISTORY_STORAGE_KEY,
+      JSON.stringify([
+        createHistoryEntry({ dataSourceKey: 'ds-basic', dataSourceName: 
'Protected Prometheus' }),
+      ]),
+    );
+
+    renderWithProviders(<MetricsExplorer />);
+
+    await screen.findByRole('img', { name: 'Message In TPS time series' });
+    const sourceSelect = await screen.findByRole('combobox', { name: '数据源' });
+    await user.click(screen.getByRole('button', { name: '查询历史' }));
+
+    const historyDialog = await screen.findByRole('dialog', { name: '指标查询历史' 
});
+    const historyItem = within(historyDialog)
+      .getByText('Consumer Lag Messages')
+      .closest('.ant-list-item');
+    expect(historyItem).not.toBeNull();
+    await user.click(within(historyItem as HTMLElement).getByRole('button', { 
name: '恢复' }));
+
+    // The auth dialog's generated title id collides with the still-closing 
history dialog's
+    // title in jsdom, so the accessible name resolves to the wrong dialog. 
Match on the
+    // unique body text instead.
+    await screen.findByText('凭据仅用于当前数据源,离开该数据源后会被清除。');
+    await user.click(screen.getByRole('button', { name: /取\s*消/ }));
+
+    const selectContainer = sourceSelect.closest('.ant-select') as HTMLElement;
+    expect(within(selectContainer).getByText('默认数据源')).toBeInTheDocument();
+    expect(within(selectContainer).queryByText('Protected 
Prometheus')).not.toBeInTheDocument();
+  });
+
   it('filters query history from other instances and shows the current 
instance context', async () => {
     const user = userEvent.setup();
     localStorage.setItem(

Reply via email to