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 b024e4471 fix(web): localize the shared instance selector placeholder
and empty-list hint (#5403)
b024e4471 is described below
commit b024e4471341c4273cefeda5ab129b1cc4f7809d
Author: Chstercc <[email protected]>
AuthorDate: Fri Oct 9 11:25:24 2026 +0800
fix(web): localize the shared instance selector placeholder and empty-list
hint (#5403)
`InstanceSelect` was the last shared component carrying hard-coded Chinese
literals:
`placeholder = '选择实例'` and `notFoundContent="暂无匹配实例"`. Both now go through
the translation
table (`common.selectInstance` plus the new `instanceSelect.notFound`, zh
and en), and an explicit
`placeholder` prop still wins. Affects the five pages that render this
selector.
---
web/src/components/InstanceSelect.tsx | 6 +--
.../components/__tests__/InstanceSelect.test.tsx | 54 ++++++++++++++++++++++
web/src/i18n/translations.ts | 1 +
3 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/web/src/components/InstanceSelect.tsx
b/web/src/components/InstanceSelect.tsx
index 7fd775b38..b8f4118a4 100644
--- a/web/src/components/InstanceSelect.tsx
+++ b/web/src/components/InstanceSelect.tsx
@@ -44,7 +44,7 @@ export function InstanceSelect({
onChange,
options,
style,
- placeholder = '选择实例',
+ placeholder,
failed,
onRetry,
}: InstanceSelectProps) {
@@ -54,7 +54,7 @@ export function InstanceSelect({
<Select
showSearch
allowClear
- placeholder={placeholder}
+ placeholder={placeholder ?? t('common.selectInstance')}
value={value ?? undefined}
onChange={(next, option) => {
if (next === undefined || next === null) {
@@ -73,7 +73,7 @@ export function InstanceSelect({
.toLowerCase()
.includes(input.toLowerCase())
}
- notFoundContent="暂无匹配实例"
+ notFoundContent={t('instanceSelect.notFound')}
style={style ?? { width: 220 }}
/>
);
diff --git a/web/src/components/__tests__/InstanceSelect.test.tsx
b/web/src/components/__tests__/InstanceSelect.test.tsx
new file mode 100644
index 000000000..73b8baa12
--- /dev/null
+++ b/web/src/components/__tests__/InstanceSelect.test.tsx
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { afterEach, describe, it, expect } from 'vitest';
+import { render, screen, fireEvent } from '@testing-library/react';
+import InstanceSelect from '../InstanceSelect';
+import { LangProvider } from '../../i18n/LangContext';
+import { LANGUAGE_STORAGE_KEY } from '../../i18n/languagePreference';
+
+const renderWithLang = (ui: React.ReactElement) =>
render(<LangProvider>{ui}</LangProvider>);
+
+describe('InstanceSelect', () => {
+ afterEach(() => {
+ localStorage.clear();
+ });
+
+ it('renders the placeholder in Chinese by default', () => {
+ renderWithLang(<InstanceSelect onChange={() => {}} options={[]} />);
+ expect(screen.getByText('选择实例')).toBeInTheDocument();
+ });
+
+ it('renders the placeholder in English when the language is en', () => {
+ localStorage.setItem(LANGUAGE_STORAGE_KEY, 'en');
+ renderWithLang(<InstanceSelect onChange={() => {}} options={[]} />);
+ expect(screen.getByText('Select Instance')).toBeInTheDocument();
+ });
+
+ it('renders the empty-list hint in English when the language is en', async
() => {
+ localStorage.setItem(LANGUAGE_STORAGE_KEY, 'en');
+ renderWithLang(<InstanceSelect onChange={() => {}} options={[]} />);
+ const select = screen.getByRole('combobox');
+ fireEvent.mouseDown(select.parentElement!);
+ expect(await screen.findByText('No matching
instances')).toBeInTheDocument();
+ });
+
+ it('keeps an explicit placeholder when one is provided', () => {
+ renderWithLang(<InstanceSelect onChange={() => {}} options={[]}
placeholder="My instance" />);
+ expect(screen.getByText('My instance')).toBeInTheDocument();
+ });
+});
diff --git a/web/src/i18n/translations.ts b/web/src/i18n/translations.ts
index bcc0edb39..b479e5546 100644
--- a/web/src/i18n/translations.ts
+++ b/web/src/i18n/translations.ts
@@ -3582,6 +3582,7 @@ const translations: Record<string, Record<Lang, string>>
= {
'common.begin': { zh: '开始', en: 'Begin' },
'common.end': { zh: '结束', en: 'End' },
'common.selectInstance': { zh: '选择实例', en: 'Select Instance' },
+ 'instanceSelect.notFound': { zh: '暂无匹配实例', en: 'No matching instances' },
'common.selectProxy': { zh: '选择代理', en: 'Select Proxy' },
'common.enableProxy': { zh: '启用代理', en: 'Enable Proxy' },
'common.proxyDisabled': { zh: '代理禁用', en: 'Proxy Disabled' },