From 4cdfe3ffb2bdca6c4f7c983210d4f0f68efdc6f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Mon, 21 Mar 2022 15:46:52 +0100
Subject: [PATCH 1/2] feat: add cancel button to variable parameter dialog

- fix enabled "switch to graph" button when form is invalid
- fix modification of the original parameter (now only modified when form is closed with "validate" button)

Fix #507
---
 jalhyd_branch                                 |  2 +-
 .../dialog-edit-param-values.component.html   | 12 ++--
 .../dialog-edit-param-values.component.ts     | 70 +++++++++++--------
 src/app/formulaire/elements/ngparam.ts        |  8 +++
 4 files changed, 53 insertions(+), 39 deletions(-)

diff --git a/jalhyd_branch b/jalhyd_branch
index 626e97d71..084f9effb 100644
--- a/jalhyd_branch
+++ b/jalhyd_branch
@@ -1 +1 @@
-devel
\ No newline at end of file
+300-supprimer-le-champ-_valuemode-dans-paramdefinition
\ No newline at end of file
diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
index 8a454d5c1..e8dbbb2c9 100644
--- a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
+++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
@@ -1,4 +1,5 @@
-<button mat-icon-button id="show-values-chart" (click)="toggleViewChart()" [title]="uitextShowValuesChart">
+<button mat-icon-button id="show-values-chart" (click)="toggleViewChart()" [title]="uitextShowValuesChart"
+    [disabled]="!viewChart && !isFormValid">
     <mat-icon *ngIf="! viewChart">show_chart</mat-icon>
     <mat-icon *ngIf="viewChart">mode_edit</mat-icon>
 </button>
@@ -119,16 +120,11 @@
 </div>
 
 <div mat-dialog-actions [attr.align]="'end'">
-    <div *ngIf="isMinMax || viewChart">
-        <button mat-raised-button [mat-dialog-close]="true" [disabled]="minMaxFormInvalid" cdkFocusInitial>
-            {{ uitextClose }}
-        </button>
-    </div>
-    <div *ngIf="isListe && ! viewChart">
+    <div>
         <button mat-raised-button color="primary" [mat-dialog-close]="true" cdkFocusInitial>
             {{ uitextCancel }}
         </button>
-        <button mat-raised-button color="warn" (click)="onValidate()">
+        <button mat-raised-button color="warn" (click)="onValidate()" [disabled]=" !isFormValid">
             {{ uitextValidate }}
         </button>
     </div>
diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
index 3c419f000..d84c85459 100644
--- a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
+++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts
@@ -53,7 +53,7 @@ export class DialogEditParamValuesComponent implements OnInit {
         private fb: FormBuilder,
         @Inject(MAT_DIALOG_DATA) public data: any
     ) {
-        this.param = data.param;
+        this.param = data.param.clone();
         // an explicit ReactiveForm is required for file input component
         const initialValue = (this.param.valueMode === ParamValueMode.LISTE ? this.valuesList : "");
         this.valuesListForm = this.fb.group({
@@ -245,42 +245,56 @@ export class DialogEditParamValuesComponent implements OnInit {
         this.param.setValueList(this, vals);
     }
 
-    /** returns true if min/max/step form is invalid */
-    public get minMaxFormInvalid(): boolean {
-        return this.minMaxForm === undefined || ! this.minMaxForm.valid;
-    }
-
     public toggleViewChart() {
-        // validate list values before switching views ?
-        if (! this.viewChart && this.param.valueMode === ParamValueMode.LISTE) {
-            if (this.onValidate(false)) {
+        // validate values before switching views ?
+        if (!this.viewChart && this.isFormValid) {
                 // toggle
-                this.viewChart = ! this.viewChart;
+            this.viewChart = true;
             }
-        } else {
-            // toggle
-            this.viewChart = ! this.viewChart;
-        }
+        else
+            this.viewChart = false;
+
         // refresh chart when displaying it only
         if (this.viewChart) {
             this.drawChart();
         }
     }
 
-    public onValidate(close = true) {
-        const status = this.validateValuesListString(this.valuesListForm.controls.valuesList.value);
+    /** returns true if form is valid */
+    public get isFormValid(): boolean {
+        var ret: boolean = false;
+        switch (this.param.valueMode) {
+            case ParamValueMode.LISTE:
+                const status = this.validateValuesListString(this.valuesListForm.controls.valuesList.value);
+                ret = status.ok;
+                if (ret) {
+                    this.valuesListForm.controls.valuesList.setErrors(null);
+                    this.valuesList = this.valuesListForm.controls.valuesList.value;
+                }
+                else
+                    this.valuesListForm.controls.valuesList.setErrors({ "model": status.message });
+                break;
 
-        if (status.ok) {
-            this.valuesListForm.controls.valuesList.setErrors(null);
-            this.valuesList = this.valuesListForm.controls.valuesList.value;
-            if (close) {
-                this.dialogRef.close();
-            }
-            return true;
-        } else {
-            this.valuesListForm.controls.valuesList.setErrors({ "model": status.message });
-            return false;
+            case ParamValueMode.MINMAX:
+                ret = this.minMaxForm !== undefined && this.minMaxForm.valid;
+                break;
         }
+        return ret;
+    }
+
+    public onValidate() {
+        switch (this.param.valueMode) {
+            case ParamValueMode.LISTE:
+                this.data.param.setValueList(this, this.param.valueList);
+                break;
+
+            case ParamValueMode.MINMAX:
+                this.data.param.setMinValue(this, this.param.minValue);
+                this.data.param.setMaxValue(this, this.param.maxValue);
+                this.data.param.setStepValue(this, this.param.stepValue);
+                break;
+        }
+        this.dialogRef.close();
     }
 
     /**
@@ -442,10 +456,6 @@ export class DialogEditParamValuesComponent implements OnInit {
         return this.intlService.localizeText("INFO_PARAMFIELD_PASVARIATION");
     }
 
-    public get uitextClose(): string {
-        return this.intlService.localizeText("INFO_OPTION_CLOSE");
-    }
-
     public get uitextCancel(): string {
         return this.intlService.localizeText("INFO_OPTION_CANCEL");
     }
diff --git a/src/app/formulaire/elements/ngparam.ts b/src/app/formulaire/elements/ngparam.ts
index 7943071ed..697667f6c 100644
--- a/src/app/formulaire/elements/ngparam.ts
+++ b/src/app/formulaire/elements/ngparam.ts
@@ -42,6 +42,14 @@ export class NgParameter extends InputField implements Observer {
         this.disabled = false;
     }
 
+    public clone(): NgParameter {
+        const ret: NgParameter = new NgParameter(this._paramDef.clone(), this.parent);
+        ret._allowEmpty = this._allowEmpty;
+        ret.unit = this.unit;
+        ret.disabled = this.disabled;
+        return ret;
+    }
+
     /**
      * Returns a text preview of the current value(s), depending on the value mode
      * @param compact if true, will represent multiple values in a more compact way
-- 
GitLab


From f61e3d356a6bb66eb28e09e41df8cca3cbf3efc2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 6 Apr 2022 13:57:50 +0200
Subject: [PATCH 2/2] test: e2e check that cancel button is present in variable
 parameter edition dialog

refs #507
---
 .vscode/launch.json                           | 24 +++++++++++++--
 e2e/variable-param-cancel.e2e-spec.ts         | 30 +++++++++++++++++++
 .../dialog-edit-param-values.component.html   |  2 +-
 3 files changed, 53 insertions(+), 3 deletions(-)
 create mode 100644 e2e/variable-param-cancel.e2e-spec.ts

diff --git a/.vscode/launch.json b/.vscode/launch.json
index 560298a30..1d92791fc 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -10,7 +10,10 @@
             "name": "Launch Chrome (local webserver)",
             "url": "http://localhost:4200",
             "webRoot": "${workspaceFolder}",
-            "runtimeExecutable": "/usr/bin/chromium-browser"
+            "runtimeExecutable": "/usr/bin/chromium",
+            "runtimeArgs": [
+                "--preserve-symlinks"
+            ]
         },
         {
             "name": "Launch Firefox (local webserver)",
@@ -19,6 +22,23 @@
             "reAttach": true,
             "url": "http://localhost:4200",
             "webRoot": "${workspaceFolder}"
+        },
+        {
+            "name": "Launch e2e current file",
+            "type": "node",
+            "request": "launch",
+            "stopOnEntry": false,
+            "program": "${workspaceRoot}/node_modules/protractor/bin/protractor",
+            "args": [
+                "${workspaceRoot}/protractor.conf.js",
+                "--specs=${file}"
+            ],
+            "cwd": "${workspaceRoot}",
+            "sourceMaps": true,
+            "outFiles": [
+                "${workspaceRoot}/dist/out-tsc-e2e/*.js"
+            ],
+            "skipSourceMapSupport": true
         }
     ]
-}
\ No newline at end of file
+}
diff --git a/e2e/variable-param-cancel.e2e-spec.ts b/e2e/variable-param-cancel.e2e-spec.ts
new file mode 100644
index 000000000..750fdd160
--- /dev/null
+++ b/e2e/variable-param-cancel.e2e-spec.ts
@@ -0,0 +1,30 @@
+import { ListPage } from "./list.po";
+import { by, element } from "protractor";
+
+/**
+ * Check that a cancel button is present in min/max/list edition dialog
+ * for variable parameters
+ */
+describe("ngHyd - check cancel button for variable parameters - ", () => {
+    let listPage: ListPage;
+
+    beforeAll(async () => {
+        listPage = new ListPage();
+    });
+
+    fit("when min/max/list values dialog opens, a cancel button should be present", async () => {
+        // start page
+        await listPage.navigateTo();
+
+        // open PAB chute
+        await listPage.clickMenuEntryForCalcType(12);
+
+        // click "var" radio on Z1 parameter
+        const z1btn = element(by.id("mat-button-toggle-2-button"));
+        await z1btn.click();
+
+        // cancel button presence
+        const cancelbtn = element(by.id("btn-cancel"));
+        expect(await cancelbtn.isPresent() && await cancelbtn.isDisplayed()).toBeTruthy();
+    });
+});
diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
index e8dbbb2c9..5fc7c8482 100644
--- a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
+++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html
@@ -121,7 +121,7 @@
 
 <div mat-dialog-actions [attr.align]="'end'">
     <div>
-        <button mat-raised-button color="primary" [mat-dialog-close]="true" cdkFocusInitial>
+        <button id="btn-cancel" mat-raised-button color="primary" [mat-dialog-close]="true" cdkFocusInitial>
             {{ uitextCancel }}
         </button>
         <button mat-raised-button color="warn" (click)="onValidate()" [disabled]=" !isFormValid">
-- 
GitLab