Newer
Older
francois.grand
committed
import { Injectable } from "@angular/core";
import { Response } from "@angular/http";
import { Observable as rxObservable } from "rxjs/Observable";
import "rxjs/add/operator/toPromise";
francois.grand
committed
import { decode } from "he";
import { CalculatorType, EnumEx, Observable } from "jalhyd";
francois.grand
committed
import { ServiceFactory } from "../service-factory";
francois.grand
committed
import { HttpService } from "../../services/http/http.service";
import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
francois.grand
committed
import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
francois.grand
committed
import { FormulaireElement } from "../../formulaire/formulaire-element";
import { InputField } from "../../formulaire/input-field";
francois.grand
committed
import { SelectField } from "../../formulaire/select-field";
import { CheckField } from "../../formulaire/check-field";
import { StringMap } from "../../stringmap";
francois.grand
committed
import { FormulaireConduiteDistributrice } from "../../formulaire/definition/concrete/form-cond-distri";
import { FormulaireLechaptCalmon } from "../../formulaire/definition/concrete/form-lechapt-calmon";
import { FormulaireSectionParametree } from "../../formulaire/definition/concrete/form-section-parametree";
import { FormulaireCourbeRemous } from "../../formulaire/definition/concrete/form-courbe-remous";
import { FormulaireRegimeUniforme } from "../../formulaire/definition/concrete/form-regime-uniforme";
import { FormulairePasseBassinDimensions } from "../../formulaire/definition/concrete/form-passe-bassin-dim";
import { FormulairePasseBassinPuissance } from "../../formulaire/definition/concrete/form-passe-bassin-puissance";
import { FormulaireParallelStructure } from "../../formulaire/definition/concrete/form-parallel-structures";
export class FormulaireService extends Observable {
private _formulaires: FormulaireDefinition[];
private _currentFormId = -1;
francois.grand
committed
constructor() {
francois.grand
committed
private get _intlService(): InternationalisationService {
return ServiceFactory.instance.internationalisationService;
}
private get _httpService(): HttpService {
return ServiceFactory.instance.httpService;
}
public get formulaires(): FormulaireDefinition[] {
return this._formulaires;
}
private loadLocalisation(calc: CalculatorType): Promise<any> {
francois.grand
committed
let f: string = this.getConfigPathPrefix(calc) + this._intlService.currentLanguage.tag + ".json"
let resp: rxObservable<Response> = this._httpService.httpGetRequestResponse(undefined, undefined, undefined, f);
let prom = resp.map(res => res.text()).toPromise();
return prom.then((res) => {
let j = JSON.parse(res);
return j as StringMap;
})
}
/**
* met à jour la langue du formulaire
* @param formId id unique du formulaire
* @param localisation ensemble id-message traduit
*/
private updateFormulaireLocalisation(formId: number, localisation: StringMap) {
for (let f of this._formulaires)
if (f.uid == formId) {
f.updateLocalisation(localisation);
break;
}
/**
* met à jour l'aide du formulaire
* @param formId id unique du formulaire
*/
private updateFormulaireHelp(formId: number) {
for (let f of this._formulaires)
if (f.uid == formId) {
f.updateHelp();
break;
}
}
/**
* charge la localisation et met à jour la langue du formulaire
*/
private loadUpdateFormulaireLocalisation(f: FormulaireDefinition): Promise<any> {
return this.loadLocalisation(f.calculatorType)
.then(localisation => {
this.updateFormulaireLocalisation(f.uid, localisation);
this.updateFormulaireHelp(f.uid);
});
}
public updateLocalisation() {
for (const c of EnumEx.getValues(CalculatorType)) {
const prom: Promise<StringMap> = this.loadLocalisation(c);
prom.then(loc => {
for (const f of this._formulaires)
if (f.calculatorType == c)
this.updateFormulaireLocalisation(f.uid, loc);
}
);
}
}
public getLocalisedTitleFromCalculatorType(type: CalculatorType) {
switch (type) {
case CalculatorType.ConduiteDistributrice:
francois.grand
committed
return this._intlService.localizeText("INFO_CONDDISTRI_TITRE");
case CalculatorType.LechaptCalmon:
francois.grand
committed
return this._intlService.localizeText("INFO_LECHAPT_TITRE");
case CalculatorType.RegimeUniforme:
francois.grand
committed
return this._intlService.localizeText("INFO_REGUNI_TITRE");
case CalculatorType.SectionParametree:
francois.grand
committed
return this._intlService.localizeText("INFO_SECTPARAM_TITRE");
case CalculatorType.CourbeRemous:
francois.grand
committed
return this._intlService.localizeText("INFO_REMOUS_TITRE")
case CalculatorType.PabDimensions:
francois.grand
committed
return this._intlService.localizeText("INFO_PABDIM_TITRE")
case CalculatorType.PabPuissance:
francois.grand
committed
return this._intlService.localizeText("INFO_PABPUISS_TITRE")
case CalculatorType.ParallelStructure:
francois.grand
committed
return this._intlService.localizeText("INFO_OUVRAGEPARAL_TITRE")
default:
return "Invalid calculator type " + type;
}
}
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"
francois.grand
committed
return this._httpService.httpGetRequest(undefined, undefined, undefined, f, processData);
private newFormulaire(ct: CalculatorType, jsonState?: {}): FormulaireDefinition {
francois.grand
committed
let f: FormulaireDefinition;
switch (ct) {
case CalculatorType.ConduiteDistributrice:
francois.grand
committed
f = new FormulaireConduiteDistributrice();
francois.grand
committed
break;
case CalculatorType.LechaptCalmon:
francois.grand
committed
f = new FormulaireLechaptCalmon();
francois.grand
committed
break;
case CalculatorType.SectionParametree:
francois.grand
committed
f = new FormulaireSectionParametree();
francois.grand
committed
break;
case CalculatorType.RegimeUniforme:
francois.grand
committed
f = new FormulaireRegimeUniforme();
francois.grand
committed
break;
case CalculatorType.CourbeRemous:
francois.grand
committed
f = new FormulaireCourbeRemous();
francois.grand
committed
break;
case CalculatorType.PabDimensions:
francois.grand
committed
f = new FormulairePasseBassinDimensions();
francois.grand
committed
break;
case CalculatorType.PabPuissance:
francois.grand
committed
f = new FormulairePasseBassinPuissance();
francois.grand
committed
break;
case CalculatorType.ParallelStructure:
francois.grand
committed
f = new FormulaireParallelStructure();
break;
francois.grand
committed
default:
throw new Error(`FormulaireService.createFormulaire() : type de calculette ${ct} non pris en charge`)
}
if (jsonState !== undefined) {
const props = jsonState["props"];
f.initSessionNub(props);
}
else
f.initSessionNub();
return f;
}
/**
* crée un formulaire d'un type donné
* @param ct type de formulaire
* @param jsonState
*/
public createFormulaire(ct: CalculatorType, jsonState?: {}): Promise<FormulaireDefinition> {
const f: FormulaireDefinition = this.newFormulaire(ct, jsonState);
if (jsonState === undefined)
f.calculatorName = decode(this.getLocalisedTitleFromCalculatorType(ct) + " (" + f.uid + ")");
let prom: Promise<Response> = this.loadConfig(f, ct);
return prom.then(_ => {
if (jsonState !== undefined)
f.deserialiseJSON(jsonState);
return f;
}).then(f => {
this.loadUpdateFormulaireLocalisation(f);
return f;
}).then(f => {
f.applyDependencies();
return f;
}).then(f => {
this.notifyObservers(
{
"form": f
});
public getFormulaireFromId(uid: number): FormulaireDefinition {
for (let f of this._formulaires)
francois.grand
committed
return undefined;
public getInputField(formId: number, elemId: string): InputField {
let s = this.getFormulaireElementById(formId, elemId);
if (!(s instanceof InputField))
throw "Form element with id '" + elemId + "' is not an input";
return <InputField>s;
}
public getCheckField(formId: number, elemId: string): CheckField {
let s = this.getFormulaireElementById(formId, elemId);
if (!(s instanceof CheckField))
throw "Form element with id '" + elemId + "' is not a checkbox";
return <CheckField>s;
public getSelectField(formId: number, elemId: string): SelectField {
let s = this.getFormulaireElementById(formId, elemId);
if (!(s instanceof SelectField))
throw "Form element with id '" + elemId + "' is not a select";
return <SelectField>s;
private getFormulaireElementById(formId: number, elemId: string): FormulaireElement {
for (let f of this._formulaires)
if (f.uid == formId) {
francois.grand
committed
let s = f.getFormulaireNodeById(elemId);
if (s != undefined)
francois.grand
committed
return s as FormulaireElement;
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.";
case CalculatorType.SectionParametree:
return "app/calculators/section-param/section-param.";
case CalculatorType.RegimeUniforme:
return "app/calculators/regime-uniforme/regime-uniforme.";
francois.grand
committed
case CalculatorType.CourbeRemous:
return "app/calculators/remous/remous.";
case CalculatorType.PabDimensions:
return "app/calculators/pab-dimensions/pab-dimensions.";
case CalculatorType.PabPuissance:
return "app/calculators/pab-puissance/pab-puissance.";
case CalculatorType.Structure:
return "app/calculators/ouvrages/ouvrages.";
case CalculatorType.ParallelStructure:
return "app/calculators/parallel-structures/parallel-structures.";
default:
throw "FormulaireService.getConfigPathPrefix() : valeur de CalculatorType " + ct + " non implémentée"
}
}
public requestCloseForm(uid: number) {
const form = this.getFormulaireFromId(uid);
if (form != undefined) {
this._formulaires = this._formulaires.filter(f => f.uid !== uid);
this.notifyObservers({
"form": form
});
}
}
public get currentFormId() {
return this._currentFormId;
}
public setCurrentForm(formId: number) {
const form = this.getFormulaireFromId(formId);
if (form == undefined) {
this._currentFormId = -1;
this.notifyObservers({
"action": "invalidFormId",
"formId": formId
});
}
else {
this._currentFormId = formId;
this.notifyObservers({
"action": "currentFormChanged",
"formId": formId
francois.grand
committed
private get currentForm(): FormulaireDefinition {
return this.getFormulaireFromId(this._currentFormId);
}
public get currentFormHasResults(): boolean {
const form = this.currentForm;
if (form != undefined)
return form.hasResults;
return false;
}
francois.grand
committed
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
private readSingleFile(file: File): Promise<any> {
return new Promise<any>((resolve, reject) => {
var fr = new FileReader();
fr.onload = () => {
resolve(fr.result);
};
fr.onerror = () => {
fr.abort();
reject(new Error(`Erreur de lecture du fichier ${file.name}`));
};
fr.readAsText(file);
});
}
public loadSession(f: File) {
this.readSingleFile(f).then(s => {
const session = JSON.parse(s);
for (const k in session)
switch (k) {
case "session":
this.deserialiseSession(session[k]);
break;
default:
throw new Error(`session file : invalid key '${k}'`);
}
}).catch(err => {
throw err;
});
francois.grand
committed
public saveForm(f: FormulaireDefinition) {
this.notifyObservers({
"action": "saveForm",
"form": f
});
}
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
private deserialiseForm(elements: {}) {
const props = elements["props"];
const ct: CalculatorType = props["calcType"];
this.createFormulaire(ct, elements);
}
private deserialiseSessionElement(element: {}) {
const keys = Object.keys(element);
if (keys.length !== 1)
throw new Error(`session file : invalid session object '${element}'`);
switch (keys[0]) {
case "form":
this.deserialiseForm(element[keys[0]]);
break;
default:
throw new Error(`session file : invalid key '${keys[0]}' in session object`);
}
}
private deserialiseSession(elements: {}) {
for (const ks in elements)
switch (ks) {
case "elements":
for (const e of elements[ks])
this.deserialiseSessionElement(e);
break;
default:
throw new Error(`session file : invalid key '${ks}' in session object`);
}
}