Skip to content

[WIP] Add internationalization support for detail page related lists#969

Merged
hotlong merged 5 commits intomainfrom
copilot/add-internationalization-support
Mar 2, 2026
Merged

[WIP] Add internationalization support for detail page related lists#969
hotlong merged 5 commits intomainfrom
copilot/add-internationalization-support

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 2, 2026

  • Analyze codebase structure, i18n patterns, and detail plugin components
  • Add detail.* translation keys to all 11 locale files (en, zh, ar, de, es, fr, ja, ko, pt, ru)
  • Create shared useDetailTranslation.ts with createSafeTranslationHook utility and DETAIL_DEFAULT_TRANSLATIONS
  • Apply i18n to DetailView hardcoded strings (Back, Edit, Share, Delete, Duplicate, Export, View history, Record not found, Related, etc.)
  • Apply i18n to DetailSection copy tooltip strings
  • Apply i18n to RelatedList hardcoded strings (record count, "No related records found", "Loading...")
  • Improve empty value display in DetailSection (replace - with styled em-dash placeholder)
  • Add "View All" and "New" button props to RelatedList component
  • Add tests for RelatedList new features (10 tests) and DetailView i18n fallback (2 tests)
  • Update tests to match new empty value styling
  • Extract shared translation hook utility per code review feedback
  • Update ROADMAP.md with P1.15 section
  • Run code review
  • Run CodeQL security check
Original prompt

This section details on the original issue you should resolve

<issue_title>提升详情页/相关表与对象字段国际化支持(参考Salesforce相关列表模式)</issue_title>
<issue_description>【背景与问题梳理】

当前ObjectUI的详情页(record detail page)存在如下待优化关键点:

  1. 无相关表(Related List)自动展示
    • 详情页未像Salesforce一样,自动根据对象模型在详情页底部或相关选项卡内展示所有"子表"数据(如订单→订单明细、联系人→相关订单等)。
    • 现有RelatedList组件与schema协议已支持,但console端未动态生成related列表,也无批量发现主从关系和字段配置逻辑。
  2. 缺失相关表增删改查与"View All"等操作
    • 相关表section缺乏"新建"、"批量操作","查看更多"等按钮与功能。
    • 当前无法对相关记录进行直接编辑或删除。
  3. 页面布��与用户体验改进
    • Salesforce采用"详细信息/相关/活动"Tab,减少页面拥挤,并提升查找效率。
    • 目前仅平铺详情与活动,缺乏可收起的分组、tab分区、数据高亮、批量导航等增强功能。
  4. 对象与字段多语言国际化未生效
    • 目前即使已配置多语言(如中/英),但对象、字段label和Tab名称未根据用户locale自动切换。
    • 详情字段、相关表列标题、按钮等key UI元素国际化不统一。
  5. 空值与日期等UI一致性优化
    • 空值显示"-"不够优雅,建议用占位符或淡化。
    • 日期始终用中文显示,需根据locale适配标准格式。
  6. 表头高亮区未开发
    • Salesforce有"高亮显示区",可快速展示关键字段。

【分项开发清单 & 建议方案】


1. 详情页相关表(Related List)自动发现与渲染

  • 在RecordDetailView中扫描对象模型,自动根据"引用"字段(master_detail/lookup/reference_to等)生成schema.related参数列表。
  • 默认按标准对象惯例(如订单页面自动出现"订单明细"、"发票"、"发货"等子列表)。
  • 支持columns/relationshipField/title等自动推断,允许手动覆盖。

2. 相关表子区块增强(参考Salesforce Dynamic Related List)

  • 相关表列表顶部支持"新建"、"批量操作"、"View All"等按钮。
  • 行内"编辑"、"���除"快捷操作。
  • 支持分页、排序、条件过滤、批量选择。
  • 支持Tab模式(详情/相关/活动)切换,相关表可收起分组显示。

3. 页面布局增强

  • 引入Tab布局(详情/相关/活动),提升信息层级与可用性。
  • 支持section可收起,分组字段配置。
  • 顶部高亮区View,显示核心主字段。

4. 对象、字段及相关表国际化

  • schema label、section title、tab名、字段名、按钮等UI文本统一适配locale。
  • DataSource和对象模型支持多语言,自动切换展示label。

5. 空值与日期处理

  • 统一空值展示(如Placeholder或淡化色),屏蔽掉无意义的"-"。
  • 日期显示根据用户语言区域自动格式化。

【附:参考资料】


请以此为工作拆解主线任务,并由此协调PR分解、进度追踪、ROADMAP及自动化测试,涉及跨repo子系统(如DataSource、国际化对象方案)请同步拆解 cross-repo issue。


联系人详情页截图 订单详情页截图

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectui Ready Ready Preview, Comment Mar 2, 2026 11:28am
objectui-demo Error Error Mar 2, 2026 11:28am
objectui-storybook Canceled Canceled Mar 2, 2026 11:28am

Request Review

Copilot AI and others added 4 commits March 2, 2026 08:35
…onents

- Add detail.* translation keys to en.ts and zh.ts locale files
- Add useDetailTranslation() hook following existing grid/list patterns
- Replace all hardcoded strings in DetailView with t() calls
- Replace all hardcoded strings in RelatedList with t() calls
- Add useSectionTranslation() for DetailSection copy tooltips
- Improve empty value display: replace plain '-' with styled em-dash
- Add 'detail' to BUILTIN_KEYS in useObjectLabel.ts
- Add onNew/onViewAll props and buttons to RelatedList
- Update tests to expect new empty value styling

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Add the detail section with translations for ar, de, es, fr, ja, ko, pt, and ru
locale files, placed before the chart section to match the existing en/zh pattern.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…sts, update ROADMAP

- Add detail.* keys to ar, de, es, fr, ja, ko, pt, ru locale files
- Add 10 new RelatedList tests (title, counts, buttons)
- Add 2 new DetailView i18n fallback tests
- Update ROADMAP.md with P1.15 Detail Page i18n section

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
- Create useDetailTranslation.ts with shared DETAIL_DEFAULT_TRANSLATIONS
  and createSafeTranslationHook utility
- DetailView, DetailSection, and RelatedList all use the shared hook
- Remove duplicate translation constants and hook implementations
- Export useDetailTranslation, DETAIL_DEFAULT_TRANSLATIONS, and
  createSafeTranslationHook from plugin-detail index

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
@hotlong hotlong marked this pull request as ready for review March 2, 2026 08:53
Copilot AI review requested due to automatic review settings March 2, 2026 08:53
@hotlong hotlong merged commit 409987e into main Mar 2, 2026
1 of 4 checks passed
Copilot stopped work on behalf of hotlong due to an error March 2, 2026 08:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds internationalization (i18n) to the plugin-detail surface (DetailView/DetailSection/RelatedList) using the same “safe translation hook with English fallback” pattern used elsewhere in ObjectUI, and wires a new detail namespace into the i18n package/locales.

Changes:

  • Introduces useDetailTranslation (with default English fallbacks) and applies it across DetailView/DetailSection/RelatedList.
  • Adds detail.* strings to all locale bundles and registers detail as a built-in i18n namespace.
  • Updates tests and ROADMAP to reflect the new i18n behavior and the empty-value placeholder change.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/plugin-detail/src/useDetailTranslation.ts Adds reusable safe translation hook + default English detail.* fallback strings.
packages/plugin-detail/src/index.tsx Exports the new translation utilities from the detail plugin entrypoint.
packages/plugin-detail/src/DetailView.tsx Replaces hardcoded UI strings with t('detail.*') translations.
packages/plugin-detail/src/DetailSection.tsx Updates copy tooltip strings to i18n + changes empty/null display to styled em-dash.
packages/plugin-detail/src/RelatedList.tsx Adds i18n for record counts/loading/empty states + adds optional New/View All header actions.
packages/plugin-detail/src/tests/RelatedList.test.tsx Adds tests for RelatedList title/count/empty state and New/View All buttons.
packages/plugin-detail/src/tests/DetailView.test.tsx Adds tests ensuring i18n fallback text renders without an I18nProvider.
packages/plugin-detail/src/tests/DetailSection.test.tsx Updates assertions to match new empty value placeholder ().
packages/i18n/src/useObjectLabel.ts Registers detail as a built-in namespace key.
packages/i18n/src/locales/en.ts Adds detail namespace English strings.
packages/i18n/src/locales/zh.ts Adds detail namespace Chinese strings.
packages/i18n/src/locales/ar.ts Adds detail namespace Arabic strings.
packages/i18n/src/locales/de.ts Adds detail namespace German strings.
packages/i18n/src/locales/es.ts Adds detail namespace Spanish strings.
packages/i18n/src/locales/fr.ts Adds detail namespace French strings.
packages/i18n/src/locales/ja.ts Adds detail namespace Japanese strings.
packages/i18n/src/locales/ko.ts Adds detail namespace Korean strings.
packages/i18n/src/locales/pt.ts Adds detail namespace Portuguese strings.
packages/i18n/src/locales/ru.ts Adds detail namespace Russian strings.
ROADMAP.md Adds a P1.15 roadmap section describing the detail page i18n work.


const displayValue = (() => {
if (value === null || value === undefined) return '-';
if (value === null || value === undefined) return <span className="text-muted-foreground/50 text-xs italic">—</span>;
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The empty-value placeholder is hardcoded as an em-dash, but there is also a detail.emptyValue translation key in the new translation set that is currently unused. Either use t('detail.emptyValue') here to keep all UI text consistently driven by i18n, or remove the unused key from the defaults/locales to avoid dead translations.

Suggested change
if (value === null || value === undefined) return <span className="text-muted-foreground/50 text-xs italic"></span>;
if (value === null || value === undefined) return <span className="text-muted-foreground/50 text-xs italic">{t('detail.emptyValue')}</span>;

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +28
const result = useObjectTranslation();
const testValue = result.t(testKey);
if (testValue === testKey) {
return {
t: (key: string, options?: Record<string, unknown>) => {
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createSafeTranslationHook repeats the same fallback translator implementation in multiple branches. Extracting a small helper (like createFallbackTranslator in packages/plugin-designer/src/hooks/useDesignerTranslation.ts) would reduce duplication and make future changes less error-prone.

Copilot uses AI. Check for mistakes.
- [x] Add `detail.*` translation keys to all 11 locale files (en, zh, ja, de, fr, es, ar, ru, pt, ko)
- [x] `useDetailTranslation` safe wrapper hook with English fallback (follows existing useGridTranslation/useListViewTranslation pattern)
- [x] DetailView fully i18n-integrated (Back, Edit, Share, Delete, Duplicate, Export, View history, Record not found, Related heading, favorites, navigation)
- [x] DetailSection copy tooltip i18n via `useSectionTranslation`
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ROADMAP.md references useSectionTranslation for DetailSection tooltip i18n, but the implementation uses useDetailTranslation and there is no useSectionTranslation in the repo. Please update this line to match the actual hook name to avoid misleading documentation.

Suggested change
- [x] DetailSection copy tooltip i18n via `useSectionTranslation`
- [x] DetailSection copy tooltip i18n via `useDetailTranslation`

Copilot uses AI. Check for mistakes.
Comment on lines 203 to 205
const handleDelete = React.useCallback(() => {
const confirmMessage = schema.deleteConfirmation || 'Are you sure you want to delete this record?';
const confirmMessage = schema.deleteConfirmation || t('detail.deleteConfirmation');
// Use window.confirm as fallback — the ActionProvider's onConfirm handler
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleDelete now calls t('detail.deleteConfirmation'), but the useCallback dependency array for this handler does not include t. This can cause stale translations if the locale changes without unmounting. Add t to the dependency list (or compute the message outside the callback and depend on that).

Copilot uses AI. Check for mistakes.
Comment on lines 218 to 221
if (navigator.share && schema.objectName && schema.resourceId) {
navigator.share({
title: schema.title || 'Record Details',
title: schema.title || t('detail.details'),
text: `${schema.objectName} #${schema.resourceId}`,
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleShare uses t('detail.details') for the share title fallback, but the useCallback dependency array for this handler does not include t. Include t in the dependencies to avoid holding onto a stale translation function when locale changes.

Copilot uses AI. Check for mistakes.
Comment on lines 46 to 47

React.useEffect(() => {
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

relatedData is initialized from the data prop but never re-synced when data changes (and the fetch effect only runs when api && !data.length). If the parent updates data after first render, the list will keep showing stale rows. Consider syncing relatedData from data in an effect (or store only fetched data in state and render data directly when provided).

Suggested change
React.useEffect(() => {
// Keep relatedData in sync with external data prop updates
React.useEffect(() => {
setRelatedData(data);
}, [data]);
React.useEffect(() => {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

提升详情页/相关表与对象字段国际化支持(参考Salesforce相关列表模式)

3 participants