From e5e4b7ab7ce6ebff484b27e33575a921056f6b65 Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Mon, 11 Sep 2017 17:13:21 +0200 Subject: [PATCH] =?UTF-8?q?-=20ajout=20du=20service=20"formulaire"=20-=20a?= =?UTF-8?q?jout=20du=20composant=20SelectFieldLineComponent=20d'affichage?= =?UTF-8?q?=20d'une=20combo=20-=20conduite=20distributrice/Lechapt-Calmon?= =?UTF-8?q?=20:=20utilisation=20du=20composant=20g=C3=A9n=C3=A9rique=20de?= =?UTF-8?q?=20calculatrice=20-=20classe=20FormulaireDefinition=20:=20ajout?= =?UTF-8?q?=20des=20d=C3=A9pendences=20-=20param-input=20:=20suppression?= =?UTF-8?q?=20de=20Material=20-=20composant=20g=C3=A9n=C3=A9rique=20de=20c?= =?UTF-8?q?alculatrice=20:=20d=C3=A9but=20d'application=20des=20d=C3=A9pen?= =?UTF-8?q?dances?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.component.ts | 20 +- src/app/app.module.ts | 6 +- .../cond_distri/conddistri.component.html | 22 +- .../cond_distri/conddistri.component.ts | 413 +----------------- .../generic/calculator.component.html | 6 + .../generic/calculator.component.ts | 224 ++++++---- src/app/calculators/generic/formulaire.ts | 228 ++++++++-- src/app/calculators/generic/ngparam.ts | 19 +- .../lechapt-calmon/lechapt-calmon.en.json | 12 +- .../lechaptcalmon.component.html | 5 +- .../lechapt-calmon/lechaptcalmon.component.ts | 55 +-- .../field-set/field-set.component.ts | 17 +- src/app/components/field-set/field-set.html | 11 +- .../param-field-line.component.ts | 28 +- .../param-field-line/param-field-line.html | 2 +- .../param-input/param-input.component.html | 11 +- .../param-input/param-input.component.ts | 25 +- .../select-field-line.component.ts | 50 +++ .../select-field-line/select-field-line.html | 8 + .../services/formulaire/formulaire.service.ts | 130 ++++++ src/app/services/http/http.service.ts | 4 +- .../internationalisation.service.ts | 49 +-- src/app/services/param/param.service.ts | 11 +- src/app/stringmap.ts | 3 + 24 files changed, 626 insertions(+), 733 deletions(-) create mode 100644 src/app/calculators/generic/calculator.component.html create mode 100644 src/app/components/select-field-line/select-field-line.component.ts create mode 100644 src/app/components/select-field-line/select-field-line.html create mode 100644 src/app/services/formulaire/formulaire.service.ts create mode 100644 src/app/stringmap.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 152c3b5d8..449c691ef 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -7,11 +7,11 @@ import { InternationalisationService, Language, LanguageCode } from './services/ import { Observer } from './services/observer'; import { ErrorService } from './services/error/error.service'; import { AlertDialog } from './components/alert-dialog/alert-dialog.component'; +import { FormulaireService } from './services/formulaire/formulaire.service'; @Component({ selector: 'nghyd-app', template: ` - <select [(ngModel)]=_currentLanguage (change)=onSelectLang($event)> <option *ngFor="let l of intlService.languages" [value]=l.code>{{l.label}}</option> </select> @@ -28,11 +28,13 @@ import { AlertDialog } from './components/alert-dialog/alert-dialog.component'; <param-input symbol="Ks"></param-input> --> `, - providers: [ParamService, InternationalisationService, HttpService] + providers: [ParamService, InternationalisationService, HttpService, FormulaireService] }) export class AppComponent implements Observer { private _currentLanguage: LanguageCode; + private _displayErrorDialog: boolean = false; + constructor(private intlService: InternationalisationService, private appRef: ApplicationRef, private dialog: MdDialog, private errorService: ErrorService) { } private initLocale() { @@ -74,16 +76,16 @@ export class AppComponent implements Observer { this.appRef.tick(); } - ngAfterViewChecked() { - this.intlService.acknowledgeLocaleChanged(); - } - // interface Observer update(data: any): void { // on ouvre un dialogue avec le message d'erreur reçu - let dialogRef = this.dialog.open(AlertDialog); - let ad: AlertDialog = dialogRef.componentInstance; - ad.text = String(data); + if (this._displayErrorDialog) { + let dialogRef = this.dialog.open(AlertDialog); + let ad: AlertDialog = dialogRef.componentInstance; + ad.text = String(data); + } + else + console.log(data); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ae0292682..e0bd25824 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -10,11 +10,13 @@ import { AppComponent } from './app.component'; import { ParamInputComponent } from './components/param-input/param-input.component'; import { FieldSetComponent } from './components/field-set/field-set.component'; import { ParamFieldLineComponent } from './components/param-field-line/param-field-line.component'; +import { SelectFieldLineComponent } from './components/select-field-line/select-field-line.component'; import { CondDistriComponent } from './calculators/cond_distri/conddistri.component'; import { LechaptCalmonComponent } from './calculators/lechapt-calmon/lechaptcalmon.component'; import { AlertDialog } from './components/alert-dialog/alert-dialog.component'; import { AppErrorModule } from './error.module'; import { CalculatorResultsComponent } from './components/calculator-results/calculator-results.component'; +import { GenericCalculatorComponent } from './calculators/generic/calculator.component'; @NgModule({ imports: [ @@ -31,8 +33,8 @@ import { CalculatorResultsComponent } from './components/calculator-results/calc AppComponent, ParamInputComponent, FieldSetComponent, - ParamFieldLineComponent, - CondDistriComponent, LechaptCalmonComponent, + ParamFieldLineComponent, SelectFieldLineComponent, + CondDistriComponent, LechaptCalmonComponent, GenericCalculatorComponent, AlertDialog, CalculatorResultsComponent ], diff --git a/src/app/calculators/cond_distri/conddistri.component.html b/src/app/calculators/cond_distri/conddistri.component.html index 20774680a..c3bec4eb3 100644 --- a/src/app/calculators/cond_distri/conddistri.component.html +++ b/src/app/calculators/cond_distri/conddistri.component.html @@ -1,18 +1,10 @@ <h1 i18n="@@titre_cond_distri">Conduite distributrice</h1> -<field-set *ngFor="let fs of _fieldSets" [fieldSet]=fs (onRadio)=onRadioClick($event)></field-set> - -<div style="text-align:center;"> - <button type="button" class="button_compute" name="Calculer" (click)="doCompute()" i18n="@@hyd_compute">Calculer</button> -</div> -<calc-results [style.display]="getResultsStyleDisplay()"></calc-results> - +<hydrocalc type="ConduiteDistributrice"></hydrocalc> <!-- - <tr *ngFor="let r of _results; let i=index" [class]="getResultClass(i)"> - - <h1>{{_title}}</h1> - <field-set *ngFor="let fs of _fieldSets" title="fs.title" fields="fs.paramList"></field-set> - <field-set title="titre de field set" fields="Q,D"></field-set> - <param-input symbol="Q"></param-input> - <param-input symbol="Q"></param-input> - <param-input symbol="Ks"></param-input> + <field-set *ngFor="let fs of _fieldSets" [fieldSet]=fs (onRadio)=onRadioClick($event)></field-set> + + <div style="text-align:center;"> + <button type="button" class="button_compute" name="Calculer" (click)="doCompute()" i18n="@@hyd_compute">Calculer</button> + </div> + <calc-results [style.display]="getResultsStyleDisplay()"></calc-results> --> \ No newline at end of file diff --git a/src/app/calculators/cond_distri/conddistri.component.ts b/src/app/calculators/cond_distri/conddistri.component.ts index 477ed697b..45b4fce07 100644 --- a/src/app/calculators/cond_distri/conddistri.component.ts +++ b/src/app/calculators/cond_distri/conddistri.component.ts @@ -1,415 +1,8 @@ -import { Component, OnInit, DoCheck, ViewChild } from '@angular/core'; -import { Response } from '@angular/http'; -import { Observable } from "rxjs/Observable"; -import 'rxjs/add/operator/toPromise'; - -import { IParamsEquation, Nub, ConduiteDistrib, ConduiteDistribParams } from "jalhyd"; - -import { ParamService } from '../../services/param/param.service'; -import { HttpService } from '../../services/http/http.service'; -import { InternationalisationService } from '../../services/internationalisation/internationalisation.service'; -import { FieldSet } from '../../calculators/generic/formulaire'; -import { NgParameter, ParamRadioConfig } from '../../calculators/generic/ngparam'; -import { GenericCalculatorComponent } from '../generic/calculator.component'; -import { CalculatorResultsComponent } from '../../components/calculator-results/calculator-results.component'; +import { Component, } from '@angular/core'; @Component({ selector: 'cond-distri', - templateUrl: "./conddistri.component.html", - // styles: [` - // .hyd_bouton_submit { - // width: 10em; - // }` - // ] - styles: [` - .button_compute { - height: 3em; - width: 30%; - } - ` - ] + templateUrl: "./conddistri.component.html" }) -export class CondDistriComponent extends GenericCalculatorComponent implements OnInit, DoCheck { - /** - * objet JSON chargé depuis le fichier de traduction - */ - // private _localisation = {}; - - /** - * objet JSON chargé depuis le fichier de configuration de la calculette - */ - // private _config = {}; - - // private _fieldSets: FieldSet[] = []; - - /** - * symbole du paramètre à calculer par défaut (cf config "idCal") - */ - // private _defaultCalculatedParam: string; - - /** - * composant d'affichage des résultats - */ - @ViewChild(CalculatorResultsComponent) - private resultsComponent: CalculatorResultsComponent; - - /** - * flag d'affichage du composant de résultats - */ - // private _showResults: boolean = false; - - constructor(private paramSvc: ParamService, private httpSvc: HttpService, private intlSvc: InternationalisationService) { - super(paramSvc, httpSvc, intlSvc); - } - - // // private loadLocalisation() { - // // let ths = this; - // // let processData = function (s: string) { - // // // fermeture nécessaire pour capturer la valeur de this (undefined sinon) - // // ths._localisation = JSON.parse(s); - // // ths.paramService.updateLocalisation(ths._localisation); - // // } - - // // let f: string = "app/calculators/cond_distri/cond_distri." + this.intlService.languageCode + ".json" - // // this.httpService.httpGetRequest(undefined, undefined, undefined, f, processData); - // // } - // private loadLocalisation(): Promise<string> { - // let ths = this; - // let processData = function (s: string) { - // // fermeture nécessaire pour capturer la valeur de this (undefined sinon) - // ths._localisation = JSON.parse(s); - // ths.paramService.updateLocalisation(ths._localisation); - // } - - // let f: string = "app/calculators/cond_distri/cond_distri." + this.intlService.currentLanguage.tag + ".json" - // let resp: Observable<Response> = this.httpService.httpGetRequestResponse(undefined, undefined, undefined, f); - - // let prom = resp.map(res => res.text()).toPromise(); - // prom.then((res) => { - // processData(res); - // }) - - // return prom; - // } - - // private logObject(obj: {}, m?: string) { - // // évite le message "Value below was evaluated just now" dans le debugger de Chrome - // if (m == undefined) - // console.log(JSON.stringify(obj)); - // else - // console.log(m + " " + JSON.stringify(obj)); - // } - - // private parseConfig() { - // this._fieldSets = []; - - // for (let conf_index in this._config) { - - // let conf = this._config[conf_index]; - // let conf_id: string = conf["id"]; - - // // field set - // if (conf_id.startsWith("fs_")) { - // let fieldSet: FieldSet = new FieldSet(conf_id); - - // let fields = conf["fields"]; - // for (let field_index in fields) { - // let field = fields[field_index]; - // if (field["type"] === "input") { - // let input_id = field["id"]; - // let param: NgParameter = this.paramService.getParameter(input_id); - // if (param != undefined) { - // param.unit = field["unit"]; - // param.v = +field["value"]; - // param.radioConfig = NgParameter.getRadioConfig(conf["option"]); - // param.radioState = ParamRadioConfig.FIX; - // param.isDefault = false; // malgré le fait qu'il soit initialisé dans la déclaration de la classe NgParam à false, quand on relit sa valeur, il vaut undefined (merci Microsoft) - // fieldSet.addField(param); - // } - // } - // } - // if (!fieldSet.isEmpty()) { - // this._fieldSets.push(fieldSet); - // } - // } - // // options globales - // else if (conf_id === "options") { - // // id du paramètre à calculer par défaut - // this._defaultCalculatedParam = conf["idCal"]; - // let p = this.getParamFromSymbol(this._defaultCalculatedParam); - // p.isDefault = true; - // p.radioState = ParamRadioConfig.CAL; - // } - // } - // } - - // private getParamFromSymbol(symbol: string): NgParameter { - // for (let fs of this._fieldSets) { - // for (let p of fs.fields) { - // if (p.symbol === symbol) - // return p; - // } - // } - // return undefined; - // } - - // private getParamFromState(st: ParamRadioConfig): NgParameter { - // for (let fs of this._fieldSets) { - // for (let p of fs.params) { - // if (p.radioState == st) - // return p; - // } - // } - // return undefined; - // } - - // private loadConfig() { - // let ths = this; - // let processData = function (s: string) { - // // fermeture nécessaire pour capturer la valeur de this (undefined sinon) - // ths._config = JSON.parse(s); - // ths.parseConfig(); - // } - - // let f: string = "app/calculators/cond_distri/cond_distri.config.json" - // this.httpService.httpGetRequest(undefined, undefined, undefined, f, processData); - // } - - // ngOnInit() { - // this.loadLocalisation(); - // this.loadConfig(); - // // this.updateLanguage(); - // } - - // private getFieldSet(id: string) { - // for (let fs of this._fieldSets) { - // if (fs.id == id) - // return fs; - // } - // return undefined; - // } - - // private updateLanguage() { - // for (let conf_index in this._config) { - // let conf = this._config[conf_index]; - // let conf_id: string = conf["id"]; - - // if (conf_id.startsWith("fs_")) { - // let fieldSet: FieldSet = this.getFieldSet(conf_id); - // if (fieldSet != undefined) - // fieldSet.title = this._localisation[conf_id]; - // } - // } - // } - - // ngDoCheck() { - // // let q = this.getParamFromSymbol("Q"); // A VIRER !!!! - // // if (q != undefined) { - // // q.radioState = ParamRadioConfig.VAR; - // // q.minValue = 1.5; - // // q.maxValue = 6; - // // q.stepValue = 0.3; - // // } - - // if (this.intlService.localeChanged) { - // const promise = this.loadLocalisation() - // .then(() => { - // this.updateLanguage(); - // }); - // } - // } - - /* - * gestion des événements clic sur les radios : - * envoi d'un message au composant parent - * cf. https://angular.io/guide/component-interaction#parent-listens-for-child-event - */ - - // private onRadioClick(info: string) { - // this._showResults = false; - - // // console.log("CondDistriComponent " + info); - // let tmp: string[] = info.split("_"); - // let symbol: string = tmp[0]; - - // let sourceParam = this.getParamFromSymbol(symbol); - // let oldState: ParamRadioConfig = sourceParam.radioState; - // let newState: ParamRadioConfig = ParamRadioConfig[tmp[1].toUpperCase()]; - // // console.log(sourceParam.symbol + " : " + ParamRadioConfig[oldState] + " -> " + ParamRadioConfig[newState]); - // // this.logObject(sourceParam, "sourceobj1"); - - // switch (oldState) { - // case ParamRadioConfig.FIX: - // switch (newState) { - // case ParamRadioConfig.VAR: - // this.resetOther(sourceParam, ParamRadioConfig.CAL); - // break; - - // case ParamRadioConfig.CAL: - // this.resetOther(sourceParam, ParamRadioConfig.VAR); - // break; - // } - // break; - - // case ParamRadioConfig.VAR: - // switch (newState) { - // case ParamRadioConfig.CAL: - // this.resetOther(sourceParam, ParamRadioConfig.VAR); - // break; - // } - // break; - - // case ParamRadioConfig.CAL: - // switch (newState) { - // case ParamRadioConfig.FIX: - // this.setDefault(); - // break; - - // case ParamRadioConfig.VAR: - // this.resetOther(sourceParam, ParamRadioConfig.CAL); - // this.setDefault(); - // break; - // } - // } - - // sourceParam.radioState = newState; - - // // this.appRef.tick(); - // // this.changeDetectorRef.detectChanges(); // provoque une détection des changements dans les contrôles - // } - - /** - * remet tous les paramètres à FIX sauf "me" et ceux (celui) à l'état "except" - */ - // private resetOther(me: NgParameter, except: ParamRadioConfig) { - // // console.log("reset me=" + me.symbol + " sauf=" + ParamRadioConfig[except]) - // for (let fs of this._fieldSets) { - // for (let p of fs.params) { - // if (p != me && p.radioState != except && p.radioConfig != ParamRadioConfig.FIX) { - // // console.log("reset " + p.symbol + " st " + ParamRadioConfig[p.radioState] + " -> FIX"); - // p.radioState = ParamRadioConfig.FIX; - // } - // } - // } - // } - - /** - * met le paramètre par défaut à CAL - */ - // private setDefault() { - // let defaultParamCal = this.getParamFromSymbol(this._defaultCalculatedParam); - // // console.log("setdefault " + defaultParamCal.symbol + " -> CAL") - // defaultParamCal.radioState = ParamRadioConfig.CAL; - // } - - // private getParameterValue(symbol: string): number { - // for (let fs of this._fieldSets) { - // for (let p of fs.params) { - // if (p.symbol === symbol) { - // switch (p.radioState) { - // case ParamRadioConfig.FIX: - // return p.v; - - // case ParamRadioConfig.VAR: - // case ParamRadioConfig.CAL: - // return undefined; - // } - // } - // } - // } - // } - - // private getComputedParameter(): NgParameter { - // return this.getParamFromState(ParamRadioConfig.CAL); - // } - - // private getVariatedParameter(): NgParameter { - // return this.getParamFromState(ParamRadioConfig.VAR); - // } - - // private addFixedResults(nDigits: number) { - // for (let fs of this._fieldSets) { - // for (let p of fs.params) { - // if (p.radioState == ParamRadioConfig.FIX && p.symbol !== "Pr") { - // this.resultsComponent.addFixedResult(p, p.v, nDigits); - // } - // } - // } - // } - - // private doCompute() { - // this._showResults = false; - // let computedParam = this.getComputedParameter(); - - // let Q: number = this.getParameterValue("Q"); // débit Q - // let D: number = this.getParameterValue("D"); // diamètre D - // let J: number = this.getParameterValue("J"); // perte de charge J - // let Lg: number = this.getParameterValue("Lg"); // Longueur de la conduite Lg - // let Nu: number = this.getParameterValue("Nu"); // Viscosité dynamique Nu - // let prec: number = this.getParameterValue("Pr"); // précision - // let nDigits = -Math.log10(prec); - - // let prms = new ConduiteDistribParams(Q, D, J, Lg, Nu); - // let nub = new ConduiteDistrib(prms); - - // let varParam = this.getVariatedParameter(); - // this.resultsComponent.reset(varParam == undefined); - // if (varParam == undefined) { - // // pas de paramètre à varier - - // let res = nub.Calc(computedParam.symbol, 0, prec).vCalc; - - // this.addFixedResults(nDigits); - // this.resultsComponent.addFixedResult(computedParam, res, nDigits); - // } - // else { - // // il y a un paramètre à varier - - // this.addFixedResults(nDigits); - // this.resultsComponent.setVariableParamHeader(varParam); - // this.resultsComponent.setVariableResultHeader(computedParam); - - // let min: number = +varParam.minValue; - // let max: number = +varParam.maxValue; - // let step: number = +varParam.stepValue; - - // for (let val = min; val <= max; val += step) { - // prms[varParam.symbol].v = val; - - // let res = nub.Calc(computedParam.symbol, 0, prec).vCalc; - // this.resultsComponent.addVarResult(val, res, nDigits); - // } - // // for (let vr of this._varResults) { - // // console.log(vr); - // // } - - // this.resultsComponent.setGraphTitle(computedParam.symbol + " = f( " + varParam.symbol + " )"); - // this.resultsComponent.generateGraph(); - // } - // this._showResults = true; - // } - - // private getResultsStyleDisplay() { - // return this._showResults ? "block" : "none"; - // } - - protected getConfigPathPrefix(): string { - return "app/calculators/cond_distri/cond_distri." - } - - protected getNubAndParameters(): [Nub, IParamsEquation] { - let Q: number = this.getParameterValue("Q"); // débit Q - let D: number = this.getParameterValue("D"); // diamètre D - let J: number = this.getParameterValue("J"); // perte de charge J - let Lg: number = this.getParameterValue("Lg"); // Longueur de la conduite Lg - let Nu: number = this.getParameterValue("Nu"); // viscosité dynamique - let prms = new ConduiteDistribParams(Q, D, J, Lg, Nu); - let nub = new ConduiteDistrib(prms); - - return [nub, prms]; - } - - protected getCalculatorResultsComponent(): CalculatorResultsComponent { - return this.resultsComponent; - } +export class CondDistriComponent { } diff --git a/src/app/calculators/generic/calculator.component.html b/src/app/calculators/generic/calculator.component.html new file mode 100644 index 000000000..e3b993013 --- /dev/null +++ b/src/app/calculators/generic/calculator.component.html @@ -0,0 +1,6 @@ +<field-set *ngFor="let fs of fieldSets" [id]=fs.id [fieldSet]=fs (onRadio)=onRadioClick($event) (onSelectChange)=onSelectChanged($event)></field-set> + +<div style="text-align:center;"> + <button type="button" class="button_compute" name="Calculer" (click)="doCompute()" i18n="@@hyd_compute">Calculer</button> +</div> +<calc-results [style.display]="getResultsStyleDisplay()"></calc-results> \ No newline at end of file diff --git a/src/app/calculators/generic/calculator.component.ts b/src/app/calculators/generic/calculator.component.ts index 536b87ce6..8c02a0219 100644 --- a/src/app/calculators/generic/calculator.component.ts +++ b/src/app/calculators/generic/calculator.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, DoCheck, ViewChild } from '@angular/core'; +import { Component, OnInit, DoCheck, ViewChild, Input } from '@angular/core'; import { Response } from '@angular/http'; import { Observable } from "rxjs/Observable"; import 'rxjs/add/operator/toPromise'; @@ -7,12 +7,13 @@ import { IParamsEquation, Nub } from "jalhyd"; import { ParamService } from '../../services/param/param.service'; import { HttpService } from '../../services/http/http.service'; +import { FormulaireService } from '../../services/formulaire/formulaire.service'; import { InternationalisationService } from '../../services/internationalisation/internationalisation.service'; -import { FormulaireDefinition } from '../../calculators/generic/formulaire'; +import { FieldSet, FormulaireDefinition, CalculatorType, Dependency, ExistenceDependency, ValueDependency } from '../../calculators/generic/formulaire'; import { NgParameter, ParamRadioConfig } from './ngparam'; import { CalculatorResultsComponent } from '../../components/calculator-results/calculator-results.component'; +import { Observer } from '../../services/observer'; -/* @Component({ selector: 'hydrocalc', templateUrl: "./calculator.component.html", @@ -24,37 +25,43 @@ import { CalculatorResultsComponent } from '../../components/calculator-results/ ` ] }) -*/ -export abstract class GenericCalculatorComponent implements OnInit, DoCheck { +export class GenericCalculatorComponent implements OnInit, DoCheck, Observer { + /** + * Calculator type input attribute + */ + private _calculatorType: CalculatorType; + + @Input() + private set type(s: string) { + this._calculatorType = CalculatorType[s]; + } + + /** + * composant d'affichage des résultats + */ + @ViewChild(CalculatorResultsComponent) + private resultsComponent: CalculatorResultsComponent; + /** * objet JSON chargé depuis le fichier de traduction */ private _localisation = {}; - // private _fieldSets: FieldSet[] = []; private _formulaire: FormulaireDefinition; - // /** - // * composant d'affichage des résultats - // */ - // @ViewChild(CalculatorResultsComponent) - // private resultsComponent: CalculatorResultsComponent; - /** * flag d'affichage du composant de résultats */ private _showResults: boolean = false; - private paramService: ParamService; - private httpService: HttpService; - private intlService: InternationalisationService; + constructor(private paramService: ParamService, private httpService: HttpService, private intlService: InternationalisationService, private formulaireService: FormulaireService) { + this.intlService.addObserver(this); + } - // constructor(private paramService: ParamService, private httpService: HttpService, private intlService: InternationalisationService) { - constructor(paramService: ParamService, httpService: HttpService, intlService: InternationalisationService) { - this.paramService = paramService; - this.httpService = httpService; - this.intlService = intlService; - this._formulaire = new FormulaireDefinition(paramService); + private get fieldSets(): FieldSet[] { + if (this._formulaire == undefined) + return []; + return this._formulaire.fieldSets; } private loadLocalisation(): Promise<string> { @@ -62,11 +69,9 @@ export abstract class GenericCalculatorComponent implements OnInit, DoCheck { let processData = function (s: string) { // fermeture nécessaire pour capturer la valeur de this (undefined sinon) ths._localisation = JSON.parse(s); - ths.paramService.updateLocalisation(ths._localisation); } - // let f: string = "app/calculators/cond_distri/cond_distri." + this.intlService.currentLanguage.tag + ".json" - let f: string = this.getConfigPathPrefix() + this.intlService.currentLanguage.tag + ".json" + let f: string = this.formulaireService.getConfigPathPrefix(this._calculatorType) + this.intlService.currentLanguage.tag + ".json" let resp: Observable<Response> = this.httpService.httpGetRequestResponse(undefined, undefined, undefined, f); let prom = resp.map(res => res.text()).toPromise(); @@ -77,6 +82,24 @@ export abstract class GenericCalculatorComponent implements OnInit, DoCheck { return prom; } + private loadFormulaire(): Promise<FormulaireDefinition> { + if (this._formulaire == undefined) { + let prom = this.formulaireService.loadFormulaire(this._calculatorType); + prom.then(res => { + this._formulaire = res; + }); + prom.then( + _ => this.loadLocalisation() + ); + prom.then( + _ => this.formulaireService.updateLocalisation(this._localisation) + ); + + return prom; + } + return undefined; + } + private logObject(obj: {}, m?: string) { // évite le message "Value below was evaluated just now" dans le debugger de Chrome if (m == undefined) @@ -85,27 +108,67 @@ export abstract class GenericCalculatorComponent implements OnInit, DoCheck { console.log(m + " " + JSON.stringify(obj)); } - /** - * chaine préfixe pour le chargement de la config et de l'internationalisation - */ - protected abstract getConfigPathPrefix(): string; - - private loadConfig() { - let ths = this; - let processData = function (s: string) { - // fermeture nécessaire pour capturer la valeur de this (undefined sinon) - ths._formulaire.parseConfig(JSON.parse(s)); - ths._formulaire.updateLanguage(ths._localisation); + /* + private getHtmlElementFromId_helper(elm: HTMLElement, id: string): HTMLElement { + if (elm.hasAttribute('id')) + if (elm.getAttribute('id') === id) + return elm; + + let kids: NodeList = elm.childNodes; + for (let i = 0; i < kids.length; i++) { + let kid = kids[i]; + if (kid instanceof HTMLElement) { + let e = this.getHtmlElementFromId_helper(<HTMLElement>kid, id); + if (e != undefined) + return e; + } } - // let f: string = "app/calculators/cond_distri/cond_distri.config.json" - let f: string = this.getConfigPathPrefix() + "config.json" - this.httpService.httpGetRequest(undefined, undefined, undefined, f, processData); + return undefined; + } + + private getHtmlElementFromId(id: string): HTMLElement { + let he: HTMLElement = this.elementRef.nativeElement; + return this.getHtmlElementFromId_helper(he, id); + } + + private getHtmlElementValue(e: HTMLElement): string { + if (e instanceof HTMLSelectElement) + return e.value; + return undefined; + } + private setHtmlElementValue(e: HTMLElement, val: string) { + if (e instanceof HTMLInputElement) + e.value = val; + } + */ + + private applyDependencies() { + if (this._formulaire == undefined) + return; + this._formulaire.applyDependencies(); + + /* + for (let d of this._formulaire.dependencies) { + if (d instanceof ExistenceDependency) { + } + else if (d instanceof ValueDependency) { + let vd = <ValueDependency>d; + let master: HTMLElement = this.getHtmlElementFromId(d.masterElement.id); + if (this.getHtmlElementValue(master) == vd.masterValue) { + let slave: HTMLElement = this.getHtmlElementFromId(d.slaveElement.id); + this.setHtmlElementValue(slave, vd.slaveValue); + } + } + } + */ } ngOnInit() { - this.loadLocalisation(); - this.loadConfig(); + let prom = this.loadFormulaire(); + prom.then( + _ => this.applyDependencies() + ); } ngDoCheck() { @@ -116,13 +179,6 @@ export abstract class GenericCalculatorComponent implements OnInit, DoCheck { // q.maxValue = 6; // q.stepValue = 0.3; // } - - if (this.intlService.localeChanged) { - const promise = this.loadLocalisation() - .then(() => { - this._formulaire.updateLanguage(this._localisation); - }); - } } /* @@ -181,24 +237,7 @@ export abstract class GenericCalculatorComponent implements OnInit, DoCheck { // this.changeDetectorRef.detectChanges(); // provoque une détection des changements dans les contrôles } - - protected getParameterValue(symbol: string): number { - // for (let fs of this._fieldSets) { - // for (let p of fs.params) { - // if (p instanceof NgParameter) - // if (p.symbol === symbol) { - // switch (p.radioState) { - // case ParamRadioConfig.FIX: - // return p.v; - - // case ParamRadioConfig.VAR: - // case ParamRadioConfig.CAL: - // return undefined; - // } - // } - // } - // } return this._formulaire.getParameterValue(symbol); } @@ -211,30 +250,13 @@ export abstract class GenericCalculatorComponent implements OnInit, DoCheck { } private addFixedResults(nDigits: number) { - // for (let fs of this._fieldSets) { - // for (let p of fs.params) { - // if (p instanceof NgParameter) - for (let p of this._formulaire.getInputParameters()) { - if (p.radioState == ParamRadioConfig.FIX && p.symbol !== "Pr") { - this.getCalculatorResultsComponent().addFixedResult(p, p.v, nDigits); - } - // } - } + for (let p of this._formulaire.getInputParameters()) + if (p.radioState == ParamRadioConfig.FIX && p.symbol !== "Pr") + this.resultsComponent.addFixedResult(p, p.v, nDigits); } - protected abstract getNubAndParameters(): [Nub, IParamsEquation]; - - protected abstract getCalculatorResultsComponent(): CalculatorResultsComponent; - private doCompute() { - // let Q: number = this.getParameterValue("Q"); // débit Q - // let D: number = this.getParameterValue("D"); // diamètre D - // let J: number = this.getParameterValue("J"); // perte de charge J - // let Lg: number = this.getParameterValue("Lg"); // Longueur de la conduite Lg - // let Nu: number = this.getParameterValue("Nu"); // Viscosité dynamique Nu - // let prms = new ConduiteDistribParams(Q, D, J, Lg, Nu); - // let nub = new ConduiteDistrib(prms); - let np: [Nub, IParamsEquation] = this.getNubAndParameters(); + let np: [Nub, IParamsEquation] = this.formulaireService.getNubAndParameters(this._calculatorType); let nub: Nub = np[0]; let prms: IParamsEquation = np[1]; @@ -245,22 +267,21 @@ export abstract class GenericCalculatorComponent implements OnInit, DoCheck { let computedParam = this.getComputedParameter(); let varParam = this.getVariatedParameter(); - let resultsComponent: CalculatorResultsComponent = this.getCalculatorResultsComponent(); - resultsComponent.reset(varParam == undefined); + this.resultsComponent.reset(varParam == undefined); if (varParam == undefined) { // pas de paramètre à varier let res = nub.Calc(computedParam.symbol, 0, prec).vCalc; this.addFixedResults(nDigits); - resultsComponent.addFixedResult(computedParam, res, nDigits); + this.resultsComponent.addFixedResult(computedParam, res, nDigits); } else { // il y a un paramètre à varier this.addFixedResults(nDigits); - resultsComponent.setVariableParamHeader(varParam); - resultsComponent.setVariableResultHeader(computedParam); + this.resultsComponent.setVariableParamHeader(varParam); + this.resultsComponent.setVariableResultHeader(computedParam); let min: number = +varParam.minValue; let max: number = +varParam.maxValue; @@ -270,14 +291,14 @@ export abstract class GenericCalculatorComponent implements OnInit, DoCheck { prms[varParam.symbol].v = val; let res = nub.Calc(computedParam.symbol, 0, prec).vCalc; - resultsComponent.addVarResult(val, res, nDigits); + this.resultsComponent.addVarResult(val, res, nDigits); } // for (let vr of this._varResults) { // console.log(vr); // } - resultsComponent.setGraphTitle(computedParam.symbol + " = f( " + varParam.symbol + " )"); - resultsComponent.generateGraph(); + this.resultsComponent.setGraphTitle(computedParam.symbol + " = f( " + varParam.symbol + " )"); + this.resultsComponent.generateGraph(); } this._showResults = true; } @@ -285,4 +306,21 @@ export abstract class GenericCalculatorComponent implements OnInit, DoCheck { private getResultsStyleDisplay() { return this._showResults ? "block" : "none"; } + + // interface Observer + + update(data: any): void { + // message de InternationalisationService + const promise = this.loadLocalisation() + .then(() => { + this.formulaireService.updateLocalisation(this._localisation); + }); + } + + /** + * réception d'un événement d'un select + */ + private onSelectChanged(val: string) { + this.applyDependencies(); + } } diff --git a/src/app/calculators/generic/formulaire.ts b/src/app/calculators/generic/formulaire.ts index 626788aaf..9831daf62 100644 --- a/src/app/calculators/generic/formulaire.ts +++ b/src/app/calculators/generic/formulaire.ts @@ -2,6 +2,11 @@ import { ParamDefinition } from 'jalhyd'; import { NgParameter, ParamRadioConfig } from '../generic/ngparam'; import { ParamService } from '../../services/param/param.service'; +import { StringMap } from '../../stringmap'; + +export enum CalculatorType { + ConduiteDistributrice, LechaptCalmon +} export class FormulaireDefinition { /** @@ -18,7 +23,19 @@ export class FormulaireDefinition { private _dependencies: Dependency[] = []; - constructor(private paramService: ParamService) { + constructor(private paramService: ParamService, private _type: CalculatorType) { + } + + public get type(): CalculatorType { + return this._type; + } + + public get fieldSets(): FieldSet[] { + return this._fieldSets; + } + + public get dependencies(): Dependency[] { + return this._dependencies; } private getFieldSet(id: string) { @@ -116,13 +133,20 @@ export class FormulaireDefinition { return undefined; } + public getFieldById(id: string): Field { + let res = this.getFormulaireElementById(id); + if (res instanceof Field) + return res; + return undefined; + } + private parse_value_dependencies(json: {}, slave: FormulaireElement) { for (let di in json) { let d = json[di]; let refField: FormulaireElement = this.getFormulaireElementById(d["refid"]); if (refField != undefined) { - let refVal = d["refvalue"]; let dep = new ValueDependency(refField, slave); + dep.masterValue = d["refvalue"]; dep.slaveValue = d["value"]; this._dependencies.push(dep); } @@ -154,32 +178,37 @@ export class FormulaireDefinition { } } - private parse_select(json: {}): SelectField { - let id = json["id"]; + private parse_select(field: {}): SelectField { + let id = field["id"]; let res: SelectField = new SelectField(id); - let values = json["select"]; - for (let v of values) - res.addValue(v["id"]); + let values = field["select"]; + + for (let v of values) { + let e: SelectEntry = new SelectEntry(v["id"], undefined); + res.addEntry(e); + } return res; } private parse_input(fieldset: {}, field: {}): NgParameter { let input_id = field["id"]; - let param: NgParameter = this.paramService.getParameter(input_id); - if (param != undefined) { - param.unit = field["unit"]; - param.v = +field["value"]; - param.radioConfig = NgParameter.getRadioConfig(fieldset["option"]); - param.radioState = ParamRadioConfig.FIX; - param.isDefault = false; // malgré le fait qu'il soit initialisé dans la déclaration de la classe NgParam à false, quand on relit sa valeur, il vaut undefined (merci Microsoft) - this.parse_dependencies(param, field); + let res: NgParameter = this.paramService.getParameter(input_id); + if (res != undefined) { + res.unit = field["unit"]; + let val = field["value"]; + if (val != undefined) + res.v = +val; + res.radioConfig = NgParameter.getRadioConfig(fieldset["option"]); + res.radioState = ParamRadioConfig.FIX; + res.isDefault = false; // malgré le fait qu'il soit initialisé dans la déclaration de la classe NgParam à false, quand on relit sa valeur, il vaut undefined (merci Microsoft) } - return param; + return res; } - private parse_fieldset(fieldset: {}, conf_id: string): FieldSet { + private parse_fieldset(fieldset: {}, conf_id: string) { let res: FieldSet = new FieldSet(conf_id); + this._fieldSets.push(res); let fields = fieldset["fields"]; for (let field_index in fields) { @@ -188,13 +217,13 @@ export class FormulaireDefinition { let param = this.parse_input(fieldset, field); if (param != undefined) res.addField(param); + this.parse_dependencies(param, field); } else if (field["type"] === "select") { let param = this.parse_select(field); - if (param != undefined) - res.addField(param); + res.addField(param); + this.parse_dependencies(param, field); } } - return res; } public parseConfig(config: {}) { @@ -209,10 +238,7 @@ export class FormulaireDefinition { // field set if (conf_id.startsWith("fs_")) { - let fieldSet: FieldSet = this.parse_fieldset(conf, conf_id); - if (fieldSet.fields.length > 0) { - this._fieldSets.push(fieldSet); - } + this.parse_fieldset(conf, conf_id); } // options globales else if (conf_id === "options") { @@ -225,39 +251,75 @@ export class FormulaireDefinition { } } - public updateLanguage(localisation: {}) { - for (let conf_index in this._config) { - let conf = this._config[conf_index]; - let conf_id: string = conf["id"]; + private getDependencyFromMasterValue(v: any): Dependency { + for (let d of this._dependencies) + if (d.masterValue === v) + return d; + return undefined; + } - if (conf_id.startsWith("fs_")) { - let fieldSet: FieldSet = this.getFieldSet(conf_id); - if (fieldSet != undefined) - fieldSet.title = localisation[conf_id]; + public applyDependencies() { + for (let d of this.dependencies) { + if (d instanceof ExistenceDependency) { + } + else if (d instanceof ValueDependency) { + let vd = <ValueDependency>d; + /* + let master: HTMLElement = this.getHtmlElementFromId(d.masterElement.id); + if (this.getHtmlElementValue(master) == vd.masterValue) { + let slave: HTMLElement = this.getHtmlElementFromId(d.slaveElement.id); + this.setHtmlElementValue(slave, vd.slaveValue); + } + */ + let master = this.getFieldById(d.masterElement.id); + if (master.getValue() == vd.masterValue) { + let slave = this.getFieldById(d.slaveElement.id); + slave.setValue(vd.slaveValue); + } } } } } -abstract class FormulaireElement { +export abstract class FormulaireElement { private _id: string; private _isDisplayed: boolean; + public label: string; constructor(id: string) { this._id = id; this._isDisplayed = true; } - get id() { + get id(): string { return this._id; } + + public abstract updateLocalisation(loc: StringMap): void; +} + +export enum FieldType { + Input, Select } export abstract class Field extends FormulaireElement { + constructor(id: string, private _type: FieldType) { + super(id); + } + + public get isInput(): boolean { + return this._type == FieldType.Input; + } + + public get isSelect(): boolean { + return this._type == FieldType.Select; + } + + public abstract getValue(): any; + public abstract setValue(val: any): void; } export class FieldSet extends FormulaireElement { - title: string; private _fields: Field[]; constructor(id: string) { @@ -273,8 +335,11 @@ export class FieldSet extends FormulaireElement { this._fields.push(f); } - public get isEmpty(): boolean { - return this._fields.length == 0; + public get hasInputs(): boolean { + for (let f of this._fields) + if (f instanceof NgParameter) + return true; + return false; } public getInput(i: number): NgParameter { @@ -288,24 +353,91 @@ export class FieldSet extends FormulaireElement { } return undefined; } + + public updateLocalisation(loc: StringMap) { + this.label = loc[this.id]; + } +} + +export class SelectEntry { + private _value: string; + public label: string; + + constructor(v: string, l: string) { + this._value = v; + this.label = l; + } + + get value(): string { + return this._value; + } } export class SelectField extends Field { - private _values: string[]; + private _entries: SelectEntry[]; + + public selectedEntry: SelectEntry; + + public get entries() { + return this._entries; + } + + constructor(id: string) { + super(id, FieldType.Select); + this._entries = []; + } + + public addEntry(e: SelectEntry) { + this._entries.push(e); + if (this.selectedEntry == undefined) + this.selectedEntry = e; + } + + public getValue() { + if (this.selectedEntry == undefined) + return undefined; + return this.selectedEntry.value; + } + + public setValue(val: string) { + for (let e of this._entries) + if (e.value === val) { + this.selectedEntry = e; + return; + } + } + + public updateLocalisation(loc: StringMap) { + this.label = loc[this.id]; + for (let e of this._entries) { + e.label = loc[e.value]; + } + } +} + +export class InputField extends Field { + private _value: any; constructor(id: string) { - super(id) - this._values = []; + super(id, FieldType.Input); + } + + public getValue() { + return this._value; + } + + public setValue(val: any) { + this._value = val; } - public addValue(value: string) { - this._values.push(value); + public updateLocalisation(loc: StringMap) { + this.label = loc[this.id]; } } -abstract class Dependency { +export abstract class Dependency { private _master: FormulaireElement; - private _masterValue: any; + public masterValue: any; private _slave: FormulaireElement; @@ -313,6 +445,14 @@ abstract class Dependency { this._master = m; this._slave = s; } + + public get masterElement(): FormulaireElement { + return this._master; + } + + public get slaveElement(): FormulaireElement { + return this._slave; + } } export class ValueDependency extends Dependency { diff --git a/src/app/calculators/generic/ngparam.ts b/src/app/calculators/generic/ngparam.ts index 889c0bf1f..c68dbe4e5 100644 --- a/src/app/calculators/generic/ngparam.ts +++ b/src/app/calculators/generic/ngparam.ts @@ -1,6 +1,7 @@ import { ParamDefinition, ParamDomainValue, ErrorMessage } from 'jalhyd'; -import { Field } from './formulaire'; +import { InputField } from './formulaire'; +import { StringMap } from '../../stringmap'; export enum ParamRadioConfig { /** @@ -22,9 +23,8 @@ export enum ParamRadioConfig { /** * class englobante de ParamDefinition (champs supplémentaires pour l'affichage, radio boutons, ...) */ -export class NgParameter extends Field { +export class NgParameter extends InputField { public unit: string; - public label: string; public radioConfig: ParamRadioConfig; public radioState: ParamRadioConfig; public isDefault: boolean = false; // archi bug du langage ! si on relit cette propriété sans l'avoir modifiée entre-temps, elle vaut undefined ! @@ -69,6 +69,14 @@ export class NgParameter extends Field { this._paramDef.v = val; } + public getValue() { + return this.v; + } + + public setValue(val: number) { + this.v = val; + } + get isDefined(): boolean { return this._paramDef.isDefined; } @@ -89,4 +97,9 @@ export class NgParameter extends Field { throw "invalid parameter radio configuration " + s; } + + + public updateLocalisation(loc: StringMap) { + this.label = loc[this.id]; + } } diff --git a/src/app/calculators/lechapt-calmon/lechapt-calmon.en.json b/src/app/calculators/lechapt-calmon/lechapt-calmon.en.json index 372fff647..983b39412 100644 --- a/src/app/calculators/lechapt-calmon/lechapt-calmon.en.json +++ b/src/app/calculators/lechapt-calmon/lechapt-calmon.en.json @@ -1,10 +1,20 @@ { + "fs_materiau": "Type of material", + "select_material": "Choice of material", + "select_material_1": "Unlined cast iron - Coarse concrete (corrosive water)", + "select_material_2": "Cast steel or uncoated - Coarse concrete (somewhat corrosive water)", + "select_material_3": "Cast steel or cement coating", + "select_material_4": "Cast iron or steel coating bitumen - Centrifuged concrete ", + "select_material_5": "Rolled steel - Smooth concrete", + "select_material_6": "Cast iron or steel coating centrifuged", + "select_material_7": "PVC - Polyethylene", + "select_material_8": "Hydraulically smooth pipe - 0.05 ≤ D ≤ 0.2", + "select_material_9": "Hydraulically smooth pipe - 0.25 ≤ D ≤ 1", "fs_hydraulique": "Hydraulic features", "Q": "Flow", "D": "Pipe diameter", "J": "Head drop", "Lg": "Pipe length", - "Nu": "Dynamic (shear) viscosity", "fs_param_calc": "Calculation parameters", "Pr": "Display accuracy" } \ No newline at end of file diff --git a/src/app/calculators/lechapt-calmon/lechaptcalmon.component.html b/src/app/calculators/lechapt-calmon/lechaptcalmon.component.html index 3a9b25a4b..00f365ed7 100644 --- a/src/app/calculators/lechapt-calmon/lechaptcalmon.component.html +++ b/src/app/calculators/lechapt-calmon/lechaptcalmon.component.html @@ -1,7 +1,10 @@ <h1>Lechapt-Calmon</h1> +<hydrocalc type="LechaptCalmon"></hydrocalc> +<!-- <field-set *ngFor="let fs of _fieldSets" [fieldSet]=fs (onRadio)=onRadioClick($event)></field-set> <div style="text-align:center;"> <button type="button" class="button_compute" name="Calculer" (click)="doCompute()" i18n="@@hyd_compute">Calculer</button> </div> -<calc-results [style.display]="getResultsStyleDisplay()"></calc-results> \ No newline at end of file +<calc-results [style.display]="getResultsStyleDisplay()"></calc-results> +--> \ No newline at end of file diff --git a/src/app/calculators/lechapt-calmon/lechaptcalmon.component.ts b/src/app/calculators/lechapt-calmon/lechaptcalmon.component.ts index 4576a4200..811e4d247 100644 --- a/src/app/calculators/lechapt-calmon/lechaptcalmon.component.ts +++ b/src/app/calculators/lechapt-calmon/lechaptcalmon.component.ts @@ -1,57 +1,8 @@ -import { Component, ViewChild } from '@angular/core'; - -//import { ConduiteDistrib, ConduiteDistribParams } from "jalhyd"; -import { IParamsEquation, Nub, LechaptCalmon, LechaptCalmonParams } from "jalhyd"; - -import { ParamService } from '../../services/param/param.service'; -import { HttpService } from '../../services/http/http.service'; -import { InternationalisationService } from '../../services/internationalisation/internationalisation.service'; -import { GenericCalculatorComponent } from '../generic/calculator.component'; -import { CalculatorResultsComponent } from '../../components/calculator-results/calculator-results.component'; - +import { Component } from '@angular/core'; @Component({ selector: 'lechapt-calmon', - templateUrl: "./lechaptcalmon.component.html", - styles: [` - .button_compute { - height: 3em; - width: 30%; - } - ` - ] + templateUrl: "./lechaptcalmon.component.html" }) -export class LechaptCalmonComponent extends GenericCalculatorComponent { - /** - * composant d'affichage des résultats - */ - @ViewChild(CalculatorResultsComponent) - private resultsComponent: CalculatorResultsComponent; - - constructor(private paramSrv: ParamService, private httpSrv: HttpService, private intlSrv: InternationalisationService) { - super(paramSrv, httpSrv, intlSrv); - } - - protected getConfigPathPrefix(): string { - return "app/calculators/lechapt-calmon/lechapt-calmon." - } - - protected getNubAndParameters(): [Nub, IParamsEquation] { - let Q: number = this.getParameterValue("Q"); // débit Q - let D: number = this.getParameterValue("D"); // diamètre D - let J: number = this.getParameterValue("J"); // perte de charge J - let Lg: number = this.getParameterValue("Lg"); // Longueur de la conduite Lg - let L: number = this.getParameterValue("L"); // paramètre de matériau 1 - let M: number = this.getParameterValue("M"); // paramètre de matériau 2 - let N: number = this.getParameterValue("N"); // paramètre de matériau 3 - - let prms = new LechaptCalmonParams(Q, D, J, Lg, L, M, N); - let nub = new LechaptCalmon(prms); - - return [nub, prms]; - } - - protected getCalculatorResultsComponent(): CalculatorResultsComponent { - return this.resultsComponent; - } +export class LechaptCalmonComponent { } diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts index a25b1fe66..095ffe9d6 100644 --- a/src/app/components/field-set/field-set.component.ts +++ b/src/app/components/field-set/field-set.component.ts @@ -34,7 +34,7 @@ export class FieldSetComponent { } private hasRadioFix(): boolean { - if (!this._fieldSet.isEmpty) + if (this._fieldSet.hasInputs) switch (this._fieldSet.getInput(0).radioConfig) { case ParamRadioConfig.FIX: return false; @@ -46,7 +46,7 @@ export class FieldSetComponent { } private hasRadioVar(): boolean { - if (!this._fieldSet.isEmpty) + if (this._fieldSet.hasInputs) switch (this._fieldSet.getInput(0).radioConfig) { case ParamRadioConfig.VAR: case ParamRadioConfig.CAL: @@ -59,7 +59,7 @@ export class FieldSetComponent { } private hasRadioCal(): boolean { - if (!this._fieldSet.isEmpty) + if (this._fieldSet.hasInputs) switch (this._fieldSet.getInput(0).radioConfig) { case ParamRadioConfig.CAL: return true; @@ -83,4 +83,15 @@ export class FieldSetComponent { @Output() private onRadio = new EventEmitter<string>(); + + /** + * réception d'un événement d'un select + */ + private onSelectChanged(val: string) { + //console.log("fieldset " + val); + this.onSelectChange.emit(val); // on transmet au parent + } + + @Output() + private onSelectChange = new EventEmitter<string>(); } diff --git a/src/app/components/field-set/field-set.html b/src/app/components/field-set/field-set.html index 2fd8f7e51..35773c065 100644 --- a/src/app/components/field-set/field-set.html +++ b/src/app/components/field-set/field-set.html @@ -1,7 +1,7 @@ <table> <tr id="tr_type_section_title"> <td colspan="5"> - <div class="fieldset_title">{{_fieldSet.title}}</div> + <div class="fieldset_title">{{_fieldSet.label}}</div> </td> </tr> <tr id="tr_fs_hydraulique_header"> @@ -10,9 +10,12 @@ <td *ngIf="hasRadioVar()" align="center" class="radio_param_header" i18n="@@radio_param_header_var">Paramètre à varier</td> <td *ngIf="hasRadioCal()" align="center" class="radio_param_header" i18n="@@radio_param_header_cal">Paramètre à calculer</td> </tr> - <tr id="tr_type_section_fs" *ngFor="let p of _fieldSet.params"> - <td colspan="5"> + <tr id="tr_type_section_fs" *ngFor="let p of _fieldSet.fields"> + <td *ngIf="p.isInput" colspan="5"> <param-field-line [symbol]=p.symbol (onRadio)=onRadioClick($event)></param-field-line> </td> + <td *ngIf="p.isSelect" colspan="5"> + <select-field-line [id]=p.id (onSelectChange)=onSelectChanged($event)></select-field-line> + </td> </tr> -</table> +</table> \ No newline at end of file diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts index c17289fde..65682d61f 100644 --- a/src/app/components/param-field-line/param-field-line.component.ts +++ b/src/app/components/param-field-line/param-field-line.component.ts @@ -19,26 +19,19 @@ import { NgParameter, ParamRadioConfig } from '../../calculators/generic/ngparam }` ] }) -export class ParamFieldLineComponent implements DoCheck { +export class ParamFieldLineComponent { private _param: NgParameter; constructor(private paramService: ParamService) { } - /** - * associated (localised) label - */ - private _label: string; - - /** - * associated unit - */ - get _unit(): string { - return this._param.unit; - } - - private updateLanguage() { - this._label = this._param.label; + private get title(): string { + let t = ""; + if (this._param.label != undefined) + t = this._param.label; + if (this._param.unit != undefined && this._param.unit != "") + t = t + " (" + this._param.unit + ")"; + return t; } /** @@ -47,7 +40,6 @@ export class ParamFieldLineComponent implements DoCheck { @Input() private set symbol(s: string) { this._param = this.paramService.getParameter(s); - this.updateLanguage(); } /** @@ -57,10 +49,6 @@ export class ParamFieldLineComponent implements DoCheck { return this._param.symbol; } - public ngDoCheck() { - this.updateLanguage(); - } - /** * calcule la présence du radio "paramètre fixé" */ diff --git a/src/app/components/param-field-line/param-field-line.html b/src/app/components/param-field-line/param-field-line.html index a3fc4efb4..162c64fc2 100644 --- a/src/app/components/param-field-line/param-field-line.html +++ b/src/app/components/param-field-line/param-field-line.html @@ -1,5 +1,5 @@ <tr id="tr_FT_rLargeurFond"> - <td align="right" class="param_title">{{_label}} ({{_unit}})</td> + <td align="right" class="param_title">{{title}}</td> <td> <!-- diff --git a/src/app/components/param-input/param-input.component.html b/src/app/components/param-input/param-input.component.html index 5d2fedc79..b19228b74 100644 --- a/src/app/components/param-input/param-input.component.html +++ b/src/app/components/param-input/param-input.component.html @@ -4,16 +4,13 @@ i18n="<meaning>|<description>@@<custom id>" <p i18n="titre saisie|Titre du contrôle de saisie de paramètre@@titre_saisie_param">Saisie de paramètre</p> --> <p *ngIf="displayTitle" i18n="@@titre_saisie_param">Saisie de paramètre</p> +<input placeholder="{{_paramDef.symbol}}" [ngModel]="_uiValue.uncheckedValueString" (ngModelChange)="setValue($event)" /> +<br/> {{_message}} +<!-- +<p *ngIf="displayTitle" i18n="@@titre_saisie_param">Saisie de paramètre</p> <md-input-container> <input mdInput placeholder="{{_paramDef.symbol}}" [ngModel]="_uiValue.uncheckedValueString" (ngModelChange)="setValue($event)" /> <md-hint>{{_message}}</md-hint> </md-input-container> -<!-- - <md-error *ngIf="_message"> - {{_message}} - </md-error> - <input mdInput placeholder="{{_paramDef.symbol}}" [ngModel]="getValue()" (ngModelChange)="setValue($event)" /> - <md-error *ngIf="hasError()"> - <md-hint *ngIf="hasError()">{{_message}}</md-hint> --> \ No newline at end of file diff --git a/src/app/components/param-input/param-input.component.ts b/src/app/components/param-input/param-input.component.ts index 60ac6f369..9ea37e20d 100644 --- a/src/app/components/param-input/param-input.component.ts +++ b/src/app/components/param-input/param-input.component.ts @@ -43,10 +43,6 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec private _message: string; - private static _idGen: number = 0; // A VIRER - private _id: number; // A VIRER - private static _startTime: number; // A VIRER - /** * flag d'affichage du titre */ @@ -65,10 +61,6 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec private _uiValue: NumericalString; constructor(private paramService: ParamService, private changeDetector: ChangeDetectorRef, private intlService: InternationalisationService) { - this._id = ParamInputComponent._idGen++; - if (ParamInputComponent._startTime == undefined) - ParamInputComponent._startTime = new Date().getTime(); - this._uiValue = new NumericalString(); } @@ -101,14 +93,6 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec this._paramDef = this.paramService.getParameter(this._paramSymbol); } - // private getValue() { - // if (this._paramDef.isDefined) - // return this._paramDef.v; - // return ""; - - // // return this._uiValue.value; - // } - /** * fonction appelée lorsque l'utilisateur fait une saisie * @param event valeur du contrôle @@ -207,10 +191,9 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec return null; } - private log(m: string) { - let t: number = new Date().getTime() - ParamInputComponent._startTime; - console.log("ParamInputComponent(" + this._id + ") " + t + " : " + m); - } + // private log(m: string) { + // console.log("ParamInputComponent(" + this._id + ") : " + m); + // } // ControlValueAccessor interface @@ -225,7 +208,7 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec } */ writeValue(value: any) { - this.log("writeValue " + value); + // this.log("writeValue " + value); } registerOnChange(fn: any) { diff --git a/src/app/components/select-field-line/select-field-line.component.ts b/src/app/components/select-field-line/select-field-line.component.ts new file mode 100644 index 000000000..4a2a11f4a --- /dev/null +++ b/src/app/components/select-field-line/select-field-line.component.ts @@ -0,0 +1,50 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; + +import { SelectField, SelectEntry } from '../../calculators/generic/formulaire'; +import { FormulaireService } from '../../services/formulaire/formulaire.service'; + +@Component({ + selector: 'select-field-line', + templateUrl: "./select-field-line.html", +}) +export class SelectFieldLineComponent { + private _select: SelectField; + + private currentValue: string; + + constructor(private formulaireService: FormulaireService) { + } + + private get entries(): SelectEntry[] { + return this._select.entries; + } + + /** + * id input attribute + */ + private _id: string; + + @Input() + private set id(s: string) { + this._id = s; + this.updateSelect(); + } + + /** + * selected value event + */ + @Output() + private onSelectChange = new EventEmitter<string>(); + + private updateSelect() { + this._select = this.formulaireService.getSelectField(this._id); + if (this._select.selectedEntry != undefined) + this.currentValue = this._select.selectedEntry.value; + } + + private onSelect(event: any) { + let val = event.target.value; + this._select.setValue(val); + this.onSelectChange.emit(val); + } +} diff --git a/src/app/components/select-field-line/select-field-line.html b/src/app/components/select-field-line/select-field-line.html new file mode 100644 index 000000000..9041cd726 --- /dev/null +++ b/src/app/components/select-field-line/select-field-line.html @@ -0,0 +1,8 @@ +<tr> + <td align="right">{{_select.label}}</td> + <td colspan="3"> + <select [(ngModel)]=currentValue (change)=onSelect($event)> + <option *ngFor="let e of entries" [value]=e.value>{{e.label}}</option> +</select> + </td> +</tr> \ No newline at end of file diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts new file mode 100644 index 000000000..90925ed38 --- /dev/null +++ b/src/app/services/formulaire/formulaire.service.ts @@ -0,0 +1,130 @@ +import { Injectable } from '@angular/core'; +import { Response } from '@angular/http'; + +import { IParamsEquation, Nub, ConduiteDistrib, ConduiteDistribParams, LechaptCalmon, LechaptCalmonParams } from "jalhyd"; + +import { ParamService } from '../param/param.service'; +import { HttpService } from '../../services/http/http.service'; +import { FormulaireDefinition, FormulaireElement, CalculatorType, SelectField } from '../../calculators/generic/formulaire'; +import { StringMap } from '../../stringmap'; + +@Injectable() +export class FormulaireService { + private _formulaires: FormulaireDefinition[]; + + constructor(private paramService: ParamService, private httpService: HttpService) { + this._formulaires = []; + } + + private loadConfig(form: FormulaireDefinition, ct: CalculatorType): Promise<Response> { + let processData = function (s: string) { + form.parseConfig(JSON.parse(s)); + } + + let f: string = this.getConfigPathPrefix(ct) + "config.json" + return this.httpService.httpGetRequest(undefined, undefined, undefined, f, processData); + } + + public loadFormulaire(ct: CalculatorType): Promise<FormulaireDefinition> { + if (ct == undefined) + throw "FormulaireService.getFormulaire() : invalid undefined CalculatorType" + + let f = new FormulaireDefinition(this.paramService, ct); + this._formulaires.push(f); + let pr: Promise<FormulaireDefinition> = this.loadConfig(f, ct) + .then(res => { + return f; + }); + return pr; + } + + private getFormulaire(ct: CalculatorType): FormulaireDefinition { + if (ct == undefined) + throw "FormulaireService.getFormulaire() : invalid undefined CalculatorType" + + for (let f of this._formulaires) { + if (f.type == ct) + return f; + } + + throw "FormulaireService.getFormulaire() : type '" + ct + "' form is not loaded"; + } + + private getFormulaireElementById(id: string): FormulaireElement { + for (let f of this._formulaires) { + let s = f.getFormulaireElementById(id); + if (s != undefined) + return s; + } + return undefined; + } + + public getSelectField(id: string): SelectField { + for (let f of this._formulaires) { + let s = f.getFormulaireElementById(id); + if (s != undefined) + if (!(s instanceof SelectField)) + throw "Form element with id '" + id + "' is not a select"; + return <SelectField>s; + } + return undefined; + } + + public updateLocalisation(localisation: StringMap) { + for (let loc_id in localisation) { + let fe = this.getFormulaireElementById(loc_id); + if (fe != undefined) + fe.updateLocalisation(localisation); + } + } + + public getNubAndParameters(ct: CalculatorType): [Nub, IParamsEquation] { + let f = this.getFormulaire(ct); + switch (ct) { + case CalculatorType.ConduiteDistributrice: + { + let Q: number = f.getParameterValue("Q"); // débit Q + let D: number = f.getParameterValue("D"); // diamètre D + let J: number = f.getParameterValue("J"); // perte de charge J + let Lg: number = f.getParameterValue("Lg"); // Longueur de la conduite Lg + let Nu: number = f.getParameterValue("Nu"); // viscosité dynamique + let prms = new ConduiteDistribParams(Q, D, J, Lg, Nu); + let nub = new ConduiteDistrib(prms); + return [nub, prms]; + } + + case CalculatorType.LechaptCalmon: + { + let Q: number = f.getParameterValue("Q"); // débit Q + let D: number = f.getParameterValue("D"); // diamètre D + let J: number = f.getParameterValue("J"); // perte de charge J + let Lg: number = f.getParameterValue("Lg"); // Longueur de la conduite Lg + let L: number = f.getParameterValue("L"); // paramètre de matériau 1 + let M: number = f.getParameterValue("M"); // paramètre de matériau 2 + let N: number = f.getParameterValue("N"); // paramètre de matériau 3 + let prms = new LechaptCalmonParams(Q, D, J, Lg, L, M, N); + let nub = new LechaptCalmon(prms); + return [nub, prms]; + } + + default: + throw "FormulaireService.getNubAndParameters() : valeur de CalculatorType " + ct + " non implémentée" + } + } + + public getConfigPathPrefix(ct: CalculatorType): string { + if (ct == undefined) + throw "FormulaireService.getConfigPathPrefix() : invalid undefined CalculatorType" + + switch (ct) { + case CalculatorType.ConduiteDistributrice: + return "app/calculators/cond_distri/cond_distri."; + + case CalculatorType.LechaptCalmon: + return "app/calculators/lechapt-calmon/lechapt-calmon."; + + default: + throw "FormulaireService.getConfigPathPrefix() : valeur de CalculatorType " + ct + " non implémentée" + } + } +} diff --git a/src/app/services/http/http.service.ts b/src/app/services/http/http.service.ts index ecc167c56..1c1556acd 100644 --- a/src/app/services/http/http.service.ts +++ b/src/app/services/http/http.service.ts @@ -17,7 +17,7 @@ export class HttpService { return s1 + s2; } - public httpGetRequest(protocol: string, host: string, port: number, path: string, processDataCallback: (s: string) => void) { + public httpGetRequest(protocol: string, host: string, port: number, path: string, processDataCallback: (s: string) => void): Promise<Response> { let resp: Observable<Response> = this.httpGetRequestResponse(protocol, host, port, path); resp.map(res => res.text()) @@ -26,6 +26,8 @@ export class HttpService { // err => this.logError(err), // () => console.log('Random Quote Complete') ); + + return resp.toPromise(); } public httpGetRequestResponse(protocol: string, host: string, port: number, path: string): Observable<Response> { diff --git a/src/app/services/internationalisation/internationalisation.service.ts b/src/app/services/internationalisation/internationalisation.service.ts index 7cfef3139..f17f03aa7 100644 --- a/src/app/services/internationalisation/internationalisation.service.ts +++ b/src/app/services/internationalisation/internationalisation.service.ts @@ -1,8 +1,11 @@ import { Injectable } from '@angular/core'; +import { Response } from '@angular/http'; import { ErrorMessage, ErrorCode } from "jalhyd"; import { HttpService } from "../http/http.service"; +import { Observable } from "../observer"; +import { StringMap } from "../../stringmap"; /* language tag : fr-FR @@ -41,19 +44,15 @@ export class Language { } @Injectable() -export class InternationalisationService { +export class InternationalisationService extends Observable { private _currLang: Language; private _sLang: string; - private _errorMessages: { [key: string]: string }; + private _errorMessages: StringMap; private _languages: Language[]; - /** - * indique que la langue a été changée - */ - private _localeChanged: boolean = false; - public constructor(private httpService: HttpService) { + super(); this._languages = []; this._languages.push(new Language(LanguageCode.FRENCH, "fr", "Français")); this._languages.push(new Language(LanguageCode.ENGLISH, "en", "English")); @@ -96,30 +95,14 @@ export class InternationalisationService { else { this._currLang = this.getLanguageFromCode(lng); } - this._localeChanged = this._currLang.code != oldLang; - - // this.loadErrorMessages(); - this.httpGetErrorMessages(); + let prom = this.httpGetErrorMessages(); + prom.then((res) => { + this.notifyObservers(undefined); + }) } - // private loadErrorMessages() { - // let l; - // switch (this.lang) { - // case Language.FRENCH: - // l = "fr"; - // break; - - // default: - // l = "en"; - // } - - // let s: string = fs.readFileSync("src/error_messages." + l + ".json", "utf8"); - // this._errorMessages = JSON.parse(s); - // } - - - private httpGetErrorMessages() { + private httpGetErrorMessages(): Promise<Response> { let is: InternationalisationService = this; let processData = function (s: string) { // fermeture nécessaire pour capturer la valeur de this (undefined sinon) @@ -137,7 +120,7 @@ export class InternationalisationService { } let f: string = "error_messages." + l + ".json" - this.httpService.httpGetRequest(undefined, undefined, undefined, "locale/" + f, processData); + return this.httpService.httpGetRequest(undefined, undefined, undefined, "locale/" + f, processData); } private getErrorMessageFromCode(c: ErrorCode): string { @@ -159,12 +142,4 @@ export class InternationalisationService { return m; } - - get localeChanged() { - return this._localeChanged; - } - - public acknowledgeLocaleChanged() { - this._localeChanged = false; - } } diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts index 935cc3f8a..64ca6dfe9 100644 --- a/src/app/services/param/param.service.ts +++ b/src/app/services/param/param.service.ts @@ -15,6 +15,7 @@ export class ParamService { this._params.push(new NgParameter(pr)); this.addParameters("cond_distri"); + this.addParameters("lechapt_calmon"); } private hasParameter(symbol: string): boolean { @@ -44,7 +45,7 @@ export class ParamService { } } - getParameter(s: string): NgParameter { + public getParameter(s: string): NgParameter { for (let p of this._params) { if (p.symbol == s) return p; @@ -52,12 +53,4 @@ export class ParamService { return undefined; } - - updateLocalisation(loc: { [key: string]: string }) { - for (let ki in loc) { - let p = this.getParameter(ki); - if (p != undefined) - p.label = loc[ki]; - } - } } diff --git a/src/app/stringmap.ts b/src/app/stringmap.ts new file mode 100644 index 000000000..75efb4f15 --- /dev/null +++ b/src/app/stringmap.ts @@ -0,0 +1,3 @@ +export interface StringMap { + [key: string]: string; +} -- GitLab