diff --git a/src/app/calculators/pab/pab.config.json b/src/app/calculators/pab/pab.config.json index a869b2b8114bd14a9af98d35daff821b6a62665f..295b7cfa071fb4e7700db265da565e1a70a11572 100644 --- a/src/app/calculators/pab/pab.config.json +++ b/src/app/calculators/pab/pab.config.json @@ -31,7 +31,7 @@ "fields": [ { "id": "select_modele_cloisons", - "type": "select", + "type": "select_cloisons", "select": [] }, { diff --git a/src/app/components/dialog-generate-pab/dialog-generate-pab.component.html b/src/app/components/dialog-generate-pab/dialog-generate-pab.component.html index f404ad3632c23454f43b316b0dfc8b8207482ed3..36b68b2c2dd9d3dd60b4e941508846d3e56d05b5 100644 --- a/src/app/components/dialog-generate-pab/dialog-generate-pab.component.html +++ b/src/app/components/dialog-generate-pab/dialog-generate-pab.component.html @@ -24,16 +24,6 @@ </div> </mat-error> - <mat-form-field> - <input matInput required [placeholder]="uitextCoteAval" pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$" - [(ngModel)]="coteAval" name="coteAval" #inputCoteAval="ngModel"> - </mat-form-field> - <mat-error *ngIf="inputCoteAval.invalid && (inputCoteAval.dirty || inputCoteAval.touched)"> - <div *ngIf="inputCoteAval.errors.required || inputCoteAval.errors.pattern"> - {{ uitextMustBeANumber }} - </div> - </mat-error> - <mat-form-field> <input matInput required [placeholder]="uitextNBBassins" pattern="^[1-9][0-9]*$" [(ngModel)]="nbBassins" name="nbBassins" #inputNbBassins="ngModel"> @@ -51,7 +41,7 @@ {{ uitextCancel }} </button> <button mat-raised-button type="submit" color="warn" (click)="generatePAB()" - [disabled]="(inputDebit.invalid || inputCoteAmont.invalid || inputCoteAval.invalid || inputNbBassins.invalid)"> + [disabled]="(inputDebit.invalid || inputCoteAmont.invalid || inputNbBassins.invalid)"> {{ uitextGenerate }} </button> </div> diff --git a/src/app/components/dialog-generate-pab/dialog-generate-pab.component.ts b/src/app/components/dialog-generate-pab/dialog-generate-pab.component.ts index 3b868359886c34ed418697f8fcadaa132edf0101..0bfec942ae226ac9d49939cad2eb4a3fe9e9c293 100644 --- a/src/app/components/dialog-generate-pab/dialog-generate-pab.component.ts +++ b/src/app/components/dialog-generate-pab/dialog-generate-pab.component.ts @@ -15,7 +15,7 @@ export class DialogGeneratePABComponent { public coteAmont = 102; - public coteAval = 99; + public chute: number; public nbBassins = 6; @@ -24,14 +24,19 @@ export class DialogGeneratePABComponent { private intlService: I18nService, private fb: FormBuilder, @Inject(MAT_DIALOG_DATA) public data: any - ) { } + ) { + this.chute = data.chute; + } public generatePAB() { + // calculate downstream elevation + const coteAval = this.coteAmont - (this.chute * this.nbBassins); + // create PAB this.dialogRef.close({ generate: true, debit: this.debit, coteAmont: this.coteAmont, - coteAval: this.coteAval, + coteAval: coteAval, nbBassins: this.nbBassins }); } diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts index 30ae96fea44b4d6d68d78d0a9013b7c586ea12ac..6f59b35054cf07202e5a1b20cf69c89950efcfbe 100644 --- a/src/app/components/field-set/field-set.component.ts +++ b/src/app/components/field-set/field-set.component.ts @@ -6,6 +6,7 @@ import { ParamFieldLineComponent } from "../param-field-line/param-field-line.co import { Field } from "../../formulaire/field"; import { InputField } from "../../formulaire/input-field"; import { SelectField } from "../../formulaire/select-field"; +import { SelectFieldCloisons } from "../../formulaire/select-field-cloisons"; import { FormulairePab } from "../../formulaire/definition/concrete/form-pab"; @Component({ @@ -185,7 +186,7 @@ export class FieldSetComponent implements DoCheck { */ private isSelectCloisonsField(f: Field): boolean { return ( - f instanceof SelectField + f instanceof SelectFieldCloisons && f.parentForm instanceof FormulairePab && f.id === (f.parentForm as FormulairePab).modeleCloisonsSelectId ); diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts index b5e7be12e51d7e97caa1ee80e71024378c4e9522..3753cc223221b9f4df301b3d9217ec0d3b137488 100644 --- a/src/app/components/fieldset-container/fieldset-container.component.ts +++ b/src/app/components/fieldset-container/fieldset-container.component.ts @@ -64,7 +64,11 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit { @Output() protected tabPressed = new EventEmitter<any>(); - private addStructure(after?: FieldSet) { + /** + * Ajoute un nouveau sous-nub (Structure, PabCloisons selon le cas) + * dans un nouveau fieldset + */ + private addSubNub(after?: FieldSet) { if (after) { this._container.addFromTemplate(0, after.indexAsKid()); } else { @@ -182,7 +186,7 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit { * réception d'un événement de demande d'ajout d'un FieldSet */ private onAddFieldset(fs: FieldSet) { - this.addStructure(fs); + this.addSubNub(fs); } /** diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts index 35fb50bb54af133ca914eca2e24e6b7b66ecc729..0976b51a916dc8ced7bcf2972d0a072bbd3de5df 100644 --- a/src/app/components/generic-calculator/calculator.component.ts +++ b/src/app/components/generic-calculator/calculator.component.ts @@ -20,6 +20,7 @@ import { ServiceFactory } from "../../services/service-factory"; import { MatDialog } from "@angular/material"; import { DialogConfirmCloseCalcComponent } from "../dialog-confirm-close-calc/dialog-confirm-close-calc.component"; import { DialogGeneratePABComponent } from "../dialog-generate-pab/dialog-generate-pab.component"; +import { SelectFieldCloisons } from "../../formulaire/select-field-cloisons"; @Component({ selector: "hydrocalc", @@ -439,7 +440,12 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, // création du dialogue de génération d'une passe à bassin const dialogRef = this.generatePABDialog.open( DialogGeneratePABComponent, - { disableClose: true } + { + data: { + chute: (this._formulaire.currentNub as Cloisons).prms.DH.v + }, + disableClose: true + } ); dialogRef.afterClosed().subscribe(result => { if (result) { @@ -453,12 +459,16 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, params.Z2.singleValue = result.coteAval; // création des bassins for (let i = 0; i < result.nbBassins; i++) { - const modeleCloisons = new PabCloisons((this._formulaire.currentNub as Cloisons)); - pab.addChild(modeleCloisons); + const pabCloisons = new PabCloisons(this._formulaire.currentNub as Cloisons); + pab.addChild(pabCloisons); // @TODO should be replace afterwards for (const e of f.allFormElements) { if (e instanceof FieldsetContainer) { - // @TODO how to pass Nub here ? (parameter exists but is never used) - e.addFromTemplate(0, undefined, modeleCloisons); + const newFieldset = e.addFromTemplate(0, undefined, pabCloisons); + // set selected value by ID; nub should be set by "select value changed" event listener + const modeleSelect = (newFieldset.getFormulaireNodeById("select_modele_cloisons") as SelectFieldCloisons); + modeleSelect.updateEntries(); + // ID of the Cloisons nub used by pabCloisons as a model + modeleSelect.setValueFromId(this._formulaire.currentNub.uid); break; } } diff --git a/src/app/components/select-cloisons-field-line/select-cloisons-field-line.component.ts b/src/app/components/select-cloisons-field-line/select-cloisons-field-line.component.ts index 652f36fbe2534d5876d4fe46bc76474957cc4e7d..3aa546880161f7c1dd54453cc8a32dfeab7c8be0 100644 --- a/src/app/components/select-cloisons-field-line/select-cloisons-field-line.component.ts +++ b/src/app/components/select-cloisons-field-line/select-cloisons-field-line.component.ts @@ -1,12 +1,12 @@ import { Component, Input, OnInit } from "@angular/core"; import { Router } from "@angular/router"; -import { SelectField } from "../../formulaire/select-field"; import { SelectEntry } from "../../formulaire/select-entry"; import { FormulaireService } from "../../services/formulaire/formulaire.service"; -import { Session, CalculatorType } from "jalhyd"; +import { CalculatorType } from "jalhyd"; import { FormulaireDefinition } from "../../formulaire/definition/form-definition"; import { FieldsetContainer } from "../../formulaire/fieldset-container"; +import { SelectFieldCloisons } from "../../formulaire/select-field-cloisons"; @Component({ selector: "select-cloisons-field-line", @@ -17,7 +17,7 @@ import { FieldsetContainer } from "../../formulaire/fieldset-container"; }) export class SelectCloisonsFieldLineComponent implements OnInit { @Input() - private _select: SelectField; + private _select: SelectFieldCloisons; public constructor( private _formService: FormulaireService, @@ -41,27 +41,8 @@ export class SelectCloisonsFieldLineComponent implements OnInit { // called every time we navigate to the module ngOnInit(): void { - this.updateAvailableEntries(); - } - - /** - * Populates the select with available Cloisons in the session - */ - public updateAvailableEntries() { - // store previous selected entry - const pse = this._select.getValue(); - this._select.clearEntries(); - // populate with available Cloisons - const cloisonsNubs = Session.getInstance().getCloisonsNubs(); - console.log(">> UAE − cloisons dispo", cloisonsNubs.length, cloisonsNubs); - for (const cl of cloisonsNubs) { - const e = new SelectEntry(cl.uid, cl); - this._select.addEntry(e); - } - // keep previously selected entry if possible - if (pse && pse.id) { - this._select.setValueFromId(pse.id); - } + console.log("------------------------- SF dans le onInit", this._select.constructor.name); + this._select.updateEntries(); } /** diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts index 3781d03556ea07762fa233953c29bffed15ffd86..41fd6a7acce5c4dd3bb2c0e7cd35e4c02c8978f1 100644 --- a/src/app/formulaire/fieldset.ts +++ b/src/app/formulaire/fieldset.ts @@ -3,12 +3,11 @@ import { CalculatorType, ComputeNodeType, ParamDefinition, LoiDebit, Props, Obse import { FormulaireElement } from "./formulaire-element"; import { Field } from "./field"; import { SelectField } from "./select-field"; +import { SelectFieldCloisons } from "./select-field-cloisons"; import { NgParameter, ParamRadioConfig } from "./ngparam"; -import { ServiceFactory } from "../services/service-factory"; import { FormulaireDefinition } from "./definition/form-definition"; import { StringMap } from "../stringmap"; import { FormulaireNode } from "./formulaire-node"; -import { ApplicationSetupService } from "../services/app-setup/app-setup.service"; export class FieldSet extends FormulaireElement implements Observer { /** @@ -26,11 +25,8 @@ export class FieldSet extends FormulaireElement implements Observer { */ private _jsonConfig: {}; - private _appSetupService: ApplicationSetupService; - constructor(parent: FormulaireNode) { super(parent); - this._appSetupService = ServiceFactory.instance.applicationSetupService; } public get nub(): Nub { @@ -81,6 +77,15 @@ export class FieldSet extends FormulaireElement implements Observer { return res; } + // non-generic version of parse_select for SelectFieldCloisons because + // downcasting is not possible with @Input() apparently + private parse_select_cloisons(json: {}): SelectField { + const res: SelectFieldCloisons = new SelectFieldCloisons(this); + res.parseConfig(json); + res.addObserver(this); + return res; + } + public get properties(): Props { return this.nub.properties; } @@ -152,6 +157,9 @@ export class FieldSet extends FormulaireElement implements Observer { } else if (field["type"] === "select") { const param = this.parse_select(field); this.addField(param); + } else if (field["type"] === "select_cloisons") { + const param = this.parse_select_cloisons(field); + this.addField(param); } } } @@ -370,6 +378,9 @@ export class FieldSet extends FormulaireElement implements Observer { case "select_target": // courbes de remous, variable à calculer this.setPropValue("varCalc", data.value.value); break; + case "select_modele_cloisons": // courbes de remous, variable à calculer + this.setPropValue("modeleCloisons", data.value.id); + break; } break; } diff --git a/src/app/formulaire/select-field-cloisons.ts b/src/app/formulaire/select-field-cloisons.ts new file mode 100644 index 0000000000000000000000000000000000000000..e9d51d6c29050ff3951e5dcdce34a8b209ae3e8f --- /dev/null +++ b/src/app/formulaire/select-field-cloisons.ts @@ -0,0 +1,84 @@ +import { SelectField } from "./select-field"; +import { Session } from "jalhyd"; +import { SelectEntry } from "./select-entry"; + +/** + * A select field that populates itself with references to + * available Cloisons modules (used by PAB) + */ +export class SelectFieldCloisons extends SelectField { + + /** + * Populates entries with available Cloisons + */ + protected populate() { + const cloisonsNubs = Session.getInstance().getCloisonsNubs(); + console.log(">> UAE − cloisons dispo", cloisonsNubs.length, cloisonsNubs); + for (const cl of cloisonsNubs) { + const e = new SelectEntry(cl.uid, cl); + this.addEntry(e); + } + } + + /** + * Reloads available entries, trying to keep the current selected + * value; does not notify observers if value did not change + */ + public updateEntries() { + console.log("=>>>> updating entries \o/", this.constructor.name); + // store previous selected entry + const pse = this._selectedEntry; + // empty + this.clearEntries(); + // populate + this.populate(); + // keep previously selected entry if possible + if (pse && pse.id) { + this.setValueFromId(pse.id); + } + } + + /** + * Updates selectedValue; notifies observers only if + * value.id has changed + */ + public setValue(v: SelectEntry) { + const previousSelectedEntry = this._selectedEntry; + this._selectedEntry = v; + if ( + ! previousSelectedEntry + || (previousSelectedEntry.id !== v.id) + ) { + this.notifyObservers({ + "action": "select", + "value": v + }, this); + } + } + + /** + * Sets value from given ID; if it was not found, sets the + * first available entry as selectedValue + */ + public setValueFromId(id: string) { + let found = false; + for (const e of this._entries) { + if (e.id === id) { + found = true; + this.setValue(e); + } + } + if (! found) { + // default to first available entry if any + if (this._entries.length > 0) { + this.setValue(this._entries[0]); + } else { + // notify observers that no value is selected anymore + this.notifyObservers({ + "action": "select", + "value": undefined + }, this); + } + } + } +} diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts index 0ae14e63337714ca880a98b15f273b2ba1e2ff2c..77178478bf22597c5060798051675df1bb4f724f 100644 --- a/src/app/formulaire/select-field.ts +++ b/src/app/formulaire/select-field.ts @@ -9,9 +9,10 @@ import { StringMap } from "../stringmap"; import { FormulaireNode } from "./formulaire-node"; export class SelectField extends Field { - private _entries: SelectEntry[]; - private _selectedEntry: SelectEntry; + protected _entries: SelectEntry[]; + + protected _selectedEntry: SelectEntry; constructor(parent: FormulaireNode) { super(parent); @@ -29,10 +30,34 @@ export class SelectField extends Field { public addEntry(e: SelectEntry) { this._entries.push(e); if (! this._selectedEntry) { - this._selectedEntry = e; + this.setValue(e); + } + } + + /** + * Reloads available entries, trying to keep the current selected + * value; should not notify observers if value did not change + */ + public updateEntries() { + // store previous selected entry + const pse = this._selectedEntry; + this._selectedEntry = undefined; + // empty + this.clearEntries(); + // populate + this.populate(); + // keep previously selected entry if possible + if (pse) { + this.setValue(pse); } } + /** + * Empties then refills entries list with available entries; does + * nothing by default (to be overloaded) + */ + protected populate() { } + public getSelectedEntryFromValue(val: any): SelectEntry { for (const se of this._entries) { if (se.value === val) { @@ -55,14 +80,6 @@ export class SelectField extends Field { } } - public setValueFromId(id: string) { - for (const e of this._entries) { - if (e.id === id) { - this.setValue(e); - } - } - } - public getLabel() { if (this._selectedEntry) { return this._selectedEntry.label;