refractor: core module (#289)
* Shift services into their own folders. * Add comments. Fixes #288
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
// import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
// import { TranslateService, LangChangeEvent } from '@ngx-translate/core';
|
||||
// import { Subject } from 'rxjs';
|
||||
|
||||
// import { extract, I18nService } from './i18n.service';
|
||||
|
||||
// const defaultLanguage = 'en-US';
|
||||
// const supportedLanguages = ['eo', 'en-US', 'fr-FR'];
|
||||
|
||||
// class MockTranslateService {
|
||||
|
||||
// currentLang: string;
|
||||
// onLangChange = new Subject();
|
||||
|
||||
// use(language: string) {
|
||||
// this.currentLang = language;
|
||||
// this.onLangChange.next({
|
||||
// lang: this.currentLang,
|
||||
// translations: {}
|
||||
// });
|
||||
// }
|
||||
|
||||
// getBrowserCultureLang() {
|
||||
// return 'en-US';
|
||||
// }
|
||||
|
||||
// setTranslation(lang: string, translations: Object, shouldMerge?: boolean) { }
|
||||
|
||||
// }
|
||||
|
||||
// describe('I18nService', () => {
|
||||
// let i18nService: I18nService;
|
||||
// let translateService: TranslateService;
|
||||
// let onLangChangeSpy: jasmine.Spy;
|
||||
|
||||
// beforeEach(() => {
|
||||
// TestBed.configureTestingModule({
|
||||
// providers: [
|
||||
// I18nService,
|
||||
// { provide: TranslateService, useClass: MockTranslateService },
|
||||
// ]
|
||||
// });
|
||||
// });
|
||||
|
||||
// beforeEach(inject([
|
||||
// I18nService,
|
||||
// TranslateService
|
||||
// ], (_i18nService: I18nService,
|
||||
// _translateService: TranslateService) => {
|
||||
|
||||
// i18nService = _i18nService;
|
||||
// translateService = _translateService;
|
||||
|
||||
// // Create spies
|
||||
// onLangChangeSpy = jasmine.createSpy('onLangChangeSpy');
|
||||
// translateService.onLangChange
|
||||
// .subscribe((event: LangChangeEvent) => {
|
||||
// onLangChangeSpy(event.lang);
|
||||
// });
|
||||
// spyOn(translateService, 'use').and.callThrough();
|
||||
// }));
|
||||
|
||||
// afterEach(() => {
|
||||
// // Cleanup
|
||||
// localStorage.removeItem('language');
|
||||
// });
|
||||
|
||||
// describe('extract', () => {
|
||||
// it('should not modify string', () => {
|
||||
// expect(extract('Hello world !')).toEqual('Hello world !');
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe('init', () => {
|
||||
// it('should init with default language', () => {
|
||||
// // Act
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Assert
|
||||
// expect(translateService.use).toHaveBeenCalledWith(defaultLanguage);
|
||||
// expect(onLangChangeSpy).toHaveBeenCalledWith(defaultLanguage);
|
||||
// });
|
||||
|
||||
// it('should init with save language', () => {
|
||||
// // Arrange
|
||||
// const savedLanguage = 'eo';
|
||||
// localStorage.setItem('language', savedLanguage);
|
||||
|
||||
// // Act
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Assert
|
||||
// expect(translateService.use).toHaveBeenCalledWith(savedLanguage);
|
||||
// expect(onLangChangeSpy).toHaveBeenCalledWith(savedLanguage);
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe('set language', () => {
|
||||
// it('should change current language', () => {
|
||||
// // Arrange
|
||||
// const newLanguage = 'eo';
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Act
|
||||
// i18nService.language = newLanguage;
|
||||
|
||||
// // Assert
|
||||
// expect(translateService.use).toHaveBeenCalledWith(newLanguage);
|
||||
// expect(onLangChangeSpy).toHaveBeenCalledWith(newLanguage);
|
||||
// });
|
||||
|
||||
// it('should change current language without a region match', () => {
|
||||
// // Arrange
|
||||
// const newLanguage = 'fr-CA';
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Act
|
||||
// i18nService.language = newLanguage;
|
||||
|
||||
// // Assert
|
||||
// expect(translateService.use).toHaveBeenCalledWith('fr-FR');
|
||||
// expect(onLangChangeSpy).toHaveBeenCalledWith('fr-FR');
|
||||
// });
|
||||
|
||||
// it('should change current language to default if unsupported', () => {
|
||||
// // Arrange
|
||||
// const newLanguage = 'es';
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Act
|
||||
// i18nService.language = newLanguage;
|
||||
|
||||
// // Assert
|
||||
// expect(translateService.use).toHaveBeenCalledWith(defaultLanguage);
|
||||
// expect(onLangChangeSpy).toHaveBeenCalledWith(defaultLanguage);
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe('get language', () => {
|
||||
// it('should return current language', () => {
|
||||
// // Arrange
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Act
|
||||
// const currentLanguage = i18nService.language;
|
||||
|
||||
// // Assert
|
||||
// expect(currentLanguage).toEqual(defaultLanguage);
|
||||
// });
|
||||
// });
|
||||
|
||||
// });
|
||||
@@ -0,0 +1,92 @@
|
||||
/** Angular Imports */
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
/** Translation Imports */
|
||||
import { TranslateService, LangChangeEvent } from '@ngx-translate/core';
|
||||
|
||||
/** Custom Services */
|
||||
import { Logger } from '../logger/logger.service';
|
||||
|
||||
/** Other Imports */
|
||||
import { includes } from 'lodash';
|
||||
import * as enUS from '../../../translations/en-US.json';
|
||||
import * as frFR from '../../../translations/fr-FR.json';
|
||||
|
||||
/** Initialize Logger */
|
||||
const log = new Logger('I18nService');
|
||||
|
||||
/**
|
||||
* Pass-through function to mark a string for translation extraction.
|
||||
* Running `npm translations:extract` will include the given string by using this.
|
||||
* @param {string} s The string to extract for translation.
|
||||
* @return {string} The same string.
|
||||
*/
|
||||
export function extract(s: string) {
|
||||
return s;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class I18nService {
|
||||
|
||||
/** Key to store current language of application in local storage. */
|
||||
private languageStorageKey = 'mifosXLanguage';
|
||||
|
||||
defaultLanguage: string;
|
||||
supportedLanguages: string[];
|
||||
|
||||
constructor(private translateService: TranslateService) {
|
||||
// Embed languages to avoid extra HTTP requests
|
||||
translateService.setTranslation('en-US', enUS);
|
||||
translateService.setTranslation('fr-FR', frFR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes i18n for the application.
|
||||
* Loads language from local storage if present, or sets default language.
|
||||
* @param {!string} defaultLanguage The default language to use.
|
||||
* @param {Array.<String>} supportedLanguages The list of supported languages.
|
||||
*/
|
||||
init(defaultLanguage: string, supportedLanguages: string[]) {
|
||||
this.defaultLanguage = defaultLanguage;
|
||||
this.supportedLanguages = supportedLanguages;
|
||||
this.language = '';
|
||||
|
||||
this.translateService.onLangChange
|
||||
.subscribe((event: LangChangeEvent) => { localStorage.setItem(this.languageStorageKey, event.lang); });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current language.
|
||||
* Note: The current language is saved to the local storage.
|
||||
* If no parameter is specified, the language is loaded from local storage (if present).
|
||||
* @param {string} language The IETF language code to set.
|
||||
*/
|
||||
set language(language: string) {
|
||||
language = language || localStorage.getItem(this.languageStorageKey) || this.translateService.getBrowserCultureLang();
|
||||
let isSupportedLanguage = includes(this.supportedLanguages, language);
|
||||
|
||||
// If no exact match is found, search without the region
|
||||
if (language && !isSupportedLanguage) {
|
||||
language = language.split('-')[0];
|
||||
language = this.supportedLanguages.find(supportedLanguage => supportedLanguage.startsWith(language)) || '';
|
||||
isSupportedLanguage = Boolean(language);
|
||||
}
|
||||
|
||||
// Fallback if language is not supported
|
||||
if (!isSupportedLanguage) {
|
||||
language = this.defaultLanguage;
|
||||
}
|
||||
|
||||
log.debug(`Language set to ${language}`);
|
||||
this.translateService.use(language);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current language.
|
||||
* @return {string} The current language code.
|
||||
*/
|
||||
get language(): string {
|
||||
return this.translateService.currentLang;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user