From 0d6d44d6aed2fe8ba2a0f00ff70ff977f02e7548 Mon Sep 17 00:00:00 2001
From: "mathias.chouet" <mathias.chouet@irstea.fr>
Date: Mon, 23 Sep 2019 14:46:09 +0200
Subject: [PATCH] Fix #293 - help links for results

---
 README.md                                     |  9 +++++++
 src/app/calculators/grille/grille.config.json |  5 +++-
 .../fixed-results.component.html              |  2 +-
 .../fixed-results.component.scss              |  6 +++++
 .../fixed-results.component.ts                | 24 ++++++++++++-------
 .../var-results.component.html                |  4 ++--
 .../var-results.component.scss                |  6 +++++
 ...rugo-compound-results-table.component.html |  2 +-
 ...rugo-compound-results-table.component.scss |  6 +++++
 .../pab-results-table.component.html          |  2 +-
 .../pab-results-table.component.scss          |  6 +++++
 .../section-results.component.ts              |  1 -
 .../definition/concrete/form-base.ts          |  5 ++++
 .../concrete/form-macrorugo-compound.ts       |  1 +
 .../concrete/form-parallel-structures.ts      |  1 +
 .../concrete/form-regime-uniforme.ts          |  1 +
 .../formulaire/definition/form-definition.ts  |  6 +++++
 .../definition/form-result-fixedvar.ts        |  3 +++
 .../form-result-macrorugo-compound.ts         |  2 ++
 .../formulaire/definition/form-result-pab.ts  |  2 ++
 .../definition/form-result-remous.ts          |  6 ++---
 .../definition/form-result-section.ts         |  4 ++++
 src/app/formulaire/definition/form-result.ts  |  4 ++++
 src/app/formulaire/formulaire-node.ts         | 20 ++++------------
 src/app/results/calculator-results.ts         | 16 +++++++++++++
 src/app/results/macrorugo-compound-results.ts |  6 +++--
 src/app/results/pab-results.ts                |  4 +++-
 src/app/results/param-calc-results.ts         | 13 ++++------
 src/app/results/remous-results.ts             |  1 +
 src/app/results/var-results.ts                | 20 +++++++++-------
 30 files changed, 134 insertions(+), 54 deletions(-)

diff --git a/README.md b/README.md
index 4b93c0343..ae73d5006 100644
--- a/README.md
+++ b/README.md
@@ -248,6 +248,15 @@ Custom Material SVG Icons will only show up when the application is deployed on
 		  - pour l'entête d'un _template_container_: `{... "type": "template_container",
         "help": "aide.html", ...}`
 
+		 - éventuellement l'URL de l'aide pour un résultat en particulier, dans le bloc d'options de la configuration :
+		   - ```json
+		   		{
+						"type": "options",
+						…
+						"resultsHelp": {
+							"HG": "devalaison/grille.html#hauteur-de-grille"
+						}
+
 	- dans _src/app/calculators/ma-calculette_ :
 
 		Créer les fichiers d'internationalisation (_ma-calculette.&lt;langue&gt;.json_). Il doivent reprendre tous les ids utilisés dans le fichier de configuration et fournir leur traduction.
diff --git a/src/app/calculators/grille/grille.config.json b/src/app/calculators/grille/grille.config.json
index aac755031..226729e6b 100644
--- a/src/app/calculators/grille/grille.config.json
+++ b/src/app/calculators/grille/grille.config.json
@@ -40,6 +40,9 @@
         "type": "options",
         "gridTypeSelectId": "select_grid_type",
         "gridProfileSelectId": "select_grid_profile",
-        "help": "devalaison/grille"
+        "help": "devalaison/grille",
+        "resultsHelp": {
+            "HG": "devalaison/grille#hauteur-de-grille"
+        }
     }
 ]
\ No newline at end of file
diff --git a/src/app/components/fixedvar-results/fixed-results.component.html b/src/app/components/fixedvar-results/fixed-results.component.html
index 67effaa6a..fe2ce37f9 100644
--- a/src/app/components/fixedvar-results/fixed-results.component.html
+++ b/src/app/components/fixedvar-results/fixed-results.component.html
@@ -12,7 +12,7 @@
 
             <ng-container matColumnDef="parametre">
                 <th mat-header-cell *matHeaderCellDef>{{ uitextParamFixes }}</th>
-                <td mat-cell *matCellDef="let element" [ngClass]="{'highlightedResult': element.isCalcResult}">{{ element.label }}</td>
+                <td mat-cell *matCellDef="let element" [innerHTML]="element.label" [ngClass]="{'highlightedResult': element.isCalcResult}"></td>
             </ng-container>
             <ng-container matColumnDef="valeur">
                 <th mat-header-cell *matHeaderCellDef>{{ uitextValeurs }}</th>
diff --git a/src/app/components/fixedvar-results/fixed-results.component.scss b/src/app/components/fixedvar-results/fixed-results.component.scss
index c2fee955e..b4ec05040 100644
--- a/src/app/components/fixedvar-results/fixed-results.component.scss
+++ b/src/app/components/fixedvar-results/fixed-results.component.scss
@@ -41,6 +41,12 @@ table.mat-table {
     ::ng-deep .mat-cell {
         padding-top: 8px;
         padding-bottom: 8px;
+
+        .material-icons {
+            font-size: 1.4em;
+            vertical-align: bottom;
+            margin-left: 4px;
+        }
     }
 }
 
diff --git a/src/app/components/fixedvar-results/fixed-results.component.ts b/src/app/components/fixedvar-results/fixed-results.component.ts
index 56d481ca4..6df588a29 100644
--- a/src/app/components/fixedvar-results/fixed-results.component.ts
+++ b/src/app/components/fixedvar-results/fixed-results.component.ts
@@ -101,6 +101,7 @@ export class FixedResultsComponent extends ResultsComponent {
                         const pos = fp.paramDefinition.parentNub.findPositionInParent();
                         label = this.intlService.localizeText("INFO_OUVRAGE") + " n°" + (pos + 1) + ": " + label;
                     }
+                    label += this._fixedResults.getHelpLink(symbol);
                     data.push({
                         label: label,
                         value: this.formattedValue(fp),
@@ -138,7 +139,8 @@ export class FixedResultsComponent extends ResultsComponent {
                                 unit = p.unit;
                             }
                         } catch (e) { /* silent fail */ }
-                        const label = this.formService.expandVariableNameAndUnit(ct, k, unit);
+                        let label = this.formService.expandVariableNameAndUnit(ct, k, unit);
+                        label += this._fixedResults.getHelpLink(symbol);
                         data.push({
                             label: label,
                             value: this.intlService.formatResult(k, er),
@@ -160,10 +162,12 @@ export class FixedResultsComponent extends ResultsComponent {
                                         ct = sn.parent.calcType;
                                     }
                                     const cn = capitalize(this.intlService.childName(sn));
+                                    let label = sprintf(this.intlService.localizeText("INFO_STUFF_N"), cn)
+                                        + (c.findPositionInParent() + 1) + " : "
+                                        + this.formService.expandVariableNameAndUnit(ct, k);
+                                    label += this._fixedResults.getHelpLink(symbol);
                                     data.push({
-                                        label: sprintf(this.intlService.localizeText("INFO_STUFF_N"), cn)
-                                                + (c.findPositionInParent() + 1) + " : "
-                                                + this.formService.expandVariableNameAndUnit(ct, k),
+                                        label: label,
                                         value: this.intlService.formatResult(k, er),
                                         isCalcResult: true // for CSS
                                     });
@@ -191,6 +195,7 @@ export class FixedResultsComponent extends ResultsComponent {
                 const pos = fp.paramDefinition.parentNub.findPositionInParent();
                 label = this.intlService.localizeText("INFO_OUVRAGE") + " n°" + (pos + 1) + ": " + label;
             }
+            label += this._fixedResults.getHelpLink(fp.symbol);
             data.push({
                 label: label,
                 value: this.formattedValue(fp),
@@ -223,7 +228,8 @@ export class FixedResultsComponent extends ResultsComponent {
                         unit = p.unit;
                     }
                 } catch (e) { /* silent fail */ }
-                const label = this.formService.expandVariableNameAndUnit(ct, k, unit);
+                let label = this.formService.expandVariableNameAndUnit(ct, k, unit);
+                label += this._fixedResults.getHelpLink(k);
                 data.push({
                     label: label,
                     value: this.intlService.formatResult(k, er),
@@ -242,10 +248,12 @@ export class FixedResultsComponent extends ResultsComponent {
                             ct = sn.parent.calcType;
                         }
                         const cn = capitalize(this.intlService.childName(sn));
+                        let label = sprintf(this.intlService.localizeText("INFO_STUFF_N"), cn)
+                            + (c.findPositionInParent() + 1) + " : "
+                            + this.formService.expandVariableNameAndUnit(ct, k);
+                        label += this._fixedResults.getHelpLink(k);
                         data.push({
-                            label: sprintf(this.intlService.localizeText("INFO_STUFF_N"), cn)
-                                    + (c.findPositionInParent() + 1) + " : "
-                                    + this.formService.expandVariableNameAndUnit(ct, k),
+                            label: label,
                             value: this.intlService.formatResult(k, er),
                             isCalcResult: true // for CSS
                         });
diff --git a/src/app/components/fixedvar-results/var-results.component.html b/src/app/components/fixedvar-results/var-results.component.html
index 8768e08b8..7b6bbeb3e 100644
--- a/src/app/components/fixedvar-results/var-results.component.html
+++ b/src/app/components/fixedvar-results/var-results.component.html
@@ -33,8 +33,8 @@
                     </ng-container>
                     <!-- generic column -->
                     <ng-container *ngFor="let h of headersWithoutLogColumn; let i = index" [matColumnDef]="h">
-                        <th mat-header-cell *matHeaderCellDef>{{ h }}</th>
-                        <td mat-cell *matCellDef="let element">{{ element[i+1] }}</td>
+                        <th mat-header-cell *matHeaderCellDef [innerHTML]="h"></th>
+                        <td mat-cell *matCellDef="let element" [innerHTML]="element[i+1]"></td>
                     </ng-container>
 
                     <tr mat-header-row *matHeaderRowDef="headers"></tr>
diff --git a/src/app/components/fixedvar-results/var-results.component.scss b/src/app/components/fixedvar-results/var-results.component.scss
index d897f5484..6dc74ba0b 100644
--- a/src/app/components/fixedvar-results/var-results.component.scss
+++ b/src/app/components/fixedvar-results/var-results.component.scss
@@ -61,6 +61,12 @@ table.mat-table {
         color: black;
         padding: 5px;
         border: none;
+
+        .material-icons {
+            font-size: 1.4em;
+            vertical-align: bottom;
+            margin-left: 4px;
+        }
     }
 
     ::ng-deep .mat-cell {
diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.html b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.html
index 1e1df2713..b6d40a92f 100644
--- a/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.html
+++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.html
@@ -19,7 +19,7 @@
 
                 <table mat-table [dataSource]="dataSet">
                     <ng-container *ngFor="let h of headers; let i = index" [matColumnDef]="h">
-                        <th mat-header-cell *matHeaderCellDef>{{ h }}</th>
+                        <th mat-header-cell *matHeaderCellDef [innerHTML]="h"></th>
                         <td mat-cell *matCellDef="let element" [innerHTML]="element[i]"></td>
                     </ng-container>
 
diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.scss b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.scss
index 14c20aa01..fc10d9cdf 100644
--- a/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.scss
+++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results-table.component.scss
@@ -62,5 +62,11 @@ table.mat-table {
         font-size: 1em;
         color: black;
         padding: 5px;
+
+        .material-icons {
+            font-size: 1.4em;
+            vertical-align: bottom;
+            margin-left: 4px;
+        }
     }
 }
diff --git a/src/app/components/pab-results/pab-results-table.component.html b/src/app/components/pab-results/pab-results-table.component.html
index 97d728f3a..f5e6fcf9b 100644
--- a/src/app/components/pab-results/pab-results-table.component.html
+++ b/src/app/components/pab-results/pab-results-table.component.html
@@ -19,7 +19,7 @@
 
                 <table mat-table [dataSource]="dataSet">
                     <ng-container *ngFor="let h of headers; let i = index" [matColumnDef]="h">
-                        <th mat-header-cell *matHeaderCellDef>{{ h }}</th>
+                        <th mat-header-cell *matHeaderCellDef [innerHTML]="h"></th>
                         <td mat-cell *matCellDef="let element" [innerHTML]="element[i]"></td>
                     </ng-container>
 
diff --git a/src/app/components/pab-results/pab-results-table.component.scss b/src/app/components/pab-results/pab-results-table.component.scss
index c0eaa55d2..d57b6484a 100644
--- a/src/app/components/pab-results/pab-results-table.component.scss
+++ b/src/app/components/pab-results/pab-results-table.component.scss
@@ -62,5 +62,11 @@ table.mat-table {
         font-size: 1em;
         color: black;
         padding: 5px;
+
+        .material-icons {
+            font-size: 1.4em;
+            vertical-align: bottom;
+            margin-left: 4px;
+        }
     }
 }
diff --git a/src/app/components/section-results/section-results.component.ts b/src/app/components/section-results/section-results.component.ts
index 3ab72436e..57215b164 100644
--- a/src/app/components/section-results/section-results.component.ts
+++ b/src/app/components/section-results/section-results.component.ts
@@ -101,7 +101,6 @@ export class SectionResultsComponent extends ResultsComponent implements DoCheck
     }
 
     private updateResults() {
-        console.log("UPDATE RESULTS");
         if (this._results && this._sectionCanvas) {
 
             this._resultElement = new ResultElement();
diff --git a/src/app/formulaire/definition/concrete/form-base.ts b/src/app/formulaire/definition/concrete/form-base.ts
index 976cf3368..35f9b9cc8 100644
--- a/src/app/formulaire/definition/concrete/form-base.ts
+++ b/src/app/formulaire/definition/concrete/form-base.ts
@@ -18,6 +18,11 @@ export class FormulaireBase extends FormulaireDefinition {
         this._formCompute = new FormComputeFixedVar(this, (this._formResult as FormResultFixedVar));
     }
 
+    protected completeParse(json: {}) {
+        super.completeParse(json);
+        this._formResult.helpLinks = this._resultsHelpLinks;
+    }
+
     /**
      * Resets the form results, the results panel on screen, the model
      * results, and does the same for all depending modules
diff --git a/src/app/formulaire/definition/concrete/form-macrorugo-compound.ts b/src/app/formulaire/definition/concrete/form-macrorugo-compound.ts
index d15d41e2b..b9690657e 100644
--- a/src/app/formulaire/definition/concrete/form-macrorugo-compound.ts
+++ b/src/app/formulaire/definition/concrete/form-macrorugo-compound.ts
@@ -153,6 +153,7 @@ export class FormulaireMacrorugoCompound extends FormulaireBase {
     protected completeParse(json: {}) {
         this.subscribeFieldsetContainer();
         this.updateApronState(this.mrcNub.properties.getPropValue("inclinedApron"));
+        this._formResult.helpLinks = this._resultsHelpLinks;
     }
 
     private get fieldsetContainer(): FieldsetContainer {
diff --git a/src/app/formulaire/definition/concrete/form-parallel-structures.ts b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
index 2c7ab7125..c4b329135 100644
--- a/src/app/formulaire/definition/concrete/form-parallel-structures.ts
+++ b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
@@ -170,6 +170,7 @@ export class FormulaireParallelStructure extends FormulaireBase {
 
     protected completeParse(json: {}) {
         this.subscribeFieldsetContainer();
+        this._formResult.helpLinks = this._resultsHelpLinks;
     }
 
     private get fieldsetContainer(): FieldsetContainer {
diff --git a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
index 79ad66e52..bb4cbd0a9 100644
--- a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
+++ b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
@@ -23,6 +23,7 @@ export class FormulaireRegimeUniforme extends FormulaireBase implements Observer
 
     protected completeParse(json: {}) {
         super.completeParse(json);
+        this._formResult.helpLinks = this._resultsHelpLinks;
     }
 
     // interface Observer
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 699fc83bf..2ba17671b 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -19,6 +19,7 @@ import { PabTable } from "../pab-table";
  * classe de base pour tous les formulaires
  */
 export abstract class FormulaireDefinition extends FormulaireNode implements Observer {
+
     /** nom du module de calcul */
     private _calculatorName: string;
 
@@ -28,6 +29,9 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
     /** propriétés par défaut (lues si _currentNub === undefined ) */
     protected _props = {};
 
+    /** aide en ligne pour les résultats */
+    protected _resultsHelpLinks: { [key: string]: string };
+
     /** fichier de configuration */
     private _jsonConfig: {};
 
@@ -137,8 +141,10 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
             this._props["nodeType"] = ComputeNodeType[dnt];
         }
         this._helpLink = json["help"];
+        this._resultsHelpLinks = json["resultsHelp"];
     }
 
+    /** called at the end of parseConfig() */
     protected completeParse(json: {}) {
     }
 
diff --git a/src/app/formulaire/definition/form-result-fixedvar.ts b/src/app/formulaire/definition/form-result-fixedvar.ts
index 4e4dfa583..512a6342d 100644
--- a/src/app/formulaire/definition/form-result-fixedvar.ts
+++ b/src/app/formulaire/definition/form-result-fixedvar.ts
@@ -56,6 +56,9 @@ export class FormResultFixedVar extends FormResult {
 
     public get results(): CalculatorResults[] {
         const res: CalculatorResults[] = [];
+        // ensure help links are propagated
+        this._fixedResults.helpLinks = this.helpLinks;
+        this._varResults.helpLinks = this.helpLinks;
         res.push(this._fixedResults);
         res.push(this._varResults);
         return res;
diff --git a/src/app/formulaire/definition/form-result-macrorugo-compound.ts b/src/app/formulaire/definition/form-result-macrorugo-compound.ts
index 73ba7e9d2..d73ec051c 100644
--- a/src/app/formulaire/definition/form-result-macrorugo-compound.ts
+++ b/src/app/formulaire/definition/form-result-macrorugo-compound.ts
@@ -24,6 +24,8 @@ export class FormResultMacrorugoCompound extends FormResult {
     }
 
     public get results(): CalculatorResults[] {
+        // ensure help links are propagated
+        this._mrcResults.helpLinks = this.helpLinks;
         return [ this._mrcResults ];
     }
 
diff --git a/src/app/formulaire/definition/form-result-pab.ts b/src/app/formulaire/definition/form-result-pab.ts
index 5adc86f13..6a4cd34fd 100644
--- a/src/app/formulaire/definition/form-result-pab.ts
+++ b/src/app/formulaire/definition/form-result-pab.ts
@@ -24,6 +24,8 @@ export class FormResultPab extends FormResult {
     }
 
     public get results(): CalculatorResults[] {
+        // ensure help links are propagated
+        this._pabResults.helpLinks = this.helpLinks;
         return [ this._pabResults ];
     }
 
diff --git a/src/app/formulaire/definition/form-result-remous.ts b/src/app/formulaire/definition/form-result-remous.ts
index 047d7a879..4ae14b792 100644
--- a/src/app/formulaire/definition/form-result-remous.ts
+++ b/src/app/formulaire/definition/form-result-remous.ts
@@ -28,8 +28,8 @@ export class FormResultRemous extends FormResult {
     }
 
     public get results(): CalculatorResults[] {
-        const res: CalculatorResults[] = [];
-        res.push(this._remousResults);
-        return res;
+        // ensure help links are propagated
+        this._remousResults.helpLinks = this.helpLinks;
+        return [ this._remousResults ];
     }
 }
diff --git a/src/app/formulaire/definition/form-result-section.ts b/src/app/formulaire/definition/form-result-section.ts
index 73d5f0e87..e4acf4a41 100644
--- a/src/app/formulaire/definition/form-result-section.ts
+++ b/src/app/formulaire/definition/form-result-section.ts
@@ -60,6 +60,10 @@ export class FormResultSection extends FormResult {
 
     public get results(): CalculatorResults[] {
         const res: CalculatorResults[] = [];
+        // ensure help links are propagated
+        this._fixedResults.helpLinks = this.helpLinks;
+        this._varResults.helpLinks = this.helpLinks;
+        this._sectionResults.helpLinks = this.helpLinks;
         res.push(this._fixedResults);
         res.push(this._varResults);
         res.push(this._sectionResults);
diff --git a/src/app/formulaire/definition/form-result.ts b/src/app/formulaire/definition/form-result.ts
index 07a3c55a0..5e5fa62eb 100644
--- a/src/app/formulaire/definition/form-result.ts
+++ b/src/app/formulaire/definition/form-result.ts
@@ -1,6 +1,10 @@
 import { CalculatorResults } from "../../results/calculator-results";
 
 export abstract class FormResult {
+
+    /** copy of options.resultsHelp read by FormDefinition.parseOptions() */
+    public helpLinks: { [key: string]: string };
+
     public abstract resetResults();
 
     public abstract get hasResults(): boolean;
diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts
index c1fb2930d..7425f0a9f 100644
--- a/src/app/formulaire/formulaire-node.ts
+++ b/src/app/formulaire/formulaire-node.ts
@@ -8,29 +8,19 @@ export abstract class FormulaireNode implements IObservable {
     /** aide en ligne */
     protected _helpLink: string;
 
-    /**
-     * identifiant dans le fichier de conf
-     */
+    /** identifiant dans le fichier de conf */
     protected _confId: string;
 
-    /**
-    * id numérique unique
-    */
+    /** id numérique unique */
     private _uid: string;
 
-    /**
-     * parent direct
-     */
+    /** parent direct */
     private _parentNode: FormulaireNode;
 
-    /**
-     * enfants (utilisé entre autres pour FormulaireDefinition, FieldSet et FieldsetContainer)
-     */
+    /** enfants (utilisé entre autres pour FormulaireDefinition, FieldSet et FieldsetContainer) */
     private _kids: FormulaireNode[];
 
-    /**
-     * implémentation par délégation de IObservable
-     */
+    /** implémentation par délégation de IObservable */
     private _observable: Observable;
 
     constructor(parent: FormulaireNode) {
diff --git a/src/app/results/calculator-results.ts b/src/app/results/calculator-results.ts
index 0fcc1c090..a3f67c0cf 100644
--- a/src/app/results/calculator-results.ts
+++ b/src/app/results/calculator-results.ts
@@ -7,6 +7,9 @@ import { sprintf } from "sprintf-js";
 
 export abstract class CalculatorResults {
 
+    /** help links by result symbol, read from calculator config */
+    public helpLinks: { [key: string]: string };
+
     /**
      * @param p parameter to generate label for
      * @param displaySymbol if true, will prefix label with parameter symbol (ex: "ZDV")
@@ -51,4 +54,17 @@ export abstract class CalculatorResults {
      * indique si il existe des résultats à afficher
      */
     public abstract get hasResults(): boolean;
+
+    public getHelpLink(symbol: string): string {
+        // add help link if any
+        if (this.helpLinks !== undefined && this.helpLinks[symbol] !== undefined) {
+            // important: no ".html" is added after the link, to allow using anchors in config file
+            const helpURL = "assets/docs-fr/calculators/" + this.helpLinks[symbol];
+            // pseudo-<mat-icon> dirty trick because <mat-icon> renderer cannot be
+            // triggered when code is set through innerHTML
+            return `<a href="${helpURL}" target="_blank"><span class="material-icons mat-accent">help</span></a>`;
+        } else {
+            return "";
+        }
+    }
 }
diff --git a/src/app/results/macrorugo-compound-results.ts b/src/app/results/macrorugo-compound-results.ts
index dbcdaa455..dd1e177f5 100644
--- a/src/app/results/macrorugo-compound-results.ts
+++ b/src/app/results/macrorugo-compound-results.ts
@@ -46,7 +46,7 @@ export class MacrorugoCompoundResults extends MultiDimensionResults {
             if (sn.parent) {
                 ct = sn.parent.calcType;
             }
-            let unit;
+            let unit: string;
             // is h a parameter ? If so, extract its unit
             try {
                 const p = sn.getParameter(h);
@@ -54,7 +54,9 @@ export class MacrorugoCompoundResults extends MultiDimensionResults {
                     unit = p.unit;
                 }
             } catch (e) { /* silent fail */ }
-            return ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct , h, unit);
+            let label = ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct , h, unit);
+            label += this.getHelpLink(h);
+            return label;
         });
     }
 
diff --git a/src/app/results/pab-results.ts b/src/app/results/pab-results.ts
index 38a027703..bcf4b2b68 100644
--- a/src/app/results/pab-results.ts
+++ b/src/app/results/pab-results.ts
@@ -52,7 +52,9 @@ export class PabResults extends MultiDimensionResults {
             if (sn.parent) {
                 ct = sn.parent.calcType;
             }
-            return ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct , h);
+            let label = ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct , h);
+            label += this.getHelpLink(h);
+            return label;
         });
     }
 
diff --git a/src/app/results/param-calc-results.ts b/src/app/results/param-calc-results.ts
index 02ec6097e..60c0e257d 100644
--- a/src/app/results/param-calc-results.ts
+++ b/src/app/results/param-calc-results.ts
@@ -7,19 +7,14 @@ import { Result, cLog } from "jalhyd";
  * les autres étant tous fixés ou avec un paramètre varié
  */
 export abstract class CalculatedParamResults extends CalculatorResults {
-    /**
-     * paramètre calculé
-     */
+
+    /** paramètre calculé */
     protected _calculatedParam: NgParameter;
 
-    /**
-     * titre de la colonne
-     */
+    /** titre de la colonne du paramètre calculé */
     public calculatedParameterHeader: string;
 
-    /**
-     * résultat du calcul sur le paramètre calculé
-     */
+    /** résultat du calcul sur le paramètre calculé */
     public result: Result;
 
     /** custom variables order for results tables  */
diff --git a/src/app/results/remous-results.ts b/src/app/results/remous-results.ts
index acb80ff68..ba7c03a95 100644
--- a/src/app/results/remous-results.ts
+++ b/src/app/results/remous-results.ts
@@ -151,6 +151,7 @@ export class RemousResults extends CalculatorResults {
             keys.push(this.extraParamSymbol);
         }
         this._varResults.resultKeys = keys;
+        this._varResults.helpLinks = this.helpLinks;
         this._varResults.update();
     }
 
diff --git a/src/app/results/var-results.ts b/src/app/results/var-results.ts
index 47a49e5f1..3594635b6 100644
--- a/src/app/results/var-results.ts
+++ b/src/app/results/var-results.ts
@@ -312,7 +312,9 @@ export class VarResults extends CalculatedParamResults implements PlottableData
     public update() {
         // refresh param headers
         this._variableParamHeaders = this._variatedParams.map((v) => {
-            return CalculatorResults.paramLabel(v, true, this.result.sourceNub);
+            let h = CalculatorResults.paramLabel(v, true, this.result.sourceNub);
+            h += this.getHelpLink(v.symbol);
+            return h;
         });
 
         // liste la plus longue
@@ -364,9 +366,9 @@ export class VarResults extends CalculatedParamResults implements PlottableData
                     unit = p.unit;
                 }
             } catch (e) { /* silent fail */ }
-            this._resultHeaders.push(
-                ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct, k, unit)
-            );
+            let rh = ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct, k, unit);
+            rh += this.getHelpLink(k);
+            this._resultHeaders.push(rh);
         }
         // entêtes des résultats des enfants
         for (const c of sn.getChildren()) {
@@ -374,11 +376,11 @@ export class VarResults extends CalculatedParamResults implements PlottableData
                 const cn = capitalize(ServiceFactory.instance.i18nService.childName(sn));
                 // using latest ResultElement; results count / types are supposed to be the same on every iteration
                 for (const k of c.result.resultElement.keys) {
-                    this._resultHeaders.push(
-                        sprintf(ServiceFactory.instance.i18nService.localizeText("INFO_STUFF_N"), cn)
-                            + (c.findPositionInParent() + 1) + " : "
-                            + ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct, k)
-                    );
+                    let rh = sprintf(ServiceFactory.instance.i18nService.localizeText("INFO_STUFF_N"), cn)
+                        + (c.findPositionInParent() + 1) + " : "
+                        + ServiceFactory.instance.formulaireService.expandVariableNameAndUnit(ct, k);
+                    rh += this.getHelpLink(k);
+                    this._resultHeaders.push(rh);
                 }
             }
         }
-- 
GitLab