From 559e4369e251e4511c1f3a1aac77ee3694e723b8 Mon Sep 17 00:00:00 2001
From: "mathias.chouet" <mathias.chouet@irstea.fr>
Date: Wed, 29 Jul 2020 15:28:56 +0200
Subject: [PATCH] Fix jalhyd#248 - load predefined Espece criteria

---
 src/app/app.module.ts                         |  3 +
 ...alog-load-predefined-espece.component.html | 25 ++++++++
 ...alog-load-predefined-espece.component.scss |  7 +++
 ...dialog-load-predefined-espece.component.ts | 61 +++++++++++++++++++
 .../calculator.component.html                 |  5 ++
 .../calculator.component.scss                 |  4 ++
 .../calculator.component.ts                   | 37 ++++++++++-
 .../formulaire/definition/form-fixedvar.ts    |  2 +-
 src/locale/messages.en.json                   |  1 +
 src/locale/messages.fr.json                   |  1 +
 10 files changed, 144 insertions(+), 2 deletions(-)
 create mode 100644 src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.html
 create mode 100644 src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.scss
 create mode 100644 src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.ts

diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 51dceda8d..b25a7887f 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -102,6 +102,7 @@ import { DialogEditParamComputedComponent } from "./components/dialog-edit-param
 import { DialogEditParamValuesComponent } from "./components/dialog-edit-param-values/dialog-edit-param-values.component";
 import { DialogGeneratePABComponent } from "./components/dialog-generate-pab/dialog-generate-pab.component";
 import { DialogGeneratePARSimulationComponent } from "./components/dialog-generate-par-simulation/dialog-generate-par-simulation.component";
+import { DialogLoadPredefinedEspeceComponent } from "./components/dialog-load-predefined-espece/dialog-load-predefined-espece.component";
 import { DialogLoadSessionComponent } from "./components/dialog-load-session/dialog-load-session.component";
 import { DialogLogEntriesDetailsComponent } from "./components/dialog-log-entries-details/dialog-log-entries-details.component";
 import { DialogSaveSessionComponent } from "./components/dialog-save-session/dialog-save-session.component";
@@ -192,6 +193,7 @@ const appRoutes: Routes = [
     DialogEditParamValuesComponent,
     DialogGeneratePABComponent,
     DialogGeneratePARSimulationComponent,
+    DialogLoadPredefinedEspeceComponent,
     DialogLoadSessionComponent,
     DialogLogEntriesDetailsComponent,
     DialogSaveSessionComponent,
@@ -245,6 +247,7 @@ const appRoutes: Routes = [
     DialogEditParamValuesComponent,
     DialogGeneratePABComponent,
     DialogGeneratePARSimulationComponent,
+    DialogLoadPredefinedEspeceComponent,
     DialogSaveSessionComponent,
     DialogLoadSessionComponent,
     DialogLogEntriesDetailsComponent
diff --git a/src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.html b/src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.html
new file mode 100644
index 000000000..13e394591
--- /dev/null
+++ b/src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.html
@@ -0,0 +1,25 @@
+<h1 mat-dialog-title [innerHTML]="uitextLoadPredefinedEspece"></h1>
+
+<form id="form-load-predefined-espece">
+
+  <div mat-dialog-content>
+    <mat-form-field>
+        <mat-select id="select-combination" [placeholder]="label" [(value)]="selectedValue">
+            <mat-option *ngFor="let e of entries" [value]="e" [title]="entryLabel(e)">
+                {{ entryLabel(e) }}
+            </mat-option>
+        </mat-select>
+    </mat-form-field>
+  </div>
+
+  <div mat-dialog-actions [attr.align]="'end'">
+    <button mat-raised-button color="primary" [mat-dialog-close]="false" cdkFocusInitial>
+      {{ uitextCancel }}
+    </button>
+    <button mat-raised-button type="submit" color="warn" (click)="loadPredefinedEspece()" id="do-load"
+      [disabled]="">
+      {{ uitextLoad }}
+    </button>
+  </div>
+
+</form>
diff --git a/src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.scss b/src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.scss
new file mode 100644
index 000000000..afeb091e7
--- /dev/null
+++ b/src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.scss
@@ -0,0 +1,7 @@
+#form-load-predefined-espece {
+    max-width: 500px;
+}
+
+mat-form-field {
+    width: 100%;
+}
diff --git a/src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.ts b/src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.ts
new file mode 100644
index 000000000..afebdcecb
--- /dev/null
+++ b/src/app/components/dialog-load-predefined-espece/dialog-load-predefined-espece.component.ts
@@ -0,0 +1,61 @@
+import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog";
+import { Inject, Component } from "@angular/core";
+
+import { I18nService } from "../../services/internationalisation.service";
+
+import { FishSpecies } from "jalhyd";
+
+@Component({
+    selector: "dialog-load-predefined-espece",
+    templateUrl: "dialog-load-predefined-espece.component.html",
+    styleUrls: ["dialog-load-predefined-espece.component.scss"]
+})
+export class DialogLoadPredefinedEspeceComponent {
+
+    public selectedValue: number;
+
+    constructor(
+        public dialogRef: MatDialogRef<DialogLoadPredefinedEspeceComponent>,
+        private intlService: I18nService,
+        @Inject(MAT_DIALOG_DATA) public data: any
+    ) {
+        this.selectedValue = 1;
+    }
+
+    public loadPredefinedEspece() {
+        this.dialogRef.close({
+            load: true,
+            selected: this.selectedValue
+        });
+    }
+
+    public get uitextLoadPredefinedEspece() {
+        return this.intlService.localizeText("INFO_CALCULATOR_LOAD_PREDEFINED_ESPECE");
+    }
+
+    public get uitextLoad() {
+        return this.intlService.localizeText("INFO_OPTION_LOAD");
+    }
+
+    public get uitextCancel() {
+        return this.intlService.localizeText("INFO_OPTION_CANCEL");
+    }
+
+    public get entries(): number[] {
+        const ret: number[] = [];
+        for (let j = 1; j < Object.keys(FishSpecies).length / 2; j++) { // exclude "0" (SPECIES_CUSTOM)
+            // const spgId = FishSpecies[j].substring(FishSpecies[j].lastIndexOf("_") + 1);
+            ret.push(j);
+        }
+        return ret;
+    }
+
+    protected entryLabel(index: number): string {
+        return this.intlService.localizeText("INFO_ENUM_" + FishSpecies[index]);
+    }
+
+    public get label() {
+        return this.intlService.localizeText("INFO_ESPECE_TITRE_COURT");
+    }
+
+}
diff --git a/src/app/components/generic-calculator/calculator.component.html b/src/app/components/generic-calculator/calculator.component.html
index 7b46d2c9e..ed13135ee 100644
--- a/src/app/components/generic-calculator/calculator.component.html
+++ b/src/app/components/generic-calculator/calculator.component.html
@@ -47,6 +47,11 @@
             <!-- nom du module de calcul -->
             <calc-name id="calculator-name" [title]="uitextCalculatorName"></calc-name>
 
+            <button mat-raised-button type="button" color="accent" id="load-predefined-espece" *ngIf="isEspece"
+              (click)="loadPredefinedEspece()" [title]="uitextLoadPredefinedEspece">
+                {{ uitextLoadPredefinedEspece }}
+            </button>
+
             <div id="calc-cards-container" class="container"
               [fxLayout]="isWide ? 'column' : 'row wrap'"
               [fxLayoutAlign]="isWide ? 'space-around stretch' : 'space-around start'">
diff --git a/src/app/components/generic-calculator/calculator.component.scss b/src/app/components/generic-calculator/calculator.component.scss
index 8507212be..1aa9e9e26 100644
--- a/src/app/components/generic-calculator/calculator.component.scss
+++ b/src/app/components/generic-calculator/calculator.component.scss
@@ -22,6 +22,10 @@
     margin-top: -54px;
 }
 
+#load-predefined-espece {
+    margin-bottom: 1em;
+}
+
 mat-card {
     margin-bottom: 2em;
 
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index d9d8f93ce..0e35ac269 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -18,7 +18,8 @@ import {
     RegimeUniforme,
     Par,
     ParSimulationParams,
-    ParSimulation
+    ParSimulation,
+    Espece
 } from "jalhyd";
 
 import { generateValuesCombination } from "../../util";
@@ -41,9 +42,11 @@ import { MatDialog } from "@angular/material/dialog";
 import { DialogConfirmCloseCalcComponent } from "../dialog-confirm-close-calc/dialog-confirm-close-calc.component";
 import { DialogGeneratePABComponent } from "../dialog-generate-pab/dialog-generate-pab.component";
 import { DialogGeneratePARSimulationComponent } from "../dialog-generate-par-simulation/dialog-generate-par-simulation.component";
+import { DialogLoadPredefinedEspeceComponent } from "../dialog-load-predefined-espece/dialog-load-predefined-espece.component";
 import { PabTable } from "../../formulaire/elements/pab-table";
 import { MultiDimensionResults } from "../../results/multidimension-results";
 import { NgParameter } from "../../formulaire/elements/ngparam";
+import { FormulaireFixedVar } from "../../formulaire/definition/form-fixedvar";
 
 import { HotkeysService, Hotkey } from "angular2-hotkeys";
 
@@ -128,6 +131,7 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
         private confirmCloseCalcDialog: MatDialog,
         private generatePABDialog: MatDialog,
         private generatePARSimulationDialog: MatDialog,
+        private loadPredefinedEspeceDialog: MatDialog,
         private _elementRef: ElementRef,
         private hotkeysService: HotkeysService,
         private appSetupService: ApplicationSetupService,
@@ -231,6 +235,10 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
         return this.intlService.localizeText("INFO_CALCULATOR_RESULTS_GENERATE_PAR_SIMULATION");
     }
 
+    public get uitextLoadPredefinedEspece(): string {
+        return this.intlService.localizeText("INFO_CALCULATOR_LOAD_PREDEFINED_ESPECE");
+    }
+
     public get uitextOpenHelp() {
         return this.intlService.localizeText("INFO_CALCULATOR_OPEN_HELP");
     }
@@ -618,6 +626,11 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
         return this.is(CalculatorType.Par);
     }
 
+    // true if current Nub is Espece
+    public get isEspece() {
+        return this.is(CalculatorType.Espece);
+    }
+
     /**
      * Returns true if no parameter is varying; ignores parameters having
      * one of the given {except} symbols, if any
@@ -975,6 +988,28 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
         );
     }
 
+    /**
+     * Opens a modal that allows to choose a predefined Espece
+     * and load its values in current Espece module
+     */
+    public loadPredefinedEspece() {
+        const dialogRef = this.loadPredefinedEspeceDialog.open(
+            DialogLoadPredefinedEspeceComponent,
+            {
+                data: { },
+                disableClose: false
+            }
+        );
+        dialogRef.afterClosed().subscribe(result => {
+            if (result && result.load) {
+                const form = this._formulaire as FormulaireFixedVar;
+                const nub = (form.currentNub as Espece);
+                nub.loadPredefinedSpecies(result.selected);
+                form.refreshFieldsets();
+            }
+        });
+    }
+
     public saveCalculator() {
         this.formulaireService.saveForm(this._formulaire);
     }
diff --git a/src/app/formulaire/definition/form-fixedvar.ts b/src/app/formulaire/definition/form-fixedvar.ts
index ca74b364d..87b008f0c 100644
--- a/src/app/formulaire/definition/form-fixedvar.ts
+++ b/src/app/formulaire/definition/form-fixedvar.ts
@@ -144,7 +144,7 @@ export class FormulaireFixedVar extends FormulaireDefinition {
     /**
      * Forces all fieldsets to update all their fields
      */
-    protected refreshFieldsets() {
+    public refreshFieldsets() {
         for (const fs of this.allFieldsets) {
             fs.updateFields();
         }
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index faaad8191..92186a745 100644
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -70,6 +70,7 @@
     "INFO_CALCULATOR_CALCULER": "Compute",
     "INFO_CALCULATOR_CLONE": "Duplicate",
     "INFO_CALCULATOR_CLOSE": "Close",
+    "INFO_CALCULATOR_LOAD_PREDEFINED_ESPECE": "Load predefined species",
     "INFO_CALCULATOR_OPEN_HELP": "Help",
     "INFO_CALCULATOR_PARAMFIXES": "Fixed parameters",
     "INFO_CALCULATOR_RESULTS_GENERATE_PAB": "Generate a fish ladder",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index b1e5adfb3..5788a49dc 100644
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -70,6 +70,7 @@
     "INFO_CALCULATOR_CALCULER": "Calculer",
     "INFO_CALCULATOR_CLONE": "Dupliquer",
     "INFO_CALCULATOR_CLOSE": "Fermer",
+    "INFO_CALCULATOR_LOAD_PREDEFINED_ESPECE": "Charger une espèce prédéfinie",
     "INFO_CALCULATOR_OPEN_HELP": "Aide",
     "INFO_CALCULATOR_PARAMFIXES": "Paramètres fixés",
     "INFO_CALCULATOR_RESULTS_GENERATE_PAB": "Générer une passe à bassins",
-- 
GitLab