From c3458284bcd65c252b6a74fe88ea9795cd36eaa2 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 12:32:38 +0000 Subject: [PATCH 1/2] fix(i18n): the cloud-connection unbound card says its state and what Connect does The "Not connected" card's body opened with the page subtitle's sentence word for word. It now says the runtime is not connected to a control plane and that Connect opens the cloud account to approve the link. All ten packs move; the key name is unchanged. A pin beside the panel holds the en text and that it does not carry the subtitle sentence. Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB --- .changeset/12655-cloud-unbound-copy.md | 7 ++ ...ConnectionPanel.unboundBody-12655.test.tsx | 76 +++++++++++++++++++ packages/i18n/src/locales/ar.ts | 2 +- packages/i18n/src/locales/de.ts | 2 +- packages/i18n/src/locales/en.ts | 2 +- packages/i18n/src/locales/es.ts | 2 +- packages/i18n/src/locales/fr.ts | 2 +- packages/i18n/src/locales/ja.ts | 2 +- packages/i18n/src/locales/ko.ts | 2 +- packages/i18n/src/locales/pt.ts | 2 +- packages/i18n/src/locales/ru.ts | 2 +- packages/i18n/src/locales/zh.ts | 2 +- 12 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 .changeset/12655-cloud-unbound-copy.md create mode 100644 packages/app-shell/src/console/cloud-connection/__tests__/CloudConnectionPanel.unboundBody-12655.test.tsx diff --git a/.changeset/12655-cloud-unbound-copy.md b/.changeset/12655-cloud-unbound-copy.md new file mode 100644 index 0000000000..a5dabfd526 --- /dev/null +++ b/.changeset/12655-cloud-unbound-copy.md @@ -0,0 +1,7 @@ +--- +'@object-ui/i18n': patch +--- + +The cloud-connection panel's "Not connected" card no longer repeats the page subtitle (objectui#12655). + +The card's body (`cloudConnection.unbound.body`) opened with the same sentence as the page header subtitle above it, so an admin read it twice. It now says the state and what the Connect button does: the runtime is not connected to a control plane, and Connect opens the cloud account in a new window, where one click approves the link, with no ids or credentials typed into the page. It names no control plane, because nothing the panel is served says which one Connect binds to. All ten language packs carry the new text in their own language. The key name is unchanged. diff --git a/packages/app-shell/src/console/cloud-connection/__tests__/CloudConnectionPanel.unboundBody-12655.test.tsx b/packages/app-shell/src/console/cloud-connection/__tests__/CloudConnectionPanel.unboundBody-12655.test.tsx new file mode 100644 index 0000000000..10de4175b9 --- /dev/null +++ b/packages/app-shell/src/console/cloud-connection/__tests__/CloudConnectionPanel.unboundBody-12655.test.tsx @@ -0,0 +1,76 @@ +/** + * ObjectUI + * Copyright (c) 2024-present ObjectStack Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * The "Not connected" card says the state and what Connect does; it does not + * repeat the page subtitle (objectui#12655). + * + * The page that hosts this panel already carries a header subtitle, served by + * the cloud-connection plugin's page metadata. The unbound card's body used to + * open with that same sentence word for word, so an admin read it twice. The + * body now says the runtime is not connected and what the Connect button does, + * and names no control plane: nothing the panel is served says which one + * Connect binds to. + */ + +import '@testing-library/jest-dom/vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { cleanup, render, screen } from '@testing-library/react'; +import { I18nProvider } from '@object-ui/i18n'; + +import { CloudConnectionPanel } from '../CloudConnectionPanel'; + +/** The page header subtitle, as the cloud-connection plugin serves it in English. */ +const PAGE_SUBTITLE = + "Connect this runtime to an ObjectStack control plane to browse your organization's private packages and install them here."; + +const UNBOUND_BODY = + 'This runtime is not connected to a control plane. Connect opens your cloud account in a new window, where one click approves the link — no ids or credentials are typed into this page.'; + +const reply = (status: number, body: unknown) => + new Response(JSON.stringify(body), { status, headers: { 'Content-Type': 'application/json' } }); + +beforeEach(() => { + vi.stubGlobal( + 'fetch', + vi.fn(async (input: unknown) => { + const url = String(input); + if (url.endsWith('/status')) { + return reply(200, { success: true, data: { environmentId: null, bound: false, connection: null } }); + } + throw new Error(`unexpected fetch: ${url}`); + }), + ); +}); + +afterEach(() => { + cleanup(); + vi.unstubAllGlobals(); +}); + +describe('CloudConnectionPanel — the unbound body says the state and what Connect does (objectui#12655)', () => { + it('renders the new body under the Not connected title, beside the Connect button', async () => { + render( + + + , + ); + + const title = await screen.findByText('Not connected'); + const card = title.closest('div.rounded-lg') as HTMLElement; + expect(card).not.toBeNull(); + + const body = screen.getByText(UNBOUND_BODY); + expect(card).toContainElement(body); + expect(card).toContainElement(screen.getByRole('button', { name: 'Connect' })); + + const text = body.textContent ?? ''; + expect(text).not.toContain(PAGE_SUBTITLE); + expect(text.startsWith('Connect this runtime')).toBe(false); + }); +}); diff --git a/packages/i18n/src/locales/ar.ts b/packages/i18n/src/locales/ar.ts index 6a4c531b8e..4042ffc94a 100644 --- a/packages/i18n/src/locales/ar.ts +++ b/packages/i18n/src/locales/ar.ts @@ -3757,7 +3757,7 @@ const ar = { }, unbound: { title: "غير متصل", - body: "اربط بيئة التشغيل هذه بمستوى تحكم ObjectStack لتصفّح الحزم الخاصة بمؤسستك وتثبيتها هنا. الموافقة بنقرة واحدة في حسابك السحابي — دون إدخال أي معرّفات أو بيانات اعتماد في هذه الصفحة.", + body: "بيئة التشغيل هذه غير متصلة بأي مستوى تحكم. يفتح «اتصال» حسابك السحابي في نافذة جديدة، حيث تتم الموافقة على الربط بنقرة واحدة — دون إدخال أي معرّفات أو بيانات اعتماد في هذه الصفحة.", connect: "اتصال", }, }, diff --git a/packages/i18n/src/locales/de.ts b/packages/i18n/src/locales/de.ts index 1a090c8d01..a9703fd0a8 100644 --- a/packages/i18n/src/locales/de.ts +++ b/packages/i18n/src/locales/de.ts @@ -3478,7 +3478,7 @@ const de = { }, unbound: { title: "Nicht verbunden", - body: "Verbinden Sie diese Runtime mit einer ObjectStack Control Plane, um die privaten Pakete Ihrer Organisation zu durchsuchen und hier zu installieren. Die Genehmigung erfolgt mit einem einzigen Klick in Ihrem Cloud-Konto — es werden keine IDs oder Zugangsdaten auf dieser Seite eingegeben.", + body: "Diese Runtime ist mit keiner Control Plane verbunden. „Verbinden“ öffnet Ihr Cloud-Konto in einem neuen Fenster, wo ein einziger Klick die Verbindung genehmigt — es werden keine IDs oder Zugangsdaten auf dieser Seite eingegeben.", connect: "Verbinden", }, }, diff --git a/packages/i18n/src/locales/en.ts b/packages/i18n/src/locales/en.ts index 06fabc2b73..28f6d0f842 100644 --- a/packages/i18n/src/locales/en.ts +++ b/packages/i18n/src/locales/en.ts @@ -4151,7 +4151,7 @@ const en = { }, unbound: { title: 'Not connected', - body: 'Connect this runtime to an ObjectStack control plane to browse your organization\'s private packages and install them here. Approval is a single click in your cloud account — no ids or credentials are typed into this page.', + body: 'This runtime is not connected to a control plane. Connect opens your cloud account in a new window, where one click approves the link — no ids or credentials are typed into this page.', connect: 'Connect', }, }, diff --git a/packages/i18n/src/locales/es.ts b/packages/i18n/src/locales/es.ts index 12b6dc4ed3..1d7aa47709 100644 --- a/packages/i18n/src/locales/es.ts +++ b/packages/i18n/src/locales/es.ts @@ -3546,7 +3546,7 @@ const es = { }, unbound: { title: "No conectado", - body: "Conecte este runtime a un plano de control de ObjectStack para explorar los paquetes privados de su organización e instalarlos aquí. La aprobación es un solo clic en su cuenta de la nube: no se escriben identificadores ni credenciales en esta página.", + body: "Este runtime no está conectado a ningún plano de control. «Conectar» abre su cuenta de la nube en una ventana nueva, donde un solo clic aprueba la conexión: no se escriben identificadores ni credenciales en esta página.", connect: "Conectar", }, }, diff --git a/packages/i18n/src/locales/fr.ts b/packages/i18n/src/locales/fr.ts index 24f67b65fe..e46c32d756 100644 --- a/packages/i18n/src/locales/fr.ts +++ b/packages/i18n/src/locales/fr.ts @@ -3543,7 +3543,7 @@ const fr = { }, unbound: { title: "Non connecté", - body: "Connectez ce runtime à un plan de contrôle ObjectStack pour parcourir les paquets privés de votre organisation et les installer ici. L'approbation se fait en un seul clic dans votre compte cloud — aucun identifiant ni justificatif n'est saisi sur cette page.", + body: "Ce runtime n'est connecté à aucun plan de contrôle. « Connecter » ouvre votre compte cloud dans une nouvelle fenêtre, où un seul clic approuve la liaison — aucun identifiant ni justificatif n'est saisi sur cette page.", connect: "Connecter", }, }, diff --git a/packages/i18n/src/locales/ja.ts b/packages/i18n/src/locales/ja.ts index 339ebab3b8..70cf4ca945 100644 --- a/packages/i18n/src/locales/ja.ts +++ b/packages/i18n/src/locales/ja.ts @@ -3480,7 +3480,7 @@ const ja = { }, unbound: { title: "未接続", - body: "このランタイムを ObjectStack コントロールプレーンに接続すると、組織のプライベートパッケージを閲覧してここにインストールできます。承認はクラウドアカウントでワンクリック。ID や認証情報をこのページに入力する必要はありません。", + body: "このランタイムはコントロールプレーンに接続されていません。「接続」を押すと新しいウィンドウでクラウドアカウントが開き、ワンクリックで接続を承認できます。ID や認証情報をこのページに入力する必要はありません。", connect: "接続", }, }, diff --git a/packages/i18n/src/locales/ko.ts b/packages/i18n/src/locales/ko.ts index 2b60fb4ba2..1047df673e 100644 --- a/packages/i18n/src/locales/ko.ts +++ b/packages/i18n/src/locales/ko.ts @@ -3477,7 +3477,7 @@ const ko = { }, unbound: { title: "연결되지 않음", - body: "이 런타임을 ObjectStack 컨트롤 플레인에 연결하면 조직의 비공개 패키지를 탐색하고 여기에 설치할 수 있습니다. 승인은 클라우드 계정에서 한 번만 클릭하면 되며, 이 페이지에 ID나 자격 증명을 입력할 필요가 없습니다.", + body: "이 런타임은 컨트롤 플레인에 연결되어 있지 않습니다. '연결'을 누르면 새 창에서 클라우드 계정이 열리고, 한 번의 클릭으로 연결을 승인할 수 있습니다. 이 페이지에 ID나 자격 증명을 입력할 필요가 없습니다.", connect: "연결", }, }, diff --git a/packages/i18n/src/locales/pt.ts b/packages/i18n/src/locales/pt.ts index fc6db33184..17a1888487 100644 --- a/packages/i18n/src/locales/pt.ts +++ b/packages/i18n/src/locales/pt.ts @@ -3541,7 +3541,7 @@ const pt = { }, unbound: { title: "Não conectado", - body: "Conecte este runtime a um plano de controle do ObjectStack para explorar os pacotes privados da sua organização e instalá-los aqui. A aprovação é um único clique na sua conta da nuvem — nenhum id ou credencial é digitado nesta página.", + body: "Este runtime não está conectado a nenhum plano de controle. “Conectar” abre sua conta da nuvem em uma nova janela, onde um único clique aprova a conexão — nenhum id ou credencial é digitado nesta página.", connect: "Conectar", }, }, diff --git a/packages/i18n/src/locales/ru.ts b/packages/i18n/src/locales/ru.ts index 428dac876f..8d21e26afd 100644 --- a/packages/i18n/src/locales/ru.ts +++ b/packages/i18n/src/locales/ru.ts @@ -3630,7 +3630,7 @@ const ru = { }, unbound: { title: "Не подключено", - body: "Подключите эту среду выполнения к управляющему слою ObjectStack, чтобы просматривать приватные пакеты вашей организации и устанавливать их здесь. Подтверждение — один клик в вашей облачной учётной записи; никакие идентификаторы и учётные данные на этой странице не вводятся.", + body: "Эта среда выполнения не подключена к управляющему слою. «Подключить» открывает вашу облачную учётную запись в новом окне, где подключение подтверждается одним кликом; никакие идентификаторы и учётные данные на этой странице не вводятся.", connect: "Подключить", }, }, diff --git a/packages/i18n/src/locales/zh.ts b/packages/i18n/src/locales/zh.ts index 265aa2a7fe..f980db105b 100644 --- a/packages/i18n/src/locales/zh.ts +++ b/packages/i18n/src/locales/zh.ts @@ -3619,7 +3619,7 @@ const zh = { }, unbound: { title: '未连接', - body: '将此运行时连接到 ObjectStack 控制平面,即可浏览并安装组织的私有包。只需在云账户中点击一次批准——无需在本页面输入任何 ID 或凭据。', + body: '此运行时尚未连接到控制平面。点击「连接」会在新窗口中打开你的云账户,只需点击一次即可批准连接——无需在本页面输入任何 ID 或凭据。', connect: '连接', }, }, From 4ba37c91fbf97ea7a6d5eaad2cd917cca9205df9 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 12:42:49 +0000 Subject: [PATCH 2/2] fix(i18n): de unbound body names the Connect button without a quote pair MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The de pack's quote-pairing pin counts every „…“ pair in the pack; the new body's quoted button name added one. The en body names the button bare, and the de body now does the same. Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB --- packages/i18n/src/locales/de.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/i18n/src/locales/de.ts b/packages/i18n/src/locales/de.ts index a9703fd0a8..837b1fadba 100644 --- a/packages/i18n/src/locales/de.ts +++ b/packages/i18n/src/locales/de.ts @@ -3478,7 +3478,7 @@ const de = { }, unbound: { title: "Nicht verbunden", - body: "Diese Runtime ist mit keiner Control Plane verbunden. „Verbinden“ öffnet Ihr Cloud-Konto in einem neuen Fenster, wo ein einziger Klick die Verbindung genehmigt — es werden keine IDs oder Zugangsdaten auf dieser Seite eingegeben.", + body: "Diese Runtime ist mit keiner Control Plane verbunden. Verbinden öffnet Ihr Cloud-Konto in einem neuen Fenster, wo ein einziger Klick die Verbindung genehmigt — es werden keine IDs oder Zugangsdaten auf dieser Seite eingegeben.", connect: "Verbinden", }, },