Skip to content
Snippets Groups Projects
Commit 902f7bed authored by Toufic Batache's avatar Toufic Batache
Browse files

- Show test case variable value in bold

- Added test case descriptions
- Added ReadMore component
- Better management of memo urls
- Fix "définition et chiffres clés" button function
- Other design improvements
parent 33a426a7
No related branches found
No related tags found
1 merge request!210Début du travail sur la nouvelle page d'accueil/d'atterrissage du simulateur
......@@ -31,11 +31,11 @@
/* LIEN SIMPLE : lien solo (en dehors d'un corps de texte), se caractérise par un écard entre les lettres plus grand*/
.lx-link-simple {
@apply underline hover:decoration-2 underline-offset-4 tracking-wider;
@apply lx-link-simple-no-underline underline;
}
/* lien simple, sans soulignement : si besoin de plus de discretion */
.lx-link-simple-no-underline {
@apply hover:underline hover:decoration-2 underline-offset-4 tracking-wider;
@apply font-sans hover:underline hover:decoration-2 underline-offset-4 tracking-wider;
}
/* LIEN UPPERCASE : lien solo à la frontière avec un bouton, se caractérise par une casse en majuscule et un écard entre les lettres plus grand*/
......
<script lang="ts">
import { afterUpdate } from "svelte"
export let as: string
export let lines: number
export let text = "lire plus"
let element: HTMLElement
let truncated = false
function truncate() {
element.style.maxHeight = "none"
const originalHeight = parseInt(window.getComputedStyle(element).height)
const maxHeight =
parseInt(window.getComputedStyle(element).lineHeight) * lines
if (originalHeight > maxHeight) {
element.style.maxHeight = `${maxHeight}px`
truncated = true
} else {
truncated = false
}
}
afterUpdate(truncate)
</script>
<svelte:window on:resize={truncate} />
<svelte:element
this={as}
bind:this={element}
{...$$restProps}
class="relative {$$props.class ?? ''}"
>
<slot />
{#if truncated}
<button
class="absolute right-0 bottom-0 flex hover:underline leading-relaxed"
on:click
>
<span class="block pl-8 bg-gradient-to-r to-70% from-transparent to-white"
>...</span
>
<span class="block text-gray-500 bg-white"
>&nbsp;{text.replace(" ", "\xa0")}</span
>
</button>
{/if}
</svelte:element>
......@@ -46,7 +46,7 @@
<button
bind:this={item}
class="w-full flex justify-between items-center py-2 pr-1 shadow-[0_1px_0_0_#a3a3a3] hover:bg-black hover:bg-opacity-5 active:bg-black active:bg-opacity-10 transition-all duration-300"
class="w-full flex justify-between items-center p-2 shadow-[0_1px_0_0_#a3a3a3] hover:bg-black hover:bg-opacity-5 active:bg-black active:bg-opacity-10 transition-all duration-300"
class:shadow-[0_2px_0_0_#525252]={isOpen}
id={itemId}
on:click={toggleOpen}
......
......@@ -3,6 +3,7 @@
import type { Writable } from "svelte/store"
import TestCasePictos from "$lib/components/test_cases/TestCasePictos.svelte"
import Tooltip from "$lib/components/Tooltip.svelte"
import VariableValueChange from "$lib/components/variables/VariableValueChange.svelte"
import {
decompositionCoreByName,
......@@ -20,6 +21,7 @@
export let year: number
const billName = getContext("billName") as Writable<string | undefined>
let descriptionsOpen = false
const dispatch = createEventDispatcher()
const evaluationByNameArray = getContext("evaluationByNameArray") as Writable<
EvaluationByName[]
......@@ -90,6 +92,72 @@
)
</script>
<div class="flex flex-col items-end mb-4">
<Tooltip arrowClass="bg-gray-100" widthClass="w-80" initialPlacement="bottom">
<span class="underline decoration-dotted hover:text-black"
>Qu'est-ce qu’un dixième ?</span
>
<div
slot="tooltip"
class="overflow-hidden bg-white text-sm font-light rounded-lg border border-gray-200 shadow-md"
>
<div class="py-2 px-3 bg-gray-100 border-b border-gray-200">
<h3 class="font-semibold text-gray-900">
Qu'est-ce qu'un dixième de niveau de vie ?
</h3>
</div>
<div class="py-2 px-3 font-normal text-black">
<p>
Chaque dixième de niveau de vie représente 10% de la population
française agrégée par ménages classés par ordre croissant de niveau de
vie. Le 1er dixième concerne donc les ménages les plus pauvres ; le
10ème dixième, les ménages les plus aisés.
</p>
<p class="mt-2">
Le niveau de vie d'un ménage correspond à son revenu disponible après
tous les prélèvements et compléments de ressources, le tout divisé par
son nombre d'unité de consommation (peu ou prou le nombre de personnes
composant le foyer).
</p>
</div>
</div>
</Tooltip>
<Tooltip arrowClass="bg-gray-100" widthClass="w-80" initialPlacement="bottom">
<span class="underline decoration-dotted hover:text-black"
>Comment sont conçus ces cas types ?</span
>
<div
slot="tooltip"
class="overflow-hidden bg-white text-sm font-light rounded-lg border border-gray-200 shadow-md"
>
<div class="py-2 px-3 bg-gray-100 border-b border-gray-200">
<h3 class="font-semibold text-gray-900">
Comment sont conçus ces cas types ?
</h3>
</div>
<div class="py-2 px-3 font-normal text-black">
<p>
LexImpact s'est appuyé sur la base POTE 2021 des déclarations d'impôt
sur le revenu des foyers fiscaux distribuée par la DGFIP. À partir de
cette base représentative de la population française, LexImpact a
étudié chacun des déciles de niveau de vie pour en extraire les
caractéristiques les plus fréquentes :
</p>
<ul class="list-inside list-disc">
<li>composition familiale,</li>
<li>activité et revenus</li>
<li>lieu de vie et statut locataire ou propriétaire</li>
</ul>
<p class="mt-2">
La méthodologie appliquée est décrite pour chaque cas type en cliquant
sur le bouton "Représentativité du cas type".
</p>
</div>
</div>
</Tooltip>
</div>
<div class="hidden md:flex justify-between gap-1 px-2 overflow-x-scroll">
{#each Object.keys(testCaseByDixieme) as dixieme}
<button
......@@ -117,19 +185,19 @@
{/each}
</div>
<div
class="md:hidden w-full bg-neutral-100 active:bg-neutral-200 border-y-4 border-t-neutral-500 border-b-neutral-100 active:border-b-neutral-200 rounded-t-lg overflow-hidden shadow-md transition"
class="md:hidden w-full bg-neutral-100 active:bg-neutral-200 border-y-4 border-t-neutral-500 border-b-neutral-100 active:border-b-neutral-200 overflow-hidden shadow-md transition"
>
<select
bind:value={selectedDixieme}
class="w-full bg-transparent border-[12px] border-transparent rounded-t-lg outline-0"
class="w-full bg-transparent font-bold tracking-wide border-[12px] border-transparent outline-0"
>
{#each Object.keys(testCaseByDixieme) as dixieme}
<option value={dixieme}>
{@html formatLongOrdinalSup(Number(dixieme))} dixième
{#if dixieme === "1"}
(le plus pauvre)
- le plus pauvre
{:else if dixieme === "10"}
(le plus riche)
- le plus riche
{/if}
</option>
{/each}
......@@ -139,8 +207,9 @@
class="relative z-10 grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-2 sm:gap-5 p-3 bg-white shadow-[0_-4px_6px_-1px_rgb(0,0,0,0.1),0_-2px_4px_-2px_rgb(0,0,0,0.1)]"
>
{#each testCaseByDixieme[selectedDixieme] as testCase}
<div class="flex flex-col items-start">
<button
class="group flex flex-col p-2 lx-card-bg-gray-underline-le-vert"
class="group flex-1 flex flex-col p-2 lx-card-bg-gray-underline-le-vert"
class:gap-2={variableName !== undefined}
on:click={() => dispatch("select", testCase.index)}
>
......@@ -161,6 +230,7 @@
{#if variableName !== undefined}
{shortLabel}&nbsp;:
<VariableValueChange
bold={true}
evaluationByName={$evaluationByNameArray[testCase.index]}
inline
name={variableName}
......@@ -173,5 +243,22 @@
/>
</div>
</button>
<button
class="lx-link-text mt-1 text-sm text-gray-500"
on:click={() => (descriptionsOpen = !descriptionsOpen)}
>
<iconify-icon
class="text-xl align-[-0.25rem] transition-transform duration-300"
class:rotate-90={descriptionsOpen}
icon="ri-arrow-right-s-line"
/>
Représentativité du cas type
</button>
{#if descriptionsOpen}
<span class="mt-1 pl-5 pr-1 text-sm">
{testCase.description}
</span>
{/if}
</div>
{/each}
</div>
......@@ -94,7 +94,9 @@
<DialogDescription as="div" class="mt-2">
<p class="mb-6 text-lg">
LexImpact a configuré différents cas types représentatifs des
ménages français classé par niveau de vie. Une fois le cas type
ménages français classé par niveau de vie.
<br/>
Une fois le cas type
sélectionné, vous pourrez le modifier.
</p>
......
......@@ -11,8 +11,8 @@
type RequestedCalculations,
} from "$lib/calculations"
import { clickOutside } from "$lib/click_outside"
import AccordionItem from "$lib/components/accordion/AccordionItem.svelte"
import Accordion from "$lib/components/accordion/Accordion.svelte"
import AccordionItem from "$lib/components/accordion/AccordionItem.svelte"
import PictoBudgetEtat from "$lib/components/pictos/PictoBudgetEtat.svelte"
import TestCaseDixiemes from "$lib/components/test_cases/TestCaseDixiemes.svelte"
import TestCasePictos from "$lib/components/test_cases/TestCasePictos.svelte"
......@@ -23,6 +23,7 @@
decompositionCoreByNameByReformName,
type EvaluationByName,
} from "$lib/decompositions"
import { memoUrlByName } from "$lib/memos"
import type { Situation } from "$lib/situations"
import { newSimulationUrl } from "$lib/urls"
import {
......@@ -132,12 +133,12 @@
</script>
<div
class="z-20 absolute inset-0 bg-black/20"
class="z-20 fixed inset-0 bg-black/20"
transition:fade={{ duration: 500, easing: quartOut }}
/>
<aside
class="z-20 fixed inset-x-0 lg:inset-x-20 xl:inset-x-36 top-32 md:top-20 bottom-0 lg:inset-y-0 flex flex-col gap-10 p-4 lg:pt-20 lg:pb-10 lg:px-20 overflow-y-scroll bg-white rounded-t-2xl lg:rounded-t-none shadow-2xl"
class="z-20 fixed inset-x-0 lg:inset-x-20 xl:inset-x-36 top-32 md:top-20 bottom-0 lg:inset-y-0 flex flex-col p-4 lg:pt-20 lg:pb-10 lg:px-8 overflow-y-scroll bg-white rounded-t-2xl lg:rounded-t-none shadow-2xl"
transition:fly={{
duration: 500,
y: innerHeight,
......@@ -149,25 +150,15 @@
excluded: [document.querySelector("nav")],
}}
>
<button
class="hidden lg:flex items-center self-end gap-2 py-1.5 px-3 bg-white hover:bg-neutral-100 active:bg-neutral-200 rounded-lg text-neutral-600 hover:text-black text-sm tracking-wider uppercase transition-all duration-200 ease-out-back"
on:click={() => dispatch("close")}
>
<iconify-icon class="text-lg" icon="ri:close-line" />
Fermer
</button>
<button
class="lg:hidden self-end fixed z-10 p-1"
on:click={() => dispatch("close")}
>
<button class="self-end fixed z-20 p-1" on:click={() => dispatch("close")}>
<iconify-icon
class="block p-1 text-2xl text-neutral-500 bg-neutral-200 rounded-full"
icon="ri:close-fill"
/>
</button>
<div class="self-center flex flex-col items-center mt-12 lg:mt-0">
<div class="flex flex-col gap-10 lg:px-12">
<div class="self-center flex flex-col items-center mt-12">
<h4 class="font-serif font-bold text-2xl">
{label}
</h4>
......@@ -181,10 +172,13 @@
<Accordion allowOnlySingle={false} childClass="px-4 lg:px-12 py-4">
<AccordionItem open={true} title="Définition">
{#if description !== undefined}
{#each Object.entries(description).sort( ([instant1], [instant2]) => instant2.localeCompare(instant1), ) as [instant, descriptions]}
{#each descriptions as { href, note, title }}
{#each Object.entries(description).sort( ([instant1], [instant2]) => instant2.localeCompare(instant1), ) as [instant, desc]}
{#each desc as { href, note, title }}
<article>
{#if note !== undefined}
<span class="break-words font-serif leading-normal text-black">
<span
class="break-words font-serif leading-normal text-black"
>
{@html note}
</span>
{/if}
......@@ -213,6 +207,7 @@
{/if}
</span>
{/if}
</article>
{/each}
{/each}
{:else}
......@@ -252,40 +247,16 @@
</div>
{/if}
{#if name === "irpp_economique" || name === "aah" || name === "prime_partage_valeur_exoneree" || name === "prime_partage_valeur_exoneree_exceptionnelle" || name === "af" || name === "af_base" || name === "af_majoration" || name === "af_allocation_forfaitaire" || name === "af_complement_degressif" || name === "af_allocation_forfaitaire_complement_degressif" || name === "prestations_familiales"}
<div class="mt-4 flex justify-end">
{#if Object.hasOwn(memoUrlByName, name)}
<a
href={name === "irpp_economique"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memo_irpp"
: name === "aah"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memo_aah"
: name === "prime_partage_valeur_exoneree"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_pepa.html"
: name === "prestations_familiales"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html"
: name === "af"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#allocations-familiales"
: name === "af_base"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#allocations-familiales-de-base"
: name === "af_majoration"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#majoration-pour-%C3%A2ge"
: name === "af_allocation_forfaitaire"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#allocation-forfaitaire"
: name === "af_complement_degressif"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#compl%C3%A9ment-d%C3%A9gressif"
: name ===
"af_allocation_forfaitaire_complement_degressif"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#compl%C3%A9ment-d%C3%A9gressif"
: "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_pepa.html"}
class="mt-4 inline-flex items-center gap-1.5 py-1.5 px-2 bg-white hover:bg-neutral-100 active:bg-neutral-200 rounded-lg font-semibold text-le-gris-dispositif hover:text-le-gris-dispositif-dark text-sm tracking-wider uppercase transition-all duration-200 ease-out-back s-y_bCXRrkrYfP"
href={memoUrlByName[name]}
rel="noreferrer"
target="_blank"
class="inline-flex items-center uppercase tracking-wider text-le-gris-dispositif-dark font-semibold hover:underline text-sm 2xl:text-md"
><iconify-icon
class="mr-1 text-lg"
icon="ri-file-text-line"
/>Définition et chiffres clés</a
>
</div>
<iconify-icon class="text-lg" icon="ri-line-chart-line" />
Chiffres clés
</a>
{/if}
</AccordionItem>
<AccordionItem
......@@ -342,7 +313,9 @@
class="font-serif italic">&nbsp;{shortLabel}&nbsp;</span
>»&nbsp;:
</span>
<div class="mt-4 mb-10 grid grid-cols-1 md:grid-cols-3 gap-2 sm:gap-5">
<div
class="mt-4 mb-10 grid grid-cols-1 md:grid-cols-3 gap-2 sm:gap-5"
>
{#each filteredTestCases as { title, situations, indices }}
<a
class="group flex flex-col gap-2 p-2 lx-card-bg-gray-underline-le-vert"
......@@ -390,6 +363,7 @@
vs
{/if}
<VariableValueChange
bold={true}
evaluationByName={$evaluationByNameArray[index]}
inline
{name}
......@@ -426,4 +400,5 @@
/>
</AccordionItem>
</Accordion>
</div>
</aside>
......@@ -4,9 +4,11 @@
import { getContext } from "svelte"
import type { Writable } from "svelte/store"
import ReadMore from "$lib/components/ReadMore.svelte"
import Tooltip from "$lib/components/Tooltip.svelte"
import type { Decomposition } from "$lib/decompositions"
import type { DisplayMode } from "$lib/displays"
import { memoUrlByName } from "$lib/memos"
import { newSimulationUrl } from "$lib/urls"
export let decomposition: Decomposition | undefined
......@@ -140,68 +142,37 @@
<!--Description du dispositif-->
{#if descriptionsByInstant !== undefined}
<!--Add variable descriptions as described in decomposition customization and order them by date. -->
{#each Object.entries(descriptionsByInstant).sort( ([instant1], [instant2]) => instant2.localeCompare(instant1), ) as [instant, descriptions]}
{#each descriptions as { href, note, title }}
{@const [latestInstant, latestDescriptions] = Object.entries(
descriptionsByInstant,
).sort(([instant1], [instant2]) => instant2.localeCompare(instant1))[0]}
{#if latestDescriptions !== undefined && latestDescriptions.length > 0}
{@const { href, note, title } = latestDescriptions[0]}
<article class="mr-4">
<div class="">
{#if note !== undefined}
<span
class="relative block max-h-11 overflow-hidden break-words font-serif text-sm leading-normal text-black"
>
{@html note}
<button
class="absolute right-0 bottom-0 flex hover:underline leading-relaxed"
<ReadMore
as="span"
class="block overflow-hidden break-words font-serif text-sm leading-normal text-black"
lines={2}
on:click={() => ($variableModalOpen = true)}
>
<span
class="block pl-8 bg-gradient-to-r to-70% from-transparent to-white"
>...</span
>
<span class="block text-gray-500 bg-white"
>&nbsp;lire&nbsp;plus</span
>
</button>
</span>
{@html note}
</ReadMore>
{/if}
</div>
</article>
{/each}
{/each}
{/if}
{/if}
</div>
{#if displayMode.parametersVariableName === "irpp_economique" || displayMode.parametersVariableName === "aah" || displayMode.parametersVariableName === "prime_partage_valeur_exoneree" || displayMode.parametersVariableName === "prime_partage_valeur_exoneree_exceptionnelle" || displayMode.parametersVariableName === "af" || displayMode.parametersVariableName === "af_base" || displayMode.parametersVariableName === "af_majoration" || displayMode.parametersVariableName === "af_allocation_forfaitaire" || displayMode.parametersVariableName === "af_complement_degressif" || displayMode.parametersVariableName === "af_allocation_forfaitaire_complement_degressif" || displayMode.parametersVariableName === "prestations_familiales"}
<div class="flex justify-end">
<a
href={displayMode.parametersVariableName === "irpp_economique"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memo_irpp"
: displayMode.parametersVariableName === "aah"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memo_aah"
: displayMode.parametersVariableName ===
"prime_partage_valeur_exoneree"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_pepa.html"
: displayMode.parametersVariableName === "prestations_familiales"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html"
: displayMode.parametersVariableName === "af"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#allocations-familiales"
: displayMode.parametersVariableName === "af_base"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#allocations-familiales-de-base"
: displayMode.parametersVariableName === "af_majoration"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#majoration-pour-%C3%A2ge"
: displayMode.parametersVariableName ===
"af_allocation_forfaitaire"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#allocation-forfaitaire"
: displayMode.parametersVariableName ===
"af_complement_degressif"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#compl%C3%A9ment-d%C3%A9gressif"
: displayMode.parametersVariableName ===
"af_allocation_forfaitaire_complement_degressif"
? "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#compl%C3%A9ment-d%C3%A9gressif"
: "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_pepa.html"}
rel="noreferrer"
target="_blank"
class="inline-flex items-center mb-8 uppercase tracking-wider text-le-gris-dispositif-dark font-semibold hover:underline text-sm 2xl:text-md"
><iconify-icon class="mr-1 text-lg" icon="ri-file-text-line" />Définition
et chiffres clés</a
<div class="flex flex-col items-end">
<button
class="mb-8 flex items-center gap-1.5 py-1.5 px-3 bg-white hover:bg-neutral-100 active:bg-neutral-200 rounded-lg font-semibold text-le-gris-dispositif-dark hover:text-black text-sm tracking-wider uppercase transition-all duration-200 ease-out-back s-y_bCXRrkrYfP"
on:click={() => ($variableModalOpen = true)}
>
</div>
<iconify-icon class="text-lg" icon="ri-file-text-line" />
Définition
{#if variable?.name !== undefined && Object.hasOwn(memoUrlByName, variable.name)}
et chiffres clés
{/if}
</button>
</div>
export const memoUrlByName: { [variableName: string]: string } = {
irpp_economique:
"https://documentation.leximpact.dev/leximpact_prepare_data/memo_irpp",
aah: "https://documentation.leximpact.dev/leximpact_prepare_data/memo_aah",
prime_partage_valeur_exoneree:
"https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_pepa.html",
prestations_familiales:
"https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html",
af: "https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#allocations-familiales",
af_base:
"https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#allocations-familiales-de-base",
af_majoration:
"https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#majoration-pour-%C3%A2ge",
af_allocation_forfaitaire:
"https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#allocation-forfaitaire",
af_complement_degressif:
"https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#compl%C3%A9ment-d%C3%A9gressif",
af_allocation_forfaitaire_complement_degressif:
"https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_prestations_familiales.html#compl%C3%A9ment-d%C3%A9gressif",
prime_partage_valeur_exoneree_exceptionnelle:
"https://documentation.leximpact.dev/leximpact_prepare_data/memos/memo_pepa.html",
}
......@@ -1878,6 +1878,7 @@
vs
{/if}
<VariableValueChange
bold={true}
evaluationByName={$evaluationByNameArray[
index
]}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment