From 76637c4130eb097ec8e32524db920a0c9fbabcc8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Sun, 8 May 2022 06:22:05 +0200
Subject: [PATCH 1/6] refactor: factorise fish ladder, predams, compound rock
 ramp fishpasses logging code to new LogHelper class

refs #517
---
 .../macrorugo-compound-results.component.ts   | 135 +-------------
 .../pab-results/pab-results.component.ts      | 160 +---------------
 .../pb-results/pb-results.component.ts        | 159 ++--------------
 src/app/results/log-helper.ts                 | 172 ++++++++++++++++++
 4 files changed, 206 insertions(+), 420 deletions(-)
 create mode 100644 src/app/results/log-helper.ts

diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
index 232f0c436..a17be949b 100644
--- a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
+++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
@@ -10,6 +10,7 @@ import { ApplicationSetupService } from "../../services/app-setup.service";
 import { I18nService } from "../../services/internationalisation.service";
 import { MacrorugoCompoundResults } from "../../results/macrorugo-compound-results";
 import { ResultsComponentDirective } from "../fixedvar-results/results.component";
+import { LogHelper } from "app/results/log-helper";
 
 @Component({
     selector: "macrorugo-compound-results",
@@ -23,6 +24,8 @@ export class MacrorugoCompoundResultsComponent extends ResultsComponentDirective
     /** résultats non mis en forme */
     private _mrcResults: MacrorugoCompoundResults;
 
+    private _logHelper: LogHelper;
+
     constructor(
         private appSetupService: ApplicationSetupService,
         private i18nService: I18nService,
@@ -33,143 +36,19 @@ export class MacrorugoCompoundResultsComponent extends ResultsComponentDirective
     @Input()
     public set results(rs: CalculatorResults[]) {
         this._mrcResults = undefined;
+        this._logHelper = undefined;
         if (rs.length > 0 && rs[0] instanceof MacrorugoCompoundResults) {
             this._mrcResults = rs[0] as MacrorugoCompoundResults;
+            this._logHelper = new LogHelper(this._mrcResults, this._mrcResults.childrenResults);
         }
     }
 
-    private mergeGlobalLog(result: Result, log: cLog) {
-        if (result) {
-            if (result.hasGlobalLog()) {
-                log.addLog(result.globalLog);
-            }
-            // if no parameter is varying, 1st element log is considered "global"
-            if (this.mrcResults.variatedParameters.length === 0) {
-                if (result.hasResultElements() && result.resultElement.hasLog()) {
-                    log.addLog(result.log);
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns the number of errors, warnings, infos among children logs
-     */
-    private logStats(): any {
-        const ret = {
-            info: 0,
-            warning: 0,
-            error: 0
-        };
-        if (this._mrcResults.result && this._mrcResults.result.hasLog()) {
-            for (const re of this._mrcResults.result.resultElements) {
-                if (re.hasLog()) {
-                    for (const m of re.log.messages) {
-                        const s = m.getSeverity();
-                        switch (s) {
-                            case MessageSeverity.INFO:
-                                ret.info ++;
-                                break;
-                            case MessageSeverity.WARNING:
-                                ret.warning ++;
-                                break;
-                            case MessageSeverity.ERROR:
-                                ret.error ++;
-                                break;
-                        }
-                    }
-                }
-            }
-        }
-        for (const cr of this._mrcResults.childrenResults) {
-            if (cr && cr.hasLog()) {
-                for (const re of cr.resultElements) {
-                    if (re.hasLog()) {
-                        for (const m of re.log.messages) {
-                            const s = m.getSeverity();
-                            switch (s) {
-                                case MessageSeverity.INFO:
-                                    ret.info ++;
-                                    break;
-                                case MessageSeverity.WARNING:
-                                    ret.warning ++;
-                                    break;
-                                case MessageSeverity.ERROR:
-                                    ret.error ++;
-                                    break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return ret;
-    }
-
-    /*
-     * Retourne les logs à afficher dans le composant de log global, au dessus
-     * du sélecteur d'itération : messages globaux et / ou résumé des messages
-     * spécifiques à chaque ResultElement
-     */
     public get globalLog(): cLog {
-        const l = new cLog();
-        if (this._mrcResults && this.mrcResults.variatedParameters.length > 0) {
-            this.mergeGlobalLog(this._mrcResults.result, l);
-            // un problème avec la MRC en général / les cloisons, à une étape quelconque ?
-            if (
-                (this.mrcResults.hasLog)
-                && l.messages.length === 0 // existing global messages make generic message below useless
-            ) {
-                const logStats = this.logStats();
-                const m = new Message(MessageCode.WARNING_PROBLEMS_ENCOUNTERED);
-                m.extraVar.info = "" + logStats.info; // to avoid displaying fixed number of digits
-                m.extraVar.warning = "" + logStats.warning;
-                m.extraVar.error = "" + logStats.error;
-                l.add(m);
-                // l.add(new Message(MessageCode.WARNING_PROBLEMS_ENCOUNTERED));
-            }
-        } // sinon pas de log global (aucun paramètre ne varie)
-        return l;
+        return this._logHelper.globalLog;
     }
 
-    /**
-     * Retourne les logs à afficher dans le composant de log local, en dessous
-     * du sélecteur d'itération : messages concernant l'itération (le ResultElement)
-     * en cours
-     */
     public get iterationLog(): cLog {
-        const l = new cLog();
-        if (this._mrcResults) {
-            if (this.mrcResults.variatedParameters.length > 0) {
-                // A. si un paramètre varie
-                const vi = this._mrcResults.variableIndex;
-                // log de la MRC pour l'itération en cours
-                if (
-                    this._mrcResults.result
-                    && this._mrcResults.result.hasResultElements()
-                    && this._mrcResults.result.resultElements[vi]
-                    && this._mrcResults.result.resultElements[vi].hasLog()
-                ) {
-                    l.addLog(this._mrcResults.result.resultElements[vi].log);
-                }
-                // logs des enfants pour l'itération en cours
-                for (const cr of this._mrcResults.childrenResults) {
-                    if (cr && cr.hasResultElements() && cr.resultElements[vi].hasLog()) {
-                        l.addLog(cr.resultElements[vi].log);
-                    }
-                }
-            } else {
-                // B. si aucun paramètre ne varie
-                this.mergeGlobalLog(this._mrcResults.result, l); // faut bien mettre le log global quelque part
-                // logs des enfants
-                for (const cr of this._mrcResults.childrenResults) {
-                    if (cr && cr.hasResultElements() && cr.resultElement.hasLog()) {
-                        l.addLog(cr.resultElement.log);
-                    }
-                }
-            }
-        }
-        return l;
+        return this._logHelper.iterationLog;
     }
 
     public get mrcResults() {
diff --git a/src/app/components/pab-results/pab-results.component.ts b/src/app/components/pab-results/pab-results.component.ts
index bb190be6a..0a0777045 100644
--- a/src/app/components/pab-results/pab-results.component.ts
+++ b/src/app/components/pab-results/pab-results.component.ts
@@ -1,4 +1,5 @@
 import { Component, Input } from "@angular/core";
+import { LogHelper } from "app/results/log-helper";
 
 import { Result, cLog, Message, MessageCode, MessageSeverity } from "jalhyd";
 
@@ -19,6 +20,8 @@ export class PabResultsComponent extends ResultsComponentDirective {
     /** résultats non mis en forme */
     private _pabResults: PabResults;
 
+    private _logHelper: LogHelper;
+
     constructor(
         private i18nService: I18nService,
     ) {
@@ -30,167 +33,18 @@ export class PabResultsComponent extends ResultsComponentDirective {
         this._pabResults = undefined;
         if (rs.length > 0 && rs[0] instanceof PabResults) {
             this._pabResults = rs[0] as PabResults;
-        }
-    }
-
-    private mergeGlobalLog(result: Result, log: cLog) {
-        if (result) {
-            if (result.hasGlobalLog()) {
-                log.addLog(result.globalLog);
-            }
-            // if no parameter is varying, 1st element log is considered "global"
-            if (this.pabResults.variatedParameters.length === 0) {
-                if (result.hasResultElements() && result.resultElement.hasLog()) {
-                    log.addLog(result.log);
-                }
-            }
-        }
-    }
 
-    /**
-     * Returns the number of errors, warnings, infos among children logs
-     */
-    private logStats(): any {
-        const ret = {
-            info: 0,
-            warning: 0,
-            error: 0
-        };
-        if (this._pabResults.result && this._pabResults.result.hasLog()) {
-            for (const re of this._pabResults.result.resultElements) {
-                if (re.hasLog()) {
-                    for (const m of re.log.messages) {
-                        const s = m.getSeverity();
-                        switch (s) {
-                            case MessageSeverity.INFO:
-                                ret.info ++;
-                                break;
-                            case MessageSeverity.WARNING:
-                                ret.warning ++;
-                                break;
-                            case MessageSeverity.ERROR:
-                                ret.error ++;
-                                break;
-                        }
-                    }
-                }
-            }
-        }
-        for (const cr of this._pabResults.cloisonsResults) {
-            if (cr && cr.hasLog()) {
-                for (const re of cr.resultElements) {
-                    if (re.hasLog()) {
-                        for (const m of re.log.messages) {
-                            const s = m.getSeverity();
-                            switch (s) {
-                                case MessageSeverity.INFO:
-                                    ret.info ++;
-                                    break;
-                                case MessageSeverity.WARNING:
-                                    ret.warning ++;
-                                    break;
-                                case MessageSeverity.ERROR:
-                                    ret.error ++;
-                                    break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        if (this._pabResults.cloisonAvalResults && this._pabResults.cloisonAvalResults.hasLog()) {
-            for (const re of this._pabResults.cloisonAvalResults.resultElements) {
-                if (re.hasLog()) {
-                    for (const m of re.log.messages) {
-                        const s = m.getSeverity();
-                        switch (s) {
-                            case MessageSeverity.INFO:
-                                ret.info ++;
-                                break;
-                            case MessageSeverity.WARNING:
-                                ret.warning ++;
-                                break;
-                            case MessageSeverity.ERROR:
-                                ret.error ++;
-                                break;
-                        }
-                    }
-                }
-            }
+            // log helper
+            this._logHelper = new LogHelper(this._pabResults, this._pabResults.cloisonsResults, this._pabResults.cloisonAvalResults);
         }
-        return ret;
     }
 
-    /*
-     * Retourne les logs à afficher dans le composant de log global, au dessus
-     * du sélecteur d'itération : messages globaux et / ou résumé des messages
-     * spécifiques à chaque ResultElement
-     */
     public get globalLog(): cLog {
-        const l = new cLog();
-        if (this._pabResults && this.pabResults.variatedParameters.length > 0) {
-            this.mergeGlobalLog(this._pabResults.result, l);
-            // un problème avec la PAB en général / les cloisons, à une étape quelconque ?
-            if (
-                (this.pabResults.hasLog)
-                && l.messages.length === 0 // existing global messages make generic message below useless
-            ) {
-                const logStats = this.logStats();
-                const m = new Message(MessageCode.WARNING_PROBLEMS_ENCOUNTERED);
-                m.extraVar.info = "" + logStats.info; // to avoid displaying fixed number of digits
-                m.extraVar.warning = "" + logStats.warning;
-                m.extraVar.error = "" + logStats.error;
-                l.add(m);
-                // l.add(new Message(MessageCode.WARNING_PROBLEMS_ENCOUNTERED));
-            }
-        } // sinon pas de log global (aucun paramètre ne varie)
-        return l;
+        return this._logHelper.globalLog;
     }
 
-    /**
-     * Retourne les logs à afficher dans le composant de log local, en dessous
-     * du sélecteur d'itération : messages concernant l'itération (le ResultElement)
-     * en cours
-     */
     public get iterationLog(): cLog {
-        const l = new cLog();
-        if (this._pabResults) {
-            if (this.pabResults.variatedParameters.length > 0) {
-                // A. si un paramètre varie
-                const vi = this._pabResults.variableIndex;
-                // log de la PAB pour l'itération en cours
-                if (
-                    this._pabResults.result
-                    && this._pabResults.result.hasResultElements()
-                    && this._pabResults.result.resultElements[vi]
-                    && this._pabResults.result.resultElements[vi].hasLog()
-                ) {
-                    l.addLog(this._pabResults.result.resultElements[vi].log);
-                }
-                // logs des enfants pour l'itération en cours
-                for (const cr of this._pabResults.cloisonsResults) {
-                    if (cr && cr.hasResultElements() && cr.resultElements[vi].hasLog()) {
-                        l.addLog(cr.resultElements[vi].log);
-                    }
-                }
-                if (this._pabResults.cloisonAvalResults && this._pabResults.cloisonAvalResults.resultElements[vi].hasLog()) {
-                    l.addLog(this._pabResults.cloisonAvalResults.resultElements[vi].log);
-                }
-            } else {
-                // B. si aucun paramètre ne varie
-                this.mergeGlobalLog(this._pabResults.result, l); // faut bien mettre le log global quelque part
-                // logs des enfants
-                for (const cr of this._pabResults.cloisonsResults) {
-                    if (cr && cr.hasResultElements() && cr.resultElement.hasLog()) {
-                        l.addLog(cr.resultElement.log);
-                    }
-                }
-                if (this._pabResults.cloisonAvalResults && this._pabResults.cloisonAvalResults.resultElement.hasLog()) {
-                    l.addLog(this._pabResults.cloisonAvalResults.resultElement.log);
-                }
-            }
-        }
-        return l;
+        return this._logHelper.iterationLog;
     }
 
     public get pabResults() {
diff --git a/src/app/components/pb-results/pb-results.component.ts b/src/app/components/pb-results/pb-results.component.ts
index a5136f9e9..4b0f2b77a 100644
--- a/src/app/components/pb-results/pb-results.component.ts
+++ b/src/app/components/pb-results/pb-results.component.ts
@@ -5,6 +5,8 @@ import { PrebarrageResults } from "../../results/prebarrage-results";
 import { I18nService } from "../../services/internationalisation.service";
 
 import { cLog, Message, MessageCode, MessageSeverity, PreBarrage, Result } from "jalhyd";
+import { ServiceFactory } from "app/services/service-factory";
+import { LogHelper } from "app/results/log-helper";
 
 @Component({
     selector: "pb-results",
@@ -18,6 +20,8 @@ export class PbResultsComponent {
     /** résultats des bassins, non mis en forme */
     private _pbResults: PrebarrageResults;
 
+    private _logHelper: LogHelper;
+
     constructor(
         private i18nService: I18nService,
     ) { }
@@ -25,9 +29,23 @@ export class PbResultsComponent {
     @Input()
     public set results(rs: CalculatorResults[]) {
         this._pbResults = undefined;
+        this._logHelper = undefined;
         for (const r of rs) {
             if (r instanceof PrebarrageResults) {
                 this._pbResults = r as PrebarrageResults;
+
+                // log helper
+
+                const childResults: Result[] = [];
+                const sn = this._pbResults.result?.sourceNub as PreBarrage;
+                if (sn?.children) {
+                    for (const cr of sn.children) {
+                        if (cr.result) {
+                            childResults.push(cr.result);
+                        }
+                    }
+                }
+                this._logHelper = new LogHelper(this._pbResults, childResults);
             }
         }
     }
@@ -56,149 +74,12 @@ export class PbResultsComponent {
         return this._pbResults && this._pbResults.hasWallResults;
     }
 
-    private mergeGlobalLog(result: Result, log: cLog) {
-        if (result) {
-            if (result.hasGlobalLog()) {
-                log.addLog(result.globalLog);
-            }
-            // if no parameter is varying, 1st element log is considered "global"
-            if (this.pbResults.variatedParameters.length === 0) {
-                if (result.hasResultElements() && result.resultElement.hasLog()) {
-                    log.addLog(result.log);
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns the number of errors, warnings, infos among children logs
-     */
-    private logStats(): any {
-        const ret = {
-            info: 0,
-            warning: 0,
-            error: 0
-        };
-        if (this._pbResults.result?.hasLog()) {
-            for (const re of this._pbResults.result.resultElements) {
-                if (re.hasLog()) {
-                    for (const m of re.log.messages) {
-                        const s = m.getSeverity();
-                        switch (s) {
-                            case MessageSeverity.INFO:
-                                ret.info ++;
-                                break;
-                            case MessageSeverity.WARNING:
-                                ret.warning ++;
-                                break;
-                            case MessageSeverity.ERROR:
-                                ret.error ++;
-                                break;
-                        }
-                    }
-                }
-            }
-        }
-        const pb = this._pbResults.result.sourceNub as PreBarrage;
-        for (const pbc of pb.children) { // bassins et cloisons
-            if (pbc.result !== undefined) {
-                for (const re of pbc.result.resultElements) {
-                    if (re.hasLog()) {
-                        for (const m of re.log.messages) {
-                            const s = m.getSeverity();
-                            switch (s) {
-                                case MessageSeverity.INFO:
-                                    ret.info ++;
-                                    break;
-                                case MessageSeverity.WARNING:
-                                    ret.warning ++;
-                                    break;
-                                case MessageSeverity.ERROR:
-                                    ret.error ++;
-                                    break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return ret;
-    }
-
-    /*
-     * Retourne les logs à afficher dans le composant de log global, au dessus
-     * du sélecteur d'itération : messages globaux et / ou résumé des messages
-     * spécifiques à chaque ResultElement
-     */
     public get globalLog(): cLog {
-        const l = new cLog();
-        /* console.log(
-            `>> Global Log >> this._pbResults: ${this._pbResults !== undefined}`
-            + `, vpl: ${this?._pbResults?.variatedParameters?.length}`
-            + `, hasLog: ${this?._pbResults?.hasLog}`
-        ); */
-        if (this._pbResults && this.pbResults.variatedParameters.length > 0) {
-            this.mergeGlobalLog(this._pbResults.result, l);
-            // console.log(">>>> after merge, messages length=", l.messages.length);
-            // un problème avec le PB en général / les cloisons / les bassins, à une étape quelconque ?
-            if (
-                (this.pbResults.hasLog)
-                && l.messages.length === 0 // existing global messages make generic message below useless
-            ) {
-                const logStats = this.logStats();
-                const m = new Message(MessageCode.WARNING_PROBLEMS_ENCOUNTERED);
-                m.extraVar.info = "" + logStats.info; // to avoid displaying fixed number of digits
-                m.extraVar.warning = "" + logStats.warning;
-                m.extraVar.error = "" + logStats.error;
-                l.add(m);
-            }
-        } // sinon pas de log global (aucun paramètre ne varie)
-        return l;
+        return this._logHelper.globalLog;
     }
 
-    /**
-     * Retourne les logs à afficher dans le composant de log local, en dessous
-     * du sélecteur d'itération : messages concernant l'itération (le ResultElement)
-     * en cours
-     */
     public get iterationLog(): cLog {
-        const l = new cLog();
-        if (this._pbResults?.result) {
-            const pb = this._pbResults.result.sourceNub as PreBarrage;
-            if (this._pbResults.variatedParameters.length > 0) {
-                // A. si un paramètre varie
-                const vi = this._pbResults.variableIndex;
-                // log du PB pour l'itération en cours
-                if (
-                    this._pbResults.result
-                    && this._pbResults.result.hasResultElements()
-                    && this._pbResults.result.resultElements[vi]
-                    && this._pbResults.result.resultElements[vi]?.hasLog()
-                ) {
-                    l.addLog(this._pbResults.result.resultElements[vi].log);
-                }
-                // logs des enfants pour l'itération en cours
-                if (pb !== undefined) {
-                    for (const pbc of pb.children) {
-                        if (pbc?.result?.hasResultElements() && pbc.result.resultElements[vi]?.hasLog()) {
-                            l.addLog(pbc.result.resultElements[vi].log);
-                        }
-                    }
-                }
-            } else {
-                // B. si aucun paramètre ne varie
-                this.mergeGlobalLog(this._pbResults.result, l); // faut bien mettre le log global quelque part
-                // logs des enfants
-                if (pb !== undefined) {
-                    for (const pbc of pb.children) {
-                        if (pbc?.result?.hasResultElements() && pbc.result.resultElement?.hasLog()) {
-                            l.addLog(pbc.result.resultElement.log);
-                        }
-                    }
-                }
-            }
-        }
-        return l;
+        return this._logHelper.iterationLog;
     }
 
     public get uitextGeneralLogTitle(): string {
diff --git a/src/app/results/log-helper.ts b/src/app/results/log-helper.ts
new file mode 100644
index 000000000..1f24f07ac
--- /dev/null
+++ b/src/app/results/log-helper.ts
@@ -0,0 +1,172 @@
+import { cLog, Message, MessageCode, MessageSeverity, Result } from "jalhyd";
+import { MultiDimensionResults } from "./multidimension-results";
+
+/**
+ * calculation log helpers
+ */
+export class LogHelper {
+    constructor(private _mdr: MultiDimensionResults, private _childrenResults: Result[], private _extraResult?: Result) {
+    }
+
+    private mergeGlobalLog(result: Result, log: cLog) {
+        if (result) {
+            if (result.hasGlobalLog()) {
+                log.addLog(result.globalLog);
+            }
+            // if no parameter is varying, 1st element log is considered "global"
+            if (this._mdr.variatedParameters.length === 0) {
+                if (result.hasResultElements() && result.resultElement.hasLog()) {
+                    log.addLog(result.log);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the number of errors, warnings, infos among children logs
+     */
+    private logStats(): any {
+        const ret = {
+            info: 0,
+            warning: 0,
+            error: 0
+        };
+        if (this._mdr.result?.hasLog()) {
+            for (const re of this._mdr.result.resultElements) {
+                if (re.hasLog()) {
+                    for (const m of re.log.messages) {
+                        const s = m.getSeverity();
+                        switch (s) {
+                            case MessageSeverity.INFO:
+                                ret.info++;
+                                break;
+                            case MessageSeverity.WARNING:
+                                ret.warning++;
+                                break;
+                            case MessageSeverity.ERROR:
+                                ret.error++;
+                                break;
+                        }
+                    }
+                }
+            }
+        }
+        for (const cr of this._childrenResults) { // bassins et cloisons
+            if (cr && cr.hasLog()) {
+                for (const re of cr.resultElements) {
+                    if (re.hasLog()) {
+                        for (const m of re.log.messages) {
+                            const s = m.getSeverity();
+                            switch (s) {
+                                case MessageSeverity.INFO:
+                                    ret.info++;
+                                    break;
+                                case MessageSeverity.WARNING:
+                                    ret.warning++;
+                                    break;
+                                case MessageSeverity.ERROR:
+                                    ret.error++;
+                                    break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (this._extraResult?.hasLog()) {
+            for (const re of this._extraResult.resultElements) {
+                if (re.hasLog()) {
+                    for (const m of re.log.messages) {
+                        const s = m.getSeverity();
+                        switch (s) {
+                            case MessageSeverity.INFO:
+                                ret.info++;
+                                break;
+                            case MessageSeverity.WARNING:
+                                ret.warning++;
+                                break;
+                            case MessageSeverity.ERROR:
+                                ret.error++;
+                                break;
+                        }
+                    }
+                }
+            }
+        }
+        return ret;
+    }
+
+    /*
+     * Retourne les logs à afficher dans le composant de log global, au dessus
+     * du sélecteur d'itération : messages globaux et / ou résumé des messages
+     * spécifiques à chaque ResultElement
+     */
+    public get globalLog(): cLog {
+        const l = new cLog();
+        if (this._mdr && this._mdr.variatedParameters.length > 0) {
+            this.mergeGlobalLog(this._mdr.result, l);
+            // un problème avec le nub en général / les cloisons / les bassins, à une étape quelconque ?
+            if (
+                (this._mdr.hasLog)
+                && l.messages.length === 0 // existing global messages make generic message below useless
+            ) {
+                const logStats = this.logStats();
+                const m = new Message(MessageCode.WARNING_PROBLEMS_ENCOUNTERED);
+                m.extraVar.info = "" + logStats.info; // to avoid displaying fixed number of digits
+                m.extraVar.warning = "" + logStats.warning;
+                m.extraVar.error = "" + logStats.error;
+                l.add(m);
+            }
+        } // sinon pas de log global (aucun paramètre ne varie)
+        return l;
+    }
+
+    /**
+     * Retourne les logs à afficher dans le composant de log local, en dessous
+     * du sélecteur d'itération : messages concernant l'itération (le ResultElement)
+     * en cours
+     */
+    public get iterationLog(): cLog {
+        const l = new cLog();
+        if (this._mdr?.result) {
+            if (this._mdr.variatedParameters.length > 0) {
+                // A. si un paramètre varie
+                const vi = this._mdr.variableIndex;
+                // log du PB pour l'itération en cours
+                if (
+                    this._mdr.result
+                    && this._mdr.result.hasResultElements()
+                    && this._mdr.result.resultElements[vi]
+                    && this._mdr.result.resultElements[vi]?.hasLog()
+                ) {
+                    l.addLog(this._mdr.result.resultElements[vi].log);
+                }
+                // logs des enfants pour l'itération en cours
+                for (const cr of this._childrenResults) {
+                    if (cr.hasResultElements() && cr.resultElements[vi]?.hasLog()) {
+                        l.addLog(cr.resultElements[vi].log);
+                    }
+                }
+                // extra results
+                if (this._extraResult?.resultElements[vi].hasLog()) {
+                    // l.addLog(this._pabResults.cloisonAvalResults.resultElements[vi].log);
+                    l.addLog(this._extraResult.resultElements[vi].log);
+                }
+            } else {
+                // B. si aucun paramètre ne varie
+                this.mergeGlobalLog(this._mdr.result, l); // faut bien mettre le log global quelque part
+                // logs des enfants
+                for (const cr of this._childrenResults) {
+                    if (cr.hasResultElements() && cr.resultElement?.hasLog()) {
+                        l.addLog(cr.resultElement.log);
+                    }
+                }
+                // extra result
+                if (this._extraResult?.resultElement.hasLog()) {
+                    l.addLog(this._extraResult.resultElement.log);
+                }
+            }
+        }
+        return l;
+    }
+}
-- 
GitLab


From b1b6c4a76856a50731a9439fcdf73e371ddff493 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Sun, 8 May 2022 06:23:59 +0200
Subject: [PATCH 2/6] fix: typo in english messages

---
 src/locale/messages.en.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index 022f3ee46..c05269d2b 100755
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -570,7 +570,7 @@
     "INFO_REMOUSRESULTS_TIRANT": "Water depth (m)",
     "INFO_REMOUSRESULTS_TIRANTCRITIQUE": "Critical water level",
     "INFO_REMOUSRESULTS_TIRANTNORMAL": "Normal water level",
-    "INFO_REPORT_BUG_BODY": "This is an issue report.\n\nPlease describe quickly the issue you encoutered, and the steps you followed:\n\n\n\n\n--- Current session state - do not modify text below ---\n------------------------------------------------------------------------\n\n",
+    "INFO_REPORT_BUG_BODY": "This is an issue report.\n\nPlease describe quickly the issue you encountered, and the steps you followed:\n\n\n\n\n--- Current session state - do not modify text below ---\n------------------------------------------------------------------------\n\n",
     "INFO_REPORT_BUG_SUBJECT": "Issue report",
     "INFO_REQUIRES": "requires",
     "INFO_RESULTS_EXPORT_AS_SPREADSHEET": "Export as XLSX",
-- 
GitLab


From bac18767dfae3e3a0f47131b190c1ab0b8c8c1be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Mon, 9 May 2022 13:52:26 +0200
Subject: [PATCH 3/6] fix: modify abstract log messages

refs #517
---
 src/app/results/log-helper.ts | 17 ++++++++++++-----
 src/locale/messages.en.json   |  3 +--
 src/locale/messages.fr.json   |  3 +--
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/src/app/results/log-helper.ts b/src/app/results/log-helper.ts
index 1f24f07ac..bf5dc3369 100644
--- a/src/app/results/log-helper.ts
+++ b/src/app/results/log-helper.ts
@@ -111,11 +111,18 @@ export class LogHelper {
                 && l.messages.length === 0 // existing global messages make generic message below useless
             ) {
                 const logStats = this.logStats();
-                const m = new Message(MessageCode.WARNING_PROBLEMS_ENCOUNTERED);
-                m.extraVar.info = "" + logStats.info; // to avoid displaying fixed number of digits
-                m.extraVar.warning = "" + logStats.warning;
-                m.extraVar.error = "" + logStats.error;
-                l.add(m);
+                let m: Message;
+                if (logStats.warning > 0) {
+                    m = new Message(MessageCode.WARNING_WARNINGS_ABSTRACT);
+                    m.extraVar.nb = "" + logStats.warning;
+                    l.add(m);
+                }
+                if (logStats.error > 0) {
+                    let c: MessageCode = logStats.error > 1 ? MessageCode.WARNING_ERRORS_ABSTRACT_PLUR : MessageCode.WARNING_ERRORS_ABSTRACT;
+                    m = new Message(c);
+                    m.extraVar.nb = "" + logStats.error;
+                    l.add(m);
+                }
             }
         } // sinon pas de log global (aucun paramètre ne varie)
         return l;
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index c05269d2b..eb3b5d866 100755
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -7,6 +7,7 @@
     "WARNING_NOTCH_SUBMERSION_GREATER_THAN_07": "Notch formula is discouraged when submersion is greater than 0.7",
     "WARNING_SLOT_SUBMERSION_NOT_BETWEEN_07_AND_09": "Slot formula is discouraged when submersion is lower than 0.7 or greater than 0.9",
     "WARNING_WEIR_SUBMERSION_LOWER_THAN_08": "Submerged weir formula is discouraged when submersion is lower than 08",
+    "WARNING_WARNINGS_ABSTRACT": "%nb% warnings occurred during calculation",
     "WARNING_ERRORS_ABSTRACT": "%nb% error occurred during calculation",
     "WARNING_ERRORS_ABSTRACT_PLUR": "%nb% errors occurred during calculation",
     "ERROR_BIEF_Z1_CALC_FAILED": "Unable to calculate upstream elevation (calculation interrupted before upstream)",
@@ -553,7 +554,6 @@
     "INFO_QUICKNAV_INPUT": "input",
     "INFO_QUICKNAV_RESULTS": "results",
     "WARNING_PREBARRAGE_BASSIN_ZF_SUP_Z1": "Bottom elevation of basin #%n% is greater than upstream water elevation",
-    "WARNING_PROBLEMS_ENCOUNTERED": "Problems occurred during calculation (info: %info%, warning: %warning%, error: %error%)",
     "INFO_REGIMEUNIFORME_DESCRIPTION": "open-channel flow normal depth",
     "INFO_REGIMEUNIFORME_TITRE_COURT": "Uniform flow",
     "INFO_REGIMEUNIFORME_TITRE": "Uniform flow calculation",
@@ -658,7 +658,6 @@
     "INFO_ESPECE_TITRE": "Fish species characteristics",
     "INFO_ESPECE_DESCRIPTION": "ichtyocompatible",
     "INFO_ESPECE_TITRE_COURT": "Species",
-    "WARNING_WARNINGS_ABSTRACT": "%nb% warnings occurred during calculation",
     "ERROR_JET_SUBMERGED_NO_SOLUTION": "There is no solution",
     "WARNING_DEVER_ZDV_INF_ZR": "Apron elevation of structure #%number% is below river bed elevation",
     "WARNING_JET_START_SUBMERGED": "Water elevation is greater than jet start elevation",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 6e487527a..60802ea9e 100755
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -7,6 +7,7 @@
     "WARNING_NOTCH_SUBMERSION_GREATER_THAN_07": "La formule de l'échancrure n'est pas conseillée pour un ennoiement supérieur à 0.7",
     "WARNING_SLOT_SUBMERSION_NOT_BETWEEN_07_AND_09": "La formule de la fente n'est pas conseillée pour un ennoiement inférieur à 0.7 et supérieur à 0.9",
     "WARNING_WEIR_SUBMERSION_LOWER_THAN_08": "La formule du seuil noyé n'est pas conseillé pour un ennoiement inférieur à 0.8",
+    "WARNING_WARNINGS_ABSTRACT": "%nb% avertissements rencontrés lors du calcul",
     "WARNING_ERRORS_ABSTRACT": "%nb% erreur rencontrée lors du calcul",
     "WARNING_ERRORS_ABSTRACT_PLUR": "%nb% erreurs rencontrées lors du calcul",
     "ERROR_BIEF_Z1_CALC_FAILED": "Impossible de calculer la cote amont (calcul interrompu avant l'amont)",
@@ -554,7 +555,6 @@
     "INFO_QUICKNAV_INPUT": "données",
     "INFO_QUICKNAV_RESULTS": "résultats",
     "WARNING_PREBARRAGE_BASSIN_ZF_SUP_Z1": "Cote de fond du bassin n°%n% supérieure à la cote de l'eau amont",
-    "WARNING_PROBLEMS_ENCOUNTERED": "Des problèmes sont survenus durant le calcul (info&nbsp;: %info%, avertissement&nbsp;: %warning%, erreur&nbsp;: %error%)",
     "INFO_REGIMEUNIFORME_DESCRIPTION": "hydraulique à surface libre hauteur normale",
     "INFO_REGIMEUNIFORME_TITRE_COURT": "R. uniforme",
     "INFO_REGIMEUNIFORME_TITRE": "Régime uniforme",
@@ -659,7 +659,6 @@
     "INFO_ESPECE_TITRE": "Caractéristiques d'une espèce",
     "INFO_ESPECE_DESCRIPTION": "ichtyocompatible",
     "INFO_ESPECE_TITRE_COURT": "Espèce",
-    "WARNING_WARNINGS_ABSTRACT": "%nb% avertissements rencontrés lors du calcul",
     "ERROR_JET_SUBMERGED_NO_SOLUTION": "Il n'y a pas de solution",
     "WARNING_DEVER_ZDV_INF_ZR": "La cote de radier de l'ouvrage n°%number% est sous la cote de fond du lit",
     "WARNING_JET_START_SUBMERGED": "La cote de l'eau est supérieure à la cote de départ du jet",
-- 
GitLab


From 7e83cb009c0010354885fde7c57641005c077d9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Thu, 12 May 2022 09:53:39 +0200
Subject: [PATCH 4/6] refactor: MultiDimensionResults class: add
 childrenResults,extraResult getters

refs #517
---
 .../macrorugo-compound-results.component.ts   |  2 +-
 .../pab-results/pab-results.component.ts      |  2 +-
 .../pb-results/pb-results.component.ts        | 13 +-----------
 src/app/results/log-helper.ts                 |  7 ++++++-
 src/app/results/macrorugo-compound-results.ts | 12 +++++++++--
 src/app/results/multidimension-results.ts     | 11 ++++++++--
 src/app/results/pab-results.ts                |  8 ++++++++
 src/app/results/prebarrage-results.ts         | 20 +++++++++++++++++++
 8 files changed, 56 insertions(+), 19 deletions(-)

diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
index a17be949b..86eba4301 100644
--- a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
+++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
@@ -39,7 +39,7 @@ export class MacrorugoCompoundResultsComponent extends ResultsComponentDirective
         this._logHelper = undefined;
         if (rs.length > 0 && rs[0] instanceof MacrorugoCompoundResults) {
             this._mrcResults = rs[0] as MacrorugoCompoundResults;
-            this._logHelper = new LogHelper(this._mrcResults, this._mrcResults.childrenResults);
+            this._logHelper = new LogHelper(this._mrcResults);
         }
     }
 
diff --git a/src/app/components/pab-results/pab-results.component.ts b/src/app/components/pab-results/pab-results.component.ts
index 0a0777045..a8f7514a9 100644
--- a/src/app/components/pab-results/pab-results.component.ts
+++ b/src/app/components/pab-results/pab-results.component.ts
@@ -35,7 +35,7 @@ export class PabResultsComponent extends ResultsComponentDirective {
             this._pabResults = rs[0] as PabResults;
 
             // log helper
-            this._logHelper = new LogHelper(this._pabResults, this._pabResults.cloisonsResults, this._pabResults.cloisonAvalResults);
+            this._logHelper = new LogHelper(this._pabResults);
         }
     }
 
diff --git a/src/app/components/pb-results/pb-results.component.ts b/src/app/components/pb-results/pb-results.component.ts
index 4b0f2b77a..911267948 100644
--- a/src/app/components/pb-results/pb-results.component.ts
+++ b/src/app/components/pb-results/pb-results.component.ts
@@ -33,19 +33,8 @@ export class PbResultsComponent {
         for (const r of rs) {
             if (r instanceof PrebarrageResults) {
                 this._pbResults = r as PrebarrageResults;
-
                 // log helper
-
-                const childResults: Result[] = [];
-                const sn = this._pbResults.result?.sourceNub as PreBarrage;
-                if (sn?.children) {
-                    for (const cr of sn.children) {
-                        if (cr.result) {
-                            childResults.push(cr.result);
-                        }
-                    }
-                }
-                this._logHelper = new LogHelper(this._pbResults, childResults);
+                this._logHelper = new LogHelper(this._pbResults);
             }
         }
     }
diff --git a/src/app/results/log-helper.ts b/src/app/results/log-helper.ts
index bf5dc3369..35764f283 100644
--- a/src/app/results/log-helper.ts
+++ b/src/app/results/log-helper.ts
@@ -5,7 +5,12 @@ import { MultiDimensionResults } from "./multidimension-results";
  * calculation log helpers
  */
 export class LogHelper {
-    constructor(private _mdr: MultiDimensionResults, private _childrenResults: Result[], private _extraResult?: Result) {
+    private _childrenResults: Result[];
+    private _extraResult?: Result;
+
+    constructor(private _mdr: MultiDimensionResults) {
+        this._childrenResults = this._mdr.childrenResults;
+        this._extraResult = this._mdr.extraResult;
     }
 
     private mergeGlobalLog(result: Result, log: cLog) {
diff --git a/src/app/results/macrorugo-compound-results.ts b/src/app/results/macrorugo-compound-results.ts
index a8274fad9..fa4f49ddd 100644
--- a/src/app/results/macrorugo-compound-results.ts
+++ b/src/app/results/macrorugo-compound-results.ts
@@ -8,7 +8,7 @@ import { ChartType } from "./chart-type";
 export class MacrorugoCompoundResults extends MultiDimensionResults implements PlottableData {
 
     /** résultats des modules MacroRugo enfants */
-    public childrenResults: Result[];
+    private _childrenResults: Result[];
 
     /** symboles des colonnes de résultat */
     protected _columns: string[];
@@ -70,7 +70,7 @@ export class MacrorugoCompoundResults extends MultiDimensionResults implements P
 
     public reset() {
         super.reset();
-        this.childrenResults = [];
+        this._childrenResults = [];
     }
 
     /**
@@ -224,4 +224,12 @@ export class MacrorugoCompoundResults extends MultiDimensionResults implements P
 
         return data;
     }
+
+    public get childrenResults(): Result[] {
+        return this._childrenResults;
+    }
+
+    public set childrenResults(cr: Result[]) {
+        this._childrenResults = cr;
+    }
 }
diff --git a/src/app/results/multidimension-results.ts b/src/app/results/multidimension-results.ts
index c7af4cc99..dd12a4686 100644
--- a/src/app/results/multidimension-results.ts
+++ b/src/app/results/multidimension-results.ts
@@ -1,7 +1,6 @@
 import { CalculatedParamResults } from "./param-calc-results";
 
-import { VariatedDetails } from "jalhyd";
-
+import { Result, VariatedDetails } from "jalhyd";
 
 export class MultiDimensionResults extends CalculatedParamResults {
 
@@ -19,4 +18,12 @@ export class MultiDimensionResults extends CalculatedParamResults {
     public set variableIndex(v: number) {
         this._variableIndex = v;
     }
+
+    public get childrenResults(): Result[] {
+        return [];
+    }
+
+    public get extraResult(): Result {
+        return undefined;
+    }
 }
diff --git a/src/app/results/pab-results.ts b/src/app/results/pab-results.ts
index d282524ef..2f9605369 100644
--- a/src/app/results/pab-results.ts
+++ b/src/app/results/pab-results.ts
@@ -256,4 +256,12 @@ export class PabResults extends MultiDimensionResults implements PlottableData {
 
         return data;
     }
+
+    public get childrenResults(): Result[] {
+        return this.cloisonsResults;
+    }
+
+    public get extraResult(): Result {
+        return this.cloisonAvalResults;
+    }
 }
diff --git a/src/app/results/prebarrage-results.ts b/src/app/results/prebarrage-results.ts
index 0c734ae51..411c4edd7 100644
--- a/src/app/results/prebarrage-results.ts
+++ b/src/app/results/prebarrage-results.ts
@@ -24,6 +24,9 @@ export class PrebarrageResults extends MultiDimensionResults implements IObserva
     /** Implémentation par délégation */
     private _observable: Observable;
 
+    /** résultats enfants */
+    private _childrenResults: Result[];
+
     public constructor() {
         super();
         this._observable = new Observable();
@@ -83,6 +86,7 @@ export class PrebarrageResults extends MultiDimensionResults implements IObserva
         this.cloisonResults.variableIndex = this._variableIndex;
         this.cloisonResults.size = this.size;
         this.result = undefined;
+        this._childrenResults = undefined;
     }
 
     /**
@@ -163,6 +167,22 @@ export class PrebarrageResults extends MultiDimensionResults implements IObserva
         return err;
     }
 
+    /** liste des résultats enfants */
+    public get childrenResults(): Result[] {
+        if (this._childrenResults === undefined) {
+            this._childrenResults = [];
+            const sn = this.result?.sourceNub as PreBarrage;
+            if (sn?.children) {
+                for (const cr of sn.children) {
+                    if (cr.result) {
+                        this._childrenResults.push(cr.result);
+                    }
+                }
+            }
+        }
+        return this._childrenResults;
+    }
+
     // interface IObservable
 
     /**
-- 
GitLab


From f0cd5234feb996781399a4a69f66c5594e385f8f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Thu, 12 May 2022 10:26:21 +0200
Subject: [PATCH 5/6] refactor: LogHelper class: use jalhyd for message log
 statistics

refs #517
---
 jalhyd_branch                 |  2 +-
 src/app/results/log-helper.ts | 99 +++++++++++++----------------------
 2 files changed, 36 insertions(+), 65 deletions(-)

diff --git a/jalhyd_branch b/jalhyd_branch
index 626e97d71..554b541df 100644
--- a/jalhyd_branch
+++ b/jalhyd_branch
@@ -1 +1 @@
-devel
\ No newline at end of file
+308-log-ameliorer-la-synthese-de-journal
\ No newline at end of file
diff --git a/src/app/results/log-helper.ts b/src/app/results/log-helper.ts
index 35764f283..d3b75c621 100644
--- a/src/app/results/log-helper.ts
+++ b/src/app/results/log-helper.ts
@@ -1,4 +1,6 @@
-import { cLog, Message, MessageCode, MessageSeverity, Result } from "jalhyd";
+import { ServiceFactory } from "app/services/service-factory";
+import { cLog, Message, MessageCode, Result, ResultElement } from "jalhyd";
+import { sprintf } from "sprintf-js";
 import { MultiDimensionResults } from "./multidimension-results";
 
 /**
@@ -31,76 +33,45 @@ export class LogHelper {
      * Returns the number of errors, warnings, infos among children logs
      */
     private logStats(): any {
-        const ret = {
-            info: 0,
-            warning: 0,
-            error: 0
-        };
-        if (this._mdr.result?.hasLog()) {
-            for (const re of this._mdr.result.resultElements) {
-                if (re.hasLog()) {
-                    for (const m of re.log.messages) {
-                        const s = m.getSeverity();
-                        switch (s) {
-                            case MessageSeverity.INFO:
-                                ret.info++;
-                                break;
-                            case MessageSeverity.WARNING:
-                                ret.warning++;
-                                break;
-                            case MessageSeverity.ERROR:
-                                ret.error++;
-                                break;
-                        }
-                    }
-                }
-            }
-        }
-        for (const cr of this._childrenResults) { // bassins et cloisons
-            if (cr && cr.hasLog()) {
-                for (const re of cr.resultElements) {
-                    if (re.hasLog()) {
-                        for (const m of re.log.messages) {
-                            const s = m.getSeverity();
-                            switch (s) {
-                                case MessageSeverity.INFO:
-                                    ret.info++;
-                                    break;
-                                case MessageSeverity.WARNING:
-                                    ret.warning++;
-                                    break;
-                                case MessageSeverity.ERROR:
-                                    ret.error++;
-                                    break;
-                            }
-                        }
-                    }
-                }
-            }
+        return this._mdr.result.sourceNub.resultElementsLogStats();
+    }
+
+    private computeResultElementLogStats(index: number): any {
+        let res;
+        const it: Iterator<ResultElement> = this._mdr.result.nthResultElementIterator(index);
+        let ire = it.next();
+        while (!ire.done) {
+            res = ire.value.logStats(res);
+            ire = it.next();
         }
-        if (this._extraResult?.hasLog()) {
-            for (const re of this._extraResult.resultElements) {
-                if (re.hasLog()) {
-                    for (const m of re.log.messages) {
-                        const s = m.getSeverity();
-                        switch (s) {
-                            case MessageSeverity.INFO:
-                                ret.info++;
-                                break;
-                            case MessageSeverity.WARNING:
-                                ret.warning++;
-                                break;
-                            case MessageSeverity.ERROR:
-                                ret.error++;
-                                break;
-                        }
-                    }
+        return res;
+    }
+
+    private resultElementStatToString(res: any): string {
+        let ret = "";
+        function ccat(n: number, code: MessageCode, b: string): string {
+            if (n > 0) {
+                const c: string = MessageCode[code];
+                const m: string = ServiceFactory.i18nService.localizeText(c);
+                const s = sprintf(m, n);
+                if (b.length > 0) {
+                    return b + ", " + s;
                 }
+                return s;
             }
+            return b;
         }
+        ret = ccat(res.error, MessageCode.WARNING_ERROR_COUNT_SHORT, ret);
+        ret = ccat(res.warning, MessageCode.WARNING_WARNING_COUNT_SHORT, ret);
+        ret = ccat(res.info, MessageCode.WARNING_INFO_COUNT_SHORT, ret);
         return ret;
     }
 
+    public resultElementsStats(index: number): string {
+        const res = this.computeResultElementLogStats(index);
+        return this.resultElementStatToString(res);
+    }
+
     /*
      * Retourne les logs à afficher dans le composant de log global, au dessus
      * du sélecteur d'itération : messages globaux et / ou résumé des messages
-- 
GitLab


From bea206c0e6adf2b8bef18f932e6a28a51526b4c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Thu, 12 May 2022 10:27:02 +0200
Subject: [PATCH 6/6] feat: PAB calculator: add error,warning,info count in
 boundary conditions select

refs #517
---
 .../variable-results-selector.component.ts    | 19 ++++++++++++++++---
 src/locale/messages.en.json                   |  3 +++
 src/locale/messages.fr.json                   |  3 +++
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/src/app/components/variable-results-selector/variable-results-selector.component.ts b/src/app/components/variable-results-selector/variable-results-selector.component.ts
index 663f1f0e5..0d68b4457 100644
--- a/src/app/components/variable-results-selector/variable-results-selector.component.ts
+++ b/src/app/components/variable-results-selector/variable-results-selector.component.ts
@@ -3,9 +3,9 @@ import { Component, Input, OnChanges } from "@angular/core";
 import { I18nService } from "../../services/internationalisation.service";
 import { fv, longestVarParam } from "../../util";
 import { MultiDimensionResults } from "../../results/multidimension-results";
-import { PrebarrageResults } from "../../results/prebarrage-results";
-import { CalculatorType, PbBassin, PbCloison, Structure, VariatedDetails } from "jalhyd";
+import { VariatedDetails } from "jalhyd";
 import { CalculatorResults } from "../../results/calculator-results";
+import { LogHelper } from "app/results/log-helper";
 
 @Component({
     selector: "variable-results-selector",
@@ -24,6 +24,9 @@ export class VariableResultsSelectorComponent implements OnChanges {
     @Input()
     private variatedParameters: VariatedDetails[];
 
+    /** stats du log synthétique */
+    private _logHelper: LogHelper;
+
     /** valeur en cours */
     private _selectedValue = 0;
 
@@ -61,6 +64,7 @@ export class VariableResultsSelectorComponent implements OnChanges {
         // get current variatedIndex even if component was rebuilt
         if (this.results) {
             this._selectedValue = this.results.variableIndex;
+            this._logHelper = new LogHelper(this.results);
         }
     }
 
@@ -80,8 +84,17 @@ export class VariableResultsSelectorComponent implements OnChanges {
         return ret;
     }
 
+    /**
+     * generate entry text for boundary conditions select
+     * @param index select option index
+     */
     protected entryLabel(index: number): string {
-        return CalculatorResults.variatingModalityLabel(this.varValues, this.results, index);
+        let res = CalculatorResults.variatingModalityLabel(this.varValues, this.results, index);
+        const restat = this._logHelper.resultElementsStats(index);
+        if (restat.length > 0) {
+            res += " - " + restat;
+        }
+        return res;
     }
 
     public get selectedValue(): number {
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index eb3b5d866..649e9e7c1 100755
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -7,6 +7,9 @@
     "WARNING_NOTCH_SUBMERSION_GREATER_THAN_07": "Notch formula is discouraged when submersion is greater than 0.7",
     "WARNING_SLOT_SUBMERSION_NOT_BETWEEN_07_AND_09": "Slot formula is discouraged when submersion is lower than 0.7 or greater than 0.9",
     "WARNING_WEIR_SUBMERSION_LOWER_THAN_08": "Submerged weir formula is discouraged when submersion is lower than 08",
+    "WARNING_INFO_COUNT_SHORT": "%d info(s)",
+    "WARNING_WARNING_COUNT_SHORT": "%d warning(s)",
+    "WARNING_ERROR_COUNT_SHORT": "%d error(s)",
     "WARNING_WARNINGS_ABSTRACT": "%nb% warnings occurred during calculation",
     "WARNING_ERRORS_ABSTRACT": "%nb% error occurred during calculation",
     "WARNING_ERRORS_ABSTRACT_PLUR": "%nb% errors occurred during calculation",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 60802ea9e..cb3e769e6 100755
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -7,6 +7,9 @@
     "WARNING_NOTCH_SUBMERSION_GREATER_THAN_07": "La formule de l'échancrure n'est pas conseillée pour un ennoiement supérieur à 0.7",
     "WARNING_SLOT_SUBMERSION_NOT_BETWEEN_07_AND_09": "La formule de la fente n'est pas conseillée pour un ennoiement inférieur à 0.7 et supérieur à 0.9",
     "WARNING_WEIR_SUBMERSION_LOWER_THAN_08": "La formule du seuil noyé n'est pas conseillé pour un ennoiement inférieur à 0.8",
+    "WARNING_INFO_COUNT_SHORT": "%d info(s)",
+    "WARNING_WARNING_COUNT_SHORT": "%d avertissement(s)",
+    "WARNING_ERROR_COUNT_SHORT": "%d erreur(s)",
     "WARNING_WARNINGS_ABSTRACT": "%nb% avertissements rencontrés lors du calcul",
     "WARNING_ERRORS_ABSTRACT": "%nb% erreur rencontrée lors du calcul",
     "WARNING_ERRORS_ABSTRACT_PLUR": "%nb% erreurs rencontrées lors du calcul",
-- 
GitLab