mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
[ACS-11213] upgrade ngx translate to v17 (#11719)
* [ACS-11213] Upgraded ngx-translate to v17 * [ACS-11213] Fix translations * [ACS-11213] Reverted redundant change * [ACS-11213] Translations fix * [ACS-11213] Fixed unit tests * [ACS-11213] Added unit tests for changes in translate-loader.service * [ACS-11213] Added empty line * [ACS-11213] Addressed copilot comments
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
"@angular/platform-browser": ">=16.0.0",
|
||||
"@angular/router": ">=16.0.0",
|
||||
"@mat-datetimepicker/core": ">=12.0.1",
|
||||
"@ngx-translate/core": ">=16.0.0",
|
||||
"@ngx-translate/core": ">=17.0.0",
|
||||
"@alfresco/js-api": ">=9.3.1",
|
||||
"@alfresco/adf-extensions": ">=8.3.1",
|
||||
"minimatch": ">=10.0.0",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { TranslateLoader, provideTranslateService } from '@ngx-translate/core';
|
||||
import { provideTranslateService, provideTranslateLoader } from '@ngx-translate/core';
|
||||
import { ABOUT_DIRECTIVES } from './about/about.module';
|
||||
import { CARD_VIEW_DIRECTIVES } from './card-view/card-view.module';
|
||||
import { CONTEXT_MENU_DIRECTIVES } from './context-menu/context-menu.module';
|
||||
@@ -38,7 +38,6 @@ import { CORE_DIRECTIVES } from './directives/directive.module';
|
||||
import { CORE_PIPES } from './pipes/pipe.module';
|
||||
import { TranslateLoaderService } from './translation/translate-loader.service';
|
||||
import { SEARCH_TEXT_INPUT_DIRECTIVES } from './search-text/search-text-input.module';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { AppConfigPipe } from './app-config';
|
||||
import { IconComponent } from './icon';
|
||||
import { DynamicChipListComponent } from './dynamic-chip-list';
|
||||
@@ -123,12 +122,8 @@ export class CoreModule {
|
||||
ngModule: CoreModule,
|
||||
providers: [
|
||||
provideTranslateService({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useClass: TranslateLoaderService,
|
||||
deps: [HttpClient]
|
||||
},
|
||||
defaultLanguage: 'en'
|
||||
loader: provideTranslateLoader(TranslateLoaderService),
|
||||
fallbackLang: 'en'
|
||||
}),
|
||||
provideAppConfig()
|
||||
]
|
||||
|
||||
@@ -18,19 +18,20 @@
|
||||
import { EventEmitter, Injectable, NgModule } from '@angular/core';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
import { provideTranslateService, TranslateLoader } from '@ngx-translate/core';
|
||||
import { Language, provideTranslateLoader, provideTranslateService, TranslateLoader, TranslationObject } from '@ngx-translate/core';
|
||||
import { TranslationService } from '../translation/translation.service';
|
||||
import { LangChangeEvent } from '../mock';
|
||||
import { Observable, of } from 'rxjs';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class NoopTranslationService {
|
||||
export class NoopTranslationService implements TranslateLoader {
|
||||
defaultLang: string = 'en';
|
||||
userLang: string;
|
||||
customLoader: any;
|
||||
|
||||
translate: any = {
|
||||
onLangChange: new EventEmitter<LangChangeEvent>()
|
||||
onLangChange: new EventEmitter<LangChangeEvent>(),
|
||||
getCurrentLang: (): Language => 'en'
|
||||
};
|
||||
|
||||
addTranslationFolder() {}
|
||||
@@ -47,6 +48,10 @@ export class NoopTranslationService {
|
||||
instant(key: string | Array<string>): string | any {
|
||||
return key;
|
||||
}
|
||||
|
||||
getTranslation(_lang: string): Observable<TranslationObject> {
|
||||
return of({});
|
||||
}
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
@@ -55,10 +60,7 @@ export class NoopTranslationService {
|
||||
provideHttpClientTesting(),
|
||||
{ provide: TranslationService, useClass: NoopTranslationService },
|
||||
provideTranslateService({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useClass: NoopTranslationService
|
||||
}
|
||||
loader: provideTranslateLoader(NoopTranslationService)
|
||||
})
|
||||
]
|
||||
})
|
||||
|
||||
@@ -40,7 +40,7 @@ describe('provideI18N', () => {
|
||||
|
||||
it('should set default language to "en" when not specified', () => {
|
||||
const translateService = TestBed.inject(TranslateService);
|
||||
expect(translateService.defaultLang).toBe('en');
|
||||
expect(translateService.getFallbackLang()).toBe('en');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('provideI18N', () => {
|
||||
|
||||
it('should set custom default language', () => {
|
||||
const translateService = TestBed.inject(TranslateService);
|
||||
expect(translateService.defaultLang).toBe('fr');
|
||||
expect(translateService.getFallbackLang()).toBe('fr');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -81,7 +81,7 @@ describe('provideI18N', () => {
|
||||
// Services should be properly configured
|
||||
expect(translateService).toBeDefined();
|
||||
expect(translationService).toBeDefined();
|
||||
expect(translateService.defaultLang).toBe('en');
|
||||
expect(translateService.getFallbackLang()).toBe('en');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -153,7 +153,7 @@ describe('provideI18N', () => {
|
||||
|
||||
it('should set translations for custom default language', () => {
|
||||
const translateService = TestBed.inject(TranslateService);
|
||||
expect(translateService.defaultLang).toBe('fr');
|
||||
expect(translateService.getFallbackLang()).toBe('fr');
|
||||
expect(translateService.instant('HELLO')).toBe('Bonjour!');
|
||||
});
|
||||
});
|
||||
@@ -184,7 +184,7 @@ describe('provideI18N', () => {
|
||||
const translateService = TestBed.inject(TranslateService);
|
||||
const loader = translateService.currentLoader as TranslateLoaderService;
|
||||
|
||||
expect(translateService.defaultLang).toBe('en');
|
||||
expect(translateService.getFallbackLang()).toBe('en');
|
||||
expect(loader).toBeDefined();
|
||||
expect(loader.providerRegistered).toBeDefined();
|
||||
expect(loader.providerRegistered('adf-core')).toBeTruthy();
|
||||
@@ -211,7 +211,7 @@ describe('provideI18N', () => {
|
||||
it('should handle empty translations object', () => {
|
||||
const translateService = TestBed.inject(TranslateService);
|
||||
expect(translateService).toBeDefined();
|
||||
expect(translateService.defaultLang).toBe('en');
|
||||
expect(translateService.getFallbackLang()).toBe('en');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
*/
|
||||
|
||||
import { EnvironmentProviders, inject, provideAppInitializer, Provider } from '@angular/core';
|
||||
import { provideTranslateService, TranslateLoader, TranslateService } from '@ngx-translate/core';
|
||||
import { provideTranslateLoader, provideTranslateService, TranslateService } from '@ngx-translate/core';
|
||||
import { TranslateLoaderService } from './translate-loader.service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { provideTranslations } from './translation.service';
|
||||
|
||||
export interface ProvideI18NConfig {
|
||||
@@ -54,12 +53,8 @@ export function provideI18N(config?: ProvideI18NConfig): (Provider | Environment
|
||||
|
||||
const result: (Provider | EnvironmentProviders)[] = [
|
||||
provideTranslateService({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useExisting: TranslateLoaderService,
|
||||
deps: [HttpClient]
|
||||
},
|
||||
defaultLanguage
|
||||
loader: provideTranslateLoader(TranslateLoaderService),
|
||||
fallbackLang: defaultLanguage
|
||||
})
|
||||
];
|
||||
|
||||
|
||||
@@ -147,10 +147,10 @@ export class TranslateLoaderService implements TranslateLoader {
|
||||
forkJoin(batch).subscribe({
|
||||
next: () => {
|
||||
const fullTranslation = this.getFullTranslationJSON(lang);
|
||||
if (fullTranslation) {
|
||||
if (Object.keys(fullTranslation).length) {
|
||||
observer.next(fullTranslation);
|
||||
}
|
||||
if (hasFailures) {
|
||||
observer.complete();
|
||||
} else if (hasFailures) {
|
||||
observer.error('Failed to load some resources');
|
||||
} else {
|
||||
observer.complete();
|
||||
|
||||
@@ -15,42 +15,49 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
import { TranslateLoaderService } from './translate-loader.service';
|
||||
import { TranslationService } from './translation.service';
|
||||
import { provideTranslateService, TranslateLoader } from '@ngx-translate/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
describe('TranslateLoader', () => {
|
||||
let translationService: TranslationService;
|
||||
let customLoader: TranslateLoaderService;
|
||||
let httpMock: HttpTestingController;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
provideTranslateService({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useClass: TranslateLoaderService,
|
||||
deps: [HttpClient]
|
||||
},
|
||||
defaultLanguage: 'en'
|
||||
}),
|
||||
TranslationService
|
||||
]
|
||||
providers: [provideHttpClientTesting(), TranslateLoaderService]
|
||||
});
|
||||
translationService = TestBed.inject(TranslationService);
|
||||
customLoader = translationService.translate.currentLoader as TranslateLoaderService;
|
||||
customLoader = TestBed.inject(TranslateLoaderService);
|
||||
httpMock = TestBed.inject(HttpTestingController);
|
||||
});
|
||||
|
||||
it('should be able to provide any TranslateLoader', () => {
|
||||
expect(translationService).toBeDefined();
|
||||
expect(translationService.translate.currentLoader).toBeDefined();
|
||||
expect(translationService.translate.currentLoader instanceof TranslateLoaderService).toBeTruthy();
|
||||
it('should be able to provide TranslateLoaderService', () => {
|
||||
expect(customLoader).toBeDefined();
|
||||
expect(customLoader instanceof TranslateLoaderService).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add the component to the list', () => {
|
||||
customLoader.registerProvider('login', 'path/login');
|
||||
expect(customLoader.providerRegistered('login')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should complete observer when gets full translation json', fakeAsync(() => {
|
||||
const language = 'en';
|
||||
let nextInvoked = false;
|
||||
let completeInvoked = false;
|
||||
|
||||
const subscription = customLoader.getTranslation(language).subscribe({
|
||||
next: () => (nextInvoked = true),
|
||||
error: () => fail('Should not call error handler'),
|
||||
complete: () => (completeInvoked = true)
|
||||
});
|
||||
const expectedRequest = httpMock.expectOne((request) => request.url.includes(`assets/adf-core/i18n/${language}.json`));
|
||||
expect(expectedRequest.request.method).toBe('GET');
|
||||
expectedRequest.flush({ 'TEST.COMPONENT': 'Composant de test' });
|
||||
tick();
|
||||
expect(nextInvoked).toBeTrue();
|
||||
expect(completeInvoked).toBeTrue();
|
||||
subscription.unsubscribe();
|
||||
httpMock.verify();
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { provideTranslateLoader, provideTranslateService, TranslateLoader } from '@ngx-translate/core';
|
||||
import { TranslationService } from './translation.service';
|
||||
import { of } from 'rxjs';
|
||||
import { provideAppConfigTesting } from '../testing';
|
||||
@@ -51,15 +51,13 @@ describe('TranslationService', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useClass: FakeLoader
|
||||
}
|
||||
providers: [
|
||||
TranslationService,
|
||||
provideAppConfigTesting(),
|
||||
provideTranslateService({
|
||||
loader: provideTranslateLoader(FakeLoader)
|
||||
})
|
||||
],
|
||||
providers: [TranslationService, provideAppConfigTesting()]
|
||||
]
|
||||
});
|
||||
|
||||
translationService = TestBed.inject(TranslationService);
|
||||
|
||||
@@ -62,7 +62,7 @@ export class TranslationService {
|
||||
this.customLoader = this.translate.currentLoader as TranslateLoaderService;
|
||||
|
||||
this.defaultLang = 'en';
|
||||
this.translate.setDefaultLang(this.defaultLang);
|
||||
this.translate.setFallbackLang(this.defaultLang);
|
||||
this.customLoader.setDefaultLang(this.defaultLang);
|
||||
|
||||
if (this.providers && this.providers.length > 0) {
|
||||
@@ -115,7 +115,7 @@ export class TranslationService {
|
||||
* @param fallback Language code to fall back to if the first one was unavailable
|
||||
*/
|
||||
loadTranslation(lang: string, fallback?: string) {
|
||||
this.translate.getTranslation(lang).subscribe(
|
||||
this.translate.currentLoader.getTranslation(lang).subscribe(
|
||||
() => {
|
||||
this.translate.use(lang);
|
||||
this.onTranslationChanged(lang);
|
||||
@@ -134,10 +134,8 @@ export class TranslationService {
|
||||
* @param lang The new language code
|
||||
*/
|
||||
onTranslationChanged(lang: string): void {
|
||||
this.translate.onTranslationChange.next({
|
||||
lang,
|
||||
translations: this.customLoader.getFullTranslationJSON?.(lang) ?? {}
|
||||
});
|
||||
const translations = this.customLoader.getFullTranslationJSON?.(lang) ?? {};
|
||||
this.translate.setTranslation(lang, translations, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user