diff --git a/src/app/calculators/parallel-structures/parallel-structures.config.json b/src/app/calculators/parallel-structures/parallel-structures.config.json index 754c7ad59e25617462c8effce9f0b2988ebc3a40..20c22185c6a9ef345fb5b19c37d3de9dc2dd6dd1 100644 --- a/src/app/calculators/parallel-structures/parallel-structures.config.json +++ b/src/app/calculators/parallel-structures/parallel-structures.config.json @@ -27,7 +27,9 @@ "id": "fs_ouvrage", "type": "fieldset_template", "calcType": "Structure", - "nodeType": "None", + "defaultNodeType": "StructureRectangle", + "defaultStructType": "VanneRectangulaire", + "defaultLoiDebit": "Cem88v", "option": "cal", "fields": [ { @@ -121,6 +123,10 @@ { "refid": "select_ouvrage", "refvalue": "select_ouvrage_seuil_rect" + }, + { + "refid": "select_loidebit1", + "refvalue": "select_loidebit1_kivi" } ] }, @@ -137,12 +143,17 @@ { "refid": "select_ouvrage", "refvalue": "select_ouvrage_seuil_rect" + }, + { + "refid": "select_loidebit1", + "refvalue": "select_loidebit1_kivi" } ] }, { "type": "input", "id": "W", + "nodeType": "StructureRectangle", "unit": "m", "dep_exist": [ { diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts index e091ef408152e70017bb85f9d237d3c3e8d16785..5f79ed52e0e607a024db089edf57c3f31ec770d7 100644 --- a/src/app/components/fieldset-container/fieldset-container.component.ts +++ b/src/app/components/fieldset-container/fieldset-container.component.ts @@ -1,8 +1,6 @@ import { Component, Input, Output, EventEmitter, QueryList, ViewChildren, DoCheck } from "@angular/core"; import { FieldsetContainer } from "../../formulaire/fieldset-container"; -import { SelectEntry } from "../../formulaire/select-entry"; -import { FieldSet } from "../../formulaire/fieldset"; import { FieldSetComponent } from "../field-set/field-set.component"; @Component({ @@ -35,7 +33,7 @@ export class FieldsetContainerComponent implements DoCheck { } private addStructure() { - this._container.addFromTemplate(this._container.templates[0].id); + this._container.addFromTemplate(0); } /* @@ -114,4 +112,4 @@ export class FieldsetContainerComponent implements DoCheck { private onInputChange(event: boolean) { this.inputChange.emit(); } -} \ No newline at end of file +} diff --git a/src/app/formulaire/definition/concrete/form-parallel-structures.ts b/src/app/formulaire/definition/concrete/form-parallel-structures.ts index 32ec9883091aa84766c6ffb8f9fdbcff1d393380..7882cce11450b8f677a622712bc313af500fac2d 100644 --- a/src/app/formulaire/definition/concrete/form-parallel-structures.ts +++ b/src/app/formulaire/definition/concrete/form-parallel-structures.ts @@ -1,4 +1,4 @@ -import { CalculatorType, CreateStructure, StructureType, LoiDebit, ComputeNodeType, Structure, ParallelStructure } from "jalhyd"; +import { CalculatorType, ComputeNodeType, Structure, ParallelStructure, SessionNub } from "jalhyd"; import { FormulaireDefinition } from "../form-definition"; import { CalculatorResults } from "../../../results/calculator-results"; @@ -13,6 +13,7 @@ import { FieldsetContainer } from "../../fieldset-container"; import { FieldSet } from "../../fieldset"; import { SelectField } from "../../select-field"; import { NgParameter } from "../../ngparam"; +import { FieldsetTemplate } from "../../fieldset-template"; export class FormulaireParallelStructure extends FormulaireDefinition { private _formFixedVar: FormDefFixedVar; @@ -34,7 +35,27 @@ export class FormulaireParallelStructure extends FormulaireDefinition { this._formCompute = new FormComputeParallelStructures(this, this._formParallelStruct, this._formResult); } - protected createNubs() { + private createStructNub(templ: FieldsetTemplate): SessionNub { + const paramService: ParamService = ServiceFactory.instance.paramService; + + // valeurs par défaut de CalculatorType, ComputeNodeType, StructureType, LoiDebit + // !!! attention !!! pour l'instant, il doit y avoir cohérence entre ces valeurs et celles du fichier de conf + // cad valeur par défaut du 1er select (type d'ouvrage), du 2ème (loi de débit). + // A terme, il faudrait analyser le fichier de conf (dépendances d'existence) pour déterminer automatiquement ces valeurs + const params = FieldSet.makeDefaultProps(templ.calcTypeFromConfig, templ.defaultNodeTypeFromConfig); + return paramService.createSessionNub(params); + } + + public addStructureNub(st: Structure) { + this.parallelStructureNub.addStructure(st); + } + + private get parallelStructureNub(): ParallelStructure { + const params = { + "calcType": CalculatorType.ParallelStructure, + "nodeType": ComputeNodeType.None + }; + return this.getSessionNub(params).nub as ParallelStructure; } protected initParse() { @@ -60,41 +81,6 @@ export class FormulaireParallelStructure extends FormulaireDefinition { * @return une chaîne représentant le "contexte" courant (ici, combinaison type d'ouvrage-loi de débit) * @param fs FieldSet contenant les listes déroulantes type d'ouvrage et loi de débit */ - private getContext(fs: FieldSet): string { - // type d'ouvrage courant - const fsStructType = this._formParallelStruct.getStructureType(fs); - - // loi de débit courante - const loiDebit = this._formParallelStruct.getLoiDebit(fs); - - return `${StructureType[fsStructType]}-${LoiDebit[loiDebit]}` - } - - /** - * réinitialisation du formulaire. - * en plus de du comportement par défaut, on remet les valeurs des champs en fonction du contexte - * (type de structure, loi de débit) - */ - public reset() { - super.reset(); - - for (const e of this.allFormElements) { - if (e instanceof FieldSet) { - const fs = e as FieldSet; - if (!fs.isTemplate && fs.calculatorType === CalculatorType.Structure) { - const fsStructType: StructureType = this._formParallelStruct.getStructureType(fs); - const loiDebit: LoiDebit = this._formParallelStruct.getLoiDebit(fs); - const st = CreateStructure(fsStructType, loiDebit); - - for (const p of fs.allFormElements) - if (p instanceof NgParameter && p.isDisplayed) { - const defaultParam = st.prms.map[p.symbol]; - p.resetValue(this, this.getContext(fs), defaultParam.v); - } - } - } - } - } public resetResults() { this._formResult.resetResults(); @@ -154,18 +140,5 @@ export class FormulaireParallelStructure extends FormulaireDefinition { // la valeur d'un des select (type d'ouvrage, loi de débit) a changé this.reset(); } - // else if (sender instanceof NgParameter) { - else { - switch (data.action) { - case "ngparamBeforeValue": // la valeur d'un NgParameter est sur le point d'être modifiée - const param: NgParameter = data.param; - - // FieldSet parent - const parentFieldset = param.getDirectParent(this) as FieldSet; - - // contexte dans lequel la valeur du paramètre est fixée manuellement - param.currentContextId = this.getContext(parentFieldset); - } - } } } diff --git a/src/app/formulaire/definition/form-def-fixedvar.ts b/src/app/formulaire/definition/form-def-fixedvar.ts index b3711d5f6b70485b22cb5169e133748aca747bb7..86ca4d19fbaf0c83b7c7ffea4b2f22ff317c1119 100644 --- a/src/app/formulaire/definition/form-def-fixedvar.ts +++ b/src/app/formulaire/definition/form-def-fixedvar.ts @@ -62,21 +62,6 @@ export class FormDefFixedVar { protected resetRadiosAndResults(sourceParam: NgParameter, oldState: ParamValueMode) { this.processRadioStateChange(sourceParam, oldState); - switch (sourceParam.valueMode) { // nouvel état - case ParamValueMode.SINGLE: - sourceParam.valueMode = ParamValueMode.SINGLE; - break; - - case ParamValueMode.MINMAX: - case ParamValueMode.LISTE: - sourceParam.valueMode = ParamValueMode.MINMAX; // min-max par défaut - break; - - case ParamValueMode.CALCUL: - sourceParam.valueMode = ParamValueMode.CALCUL; - break; - } - // on vérifie qu'il y a au moins un paramètre "à calculer" et sinon, on prend le 1er qui est à "fixé" if (this._formBase.getDisplayedParamFromState(ParamRadioConfig.CAL) == undefined) { let newCal: NgParameter = undefined; diff --git a/src/app/formulaire/definition/form-def-parallel-structures.ts b/src/app/formulaire/definition/form-def-parallel-structures.ts index a9965b2a272a2090eb4fc7103c74be9a8be508d2..e26992be7e00ce71f7eff03a1de966de31d42cfd 100644 --- a/src/app/formulaire/definition/form-def-parallel-structures.ts +++ b/src/app/formulaire/definition/form-def-parallel-structures.ts @@ -33,9 +33,6 @@ export class FormDefParallelStructures { * @return type d'ouvrage courant du FieldSet donné */ public getStructureType(fs: FieldSet): StructureType { - if (fs.calculatorType !== CalculatorType.Structure) - throw new Error(`FormDefParallelStructures.getStructureType() : le FieldSet n'est pas du type Structure`); - let structType: string = fs.getSelectedValue("select_ouvrage"); if (structType == undefined) throw new Error(`FormDefParallelStructures.getStructureType() : aucun ouvrage trouvé dans le FieldSet`); @@ -50,9 +47,6 @@ export class FormDefParallelStructures { * @return loi de débit courante du FieldSet donné */ public getLoiDebit(fs: FieldSet): LoiDebit { - if (fs.calculatorType !== CalculatorType.Structure) - throw new Error(`FormDefParallelStructures.getLoiDebit() : le FieldSet n'est pas du type Structure`); - let loiDebit: string = fs.getSelectedValue("select_loidebit1"); if (loiDebit == undefined) loiDebit = fs.getSelectedValue("select_loidebit2"); diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts index 0b0b14ae1b488f31b5376d3cf12f1d8d82460267..3dc10da8a564de04a8795d7225d7c528c8339e0a 100644 --- a/src/app/formulaire/definition/form-definition.ts +++ b/src/app/formulaire/definition/form-definition.ts @@ -1,4 +1,5 @@ -import { CalculatorType, ComputeNodeType, Nub, ParamDefinition } from "jalhyd"; +import { CalculatorType, ComputeNodeType, Nub, ParamDefinition, SessionNub, Props } from "jalhyd"; + import { FormulaireElement } from "../formulaire-element"; import { NgParameter, ParamRadioConfig } from "../ngparam"; import { Field } from "../field"; @@ -13,6 +14,7 @@ import { DeepFieldsetIterator } from "../form-iterator/deep-fieldset-iterator"; import { DeepFormulaireElementIterator } from "../form-iterator/deep-element-iterator"; import { TopFormulaireElementIterator } from "../form-iterator/top-element-iterator"; import { CalculatorResults } from "../../results/calculator-results"; +import { FieldsetTemplate } from "../fieldset-template"; /** * classe de base pour tous les formulaires @@ -28,18 +30,12 @@ export abstract class FormulaireDefinition extends FormulaireNode { */ private _calculatorName: string; - /** - * map des Nub appartenant à ce formulaire - */ - protected _nubs: Map<ComputeNodeType, Nub>; - protected _paramService: ParamService; constructor(calcType: CalculatorType, ) { super(); this._calcType = calcType; - this._nubs = new Map(); this._paramService = ServiceFactory.instance.paramService; } @@ -55,32 +51,41 @@ export abstract class FormulaireDefinition extends FormulaireNode { this._calculatorName = name; } + private findNub(params: Props | {}) { + return this._paramService.findSessionNub(params); + } + + public createSessionNub(params: Props | {}): SessionNub { + return this._paramService.createSessionNub(params); + } + /** - * @return le Nub associé à un type de noeud donné - * @param nodeType type de noeud + * @return le Nub associé à un type de noeud donné, le crée si nécessaire + * @param params paramètres de contexte de création du nub */ - public getNub(nodeType: ComputeNodeType): Nub { - return this._nubs.get(nodeType); + public getSessionNub(params: Props | {}): SessionNub { + let res = this.findNub(params); + if (!res) + res = this.createSessionNub(params); + return res; + } + + public replaceSessionNub(sn: SessionNub, params: Props) { + return this._paramService.replaceSessionNub(sn, params); } /** * @return le paramètre d'un type de noeud * @param symbol symbole du paramètre - * @param nodeType type de noeud + * @param params paramètres de contexte de création du nub */ - public getNubParamFromSymbol(nodeType: ComputeNodeType, symbol: string): ParamDefinition { - let nub = this._nubs.get(nodeType); - - if (nub == undefined) // on prend le 1er - for (const e of this._nubs.entries()) { - nub = e[1]; // valeur - break; - } + public getNubParamFromSymbol(symbol: string, params: Props | {}): ParamDefinition { + let sessionNub: SessionNub = this.getSessionNub(params); - if (nub) - return nub.getParameter(symbol); + if (sessionNub) + return sessionNub.nub.getParameter(symbol); - return undefined; + throw new Error(`FormulaireDefinition.getNubParamFromSymbol() : pas de Nub trouvé pour ${params}`) } protected abstract initParse(); @@ -94,16 +99,13 @@ export abstract class FormulaireDefinition extends FormulaireNode { return undefined; } - private parse_fieldset(json: {}): FieldSet { - const ct: string = json["calcType"]; - let calc_type: CalculatorType = ct == undefined ? this._calcType : CalculatorType[ct]; - - const res: FieldSet = new FieldSet(calc_type, json["type"] === "fieldset_template"); - res.parseConfig(json, { "parentForm": this }); - return res; + private parse_fieldset(json: {}) { + const fs: FieldSet = new FieldSet(); + this.kids.push(fs); + fs.parseConfig(json, { "parentForm": this }); } - private parse_template_container(json: {}, templates: { [key: string]: FieldSet }) { + private parse_template_container(json: {}, templates: any[]) { const fsc: FieldsetContainer = new FieldsetContainer(this); fsc.parseConfig(json, templates); this.formElements.push(fsc); @@ -128,7 +130,7 @@ export abstract class FormulaireDefinition extends FormulaireNode { case "fieldset_template": for (const k of this.kids) if (k instanceof FieldsetContainer) - k.parseDependencies(conf); + k.parseDependencies(conf, this); break; } } @@ -137,21 +139,19 @@ export abstract class FormulaireDefinition extends FormulaireNode { public parseConfig(json: {}) { this.initParse(); - const templates: { [key: string]: FieldSet } = {}; + const templates: any[] = []; for (let conf_index in json) { const conf = json[conf_index]; const type: string = conf["type"]; switch (type) { - // field set case "fieldset": + this.parse_fieldset(conf); + break; + case "fieldset_template": - const fs: FieldSet = this.parse_fieldset(conf); - if (fs.isTemplate) - templates[fs.id] = fs; - else - this.kids.push(fs); + templates.push(conf); break; // options globales @@ -278,7 +278,7 @@ export abstract class FormulaireDefinition extends FormulaireNode { } public applyDependencies() { - for (const fe of this.allFormElements) + for (const fe of this.topFormElements) fe.applyDependencies(this); } diff --git a/src/app/formulaire/field.ts b/src/app/formulaire/field.ts index 34411775bf650f29fcaa476213407f350b3b8b05..488f6aabf261c54196d735f0d310d8c10ca5570f 100644 --- a/src/app/formulaire/field.ts +++ b/src/app/formulaire/field.ts @@ -1,5 +1,5 @@ +import { FormulaireNode } from "./formulaire-node"; import { FormulaireElement } from "./formulaire-element"; -import { FormulaireDefinition } from "./definition/form-definition"; import { ValueDependency } from "./dependency/value-dependency"; export abstract class Field extends FormulaireElement { @@ -12,10 +12,10 @@ export abstract class Field extends FormulaireElement { public abstract getValue(): any; public abstract setValue(sender: any, val: any): void; - private parse_value_dependencies(json: {}, parentForm: FormulaireDefinition) { + private parse_value_dependencies(json: {}, parentNode: FormulaireNode) { for (let di in json) { let d = json[di]; - let masterField: FormulaireElement = parentForm.getFormulaireNodeById(d["refid"]) as FormulaireElement; + let masterField: FormulaireElement = parentNode.getFormulaireNodeById(d["refid"]) as FormulaireElement; if (masterField != undefined) { let masterValue = d["refvalue"]; let dep = new ValueDependency(masterField, masterValue); @@ -27,11 +27,11 @@ export abstract class Field extends FormulaireElement { } } - public parseDependencies(json: {}, parentForm: FormulaireDefinition) { - super.parseDependencies(json, parentForm); + public parseDependencies(json: {}, parentNode: FormulaireNode) { + super.parseDependencies(json, parentNode); const dep = json["dep_value"]; if (dep != undefined) - this.parse_value_dependencies(dep, parentForm); + this.parse_value_dependencies(dep, parentNode); } } diff --git a/src/app/formulaire/fieldset-container.ts b/src/app/formulaire/fieldset-container.ts index 5999f7c6545fcf7a5470df486d82d79819fe562a..8f263fab45aa5bdfa9af80500a4d9e2a779905a1 100644 --- a/src/app/formulaire/fieldset-container.ts +++ b/src/app/formulaire/fieldset-container.ts @@ -1,73 +1,51 @@ +import { Structure } from "jalhyd"; + import { FormulaireElement } from "./formulaire-element"; import { FieldSet } from "./fieldset"; +import { FieldsetTemplate } from "./fieldset-template"; import { Dependency } from "./dependency/dependency"; import { StringMap } from "../stringmap"; import { FormulaireDefinition } from "./definition/form-definition"; -import { FormulaireNode } from "./formulaire-node"; +import { FormulaireParallelStructure } from "./definition/concrete/form-parallel-structures"; export class FieldsetContainer extends FormulaireElement { - private _templates: FieldSet[]; + private _templates: FieldsetTemplate[]; private _localisation: StringMap; public title: string - constructor(private parentForm: FormulaireDefinition) { + constructor(private _parentForm: FormulaireDefinition) { super(); this._templates = []; } - /** - * cherche un FormulaireNode par son id de conf - */ - public getFormulaireNodeById(id: string): FormulaireNode { - const res = super.getFormulaireNodeById(id); - if (res !== undefined) - return res; - - for (const t of this._templates) { - const res = t.getFormulaireNodeById(id); - if (res !== undefined) - return res; - } - - return undefined; + public get parentForm() { + return this._parentForm; } - private checkTemplate(fs: FieldSet) { - if (!fs.isTemplate) - throw new Error(`le Fieldset ${fs.id} n'est pas un template`); + private addTemplate(fst: FieldsetTemplate) { + this._templates.push(new FieldsetTemplate(fst)); } - public addTemplate(fs: FieldSet) { - if (this.hasTemplate(fs)) - console.log(`Warning : le Fieldset template ${fs.id} a déjà été ajouté`); - else - this._templates.push(fs); + public getTemplate(index: number): FieldsetTemplate { + return this._templates[index]; } - private hasTemplate(fs: FieldSet): boolean { - this.checkTemplate(fs); - - for (const f of this._templates) - if (f.id === fs.id) - return true; - return false; + public addFieldset(fs: FieldSet) { + this.fieldsets.push(fs); } - private getTemplate(id: string) { - for (const f of this._templates) - if (f.id === id) - return f; - return undefined; - } + public addFromTemplate(index: number) { + const templ: FieldsetTemplate = this._templates[index]; - public addFromTemplate(templId: string) { - const templ: FieldSet = this.getTemplate(templId); - const inst = templ.instanciateTemplate(); - this.fieldsets.push(inst); - inst.applyDependencies(this.parentForm); - this.updateLocalisation() + const inst: FieldSet = templ.instantiateTemplate(this); + if (inst.sessionNub.nub instanceof Structure) { + const psf = this.parentForm as FormulaireParallelStructure; + psf.addStructureNub(inst.sessionNub.nub as Structure); + } + + this.updateLocalisation(); // notification de création d'un FieldSet this.notifyObservers({ @@ -80,24 +58,15 @@ export class FieldsetContainer extends FormulaireElement { return this.kids as FieldSet[]; } - public get templates(): FieldSet[] { - return this._templates; - } - public parseConfig(json: {}, data?: {}) { this._confId = json["id"]; + const templates = data as any[]; - const templs: string[] = json["templates"]; - for (const t of templs) - // this.addTemplate(this.getFieldsetTemplate(t)); - this.addTemplate(data[t]); - } - - public parseDependencies(json: {}) { - super.parseDependencies(json, this.parentForm); - - for (const t of this._templates) - t.parseDependencies(json, this.parentForm); + const templateNames: string[] = json["templates"]; + for (const t of templateNames) + for (const d of templates) + if (d.id == t) + this.addTemplate(d); } protected verifyDependency(d: Dependency): boolean { @@ -111,9 +80,6 @@ export class FieldsetContainer extends FormulaireElement { this._localisation = loc; super.updateLocalisation(loc); - - for (let t of this._templates) - t.updateLocalisation(loc); } /** @@ -129,6 +95,6 @@ export class FieldsetContainer extends FormulaireElement { * crée une nouvelle instance */ protected clone(): FieldsetContainer { - return new FieldsetContainer(this.parentForm); + return new FieldsetContainer(this._parentForm); } } diff --git a/src/app/formulaire/fieldset-template.ts b/src/app/formulaire/fieldset-template.ts new file mode 100644 index 0000000000000000000000000000000000000000..a8db81d579249effe4ec4a4111ab9f11358e64c0 --- /dev/null +++ b/src/app/formulaire/fieldset-template.ts @@ -0,0 +1,48 @@ +import { FieldSet } from "./fieldset"; +import { CalculatorType, ComputeNodeType } from "jalhyd"; +import { FormulaireDefinition } from "./definition/form-definition"; +import { FieldsetContainer } from "./fieldset-container"; + +export class FieldsetTemplate { + private _jsonConfig: {}; + + constructor(config: {}) { + this._jsonConfig = config; + } + + public get config() { + return this._jsonConfig; + } + + public get calcTypeFromConfig(): CalculatorType { + for (const k in this._jsonConfig) { + if (k === "calcType") { + const ct: string = this._jsonConfig[k]; + var calcType: CalculatorType = CalculatorType[ct]; + break; + } + } + + return calcType; + } + + public get defaultNodeTypeFromConfig(): ComputeNodeType { + for (const k in this._jsonConfig) { + if (k === "defaultNodeType") { + const nt: string = this._jsonConfig[k]; + var nodeType: ComputeNodeType = ComputeNodeType[nt]; + break; + } + } + + return nodeType; + } + + public instantiateTemplate(cont: FieldsetContainer): FieldSet { + const res = new FieldSet(); + res.parent_fsc = cont; + cont.addFieldset(res); + res.parseConfig(this._jsonConfig, { "parentForm": cont.parentForm, "createNub": true }); + return res; + } +} diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts index 384e9f1e2c81dfb09d510fc24fcaeec3d964d747..e93200e4d3f3f2c6a24fc17a66682dd9faa47a4e 100644 --- a/src/app/formulaire/fieldset.ts +++ b/src/app/formulaire/fieldset.ts @@ -1,4 +1,4 @@ -import { CalculatorType, ComputeNodeType, ParamDefinition } from "jalhyd"; +import { CalculatorType, ComputeNodeType, ParamDefinition, LoiDebit, StructureType, Props, loiAdmissibles, SessionNub } from "jalhyd"; import { FormulaireElement } from "./formulaire-element"; import { Dependency } from "./dependency/dependency"; @@ -10,37 +10,61 @@ import { NgParameter, ParamRadioConfig } from "./ngparam"; import { ServiceFactory } from "../services/service-factory"; import { ParamService } from "../services/param/param.service"; import { FormulaireDefinition } from "./definition/form-definition"; +import { Observer } from "../services/observer"; +import { StringMap } from "../stringmap"; +import { FieldsetContainer } from "./fieldset-container"; -export class FieldSet extends FormulaireElement { - private _calcType: CalculatorType; +export class FieldSet extends FormulaireElement implements Observer { + /** + * formulaire parent + */ + private _parentForm: FormulaireDefinition; - constructor(calcType: CalculatorType, isTmpl: boolean = false) { - super(isTmpl); - this._calcType = calcType; - } + /** + * SessionNub associé + */ + private _sessionNub: SessionNub; + + /** + * dictionnaire de traduction + */ + private _localisation: StringMap; + + /** + * fichier de configuration + */ + private _jsonConfig: {}; + + /** + * propriétés déterminant l'état actuel du FieldSet (type de section, loi de débit, ...) + */ + private _props: Props; + + public parent_fsc: FieldsetContainer; // A VIRER - public get calculatorType(): CalculatorType { - return this._calcType; + constructor() { + super(false); + this._props = new Props(); } public get fields(): Field[] { return this.kids as Field[]; } + public get sessionNub(): SessionNub { + return this._sessionNub; + } + /** * crée une nouvelle instance */ protected clone(): FieldSet { - return new FieldSet(this._calcType); - } - - public instanciateTemplate(): FieldSet { - const res = this.getDeepClone() as FieldSet; - this.copyDependencies(res, res); - return res; + return new FieldSet(); } public addField(f: Field) { + if (f == undefined) + throw new Error("FieldSet.addField() : argument incorrect (undefined)"); this.fields.push(f); } @@ -83,13 +107,88 @@ export class FieldSet extends FormulaireElement { private parse_select(json: {}): SelectField { let res: SelectField = new SelectField(this.isTemplate); res.parseConfig(json); + res.addObserver(this); return res; } - private parse_input(json: {}, parentForm: FormulaireDefinition, default_radio_config: string): NgParameter { + public getPropValue(key: string): any { + return this._props.getPropValue(key); + } + + public setPropValue(key: string, val: any): boolean { + const changed = this._props.getPropValue(key) !== val; + if (changed) { + this._props.setPropValue(key, val); + + // si prop=type d'ouvrage, on prend une loi de débit compatible avec (spécifique aux ouvrages //) comme valeur par défaut + if (key === "structureType") { + { + const sst: string = StructureType[val]; + const ld: LoiDebit = loiAdmissibles[sst][0]; + this.setPropValue("loiDebit", ld); + } + } + } + return changed; + } + + /** + * valeurs par défaut pour StructureType, LoiDebit en fonction d'un ComputeNodeType + */ + private static defaultProps(nodeType: ComputeNodeType): [StructureType, LoiDebit] { + let structType: StructureType; + let loiDebit: LoiDebit + switch (nodeType) { + case ComputeNodeType.StructureRectangle: + structType = StructureType.VanneRectangulaire; + loiDebit = LoiDebit.Cem88v; + break; + + case ComputeNodeType.StructureKIVI: + structType = StructureType.SeuilRectangulaire; + loiDebit = LoiDebit.KIVI; + break; + } + return [structType, loiDebit]; + } + + /** + * crée un objet Props servant de filtre pour sélectionner un Nub + * @param calcType + * @param nodeType + */ + public static makeDefaultProps(calcType: CalculatorType, nodeType: ComputeNodeType): Props { + const res: Props = new Props(); + + res.setPropValue("calcType", calcType); + res.setPropValue("nodeType", nodeType); + + const p: [StructureType, LoiDebit] = FieldSet.defaultProps(nodeType); + res.setPropValue("structureType", p[0]); + res.setPropValue("loiDebit", p[1]); + + return res; + } + + private getNubParamFromSymbol(symbol: string): ParamDefinition { + if (this._sessionNub) + return this._sessionNub.nub.getParameter(symbol); + + return this._parentForm.getNubParamFromSymbol(symbol, this._props); + } + + /** + * crée un input + * @param json definition de l'input, extrait du fichier de conf de la calculette + * @param node_type_filter filtre sur le type de noeud (input créé si undefined ou égal) + * @param default_radio_config config du radio fixé/à varier/à calculer + */ + private parse_input(json: {}, default_radio_config: string): NgParameter { const input_id: string = json["id"]; const paramService: ParamService = ServiceFactory.instance.paramService; + const calcType: CalculatorType = this.getPropValue("calcType"); + switch (input_id) { case "Pr": var res: NgParameter = paramService.createParameter(input_id, this.isTemplate); @@ -97,35 +196,29 @@ export class FieldSet extends FormulaireElement { default: const nt: string = json["nodeType"]; - let node_type: ComputeNodeType = nt == undefined ? ComputeNodeType.None : ComputeNodeType[nt]; + let nodeType: ComputeNodeType = nt == undefined ? this.getPropValue("nodeType") : ComputeNodeType[nt]; - const nubParam: ParamDefinition = parentForm.getNubParamFromSymbol(node_type, input_id); - if (nubParam == undefined) - throw new Error(`pas de paramètre '${input_id}' trouvé pour CalculatorType.${CalculatorType[parentForm.calculatorType]}/ComputeNodeType.${ComputeNodeType[node_type]}`); - res = new NgParameter(nubParam, this.isTemplate); + const nubParam: ParamDefinition = this.getNubParamFromSymbol(input_id); + if (nubParam) + res = new NgParameter(nubParam, this.isTemplate); } - res.parseConfig(json, { "radioConfig": default_radio_config }); + if (res) + res.parseConfig(json, { "radioConfig": default_radio_config }); return res; } - public parseConfig(json: {}, data?: {}) { - const parentForm: FormulaireDefinition = data["parentForm"]; - - this._confId = json["id"]; - - const nt: string = json["nodeType"]; - let node_type: ComputeNodeType = nt == undefined ? ComputeNodeType.None : ComputeNodeType[nt]; - - const fields = json["fields"]; + private parseFields() { + const fields = this._jsonConfig["fields"]; for (const field_index in fields) { const field = fields[field_index]; if (field["type"] === "input") { - const default_radio_config = json["option"]; - const param = this.parse_input(field, parentForm, default_radio_config); - this.addField(param); + const default_radio_config = this._jsonConfig["option"]; + const param = this.parse_input(field, default_radio_config); + if (param) // potentiellement undefined car certaines définitions de FieldSet comportent des paramètres qui ne sont pas tous affichés en même temps (cf. ouvrages //) + this.addField(param); } else if (field["type"] === "select") { const param = this.parse_select(field); this.addField(param); @@ -136,8 +229,114 @@ export class FieldSet extends FormulaireElement { } } - public parseDependencies(json: {}, parentForm: FormulaireDefinition) { - super.parseDependencies(json, parentForm); + private clearFields() { + for (const n of this.kids) + n.removeObserver(this); + + this.clearKids(); + } + + /** + * met à jour le SessionNubnub associé + * @param createOrUpdate true pour forcer la création d'un SessionNub + */ + private updateNub(createOrUpdate: boolean) { + if (this._sessionNub) + this._sessionNub = this._parentForm.replaceSessionNub(this._sessionNub, this._props); + else { + if (createOrUpdate) + this._sessionNub = this._parentForm.createSessionNub(this._props); + else + this._sessionNub = this._parentForm.getSessionNub(this._props); + } + } + + public updateLocalisation(loc?: StringMap) { + if (loc == undefined) + loc = this._localisation; + else + this._localisation = loc; + + if (loc) + super.updateLocalisation(loc); + } + + /** + * @param createOrUpdate true pour forcer la création d'un SessionNub + */ + private updateFields(createOrUpdate: boolean = false) { + this.clearFields(); + this.updateNub(createOrUpdate); + this.parseFields(); + this.parseDependencies(this._jsonConfig); + this.updateLocalisation(); + + // MAJ des selects avec les valeurs actuelles des propriétés + // spécifique à chaque calculette, à revoir + + if (this._confId === "fs_ouvrage") { + const sf1: SelectField = this.getFormulaireNodeById("select_ouvrage") as SelectField; + const st: StructureType = this.getPropValue("structureType"); + const se1 = sf1.getSelectedEntryFromValue(st); + sf1.setValue(se1); + + switch (st) { + case StructureType.SeuilRectangulaire: + const sf2: SelectField = this.getFormulaireNodeById("select_loidebit1") as SelectField; + const se2 = sf2.getSelectedEntryFromValue(this.getPropValue("loiDebit")); + sf2.setValue(se2); + break; + + case StructureType.VanneRectangulaire: + const sf3: SelectField = this.getFormulaireNodeById("select_loidebit2") as SelectField; + const se3 = sf3.getSelectedEntryFromValue(this.getPropValue("loiDebit")); + sf3.setValue(se3); + break; + } + } + + // fin MAJ selects + + this.applyDependencies(this._parentForm); + } + + public parseConfig(json: {}, data?: {}) { + this._jsonConfig = json; + this._parentForm = data["parentForm"]; + const cn = data["createNub"]; // flag pour forcer la création d'un SessionNub (true pour création/false pour MAJ, false par défaut ) + const createOrUpdate = cn ? cn : false; + + this._confId = json["id"]; + + const ct: string = json["calcType"]; + const calc_type: CalculatorType = ct == undefined ? this._parentForm.calculatorType : CalculatorType[ct]; + this.setPropValue("calcType", calc_type); + + const nt: string = json["nodeType"]; + const node_type: ComputeNodeType = nt == undefined ? ComputeNodeType.None : ComputeNodeType[nt]; + + const dnt: string = json["defaultNodeType"]; + const default_node_type: ComputeNodeType = dnt == undefined ? ComputeNodeType.None : ComputeNodeType[dnt]; + + if (nt !== undefined && dnt !== undefined) + throw new Error("les champs 'nodeType' et 'defaultNodeType' ne doivent pas être définis en même temps") + + const ntype = dnt !== undefined ? default_node_type : node_type; + + this.setPropValue("nodeType", ntype); + + const st: string = json["defaultStructType"]; + if (st) + this.setPropValue("structureType", StructureType[st]) + const ld: string = json["defaultLoiDebit"]; + if (ld) + this.setPropValue("loiDebit", LoiDebit[ld]) + + this.updateFields(createOrUpdate); + } + + public parseDependencies(json: {}) { + super.parseDependencies(json, this); for (const k1 in json) { if (k1 === "fields") { @@ -150,7 +349,7 @@ export class FieldSet extends FormulaireElement { case "check": for (const k of this.kids) if (k.id == field["id"]) { - k.parseDependencies(field, parentForm); + k.parseDependencies(field, this); break; } break; @@ -197,4 +396,24 @@ export class FieldSet extends FormulaireElement { } return undefined; } + + // interface Observer + + update(sender: any, data: any) { + if (data.action && data.action === "select") { + let update = false; + if (data.value.id.indexOf("select_ouvrage") != -1) + update = update || this.setPropValue("structureType", data.value.value); + else if (data.value.id.indexOf("select_loidebit1") != -1) + update = update || this.setPropValue("loiDebit", data.value.value); + else if (data.value.id.indexOf("select_loidebit2") != -1) + update = update || this.setPropValue("loiDebit", data.value.value); + + if (update) { + console.log("--select"); + this.updateFields(); + this._parentForm.reset(); + } + } + } } diff --git a/src/app/formulaire/formulaire-element.ts b/src/app/formulaire/formulaire-element.ts index 49b73808de7befbd431b095ca69c1c044dfeceeb..ca1c6e10a9a3250ad93e21d96418cfcbb54790b3 100644 --- a/src/app/formulaire/formulaire-element.ts +++ b/src/app/formulaire/formulaire-element.ts @@ -51,10 +51,15 @@ export abstract class FormulaireElement extends FormulaireNode { return Number(s) != NaN; } - private parse_existence_dependencies(json: {}, parentForm: FormulaireDefinition) { + /** + * analyse les dépendances d'existence + * @param json configuration de la dépendance + * @param parentNode node parent dans lequel rechercher l'élément master (dont l'existence dépend) + */ + private parse_existence_dependencies(json: {}, parentNode: FormulaireNode) { for (let di in json) { let d = json[di]; - let masterField: FormulaireElement = parentForm.getFormulaireNodeById(d["refid"]) as FormulaireElement; + let masterField: FormulaireElement = parentNode.getFormulaireNodeById(d["refid"]) as FormulaireElement; if (masterField != undefined) { let rv = d["refvalue"]; if (rv != undefined) @@ -82,14 +87,19 @@ export abstract class FormulaireElement extends FormulaireNode { this._dependencies.push(dep); } else - throw new Error(`la dépendance d'existence de '${this.id}' fait référence à un élément inconnu '${d["refid"]}'`); + console.log(`WARNING : la dépendance d'existence de '${this.id}' fait référence à un élément inconnu '${d["refid"]}'`); } } - public parseDependencies(json: {}, parentForm: FormulaireDefinition) { + /** + * analyse les dépendances (existence/valeur) + * @param json configuration de la dépendance + * @param parentNode node parent dans lequel rechercher l'élément master (dont l'existence dépend) + */ + public parseDependencies(json: {}, parentNode: FormulaireNode) { const dep = json["dep_exist"]; if (dep != undefined) - this.parse_existence_dependencies(dep, parentForm); + this.parse_existence_dependencies(dep, parentNode); } protected abstract verifyDependency(d: Dependency): boolean; diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts index 285e8917d43581a44362ed7f74f9a4456ea7e1ef..8f33e3f9ad538327c7aa4c5d00fd23ce8adc41b2 100644 --- a/src/app/formulaire/formulaire-node.ts +++ b/src/app/formulaire/formulaire-node.ts @@ -53,6 +53,10 @@ export abstract class FormulaireNode implements IObservable { return this._kids; } + public clearKids() { + this._kids = []; + } + public get isTemplate(): boolean { return this._isTemplate; } @@ -183,7 +187,12 @@ export abstract class FormulaireNode implements IObservable { public abstract parseConfig(json: {}, data?: {}); - public abstract parseDependencies(json: {}, parentForm: FormulaireDefinition); + /** + * analyse les dépendances (existence/valeur) + * @param json configuration de la dépendance + * @param parentNode nod parent dans lequel rechercher l'élément master (dont l'existence dépend) + */ + public abstract parseDependencies(json: {}, parentNode: FormulaireNode); // interface IObservable diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts index 5fcebe23cada23030b8479197cfabdd022c7eb81..530221a2fc0eb1ea9d1bc00023f72265f5cbadf1 100644 --- a/src/app/formulaire/ngparam.ts +++ b/src/app/formulaire/ngparam.ts @@ -26,14 +26,6 @@ export enum ParamRadioConfig { CAL }; -/** - * infos sur le contexte, les valeurs par défaut et saisie manuellement - */ -class Context { - public default: number; - public current: number; -} - /** * classe englobante de ParamDefinition (champs supplémentaires pour l'affichage, radio boutons, ...) */ @@ -46,18 +38,6 @@ export class NgParameter extends InputField { */ public isDefault: boolean = false; // archi bug du langage ! si on relit cette propriété sans l'avoir modifiée entre-temps, elle vaut undefined ! - /** - * dictionnaire indiquant la valeur du paramètre dans différents contextes - * clé : contexte représenté par une chaîne - * valeur : instance de Context - */ - private _contexts: { [key: string]: Context } = {}; - - /** - * id du contexte courant - */ - public currentContextId: string; - constructor(private _paramDef: ParamDefinition, isTmpl = false) { super(isTmpl); } @@ -115,74 +95,6 @@ export class NgParameter extends InputField { ); } - /** - * @return true si la valeur du paramètre a été modifiée manuellement dans un contexte donné - * @param contextId id du contexte - */ - private isOverriden(contextId: string) { - const cnt = this._contexts[contextId]; - if (cnt == undefined) - return false; - return cnt.current != undefined; - } - - /** - * fixe la valeur du paramètre dans un contexte donné - * @param contextId id du contexte (par ex dans les ouvrages //, valeur de StructureType+LoiDebit) - * @param defaultValue valeur par défaut si la valeur du paramètre n'a pas été modifiée par setValue() depuis la création de l'objet - */ - public resetValue(sender: any, contextId: string, defaultValue: number) { - if (this.valueMode == ParamValueMode.SINGLE) { - if (!this.isOverriden(contextId)) { - this._paramDef.v = defaultValue; - this.setContextValue(contextId, defaultValue, false); - } - else - this._paramDef.v = this.getContextValue(contextId); - this.notifyValueModified(sender); - } - } - - /** - * @return la valeur du paramètre dans un contexte donné - * @param contextId id du contexte - */ - private getContextValue(contextId: string): number { - if (contextId == undefined) - return this._paramDef.v; - - const cnt = this._contexts[contextId]; - if (cnt == undefined) - return this._paramDef.v; - - if (cnt.current != undefined) - return cnt.current; - - return cnt.default; - } - - /** - * fixe la valeur du paramètre dans un contexte donné - * @param contextId id du contexte - * @param val valeur du paramètre - * @param currentOrDefault true si on fixe la valeur modifiée à la main, false si valeur par défaut - */ - private setContextValue(contextId: string, val: number, currentOrDefault: boolean) { - if (contextId != undefined) { - var cnt = this._contexts[contextId]; - - if (cnt == undefined) - cnt = new Context(); - - if (currentOrDefault) - cnt.current = val; - else - cnt.default = val; - - this._contexts[contextId] = cnt; - } - } - /** * fixe la valeur du paramètre. * une notification préalable est envoyée pour laisser l'occasion aux objets liés de préciser le contexte @@ -191,17 +103,7 @@ export class NgParameter extends InputField { * @param val */ public setValue(sender: any, val: number) { - // on laisse l'occasion de préciser le contexte - this.notifyObservers( - { - "action": "ngparamBeforeValue", - "param": this, - "value": val - }, sender - ) - this._paramDef.v = val; - this.setContextValue(this.currentContextId, val, true); this.notifyValueModified(sender); } @@ -381,7 +283,6 @@ export class NgParameter extends InputField { if (val != undefined) this.setValue(this, +val); this.radioConfig = NgParameter.getRadioConfig(radioConfig); - this.valueMode = ParamValueMode.SINGLE; this.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) } diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts index e53d3bd0de36bbf1dc00c20751fff26a3289683b..0163b4ada1e2b75217c37832624aa519ab915b04 100644 --- a/src/app/services/param/param.service.ts +++ b/src/app/services/param/param.service.ts @@ -1,4 +1,4 @@ -import { ParamDomain, ComputeNodeType, ParamDefinition, ParamDomainValue, ParamCalculability, CalculatorType, NubFactory } from "jalhyd"; +import { ParamDomain, ParamDefinition, ParamDomainValue, ParamCalculability, NubFactory, SessionNub, Props } from "jalhyd"; import { NgParameter } from "../../formulaire/ngparam"; import { FormulaireDefinition } from "../../formulaire/definition/form-definition"; @@ -24,25 +24,6 @@ export class ParamService { return p; } - /** - * crée un paramètre de ComputeNode - * @param calcType type de calculette - * @param nodeType type de noeud - * @param symbol symbole du paramètre - * @param isTmpl true si le paramètre créé est un template - */ - // public createNodeParameter(calcType: CalculatorType, nodeType: ComputeNodeType, symbol: string, isTmpl = false): NgParameter { - // if (symbol === "Pr") - // var prmDef: ParamDefinition = this.createAccuracyParameter(); - // else - // prmDef = ComputeNodeParameters.getInstance().getComputeNodeParameter(calcType, nodeType, symbol); - - // if (prmDef == undefined) - // throw new Error(`ParamService.createParameter() : pas de paramètre '${symbol}' pour la calculette ${CalculatorType[calcType]}/type de noeud ${ComputeNodeType[nodeType]}`); - - // return new NgParameter(prmDef.clone(), isTmpl); - // } - /** * * @param calcType crée un NgParameter n'appartenant pas à un ComputeNode @@ -52,6 +33,7 @@ export class ParamService { if (symbol === "Pr") { var prmDef: ParamDefinition = this.createAccuracyParameter(); var p = new NgParameter(prmDef.clone(), isTmpl); + p.confId = "Pr"; } else { const dom = new ParamDomain(ParamDomainValue.POS_NULL); @@ -109,7 +91,15 @@ export class ParamService { return p; } - public createNub(calcType: CalculatorType, nodeType: ComputeNodeType = ComputeNodeType.None) { - return NubFactory.getInstance().createNub(calcType, nodeType); + public createSessionNub(params: Props | {}): SessionNub { + return NubFactory.getInstance().createSessionNub(params); + } + + public findSessionNub(params: Props | {}): SessionNub { + return NubFactory.getInstance().findSessionNub(params); + } + + public replaceSessionNub(sn: SessionNub, params: Props): SessionNub { + return NubFactory.getInstance().replaceSessionNub(sn, params); } }