diff --git a/frontend/taskdeck-web/src/locales/en/inbox.ts b/frontend/taskdeck-web/src/locales/en/inbox.ts index 4d8d4e170..e4dbdb58c 100644 --- a/frontend/taskdeck-web/src/locales/en/inbox.ts +++ b/frontend/taskdeck-web/src/locales/en/inbox.ts @@ -148,6 +148,12 @@ export default { // name are for. `bodyPlaceholder` is a sentence and is capitalized; // `labelsPlaceholder` is a fragment continuing the box and is not. composer: { + eyebrow: 'Capture · Draft', + meta: 'local-only · saves to Inbox', + footerBefore: 'Captures land in ', + footerInbox: 'Inbox', + footerAfter: '. Linking to a board creates a proposal, not a card.', + submit: 'Capture', bodyLabel: 'Body', bodyAria: 'Body: write the text of this capture', bodyPlaceholder: 'The thought, in plain language…', diff --git a/frontend/taskdeck-web/src/locales/es/inbox.ts b/frontend/taskdeck-web/src/locales/es/inbox.ts index 91aff1813..c816bb5e3 100644 --- a/frontend/taskdeck-web/src/locales/es/inbox.ts +++ b/frontend/taskdeck-web/src/locales/es/inbox.ts @@ -106,6 +106,12 @@ export default { // en mayúscula inicial a propósito; `labelsPlaceholder` es un fragmento que // continúa el campo y va en minúscula. composer: { + eyebrow: 'Captura · Borrador', + meta: 'solo local · se guarda en Inbox', + footerBefore: 'Las capturas llegan al ', + footerInbox: 'Inbox', + footerAfter: '. Vincularlas a un tablero crea una propuesta, no una tarjeta.', + submit: 'Capturar', bodyLabel: 'Texto', bodyAria: 'Texto: escribe el contenido de esta captura', bodyPlaceholder: 'La idea, en lenguaje sencillo…', diff --git a/frontend/taskdeck-web/src/locales/it/inbox.ts b/frontend/taskdeck-web/src/locales/it/inbox.ts index d9ab1235b..80723f1ad 100644 --- a/frontend/taskdeck-web/src/locales/it/inbox.ts +++ b/frontend/taskdeck-web/src/locales/it/inbox.ts @@ -104,6 +104,12 @@ export default { // per scelta; `labelsPlaceholder` è un frammento che prosegue il campo e resta // in minuscolo. composer: { + eyebrow: 'Cattura · Bozza', + meta: 'solo locale · salva nell’Inbox', + footerBefore: 'Le catture arrivano nell’', + footerInbox: 'Inbox', + footerAfter: '. Collegarle a una bacheca crea una proposta, non una scheda.', + submit: 'Cattura', bodyLabel: 'Testo', bodyAria: 'Testo: scrivi il contenuto di questa cattura', bodyPlaceholder: 'Il pensiero, in parole semplici…', diff --git a/frontend/taskdeck-web/src/tests/views/paper/inbox/PaperCaptureComposer.spec.ts b/frontend/taskdeck-web/src/tests/views/paper/inbox/PaperCaptureComposer.spec.ts index c9f81e97e..f937637e5 100644 --- a/frontend/taskdeck-web/src/tests/views/paper/inbox/PaperCaptureComposer.spec.ts +++ b/frontend/taskdeck-web/src/tests/views/paper/inbox/PaperCaptureComposer.spec.ts @@ -163,6 +163,53 @@ describe('PaperCaptureComposer', () => { } } + function surfaceCopy(wrapper: ReturnType) { + return { + eyebrow: wrapper.get('.paper-composer__header .tagstamp').text(), + meta: wrapper.get('.paper-composer__meta').text(), + footer: wrapper.get('.paper-composer__footer .tk-meta').text(), + submit: wrapper.get('.paper-composer__footer .phlbtn-label').text(), + } + } + + it.each([ + [ + 'en', + { + eyebrow: 'Capture · Draft', + meta: 'local-only · saves to Inbox', + footer: 'Captures land in Inbox. Linking to a board creates a proposal, not a card.', + submit: 'Capture', + }, + ], + [ + 'it', + { + eyebrow: 'Cattura · Bozza', + meta: 'solo locale · salva nell’Inbox', + footer: 'Le catture arrivano nell’Inbox. Collegarle a una bacheca crea una proposta, non una scheda.', + submit: 'Cattura', + }, + ], + [ + 'es', + { + eyebrow: 'Captura · Borrador', + meta: 'solo local · se guarda en Inbox', + footer: 'Las capturas llegan al Inbox. Vincularlas a un tablero crea una propuesta, no una tarjeta.', + submit: 'Capturar', + }, + ], + ] as const)('renders the composer surface copy in %s', (locale, expected) => { + const previousLocale = i18n.global.locale.value + try { + i18n.global.locale.value = locale as SupportedLocale + expect(surfaceCopy(mount(PaperCaptureComposer))).toEqual(expected) + } finally { + i18n.global.locale.value = previousLocale + } + }) + it('renders the field chrome in English on the default locale', () => { const wrapper = mount(PaperCaptureComposer) const chrome = fieldChrome(wrapper) @@ -279,6 +326,32 @@ describe('PaperCaptureComposer', () => { } }) + it('re-renders the composer surface copy when the locale switches after mount', async () => { + const previousLocale = i18n.global.locale.value + try { + i18n.global.locale.value = 'en' as SupportedLocale + const wrapper = mount(PaperCaptureComposer) + expect(surfaceCopy(wrapper)).toEqual({ + eyebrow: 'Capture · Draft', + meta: 'local-only · saves to Inbox', + footer: 'Captures land in Inbox. Linking to a board creates a proposal, not a card.', + submit: 'Capture', + }) + + i18n.global.locale.value = 'it' as SupportedLocale + await nextTick() + + expect(surfaceCopy(wrapper)).toEqual({ + eyebrow: 'Cattura · Bozza', + meta: 'solo locale · salva nell’Inbox', + footer: 'Le catture arrivano nell’Inbox. Collegarle a una bacheca crea una proposta, non una scheda.', + submit: 'Cattura', + }) + } finally { + i18n.global.locale.value = previousLocale + } + }) + it('reflects label selections in the submit payload', async () => { const wrapper = mount(PaperCaptureComposer) const labelInput = wrapper.find('input[type="text"]') diff --git a/frontend/taskdeck-web/src/views/paper/inbox/PaperCaptureComposer.vue b/frontend/taskdeck-web/src/views/paper/inbox/PaperCaptureComposer.vue index 2c8e113fc..ff65904cc 100644 --- a/frontend/taskdeck-web/src/views/paper/inbox/PaperCaptureComposer.vue +++ b/frontend/taskdeck-web/src/views/paper/inbox/PaperCaptureComposer.vue @@ -229,8 +229,8 @@ defineExpose({ focus: () => bodyRef.value?.focus(), resetDraft, snapshotDraft, r