Skip to content

feat(i18n): add missing translations for plugin-detail, plugin-view, plugin-map, plugin-workflow#1128

Merged
hotlong merged 15 commits intomainfrom
copilot/fix-missing-internationalization
Mar 26, 2026
Merged

feat(i18n): add missing translations for plugin-detail, plugin-view, plugin-map, plugin-workflow#1128
hotlong merged 15 commits intomainfrom
copilot/fix-missing-internationalization

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 25, 2026

Comprehensive i18n audit across all packages. Added missing translation keys and wired up components in plugin-detail.

Locale files (all 10 languages: en, zh, ja, ko, de, fr, es, pt, ru, ar)

  • New view namespace (14 keys) — ViewTabBar: rename, duplicate, share, pin, delete, save-as-view
  • New map namespace (5 keys) — ObjectMap: search, location details, coordinate warnings
  • New workflow namespace (59 keys) — WorkflowDesigner/FlowDesigner: node types, statuses, properties, concurrency policies, BPMN tools
  • Extended detail namespace (55+ keys) — comments, attachments, diff viewer, discussion panel, rich text toolbar, subscription toggle, record navigation, activity timeline, threaded replies

Component updates (plugin-detail)

All 9 sub-components now use useDetailTranslation() instead of hardcoded English strings:

  • RecordComments, CommentAttachment, DiffView, RecordChatterPanel
  • RichTextCommentInput, SubscriptionToggle, RecordNavigationEnhanced
  • RecordActivityTimeline, ThreadedReplies
// Before
<CardTitle>Comments</CardTitle>
<input placeholder="Search comments…" />

// After
const { t } = useDetailTranslation();
<CardTitle>{t('detail.comments')}</CardTitle>
<input placeholder={t('detail.searchComments')} />

Not yet completed

Translation keys are defined in all locale files but components not yet wired up for:

  • plugin-view/ViewTabBar.tsx
  • plugin-map/ObjectMap.tsx
  • plugin-workflow/WorkflowDesigner.tsx, FlowDesigner.tsx

These need safe translation hooks created (following the createSafeTranslationHook pattern from plugin-detail) and string replacements in the components.

Original prompt

排查所有的代码软件包组件,修正遗漏的国际化部分


✨ 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 25, 2026

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

Project Deployment Actions Updated (UTC)
objectui-demo Ready Ready Preview, Comment Mar 26, 2026 3:28am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Mar 26, 2026 3:28am
objectui-storybook Ignored Ignored Mar 26, 2026 3:28am

Request Review

Copilot AI and others added 10 commits March 25, 2026 13:07
…tail enhancements

Add new translation keys to the English locale file:
- detail: comments, attachments, diff, discussion, rich text editor,
  subscription, navigation, activity timeline, and replies
- view: new namespace for view management actions
- map: new namespace for map/location features
- workflow: new namespace for workflow builder UI

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ail keys

Add new translation keys to zh.ts matching the recently added en.ts keys:
- detail: comments, attachments, diff, discussion, rich editor, subscriptions,
  navigation, activity timeline, and reply translations
- view: view management actions (rename, duplicate, share, pin, etc.)
- map: location search, markers, and coordinate validation messages
- workflow: full workflow designer translations (nodes, events, BPMN, etc.)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nd workflow namespaces

Add all new translation keys from en.ts to ja.ts:
- detail section: activity, editRow, deleteRow, comments, attachments,
  diff, discussion, rich text editor, subscription, navigation,
  activity timeline, and reply keys
- view namespace: rename, duplicate, share, pin, delete, add views
- map namespace: search locations, markers, invalid coordinates
- workflow namespace: status labels, node types, connections, BPMN tools

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…il keys

Add missing translation keys to ko.ts to match en.ts:
- detail section: comments, attachments, diff, discussion, rich text editor,
  subscription, navigation, and activity timeline keys
- view namespace: view management actions (rename, duplicate, share, pin, etc.)
- map namespace: location search, markers, and coordinate validation
- workflow namespace: workflow states, node types, connections, and actions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…il keys

Add missing German translation keys to de.ts matching en.ts structure:
- detail: comments, attachments, diff, discussion, rich text editor,
  subscription, navigation, activity timeline, and replies sections
- view: rename, duplicate, share, pin/unpin, delete, and filter/sort labels
- map: search, location details, markers, and invalid coordinates messages
- workflow: status labels, node types, properties, connections, concurrency
  modes, event types, and editor actions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…il keys

Add French translations matching the new keys in en.ts:
- detail: comments, attachments, diff, discussion, rich text editor,
  subscription, navigation, activity timeline, and reply keys
- view: rename, duplicate, share, pin/unpin, delete, save as view
- map: search locations, location details, markers, invalid coordinates
- workflow: full workflow editor translations (nodes, events, BPMN, etc.)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…low keys

Add Spanish (es) translations matching new keys in en.ts:
- detail: comments, attachments, diff, discussion, rich text, navigation, activity timeline, replies
- view: rename, duplicate, share, pin, delete, save as view, filters/sort
- map: search locations, markers, invalid coordinates
- workflow: statuses, node types, concurrency, events, BPMN import/export

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rkflow namespaces

Add new translation keys to pt.ts matching the en.ts structure:
- detail: comments, attachments, diff, discussion, rich text editor,
  subscription, navigation, activity timeline, and replies
- view: rename, duplicate, share, pin/unpin, delete, and filter controls
- map: search locations, markers, and invalid coordinates messages
- workflow: statuses, node types, connections, concurrency modes,
  events, and BPMN import/export

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…low keys

Add Russian translations matching the new keys added to en.ts:
- detail: comments, attachments, diff, discussion, rich text editor,
  subscription, navigation, activity timeline, and replies
- view: rename, duplicate, share, pin, delete, and filter labels
- map: search, location details, markers, and coordinate warnings
- workflow: statuses, node types, gateway types, events, BPMN actions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ow namespaces

Add Arabic (ar) translations for:
- detail: comments, activity feed, diff viewer, navigation, and toolbar keys
- view: view management actions (rename, duplicate, share, pin, delete)
- map: location search, markers, and coordinate validation messages
- workflow: workflow designer nodes, properties, concurrency, and BPMN tools

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI and others added 3 commits March 25, 2026 13:37
Add all new i18n keys from en.ts to the detail plugin's fallback
translations, covering: comments, attachments, diff, discussion,
rich text editor, subscription, navigation, activity timeline,
and replies sections.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…w with i18n translation calls

- Import useDetailTranslation hook
- Replace 'Unified diff', 'Side-by-side diff', 'No changes', 'Previous', 'Current' with t() calls

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Updated 6 components to use useDetailTranslation hook:
- RecordChatterPanel: discussion labels
- RichTextCommentInput: toolbar tooltips, placeholder
- SubscriptionToggle: subscribe/unsubscribe tooltips
- RecordNavigationEnhanced: nav titles, position indicator, search
- RecordActivityTimeline: filter options, placeholders, labels
- ThreadedReplies: reply count, placeholder

FILTER_OPTIONS converted to getFilterOptions(t) function for i18n.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix missing internationalization in code packages feat(i18n): add missing translations for plugin-detail, plugin-view, plugin-map, plugin-workflow Mar 25, 2026
Copilot AI requested a review from hotlong March 25, 2026 13:43
@hotlong hotlong marked this pull request as ready for review March 25, 2026 13:44
Copilot AI review requested due to automatic review settings March 25, 2026 13:44
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

This PR expands the built-in locale packs with missing detail, plus new view, map, and workflow namespaces, and starts wiring @object-ui/plugin-detail components to use useDetailTranslation() instead of hardcoded UI strings.

Changes:

  • Added many new translation keys across all built-in locales (10 languages), including new view, map, and workflow namespaces and an expanded detail namespace.
  • Updated multiple plugin-detail subcomponents to use useDetailTranslation() for visible labels/tooltips/placeholders.
  • Refactored RecordActivityTimeline filter labels to be generated from t(...).

Reviewed changes

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

Show a summary per file
File Description
packages/plugin-detail/src/useDetailTranslation.ts Adds many new fallback English detail.* keys used by updated components.
packages/plugin-detail/src/ThreadedReplies.tsx Localizes reply count label and reply input placeholder.
packages/plugin-detail/src/SubscriptionToggle.tsx Localizes tooltip title (but leaves aria-label hardcoded).
packages/plugin-detail/src/RichTextCommentInput.tsx Localizes toolbar titles and placeholder fallback (with a minor placeholder API behavior change).
packages/plugin-detail/src/RecordNavigationEnhanced.tsx Localizes navigation tooltips/titles and record position string.
packages/plugin-detail/src/RecordComments.tsx Localizes headings/placeholders/labels for comments UI (aria-labels still hardcoded).
packages/plugin-detail/src/RecordChatterPanel.tsx Localizes “Discussion” header and collapsed button label (aria-labels still hardcoded).
packages/plugin-detail/src/RecordActivityTimeline.tsx Localizes title, filter option labels, placeholders, and “Load more” label (some aria-labels still hardcoded).
packages/plugin-detail/src/DiffView.tsx Localizes diff mode titles and “No changes”/version headers.
packages/plugin-detail/src/CommentAttachment.tsx Localizes dropzone text, attachment count, and remove tooltip.
packages/i18n/src/locales/en.ts Adds view, map, workflow namespaces and extends detail.
packages/i18n/src/locales/zh.ts Adds view, map, workflow namespaces and extends detail.
packages/i18n/src/locales/ja.ts Adds view, map, workflow namespaces and extends detail.
packages/i18n/src/locales/ko.ts Adds view, map, workflow namespaces and extends detail.
packages/i18n/src/locales/de.ts Adds view, map, workflow namespaces and extends detail.
packages/i18n/src/locales/fr.ts Adds view, map, workflow namespaces and extends detail.
packages/i18n/src/locales/es.ts Adds view, map, workflow namespaces and extends detail.
packages/i18n/src/locales/pt.ts Adds view, map, workflow namespaces and extends detail.
packages/i18n/src/locales/ru.ts Adds view, map, workflow namespaces and extends detail.
packages/i18n/src/locales/ar.ts Adds view, map, workflow namespaces and extends detail.
Comments suppressed due to low confidence (2)

packages/plugin-detail/src/RecordComments.tsx:127

  • The search input/clear button aria-label values are still hardcoded ("Search comments", "Clear search"). Since this PR is wiring translations, these labels should also come from t(...) so assistive tech matches the active locale.
              <input
                className="w-full rounded-md border border-input bg-background pl-8 pr-8 py-1.5 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
                placeholder={t('detail.searchComments')}
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                aria-label="Search comments"
              />
              {searchQuery && (
                <button
                  className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
                  onClick={() => setSearchQuery('')}
                  aria-label="Clear search"
                  type="button"

packages/plugin-detail/src/RecordChatterPanel.tsx:186

  • The collapse button uses a hardcoded aria-label ("Hide discussion"). Please translate this to match the active locale (likely reuse detail.hideDiscussion).
              <Button
                variant="ghost"
                size="icon"
                className="h-7 w-7"
                onClick={() => setCollapsed(true)}
                aria-label="Hide discussion"
              >
                <PanelRightClose className="h-3.5 w-3.5" />

@@ -201,7 +203,7 @@ export const RecordComments: React.FC<RecordCommentsProps> = ({
aria-label={comment.pinned ? 'Unpin comment' : 'Pin comment'}
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

The pin/unpin action aria-label is still hardcoded ("Pin comment"/"Unpin comment"). Please translate it (can reuse detail.pin/detail.unpin, or add dedicated aria-label keys if you want different wording).

Suggested change
aria-label={comment.pinned ? 'Unpin comment' : 'Pin comment'}
aria-label={comment.pinned ? t('detail.unpin') : t('detail.pin')}

Copilot uses AI. Check for mistakes.
ref={textareaRef}
className="w-full min-h-[80px] px-3 py-2 text-sm bg-transparent resize-none focus:outline-none placeholder:text-muted-foreground"
placeholder={placeholder}
placeholder={placeholder || t('detail.writeComment')}
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

placeholder={placeholder || t('detail.writeComment')} treats an intentionally empty string placeholder as falsy and forces the default translation. If consumers pass placeholder="" to suppress placeholder text, this becomes impossible. Consider using nullish coalescing (placeholder ?? ...) and keeping the prop default as undefined to preserve the distinction.

Suggested change
placeholder={placeholder || t('detail.writeComment')}
placeholder={placeholder ?? t('detail.writeComment')}

Copilot uses AI. Check for mistakes.
@@ -48,7 +50,7 @@ export const SubscriptionToggle: React.FC<SubscriptionToggleProps> = ({
onClick={handleToggle}
disabled={isLoading || !onToggle}
aria-label={subscription.subscribed ? 'Unsubscribe from notifications' : 'Subscribe to notifications'}
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

The button aria-label is still hardcoded in English while the title is now translated. For screen reader users in non-English locales, this should be localized too (either reuse the tooltip keys or add dedicated detail.subscribeAriaLabel / detail.unsubscribeAriaLabel keys).

Suggested change
aria-label={subscription.subscribed ? 'Unsubscribe from notifications' : 'Subscribe to notifications'}
aria-label={
subscription.subscribed
? t('detail.unsubscribeAriaLabel')
: t('detail.subscribeAriaLabel')
}

Copilot uses AI. Check for mistakes.
@@ -164,15 +166,15 @@ export const RecordChatterPanel: React.FC<RecordChatterPanelProps> = ({
aria-label="Show discussion"
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

The collapsed-state toggle still uses a hardcoded aria-label ("Show discussion"). Since detail.showDiscussion was added, consider localizing the aria-label too (either reuse that key or add a dedicated one).

Suggested change
aria-label="Show discussion"
aria-label={t('detail.showDiscussion', { count: items.length })}

Copilot uses AI. Check for mistakes.
@@ -254,7 +258,7 @@ export const RecordActivityTimeline: React.FC<RecordActivityTimelineProps> = ({
onChange={(e) => handleFilterChange(e.target.value as FeedFilterMode)}
aria-label="Filter activity"
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

The filter <select> has a hardcoded aria-label ("Filter activity"). To keep accessibility text localized, this should use t(...) (you may need a new detail.filterActivity key if none exists).

Suggested change
aria-label="Filter activity"
aria-label={t('detail.filterActivity')}

Copilot uses AI. Check for mistakes.
@@ -254,7 +258,7 @@ export const RecordActivityTimeline: React.FC<RecordActivityTimelineProps> = ({
onChange={(e) => handleFilterChange(e.target.value as FeedFilterMode)}
aria-label="Filter activity"
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

This <select> still has a hardcoded aria-label ("Filter activity"). To keep accessibility text localized, consider switching it to t(...) (you may need to add a new detail.filterActivity key).

Suggested change
aria-label="Filter activity"
aria-label={t('detail.filterActivity')}

Copilot uses AI. Check for mistakes.
Comment on lines 272 to 276
<div className="flex gap-2">
<textarea
className="flex-1 min-h-[60px] rounded-md border border-input bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring resize-none"
placeholder="Leave a comment… (Ctrl+Enter to submit)"
placeholder={t('detail.leaveCommentPlaceholder')}
value={commentText}
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

In this comment-input section, the textarea placeholder is now localized, but the adjacent submit button further down still uses a hardcoded aria-label ("Submit comment"). Please localize that aria-label as well to match the active locale.

Copilot uses AI. Check for mistakes.
Comment on lines 423 to 427
) : (
<ChevronDown className="h-4 w-4 mr-1" />
)}
Load more
{t('detail.loadMore')}
</Button>
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

This "Load more" UI is now localized via t('detail.loadMore'), but the same button still has a hardcoded aria-label ("Load more activity") a few lines above. Please translate the aria-label too (reuse detail.loadMore or add a dedicated key).

Copilot uses AI. Check for mistakes.
@hotlong
Copy link
Copy Markdown
Contributor

hotlong commented Mar 26, 2026

@copilot fix all

…ail components

- RecordComments: localize search/clear/pin aria-labels
- RichTextCommentInput: use nullish coalescing (??) for placeholder
- SubscriptionToggle: localize aria-label with dedicated keys
- RecordChatterPanel: localize open/close/show/hide aria-labels
- RecordActivityTimeline: localize filter/submit/loadMore aria-labels
- Add 6 new aria-label i18n keys to all 10 locale files
- Update tests to match new translated aria-label values

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Agent-Logs-Url: https://github.com/objectstack-ai/objectui/sessions/c53af9f6-b108-4fe1-97eb-b61b5d987c77
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 26, 2026

@copilot fix all

Fixed all 8 review comments in fb69626:

  1. RecordComments.tsx — pin/unpin aria-label now uses t('detail.unpin')/t('detail.pin'); search and clear button aria-labels also localized
  2. RichTextCommentInput.tsx — switched || to ?? for placeholder so placeholder="" is respected
  3. SubscriptionToggle.tsxaria-label now uses dedicated t('detail.unsubscribeAriaLabel')/t('detail.subscribeAriaLabel') keys
  4. RecordChatterPanel.tsx — all 4 aria-labels (open/close/show/hide discussion) now use t()
  5. RecordActivityTimeline.tsxFilter activity select, Submit comment button, and Load more button aria-labels all localized via t()
  6. Added 6 new i18n keys (filterActivity, openDiscussion, closeDiscussion, subscribeAriaLabel, unsubscribeAriaLabel, clearSearch) to all 10 locale files
  7. All 333 tests pass

Now continuing with the remaining plugin wiring (ViewTabBar, ObjectMap, WorkflowDesigner, FlowDesigner).

@hotlong hotlong merged commit 6968ac6 into main Mar 26, 2026
4 checks passed
Copilot stopped work on behalf of hotlong due to an error March 26, 2026 03:30
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.

3 participants