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' },

Reply via email to