Newer
Older
francois.grand
committed
import { Message, MessageCode, Observable } from "jalhyd";
francois.grand
committed
import { StringMap } from "../../stringmap";
import { ApplicationSetupService } from "../app-setup/app-setup.service";
import { HttpService } from "../http/http.service";
francois.grand
committed
/*
language tag : fr-FR
primary subcode : fr
optional subcode : FR
*/
francois.grand
committed
export enum LanguageCode {
francois.grand
committed
FRENCH,
ENGLISH,
}
francois.grand
committed
export class Language {
private _code: LanguageCode;
private _tag: string;
private _label: string;
constructor(c: LanguageCode, t: string, l: string) {
this._code = c;
this._tag = t;
this._label = l;
}
get code(): LanguageCode {
return this._code;
}
get tag(): string {
return this._tag;
}
get label(): string {
return this._label;
}
}
francois.grand
committed
@Injectable()
export class I18nService extends Observable {
francois.grand
committed
private _currLang: Language;
private _Messages: StringMap;
francois.grand
committed
private _languages: Language[];
constructor(
private applicationSetupService: ApplicationSetupService,
private httpService: HttpService) {
francois.grand
committed
this._languages = [];
this._languages.push(new Language(LanguageCode.FRENCH, "fr", "Français"));
this._languages.push(new Language(LanguageCode.ENGLISH, "en", "English"));
francois.grand
committed
}
francois.grand
committed
public get languages() {
return this._languages;
}
francois.grand
committed
francois.grand
committed
public get currentLanguage() {
return this._currLang;
}
francois.grand
committed
public get currentMap() {
return this._Messages;
}
francois.grand
committed
private getLanguageFromCode(lc: LanguageCode) {
for (const l of this._languages) {
if (l.code === lc) {
francois.grand
committed
return l;
francois.grand
committed
}
throw new Message(MessageCode.ERROR_LANG_UNSUPPORTED);
francois.grand
committed
}
francois.grand
committed
private getLanguageFromTag(tag: string) {
for (const l of this._languages) {
if (l.tag === tag) {
francois.grand
committed
return l;
francois.grand
committed
}
const e = new Message(MessageCode.ERROR_LANG_UNSUPPORTED);
francois.grand
committed
e.extraVar["locale"] = tag;
throw e;
}
francois.grand
committed
public setLocale(lng: string | LanguageCode) {
let oldLang;
if (this._currLang !== undefined) {
oldLang = this._currLang.code;
}
francois.grand
committed
if (typeof lng === "string") {
francois.grand
committed
this._currLang = this.getLanguageFromTag(t);
francois.grand
committed
this._currLang = this.getLanguageFromCode(lng);
francois.grand
committed
François
committed
if (this._currLang.code !== oldLang) {
this._Messages = undefined;
const prom = this.httpGetMessages();
const is: I18nService = this;
François
committed
prom.then((res) => {
is.notifyObservers(undefined);
François
committed
}
const is: I18nService = this;
francois.grand
committed
// fermeture nécessaire pour capturer la valeur de this (undefined sinon)
is._Messages = JSON.parse(s);
francois.grand
committed
francois.grand
committed
switch (this._currLang.code) {
case LanguageCode.FRENCH:
francois.grand
committed
l = "fr";
break;
default:
l = "en";
}
const f: string = "messages." + l + ".json";
return this.httpService.httpGetRequestPromise("locale/" + f).then(
francois.grand
committed
}
private getMessageFromCode(c: MessageCode): string {
if (this._Messages[MessageCode[c]] === undefined) {
return `*** Message ${MessageCode[c]} non traduit ***`;
}
return this._Messages[MessageCode[c]];
francois.grand
committed
}
private replaceAll(str: string, find: string, replace: string) {
return str.replace(new RegExp(find, "g"), replace);
francois.grand
committed
}
francois.grand
committed
/**
* traduit un message
* @param r message
* @param nDigits nombre de chiffres à utiliser pour l'arrondi dans le cas de données numériques
*/
public localizeMessage(r: Message, nDigits: number = 3): string {
let m: string = this.getMessageFromCode(r.code);
francois.grand
committed
for (const k in r.extraVar) {
if (r.extraVar.hasOwnProperty(k)) {
const v: any = r.extraVar[k];
let s: string;
if (typeof v === "number") {
s = v.toFixed(nDigits);
} else {
s = v;
}
m = this.replaceAll(m, "%" + k + "%", s);
}
francois.grand
committed
}
return m;
}
* Traduit un texte défini dans un fichier de langue (locale/error_message.xx.json par défaut)
* Les ids dans ces fichiers sont soit un enum de JalHyd, soit une chaine libre correspondant au code passé àlocalizeText()
* @param code id du texte
* @param messages Contenu du fichier de langua à utiliser (locale/error_message.xx.json par défaut)
public localizeText(code: string, messages = this._Messages) {
if (messages === undefined) {
francois.grand
committed
return `*** messages not loaded: ${code} ***`;
return `*** message not exists: ${code} ***`;
francois.grand
committed
/**
* analyse un libellé du type ouvrage[n].XX
*/
private parseLabel(lbl: string) {
const re = /([A-Z,a-z]+)\[(\d+)\]\.(.+)/;
return re.exec(lbl);
}
/**
David Dorchies
committed
* Traduit un libellé qui peut être un code
francois.grand
committed
*/
public getExtraResLabel(s: string) {
David Dorchies
committed
const key = "INFO_EXTRARES_LIB_";
const match = this.parseLabel(s);
if (match) {
// Code du type "Ouvrage[n].XXX"
// Les libellés correspondants sont INFO OUVRAGE et INFO_EXTRARES_LIB_OUVRAGE_XXX
return this.localizeText(`INFO_${match[1].toUpperCase()}`) + " n°" + (+match[2] + 1) + ": " +
this.localizeText(`${key}${match[1].toUpperCase()}_${match[3].toUpperCase()}`);
} else {
// Autres codes INFO_EXTRARES_LIB_XXX
return this.localizeText(`${key}${s.toUpperCase()}`);
}
francois.grand
committed
}
francois.grand
committed
/**
* Met en forme un extraResult en fonction du libellé qui l'accompagne
* Les extraResult avec le terme "ENUM_" sont traduit avec le message INFO_EXTRARES_ENUM_[Nom de la variable après ENUM_]
francois.grand
committed
*/
public formatResult(label: string, value: number): string {
const match = label.indexOf("ENUM_");
if (match > -1) {
return this.localizeText(`INFO_EXTRARES_${label.substring(match).toUpperCase()}_${value}`);
David Dorchies
committed
}
const nDigits = this.applicationSetupService.displayDigits;
francois.grand
committed
return value.toFixed(nDigits);
}
David Dorchies
committed