From cba0bc41b88537c753235512c9357e3aeb81132d Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Mon, 10 Mar 2025 10:38:07 +0100
Subject: [PATCH 01/13] Copie ancien composant pour les avoir en vue le temps
 de la refacto

---
 .../test_case_selected/PaySlipViewOld.svelte  | 705 ++++++++++++++++++
 .../compare_mode/PaySlipCompareViewOld.svelte | 588 +++++++++++++++
 2 files changed, 1293 insertions(+)
 create mode 100644 src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipViewOld.svelte
 create mode 100644 src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareViewOld.svelte

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipViewOld.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipViewOld.svelte
new file mode 100644
index 000000000..067133a29
--- /dev/null
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipViewOld.svelte
@@ -0,0 +1,705 @@
+<script lang="ts">
+  import type { VariableByName } from "@openfisca/json-model"
+
+  import { goto } from "$app/navigation"
+  import OilSpendingBill from "$lib/components/impacts_view/test_cases_view/test_case_selected/OilSpendingBill.svelte"
+  import TestCaseGraph from "$lib/components/impacts_view/test_cases_view/test_case_selected/graph/TestCaseGraph.svelte"
+  import Tooltip from "$lib/components/ui_transverse_components/Tooltip.svelte"
+  import {
+    type VisibleDecomposition,
+    type EvaluationByName,
+    isChildOrDescendant,
+  } from "$lib/decompositions"
+  import { buildVisibleDecompositions } from "$lib/decompositions"
+  import type { DisplayMode } from "$lib/displays"
+  import { entityByKey, personEntityKey } from "$lib/entities"
+  import { trackTestCaseGraph } from "$lib/matomo"
+  import { revaluationName, shared } from "$lib/shared.svelte"
+  import {
+    type ActiveSlider,
+    getSituationVariableValue,
+    setSituationVariableValue,
+    type Situation,
+  } from "$lib/situations"
+  import { newSimulationUrl } from "$lib/urls"
+  import { removeNegativeZero } from "$lib/values"
+  import {
+    oilTypes,
+    type ValuesByCalculationNameByVariableName,
+    type VariableValue,
+  } from "$lib/variables"
+  import LinkedVariables from "$lib/components/impacts_view/test_cases_view/test_case_selected/LinkedVariables.svelte"
+  import { iterToDepth } from "$lib/iterators"
+  import StandardOfLiving from "$lib/components/impacts_view/test_cases_view/test_case_selected/StandardOfLiving.svelte"
+
+  interface Props {
+    displayMode: DisplayMode
+    evaluationByName: EvaluationByName
+    showLoader?: boolean
+    situation: Situation
+    situationIndex: number
+    valuesByCalculationNameByVariableName: ValuesByCalculationNameByVariableName
+    variableSummaryByName: VariableByName
+    year: number
+  }
+
+  let {
+    displayMode,
+    evaluationByName,
+    showLoader = true,
+    situation = $bindable(),
+    situationIndex,
+    valuesByCalculationNameByVariableName,
+    variableSummaryByName,
+    year,
+  }: Props = $props()
+
+  const dateFormatter = new Intl.DateTimeFormat("fr-FR", { dateStyle: "full" })
+    .format
+  const deltaFormatter = (value: number): string =>
+    new Intl.NumberFormat("fr-FR", {
+      currency: "EUR",
+      maximumFractionDigits: 0,
+      minimumFractionDigits: 0,
+      signDisplay: "never",
+      style: "currency",
+    }).format(removeNegativeZero(value))
+  const firstDeltaFormatter = (value: number): string =>
+    new Intl.NumberFormat("fr-FR", {
+      currency: "EUR",
+      maximumFractionDigits: 0,
+      minimumFractionDigits: 0,
+      style: "currency",
+    }).format(removeNegativeZero(value))
+  const personEntity = entityByKey[personEntityKey]
+
+  const oilSpendings = oilTypes.map((name) => ({
+    depenseTtcVariableName: `depense_${name}_ttc`,
+    nombreLitresVariableName: `nombre_litres_${name}`,
+    // prixTtcLitreVariableName: `prix_${name}_hors_remise_ttc_sortie`,
+    prixTtcLitreVariableName: `prix_${name}_ttc`,
+    ticpeVariableName: `${name}_ticpe`,
+    tvaVariableName: `tva_sur_${name}`,
+  }))
+
+  let useRevaluationInsteadOfLaw = $derived(revaluationName !== undefined)
+
+  let firstCalculationName = $derived(
+    useRevaluationInsteadOfLaw ? "revaluation" : "law",
+  )
+
+  let runningCalculationNames = $derived(
+    Object.entries(shared.calculationByName)
+      .filter(([, calculation]) => calculation.running)
+      .map(([calculationName]) => calculationName),
+  )
+
+  let modificationsAmendmentCount = $derived(
+    Object.keys(shared.parametricReform).length,
+  )
+
+  let visibleDecompositions: VisibleDecomposition[] = $state([])
+
+  $effect(() => {
+    visibleDecompositions = buildVisibleDecompositions(
+      shared.decompositionByName,
+      entityByKey,
+      evaluationByName,
+      situation,
+      variableSummaryByName,
+      shared.waterfall,
+      shared.showNulls,
+      useRevaluationInsteadOfLaw,
+      shared.vectorLength,
+      year,
+    )
+  })
+
+  let personSituation = $derived(situation[personEntity.key_plural!])
+
+  function getCorrectSimulationUrl(variableName: string) {
+    const newDisplayMode =
+      displayMode.edit !== undefined
+        ? {
+            ...displayMode,
+            variableName: variableName,
+          }
+        : {
+            ...displayMode,
+            mobileLaw: true,
+            parametersVariableName: variableName,
+          }
+    return newSimulationUrl(newDisplayMode)
+  }
+
+  function getFirstPersonActivity(personSituation) {
+    const populationId = Object.keys(personSituation).sort(
+      (populationId1, populationId2) =>
+        populationId1.localeCompare(populationId2),
+    )[0]
+    return getVariableValue(situation, "activite", populationId)
+  }
+
+  function getVariableValue(
+    situation: Situation,
+    variableName: string,
+    populationId: string,
+  ): VariableValue | undefined {
+    const variable = variableSummaryByName[variableName]
+    if (variable === undefined) {
+      return undefined
+    }
+    return getSituationVariableValue(situation, variable, populationId, year)
+  }
+
+  function removeSituationSlider() {
+    if (shared.savedSituation !== undefined) {
+      situation = shared.savedSituation
+      delete shared.savedSituation
+      if (shared.savedSituationIndex !== undefined) {
+        shared.testCases[shared.savedSituationIndex] = situation
+        delete shared.savedSituationIndex
+      }
+    }
+  }
+
+  function requestAxesCalculation() {
+    // Ensure that situation of previous curve is not merged with the new one.
+    if (
+      shared.savedSituation !== undefined &&
+      shared.savedSituationIndex !== undefined
+    ) {
+      shared.testCases[shared.savedSituationIndex] = shared.savedSituation
+    }
+
+    shared.savedSituation = situation
+    shared.savedSituationIndex = situationIndex
+    situation = structuredClone($state.snapshot(situation))
+    shared.testCases[situationIndex] = situation
+    if (
+      situation.sliders?.length === undefined ||
+      situation.sliders?.length <= 0
+    ) {
+      console.error(
+        "requestAxesCalculation",
+        "Situation sliders list is undefined",
+      )
+      return
+    }
+
+    // Get situation
+    const variable = variableSummaryByName[situation.sliders?.[0].name]
+    const slider = situation.sliders.find(
+      (slider) =>
+        slider.entity === variable.entity && slider.name === variable.name,
+    ) as ActiveSlider | undefined
+
+    if (slider === undefined) {
+      console.error("requestAxesCalculation", "Slider is undefined")
+      return
+    }
+
+    const updatedMin = slider.min
+    const updatedMax = slider.max
+    const updatedStepValue = (updatedMax - updatedMin) / 100 ?? slider.stepValue
+
+    const value = getSituationVariableValue(
+      situation,
+      variable,
+      slider.id,
+      year,
+    ) as number
+
+    const vectorIndex = Math.max(
+      0,
+      Math.min(100, Math.round(value / updatedStepValue)),
+    )
+
+    // Update situation
+    setSituationVariableValue(
+      entityByKey,
+      situation,
+      variable,
+      slider.id,
+      year,
+      Math.round(updatedStepValue * vectorIndex),
+    )
+    situation.slider = {
+      ...slider,
+      min: updatedMin,
+      max: updatedMax,
+      stepValue: updatedStepValue,
+      vectorIndex: vectorIndex,
+    }
+  }
+
+  function zoomIn(index: number) {
+    let visibleDecomposition = visibleDecompositions[index]
+    if (
+      visibleDecomposition === undefined ||
+      visibleDecomposition.visibleChildren === undefined
+    ) {
+      return
+    }
+    let decomposition = visibleDecomposition.decomposition
+    if (!decomposition.open) {
+      shared.decompositionByName[decomposition.name] = {
+        ...decomposition,
+        open: true,
+      }
+      return
+    }
+  }
+
+  function zoomOut(index: number) {
+    let visibleDecomposition = visibleDecompositions[index]
+    if (
+      visibleDecomposition === undefined ||
+      visibleDecomposition.visibleChildren === undefined
+    ) {
+      return
+    }
+    let decomposition = visibleDecomposition.decomposition
+    if (decomposition.open) {
+      shared.decompositionByName[decomposition.name] = {
+        ...decomposition,
+        open: false,
+      }
+      return
+    }
+  }
+</script>
+
+<!--Ce composant se découpe en 3 zones : 
+- ZONE 1 : FEUILLE DE PAIE
+- ZONE 2 : VARIALBES COMPLÉMENTAIRES À LA FEUILLE DE PAIE
+- ZONE 3 : TICKET DE CARBURANT & GRAPHIQUE DES CAS TYPES
+-->
+
+{#if visibleDecompositions.length > 0}
+  {@const firstPersonActivity = getFirstPersonActivity(personSituation)}
+
+  <!--ZONE 1 : FEUILLE DE PAIE -->
+  <!-- Bouton affichage des montants nuls -->
+  <div
+    class="mx-4 mb-3 flex justify-start"
+    id="situation_{situationIndex}_waterfall_showall"
+  >
+    <label class="inline-flex cursor-pointer items-center">
+      <input
+        type="checkbox"
+        value=""
+        class="peer sr-only"
+        bind:checked={shared.showNulls}
+      />
+      <div
+        class="peer relative h-6 w-11 shrink-0 rounded-full bg-gray-400 after:absolute after:start-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:bg-white after:transition-all after:content-[''] peer-checked:bg-le-bleu peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-0"
+      ></div>
+      <span class="ms-3 text-sm font-medium text-gray-900 dark:text-gray-300"
+        >Montrer tous les dispositifs<span
+          class="hidden sm:inline-flex md:hidden lg:inline-flex"
+          >, y compris si leur montant est à 0€</span
+        ></span
+      >
+    </label>
+  </div>
+  <!-- Feuille de paie-->
+  <div class="flex justify-between">
+    <div class="w-3/5 flex-auto">
+      {#each visibleDecompositions as { decomposition, depth, rows, trunk, visibleChildren }, index}
+        <!-- Ligne de la feuille de paie-->
+        <div
+          class="flex min-h-8 items-stretch justify-between border-t border-gray-200 px-4"
+          class:bg-gray-100={trunk && index !== 0}
+          class:border-gray-300={trunk && index !== 0}
+          class:fond={decomposition.name ===
+            displayMode.parametersVariableName ||
+            (displayMode.parametersVariableName &&
+              isChildOrDescendant(
+                shared.decompositionByName,
+                decomposition.name,
+                displayMode.parametersVariableName,
+              ))}
+          class:text-lg={decomposition.name ===
+            displayMode.parametersVariableName}
+          class:items-start={decomposition.name ===
+            displayMode.parametersVariableName}
+        >
+          <!-- Colonne 1 "Nom du dispositif"-->
+          <div class="flex-1 overflow-x-hidden">
+            {#each rows as { calculationName }}
+              {#if calculationName === firstCalculationName}
+                <div class="flex h-full w-full items-center">
+                  <!--Si c'est une variable de type tronc, exemple : Rémunération brute -->
+                  {#if trunk && index !== 0}
+                    <!--Les class permettent que le nom de la variable soit caché avec "..." et rendu visible au survol. Le comportement est différent si la variable est sélectionnée-->
+                    <div
+                      class="flex w-full items-center"
+                      class:whitespace-nowrap={decomposition.name !==
+                        displayMode.parametersVariableName}
+                    >
+                      <!-- Nom de la variable tronc, cliquable -->
+                      <a
+                        class="cursor-pointer overflow-x-hidden text-ellipsis text-gray-500 hover:z-20 hover:overflow-x-visible hover:bg-white hover:bg-opacity-90 hover:pr-1 hover:text-le-gris-dispositif-dark hover:underline"
+                        class:font-bold={decomposition.name ===
+                          displayMode.parametersVariableName}
+                        class:hover:absolute={decomposition.name !==
+                          displayMode.parametersVariableName}
+                        href={getCorrectSimulationUrl(decomposition.name)}
+                        data-sveltekit-noscroll
+                        >{decomposition.short_label ?? decomposition.label}</a
+                      >
+                    </div>
+                  {:else if visibleChildren === undefined}
+                    <!--Si c'est une variable Non-trunk, leaf-variable : La variable n'a pas de variables enfants et elle n'est pas une variable tronc -->
+
+                    <div
+                      class="flex h-full w-full items-center"
+                      class:whitespace-nowrap={decomposition.name !==
+                        displayMode.parametersVariableName}
+                    >
+                      <!--Indentation pour chaque niveau de l'arbre, illustré par une bordure-->
+                      {#each iterToDepth(depth)}
+                        <div
+                          class={`min-h-full border-l-2 bg-white pr-3 ${
+                            decomposition.name !==
+                              displayMode.parametersVariableName &&
+                            !(
+                              displayMode.parametersVariableName &&
+                              isChildOrDescendant(
+                                shared.decompositionByName,
+                                decomposition.name,
+                                displayMode.parametersVariableName,
+                              )
+                            )
+                              ? "border-gray-400"
+                              : "border-black"
+                          }`}
+                        ></div>
+                      {/each}
+                      <!--Si la variable est obsolète, ou que sa date de relecture est inconnue ou trop ancienne, un picto attention est affiché -->
+                      {#if decomposition.obsolete || decomposition.last_value_still_valid_on === undefined || decomposition.last_value_still_valid_on < (new Date().getFullYear() - 2).toString()}
+                        <Tooltip
+                          allowFlip={false}
+                          arrowClass="bg-gray-100"
+                          widthClass="w-80"
+                          initialPlacement="bottom"
+                        >
+                          <iconify-icon
+                            class="mr-0.5 shadow-none {decomposition.obsolete
+                              ? 'text-[#FF4133]'
+                              : 'text-[#FFAC33]'}"
+                            icon="material-symbols:warning-rounded"
+                            width="16"
+                            height="16"
+                          ></iconify-icon>
+                          {#snippet tooltip()}
+                            <div
+                              class="overflow-hidden rounded-lg border border-gray-200 bg-white shadow-2xl"
+                            >
+                              <div
+                                class="border-b border-gray-200 bg-gray-100 px-3 py-2"
+                              >
+                                <h3 class="font-semibold text-gray-900">
+                                  ⚠️ Ce dispositif n'est peut-être pas à jour
+                                </h3>
+                              </div>
+                              <div
+                                class="px-3 py-2 text-sm font-light text-gray-500"
+                              >
+                                Dernière relecture :
+                                {#if decomposition.last_value_still_valid_on === undefined}
+                                  date indéterminée
+                                {:else}{dateFormatter(
+                                    new Date(
+                                      decomposition.last_value_still_valid_on,
+                                    ),
+                                  )}
+                                {/if}
+                                {#if decomposition.obsolete}
+                                  ; Obsolète !{/if}
+                              </div>
+                            </div>
+                          {/snippet}
+                        </Tooltip>
+                      {/if}
+                      <!-- Nom de la variable non-trunk, leaf, cliquable -->
+                      <a
+                        class="cursor-pointer overflow-x-hidden text-ellipsis font-serif hover:z-20 hover:overflow-x-visible hover:bg-white hover:bg-opacity-90 hover:pr-1 hover:text-le-gris-dispositif-dark hover:underline"
+                        class:font-bold={decomposition.name ===
+                          displayMode.parametersVariableName}
+                        class:hover:text-wrap={decomposition.name !==
+                          displayMode.parametersVariableName}
+                        href={getCorrectSimulationUrl(decomposition.name)}
+                        data-sveltekit-noscroll
+                        >{decomposition.short_label ?? decomposition.label}</a
+                      >
+                    </div>
+                  {:else}
+                    <!-- Si c'est une variable Non-trunk, Non-leaf : La variable a des variables enfants et n'est pas une variable tronc | une flèche à droite permet d'ouvrir les variables enfants-->
+
+                    <div
+                      class="flex h-full w-full items-center justify-start"
+                      class:whitespace-nowrap={decomposition.name !==
+                        displayMode.parametersVariableName}
+                    >
+                      <!--Indentation pour chaque niveau de l'arbre, illustré par une bordure-->
+                      {#each iterToDepth(depth)}
+                        <div
+                          class={`min-h-full border-l-2 bg-white pr-3 ${
+                            decomposition.name !==
+                              displayMode.parametersVariableName &&
+                            !(
+                              displayMode.parametersVariableName &&
+                              isChildOrDescendant(
+                                shared.decompositionByName,
+                                decomposition.name,
+                                displayMode.parametersVariableName,
+                              )
+                            )
+                              ? "border-gray-400"
+                              : "border-black"
+                          }`}
+                        ></div>
+                      {/each}
+                      <button
+                        class="cursor-pointer overflow-x-hidden text-ellipsis text-left font-serif hover:z-20 hover:overflow-x-visible hover:bg-white hover:bg-opacity-90 hover:text-le-gris-dispositif-dark hover:underline"
+                        class:hover:text-wrap={decomposition.name !==
+                          displayMode.parametersVariableName}
+                        class:font-bold={decomposition.name ===
+                          displayMode.parametersVariableName}
+                        onclick={() => {
+                          // Non-leaf decomposition node in variable inputs mode => no-link
+                          if (decomposition.open) {
+                            zoomOut(index)
+                          } else {
+                            zoomIn(index)
+                          }
+                          // Leaf decomposition node with parameters in parameters mode => link
+                          if (displayMode.edit === undefined) {
+                            goto(getCorrectSimulationUrl(decomposition.name), {
+                              noScroll: true,
+                            })
+                          }
+                        }}
+                        data-sveltekit-noscroll
+                        >{decomposition.short_label ??
+                          decomposition.label}</button
+                      >
+                      <button
+                        class="text-black"
+                        aria-label={decomposition.open
+                          ? "Ouvrir variables enfants"
+                          : "Fermer"}
+                        onclick={() =>
+                          decomposition.open ? zoomOut(index) : zoomIn(index)}
+                      >
+                        <iconify-icon
+                          class="align-[-0.25rem] text-lg hover:text-le-gris-dispositif"
+                          icon={decomposition.open
+                            ? "ri-arrow-down-s-line"
+                            : "ri-arrow-right-s-line"}
+                        ></iconify-icon>
+                      </button>
+                    </div>
+                  {/if}
+                </div>
+              {/if}
+            {/each}
+          </div>
+
+          <!-- Colonne 2 - Valeur du dispositif-->
+          <div
+            class="flex flex-nowrap pr-1 sm:items-center md:pr-4"
+            class:py-1={!trunk}
+            class:items-end={!trunk}
+          >
+            <div class="flex flex-col justify-end sm:flex-row sm:items-center">
+              {#each rows as { calculationName, deltaAtVectorIndex }}
+                <span
+                  class="h-full pl-1 text-right text-sm"
+                  class:content-center={trunk}
+                  class:content-start={!trunk}
+                >
+                  <!--Loader squelette pendant que la valeur charge -->
+                  {#if showLoader && runningCalculationNames.length > 0}
+                    {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}
+                      <span
+                        class="animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
+                      >
+                        <span class="text-white blur">value €</span>
+                      </span>
+                    {/if}
+                    {#if runningCalculationNames.includes("bill")}
+                      <span
+                        class="animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
+                      >
+                        <span class="text-white blur">value €</span>
+                      </span>
+                    {/if}
+                    {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
+                      <span
+                        class="animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
+                      >
+                        <span class="text-white blur">value €</span>
+                      </span>
+                    {/if}
+                    <!--Valeur du waterfall-->
+                  {:else if trunk && index !== 0}
+                    <span
+                      class=" {calculationName === firstCalculationName
+                        ? rows.find((row) => row.calculationName === 'bill') ===
+                          undefined
+                          ? rows.find(
+                              (row) => row.calculationName === 'amendment',
+                            ) === undefined
+                            ? 'text-gray-500'
+                            : 'text-gray-500 line-through-amendment'
+                          : 'text-gray-500 line-through-bill'
+                        : calculationName === 'bill'
+                          ? rows.find(
+                              (row) => row.calculationName === 'amendment',
+                            ) === undefined
+                            ? 'text-le-rouge-bill'
+                            : 'text-le-rouge-bill line-through-amendment'
+                          : 'bg-le-jaune text-gray-500'}"
+                      class:text-base={decomposition.name !==
+                        displayMode.parametersVariableName}
+                      class:text-2xl={decomposition.name ===
+                        displayMode.parametersVariableName}
+                      class:font-bold={decomposition.name ===
+                        displayMode.parametersVariableName}
+                      ><span
+                        class="content-center pr-1 font-normal text-gray-500"
+                        >=</span
+                      >{firstDeltaFormatter(deltaAtVectorIndex ?? 0)}</span
+                    >
+                  {:else}
+                    <span
+                      class="font-bold {calculationName === firstCalculationName
+                        ? rows.find((row) => row.calculationName === 'bill') ===
+                          undefined
+                          ? rows.find(
+                              (row) => row.calculationName === 'amendment',
+                            ) === undefined
+                            ? ''
+                            : 'line-through-amendment'
+                          : 'line-through-bill'
+                        : calculationName === 'bill'
+                          ? rows.find(
+                              (row) => row.calculationName === 'amendment',
+                            ) === undefined
+                            ? 'text-le-rouge-bill'
+                            : 'text-le-rouge-bill line-through-amendment'
+                          : 'bg-le-jaune'}"
+                      class:opacity-20={decomposition.open}
+                      class:text-base={decomposition.name !==
+                        displayMode.parametersVariableName}
+                      class:text-3xl={decomposition.name ===
+                        displayMode.parametersVariableName}
+                      class:font-semibold={decomposition.name ===
+                        displayMode.parametersVariableName}
+                      >{#if index !== 0}{#if deltaAtVectorIndex < 0}-{:else if deltaAtVectorIndex > 0}+{/if}{/if}
+                      {deltaFormatter(deltaAtVectorIndex ?? 0)}</span
+                    >
+                  {/if}
+                </span>
+              {/each}
+            </div>
+          </div>
+        </div>
+        <!--Affichage des variables liées s'il y en a-->
+        {#if displayMode.parametersVariableName !== undefined && decomposition.name === displayMode.parametersVariableName}
+          <LinkedVariables
+            {displayMode}
+            {evaluationByName}
+            {situationIndex}
+            {variableSummaryByName}
+            {decomposition}
+            {depth}
+            {visibleChildren}
+          />
+        {/if}
+      {/each}
+    </div>
+  </div>
+
+  <!--AJout de la variable niveau de vie-->
+  {#if shared.waterfall.name === "brut_to_disponible"}
+    <StandardOfLiving {situation} {valuesByCalculationNameByVariableName} />
+  {/if}
+
+  <!--ZONE 3.A : TICKET DE CARBURANT-->
+  {#if shared.waterfall.name === "disponible_to_disponible_apres_taxes_carburant"}
+    {#each oilSpendings as { depenseTtcVariableName, nombreLitresVariableName, prixTtcLitreVariableName, ticpeVariableName, tvaVariableName }}
+      <OilSpendingBill
+        {depenseTtcVariableName}
+        {nombreLitresVariableName}
+        {prixTtcLitreVariableName}
+        on:changeTestCaseToEditIndex
+        {situation}
+        {situationIndex}
+        {ticpeVariableName}
+        {tvaVariableName}
+        {valuesByCalculationNameByVariableName}
+        {year}
+      />
+    {/each}
+  {:else}
+    <!--ZONE 3.B : GRAPHIQUE DES CAS TYPES-->
+    {#if firstPersonActivity !== "inactif"}
+      <button
+        class="mt-10 flex w-full items-center gap-2 border-b px-4 py-2 text-start text-neutral-600 transition-all hover:bg-neutral-100 active:bg-neutral-200"
+        onclick={() => {
+          if (situation.slider === undefined) {
+            requestAxesCalculation()
+            trackTestCaseGraph(firstPersonActivity)
+          } else {
+            removeSituationSlider()
+          }
+        }}
+      >
+        <iconify-icon class="text-lg" icon="ri-line-chart-fill"></iconify-icon>
+        <span class="flex-1 font-bold">
+          Voir ce cas type sur un graphique faisant évoluer {#if firstPersonActivity === "actif"}
+            le salaire
+          {:else if firstPersonActivity === "retraite"}
+            la retraite
+          {:else if firstPersonActivity === "chomeur"}
+            le chômage
+          {:else}
+            le revenu
+          {/if}
+          :
+        </span>
+        <iconify-icon
+          class="text-3xl"
+          icon={situation.slider !== undefined
+            ? "ri-arrow-drop-down-line"
+            : "ri-arrow-drop-right-line"}
+        ></iconify-icon>
+      </button>
+      <TestCaseGraph
+        {displayMode}
+        {evaluationByName}
+        evaluationByNameArray={shared.evaluationByNameArray}
+        {situation}
+        {situationIndex}
+        {useRevaluationInsteadOfLaw}
+        {valuesByCalculationNameByVariableName}
+        {variableSummaryByName}
+        vectorLength={shared.vectorLength}
+        waterfall={shared.waterfall}
+        {year}
+      />
+    {/if}
+  {/if}
+{/if}
+
+<style lang="postcss">
+  .fond {
+    background-color: #ffffff;
+    /* Polka dots - Heropatterns.com échelle réduite */
+    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3E%3Cpath fill='%23A0A0A0' fill-opacity='0.4' d='M1 3h1v1H1V3zm2-2h1v1H3V1z'%3E%3C/path%3E%3C/svg%3E");
+  }
+</style>
diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareViewOld.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareViewOld.svelte
new file mode 100644
index 000000000..9243424b9
--- /dev/null
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareViewOld.svelte
@@ -0,0 +1,588 @@
+<script lang="ts">
+  import { preventDefault } from "svelte/legacy"
+
+  import type { VariableByName } from "@openfisca/json-model"
+
+  import { goto } from "$app/navigation"
+  import { page } from "$app/stores"
+  import Tooltip from "$lib/components/ui_transverse_components/Tooltip.svelte"
+  import type {
+    EvaluationByName,
+    VisibleDecompositionForComparison,
+  } from "$lib/decompositions"
+  import { buildVisibleDecompositionsForComparison } from "$lib/decompositions"
+  import type { DisplayMode } from "$lib/displays"
+  import { entityByKey } from "$lib/entities"
+  import { shared } from "$lib/shared.svelte"
+  import type { Situation } from "$lib/situations"
+  import { newSimulationUrl } from "$lib/urls"
+  import { removeNegativeZero } from "$lib/values"
+
+  interface Props {
+    displayMode: DisplayMode
+    evaluationByNameArray: EvaluationByName[]
+    situations: Situation[]
+    situationsToCompareIndex: number[]
+    showLoader?: boolean
+    variableSummaryByName: VariableByName
+    year: number
+  }
+
+  let {
+    displayMode,
+    evaluationByNameArray,
+    situations,
+    situationsToCompareIndex,
+    showLoader = true,
+    variableSummaryByName,
+    year,
+  }: Props = $props()
+
+  const dateFormatter = new Intl.DateTimeFormat("fr-FR", { dateStyle: "full" })
+    .format
+  const deltaFormatter = (value: number): string =>
+    new Intl.NumberFormat("fr-FR", {
+      currency: "EUR",
+      maximumFractionDigits: 0,
+      minimumFractionDigits: 0,
+      signDisplay: "never",
+      style: "currency",
+    }).format(removeNegativeZero(value))
+
+  let useRevaluationInsteadOfLaw = $derived(
+    $page.data.revaluationName !== undefined,
+  )
+
+  let firstCalculationName = $derived(
+    useRevaluationInsteadOfLaw ? "revaluation" : "law",
+  )
+
+  let runningCalculationNames = $derived(
+    Object.entries(shared.calculationByName)
+      .filter(([, calculation]) => calculation.running)
+      .map(([calculationName]) => calculationName),
+  )
+
+  let modificationsAmendmentCount = $derived(
+    Object.keys(shared.parametricReform).length,
+  )
+
+  let visibleDecompositions: VisibleDecompositionForComparison[] = $state([])
+
+  $effect(() => {
+    visibleDecompositions = buildVisibleDecompositionsForComparison(
+      shared.decompositionByName,
+      entityByKey,
+      situationsToCompareIndex.map(
+        (situationIndex) => evaluationByNameArray[situationIndex],
+      ),
+      situationsToCompareIndex.map(
+        (situationIndex) => situations[situationIndex],
+      ),
+      variableSummaryByName,
+      shared.waterfall,
+      shared.showNulls,
+      useRevaluationInsteadOfLaw,
+      shared.vectorLength,
+      year,
+    )
+  })
+
+  function* iterToDepth(depth: number): Generator<number, void, unknown> {
+    for (let i = 0; i < depth; i++) {
+      yield i
+    }
+  }
+
+  function zoomIn(index: number) {
+    let visibleDecomposition = visibleDecompositions[index]
+    if (
+      visibleDecomposition === undefined ||
+      visibleDecomposition.visibleChildren === undefined
+    ) {
+      return
+    }
+    let decomposition = visibleDecomposition.decomposition
+    if (!decomposition.open) {
+      shared.decompositionByName[decomposition.name] = {
+        ...decomposition,
+        open: true,
+      }
+      return
+    }
+  }
+
+  function zoomOut(index: number) {
+    let visibleDecomposition = visibleDecompositions[index]
+    if (
+      visibleDecomposition === undefined ||
+      visibleDecomposition.visibleChildren === undefined
+    ) {
+      return
+    }
+    let decomposition = visibleDecomposition.decomposition
+    if (decomposition.open) {
+      shared.decompositionByName[decomposition.name] = {
+        ...decomposition,
+        open: false,
+      }
+      return
+    }
+  }
+</script>
+
+{#if visibleDecompositions.length > 0}
+  <div>
+    <div class="h-5 bg-gradient-to-b from-gray-100 to-transparent" />
+    <!--Montants-nuls-->
+    <div class="mx-1 mb-3 flex justify-start">
+      <label class="inline-flex cursor-pointer items-center">
+        <input
+          type="checkbox"
+          value=""
+          class="peer sr-only"
+          bind:checked={shared.showNulls}
+        />
+        <div
+          class="peer relative h-6 w-11 shrink-0 rounded-full bg-gray-400 after:absolute after:start-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:bg-white after:transition-all after:content-[''] peer-checked:bg-le-bleu peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-0"
+        ></div>
+        <span class="ms-3 text-sm font-medium text-gray-900 dark:text-gray-300"
+          >Montrer tous les dispositifs, y compris si leur montant est à 0€.</span
+        >
+      </label>
+    </div>
+  </div>
+  <!-- Labels and compared amounts of decompositions -->
+  <div>
+    {#each visibleDecompositions as { decomposition, depth, rows, trunk, visibleChildren }, index}
+      <!-- Decomposition label -->
+      <div class="flex h-7 items-center whitespace-nowrap">
+        {#if trunk}
+          <div
+            class="ml-2 mt-2 w-full overflow-x-hidden text-ellipsis border-gray-300 text-left text-base text-gray-500 hover:z-20 hover:overflow-x-visible"
+            class:border-t={index !== 0}
+          >
+            {#if displayMode.edit !== undefined}
+              <!-- Trunk decomposition node, in variable inputs mode => link -->
+              <a
+                class="cursor-pointer text-base hover:underline"
+                href={newSimulationUrl({
+                  ...displayMode,
+                  variableName: decomposition.name,
+                })}
+                data-sveltekit-noscroll
+                >{decomposition.short_label ?? decomposition.label}</a
+              >
+            {:else}
+              <!-- Trunk decomposition node with parameters, in parameters mode => link -->
+              <a
+                class="cursor-pointer text-base hover:underline"
+                href={newSimulationUrl({
+                  ...displayMode,
+                  mobileLaw: true,
+                  parametersVariableName: decomposition.name,
+                })}
+                data-sveltekit-noscroll
+                >{decomposition.short_label ?? decomposition.label}</a
+              >
+            {/if}
+          </div>
+        {:else}
+          {#each [...iterToDepth(depth)] as _level}
+            <div class="ml-2 h-full border-l border-le-gris-dispositif">
+              &nbsp;
+            </div>
+          {/each}
+          {#if visibleChildren === undefined}
+            <!-- Leaf node (except the first one, that belongs to trunk) -->
+            <div class="ml-4">
+              {#if decomposition.obsolete || decomposition.last_value_still_valid_on === undefined || decomposition.last_value_still_valid_on < (new Date().getFullYear() - 2).toString()}
+                <Tooltip
+                  allowFlip={false}
+                  arrowClass="bg-gray-100"
+                  widthClass="w-80"
+                  initialPlacement="bottom"
+                >
+                  <iconify-icon
+                    class="mr-1 shadow-none {decomposition.obsolete
+                      ? 'text-[#FF4133]'
+                      : 'text-[#FFAC33]'}"
+                    icon="material-symbols:warning-rounded"
+                    width="16"
+                    height="16"
+                  ></iconify-icon>
+                  {#snippet tooltip()}
+                    <div
+                      class="overflow-hidden rounded-lg border border-gray-200 bg-white shadow-2xl"
+                    >
+                      <div
+                        class="border-b border-gray-200 bg-gray-100 px-3 py-2"
+                      >
+                        <h3 class="font-semibold text-gray-900">
+                          ⚠️ Ce dispositif n'est peut-être pas à jour
+                        </h3>
+                      </div>
+                      <div class="px-3 py-2 text-sm font-light text-gray-500">
+                        Dernière relecture :
+                        {#if decomposition.last_value_still_valid_on === undefined}
+                          date indéterminée
+                        {:else}{dateFormatter(
+                            new Date(decomposition.last_value_still_valid_on),
+                          )}
+                        {/if}
+                        {#if decomposition.obsolete}
+                          ; Obsolète !{/if}
+                      </div>
+                    </div>
+                  {/snippet}
+                </Tooltip>
+              {/if}
+            </div>
+
+            {#if displayMode.edit !== undefined}
+              <!-- Leaf decomposition node in variable inputs mode => link -->
+              <a
+                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
+                href={newSimulationUrl({
+                  ...displayMode,
+                  variableName: decomposition.name,
+                })}
+                data-sveltekit-noscroll
+                >{decomposition.short_label ?? decomposition.label}</a
+              >
+            {:else}
+              <!-- Leaf decomposition node with parameters in parameters mode => link -->
+              <a
+                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
+                href={newSimulationUrl({
+                  ...displayMode,
+                  mobileLaw: true,
+                  parametersVariableName: decomposition.name,
+                })}
+                data-sveltekit-noscroll
+                >{decomposition.short_label ?? decomposition.label}</a
+              >
+            {/if}
+          {:else}
+            <!-- Non-trunk, non-leaf variablev-->
+            {#if decomposition.open}
+              <button class="p-0 text-black" onclick={() => zoomOut(index)}>
+                <iconify-icon
+                  class="align-[-0.2rem] text-lg"
+                  icon="ri-arrow-up-s-line"
+                ></iconify-icon>
+              </button>
+            {:else}
+              <button class="p-0 text-black" onclick={() => zoomIn(index)}>
+                <iconify-icon
+                  class="align-[-0.2rem] text-lg"
+                  icon="ri-arrow-right-s-line"
+                ></iconify-icon>
+              </button>
+            {/if}
+
+            {#if displayMode.edit !== undefined}
+              <!-- Non-lead decomposition node in variable inputs mode => no-link -->
+              <button
+                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base text-black hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-black hover:underline"
+                onclick={() => {
+                  if (decomposition.open) {
+                    zoomOut(index)
+                  } else {
+                    zoomIn(index)
+                  }
+                }}
+              >
+                {decomposition.short_label ?? decomposition.label}
+              </button>
+            {:else}
+              <!-- Leaf decomposition node with parameters in parameters mode => link -->
+              <a
+                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
+                href={newSimulationUrl({
+                  ...displayMode,
+                  parametersVariableName: decomposition.name,
+                })}
+                onclick={preventDefault(() => {
+                  if (decomposition.open) {
+                    zoomOut(index)
+                  } else {
+                    zoomIn(index)
+                  }
+                  goto(
+                    newSimulationUrl({
+                      ...displayMode,
+                      parametersVariableName: decomposition.name,
+                    }),
+                    { noScroll: true },
+                  )
+                })}
+                data-sveltekit-noscroll
+                >{decomposition.short_label ?? decomposition.label}</a
+              >
+            {/if}
+          {/if}
+        {/if}
+      </div>
+
+      {#each rows as { calculationName, deltaAtVectorIndexArray }}
+        <!-- Decomposition compared amounts -->
+        {#if !decomposition.open || trunk || index === 0}
+          <div class="relative flex items-center whitespace-nowrap">
+            {#if !decomposition.open && !trunk}
+              <div class="absolute">
+                {#each iterToDepth(depth)}
+                  <div class="ml-2 h-full border-l border-le-gris-dispositif">
+                    &nbsp;
+                  </div>
+                {/each}
+              </div>
+            {/if}
+            <div
+              class="justify-center {decomposition.open &&
+              trunk &&
+              visibleChildren.length > 1 &&
+              calculationName === firstCalculationName
+                ? ''
+                : ' border-none'} {calculationName === firstCalculationName
+                ? ''
+                : '-mt-1 mb-1'} flex w-full text-sm"
+            >
+              {#if decomposition.open || index === 0}
+                <!---Composant loader pour les valeurs intermédiaires-->
+                {#if showLoader && runningCalculationNames.length > 0}
+                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
+                      class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  {#if runningCalculationNames.includes("bill")}
+                    <span
+                      class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
+                    <span
+                      class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  <!--Valeurs du waterfall des montants intermédiaires -->
+                {:else if trunk || index === 0}
+                  {#if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
+                    {#if decomposition.open && trunk}
+                      <span class="mx-2 text-gray-500">=</span>
+                    {/if}
+                    <span
+                      class="text-sm {calculationName === firstCalculationName
+                        ? rows.find((row) => row.calculationName === 'bill') ===
+                          undefined
+                          ? rows.find(
+                              (row) => row.calculationName === 'amendment',
+                            ) === undefined
+                            ? 'text-gray-500'
+                            : 'text-gray-500 line-through-amendment'
+                          : 'text-gray-500 line-through-bill'
+                        : calculationName === 'bill'
+                          ? rows.find(
+                              (row) => row.calculationName === 'amendment',
+                            ) === undefined
+                            ? 'text-le-rouge-bill'
+                            : 'text-le-rouge-bill line-through-amendment'
+                          : 'bg-le-jaune'}"
+                      >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
+                    >
+                  {:else}
+                    <div class="flex w-full justify-center">
+                      <div class="mx-4 w-1/2">
+                        {#if decomposition.open && trunk}
+                          <span class="mx-2 text-gray-500">=</span>
+                        {/if}
+                        <span
+                          class="text-right text-sm {calculationName ===
+                          firstCalculationName
+                            ? rows.find(
+                                (row) => row.calculationName === 'bill',
+                              ) === undefined
+                              ? rows.find(
+                                  (row) => row.calculationName === 'amendment',
+                                ) === undefined
+                                ? 'text-gray-500'
+                                : 'text-gray-500 line-through-amendment'
+                              : 'text-gray-500 line-through-bill'
+                            : calculationName === 'bill'
+                              ? rows.find(
+                                  (row) => row.calculationName === 'amendment',
+                                ) === undefined
+                                ? 'text-le-rouge-bill'
+                                : 'text-le-rouge-bill line-through-amendment'
+                              : 'bg-le-jaune'}"
+                          >{deltaFormatter(
+                            deltaAtVectorIndexArray[0] ?? 0,
+                          )}</span
+                        >
+                      </div>
+                      <div class="mx-4 w-1/2">
+                        {#if decomposition.open && trunk}
+                          <span class="mx-2 text-gray-500">=</span>
+                        {/if}
+                        <span
+                          class="text-left text-sm {calculationName ===
+                          firstCalculationName
+                            ? rows.find(
+                                (row) => row.calculationName === 'bill',
+                              ) === undefined
+                              ? rows.find(
+                                  (row) => row.calculationName === 'amendment',
+                                ) === undefined
+                                ? 'text-gray-500'
+                                : 'text-gray-500 line-through-amendment'
+                              : 'text-gray-500 line-through-bill'
+                            : calculationName === 'bill'
+                              ? rows.find(
+                                  (row) => row.calculationName === 'amendment',
+                                ) === undefined
+                                ? 'text-le-rouge-bill'
+                                : 'text-le-rouge-bill line-through-amendment'
+                              : 'bg-le-jaune'}"
+                          >{deltaFormatter(
+                            deltaAtVectorIndexArray[1] ?? 0,
+                          )}</span
+                        >
+                      </div>
+                    </div>
+                  {/if}
+                {/if}
+                <!--Montant des dispositifs-->
+              {:else if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
+                <!---Composant loader pour la valeur suivante-->
+                {#if showLoader && runningCalculationNames.length > 0}
+                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
+                      class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  {#if runningCalculationNames.includes("bill")}
+                    <span
+                      class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
+                    <span
+                      class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  <!--Valeur-->
+                {:else}
+                  <span
+                    class="text-base font-bold {calculationName ===
+                    firstCalculationName
+                      ? rows.find((row) => row.calculationName === 'bill') ===
+                        undefined
+                        ? rows.find(
+                            (row) => row.calculationName === 'amendment',
+                          ) === undefined
+                          ? ''
+                          : 'line-through-amendment'
+                        : 'line-through-bill'
+                      : calculationName === 'bill'
+                        ? rows.find(
+                            (row) => row.calculationName === 'amendment',
+                          ) === undefined
+                          ? 'text-le-rouge-bill'
+                          : 'text-le-rouge-bill line-through-amendment'
+                        : 'bg-le-jaune'}"
+                    >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
+                  >
+                {/if}
+              {:else}
+                <!---Composant loader pour la valeur suivante-->
+                {#if showLoader && runningCalculationNames.length > 0}
+                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
+                      class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  {#if runningCalculationNames.includes("bill")}
+                    <span
+                      class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
+                    <span
+                      class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  <!--Valeur dispositifs-->
+                {:else}
+                  <div class="flex w-full justify-center">
+                    <div class="mx-4 w-1/2">
+                      <span
+                        class="text-base font-bold {calculationName ===
+                        firstCalculationName
+                          ? rows.find(
+                              (row) => row.calculationName === 'bill',
+                            ) === undefined
+                            ? rows.find(
+                                (row) => row.calculationName === 'amendment',
+                              ) === undefined
+                              ? ''
+                              : 'line-through-amendment'
+                            : 'line-through-bill'
+                          : calculationName === 'bill'
+                            ? rows.find(
+                                (row) => row.calculationName === 'amendment',
+                              ) === undefined
+                              ? 'text-le-rouge-bill'
+                              : 'text-le-rouge-bill line-through-amendment'
+                            : 'bg-le-jaune'}"
+                        >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
+                      >
+                    </div>
+                    <div class="mx-4 w-1/2">
+                      <span
+                        class="text-base font-bold {calculationName ===
+                        firstCalculationName
+                          ? rows.find(
+                              (row) => row.calculationName === 'bill',
+                            ) === undefined
+                            ? rows.find(
+                                (row) => row.calculationName === 'amendment',
+                              ) === undefined
+                              ? ''
+                              : 'line-through-amendment'
+                            : 'line-through-bill'
+                          : calculationName === 'bill'
+                            ? rows.find(
+                                (row) => row.calculationName === 'amendment',
+                              ) === undefined
+                              ? 'text-le-rouge-bill'
+                              : 'text-le-rouge-bill line-through-amendment'
+                            : 'bg-le-jaune'}"
+                        >{deltaFormatter(deltaAtVectorIndexArray[1] ?? 0)}</span
+                      >
+                    </div>
+                  </div>
+                {/if}
+              {/if}
+            </div>
+          </div>
+        {/if}
+      {/each}
+    {/each}
+  </div>
+{/if}
-- 
GitLab


From 309609725d1f0d8f3edf0f3ef62f6798c62a0742 Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Mon, 10 Mar 2025 10:38:27 +0100
Subject: [PATCH 02/13] =?UTF-8?q?Modifie=20la=20div=20g=C3=A9n=C3=A9rale?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../compare_mode/PaySlipCompareView.svelte    | 796 +++++++++---------
 1 file changed, 421 insertions(+), 375 deletions(-)

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
index 9243424b9..162b81f26 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
@@ -6,9 +6,10 @@
   import { goto } from "$app/navigation"
   import { page } from "$app/stores"
   import Tooltip from "$lib/components/ui_transverse_components/Tooltip.svelte"
-  import type {
-    EvaluationByName,
-    VisibleDecompositionForComparison,
+  import {
+    type EvaluationByName,
+    type VisibleDecompositionForComparison,
+    isChildOrDescendant,
   } from "$lib/decompositions"
   import { buildVisibleDecompositionsForComparison } from "$lib/decompositions"
   import type { DisplayMode } from "$lib/displays"
@@ -153,257 +154,258 @@
     </div>
   </div>
   <!-- Labels and compared amounts of decompositions -->
-  <div>
-    {#each visibleDecompositions as { decomposition, depth, rows, trunk, visibleChildren }, index}
-      <!-- Decomposition label -->
-      <div class="flex h-7 items-center whitespace-nowrap">
-        {#if trunk}
-          <div
-            class="ml-2 mt-2 w-full overflow-x-hidden text-ellipsis border-gray-300 text-left text-base text-gray-500 hover:z-20 hover:overflow-x-visible"
-            class:border-t={index !== 0}
-          >
-            {#if displayMode.edit !== undefined}
-              <!-- Trunk decomposition node, in variable inputs mode => link -->
-              <a
-                class="cursor-pointer text-base hover:underline"
-                href={newSimulationUrl({
-                  ...displayMode,
-                  variableName: decomposition.name,
-                })}
-                data-sveltekit-noscroll
-                >{decomposition.short_label ?? decomposition.label}</a
+  <!-- Feuille de paie-->
+  <div class="flex justify-between">
+    <div class="w-3/5 flex-auto">
+      {#each visibleDecompositions as { decomposition, depth, rows, trunk, visibleChildren }, index}
+        <!-- Ligne de la feuille de paie-->
+        <div
+          class="flex min-h-8 flex-col items-stretch justify-between border-t border-gray-200 px-4"
+          class:bg-gray-100={trunk && index !== 0}
+          class:border-gray-300={trunk && index !== 0}
+          class:fond={decomposition.name ===
+            displayMode.parametersVariableName ||
+            (displayMode.parametersVariableName &&
+              isChildOrDescendant(
+                shared.decompositionByName,
+                decomposition.name,
+                displayMode.parametersVariableName,
+              ))}
+          class:text-lg={decomposition.name ===
+            displayMode.parametersVariableName}
+          class:items-start={decomposition.name ===
+            displayMode.parametersVariableName}
+        >
+          <!-- "Nom du dispositif" -->
+          <div class="flex h-7 items-center whitespace-nowrap">
+            {#if trunk && index !== 0}
+              <div
+                class="ml-2 mt-2 w-full overflow-x-hidden text-ellipsis border-gray-300 text-left text-base text-gray-500 hover:z-20 hover:overflow-x-visible"
+                class:border-t={index !== 0}
               >
+                {#if displayMode.edit !== undefined}
+                  <!-- Trunk decomposition node, in variable inputs mode => link -->
+                  <a
+                    class="cursor-pointer text-base hover:underline"
+                    href={newSimulationUrl({
+                      ...displayMode,
+                      variableName: decomposition.name,
+                    })}
+                    data-sveltekit-noscroll
+                    >{decomposition.short_label ?? decomposition.label}</a
+                  >
+                {:else}
+                  <!-- Trunk decomposition node with parameters, in parameters mode => link -->
+                  <a
+                    class="cursor-pointer text-base hover:underline"
+                    href={newSimulationUrl({
+                      ...displayMode,
+                      mobileLaw: true,
+                      parametersVariableName: decomposition.name,
+                    })}
+                    data-sveltekit-noscroll
+                    >{decomposition.short_label ?? decomposition.label}</a
+                  >
+                {/if}
+              </div>
             {:else}
-              <!-- Trunk decomposition node with parameters, in parameters mode => link -->
-              <a
-                class="cursor-pointer text-base hover:underline"
-                href={newSimulationUrl({
-                  ...displayMode,
-                  mobileLaw: true,
-                  parametersVariableName: decomposition.name,
-                })}
-                data-sveltekit-noscroll
-                >{decomposition.short_label ?? decomposition.label}</a
-              >
-            {/if}
-          </div>
-        {:else}
-          {#each [...iterToDepth(depth)] as _level}
-            <div class="ml-2 h-full border-l border-le-gris-dispositif">
-              &nbsp;
-            </div>
-          {/each}
-          {#if visibleChildren === undefined}
-            <!-- Leaf node (except the first one, that belongs to trunk) -->
-            <div class="ml-4">
-              {#if decomposition.obsolete || decomposition.last_value_still_valid_on === undefined || decomposition.last_value_still_valid_on < (new Date().getFullYear() - 2).toString()}
-                <Tooltip
-                  allowFlip={false}
-                  arrowClass="bg-gray-100"
-                  widthClass="w-80"
-                  initialPlacement="bottom"
-                >
-                  <iconify-icon
-                    class="mr-1 shadow-none {decomposition.obsolete
-                      ? 'text-[#FF4133]'
-                      : 'text-[#FFAC33]'}"
-                    icon="material-symbols:warning-rounded"
-                    width="16"
-                    height="16"
-                  ></iconify-icon>
-                  {#snippet tooltip()}
-                    <div
-                      class="overflow-hidden rounded-lg border border-gray-200 bg-white shadow-2xl"
+              {#each [...iterToDepth(depth)] as _level}
+                <div class="ml-2 h-full border-l border-le-gris-dispositif">
+                  &nbsp;
+                </div>
+              {/each}
+              {#if visibleChildren === undefined}
+                <!-- Leaf node (except the first one, that belongs to trunk) -->
+                <div class="ml-4">
+                  {#if decomposition.obsolete || decomposition.last_value_still_valid_on === undefined || decomposition.last_value_still_valid_on < (new Date().getFullYear() - 2).toString()}
+                    <Tooltip
+                      allowFlip={false}
+                      arrowClass="bg-gray-100"
+                      widthClass="w-80"
+                      initialPlacement="bottom"
                     >
-                      <div
-                        class="border-b border-gray-200 bg-gray-100 px-3 py-2"
-                      >
-                        <h3 class="font-semibold text-gray-900">
-                          ⚠️ Ce dispositif n'est peut-être pas à jour
-                        </h3>
-                      </div>
-                      <div class="px-3 py-2 text-sm font-light text-gray-500">
-                        Dernière relecture :
-                        {#if decomposition.last_value_still_valid_on === undefined}
-                          date indéterminée
-                        {:else}{dateFormatter(
-                            new Date(decomposition.last_value_still_valid_on),
-                          )}
-                        {/if}
-                        {#if decomposition.obsolete}
-                          ; Obsolète !{/if}
-                      </div>
-                    </div>
-                  {/snippet}
-                </Tooltip>
-              {/if}
-            </div>
+                      <iconify-icon
+                        class="mr-1 shadow-none {decomposition.obsolete
+                          ? 'text-[#FF4133]'
+                          : 'text-[#FFAC33]'}"
+                        icon="material-symbols:warning-rounded"
+                        width="16"
+                        height="16"
+                      ></iconify-icon>
+                      {#snippet tooltip()}
+                        <div
+                          class="overflow-hidden rounded-lg border border-gray-200 bg-white shadow-2xl"
+                        >
+                          <div
+                            class="border-b border-gray-200 bg-gray-100 px-3 py-2"
+                          >
+                            <h3 class="font-semibold text-gray-900">
+                              ⚠️ Ce dispositif n'est peut-être pas à jour
+                            </h3>
+                          </div>
+                          <div
+                            class="px-3 py-2 text-sm font-light text-gray-500"
+                          >
+                            Dernière relecture :
+                            {#if decomposition.last_value_still_valid_on === undefined}
+                              date indéterminée
+                            {:else}{dateFormatter(
+                                new Date(
+                                  decomposition.last_value_still_valid_on,
+                                ),
+                              )}
+                            {/if}
+                            {#if decomposition.obsolete}
+                              ; Obsolète !{/if}
+                          </div>
+                        </div>
+                      {/snippet}
+                    </Tooltip>
+                  {/if}
+                </div>
 
-            {#if displayMode.edit !== undefined}
-              <!-- Leaf decomposition node in variable inputs mode => link -->
-              <a
-                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
-                href={newSimulationUrl({
-                  ...displayMode,
-                  variableName: decomposition.name,
-                })}
-                data-sveltekit-noscroll
-                >{decomposition.short_label ?? decomposition.label}</a
-              >
-            {:else}
-              <!-- Leaf decomposition node with parameters in parameters mode => link -->
-              <a
-                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
-                href={newSimulationUrl({
-                  ...displayMode,
-                  mobileLaw: true,
-                  parametersVariableName: decomposition.name,
-                })}
-                data-sveltekit-noscroll
-                >{decomposition.short_label ?? decomposition.label}</a
-              >
-            {/if}
-          {:else}
-            <!-- Non-trunk, non-leaf variablev-->
-            {#if decomposition.open}
-              <button class="p-0 text-black" onclick={() => zoomOut(index)}>
-                <iconify-icon
-                  class="align-[-0.2rem] text-lg"
-                  icon="ri-arrow-up-s-line"
-                ></iconify-icon>
-              </button>
-            {:else}
-              <button class="p-0 text-black" onclick={() => zoomIn(index)}>
-                <iconify-icon
-                  class="align-[-0.2rem] text-lg"
-                  icon="ri-arrow-right-s-line"
-                ></iconify-icon>
-              </button>
-            {/if}
+                {#if displayMode.edit !== undefined}
+                  <!-- Leaf decomposition node in variable inputs mode => link -->
+                  <a
+                    class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
+                    href={newSimulationUrl({
+                      ...displayMode,
+                      variableName: decomposition.name,
+                    })}
+                    data-sveltekit-noscroll
+                    >{decomposition.short_label ?? decomposition.label}</a
+                  >
+                {:else}
+                  <!-- Leaf decomposition node with parameters in parameters mode => link -->
+                  <a
+                    class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
+                    href={newSimulationUrl({
+                      ...displayMode,
+                      mobileLaw: true,
+                      parametersVariableName: decomposition.name,
+                    })}
+                    data-sveltekit-noscroll
+                    >{decomposition.short_label ?? decomposition.label}</a
+                  >
+                {/if}
+              {:else}
+                <!-- Non-trunk, non-leaf variablev-->
+                {#if decomposition.open}
+                  <button class="p-0 text-black" onclick={() => zoomOut(index)}>
+                    <iconify-icon
+                      class="align-[-0.2rem] text-lg"
+                      icon="ri-arrow-up-s-line"
+                    ></iconify-icon>
+                  </button>
+                {:else}
+                  <button class="p-0 text-black" onclick={() => zoomIn(index)}>
+                    <iconify-icon
+                      class="align-[-0.2rem] text-lg"
+                      icon="ri-arrow-right-s-line"
+                    ></iconify-icon>
+                  </button>
+                {/if}
 
-            {#if displayMode.edit !== undefined}
-              <!-- Non-lead decomposition node in variable inputs mode => no-link -->
-              <button
-                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base text-black hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-black hover:underline"
-                onclick={() => {
-                  if (decomposition.open) {
-                    zoomOut(index)
-                  } else {
-                    zoomIn(index)
-                  }
-                }}
-              >
-                {decomposition.short_label ?? decomposition.label}
-              </button>
-            {:else}
-              <!-- Leaf decomposition node with parameters in parameters mode => link -->
-              <a
-                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
-                href={newSimulationUrl({
-                  ...displayMode,
-                  parametersVariableName: decomposition.name,
-                })}
-                onclick={preventDefault(() => {
-                  if (decomposition.open) {
-                    zoomOut(index)
-                  } else {
-                    zoomIn(index)
-                  }
-                  goto(
-                    newSimulationUrl({
+                {#if displayMode.edit !== undefined}
+                  <!-- Non-lead decomposition node in variable inputs mode => no-link -->
+                  <button
+                    class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base text-black hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-black hover:underline"
+                    onclick={() => {
+                      if (decomposition.open) {
+                        zoomOut(index)
+                      } else {
+                        zoomIn(index)
+                      }
+                    }}
+                  >
+                    {decomposition.short_label ?? decomposition.label}
+                  </button>
+                {:else}
+                  <!-- Leaf decomposition node with parameters in parameters mode => link -->
+                  <a
+                    class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
+                    href={newSimulationUrl({
                       ...displayMode,
                       parametersVariableName: decomposition.name,
-                    }),
-                    { noScroll: true },
-                  )
-                })}
-                data-sveltekit-noscroll
-                >{decomposition.short_label ?? decomposition.label}</a
-              >
+                    })}
+                    onclick={preventDefault(() => {
+                      if (decomposition.open) {
+                        zoomOut(index)
+                      } else {
+                        zoomIn(index)
+                      }
+                      goto(
+                        newSimulationUrl({
+                          ...displayMode,
+                          parametersVariableName: decomposition.name,
+                        }),
+                        { noScroll: true },
+                      )
+                    })}
+                    data-sveltekit-noscroll
+                    >{decomposition.short_label ?? decomposition.label}</a
+                  >
+                {/if}
+              {/if}
             {/if}
-          {/if}
-        {/if}
-      </div>
+          </div>
 
-      {#each rows as { calculationName, deltaAtVectorIndexArray }}
-        <!-- Decomposition compared amounts -->
-        {#if !decomposition.open || trunk || index === 0}
-          <div class="relative flex items-center whitespace-nowrap">
-            {#if !decomposition.open && !trunk}
-              <div class="absolute">
-                {#each iterToDepth(depth)}
-                  <div class="ml-2 h-full border-l border-le-gris-dispositif">
-                    &nbsp;
+          {#each rows as { calculationName, deltaAtVectorIndexArray }}
+            <!-- Decomposition compared amounts -->
+            {#if !decomposition.open || trunk || index === 0}
+              <div class="relative flex items-center whitespace-nowrap">
+                {#if !decomposition.open && !trunk}
+                  <div class="absolute">
+                    {#each iterToDepth(depth)}
+                      <div
+                        class="ml-2 h-full border-l border-le-gris-dispositif"
+                      >
+                        &nbsp;
+                      </div>
+                    {/each}
                   </div>
-                {/each}
-              </div>
-            {/if}
-            <div
-              class="justify-center {decomposition.open &&
-              trunk &&
-              visibleChildren.length > 1 &&
-              calculationName === firstCalculationName
-                ? ''
-                : ' border-none'} {calculationName === firstCalculationName
-                ? ''
-                : '-mt-1 mb-1'} flex w-full text-sm"
-            >
-              {#if decomposition.open || index === 0}
-                <!---Composant loader pour les valeurs intermédiaires-->
-                {#if showLoader && runningCalculationNames.length > 0}
-                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
-                      class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("bill")}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  <!--Valeurs du waterfall des montants intermédiaires -->
-                {:else if trunk || index === 0}
-                  {#if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
-                    {#if decomposition.open && trunk}
-                      <span class="mx-2 text-gray-500">=</span>
-                    {/if}
-                    <span
-                      class="text-sm {calculationName === firstCalculationName
-                        ? rows.find((row) => row.calculationName === 'bill') ===
-                          undefined
-                          ? rows.find(
-                              (row) => row.calculationName === 'amendment',
-                            ) === undefined
-                            ? 'text-gray-500'
-                            : 'text-gray-500 line-through-amendment'
-                          : 'text-gray-500 line-through-bill'
-                        : calculationName === 'bill'
-                          ? rows.find(
-                              (row) => row.calculationName === 'amendment',
-                            ) === undefined
-                            ? 'text-le-rouge-bill'
-                            : 'text-le-rouge-bill line-through-amendment'
-                          : 'bg-le-jaune'}"
-                      >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
-                    >
-                  {:else}
-                    <div class="flex w-full justify-center">
-                      <div class="mx-4 w-1/2">
+                {/if}
+                <div
+                  class="justify-center {decomposition.open &&
+                  trunk &&
+                  visibleChildren.length > 1 &&
+                  calculationName === firstCalculationName
+                    ? ''
+                    : ' border-none'} {calculationName === firstCalculationName
+                    ? ''
+                    : '-mt-1 mb-1'} flex w-full text-sm"
+                >
+                  {#if decomposition.open || index === 0}
+                    <!---Composant loader pour les valeurs intermédiaires-->
+                    {#if showLoader && runningCalculationNames.length > 0}
+                      {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
+                          class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
+                        >
+                          <span class="text-white blur">value €</span>
+                        </span>
+                      {/if}
+                      {#if runningCalculationNames.includes("bill")}
+                        <span
+                          class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
+                        >
+                          <span class="text-white blur">value €</span>
+                        </span>
+                      {/if}
+                      {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
+                        <span
+                          class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
+                        >
+                          <span class="text-white blur">value €</span>
+                        </span>
+                      {/if}
+                      <!--Valeurs du waterfall des montants intermédiaires -->
+                    {:else if trunk || index === 0}
+                      {#if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
                         {#if decomposition.open && trunk}
                           <span class="mx-2 text-gray-500">=</span>
                         {/if}
                         <span
-                          class="text-right text-sm {calculationName ===
+                          class="text-sm {calculationName ===
                           firstCalculationName
                             ? rows.find(
                                 (row) => row.calculationName === 'bill',
@@ -425,112 +427,97 @@
                             deltaAtVectorIndexArray[0] ?? 0,
                           )}</span
                         >
-                      </div>
-                      <div class="mx-4 w-1/2">
-                        {#if decomposition.open && trunk}
-                          <span class="mx-2 text-gray-500">=</span>
-                        {/if}
+                      {:else}
+                        <div class="flex w-full justify-center">
+                          <div class="mx-4 w-1/2">
+                            {#if decomposition.open && trunk}
+                              <span class="mx-2 text-gray-500">=</span>
+                            {/if}
+                            <span
+                              class="text-right text-sm {calculationName ===
+                              firstCalculationName
+                                ? rows.find(
+                                    (row) => row.calculationName === 'bill',
+                                  ) === undefined
+                                  ? rows.find(
+                                      (row) =>
+                                        row.calculationName === 'amendment',
+                                    ) === undefined
+                                    ? 'text-gray-500'
+                                    : 'text-gray-500 line-through-amendment'
+                                  : 'text-gray-500 line-through-bill'
+                                : calculationName === 'bill'
+                                  ? rows.find(
+                                      (row) =>
+                                        row.calculationName === 'amendment',
+                                    ) === undefined
+                                    ? 'text-le-rouge-bill'
+                                    : 'text-le-rouge-bill line-through-amendment'
+                                  : 'bg-le-jaune'}"
+                              >{deltaFormatter(
+                                deltaAtVectorIndexArray[0] ?? 0,
+                              )}</span
+                            >
+                          </div>
+                          <div class="mx-4 w-1/2">
+                            {#if decomposition.open && trunk}
+                              <span class="mx-2 text-gray-500">=</span>
+                            {/if}
+                            <span
+                              class="text-left text-sm {calculationName ===
+                              firstCalculationName
+                                ? rows.find(
+                                    (row) => row.calculationName === 'bill',
+                                  ) === undefined
+                                  ? rows.find(
+                                      (row) =>
+                                        row.calculationName === 'amendment',
+                                    ) === undefined
+                                    ? 'text-gray-500'
+                                    : 'text-gray-500 line-through-amendment'
+                                  : 'text-gray-500 line-through-bill'
+                                : calculationName === 'bill'
+                                  ? rows.find(
+                                      (row) =>
+                                        row.calculationName === 'amendment',
+                                    ) === undefined
+                                    ? 'text-le-rouge-bill'
+                                    : 'text-le-rouge-bill line-through-amendment'
+                                  : 'bg-le-jaune'}"
+                              >{deltaFormatter(
+                                deltaAtVectorIndexArray[1] ?? 0,
+                              )}</span
+                            >
+                          </div>
+                        </div>
+                      {/if}
+                    {/if}
+                    <!--Montant des dispositifs-->
+                  {:else if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
+                    <!---Composant loader pour la valeur suivante-->
+                    {#if showLoader && runningCalculationNames.length > 0}
+                      {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
+                          class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
+                        >
+                          <span class="text-white blur">value €</span>
+                        </span>
+                      {/if}
+                      {#if runningCalculationNames.includes("bill")}
                         <span
-                          class="text-left text-sm {calculationName ===
-                          firstCalculationName
-                            ? rows.find(
-                                (row) => row.calculationName === 'bill',
-                              ) === undefined
-                              ? rows.find(
-                                  (row) => row.calculationName === 'amendment',
-                                ) === undefined
-                                ? 'text-gray-500'
-                                : 'text-gray-500 line-through-amendment'
-                              : 'text-gray-500 line-through-bill'
-                            : calculationName === 'bill'
-                              ? rows.find(
-                                  (row) => row.calculationName === 'amendment',
-                                ) === undefined
-                                ? 'text-le-rouge-bill'
-                                : 'text-le-rouge-bill line-through-amendment'
-                              : 'bg-le-jaune'}"
-                          >{deltaFormatter(
-                            deltaAtVectorIndexArray[1] ?? 0,
-                          )}</span
+                          class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
                         >
-                      </div>
-                    </div>
-                  {/if}
-                {/if}
-                <!--Montant des dispositifs-->
-              {:else if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
-                <!---Composant loader pour la valeur suivante-->
-                {#if showLoader && runningCalculationNames.length > 0}
-                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
-                      class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("bill")}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  <!--Valeur-->
-                {:else}
-                  <span
-                    class="text-base font-bold {calculationName ===
-                    firstCalculationName
-                      ? rows.find((row) => row.calculationName === 'bill') ===
-                        undefined
-                        ? rows.find(
-                            (row) => row.calculationName === 'amendment',
-                          ) === undefined
-                          ? ''
-                          : 'line-through-amendment'
-                        : 'line-through-bill'
-                      : calculationName === 'bill'
-                        ? rows.find(
-                            (row) => row.calculationName === 'amendment',
-                          ) === undefined
-                          ? 'text-le-rouge-bill'
-                          : 'text-le-rouge-bill line-through-amendment'
-                        : 'bg-le-jaune'}"
-                    >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
-                  >
-                {/if}
-              {:else}
-                <!---Composant loader pour la valeur suivante-->
-                {#if showLoader && runningCalculationNames.length > 0}
-                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
-                      class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("bill")}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  <!--Valeur dispositifs-->
-                {:else}
-                  <div class="flex w-full justify-center">
-                    <div class="mx-4 w-1/2">
+                          <span class="text-white blur">value €</span>
+                        </span>
+                      {/if}
+                      {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
+                        <span
+                          class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
+                        >
+                          <span class="text-white blur">value €</span>
+                        </span>
+                      {/if}
+                      <!--Valeur-->
+                    {:else}
                       <span
                         class="text-base font-bold {calculationName ===
                         firstCalculationName
@@ -552,37 +539,96 @@
                             : 'bg-le-jaune'}"
                         >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
                       >
-                    </div>
-                    <div class="mx-4 w-1/2">
-                      <span
-                        class="text-base font-bold {calculationName ===
-                        firstCalculationName
-                          ? rows.find(
-                              (row) => row.calculationName === 'bill',
-                            ) === undefined
-                            ? rows.find(
-                                (row) => row.calculationName === 'amendment',
-                              ) === undefined
-                              ? ''
-                              : 'line-through-amendment'
-                            : 'line-through-bill'
-                          : calculationName === 'bill'
-                            ? rows.find(
-                                (row) => row.calculationName === 'amendment',
-                              ) === undefined
-                              ? 'text-le-rouge-bill'
-                              : 'text-le-rouge-bill line-through-amendment'
-                            : 'bg-le-jaune'}"
-                        >{deltaFormatter(deltaAtVectorIndexArray[1] ?? 0)}</span
-                      >
-                    </div>
-                  </div>
-                {/if}
-              {/if}
-            </div>
-          </div>
-        {/if}
+                    {/if}
+                  {:else}
+                    <!---Composant loader pour la valeur suivante-->
+                    {#if showLoader && runningCalculationNames.length > 0}
+                      {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
+                          class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
+                        >
+                          <span class="text-white blur">value €</span>
+                        </span>
+                      {/if}
+                      {#if runningCalculationNames.includes("bill")}
+                        <span
+                          class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
+                        >
+                          <span class="text-white blur">value €</span>
+                        </span>
+                      {/if}
+                      {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
+                        <span
+                          class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
+                        >
+                          <span class="text-white blur">value €</span>
+                        </span>
+                      {/if}
+                      <!--Valeur dispositifs-->
+                    {:else}
+                      <div class="flex w-full justify-center">
+                        <div class="mx-4 w-1/2">
+                          <span
+                            class="text-base font-bold {calculationName ===
+                            firstCalculationName
+                              ? rows.find(
+                                  (row) => row.calculationName === 'bill',
+                                ) === undefined
+                                ? rows.find(
+                                    (row) =>
+                                      row.calculationName === 'amendment',
+                                  ) === undefined
+                                  ? ''
+                                  : 'line-through-amendment'
+                                : 'line-through-bill'
+                              : calculationName === 'bill'
+                                ? rows.find(
+                                    (row) =>
+                                      row.calculationName === 'amendment',
+                                  ) === undefined
+                                  ? 'text-le-rouge-bill'
+                                  : 'text-le-rouge-bill line-through-amendment'
+                                : 'bg-le-jaune'}"
+                            >{deltaFormatter(
+                              deltaAtVectorIndexArray[0] ?? 0,
+                            )}</span
+                          >
+                        </div>
+                        <div class="mx-4 w-1/2">
+                          <span
+                            class="text-base font-bold {calculationName ===
+                            firstCalculationName
+                              ? rows.find(
+                                  (row) => row.calculationName === 'bill',
+                                ) === undefined
+                                ? rows.find(
+                                    (row) =>
+                                      row.calculationName === 'amendment',
+                                  ) === undefined
+                                  ? ''
+                                  : 'line-through-amendment'
+                                : 'line-through-bill'
+                              : calculationName === 'bill'
+                                ? rows.find(
+                                    (row) =>
+                                      row.calculationName === 'amendment',
+                                  ) === undefined
+                                  ? 'text-le-rouge-bill'
+                                  : 'text-le-rouge-bill line-through-amendment'
+                                : 'bg-le-jaune'}"
+                            >{deltaFormatter(
+                              deltaAtVectorIndexArray[1] ?? 0,
+                            )}</span
+                          >
+                        </div>
+                      </div>
+                    {/if}
+                  {/if}
+                </div>
+              </div>
+            {/if}
+          {/each}
+        </div>
       {/each}
-    {/each}
+    </div>
   </div>
 {/if}
-- 
GitLab


From 0ea9f794d322a1ab1a989bbc75df02d15e76ba8c Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Mon, 10 Mar 2025 13:49:21 +0100
Subject: [PATCH 03/13] =?UTF-8?q?Applique=20la=20structure=20de=20la=20nou?=
 =?UTF-8?q?velle=20PaySlip=20au=20mode=20compar=C3=A9,=20en=20gardant=20le?=
 =?UTF-8?q?=20principe=20de=20l'affichage=20des=20montants?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../compare_mode/PaySlipCompareView.svelte    | 818 ++++++++----------
 1 file changed, 384 insertions(+), 434 deletions(-)

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
index 162b81f26..fa7b9c557 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
@@ -95,6 +95,21 @@
     }
   }
 
+  function getCorrectSimulationUrl(variableName: string) {
+    const newDisplayMode =
+      displayMode.edit !== undefined
+        ? {
+            ...displayMode,
+            variableName: variableName,
+          }
+        : {
+            ...displayMode,
+            mobileLaw: true,
+            parametersVariableName: variableName,
+          }
+    return newSimulationUrl(newDisplayMode)
+  }
+
   function zoomIn(index: number) {
     let visibleDecomposition = visibleDecompositions[index]
     if (
@@ -134,7 +149,7 @@
 
 {#if visibleDecompositions.length > 0}
   <div>
-    <div class="h-5 bg-gradient-to-b from-gray-100 to-transparent" />
+    <div class="h-5 bg-gradient-to-b from-gray-100 to-transparent"></div>
     <!--Montants-nuls-->
     <div class="mx-1 mb-3 flex justify-start">
       <label class="inline-flex cursor-pointer items-center">
@@ -153,373 +168,252 @@
       </label>
     </div>
   </div>
-  <!-- Labels and compared amounts of decompositions -->
   <!-- Feuille de paie-->
-  <div class="flex justify-between">
-    <div class="w-3/5 flex-auto">
-      {#each visibleDecompositions as { decomposition, depth, rows, trunk, visibleChildren }, index}
-        <!-- Ligne de la feuille de paie-->
-        <div
-          class="flex min-h-8 flex-col items-stretch justify-between border-t border-gray-200 px-4"
-          class:bg-gray-100={trunk && index !== 0}
-          class:border-gray-300={trunk && index !== 0}
-          class:fond={decomposition.name ===
-            displayMode.parametersVariableName ||
-            (displayMode.parametersVariableName &&
-              isChildOrDescendant(
-                shared.decompositionByName,
-                decomposition.name,
-                displayMode.parametersVariableName,
-              ))}
-          class:text-lg={decomposition.name ===
-            displayMode.parametersVariableName}
-          class:items-start={decomposition.name ===
-            displayMode.parametersVariableName}
-        >
+
+  <div class="flex-auto">
+    {#each visibleDecompositions as { decomposition, depth, rows, trunk, visibleChildren }, index}
+      <!-- Ligne de la feuille de paie-->
+      <div
+        class="flex min-h-8 border-t border-gray-200 px-4"
+        class:border-gray-300={trunk && index !== 0}
+        class:fond={decomposition.name === displayMode.parametersVariableName ||
+          (displayMode.parametersVariableName &&
+            isChildOrDescendant(
+              shared.decompositionByName,
+              decomposition.name,
+              displayMode.parametersVariableName,
+            ))}
+        class:text-lg={decomposition.name ===
+          displayMode.parametersVariableName}
+      >
+        {#each iterToDepth(depth)}
+          <div
+            class={`min-h-full border-l-2 pr-3 ${
+              decomposition.name !== displayMode.parametersVariableName &&
+              !(
+                displayMode.parametersVariableName &&
+                isChildOrDescendant(
+                  shared.decompositionByName,
+                  decomposition.name,
+                  displayMode.parametersVariableName,
+                )
+              )
+                ? "border-gray-400"
+                : "border-black"
+            }`}
+          >
+            &nbsp;
+          </div>
+        {/each}
+        <div class="flex w-full flex-col">
           <!-- "Nom du dispositif" -->
-          <div class="flex h-7 items-center whitespace-nowrap">
-            {#if trunk && index !== 0}
-              <div
-                class="ml-2 mt-2 w-full overflow-x-hidden text-ellipsis border-gray-300 text-left text-base text-gray-500 hover:z-20 hover:overflow-x-visible"
-                class:border-t={index !== 0}
-              >
-                {#if displayMode.edit !== undefined}
-                  <!-- Trunk decomposition node, in variable inputs mode => link -->
-                  <a
-                    class="cursor-pointer text-base hover:underline"
-                    href={newSimulationUrl({
-                      ...displayMode,
-                      variableName: decomposition.name,
-                    })}
-                    data-sveltekit-noscroll
-                    >{decomposition.short_label ?? decomposition.label}</a
-                  >
-                {:else}
-                  <!-- Trunk decomposition node with parameters, in parameters mode => link -->
-                  <a
-                    class="cursor-pointer text-base hover:underline"
-                    href={newSimulationUrl({
-                      ...displayMode,
-                      mobileLaw: true,
-                      parametersVariableName: decomposition.name,
-                    })}
-                    data-sveltekit-noscroll
-                    >{decomposition.short_label ?? decomposition.label}</a
-                  >
-                {/if}
-              </div>
-            {:else}
-              {#each [...iterToDepth(depth)] as _level}
-                <div class="ml-2 h-full border-l border-le-gris-dispositif">
-                  &nbsp;
-                </div>
-              {/each}
-              {#if visibleChildren === undefined}
-                <!-- Leaf node (except the first one, that belongs to trunk) -->
-                <div class="ml-4">
-                  {#if decomposition.obsolete || decomposition.last_value_still_valid_on === undefined || decomposition.last_value_still_valid_on < (new Date().getFullYear() - 2).toString()}
-                    <Tooltip
-                      allowFlip={false}
-                      arrowClass="bg-gray-100"
-                      widthClass="w-80"
-                      initialPlacement="bottom"
+          <div class="flex-1 overflow-x-hidden">
+            {#each rows as { calculationName }}
+              {#if calculationName === firstCalculationName}
+                <div class="flex h-full w-full items-center">
+                  {#if trunk && index !== 0}
+                    <!--Les class permettent que le nom de la variable soit caché avec "..." et rendu visible au survol. Le comportement est différent si la variable est sélectionnée-->
+                    <div
+                      class="flex w-full items-center"
+                      class:whitespace-nowrap={decomposition.name !==
+                        displayMode.parametersVariableName}
                     >
-                      <iconify-icon
-                        class="mr-1 shadow-none {decomposition.obsolete
-                          ? 'text-[#FF4133]'
-                          : 'text-[#FFAC33]'}"
-                        icon="material-symbols:warning-rounded"
-                        width="16"
-                        height="16"
-                      ></iconify-icon>
-                      {#snippet tooltip()}
-                        <div
-                          class="overflow-hidden rounded-lg border border-gray-200 bg-white shadow-2xl"
+                      <!-- Nom de la variable tronc, cliquable -->
+                      <a
+                        class="cursor-pointer overflow-x-hidden text-ellipsis text-gray-500 hover:z-20 hover:overflow-x-visible hover:bg-white hover:bg-opacity-90 hover:pr-1 hover:text-le-gris-dispositif-dark hover:underline"
+                        class:font-bold={decomposition.name ===
+                          displayMode.parametersVariableName}
+                        class:hover:absolute={decomposition.name !==
+                          displayMode.parametersVariableName}
+                        href={getCorrectSimulationUrl(decomposition.name)}
+                        data-sveltekit-noscroll
+                        >{decomposition.short_label ?? decomposition.label}</a
+                      >
+                    </div>
+                  {:else if visibleChildren === undefined}
+                    <!--Si c'est une variable Non-trunk, leaf-variable : La variable n'a pas de variables enfants et elle n'est pas une variable tronc -->
+
+                    <div
+                      class="flex h-full w-full items-center"
+                      class:whitespace-nowrap={decomposition.name !==
+                        displayMode.parametersVariableName}
+                    >
+                      <!--Si la variable est obsolète, ou que sa date de relecture est inconnue ou trop ancienne, un picto attention est affiché -->
+                      {#if decomposition.obsolete || decomposition.last_value_still_valid_on === undefined || decomposition.last_value_still_valid_on < (new Date().getFullYear() - 2).toString()}
+                        <Tooltip
+                          allowFlip={false}
+                          arrowClass="bg-gray-100"
+                          widthClass="w-80"
+                          initialPlacement="bottom"
                         >
-                          <div
-                            class="border-b border-gray-200 bg-gray-100 px-3 py-2"
-                          >
-                            <h3 class="font-semibold text-gray-900">
-                              ⚠️ Ce dispositif n'est peut-être pas à jour
-                            </h3>
-                          </div>
-                          <div
-                            class="px-3 py-2 text-sm font-light text-gray-500"
-                          >
-                            Dernière relecture :
-                            {#if decomposition.last_value_still_valid_on === undefined}
-                              date indéterminée
-                            {:else}{dateFormatter(
-                                new Date(
-                                  decomposition.last_value_still_valid_on,
-                                ),
-                              )}
-                            {/if}
-                            {#if decomposition.obsolete}
-                              ; Obsolète !{/if}
-                          </div>
-                        </div>
-                      {/snippet}
-                    </Tooltip>
+                          <iconify-icon
+                            class="mr-0.5 shadow-none {decomposition.obsolete
+                              ? 'text-[#FF4133]'
+                              : 'text-[#FFAC33]'}"
+                            icon="material-symbols:warning-rounded"
+                            width="16"
+                            height="16"
+                          ></iconify-icon>
+                          {#snippet tooltip()}
+                            <div
+                              class="overflow-hidden rounded-lg border border-gray-200 bg-white shadow-2xl"
+                            >
+                              <div
+                                class="border-b border-gray-200 bg-gray-100 px-3 py-2"
+                              >
+                                <h3 class="font-semibold text-gray-900">
+                                  ⚠️ Ce dispositif n'est peut-être pas à jour
+                                </h3>
+                              </div>
+                              <div
+                                class="px-3 py-2 text-sm font-light text-gray-500"
+                              >
+                                Dernière relecture :
+                                {#if decomposition.last_value_still_valid_on === undefined}
+                                  date indéterminée
+                                {:else}{dateFormatter(
+                                    new Date(
+                                      decomposition.last_value_still_valid_on,
+                                    ),
+                                  )}
+                                {/if}
+                                {#if decomposition.obsolete}
+                                  ; Obsolète !{/if}
+                              </div>
+                            </div>
+                          {/snippet}
+                        </Tooltip>
+                      {/if}
+                      <!-- Nom de la variable non-trunk, leaf, cliquable -->
+                      <a
+                        class="cursor-pointer overflow-x-hidden text-ellipsis font-serif hover:z-20 hover:overflow-x-visible hover:bg-white hover:bg-opacity-90 hover:pr-1 hover:text-le-gris-dispositif-dark hover:underline"
+                        class:font-bold={decomposition.name ===
+                          displayMode.parametersVariableName}
+                        class:hover:text-wrap={decomposition.name !==
+                          displayMode.parametersVariableName}
+                        href={getCorrectSimulationUrl(decomposition.name)}
+                        data-sveltekit-noscroll
+                        >{decomposition.short_label ?? decomposition.label}</a
+                      >
+                    </div>
+                  {:else}
+                    <!-- Si c'est une variable Non-trunk, Non-leaf : La variable a des variables enfants et n'est pas une variable tronc | une flèche à droite permet d'ouvrir les variables enfants-->
+
+                    <div
+                      class="flex h-full w-full items-center justify-start"
+                      class:whitespace-nowrap={decomposition.name !==
+                        displayMode.parametersVariableName}
+                    >
+                      <button
+                        class="cursor-pointer overflow-x-hidden text-ellipsis text-left font-serif hover:z-20 hover:overflow-x-visible hover:bg-white hover:bg-opacity-90 hover:text-le-gris-dispositif-dark hover:underline"
+                        class:hover:text-wrap={decomposition.name !==
+                          displayMode.parametersVariableName}
+                        class:font-bold={decomposition.name ===
+                          displayMode.parametersVariableName}
+                        onclick={() => {
+                          // Non-leaf decomposition node in variable inputs mode => no-link
+                          if (decomposition.open) {
+                            zoomOut(index)
+                          } else {
+                            zoomIn(index)
+                          }
+                          // Leaf decomposition node with parameters in parameters mode => link
+                          if (displayMode.edit === undefined) {
+                            goto(getCorrectSimulationUrl(decomposition.name), {
+                              noScroll: true,
+                            })
+                          }
+                        }}
+                        data-sveltekit-noscroll
+                        >{decomposition.short_label ??
+                          decomposition.label}</button
+                      >
+                      <button
+                        class="text-black"
+                        aria-label={decomposition.open
+                          ? "Ouvrir variables enfants"
+                          : "Fermer"}
+                        onclick={() =>
+                          decomposition.open ? zoomOut(index) : zoomIn(index)}
+                      >
+                        <iconify-icon
+                          class="align-[-0.25rem] text-lg hover:text-le-gris-dispositif"
+                          icon={decomposition.open
+                            ? "ri-arrow-down-s-line"
+                            : "ri-arrow-right-s-line"}
+                        ></iconify-icon>
+                      </button>
+                    </div>
                   {/if}
                 </div>
-
-                {#if displayMode.edit !== undefined}
-                  <!-- Leaf decomposition node in variable inputs mode => link -->
-                  <a
-                    class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
-                    href={newSimulationUrl({
-                      ...displayMode,
-                      variableName: decomposition.name,
-                    })}
-                    data-sveltekit-noscroll
-                    >{decomposition.short_label ?? decomposition.label}</a
-                  >
-                {:else}
-                  <!-- Leaf decomposition node with parameters in parameters mode => link -->
-                  <a
-                    class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
-                    href={newSimulationUrl({
-                      ...displayMode,
-                      mobileLaw: true,
-                      parametersVariableName: decomposition.name,
-                    })}
-                    data-sveltekit-noscroll
-                    >{decomposition.short_label ?? decomposition.label}</a
-                  >
-                {/if}
-              {:else}
-                <!-- Non-trunk, non-leaf variablev-->
-                {#if decomposition.open}
-                  <button class="p-0 text-black" onclick={() => zoomOut(index)}>
-                    <iconify-icon
-                      class="align-[-0.2rem] text-lg"
-                      icon="ri-arrow-up-s-line"
-                    ></iconify-icon>
-                  </button>
-                {:else}
-                  <button class="p-0 text-black" onclick={() => zoomIn(index)}>
-                    <iconify-icon
-                      class="align-[-0.2rem] text-lg"
-                      icon="ri-arrow-right-s-line"
-                    ></iconify-icon>
-                  </button>
-                {/if}
-
-                {#if displayMode.edit !== undefined}
-                  <!-- Non-lead decomposition node in variable inputs mode => no-link -->
-                  <button
-                    class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base text-black hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-black hover:underline"
-                    onclick={() => {
-                      if (decomposition.open) {
-                        zoomOut(index)
-                      } else {
-                        zoomIn(index)
-                      }
-                    }}
-                  >
-                    {decomposition.short_label ?? decomposition.label}
-                  </button>
-                {:else}
-                  <!-- Leaf decomposition node with parameters in parameters mode => link -->
-                  <a
-                    class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
-                    href={newSimulationUrl({
-                      ...displayMode,
-                      parametersVariableName: decomposition.name,
-                    })}
-                    onclick={preventDefault(() => {
-                      if (decomposition.open) {
-                        zoomOut(index)
-                      } else {
-                        zoomIn(index)
-                      }
-                      goto(
-                        newSimulationUrl({
-                          ...displayMode,
-                          parametersVariableName: decomposition.name,
-                        }),
-                        { noScroll: true },
-                      )
-                    })}
-                    data-sveltekit-noscroll
-                    >{decomposition.short_label ?? decomposition.label}</a
-                  >
-                {/if}
               {/if}
-            {/if}
+            {/each}
           </div>
 
-          {#each rows as { calculationName, deltaAtVectorIndexArray }}
-            <!-- Decomposition compared amounts -->
-            {#if !decomposition.open || trunk || index === 0}
-              <div class="relative flex items-center whitespace-nowrap">
-                {#if !decomposition.open && !trunk}
-                  <div class="absolute">
-                    {#each iterToDepth(depth)}
-                      <div
-                        class="ml-2 h-full border-l border-le-gris-dispositif"
-                      >
-                        &nbsp;
-                      </div>
-                    {/each}
-                  </div>
-                {/if}
-                <div
-                  class="justify-center {decomposition.open &&
-                  trunk &&
-                  visibleChildren.length > 1 &&
-                  calculationName === firstCalculationName
-                    ? ''
-                    : ' border-none'} {calculationName === firstCalculationName
-                    ? ''
-                    : '-mt-1 mb-1'} flex w-full text-sm"
-                >
-                  {#if decomposition.open || index === 0}
-                    <!---Composant loader pour les valeurs intermédiaires-->
-                    {#if showLoader && runningCalculationNames.length > 0}
-                      {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
-                          class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
-                        >
-                          <span class="text-white blur">value €</span>
-                        </span>
-                      {/if}
-                      {#if runningCalculationNames.includes("bill")}
-                        <span
-                          class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
-                        >
-                          <span class="text-white blur">value €</span>
-                        </span>
-                      {/if}
-                      {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
-                        <span
-                          class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
-                        >
-                          <span class="text-white blur">value €</span>
-                        </span>
-                      {/if}
-                      <!--Valeurs du waterfall des montants intermédiaires -->
-                    {:else if trunk || index === 0}
-                      {#if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
-                        {#if decomposition.open && trunk}
-                          <span class="mx-2 text-gray-500">=</span>
-                        {/if}
-                        <span
-                          class="text-sm {calculationName ===
-                          firstCalculationName
+          <!-- "Valeur du dispositif"-->
+
+          <div class="flex w-full flex-col items-stretch">
+            {#each rows as { calculationName, deltaAtVectorIndexArray }}
+              <div class="h-full justify-center pl-1 text-sm">
+                <!--Si la valeur charge, alors un squelette est affiché -->
+                {#if showLoader && runningCalculationNames.length > 0}
+                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}
+                    <span
+                      class="animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  {#if runningCalculationNames.includes("bill")}
+                    <span
+                      class="animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
+                    <span
+                      class="animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
+                    >
+                      <span class="text-white blur">value €</span>
+                    </span>
+                  {/if}
+                  <!--Si la valeur du cas type 0 est égale à la valeur du cas type 1 : Une seule valeur est alors affichée -->
+                {:else if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
+                  <div class="flex w-full justify-center">
+                    {#if trunk && index !== 0}
+                      <span
+                        class={calculationName === firstCalculationName
+                          ? rows.find(
+                              (row) => row.calculationName === "bill",
+                            ) === undefined
                             ? rows.find(
-                                (row) => row.calculationName === 'bill',
+                                (row) => row.calculationName === "amendment",
                               ) === undefined
-                              ? rows.find(
-                                  (row) => row.calculationName === 'amendment',
-                                ) === undefined
-                                ? 'text-gray-500'
-                                : 'text-gray-500 line-through-amendment'
-                              : 'text-gray-500 line-through-bill'
-                            : calculationName === 'bill'
-                              ? rows.find(
-                                  (row) => row.calculationName === 'amendment',
-                                ) === undefined
-                                ? 'text-le-rouge-bill'
-                                : 'text-le-rouge-bill line-through-amendment'
-                              : 'bg-le-jaune'}"
-                          >{deltaFormatter(
-                            deltaAtVectorIndexArray[0] ?? 0,
-                          )}</span
-                        >
-                      {:else}
-                        <div class="flex w-full justify-center">
-                          <div class="mx-4 w-1/2">
-                            {#if decomposition.open && trunk}
-                              <span class="mx-2 text-gray-500">=</span>
-                            {/if}
-                            <span
-                              class="text-right text-sm {calculationName ===
-                              firstCalculationName
-                                ? rows.find(
-                                    (row) => row.calculationName === 'bill',
-                                  ) === undefined
-                                  ? rows.find(
-                                      (row) =>
-                                        row.calculationName === 'amendment',
-                                    ) === undefined
-                                    ? 'text-gray-500'
-                                    : 'text-gray-500 line-through-amendment'
-                                  : 'text-gray-500 line-through-bill'
-                                : calculationName === 'bill'
-                                  ? rows.find(
-                                      (row) =>
-                                        row.calculationName === 'amendment',
-                                    ) === undefined
-                                    ? 'text-le-rouge-bill'
-                                    : 'text-le-rouge-bill line-through-amendment'
-                                  : 'bg-le-jaune'}"
-                              >{deltaFormatter(
-                                deltaAtVectorIndexArray[0] ?? 0,
-                              )}</span
-                            >
-                          </div>
-                          <div class="mx-4 w-1/2">
-                            {#if decomposition.open && trunk}
-                              <span class="mx-2 text-gray-500">=</span>
-                            {/if}
-                            <span
-                              class="text-left text-sm {calculationName ===
-                              firstCalculationName
-                                ? rows.find(
-                                    (row) => row.calculationName === 'bill',
-                                  ) === undefined
-                                  ? rows.find(
-                                      (row) =>
-                                        row.calculationName === 'amendment',
-                                    ) === undefined
-                                    ? 'text-gray-500'
-                                    : 'text-gray-500 line-through-amendment'
-                                  : 'text-gray-500 line-through-bill'
-                                : calculationName === 'bill'
-                                  ? rows.find(
-                                      (row) =>
-                                        row.calculationName === 'amendment',
-                                    ) === undefined
-                                    ? 'text-le-rouge-bill'
-                                    : 'text-le-rouge-bill line-through-amendment'
-                                  : 'bg-le-jaune'}"
-                              >{deltaFormatter(
-                                deltaAtVectorIndexArray[1] ?? 0,
-                              )}</span
-                            >
-                          </div>
-                        </div>
-                      {/if}
-                    {/if}
-                    <!--Montant des dispositifs-->
-                  {:else if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
-                    <!---Composant loader pour la valeur suivante-->
-                    {#if showLoader && runningCalculationNames.length > 0}
-                      {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
-                          class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
-                        >
-                          <span class="text-white blur">value €</span>
-                        </span>
-                      {/if}
-                      {#if runningCalculationNames.includes("bill")}
-                        <span
-                          class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
-                        >
-                          <span class="text-white blur">value €</span>
-                        </span>
-                      {/if}
-                      {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
-                        <span
-                          class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
-                        >
-                          <span class="text-white blur">value €</span>
-                        </span>
-                      {/if}
-                      <!--Valeur-->
+                              ? "text-gray-500"
+                              : "text-gray-500 line-through-amendment"
+                            : "text-gray-500 line-through-bill"
+                          : calculationName === "bill"
+                            ? rows.find(
+                                (row) => row.calculationName === "amendment",
+                              ) === undefined
+                              ? "text-le-rouge-bill"
+                              : "text-le-rouge-bill line-through-amendment"
+                            : "bg-le-jaune text-gray-500"}
+                        class:text-base={decomposition.name !==
+                          displayMode.parametersVariableName}
+                        class:text-2xl={decomposition.name ===
+                          displayMode.parametersVariableName}
+                        class:font-bold={decomposition.name ===
+                          displayMode.parametersVariableName}
+                        ><span
+                          class="content-center pr-1 font-normal text-gray-500"
+                          >=</span
+                        >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
+                      >
                     {:else}
                       <span
-                        class="text-base font-bold {calculationName ===
+                        class="font-bold {calculationName ===
                         firstCalculationName
                           ? rows.find(
                               (row) => row.calculationName === 'bill',
@@ -537,98 +431,154 @@
                               ? 'text-le-rouge-bill'
                               : 'text-le-rouge-bill line-through-amendment'
                             : 'bg-le-jaune'}"
-                        >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
+                        class:opacity-20={decomposition.open}
+                        class:text-base={decomposition.name !==
+                          displayMode.parametersVariableName}
+                        class:text-3xl={decomposition.name ===
+                          displayMode.parametersVariableName}
+                        class:font-semibold={decomposition.name ===
+                          displayMode.parametersVariableName}
+                        >{#if index !== 0}{#if deltaAtVectorIndexArray[0] < 0}-{:else if deltaAtVectorIndexArray[0] > 0}+{/if}{/if}
+                        {deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
                       >
                     {/if}
-                  {:else}
-                    <!---Composant loader pour la valeur suivante-->
-                    {#if showLoader && runningCalculationNames.length > 0}
-                      {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
-                          class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
+                  </div>
+                  <!--Si la valeur du cas type 0 est DIFFÉRENTE de la valeur du cas type 1 : les deux valeurs sont affichées côte à côte -->
+                {:else}
+                  <div class="flex w-full text-center">
+                    <div class="mx-4 w-1/2">
+                      {#if trunk && index !== 0}
+                        <span
+                          class={calculationName === firstCalculationName
+                            ? rows.find(
+                                (row) => row.calculationName === "bill",
+                              ) === undefined
+                              ? rows.find(
+                                  (row) => row.calculationName === "amendment",
+                                ) === undefined
+                                ? "text-gray-500"
+                                : "text-gray-500 line-through-amendment"
+                              : "text-gray-500 line-through-bill"
+                            : calculationName === "bill"
+                              ? rows.find(
+                                  (row) => row.calculationName === "amendment",
+                                ) === undefined
+                                ? "text-le-rouge-bill"
+                                : "text-le-rouge-bill line-through-amendment"
+                              : "bg-le-jaune text-gray-500"}
+                          class:text-base={decomposition.name !==
+                            displayMode.parametersVariableName}
+                          class:text-2xl={decomposition.name ===
+                            displayMode.parametersVariableName}
+                          class:font-bold={decomposition.name ===
+                            displayMode.parametersVariableName}
+                          ><span
+                            class="content-center pr-1 font-normal text-gray-500"
+                            >=</span
+                          >{deltaFormatter(
+                            deltaAtVectorIndexArray[0] ?? 0,
+                          )}</span
                         >
-                          <span class="text-white blur">value €</span>
-                        </span>
-                      {/if}
-                      {#if runningCalculationNames.includes("bill")}
+                      {:else}
                         <span
-                          class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
+                          class="text-base font-bold {calculationName ===
+                          firstCalculationName
+                            ? rows.find(
+                                (row) => row.calculationName === 'bill',
+                              ) === undefined
+                              ? rows.find(
+                                  (row) => row.calculationName === 'amendment',
+                                ) === undefined
+                                ? ''
+                                : 'line-through-amendment'
+                              : 'line-through-bill'
+                            : calculationName === 'bill'
+                              ? rows.find(
+                                  (row) => row.calculationName === 'amendment',
+                                ) === undefined
+                                ? 'text-le-rouge-bill'
+                                : 'text-le-rouge-bill line-through-amendment'
+                              : 'bg-le-jaune'}"
+                          >{#if trunk && index === 0}={:else if deltaAtVectorIndexArray[0] < 0}-{:else if deltaAtVectorIndexArray[0] > 0}+{/if}{deltaFormatter(
+                            deltaAtVectorIndexArray[0] ?? 0,
+                          )}</span
                         >
-                          <span class="text-white blur">value €</span>
-                        </span>
                       {/if}
-                      {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
+                    </div>
+                    <div class="mx-4 w-1/2">
+                      {#if trunk && index !== 0}
                         <span
-                          class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
+                          class={calculationName === firstCalculationName
+                            ? rows.find(
+                                (row) => row.calculationName === "bill",
+                              ) === undefined
+                              ? rows.find(
+                                  (row) => row.calculationName === "amendment",
+                                ) === undefined
+                                ? "text-gray-500"
+                                : "text-gray-500 line-through-amendment"
+                              : "text-gray-500 line-through-bill"
+                            : calculationName === "bill"
+                              ? rows.find(
+                                  (row) => row.calculationName === "amendment",
+                                ) === undefined
+                                ? "text-le-rouge-bill"
+                                : "text-le-rouge-bill line-through-amendment"
+                              : "bg-le-jaune text-gray-500"}
+                          class:text-base={decomposition.name !==
+                            displayMode.parametersVariableName}
+                          class:text-2xl={decomposition.name ===
+                            displayMode.parametersVariableName}
+                          class:font-bold={decomposition.name ===
+                            displayMode.parametersVariableName}
+                          ><span
+                            class="content-center pr-1 font-normal text-gray-500"
+                            >=</span
+                          >{deltaFormatter(
+                            deltaAtVectorIndexArray[1] ?? 0,
+                          )}</span
                         >
-                          <span class="text-white blur">value €</span>
-                        </span>
-                      {/if}
-                      <!--Valeur dispositifs-->
-                    {:else}
-                      <div class="flex w-full justify-center">
-                        <div class="mx-4 w-1/2">
-                          <span
-                            class="text-base font-bold {calculationName ===
-                            firstCalculationName
+                      {:else}
+                        <span
+                          class="text-base font-bold {calculationName ===
+                          firstCalculationName
+                            ? rows.find(
+                                (row) => row.calculationName === 'bill',
+                              ) === undefined
                               ? rows.find(
-                                  (row) => row.calculationName === 'bill',
+                                  (row) => row.calculationName === 'amendment',
                                 ) === undefined
-                                ? rows.find(
-                                    (row) =>
-                                      row.calculationName === 'amendment',
-                                  ) === undefined
-                                  ? ''
-                                  : 'line-through-amendment'
-                                : 'line-through-bill'
-                              : calculationName === 'bill'
-                                ? rows.find(
-                                    (row) =>
-                                      row.calculationName === 'amendment',
-                                  ) === undefined
-                                  ? 'text-le-rouge-bill'
-                                  : 'text-le-rouge-bill line-through-amendment'
-                                : 'bg-le-jaune'}"
-                            >{deltaFormatter(
-                              deltaAtVectorIndexArray[0] ?? 0,
-                            )}</span
-                          >
-                        </div>
-                        <div class="mx-4 w-1/2">
-                          <span
-                            class="text-base font-bold {calculationName ===
-                            firstCalculationName
+                                ? ''
+                                : 'line-through-amendment'
+                              : 'line-through-bill'
+                            : calculationName === 'bill'
                               ? rows.find(
-                                  (row) => row.calculationName === 'bill',
+                                  (row) => row.calculationName === 'amendment',
                                 ) === undefined
-                                ? rows.find(
-                                    (row) =>
-                                      row.calculationName === 'amendment',
-                                  ) === undefined
-                                  ? ''
-                                  : 'line-through-amendment'
-                                : 'line-through-bill'
-                              : calculationName === 'bill'
-                                ? rows.find(
-                                    (row) =>
-                                      row.calculationName === 'amendment',
-                                  ) === undefined
-                                  ? 'text-le-rouge-bill'
-                                  : 'text-le-rouge-bill line-through-amendment'
-                                : 'bg-le-jaune'}"
-                            >{deltaFormatter(
-                              deltaAtVectorIndexArray[1] ?? 0,
-                            )}</span
-                          >
-                        </div>
-                      </div>
-                    {/if}
-                  {/if}
-                </div>
+                                ? 'text-le-rouge-bill'
+                                : 'text-le-rouge-bill line-through-amendment'
+                              : 'bg-le-jaune'}"
+                          >{#if trunk && index === 0}={:else if deltaAtVectorIndexArray[1] < 0}-{:else if deltaAtVectorIndexArray[1] > 0}+{/if}{deltaFormatter(
+                            deltaAtVectorIndexArray[1] ?? 0,
+                          )}</span
+                        >
+                      {/if}
+                    </div>
+                  </div>
+                {/if}
               </div>
-            {/if}
-          {/each}
+            {/each}
+          </div>
         </div>
-      {/each}
-    </div>
+      </div>
+    {/each}
   </div>
 {/if}
+
+<style lang="postcss">
+  .fond {
+    background-color: #ffffff;
+    /* Polka dots - Heropatterns.com échelle réduite */
+    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3E%3Cpath fill='%23A0A0A0' fill-opacity='0.4' d='M1 3h1v1H1V3zm2-2h1v1H3V1z'%3E%3C/path%3E%3C/svg%3E");
+  }
+</style>
-- 
GitLab


From 164c1034f40e1a1b97cc472642a9231038fbd8bb Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Mon, 10 Mar 2025 14:03:03 +0100
Subject: [PATCH 04/13] Fix les bordures qui permettent de suivre les variables
 enfants

---
 .../compare_mode/PaySlipCompareView.svelte          | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
index fa7b9c557..6d6dcdc0f 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
@@ -186,6 +186,7 @@
         class:text-lg={decomposition.name ===
           displayMode.parametersVariableName}
       >
+        <!--Indentation pour chaque niveau de l'arbre, illustré par une bordure-->
         {#each iterToDepth(depth)}
           <div
             class={`min-h-full border-l-2 pr-3 ${
@@ -223,8 +224,6 @@
                         class="cursor-pointer overflow-x-hidden text-ellipsis text-gray-500 hover:z-20 hover:overflow-x-visible hover:bg-white hover:bg-opacity-90 hover:pr-1 hover:text-le-gris-dispositif-dark hover:underline"
                         class:font-bold={decomposition.name ===
                           displayMode.parametersVariableName}
-                        class:hover:absolute={decomposition.name !==
-                          displayMode.parametersVariableName}
                         href={getCorrectSimulationUrl(decomposition.name)}
                         data-sveltekit-noscroll
                         >{decomposition.short_label ?? decomposition.label}</a
@@ -381,6 +380,10 @@
                   <!--Si la valeur du cas type 0 est égale à la valeur du cas type 1 : Une seule valeur est alors affichée -->
                 {:else if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
                   <div class="flex w-full justify-center">
+                    <!--Retrait de la marge appliquée avec l'identation-->
+                    {#each iterToDepth(depth)}
+                      <div class="-mr-3"></div>
+                    {/each}
                     {#if trunk && index !== 0}
                       <span
                         class={calculationName === firstCalculationName
@@ -434,7 +437,7 @@
                         class:opacity-20={decomposition.open}
                         class:text-base={decomposition.name !==
                           displayMode.parametersVariableName}
-                        class:text-3xl={decomposition.name ===
+                        class:text-2xl={decomposition.name ===
                           displayMode.parametersVariableName}
                         class:font-semibold={decomposition.name ===
                           displayMode.parametersVariableName}
@@ -446,6 +449,10 @@
                   <!--Si la valeur du cas type 0 est DIFFÉRENTE de la valeur du cas type 1 : les deux valeurs sont affichées côte à côte -->
                 {:else}
                   <div class="flex w-full text-center">
+                    <!--Retrait de la marge appliquée avec l'identation-->
+                    {#each iterToDepth(depth)}
+                      <div class="-mr-3"></div>
+                    {/each}
                     <div class="mx-4 w-1/2">
                       {#if trunk && index !== 0}
                         <span
-- 
GitLab


From e4ff84f97c4f8530c6267dceb94a9504c206d1fa Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Mon, 10 Mar 2025 14:10:08 +0100
Subject: [PATCH 05/13] =?UTF-8?q?Fix=20le=20layout=20qui=20accueille=20le?=
 =?UTF-8?q?=20waterfall=20compar=C3=A9,=20et=20harmonise=20avec=20le=20cod?=
 =?UTF-8?q?e=20pr=C3=A9sent=20dans=20TestCaseView?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../compare_mode/TestCaseCompareView.svelte   | 234 ++----------------
 1 file changed, 15 insertions(+), 219 deletions(-)

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/TestCaseCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/TestCaseCompareView.svelte
index 2f884fbaf..b5c7b433d 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/TestCaseCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/TestCaseCompareView.svelte
@@ -1,14 +1,14 @@
 <script lang="ts">
   import type { DecompositionReference } from "@openfisca/json-model"
+  import SourcesMethodTooltip from "$lib/components/impacts_view/SourcesMethodTooltip.svelte"
   import { createEventDispatcher } from "svelte"
 
   import type { CalculationName } from "$lib/calculations.svelte"
   import TestCaseSummary from "$lib/components/impacts_view/test_cases_view/test_case_selected/TestCaseSummary.svelte"
-  import ValueChangeCompare from "$lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/ValueChangeCompare.svelte"
   import PaySlipCompareView from "$lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte"
   import { type EvaluationByName, waterfalls } from "$lib/decompositions"
   import type { DisplayMode } from "$lib/displays"
-  import { billName, revaluationName, shared } from "$lib/shared.svelte"
+  import { shared } from "$lib/shared.svelte"
   import { newSimulationUrl } from "$lib/urls"
   import { variableSummaryByName } from "$lib/variables"
 
@@ -100,217 +100,9 @@
   </div>
   <div id="situation_{situationsToCompareIndex.join('_')}_waterfall">
     {#if variableSummaryByName !== undefined}
-      <div class="flex justify-between bg-gray-100">
+      <div class="flex w-full justify-between bg-gray-200">
         <!-- Impacts et waterfall -->
-        <div
-          class="min-h-[30em] w-10/12 bg-gradient-to-r from-gray-100 from-50% to-white to-50% bg-cover bg-center bg-no-repeat px-3 text-center md:w-11/12"
-        >
-          <div class="relative flex-col border-gray-400 p-3 pb-6">
-            <div
-              class="flex justify-between gap-4"
-              title="⚠️ Les dispositifs n'étant pas tous à jour, cette somme est à considérer avec prudence."
-            >
-              <div class="mb-4 w-full flex-col text-gray-700">
-                <p class="mb-1 text-base font-medium">
-                  {shared.waterfall.totalLabel}<svg
-                    aria-hidden="true"
-                    class="mx-1 inline-flex h-4 w-4 fill-current text-white"
-                    viewBox="0 0 24 22"
-                    xmlns="http://www.w3.org/2000/svg"
-                  >
-                    <path
-                      class="text-[#FFAC33]"
-                      d="M0.124322 18.4377C-0.240619 19.1041 0.241623 19.918 1.00142 19.918H20.6259C21.3857 19.918 21.868 19.1041 21.503 18.4377L11.6908 0.519686C11.3113 -0.173228 10.316 -0.173229 9.93658 0.519685L0.124322 18.4377ZM11.8591 16.8375C11.8591 17.3898 11.4114 17.8375 10.8591 17.8375H10.7682C10.2159 17.8375 9.76822 17.3898 9.76822 16.8375V16.627C9.76822 16.0747 10.2159 15.627 10.7682 15.627H10.8591C11.4114 15.627 11.8591 16.0747 11.8591 16.627V16.8375ZM11.8591 12.7416C11.8591 13.2938 11.4114 13.7416 10.8591 13.7416H10.7682C10.2159 13.7416 9.76822 13.2938 9.76822 12.7416V7.3298C9.76822 6.77751 10.2159 6.3298 10.7682 6.3298H10.8591C11.4114 6.3298 11.8591 6.77751 11.8591 7.3298V12.7416Z"
-                    />
-                    <path
-                      d="M10.7686 17.8378H10.8595C11.4117 17.8378 11.8595 17.3901 11.8595 16.8378V16.6273C11.8595 16.075 11.4117 15.6273 10.8595 15.6273H10.7686C10.2163 15.6273 9.76855 16.075 9.76855 16.6273V16.8378C9.76855 17.3901 10.2163 17.8378 10.7686 17.8378Z"
-                    />
-                    <path
-                      d="M10.7686 13.7418H10.8595C11.4117 13.7418 11.8595 13.2941 11.8595 12.7418V7.33008C11.8595 6.77779 11.4117 6.33008 10.8595 6.33008H10.7686C10.2163 6.33008 9.76855 6.77779 9.76855 7.33008V12.7418C9.76855 13.2941 10.2163 13.7418 10.7686 13.7418Z"
-                    />
-                  </svg>:
-                </p>
-                <ValueChangeCompare
-                  legend
-                  unitName="currency-EUR"
-                  valueByCalculationName0={{
-                    amendment:
-                      Object.keys(shared.parametricReform).length === 0
-                        ? undefined
-                        : calculateTotal(
-                            shared.evaluationByNameArray[
-                              situationsToCompareIndex[0]
-                            ],
-                            "amendment",
-                            shared.waterfall.root,
-                            shared.waterfall.total,
-                          ),
-                    bill:
-                      billName === undefined
-                        ? undefined
-                        : calculateTotal(
-                            shared.evaluationByNameArray[
-                              situationsToCompareIndex[0]
-                            ],
-                            "bill",
-                            shared.waterfall.root,
-                            shared.waterfall.total,
-                          ),
-                    law: calculateTotal(
-                      shared.evaluationByNameArray[situationsToCompareIndex[0]],
-                      "law",
-                      shared.waterfall.root,
-                      shared.waterfall.total,
-                    ),
-                    revaluation:
-                      revaluationName === undefined
-                        ? undefined
-                        : calculateTotal(
-                            shared.evaluationByNameArray[
-                              situationsToCompareIndex[0]
-                            ],
-                            "revaluation",
-                            shared.waterfall.root,
-                            shared.waterfall.total,
-                          ),
-                  }}
-                  valueByCalculationName1={{
-                    amendment:
-                      Object.keys(shared.parametricReform).length === 0
-                        ? undefined
-                        : calculateTotal(
-                            shared.evaluationByNameArray[
-                              situationsToCompareIndex[1]
-                            ],
-                            "amendment",
-                            shared.waterfall.root,
-                            shared.waterfall.total,
-                          ),
-                    bill:
-                      billName === undefined
-                        ? undefined
-                        : calculateTotal(
-                            shared.evaluationByNameArray[
-                              situationsToCompareIndex[1]
-                            ],
-                            "bill",
-                            shared.waterfall.root,
-                            shared.waterfall.total,
-                          ),
-                    law: calculateTotal(
-                      shared.evaluationByNameArray[situationsToCompareIndex[1]],
-                      "law",
-                      shared.waterfall.root,
-                      shared.waterfall.total,
-                    ),
-                    revaluation:
-                      revaluationName === undefined
-                        ? undefined
-                        : calculateTotal(
-                            shared.evaluationByNameArray[
-                              situationsToCompareIndex[1]
-                            ],
-                            "revaluation",
-                            shared.waterfall.root,
-                            shared.waterfall.total,
-                          ),
-                  }}
-                />
-              </div>
-              <!-- <div class="flex-col w-1/2 text-gray-500 text-sm mt-8">
-                <p>
-                  dont <span class="font-bold text-black">100 €</span> de compléments
-                  de ressources.
-                </p>
-                <p>
-                  dont <span class="font-bold text-black">200 €</span> de prélèvements
-                  obligatoires.
-                </p>
-              </div> -->
-            </div>
-            {#if displayMode.parametersVariableName !== undefined && shared.decompositionByName[displayMode.parametersVariableName] !== undefined}
-              <div class="mt-2 flex-col">
-                <p class="mb-1 text-lg font-black">
-                  {shared.decompositionByName[
-                    displayMode.parametersVariableName
-                  ].short_label ??
-                    shared.decompositionByName[
-                      displayMode.parametersVariableName
-                    ].label ??
-                    displayMode.parametersVariableName}&nbsp;:
-                </p>
-                <div class="text-2xl font-semibold">
-                  <ValueChangeCompare
-                    unitName="currency-EUR"
-                    valueByCalculationName0={{
-                      amendment:
-                        Object.keys(shared.parametricReform).length === 0
-                          ? undefined
-                          : (shared.evaluationByNameArray[
-                              situationsToCompareIndex[0]
-                            ][displayMode.parametersVariableName]
-                              ?.calculationEvaluationByName["amendment"]
-                              ?.deltaAtVectorIndex ?? 0),
-                      bill:
-                        billName === undefined
-                          ? undefined
-                          : (shared.evaluationByNameArray[
-                              situationsToCompareIndex[0]
-                            ][displayMode.parametersVariableName]
-                              ?.calculationEvaluationByName["bill"]
-                              ?.deltaAtVectorIndex ?? 0),
-                      law:
-                        shared.evaluationByNameArray[
-                          situationsToCompareIndex[0]
-                        ][displayMode.parametersVariableName]
-                          ?.calculationEvaluationByName["law"]
-                          ?.deltaAtVectorIndex ?? 0,
-                      revaluation:
-                        revaluationName === undefined
-                          ? undefined
-                          : (shared.evaluationByNameArray[
-                              situationsToCompareIndex[0]
-                            ][displayMode.parametersVariableName]
-                              ?.calculationEvaluationByName["revaluation"]
-                              ?.deltaAtVectorIndex ?? 0),
-                    }}
-                    valueByCalculationName1={{
-                      amendment:
-                        Object.keys(shared.parametricReform).length === 0
-                          ? undefined
-                          : (shared.evaluationByNameArray[
-                              situationsToCompareIndex[1]
-                            ][displayMode.parametersVariableName]
-                              ?.calculationEvaluationByName["amendment"]
-                              ?.deltaAtVectorIndex ?? 0),
-                      bill:
-                        billName === undefined
-                          ? undefined
-                          : (shared.evaluationByNameArray[
-                              situationsToCompareIndex[1]
-                            ][displayMode.parametersVariableName]
-                              ?.calculationEvaluationByName["bill"]
-                              ?.deltaAtVectorIndex ?? 0),
-                      law:
-                        shared.evaluationByNameArray[
-                          situationsToCompareIndex[1]
-                        ][displayMode.parametersVariableName]
-                          ?.calculationEvaluationByName["law"]
-                          ?.deltaAtVectorIndex ?? 0,
-                      revaluation:
-                        revaluationName === undefined
-                          ? undefined
-                          : (shared.evaluationByNameArray[
-                              situationsToCompareIndex[1]
-                            ][displayMode.parametersVariableName]
-                              ?.calculationEvaluationByName["revaluation"]
-                              ?.deltaAtVectorIndex ?? 0),
-                    }}
-                  />
-                </div>
-              </div>
-            {/if}
-          </div>
+        <div class="relative w-10/12 bg-white pb-4 md:w-11/12">
           <PaySlipCompareView
             {displayMode}
             evaluationByNameArray={shared.evaluationByNameArray}
@@ -321,15 +113,16 @@
           />
         </div>
         <!--Onglets-->
-        <div
-          class="flex h-[24em] w-2/12 flex-col justify-between bg-gray-100 md:w-1/12"
-        >
+        <div class="flex w-2/12 flex-col justify-start bg-gray-200 md:w-1/12">
           {#each waterfalls as { icon, label, name }}
             <a
-              class="flex grow items-center justify-center shadow-inner"
+              class="group flex h-[9em] shrink items-center justify-center shadow-inner"
               class:bg-white={name === shared.waterfall.name}
+              class:hover:bg-gray-300={name !== shared.waterfall.name}
               class:border-le-bleu={name === shared.waterfall.name}
               class:border-r-4={name === shared.waterfall.name}
+              class:border-l={name !== shared.waterfall.name}
+              class:border-gray-300={name !== shared.waterfall.name}
               class:shadow-none={name === shared.waterfall.name}
               href={newSimulationUrl({
                 ...displayMode,
@@ -338,17 +131,19 @@
               data-sveltekit-noscroll
             >
               <div class="origin-center rotate-90">
-                <div class="mr-5 flex">
+                <div class="mr-6 flex">
                   {#if icon !== undefined}
                     <img
                       class="block origin-center -rotate-90"
-                      alt=""
+                      alt="Icone pour {label}"
                       src={icon}
                     />
                   {/if}
                   <span
-                    class="ml-2 text-xs uppercase tracking-wide text-gray-500 xl:text-sm"
+                    class="ml-2 text-xs uppercase tracking-wide text-gray-600 xl:text-sm"
                     class:text-le-bleu={name === shared.waterfall.name}
+                    class:group-hover:text-black={name !==
+                      shared.waterfall.name}
                     class:font-bold={name === shared.waterfall.name}
                   >
                     {label}
@@ -359,6 +154,7 @@
           {/each}
         </div>
       </div>
+      <SourcesMethodTooltip {displayMode} />
     {/if}
   </div>
 </div>
-- 
GitLab


From 4ca47a716a4bc3ae5ab4348305a430e3d2c2c00c Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Mon, 10 Mar 2025 16:56:42 +0100
Subject: [PATCH 06/13] ajout margin bouton affichage des variables

---
 .../test_case_selected/compare_mode/PaySlipCompareView.svelte   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
index 6d6dcdc0f..746b0427e 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
@@ -151,7 +151,7 @@
   <div>
     <div class="h-5 bg-gradient-to-b from-gray-100 to-transparent"></div>
     <!--Montants-nuls-->
-    <div class="mx-1 mb-3 flex justify-start">
+    <div class="mx-4 mb-3 flex justify-start">
       <label class="inline-flex cursor-pointer items-center">
         <input
           type="checkbox"
-- 
GitLab


From 448796e97eb1c43350013e55b1229c04c2c35eff Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Mon, 10 Mar 2025 18:02:35 +0100
Subject: [PATCH 07/13] Centre le squelette du loader au milieu de la payslip

---
 .../compare_mode/PaySlipCompareView.svelte    | 51 +++++++++++--------
 1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
index 746b0427e..de17c2cc9 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
@@ -356,27 +356,36 @@
               <div class="h-full justify-center pl-1 text-sm">
                 <!--Si la valeur charge, alors un squelette est affiché -->
                 {#if showLoader && runningCalculationNames.length > 0}
-                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}
-                    <span
-                      class="animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("bill")}
-                    <span
-                      class="animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
-                    <span
-                      class="animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
+                  <div class="flex w-full justify-center">
+                    {#each iterToDepth(depth)}
+                      <div class="-mr-3"></div>
+                    {/each}
+                    {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}
+                      <span
+                        class="animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
+                      >
+                        <span class="text-white blur">value €</span>
+                      </span>
+                    {/if}
+
+                    {#if runningCalculationNames.includes("bill")}
+                      {#each iterToDepth(depth)}
+                        <div class="-mr-3"></div>
+                      {/each}
+                      <span
+                        class="animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
+                      >
+                        <span class="text-white blur">value €</span>
+                      </span>
+                    {/if}
+                    {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
+                      <span
+                        class="animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
+                      >
+                        <span class="text-white blur">value €</span>
+                      </span>
+                    {/if}
+                  </div>
                   <!--Si la valeur du cas type 0 est égale à la valeur du cas type 1 : Une seule valeur est alors affichée -->
                 {:else if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
                   <div class="flex w-full justify-center">
-- 
GitLab


From 20ef490b5bbaed77e1a56c18087d610b5cc7c1aa Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Mon, 10 Mar 2025 18:14:53 +0100
Subject: [PATCH 08/13] =?UTF-8?q?Ajoute=20baisse=20de=20l'opacit=C3=A9=20s?=
 =?UTF-8?q?ur=20les=20montants=20doubles?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../test_case_selected/compare_mode/PaySlipCompareView.svelte   | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
index de17c2cc9..64e4f3275 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
@@ -515,6 +515,7 @@
                                 ? 'text-le-rouge-bill'
                                 : 'text-le-rouge-bill line-through-amendment'
                               : 'bg-le-jaune'}"
+                          class:opacity-20={decomposition.open}
                           >{#if trunk && index === 0}={:else if deltaAtVectorIndexArray[0] < 0}-{:else if deltaAtVectorIndexArray[0] > 0}+{/if}{deltaFormatter(
                             deltaAtVectorIndexArray[0] ?? 0,
                           )}</span
@@ -574,6 +575,7 @@
                                 ? 'text-le-rouge-bill'
                                 : 'text-le-rouge-bill line-through-amendment'
                               : 'bg-le-jaune'}"
+                          class:opacity-20={decomposition.open}
                           >{#if trunk && index === 0}={:else if deltaAtVectorIndexArray[1] < 0}-{:else if deltaAtVectorIndexArray[1] > 0}+{/if}{deltaFormatter(
                             deltaAtVectorIndexArray[1] ?? 0,
                           )}</span
-- 
GitLab


From 2c332eb2c9a8813ca17052c5bf364b7d95780e5f Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Wed, 19 Mar 2025 10:34:49 +0100
Subject: [PATCH 09/13] =?UTF-8?q?Essai=20(sans=20succ=C3=A8s)=20d'ajouter?=
 =?UTF-8?q?=20les=20variables=20li=C3=A9es=20dans=20la=20feuille=20de=20pa?=
 =?UTF-8?q?ie=20compar=C3=A9e?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../compare_mode/LinkedVariables.svelte       | 136 ++++++++++++++++++
 .../compare_mode/PaySlipCompareView.svelte    |  28 ++++
 2 files changed, 164 insertions(+)
 create mode 100644 src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariables.svelte

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariables.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariables.svelte
new file mode 100644
index 000000000..788f0c739
--- /dev/null
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariables.svelte
@@ -0,0 +1,136 @@
+<script lang="ts">
+  import {
+    type Decomposition,
+    type EvaluationByName,
+  } from "$lib/decompositions"
+  import type { DisplayMode } from "$lib/displays"
+  import { billName, revaluationName, shared } from "$lib/shared.svelte"
+  import { variableSummaryByNameByReformName } from "$lib/variables"
+  import type {
+    DecompositionReference,
+    VariableByName,
+  } from "@openfisca/json-model"
+  import VariableValueChange from "$lib/components/impacts_view/ValueChange.svelte"
+  import {
+    isNullVariableValueByCalculationName,
+    variableValueByCalculationNameFromEvaluation,
+  } from "$lib/calculations.svelte"
+  import { newSimulationUrl } from "$lib/urls"
+  import { removeNegativeZero } from "$lib/values"
+
+  interface Props {
+    displayMode: DisplayMode
+    evaluationByNameArray: EvaluationByName[]
+    situationsToCompareIndex: number[]
+    variableSummaryByName: VariableByName
+    decomposition: Decomposition
+    visibleChildren: DecompositionReference[] | undefined
+  }
+
+  let {
+    displayMode,
+    evaluationByNameArray,
+    decomposition,
+    situationsToCompareIndex,
+    variableSummaryByName,
+    visibleChildren,
+  }: Props = $props()
+
+  const variableSummary =
+    billName === undefined
+      ? variableSummaryByName[displayMode.parametersVariableName!]
+      : variableSummaryByNameByReformName[billName][
+          displayMode.parametersVariableName!
+        ]
+
+  const linkedVariables = variableSummary.linked_other_variables
+
+  const deltaFormatter = (value: number): string =>
+    new Intl.NumberFormat("fr-FR", {
+      currency: "EUR",
+      maximumFractionDigits: 0,
+      minimumFractionDigits: 0,
+      signDisplay: "never",
+      style: "currency",
+    }).format(removeNegativeZero(value))
+</script>
+
+{#if linkedVariables !== undefined}
+  <div class="fond flex pr-4">
+    <!--Indentation pour chaque niveau de l'arbre, illustré par une bordure-->
+
+    <div
+      class="w-full border-dashed border-black"
+      class:border-l-0={!decomposition.open}
+      class:border-l-2={decomposition.open && visibleChildren !== undefined}
+      class:pl-0.5={!decomposition.open}
+    >
+      <div
+        class="mb-2 flex w-full grow flex-col justify-end lg:flex-row"
+        id="situation_{situationsToCompareIndex}_totalimpact"
+      >
+        <div class="flex w-full grow py-3 pl-5">
+          {#if linkedVariables !== undefined}
+            {@const linkedVariablesValueByCalculationName = linkedVariables.map(
+              (name) =>
+                variableValueByCalculationNameFromEvaluation(
+                  evaluationByNameArray[name],
+                  revaluationName,
+                  billName,
+                  shared.parametricReform,
+                ),
+            )}
+            {#if shared.showNulls || !linkedVariablesValueByCalculationName.every(isNullVariableValueByCalculationName)}
+              <ul
+                class="flex h-fit flex-col rounded-md border bg-white p-2 text-gray-800"
+              >
+                {#each linkedVariables as linkedVariableName, index}
+                  {@const linkedVariableValueByCalculationName =
+                    linkedVariablesValueByCalculationName[index]}
+                  {#if shared.showNulls || !isNullVariableValueByCalculationName(linkedVariableValueByCalculationName)}
+                    {@const linkedVariableSummary =
+                      billName === undefined
+                        ? variableSummaryByName[linkedVariableName]
+                        : variableSummaryByNameByReformName[billName][
+                            linkedVariableName
+                          ]}
+                    <li class="flex justify-between gap-2 text-sm">
+                      <a
+                        class="2xl:text-md max-w-32 cursor-pointer overflow-x-hidden text-ellipsis text-nowrap hover:underline sm:max-w-none lg:max-w-44 xl:max-w-none"
+                        href={newSimulationUrl({
+                          ...displayMode,
+                          parametersVariableName: linkedVariableName,
+                        })}
+                        data-sveltekit-noscroll
+                        ><span class="text-gray-600"
+                          >{linkedVariableSummary.short_label ??
+                            linkedVariableSummary.label ??
+                            linkedVariableName}&nbsp;:&nbsp;</span
+                        ></a
+                      >
+                      <VariableValueChange
+                        {evaluationByNameArray}
+                        name={linkedVariableName}
+                        valueByCalculationName={linkedVariableValueByCalculationName}
+                        inline
+                        bold
+                      />
+                    </li>
+                  {/if}
+                {/each}
+              </ul>
+            {/if}
+          {/if}
+        </div>
+      </div>
+    </div>
+  </div>
+{/if}
+
+<style lang="postcss">
+  .fond {
+    background-color: #ffffff;
+    /* Polka dots - Heropatterns.com échelle réduite */
+    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3E%3Cpath fill='%23A0A0A0' fill-opacity='0.4' d='M1 3h1v1H1V3zm2-2h1v1H3V1z'%3E%3C/path%3E%3C/svg%3E");
+  }
+</style>
diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
index 64e4f3275..90339e764 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
@@ -18,6 +18,7 @@
   import type { Situation } from "$lib/situations"
   import { newSimulationUrl } from "$lib/urls"
   import { removeNegativeZero } from "$lib/values"
+  import LinkedVariables from "$lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariables.svelte"
 
   interface Props {
     displayMode: DisplayMode
@@ -585,7 +586,34 @@
                   </div>
                 {/if}
               </div>
+              <!--Affichage des variables liées s'il y en a-->
+              {#if displayMode.parametersVariableName !== undefined && decomposition.name === displayMode.parametersVariableName}
+                <LinkedVariables
+                  {displayMode}
+                  {evaluationByNameArray}
+                  {situationsToCompareIndex}
+                  {variableSummaryByName}
+                  {decomposition}
+                  {visibleChildren}
+                />
+              {/if}
+            {/each}
+            <!--Affichage des variables liées s'il y en a
+            {#each rows as { deltaAtVectorIndexArray }}
+              {#if displayMode.parametersVariableName !== undefined && decomposition.name === displayMode.parametersVariableName}
+                <LinkedVariables
+                  {deltaAtVectorIndexArray}
+                  {displayMode}
+                  {evaluationByNameArray}
+                  {situationsToCompareIndex}
+                  {variableSummaryByName}
+                  {decomposition}
+                  {depth}
+                  {visibleChildren}
+                />
+              {/if}
             {/each}
+          -->
           </div>
         </div>
       </div>
-- 
GitLab


From e2191b5b577e9739099103eeaf193ab55be42d50 Mon Sep 17 00:00:00 2001
From: David Smadja <david.smadja@assemblee-nationale.fr>
Date: Mon, 24 Mar 2025 13:40:43 +0100
Subject: [PATCH 10/13] rework linkedvariables for compare view

---
 .../compare_mode/LinkedVariables.svelte       | 136 -------------
 .../LinkedVariablesCompareView.svelte         | 180 ++++++++++++++++++
 .../compare_mode/PaySlipCompareView.svelte    |   6 +-
 3 files changed, 182 insertions(+), 140 deletions(-)
 delete mode 100644 src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariables.svelte
 create mode 100644 src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariablesCompareView.svelte

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariables.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariables.svelte
deleted file mode 100644
index 788f0c739..000000000
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariables.svelte
+++ /dev/null
@@ -1,136 +0,0 @@
-<script lang="ts">
-  import {
-    type Decomposition,
-    type EvaluationByName,
-  } from "$lib/decompositions"
-  import type { DisplayMode } from "$lib/displays"
-  import { billName, revaluationName, shared } from "$lib/shared.svelte"
-  import { variableSummaryByNameByReformName } from "$lib/variables"
-  import type {
-    DecompositionReference,
-    VariableByName,
-  } from "@openfisca/json-model"
-  import VariableValueChange from "$lib/components/impacts_view/ValueChange.svelte"
-  import {
-    isNullVariableValueByCalculationName,
-    variableValueByCalculationNameFromEvaluation,
-  } from "$lib/calculations.svelte"
-  import { newSimulationUrl } from "$lib/urls"
-  import { removeNegativeZero } from "$lib/values"
-
-  interface Props {
-    displayMode: DisplayMode
-    evaluationByNameArray: EvaluationByName[]
-    situationsToCompareIndex: number[]
-    variableSummaryByName: VariableByName
-    decomposition: Decomposition
-    visibleChildren: DecompositionReference[] | undefined
-  }
-
-  let {
-    displayMode,
-    evaluationByNameArray,
-    decomposition,
-    situationsToCompareIndex,
-    variableSummaryByName,
-    visibleChildren,
-  }: Props = $props()
-
-  const variableSummary =
-    billName === undefined
-      ? variableSummaryByName[displayMode.parametersVariableName!]
-      : variableSummaryByNameByReformName[billName][
-          displayMode.parametersVariableName!
-        ]
-
-  const linkedVariables = variableSummary.linked_other_variables
-
-  const deltaFormatter = (value: number): string =>
-    new Intl.NumberFormat("fr-FR", {
-      currency: "EUR",
-      maximumFractionDigits: 0,
-      minimumFractionDigits: 0,
-      signDisplay: "never",
-      style: "currency",
-    }).format(removeNegativeZero(value))
-</script>
-
-{#if linkedVariables !== undefined}
-  <div class="fond flex pr-4">
-    <!--Indentation pour chaque niveau de l'arbre, illustré par une bordure-->
-
-    <div
-      class="w-full border-dashed border-black"
-      class:border-l-0={!decomposition.open}
-      class:border-l-2={decomposition.open && visibleChildren !== undefined}
-      class:pl-0.5={!decomposition.open}
-    >
-      <div
-        class="mb-2 flex w-full grow flex-col justify-end lg:flex-row"
-        id="situation_{situationsToCompareIndex}_totalimpact"
-      >
-        <div class="flex w-full grow py-3 pl-5">
-          {#if linkedVariables !== undefined}
-            {@const linkedVariablesValueByCalculationName = linkedVariables.map(
-              (name) =>
-                variableValueByCalculationNameFromEvaluation(
-                  evaluationByNameArray[name],
-                  revaluationName,
-                  billName,
-                  shared.parametricReform,
-                ),
-            )}
-            {#if shared.showNulls || !linkedVariablesValueByCalculationName.every(isNullVariableValueByCalculationName)}
-              <ul
-                class="flex h-fit flex-col rounded-md border bg-white p-2 text-gray-800"
-              >
-                {#each linkedVariables as linkedVariableName, index}
-                  {@const linkedVariableValueByCalculationName =
-                    linkedVariablesValueByCalculationName[index]}
-                  {#if shared.showNulls || !isNullVariableValueByCalculationName(linkedVariableValueByCalculationName)}
-                    {@const linkedVariableSummary =
-                      billName === undefined
-                        ? variableSummaryByName[linkedVariableName]
-                        : variableSummaryByNameByReformName[billName][
-                            linkedVariableName
-                          ]}
-                    <li class="flex justify-between gap-2 text-sm">
-                      <a
-                        class="2xl:text-md max-w-32 cursor-pointer overflow-x-hidden text-ellipsis text-nowrap hover:underline sm:max-w-none lg:max-w-44 xl:max-w-none"
-                        href={newSimulationUrl({
-                          ...displayMode,
-                          parametersVariableName: linkedVariableName,
-                        })}
-                        data-sveltekit-noscroll
-                        ><span class="text-gray-600"
-                          >{linkedVariableSummary.short_label ??
-                            linkedVariableSummary.label ??
-                            linkedVariableName}&nbsp;:&nbsp;</span
-                        ></a
-                      >
-                      <VariableValueChange
-                        {evaluationByNameArray}
-                        name={linkedVariableName}
-                        valueByCalculationName={linkedVariableValueByCalculationName}
-                        inline
-                        bold
-                      />
-                    </li>
-                  {/if}
-                {/each}
-              </ul>
-            {/if}
-          {/if}
-        </div>
-      </div>
-    </div>
-  </div>
-{/if}
-
-<style lang="postcss">
-  .fond {
-    background-color: #ffffff;
-    /* Polka dots - Heropatterns.com échelle réduite */
-    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3E%3Cpath fill='%23A0A0A0' fill-opacity='0.4' d='M1 3h1v1H1V3zm2-2h1v1H3V1z'%3E%3C/path%3E%3C/svg%3E");
-  }
-</style>
diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariablesCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariablesCompareView.svelte
new file mode 100644
index 000000000..c6321c6e9
--- /dev/null
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariablesCompareView.svelte
@@ -0,0 +1,180 @@
+<script lang="ts">
+  import {
+    type Decomposition,
+    type EvaluationByName,
+  } from "$lib/decompositions"
+  import type { DisplayMode } from "$lib/displays"
+  import { billName, revaluationName, shared } from "$lib/shared.svelte"
+  import { variableSummaryByNameByReformName } from "$lib/variables"
+  import type {
+    DecompositionReference,
+    VariableByName,
+  } from "@openfisca/json-model"
+  import VariableValueChange from "$lib/components/impacts_view/ValueChange.svelte"
+  import {
+    isNullVariableValueByCalculationName,
+    variableValueByCalculationNameFromEvaluation,
+  } from "$lib/calculations.svelte"
+  import { newSimulationUrl } from "$lib/urls"
+
+  interface Props {
+    displayMode: DisplayMode
+    evaluationByNameArray: EvaluationByName[]
+    situationsToCompareIndex: number[]
+    variableSummaryByName: VariableByName
+    decomposition: Decomposition
+    visibleChildren: DecompositionReference[] | undefined
+  }
+
+  let {
+    displayMode,
+    evaluationByNameArray,
+    situationsToCompareIndex,
+    variableSummaryByName,
+    decomposition,
+    visibleChildren,
+  }: Props = $props()
+
+  const variableSummary =
+    billName === undefined
+      ? variableSummaryByName[displayMode.parametersVariableName!]
+      : variableSummaryByNameByReformName[billName][
+          displayMode.parametersVariableName!
+        ]
+
+  const linkedVariables = variableSummary.linked_other_variables
+  const situationIndexLeft = situationsToCompareIndex[0]
+  const situationIndexRight = situationsToCompareIndex[1]
+  let evaluationByNameLeft: EvaluationByName = $derived(
+    evaluationByNameArray[situationIndexLeft],
+  )
+  let evaluationByNameRight: EvaluationByName = $derived(
+    evaluationByNameArray[situationIndexRight],
+  )
+</script>
+
+{#if linkedVariables !== undefined}
+  <div
+    class="fond flex w-full grow border-dashed border-black px-4"
+    class:border-l-0={!decomposition.open}
+    class:border-l-2={decomposition.open && visibleChildren !== undefined}
+    class:pl-0.5={!decomposition.open}
+  >
+    <!-- <div
+      class="mb-2 flex w-full grow flex-col justify-end lg:flex-row"
+      id="situation_{situationIndexLeft}_totalimpact"
+    > -->
+    <div class="flex w-full grow justify-around py-3 pl-5">
+      {#if linkedVariables !== undefined}
+        {@const linkedVariablesValueByCalculationNameLeft = linkedVariables.map(
+          (name) =>
+            variableValueByCalculationNameFromEvaluation(
+              evaluationByNameLeft[name],
+              revaluationName,
+              billName,
+              shared.parametricReform,
+            ),
+        )}
+        {#if shared.showNulls || !linkedVariablesValueByCalculationNameLeft.every(isNullVariableValueByCalculationName)}
+          <ul
+            class="flex h-fit flex-col rounded-md border bg-white p-2 text-gray-800"
+          >
+            {#each linkedVariables as linkedVariableName, index}
+              {@const linkedVariableValueByCalculationNameLeft =
+                linkedVariablesValueByCalculationNameLeft[index]}
+              {#if shared.showNulls || !isNullVariableValueByCalculationName(linkedVariableValueByCalculationNameLeft)}
+                {@const linkedVariableSummary =
+                  billName === undefined
+                    ? variableSummaryByName[linkedVariableName]
+                    : variableSummaryByNameByReformName[billName][
+                        linkedVariableName
+                      ]}
+                <li class="flex justify-between gap-2 text-sm">
+                  <a
+                    class="2xl:text-md max-w-32 cursor-pointer overflow-x-hidden text-ellipsis text-nowrap hover:underline sm:max-w-none lg:max-w-44 xl:max-w-none"
+                    href={newSimulationUrl({
+                      ...displayMode,
+                      parametersVariableName: linkedVariableName,
+                    })}
+                    data-sveltekit-noscroll
+                    ><span class="text-gray-600"
+                      >{linkedVariableSummary.short_label ??
+                        linkedVariableSummary.label ??
+                        linkedVariableName}&nbsp;:&nbsp;</span
+                    ></a
+                  >
+                  <VariableValueChange
+                    {evaluationByNameLeft}
+                    name={linkedVariableName}
+                    valueByCalculationName={linkedVariableValueByCalculationNameLeft}
+                    inline
+                    bold
+                  />
+                </li>
+              {/if}
+            {/each}
+          </ul>
+        {/if}
+
+        {@const linkedVariablesValueByCalculationNameRight =
+          linkedVariables.map((name) =>
+            variableValueByCalculationNameFromEvaluation(
+              evaluationByNameRight[name],
+              revaluationName,
+              billName,
+              shared.parametricReform,
+            ),
+          )}
+        {#if shared.showNulls || !linkedVariablesValueByCalculationNameRight.every(isNullVariableValueByCalculationName)}
+          <ul
+            class="flex h-fit flex-col rounded-md border bg-white p-2 text-gray-800"
+          >
+            {#each linkedVariables as linkedVariableName, index}
+              {@const linkedVariableValueByCalculationNameRight =
+                linkedVariablesValueByCalculationNameRight[index]}
+              {#if shared.showNulls || !isNullVariableValueByCalculationName(linkedVariableValueByCalculationNameRight)}
+                {@const linkedVariableSummary =
+                  billName === undefined
+                    ? variableSummaryByName[linkedVariableName]
+                    : variableSummaryByNameByReformName[billName][
+                        linkedVariableName
+                      ]}
+                <li class="flex justify-between gap-2 text-sm">
+                  <a
+                    class="2xl:text-md max-w-32 cursor-pointer overflow-x-hidden text-ellipsis text-nowrap hover:underline sm:max-w-none lg:max-w-44 xl:max-w-none"
+                    href={newSimulationUrl({
+                      ...displayMode,
+                      parametersVariableName: linkedVariableName,
+                    })}
+                    data-sveltekit-noscroll
+                    ><span class="text-gray-600"
+                      >{linkedVariableSummary.short_label ??
+                        linkedVariableSummary.label ??
+                        linkedVariableName}&nbsp;:&nbsp;</span
+                    ></a
+                  >
+                  <VariableValueChange
+                    {evaluationByNameRight}
+                    name={linkedVariableName}
+                    valueByCalculationName={linkedVariableValueByCalculationNameRight}
+                    inline
+                    bold
+                  />
+                </li>
+              {/if}
+            {/each}
+          </ul>
+        {/if}
+      {/if}
+    </div>
+    <!-- </div> -->
+  </div>
+{/if}
+
+<style lang="postcss">
+  .fond {
+    background-color: #ffffff;
+    /* Polka dots - Heropatterns.com échelle réduite */
+    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3E%3Cpath fill='%23A0A0A0' fill-opacity='0.4' d='M1 3h1v1H1V3zm2-2h1v1H3V1z'%3E%3C/path%3E%3C/svg%3E");
+  }
+</style>
diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
index 90339e764..6f7313437 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
@@ -1,6 +1,4 @@
 <script lang="ts">
-  import { preventDefault } from "svelte/legacy"
-
   import type { VariableByName } from "@openfisca/json-model"
 
   import { goto } from "$app/navigation"
@@ -18,7 +16,7 @@
   import type { Situation } from "$lib/situations"
   import { newSimulationUrl } from "$lib/urls"
   import { removeNegativeZero } from "$lib/values"
-  import LinkedVariables from "$lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariables.svelte"
+  import LinkedVariablesCompareView from "$lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariablesCompareView.svelte"
 
   interface Props {
     displayMode: DisplayMode
@@ -588,7 +586,7 @@
               </div>
               <!--Affichage des variables liées s'il y en a-->
               {#if displayMode.parametersVariableName !== undefined && decomposition.name === displayMode.parametersVariableName}
-                <LinkedVariables
+                <LinkedVariablesCompareView
                   {displayMode}
                   {evaluationByNameArray}
                   {situationsToCompareIndex}
-- 
GitLab


From f7c858aabf5cf6660ac97b7a8e9cc656c2055e4d Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Wed, 2 Apr 2025 10:40:34 +0200
Subject: [PATCH 11/13] Fix responsive

---
 .../compare_mode/LinkedVariablesCompareView.svelte            | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariablesCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariablesCompareView.svelte
index c6321c6e9..74abac17f 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariablesCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/LinkedVariablesCompareView.svelte
@@ -91,7 +91,7 @@
                       ]}
                 <li class="flex justify-between gap-2 text-sm">
                   <a
-                    class="2xl:text-md max-w-32 cursor-pointer overflow-x-hidden text-ellipsis text-nowrap hover:underline sm:max-w-none lg:max-w-44 xl:max-w-none"
+                    class="2xl:text-md xs:max-w-44 max-w-32 cursor-pointer overflow-x-hidden text-ellipsis text-nowrap hover:underline sm:max-w-32 lg:max-w-44 2xl:max-w-none"
                     href={newSimulationUrl({
                       ...displayMode,
                       parametersVariableName: linkedVariableName,
@@ -141,7 +141,7 @@
                       ]}
                 <li class="flex justify-between gap-2 text-sm">
                   <a
-                    class="2xl:text-md max-w-32 cursor-pointer overflow-x-hidden text-ellipsis text-nowrap hover:underline sm:max-w-none lg:max-w-44 xl:max-w-none"
+                    class="2xl:text-md xs:max-w-44 max-w-32 cursor-pointer overflow-x-hidden text-ellipsis text-nowrap hover:underline sm:max-w-32 lg:max-w-44 2xl:max-w-none"
                     href={newSimulationUrl({
                       ...displayMode,
                       parametersVariableName: linkedVariableName,
-- 
GitLab


From 0f050f554e11433ac5a01cf1a6cc7a5ceaecc65b Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Wed, 2 Apr 2025 10:50:10 +0200
Subject: [PATCH 12/13] =?UTF-8?q?D=C3=A9place=20hors=20du=20each=20le=20co?=
 =?UTF-8?q?mposant=20LinkedVariableCompareView=20afin=20qu'il=20ne=20s'aff?=
 =?UTF-8?q?iche=20pas=20deux=20fois=20si=20il=20y=20a=20un=20changement=20?=
 =?UTF-8?q?d=C3=BB=20=C3=A0=20un=20amendement.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../compare_mode/PaySlipCompareView.svelte    | 38 ++++++-------------
 1 file changed, 11 insertions(+), 27 deletions(-)

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
index 6f7313437..7e651b9e2 100644
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
+++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareView.svelte
@@ -584,34 +584,18 @@
                   </div>
                 {/if}
               </div>
-              <!--Affichage des variables liées s'il y en a-->
-              {#if displayMode.parametersVariableName !== undefined && decomposition.name === displayMode.parametersVariableName}
-                <LinkedVariablesCompareView
-                  {displayMode}
-                  {evaluationByNameArray}
-                  {situationsToCompareIndex}
-                  {variableSummaryByName}
-                  {decomposition}
-                  {visibleChildren}
-                />
-              {/if}
-            {/each}
-            <!--Affichage des variables liées s'il y en a
-            {#each rows as { deltaAtVectorIndexArray }}
-              {#if displayMode.parametersVariableName !== undefined && decomposition.name === displayMode.parametersVariableName}
-                <LinkedVariables
-                  {deltaAtVectorIndexArray}
-                  {displayMode}
-                  {evaluationByNameArray}
-                  {situationsToCompareIndex}
-                  {variableSummaryByName}
-                  {decomposition}
-                  {depth}
-                  {visibleChildren}
-                />
-              {/if}
             {/each}
-          -->
+            <!--Affichage des variables liées s'il y en a-->
+            {#if displayMode.parametersVariableName !== undefined && decomposition.name === displayMode.parametersVariableName}
+              <LinkedVariablesCompareView
+                {displayMode}
+                {evaluationByNameArray}
+                {situationsToCompareIndex}
+                {variableSummaryByName}
+                {decomposition}
+                {visibleChildren}
+              />
+            {/if}
           </div>
         </div>
       </div>
-- 
GitLab


From 231b0a852f8f8b094fb74389c9e58cf0fb9e8008 Mon Sep 17 00:00:00 2001
From: Dorine Lambinet <dorine.lambinet@assemblee-nationale.fr>
Date: Wed, 2 Apr 2025 10:51:01 +0200
Subject: [PATCH 13/13] Supprime ancien composant PaySlipCompareViewOld

---
 .../compare_mode/PaySlipCompareViewOld.svelte | 588 ------------------
 1 file changed, 588 deletions(-)
 delete mode 100644 src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareViewOld.svelte

diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareViewOld.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareViewOld.svelte
deleted file mode 100644
index 9243424b9..000000000
--- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/compare_mode/PaySlipCompareViewOld.svelte
+++ /dev/null
@@ -1,588 +0,0 @@
-<script lang="ts">
-  import { preventDefault } from "svelte/legacy"
-
-  import type { VariableByName } from "@openfisca/json-model"
-
-  import { goto } from "$app/navigation"
-  import { page } from "$app/stores"
-  import Tooltip from "$lib/components/ui_transverse_components/Tooltip.svelte"
-  import type {
-    EvaluationByName,
-    VisibleDecompositionForComparison,
-  } from "$lib/decompositions"
-  import { buildVisibleDecompositionsForComparison } from "$lib/decompositions"
-  import type { DisplayMode } from "$lib/displays"
-  import { entityByKey } from "$lib/entities"
-  import { shared } from "$lib/shared.svelte"
-  import type { Situation } from "$lib/situations"
-  import { newSimulationUrl } from "$lib/urls"
-  import { removeNegativeZero } from "$lib/values"
-
-  interface Props {
-    displayMode: DisplayMode
-    evaluationByNameArray: EvaluationByName[]
-    situations: Situation[]
-    situationsToCompareIndex: number[]
-    showLoader?: boolean
-    variableSummaryByName: VariableByName
-    year: number
-  }
-
-  let {
-    displayMode,
-    evaluationByNameArray,
-    situations,
-    situationsToCompareIndex,
-    showLoader = true,
-    variableSummaryByName,
-    year,
-  }: Props = $props()
-
-  const dateFormatter = new Intl.DateTimeFormat("fr-FR", { dateStyle: "full" })
-    .format
-  const deltaFormatter = (value: number): string =>
-    new Intl.NumberFormat("fr-FR", {
-      currency: "EUR",
-      maximumFractionDigits: 0,
-      minimumFractionDigits: 0,
-      signDisplay: "never",
-      style: "currency",
-    }).format(removeNegativeZero(value))
-
-  let useRevaluationInsteadOfLaw = $derived(
-    $page.data.revaluationName !== undefined,
-  )
-
-  let firstCalculationName = $derived(
-    useRevaluationInsteadOfLaw ? "revaluation" : "law",
-  )
-
-  let runningCalculationNames = $derived(
-    Object.entries(shared.calculationByName)
-      .filter(([, calculation]) => calculation.running)
-      .map(([calculationName]) => calculationName),
-  )
-
-  let modificationsAmendmentCount = $derived(
-    Object.keys(shared.parametricReform).length,
-  )
-
-  let visibleDecompositions: VisibleDecompositionForComparison[] = $state([])
-
-  $effect(() => {
-    visibleDecompositions = buildVisibleDecompositionsForComparison(
-      shared.decompositionByName,
-      entityByKey,
-      situationsToCompareIndex.map(
-        (situationIndex) => evaluationByNameArray[situationIndex],
-      ),
-      situationsToCompareIndex.map(
-        (situationIndex) => situations[situationIndex],
-      ),
-      variableSummaryByName,
-      shared.waterfall,
-      shared.showNulls,
-      useRevaluationInsteadOfLaw,
-      shared.vectorLength,
-      year,
-    )
-  })
-
-  function* iterToDepth(depth: number): Generator<number, void, unknown> {
-    for (let i = 0; i < depth; i++) {
-      yield i
-    }
-  }
-
-  function zoomIn(index: number) {
-    let visibleDecomposition = visibleDecompositions[index]
-    if (
-      visibleDecomposition === undefined ||
-      visibleDecomposition.visibleChildren === undefined
-    ) {
-      return
-    }
-    let decomposition = visibleDecomposition.decomposition
-    if (!decomposition.open) {
-      shared.decompositionByName[decomposition.name] = {
-        ...decomposition,
-        open: true,
-      }
-      return
-    }
-  }
-
-  function zoomOut(index: number) {
-    let visibleDecomposition = visibleDecompositions[index]
-    if (
-      visibleDecomposition === undefined ||
-      visibleDecomposition.visibleChildren === undefined
-    ) {
-      return
-    }
-    let decomposition = visibleDecomposition.decomposition
-    if (decomposition.open) {
-      shared.decompositionByName[decomposition.name] = {
-        ...decomposition,
-        open: false,
-      }
-      return
-    }
-  }
-</script>
-
-{#if visibleDecompositions.length > 0}
-  <div>
-    <div class="h-5 bg-gradient-to-b from-gray-100 to-transparent" />
-    <!--Montants-nuls-->
-    <div class="mx-1 mb-3 flex justify-start">
-      <label class="inline-flex cursor-pointer items-center">
-        <input
-          type="checkbox"
-          value=""
-          class="peer sr-only"
-          bind:checked={shared.showNulls}
-        />
-        <div
-          class="peer relative h-6 w-11 shrink-0 rounded-full bg-gray-400 after:absolute after:start-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:bg-white after:transition-all after:content-[''] peer-checked:bg-le-bleu peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-0"
-        ></div>
-        <span class="ms-3 text-sm font-medium text-gray-900 dark:text-gray-300"
-          >Montrer tous les dispositifs, y compris si leur montant est à 0€.</span
-        >
-      </label>
-    </div>
-  </div>
-  <!-- Labels and compared amounts of decompositions -->
-  <div>
-    {#each visibleDecompositions as { decomposition, depth, rows, trunk, visibleChildren }, index}
-      <!-- Decomposition label -->
-      <div class="flex h-7 items-center whitespace-nowrap">
-        {#if trunk}
-          <div
-            class="ml-2 mt-2 w-full overflow-x-hidden text-ellipsis border-gray-300 text-left text-base text-gray-500 hover:z-20 hover:overflow-x-visible"
-            class:border-t={index !== 0}
-          >
-            {#if displayMode.edit !== undefined}
-              <!-- Trunk decomposition node, in variable inputs mode => link -->
-              <a
-                class="cursor-pointer text-base hover:underline"
-                href={newSimulationUrl({
-                  ...displayMode,
-                  variableName: decomposition.name,
-                })}
-                data-sveltekit-noscroll
-                >{decomposition.short_label ?? decomposition.label}</a
-              >
-            {:else}
-              <!-- Trunk decomposition node with parameters, in parameters mode => link -->
-              <a
-                class="cursor-pointer text-base hover:underline"
-                href={newSimulationUrl({
-                  ...displayMode,
-                  mobileLaw: true,
-                  parametersVariableName: decomposition.name,
-                })}
-                data-sveltekit-noscroll
-                >{decomposition.short_label ?? decomposition.label}</a
-              >
-            {/if}
-          </div>
-        {:else}
-          {#each [...iterToDepth(depth)] as _level}
-            <div class="ml-2 h-full border-l border-le-gris-dispositif">
-              &nbsp;
-            </div>
-          {/each}
-          {#if visibleChildren === undefined}
-            <!-- Leaf node (except the first one, that belongs to trunk) -->
-            <div class="ml-4">
-              {#if decomposition.obsolete || decomposition.last_value_still_valid_on === undefined || decomposition.last_value_still_valid_on < (new Date().getFullYear() - 2).toString()}
-                <Tooltip
-                  allowFlip={false}
-                  arrowClass="bg-gray-100"
-                  widthClass="w-80"
-                  initialPlacement="bottom"
-                >
-                  <iconify-icon
-                    class="mr-1 shadow-none {decomposition.obsolete
-                      ? 'text-[#FF4133]'
-                      : 'text-[#FFAC33]'}"
-                    icon="material-symbols:warning-rounded"
-                    width="16"
-                    height="16"
-                  ></iconify-icon>
-                  {#snippet tooltip()}
-                    <div
-                      class="overflow-hidden rounded-lg border border-gray-200 bg-white shadow-2xl"
-                    >
-                      <div
-                        class="border-b border-gray-200 bg-gray-100 px-3 py-2"
-                      >
-                        <h3 class="font-semibold text-gray-900">
-                          ⚠️ Ce dispositif n'est peut-être pas à jour
-                        </h3>
-                      </div>
-                      <div class="px-3 py-2 text-sm font-light text-gray-500">
-                        Dernière relecture :
-                        {#if decomposition.last_value_still_valid_on === undefined}
-                          date indéterminée
-                        {:else}{dateFormatter(
-                            new Date(decomposition.last_value_still_valid_on),
-                          )}
-                        {/if}
-                        {#if decomposition.obsolete}
-                          ; Obsolète !{/if}
-                      </div>
-                    </div>
-                  {/snippet}
-                </Tooltip>
-              {/if}
-            </div>
-
-            {#if displayMode.edit !== undefined}
-              <!-- Leaf decomposition node in variable inputs mode => link -->
-              <a
-                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
-                href={newSimulationUrl({
-                  ...displayMode,
-                  variableName: decomposition.name,
-                })}
-                data-sveltekit-noscroll
-                >{decomposition.short_label ?? decomposition.label}</a
-              >
-            {:else}
-              <!-- Leaf decomposition node with parameters in parameters mode => link -->
-              <a
-                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
-                href={newSimulationUrl({
-                  ...displayMode,
-                  mobileLaw: true,
-                  parametersVariableName: decomposition.name,
-                })}
-                data-sveltekit-noscroll
-                >{decomposition.short_label ?? decomposition.label}</a
-              >
-            {/if}
-          {:else}
-            <!-- Non-trunk, non-leaf variablev-->
-            {#if decomposition.open}
-              <button class="p-0 text-black" onclick={() => zoomOut(index)}>
-                <iconify-icon
-                  class="align-[-0.2rem] text-lg"
-                  icon="ri-arrow-up-s-line"
-                ></iconify-icon>
-              </button>
-            {:else}
-              <button class="p-0 text-black" onclick={() => zoomIn(index)}>
-                <iconify-icon
-                  class="align-[-0.2rem] text-lg"
-                  icon="ri-arrow-right-s-line"
-                ></iconify-icon>
-              </button>
-            {/if}
-
-            {#if displayMode.edit !== undefined}
-              <!-- Non-lead decomposition node in variable inputs mode => no-link -->
-              <button
-                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base text-black hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-black hover:underline"
-                onclick={() => {
-                  if (decomposition.open) {
-                    zoomOut(index)
-                  } else {
-                    zoomIn(index)
-                  }
-                }}
-              >
-                {decomposition.short_label ?? decomposition.label}
-              </button>
-            {:else}
-              <!-- Leaf decomposition node with parameters in parameters mode => link -->
-              <a
-                class="cursor-pointer overflow-x-hidden text-ellipsis font-serif text-base hover:z-20 hover:overflow-x-visible hover:bg-white hover:text-le-gris-dispositif hover:underline"
-                href={newSimulationUrl({
-                  ...displayMode,
-                  parametersVariableName: decomposition.name,
-                })}
-                onclick={preventDefault(() => {
-                  if (decomposition.open) {
-                    zoomOut(index)
-                  } else {
-                    zoomIn(index)
-                  }
-                  goto(
-                    newSimulationUrl({
-                      ...displayMode,
-                      parametersVariableName: decomposition.name,
-                    }),
-                    { noScroll: true },
-                  )
-                })}
-                data-sveltekit-noscroll
-                >{decomposition.short_label ?? decomposition.label}</a
-              >
-            {/if}
-          {/if}
-        {/if}
-      </div>
-
-      {#each rows as { calculationName, deltaAtVectorIndexArray }}
-        <!-- Decomposition compared amounts -->
-        {#if !decomposition.open || trunk || index === 0}
-          <div class="relative flex items-center whitespace-nowrap">
-            {#if !decomposition.open && !trunk}
-              <div class="absolute">
-                {#each iterToDepth(depth)}
-                  <div class="ml-2 h-full border-l border-le-gris-dispositif">
-                    &nbsp;
-                  </div>
-                {/each}
-              </div>
-            {/if}
-            <div
-              class="justify-center {decomposition.open &&
-              trunk &&
-              visibleChildren.length > 1 &&
-              calculationName === firstCalculationName
-                ? ''
-                : ' border-none'} {calculationName === firstCalculationName
-                ? ''
-                : '-mt-1 mb-1'} flex w-full text-sm"
-            >
-              {#if decomposition.open || index === 0}
-                <!---Composant loader pour les valeurs intermédiaires-->
-                {#if showLoader && runningCalculationNames.length > 0}
-                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
-                      class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("bill")}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  <!--Valeurs du waterfall des montants intermédiaires -->
-                {:else if trunk || index === 0}
-                  {#if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
-                    {#if decomposition.open && trunk}
-                      <span class="mx-2 text-gray-500">=</span>
-                    {/if}
-                    <span
-                      class="text-sm {calculationName === firstCalculationName
-                        ? rows.find((row) => row.calculationName === 'bill') ===
-                          undefined
-                          ? rows.find(
-                              (row) => row.calculationName === 'amendment',
-                            ) === undefined
-                            ? 'text-gray-500'
-                            : 'text-gray-500 line-through-amendment'
-                          : 'text-gray-500 line-through-bill'
-                        : calculationName === 'bill'
-                          ? rows.find(
-                              (row) => row.calculationName === 'amendment',
-                            ) === undefined
-                            ? 'text-le-rouge-bill'
-                            : 'text-le-rouge-bill line-through-amendment'
-                          : 'bg-le-jaune'}"
-                      >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
-                    >
-                  {:else}
-                    <div class="flex w-full justify-center">
-                      <div class="mx-4 w-1/2">
-                        {#if decomposition.open && trunk}
-                          <span class="mx-2 text-gray-500">=</span>
-                        {/if}
-                        <span
-                          class="text-right text-sm {calculationName ===
-                          firstCalculationName
-                            ? rows.find(
-                                (row) => row.calculationName === 'bill',
-                              ) === undefined
-                              ? rows.find(
-                                  (row) => row.calculationName === 'amendment',
-                                ) === undefined
-                                ? 'text-gray-500'
-                                : 'text-gray-500 line-through-amendment'
-                              : 'text-gray-500 line-through-bill'
-                            : calculationName === 'bill'
-                              ? rows.find(
-                                  (row) => row.calculationName === 'amendment',
-                                ) === undefined
-                                ? 'text-le-rouge-bill'
-                                : 'text-le-rouge-bill line-through-amendment'
-                              : 'bg-le-jaune'}"
-                          >{deltaFormatter(
-                            deltaAtVectorIndexArray[0] ?? 0,
-                          )}</span
-                        >
-                      </div>
-                      <div class="mx-4 w-1/2">
-                        {#if decomposition.open && trunk}
-                          <span class="mx-2 text-gray-500">=</span>
-                        {/if}
-                        <span
-                          class="text-left text-sm {calculationName ===
-                          firstCalculationName
-                            ? rows.find(
-                                (row) => row.calculationName === 'bill',
-                              ) === undefined
-                              ? rows.find(
-                                  (row) => row.calculationName === 'amendment',
-                                ) === undefined
-                                ? 'text-gray-500'
-                                : 'text-gray-500 line-through-amendment'
-                              : 'text-gray-500 line-through-bill'
-                            : calculationName === 'bill'
-                              ? rows.find(
-                                  (row) => row.calculationName === 'amendment',
-                                ) === undefined
-                                ? 'text-le-rouge-bill'
-                                : 'text-le-rouge-bill line-through-amendment'
-                              : 'bg-le-jaune'}"
-                          >{deltaFormatter(
-                            deltaAtVectorIndexArray[1] ?? 0,
-                          )}</span
-                        >
-                      </div>
-                    </div>
-                  {/if}
-                {/if}
-                <!--Montant des dispositifs-->
-              {:else if deltaAtVectorIndexArray[0] === deltaAtVectorIndexArray[1]}
-                <!---Composant loader pour la valeur suivante-->
-                {#if showLoader && runningCalculationNames.length > 0}
-                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
-                      class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("bill")}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  <!--Valeur-->
-                {:else}
-                  <span
-                    class="text-base font-bold {calculationName ===
-                    firstCalculationName
-                      ? rows.find((row) => row.calculationName === 'bill') ===
-                        undefined
-                        ? rows.find(
-                            (row) => row.calculationName === 'amendment',
-                          ) === undefined
-                          ? ''
-                          : 'line-through-amendment'
-                        : 'line-through-bill'
-                      : calculationName === 'bill'
-                        ? rows.find(
-                            (row) => row.calculationName === 'amendment',
-                          ) === undefined
-                          ? 'text-le-rouge-bill'
-                          : 'text-le-rouge-bill line-through-amendment'
-                        : 'bg-le-jaune'}"
-                    >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
-                  >
-                {/if}
-              {:else}
-                <!---Composant loader pour la valeur suivante-->
-                {#if showLoader && runningCalculationNames.length > 0}
-                  {#if runningCalculationNames.includes("law") || runningCalculationNames.includes("revaluation")}<span
-                      class="mx-1 animate-pulse-2 bg-gray-500 px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("bill")}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-rouge-bill px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  {#if runningCalculationNames.includes("amendment") && modificationsAmendmentCount > 0}
-                    <span
-                      class="mx-1 animate-pulse-2 bg-le-jaune px-1 text-black blur-xs"
-                    >
-                      <span class="text-white blur">value €</span>
-                    </span>
-                  {/if}
-                  <!--Valeur dispositifs-->
-                {:else}
-                  <div class="flex w-full justify-center">
-                    <div class="mx-4 w-1/2">
-                      <span
-                        class="text-base font-bold {calculationName ===
-                        firstCalculationName
-                          ? rows.find(
-                              (row) => row.calculationName === 'bill',
-                            ) === undefined
-                            ? rows.find(
-                                (row) => row.calculationName === 'amendment',
-                              ) === undefined
-                              ? ''
-                              : 'line-through-amendment'
-                            : 'line-through-bill'
-                          : calculationName === 'bill'
-                            ? rows.find(
-                                (row) => row.calculationName === 'amendment',
-                              ) === undefined
-                              ? 'text-le-rouge-bill'
-                              : 'text-le-rouge-bill line-through-amendment'
-                            : 'bg-le-jaune'}"
-                        >{deltaFormatter(deltaAtVectorIndexArray[0] ?? 0)}</span
-                      >
-                    </div>
-                    <div class="mx-4 w-1/2">
-                      <span
-                        class="text-base font-bold {calculationName ===
-                        firstCalculationName
-                          ? rows.find(
-                              (row) => row.calculationName === 'bill',
-                            ) === undefined
-                            ? rows.find(
-                                (row) => row.calculationName === 'amendment',
-                              ) === undefined
-                              ? ''
-                              : 'line-through-amendment'
-                            : 'line-through-bill'
-                          : calculationName === 'bill'
-                            ? rows.find(
-                                (row) => row.calculationName === 'amendment',
-                              ) === undefined
-                              ? 'text-le-rouge-bill'
-                              : 'text-le-rouge-bill line-through-amendment'
-                            : 'bg-le-jaune'}"
-                        >{deltaFormatter(deltaAtVectorIndexArray[1] ?? 0)}</span
-                      >
-                    </div>
-                  </div>
-                {/if}
-              {/if}
-            </div>
-          </div>
-        {/if}
-      {/each}
-    {/each}
-  </div>
-{/if}
-- 
GitLab