diff --git a/e2e/calculator.po.ts b/e2e/calculator.po.ts index 12c5a8de42cace9dad88a7905d233e0091842aeb..f2b98b2d9f606cd83c86316d46287b1e493676c1 100644 --- a/e2e/calculator.po.ts +++ b/e2e/calculator.po.ts @@ -414,11 +414,17 @@ export class CalculatorPage { /** * check that an input is empty * @param id input id (parameter name) + * @param empty true to check input is empty, false to check it is NOT empty */ - async checkEmptyInput(id: string) { + async checkEmptyInput(id: string, empty: boolean = true) { const inp = this.getInputById(id); const val = await inp.getAttribute("value"); - expect(val).toEqual(""); + if (empty) { + expect(val).toEqual(""); + } + else { + expect(val).not.toEqual(""); + } } /** diff --git a/e2e/solveur.e2e-spec.ts b/e2e/solveur.e2e-spec.ts index afe88721eb9b32753d9db0ec05fb40e0727c0a82..8c8383565b3557cf112c5c7f257e4712249e71b7 100644 --- a/e2e/solveur.e2e-spec.ts +++ b/e2e/solveur.e2e-spec.ts @@ -11,7 +11,6 @@ import { changeSelectValue, scrollPageToTop } from "./util.po"; * Clone calculators */ describe("Solveur - ", () => { - let startPage: AppPage; let listPage: ListPage; let calcPage: CalculatorPage; let navbar: Navbar; @@ -19,7 +18,6 @@ describe("Solveur - ", () => { let prefPage: PreferencesPage; beforeAll(async () => { - startPage = new AppPage(); prefPage = new PreferencesPage(); listPage = new ListPage(); calcPage = new CalculatorPage(); @@ -28,10 +26,8 @@ describe("Solveur - ", () => { }); beforeEach(async () => { - await prefPage.navigateTo(); // disable evil option "empty fields on module creation" - await prefPage.disableEvilEmptyFields(); - await browser.sleep(200); + await prefPage.setEmptyFields(false); // force language to prevent issues due to default browser language await prefPage.changeLanguage(1); // fr await browser.sleep(200); @@ -171,7 +167,7 @@ describe("Solveur - ", () => { // check "search parameter" value has not changed expect(await calcPage.getSelectValueText(sel)).toEqual(selText); }); - + it("check solver searched parameter is set to 'bottom slope'", async () => { // open "canal critical slope" example const examples = await element.all(by.css("#examples-list .load-example")); @@ -188,3 +184,225 @@ describe("Solveur - ", () => { expect(selText).toEqual("If - Pente du fond (Sec. param.)"); }); }); + +/** + * solver with empty fields option + */ +describe("Solveur - nghyd#601 with empty fields option", () => { + let prefPage: PreferencesPage; + let navBar: Navbar; + let listPage: ListPage; + let calcPage: CalculatorPage; + + beforeAll(async () => { + prefPage = new PreferencesPage(); + navBar = new Navbar(); + listPage = new ListPage(); + calcPage = new CalculatorPage(); + }); + + async function openCalculator(id: number) { + await navBar.clickNewCalculatorButton(); + await browser.sleep(200); + + await listPage.clickMenuEntryForCalcType(id); + await browser.sleep(200); + } + + async function openSolver() { + await openCalculator(22); + } + + beforeEach(async () => { + // enable evil option "empty fields on module creation" + await prefPage.setEmptyFields(true); + }); + + it("check solver with empty fields option does not fill inputs - solver alone", async () => { + // open new solver calculator + await openSolver(); + + // check inputs are empty + await calcPage.checkEmptyInput("Ytarget"); + await browser.sleep(200); + + await calcPage.checkEmptyInput("Xinit"); + await browser.sleep(200); + }); + + it("check solver with empty fields option does not fill target parameter input", async () => { + // open "parallel structures" calculator + await openCalculator(8); + + // open second "parallel structures" calculator + await openCalculator(8); + + // link Q to first calculator's + const inpQ = calcPage.getInputById("Q"); + await calcPage.setParamMode(inpQ, "link"); + await browser.sleep(200); + + // open new solver calculator + await openSolver(); + + // check target parameter input is empty + await calcPage.checkEmptyInput("Ytarget"); + await browser.sleep(200); + + // check initial value input is not empty + await calcPage.checkEmptyInput("Xinit"); + await browser.sleep(200); + }); + + it("check removing and recreating solver with empty fields option does not fill target parameter input", async () => { + await navBar.clickNewCalculatorButton(); + await browser.sleep(200); + + // open "channel flow with hydraulic structures" example + const examples = await element.all(by.css("#examples-list .load-example")); + await examples[1].click(); + await browser.sleep(500); + + // close existing "solver" calculator + await navBar.middleClickCalculatorTab(3); + await browser.sleep(500); + + // open new solver calculator + await openSolver(); + + // check target parameter input is empty + await calcPage.checkEmptyInput("Ytarget"); + await browser.sleep(200); + + // check initial value input is not empty + await calcPage.checkEmptyInput("Xinit", false); + await browser.sleep(200); + }); +}); + +/** + * solver without empty fields option + */ +describe("Solveur - nghyd#601 without empty fields option", () => { + let prefPage: PreferencesPage; + let navBar: Navbar; + let listPage: ListPage; + let calcPage: CalculatorPage; + + beforeAll(async () => { + prefPage = new PreferencesPage(); + navBar = new Navbar(); + listPage = new ListPage(); + calcPage = new CalculatorPage(); + }); + + async function openCalculator(id: number) { + await navBar.clickNewCalculatorButton(); + await browser.sleep(200); + + await listPage.clickMenuEntryForCalcType(id); + await browser.sleep(200); + } + + async function openSolver() { + await openCalculator(22); + } + + beforeEach(async () => { + await browser.manage().window().setPosition(2000, 30); + + // disable evil option "empty fields on module creation" + await prefPage.setEmptyFields(false); + }); + + it("check solver without empty fields option does not fill inputs - solver alone", async () => { + // open new solver calculator + await openSolver(); + + // check inputs are empty + await calcPage.checkEmptyInput("Ytarget"); + await browser.sleep(200); + + await calcPage.checkEmptyInput("Xinit"); + await browser.sleep(200); + }); + + it("check solver without empty fields option fills inputs", async () => { + // open "parallel structures" calculator + await openCalculator(8); + + // open second "parallel structures" calculator + await openCalculator(8); + + // link Q to first calculator's + const inpQ = calcPage.getInputById("Q"); + await calcPage.setParamMode(inpQ, "link"); + await browser.sleep(200); + + // open new solver calculator + await openSolver(); + + // check target parameter input is not empty + await calcPage.checkEmptyInput("Ytarget", false); + await browser.sleep(200); + + // check initial value input is not empty + await calcPage.checkEmptyInput("Xinit", false); + await browser.sleep(200); + }); + + it("check removing and recreating solver without empty fields option fills inputs", async () => { + await navBar.clickNewCalculatorButton(); + await browser.sleep(200); + + // open "channel flow with hydraulic structures" example + const examples = await element.all(by.css("#examples-list .load-example")); + await examples[1].click(); + await browser.sleep(500); + + // close existing "solver" calculator + await navBar.middleClickCalculatorTab(3); + await browser.sleep(500); + + // open new solver calculator + await openSolver(); + + // check target parameter input is not empty + await calcPage.checkEmptyInput("Ytarget", false); + await browser.sleep(200); + + // check initial value input is not empty + await calcPage.checkEmptyInput("Xinit", false); + await browser.sleep(200); + }); + + it(" with empty fields option, check selecting a target module does not fill inputs", async () => { + // enable evil option "empty fields on module creation" + await prefPage.setEmptyFields(true); + await browser.sleep(200); + + await navBar.clickNewCalculatorButton(); + await browser.sleep(200); + + // open "channel flow with hydraulic structures" example + const examples = await element.all(by.css("#examples-list .load-example")); + await examples[1].click(); + await browser.sleep(500); + + // close existing "solver" calculator + await navBar.middleClickCalculatorTab(3); + await browser.sleep(500); + + // open new solver calculator + await openSolver(); + await browser.sleep(500); + + // select other target module + const ntc = calcPage.getSelectById("select_target_nub"); + await changeSelectValue(ntc, 1); + + // check target value input is empty + await calcPage.checkEmptyInput("Ytarget", true); + await browser.sleep(200); + }); +}); diff --git a/jalhyd_branch b/jalhyd_branch index cf4a15c270bac55dd48db6135f27a19b29c8ef52..50cc6a0b1d745d24a600141a8d4218324a03332e 100644 --- a/jalhyd_branch +++ b/jalhyd_branch @@ -1 +1 @@ -215-conduites-en-charge-ajouter-loi-de-strickler-exercice-dans-livre-de-bennis +342-solveur-multimodule-le-module-existe-toujours-apres-suppression diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts index 46a03da75a97cdd7ca22c2b287b8ad65f0bca0c8..d0c386beaa26e635bee7495b6bf8b9ead978abb9 100644 --- a/src/app/components/generic-calculator/calculator.component.ts +++ b/src/app/components/generic-calculator/calculator.component.ts @@ -412,6 +412,7 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe */ protected afterFirstViewChecked() { this.updateUIValidity(); + this.formulaire.setFirstDisplayCompleted(); } public onCloseForm() { diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts index c6b05ea1ba0dd4a3fe92354006e6d8eeb4a95a5d..d7022502972c2cc748f6477791ce8e32ce60f977 100644 --- a/src/app/formulaire/definition/form-definition.ts +++ b/src/app/formulaire/definition/form-definition.ts @@ -62,6 +62,11 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs */ protected _calcResults: CalculatorResults[]; + /** + * Flag indiquant que le composant calculette est proche de la fin du 1er affichage (1er appel à AfterViewChecked) + */ + private _firstDisplay: boolean = true; + constructor(parent?: FormulaireNode) { super(parent); SessionSettings.instance.addObserver(this); @@ -81,6 +86,14 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs return this._calculateDisabled; } + public get isFirstDisplay(): boolean { + return this._firstDisplay; + } + + public setFirstDisplayCompleted() { + this._firstDisplay = false; + } + public getPropValue(key: string): any { if (this._currentNub === undefined) return this.defaultProperties[key]; diff --git a/src/app/formulaire/definition/form-solveur.ts b/src/app/formulaire/definition/form-solveur.ts index ce7be1797a493253662eb914bf8a6ae1d3495d82..08318dd8c33b6cab048e2f9538f2f562eeb2cd61 100644 --- a/src/app/formulaire/definition/form-solveur.ts +++ b/src/app/formulaire/definition/form-solveur.ts @@ -1,9 +1,10 @@ -import { IObservable, ParamDefinition, Nub } from "jalhyd"; +import { IObservable, ParamDefinition, Nub, Props, Solveur, SolveurParams } from "jalhyd"; import { NgParameter } from "../elements/ngparam"; import { FormulaireFixedVar } from "./form-fixedvar"; import { SelectField } from "../elements/select/select-field"; import { FieldSet } from "../elements/fieldset"; +import { ServiceFactory } from "app/services/service-factory"; /** * Formulaire pour les Solveurs @@ -34,6 +35,16 @@ export class FormulaireSolveur extends FormulaireFixedVar { } } + public initNub(props?: Props) { + super.initNub(props); + + // subscribe to Ytarget to be able to reset it during form construction (with empty fields option set) + // cf. nghyd#601 + + const n: Solveur = this._currentNub as Solveur; + n.prms.Ytarget.addObserver(this); + } + // interface Observer public update(sender: IObservable, data: any) { @@ -47,11 +58,20 @@ export class FormulaireSolveur extends FormulaireFixedVar { } } // copied from FormFixedVar, to avoid calling super.update() - if (data.action === "propertyChange") { + else if (data.action === "propertyChange") { this.reset(); + if (data.name === "nubToCalculate") { + const n = (this.currentNub as Solveur).nubToCalculate; + if (n !== undefined) { + const prms: SolveurParams = this.currentNub.prms as SolveurParams; + // update Ytarget + if (prms.Ytarget.singleValue === undefined && !ServiceFactory.applicationSetupService.enableEmptyFieldsOnFormInit) { + prms.Ytarget.singleValue = n.calculatedParam.singleValue; + } + } + } } - - if (sender instanceof SelectField) { + else if (sender instanceof SelectField) { if (sender.id === "select_target_nub" && data.action === "select") { // update Solveur property: Nub to calculate try { @@ -81,9 +101,7 @@ export class FormulaireSolveur extends FormulaireFixedVar { // reflect changes in GUI const inputXinit = this.getFormulaireNodeById("Xinit") as NgParameter; inputXinit.notifyValueModified(this); - } - } else if (sender instanceof SelectField) { - if (sender.id === this._targettedResultSelectId) { + } else if (sender.id === this._targettedResultSelectId) { // refresh parameters selector this.refreshParameterEntries(); } diff --git a/src/app/formulaire/elements/fieldset.ts b/src/app/formulaire/elements/fieldset.ts index 7b709eb764cb73580a7f56d1c2b24ed17b2a4c97..73e6b8535049442f73d2a8ac0dd748d32a53feeb 100644 --- a/src/app/formulaire/elements/fieldset.ts +++ b/src/app/formulaire/elements/fieldset.ts @@ -4,7 +4,8 @@ import { IProperties, Observer, Nub, - enumValueFromString + enumValueFromString, + ParamValueMode } from "jalhyd"; import { FormulaireElement } from "./formulaire-element"; @@ -215,8 +216,32 @@ export class FieldSet extends FormulaireElement implements IProperties { public updateFields(forceClear: boolean) { if (forceClear) { this.clearFields(); + this.parseFields(); } - this.parseFields(); + else { + const nub = this.parentForm.currentNub; + for (const e of this.parentForm.allFormElements) { + if (e instanceof NgParameter) { + const p: ParamDefinition = nub.getParameter(e.symbol); + switch (e.paramDefinition.valueMode) { + case ParamValueMode.SINGLE: + e.setValue(this, p.singleValue); + break; + + case ParamValueMode.MINMAX: + e.setMinValue(this, p.min); + e.setMaxValue(this, p.max); + e.setStepValue(this, p.step); + break; + + case ParamValueMode.LISTE: + e.setValueList(this, p.valueList); + break; + } + } + } + } + this.updateLocalisation(); // for all select fields known by the form, set selected value