diff --git a/.changeset/setup-nav-distinct-organization-labels.md b/.changeset/setup-nav-distinct-organization-labels.md new file mode 100644 index 00000000000..f96e187d571 --- /dev/null +++ b/.changeset/setup-nav-distinct-organization-labels.md @@ -0,0 +1,10 @@ +--- +'@objectstack/platform-objects': patch +--- + +fix(platform-objects): Setup → People & Organization no longer shows two identical "组织" / "組織" entries + +Clause-②: no +Metadata-protocol: none + +`nav_organization` (the active organization's record page) and `nav_organizations` (the organization list, shown where `org-scoping` is mounted) both translated to "组织" in zh-CN and "組織" in ja-JP, so a multi-organization deployment showed two identical menu entries that open different pages. They now read "当前组织" / "所有组织" (zh-CN) and "現在の組織" / "すべての組織" (ja-JP). A new test fails when any two entries in one Setup nav group read the same in any shipped locale. diff --git a/packages/platform-objects/src/apps/setup-nav-distinct-labels.test.ts b/packages/platform-objects/src/apps/setup-nav-distinct-labels.test.ts new file mode 100644 index 00000000000..d36c63cd406 --- /dev/null +++ b/packages/platform-objects/src/apps/setup-nav-distinct-labels.test.ts @@ -0,0 +1,43 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. +// +// No two Setup nav entries in one group read the same in any locale. +// +// The defect: People & Organization carries `nav_organization` (the active +// organization's record page) and `nav_organizations` (the organization list, +// shown where `org-scoping` is mounted). English tells them apart by the +// plural; zh-CN and ja-JP have no plural, so both read "组织" / "組織" and a +// multi-organization deployment showed two identical menu entries that open +// different pages. +import { describe, it, expect } from 'vitest'; + +import { SETUP_NAV_CONTRIBUTIONS } from './setup-nav.contributions.js'; +import { en } from './translations/en.js'; +import { zhCN } from './translations/zh-CN.js'; +import { jaJP } from './translations/ja-JP.js'; +import { esES } from './translations/es-ES.js'; + +const LOCALES = { en, 'zh-CN': zhCN, 'ja-JP': jaJP, 'es-ES': esES } as const; + +type NavItem = { id?: string; label?: string }; + +describe('Setup nav labels are distinct within a group', () => { + for (const [locale, bundle] of Object.entries(LOCALES)) { + const navigation = ((bundle as any).apps?.setup?.navigation ?? {}) as Record; + + for (const contribution of SETUP_NAV_CONTRIBUTIONS) { + it(`${locale} · ${contribution.group}`, () => { + const seen = new Map(); + for (const item of (contribution.items ?? []) as NavItem[]) { + if (!item.id) continue; + const label = navigation[item.id]?.label ?? item.label; + if (!label) continue; + expect( + seen.get(label), + `${item.id} and ${seen.get(label)} both read "${label}" in ${locale}`, + ).toBeUndefined(); + seen.set(label, item.id); + } + }); + } + } +}); diff --git a/packages/platform-objects/src/apps/translations/ja-JP.ts b/packages/platform-objects/src/apps/translations/ja-JP.ts index 6177d2c0290..4499fcad817 100644 --- a/packages/platform-objects/src/apps/translations/ja-JP.ts +++ b/packages/platform-objects/src/apps/translations/ja-JP.ts @@ -54,10 +54,10 @@ export const jaJP: TranslationData = { nav_system_overview: { label: 'システム概要' }, nav_users: { label: 'ユーザー' }, - nav_organization: { label: '組織' }, + nav_organization: { label: '現在の組織' }, nav_business_units: { label: 'ビジネスユニット' }, nav_teams: { label: 'チーム' }, - nav_organizations: { label: '組織' }, + nav_organizations: { label: 'すべての組織' }, nav_invitations: { label: '招待' }, nav_positions: { label: 'ポジション' }, diff --git a/packages/platform-objects/src/apps/translations/zh-CN.ts b/packages/platform-objects/src/apps/translations/zh-CN.ts index b1fe4c4f0bc..b891279a68c 100644 --- a/packages/platform-objects/src/apps/translations/zh-CN.ts +++ b/packages/platform-objects/src/apps/translations/zh-CN.ts @@ -57,10 +57,10 @@ export const zhCN: TranslationData = { nav_system_overview: { label: '系统概览' }, nav_users: { label: '用户' }, - nav_organization: { label: '组织' }, + nav_organization: { label: '当前组织' }, nav_business_units: { label: '业务单元' }, nav_teams: { label: '团队' }, - nav_organizations: { label: '组织' }, + nav_organizations: { label: '所有组织' }, nav_invitations: { label: '邀请' }, nav_positions: { label: '岗位' },