diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/i18n/domain/VueI18nModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/i18n/domain/VueI18nModuleFactory.java index 0abd0ca91be..6f9ce393389 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/i18n/domain/VueI18nModuleFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/i18n/domain/VueI18nModuleFactory.java @@ -65,7 +65,6 @@ public JHipsterModule buildModule(JHipsterModuleProperties properties) { .and() .in(path("./vitest.config.ts")) .add(lineAfterRegex("test:"), properties.indentation().times(2) + "setupFiles: ['./src/test/setupTests.ts'],") - .add(lineAfterText("'src/main/webapp/app/main.ts',"), properties.indentation().times(4) + "'src/main/webapp/app/Translations.ts',") .and() .and() .build(); diff --git a/src/main/resources/generator/client/common/i18n/Translations.ts b/src/main/resources/generator/client/common/i18n/Translations.ts index e82e63bb19a..72d35ac7e8b 100644 --- a/src/main/resources/generator/client/common/i18n/Translations.ts +++ b/src/main/resources/generator/client/common/i18n/Translations.ts @@ -10,13 +10,13 @@ const toLanguage = ([key, value]: [string, ResourceKey]): [string, ResourceLangu }, ]; -const mergeTranslations = (translations: Translations[]): Translations => +export const mergeTranslations = (translations: Translations[]): Translations => translations .flatMap(translations => Object.entries(translations)) .reduce( (acc, [key, translation]) => ({ ...acc, - [key]: acc[key] ? { ...acc[key], ...translation } : translation, + [key]: acc[key] ? { ...acc[key], ...deepMerge(acc[key], translation) } : translation, }), {} as Translations, ); @@ -31,3 +31,12 @@ export const toTranslationResources = (...translations: Translations[]): Resourc }), {}, ); + +const deepMerge = (target: Translation, source: Translation): Translation => { + for (const key of Object.keys(source)) { + if (source[key] instanceof Object && key in target) { + Object.assign(source[key], deepMerge(target[key] as Translation, source[key] as Translation)); + } + } + return { ...target, ...source }; +}; diff --git a/src/main/resources/generator/client/common/i18n/i18n.spec.ts b/src/main/resources/generator/client/common/i18n/i18n.spec.ts index e032457f928..326c93a9648 100644 --- a/src/main/resources/generator/client/common/i18n/i18n.spec.ts +++ b/src/main/resources/generator/client/common/i18n/i18n.spec.ts @@ -1,4 +1,5 @@ import i18n from '@/i18n'; +import { mergeTranslations } from '@/Translations'; describe('i18n configuration', () => { it('loads en translation', () => { @@ -8,4 +9,37 @@ describe('i18n configuration', () => { it('loads fr translation', () => { expect(i18n.getResourceBundle('fr', '')['home']['translationEnabled']).toEqual('Internationalisation activée'); }); + + describe('mergeTranslations function', () => { + it('merges translations correctly when keys overlap', () => { + const translationSet1 = { + en: { + home: { + translationEnabled: 'Internationalization enabled', + welcome: 'Welcome', + }, + }, + }; + + const translationSet2 = { + en: { + home: { + anotherMessage: 'Another message', + }, + }, + }; + + const mergedResult = mergeTranslations([translationSet1, translationSet2]); + + expect(mergedResult).toEqual({ + en: { + home: { + translationEnabled: 'Internationalization enabled', + welcome: 'Welcome', + anotherMessage: 'Another message', + }, + }, + }); + }); + }); }); diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/i18n/domain/VueI18nModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/vue/i18n/domain/VueI18nModuleFactoryTest.java index 08ee045d4dc..774a3b4baec 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/i18n/domain/VueI18nModuleFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/i18n/domain/VueI18nModuleFactoryTest.java @@ -58,10 +58,7 @@ void shouldBuildI18nModule() { .and() .hasFile("src/main/webapp/app/home/locales/fr.ts") .and() - .hasFile("src/test/webapp/unit/home/infrastructure/primary/HomepageVue.spec.ts") - .and() - .hasFile("vitest.config.ts") - .containing("src/main/webapp/app/Translations.ts"); + .hasFile("src/test/webapp/unit/home/infrastructure/primary/HomepageVue.spec.ts"); } private ModuleFile mainFile() {