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 4323fcabb fix(producer): keep the picked scope when the display
language changes (#4890)
4323fcabb is described below
commit 4323fcabb678139cb8d2ea9840fc59efbe3cbda7
Author: 烤化の初雪 <[email protected]>
AuthorDate: Thu Oct 1 17:25:24 2026 +0800
fix(producer): keep the picked scope when the display language changes
(#4890)
The topic-list effect in `Producer.tsx` depends on `fetchTopicFailedMessage`
(`t('producer.fetchTopicFailed')`), a value of the current language, and
its body
started with an unconditional
`form.setFieldsValue({ selectedTopic: undefined, producerGroup: undefined
})`.
Switching the display language therefore re-ran the effect and cleared the
topic
and producer-group the operator had just picked, leaving the page unable to
query until both were selected again — the third occurrence of this pattern,
after `BrokerCluster` (#4590) and `Ops` (#4818).
The reset now happens only for the instance it was written for. A ref
records the
instance the form was cleared for, so the instance transition (initial
auto-selection or a manual switch) still clears the scope, while the extra
effect
run that a language change causes leaves the selection untouched. The topic
list
itself is still reloaded, so the localized error message keeps following the
language.
Co-authored-by: unbridled-41
<[email protected]>
---
web/src/pages/studio/Producer.tsx | 11 ++++-
web/src/pages/studio/__tests__/Producer.test.tsx | 51 +++++++++++++++++++++++-
2 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/web/src/pages/studio/Producer.tsx
b/web/src/pages/studio/Producer.tsx
index dc85973ce..6177d120c 100644
--- a/web/src/pages/studio/Producer.tsx
+++ b/web/src/pages/studio/Producer.tsx
@@ -94,6 +94,8 @@ const ProducerPage = () => {
const producerGroupRequestIdRef = useRef(0);
const selectedTopic = Form.useWatch('selectedTopic', form);
+ // Instance whose scope the form was last cleared for; see the topic-list
effect below.
+ const lastResetInstanceRef = useRef<string | undefined>(undefined);
useEffect(() => {
let cancelled = false;
@@ -150,7 +152,14 @@ const ProducerPage = () => {
};
}
- form.setFieldsValue({ selectedTopic: undefined, producerGroup: undefined
});
+ // The topic list belongs to the instance, so the picked topic and
producer group are
+ // dropped when the instance changes. The effect also re-runs when the
display
+ // language changes (it feeds a localized error message), and clearing the
form there
+ // too silently discarded the scope the operator had just selected.
+ if (lastResetInstanceRef.current !== selectedInstanceId) {
+ lastResetInstanceRef.current = selectedInstanceId;
+ form.setFieldsValue({ selectedTopic: undefined, producerGroup: undefined
});
+ }
void fetchTopicList(selectedInstanceId)
.then((topics) => {
diff --git a/web/src/pages/studio/__tests__/Producer.test.tsx
b/web/src/pages/studio/__tests__/Producer.test.tsx
index b54ddb2cf..b4b33736d 100644
--- a/web/src/pages/studio/__tests__/Producer.test.tsx
+++ b/web/src/pages/studio/__tests__/Producer.test.tsx
@@ -19,7 +19,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect,
it, vi } from 'vite
import { fireEvent, render, screen, waitFor, within } 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 ProducerPage from '../Producer';
import {
type ProducerConnection,
@@ -64,6 +64,15 @@ const renderWithProviders = (ui: React.ReactElement) => {
);
};
+const LanguageSwitch = () => {
+ const { setLang } = useLang();
+ return (
+ <button type="button" onClick={() => setLang('en')}>
+ switch-language
+ </button>
+ );
+};
+
const producerResult = (connectionSet: ProducerConnection[]):
ProducerConnectionResult => ({
connectionSet,
complete: true,
@@ -638,4 +647,44 @@ describe('ProducerPage', () => {
expect(fetchProducerGroups).not.toHaveBeenCalled();
});
+
+ it('keeps the picked topic and producer group when the display language
changes', async () => {
+ const user = userEvent.setup();
+ render(
+ <App>
+ <LangProvider>
+ <LanguageSwitch />
+ <ProducerPage />
+ </LangProvider>
+ </App>,
+ );
+
+ await waitFor(() => expect(fetchTopicList).toHaveBeenCalledTimes(1));
+ const [, topicSelect, groupInput] = screen.getAllByRole('combobox');
+ fireEvent.mouseDown(topicSelect.parentElement!);
+ await user.click(
+ await screen.findByText('order-events', { selector:
'.ant-select-item-option-content' }),
+ );
+ await user.type(groupInput, 'order-producer');
+
+ // The topic-list effect re-runs on a language change (it feeds a
localized error
+ // message) and it used to clear both inputs on every run, so picking a
language
+ // silently discarded the operator's query scope.
+ await user.click(screen.getByRole('button', { name: 'switch-language' }));
+
+ expect(
+ screen.getByText('order-events', { selector:
'.ant-select-selection-item' }),
+ ).toBeInTheDocument();
+ expect(screen.getAllByRole('combobox')[2]).toHaveValue('order-producer');
+
+ // The preserved scope is still the one the query runs with.
+ await user.click(screen.getByRole('button', { name: /Search/ }));
+ await waitFor(() => {
+ expect(queryProducerConnection).toHaveBeenCalledWith(
+ 'instance-1',
+ 'order-events',
+ 'order-producer',
+ );
+ });
+ });
});