diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipView.svelte index fc44777c8b93861d51810a067bbf9a01f6204a1a..d66fbe686eddbaa5962fb0bfad351d55a62620d0 100644 --- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipView.svelte +++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/PaySlipView.svelte @@ -8,23 +8,16 @@ import ValueChange from "$lib/components/impacts_view/ValueChange.svelte" import VariableValueChange from "$lib/components/impacts_view/VariableValueChange.svelte" import { - isNullVariableValueByCalculationName, - variableValueByCalculationNameFromEvaluation, - } from "$lib/calculations.svelte" - import { - getDecompositionParentName, type VisibleDecomposition, type EvaluationByName, + isChildOrDescendant, } from "$lib/decompositions" - import { - buildVisibleDecompositions, - type DecompositionByName, - } 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 publicConfig from "$lib/public_config" - import { revaluationName, shared, billName } from "$lib/shared.svelte" + import { revaluationName, shared } from "$lib/shared.svelte" import { type ActiveSlider, getCalculatedVariableValueByCalculationName, @@ -38,13 +31,13 @@ oilTypes, type ValuesByCalculationNameByVariableName, type VariableValue, - variableSummaryByNameByReformName, } from "$lib/variables" + import LinkedVariables from "$lib/components/variables/LinkedVariables.svelte" + import { iterToDepth } from "$lib/iterators" interface Props { displayMode: DisplayMode evaluationByName: EvaluationByName - highlightDecomposition?: boolean showLoader?: boolean situation: Situation situationIndex: number @@ -58,7 +51,6 @@ let { displayMode, evaluationByName, - highlightDecomposition = false, showLoader = true, situation = $bindable(), situationIndex, @@ -200,12 +192,6 @@ ).law } - function* iterToDepth(depth: number): Generator<number, void, unknown> { - for (let i = 0; i < depth; i++) { - yield i - } - } - function removeSituationSlider() { if (shared.savedSituation !== undefined) { situation = shared.savedSituation @@ -322,28 +308,6 @@ return } } - - function isChildOrDescendant( - decompositionByName: DecompositionByName, - currentName: string, - selectedName: string, - ) { - // Vérifie si currentName appartient aux descendants de selectedName - let parentName = getDecompositionParentName( - decompositionByName, - currentName, - ) - - while (parentName) { - if (parentName === selectedName) { - return true // Trouvé : currentName est un descendant de selectedName - } - // Continue à remonter dans l'arborescence - parentName = getDecompositionParentName(decompositionByName, parentName) - } - - return false // Aucun parent ne correspond à selectedName - } </script> <!--Ce composant se découpe en 3 zones : @@ -683,135 +647,16 @@ </div> </div> <!--Affichage des variables liées s'il y en a--> - {#if decomposition.name === displayMode.parametersVariableName} - {#if displayMode.parametersVariableName !== undefined} - {@const variableSummary = - billName === undefined - ? variableSummaryByName[displayMode.parametersVariableName] - : variableSummaryByNameByReformName[billName][ - displayMode.parametersVariableName - ]} - - {#if variableSummary !== undefined} - {@const linkedVariablesList = [ - variableSummary.linked_output_variables?.filter( - (variableName) => - !variableSummary.linked_added_variables?.includes( - variableName, - ), - ), - variableSummary.linked_other_variables?.filter( - (variableName) => - !variableSummary.linked_added_variables?.includes( - variableName, - ) && - !variableSummary.linked_output_variables?.includes( - variableName, - ), - ), - ].filter((value) => value !== undefined && value.length > 0)} - {#if linkedVariablesList.length > 0} - <div class="fond flex px-4"> - <!--Indentation pour chaque niveau de l'arbre, illustré par une bordure--> - {#each iterToDepth(depth)} - <div - class={`min-h-full border-l-2 bg-white pl-1 pr-2 ${ - decomposition.name !== - displayMode.parametersVariableName && - !( - displayMode.parametersVariableName && - isChildOrDescendant( - shared.decompositionByName, - decomposition.name, - displayMode.parametersVariableName, - ) - ) - ? "border-gray-400" - : "border-black" - }`} - > - - </div> - {/each} - <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_{situationIndex}_totalimpact" - > - {#each linkedVariablesList as linkedVariables} - <div class="flex w-full grow py-3 pl-5"> - {#if linkedVariables !== undefined && linkedVariables.length > 0} - {@const linkedVariablesValueByCalculationName = - linkedVariables.map((name) => - variableValueByCalculationNameFromEvaluation( - evaluationByName[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} : </span - ></a - > - <VariableValueChange - {evaluationByName} - name={linkedVariableName} - valueByCalculationName={linkedVariableValueByCalculationName} - inline - bold - /> - </li> - {/if} - {/each} - </ul> - {/if} - {/if} - </div> - {/each} - </div> - </div> - </div> - {/if} - {/if} - {/if} + {#if displayMode.parametersVariableName !== undefined && decomposition.name === displayMode.parametersVariableName} + <LinkedVariables + {displayMode} + {evaluationByName} + {situationIndex} + {variableSummaryByName} + {decomposition} + {depth} + {visibleChildren} + ></LinkedVariables> {/if} {/each} </div> diff --git a/src/lib/components/impacts_view/test_cases_view/test_case_selected/TestCaseView.svelte b/src/lib/components/impacts_view/test_cases_view/test_case_selected/TestCaseView.svelte index 01e834480345a7d00e527e8288f3c1167b191e6f..8d53e3fba2d551de4929ff32498f474a1173ab8f 100644 --- a/src/lib/components/impacts_view/test_cases_view/test_case_selected/TestCaseView.svelte +++ b/src/lib/components/impacts_view/test_cases_view/test_case_selected/TestCaseView.svelte @@ -16,7 +16,6 @@ interface Props { displayMode: DisplayMode - highlightDecomposition?: boolean situation: Situation situationIndex: number valuesByCalculationNameByVariableName: ValuesByCalculationNameByVariableName @@ -25,7 +24,6 @@ let { displayMode, - highlightDecomposition = false, situation, situationIndex, valuesByCalculationNameByVariableName, @@ -79,7 +77,6 @@ <PaySlipView {displayMode} {evaluationByName} - {highlightDecomposition} {situation} {situationIndex} variableSummaryByName={completeVariableSummaryByName} diff --git a/src/lib/components/legislation_view/parameters/LinkedVariables.svelte b/src/lib/components/legislation_view/parameters/LinkedVariables.svelte new file mode 100644 index 0000000000000000000000000000000000000000..07021ba3900f0a2339573dd8dec6639015a25530 --- /dev/null +++ b/src/lib/components/legislation_view/parameters/LinkedVariables.svelte @@ -0,0 +1,155 @@ +<script lang="ts"> + import { + isChildOrDescendant, + 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 "./VariableValueChange.svelte" + import { iterToDepth } from "$lib/iterators" + import { + isNullVariableValueByCalculationName, + variableValueByCalculationNameFromEvaluation, + } from "$lib/calculations.svelte" + import { newSimulationUrl } from "$lib/urls" + + interface Props { + displayMode: DisplayMode + evaluationByName: EvaluationByName + situationIndex: number + variableSummaryByName: VariableByName + decomposition: Decomposition + depth: number + visibleChildren: DecompositionReference[] | undefined + } + + let { + displayMode, + evaluationByName, + situationIndex, + variableSummaryByName, + decomposition, + depth, + visibleChildren, + }: Props = $props() + + const variableSummary = + billName === undefined + ? variableSummaryByName[displayMode.parametersVariableName!] + : variableSummaryByNameByReformName[billName][ + displayMode.parametersVariableName! + ] + + const linkedVariablesList = + variableSummary !== undefined + ? [ + variableSummary.linked_output_variables?.filter( + (variableName) => + !variableSummary.linked_added_variables?.includes(variableName), + ), + variableSummary.linked_other_variables?.filter( + (variableName) => + !variableSummary.linked_added_variables?.includes(variableName) && + !variableSummary.linked_output_variables?.includes(variableName), + ), + ].filter((value) => value !== undefined && value.length > 0) + : undefined +</script> + +{#if linkedVariablesList !== undefined && linkedVariablesList.length > 0} + <div class="fond flex px-4"> + <!--Indentation pour chaque niveau de l'arbre, illustré par une bordure--> + {#each iterToDepth(depth)} + <div + class={`min-h-full border-l-2 bg-white pl-1 pr-2 ${ + decomposition.name !== displayMode.parametersVariableName && + !( + displayMode.parametersVariableName && + isChildOrDescendant( + shared.decompositionByName, + decomposition.name, + displayMode.parametersVariableName, + ) + ) + ? "border-gray-400" + : "border-black" + }`} + > + + </div> + {/each} + <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_{situationIndex}_totalimpact" + > + {#each linkedVariablesList as linkedVariables} + <div class="flex w-full grow py-3 pl-5"> + {#if linkedVariables !== undefined && linkedVariables.length > 0} + {@const linkedVariablesValueByCalculationName = + linkedVariables.map((name) => + variableValueByCalculationNameFromEvaluation( + evaluationByName[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} : </span + ></a + > + <VariableValueChange + {evaluationByName} + name={linkedVariableName} + valueByCalculationName={linkedVariableValueByCalculationName} + inline + bold + /> + </li> + {/if} + {/each} + </ul> + {/if} + {/if} + </div> + {/each} + </div> + </div> + </div> +{/if} diff --git a/src/lib/decompositions.ts b/src/lib/decompositions.ts index b5dcef1415b0c37041215b995e5f676309ac6b7b..352b68579b47edfce682d3086c015b0d5d796355 100644 --- a/src/lib/decompositions.ts +++ b/src/lib/decompositions.ts @@ -1714,6 +1714,27 @@ export function getNonTrunkParentInVisibleDecompositions( return undefined } +export function isChildOrDescendant( + decompositionByName: DecompositionByName, + currentName: string, + selectedName: string, +) { + // Vérifie si currentName appartient aux descendants de selectedName + let parentName = getDecompositionParentName( + decompositionByName, + currentName, + ) + + while (parentName) { + if (parentName === selectedName) { + return true // Trouvé : currentName est un descendant de selectedName + } + // Continue à remonter dans l'arborescence + parentName = getDecompositionParentName(decompositionByName, parentName) + } + + return false // Aucun parent ne correspond à selectedName +} function patchDecompositionCoreByName( decompositionCoreByName: DecompositionCoreByName, diff --git a/src/lib/iterators.ts b/src/lib/iterators.ts index 6b419e281b8086461fb3eae8407199294fd9aaae..92b7fe21ffed708f620957d3161034c511dd23f7 100644 --- a/src/lib/iterators.ts +++ b/src/lib/iterators.ts @@ -11,3 +11,9 @@ export function* iterToLimit<T>( index++ } } + +export function* iterToDepth(depth: number): Generator<number, void, unknown> { + for (let i = 0; i < depth; i++) { + yield i + } +} diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 9f4dd2b52231b351b664dd2a6e078531e7850981..53999888f5310f8ea8a63eda6f31be6c4857eba7 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,6 +1,4 @@ <script lang="ts"> - import { run } from "svelte/legacy" - import { type Audit, auditInteger, @@ -231,7 +229,6 @@ const suffix = longOrdinalSuffixes.get(rule) return `${n}<sup>${suffix}</sup>` } - let highlightDecomposition = false let isBudgetConnexionModalOpen = $state(false) let isBudgetSharingModalOpen = $state(false) let isTestCaseSelectModalOpen = $state(false) @@ -1452,7 +1449,6 @@ {#if shared.testCasesIndex.length === 1} <TestCaseView {displayMode} - {highlightDecomposition} on:changeTestCasesIndex={({ detail }) => changeTestCasesIndex(detail)} on:changeTestCaseToEditIndex={({ detail }) => {