From 17795a9fe8474aef1e1b5f3a0bdbbc6b0fb1863d Mon Sep 17 00:00:00 2001
From: David Smadja <david.smadja@assemblee-nationale.fr>
Date: Fri, 14 Feb 2025 17:51:08 +0100
Subject: [PATCH] Move StandardOfLiving into its own component

---
 src/lib/components/StandardOfLiving.svelte    | 160 ++++++++++++++++++
 .../test_case_selected/PaySlipView.svelte     | 147 +---------------
 2 files changed, 164 insertions(+), 143 deletions(-)
 create mode 100644 src/lib/components/StandardOfLiving.svelte

diff --git a/src/lib/components/StandardOfLiving.svelte b/src/lib/components/StandardOfLiving.svelte
new file mode 100644
index 000000000..65e4a2477
--- /dev/null
+++ b/src/lib/components/StandardOfLiving.svelte
@@ -0,0 +1,160 @@
+<script lang="ts">
+  import { entityByKey } from "$lib/entities"
+  import publicConfig from "$lib/public_config"
+  import {
+    getCalculatedVariableValueByCalculationName,
+    type Situation,
+  } from "$lib/situations"
+  import {
+    variableSummaryByName,
+    type ValuesByCalculationNameByVariableName,
+    type VariableValue,
+  } from "$lib/variables"
+  import Tooltip from "$lib/components/Tooltip.svelte"
+  import ValueChange from "$lib/components/ValueChange.svelte"
+
+  interface Props {
+    situation: Situation
+    valuesByCalculationNameByVariableName: ValuesByCalculationNameByVariableName
+  }
+
+  let { situation, valuesByCalculationNameByVariableName }: Props = $props()
+
+  const { householdEntityKey } = publicConfig
+  const householdEntity = entityByKey[householdEntityKey]
+  let householdSituation = $derived(situation[householdEntity.key_plural!])
+
+  const populationId = $derived(
+    Object.keys(householdSituation).sort((populationId1, populationId2) =>
+      populationId1.localeCompare(populationId2),
+    )[0],
+  )
+  const niveau_de_vie = $derived(
+    getCalculatedVariableNumberValue(
+      situation,
+      valuesByCalculationNameByVariableName,
+      "niveau_de_vie",
+      populationId,
+    ) ?? 0,
+  )
+
+  function getCalculatedVariableNumberValue(
+    situation: Situation,
+    valuesByCalculationNameByVariableName: ValuesByCalculationNameByVariableName,
+    variableName: string,
+    populationId: string,
+  ): number | undefined {
+    return getCalculatedVariableValue(
+      situation,
+      valuesByCalculationNameByVariableName,
+      variableName,
+      populationId,
+    ) as number | undefined
+  }
+
+  function getCalculatedVariableValue(
+    situation: Situation,
+    valuesByCalculationNameByVariableName: ValuesByCalculationNameByVariableName,
+    variableName: string,
+    populationId: string,
+  ): VariableValue | undefined {
+    const variable = variableSummaryByName[variableName]
+    if (variable === undefined) {
+      return undefined
+    }
+    return getCalculatedVariableValueByCalculationName(
+      situation,
+      valuesByCalculationNameByVariableName,
+      variable,
+      populationId,
+    ).law
+  }
+</script>
+
+<div class="relative flex flex-col">
+  {#if niveau_de_vie !== 0}
+    <div
+      class="flex min-h-8 items-center justify-between border-t-2 border-double border-gray-400 bg-neutral-200 px-4 font-bold text-gray-600"
+    >
+      <Tooltip arrowClass="bg-white" widthClass="w-80" initialPlacement="right">
+        <span
+          class="cursor-default font-normal underline decoration-dotted hover:text-black"
+          >Niveau de vie
+          <iconify-icon
+            class="align-[-0.15rem] text-sm"
+            icon="ri-information-line"
+          ></iconify-icon></span
+        >
+        {#snippet tooltip()}
+          <div
+            class="overflow-hidden rounded-lg border border-gray-200 bg-white text-start text-sm font-normal shadow-md"
+          >
+            <div class="border-b border-gray-200 bg-gray-100 px-3 py-2">
+              <h3 class="font-semibold text-gray-900">
+                Qu'est-ce que le niveau de vie ?
+              </h3>
+            </div>
+
+            <div class="px-3 py-2">
+              <span class="font-normal text-black">
+                Selon l'Insee, <i
+                  >« Le niveau de vie est égal au revenu disponible du ménage
+                  divisé par le nombre d'unités de consommation (UC). Le niveau
+                  de vie est donc le même pour tous les individus d'un même
+                  ménage. Le niveau de vie correspond à ce qu’Eurostat nomme «
+                  revenu disponible équivalent ». »</i
+                >
+              </span> <br />
+              <br />
+              <b>Niveau de vie de ce cas type :</b>
+              <p class="flex flex-wrap gap-1 text-nowrap">
+                Revenu disponible de
+                <ValueChange
+                  unitName="currency-EUR"
+                  valueByCalculationName={getCalculatedVariableValueByCalculationName(
+                    situation,
+                    valuesByCalculationNameByVariableName,
+                    variableSummaryByName["revenu_disponible"],
+                    populationId,
+                  )}
+                /> ÷
+                <ValueChange
+                  unitName={null}
+                  valueByCalculationName={getCalculatedVariableValueByCalculationName(
+                    situation,
+                    valuesByCalculationNameByVariableName,
+                    variableSummaryByName["unites_consommation"],
+                    populationId,
+                  )}
+                /> UC
+              </p>
+
+              <br />
+              <a
+                class="lx-link-simple"
+                href="https://www.insee.fr/fr/metadonnees/definition/c1890"
+                target="_blank"
+                ><iconify-icon
+                  class="align-[-0.15rem] text-sm"
+                  icon="ri-book-open-fill"
+                ></iconify-icon> Définition Insee</a
+              >
+            </div>
+          </div>
+        {/snippet}
+      </Tooltip>
+
+      <p class="mr-4 flex gap-1 p-0.5 text-sm">
+        = <ValueChange
+          unitName="currency-EUR"
+          valueByCalculationName={getCalculatedVariableValueByCalculationName(
+            situation,
+            valuesByCalculationNameByVariableName,
+            variableSummaryByName["niveau_de_vie"],
+            populationId,
+          )}
+        />
+      </p>
+    </div>
+  {/if}
+</div>
diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipView.svelte
index d66fbe686..786464f6e 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipView.svelte
@@ -16,11 +16,9 @@
   import type { DisplayMode } from "$lib/displays"
   import { entityByKey, personEntityKey } from "$lib/entities"
   import { trackTestCaseGraph } from "$lib/matomo"
-  import publicConfig from "$lib/public_config"
   import { revaluationName, shared } from "$lib/shared.svelte"
   import {
     type ActiveSlider,
-    getCalculatedVariableValueByCalculationName,
     getSituationVariableValue,
     setSituationVariableValue,
     type Situation,
@@ -34,6 +32,7 @@
   } from "$lib/variables"
   import LinkedVariables from "$lib/components/variables/LinkedVariables.svelte"
   import { iterToDepth } from "$lib/iterators"
+  import StandardOfLiving from "$lib/components/StandardOfLiving.svelte"
 
   interface Props {
     displayMode: DisplayMode
@@ -46,8 +45,6 @@
     year: number
   }
 
-  const { householdEntityKey } = publicConfig
-
   let {
     displayMode,
     evaluationByName,
@@ -76,7 +73,6 @@
       minimumFractionDigits: 0,
       style: "currency",
     }).format(removeNegativeZero(value))
-  const householdEntity = entityByKey[householdEntityKey]
   const personEntity = entityByKey[personEntityKey]
 
   const oilSpendings = oilTypes.map((name) => ({
@@ -121,9 +117,7 @@
     )
   })
 
-  let personSituation = $derived(situation[personEntity.key_plural])
-
-  let householdSituation = $derived(situation[householdEntity.key_plural])
+  let personSituation = $derived(situation[personEntity.key_plural!])
 
   function getCorrectSimulationUrl(variableName: string) {
     const newDisplayMode =
@@ -160,38 +154,6 @@
     return getSituationVariableValue(situation, variable, populationId, year)
   }
 
-  function getCalculatedVariableNumberValue(
-    situation: Situation,
-    valuesByCalculationNameByVariableName: ValuesByCalculationNameByVariableName,
-    variableName: string,
-    populationId: string,
-  ): number | undefined {
-    return getCalculatedVariableValue(
-      situation,
-      valuesByCalculationNameByVariableName,
-      variableName,
-      populationId,
-    ) as number | undefined
-  }
-
-  function getCalculatedVariableValue(
-    situation: Situation,
-    valuesByCalculationNameByVariableName: ValuesByCalculationNameByVariableName,
-    variableName: string,
-    populationId: string,
-  ): VariableValue | undefined {
-    const variable = variableSummaryByName[variableName]
-    if (variable === undefined) {
-      return undefined
-    }
-    return getCalculatedVariableValueByCalculationName(
-      situation,
-      valuesByCalculationNameByVariableName,
-      variable,
-      populationId,
-    ).law
-  }
-
   function removeSituationSlider() {
     if (shared.savedSituation !== undefined) {
       situation = shared.savedSituation
@@ -656,7 +618,7 @@
             {decomposition}
             {depth}
             {visibleChildren}
-          ></LinkedVariables>
+          />
         {/if}
       {/each}
     </div>
@@ -664,108 +626,7 @@
 
   <!--AJout de la variable niveau de vie-->
   {#if shared.waterfall.name === "brut_to_disponible"}
-    <div class="relative flex flex-col">
-      {#each Object.keys(householdSituation).sort( (populationId1, populationId2) => populationId1.localeCompare(populationId2), ) as populationId}
-        {@const niveau_de_vie =
-          getCalculatedVariableNumberValue(
-            situation,
-            valuesByCalculationNameByVariableName,
-            "niveau_de_vie",
-            populationId,
-          ) ?? 0}
-
-        {#if niveau_de_vie !== 0}
-          <div
-            class="flex min-h-8 items-center justify-between border-t-2 border-double border-gray-400 bg-neutral-200 px-4 font-bold text-gray-600"
-          >
-            <Tooltip
-              arrowClass="bg-white"
-              widthClass="w-80"
-              initialPlacement="right"
-            >
-              <span
-                class="cursor-default font-normal underline decoration-dotted hover:text-black"
-                >Niveau de vie
-                <iconify-icon
-                  class="align-[-0.15rem] text-sm"
-                  icon="ri-information-line"
-                ></iconify-icon></span
-              >
-              {#snippet tooltip()}
-                <div
-                  class="overflow-hidden rounded-lg border border-gray-200 bg-white text-start text-sm font-normal shadow-md"
-                >
-                  <div class="border-b border-gray-200 bg-gray-100 px-3 py-2">
-                    <h3 class="font-semibold text-gray-900">
-                      Qu'est-ce que le niveau de vie ?
-                    </h3>
-                  </div>
-
-                  <div class="px-3 py-2">
-                    <span class="font-normal text-black">
-                      Selon l'Insee, <i
-                        >« Le niveau de vie est égal au revenu disponible du
-                        ménage divisé par le nombre d'unités de consommation
-                        (UC). Le niveau de vie est donc le même pour tous les
-                        individus d'un même ménage. Le niveau de vie correspond
-                        à ce qu’Eurostat nomme « revenu disponible équivalent ».
-                        »</i
-                      >
-                    </span> <br />
-                    <br />
-                    <b>Niveau de vie de ce cas type :</b>
-                    <p class="flex flex-wrap gap-1 text-nowrap">
-                      Revenu disponible de
-                      <ValueChange
-                        unitName="currency-EUR"
-                        valueByCalculationName={getCalculatedVariableValueByCalculationName(
-                          situation,
-                          valuesByCalculationNameByVariableName,
-                          variableSummaryByName["revenu_disponible"],
-                          populationId,
-                        )}
-                      /> ÷
-                      <ValueChange
-                        unitName={null}
-                        valueByCalculationName={getCalculatedVariableValueByCalculationName(
-                          situation,
-                          valuesByCalculationNameByVariableName,
-                          variableSummaryByName["unites_consommation"],
-                          populationId,
-                        )}
-                      /> UC
-                    </p>
-
-                    <br />
-                    <a
-                      class="lx-link-simple"
-                      href="https://www.insee.fr/fr/metadonnees/definition/c1890"
-                      target="_blank"
-                      ><iconify-icon
-                        class="align-[-0.15rem] text-sm"
-                        icon="ri-book-open-fill"
-                      ></iconify-icon> Définition Insee</a
-                    >
-                  </div>
-                </div>
-              {/snippet}
-            </Tooltip>
-
-            <p class="mr-4 flex gap-1 p-0.5 text-sm">
-              = <ValueChange
-                unitName="currency-EUR"
-                valueByCalculationName={getCalculatedVariableValueByCalculationName(
-                  situation,
-                  valuesByCalculationNameByVariableName,
-                  variableSummaryByName["niveau_de_vie"],
-                  populationId,
-                )}
-              />
-            </p>
-          </div>
-        {/if}
-      {/each}
-    </div>
+    <StandardOfLiving {situation} {valuesByCalculationNameByVariableName} />
   {/if}
 
   <!--ZONE 3.A : TICKET DE CARBURANT-->
-- 
GitLab