From cfaf56405fb753e30f80fd6b42d2140a63ac5148 Mon Sep 17 00:00:00 2001 From: "mathias.chouet" <mathias.chouet@irstea.fr> Date: Tue, 1 Sep 2020 11:17:00 +0200 Subject: [PATCH] Fix #223 - enhance translation system --- .../calculator.component.ts | 2 + .../formulaire/elements/formulaire-element.ts | 14 ++--- src/app/formulaire/elements/select-field.ts | 11 ++-- src/app/services/formulaire.service.ts | 52 +++++++++++++++++-- .../services/internationalisation.service.ts | 13 ++--- 5 files changed, 66 insertions(+), 26 deletions(-) diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts index f1cd53d10..d16af2522 100644 --- a/src/app/components/generic-calculator/calculator.component.ts +++ b/src/app/components/generic-calculator/calculator.component.ts @@ -433,6 +433,8 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe this.setForm(this.formulaireService.getFormulaireFromId(uid)); this.resultsComponent.formulaire = this._formulaire; this._calculatorNameComponent.model = this._formulaire; + // reload localisation in all cases (it does not eat bread) + this.formulaireService.updateFormulaireLocalisation(this._formulaire); // call Form init hook this._formulaire.onCalculatorInit(); break; diff --git a/src/app/formulaire/elements/formulaire-element.ts b/src/app/formulaire/elements/formulaire-element.ts index 79a4899ea..579b62648 100644 --- a/src/app/formulaire/elements/formulaire-element.ts +++ b/src/app/formulaire/elements/formulaire-element.ts @@ -1,8 +1,7 @@ import { FormulaireNode } from "./formulaire-node"; -import { StringMap } from "../../stringmap"; -import { I18nService } from "../../services/internationalisation.service"; import { ServiceFactory } from "../../services/service-factory"; import { FormulaireDefinition } from "../definition/form-definition"; +import { FormulaireService } from "../../services/formulaire.service"; /** * élément (enfant) du formulaire : fieldset, input, container, ... @@ -18,7 +17,7 @@ export abstract class FormulaireElement extends FormulaireNode { */ protected _label: string; - private intlService: I18nService; + private formulaireService: FormulaireService; public static removePrefix(s: string, prefix: string): string { if (s.startsWith(prefix)) { @@ -30,7 +29,7 @@ export abstract class FormulaireElement extends FormulaireNode { constructor(parent: FormulaireNode) { super(parent); this._isDisplayed = true; - this.intlService = ServiceFactory.i18nService; + this.formulaireService = ServiceFactory.formulaireService; } get isDisplayed(): boolean { @@ -71,11 +70,8 @@ export abstract class FormulaireElement extends FormulaireNode { * @param loc calculator-specific localised messages map * @param key Element label key */ - public updateLocalisation(key?: string) { - if (!key) { - key = this._confId; - } - this._label = this.intlService.localizeText(key); + public updateLocalisation() { + this._label = this.formulaireService.localizeText(this._confId, this.parentForm.currentNub.calcType); for (const f of this.getKids()) { f.updateLocalisation(); } diff --git a/src/app/formulaire/elements/select-field.ts b/src/app/formulaire/elements/select-field.ts index 4f7196cf6..680cab630 100644 --- a/src/app/formulaire/elements/select-field.ts +++ b/src/app/formulaire/elements/select-field.ts @@ -10,7 +10,6 @@ import { import { Field } from "./field"; import { SelectEntry } from "./select-entry"; -import { StringMap } from "../../stringmap"; import { FormulaireNode } from "./formulaire-node"; import { FormulaireDefinition } from "../definition/form-definition"; import { ServiceFactory } from "../../services/service-factory"; @@ -114,10 +113,12 @@ export class SelectField extends Field { super.updateLocalisation(); for (const e of this._entries) { // some Select fields already have a translated label at this time; translate others - if (e.label === undefined) { - const aId = e.id.split("_"); - e.label = ServiceFactory.i18nService.localizeText(`${aId[1].toUpperCase()}_${aId[2]}`); - } + const aId = e.id.split("_"); + const trad = ServiceFactory.formulaireService.localizeText( + `${aId[1].toUpperCase()}_${aId[2]}`, + this.parentForm.currentNub.calcType + ); + e.label = trad; } } diff --git a/src/app/services/formulaire.service.ts b/src/app/services/formulaire.service.ts index 72818b95e..0a2f94e14 100644 --- a/src/app/services/formulaire.service.ts +++ b/src/app/services/formulaire.service.ts @@ -91,6 +91,51 @@ export class FormulaireService extends Observable { return this.intlService.localizeText(`INFO_${sCalculator}_TITRE_COURT`); } + /** + * Forces update of all form strings in given Formulaire, with current language + */ + public updateFormulaireLocalisation(f: FormulaireDefinition) { + const requiredLang = this.intlService.currentLanguage; + f.updateLocalisation(requiredLang); + } + + + /** + * Tente de trouver une traduction pour textKey dans les fichiers de langues + * spécifiques du module de calcul en cours, dans la langue en cours, puis + * dans la langue par défaut; si aucune traduction n'est trouvée, demande au + * service i18n de rechercher dans les fichiers de langues globaux + * @param textKey la clé du texte à traduire + */ + public localizeText(textKey: string, ct: CalculatorType): string { + const calcType = /* this.currentForm?.currentNub?.calcType || */ ct; + if (calcType !== undefined) { + // throw new Error("FormulaireService.localizeText(): cannot find CalculatorType for current form's Nub"); + let langCache = this.i18nService.languageCache; + if (langCache && langCache[calcType]) { + langCache = langCache[calcType]; // …for target Nub type + } + // try current language + if ( + langCache + && langCache[this.intlService.currentLanguage] + && langCache[this.intlService.currentLanguage][textKey] !== undefined + ) { + return langCache[this.intlService.currentLanguage][textKey]; + + } else if ( // try calculator type specific translation, but for default language + langCache + && langCache[this.appSetupService.fallbackLanguage] + && langCache[this.appSetupService.fallbackLanguage][textKey] !== undefined + ) { + return langCache[this.appSetupService.fallbackLanguage][textKey]; + + } + } + // fallback to global (not calculator type specific) translation system + return this.i18nService.localizeText(textKey); + } + /** * Returns variable name from symbol * @param calcType @@ -107,7 +152,7 @@ export class FormulaireService extends Observable { langCache = langCache[this.intlService.currentLanguage]; // … for current language } if (langCache && langCache[symbol] !== undefined) { - s = this.intlService.localizeText(symbol, langCache); + s = this.localizeText(symbol, calcType); } else { // is symbol of the form ouvrages[i]… ? const re = /([A-Z,a-z]+)\[(\d+)\]\.(.+)/; @@ -161,7 +206,7 @@ export class FormulaireService extends Observable { } else { const unitKey = "UNIT_" + symbolBase; if (langCache && langCache[unitKey] !== undefined) { - unit = this.intlService.localizeText(unitKey, langCache); + unit = this.localizeText(unitKey, calcType); } } } @@ -287,8 +332,7 @@ export class FormulaireService extends Observable { const f: FormulaireDefinition = this.newFormulaire(ct); this._formulaires.push(f); // Charge la configuration dépendamment du type - const prom: Promise<any> = this.loadConfig(ct); - return prom.then(s => { + return this.loadConfig(ct).then(s => { f.preparseConfig(s); // Associe le Nub fourni (chargement de session / duplication de module), sinon en crée un nouveau diff --git a/src/app/services/internationalisation.service.ts b/src/app/services/internationalisation.service.ts index 26d2cecce..ed8011d09 100644 --- a/src/app/services/internationalisation.service.ts +++ b/src/app/services/internationalisation.service.ts @@ -79,7 +79,6 @@ export class I18nService extends Observable implements Observer { this._Messages = undefined; // reload all messages: global lang files, plus lang files for all calculators ! const that = this; - console.log("> promise.all !"); const promisesList: Promise<any>[] = []; for (const ct in CalculatorType) { const calcType = Number(ct); @@ -88,7 +87,6 @@ export class I18nService extends Observable implements Observer { } } Promise.all(promisesList).then(() => { - console.log(">> get global messages !"); this.httpGetMessages(code).then((res: any) => { that._Messages = res; // propagate language change to all application @@ -174,16 +172,15 @@ export class I18nService extends Observable implements Observer { * * @param textKey id du texte (ex: "ERROR_PARAM_NULL") */ - public localizeText(textKey: string, msg?: StringMap) { - const messages = msg || this._Messages; - if (! messages) { + public localizeText(textKey: string) { + if (! this._Messages) { return `*** messages not loaded: ${this._currentLanguage} ***`; } - if (messages[textKey] !== undefined) { - return decodeHtml(messages[textKey]); + if (this._Messages[textKey] !== undefined) { + return decodeHtml(this._Messages[textKey]); } else { // try general message - if (msg !== undefined && this._Messages["INFO_LIB_" + textKey.toUpperCase()] !== undefined) { + if (this._Messages !== undefined && this._Messages["INFO_LIB_" + textKey.toUpperCase()] !== undefined) { return decodeHtml(this._Messages["INFO_LIB_" + textKey.toUpperCase()]); } if (!isDevMode()) { -- GitLab