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 00c5ce1b6 fix(ops): keep the unsaved NameServer selection when the 
display language changes (#4818)
00c5ce1b6 is described below

commit 00c5ce1b6cd0b08eb625e15270f7225eb71ec1d0
Author: Apulupie <[email protected]>
AuthorDate: Thu Oct 1 17:24:45 2026 +0800

    fix(ops): keep the unsaved NameServer selection when the display language 
changes (#4818)
    
    Co-authored-by: Frun1na <[email protected]>
---
 web/src/pages/studio/Ops.tsx                |  7 ++++-
 web/src/pages/studio/__tests__/Ops.test.tsx | 47 +++++++++++++++++++++++++++--
 2 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/web/src/pages/studio/Ops.tsx b/web/src/pages/studio/Ops.tsx
index 667877554..5d84e12dc 100644
--- a/web/src/pages/studio/Ops.tsx
+++ b/web/src/pages/studio/Ops.tsx
@@ -82,7 +82,12 @@ const OpsPage: React.FC = () => {
           setNamesrvAddrList(data.namesvrAddrList);
           setUseVIPChannel(data.useVIPChannel);
           setUseTLS(data.useTLS);
-          setSelectedNamesrv(data.currentNamesrv);
+          // The effect re-runs when the display language changes (it feeds a 
localized error
+          // message); an unsaved selection that is still in the freshly 
loaded list must survive
+          // that re-run instead of snapping back to the stored current 
NameServer.
+          setSelectedNamesrv((current) =>
+            current && data.namesvrAddrList.includes(current) ? current : 
data.currentNamesrv,
+          );
           setCurrentNamesrv(data.currentNamesrv);
           setConfigurationAvailable(data.configurationAvailable);
           setUnavailableReason(data.unavailableReason || '');
diff --git a/web/src/pages/studio/__tests__/Ops.test.tsx 
b/web/src/pages/studio/__tests__/Ops.test.tsx
index a6efa1cfd..c0a11e2df 100644
--- a/web/src/pages/studio/__tests__/Ops.test.tsx
+++ b/web/src/pages/studio/__tests__/Ops.test.tsx
@@ -17,14 +17,28 @@
 
 import type { ReactElement } from 'react';
 import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
-import { fireEvent, render, screen, waitFor } from '@testing-library/react';
+import { act, fireEvent, render, screen, waitFor } from 
'@testing-library/react';
 import userEvent from '@testing-library/user-event';
 import { App } from 'antd';
-import { LangProvider } from '../../../i18n/LangContext';
+import { LangProvider, useLang } from '../../../i18n/LangContext';
 import OpsPage from '../Ops';
-import { addNameSvrAddr, deleteNameSvrAddr, queryOpsHomePage, 
updateIsVIPChannel } from '../../../api/ops';
+import {
+  addNameSvrAddr,
+  deleteNameSvrAddr,
+  queryOpsHomePage,
+  updateIsVIPChannel,
+} from '../../../api/ops';
 import useAuthStore from '../../../stores/authStore';
 
+const LanguageSwitch = () => {
+  const { setLang } = useLang();
+  return (
+    <button type="button" onClick={() => setLang('en')}>
+      switch-language
+    </button>
+  );
+};
+
 vi.mock('../../../api/ops', () => ({
   addNameSvrAddr: vi.fn(),
   deleteNameSvrAddr: vi.fn(),
@@ -85,6 +99,33 @@ describe('OpsPage', () => {
     expect(screen.getAllByRole('switch')[1]).not.toBeChecked();
   });
 
+  it('keeps the unsaved NameServer selection when the display language 
changes', async () => {
+    const user = userEvent.setup();
+    renderWithProviders(
+      <>
+        <LanguageSwitch />
+        <OpsPage />
+      </>,
+    );
+
+    expect(await screen.findByText('127.0.0.1:9876')).toBeInTheDocument();
+    await user.click(screen.getByRole('combobox'));
+    await user.click(
+      await screen.findByText('127.0.0.2:9876', { selector: 
'.ant-select-item-option-content' }),
+    );
+
+    await user.click(screen.getByRole('button', { name: 'switch-language' }));
+    // Let every effect triggered by the language change settle before 
asserting.
+    await act(async () => {
+      await Promise.resolve();
+    });
+
+    // The selection the user made but did not save must survive the refetch.
+    expect(
+      await screen.findByText('127.0.0.2:9876', { selector: 
'.ant-select-selection-item' }),
+    ).toBeInTheDocument();
+  }, 20_000);
+
   it('prevents overlapping NameServer mutations', async () => {
     vi.mocked(addNameSvrAddr).mockImplementation(() => new Promise(() => {}));
     renderWithProviders(<OpsPage />);

Reply via email to